1 #include "ecore_xcb_private.h"
4 #include <xcb/xcb_event.h>
9 xcb_shm_segment_info_t shminfo;
18 /* local function prototypes */
19 static void _ecore_xcb_image_shm_check(void);
20 static void _ecore_xcb_image_shm_create(Ecore_X_Image *im);
21 static xcb_format_t *_ecore_xcb_image_find_format(const xcb_setup_t *setup,
25 static int _ecore_xcb_image_shm_can = -1;
28 ecore_x_image_new(int w,
35 LOGFN(__FILE__, __LINE__, __FUNCTION__);
37 if (!(im = calloc(1, sizeof(Ecore_X_Image)))) return NULL;
42 _ecore_xcb_image_shm_check();
43 im->shm = _ecore_xcb_image_shm_can;
48 ecore_x_image_free(Ecore_X_Image *im)
50 LOGFN(__FILE__, __LINE__, __FUNCTION__);
58 xcb_shm_detach(_ecore_xcb_conn, im->shminfo.shmseg);
59 xcb_image_destroy(im->xim);
60 shmdt(im->shminfo.shmaddr);
61 shmctl(im->shminfo.shmid, IPC_RMID, 0);
66 if (im->xim->data) free(im->xim->data);
68 xcb_image_destroy(im->xim);
76 ecore_x_image_get(Ecore_X_Image *im,
77 Ecore_X_Drawable draw,
85 Eina_Bool ret = EINA_TRUE;
87 LOGFN(__FILE__, __LINE__, __FUNCTION__);
92 if (!im->xim) _ecore_xcb_image_shm_create(im);
93 if (!im->xim) return EINA_FALSE;
95 if ((sx == 0) && (w == im->w))
97 im->xim->data = (uint8_t *)im->data + (im->xim->stride * sy) +
103 if (!xcb_image_shm_get(_ecore_xcb_conn, draw, im->xim,
104 im->shminfo, x, y, 0xffffffff))
106 DBG("\tImage Shm Get Failed");
110 ecore_x_sync(); // needed
116 tim = ecore_x_image_new(w, h, im->vis, im->depth);
119 ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
122 unsigned char *spixels, *pixels;
123 int sbpp = 0, sbpl = 0, srows = 0;
124 int bpp = 0, bpl = 0, rows = 0;
127 ecore_x_image_data_get(tim, &sbpl, &srows, &sbpp);
128 pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
129 if ((spixels) && (pixels))
131 unsigned char *p, *sp;
134 p = (pixels + (sy * bpl) + (sx * bpp));
136 for (r = srows; r > 0; r--)
144 ecore_x_image_free(tim);
153 xcb_image_get(_ecore_xcb_conn, draw, x, y, w, h,
154 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
155 if (!im->xim) ret = EINA_FALSE;
157 ecore_x_sync(); // needed
161 im->data = (unsigned char *)im->xim->data;
162 im->bpl = im->xim->stride;
163 im->rows = im->xim->height;
164 if (im->xim->bpp <= 8)
166 else if (im->xim->bpp <= 16)
177 ecore_x_image_data_get(Ecore_X_Image *im,
182 LOGFN(__FILE__, __LINE__, __FUNCTION__);
184 if (!im) return NULL;
185 if (!im->xim) _ecore_xcb_image_shm_create(im);
186 if (!im->xim) return NULL;
188 if (bpl) *bpl = im->bpl;
189 if (rows) *rows = im->rows;
190 if (bpp) *bpp = im->bpp;
196 ecore_x_image_put(Ecore_X_Image *im,
197 Ecore_X_Drawable draw,
208 LOGFN(__FILE__, __LINE__, __FUNCTION__);
213 uint32_t mask, values[1];
215 tgc = xcb_generate_id(_ecore_xcb_conn);
216 mask = XCB_GC_SUBWINDOW_MODE;
217 values[0] = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS;
218 xcb_create_gc(_ecore_xcb_conn, tgc, draw, mask, values);
221 if (!im->xim) _ecore_xcb_image_shm_create(im);
225 xcb_shm_put_image(_ecore_xcb_conn, draw, gc, im->xim->width,
226 im->xim->height, sx, sy, w, h, x, y,
227 im->xim->depth, im->xim->format, 0,
229 im->xim->data - im->shminfo.shmaddr);
230 // xcb_image_shm_put(_ecore_xcb_conn, draw, gc, im->xim,
231 // im->shminfo, sx, sy, x, y, w, h, 0);
233 xcb_image_put(_ecore_xcb_conn, draw, gc, im->xim, sx, sy, 0);
235 if (tgc) ecore_x_gc_free(tgc);
240 ecore_x_image_is_argb32_get(Ecore_X_Image *im)
242 xcb_visualtype_t *vis;
244 LOGFN(__FILE__, __LINE__, __FUNCTION__);
247 vis = (xcb_visualtype_t *)im->vis;
248 if (!im->xim) _ecore_xcb_image_shm_create(im);
250 if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
251 (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) &&
252 (im->depth >= 24) && (vis->red_mask == 0xff0000) &&
253 (vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff))
255 #ifdef WORDS_BIGENDIAN
256 if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) return EINA_TRUE;
258 if (im->xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST) return EINA_TRUE;
266 ecore_x_image_to_argb_convert(void *src,
280 xcb_visualtype_t *vis;
282 int n = 0, nret = 0, i, row, mode = 0;
283 unsigned int pal[256], r, g, b;
297 LOGFN(__FILE__, __LINE__, __FUNCTION__);
302 vis = (xcb_visualtype_t *)v;
303 n = vis->colormap_entries;
305 ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) ||
306 (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) ||
307 (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) ||
308 (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY)))
310 xcb_query_colors_cookie_t cookie;
311 xcb_query_colors_reply_t *reply;
315 c = (xcb_colormap_t)((xcb_screen_t *)
316 _ecore_xcb_screen)->default_colormap;
319 cols = alloca(n * sizeof(uint32_t));
320 for (i = 0; i < n; i++)
323 cookie = xcb_query_colors_unchecked(_ecore_xcb_conn, c, n, cols);
324 reply = xcb_query_colors_reply(_ecore_xcb_conn, cookie, NULL);
327 xcb_rgb_iterator_t iter;
330 iter = xcb_query_colors_colors_iterator(reply);
331 ret = xcb_query_colors_colors(reply);
334 for (i = 0; iter.rem; xcb_rgb_next(&iter), i++)
336 pal[i] = 0xff000000 |
337 ((iter.data->red >> 8) << 16) |
338 ((iter.data->green >> 8) << 8) |
339 ((iter.data->blue >> 8));
346 else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
347 (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR))
349 if ((vis->red_mask == 0x00ff0000) &&
350 (vis->green_mask == 0x0000ff00) &&
351 (vis->blue_mask == 0x000000ff))
353 else if ((vis->red_mask == 0x000000ff) &&
354 (vis->green_mask == 0x0000ff00) &&
355 (vis->blue_mask == 0x00ff0000))
357 else if ((vis->red_mask == 0xff000000) &&
358 (vis->green_mask == 0x00ff0000) &&
359 (vis->blue_mask == 0x0000ff00))
361 else if ((vis->red_mask == 0x0000ff00) &&
362 (vis->green_mask == 0x00ff0000) &&
363 (vis->blue_mask == 0xff000000))
365 else if ((vis->red_mask == 0x0003f000) &&
366 (vis->green_mask == 0x00000fc0) &&
367 (vis->blue_mask == 0x0000003f))
369 else if ((vis->red_mask == 0x0000f800) &&
370 (vis->green_mask == 0x000007e0) &&
371 (vis->blue_mask == 0x0000001f))
373 else if ((vis->red_mask == 0x0000001f) &&
374 (vis->green_mask == 0x000007e0) &&
375 (vis->blue_mask == 0x0000f800))
377 else if ((vis->red_mask == 0x00007c00) &&
378 (vis->green_mask == 0x000003e0) &&
379 (vis->blue_mask == 0x0000001f))
384 for (row = 0; row < h; row++)
388 unsigned int *s32, *dp, *de;
390 dp = ((unsigned int *)(((unsigned char *)dst) +
391 ((dy + row) * dbpl))) + dx;
396 s8 = ((unsigned char *)(((unsigned char *)src) +
397 ((y + row) * sbpl))) + x;
411 s16 = ((unsigned short *)(((unsigned char *)src) +
412 ((y + row) * sbpl))) + x;
418 r = (*s16 & 0xf800) << 8;
419 g = (*s16 & 0x07e0) << 5;
420 b = (*s16 & 0x001f) << 3;
421 r |= (r >> 5) & 0xff0000;
422 g |= (g >> 6) & 0x00ff00;
424 *dp = 0xff000000 | r | g | b;
432 r = (*s16 & 0x001f) << 19;
433 g = (*s16 & 0x07e0) << 5;
434 b = (*s16 & 0xf800) >> 8;
435 r |= (r >> 5) & 0xff0000;
436 g |= (g >> 6) & 0x00ff00;
438 *dp = 0xff000000 | r | g | b;
446 r = (*s16 & 0x7c00) << 9;
447 g = (*s16 & 0x03e0) << 6;
448 b = (*s16 & 0x001f) << 3;
449 r |= (r >> 5) & 0xff0000;
450 g |= (g >> 5) & 0x00ff00;
452 *dp = 0xff000000 | r | g | b;
465 s32 = ((unsigned int *)(((unsigned char *)src) +
466 ((y + row) * sbpl))) + x;
472 *dp = 0xff000000 | *s32;
480 r = *s32 & 0x000000ff;
481 g = *s32 & 0x0000ff00;
482 b = *s32 & 0x00ff0000;
483 *dp = 0xff000000 | (r << 16) | (g) | (b >> 16);
491 *dp = 0xff000000 | (*s32 >> 8);
499 r = *s32 & 0x0000ff00;
500 g = *s32 & 0x00ff0000;
501 b = *s32 & 0xff000000;
502 *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24);
510 r = (*s32 & 0x3f000) << 6;
511 g = (*s32 & 0x00fc0) << 4;
512 b = (*s32 & 0x0003f) << 2;
513 r |= (r >> 6) & 0xff0000;
514 g |= (g >> 6) & 0x00ff00;
516 *dp = 0xff000000 | r | g | b;
536 /* local functions */
538 _ecore_xcb_image_shm_check(void)
540 // xcb_shm_query_version_reply_t *reply;
541 xcb_shm_segment_info_t shminfo;
542 xcb_shm_get_image_cookie_t cookie;
543 xcb_shm_get_image_reply_t *ireply;
544 xcb_image_t *img = 0;
547 if (_ecore_xcb_image_shm_can != -1) return;
551 /* xcb_shm_query_version_reply(_ecore_xcb_conn, */
552 /* xcb_shm_query_version(_ecore_xcb_conn), NULL); */
555 /* _ecore_xcb_image_shm_can = 0; */
559 /* if ((reply->major_version < 1) || */
560 /* ((reply->major_version == 1) && (reply->minor_version == 0))) */
562 /* _ecore_xcb_image_shm_can = 0; */
569 depth = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth;
571 ecore_x_sync(); // needed
573 img = _ecore_xcb_image_create_native(1, 1, XCB_IMAGE_FORMAT_Z_PIXMAP,
574 depth, NULL, ~0, NULL);
577 _ecore_xcb_image_shm_can = 0;
582 shmget(IPC_PRIVATE, img->stride * img->height, (IPC_CREAT | 0666));
583 if (shminfo.shmid == (uint32_t)-1)
585 xcb_image_destroy(img);
586 _ecore_xcb_image_shm_can = 0;
590 shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
591 img->data = shminfo.shmaddr;
592 if (img->data == (uint8_t *)-1)
594 xcb_image_destroy(img);
595 _ecore_xcb_image_shm_can = 0;
599 shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn);
600 xcb_shm_attach(_ecore_xcb_conn, shminfo.shmseg, shminfo.shmid, 0);
603 xcb_shm_get_image(_ecore_xcb_conn,
604 ((xcb_screen_t *)_ecore_xcb_screen)->root,
605 0, 0, img->width, img->height,
606 0xffffffff, img->format,
607 shminfo.shmseg, img->data - shminfo.shmaddr);
609 ecore_x_sync(); // needed
611 ireply = xcb_shm_get_image_reply(_ecore_xcb_conn, cookie, NULL);
614 _ecore_xcb_image_shm_can = 1;
618 _ecore_xcb_image_shm_can = 0;
620 xcb_shm_detach(_ecore_xcb_conn, shminfo.shmseg);
621 xcb_image_destroy(img);
622 shmdt(shminfo.shmaddr);
623 shmctl(shminfo.shmid, IPC_RMID, 0);
627 _ecore_xcb_image_shm_create(Ecore_X_Image *im)
632 _ecore_xcb_image_create_native(im->w, im->h, XCB_IMAGE_FORMAT_Z_PIXMAP,
633 im->depth, NULL, ~0, NULL);
634 if (!im->xim) return;
636 im->shminfo.shmid = shmget(IPC_PRIVATE, im->xim->size, (IPC_CREAT | 0666));
637 if (im->shminfo.shmid == (uint32_t)-1)
639 xcb_image_destroy(im->xim);
643 im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
644 im->xim->data = im->shminfo.shmaddr;
645 if ((!im->xim->data) || (im->xim->data == (uint8_t *)-1))
647 DBG("Shm Create No Image Data");
648 xcb_image_destroy(im->xim);
649 shmdt(im->shminfo.shmaddr);
650 shmctl(im->shminfo.shmid, IPC_RMID, 0);
654 im->shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn);
655 xcb_shm_attach(_ecore_xcb_conn, im->shminfo.shmseg, im->shminfo.shmid, 0);
657 im->data = (unsigned char *)im->xim->data;
658 im->bpl = im->xim->stride;
659 im->rows = im->xim->height;
660 if (im->xim->bpp <= 8)
662 else if (im->xim->bpp <= 16)
669 _ecore_xcb_image_create_native(int w,
671 xcb_image_format_t format,
677 static uint8_t dpth = 0;
678 static xcb_format_t *fmt = NULL;
679 const xcb_setup_t *setup;
680 xcb_image_format_t xif;
684 /* NB: We cannot use xcb_image_create_native as it only creates images
685 * using MSB_FIRST, so this routine recreates that function and uses
686 * the endian-ness of the server setup */
687 setup = xcb_get_setup(_ecore_xcb_conn);
690 if ((xif == XCB_IMAGE_FORMAT_Z_PIXMAP) && (depth == 1))
691 xif = XCB_IMAGE_FORMAT_XY_PIXMAP;
696 fmt = _ecore_xcb_image_find_format(setup, depth);
702 case XCB_IMAGE_FORMAT_XY_BITMAP:
703 if (depth != 1) return 0;
705 case XCB_IMAGE_FORMAT_XY_PIXMAP:
706 case XCB_IMAGE_FORMAT_Z_PIXMAP:
707 return xcb_image_create(w, h, xif,
709 fmt->depth, fmt->bits_per_pixel,
710 setup->bitmap_format_scanline_unit,
711 setup->image_byte_order,
712 setup->bitmap_format_bit_order,
722 static xcb_format_t *
723 _ecore_xcb_image_find_format(const xcb_setup_t *setup,
726 xcb_format_t *fmt, *fmtend;
730 fmt = xcb_setup_pixmap_formats(setup);
731 fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
732 for (; fmt != fmtend; ++fmt)
733 if (fmt->depth == depth)