menu: pass extension lists as argument
[libpicofe.git] / gl_platform.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <EGL/egl.h>
4 #include <GLES/gl.h>
5
6 #include "gl.h"
7 #include "gl_platform.h"
8
9 #ifdef VCOS_VERSION
10
11 /*
12  * hacks for Broadcom VideoCore / Raspberry Pi..
13  * Why do I have to do this proprietary API stuff,
14  * couldn't they implement EGL properly? D:
15  */
16 #include <bcm_host.h>
17 #include <X11/Xlib.h>
18
19 static Display *x11display;
20 static Window x11window;
21 static DISPMANX_DISPLAY_HANDLE_T m_dispmanDisplay;
22 static EGL_DISPMANX_WINDOW_T m_nativeWindow;
23
24 static void get_window_rect(VC_RECT_T *rect)
25 {
26         XWindowAttributes xattrs_root;
27         uint32_t disp_w = 0, disp_h = 0;
28         int dx = 0, dy = 0;
29         unsigned int dw = 0, dh = 0, dummy;
30         Window root, dummyw;
31
32         graphics_get_display_size(0, &disp_w, &disp_h);
33         if (disp_w == 0 || disp_h == 0)
34                 fprintf(stderr, "ERROR: graphics_get_display_size is broken\n");
35
36         // default to fullscreen
37         rect->x = rect->y = 0;
38         rect->width = disp_w;
39         rect->height = disp_h;
40
41         if (x11display == NULL || x11window == 0)
42                 return; // use fullscreen
43
44         XGetGeometry(x11display, x11window, &root, &dx, &dy, &dw, &dh,
45                 &dummy, &dummy);
46         XGetWindowAttributes(x11display, root, &xattrs_root);
47
48         if (dw == xattrs_root.width && dh == xattrs_root.height)
49                 return; // use fullscreen
50
51         XTranslateCoordinates(x11display, x11window, root,
52                 dx, dy, &dx, &dy, &dummyw);
53
54         // how to deal with that weird centering thing?
55         // this is not quite right..
56         dx += (disp_w - xattrs_root.width) / 2;
57         dy += (disp_h - xattrs_root.height) / 2;
58
59         rect->x = dx;
60         rect->y = dy;
61         rect->width = dw;
62         rect->height = dh;
63 }
64
65 static void submit_rect(void)
66 {
67         DISPMANX_UPDATE_HANDLE_T m_dispmanUpdate;
68         DISPMANX_ELEMENT_HANDLE_T m_dispmanElement;
69         VC_RECT_T srcRect = { 0, }; // unused, but we segfault without passing it??
70         VC_RECT_T dstRect;
71
72         get_window_rect(&dstRect);
73
74         m_dispmanDisplay = vc_dispmanx_display_open(0);
75         m_dispmanUpdate = vc_dispmanx_update_start(0);
76
77         m_dispmanElement = vc_dispmanx_element_add(m_dispmanUpdate,
78                 m_dispmanDisplay, 0, &dstRect, 0, &srcRect,
79                 DISPMANX_PROTECTION_NONE, 0, 0, DISPMANX_NO_ROTATE);
80
81         m_nativeWindow.element = m_dispmanElement;
82         m_nativeWindow.width = dstRect.width;
83         m_nativeWindow.height = dstRect.height;
84
85         vc_dispmanx_update_submit_sync(m_dispmanUpdate);
86 }
87
88 int gl_platform_init(void **display, void **window, int *quirks)
89 {
90         x11display = *display;
91         x11window = (Window)*window;
92
93         bcm_host_init();
94         submit_rect();
95
96         *display = EGL_DEFAULT_DISPLAY;
97         *window = &m_nativeWindow;
98         *quirks |= GL_QUIRK_ACTIVATE_RECREATE;
99
100         return 0;
101 }
102
103 void gl_platform_finish(void)
104 {
105         vc_dispmanx_display_close(m_dispmanDisplay);
106         bcm_host_deinit();
107 }
108
109 #else
110
111 int gl_platform_init(void **display, void **window, int *quirks)
112 {
113         return 0;
114 }
115
116 void gl_platform_finish(void)
117 {
118 }
119
120 #endif