1 /* -*-c-*- */
2 /* Copyright (C) 2002 Olivier Chapuis */
3 /* This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, see: <http://www.gnu.org/licenses/>
15 */
16
17 /* ---------------------------- included header files ---------------------- */
18
19 #include "config.h"
20
21 #include <stdio.h>
22
23 #include <X11/Xlib.h>
24
25 #include <fvwmlib.h>
26 #include "PictureBase.h"
27 #include "Colorset.h"
28 #include "FRenderInit.h"
29 #include "FRenderInterface.h"
30 #include "Graphics.h"
31 #include "PictureGraphics.h"
32 #include "PictureUtils.h"
33 #include "FImage.h"
34 #include "Grab.h"
35
36 /* ---------------------------- local definitions -------------------------- */
37
38 /* ---------------------------- local macros ------------------------------- */
39
40 /* ---------------------------- imports ------------------------------------ */
41
42 /* ---------------------------- included code files ------------------------ */
43
44 /* ---------------------------- local types -------------------------------- */
45
46 /* ---------------------------- forward declarations ----------------------- */
47
48 /* ---------------------------- local variables ---------------------------- */
49
50 static Bool PGrabImageError = True;
51
52 /* ---------------------------- exported variables (globals) --------------- */
53
54 /* ---------------------------- local functions ---------------------------- */
55 static
FSetBackingStore(Display * dpy,Window win,int backing_store)56 int FSetBackingStore(Display *dpy, Window win, int backing_store)
57 {
58 XWindowAttributes attributes;
59 XSetWindowAttributes set_attributes;
60 int old_bs;
61
62 XGetWindowAttributes(dpy, win, &attributes);
63 if (attributes.backing_store == backing_store)
64 {
65 return -1;
66 }
67 old_bs = attributes.backing_store;
68 set_attributes.backing_store = backing_store;
69 XChangeWindowAttributes(dpy, win, CWBackingStore, &set_attributes);
70 return old_bs;
71 }
72
73 static
PCopyArea(Display * dpy,Pixmap pixmap,Pixmap mask,int depth,Drawable d,GC gc,int src_x,int src_y,int src_w,int src_h,int dest_x,int dest_y)74 void PCopyArea(Display *dpy, Pixmap pixmap, Pixmap mask, int depth,
75 Drawable d, GC gc,
76 int src_x, int src_y, int src_w, int src_h,
77 int dest_x, int dest_y)
78 {
79 XGCValues gcv;
80 unsigned long gcm;
81 GC my_gc = None;
82
83 if (gc == None)
84 {
85 my_gc = fvwmlib_XCreateGC(dpy, d, 0, NULL);
86 }
87 gcm = GCClipMask | GCClipXOrigin | GCClipYOrigin;
88 gcv.clip_x_origin = dest_x - src_x; /* */
89 gcv.clip_y_origin = dest_y - src_y; /* */
90 if (depth == Pdepth)
91 {
92 gcv.clip_mask = mask;
93 if (my_gc != None)
94 {
95 XChangeGC(dpy,my_gc,gcm,&gcv);
96 }
97 else
98 {
99 XChangeGC(dpy,gc,gcm,&gcv);
100 }
101 XCopyArea(dpy, pixmap, d,
102 (my_gc != None)? my_gc:gc,
103 src_x, src_y, src_w, src_h,
104 dest_x, dest_y);
105 }
106 else
107 {
108 /* monochrome bitmap */
109 gcv.clip_mask = mask;
110 if (my_gc != None)
111 {
112 gcv.foreground = PictureWhitePixel();
113 gcv.background = PictureBlackPixel();
114 gcm |= GCBackground|GCForeground;
115 XChangeGC(dpy,my_gc,gcm,&gcv);
116 }
117 else
118 {
119 XChangeGC(dpy,gc,gcm,&gcv);
120 }
121 XCopyPlane(dpy, pixmap, d,
122 (my_gc != None)? my_gc:gc,
123 src_x, src_y, src_w, src_h,
124 dest_x, dest_y, 1);
125 }
126 if (my_gc != None)
127 {
128 XFreeGC(dpy, my_gc);
129 }
130 else
131 {
132 gcm = GCClipMask;
133 gcv.clip_mask = None;
134 XChangeGC(dpy, gc, gcm, &gcv);
135 }
136 }
137
138 static
PTileRectangle(Display * dpy,Window win,Pixmap pixmap,Pixmap mask,int depth,int src_x,int src_y,Drawable d,GC gc,GC mono_gc,int dest_x,int dest_y,int dest_w,int dest_h)139 void PTileRectangle(Display *dpy, Window win, Pixmap pixmap, Pixmap mask,
140 int depth,
141 int src_x, int src_y,
142 Drawable d, GC gc, GC mono_gc,
143 int dest_x, int dest_y, int dest_w, int dest_h)
144 {
145 Pixmap tile_mask = None;
146 XGCValues gcv;
147 unsigned long gcm;
148 GC my_gc = None;
149 GC my_mono_gc = None;
150
151 if (gc == None)
152 {
153 my_gc = fvwmlib_XCreateGC(dpy, d, 0, NULL);
154 }
155 if (mono_gc == None && (mask != None || Pdepth != depth))
156 {
157 if (mask != None)
158 my_mono_gc = fvwmlib_XCreateGC(dpy, mask, 0, NULL);
159 else if (depth != Pdepth)
160 my_mono_gc = fvwmlib_XCreateGC(dpy, pixmap, 0, NULL);
161 }
162 gcm = 0;
163 if (mask != None)
164 {
165 /* create a till mask */
166 tile_mask = XCreatePixmap(dpy, win, dest_w, dest_h, 1);
167 gcv.tile = mask;
168 gcv.ts_x_origin = src_x;
169 gcv.ts_y_origin = src_y;
170 gcv.fill_style = FillTiled;
171 gcm = GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin |
172 GCTile;
173 if (mono_gc != None)
174 {
175 XChangeGC(dpy, mono_gc, gcm, &gcv);
176 }
177 else
178 {
179 gcv.foreground = 1;
180 gcv.background = 0;
181 gcm |= GCBackground|GCForeground;
182 XChangeGC(dpy, my_mono_gc, gcm, &gcv);
183 }
184 XFillRectangle(dpy, tile_mask,
185 (mono_gc != None)? mono_gc:my_mono_gc,
186 src_x, src_y, dest_w, dest_h);
187 if (mono_gc != None)
188 {
189 gcv.fill_style = FillSolid;
190 gcm = GCFillStyle;
191 XChangeGC(dpy, mono_gc, gcm, &gcv);
192 }
193 }
194
195 gcv.tile = pixmap;
196 gcv.ts_x_origin = dest_x - src_x;
197 gcv.ts_y_origin = dest_y - src_y;
198 gcv.fill_style = FillTiled;
199 gcm = GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
200 gcv.clip_mask = tile_mask;
201 gcv.clip_x_origin = dest_x;
202 gcv.clip_y_origin = dest_y;;
203 gcm |= GCClipMask | GCClipXOrigin | GCClipYOrigin;
204 if (depth != Pdepth)
205 {
206 Pixmap my_pixmap = None;
207
208 XChangeGC(dpy,
209 (mono_gc != None)? mono_gc:my_mono_gc, gcm, &gcv);
210 my_pixmap = XCreatePixmap(dpy, win, dest_w, dest_h, 1);
211 XFillRectangle(dpy, my_pixmap,
212 (mono_gc != None)? mono_gc:my_mono_gc,
213 0, 0, dest_w, dest_h);
214 gcv.clip_mask = my_pixmap;
215 gcv.fill_style = FillSolid;
216 gcm = GCFillStyle | GCClipMask;
217 XChangeGC(dpy,
218 (mono_gc != None)? mono_gc:my_mono_gc,
219 gcm, &gcv);
220 XCopyPlane(dpy, my_pixmap, d,
221 (my_gc != None)? my_gc:gc,
222 0, 0, dest_w, dest_h, dest_x, dest_y, 1);
223 if (my_pixmap != None)
224 {
225 XFreePixmap(dpy, my_pixmap);
226 }
227 }
228 else
229 {
230 XChangeGC(dpy, (gc != None)? gc:my_gc, gcm, &gcv);
231 XFillRectangle(dpy, d,
232 (gc != None)? gc:my_gc,
233 dest_x, dest_y, dest_w, dest_h);
234 }
235 if (my_gc != None)
236 {
237 XFreeGC(dpy, my_gc);
238 }
239 else
240 {
241 gcv.clip_mask = None;
242 gcv.fill_style = FillSolid;
243 gcm = GCFillStyle | GCClipMask;
244 XChangeGC(dpy, gc, gcm, &gcv);
245 }
246 if (my_mono_gc != None)
247 {
248 XFreeGC(dpy, my_mono_gc);
249 }
250 else if (mono_gc != None)
251 {
252 gcv.clip_mask = None;
253 gcv.fill_style = FillSolid;
254 gcm = GCFillStyle | GCClipMask;
255 XChangeGC(dpy, mono_gc, gcm, &gcv);
256 }
257 if (tile_mask != None)
258 {
259 XFreePixmap(dpy, tile_mask);
260 }
261 }
262
263 static
PGrabImageErrorHandler(void)264 void PGrabImageErrorHandler(void)
265 {
266 PGrabImageError = True;
267 }
268
269 static
PGrabXImage(Display * dpy,Drawable d,int x,int y,int w,int h,Bool d_is_a_window)270 FImage *PGrabXImage(
271 Display *dpy, Drawable d, int x, int y, int w, int h, Bool d_is_a_window)
272 {
273
274 Bool try_to_grab = True;
275 XWindowAttributes xwa;
276 XErrorHandler saved_eh = NULL;
277 FImage *fim = NULL;
278
279 PGrabImageError = 0;
280 if (d_is_a_window)
281 {
282 MyXGrabServer(dpy);
283 XGetWindowAttributes(dpy, d, &xwa);
284 XSync(dpy, False);
285
286 if (xwa.map_state != IsViewable &&
287 xwa.backing_store == NotUseful)
288 {
289 try_to_grab = False;
290 #if 0
291 fprintf(stderr, "Bad attribute! %i,%i\n",
292 xwa.map_state != IsViewable,
293 xwa.backing_store == NotUseful);
294 #endif
295 }
296 else
297 {
298 saved_eh = XSetErrorHandler(
299 (XErrorHandler) PGrabImageErrorHandler);
300 #if 0
301 fprintf(stderr, "Attribute ok! %i,%i\n",
302 xwa.map_state != IsViewable,
303 xwa.backing_store == NotUseful);
304 #endif
305 }
306 }
307 if (try_to_grab)
308 {
309 fim = FGetFImage(dpy, d, Pvisual, Pdepth, x, y, w, h, AllPlanes,
310 ZPixmap);
311 if (PGrabImageError)
312 {
313 #if 0
314 fprintf(stderr, "XGetImage error during the grab\n");
315 #endif
316 if (fim != NULL)
317 {
318 FDestroyFImage(dpy, fim);
319 fim = NULL;
320 }
321 }
322 if (d_is_a_window)
323 {
324 XSetErrorHandler((XErrorHandler) saved_eh);
325 }
326 }
327
328 if (d_is_a_window)
329 {
330 MyXUngrabServer(dpy);
331 }
332 return fim;
333 }
334
335 static
PCreateRenderPixmap(Display * dpy,Window win,Pixmap pixmap,Pixmap mask,Pixmap alpha,int depth,int added_alpha_percent,Pixel tint,int tint_percent,Bool d_is_a_window,Drawable d,GC gc,GC mono_gc,GC alpha_gc,int src_x,int src_y,int src_w,int src_h,int dest_x,int dest_y,int dest_w,int dest_h,Bool do_repeat,int * new_w,int * new_h,Bool * new_do_repeat,Pixmap * new_mask)336 Pixmap PCreateRenderPixmap(
337 Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha,
338 int depth, int added_alpha_percent, Pixel tint, int tint_percent,
339 Bool d_is_a_window, Drawable d, GC gc, GC mono_gc, GC alpha_gc,
340 int src_x, int src_y, int src_w, int src_h,
341 int dest_x, int dest_y, int dest_w, int dest_h, Bool do_repeat,
342 int *new_w, int *new_h, Bool *new_do_repeat,
343 Pixmap *new_mask)
344 {
345 FImage *pixmap_fim = NULL;
346 FImage *mask_fim = NULL;
347 FImage *alpha_fim = NULL;
348 FImage *dest_fim = NULL;
349 FImage *new_mask_fim = NULL;
350 FImage *out_fim = NULL;
351 Pixmap pixmap_copy = None;
352 Pixmap src_pix = None;
353 Pixmap out_pix = None;
354 unsigned short *am = NULL;
355 XColor *colors = NULL, *dest_colors = NULL;
356 XColor tint_color, c;
357 int w ,h, n_src_w, n_src_h;
358 int j, i, j1, i1, m = 0, k = 0, l = 0;
359 Bool do_free_mono_gc = False;
360 Bool make_new_mask = False;
361 Bool error = False;
362
363 *new_mask = None;
364 *new_do_repeat = do_repeat;
365
366 if (depth != Pdepth)
367 {
368 pixmap_copy = XCreatePixmap(dpy, win, src_w, src_h, Pdepth);
369 if (gc == None)
370 {
371 gc = PictureDefaultGC(dpy, win);
372 }
373 if (pixmap_copy && gc)
374 {
375 XCopyPlane(
376 dpy, pixmap, pixmap_copy, gc,
377 src_x, src_y, src_w, src_h,
378 0, 0, 1);
379 }
380 else
381 {
382 error = True;
383 goto bail;
384 }
385 src_x = src_y = 0;
386 }
387 src_pix = (pixmap_copy)? pixmap_copy:pixmap;
388
389 if (src_pix == ParentRelative)
390 {
391 pixmap_fim = PGrabXImage(
392 dpy, d, dest_x, dest_y, dest_w, dest_h, d_is_a_window);
393 }
394 else
395 {
396 pixmap_fim = FGetFImage(
397 dpy, src_pix, Pvisual, Pdepth, src_x, src_y, src_w,
398 src_h, AllPlanes, ZPixmap);
399 }
400 if (!pixmap_fim)
401 {
402 error = True;
403 goto bail;
404 }
405 if (mask != None)
406 {
407 mask_fim = FGetFImage(
408 dpy, mask, Pvisual, 1, src_x, src_y, src_w, src_h,
409 AllPlanes, ZPixmap);
410 if (!mask_fim)
411 {
412 error = True;
413 goto bail;
414 }
415 if (src_x != 0 || src_y != 0)
416 make_new_mask = True;
417 }
418 if (alpha != None)
419 {
420 alpha_fim = FGetFImage(
421 dpy, alpha, Pvisual, FRenderGetAlphaDepth(), src_x,
422 src_y, src_w, src_h, AllPlanes, ZPixmap);
423 if (!alpha_fim)
424 {
425 error = True;
426 goto bail;
427 }
428 }
429
430 if (alpha != None || added_alpha_percent < 100)
431 {
432 dest_fim = PGrabXImage(
433 dpy, d, dest_x, dest_y, dest_w, dest_h, d_is_a_window);
434 /* accept this error */
435 }
436
437 if (dest_fim && do_repeat && (dest_w > src_w || dest_h > src_h))
438 {
439 *new_do_repeat = False;
440 if (mask)
441 {
442 make_new_mask = True;
443 }
444 w = dest_w;
445 h = dest_h;
446 n_src_w = (w < src_w)? w:src_w;
447 n_src_h = (h < src_h)? h:src_h;
448 }
449 else
450 {
451 n_src_w = w = (dest_w < src_w)? dest_w:src_w;
452 n_src_h = h = (dest_h < src_h)? dest_h:src_h;
453 }
454 *new_w = w;
455 *new_h = h;
456
457 out_pix = XCreatePixmap(dpy, win, w, h, Pdepth);
458 out_fim = FCreateFImage(
459 dpy, Pvisual, Pdepth, ZPixmap, w, h);
460 if (gc == None)
461 {
462 gc = PictureDefaultGC(dpy, win);
463 }
464
465 if (!out_pix || !out_fim || !gc)
466 {
467 error = True;
468 goto bail;
469 }
470
471 colors = fxmalloc(n_src_w * n_src_h * sizeof(XColor));
472 if (dest_fim)
473 {
474 dest_colors = fxmalloc(w * h * sizeof(XColor));
475 }
476 am = fxmalloc(n_src_w * n_src_h * sizeof(unsigned short));
477
478 if (tint_percent > 0)
479 {
480 tint_color.pixel = tint;
481 XQueryColor(dpy, Pcmap, &tint_color);
482 }
483
484 for (j = 0; j < n_src_h; j++)
485 {
486 for (i = 0; i < n_src_w; i++, m++)
487 {
488 if (mask_fim != NULL &&
489 (XGetPixel(mask_fim->im, i, j) == 0))
490 {
491 am[m] = 0;
492 }
493 else if (alpha_fim != NULL)
494 {
495 am[m] = XGetPixel(alpha_fim->im, i, j);
496 if (am[m] == 0 && !dest_fim)
497 {
498 make_new_mask = True;
499 }
500 }
501 else
502 {
503 am[m] = 255;
504 }
505 if (added_alpha_percent < 100)
506 {
507 am[m] = (unsigned short)
508 ((am[m] * added_alpha_percent) / 100);
509 }
510 if (am[m] > 0)
511 {
512 if (!dest_fim)
513 {
514 if (am[m] < 130)
515 {
516 am[m] = 0;
517 make_new_mask = True;
518 }
519 else
520 {
521 am[m] = 255;
522 }
523 }
524 else if (am[m] < 255)
525 {
526 dest_colors[l++].pixel =
527 XGetPixel(dest_fim->im, i, j);
528 }
529 if (am[m] > 0)
530 {
531 colors[k++].pixel =
532 XGetPixel(pixmap_fim->im, i, j);
533 }
534 }
535 }
536 }
537
538 for (i = 0; i < k; i += 256)
539 XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256));
540
541 if (do_repeat && dest_fim && (n_src_h < h || n_src_w < w))
542 {
543 for (j1 = 0; j1 < h+n_src_h; j1 +=n_src_h)
544 {
545 for (i1 = 0; i1 < w+n_src_w; i1 += n_src_w)
546 {
547 for(j = 0;
548 !(i1==0 && j1==0) && j < n_src_h && j+j1 < h;
549 j++)
550 {
551 for(i = 0; i < n_src_w && i+i1 < w; i++)
552 {
553 m = j*n_src_w + i;
554 if (am[m] > 0 && am[m] < 255)
555 {
556 dest_colors[l++].pixel =
557 XGetPixel(
558 dest_fim
559 ->im,
560 i1+i,
561 j1+j);
562 }
563 }
564 }
565 }
566 }
567 }
568
569 for (i = 0; i < l; i += 256)
570 XQueryColors(dpy, Pcmap, &dest_colors[i], min(l - i, 256));
571
572 if (make_new_mask)
573 {
574 *new_mask = XCreatePixmap(dpy, win, w, h, 1);
575 if (*new_mask)
576 {
577 new_mask_fim = FCreateFImage(
578 dpy, Pvisual, 1, ZPixmap, w, h);
579 if (!new_mask_fim)
580 {
581 error = True;
582 goto bail;
583 }
584 if (mono_gc == None)
585 {
586 mono_gc = fvwmlib_XCreateGC(
587 dpy, *new_mask, 0, NULL);
588 do_free_mono_gc = True;
589 }
590 }
591 }
592
593 l = 0; m = 0; k = 0;
594 c.flags = DoRed | DoGreen | DoBlue;
595 for (j = 0; j < n_src_h; j++)
596 {
597 for (i = 0; i < n_src_w; i++, m++)
598 {
599 if (am[m] > 0)
600 {
601 if (*new_mask)
602 {
603 XPutPixel(new_mask_fim->im, i, j, 1);
604 }
605 if (tint_percent > 0)
606 {
607 colors[k].blue = (unsigned short)
608 (((100-tint_percent)*
609 colors[k].blue +
610 tint_color.blue *
611 tint_percent) /
612 100);
613 colors[k].green = (unsigned short)
614 (((100-tint_percent)*
615 colors[k].green +
616 tint_color.green *
617 tint_percent) /
618 100);
619 colors[k].red = (unsigned short)
620 (((100-tint_percent)*
621 colors[k].red +
622 tint_color.red *
623 tint_percent) /
624 100);
625 }
626 c.blue = colors[k].blue;
627 c.green = colors[k].green;
628 c.red = colors[k].red;
629 if (am[m] < 255 && dest_fim)
630 {
631 c.blue = (unsigned short)
632 (((255 - am[m])*
633 dest_colors[l].blue +
634 c.blue * am[m]) /
635 255);
636 c.green = (unsigned short)
637 (((255 - am[m])*
638 dest_colors[l].green +
639 c.green * am[m]) /
640 255);
641 c.red = (unsigned short)
642 (((255 - am[m])*
643 dest_colors[l].red +
644 c.red * am[m]) /
645 255);
646 l++;
647 }
648 PictureAllocColor(Pdpy, Pcmap, &c, False);
649 colors[k].pixel = c.pixel;
650 k++;
651 }
652 else
653 {
654 if (dest_fim)
655 {
656 c.pixel = XGetPixel(dest_fim->im, i, j);
657 }
658 else
659 {
660 c.pixel = XGetPixel(
661 pixmap_fim->im, i, j);
662 }
663 if (*new_mask)
664 {
665 XPutPixel(new_mask_fim->im, i, j, 0);
666 }
667 }
668 XPutPixel(out_fim->im, i, j, c.pixel);
669 }
670 }
671
672 /* tile: editor ligne width limit 107 !!*/
673 if (do_repeat && dest_fim && (n_src_h < h || n_src_w < w))
674 {
675 for (j1 = 0; j1 < h+n_src_h; j1 +=n_src_h)
676 {
677 for (i1 = 0; i1 < w+n_src_w; i1 += n_src_w)
678 {
679 k = 0;
680 for(j = 0;
681 !(i1==0 && j1==0) && j < n_src_h; j++)
682 {
683 for(i = 0; i < n_src_w; i++)
684 {
685 m = j*n_src_w + i;
686 if (!(i+i1 < w && j+j1 < h))
687 {
688 if (am[m] > 0)
689 {
690 k++;
691 }
692 }
693 else
694 {
695 if (am[m] > 0)
696 {
697 if (*new_mask)
698 {
699 XPutPixel(
700 new_mask_fim->im, i+i1,
701 j+j1, 1);
702 }
703 c.blue = colors[k].blue;
704 c.green = colors[k].green;
705 c.red = colors[k].red;
706 c.pixel = colors[k].pixel;
707 k++;
708 if (am[m] < 255)
709 {
710 c.blue = (unsigned short)
711 (((255 - am[m])*
712 dest_colors[l].blue +
713 c.blue * am[m]) /
714 255);
715 c.green = (unsigned short)
716 (((255 - am[m])*
717 dest_colors[l].green +
718 c.green * am[m]) /
719 255);
720 c.red = (unsigned short)
721 (((255 - am[m])*
722 dest_colors[l].red +
723 c.red * am[m]) /
724 255);
725 l++;
726 PictureAllocColor(
727 Pdpy, Pcmap, &c, False);
728 }
729 }
730 else
731 {
732 c.pixel = XGetPixel(
733 dest_fim->im, i+i1, j+j1);
734 if (*new_mask)
735 {
736 XPutPixel(
737 new_mask_fim->im, i+i1,
738 j+j1, 0);
739 }
740 }
741 XPutPixel(out_fim->im, i+i1, j+j1, c.pixel);
742 }
743 }
744 }
745 }
746 }
747 }
748
749 FPutFImage(dpy, out_pix, gc, out_fim, 0, 0, 0, 0, w, h);
750 if (*new_mask && mono_gc)
751 {
752 FPutFImage(
753 dpy, *new_mask, mono_gc, new_mask_fim,
754 0, 0, 0, 0, w, h);
755 }
756
757 bail:
758 if (colors)
759 {
760 free(colors);
761 }
762 if (dest_colors)
763 {
764 free(dest_colors);
765 }
766 if (am)
767 {
768 free(am);
769 }
770 if (pixmap_copy)
771 {
772 XFreePixmap(dpy, pixmap_copy);
773 }
774 if (pixmap_fim)
775 {
776 FDestroyFImage(dpy, pixmap_fim);
777 }
778 if (mask_fim)
779 {
780 FDestroyFImage(dpy, mask_fim);
781 }
782 if (alpha_fim)
783 {
784 FDestroyFImage(dpy, alpha_fim);
785 }
786 if (dest_fim)
787 {
788 FDestroyFImage(dpy, dest_fim);
789 }
790 if (new_mask_fim)
791 {
792 FDestroyFImage(dpy, new_mask_fim);
793 }
794 if (do_free_mono_gc && mono_gc)
795 {
796 XFreeGC(dpy, mono_gc);
797 }
798 if (out_fim)
799 {
800 FDestroyFImage(dpy, out_fim);
801 }
802 if (error)
803 {
804 if (out_pix != None)
805 {
806 XFreePixmap(dpy, out_pix);
807 out_pix = None;
808 }
809 if (*new_mask != None)
810 {
811 XFreePixmap(dpy, *new_mask);
812 *new_mask = None;
813 }
814 }
815
816 return out_pix;
817 }
818
819 /* never used and tested */
820 static
PCreateDitherPixmap(Display * dpy,Window win,Drawable src,Pixmap mask,int depth,GC gc,int in_width,int in_height,int out_width,int out_height)821 Pixmap PCreateDitherPixmap(
822 Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc,
823 int in_width, int in_height, int out_width, int out_height)
824 {
825 FImage *src_fim;
826 FImage *mask_fim = NULL;
827 FImage *out_fim;
828 Pixmap out_pix = None;
829 unsigned char *cm;
830 XColor *colors;
831 XColor c;
832 int j, i, m = 0, k = 0, x = 0, y = 0;
833
834 if (depth != Pdepth)
835 return None;
836
837 if (!(src_fim =
838 FGetFImage(
839 dpy, src, Pvisual, depth, 0, 0, in_width, in_height,
840 AllPlanes, ZPixmap)))
841 {
842 return None;
843 }
844 if (mask != None)
845 {
846 mask_fim = FGetFImage(
847 dpy, mask, Pvisual, 1, 0, 0, in_width, in_height,
848 AllPlanes, ZPixmap);
849 if (!mask_fim)
850 {
851 FDestroyFImage(dpy, mask_fim);
852 return None;
853 }
854 }
855 out_pix = XCreatePixmap(dpy, win, out_width, out_height, Pdepth);
856 out_fim = FCreateFImage(
857 dpy, Pvisual, Pdepth, ZPixmap, out_width, out_height);
858 if (gc == None)
859 {
860 gc = PictureDefaultGC(dpy, win);
861 }
862
863 if (!out_pix || !out_fim || !gc)
864 {
865 FDestroyFImage(dpy, src_fim);
866 if (mask_fim)
867 {
868 FDestroyFImage(dpy, mask_fim);
869 }
870 if (out_pix)
871 {
872 XFreePixmap(dpy, out_pix);
873 }
874 if (out_fim)
875 {
876 FDestroyFImage(dpy, out_fim);
877 }
878 return None;
879 }
880
881 colors = fxmalloc(out_width * out_height * sizeof(XColor));
882 cm = fxmalloc(out_width * out_height * sizeof(char));
883
884 x = y = 0;
885 for (j = 0; j < out_height; j++,y++)
886 {
887 if (y == in_height)
888 y = 0;
889 for (i = 0; i < out_width; i++,x++)
890 {
891 if (x == in_width)
892 x = 0;
893 if (mask_fim != NULL &&
894 (XGetPixel(mask_fim->im, x, y) == 0))
895 {
896 cm[m++] = 0;
897 }
898 else
899 {
900 cm[m++] = 255;
901 colors[k++].pixel = XGetPixel(src_fim->im, x, y);
902 }
903 }
904 }
905
906 for (i = 0; i < k; i += 256)
907 XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256));
908
909 k = 0;m = 0;
910 for (j = 0; j < out_height; j++)
911 {
912 for (i = 0; i < out_width; i++)
913 {
914
915 if (cm[m] > 0)
916 {
917 c = colors[k++];
918 PictureAllocColorAllProp(
919 Pdpy, Pcmap, &c, i, j, False, False,
920 True);
921 }
922 else
923 {
924 c.pixel = XGetPixel(src_fim->im, i, j);
925 }
926 XPutPixel(out_fim->im, i, j, c.pixel);
927 m++;
928 }
929 }
930 free(colors);
931 free(cm);
932 FDestroyFImage(dpy, src_fim);
933 if (mask_fim)
934 {
935 FDestroyFImage(dpy, mask_fim);
936 }
937 FPutFImage(
938 dpy, out_pix, gc, out_fim, 0, 0, 0, 0, out_width, out_height);
939 FDestroyFImage(dpy, out_fim);
940
941 return out_pix;
942 }
943
944 /* ---------------------------- interface functions ------------------------ */
945
PictureBitmapToPixmap(Display * dpy,Window win,Pixmap src,int depth,GC gc,int src_x,int src_y,int src_w,int src_h)946 Pixmap PictureBitmapToPixmap(
947 Display *dpy, Window win, Pixmap src, int depth, GC gc,
948 int src_x, int src_y, int src_w, int src_h)
949 {
950 Pixmap dest = None;
951
952 dest = XCreatePixmap(dpy, win, src_w, src_h, depth);
953 if (dest && gc == None)
954 {
955 gc = PictureDefaultGC(dpy, win);
956 }
957 if (dest && gc)
958 {
959 XCopyPlane(
960 dpy, src, dest, gc,
961 src_x, src_y, src_w, src_h, 0, 0, 1);
962 }
963
964 return dest;
965 }
966
PGraphicsRenderPixmaps(Display * dpy,Window win,Pixmap pixmap,Pixmap mask,Pixmap alpha,int depth,FvwmRenderAttributes * fra,Drawable d,GC gc,GC mono_gc,GC alpha_gc,int src_x,int src_y,int src_w,int src_h,int dest_x,int dest_y,int dest_w,int dest_h,int do_repeat)967 void PGraphicsRenderPixmaps(
968 Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha,
969 int depth, FvwmRenderAttributes *fra, Drawable d,
970 GC gc, GC mono_gc, GC alpha_gc,
971 int src_x, int src_y, int src_w, int src_h,
972 int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat)
973 {
974 FvwmRenderAttributes t_fra;
975 Pixmap xrs_pixmap = None;
976 Pixmap xrs_mask = None;
977 Pixmap tmp_pixmap, tmp_mask;
978 Bool d_is_a_window;
979
980 t_fra.added_alpha_percent = 100;
981 t_fra.tint_percent = 0;
982 t_fra.mask = 0;
983 t_fra.tint = None;
984
985 if (fra)
986 {
987 t_fra.mask = fra->mask;
988 if (fra->mask & FRAM_HAVE_ICON_CSET)
989 {
990 t_fra.added_alpha_percent =
991 fra->colorset->icon_alpha_percent;
992 t_fra.tint_percent = fra->colorset->icon_tint_percent;
993 t_fra.tint = fra->colorset->icon_tint;
994 }
995 if (fra->mask & FRAM_HAVE_ADDED_ALPHA)
996 {
997 t_fra.added_alpha_percent = fra->added_alpha_percent;
998 }
999 if (fra->mask & FRAM_HAVE_TINT)
1000 {
1001 t_fra.tint_percent = fra->tint_percent;
1002 t_fra.tint = fra->tint;
1003 }
1004 }
1005 if (dest_w == 0 && dest_h == 0)
1006 {
1007 dest_w = src_w; dest_h = src_h;
1008 }
1009
1010 /* use XRender only when "needed" (backing store pbs) */
1011 if (t_fra.tint_percent > 0 || t_fra.added_alpha_percent < 100
1012 || alpha != None)
1013 {
1014 /* for testing XRender simulation add && 0 */
1015 if (FRenderRender(
1016 dpy, win, pixmap, mask, alpha, depth,
1017 t_fra.added_alpha_percent, t_fra.tint,
1018 t_fra.tint_percent,
1019 d, gc, alpha_gc, src_x, src_y, src_w, src_h,
1020 dest_x, dest_y, dest_w, dest_h, do_repeat))
1021 {
1022 return;
1023 }
1024 }
1025
1026 /* no render extension or something strange happen */
1027 if (t_fra.tint_percent > 0 || t_fra.added_alpha_percent < 100
1028 || alpha != None)
1029 {
1030 int new_w, new_h, new_do_repeat;
1031
1032 d_is_a_window = !!(t_fra.mask & FRAM_DEST_IS_A_WINDOW);
1033 xrs_pixmap = PCreateRenderPixmap(
1034 dpy, win, pixmap, mask, alpha, depth,
1035 t_fra.added_alpha_percent, t_fra.tint,
1036 t_fra.tint_percent, d_is_a_window, d,
1037 gc, mono_gc, alpha_gc,
1038 src_x, src_y, src_w, src_h,
1039 dest_x, dest_y, dest_w, dest_h, do_repeat,
1040 &new_w, &new_h, &new_do_repeat, &xrs_mask);
1041 if (xrs_pixmap)
1042 {
1043 src_x = 0;
1044 src_y = 0;
1045 src_w = new_w;
1046 src_h = new_h;
1047 depth = Pdepth;
1048 do_repeat = new_do_repeat;
1049 }
1050 }
1051 tmp_pixmap = (xrs_pixmap != None)? xrs_pixmap:pixmap;
1052 tmp_mask = (xrs_mask != None)? xrs_mask:mask;
1053 if (do_repeat)
1054 {
1055 PTileRectangle(
1056 dpy, win, tmp_pixmap, tmp_mask, depth,
1057 src_x, src_y, d, gc, mono_gc, dest_x, dest_y, dest_w,
1058 dest_h);
1059 }
1060 else
1061 {
1062 PCopyArea(
1063 dpy, tmp_pixmap, tmp_mask, depth, d, gc,
1064 src_x, src_y, src_w, src_h, dest_x, dest_y);
1065 }
1066 if (xrs_pixmap)
1067 {
1068 XFreePixmap(dpy, xrs_pixmap);
1069 }
1070 if (xrs_mask)
1071 {
1072 XFreePixmap(dpy, xrs_mask);
1073 }
1074 }
1075
PGraphicsRenderPicture(Display * dpy,Window win,FvwmPicture * p,FvwmRenderAttributes * fra,Drawable d,GC gc,GC mono_gc,GC alpha_gc,int src_x,int src_y,int src_w,int src_h,int dest_x,int dest_y,int dest_w,int dest_h,int do_repeat)1076 void PGraphicsRenderPicture(
1077 Display *dpy, Window win, FvwmPicture *p, FvwmRenderAttributes *fra,
1078 Drawable d, GC gc, GC mono_gc, GC alpha_gc,
1079 int src_x, int src_y, int src_w, int src_h,
1080 int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat)
1081 {
1082 PGraphicsRenderPixmaps(
1083 dpy, win, p->picture, p->mask, p->alpha, p->depth, fra,
1084 d, gc, mono_gc, alpha_gc,
1085 src_x, src_y, src_w, src_h,
1086 dest_x, dest_y, dest_w, dest_h, do_repeat);
1087 }
1088
PGraphicsCopyPixmaps(Display * dpy,Pixmap pixmap,Pixmap mask,Pixmap alpha,int depth,Drawable d,GC gc,int src_x,int src_y,int src_w,int src_h,int dest_x,int dest_y)1089 void PGraphicsCopyPixmaps(
1090 Display *dpy, Pixmap pixmap, Pixmap mask, Pixmap alpha,
1091 int depth, Drawable d, GC gc, int src_x, int src_y, int src_w, int src_h,
1092 int dest_x, int dest_y)
1093 {
1094 PGraphicsRenderPixmaps(
1095 dpy, None, pixmap, mask, alpha, depth, 0, d, gc, None, None,
1096 src_x, src_y, src_w, src_h, dest_x, dest_y, src_w, src_h, False);
1097 }
1098
PGraphicsCopyFvwmPicture(Display * dpy,FvwmPicture * p,Drawable d,GC gc,int src_x,int src_y,int src_w,int src_h,int dest_x,int dest_y)1099 void PGraphicsCopyFvwmPicture(
1100 Display *dpy, FvwmPicture *p, Drawable d, GC gc,
1101 int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y)
1102 {
1103 PGraphicsRenderPicture(
1104 dpy, None, p, 0, d, gc, None, None, src_x, src_y, src_w, src_h,
1105 dest_x, dest_y, src_w, src_h, False);
1106 }
1107
PGraphicsTileRectangle(Display * dpy,Window win,Pixmap pixmap,Pixmap mask,Pixmap alpha,int depth,Drawable d,GC gc,GC mono_gc,int src_x,int src_y,int src_w,int src_h,int dest_x,int dest_y,int dest_w,int dest_h)1108 void PGraphicsTileRectangle(
1109 Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha,
1110 int depth, Drawable d, GC gc, GC mono_gc,
1111 int src_x, int src_y, int src_w, int src_h,
1112 int dest_x, int dest_y, int dest_w, int dest_h)
1113 {
1114 PGraphicsRenderPixmaps(
1115 dpy, win, pixmap, mask, alpha, depth, 0, d, gc, mono_gc, None,
1116 src_x, src_y, dest_w, dest_h, dest_x, dest_y, dest_w, dest_h,
1117 True);
1118 }
1119
PGraphicsCreateStretchPicture(Display * dpy,Window win,FvwmPicture * src,int dest_width,int dest_height,GC gc,GC mono_gc,GC alpha_gc)1120 FvwmPicture *PGraphicsCreateStretchPicture(
1121 Display *dpy, Window win, FvwmPicture *src,
1122 int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc)
1123 {
1124 Pixmap pixmap = None, mask = None, alpha = None;
1125 FvwmPicture *q;
1126
1127 if (src == NULL || src->picture == None)
1128 {
1129 return NULL;
1130 }
1131 pixmap = CreateStretchPixmap(
1132 dpy, src->picture, src->width, src->height, src->depth,
1133 dest_width, dest_height, gc);
1134 if (!pixmap)
1135 {
1136 return NULL;
1137 }
1138 if (src->mask)
1139 {
1140 mask = CreateStretchPixmap(
1141 dpy, src->mask, src->width, src->height, 1,
1142 dest_width, dest_height, mono_gc);
1143 }
1144 if (src->alpha)
1145 {
1146 alpha = CreateStretchPixmap(
1147 dpy, src->alpha, src->width, src->height,
1148 FRenderGetAlphaDepth(),
1149 dest_width, dest_height, alpha_gc);
1150 }
1151
1152 q = fxcalloc(1, sizeof(FvwmPicture));
1153 q->count = 1;
1154 q->name = NULL;
1155 q->next = NULL;
1156 q->stamp = pixmap;
1157 q->picture = pixmap;
1158 q->mask = mask;
1159 q->alpha = alpha;
1160 q->width = dest_width;
1161 q->height = dest_height;
1162 q->depth = src->depth;
1163 q->alloc_pixels = 0;
1164 q->nalloc_pixels = 0;
1165
1166 return q;
1167 }
1168
PGraphicsCreateTiledPicture(Display * dpy,Window win,FvwmPicture * src,int dest_width,int dest_height,GC gc,GC mono_gc,GC alpha_gc)1169 FvwmPicture *PGraphicsCreateTiledPicture(
1170 Display *dpy, Window win, FvwmPicture *src,
1171 int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc)
1172 {
1173 Pixmap pixmap = None, mask = None, alpha = None;
1174 FvwmPicture *q;
1175
1176 if (src == NULL || src->picture == None)
1177 {
1178 return NULL;
1179 }
1180 pixmap = CreateTiledPixmap(
1181 dpy, src->picture, src->width, src->height, dest_width,
1182 dest_height, src->depth, gc);
1183 if (!pixmap)
1184 {
1185 return NULL;
1186 }
1187 if (src->mask)
1188 {
1189 mask = CreateTiledPixmap(
1190 dpy, src->mask, src->width, src->height, dest_width,
1191 dest_height, 1, mono_gc);
1192 }
1193 if (src->alpha)
1194 {
1195 alpha = CreateTiledPixmap(
1196 dpy, src->alpha, src->width, src->height, dest_width,
1197 dest_height, FRenderGetAlphaDepth(), alpha_gc);
1198 }
1199
1200 q = fxcalloc(1, sizeof(FvwmPicture));
1201 q->count = 1;
1202 q->name = NULL;
1203 q->next = NULL;
1204 q->stamp = pixmap;
1205 q->picture = pixmap;
1206 q->mask = mask;
1207 q->alpha = alpha;
1208 q->width = dest_width;
1209 q->height = dest_height;
1210 q->depth = src->depth;
1211 q->alloc_pixels = 0;
1212 q->nalloc_pixels = 0;
1213
1214 return q;
1215 }
1216
PGraphicsCreateTransparency(Display * dpy,Window win,FvwmRenderAttributes * fra,GC gc,int x,int y,int width,int height,Bool parent_relative)1217 Pixmap PGraphicsCreateTransparency(
1218 Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
1219 int x, int y, int width, int height, Bool parent_relative)
1220 {
1221 Pixmap r = None, dp = None;
1222 XID junk;
1223 XID root;
1224 int dummy, sx, sy, sw, sh;
1225 int gx = x, gy = y, gh = height, gw = width;
1226 int old_backing_store = -1;
1227
1228 if (parent_relative)
1229 {
1230 old_backing_store = FSetBackingStore(dpy, win, Always);
1231 XSetWindowBackgroundPixmap(dpy, win, ParentRelative);
1232 XClearArea(dpy, win, x, y, width, height, False);
1233 XSync(dpy, False);
1234 }
1235
1236 if (parent_relative)
1237 {
1238 /* this block is not useful if backing store ... */
1239 if (!XGetGeometry(
1240 dpy, win, &root, (int *)&junk, (int *)&junk,
1241 (unsigned int *)&sw, (unsigned int *)&sh,
1242 (unsigned int *)&junk, (unsigned int *)&junk))
1243 {
1244 goto bail;
1245 }
1246 XTranslateCoordinates(
1247 dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy, &junk);
1248 if (sx >= DisplayWidth(dpy, DefaultScreen(dpy)))
1249 {
1250 goto bail;
1251 }
1252 if (sy >= DisplayHeight(dpy, DefaultScreen(dpy)))
1253 {
1254 goto bail;
1255 }
1256 if (sx < 0)
1257 {
1258 gx = gx - sx;
1259 gw = width + sx;
1260 sx = 0;
1261 if (gw <= 0)
1262 {
1263 goto bail;
1264 }
1265 }
1266 if (sy < 0)
1267 {
1268 gy = gy - sy;
1269 gh = height + sy;
1270 sy = 0;
1271 if (gh <= 0)
1272 {
1273 goto bail;
1274 }
1275 }
1276 if (sx + gw > DisplayWidth(dpy, DefaultScreen(dpy)))
1277 {
1278 gw = DisplayWidth(dpy, DefaultScreen(dpy)) - sx;
1279 }
1280 if (sy + gh > DisplayHeight(dpy, DefaultScreen(dpy)))
1281 {
1282 gh = DisplayHeight(dpy, DefaultScreen(dpy)) - sy;
1283 }
1284 }
1285 #if 0
1286 fprintf(
1287 stderr,"Geo: %i,%i,%i,%i / %i,%i,%i,%i / %i,%i,%i,%i\n",
1288 gx,gy,gw,gh, x,y,width,height, sx,sy,sw,sh);
1289 #endif
1290 if (XRenderSupport && FRenderGetExtensionSupported())
1291 {
1292 r = XCreatePixmap(dpy, win, gw, gh, Pdepth);
1293 if (FRenderRender(
1294 dpy, win, ParentRelative, None, None, Pdepth, 100,
1295 fra->tint, fra->tint_percent, r, gc, None,
1296 gx, gy, gw, gh, 0, 0, gw, gh, False))
1297 {
1298 goto bail;
1299 }
1300 XFreePixmap(dpy, r);
1301 }
1302 r = PCreateRenderPixmap(
1303 dpy, win, ParentRelative, None, None, Pdepth, 100, fra->tint,
1304 fra->tint_percent,
1305 True, win,
1306 gc, None, None, gx, gy, gw, gh, gx, gy, gw, gh,
1307 False, &dummy, &dummy, &dummy, &dp);
1308
1309 bail:
1310 if (old_backing_store >= 0)
1311 {
1312 FSetBackingStore(dpy, win, old_backing_store);
1313 }
1314 return r;
1315 }
1316
PGraphicsTintRectangle(Display * dpy,Window win,Pixel tint,int tint_percent,Drawable dest,Bool dest_is_a_window,GC gc,GC mono_gc,GC alpha_gc,int dest_x,int dest_y,int dest_w,int dest_h)1317 void PGraphicsTintRectangle(
1318 Display *dpy, Window win, Pixel tint, int tint_percent,
1319 Drawable dest, Bool dest_is_a_window, GC gc, GC mono_gc, GC alpha_gc,
1320 int dest_x, int dest_y, int dest_w, int dest_h)
1321 {
1322 Pixmap p;
1323 FvwmRenderAttributes fra;
1324
1325 #if 0
1326 /* this does not work. why? */
1327 if (FRenderTintRectangle(
1328 dpy, win, None, tint, tint_percent, dest,
1329 dest_x, dest_y, dest_w, dest_h))
1330 {
1331 return;
1332 }
1333 #else
1334
1335 if (FRenderRender(
1336 dpy, win, ParentRelative, None, None, Pdepth, 100,
1337 tint, tint_percent, win, gc, None,
1338 dest_x, dest_y, dest_w, dest_h,
1339 dest_x, dest_y, dest_w, dest_h, False))
1340 {
1341
1342 return;
1343 }
1344 #endif
1345
1346 if (dest_is_a_window)
1347 {
1348 fra.tint = tint;
1349 fra.tint_percent = tint_percent;
1350 fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT;
1351 p = PGraphicsCreateTransparency(
1352 dpy, dest, &fra, gc, dest_x, dest_y, dest_w, dest_h,
1353 False);
1354 if (p)
1355 {
1356 XCopyArea(
1357 dpy, p, dest, gc, 0, 0, dest_w, dest_h,
1358 dest_x, dest_y);
1359 XFreePixmap(dpy, p);
1360 }
1361 }
1362 }
1363
1364 #if 0 /* humm... maybe useful one day with menus */
1365 Pixmap PGraphicsCreateTranslucent(
1366 Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
1367 int x, int y, int width, int height)
1368 {
1369 Pixmap r = None;
1370 int gx = x, gy = y, gh = height, gw = width;
1371 FvwmRenderAttributes t_fra;
1372 Pixmap root_pix = None;
1373 Pixmap dp = None;
1374 int dummy;
1375
1376 t_fra.added_alpha_percent = 100;
1377 t_fra.tint_percent = 0;
1378 t_fra.tint = 0;
1379 t_fra.mask = 0;
1380
1381 if (fra)
1382 {
1383 if (fra->mask & FRAM_HAVE_TINT)
1384 {
1385 t_fra.tint_percent = fra->tint_percent;
1386 t_fra.tint = fra->tint;
1387 t_fra.mask = FRAM_HAVE_TINT;
1388 }
1389 }
1390
1391 if (x >= DisplayWidth(dpy, DefaultScreen(dpy)))
1392 {
1393 goto bail;
1394 }
1395 if (y >= DisplayHeight(dpy, DefaultScreen(dpy)))
1396 {
1397 goto bail;
1398 }
1399 if (x < 0)
1400 {
1401 gx = 0;
1402 gw = width + x;
1403 if (gw <= 0)
1404 {
1405 goto bail;
1406 }
1407 }
1408 if (y < 0)
1409 {
1410 gy = 0;
1411 gh = gh+y;
1412 if (gh <= 0)
1413 {
1414 goto bail;
1415 }
1416 }
1417 if (gx + gw > DisplayWidth(dpy, DefaultScreen(dpy)))
1418 {
1419 gw = DisplayWidth(dpy, DefaultScreen(dpy)) - gx;
1420 }
1421 if (gy + gh > DisplayHeight(dpy, DefaultScreen(dpy)))
1422 {
1423 gh = DisplayHeight(dpy, DefaultScreen(dpy)) - gy;
1424 }
1425 {
1426 /* make a screen shoot */
1427 GC my_gc;
1428 unsigned long valuemask = GCSubwindowMode;
1429 XGCValues values;
1430
1431 values.subwindow_mode = IncludeInferiors;
1432 root_pix = XCreatePixmap(dpy, win, gw, gh, Pdepth);
1433 my_gc = fvwmlib_XCreateGC(dpy, win, 0, NULL);
1434 XChangeGC(dpy, my_gc, valuemask, &values);
1435 MyXGrabServer(dpy);
1436 XCopyArea(
1437 dpy, DefaultRootWindow(dpy), root_pix, my_gc,
1438 gx, gy, gw, gh, 0, 0);
1439 MyXUngrabServer(dpy);
1440 XFreeGC(dpy,my_gc);
1441 }
1442 if (XRenderSupport && FRenderGetExtensionSupported())
1443 {
1444 r = XCreatePixmap(dpy, win, gw, gh, Pdepth);
1445 if (FRenderRender(
1446 dpy, win, root_pix, None, None, Pdepth,
1447 t_fra.added_alpha_percent, t_fra.tint,
1448 t_fra.tint_percent, r, gc, None,
1449 0, 0, gw, gh, 0, 0, gw, gh, False))
1450 {
1451 goto bail;
1452 }
1453 XFreePixmap(dpy, r);
1454 r = None;
1455 }
1456 r = PCreateRenderPixmap(
1457 dpy, win, root_pix, None, None, Pdepth, 100,
1458 fra->tint, fra->tint_percent, True, win,
1459 gc, None, None, 0, 0, gw, gh, gx, gy, gw, gh,
1460 False, &dummy, &dummy, &dummy, &dp);
1461
1462 bail:
1463 if (root_pix)
1464 {
1465 XFreePixmap(dpy, root_pix);
1466 }
1467 if (dp)
1468 {
1469 XFreePixmap(dpy, dp);
1470 }
1471 return r;
1472 }
1473 #endif
1474
1475
1476 /* never tested and used ! */
PGraphicsCreateDitherPixmap(Display * dpy,Window win,Drawable src,Pixmap mask,int depth,GC gc,int in_width,int in_height,int out_width,int out_height)1477 Pixmap PGraphicsCreateDitherPixmap(
1478 Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc,
1479 int in_width, int in_height, int out_width, int out_height)
1480 {
1481 return PCreateDitherPixmap(
1482 dpy, win, src, mask, depth, gc,
1483 in_width, in_height, out_width, out_height);
1484 }
1485