Rev 4503 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4503 | Serge | 1 | /* |
2 | * Copyright (C) 2010 LunarG Inc. |
||
3 | * |
||
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: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice shall be included |
||
12 | * in all copies or substantial portions of the Software. |
||
13 | * |
||
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. |
||
21 | * |
||
22 | * Authors: |
||
23 | * Chia-I Wu |
||
24 | */ |
||
25 | |||
26 | #include |
||
27 | #include |
||
28 | #include |
||
29 | #include |
||
30 | #include |
||
31 | |||
32 | #include "EGL/egl.h" |
||
33 | #include "EGL/eglext.h" |
||
34 | |||
35 | #include "render.h" |
||
36 | #include "eglutint.h" |
||
37 | #include |
||
38 | |||
39 | static struct eglut_state _eglut_state = { |
||
40 | .api_mask = EGLUT_OPENGL_BIT, |
||
41 | .window_width = 300, |
||
42 | .window_height = 300, |
||
43 | .verbose = 0, |
||
44 | .num_windows = 0, |
||
45 | }; |
||
46 | |||
47 | struct eglut_state *_eglut = &_eglut_state; |
||
48 | |||
49 | void |
||
50 | _eglutFatal(char *format, ...) |
||
51 | { |
||
52 | va_list args; |
||
53 | |||
54 | va_start(args, format); |
||
55 | |||
56 | fprintf(stderr, "EGLUT: "); |
||
57 | vfprintf(stderr, format, args); |
||
58 | va_end(args); |
||
59 | putc('\n', stderr); |
||
60 | |||
61 | exit(1); |
||
62 | } |
||
63 | |||
64 | /* return current time (in milliseconds) */ |
||
65 | int |
||
66 | _eglutNow(void) |
||
67 | { |
||
68 | struct timeval tv; |
||
69 | struct timezone tz; |
||
70 | (void) gettimeofday(&tv, &tz); |
||
71 | return tv.tv_sec * 1000 + tv.tv_usec / 1000; |
||
72 | } |
||
73 | |||
74 | static void |
||
75 | _eglutDestroyWindow(struct eglut_window *win) |
||
76 | { |
||
77 | eglDestroySurface(_eglut->dpy, win->surface); |
||
78 | _eglutNativeFiniWindow(win); |
||
79 | eglDestroyContext(_eglut->dpy, win->context); |
||
80 | } |
||
81 | |||
82 | static EGLConfig |
||
83 | _eglutChooseConfig(void) |
||
84 | { |
||
85 | EGLConfig config; |
||
86 | EGLint config_attribs[32]; |
||
87 | EGLint num_configs, i; |
||
88 | |||
89 | i = 0; |
||
90 | config_attribs[i++] = EGL_RED_SIZE; |
||
91 | config_attribs[i++] = 1; |
||
92 | config_attribs[i++] = EGL_GREEN_SIZE; |
||
93 | config_attribs[i++] = 1; |
||
94 | config_attribs[i++] = EGL_BLUE_SIZE; |
||
95 | config_attribs[i++] = 1; |
||
96 | config_attribs[i++] = EGL_DEPTH_SIZE; |
||
97 | config_attribs[i++] = 1; |
||
98 | |||
99 | config_attribs[i++] = EGL_SURFACE_TYPE; |
||
100 | config_attribs[i++] = EGL_WINDOW_BIT; |
||
101 | |||
102 | config_attribs[i++] = EGL_RENDERABLE_TYPE; |
||
103 | config_attribs[i++] = EGL_OPENGL_BIT; |
||
104 | config_attribs[i] = EGL_NONE; |
||
105 | |||
106 | // renderable_type = 0x0; |
||
107 | // if (_eglut->api_mask & EGLUT_OPENGL_BIT) |
||
108 | // renderable_type |= EGL_OPENGL_BIT; |
||
109 | // if (_eglut->api_mask & EGLUT_OPENGL_ES1_BIT) |
||
110 | // renderable_type |= EGL_OPENGL_ES_BIT; |
||
111 | // if (_eglut->api_mask & EGLUT_OPENGL_ES2_BIT) |
||
112 | // renderable_type |= EGL_OPENGL_ES2_BIT; |
||
113 | // if (_eglut->api_mask & EGLUT_OPENVG_BIT) |
||
114 | // renderable_type |= EGL_OPENVG_BIT; |
||
115 | |||
116 | if (!eglChooseConfig(_eglut->dpy, |
||
117 | config_attribs, &config, 1, &num_configs) || !num_configs) |
||
118 | _eglutFatal("failed to choose a config"); |
||
119 | |||
120 | return config; |
||
121 | } |
||
122 | |||
123 | static struct eglut_window * |
||
124 | _eglutCreateWindow(const char *title, int x, int y, int w, int h) |
||
125 | { |
||
126 | struct eglut_window *win; |
||
127 | |||
128 | win = calloc(1, sizeof(*win)); |
||
129 | if (!win) |
||
130 | _eglutFatal("failed to allocate window"); |
||
131 | |||
132 | win->config = _eglutChooseConfig(); |
||
133 | |||
134 | eglBindAPI(EGL_OPENGL_API); |
||
135 | win->context = eglCreateContext(_eglut->dpy, win->config, EGL_NO_CONTEXT, NULL); |
||
136 | if (!win->context) |
||
137 | _eglutFatal("failed to create context"); |
||
138 | |||
139 | _eglutNativeInitWindow(win, title, x, y, w, h); |
||
140 | switch (_eglut->surface_type) { |
||
141 | case EGL_WINDOW_BIT: |
||
142 | win->surface = eglCreateWindowSurface(_eglut->dpy, |
||
143 | win->config, win->native.u.window, NULL); |
||
144 | break; |
||
145 | default: |
||
146 | break; |
||
147 | } |
||
148 | if (win->surface == EGL_NO_SURFACE) |
||
149 | _eglutFatal("failed to create surface"); |
||
150 | |||
151 | return win; |
||
152 | } |
||
153 | |||
154 | void |
||
155 | eglutInitAPIMask(int mask) |
||
156 | { |
||
157 | _eglut->api_mask = mask; |
||
158 | } |
||
159 | |||
160 | void |
||
161 | eglutInitWindowSize(int width, int height) |
||
162 | { |
||
163 | _eglut->window_width = width; |
||
164 | _eglut->window_height = height; |
||
165 | } |
||
166 | |||
167 | void |
||
168 | eglutInit(int argc, char **argv) |
||
169 | { |
||
170 | int i; |
||
171 | |||
172 | for (i = 1; i < argc; i++) { |
||
173 | if (strcmp(argv[i], "-display") == 0) |
||
174 | _eglut->display_name = argv[++i]; |
||
175 | else if (strcmp(argv[i], "-info") == 0) { |
||
176 | _eglut->verbose = 1; |
||
177 | } |
||
178 | } |
||
179 | |||
180 | _eglutNativeInitDisplay(); |
||
181 | _eglut->dpy = eglGetDisplay(_eglut->native_dpy); |
||
182 | |||
183 | if (!eglInitialize(_eglut->dpy, &_eglut->major, &_eglut->minor)) |
||
184 | _eglutFatal("failed to initialize EGL display"); |
||
185 | |||
186 | _eglut->init_time = _eglutNow(); |
||
187 | |||
188 | printf("EGL_VERSION = %s\n", eglQueryString(_eglut->dpy, EGL_VERSION)); |
||
189 | if (_eglut->verbose) { |
||
190 | printf("EGL_VENDOR = %s\n", eglQueryString(_eglut->dpy, EGL_VENDOR)); |
||
191 | printf("EGL_EXTENSIONS = %s\n", |
||
192 | eglQueryString(_eglut->dpy, EGL_EXTENSIONS)); |
||
193 | printf("EGL_CLIENT_APIS = %s\n", |
||
194 | eglQueryString(_eglut->dpy, EGL_CLIENT_APIS)); |
||
195 | } |
||
196 | } |
||
197 | |||
198 | int |
||
199 | eglutGet(int state) |
||
200 | { |
||
201 | int val; |
||
202 | |||
203 | switch (state) { |
||
204 | case EGLUT_ELAPSED_TIME: |
||
205 | val = _eglutNow() - _eglut->init_time; |
||
206 | break; |
||
207 | default: |
||
208 | val = -1; |
||
209 | break; |
||
210 | } |
||
211 | |||
212 | return val; |
||
213 | } |
||
214 | |||
215 | void |
||
216 | eglutIdleFunc(EGLUTidleCB func) |
||
217 | { |
||
218 | _eglut->idle_cb = func; |
||
219 | } |
||
220 | |||
221 | void |
||
222 | eglutPostRedisplay(void) |
||
223 | { |
||
224 | _eglut->redisplay = 1; |
||
225 | } |
||
226 | |||
227 | void |
||
228 | eglutMainLoop(void) |
||
229 | { |
||
230 | struct eglut_window *win = _eglut->current; |
||
231 | |||
232 | if (!win) |
||
233 | _eglutFatal("no window is created\n"); |
||
234 | |||
235 | if (win->reshape_cb) |
||
236 | win->reshape_cb(win->native.width, win->native.height); |
||
237 | |||
238 | _eglutNativeEventLoop(); |
||
239 | } |
||
240 | |||
241 | void |
||
242 | eglutFini(void) |
||
243 | { |
||
244 | eglTerminate(_eglut->dpy); |
||
245 | _eglutNativeFiniDisplay(); |
||
246 | } |
||
247 | |||
248 | void |
||
249 | eglutDestroyWindow(int win) |
||
250 | { |
||
251 | eglMakeCurrent(_eglut->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
||
252 | _eglutDestroyWindow(_eglut->current); |
||
253 | } |
||
254 | |||
255 | static void |
||
256 | _eglutDefaultKeyboard(unsigned char key) |
||
257 | { |
||
258 | } |
||
259 | |||
260 | int |
||
261 | eglutCreateWindow(const char *title) |
||
262 | { |
||
263 | struct eglut_window *win; |
||
264 | int skinh; |
||
265 | |||
266 | win = _eglutCreateWindow(title, 20, 20, |
||
267 | _eglut->window_width, _eglut->window_height); |
||
268 | |||
269 | win->index = _eglut->num_windows++; |
||
270 | win->reshape_cb = NULL; |
||
271 | win->display_cb = NULL; |
||
272 | win->keyboard_cb = _eglutDefaultKeyboard; |
||
273 | win->special_cb = NULL; |
||
274 | |||
275 | if (!eglMakeCurrent(_eglut->dpy, win->surface, win->surface, win->context)) |
||
276 | _eglutFatal("failed to make window current"); |
||
277 | _eglut->current = win; |
||
278 | |||
279 | skinh = get_skin_height(); |
||
280 | |||
281 | _eglut->render = create_render(_eglut->dpy, win->surface, TYPE_3_BORDER_WIDTH, skinh); |
||
282 | return win->index; |
||
283 | } |
||
284 | |||
285 | int |
||
286 | eglutGetWindowWidth(void) |
||
287 | { |
||
288 | struct eglut_window *win = _eglut->current; |
||
289 | return win->native.width; |
||
290 | } |
||
291 | |||
292 | int |
||
293 | eglutGetWindowHeight(void) |
||
294 | { |
||
295 | struct eglut_window *win = _eglut->current; |
||
296 | return win->native.height; |
||
297 | } |
||
298 | |||
299 | void |
||
300 | eglutDisplayFunc(EGLUTdisplayCB func) |
||
301 | { |
||
302 | struct eglut_window *win = _eglut->current; |
||
303 | win->display_cb = func; |
||
304 | |||
305 | } |
||
306 | |||
307 | void |
||
308 | eglutReshapeFunc(EGLUTreshapeCB func) |
||
309 | { |
||
310 | struct eglut_window *win = _eglut->current; |
||
311 | win->reshape_cb = func; |
||
312 | } |
||
313 | |||
314 | void |
||
315 | eglutKeyboardFunc(EGLUTkeyboardCB func) |
||
316 | { |
||
317 | struct eglut_window *win = _eglut->current; |
||
318 | win->keyboard_cb = func; |
||
319 | } |
||
320 | |||
321 | void |
||
322 | eglutSpecialFunc(EGLUTspecialCB func) |
||
323 | { |
||
324 | struct eglut_window *win = _eglut->current; |
||
325 | win->special_cb = func; |
||
326 | } |
||
327 | |||
328 | int atexit(void (*func)(void)) |
||
329 | { |
||
330 | return 0; |
||
331 | };> |