libbcmhost-shim: new shim library for r-pi's bcm stuff
[openpandora.oe.git] / recipes / armhf / libbcmhost-shim / bcm_host_shim.c
1 /*
2  * bcm_host_shim
3  * (C) notaz, 2016
4  *
5  * This work is licensed under the terms of 3-clause BSD license.
6  */
7 #define _GNU_SOURCE
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <unistd.h>
11 #include <dlfcn.h>
12
13 #define SCREEN_WIDTH  800
14 #define SCREEN_HEIGHT 480
15
16 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
17
18 void bcm_host_init(void)
19 {
20 }
21
22 void bcm_host_deinit(void)
23 {
24 }
25
26 uint32_t vc_dispmanx_display_open(uint32_t dev)
27 {
28         return 0xf00;
29 }
30
31 uint32_t vc_dispmanx_element_add()
32 {
33         return 0xf04;
34 }
35
36 uint32_t vc_dispmanx_update_start(int32_t prio)
37 {
38         return 0xf08;
39 }
40
41 int vc_dispmanx_update_submit_sync(uint32_t upd_handle)
42 {
43         //printf("%s\n", __func__);
44         return 0;
45 }
46
47 int graphics_get_display_size(uint16_t dpy, uint32_t *w, uint32_t *h)
48 {
49         *w = SCREEN_WIDTH;
50         *h = SCREEN_HEIGHT;
51         return 0;
52 }
53
54 #ifndef SDL_FULLSCREEN
55 #define SDL_FULLSCREEN 0x80000000
56 #define SDL_RESIZABLE  0x00000010
57 #endif
58
59 static void *get_real_func(const char *name)
60 {
61         void *f;
62
63         f = dlsym(RTLD_NEXT, name);
64         if (f == NULL) {
65                 fprintf(stderr, "%s: %s\n", name, dlerror());
66                 _exit(1);
67         }
68         return f;
69 }
70
71 /* pandora's SGX driver can only run fullscreen */
72 void *SDL_SetVideoMode(int width, int height, int bpp, uint32_t flags)
73 {
74         static void * (*f)(int, int, int, uint32_t);
75
76         //printf("%s %d %x\n", __func__, bpp, flags);
77
78         width = height = bpp = 0;
79         flags &= ~SDL_RESIZABLE;
80         flags |=  SDL_FULLSCREEN;
81
82         if (f == NULL)
83                 f = get_real_func(__func__);
84
85         return f(width, height, bpp, flags);
86 }
87
88 int SDL_PollEvent(void *e)
89 {
90         static int (*f)(void *);
91         int ret;
92
93         if (f == NULL)
94                 f = get_real_func(__func__);
95
96         ret = f(e);
97
98         // event, SDL_KEYDOWN, SDLK_q
99         if (ret != 0 && e != NULL) {
100                 if (*(uint8_t *)e == 2 && ((uint32_t *)e)[2] == 113)
101                         *(uint8_t *)e = 12; // SDL_QUIT
102         }
103
104         return ret;
105 }
106
107 /* can't use 8bits/channel on pandora, must filter out confing */
108 #ifndef EGL_NONE
109 #define EGL_NONE                          0x3038
110 #define EGL_RED_SIZE                      0x3024
111 #define EGL_GREEN_SIZE                    0x3023
112 #define EGL_BLUE_SIZE                     0x3022
113 #define EGL_ALPHA_SIZE                    0x3021
114 #define EGL_SURFACE_TYPE                  0x3033
115 #endif
116
117 int eglChooseConfig(void *dpy, const int32_t *attrib_list,
118         void *configs, int32_t config_size, int32_t *num_config)
119 {
120         static int (*f)(void *, const int32_t *,
121                         void *, int32_t, int32_t *);
122         int32_t attrib_list_c[64];
123         int i, o;
124
125         //printf("%s\n", __func__);
126
127         if (f == NULL)
128                 f = get_real_func(__func__);
129
130         for (i = o = 0; o < ARRAY_SIZE(attrib_list_c) - 2; i += 2) {
131                 if (attrib_list == NULL || attrib_list[i] == EGL_NONE)
132                         break;
133
134                 switch (attrib_list[i]) {
135                 case EGL_RED_SIZE:
136                 case EGL_GREEN_SIZE:
137                 case EGL_BLUE_SIZE:
138                 case EGL_SURFACE_TYPE:
139                 case EGL_ALPHA_SIZE:
140                         continue;
141                 }
142
143                 attrib_list_c[o++] = attrib_list[i + 0];
144                 attrib_list_c[o++] = attrib_list[i + 1];
145         }
146         attrib_list_c[o++] = EGL_NONE;
147
148         return f(dpy, attrib_list_c, configs, config_size, num_config);
149 }
150
151 void *eglCreateWindowSurface(void *dpy, void *config, void *win,
152         const int32_t *attrib_list)
153 {
154         static void * (*f)(void *, void *, void *, const int32_t *);
155
156         //printf("%s\n", __func__);
157
158         if (f == NULL)
159                 f = get_real_func(__func__);
160
161         return f(dpy, config, NULL, attrib_list);
162 }