egl: Minor changes to the _EGLScreen interface.
[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 screens' handles can be obtained with eglGetScreensMESA().
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 #include <assert.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "egldisplay.h"
19 #include "eglcurrent.h"
20 #include "eglmode.h"
21 #include "eglconfig.h"
22 #include "eglsurface.h"
23 #include "eglscreen.h"
24 #include "eglmutex.h"
25
26
27 #ifdef EGL_MESA_screen_surface
28
29
30 /* ugh, no atomic op? */
31 static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex);
32 static EGLScreenMESA _eglNextScreenHandle = 1;
33
34
35 /**
36 * Return a new screen handle/ID.
37 * NOTE: we never reuse these!
38 */
39 static EGLScreenMESA
40 _eglAllocScreenHandle(void)
41 {
42 EGLScreenMESA s;
43
44 _eglLockMutex(&_eglNextScreenHandleMutex);
45 s = _eglNextScreenHandle++;
46 _eglUnlockMutex(&_eglNextScreenHandleMutex);
47
48 return s;
49 }
50
51
52 /**
53 * Initialize an _EGLScreen object to default values.
54 */
55 void
56 _eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy)
57 {
58 memset(screen, 0, sizeof(_EGLScreen));
59 screen->Display = dpy;
60 screen->StepX = 1;
61 screen->StepY = 1;
62 }
63
64
65 /**
66 * Link a screen to its display and return the handle of the link.
67 * The handle can be passed to client directly.
68 */
69 EGLScreenMESA
70 _eglLinkScreen(_EGLScreen *screen)
71 {
72 _EGLDisplay *display;
73
74 assert(screen && screen->Display);
75 display = screen->Display;
76
77 if (!display->Screens) {
78 display->Screens = _eglCreateArray("Screen", 4);
79 if (!display->Screens)
80 return (EGLScreenMESA) 0;
81 }
82 screen->Handle = _eglAllocScreenHandle();
83 _eglAppendArray(display->Screens, (void *) screen);
84
85 return screen->Handle;
86 }
87
88
89 /**
90 * Lookup a handle to find the linked config.
91 * Return NULL if the handle has no corresponding linked config.
92 */
93 _EGLScreen *
94 _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
95 {
96 EGLint i;
97
98 if (!display || !display->Screens)
99 return NULL;
100
101 for (i = 0; i < display->Screens->Size; i++) {
102 _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
103 if (scr->Handle == screen) {
104 assert(scr->Display == display);
105 return scr;
106 }
107 }
108 return NULL;
109 }
110
111
112 static EGLBoolean
113 _eglFlattenScreen(void *elem, void *buffer)
114 {
115 _EGLScreen *scr = (_EGLScreen *) elem;
116 EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
117 *handle = _eglGetScreenHandle(scr);
118 return EGL_TRUE;
119 }
120
121
122 EGLBoolean
123 _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
124 EGLint max_screens, EGLint *num_screens)
125 {
126 *num_screens = _eglFlattenArray(display->Screens, (void *) screens,
127 sizeof(screens[0]), max_screens, _eglFlattenScreen);
128
129 return EGL_TRUE;
130 }
131
132
133 /**
134 * Set a screen's surface origin.
135 */
136 EGLBoolean
137 _eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
138 _EGLScreen *scrn, EGLint x, EGLint y)
139 {
140 scrn->OriginX = x;
141 scrn->OriginY = y;
142
143 return EGL_TRUE;
144 }
145
146
147 /**
148 * Query a screen's current surface.
149 */
150 EGLBoolean
151 _eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
152 _EGLScreen *scrn, _EGLSurface **surf)
153 {
154 *surf = scrn->CurrentSurface;
155 return EGL_TRUE;
156 }
157
158
159 /**
160 * Query a screen's current mode.
161 */
162 EGLBoolean
163 _eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
164 _EGLMode **m)
165 {
166 *m = scrn->CurrentMode;
167 return EGL_TRUE;
168 }
169
170
171 EGLBoolean
172 _eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
173 EGLint attribute, EGLint *value)
174 {
175 switch (attribute) {
176 case EGL_SCREEN_POSITION_MESA:
177 value[0] = scrn->OriginX;
178 value[1] = scrn->OriginY;
179 break;
180 case EGL_SCREEN_POSITION_GRANULARITY_MESA:
181 value[0] = scrn->StepX;
182 value[1] = scrn->StepY;
183 break;
184 default:
185 _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
186 return EGL_FALSE;
187 }
188
189 return EGL_TRUE;
190 }
191
192
193 #endif /* EGL_MESA_screen_surface */