egl: match geometry position of glxgears
[mesa-demos.git] / src / egl / eglut / eglut.c
blob9921746019b5211fc38d4216817fc1d2c10eb6ec
1 /*
2 * Copyright (C) 2010 LunarG Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
22 * Authors:
23 * Chia-I Wu <olv@lunarg.com>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <sys/time.h>
32 #include "EGL/egl.h"
33 #include "EGL/eglext.h"
35 #include "eglutint.h"
37 static struct eglut_state _eglut_state = {
38 .api_mask = EGLUT_OPENGL_ES1_BIT,
39 .window_width = 300,
40 .window_height = 300,
41 .verbose = 0,
42 .num_windows = 0,
45 struct eglut_state *_eglut = &_eglut_state;
47 void
48 _eglutFatal(char *format, ...)
50 va_list args;
52 va_start(args, format);
54 fprintf(stderr, "EGLUT: ");
55 vfprintf(stderr, format, args);
56 va_end(args);
57 putc('\n', stderr);
59 exit(1);
62 /* return current time (in milliseconds) */
63 int
64 _eglutNow(void)
66 struct timeval tv;
67 #ifdef __VMS
68 (void) gettimeofday(&tv, NULL );
69 #else
70 struct timezone tz;
71 (void) gettimeofday(&tv, &tz);
72 #endif
73 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
76 static void
77 _eglutDestroyWindow(struct eglut_window *win)
79 if (_eglut->surface_type != EGL_PBUFFER_BIT)
80 eglDestroySurface(_eglut->dpy, win->surface);
82 _eglutNativeFiniWindow(win);
84 eglDestroyContext(_eglut->dpy, win->context);
87 static EGLConfig
88 _eglutChooseConfig(void)
90 EGLConfig config;
91 EGLint config_attribs[32];
92 EGLint renderable_type, num_configs, i;
94 i = 0;
95 config_attribs[i++] = EGL_RED_SIZE;
96 config_attribs[i++] = 1;
97 config_attribs[i++] = EGL_GREEN_SIZE;
98 config_attribs[i++] = 1;
99 config_attribs[i++] = EGL_BLUE_SIZE;
100 config_attribs[i++] = 1;
101 config_attribs[i++] = EGL_DEPTH_SIZE;
102 config_attribs[i++] = 1;
104 config_attribs[i++] = EGL_SURFACE_TYPE;
105 config_attribs[i++] = _eglut->surface_type;
107 config_attribs[i++] = EGL_RENDERABLE_TYPE;
108 renderable_type = 0x0;
109 if (_eglut->api_mask & EGLUT_OPENGL_BIT)
110 renderable_type |= EGL_OPENGL_BIT;
111 if (_eglut->api_mask & EGLUT_OPENGL_ES1_BIT)
112 renderable_type |= EGL_OPENGL_ES_BIT;
113 if (_eglut->api_mask & EGLUT_OPENGL_ES2_BIT)
114 renderable_type |= EGL_OPENGL_ES2_BIT;
115 if (_eglut->api_mask & EGLUT_OPENVG_BIT)
116 renderable_type |= EGL_OPENVG_BIT;
117 config_attribs[i++] = renderable_type;
119 config_attribs[i] = EGL_NONE;
121 if (!eglChooseConfig(_eglut->dpy,
122 config_attribs, &config, 1, &num_configs) || !num_configs)
123 _eglutFatal("failed to choose a config");
125 return config;
128 static struct eglut_window *
129 _eglutCreateWindow(const char *title, int x, int y, int w, int h)
131 struct eglut_window *win;
132 EGLint context_attribs[4];
133 EGLint api, i;
135 win = calloc(1, sizeof(*win));
136 if (!win)
137 _eglutFatal("failed to allocate window");
139 win->config = _eglutChooseConfig();
141 i = 0;
142 context_attribs[i] = EGL_NONE;
144 /* multiple APIs? */
146 api = EGL_OPENGL_ES_API;
147 if (_eglut->api_mask & EGLUT_OPENGL_BIT) {
148 api = EGL_OPENGL_API;
150 else if (_eglut->api_mask & EGLUT_OPENVG_BIT) {
151 api = EGL_OPENVG_API;
153 else if (_eglut->api_mask & EGLUT_OPENGL_ES2_BIT) {
154 context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
155 context_attribs[i++] = 2;
158 context_attribs[i] = EGL_NONE;
160 eglBindAPI(api);
161 win->context = eglCreateContext(_eglut->dpy,
162 win->config, EGL_NO_CONTEXT, context_attribs);
163 if (!win->context)
164 _eglutFatal("failed to create context");
166 _eglutNativeInitWindow(win, title, x, y, w, h);
167 switch (_eglut->surface_type) {
168 case EGL_WINDOW_BIT:
169 win->surface = eglCreateWindowSurface(_eglut->dpy,
170 win->config, win->native.u.window, NULL);
171 break;
172 case EGL_PIXMAP_BIT:
173 win->surface = eglCreatePixmapSurface(_eglut->dpy,
174 win->config, win->native.u.pixmap, NULL);
175 break;
176 case EGL_PBUFFER_BIT:
177 win->surface = win->native.u.surface;
178 break;
179 default:
180 break;
182 if (win->surface == EGL_NO_SURFACE)
183 _eglutFatal("failed to create surface");
185 return win;
188 void
189 eglutInitAPIMask(int mask)
191 _eglut->api_mask = mask;
194 void
195 eglutInitWindowSize(int width, int height)
197 _eglut->window_width = width;
198 _eglut->window_height = height;
201 void
202 eglutInit(int argc, char **argv)
204 int i;
206 for (i = 1; i < argc; i++) {
207 if (strcmp(argv[i], "-display") == 0)
208 _eglut->display_name = argv[++i];
209 else if (strcmp(argv[i], "-info") == 0) {
210 _eglut->verbose = 1;
214 _eglutNativeInitDisplay();
215 _eglut->dpy = eglGetDisplay(_eglut->native_dpy);
217 if (!eglInitialize(_eglut->dpy, &_eglut->major, &_eglut->minor))
218 _eglutFatal("failed to initialize EGL display");
220 _eglut->init_time = _eglutNow();
222 printf("EGL_VERSION = %s\n", eglQueryString(_eglut->dpy, EGL_VERSION));
223 if (_eglut->verbose) {
224 printf("EGL_VENDOR = %s\n", eglQueryString(_eglut->dpy, EGL_VENDOR));
225 printf("EGL_EXTENSIONS = %s\n",
226 eglQueryString(_eglut->dpy, EGL_EXTENSIONS));
227 printf("EGL_CLIENT_APIS = %s\n",
228 eglQueryString(_eglut->dpy, EGL_CLIENT_APIS));
233 eglutGet(int state)
235 int val;
237 switch (state) {
238 case EGLUT_ELAPSED_TIME:
239 val = _eglutNow() - _eglut->init_time;
240 break;
241 default:
242 val = -1;
243 break;
246 return val;
249 void
250 eglutIdleFunc(EGLUTidleCB func)
252 _eglut->idle_cb = func;
255 void
256 eglutPostRedisplay(void)
258 _eglut->redisplay = 1;
261 void
262 eglutMainLoop(void)
264 struct eglut_window *win = _eglut->current;
266 if (!win)
267 _eglutFatal("no window is created\n");
269 if (win->reshape_cb)
270 win->reshape_cb(win->native.width, win->native.height);
272 _eglutNativeEventLoop();
275 static void
276 _eglutFini(void)
278 eglTerminate(_eglut->dpy);
279 _eglutNativeFiniDisplay();
282 void
283 eglutDestroyWindow(int win)
285 struct eglut_window *window = _eglut->current;
287 if (window->index != win)
288 return;
290 eglMakeCurrent(_eglut->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
292 _eglutDestroyWindow(_eglut->current);
295 static void
296 _eglutDefaultKeyboard(unsigned char key)
298 if (key == 27) {
299 if (_eglut->current)
300 eglutDestroyWindow(_eglut->current->index);
301 _eglutFini();
303 exit(0);
308 eglutCreateWindow(const char *title)
310 struct eglut_window *win;
312 win = _eglutCreateWindow(title, 0, 0,
313 _eglut->window_width, _eglut->window_height);
315 win->index = _eglut->num_windows++;
316 win->reshape_cb = NULL;
317 win->display_cb = NULL;
318 win->keyboard_cb = _eglutDefaultKeyboard;
319 win->special_cb = NULL;
321 if (!eglMakeCurrent(_eglut->dpy, win->surface, win->surface, win->context))
322 _eglutFatal("failed to make window current");
323 _eglut->current = win;
325 return win->index;
329 eglutGetWindowWidth(void)
331 struct eglut_window *win = _eglut->current;
332 return win->native.width;
336 eglutGetWindowHeight(void)
338 struct eglut_window *win = _eglut->current;
339 return win->native.height;
342 void
343 eglutDisplayFunc(EGLUTdisplayCB func)
345 struct eglut_window *win = _eglut->current;
346 win->display_cb = func;
350 void
351 eglutReshapeFunc(EGLUTreshapeCB func)
353 struct eglut_window *win = _eglut->current;
354 win->reshape_cb = func;
357 void
358 eglutKeyboardFunc(EGLUTkeyboardCB func)
360 struct eglut_window *win = _eglut->current;
361 win->keyboard_cb = func;
364 void
365 eglutSpecialFunc(EGLUTspecialCB func)
367 struct eglut_window *win = _eglut->current;
368 win->special_cb = func;