in_sdl: give names to gamepad buttons
[libpicofe.git] / gl_platform.c
CommitLineData
0d645bc5 1#include <stdio.h>
2#include <stdlib.h>
3#include <EGL/egl.h>
4#include <GLES/gl.h>
5
d5d1b164 6#include "gl_loader.h"
0d645bc5 7#include "gl.h"
8#include "gl_platform.h"
9
10#ifdef VCOS_VERSION
11
12/*
13 * hacks for Broadcom VideoCore / Raspberry Pi..
14 * Why do I have to do this proprietary API stuff,
15 * couldn't they implement EGL properly? D:
16 */
17#include <bcm_host.h>
18#include <X11/Xlib.h>
cceadf4c 19#include <dlfcn.h>
0d645bc5 20
21static Display *x11display;
22static Window x11window;
23static DISPMANX_DISPLAY_HANDLE_T m_dispmanDisplay;
24static EGL_DISPMANX_WINDOW_T m_nativeWindow;
25
cceadf4c 26static void *x11lib;
27#define FPTR(f) typeof(f) * p##f
28static FPTR(XGetGeometry);
29static FPTR(XGetWindowAttributes);
30static FPTR(XTranslateCoordinates);
31
0d645bc5 32static void get_window_rect(VC_RECT_T *rect)
33{
34 XWindowAttributes xattrs_root;
35 uint32_t disp_w = 0, disp_h = 0;
36 int dx = 0, dy = 0;
37 unsigned int dw = 0, dh = 0, dummy;
38 Window root, dummyw;
39
40 graphics_get_display_size(0, &disp_w, &disp_h);
41 if (disp_w == 0 || disp_h == 0)
42 fprintf(stderr, "ERROR: graphics_get_display_size is broken\n");
43
44 // default to fullscreen
45 rect->x = rect->y = 0;
46 rect->width = disp_w;
47 rect->height = disp_h;
48
49 if (x11display == NULL || x11window == 0)
50 return; // use fullscreen
51
cceadf4c 52 pXGetGeometry(x11display, x11window, &root, &dx, &dy, &dw, &dh,
0d645bc5 53 &dummy, &dummy);
cceadf4c 54 pXGetWindowAttributes(x11display, root, &xattrs_root);
0d645bc5 55
56 if (dw == xattrs_root.width && dh == xattrs_root.height)
57 return; // use fullscreen
58
cceadf4c 59 pXTranslateCoordinates(x11display, x11window, root,
0d645bc5 60 dx, dy, &dx, &dy, &dummyw);
61
62 // how to deal with that weird centering thing?
63 // this is not quite right..
64 dx += (disp_w - xattrs_root.width) / 2;
65 dy += (disp_h - xattrs_root.height) / 2;
66
67 rect->x = dx;
68 rect->y = dy;
69 rect->width = dw;
70 rect->height = dh;
71}
72
73static void submit_rect(void)
74{
75 DISPMANX_UPDATE_HANDLE_T m_dispmanUpdate;
76 DISPMANX_ELEMENT_HANDLE_T m_dispmanElement;
77 VC_RECT_T srcRect = { 0, }; // unused, but we segfault without passing it??
78 VC_RECT_T dstRect;
79
80 get_window_rect(&dstRect);
81
82 m_dispmanDisplay = vc_dispmanx_display_open(0);
83 m_dispmanUpdate = vc_dispmanx_update_start(0);
84
85 m_dispmanElement = vc_dispmanx_element_add(m_dispmanUpdate,
86 m_dispmanDisplay, 0, &dstRect, 0, &srcRect,
87 DISPMANX_PROTECTION_NONE, 0, 0, DISPMANX_NO_ROTATE);
88
89 m_nativeWindow.element = m_dispmanElement;
90 m_nativeWindow.width = dstRect.width;
91 m_nativeWindow.height = dstRect.height;
92
93 vc_dispmanx_update_submit_sync(m_dispmanUpdate);
94}
95
4388a645 96int gl_platform_init(void **display, int *quirks)
0d645bc5 97{
cceadf4c 98 x11display = NULL;
cceadf4c 99
100 x11lib = dlopen("libX11.so.6", RTLD_LAZY);
101 if (x11lib != NULL) {
102 pXGetGeometry = dlsym(x11lib, "XGetGeometry");
103 pXGetWindowAttributes = dlsym(x11lib, "XGetWindowAttributes");
104 pXTranslateCoordinates = dlsym(x11lib, "XTranslateCoordinates");
105 if (pXGetGeometry != NULL && pXGetWindowAttributes != NULL
106 && pXTranslateCoordinates != NULL)
107 {
108 x11display = *display;
cceadf4c 109 }
110 }
0d645bc5 111
112 bcm_host_init();
0d645bc5 113
114 *display = EGL_DEFAULT_DISPLAY;
4388a645 115
116 return gl_load();
117}
118
119int gl_platform_create(void **window, int *quirks)
120{
121 x11window = 0;
122
123 if (x11lib != NULL) {
124 x11window = (Window)*window;
125 }
126
127 submit_rect();
128
0d645bc5 129 *window = &m_nativeWindow;
130 *quirks |= GL_QUIRK_ACTIVATE_RECREATE;
131
4388a645 132 return !x11lib;
0d645bc5 133}
134
4388a645 135void gl_platform_destroy(void)
136{
137 vc_dispmanx_display_close(m_dispmanDisplay);
138
139 x11window = 0;
140}
141
142void gl_platform_shutdown(void)
0d645bc5 143{
d5d1b164 144 gl_unload();
145
0d645bc5 146 bcm_host_deinit();
cceadf4c 147
148 if (x11lib) {
149 dlclose(x11lib);
150 x11lib = NULL;
151 }
152
153 x11display = NULL;
0d645bc5 154}
155
156#else
157
4388a645 158int gl_platform_init(void **display, int *quirks)
0d645bc5 159{
d5d1b164 160 return gl_load();
0d645bc5 161}
162
4388a645 163int gl_platform_create(void **window, int *quirks)
164{
165 return 0;
166}
167
168void gl_platform_destroy(void)
169{
170}
171
172void gl_platform_shutdown(void)
0d645bc5 173{
d5d1b164 174 gl_unload();
0d645bc5 175}
176
177#endif