e213e9a8472dc8b8a3104b111c16b4bbebb8db3f
2 * Ideas for screen management extension to EGL.
4 * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
5 * The screens' handles can be obtained with eglGetScreensMESA().
7 * A new kind of EGLSurface is possible- one which can be directly scanned
8 * out on a screen. Such a surface is created with eglCreateScreenSurface().
10 * To actually display a screen surface on a screen, the eglShowSurface()
18 #include "egldisplay.h"
19 #include "eglglobals.h"
21 #include "eglconfig.h"
22 #include "eglsurface.h"
23 #include "eglscreen.h"
27 * Initialize an _EGLScreen object to default values.
30 _eglInitScreen(_EGLScreen
*screen
)
32 /* just init to zero for now */
33 memset(screen
, 0, sizeof(_EGLScreen
));
38 * Given a public screen handle, return the internal _EGLScreen object.
41 _eglLookupScreen(EGLDisplay dpy
, EGLScreenMESA screen
)
44 _EGLDisplay
*display
= _eglLookupDisplay(dpy
);
49 for (i
= 0; i
< display
->NumScreens
; i
++) {
50 if (display
->Screens
[i
]->Handle
== screen
)
51 return display
->Screens
[i
];
58 * Add the given _EGLScreen to the display's list of screens.
61 _eglAddScreen(_EGLDisplay
*display
, _EGLScreen
*screen
)
68 screen
->Handle
= _eglAllocScreenHandle();
69 n
= display
->NumScreens
;
70 display
->Screens
= realloc(display
->Screens
, (n
+1) * sizeof(_EGLScreen
*));
71 display
->Screens
[n
] = screen
;
72 display
->NumScreens
++;
78 _eglGetScreensMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA
*screens
,
79 EGLint max_screens
, EGLint
*num_screens
)
81 _EGLDisplay
*display
= _eglLookupDisplay(dpy
);
85 _eglError(EGL_BAD_DISPLAY
, "eglGetScreensMESA");
89 if (display
->NumScreens
> max_screens
) {
93 n
= display
->NumScreens
;
98 for (i
= 0; i
< n
; i
++)
99 screens
[i
] = display
->Screens
[i
]->Handle
;
109 * Initialize the given _EGLSurface object. Do error checking.
110 * Assign it an EGLSurface handle and insert into hash table.
111 * \return EGLSurface handle or EGL_NO_SURFACE if error.
114 _eglInitScreenSurface(_EGLSurface
*surf
, _EGLDriver
*drv
, EGLDisplay dpy
,
115 EGLConfig config
, const EGLint
*attrib_list
)
117 EGLint width
= 0, height
= 0;
120 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
121 switch (attrib_list
[i
]) {
123 width
= attrib_list
[++i
];
126 height
= attrib_list
[++i
];
129 _eglError(EGL_BAD_ATTRIBUTE
, "eglCreateScreenSurfaceMESA");
130 return EGL_NO_SURFACE
;
134 if (width
<= 0 || height
<= 0) {
135 _eglError(EGL_BAD_ATTRIBUTE
,
136 "eglCreateScreenSurfaceMESA(width or height)");
137 return EGL_NO_SURFACE
;
140 _eglInitSurface(surf
);
142 surf
->Height
= height
;
143 surf
->Type
= EGL_SCREEN_BIT_MESA
;
144 surf
->Config
= _eglLookupConfig(drv
, dpy
, config
);
146 /* insert into hash table */
147 _eglSaveSurface(surf
);
148 assert(surf
->Handle
);
155 * Create a drawing surface which can be directly displayed on a screen.
158 _eglCreateScreenSurfaceMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
159 const EGLint
*attrib_list
)
164 surf
= (_EGLSurface
*) malloc(sizeof(_EGLSurface
));
165 surface
= _eglInitScreenSurface(surf
, drv
, dpy
, config
, attrib_list
);
166 if (surface
== EGL_NO_SURFACE
)
174 * Show the given surface on the named screen.
175 * If surface is EGL_NO_SURFACE, disable the screen's output.
177 * This is just a placeholder function; drivers will always override
178 * this with code that _really_ shows the surface.
181 _eglShowSurfaceMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA screen
,
182 EGLSurface surface
, EGLModeMESA m
)
184 _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
185 _EGLMode
*mode
= _eglLookupMode(dpy
, m
);
188 _eglError(EGL_BAD_SCREEN_MESA
, "eglShowSurfaceMESA");
191 if (!mode
&& (m
!= EGL_NO_MODE_MESA
)) {
192 _eglError(EGL_BAD_MODE_MESA
, "eglShowSurfaceMESA");
196 if (surface
== EGL_NO_SURFACE
) {
197 scrn
->CurrentSurface
= NULL
;
199 _EGLSurface
*surf
= _eglLookupSurface(surface
);
200 if (!surf
|| surf
->Type
!= EGL_SCREEN_BIT_MESA
) {
201 _eglError(EGL_BAD_SURFACE
, "eglShowSurfaceMESA");
204 if (surf
->Width
< mode
->Width
|| surf
->Height
< mode
->Height
) {
205 _eglError(EGL_BAD_SURFACE
,
206 "eglShowSurfaceMESA(surface smaller than screen size)");
210 scrn
->CurrentSurface
= surf
;
211 scrn
->CurrentMode
= mode
;
218 * Set a screen's current display mode.
219 * Note: mode = EGL_NO_MODE is valid (turns off the screen)
221 * This is just a placeholder function; drivers will always override
222 * this with code that _really_ sets the mode.
225 _eglScreenModeMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA screen
,
228 _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
231 _eglError(EGL_BAD_SCREEN_MESA
, "eglScreenModeMESA");
235 scrn
->CurrentMode
= _eglLookupMode(dpy
, mode
);
242 * Set a screen's surface origin.
245 _eglScreenPositionMESA(_EGLDriver
*drv
, EGLDisplay dpy
,
246 EGLScreenMESA screen
, EGLint x
, EGLint y
)
248 _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
250 _eglError(EGL_BAD_SCREEN_MESA
, "eglScreenPositionMESA");
262 * Query a screen's current surface.
265 _eglQueryScreenSurfaceMESA(_EGLDriver
*drv
, EGLDisplay dpy
,
266 EGLScreenMESA screen
, EGLSurface
*surface
)
268 const _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
269 if (scrn
->CurrentSurface
)
270 *surface
= scrn
->CurrentSurface
->Handle
;
272 *surface
= EGL_NO_SURFACE
;
278 * Query a screen's current mode.
281 _eglQueryScreenModeMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA screen
,
284 const _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
285 if (scrn
->CurrentMode
)
286 *mode
= scrn
->CurrentMode
->Handle
;
288 *mode
= EGL_NO_MODE_MESA
;
294 _eglQueryScreenMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA screen
,
295 EGLint attribute
, EGLint
*value
)
297 const _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
300 _eglError(EGL_BAD_SCREEN_MESA
, "eglQueryScreenMESA");
305 case EGL_SCREEN_POSITION_MESA
:
306 value
[0] = scrn
->OriginX
;
307 value
[1] = scrn
->OriginY
;
310 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryScreenMESA");
319 _eglDestroyScreenModes(_EGLScreen
*scrn
)
326 * Default fallback routine - drivers should usually override this.
329 _eglDestroyScreen(_EGLScreen
*scrn
)
331 _eglDestroyScreenModes(scrn
);