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 if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
223 // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
227 unsigned char *spixels, *sp, *pixels, *p;
228 int bpp, bpl, rows, sbpp, sbpl, srows;
231 tim = ecore_x_image_new(w, h, im->vis, im->depth);
234 ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
237 spixels = ecore_x_image_data_get(tim,
241 pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
242 if ((pixels) && (spixels))
244 p = pixels + (sy * bpl) + (sx * bpp);
246 for (r = srows; r > 0; r--)
255 ecore_x_image_free(tim);
259 XSetErrorHandler((XErrorHandler)ph);
260 if (_ecore_x_image_err)
265 printf("currently unimplemented ecore_x_image_get without shm\n");
270 } /* ecore_x_image_get */
273 ecore_x_image_put(Ecore_X_Image *im __UNUSED__,
274 Ecore_X_Drawable draw __UNUSED__,
282 LOGFN(__FILE__, __LINE__, __FUNCTION__);
283 printf("ecore_x_image_put: unimplemented!\n");
284 } /* ecore_x_image_put */
287 ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp)
289 LOGFN(__FILE__, __LINE__, __FUNCTION__);
291 _ecore_x_image_shm_create(im);
306 } /* ecore_x_image_data_get */