2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
9 #include "ecore_x_private.h"
12 #include <X11/extensions/XShm.h>
13 #include <X11/Xutil.h>
18 static int _ecore_x_image_shm_can = -1;
19 static int _ecore_x_image_err = 0;
22 _ecore_x_image_error_handler(Display * d __UNUSED__, XErrorEvent * ev __UNUSED__)
24 _ecore_x_image_err = 1;
28 _ecore_x_image_shm_check(void)
31 XShmSegmentInfo shminfo;
34 if (_ecore_x_image_shm_can != -1) return;
36 XSync(_ecore_x_disp, False);
37 _ecore_x_image_err = 0;
39 xim = XShmCreateImage(_ecore_x_disp,
40 DefaultVisual(_ecore_x_disp,
41 DefaultScreen(_ecore_x_disp)),
42 DefaultDepth(_ecore_x_disp,
43 DefaultScreen(_ecore_x_disp)),
48 _ecore_x_image_shm_can = 0;
52 shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
54 if (shminfo.shmid == -1)
57 _ecore_x_image_shm_can = 0;
61 shminfo.readOnly = False;
62 shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
63 xim->data = shminfo.shmaddr;
65 if (xim->data == (char *)-1)
68 _ecore_x_image_shm_can = 0;
72 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
73 XShmAttach(_ecore_x_disp, &shminfo);
74 XShmGetImage(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp),
75 xim, 0, 0, 0xffffffff);
76 XSync(_ecore_x_disp, False);
77 XSetErrorHandler((XErrorHandler)ph);
78 if (_ecore_x_image_err)
80 XShmDetach(_ecore_x_disp, &shminfo);
82 shmdt(shminfo.shmaddr);
83 shmctl(shminfo.shmid, IPC_RMID, 0);
84 _ecore_x_image_shm_can = 0;
88 XShmDetach(_ecore_x_disp, &shminfo);
90 shmdt(shminfo.shmaddr);
91 shmctl(shminfo.shmid, IPC_RMID, 0);
93 _ecore_x_image_shm_can = 1;
98 XShmSegmentInfo shminfo;
109 ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth)
113 im = calloc(1, sizeof(Ecore_X_Image));
114 if (!im) return NULL;
115 LOGFN(__FILE__, __LINE__, __FUNCTION__);
120 _ecore_x_image_shm_check();
121 im->shm = _ecore_x_image_shm_can;
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);
144 im->xim->data = NULL;
145 XDestroyImage(im->xim);
152 _ecore_x_image_shm_create(Ecore_X_Image *im)
154 im->xim = XShmCreateImage(_ecore_x_disp, im->vis, im->depth,
155 ZPixmap, NULL, &(im->shminfo),
157 if (!im->xim) return;
159 im->shminfo.shmid = shmget(IPC_PRIVATE,
160 im->xim->bytes_per_line * im->xim->height,
162 if (im->shminfo.shmid == -1)
164 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) ||
171 (im->xim->data == NULL))
173 shmdt(im->shminfo.shmaddr);
174 shmctl(im->shminfo.shmid, IPC_RMID, 0);
175 XDestroyImage(im->xim);
178 XShmAttach(_ecore_x_disp, &im->shminfo);
180 im->data = (unsigned char *)im->xim->data;
182 im->bpl = im->xim->bytes_per_line;
183 im->rows = im->xim->height;
184 if (im->xim->bits_per_pixel <= 8) im->bpp = 1;
185 else if (im->xim->bits_per_pixel <= 16) im->bpp = 2;
190 ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw,
191 int x, int y, int sx, int sy, int w, int h)
196 LOGFN(__FILE__, __LINE__, __FUNCTION__);
199 if (!im->xim) _ecore_x_image_shm_create(im);
200 if (!im->xim) return 0;
201 _ecore_x_image_err = 0;
203 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
204 if ((sx == 0) && (w == im->w))
206 im->xim->data = (char *)
207 im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
210 if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
214 // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
218 unsigned char *spixels, *sp, *pixels, *p;
219 int bpp, bpl, rows, sbpp, sbpl, srows;
222 tim = ecore_x_image_new(w, h, im->vis, im->depth);
225 ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
228 spixels = ecore_x_image_data_get(tim, &sbpl, &srows, &sbpp);
229 pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
230 if ((pixels) && (spixels))
232 p = pixels + (sy * bpl) + (sx * bpp);
234 for (r = srows; r > 0; r--)
242 ecore_x_image_free(tim);
245 XSetErrorHandler((XErrorHandler)ph);
246 if (_ecore_x_image_err) ret = 0;
250 printf("currently unimplemented ecore_x_image_get without shm\n");
257 ecore_x_image_put(Ecore_X_Image *im __UNUSED__, Ecore_X_Drawable draw __UNUSED__, int x __UNUSED__, int y __UNUSED__, int sx __UNUSED__, int sy __UNUSED__, int w __UNUSED__, int h __UNUSED__)
259 LOGFN(__FILE__, __LINE__, __FUNCTION__);
260 printf("ecore_x_image_put: unimplemented!\n");
264 ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp)
266 LOGFN(__FILE__, __LINE__, __FUNCTION__);
267 if (!im->xim) _ecore_x_image_shm_create(im);
268 if (!im->xim) return NULL;
270 if (bpl) *bpl = im->bpl;
271 if (rows) *rows = im->rows;
272 if (bpp) *bpp = im->bpp;