docs: Update status of GL 3.x related extensions
[mesa.git] / src / driclient / src / driclient.c
1 #include "driclient.h"
2 #include <assert.h>
3 #include <stdlib.h>
4
5 int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf)
6 {
7 int evbase, errbase;
8 char *driver_name;
9 int newly_opened;
10 drm_magic_t magic;
11 drmVersionPtr drm_version;
12 drm_handle_t sarea_handle;
13 char *bus_id;
14 dri_screen_t *dri_scrn;
15
16 assert(display);
17 assert(dri_screen);
18
19 if (!XF86DRIQueryExtension(display, &evbase, &errbase))
20 return 1;
21
22 dri_scrn = calloc(1, sizeof(dri_screen_t));
23
24 if (!dri_scrn)
25 return 1;
26
27 if (!XF86DRIQueryVersion(display, &dri_scrn->dri.major, &dri_scrn->dri.minor, &dri_scrn->dri.patch))
28 goto free_screen;
29
30 dri_scrn->display = display;
31 dri_scrn->num = screen;
32 dri_scrn->draw_lock_id = 1;
33
34 if (!XF86DRIOpenConnection(display, screen, &sarea_handle, &bus_id))
35 goto free_screen;
36
37 dri_scrn->fd = -1;
38 dri_scrn->fd = drmOpenOnce(NULL, bus_id, &newly_opened);
39 XFree(bus_id);
40
41 if (dri_scrn->fd < 0)
42 goto close_connection;
43
44 if (drmGetMagic(dri_scrn->fd, &magic))
45 goto close_drm;
46
47 drm_version = drmGetVersion(dri_scrn->fd);
48
49 if (!drm_version)
50 goto close_drm;
51
52 dri_scrn->drm.major = drm_version->version_major;
53 dri_scrn->drm.minor = drm_version->version_minor;
54 dri_scrn->drm.patch = drm_version->version_patchlevel;
55 drmFreeVersion(drm_version);
56
57 if (!XF86DRIAuthConnection(display, screen, magic))
58 goto close_drm;
59
60 if (!XF86DRIGetClientDriverName
61 (
62 display,
63 screen,
64 &dri_scrn->ddx.major,
65 &dri_scrn->ddx.minor,
66 &dri_scrn->ddx.patch,
67 &driver_name
68 ))
69 goto close_drm;
70
71 if (drmMap(dri_scrn->fd, sarea_handle, SAREA_MAX, (drmAddress)&dri_scrn->sarea))
72 goto close_drm;
73
74 dri_scrn->drawable_hash = drmHashCreate();
75
76 if (!dri_scrn->drawable_hash)
77 goto unmap_sarea;
78
79 if (dri_framebuf)
80 {
81 if (!XF86DRIGetDeviceInfo
82 (
83 display,
84 screen, &dri_framebuf->drm_handle,
85 &dri_framebuf->base,
86 &dri_framebuf->size,
87 &dri_framebuf->stride,
88 &dri_framebuf->private_size,
89 &dri_framebuf->private
90 ))
91 goto destroy_hash;
92 }
93
94 *dri_screen = dri_scrn;
95
96 return 0;
97
98 destroy_hash:
99 drmHashDestroy(dri_scrn->drawable_hash);
100 unmap_sarea:
101 drmUnmap(dri_scrn->sarea, SAREA_MAX);
102 close_drm:
103 drmCloseOnce(dri_scrn->fd);
104 close_connection:
105 XF86DRICloseConnection(display, screen);
106 free_screen:
107 free(dri_scrn);
108
109 return 1;
110 }
111
112 int driDestroyScreen(dri_screen_t *dri_screen)
113 {
114 Drawable draw;
115 dri_drawable_t *dri_draw;
116
117 assert(dri_screen);
118
119 if (drmHashFirst(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
120 {
121 dri_draw->refcount = 1;
122 driDestroyDrawable(dri_draw);
123
124 while (drmHashNext(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
125 {
126 dri_draw->refcount = 1;
127 driDestroyDrawable(dri_draw);
128 }
129 }
130
131 drmHashDestroy(dri_screen->drawable_hash);
132 drmUnmap(dri_screen->sarea, SAREA_MAX);
133 drmCloseOnce(dri_screen->fd);
134 XF86DRICloseConnection(dri_screen->display, dri_screen->num);
135 free(dri_screen);
136
137 return 0;
138 }
139
140 int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable)
141 {
142 int evbase, errbase;
143 dri_drawable_t *dri_draw;
144
145 assert(dri_screen);
146 assert(dri_drawable);
147
148 if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
149 return 1;
150
151 if (!drmHashLookup(dri_screen->drawable_hash, drawable, (void**)dri_drawable))
152 {
153 /* Found */
154 (*dri_drawable)->refcount++;
155 return 0;
156 }
157
158 dri_draw = calloc(1, sizeof(dri_drawable_t));
159
160 if (!dri_draw)
161 return 1;
162
163 if (!XF86DRICreateDrawable(dri_screen->display, 0, drawable, &dri_draw->drm_drawable))
164 {
165 free(dri_draw);
166 return 1;
167 }
168
169 dri_draw->x_drawable = drawable;
170 dri_draw->sarea_index = 0;
171 dri_draw->sarea_stamp = NULL;
172 dri_draw->last_sarea_stamp = 0;
173 dri_draw->dri_screen = dri_screen;
174 dri_draw->refcount = 1;
175
176 if (drmHashInsert(dri_screen->drawable_hash, drawable, dri_draw))
177 {
178 XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
179 free(dri_draw);
180 return 1;
181 }
182
183 if (!dri_draw->sarea_stamp || *dri_draw->sarea_stamp != dri_draw->last_sarea_stamp)
184 {
185 DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
186
187 if (driUpdateDrawableInfo(dri_draw))
188 {
189 XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
190 free(dri_draw);
191 DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
192 return 1;
193 }
194
195 DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
196 }
197
198 *dri_drawable = dri_draw;
199
200 return 0;
201 }
202
203 int driUpdateDrawableInfo(dri_drawable_t *dri_drawable)
204 {
205 assert(dri_drawable);
206
207 if (dri_drawable->cliprects)
208 {
209 XFree(dri_drawable->cliprects);
210 dri_drawable->cliprects = NULL;
211 }
212 if (dri_drawable->back_cliprects)
213 {
214 XFree(dri_drawable->back_cliprects);
215 dri_drawable->back_cliprects = NULL;
216 }
217
218 DRM_SPINUNLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
219
220 if (!XF86DRIGetDrawableInfo
221 (
222 dri_drawable->dri_screen->display,
223 dri_drawable->dri_screen->num,
224 dri_drawable->x_drawable,
225 &dri_drawable->sarea_index,
226 &dri_drawable->last_sarea_stamp,
227 &dri_drawable->x,
228 &dri_drawable->y,
229 &dri_drawable->w,
230 &dri_drawable->h,
231 &dri_drawable->num_cliprects,
232 &dri_drawable->cliprects,
233 &dri_drawable->back_x,
234 &dri_drawable->back_y,
235 &dri_drawable->num_back_cliprects,
236 &dri_drawable->back_cliprects
237 ))
238 {
239 dri_drawable->sarea_stamp = &dri_drawable->last_sarea_stamp;
240 dri_drawable->num_cliprects = 0;
241 dri_drawable->cliprects = NULL;
242 dri_drawable->num_back_cliprects = 0;
243 dri_drawable->back_cliprects = 0;
244
245 return 1;
246 }
247 else
248 dri_drawable->sarea_stamp = &dri_drawable->dri_screen->sarea->drawableTable[dri_drawable->sarea_index].stamp;
249
250 DRM_SPINLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
251
252 return 0;
253 }
254
255 int driDestroyDrawable(dri_drawable_t *dri_drawable)
256 {
257 assert(dri_drawable);
258
259 if (--dri_drawable->refcount == 0)
260 {
261 if (dri_drawable->cliprects)
262 XFree(dri_drawable->cliprects);
263 if (dri_drawable->back_cliprects)
264 XFree(dri_drawable->back_cliprects);
265 drmHashDelete(dri_drawable->dri_screen->drawable_hash, dri_drawable->x_drawable);
266 XF86DRIDestroyDrawable(dri_drawable->dri_screen->display, dri_drawable->dri_screen->num, dri_drawable->x_drawable);
267 free(dri_drawable);
268 }
269
270 return 0;
271 }
272
273 int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context)
274 {
275 int evbase, errbase;
276 dri_context_t *dri_ctx;
277
278 assert(dri_screen);
279 assert(visual);
280 assert(dri_context);
281
282 if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
283 return 1;
284
285 dri_ctx = calloc(1, sizeof(dri_context_t));
286
287 if (!dri_ctx)
288 return 1;
289
290 if (!XF86DRICreateContext(dri_screen->display, dri_screen->num, visual, &dri_ctx->id, &dri_ctx->drm_context))
291 {
292 free(dri_ctx);
293 return 1;
294 }
295
296 dri_ctx->dri_screen = dri_screen;
297 *dri_context = dri_ctx;
298
299 return 0;
300 }
301
302 int driDestroyContext(dri_context_t *dri_context)
303 {
304 assert(dri_context);
305
306 XF86DRIDestroyContext(dri_context->dri_screen->display, dri_context->dri_screen->num, dri_context->id);
307 free(dri_context);
308
309 return 0;
310 }