3 #endif /* ifdef HAVE_CONFIG_H */
5 #include "ecore_x_private.h"
8 #include <X11/extensions/XShm.h>
14 static int _ecore_x_image_shm_can = -1;
15 static int _ecore_x_image_err = 0;
18 _ecore_x_image_error_handler(Display *d __UNUSED__, XErrorEvent *ev __UNUSED__)
20 _ecore_x_image_err = 1;
22 } /* _ecore_x_image_error_handler */
25 _ecore_x_image_shm_check(void)
28 XShmSegmentInfo shminfo;
31 if (_ecore_x_image_shm_can != -1)
34 XSync(_ecore_x_disp, False);
35 _ecore_x_image_err = 0;
37 xim = XShmCreateImage(_ecore_x_disp,
38 DefaultVisual(_ecore_x_disp,
39 DefaultScreen(_ecore_x_disp)),
40 DefaultDepth(_ecore_x_disp,
41 DefaultScreen(_ecore_x_disp)),
46 _ecore_x_image_shm_can = 0;
50 shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
52 if (shminfo.shmid == -1)
55 _ecore_x_image_shm_can = 0;
59 shminfo.readOnly = False;
60 shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
61 xim->data = shminfo.shmaddr;
63 if (xim->data == (char *)-1)
66 _ecore_x_image_shm_can = 0;
70 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
71 XShmAttach(_ecore_x_disp, &shminfo);
72 XShmGetImage(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp),
73 xim, 0, 0, 0xffffffff);
74 XSync(_ecore_x_disp, False);
75 XSetErrorHandler((XErrorHandler)ph);
76 if (_ecore_x_image_err)
78 XShmDetach(_ecore_x_disp, &shminfo);
80 shmdt(shminfo.shmaddr);
81 shmctl(shminfo.shmid, IPC_RMID, 0);
82 _ecore_x_image_shm_can = 0;
86 XShmDetach(_ecore_x_disp, &shminfo);
88 shmdt(shminfo.shmaddr);
89 shmctl(shminfo.shmid, IPC_RMID, 0);
91 _ecore_x_image_shm_can = 1;
92 } /* _ecore_x_image_shm_check */
96 XShmSegmentInfo shminfo;
107 ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth)
111 im = calloc(1, sizeof(Ecore_X_Image));
115 LOGFN(__FILE__, __LINE__, __FUNCTION__);
120 _ecore_x_image_shm_check();
121 im->shm = _ecore_x_image_shm_can;
123 } /* ecore_x_image_new */
126 ecore_x_image_free(Ecore_X_Image *im)
128 LOGFN(__FILE__, __LINE__, __FUNCTION__);
133 XShmDetach(_ecore_x_disp, &(im->shminfo));
134 XDestroyImage(im->xim);
135 shmdt(im->shminfo.shmaddr);
136 shmctl(im->shminfo.shmid, IPC_RMID, 0);
142 im->xim->data = NULL;
143 XDestroyImage(im->xim);
147 } /* ecore_x_image_free */
150 _ecore_x_image_shm_create(Ecore_X_Image *im)
152 im->xim = XShmCreateImage(_ecore_x_disp, im->vis, im->depth,
153 ZPixmap, NULL, &(im->shminfo),
158 im->shminfo.shmid = shmget(IPC_PRIVATE,
159 im->xim->bytes_per_line * im->xim->height,
161 if (im->shminfo.shmid == -1)
163 XDestroyImage(im->xim);
167 im->shminfo.readOnly = False;
168 im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
169 im->xim->data = im->shminfo.shmaddr;
170 if ((im->xim->data == (char *)-1) ||
173 shmdt(im->shminfo.shmaddr);
174 shmctl(im->shminfo.shmid, IPC_RMID, 0);
175 XDestroyImage(im->xim);
179 XShmAttach(_ecore_x_disp, &im->shminfo);
181 im->data = (unsigned char *)im->xim->data;
183 im->bpl = im->xim->bytes_per_line;
184 im->rows = im->xim->height;
185 if (im->xim->bits_per_pixel <= 8)
187 else if (im->xim->bits_per_pixel <= 16)
191 } /* _ecore_x_image_shm_create */
194 ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw,
195 int x, int y, int sx, int sy, int w, int h)
197 Eina_Bool ret = EINA_TRUE;
200 LOGFN(__FILE__, __LINE__, __FUNCTION__);
204 _ecore_x_image_shm_create(im);
209 _ecore_x_image_err = 0;
211 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
212 if ((sx == 0) && (w == im->w))
214 im->xim->data = (char *)
215 im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
218 XGrabServer(_ecore_x_disp);
219 if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
221 XUngrabServer(_ecore_x_disp);
224 // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
228 unsigned char *spixels, *sp, *pixels, *p;
229 int bpp, bpl, rows, sbpp, sbpl, srows;
232 tim = ecore_x_image_new(w, h, im->vis, im->depth);
235 ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
238 spixels = ecore_x_image_data_get(tim,
242 pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
243 if ((pixels) && (spixels))
245 p = pixels + (sy * bpl) + (sx * bpp);
247 for (r = srows; r > 0; r--)
256 ecore_x_image_free(tim);
260 XSetErrorHandler((XErrorHandler)ph);
261 if (_ecore_x_image_err)
266 printf("currently unimplemented ecore_x_image_get without shm\n");
271 } /* ecore_x_image_get */
274 ecore_x_image_put(Ecore_X_Image *im,
275 Ecore_X_Drawable draw,
286 LOGFN(__FILE__, __LINE__, __FUNCTION__);
290 memset(&gcv, 0, sizeof(gcv));
291 gcv.subwindow_mode = IncludeInferiors;
292 tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv);
295 if (!im->xim) _ecore_x_image_shm_create(im);
297 XShmPutImage(_ecore_x_disp, draw, gc, im->xim, sx, sy, x, y, w, h, False);
298 if (tgc) ecore_x_gc_free(tgc);
299 } /* ecore_x_image_put */
302 ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp)
304 LOGFN(__FILE__, __LINE__, __FUNCTION__);
305 if (!im->xim) _ecore_x_image_shm_create(im);
306 if (!im->xim) return NULL;
307 if (bpl) *bpl = im->bpl;
308 if (rows) *rows = im->rows;
309 if (bpp) *bpp = im->bpp;
311 } /* ecore_x_image_data_get */
314 ecore_x_image_is_argb32_get(Ecore_X_Image *im)
316 Visual *vis = im->vis;
317 if (!im->xim) _ecore_x_image_shm_create(im);
318 if (((vis->class == TrueColor) ||
319 (vis->class == DirectColor)) &&
321 (vis->red_mask == 0xff0000) &&
322 (vis->green_mask == 0x00ff00) &&
323 (vis->blue_mask == 0x0000ff))
325 #ifdef WORDS_BIGENDIAN
326 if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE;
328 if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE;
335 ecore_x_image_to_argb_convert(void *src, int sbpp,
339 int x, int y, int w, int h,
346 int n = 0, nret = 0, i, row;
347 unsigned int pal[256], r, g, b;
364 n = vis->map_entries;
366 ((vis->class == PseudoColor) ||
367 (vis->class == StaticColor) ||
368 (vis->class == GrayScale) ||
369 (vis->class == StaticGray)))
371 if (!c) c = DefaultColormap(_ecore_x_disp,
372 DefaultScreen(_ecore_x_disp));
373 cols = alloca(n * sizeof(XColor));
374 for (i = 0; i < n; i++)
377 cols[i].flags = DoRed | DoGreen | DoBlue;
382 XQueryColors(_ecore_x_disp, c, cols, n);
383 for (i = 0; i < n; i++)
385 pal[i] = 0xff000000 |
386 ((cols[i].red >> 8) << 16) |
387 ((cols[i].green >> 8) << 8 ) |
388 ((cols[i].blue >> 8) );
392 else if ((vis->class == TrueColor) ||
393 (vis->class == DirectColor))
395 if ((vis->red_mask == 0x00ff0000) &&
396 (vis->green_mask == 0x0000ff00) &&
397 (vis->blue_mask == 0x000000ff))
399 else if ((vis->red_mask == 0x000000ff) &&
400 (vis->green_mask == 0x0000ff00) &&
401 (vis->blue_mask == 0x00ff0000))
403 else if ((vis->red_mask == 0xff000000) &&
404 (vis->green_mask == 0x00ff0000) &&
405 (vis->blue_mask == 0x0000ff00))
407 else if ((vis->red_mask == 0x0000ff00) &&
408 (vis->green_mask == 0x00ff0000) &&
409 (vis->blue_mask == 0xff000000))
411 else if ((vis->red_mask == 0x0003f000) &&
412 (vis->green_mask == 0x00000fc0) &&
413 (vis->blue_mask == 0x0000003f))
415 else if ((vis->red_mask == 0x0000f800) &&
416 (vis->green_mask == 0x000007e0) &&
417 (vis->blue_mask == 0x0000001f))
419 else if ((vis->red_mask == 0x0000001f) &&
420 (vis->green_mask == 0x000007e0) &&
421 (vis->blue_mask == 0x0000f800))
423 else if ((vis->red_mask == 0x00007c00) &&
424 (vis->green_mask == 0x000003e0) &&
425 (vis->blue_mask == 0x0000001f))
430 for (row = 0; row < h; row++)
435 unsigned int *dp, *de;
437 dp = ((unsigned int *)(((unsigned char *)dst) +
438 ((dy + row) * dbpl))) + dx;
443 s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
456 s16 = ((unsigned short *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
462 r = (*s16 & 0xf800) << 8;
463 g = (*s16 & 0x07e0) << 5;
464 b = (*s16 & 0x001f) << 3;
465 r |= (r >> 5) & 0xff0000;
466 g |= (g >> 6) & 0x00ff00;
468 *dp = 0xff000000 | r | g | b;
475 r = (*s16 & 0x001f) << 19;
476 g = (*s16 & 0x07e0) << 5;
477 b = (*s16 & 0xf800) >> 8;
478 r |= (r >> 5) & 0xff0000;
479 g |= (g >> 6) & 0x00ff00;
481 *dp = 0xff000000 | r | g | b;
488 r = (*s16 & 0x7c00) << 9;
489 g = (*s16 & 0x03e0) << 6;
490 b = (*s16 & 0x001f) << 3;
491 r |= (r >> 5) & 0xff0000;
492 g |= (g >> 5) & 0x00ff00;
494 *dp = 0xff000000 | r | g | b;
505 s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
511 *dp = 0xff000000 | *s32;
518 r = *s32 & 0x000000ff;
519 g = *s32 & 0x0000ff00;
520 b = *s32 & 0x00ff0000;
521 *dp = 0xff000000 | (r << 16) | (g) | (b >> 16);
528 *dp = 0xff000000 | (*s32 >> 8);
535 r = *s32 & 0x0000ff00;
536 g = *s32 & 0x00ff0000;
537 b = *s32 & 0xff000000;
538 *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24);
545 r = (*s32 & 0x3f000) << 6;
546 g = (*s32 & 0x00fc0) << 4;
547 b = (*s32 & 0x0003f) << 2;
548 r |= (r >> 6) & 0xff0000;
549 g |= (g >> 6) & 0x00ff00;
551 *dp = 0xff000000 | r | g | b;