comments and minor clean-up
[mesa.git] / src / egl / main / eglscreen.c
1 /*
2 * Ideas for screen management extension to EGL.
3 *
4 * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
5 * The number of screens can be queried with eglQueryDisplay(EGL_SCREEN_COUNT).
6 *
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().
9 *
10 * To actually display a screen surface on a screen, the eglShowSurface()
11 * function is called.
12 *
13 */
14
15 #include <assert.h>
16 #include <stdlib.h>
17 #include "egldisplay.h"
18 #include "eglglobals.h"
19 #include "eglmode.h"
20 #include "eglsurface.h"
21 #include "eglscreen.h"
22
23
24 _EGLScreen *
25 _eglLookupScreen(EGLDisplay dpy, GLint screenNumber)
26 {
27 _EGLDisplay *disp = _eglLookupDisplay(dpy);
28 if (!disp || screenNumber < 0 || screenNumber >= disp->NumScreens) {
29 return NULL;
30 }
31 else {
32 return disp->Screens + screenNumber;
33 }
34 }
35
36
37 /**
38 * Create a drawing surface which can be directly displayed on a screen.
39 */
40 EGLSurface
41 _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
42 const EGLint *attrib_list)
43 {
44 _EGLSurface *surf;
45 EGLint width = 0, height = 0;
46 EGLint i;
47
48 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
49 switch (attrib_list[i]) {
50 case EGL_WIDTH:
51 width = attrib_list[++i];
52 break;
53 case EGL_HEIGHT:
54 height = attrib_list[++i];
55 break;
56 default:
57 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateScreenSurfaceMESA");
58 return EGL_NO_SURFACE;
59 }
60 }
61
62 if (width <= 0 || height <= 0) {
63 _eglError(EGL_BAD_ATTRIBUTE,
64 "eglCreateScreenSurfaceMESA(width or height)");
65 return EGL_NO_SURFACE;
66 }
67
68 surf = (_EGLSurface *) malloc(sizeof(_EGLSurface));
69 _eglInitSurface(surf);
70 surf->Width = width;
71 surf->Height = height;
72 surf->Type = EGL_SCREEN_BIT_MESA;
73
74 /* insert into hash table */
75 _eglSaveSurface(surf);
76 assert(surf->Handle);
77
78 return surf->Handle;
79 }
80
81
82 /**
83 * Show the given surface on the named screen.
84 * If surface is EGL_NO_SURFACE, disable the screen's output.
85 *
86 * This is just a placeholder function; drivers will always override
87 * this with code that _really_ shows the surface.
88 */
89 EGLBoolean
90 _eglShowSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
91 EGLSurface surface)
92 {
93 _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
94 _EGLMode *mode;
95
96 if (!scrn) {
97 _eglError(EGL_BAD_SCREEN_MESA, "eglShowSurfaceMESA");
98 return EGL_FALSE;
99 }
100
101 /*
102 * XXX: Check if the surface's configuration is compatible with the
103 * current screen mode.
104 */
105
106 mode = scrn->CurrentMode;
107 if (mode == EGL_NO_MODE_MESA) {
108 _eglError(EGL_BAD_MODE_MESA, "eglShowSurfaceMESA(no current mode)");
109 return EGL_FALSE;
110 }
111
112 if (surface == EGL_NO_SURFACE) {
113 scrn->CurrentSurface = NULL;
114 }
115 else {
116 _EGLSurface *surf = _eglLookupSurface(surface);
117 if (!surf || surf->Type != EGL_SCREEN_BIT_MESA) {
118 _eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
119 return EGL_FALSE;
120 }
121 if (surf->Width < mode->Width || surf->Height < mode->Height) {
122 _eglError(EGL_BAD_SURFACE,
123 "eglShowSurfaceMESA(surface smaller than screen size)");
124 return EGL_FALSE;
125 }
126
127 scrn->CurrentSurface = surf;
128 }
129
130 return EGL_TRUE;
131 }
132
133
134 /**
135 * Set a screen's current display mode.
136 * Note: mode = EGL_NO_MODE is valid (turns off the screen)
137 *
138 * This is just a placeholder function; drivers will always override
139 * this with code that _really_ sets the mode.
140 */
141 EGLBoolean
142 _eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
143 EGLModeMESA mode)
144 {
145 _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
146
147 if (!scrn) {
148 _eglError(EGL_BAD_SCREEN_MESA, "eglScreenModeMESA");
149 return EGL_FALSE;
150 }
151
152 scrn->CurrentMode = _eglLookupMode(dpy, mode);
153
154 return EGL_TRUE;
155 }
156
157
158 /**
159 * Set a screen's surface origin.
160 */
161 EGLBoolean
162 _eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
163 EGLint screen_number, EGLint x, EGLint y)
164 {
165 _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
166 if (!scrn) {
167 _eglError(EGL_BAD_SCREEN_MESA, "eglScreenPositionMESA");
168 return EGL_FALSE;
169 }
170
171 scrn->OriginX = x;
172 scrn->OriginY = y;
173
174 return EGL_TRUE;
175 }
176
177
178 EGLBoolean
179 _eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy,
180 EGLint attribute, EGLint *value)
181 {
182 const _EGLDisplay *display = _eglLookupDisplay(dpy);
183 switch (attribute) {
184 case EGL_SCREEN_COUNT_MESA:
185 *value = display->NumScreens;
186 break;
187 default:
188 _eglError(EGL_BAD_ATTRIBUTE, "eglQueryDisplayMESA");
189 return EGL_FALSE;
190 }
191 return EGL_TRUE;
192 }
193
194
195 /**
196 * Query a screen's current surface.
197 */
198 EGLBoolean
199 _eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
200 EGLint screen_number, EGLSurface *surface)
201 {
202 const _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
203 if (scrn->CurrentSurface)
204 *surface = scrn->CurrentSurface->Handle;
205 else
206 *surface = EGL_NO_SURFACE;
207 return EGL_TRUE;
208 }
209
210
211 /**
212 * Query a screen's current mode.
213 */
214 EGLBoolean
215 _eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
216 EGLModeMESA *mode)
217 {
218 const _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
219 if (scrn->CurrentMode)
220 *mode = scrn->CurrentMode->Handle;
221 else
222 *mode = EGL_NO_MODE_MESA;
223 return EGL_TRUE;
224 }
225
226
227 EGLBoolean
228 _eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
229 EGLint attribute, EGLint *value)
230 {
231 const _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
232
233 if (!scrn) {
234 _eglError(EGL_BAD_SCREEN_MESA, "eglQueryScreenMESA");
235 return EGL_FALSE;
236 }
237
238 switch (attribute) {
239 case EGL_SCREEN_POSITION_MESA:
240 value[0] = scrn->OriginX;
241 value[1] = scrn->OriginY;
242 break;
243 default:
244 _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
245 return EGL_FALSE;
246 }
247
248 return EGL_TRUE;
249 }
250
251
252
253 void
254 _eglDeleteScreen(_EGLScreen *scrn)
255 {
256 free(scrn->Modes);
257 free(scrn);
258 }
259