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.
23 * Chia-I Wu <olv@lunarg.com>
33 #include "EGL/eglext.h"
37 static struct eglut_state _eglut_state
= {
38 .api_mask
= EGLUT_OPENGL_ES1_BIT
,
45 struct eglut_state
*_eglut
= &_eglut_state
;
48 _eglutFatal(char *format
, ...)
52 va_start(args
, format
);
54 fprintf(stderr
, "EGLUT: ");
55 vfprintf(stderr
, format
, args
);
62 /* return current time (in milliseconds) */
68 (void) gettimeofday(&tv
, NULL
);
71 (void) gettimeofday(&tv
, &tz
);
73 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
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
);
88 _eglutChooseConfig(void)
91 EGLint config_attribs
[32];
92 EGLint renderable_type
, num_configs
, i
;
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");
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];
135 win
= calloc(1, sizeof(*win
));
137 _eglutFatal("failed to allocate window");
139 win
->config
= _eglutChooseConfig();
142 context_attribs
[i
] = EGL_NONE
;
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
;
161 win
->context
= eglCreateContext(_eglut
->dpy
,
162 win
->config
, EGL_NO_CONTEXT
, context_attribs
);
164 _eglutFatal("failed to create context");
166 _eglutNativeInitWindow(win
, title
, x
, y
, w
, h
);
167 switch (_eglut
->surface_type
) {
169 win
->surface
= eglCreateWindowSurface(_eglut
->dpy
,
170 win
->config
, win
->native
.u
.window
, NULL
);
173 win
->surface
= eglCreatePixmapSurface(_eglut
->dpy
,
174 win
->config
, win
->native
.u
.pixmap
, NULL
);
176 case EGL_PBUFFER_BIT
:
177 win
->surface
= win
->native
.u
.surface
;
182 if (win
->surface
== EGL_NO_SURFACE
)
183 _eglutFatal("failed to create surface");
189 eglutInitAPIMask(int mask
)
191 _eglut
->api_mask
= mask
;
195 eglutInitWindowSize(int width
, int height
)
197 _eglut
->window_width
= width
;
198 _eglut
->window_height
= height
;
202 eglutInit(int argc
, char **argv
)
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) {
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
));
238 case EGLUT_ELAPSED_TIME
:
239 val
= _eglutNow() - _eglut
->init_time
;
250 eglutIdleFunc(EGLUTidleCB func
)
252 _eglut
->idle_cb
= func
;
256 eglutPostRedisplay(void)
258 _eglut
->redisplay
= 1;
264 struct eglut_window
*win
= _eglut
->current
;
267 _eglutFatal("no window is created\n");
270 win
->reshape_cb(win
->native
.width
, win
->native
.height
);
272 _eglutNativeEventLoop();
278 eglTerminate(_eglut
->dpy
);
279 _eglutNativeFiniDisplay();
283 eglutDestroyWindow(int win
)
285 struct eglut_window
*window
= _eglut
->current
;
287 if (window
->index
!= win
)
290 eglMakeCurrent(_eglut
->dpy
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
292 _eglutDestroyWindow(_eglut
->current
);
296 _eglutDefaultKeyboard(unsigned char key
)
300 eglutDestroyWindow(_eglut
->current
->index
);
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
;
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
;
343 eglutDisplayFunc(EGLUTdisplayCB func
)
345 struct eglut_window
*win
= _eglut
->current
;
346 win
->display_cb
= func
;
351 eglutReshapeFunc(EGLUTreshapeCB func
)
353 struct eglut_window
*win
= _eglut
->current
;
354 win
->reshape_cb
= func
;
358 eglutKeyboardFunc(EGLUTkeyboardCB func
)
360 struct eglut_window
*win
= _eglut
->current
;
361 win
->keyboard_cb
= func
;
365 eglutSpecialFunc(EGLUTspecialCB func
)
367 struct eglut_window
*win
= _eglut
->current
;
368 win
->special_cb
= func
;