aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xlib/ecore_x_image.c')
-rw-r--r--libraries/ecore/src/lib/ecore_x/xlib/ecore_x_image.c600
1 files changed, 0 insertions, 600 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_image.c b/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_image.c
deleted file mode 100644
index b8e720c..0000000
--- a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_image.c
+++ /dev/null
@@ -1,600 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdlib.h>
6#include <string.h>
7#include <sys/ipc.h>
8#include <sys/shm.h>
9
10#include "ecore_x_private.h"
11#include "Ecore_X.h"
12
13#include <X11/extensions/XShm.h>
14#include <X11/Xutil.h>
15
16static int _ecore_x_image_shm_can = -1;
17static int _ecore_x_image_err = 0;
18
19static int
20_ecore_x_image_error_handler(Display *d __UNUSED__,
21 XErrorEvent *ev __UNUSED__)
22{
23 _ecore_x_image_err = 1;
24 return 0;
25}
26
27static void
28_ecore_x_image_shm_check(void)
29{
30 XErrorHandler ph;
31 XShmSegmentInfo shminfo;
32 XImage *xim;
33
34 if (_ecore_x_image_shm_can != -1)
35 return;
36
37 XSync(_ecore_x_disp, False);
38 _ecore_x_image_err = 0;
39
40 xim = XShmCreateImage(_ecore_x_disp,
41 DefaultVisual(_ecore_x_disp,
42 DefaultScreen(_ecore_x_disp)),
43 DefaultDepth(_ecore_x_disp,
44 DefaultScreen(_ecore_x_disp)),
45 ZPixmap, NULL,
46 &shminfo, 1, 1);
47 if (!xim)
48 {
49 _ecore_x_image_shm_can = 0;
50 return;
51 }
52
53 shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
54 IPC_CREAT | 0666);
55 if (shminfo.shmid == -1)
56 {
57 XDestroyImage(xim);
58 _ecore_x_image_shm_can = 0;
59 return;
60 }
61
62 shminfo.readOnly = False;
63 shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
64 xim->data = shminfo.shmaddr;
65
66 if (xim->data == (char *)-1)
67 {
68 XDestroyImage(xim);
69 _ecore_x_image_shm_can = 0;
70 return;
71 }
72
73 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
74 XShmAttach(_ecore_x_disp, &shminfo);
75 XShmGetImage(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp),
76 xim, 0, 0, 0xffffffff);
77 XSync(_ecore_x_disp, False);
78 XSetErrorHandler((XErrorHandler)ph);
79 if (_ecore_x_image_err)
80 {
81 XShmDetach(_ecore_x_disp, &shminfo);
82 XDestroyImage(xim);
83 shmdt(shminfo.shmaddr);
84 shmctl(shminfo.shmid, IPC_RMID, 0);
85 _ecore_x_image_shm_can = 0;
86 return;
87 }
88
89 XShmDetach(_ecore_x_disp, &shminfo);
90 XDestroyImage(xim);
91 shmdt(shminfo.shmaddr);
92 shmctl(shminfo.shmid, IPC_RMID, 0);
93
94 _ecore_x_image_shm_can = 1;
95}
96
97struct _Ecore_X_Image
98{
99 XShmSegmentInfo shminfo;
100 Ecore_X_Visual vis;
101 XImage *xim;
102 int depth;
103 int w, h;
104 int bpl, bpp, rows;
105 unsigned char *data;
106 Eina_Bool shm : 1;
107};
108
109EAPI Ecore_X_Image *
110ecore_x_image_new(int w,
111 int h,
112 Ecore_X_Visual vis,
113 int depth)
114{
115 Ecore_X_Image *im;
116
117 im = calloc(1, sizeof(Ecore_X_Image));
118 if (!im)
119 return NULL;
120
121 LOGFN(__FILE__, __LINE__, __FUNCTION__);
122 im->w = w;
123 im->h = h;
124 im->vis = vis;
125 im->depth = depth;
126 _ecore_x_image_shm_check();
127 im->shm = _ecore_x_image_shm_can;
128 return im;
129}
130
131EAPI void
132ecore_x_image_free(Ecore_X_Image *im)
133{
134 LOGFN(__FILE__, __LINE__, __FUNCTION__);
135 if (im->shm)
136 {
137 if (im->xim)
138 {
139 XShmDetach(_ecore_x_disp, &(im->shminfo));
140 XDestroyImage(im->xim);
141 shmdt(im->shminfo.shmaddr);
142 shmctl(im->shminfo.shmid, IPC_RMID, 0);
143 }
144 }
145 else if (im->xim)
146 {
147 free(im->xim->data);
148 im->xim->data = NULL;
149 XDestroyImage(im->xim);
150 }
151
152 free(im);
153}
154
155static void
156_ecore_x_image_shm_create(Ecore_X_Image *im)
157{
158 im->xim = XShmCreateImage(_ecore_x_disp, im->vis, im->depth,
159 ZPixmap, NULL, &(im->shminfo),
160 im->w, im->h);
161 if (!im->xim)
162 return;
163
164 im->shminfo.shmid = shmget(IPC_PRIVATE,
165 im->xim->bytes_per_line * im->xim->height,
166 IPC_CREAT | 0666);
167 if (im->shminfo.shmid == -1)
168 {
169 XDestroyImage(im->xim);
170 return;
171 }
172
173 im->shminfo.readOnly = False;
174 im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
175 im->xim->data = im->shminfo.shmaddr;
176 if ((im->xim->data == (char *)-1) ||
177 (!im->xim->data))
178 {
179 shmdt(im->shminfo.shmaddr);
180 shmctl(im->shminfo.shmid, IPC_RMID, 0);
181 XDestroyImage(im->xim);
182 return;
183 }
184
185 XShmAttach(_ecore_x_disp, &im->shminfo);
186
187 im->data = (unsigned char *)im->xim->data;
188
189 im->bpl = im->xim->bytes_per_line;
190 im->rows = im->xim->height;
191 if (im->xim->bits_per_pixel <= 8)
192 im->bpp = 1;
193 else if (im->xim->bits_per_pixel <= 16)
194 im->bpp = 2;
195 else
196 im->bpp = 4;
197}
198
199EAPI Eina_Bool
200ecore_x_image_get(Ecore_X_Image *im,
201 Ecore_X_Drawable draw,
202 int x,
203 int y,
204 int sx,
205 int sy,
206 int w,
207 int h)
208{
209 Eina_Bool ret = EINA_TRUE;
210 XErrorHandler ph;
211
212 LOGFN(__FILE__, __LINE__, __FUNCTION__);
213 if (im->shm)
214 {
215 if (!im->xim)
216 _ecore_x_image_shm_create(im);
217
218 if (!im->xim)
219 return 0;
220
221 _ecore_x_image_err = 0;
222 // optimised path
223 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
224 if ((sx == 0) && (w == im->w))
225 {
226 im->xim->data = (char *)
227 im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
228 im->xim->width = w;
229 im->xim->height = h;
230 XGrabServer(_ecore_x_disp);
231 if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
232 ret = EINA_FALSE;
233 XUngrabServer(_ecore_x_disp);
234 ecore_x_sync();
235 }
236 // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
237 else
238 {
239 Ecore_X_Image *tim;
240 unsigned char *spixels, *sp, *pixels, *p;
241 int bpp, bpl, rows, sbpp, sbpl, srows;
242 int r;
243
244 tim = ecore_x_image_new(w, h, im->vis, im->depth);
245 if (tim)
246 {
247 ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
248 if (ret)
249 {
250 spixels = ecore_x_image_data_get(tim,
251 &sbpl,
252 &srows,
253 &sbpp);
254 pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
255 if ((pixels) && (spixels))
256 {
257 p = pixels + (sy * bpl) + (sx * bpp);
258 sp = spixels;
259 for (r = srows; r > 0; r--)
260 {
261 memcpy(p, sp, sbpl);
262 p += bpl;
263 sp += sbpl;
264 }
265 }
266 }
267
268 ecore_x_image_free(tim);
269 }
270 }
271
272 XSetErrorHandler((XErrorHandler)ph);
273 if (_ecore_x_image_err)
274 ret = EINA_FALSE;
275 }
276 else
277 {
278 printf("currently unimplemented ecore_x_image_get without shm\n");
279 ret = EINA_FALSE;
280 }
281
282 return ret;
283}
284
285EAPI void
286ecore_x_image_put(Ecore_X_Image *im,
287 Ecore_X_Drawable draw,
288 Ecore_X_GC gc,
289 int x,
290 int y,
291 int sx,
292 int sy,
293 int w,
294 int h)
295{
296 Ecore_X_GC tgc = 0;
297
298 LOGFN(__FILE__, __LINE__, __FUNCTION__);
299 if (!gc)
300 {
301 XGCValues gcv;
302 memset(&gcv, 0, sizeof(gcv));
303 gcv.subwindow_mode = IncludeInferiors;
304 tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv);
305 gc = tgc;
306 }
307 if (!im->xim) _ecore_x_image_shm_create(im);
308 if (im->xim)
309 XShmPutImage(_ecore_x_disp, draw, gc, im->xim, sx, sy, x, y, w, h, False);
310 if (tgc) ecore_x_gc_free(tgc);
311}
312
313EAPI void *
314ecore_x_image_data_get(Ecore_X_Image *im,
315 int *bpl,
316 int *rows,
317 int *bpp)
318{
319 LOGFN(__FILE__, __LINE__, __FUNCTION__);
320 if (!im->xim) _ecore_x_image_shm_create(im);
321 if (!im->xim) return NULL;
322 if (bpl) *bpl = im->bpl;
323 if (rows) *rows = im->rows;
324 if (bpp) *bpp = im->bpp;
325 return im->data;
326}
327
328EAPI Eina_Bool
329ecore_x_image_is_argb32_get(Ecore_X_Image *im)
330{
331 Visual *vis = im->vis;
332 if (!im->xim) _ecore_x_image_shm_create(im);
333 if (((vis->class == TrueColor) ||
334 (vis->class == DirectColor)) &&
335 (im->depth >= 24) &&
336 (vis->red_mask == 0xff0000) &&
337 (vis->green_mask == 0x00ff00) &&
338 (vis->blue_mask == 0x0000ff))
339 {
340#ifdef WORDS_BIGENDIAN
341 if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE;
342#else
343 if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE;
344#endif
345 }
346 return EINA_FALSE;
347}
348
349EAPI Eina_Bool
350ecore_x_image_to_argb_convert(void *src,
351 int sbpp,
352 int sbpl,
353 Ecore_X_Colormap c,
354 Ecore_X_Visual v,
355 int x,
356 int y,
357 int w,
358 int h,
359 unsigned int *dst,
360 int dbpl,
361 int dx,
362 int dy)
363{
364 Visual *vis = v;
365 XColor *cols = NULL;
366 int n = 0, nret = 0, i, row;
367 unsigned int pal[256], r, g, b;
368 enum
369 {
370 rgbnone = 0,
371 rgb565,
372 bgr565,
373 rgbx555,
374 argbx888,
375 abgrx888,
376 rgba888x,
377 bgra888x,
378 argbx666
379 };
380 int mode = 0;
381
382 sbpp *= 8;
383
384 n = vis->map_entries;
385 if ((n <= 256) &&
386 ((vis->class == PseudoColor) ||
387 (vis->class == StaticColor) ||
388 (vis->class == GrayScale) ||
389 (vis->class == StaticGray)))
390 {
391 if (!c)
392 c = DefaultColormap(_ecore_x_disp,
393 DefaultScreen(_ecore_x_disp));
394 cols = alloca(n * sizeof(XColor));
395 for (i = 0; i < n; i++)
396 {
397 cols[i].pixel = i;
398 cols[i].flags = DoRed | DoGreen | DoBlue;
399 cols[i].red = 0;
400 cols[i].green = 0;
401 cols[i].blue = 0;
402 }
403 XQueryColors(_ecore_x_disp, c, cols, n);
404 for (i = 0; i < n; i++)
405 {
406 pal[i] = 0xff000000 |
407 ((cols[i].red >> 8) << 16) |
408 ((cols[i].green >> 8) << 8) |
409 ((cols[i].blue >> 8));
410 }
411 nret = n;
412 }
413 else if ((vis->class == TrueColor) ||
414 (vis->class == DirectColor))
415 {
416 if ((vis->red_mask == 0x00ff0000) &&
417 (vis->green_mask == 0x0000ff00) &&
418 (vis->blue_mask == 0x000000ff))
419 mode = argbx888;
420 else if ((vis->red_mask == 0x000000ff) &&
421 (vis->green_mask == 0x0000ff00) &&
422 (vis->blue_mask == 0x00ff0000))
423 mode = abgrx888;
424 else if ((vis->red_mask == 0xff000000) &&
425 (vis->green_mask == 0x00ff0000) &&
426 (vis->blue_mask == 0x0000ff00))
427 mode = rgba888x;
428 else if ((vis->red_mask == 0x0000ff00) &&
429 (vis->green_mask == 0x00ff0000) &&
430 (vis->blue_mask == 0xff000000))
431 mode = bgra888x;
432 else if ((vis->red_mask == 0x0003f000) &&
433 (vis->green_mask == 0x00000fc0) &&
434 (vis->blue_mask == 0x0000003f))
435 mode = argbx666;
436 else if ((vis->red_mask == 0x0000f800) &&
437 (vis->green_mask == 0x000007e0) &&
438 (vis->blue_mask == 0x0000001f))
439 mode = rgb565;
440 else if ((vis->red_mask == 0x0000001f) &&
441 (vis->green_mask == 0x000007e0) &&
442 (vis->blue_mask == 0x0000f800))
443 mode = bgr565;
444 else if ((vis->red_mask == 0x00007c00) &&
445 (vis->green_mask == 0x000003e0) &&
446 (vis->blue_mask == 0x0000001f))
447 mode = rgbx555;
448 else
449 return EINA_FALSE;
450 }
451 for (row = 0; row < h; row++)
452 {
453 unsigned char *s8;
454 unsigned short *s16;
455 unsigned int *s32;
456 unsigned int *dp, *de;
457
458 dp = ((unsigned int *)(((unsigned char *)dst) +
459 ((dy + row) * dbpl))) + dx;
460 de = dp + w;
461 switch (sbpp)
462 {
463 case 8:
464 s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
465 if (nret > 0)
466 {
467 while (dp < de)
468 {
469 *dp = pal[*s8];
470 s8++; dp++;
471 }
472 }
473 else
474 return EINA_FALSE;
475 break;
476
477 case 16:
478 s16 = ((unsigned short *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
479 switch (mode)
480 {
481 case rgb565:
482 while (dp < de)
483 {
484 r = (*s16 & 0xf800) << 8;
485 g = (*s16 & 0x07e0) << 5;
486 b = (*s16 & 0x001f) << 3;
487 r |= (r >> 5) & 0xff0000;
488 g |= (g >> 6) & 0x00ff00;
489 b |= (b >> 5);
490 *dp = 0xff000000 | r | g | b;
491 s16++; dp++;
492 }
493 break;
494
495 case bgr565:
496 while (dp < de)
497 {
498 r = (*s16 & 0x001f) << 19;
499 g = (*s16 & 0x07e0) << 5;
500 b = (*s16 & 0xf800) >> 8;
501 r |= (r >> 5) & 0xff0000;
502 g |= (g >> 6) & 0x00ff00;
503 b |= (b >> 5);
504 *dp = 0xff000000 | r | g | b;
505 s16++; dp++;
506 }
507 break;
508
509 case rgbx555:
510 while (dp < de)
511 {
512 r = (*s16 & 0x7c00) << 9;
513 g = (*s16 & 0x03e0) << 6;
514 b = (*s16 & 0x001f) << 3;
515 r |= (r >> 5) & 0xff0000;
516 g |= (g >> 5) & 0x00ff00;
517 b |= (b >> 5);
518 *dp = 0xff000000 | r | g | b;
519 s16++; dp++;
520 }
521 break;
522
523 default:
524 return EINA_FALSE;
525 break;
526 }
527 break;
528
529 case 24:
530 case 32:
531 s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
532 switch (mode)
533 {
534 case argbx888:
535 while (dp < de)
536 {
537 *dp = 0xff000000 | *s32;
538 s32++; dp++;
539 }
540 break;
541
542 case abgrx888:
543 while (dp < de)
544 {
545 r = *s32 & 0x000000ff;
546 g = *s32 & 0x0000ff00;
547 b = *s32 & 0x00ff0000;
548 *dp = 0xff000000 | (r << 16) | (g) | (b >> 16);
549 s32++; dp++;
550 }
551 break;
552
553 case rgba888x:
554 while (dp < de)
555 {
556 *dp = 0xff000000 | (*s32 >> 8);
557 s32++; dp++;
558 }
559 break;
560
561 case bgra888x:
562 while (dp < de)
563 {
564 r = *s32 & 0x0000ff00;
565 g = *s32 & 0x00ff0000;
566 b = *s32 & 0xff000000;
567 *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24);
568 s32++; dp++;
569 }
570 break;
571
572 case argbx666:
573 while (dp < de)
574 {
575 r = (*s32 & 0x3f000) << 6;
576 g = (*s32 & 0x00fc0) << 4;
577 b = (*s32 & 0x0003f) << 2;
578 r |= (r >> 6) & 0xff0000;
579 g |= (g >> 6) & 0x00ff00;
580 b |= (b >> 6);
581 *dp = 0xff000000 | r | g | b;
582 s32++; dp++;
583 }
584 break;
585
586 default:
587 return EINA_FALSE;
588 break;
589 }
590 break;
591 break;
592
593 default:
594 return EINA_FALSE;
595 break;
596 }
597 }
598 return EINA_TRUE;
599}
600