2010-11-11 Alejandro G. Castro <alex@igalia.com>
[WebKit-https.git] / 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         }
365
366         if (display->hasExistingWindowSurface(window))
367         {
368             return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
369         }
370
371         EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config);
372
373         return success(surface);
374     }
375     catch(std::bad_alloc&)
376     {
377         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
378     }
379
380     return EGL_NO_SURFACE;
381 }
382
383 EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
384 {
385     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
386           dpy, config, attrib_list);
387
388     try
389     {
390         egl::Display *display = static_cast<egl::Display*>(dpy);
391
392         if (!validate(display, config))
393         {
394             return EGL_NO_SURFACE;
395         }
396
397         UNIMPLEMENTED();   // FIXME
398
399         return success(EGL_NO_DISPLAY);
400     }
401     catch(std::bad_alloc&)
402     {
403         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
404     }
405
406     return EGL_NO_SURFACE;
407 }
408
409 EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
410 {
411     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
412           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
413
414     try
415     {
416         egl::Display *display = static_cast<egl::Display*>(dpy);
417
418         if (!validate(display, config))
419         {
420             return EGL_NO_SURFACE;
421         }
422
423         UNIMPLEMENTED();   // FIXME
424
425         return success(EGL_NO_DISPLAY);
426     }
427     catch(std::bad_alloc&)
428     {
429         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
430     }
431
432     return EGL_NO_SURFACE;
433 }
434
435 EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
436 {
437     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
438
439     try
440     {
441         egl::Display *display = static_cast<egl::Display*>(dpy);
442
443         if (!validate(display))
444         {
445             return EGL_FALSE;
446         }
447
448         if (surface == EGL_NO_SURFACE)
449         {
450             return error(EGL_BAD_SURFACE, EGL_FALSE);
451         }
452
453         display->destroySurface((egl::Surface*)surface);
454
455         return success(EGL_TRUE);
456     }
457     catch(std::bad_alloc&)
458     {
459         return error(EGL_BAD_ALLOC, EGL_FALSE);
460     }
461
462     return EGL_FALSE;
463 }
464
465 EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
466 {
467     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
468           dpy, surface, attribute, value);
469
470     try
471     {
472         egl::Display *display = static_cast<egl::Display*>(dpy);
473
474         if (!validate(display))
475         {
476             return EGL_FALSE;
477         }
478
479         if (surface == EGL_NO_SURFACE)
480         {
481             return error(EGL_BAD_SURFACE, EGL_FALSE);
482         }
483
484         egl::Surface *eglSurface = (egl::Surface*)surface;
485
486         switch (attribute)
487         {
488           case EGL_VG_ALPHA_FORMAT:
489             UNIMPLEMENTED();   // FIXME
490             break;
491           case EGL_VG_COLORSPACE:
492             UNIMPLEMENTED();   // FIXME
493             break;
494           case EGL_CONFIG_ID:
495             UNIMPLEMENTED();   // FIXME
496             break;
497           case EGL_HEIGHT:
498             *value = eglSurface->getHeight();
499             break;
500           case EGL_HORIZONTAL_RESOLUTION:
501             UNIMPLEMENTED();   // FIXME
502             break;
503           case EGL_LARGEST_PBUFFER:
504             UNIMPLEMENTED();   // FIXME
505             break;
506           case EGL_MIPMAP_TEXTURE:
507             UNIMPLEMENTED();   // FIXME
508             break;
509           case EGL_MIPMAP_LEVEL:
510             UNIMPLEMENTED();   // FIXME
511             break;
512           case EGL_MULTISAMPLE_RESOLVE:
513             UNIMPLEMENTED();   // FIXME
514             break;
515           case EGL_PIXEL_ASPECT_RATIO:
516             UNIMPLEMENTED();   // FIXME
517             break;
518           case EGL_RENDER_BUFFER:
519             UNIMPLEMENTED();   // FIXME
520             break;
521           case EGL_SWAP_BEHAVIOR:
522             UNIMPLEMENTED();   // FIXME
523             break;
524           case EGL_TEXTURE_FORMAT:
525             UNIMPLEMENTED();   // FIXME
526             break;
527           case EGL_TEXTURE_TARGET:
528             UNIMPLEMENTED();   // FIXME
529             break;
530           case EGL_VERTICAL_RESOLUTION:
531             UNIMPLEMENTED();   // FIXME
532             break;
533           case EGL_WIDTH:
534             *value = eglSurface->getWidth();
535             break;
536           default:
537             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
538         }
539
540         return success(EGL_TRUE);
541     }
542     catch(std::bad_alloc&)
543     {
544         return error(EGL_BAD_ALLOC, EGL_FALSE);
545     }
546
547     return EGL_FALSE;
548 }
549
550 EGLBoolean __stdcall eglBindAPI(EGLenum api)
551 {
552     TRACE("(EGLenum api = 0x%X)", api);
553
554     try
555     {
556         switch (api)
557         {
558           case EGL_OPENGL_API:
559           case EGL_OPENVG_API:
560             return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
561           case EGL_OPENGL_ES_API:
562             break;
563           default:
564             return error(EGL_BAD_PARAMETER, EGL_FALSE);
565         }
566
567         egl::setCurrentAPI(api);
568
569         return success(EGL_TRUE);
570     }
571     catch(std::bad_alloc&)
572     {
573         return error(EGL_BAD_ALLOC, EGL_FALSE);
574     }
575
576     return EGL_FALSE;
577 }
578
579 EGLenum __stdcall eglQueryAPI(void)
580 {
581     TRACE("()");
582
583     try
584     {
585         EGLenum API = egl::getCurrentAPI();
586
587         return success(API);
588     }
589     catch(std::bad_alloc&)
590     {
591         return error(EGL_BAD_ALLOC, EGL_FALSE);
592     }
593
594     return EGL_FALSE;
595 }
596
597 EGLBoolean __stdcall eglWaitClient(void)
598 {
599     TRACE("()");
600
601     try
602     {
603         UNIMPLEMENTED();   // FIXME
604
605         return success(0);
606     }
607     catch(std::bad_alloc&)
608     {
609         return error(EGL_BAD_ALLOC, EGL_FALSE);
610     }
611
612     return EGL_FALSE;
613 }
614
615 EGLBoolean __stdcall eglReleaseThread(void)
616 {
617     TRACE("()");
618
619     try
620     {
621         eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
622
623         return success(EGL_TRUE);
624     }
625     catch(std::bad_alloc&)
626     {
627         return error(EGL_BAD_ALLOC, EGL_FALSE);
628     }
629
630     return EGL_FALSE;
631 }
632
633 EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
634 {
635     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
636           "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
637           dpy, buftype, buffer, config, attrib_list);
638
639     try
640     {
641         egl::Display *display = static_cast<egl::Display*>(dpy);
642
643         if (!validate(display, config))
644         {
645             return EGL_NO_SURFACE;
646         }
647
648         UNIMPLEMENTED();   // FIXME
649
650         return success(EGL_NO_SURFACE);
651     }
652     catch(std::bad_alloc&)
653     {
654         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
655     }
656
657     return EGL_NO_SURFACE;
658 }
659
660 EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
661 {
662     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
663           dpy, surface, attribute, value);
664
665     try
666     {
667         egl::Display *display = static_cast<egl::Display*>(dpy);
668
669         if (!validate(display))
670         {
671             return EGL_FALSE;
672         }
673
674         UNIMPLEMENTED();   // FIXME
675
676         return success(EGL_TRUE);
677     }
678     catch(std::bad_alloc&)
679     {
680         return error(EGL_BAD_ALLOC, EGL_FALSE);
681     }
682
683     return EGL_FALSE;
684 }
685
686 EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
687 {
688     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
689
690     try
691     {
692         egl::Display *display = static_cast<egl::Display*>(dpy);
693
694         if (!validate(display))
695         {
696             return EGL_FALSE;
697         }
698
699         UNIMPLEMENTED();   // FIXME
700
701         return success(EGL_TRUE);
702     }
703     catch(std::bad_alloc&)
704     {
705         return error(EGL_BAD_ALLOC, EGL_FALSE);
706     }
707
708     return EGL_FALSE;
709 }
710
711 EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
712 {
713     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
714
715     try
716     {
717         egl::Display *display = static_cast<egl::Display*>(dpy);
718
719         if (!validate(display))
720         {
721             return EGL_FALSE;
722         }
723
724         UNIMPLEMENTED();   // FIXME
725
726         return success(EGL_TRUE);
727     }
728     catch(std::bad_alloc&)
729     {
730         return error(EGL_BAD_ALLOC, EGL_FALSE);
731     }
732
733     return EGL_FALSE;
734 }
735
736 EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
737 {
738     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
739
740     try
741     {
742         egl::Display *display = static_cast<egl::Display*>(dpy);
743
744         if (!validate(display))
745         {
746             return EGL_FALSE;
747         }
748
749         display->setSwapInterval(interval);
750
751         return success(EGL_TRUE);
752     }
753     catch(std::bad_alloc&)
754     {
755         return error(EGL_BAD_ALLOC, EGL_FALSE);
756     }
757
758     return EGL_FALSE;
759 }
760
761 EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
762 {
763     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
764           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
765
766     try
767     {
768         egl::Display *display = static_cast<egl::Display*>(dpy);
769
770         if (!validate(display, config))
771         {
772             return EGL_NO_CONTEXT;
773         }
774
775         EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
776
777         return success(context);
778     }
779     catch(std::bad_alloc&)
780     {
781         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
782     }
783
784     return EGL_NO_CONTEXT;
785 }
786
787 EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
788 {
789     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
790
791     try
792     {
793         egl::Display *display = static_cast<egl::Display*>(dpy);
794
795         if (!validate(display))
796         {
797             return EGL_FALSE;
798         }
799
800         if (ctx == EGL_NO_CONTEXT)
801         {
802             return error(EGL_BAD_CONTEXT, EGL_FALSE);
803         }
804
805         display->destroyContext((gl::Context*)ctx);
806
807         return success(EGL_TRUE);
808     }
809     catch(std::bad_alloc&)
810     {
811         return error(EGL_BAD_ALLOC, EGL_FALSE);
812     }
813
814     return EGL_FALSE;
815 }
816
817 EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
818 {
819     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
820           dpy, draw, read, ctx);
821
822     try
823     {
824         egl::Display *display = static_cast<egl::Display*>(dpy);
825         gl::Context *context = static_cast<gl::Context*>(ctx);
826         IDirect3DDevice9 *device = display->getDevice();
827
828         if (!device || device->TestCooperativeLevel() != D3D_OK)
829         {
830             return error(EGL_CONTEXT_LOST, EGL_FALSE);
831         }
832
833         if (ctx != EGL_NO_CONTEXT && !validate(display, context))
834         {
835             return EGL_FALSE;
836         }
837
838         if ((draw != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(draw))) ||
839             (read != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(read))))
840         {
841             return EGL_FALSE;
842         }
843
844         if (draw != read)
845         {
846             UNIMPLEMENTED();   // FIXME
847         }
848
849         egl::setCurrentDisplay(dpy);
850         egl::setCurrentDrawSurface(draw);
851         egl::setCurrentReadSurface(read);
852
853         glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
854
855         return success(EGL_TRUE);
856     }
857     catch(std::bad_alloc&)
858     {
859         return error(EGL_BAD_ALLOC, EGL_FALSE);
860     }
861
862     return EGL_FALSE;
863 }
864
865 EGLContext __stdcall eglGetCurrentContext(void)
866 {
867     TRACE("()");
868
869     try
870     {
871         EGLContext context = glGetCurrentContext();
872
873         return success(context);
874     }
875     catch(std::bad_alloc&)
876     {
877         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
878     }
879
880     return EGL_NO_CONTEXT;
881 }
882
883 EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
884 {
885     TRACE("(EGLint readdraw = %d)", readdraw);
886
887     try
888     {
889         if (readdraw == EGL_READ)
890         {
891             EGLSurface read = egl::getCurrentReadSurface();
892             return success(read);
893         }
894         else if (readdraw == EGL_DRAW)
895         {
896             EGLSurface draw = egl::getCurrentDrawSurface();
897             return success(draw);
898         }
899         else
900         {
901             return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
902         }
903     }
904     catch(std::bad_alloc&)
905     {
906         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
907     }
908
909     return EGL_NO_SURFACE;
910 }
911
912 EGLDisplay __stdcall eglGetCurrentDisplay(void)
913 {
914     TRACE("()");
915
916     try
917     {
918         EGLDisplay dpy = egl::getCurrentDisplay();
919
920         return success(dpy);
921     }
922     catch(std::bad_alloc&)
923     {
924         return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
925     }
926
927     return EGL_NO_DISPLAY;
928 }
929
930 EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
931 {
932     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
933           dpy, ctx, attribute, value);
934
935     try
936     {
937         egl::Display *display = static_cast<egl::Display*>(dpy);
938
939         if (!validate(display))
940         {
941             return EGL_FALSE;
942         }
943
944         UNIMPLEMENTED();   // FIXME
945
946         return success(0);
947     }
948     catch(std::bad_alloc&)
949     {
950         return error(EGL_BAD_ALLOC, EGL_FALSE);
951     }
952
953     return EGL_FALSE;
954 }
955
956 EGLBoolean __stdcall eglWaitGL(void)
957 {
958     TRACE("()");
959
960     try
961     {
962         UNIMPLEMENTED();   // FIXME
963
964         return success(0);
965     }
966     catch(std::bad_alloc&)
967     {
968         return error(EGL_BAD_ALLOC, EGL_FALSE);
969     }
970
971     return EGL_FALSE;
972 }
973
974 EGLBoolean __stdcall eglWaitNative(EGLint engine)
975 {
976     TRACE("(EGLint engine = %d)", engine);
977
978     try
979     {
980         UNIMPLEMENTED();   // FIXME
981
982         return success(0);
983     }
984     catch(std::bad_alloc&)
985     {
986         return error(EGL_BAD_ALLOC, EGL_FALSE);
987     }
988
989     return EGL_FALSE;
990 }
991
992 EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
993 {
994     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
995
996     try
997     {
998         egl::Display *display = static_cast<egl::Display*>(dpy);
999
1000         if (!validate(display))
1001         {
1002             return EGL_FALSE;
1003         }
1004
1005         if (surface == EGL_NO_SURFACE)
1006         {
1007             return error(EGL_BAD_SURFACE, EGL_FALSE);
1008         }
1009
1010         egl::Surface *eglSurface = (egl::Surface*)surface;
1011
1012         if (eglSurface->swap())
1013         {
1014             return success(EGL_TRUE);
1015         }
1016     }
1017     catch(std::bad_alloc&)
1018     {
1019         return error(EGL_BAD_ALLOC, EGL_FALSE);
1020     }
1021
1022     return EGL_FALSE;
1023 }
1024
1025 EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
1026 {
1027     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
1028
1029     try
1030     {
1031         egl::Display *display = static_cast<egl::Display*>(dpy);
1032
1033         if (!validate(display))
1034         {
1035             return EGL_FALSE;
1036         }
1037
1038         UNIMPLEMENTED();   // FIXME
1039
1040         return success(0);
1041     }
1042     catch(std::bad_alloc&)
1043     {
1044         return error(EGL_BAD_ALLOC, EGL_FALSE);
1045     }
1046
1047     return EGL_FALSE;
1048 }
1049
1050 __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
1051 {
1052     TRACE("(const char *procname = \"%s\")", procname);
1053
1054     try
1055     {
1056         struct Extension
1057         {
1058             const char *name;
1059             __eglMustCastToProperFunctionPointerType address;
1060         };
1061
1062         static const Extension eglExtensions[] =
1063         {
1064             {"", NULL},
1065         };
1066
1067         for (int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
1068         {
1069             if (strcmp(procname, eglExtensions[ext].name) == 0)
1070             {
1071                 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
1072             }
1073         }
1074
1075         return glGetProcAddress(procname);
1076     }
1077     catch(std::bad_alloc&)
1078     {
1079         return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
1080     }
1081
1082     return NULL;
1083 }
1084 }