Merge branch '7.8'
[mesa.git] / progs / egl / openvg / trivial / eglcommon.c
1 #include "eglcommon.h"
2
3
4 #include <assert.h>
5 #include <math.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h>
11 #include <X11/keysym.h>
12 #include <VG/openvg.h> /* using full OpenGL for now */
13 #include <GLES/egl.h>
14
15
16 static init_func init = 0;
17 static draw_func draw = 0;
18 static reshape_func reshape = 0;
19 static key_func keyPress = 0;
20 static VGint width = 300, height = 300;
21
22
23 void set_window_size(int w, int h)
24 {
25 width = w;
26 height = h;
27 }
28
29 /*
30 * Create an RGB, double-buffered X window.
31 * Return the window and context handles.
32 */
33 static void
34 make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
35 const char *name,
36 int x, int y, int width, int height,
37 Window *winRet,
38 EGLContext *ctxRet,
39 EGLSurface *surfRet)
40 {
41 static const EGLint attribs[] = {
42 EGL_RED_SIZE, 1,
43 EGL_GREEN_SIZE, 1,
44 EGL_BLUE_SIZE, 1,
45 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
46 EGL_NONE
47 };
48
49 int scrnum;
50 XSetWindowAttributes attr;
51 unsigned long mask;
52 Window root;
53 Window win;
54 XVisualInfo *visInfo, visTemplate;
55 int num_visuals;
56 EGLContext ctx;
57 EGLConfig config;
58 EGLint num_configs;
59 EGLint vid;
60
61 scrnum = DefaultScreen( x_dpy );
62 root = RootWindow( x_dpy, scrnum );
63
64 if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) ||
65 !num_configs) {
66 printf("Error: couldn't get an EGL visual config\n");
67 exit(1);
68 }
69
70 assert(config);
71
72 if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
73 printf("Error: eglGetConfigAttrib() failed\n");
74 exit(1);
75 }
76
77 /* The X window visual must match the EGL config */
78 visTemplate.visualid = vid;
79 visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
80 if (!visInfo) {
81 printf("Error: couldn't get X visual\n");
82 exit(1);
83 }
84
85 /* window attributes */
86 attr.background_pixel = 0;
87 attr.border_pixel = 0;
88 attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
89 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
90 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
91
92 win = XCreateWindow( x_dpy, root, 0, 0, width, height,
93 0, visInfo->depth, InputOutput,
94 visInfo->visual, mask, &attr );
95
96 /* set hints and properties */
97 {
98 XSizeHints sizehints;
99 sizehints.x = x;
100 sizehints.y = y;
101 sizehints.width = width;
102 sizehints.height = height;
103 sizehints.flags = USSize | USPosition;
104 XSetNormalHints(x_dpy, win, &sizehints);
105 XSetStandardProperties(x_dpy, win, name, name,
106 None, (char **)NULL, 0, &sizehints);
107 }
108
109 eglBindAPI(EGL_OPENVG_API);
110
111 ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
112 if (!ctx) {
113 printf("Error: eglCreateContext failed\n");
114 exit(1);
115 }
116
117 *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
118
119 if (!*surfRet) {
120 printf("Error: eglCreateWindowSurface failed\n");
121 exit(1);
122 }
123
124 XFree(visInfo);
125
126 *winRet = win;
127 *ctxRet = ctx;
128 }
129
130 static void
131 event_loop(Display *dpy, Window win,
132 EGLDisplay egl_dpy, EGLSurface egl_surf)
133 {
134 while (1) {
135 int redraw = 0;
136 XEvent event;
137
138 XNextEvent(dpy, &event);
139
140 switch (event.type) {
141 case Expose:
142 redraw = 1;
143 break;
144 case ConfigureNotify:
145 if (reshape) {
146 width = event.xconfigure.width;
147 height = event.xconfigure.height;
148 reshape(event.xconfigure.width, event.xconfigure.height);
149 }
150 break;
151 case KeyPress:
152 {
153 char buffer[10];
154 int r, code;
155 code = XLookupKeysym(&event.xkey, 0);
156 if (!keyPress || !keyPress(code)) {
157 r = XLookupString(&event.xkey, buffer, sizeof(buffer),
158 NULL, NULL);
159 if (buffer[0] == 27) {
160 /* escape */
161 return;
162 }
163 }
164 }
165 redraw = 1;
166 break;
167 default:
168 ; /*no-op*/
169 }
170
171 if (redraw) {
172 draw();
173 eglSwapBuffers(egl_dpy, egl_surf);
174 }
175 }
176 }
177
178 int window_width(void)
179 {
180 return width;
181 }
182
183 int window_height(void)
184 {
185 return height;
186 }
187
188 static void
189 usage(void)
190 {
191 printf("Usage:\n");
192 printf(" -display <displayname> set the display to run on\n");
193 printf(" -info display OpenGL renderer info\n");
194 }
195
196 int run(int argc, char **argv,
197 init_func init_f,
198 reshape_func resh_f,
199 draw_func draw_f,
200 key_func key_f)
201 {
202 const int winWidth = width, winHeight = height;
203 Display *x_dpy;
204 Window win;
205 EGLSurface egl_surf;
206 EGLContext egl_ctx;
207 EGLDisplay egl_dpy;
208 char *dpyName = NULL;
209 GLboolean printInfo = GL_FALSE;
210 EGLint egl_major, egl_minor;
211 int i;
212 const char *s;
213
214 init = init_f;
215 draw = draw_f;
216 reshape = resh_f;
217 keyPress = key_f;
218
219 for (i = 1; i < argc; i++) {
220 if (strcmp(argv[i], "-display") == 0) {
221 dpyName = argv[i+1];
222 i++;
223 }
224 else if (strcmp(argv[i], "-info") == 0) {
225 printInfo = GL_TRUE;
226 }
227 }
228
229 x_dpy = XOpenDisplay(dpyName);
230 if (!x_dpy) {
231 printf("Error: couldn't open display %s\n",
232 dpyName ? dpyName : getenv("DISPLAY"));
233 return -1;
234 }
235
236 egl_dpy = eglGetDisplay(x_dpy);
237 if (!egl_dpy) {
238 printf("Error: eglGetDisplay() failed\n");
239 return -1;
240 }
241
242 if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
243 printf("Error: eglInitialize() failed\n");
244 return -1;
245 }
246
247 s = eglQueryString(egl_dpy, EGL_VERSION);
248 printf("EGL_VERSION = %s\n", s);
249
250 make_x_window(x_dpy, egl_dpy,
251 "OpenVG Example", 0, 0, winWidth, winHeight,
252 &win, &egl_ctx, &egl_surf);
253
254 XMapWindow(x_dpy, win);
255 if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
256 printf("Error: eglMakeCurrent() failed\n");
257 return -1;
258 }
259
260 if (printInfo) {
261 printf("VG_RENDERER = %s\n", (char *) vgGetString(VG_RENDERER));
262 printf("VG_VERSION = %s\n", (char *) vgGetString(VG_VERSION));
263 printf("VG_VENDOR = %s\n", (char *) vgGetString(VG_VENDOR));
264 }
265
266 if (init)
267 init();
268
269 /* Set initial projection/viewing transformation.
270 * We can't be sure we'll get a ConfigureNotify event when the window
271 * first appears.
272 */
273 if (reshape)
274 reshape(winWidth, winHeight);
275
276 event_loop(x_dpy, win, egl_dpy, egl_surf);
277
278 eglMakeCurrent(egl_dpy, 0, 0, 0);
279 eglDestroyContext(egl_dpy, egl_ctx);
280 eglDestroySurface(egl_dpy, egl_surf);
281 eglTerminate(egl_dpy);
282
283
284 XDestroyWindow(x_dpy, win);
285 XCloseDisplay(x_dpy);
286
287 return 0;
288 }
289