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