1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_XRender_Xcb.h"
6 static Evas_List *_image_info_list = NULL;
8 static int _xcb_err = 0;
12 xcb_render_pictforminfo_id = 1 << 0,
13 xcb_render_pictforminfo_type_t = 1 << 1,
14 xcb_render_pictforminfo_depth_t = 1 << 2,
15 xcb_render_pictforminfo_red_shift_t = 1 << 3,
16 xcb_render_pictforminfo_red_mask_t = 1 << 4,
17 xcb_render_pictforminfo_green_shift_t = 1 << 5,
18 xcb_render_pictforminfo_green_mask_t = 1 << 6,
19 xcb_render_pictforminfo_blue_shift_t = 1 << 7,
20 xcb_render_pictforminfo_blue_mask_t = 1 << 8,
21 xcb_render_pictforminfo_alpha_shift_t = 1 << 9,
22 xcb_render_pictforminfo_alpha_mask_t = 1 << 10,
23 xcb_render_pictforminfo_colormap_t = 1 << 11,
28 xcb_render_standard_pictforminfoargb_32_t,
29 xcb_render_standard_pictforminforgb_24_t,
30 xcb_render_standard_pictforminfoa_8_t,
31 xcb_render_standard_pictforminfoa_4_t,
32 xcb_render_standard_pictforminfoa_1_t,
33 xcb_render_standard_pictforminfo_count_t
36 static xcb_render_pictforminfo_t *
37 xcb_render_find_pictforminfo (xcb_connection_t *conn, uint32_t mask, const xcb_render_pictforminfo_t *template, int count)
39 xcb_render_query_pict_formats_cookie_t cookie;
40 xcb_render_query_pict_formats_reply_t *rep;
41 xcb_render_pictforminfo_iterator_t iter_forminfo;
43 cookie = xcb_render_query_pict_formats_unchecked (conn);
44 rep = xcb_render_query_pict_formats_reply (conn, cookie, NULL);
45 iter_forminfo = xcb_render_query_pict_formats_formats_iterator (rep);
46 for (; iter_forminfo.rem; xcb_render_pictforminfo_next (&iter_forminfo)) {
47 if (mask & xcb_render_pictforminfo_id)
48 if (template->id != iter_forminfo.data->id)
50 if (mask & xcb_render_pictforminfo_type_t)
51 if (template->type != iter_forminfo.data->type)
53 if (mask & xcb_render_pictforminfo_depth_t)
54 if (template->depth != iter_forminfo.data->depth)
56 if (mask & xcb_render_pictforminfo_red_shift_t)
57 if (template->direct.red_shift != iter_forminfo.data->direct.red_shift)
59 if (mask & xcb_render_pictforminfo_red_mask_t)
60 if (template->direct.red_mask != iter_forminfo.data->direct.red_mask)
62 if (mask & xcb_render_pictforminfo_green_shift_t)
63 if (template->direct.green_shift != iter_forminfo.data->direct.green_shift)
65 if (mask & xcb_render_pictforminfo_green_mask_t)
66 if (template->direct.green_mask != iter_forminfo.data->direct.green_mask)
68 if (mask & xcb_render_pictforminfo_blue_shift_t)
69 if (template->direct.blue_shift != iter_forminfo.data->direct.blue_shift)
71 if (mask & xcb_render_pictforminfo_blue_mask_t)
72 if (template->direct.blue_mask != iter_forminfo.data->direct.blue_mask)
74 if (mask & xcb_render_pictforminfo_alpha_shift_t)
75 if (template->direct.alpha_shift != iter_forminfo.data->direct.alpha_shift)
77 if (mask & xcb_render_pictforminfo_alpha_mask_t)
78 if (template->direct.alpha_mask != iter_forminfo.data->direct.alpha_mask)
80 if (mask & xcb_render_pictforminfo_colormap_t)
81 if (template->colormap != iter_forminfo.data->colormap)
84 xcb_render_pictforminfo_t *forminfo;
86 forminfo = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
87 memcpy (forminfo, iter_forminfo.data, sizeof (xcb_render_pictforminfo_t));
97 static xcb_render_pictforminfo_t *
98 xcb_render_find_standard_pictforminfo (xcb_connection_t *conn, int format)
100 xcb_render_pictforminfo_t *forminfo = NULL;
102 xcb_render_pictforminfo_t template;
104 } standardFormats[xcb_render_standard_pictforminfo_count_t] = {
105 /* StandardPICTFORMINFOARGB32 */
109 XCB_RENDER_PICT_TYPE_DIRECT, /* type */
113 16, /* direct.red_shift */
114 0xff, /* direct.red_mask */
115 8, /* direct.green_shift */
116 0xff, /* direct.green_mask */
117 0, /* direct.blue_shift */
118 0xff, /* direct.blue_mask */
119 24, /* direct.alpha_shift */
120 0xff /* direct.alpha_mask */
124 xcb_render_pictforminfo_type_t |
125 xcb_render_pictforminfo_depth_t |
126 xcb_render_pictforminfo_red_shift_t |
127 xcb_render_pictforminfo_red_mask_t |
128 xcb_render_pictforminfo_green_shift_t |
129 xcb_render_pictforminfo_green_mask_t |
130 xcb_render_pictforminfo_blue_shift_t |
131 xcb_render_pictforminfo_blue_mask_t |
132 xcb_render_pictforminfo_alpha_shift_t |
133 xcb_render_pictforminfo_alpha_mask_t
135 /* StandardPICTFORMINFORGB24 */
139 XCB_RENDER_PICT_TYPE_DIRECT, /* type */
143 16, /* direct.red_shift */
144 0xff, /* direct.red_mask */
145 8, /* direct.green_shift */
146 0xff, /* direct.green_mask */
147 0, /* direct.blue_shift */
148 0xff, /* direct.blue_mask */
149 0, /* direct.alpha_shift */
150 0x00 /* direct.alpha_mask */
154 xcb_render_pictforminfo_type_t |
155 xcb_render_pictforminfo_depth_t |
156 xcb_render_pictforminfo_red_shift_t |
157 xcb_render_pictforminfo_red_mask_t |
158 xcb_render_pictforminfo_green_shift_t |
159 xcb_render_pictforminfo_green_mask_t |
160 xcb_render_pictforminfo_blue_shift_t |
161 xcb_render_pictforminfo_blue_mask_t |
162 xcb_render_pictforminfo_alpha_mask_t
164 /* StandardPICTFORMINFOA8 */
168 XCB_RENDER_PICT_TYPE_DIRECT, /* type */
172 0, /* direct.red_shift */
173 0x00, /* direct.red_mask */
174 0, /* direct.green_shift */
175 0x00, /* direct.green_mask */
176 0, /* direct.blue_shift */
177 0x00, /* direct.blue_mask */
178 0, /* direct.alpha_shift */
179 0xff /* direct.alpha_mask */
183 xcb_render_pictforminfo_type_t |
184 xcb_render_pictforminfo_depth_t |
185 xcb_render_pictforminfo_red_mask_t |
186 xcb_render_pictforminfo_green_mask_t |
187 xcb_render_pictforminfo_blue_mask_t |
188 xcb_render_pictforminfo_alpha_shift_t |
189 xcb_render_pictforminfo_alpha_mask_t
191 /* StandardPICTFORMINFOA4 */
195 XCB_RENDER_PICT_TYPE_DIRECT, /* type */
199 0, /* direct.red_shift */
200 0x00, /* direct.red_mask */
201 0, /* direct.green_shift */
202 0x00, /* direct.green_mask */
203 0, /* direct.blue_shift */
204 0x00, /* direct.blue_mask */
205 0, /* direct.alpha_shift */
206 0x0f /* direct.alpha_mask */
210 xcb_render_pictforminfo_type_t |
211 xcb_render_pictforminfo_depth_t |
212 xcb_render_pictforminfo_red_mask_t |
213 xcb_render_pictforminfo_green_mask_t |
214 xcb_render_pictforminfo_blue_mask_t |
215 xcb_render_pictforminfo_alpha_shift_t |
216 xcb_render_pictforminfo_alpha_mask_t
218 /* StandardPICTFORMINFOA1 */
222 XCB_RENDER_PICT_TYPE_DIRECT, /* type */
226 0, /* direct.red_shift */
227 0x00, /* direct.red_mask */
228 0, /* direct.green_shift */
229 0x00, /* direct.green_mask */
230 0, /* direct.blue_shift */
231 0x00, /* direct.blue_mask */
232 0, /* direct.alpha_shift */
233 0x01 /* direct.alpha_mask */
237 xcb_render_pictforminfo_type_t |
238 xcb_render_pictforminfo_depth_t |
239 xcb_render_pictforminfo_red_mask_t |
240 xcb_render_pictforminfo_green_mask_t |
241 xcb_render_pictforminfo_blue_mask_t |
242 xcb_render_pictforminfo_alpha_shift_t |
243 xcb_render_pictforminfo_alpha_mask_t
246 if ((format >= 0) && (format < xcb_render_standard_pictforminfo_count_t))
247 forminfo = xcb_render_find_pictforminfo (conn,
248 standardFormats[format].mask,
249 &standardFormats[format].template,
255 _tmp_xcb_err(xcb_connection_t *conn/* , XErrorEvent *ev */)
262 _xr_image_info_get(xcb_connection_t *conn, xcb_drawable_t draw, xcb_visualid_t vis)
264 xcb_get_geometry_cookie_t cookie;
265 xcb_get_geometry_reply_t *rep;
266 Xcb_Image_Info *xcbinf;
267 Xcb_Image_Info *xcbinf2;
271 for (l = _image_info_list; l; l = l->next)
274 if (xcbinf->conn == conn)
280 xcbinf = calloc(1, sizeof(Xcb_Image_Info));
281 if (!xcbinf) return NULL;
283 xcbinf->references = 1;
286 cookie = xcb_get_geometry_unchecked(xcbinf->conn, xcbinf->draw);
287 rep = xcb_get_geometry_reply(xcbinf->conn, cookie, NULL);
288 xcbinf->root = rep->root;
291 xcbinf->fmt32 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoargb_32_t);
292 xcbinf->fmt24 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminforgb_24_t);
293 xcbinf->fmt8 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoa_8_t);
294 xcbinf->fmt4 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoa_4_t);
295 xcbinf->fmt1 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoa_1_t);
296 xcbinf->mul = _xr_render_surface_new(xcbinf, 1, 1, xcbinf->fmt32, 1);
297 _xr_render_surface_repeat_set(xcbinf->mul, 1);
298 xcbinf->mul_r = xcbinf->mul_g = xcbinf->mul_b = xcbinf->mul_a = 0xff;
299 _xr_render_surface_solid_rectangle_set(xcbinf->mul, xcbinf->mul_r, xcbinf->mul_g, xcbinf->mul_b, xcbinf->mul_a, 0, 0, 1, 1);
302 xcbinf->can_do_shm = xcbinf2->can_do_shm;
303 xcbinf->depth = xcbinf2->depth;
307 xcb_shm_segment_info_t shm_info;
313 xcb_screen_iterator_t iter_screen;
315 rep = (xcb_setup_t *)xcb_get_setup(xcbinf->conn);
316 iter_screen = xcb_setup_roots_iterator(rep);
317 for (; iter_screen.rem ; xcb_screen_next (&iter_screen)) {
318 xcb_depth_iterator_t iter_depth;
320 iter_depth = xcb_screen_allowed_depths_iterator (iter_screen.data);
321 for (; iter_depth.rem ; xcb_depth_next (&iter_depth)) {
322 xcb_visualtype_iterator_t iter_visual;
324 iter_visual = xcb_depth_visuals_iterator (iter_depth.data);
325 for (; iter_visual.rem ; xcb_visualtype_next (&iter_visual)) {
326 if (iter_visual.data->visual_id == vis)
327 xcbinf->depth = iter_depth.data->depth;
333 xcbinf->can_do_shm = 0;
336 shm_info.shmseg = xcb_generate_id(xcbinf->conn);
337 xcbim = xcb_image_shm_create(xcbinf->conn, xcbinf->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, NULL, 1, 1);
339 shm_info.shmid = shmget(IPC_PRIVATE, xcbim->bytes_per_line * xcbim->height, IPC_CREAT | 0777);
340 if (shm_info.shmid >= 0) {
341 shm_info.shmaddr = xcbim->data = shmat(shm_info.shmid, 0, 0);
342 if ((shm_info.shmaddr != NULL) && (shm_info.shmaddr != (void *) -1)) {
343 xcb_get_input_focus_reply_t *reply;
345 * FIXME: no error mechanism
347 /* XErrorHandler ph; */
350 reply = xcb_get_input_focus_reply(xcbinf->conn,
351 xcb_get_input_focus_unchecked(xcbinf->conn),
355 /* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
356 xcb_shm_attach(xcbinf->conn, shm_info.shmseg, shm_info.shmid, 0);
358 reply = xcb_get_input_focus_reply(xcbinf->conn,
359 xcb_get_input_focus_unchecked(xcbinf->conn),
362 /* XSetErrorHandler((XErrorHandler)ph); */
363 if (!_xcb_err) xcbinf->can_do_shm = 1;
364 shmdt(shm_info.shmaddr);
366 shmctl(shm_info.shmid, IPC_RMID, 0);
368 xcb_image_shm_destroy(xcbim);
371 _image_info_list = evas_list_prepend(_image_info_list, xcbinf);
376 _xr_image_info_free(Xcb_Image_Info *xcbinf)
381 xcb_get_input_focus_reply_t *reply;
383 reply = xcb_get_input_focus_reply(xcbinf->conn,
384 xcb_get_input_focus_unchecked(xcbinf->conn),
388 _xr_image_info_pool_flush(xcbinf, 0, 0);
389 xcbinf->references--;
390 if (xcbinf->references != 0) return;
391 _xr_render_surface_free(xcbinf->mul);
403 _image_info_list = evas_list_remove(_image_info_list, xcbinf);
407 _xr_image_info_pool_flush(Xcb_Image_Info *xcbinf, int max_num, int max_mem)
409 if ((xcbinf->pool_mem <= max_mem) && (evas_list_count(xcbinf->pool) <= max_num)) return;
410 while ((xcbinf->pool_mem > max_mem) || (evas_list_count(xcbinf->pool) > max_num))
412 Xcb_Image_Image *xcbim;
414 if (!xcbinf->pool) break;
415 xcbim = xcbinf->pool->data;
416 _xr_image_free(xcbim);
421 _xr_image_new(Xcb_Image_Info *xcbinf, int w, int h, int depth)
423 Xcb_Image_Image *xcbim, *xcbim2;
427 for (l = xcbinf->pool; l; l = l->next)
430 if ((xcbim->w >= w) && (xcbim->h >= h) && (xcbim->depth == depth) && (xcbim->available))
432 if (!xcbim2) xcbim2 = xcbim;
433 else if ((xcbim->w * xcbim->h) < (xcbim2->w * xcbim2->h)) xcbim2 = xcbim;
438 xcbim2->available = 0;
441 xcbim = calloc(1, sizeof(Xcb_Image_Image));
444 xcbim->xcbinf = xcbinf;
447 xcbim->depth = depth;
448 xcbim->available = 0;
449 if (xcbim->xcbinf->can_do_shm)
451 xcbim->shm_info = calloc(1, sizeof(xcb_shm_segment_info_t));
454 xcbim->shm_info->shmseg = xcb_generate_id(xcbinf->conn);
455 xcbim->xcbim = xcb_image_shm_create(xcbim->xcbinf->conn, xcbim->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, NULL, xcbim->w, xcbim->h);
458 xcbim->shm_info->shmid = shmget(IPC_PRIVATE, xcbim->xcbim->bytes_per_line * xcbim->xcbim->height, IPC_CREAT | 0777);
459 if (xcbim->shm_info->shmid >= 0)
461 xcbim->shm_info->shmaddr = xcbim->xcbim->data = shmat(xcbim->shm_info->shmid, 0, 0);
462 if ((xcbim->shm_info->shmaddr) && (xcbim->shm_info->shmaddr != (void *) -1))
464 xcb_get_input_focus_reply_t *reply;
466 * FIXME: no error mechanism
468 /* XErrorHandler ph; */
471 reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
472 xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
476 /* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
477 xcb_shm_attach(xcbim->xcbinf->conn, xcbim->shm_info->shmseg, xcbim->shm_info->shmid, 0);
479 reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
480 xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
483 /* XSetErrorHandler((XErrorHandler)ph); */
484 if (!_xcb_err) goto xcbim_ok;
485 shmdt(xcbim->shm_info->shmaddr);
487 shmctl(xcbim->shm_info->shmid, IPC_RMID, 0);
489 xcb_image_shm_destroy(xcbim->xcbim);
491 free(xcbim->shm_info);
492 xcbim->shm_info = NULL;
495 xcbim->xcbim = xcb_image_create(xcbim->xcbinf->conn, xcbim->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, 0, NULL, xcbim->w, xcbim->h, 32, 0);
501 xcbim->xcbim->data = malloc(xcbim->xcbim->bytes_per_line * xcbim->xcbim->height);
502 if (!xcbim->xcbim->data)
504 xcb_image_destroy(xcbim->xcbim);
511 _xr_image_info_pool_flush(xcbinf, 32, (1600 * 1200 * 32 * 2));
513 xcbim->line_bytes = xcbim->xcbim->bytes_per_line;
514 xcbim->data = (void *)(xcbim->xcbim->data);
515 xcbinf->pool_mem += (xcbim->w * xcbim->h * xcbim->depth);
516 xcbinf->pool = evas_list_append(xcbinf->pool, xcbim);
521 _xr_image_free(Xcb_Image_Image *xcbim)
525 if (!xcbim->available)
527 xcb_get_input_focus_reply_t *reply;
529 reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
530 xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
534 xcb_shm_detach(xcbim->xcbinf->conn, xcbim->shm_info->shmseg);
535 xcb_image_shm_destroy(xcbim->xcbim);
536 shmdt(xcbim->shm_info->shmaddr);
537 shmctl(xcbim->shm_info->shmid, IPC_RMID, 0);
538 free(xcbim->shm_info);
542 free(xcbim->xcbim->data);
543 xcbim->xcbim->data = NULL;
544 xcb_image_destroy(xcbim->xcbim);
546 xcbim->xcbinf->pool_mem -= (xcbim->w * xcbim->h * xcbim->depth);
547 xcbim->xcbinf->pool = evas_list_remove(xcbim->xcbinf->pool, xcbim);
552 _xr_image_put(Xcb_Image_Image *xcbim, xcb_drawable_t draw, int x, int y, int w, int h)
554 xcb_get_input_focus_reply_t *reply;
557 gc = xcb_generate_id(xcbim->xcbinf->conn);
558 xcb_create_gc(xcbim->xcbinf->conn, gc, draw, 0, NULL);
561 xcb_shm_put_image(xcbim->xcbinf->conn, draw, gc,
562 xcbim->xcbim->width, xcbim->xcbim->height,
566 xcbim->xcbim->depth, xcbim->xcbim->format,
568 xcbim->shm_info->shmseg,
569 xcbim->xcbim->data - xcbim->shm_info->shmaddr);
571 reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
572 xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
577 xcb_image_put(xcbim->xcbinf->conn, draw, gc, xcbim->xcbim, 0, 0, x, y, w, h);
578 xcbim->available = 1;
579 xcb_free_gc(xcbim->xcbinf->conn, gc);