egl: Add funtions to link contexts and surfaces to displays.
[mesa.git] / src / egl / main / egldisplay.c
1
2 /**
3 * Functions related to EGLDisplay.
4 */
5
6 #include <assert.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "eglcontext.h"
10 #include "eglsurface.h"
11 #include "egldisplay.h"
12 #include "egldriver.h"
13 #include "eglglobals.h"
14 #include "eglhash.h"
15 #include "eglstring.h"
16
17
18 /**
19 * Allocate a new _EGLDisplay object for the given nativeDisplay handle.
20 * We'll also try to determine the device driver name at this time.
21 *
22 * Note that nativeDisplay may be an X Display ptr, or a string.
23 */
24 _EGLDisplay *
25 _eglNewDisplay(NativeDisplayType nativeDisplay)
26 {
27 _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
28 if (dpy) {
29 dpy->NativeDisplay = nativeDisplay;
30 #if defined(_EGL_PLATFORM_X)
31 dpy->Xdpy = (Display *) nativeDisplay;
32 #endif
33
34 dpy->DriverName = _eglChooseDriver(dpy);
35 if (!dpy->DriverName) {
36 free(dpy);
37 return NULL;
38 }
39 }
40 return dpy;
41 }
42
43
44 /**
45 * Link a display to itself and return the handle of the link.
46 * The handle can be passed to client directly.
47 */
48 EGLDisplay
49 _eglLinkDisplay(_EGLDisplay *dpy)
50 {
51 EGLuint key;
52 key = _eglHashGenKey(_eglGlobal.Displays);
53 assert(key);
54 /* "link" the display to the hash table */
55 _eglHashInsert(_eglGlobal.Displays, key, dpy);
56 dpy->Handle = (EGLDisplay) key;
57
58 return dpy->Handle;
59 }
60
61
62 /**
63 * Unlink a linked display from itself.
64 * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
65 */
66 void
67 _eglUnlinkDisplay(_EGLDisplay *dpy)
68 {
69 _eglHashRemove(_eglGlobal.Displays, (EGLuint) dpy->Handle);
70 dpy->Handle = EGL_NO_DISPLAY;
71 }
72
73
74 /**
75 * Return the handle of a linked display, or EGL_NO_DISPLAY.
76 */
77 EGLDisplay
78 _eglGetDisplayHandle(_EGLDisplay *display)
79 {
80 if (display)
81 return display->Handle;
82 else
83 return EGL_NO_DISPLAY;
84 }
85
86
87 /**
88 * Lookup a handle to find the linked display.
89 * Return NULL if the handle has no corresponding linked display.
90 */
91 _EGLDisplay *
92 _eglLookupDisplay(EGLDisplay dpy)
93 {
94 EGLuint key = (EGLuint) dpy;
95 return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key);
96 }
97
98
99 /**
100 * Free all the data hanging of an _EGLDisplay object, but not
101 * the object itself.
102 */
103 void
104 _eglCleanupDisplay(_EGLDisplay *disp)
105 {
106 EGLint i;
107
108 for (i = 0; i < disp->NumConfigs; i++) {
109 free(disp->Configs[i]);
110 }
111 free(disp->Configs);
112 disp->Configs = NULL;
113
114 /* XXX incomplete */
115
116 free((void *) disp->DriverName);
117 disp->DriverName = NULL;
118
119 /* driver deletes the _EGLDisplay object */
120 }
121
122
123 /**
124 * Link a context to a display and return the handle of the link.
125 * The handle can be passed to client directly.
126 */
127 EGLContext
128 _eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy)
129 {
130 ctx->Display = dpy;
131 ctx->Next = dpy->ContextList;
132 dpy->ContextList = ctx;
133 return (EGLContext) ctx;
134 }
135
136
137 /**
138 * Unlink a linked context from its display.
139 * Accessing an unlinked context should generate EGL_BAD_CONTEXT error.
140 */
141 void
142 _eglUnlinkContext(_EGLContext *ctx)
143 {
144 _EGLContext *prev;
145
146 prev = ctx->Display->ContextList;
147 if (prev != ctx) {
148 while (prev) {
149 if (prev->Next == ctx)
150 break;
151 prev = prev->Next;
152 }
153 assert(prev);
154 prev->Next = ctx->Next;
155 }
156 else {
157 ctx->Display->ContextList = ctx->Next;
158 }
159
160 ctx->Next = NULL;
161 ctx->Display = NULL;
162 }
163
164
165 /**
166 * Return the handle of a linked context, or EGL_NO_CONTEXT.
167 */
168 EGLContext
169 _eglGetContextHandle(_EGLContext *ctx)
170 {
171 return (EGLContext) (ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT;
172 }
173
174
175 /**
176 * Lookup a handle to find the linked context.
177 * Return NULL if the handle has no corresponding linked context.
178 */
179 _EGLContext *
180 _eglLookupContext(EGLContext ctx)
181 {
182 _EGLContext *context = (_EGLContext *) ctx;
183 return (context && context->Display) ? context : NULL;
184 }
185
186
187 /**
188 * Link a surface to a display and return the handle of the link.
189 * The handle can be passed to client directly.
190 */
191 EGLSurface
192 _eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy)
193 {
194 EGLuint key;
195
196 surf->Display = dpy;
197 surf->Next = dpy->SurfaceList;
198 dpy->SurfaceList = surf;
199
200 key = _eglHashGenKey(_eglGlobal.Surfaces);
201 assert(key);
202 _eglHashInsert(_eglGlobal.Surfaces, key, surf);
203
204 surf->Handle = (EGLSurface) key;
205 return surf->Handle;
206 }
207
208
209 /**
210 * Unlink a linked surface from its display.
211 * Accessing an unlinked surface should generate EGL_BAD_SURFACE error.
212 */
213 void
214 _eglUnlinkSurface(_EGLSurface *surf)
215 {
216 _EGLSurface *prev;
217
218 _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
219 surf->Handle = EGL_NO_SURFACE;
220
221 prev = surf->Display->SurfaceList;
222 if (prev != surf) {
223 while (prev) {
224 if (prev->Next == surf)
225 break;
226 prev = prev->Next;
227 }
228 assert(prev);
229 prev->Next = surf->Next;
230 }
231 else {
232 prev = NULL;
233 surf->Display->SurfaceList = surf->Next;
234 }
235
236 surf->Next = NULL;
237 surf->Display = NULL;
238 }
239
240
241 /**
242 * Return the handle of a linked surface, or EGL_NO_SURFACE.
243 */
244 EGLSurface
245 _eglGetSurfaceHandle(_EGLSurface *surface)
246 {
247 if (surface)
248 return surface->Handle;
249 else
250 return EGL_NO_SURFACE;
251 }
252
253
254 /**
255 * Lookup a handle to find the linked surface.
256 * Return NULL if the handle has no corresponding linked surface.
257 */
258 _EGLSurface *
259 _eglLookupSurface(EGLSurface surf)
260 {
261 _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
262 (EGLuint) surf);
263 return c;
264 }