2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies of the Software, its documentation and marketing & publicity
13 * materials, and acknowledgment shall be given in the documentation, materials
14 * and software packages that this Software was used.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include <X11/Xutil.h>
29 #include <X11/extensions/XShm.h>
32 EFillPixmap(Window win, Pixmap pmap, int x, int y, int w, int h)
37 gcv.subwindow_mode = IncludeInferiors;
38 gc = EXCreateGC(win, GCSubwindowMode, &gcv);
39 XCopyArea(disp, win, pmap, gc, x, y, w, h, x, y);
44 EPastePixmap(Window win, Pixmap pmap, int x, int y, int w, int h)
49 gcv.subwindow_mode = IncludeInferiors;
50 gc = EXCreateGC(win, GCSubwindowMode, &gcv);
51 XCopyArea(disp, pmap, win, gc, x, y, w, h, x, y);
56 ECreatePixImg(Window win, int w, int h)
61 pi = EMALLOC(PixImg, 1);
65 pi->shminfo = EMALLOC(XShmSegmentInfo, 1);
68 pi->xim = XShmCreateImage(disp, WinGetVisual(VROOT),
69 WinGetDepth(VROOT), ZPixmap, NULL,
74 shmget(IPC_PRIVATE, pi->xim->bytes_per_line * pi->xim->height,
76 if (pi->shminfo->shmid >= 0)
78 pi->shminfo->shmaddr = pi->xim->data =
79 (char *)shmat(pi->shminfo->shmid, 0, 0);
80 if (pi->shminfo->shmaddr != (void *)-1)
82 pi->shminfo->readOnly = False;
83 Dpy.last_error_code = 0;
84 XShmAttach(disp, pi->shminfo);
86 if (Dpy.last_error_code == 0)
89 XShmCreatePixmap(disp, win, pi->shminfo->shmaddr,
94 gcv.subwindow_mode = IncludeInferiors;
96 EXCreateGC(win, GCSubwindowMode, &gcv);
100 EFreePixmap(pi->pmap);
102 XShmDetach(disp, pi->shminfo);
104 shmdt(pi->shminfo->shmaddr);
106 shmctl(pi->shminfo->shmid, IPC_RMID, 0);
108 XDestroyImage(pi->xim);
117 EDestroyPixImg(PixImg * pi)
122 XShmDetach(disp, pi->shminfo);
123 shmdt(pi->shminfo->shmaddr);
124 shmctl(pi->shminfo->shmid, IPC_RMID, 0);
125 XDestroyImage(pi->xim);
127 EFreePixmap(pi->pmap);
133 EBlendRemoveShape(Win win, Pixmap pmap, int x, int y)
136 Window root = WinGetXwin(VROOT);
147 if (win->num_rect <= 0)
161 gcv.subwindow_mode = IncludeInferiors;
162 gc = EXCreateGC(root, GCSubwindowMode, &gcv);
164 mask = XCreatePixmap(disp, root, w, h, 1);
165 gcm = EXCreateGC(mask, 0, NULL);
166 XSetForeground(disp, gcm, 1);
167 XFillRectangle(disp, mask, gcm, 0, 0, w, h);
168 XSetForeground(disp, gcm, 0);
170 for (i = 0; i < win->num_rect; i++)
171 XFillRectangle(disp, mask, gcm, rl[i].x, rl[i].y, rl[i].width,
173 XSetClipMask(disp, gc, mask);
175 XFreePixmap(disp, mask);
178 XSetClipOrigin(disp, gc, x, y);
179 XCopyArea(disp, pmap, root, gc, x, y, w, h, x, y);
183 EBlendPixImg(Win win, PixImg * s1, PixImg * s2, PixImg * dst, int x, int y,
187 Window root = WinGetXwin(VROOT);
202 gcv.subwindow_mode = IncludeInferiors;
203 gc = EXCreateGC(root, GCSubwindowMode, &gcv);
205 XSetClipRectangles(disp, gc, x, y, win->rects, win->num_rect,
209 XSetClipOrigin(disp, gc, x, y);
213 if ((x >= WinGetW(VROOT)) || (y >= WinGetH(VROOT)))
215 if (x + w > WinGetW(VROOT))
216 w -= ((x + w) - WinGetW(VROOT));
223 if (y + h > WinGetH(VROOT))
224 h -= ((y + h) - WinGetH(VROOT));
231 if ((w <= 0) || (h <= 0))
236 switch (dst->xim->bits_per_pixel)
239 for (j = 0; j < h; j++)
241 unsigned int *ptr1, *ptr2, *ptr3;
244 (unsigned int *)(s1->xim->data +
245 (x * ((s1->xim->bits_per_pixel) >> 3)) +
246 ((j + y) * s1->xim->bytes_per_line));
248 (unsigned int *)(s2->xim->data +
249 (ox * ((s2->xim->bits_per_pixel) >> 3)) +
250 ((j + oy) * s2->xim->bytes_per_line));
252 (unsigned int *)(dst->xim->data +
253 (ox * ((dst->xim->bits_per_pixel) >> 3)) +
254 ((j + oy) * dst->xim->bytes_per_line));
255 for (i = 0; i < w; i++)
261 *ptr3++ = ((p1 >> 1) & 0x7f7f7f7f) +
262 ((p2 >> 1) & 0x7f7f7f7f) + (p1 & p2 & 0x01010101);
267 for (j = 0; j < h; j++)
269 for (i = 0; i < w; i++)
273 p1 = XGetPixel(s1->xim, (i + x), (j + y));
274 p2 = XGetPixel(s2->xim, (i + ox), (j + oy));
275 XPutPixel(dst->xim, (i + ox), (j + oy),
276 (((p1 >> 1) & 0x7f7f7f7f) +
277 ((p2 >> 1) & 0x7f7f7f7f) +
278 (p1 & p2 & 0x01010101)));
283 if (WinGetDepth(VROOT) != 15)
285 for (j = 0; j < h; j++)
287 unsigned int *ptr1, *ptr2, *ptr3;
290 (unsigned int *)(s1->xim->data +
291 (x * ((s1->xim->bits_per_pixel) >> 3)) +
292 ((j + y) * s1->xim->bytes_per_line));
294 (unsigned int *)(s2->xim->data +
295 (ox * ((s2->xim->bits_per_pixel) >> 3)) +
296 ((j + oy) * s2->xim->bytes_per_line));
298 (unsigned int *)(dst->xim->data +
299 (ox * ((dst->xim->bits_per_pixel) >> 3)) +
300 ((j + oy) * dst->xim->bytes_per_line));
303 for (i = 0; i < w; i += 2)
311 ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) |
312 (0x78 << 24) | (0x7c << 19) | (0x78 << 13)))
315 ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) |
316 (0x78 << 24) | (0x7c << 19) | (0x78 << 13)))
319 ((0x1 << 11) | (0x1 << 5) | (0x1) |
320 (0x1 << 27) | (0x1 << 21) | (0x1 << 16)));
325 for (i = 0; i < (w - 1); i += 2)
333 ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) |
334 (0x78 << 24) | (0x7c << 19) | (0x78 << 13)))
337 ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) |
338 (0x78 << 24) | (0x7c << 19) | (0x78 << 13)))
341 ((0x1 << 11) | (0x1 << 5) | (0x1) |
342 (0x1 << 27) | (0x1 << 21) | (0x1 << 16)));
345 unsigned short *pptr1, *pptr2, *pptr3;
346 unsigned short pp1, pp2;
348 pptr1 = (unsigned short *)ptr1;
349 pptr2 = (unsigned short *)ptr2;
350 pptr3 = (unsigned short *)ptr3;
355 ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3)))
358 ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3)))
359 + (pp1 & pp2 & ((0x1 << 11) | (0x1 << 5) | (0x1)));
366 for (j = 0; j < h; j++)
368 unsigned int *ptr1, *ptr2, *ptr3;
371 (unsigned int *)(s1->xim->data +
372 (x * (s1->xim->bits_per_pixel >> 3)) +
373 ((j + y) * s1->xim->bytes_per_line));
375 (unsigned int *)(s2->xim->data +
376 (ox * ((s2->xim->bits_per_pixel) >> 3)) +
377 ((j + oy) * s2->xim->bytes_per_line));
379 (unsigned int *)(dst->xim->data +
380 (ox * ((dst->xim->bits_per_pixel) >> 3)) +
381 ((j + oy) * dst->xim->bytes_per_line));
384 for (i = 0; i < w; i += 2)
392 ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) |
393 (0x78 << 23) | (0x78 << 18) | (0x78 << 13)))
396 ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) |
397 (0x78 << 23) | (0x78 << 18) | (0x78 << 13)))
400 ((0x1 << 10) | (0x1 << 5) | (0x1) |
401 (0x1 << 26) | (0x1 << 20) | (0x1 << 16)));
406 for (i = 0; i < (w - 1); i += 2)
414 ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) |
415 (0x78 << 23) | (0x78 << 18) | (0x78 << 13)))
418 ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) |
419 (0x78 << 23) | (0x78 << 18) | (0x78 << 13)))
422 ((0x1 << 10) | (0x1 << 5) | (0x1) |
423 (0x1 << 26) | (0x1 << 20) | (0x1 << 16)));
426 unsigned short *pptr1, *pptr2, *pptr3;
427 unsigned short pp1, pp2;
429 pptr1 = (unsigned short *)ptr1;
430 pptr2 = (unsigned short *)ptr2;
431 pptr3 = (unsigned short *)ptr3;
436 ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3)))
439 ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3)))
440 + (pp1 & pp2 & ((0x1 << 10) | (0x1 << 5) | (0x1)));
447 for (j = 0; j < h; j++)
449 unsigned char *ptr1, *ptr2, *ptr3;
452 (unsigned char *)(s1->xim->data +
454 ((s1->xim->bits_per_pixel) >> 3)) +
455 ((j + y) * s1->xim->bytes_per_line));
457 (unsigned char *)(s2->xim->data +
459 ((s2->xim->bits_per_pixel) >> 3)) +
460 ((j + oy) * s2->xim->bytes_per_line));
462 (unsigned char *)(dst->xim->data +
464 ((dst->xim->bits_per_pixel) >> 3)) +
465 ((j + oy) * dst->xim->bytes_per_line));
471 for (i = 0; i < w; i += 2)
486 for (i = 0; i < w; i += 2)
504 for (i = 0; i < (w - 1); i += 2)
520 for (i = 0; i < (w - 1); i += 2)
537 /* workaround since XCopyArea doesnt always work with shared pixmaps */
538 XShmPutImage(disp, root, gc, dst->xim, ox, oy, x, y, w, h, False);
539 /* XCopyArea(disp, dst->pmap, root, gc, ox, oy, w, h, x, y); */
540 /* I dont believe it - you cannot do this to a shared pixmaps to the screen */
541 /* XCopyArea(disp, dst->pmap, root, dst->gc, x, y, w, h, x, y); */