Part 2 of 2: <http://webkit.org/b/56337> Enable -Werror on ANGLE
[WebKit-https.git] / Source / ThirdParty / ANGLE / src / libEGL / libEGL.cpp
1 //
2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // libEGL.cpp: Implements the exported EGL functions.
8
9 #include <exception>
10
11 #include "common/debug.h"
12 #include "libGLESv2/Context.h"
13
14 #include "libEGL/main.h"
15 #include "libEGL/Display.h"
16
17
18 bool validate(egl::Display *display)
19 {
20     if (display == EGL_NO_DISPLAY)
21     {
22         return error(EGL_BAD_DISPLAY, false);
23     }
24
25     if (!display->isInitialized())
26     {
27         return error(EGL_NOT_INITIALIZED, false);
28     }
29
30     return true;
31 }
32
33 bool validate(egl::Display *display, EGLConfig config)
34 {
35     if (!validate(display))
36     {
37         return false;
38     }
39
40     if (!display->isValidConfig(config))
41     {
42         return error(EGL_BAD_CONFIG, false);
43     }
44
45     return true;
46 }
47
48 bool validate(egl::Display *display, gl::Context *context)
49 {
50     if (!validate(display))
51     {
52         return false;
53     }
54
55     if (!display->isValidContext(context))
56     {
57         return error(EGL_BAD_CONTEXT, false);
58     }
59
60     return true;
61 }
62
63 bool validate(egl::Display *display, egl::Surface *surface)
64 {
65     if (!validate(display))
66     {
67         return false;
68     }
69
70     if (!display->isValidSurface(surface))
71     {
72         return error(EGL_BAD_SURFACE, false);
73     }
74
75     return true;
76 }
77
78 extern "C"
79 {
80 EGLint __stdcall eglGetError(void)
81 {
82     TRACE("()");
83
84     EGLint error = egl::getCurrentError();
85
86     if (error != EGL_SUCCESS)
87     {
88         egl::setCurrentError(EGL_SUCCESS);
89     }
90
91     return error;
92 }
93
94 EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
95 {
96     TRACE("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
97
98     try
99     {
100         // FIXME: Return the same EGLDisplay handle when display_id already created a display
101
102         if (display_id == EGL_DEFAULT_DISPLAY)
103         {
104             return new egl::Display((HDC)NULL);
105         }
106         else
107         {
108             // FIXME: Check if display_id is a valid display device context
109
110             return new egl::Display((HDC)display_id);
111         }
112     }
113     catch(std::bad_alloc&)
114     {
115         return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
116     }
117
118     return EGL_NO_DISPLAY;
119 }
120
121 EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
122 {
123     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
124           dpy, major, minor);
125
126     try
127     {
128         if (dpy == EGL_NO_DISPLAY)
129         {
130             return error(EGL_BAD_DISPLAY, EGL_FALSE);
131         }
132
133         egl::Display *display = static_cast<egl::Display*>(dpy);
134
135         if (!display->initialize())
136         {
137             return error(EGL_NOT_INITIALIZED, EGL_FALSE);
138         }
139
140         if (major) *major = 1;
141         if (minor) *minor = 4;
142
143         return success(EGL_TRUE);
144     }
145     catch(std::bad_alloc&)
146     {
147         return error(EGL_BAD_ALLOC, EGL_FALSE);
148     }
149
150     return EGL_FALSE;
151 }
152
153 EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
154 {
155     TRACE("(EGLDisplay dpy = 0x%0.8p)", dpy);
156
157     try
158     {
159         if (dpy == EGL_NO_DISPLAY)
160         {
161             return error(EGL_BAD_DISPLAY, EGL_FALSE);
162         }
163
164         egl::Display *display = static_cast<egl::Display*>(dpy);
165
166         display->terminate();
167
168         return success(EGL_TRUE);
169     }
170     catch(std::bad_alloc&)
171     {
172         return error(EGL_BAD_ALLOC, EGL_FALSE);
173     }
174
175     return EGL_FALSE;
176 }
177
178 const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
179 {
180     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
181
182     try
183     {
184         egl::Display *display = static_cast<egl::Display*>(dpy);
185
186         if (!validate(display))
187         {
188             return NULL;
189         }
190
191         switch (name)
192         {
193           case EGL_CLIENT_APIS:
194             return success("OpenGL_ES");
195           case EGL_EXTENSIONS:
196             return success("");
197           case EGL_VENDOR:
198             return success("TransGaming Inc.");
199           case EGL_VERSION:
200             return success("1.4 (git-devel "__DATE__" " __TIME__")");
201         }
202
203         return error(EGL_BAD_PARAMETER, (const char*)NULL);
204     }
205     catch(std::bad_alloc&)
206     {
207         return error(EGL_BAD_ALLOC, (const char*)NULL);
208     }
209
210     return NULL;
211 }
212
213 EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
214 {
215     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
216           "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
217           dpy, configs, config_size, num_config);
218
219     try
220     {
221         egl::Display *display = static_cast<egl::Display*>(dpy);
222
223         if (!validate(display))
224         {
225             return EGL_FALSE;
226         }
227
228         if (!num_config)
229         {
230             return error(EGL_BAD_PARAMETER, EGL_FALSE);
231         }
232
233         const EGLint attribList[] =    {EGL_NONE};
234
235         if (!display->getConfigs(configs, attribList, config_size, num_config))
236         {
237             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
238         }
239
240         return success(EGL_TRUE);
241     }
242     catch(std::bad_alloc&)
243     {
244         return error(EGL_BAD_ALLOC, EGL_FALSE);
245     }
246
247     return EGL_FALSE;
248 }
249
250 EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
251 {
252     TRACE("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
253           "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
254           dpy, attrib_list, configs, config_size, num_config);
255
256     try
257     {
258         egl::Display *display = static_cast<egl::Display*>(dpy);
259
260         if (!validate(display))
261         {
262             return EGL_FALSE;
263         }
264
265         if (!num_config)
266         {
267             return error(EGL_BAD_PARAMETER, EGL_FALSE);
268         }
269
270         const EGLint attribList[] =    {EGL_NONE};
271
272         if (!attrib_list)
273         {
274             attrib_list = attribList;
275         }
276
277         display->getConfigs(configs, attrib_list, config_size, num_config);
278
279         return success(EGL_TRUE);
280     }
281     catch(std::bad_alloc&)
282     {
283         return error(EGL_BAD_ALLOC, EGL_FALSE);
284     }
285
286     return EGL_FALSE;
287 }
288
289 EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
290 {
291     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
292           dpy, config, attribute, value);
293
294     try
295     {
296         egl::Display *display = static_cast<egl::Display*>(dpy);
297
298         if (!validate(display, config))
299         {
300             return EGL_FALSE;
301         }
302
303         if (!display->getConfigAttrib(config, attribute, value))
304         {
305             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
306         }
307
308         return success(EGL_TRUE);
309     }
310     catch(std::bad_alloc&)
311     {
312         return error(EGL_BAD_ALLOC, EGL_FALSE);
313     }
314
315     return EGL_FALSE;
316 }
317
318 EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
319 {
320     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
321           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
322
323     try
324     {
325         egl::Display *display = static_cast<egl::Display*>(dpy);
326
327         if (!validate(display, config))
328         {
329             return EGL_NO_SURFACE;
330         }
331
332         HWND window = (HWND)win;
333
334         if (!IsWindow(window))
335         {
336             return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
337         }
338
339         if (attrib_list)
340         {
341             while (*attrib_list != EGL_NONE)
342             {
343                 switch (attrib_list[0])
344                 {
345                   case EGL_RENDER_BUFFER:
346                     switch (attrib_list[1])
347                     {
348                       case EGL_BACK_BUFFER:
349                         break;
350                       case EGL_SINGLE_BUFFER:
351                         return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
352                       default:
353                         return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
354                     }
355                     break;
356                   case EGL_VG_COLORSPACE:
357                     return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
358                   case EGL_VG_ALPHA_FORMAT:
359                     return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
360                   default:
361                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
362                 }
363
364                 attrib_list += 2;
365             }
366         }
367
368         if (display->hasExistingWindowSurface(window))
369         {
370             return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
371         }
372
373         EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config);
374
375         return success(surface);
376     }
377     catch(std::bad_alloc&)
378     {
379         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
380     }
381
382     return EGL_NO_SURFACE;
383 }
384
385 EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
386 {
387     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
388           dpy, config, attrib_list);
389
390     try
391     {
392         egl::Display *display = static_cast<egl::Display*>(dpy);
393
394         if (!validate(display, config))
395         {
396             return EGL_NO_SURFACE;
397         }
398
399         UNIMPLEMENTED();   // FIXME
400
401         return success(EGL_NO_DISPLAY);
402     }
403     catch(std::bad_alloc&)
404     {
405         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
406     }
407
408     return EGL_NO_SURFACE;
409 }
410
411 EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
412 {
413     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
414           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
415
416     try
417     {
418         egl::Display *display = static_cast<egl::Display*>(dpy);
419
420         if (!validate(display, config))
421         {
422             return EGL_NO_SURFACE;
423         }
424
425         UNIMPLEMENTED();   // FIXME
426
427         return success(EGL_NO_DISPLAY);
428     }
429     catch(std::bad_alloc&)
430     {
431         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
432     }
433
434     return EGL_NO_SURFACE;
435 }
436
437 EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
438 {
439     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
440
441     try
442     {
443         egl::Display *display = static_cast<egl::Display*>(dpy);
444
445         if (!validate(display))
446         {
447             return EGL_FALSE;
448         }
449
450         if (surface == EGL_NO_SURFACE)
451         {
452             return error(EGL_BAD_SURFACE, EGL_FALSE);
453         }
454
455         display->destroySurface((egl::Surface*)surface);
456
457         return success(EGL_TRUE);
458     }
459     catch(std::bad_alloc&)
460     {
461         return error(EGL_BAD_ALLOC, EGL_FALSE);
462     }
463
464     return EGL_FALSE;
465 }
466
467 EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
468 {
469     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
470           dpy, surface, attribute, value);
471
472     try
473     {
474         egl::Display *display = static_cast<egl::Display*>(dpy);
475
476         if (!validate(display))
477         {
478             return EGL_FALSE;
479         }
480
481         if (surface == EGL_NO_SURFACE)
482         {
483             return error(EGL_BAD_SURFACE, EGL_FALSE);
484         }
485
486         egl::Surface *eglSurface = (egl::Surface*)surface;
487
488         switch (attribute)
489         {
490           case EGL_VG_ALPHA_FORMAT:
491             UNIMPLEMENTED();   // FIXME
492             break;
493           case EGL_VG_COLORSPACE:
494             UNIMPLEMENTED();   // FIXME
495             break;
496           case EGL_CONFIG_ID:
497             UNIMPLEMENTED();   // FIXME
498             break;
499           case EGL_HEIGHT:
500             *value = eglSurface->getHeight();
501             break;
502           case EGL_HORIZONTAL_RESOLUTION:
503             UNIMPLEMENTED();   // FIXME
504             break;
505           case EGL_LARGEST_PBUFFER:
506             UNIMPLEMENTED();   // FIXME
507             break;
508           case EGL_MIPMAP_TEXTURE:
509             UNIMPLEMENTED();   // FIXME
510             break;
511           case EGL_MIPMAP_LEVEL:
512             UNIMPLEMENTED();   // FIXME
513             break;
514           case EGL_MULTISAMPLE_RESOLVE:
515             UNIMPLEMENTED();   // FIXME
516             break;
517           case EGL_PIXEL_ASPECT_RATIO:
518             UNIMPLEMENTED();   // FIXME
519             break;
520           case EGL_RENDER_BUFFER:
521             UNIMPLEMENTED();   // FIXME
522             break;
523           case EGL_SWAP_BEHAVIOR:
524             UNIMPLEMENTED();   // FIXME
525             break;
526           case EGL_TEXTURE_FORMAT:
527             UNIMPLEMENTED();   // FIXME
528             break;
529           case EGL_TEXTURE_TARGET:
530             UNIMPLEMENTED();   // FIXME
531             break;
532           case EGL_VERTICAL_RESOLUTION:
533             UNIMPLEMENTED();   // FIXME
534             break;
535           case EGL_WIDTH:
536             *value = eglSurface->getWidth();
537             break;
538           default:
539             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
540         }
541
542         return success(EGL_TRUE);
543     }
544     catch(std::bad_alloc&)
545     {
546         return error(EGL_BAD_ALLOC, EGL_FALSE);
547     }
548
549     return EGL_FALSE;
550 }
551
552 EGLBoolean __stdcall eglBindAPI(EGLenum api)
553 {
554     TRACE("(EGLenum api = 0x%X)", api);
555
556     try
557     {
558         switch (api)
559         {
560           case EGL_OPENGL_API:
561           case EGL_OPENVG_API:
562             return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
563           case EGL_OPENGL_ES_API:
564             break;
565           default:
566             return error(EGL_BAD_PARAMETER, EGL_FALSE);
567         }
568
569         egl::setCurrentAPI(api);
570
571         return success(EGL_TRUE);
572     }
573     catch(std::bad_alloc&)
574     {
575         return error(EGL_BAD_ALLOC, EGL_FALSE);
576     }
577
578     return EGL_FALSE;
579 }
580
581 EGLenum __stdcall eglQueryAPI(void)
582 {
583     TRACE("()");
584
585     try
586     {
587         EGLenum API = egl::getCurrentAPI();
588
589         return success(API);
590     }
591     catch(std::bad_alloc&)
592     {
593         return error(EGL_BAD_ALLOC, EGL_FALSE);
594     }
595
596     return EGL_FALSE;
597 }
598
599 EGLBoolean __stdcall eglWaitClient(void)
600 {
601     TRACE("()");
602
603     try
604     {
605         UNIMPLEMENTED();   // FIXME
606
607         return success(0);
608     }
609     catch(std::bad_alloc&)
610     {
611         return error(EGL_BAD_ALLOC, EGL_FALSE);
612     }
613
614     return EGL_FALSE;
615 }
616
617 EGLBoolean __stdcall eglReleaseThread(void)
618 {
619     TRACE("()");
620
621     try
622     {
623         eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
624
625         return success(EGL_TRUE);
626     }
627     catch(std::bad_alloc&)
628     {
629         return error(EGL_BAD_ALLOC, EGL_FALSE);
630     }
631
632     return EGL_FALSE;
633 }
634
635 EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
636 {
637     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
638           "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
639           dpy, buftype, buffer, config, attrib_list);
640
641     try
642     {
643         egl::Display *display = static_cast<egl::Display*>(dpy);
644
645         if (!validate(display, config))
646         {
647             return EGL_NO_SURFACE;
648         }
649
650         UNIMPLEMENTED();   // FIXME
651
652         return success(EGL_NO_SURFACE);
653     }
654     catch(std::bad_alloc&)
655     {
656         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
657     }
658
659     return EGL_NO_SURFACE;
660 }
661
662 EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
663 {
664     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
665           dpy, surface, attribute, value);
666
667     try
668     {
669         egl::Display *display = static_cast<egl::Display*>(dpy);
670
671         if (!validate(display))
672         {
673             return EGL_FALSE;
674         }
675
676         UNIMPLEMENTED();   // FIXME
677
678         return success(EGL_TRUE);
679     }
680     catch(std::bad_alloc&)
681     {
682         return error(EGL_BAD_ALLOC, EGL_FALSE);
683     }
684
685     return EGL_FALSE;
686 }
687
688 EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
689 {
690     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
691
692     try
693     {
694         egl::Display *display = static_cast<egl::Display*>(dpy);
695
696         if (!validate(display))
697         {
698             return EGL_FALSE;
699         }
700
701         UNIMPLEMENTED();   // FIXME
702
703         return success(EGL_TRUE);
704     }
705     catch(std::bad_alloc&)
706     {
707         return error(EGL_BAD_ALLOC, EGL_FALSE);
708     }
709
710     return EGL_FALSE;
711 }
712
713 EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
714 {
715     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
716
717     try
718     {
719         egl::Display *display = static_cast<egl::Display*>(dpy);
720
721         if (!validate(display))
722         {
723             return EGL_FALSE;
724         }
725
726         UNIMPLEMENTED();   // FIXME
727
728         return success(EGL_TRUE);
729     }
730     catch(std::bad_alloc&)
731     {
732         return error(EGL_BAD_ALLOC, EGL_FALSE);
733     }
734
735     return EGL_FALSE;
736 }
737
738 EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
739 {
740     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
741
742     try
743     {
744         egl::Display *display = static_cast<egl::Display*>(dpy);
745
746         if (!validate(display))
747         {
748             return EGL_FALSE;
749         }
750
751         egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
752
753         if (draw_surface == NULL)
754         {
755             return error(EGL_BAD_SURFACE, EGL_FALSE);
756         }
757         
758         draw_surface->setSwapInterval(interval);
759
760         return success(EGL_TRUE);
761     }
762     catch(std::bad_alloc&)
763     {
764         return error(EGL_BAD_ALLOC, EGL_FALSE);
765     }
766
767     return EGL_FALSE;
768 }
769
770 EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
771 {
772     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
773           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
774
775     try
776     {
777         // Get the requested client version (default is 1) and check it is two.
778         EGLint client_version = 1;
779         if (attrib_list)
780         {
781             for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
782             {
783                 if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
784                 {
785                     client_version = attribute[1];
786                 }
787                 else
788                 {
789                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
790                 }
791             }
792         }
793
794         if (client_version != 2)
795         {
796             return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
797         }
798
799         egl::Display *display = static_cast<egl::Display*>(dpy);
800
801         if (!validate(display, config))
802         {
803             return EGL_NO_CONTEXT;
804         }
805
806         EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
807
808         return success(context);
809     }
810     catch(std::bad_alloc&)
811     {
812         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
813     }
814
815     return EGL_NO_CONTEXT;
816 }
817
818 EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
819 {
820     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
821
822     try
823     {
824         egl::Display *display = static_cast<egl::Display*>(dpy);
825
826         if (!validate(display))
827         {
828             return EGL_FALSE;
829         }
830
831         if (ctx == EGL_NO_CONTEXT)
832         {
833             return error(EGL_BAD_CONTEXT, EGL_FALSE);
834         }
835
836         display->destroyContext((gl::Context*)ctx);
837
838         return success(EGL_TRUE);
839     }
840     catch(std::bad_alloc&)
841     {
842         return error(EGL_BAD_ALLOC, EGL_FALSE);
843     }
844
845     return EGL_FALSE;
846 }
847
848 EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
849 {
850     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
851           dpy, draw, read, ctx);
852
853     try
854     {
855         egl::Display *display = static_cast<egl::Display*>(dpy);
856         gl::Context *context = static_cast<gl::Context*>(ctx);
857         IDirect3DDevice9 *device = display->getDevice();
858
859         if (!device || FAILED(device->TestCooperativeLevel()))
860         {
861             return error(EGL_CONTEXT_LOST, EGL_FALSE);
862         }
863
864         if (ctx != EGL_NO_CONTEXT && !validate(display, context))
865         {
866             return EGL_FALSE;
867         }
868
869         if ((draw != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(draw))) ||
870             (read != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(read))))
871         {
872             return EGL_FALSE;
873         }
874
875         if (draw != read)
876         {
877             UNIMPLEMENTED();   // FIXME
878         }
879
880         egl::setCurrentDisplay(dpy);
881         egl::setCurrentDrawSurface(draw);
882         egl::setCurrentReadSurface(read);
883
884         glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
885
886         return success(EGL_TRUE);
887     }
888     catch(std::bad_alloc&)
889     {
890         return error(EGL_BAD_ALLOC, EGL_FALSE);
891     }
892
893     return EGL_FALSE;
894 }
895
896 EGLContext __stdcall eglGetCurrentContext(void)
897 {
898     TRACE("()");
899
900     try
901     {
902         EGLContext context = glGetCurrentContext();
903
904         return success(context);
905     }
906     catch(std::bad_alloc&)
907     {
908         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
909     }
910
911     return EGL_NO_CONTEXT;
912 }
913
914 EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
915 {
916     TRACE("(EGLint readdraw = %d)", readdraw);
917
918     try
919     {
920         if (readdraw == EGL_READ)
921         {
922             EGLSurface read = egl::getCurrentReadSurface();
923             return success(read);
924         }
925         else if (readdraw == EGL_DRAW)
926         {
927             EGLSurface draw = egl::getCurrentDrawSurface();
928             return success(draw);
929         }
930         else
931         {
932             return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
933         }
934     }
935     catch(std::bad_alloc&)
936     {
937         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
938     }
939
940     return EGL_NO_SURFACE;
941 }
942
943 EGLDisplay __stdcall eglGetCurrentDisplay(void)
944 {
945     TRACE("()");
946
947     try
948     {
949         EGLDisplay dpy = egl::getCurrentDisplay();
950
951         return success(dpy);
952     }
953     catch(std::bad_alloc&)
954     {
955         return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
956     }
957
958     return EGL_NO_DISPLAY;
959 }
960
961 EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
962 {
963     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
964           dpy, ctx, attribute, value);
965
966     try
967     {
968         egl::Display *display = static_cast<egl::Display*>(dpy);
969
970         if (!validate(display))
971         {
972             return EGL_FALSE;
973         }
974
975         UNIMPLEMENTED();   // FIXME
976
977         return success(0);
978     }
979     catch(std::bad_alloc&)
980     {
981         return error(EGL_BAD_ALLOC, EGL_FALSE);
982     }
983
984     return EGL_FALSE;
985 }
986
987 EGLBoolean __stdcall eglWaitGL(void)
988 {
989     TRACE("()");
990
991     try
992     {
993         UNIMPLEMENTED();   // FIXME
994
995         return success(0);
996     }
997     catch(std::bad_alloc&)
998     {
999         return error(EGL_BAD_ALLOC, EGL_FALSE);
1000     }
1001
1002     return EGL_FALSE;
1003 }
1004
1005 EGLBoolean __stdcall eglWaitNative(EGLint engine)
1006 {
1007     TRACE("(EGLint engine = %d)", engine);
1008
1009     try
1010     {
1011         UNIMPLEMENTED();   // FIXME
1012
1013         return success(0);
1014     }
1015     catch(std::bad_alloc&)
1016     {
1017         return error(EGL_BAD_ALLOC, EGL_FALSE);
1018     }
1019
1020     return EGL_FALSE;
1021 }
1022
1023 EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1024 {
1025     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
1026
1027     try
1028     {
1029         egl::Display *display = static_cast<egl::Display*>(dpy);
1030
1031         if (!validate(display))
1032         {
1033             return EGL_FALSE;
1034         }
1035
1036         if (surface == EGL_NO_SURFACE)
1037         {
1038             return error(EGL_BAD_SURFACE, EGL_FALSE);
1039         }
1040
1041         egl::Surface *eglSurface = (egl::Surface*)surface;
1042
1043         if (eglSurface->swap())
1044         {
1045             return success(EGL_TRUE);
1046         }
1047     }
1048     catch(std::bad_alloc&)
1049     {
1050         return error(EGL_BAD_ALLOC, EGL_FALSE);
1051     }
1052
1053     return EGL_FALSE;
1054 }
1055
1056 EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
1057 {
1058     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
1059
1060     try
1061     {
1062         egl::Display *display = static_cast<egl::Display*>(dpy);
1063
1064         if (!validate(display))
1065         {
1066             return EGL_FALSE;
1067         }
1068
1069         UNIMPLEMENTED();   // FIXME
1070
1071         return success(0);
1072     }
1073     catch(std::bad_alloc&)
1074     {
1075         return error(EGL_BAD_ALLOC, EGL_FALSE);
1076     }
1077
1078     return EGL_FALSE;
1079 }
1080
1081 __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
1082 {
1083     TRACE("(const char *procname = \"%s\")", procname);
1084
1085     try
1086     {
1087         struct Extension
1088         {
1089             const char *name;
1090             __eglMustCastToProperFunctionPointerType address;
1091         };
1092
1093         static const Extension eglExtensions[] =
1094         {
1095             {"", NULL},
1096         };
1097
1098         for (int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
1099         {
1100             if (strcmp(procname, eglExtensions[ext].name) == 0)
1101             {
1102                 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
1103             }
1104         }
1105
1106         return glGetProcAddress(procname);
1107     }
1108     catch(std::bad_alloc&)
1109     {
1110         return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
1111     }
1112
1113     return NULL;
1114 }
1115 }