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) +
99 im->xim->width = MIN(w, im->w);
100 im->xim->height = MIN(h, im->h);
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;
249 if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
250 (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) &&
252 (vis->red_mask == 0xff0000) &&
253 (vis->green_mask == 0x00ff00) &&
254 (vis->blue_mask == 0x0000ff))
256 const xcb_setup_t *setup = xcb_get_setup(_ecore_xcb_conn);
258 if (!setup) return EINA_FALSE;
259 #ifdef WORDS_BIGENDIAN
260 if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST) return EINA_TRUE;
262 if (setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST) return EINA_TRUE;
270 ecore_x_image_to_argb_convert(void *src,
284 xcb_visualtype_t *vis;
286 int n = 0, nret = 0, i, row, mode = 0;
287 unsigned int pal[256], r, g, b;
303 LOGFN(__FILE__, __LINE__, __FUNCTION__);
308 vis = (xcb_visualtype_t *)v;
309 n = vis->colormap_entries;
311 ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) ||
312 (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) ||
313 (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) ||
314 (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY)))
316 xcb_query_colors_cookie_t cookie;
317 xcb_query_colors_reply_t *reply;
321 c = (xcb_colormap_t)((xcb_screen_t *)
322 _ecore_xcb_screen)->default_colormap;
325 cols = alloca(n * sizeof(uint32_t));
326 for (i = 0; i < n; i++)
329 cookie = xcb_query_colors_unchecked(_ecore_xcb_conn, c, n, cols);
330 reply = xcb_query_colors_reply(_ecore_xcb_conn, cookie, NULL);
333 xcb_rgb_iterator_t iter;
336 iter = xcb_query_colors_colors_iterator(reply);
337 ret = xcb_query_colors_colors(reply);
340 for (i = 0; iter.rem; xcb_rgb_next(&iter), i++)
342 pal[i] = 0xff000000 |
343 ((iter.data->red >> 8) << 16) |
344 ((iter.data->green >> 8) << 8) |
345 ((iter.data->blue >> 8));
352 else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
353 (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR))
357 if ((vis->red_mask == 0x00ff0000) &&
358 (vis->green_mask == 0x0000ff00) &&
359 (vis->blue_mask == 0x000000ff))
361 else if ((vis->red_mask == 0x000000ff) &&
362 (vis->green_mask == 0x0000ff00) &&
363 (vis->blue_mask == 0x00ff0000))
370 if ((vis->red_mask == 0x00ff0000) &&
371 (vis->green_mask == 0x0000ff00) &&
372 (vis->blue_mask == 0x000000ff))
374 else if ((vis->red_mask == 0x000000ff) &&
375 (vis->green_mask == 0x0000ff00) &&
376 (vis->blue_mask == 0x00ff0000))
378 else if ((vis->red_mask == 0xff000000) &&
379 (vis->green_mask == 0x00ff0000) &&
380 (vis->blue_mask == 0x0000ff00))
382 else if ((vis->red_mask == 0x0000ff00) &&
383 (vis->green_mask == 0x00ff0000) &&
384 (vis->blue_mask == 0xff000000))
386 else if ((vis->red_mask == 0x0003f000) &&
387 (vis->green_mask == 0x00000fc0) &&
388 (vis->blue_mask == 0x0000003f))
390 else if ((vis->red_mask == 0x0000f800) &&
391 (vis->green_mask == 0x000007e0) &&
392 (vis->blue_mask == 0x0000001f))
394 else if ((vis->red_mask == 0x0000001f) &&
395 (vis->green_mask == 0x000007e0) &&
396 (vis->blue_mask == 0x0000f800))
398 else if ((vis->red_mask == 0x00007c00) &&
399 (vis->green_mask == 0x000003e0) &&
400 (vis->blue_mask == 0x0000001f))
406 for (row = 0; row < h; row++)
410 unsigned int *s32, *dp, *de;
412 dp = ((unsigned int *)(((unsigned char *)dst) +
413 ((dy + row) * dbpl))) + dx;
418 s8 = ((unsigned char *)(((unsigned char *)src) +
419 ((y + row) * sbpl))) + x;
433 s16 = ((unsigned short *)(((unsigned char *)src) +
434 ((y + row) * sbpl))) + x;
440 r = (*s16 & 0xf800) << 8;
441 g = (*s16 & 0x07e0) << 5;
442 b = (*s16 & 0x001f) << 3;
443 r |= (r >> 5) & 0xff0000;
444 g |= (g >> 6) & 0x00ff00;
446 *dp = 0xff000000 | r | g | b;
454 r = (*s16 & 0x001f) << 19;
455 g = (*s16 & 0x07e0) << 5;
456 b = (*s16 & 0xf800) >> 8;
457 r |= (r >> 5) & 0xff0000;
458 g |= (g >> 6) & 0x00ff00;
460 *dp = 0xff000000 | r | g | b;
468 r = (*s16 & 0x7c00) << 9;
469 g = (*s16 & 0x03e0) << 6;
470 b = (*s16 & 0x001f) << 3;
471 r |= (r >> 5) & 0xff0000;
472 g |= (g >> 5) & 0x00ff00;
474 *dp = 0xff000000 | r | g | b;
486 s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8));
492 *dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0];
499 *dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2];
510 s32 = ((unsigned int *)(((unsigned char *)src) +
511 ((y + row) * sbpl))) + x;
517 *dp = 0xff000000 | *s32;
525 r = *s32 & 0x000000ff;
526 g = *s32 & 0x0000ff00;
527 b = *s32 & 0x00ff0000;
528 *dp = 0xff000000 | (r << 16) | (g) | (b >> 16);
536 *dp = 0xff000000 | (*s32 >> 8);
544 r = *s32 & 0x0000ff00;
545 g = *s32 & 0x00ff0000;
546 b = *s32 & 0xff000000;
547 *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24);
555 r = (*s32 & 0x3f000) << 6;
556 g = (*s32 & 0x00fc0) << 4;
557 b = (*s32 & 0x0003f) << 2;
558 r |= (r >> 6) & 0xff0000;
559 g |= (g >> 6) & 0x00ff00;
561 *dp = 0xff000000 | r | g | b;
580 /* local functions */
582 _ecore_xcb_image_shm_check(void)
584 // xcb_shm_query_version_reply_t *reply;
585 xcb_shm_segment_info_t shminfo;
586 xcb_shm_get_image_cookie_t cookie;
587 xcb_shm_get_image_reply_t *ireply;
588 xcb_image_t *img = 0;
591 if (_ecore_xcb_image_shm_can != -1) return;
595 /* xcb_shm_query_version_reply(_ecore_xcb_conn, */
596 /* xcb_shm_query_version(_ecore_xcb_conn), NULL); */
599 /* _ecore_xcb_image_shm_can = 0; */
603 /* if ((reply->major_version < 1) || */
604 /* ((reply->major_version == 1) && (reply->minor_version == 0))) */
606 /* _ecore_xcb_image_shm_can = 0; */
613 depth = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth;
615 ecore_x_sync(); // needed
617 img = _ecore_xcb_image_create_native(1, 1, XCB_IMAGE_FORMAT_Z_PIXMAP,
618 depth, NULL, ~0, NULL);
621 _ecore_xcb_image_shm_can = 0;
626 shmget(IPC_PRIVATE, img->stride * img->height, (IPC_CREAT | 0600));
627 if (shminfo.shmid == (uint32_t)-1)
629 xcb_image_destroy(img);
630 _ecore_xcb_image_shm_can = 0;
634 shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
635 img->data = shminfo.shmaddr;
636 if (img->data == (uint8_t *)-1)
638 xcb_image_destroy(img);
639 _ecore_xcb_image_shm_can = 0;
643 shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn);
644 xcb_shm_attach(_ecore_xcb_conn, shminfo.shmseg, shminfo.shmid, 0);
647 xcb_shm_get_image(_ecore_xcb_conn,
648 ((xcb_screen_t *)_ecore_xcb_screen)->root,
649 0, 0, img->width, img->height,
650 0xffffffff, img->format,
651 shminfo.shmseg, img->data - shminfo.shmaddr);
653 ecore_x_sync(); // needed
655 ireply = xcb_shm_get_image_reply(_ecore_xcb_conn, cookie, NULL);
658 _ecore_xcb_image_shm_can = 1;
662 _ecore_xcb_image_shm_can = 0;
664 xcb_shm_detach(_ecore_xcb_conn, shminfo.shmseg);
665 xcb_image_destroy(img);
666 shmdt(shminfo.shmaddr);
667 shmctl(shminfo.shmid, IPC_RMID, 0);
671 _ecore_xcb_image_shm_create(Ecore_X_Image *im)
676 _ecore_xcb_image_create_native(im->w, im->h, XCB_IMAGE_FORMAT_Z_PIXMAP,
677 im->depth, NULL, ~0, NULL);
678 if (!im->xim) return;
680 im->shminfo.shmid = shmget(IPC_PRIVATE, im->xim->size, (IPC_CREAT | 0600));
681 if (im->shminfo.shmid == (uint32_t)-1)
683 xcb_image_destroy(im->xim);
687 im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
688 im->xim->data = im->shminfo.shmaddr;
689 if ((!im->xim->data) || (im->xim->data == (uint8_t *)-1))
691 DBG("Shm Create No Image Data");
692 xcb_image_destroy(im->xim);
693 shmdt(im->shminfo.shmaddr);
694 shmctl(im->shminfo.shmid, IPC_RMID, 0);
698 im->shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn);
699 xcb_shm_attach(_ecore_xcb_conn, im->shminfo.shmseg, im->shminfo.shmid, 0);
701 im->data = (unsigned char *)im->xim->data;
702 im->bpl = im->xim->stride;
703 im->rows = im->xim->height;
704 if (im->xim->bpp <= 8)
706 else if (im->xim->bpp <= 16)
713 _ecore_xcb_image_create_native(int w,
715 xcb_image_format_t format,
721 static uint8_t dpth = 0;
722 static xcb_format_t *fmt = NULL;
723 const xcb_setup_t *setup;
724 xcb_image_format_t xif;
728 /* NB: We cannot use xcb_image_create_native as it only creates images
729 * using MSB_FIRST, so this routine recreates that function and uses
730 * the endian-ness of the server setup */
731 setup = xcb_get_setup(_ecore_xcb_conn);
734 if ((xif == XCB_IMAGE_FORMAT_Z_PIXMAP) && (depth == 1))
735 xif = XCB_IMAGE_FORMAT_XY_PIXMAP;
740 fmt = _ecore_xcb_image_find_format(setup, depth);
746 case XCB_IMAGE_FORMAT_XY_BITMAP:
747 if (depth != 1) return 0;
749 case XCB_IMAGE_FORMAT_XY_PIXMAP:
750 case XCB_IMAGE_FORMAT_Z_PIXMAP:
751 return xcb_image_create(w, h, xif,
753 fmt->depth, fmt->bits_per_pixel,
754 setup->bitmap_format_scanline_unit,
755 setup->image_byte_order,
756 setup->bitmap_format_bit_order,
766 static xcb_format_t *
767 _ecore_xcb_image_find_format(const xcb_setup_t *setup,
770 xcb_format_t *fmt, *fmtend;
774 fmt = xcb_setup_pixmap_formats(setup);
775 fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
776 for (; fmt != fmtend; ++fmt)
777 if (fmt->depth == depth)