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 * Return a new screen handle/ID.
28 * NOTE: we never reuse these!
31 _eglAllocScreenHandle(void)
33 EGLScreenMESA s
= _eglGlobal
.FreeScreenHandle
;
34 _eglGlobal
.FreeScreenHandle
++;
40 * Initialize an _EGLScreen object to default values.
43 _eglInitScreen(_EGLScreen
*screen
)
45 memset(screen
, 0, sizeof(_EGLScreen
));
52 * Given a public screen handle, return the internal _EGLScreen object.
55 _eglLookupScreen(EGLDisplay dpy
, EGLScreenMESA screen
)
58 _EGLDisplay
*display
= _eglLookupDisplay(dpy
);
63 for (i
= 0; i
< display
->NumScreens
; i
++) {
64 if (display
->Screens
[i
]->Handle
== screen
)
65 return display
->Screens
[i
];
72 * Add the given _EGLScreen to the display's list of screens.
75 _eglAddScreen(_EGLDisplay
*display
, _EGLScreen
*screen
)
82 screen
->Handle
= _eglAllocScreenHandle();
83 n
= display
->NumScreens
;
84 display
->Screens
= realloc(display
->Screens
, (n
+1) * sizeof(_EGLScreen
*));
85 display
->Screens
[n
] = screen
;
86 display
->NumScreens
++;
92 _eglGetScreensMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA
*screens
,
93 EGLint max_screens
, EGLint
*num_screens
)
95 _EGLDisplay
*display
= _eglLookupDisplay(dpy
);
99 _eglError(EGL_BAD_DISPLAY
, "eglGetScreensMESA");
103 if (display
->NumScreens
> max_screens
) {
107 n
= display
->NumScreens
;
112 for (i
= 0; i
< n
; i
++)
113 screens
[i
] = display
->Screens
[i
]->Handle
;
123 * Example function - drivers should do a proper implementation.
126 _eglCreateScreenSurfaceMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
127 const EGLint
*attrib_list
)
129 #if 0 /* THIS IS JUST EXAMPLE CODE */
132 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
134 return EGL_NO_SURFACE
;
136 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_SCREEN_BIT_MESA
,
137 config
, attrib_list
)) {
139 return EGL_NO_SURFACE
;
142 _eglSaveSurface(surf
);
146 return EGL_NO_SURFACE
;
151 * Show the given surface on the named screen.
152 * If surface is EGL_NO_SURFACE, disable the screen's output.
154 * This is just a placeholder function; drivers will always override
155 * this with code that _really_ shows the surface.
158 _eglShowScreenSurfaceMESA(_EGLDriver
*drv
, EGLDisplay dpy
,
159 EGLScreenMESA screen
, EGLSurface surface
,
162 _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
163 _EGLMode
*mode
= _eglLookupMode(dpy
, m
);
166 _eglError(EGL_BAD_SCREEN_MESA
, "eglShowSurfaceMESA");
169 if (!mode
&& (m
!= EGL_NO_MODE_MESA
)) {
170 _eglError(EGL_BAD_MODE_MESA
, "eglShowSurfaceMESA");
174 if (surface
== EGL_NO_SURFACE
) {
175 scrn
->CurrentSurface
= NULL
;
178 _EGLSurface
*surf
= _eglLookupSurface(surface
);
179 if (!surf
|| surf
->Type
!= EGL_SCREEN_BIT_MESA
) {
180 _eglError(EGL_BAD_SURFACE
, "eglShowSurfaceMESA");
183 if (surf
->Width
< mode
->Width
|| surf
->Height
< mode
->Height
) {
184 _eglError(EGL_BAD_SURFACE
,
185 "eglShowSurfaceMESA(surface smaller than screen size)");
189 scrn
->CurrentSurface
= surf
;
190 scrn
->CurrentMode
= mode
;
197 * Set a screen's current display mode.
198 * Note: mode = EGL_NO_MODE is valid (turns off the screen)
200 * This is just a placeholder function; drivers will always override
201 * this with code that _really_ sets the mode.
204 _eglScreenModeMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA screen
,
207 _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
210 _eglError(EGL_BAD_SCREEN_MESA
, "eglScreenModeMESA");
214 scrn
->CurrentMode
= _eglLookupMode(dpy
, mode
);
221 * Set a screen's surface origin.
224 _eglScreenPositionMESA(_EGLDriver
*drv
, EGLDisplay dpy
,
225 EGLScreenMESA screen
, EGLint x
, EGLint y
)
227 _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
229 _eglError(EGL_BAD_SCREEN_MESA
, "eglScreenPositionMESA");
241 * Query a screen's current surface.
244 _eglQueryScreenSurfaceMESA(_EGLDriver
*drv
, EGLDisplay dpy
,
245 EGLScreenMESA screen
, EGLSurface
*surface
)
247 const _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
248 if (scrn
->CurrentSurface
)
249 *surface
= scrn
->CurrentSurface
->Handle
;
251 *surface
= EGL_NO_SURFACE
;
257 * Query a screen's current mode.
260 _eglQueryScreenModeMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA screen
,
263 const _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
264 if (scrn
->CurrentMode
)
265 *mode
= scrn
->CurrentMode
->Handle
;
267 *mode
= EGL_NO_MODE_MESA
;
273 _eglQueryScreenMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLScreenMESA screen
,
274 EGLint attribute
, EGLint
*value
)
276 const _EGLScreen
*scrn
= _eglLookupScreen(dpy
, screen
);
279 _eglError(EGL_BAD_SCREEN_MESA
, "eglQueryScreenMESA");
284 case EGL_SCREEN_POSITION_MESA
:
285 value
[0] = scrn
->OriginX
;
286 value
[1] = scrn
->OriginY
;
288 case EGL_SCREEN_POSITION_GRANULARITY_MESA
:
289 value
[0] = scrn
->StepX
;
290 value
[1] = scrn
->StepY
;
293 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryScreenMESA");
302 * Delete the modes associated with given screen.
305 _eglDestroyScreenModes(_EGLScreen
*scrn
)
308 for (i
= 0; i
< scrn
->NumModes
; i
++) {
309 if (scrn
->Modes
[i
].Name
)
310 free((char *) scrn
->Modes
[i
].Name
); /* cast away const */
320 * Default fallback routine - drivers should usually override this.
323 _eglDestroyScreen(_EGLScreen
*scrn
)
325 _eglDestroyScreenModes(scrn
);