scons: Actually add src/glx/SConscript.
[profile/ivi/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 }