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 = (XColor *)safemalloc(n_src_w * n_src_h * sizeof(XColor));
472 if (dest_fim)
473 {
474 dest_colors =
475 (XColor *)safemalloc(w * h * sizeof(XColor));
476 }
477 am = (unsigned short *)safemalloc(
478 n_src_w * n_src_h * sizeof(unsigned short));
479
480 if (tint_percent > 0)
481 {
482 tint_color.pixel = tint;
483 XQueryColor(dpy, Pcmap, &tint_color);
484 }
485
486 for (j = 0; j < n_src_h; j++)
487 {
488 for (i = 0; i < n_src_w; i++, m++)
489 {
490 if (mask_fim != NULL &&
491 (XGetPixel(mask_fim->im, i, j) == 0))
492 {
493 am[m] = 0;
494 }
495 else if (alpha_fim != NULL)
496 {
497 am[m] = XGetPixel(alpha_fim->im, i, j);
498 if (am[m] == 0 && !dest_fim)
499 {
500 make_new_mask = True;
501 }
502 }
503 else
504 {
505 am[m] = 255;
506 }
507 if (added_alpha_percent < 100)
508 {
509 am[m] = (unsigned short)
510 ((am[m] * added_alpha_percent) / 100);
511 }
512 if (am[m] > 0)
513 {
514 if (!dest_fim)
515 {
516 if (am[m] < 130)
517 {
518 am[m] = 0;
519 make_new_mask = True;
520 }
521 else
522 {
523 am[m] = 255;
524 }
525 }
526 else if (am[m] < 255)
527 {
528 dest_colors[l++].pixel =
529 XGetPixel(dest_fim->im, i, j);
530 }
531 if (am[m] > 0)
532 {
533 colors[k++].pixel =
534 XGetPixel(pixmap_fim->im, i, j);
535 }
536 }
537 }
538 }
539
540 for (i = 0; i < k; i += 256)
541 XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256));
542
543 if (do_repeat && dest_fim && (n_src_h < h || n_src_w < w))
544 {
545 for (j1 = 0; j1 < h+n_src_h; j1 +=n_src_h)
546 {
547 for (i1 = 0; i1 < w+n_src_w; i1 += n_src_w)
548 {
549 for(j = 0;
550 !(i1==0 && j1==0) && j < n_src_h && j+j1 < h;
551 j++)
552 {
553 for(i = 0; i < n_src_w && i+i1 < w; i++)
554 {
555 m = j*n_src_w + i;
556 if (am[m] > 0 && am[m] < 255)
557 {
558 dest_colors[l++].pixel =
559 XGetPixel(
560 dest_fim
561 ->im,
562 i1+i,
563 j1+j);
564 }
565 }
566 }
567 }
568 }
569 }
570
571 for (i = 0; i < l; i += 256)
572 XQueryColors(dpy, Pcmap, &dest_colors[i], min(l - i, 256));
573
574 if (make_new_mask)
575 {
576 *new_mask = XCreatePixmap(dpy, win, w, h, 1);
577 if (*new_mask)
578 {
579 new_mask_fim = FCreateFImage(
580 dpy, Pvisual, 1, ZPixmap, w, h);
581 if (mono_gc == None)
582 {
583 mono_gc = fvwmlib_XCreateGC(
584 dpy, *new_mask, 0, NULL);
585 do_free_mono_gc = True;
586 }
587 }
588 }
589
590 l = 0; m = 0; k = 0;
591 c.flags = DoRed | DoGreen | DoBlue;
592 for (j = 0; j < n_src_h; j++)
593 {
594 for (i = 0; i < n_src_w; i++, m++)
595 {
596 if (am[m] > 0)
597 {
598 if (*new_mask)
599 {
600 XPutPixel(new_mask_fim->im, i, j, 1);
601 }
602 if (tint_percent > 0)
603 {
604 colors[k].blue = (unsigned short)
605 (((100-tint_percent)*
606 colors[k].blue +
607 tint_color.blue *
608 tint_percent) /
609 100);
610 colors[k].green = (unsigned short)
611 (((100-tint_percent)*
612 colors[k].green +
613 tint_color.green *
614 tint_percent) /
615 100);
616 colors[k].red = (unsigned short)
617 (((100-tint_percent)*
618 colors[k].red +
619 tint_color.red *
620 tint_percent) /
621 100);
622 }
623 c.blue = colors[k].blue;
624 c.green = colors[k].green;
625 c.red = colors[k].red;
626 if (am[m] < 255 && dest_fim)
627 {
628 c.blue = (unsigned short)
629 (((255 - am[m])*
630 dest_colors[l].blue +
631 c.blue * am[m]) /
632 255);
633 c.green = (unsigned short)
634 (((255 - am[m])*
635 dest_colors[l].green +
636 c.green * am[m]) /
637 255);
638 c.red = (unsigned short)
639 (((255 - am[m])*
640 dest_colors[l].red +
641 c.red * am[m]) /
642 255);
643 l++;
644 }
645 PictureAllocColor(Pdpy, Pcmap, &c, False);
646 colors[k].pixel = c.pixel;
647 k++;
648 }
649 else
650 {
651 if (dest_fim)
652 {
653 c.pixel = XGetPixel(dest_fim->im, i, j);
654 }
655 else
656 {
657 c.pixel = XGetPixel(
658 pixmap_fim->im, i, j);
659 }
660 if (*new_mask)
661 {
662 XPutPixel(new_mask_fim->im, i, j, 0);
663 }
664 }
665 XPutPixel(out_fim->im, i, j, c.pixel);
666 }
667 }
668
669 /* tile: editor ligne width limit 107 !!*/
670 if (do_repeat && dest_fim && (n_src_h < h || n_src_w < w))
671 {
672 for (j1 = 0; j1 < h+n_src_h; j1 +=n_src_h)
673 {
674 for (i1 = 0; i1 < w+n_src_w; i1 += n_src_w)
675 {
676 k = 0;
677 for(j = 0;
678 !(i1==0 && j1==0) && j < n_src_h; j++)
679 {
680 for(i = 0; i < n_src_w; i++)
681 {
682 m = j*n_src_w + i;
683 if (!(i+i1 < w && j+j1 < h))
684 {
685 if (am[m] > 0)
686 {
687 k++;
688 }
689 }
690 else
691 {
692 if (am[m] > 0)
693 {
694 if (*new_mask)
695 {
696 XPutPixel(
697 new_mask_fim->im, i+i1,
698 j+j1, 1);
699 }
700 c.blue = colors[k].blue;
701 c.green = colors[k].green;
702 c.red = colors[k].red;
703 c.pixel = colors[k].pixel;
704 k++;
705 if (am[m] < 255)
706 {
707 c.blue = (unsigned short)
708 (((255 - am[m])*
709 dest_colors[l].blue +
710 c.blue * am[m]) /
711 255);
712 c.green = (unsigned short)
713 (((255 - am[m])*
714 dest_colors[l].green +
715 c.green * am[m]) /
716 255);
717 c.red = (unsigned short)
718 (((255 - am[m])*
719 dest_colors[l].red +
720 c.red * am[m]) /
721 255);
722 l++;
723 PictureAllocColor(
724 Pdpy, Pcmap, &c, False);
725 }
726 }
727 else
728 {
729 c.pixel = XGetPixel(
730 dest_fim->im, i+i1, j+j1);
731 if (*new_mask)
732 {
733 XPutPixel(
734 new_mask_fim->im, i+i1,
735 j+j1, 0);
736 }
737 }
738 XPutPixel(out_fim->im, i+i1, j+j1, c.pixel);
739 }
740 }
741 }
742 }
743 }
744 }
745
746 FPutFImage(dpy, out_pix, gc, out_fim, 0, 0, 0, 0, w, h);
747 if (*new_mask && mono_gc)
748 {
749 FPutFImage(
750 dpy, *new_mask, mono_gc, new_mask_fim,
751 0, 0, 0, 0, w, h);
752 }
753
754 bail:
755 if (colors)
756 {
757 free(colors);
758 }
759 if (dest_colors)
760 {
761 free(dest_colors);
762 }
763 if (am)
764 {
765 free(am);
766 }
767 if (pixmap_copy)
768 {
769 XFreePixmap(dpy, pixmap_copy);
770 }
771 if (pixmap_fim)
772 {
773 FDestroyFImage(dpy, pixmap_fim);
774 }
775 if (mask_fim)
776 {
777 FDestroyFImage(dpy, mask_fim);
778 }
779 if (alpha_fim)
780 {
781 FDestroyFImage(dpy, alpha_fim);
782 }
783 if (dest_fim)
784 {
785 FDestroyFImage(dpy, dest_fim);
786 }
787 if (new_mask_fim)
788 {
789 FDestroyFImage(dpy, new_mask_fim);
790 }
791 if (do_free_mono_gc && mono_gc)
792 {
793 XFreeGC(dpy, mono_gc);
794 }
795 if (out_fim)
796 {
797 FDestroyFImage(dpy, out_fim);
798 }
799 if (error)
800 {
801 if (out_pix != None)
802 {
803 XFreePixmap(dpy, out_pix);
804 out_pix = None;
805 }
806 if (*new_mask != None)
807 {
808 XFreePixmap(dpy, *new_mask);
809 *new_mask = None;
810 }
811 }
812
813 return out_pix;
814 }
815
816 /* never used and tested */
817 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)818 Pixmap PCreateDitherPixmap(
819 Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc,
820 int in_width, int in_height, int out_width, int out_height)
821 {
822 FImage *src_fim;
823 FImage *mask_fim = NULL;
824 FImage *out_fim;
825 Pixmap out_pix = None;
826 unsigned char *cm;
827 XColor *colors;
828 XColor c;
829 int j, i, m = 0, k = 0, x = 0, y = 0;
830
831 if (depth != Pdepth)
832 return None;
833
834 if (!(src_fim =
835 FGetFImage(
836 dpy, src, Pvisual, depth, 0, 0, in_width, in_height,
837 AllPlanes, ZPixmap)))
838 {
839 return None;
840 }
841 if (mask != None)
842 {
843 mask_fim = FGetFImage(
844 dpy, mask, Pvisual, 1, 0, 0, in_width, in_height,
845 AllPlanes, ZPixmap);
846 if (!mask_fim)
847 {
848 FDestroyFImage(dpy, mask_fim);
849 return None;
850 }
851 }
852 out_pix = XCreatePixmap(dpy, win, out_width, out_height, Pdepth);
853 out_fim = FCreateFImage(
854 dpy, Pvisual, Pdepth, ZPixmap, out_width, out_height);
855 if (gc == None)
856 {
857 gc = PictureDefaultGC(dpy, win);
858 }
859
860 if (!out_pix || !out_fim || !gc)
861 {
862 FDestroyFImage(dpy, src_fim);
863 if (mask_fim)
864 {
865 FDestroyFImage(dpy, mask_fim);
866 }
867 if (out_pix)
868 {
869 XFreePixmap(dpy, out_pix);
870 }
871 if (out_fim)
872 {
873 FDestroyFImage(dpy, out_fim);
874 }
875 return None;
876 }
877
878 colors = (XColor *)safemalloc(out_width * out_height * sizeof(XColor));
879 cm = (unsigned char *)safemalloc(out_width * out_height * sizeof(char));
880
881 x = y = 0;
882 for (j = 0; j < out_height; j++,y++)
883 {
884 if (y == in_height)
885 y = 0;
886 for (i = 0; i < out_width; i++,x++)
887 {
888 if (x == in_width)
889 x = 0;
890 if (mask_fim != NULL &&
891 (XGetPixel(mask_fim->im, x, y) == 0))
892 {
893 cm[m++] = 0;
894 }
895 else
896 {
897 cm[m++] = 255;
898 colors[k++].pixel = XGetPixel(src_fim->im, x, y);
899 }
900 }
901 }
902
903 for (i = 0; i < k; i += 256)
904 XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256));
905
906 k = 0;m = 0;
907 for (j = 0; j < out_height; j++)
908 {
909 for (i = 0; i < out_width; i++)
910 {
911
912 if (cm[m] > 0)
913 {
914 c = colors[k++];
915 PictureAllocColorAllProp(
916 Pdpy, Pcmap, &c, i, j, False, False,
917 True);
918 }
919 else
920 {
921 c.pixel = XGetPixel(src_fim->im, i, j);
922 }
923 XPutPixel(out_fim->im, i, j, c.pixel);
924 m++;
925 }
926 }
927 free(colors);
928 free(cm);
929 FDestroyFImage(dpy, src_fim);
930 if (mask_fim)
931 {
932 FDestroyFImage(dpy, mask_fim);
933 }
934 FPutFImage(
935 dpy, out_pix, gc, out_fim, 0, 0, 0, 0, out_width, out_height);
936 FDestroyFImage(dpy, out_fim);
937
938 return out_pix;
939 }
940
941 /* ---------------------------- interface functions ------------------------ */
942
PictureBitmapToPixmap(Display * dpy,Window win,Pixmap src,int depth,GC gc,int src_x,int src_y,int src_w,int src_h)943 Pixmap PictureBitmapToPixmap(
944 Display *dpy, Window win, Pixmap src, int depth, GC gc,
945 int src_x, int src_y, int src_w, int src_h)
946 {
947 Pixmap dest = None;
948
949 dest = XCreatePixmap(dpy, win, src_w, src_h, depth);
950 if (dest && gc == None)
951 {
952 gc = PictureDefaultGC(dpy, win);
953 }
954 if (dest && gc)
955 {
956 XCopyPlane(
957 dpy, src, dest, gc,
958 src_x, src_y, src_w, src_h, 0, 0, 1);
959 }
960
961 return dest;
962 }
963
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)964 void PGraphicsRenderPixmaps(
965 Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha,
966 int depth, FvwmRenderAttributes *fra, Drawable d,
967 GC gc, GC mono_gc, GC alpha_gc,
968 int src_x, int src_y, int src_w, int src_h,
969 int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat)
970 {
971 FvwmRenderAttributes t_fra;
972 Pixmap xrs_pixmap = None;
973 Pixmap xrs_mask = None;
974 Pixmap tmp_pixmap, tmp_mask;
975 Bool d_is_a_window;
976
977 t_fra.added_alpha_percent = 100;
978 t_fra.tint_percent = 0;
979 t_fra.mask = 0;
980 t_fra.tint = None;
981
982 if (fra)
983 {
984 t_fra.mask = fra->mask;
985 if (fra->mask & FRAM_HAVE_ICON_CSET)
986 {
987 t_fra.added_alpha_percent =
988 fra->colorset->icon_alpha_percent;
989 t_fra.tint_percent = fra->colorset->icon_tint_percent;
990 t_fra.tint = fra->colorset->icon_tint;
991 }
992 if (fra->mask & FRAM_HAVE_ADDED_ALPHA)
993 {
994 t_fra.added_alpha_percent = fra->added_alpha_percent;
995 }
996 if (fra->mask & FRAM_HAVE_TINT)
997 {
998 t_fra.tint_percent = fra->tint_percent;
999 t_fra.tint = fra->tint;
1000 }
1001 }
1002 if (dest_w == 0 && dest_h == 0)
1003 {
1004 dest_w = src_w; dest_h = src_h;
1005 }
1006
1007 /* use XRender only when "needed" (backing store pbs) */
1008 if (t_fra.tint_percent > 0 || t_fra.added_alpha_percent < 100
1009 || alpha != None)
1010 {
1011 /* for testing XRender simulation add && 0 */
1012 if (FRenderRender(
1013 dpy, win, pixmap, mask, alpha, depth,
1014 t_fra.added_alpha_percent, t_fra.tint,
1015 t_fra.tint_percent,
1016 d, gc, alpha_gc, src_x, src_y, src_w, src_h,
1017 dest_x, dest_y, dest_w, dest_h, do_repeat))
1018 {
1019 return;
1020 }
1021 }
1022
1023 /* no render extension or something strange happen */
1024 if (t_fra.tint_percent > 0 || t_fra.added_alpha_percent < 100
1025 || alpha != None)
1026 {
1027 int new_w, new_h, new_do_repeat;
1028
1029 d_is_a_window = !!(t_fra.mask & FRAM_DEST_IS_A_WINDOW);
1030 xrs_pixmap = PCreateRenderPixmap(
1031 dpy, win, pixmap, mask, alpha, depth,
1032 t_fra.added_alpha_percent, t_fra.tint,
1033 t_fra.tint_percent, d_is_a_window, d,
1034 gc, mono_gc, alpha_gc,
1035 src_x, src_y, src_w, src_h,
1036 dest_x, dest_y, dest_w, dest_h, do_repeat,
1037 &new_w, &new_h, &new_do_repeat, &xrs_mask);
1038 if (xrs_pixmap)
1039 {
1040 src_x = 0;
1041 src_y = 0;
1042 src_w = new_w;
1043 src_h = new_h;
1044 depth = Pdepth;
1045 do_repeat = new_do_repeat;
1046 }
1047 }
1048 tmp_pixmap = (xrs_pixmap != None)? xrs_pixmap:pixmap;
1049 tmp_mask = (xrs_mask != None)? xrs_mask:mask;
1050 if (do_repeat)
1051 {
1052 PTileRectangle(
1053 dpy, win, tmp_pixmap, tmp_mask, depth,
1054 src_x, src_y, d, gc, mono_gc, dest_x, dest_y, dest_w,
1055 dest_h);
1056 }
1057 else
1058 {
1059 PCopyArea(
1060 dpy, tmp_pixmap, tmp_mask, depth, d, gc,
1061 src_x, src_y, src_w, src_h, dest_x, dest_y);
1062 }
1063 if (xrs_pixmap)
1064 {
1065 XFreePixmap(dpy, xrs_pixmap);
1066 }
1067 if (xrs_mask)
1068 {
1069 XFreePixmap(dpy, xrs_mask);
1070 }
1071 }
1072
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)1073 void PGraphicsRenderPicture(
1074 Display *dpy, Window win, FvwmPicture *p, FvwmRenderAttributes *fra,
1075 Drawable d, GC gc, GC mono_gc, GC alpha_gc,
1076 int src_x, int src_y, int src_w, int src_h,
1077 int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat)
1078 {
1079 PGraphicsRenderPixmaps(
1080 dpy, win, p->picture, p->mask, p->alpha, p->depth, fra,
1081 d, gc, mono_gc, alpha_gc,
1082 src_x, src_y, src_w, src_h,
1083 dest_x, dest_y, dest_w, dest_h, do_repeat);
1084 }
1085
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)1086 void PGraphicsCopyPixmaps(
1087 Display *dpy, Pixmap pixmap, Pixmap mask, Pixmap alpha,
1088 int depth, Drawable d, GC gc, int src_x, int src_y, int src_w, int src_h,
1089 int dest_x, int dest_y)
1090 {
1091 PGraphicsRenderPixmaps(
1092 dpy, None, pixmap, mask, alpha, depth, 0, d, gc, None, None,
1093 src_x, src_y, src_w, src_h, dest_x, dest_y, src_w, src_h, False);
1094 }
1095
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)1096 void PGraphicsCopyFvwmPicture(
1097 Display *dpy, FvwmPicture *p, Drawable d, GC gc,
1098 int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y)
1099 {
1100 PGraphicsRenderPicture(
1101 dpy, None, p, 0, d, gc, None, None, src_x, src_y, src_w, src_h,
1102 dest_x, dest_y, src_w, src_h, False);
1103 }
1104
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)1105 void PGraphicsTileRectangle(
1106 Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha,
1107 int depth, Drawable d, GC gc, GC mono_gc,
1108 int src_x, int src_y, int src_w, int src_h,
1109 int dest_x, int dest_y, int dest_w, int dest_h)
1110 {
1111 PGraphicsRenderPixmaps(
1112 dpy, win, pixmap, mask, alpha, depth, 0, d, gc, mono_gc, None,
1113 src_x, src_y, dest_w, dest_h, dest_x, dest_y, dest_w, dest_h,
1114 True);
1115 }
1116
PGraphicsCreateStretchPicture(Display * dpy,Window win,FvwmPicture * src,int dest_width,int dest_height,GC gc,GC mono_gc,GC alpha_gc)1117 FvwmPicture *PGraphicsCreateStretchPicture(
1118 Display *dpy, Window win, FvwmPicture *src,
1119 int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc)
1120 {
1121 Pixmap pixmap = None, mask = None, alpha = None;
1122 FvwmPicture *q;
1123
1124 if (src == NULL || src->picture == None)
1125 {
1126 return NULL;
1127 }
1128 pixmap = CreateStretchPixmap(
1129 dpy, src->picture, src->width, src->height, src->depth,
1130 dest_width, dest_height, gc);
1131 if (!pixmap)
1132 {
1133 return NULL;
1134 }
1135 if (src->mask)
1136 {
1137 mask = CreateStretchPixmap(
1138 dpy, src->mask, src->width, src->height, 1,
1139 dest_width, dest_height, mono_gc);
1140 }
1141 if (src->alpha)
1142 {
1143 alpha = CreateStretchPixmap(
1144 dpy, src->alpha, src->width, src->height,
1145 FRenderGetAlphaDepth(),
1146 dest_width, dest_height, alpha_gc);
1147 }
1148
1149 q = (FvwmPicture*)safemalloc(sizeof(FvwmPicture));
1150 memset(q, 0, sizeof(FvwmPicture));
1151 q->count = 1;
1152 q->name = NULL;
1153 q->next = NULL;
1154 q->stamp = pixmap;
1155 q->picture = pixmap;
1156 q->mask = mask;
1157 q->alpha = alpha;
1158 q->width = dest_width;
1159 q->height = dest_height;
1160 q->depth = src->depth;
1161 q->alloc_pixels = 0;
1162 q->nalloc_pixels = 0;
1163
1164 return q;
1165 }
1166
PGraphicsCreateTiledPicture(Display * dpy,Window win,FvwmPicture * src,int dest_width,int dest_height,GC gc,GC mono_gc,GC alpha_gc)1167 FvwmPicture *PGraphicsCreateTiledPicture(
1168 Display *dpy, Window win, FvwmPicture *src,
1169 int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc)
1170 {
1171 Pixmap pixmap = None, mask = None, alpha = None;
1172 FvwmPicture *q;
1173
1174 if (src == NULL || src->picture == None)
1175 {
1176 return NULL;
1177 }
1178 pixmap = CreateTiledPixmap(
1179 dpy, src->picture, src->width, src->height, dest_width,
1180 dest_height, src->depth, gc);
1181 if (!pixmap)
1182 {
1183 return NULL;
1184 }
1185 if (src->mask)
1186 {
1187 mask = CreateTiledPixmap(
1188 dpy, src->mask, src->width, src->height, dest_width,
1189 dest_height, 1, mono_gc);
1190 }
1191 if (src->alpha)
1192 {
1193 alpha = CreateTiledPixmap(
1194 dpy, src->alpha, src->width, src->height, dest_width,
1195 dest_height, FRenderGetAlphaDepth(), alpha_gc);
1196 }
1197
1198 q = (FvwmPicture*)safemalloc(sizeof(FvwmPicture));
1199 memset(q, 0, sizeof(FvwmPicture));
1200 q->count = 1;
1201 q->name = NULL;
1202 q->next = NULL;
1203 q->stamp = pixmap;
1204 q->picture = pixmap;
1205 q->mask = mask;
1206 q->alpha = alpha;
1207 q->width = dest_width;
1208 q->height = dest_height;
1209 q->depth = src->depth;
1210 q->alloc_pixels = 0;
1211 q->nalloc_pixels = 0;
1212
1213 return q;
1214 }
1215
PGraphicsCreateTransparency(Display * dpy,Window win,FvwmRenderAttributes * fra,GC gc,int x,int y,int width,int height,Bool parent_relative)1216 Pixmap PGraphicsCreateTransparency(
1217 Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
1218 int x, int y, int width, int height, Bool parent_relative)
1219 {
1220 Pixmap r = None, dp = None;
1221 XID junk;
1222 XID root;
1223 int dummy, sx, sy, sw, sh;
1224 int gx = x, gy = y, gh = height, gw = width;
1225 int old_backing_store = -1;
1226
1227 if (parent_relative)
1228 {
1229 old_backing_store = FSetBackingStore(dpy, win, Always);
1230 XSetWindowBackgroundPixmap(dpy, win, ParentRelative);
1231 XClearArea(dpy, win, x, y, width, height, False);
1232 XSync(dpy, False);
1233 }
1234
1235 if (parent_relative)
1236 {
1237 /* this block is not useful if backing store ... */
1238 if (!XGetGeometry(
1239 dpy, win, &root, (int *)&junk, (int *)&junk,
1240 (unsigned int *)&sw, (unsigned int *)&sh,
1241 (unsigned int *)&junk, (unsigned int *)&junk))
1242 {
1243 goto bail;
1244 }
1245 XTranslateCoordinates(
1246 dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy, &junk);
1247 if (sx >= DisplayWidth(dpy, DefaultScreen(dpy)))
1248 {
1249 goto bail;
1250 }
1251 if (sy >= DisplayHeight(dpy, DefaultScreen(dpy)))
1252 {
1253 goto bail;
1254 }
1255 if (sx < 0)
1256 {
1257 gx = gx - sx;
1258 gw = width + sx;
1259 sx = 0;
1260 if (gw <= 0)
1261 {
1262 goto bail;
1263 }
1264 }
1265 if (sy < 0)
1266 {
1267 gy = gy - sy;
1268 gh = height + sy;
1269 sy = 0;
1270 if (gh <= 0)
1271 {
1272 goto bail;
1273 }
1274 }
1275 if (sx + gw > DisplayWidth(dpy, DefaultScreen(dpy)))
1276 {
1277 gw = DisplayWidth(dpy, DefaultScreen(dpy)) - sx;
1278 }
1279 if (sy + gh > DisplayHeight(dpy, DefaultScreen(dpy)))
1280 {
1281 gh = DisplayHeight(dpy, DefaultScreen(dpy)) - sy;
1282 }
1283 }
1284 #if 0
1285 fprintf(
1286 stderr,"Geo: %i,%i,%i,%i / %i,%i,%i,%i / %i,%i,%i,%i\n",
1287 gx,gy,gw,gh, x,y,width,height, sx,sy,sw,sh);
1288 #endif
1289 if (XRenderSupport && FRenderGetExtensionSupported())
1290 {
1291 r = XCreatePixmap(dpy, win, gw, gh, Pdepth);
1292 if (FRenderRender(
1293 dpy, win, ParentRelative, None, None, Pdepth, 100,
1294 fra->tint, fra->tint_percent, r, gc, None,
1295 gx, gy, gw, gh, 0, 0, gw, gh, False))
1296 {
1297 goto bail;
1298 }
1299 XFreePixmap(dpy, r);
1300 }
1301 r = PCreateRenderPixmap(
1302 dpy, win, ParentRelative, None, None, Pdepth, 100, fra->tint,
1303 fra->tint_percent,
1304 True, win,
1305 gc, None, None, gx, gy, gw, gh, gx, gy, gw, gh,
1306 False, &dummy, &dummy, &dummy, &dp);
1307
1308 bail:
1309 if (old_backing_store >= 0)
1310 {
1311 FSetBackingStore(dpy, win, old_backing_store);
1312 }
1313 return r;
1314 }
1315
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)1316 void PGraphicsTintRectangle(
1317 Display *dpy, Window win, Pixel tint, int tint_percent,
1318 Drawable dest, Bool dest_is_a_window, GC gc, GC mono_gc, GC alpha_gc,
1319 int dest_x, int dest_y, int dest_w, int dest_h)
1320 {
1321 Pixmap p;
1322 FvwmRenderAttributes fra;
1323
1324 #if 0
1325 /* this does not work. why? */
1326 if (FRenderTintRectangle(
1327 dpy, win, None, tint, tint_percent, dest,
1328 dest_x, dest_y, dest_w, dest_h))
1329 {
1330 return;
1331 }
1332 #else
1333
1334 if (FRenderRender(
1335 dpy, win, ParentRelative, None, None, Pdepth, 100,
1336 tint, tint_percent, win, gc, None,
1337 dest_x, dest_y, dest_w, dest_h,
1338 dest_x, dest_y, dest_w, dest_h, False))
1339 {
1340
1341 return;
1342 }
1343 #endif
1344
1345 if (dest_is_a_window)
1346 {
1347 fra.tint = tint;
1348 fra.tint_percent = tint_percent;
1349 fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT;
1350 p = PGraphicsCreateTransparency(
1351 dpy, dest, &fra, gc, dest_x, dest_y, dest_w, dest_h,
1352 False);
1353 if (p)
1354 {
1355 XCopyArea(
1356 dpy, p, dest, gc, 0, 0, dest_w, dest_h,
1357 dest_x, dest_y);
1358 XFreePixmap(dpy, p);
1359 }
1360 }
1361 }
1362
1363 #if 0 /* humm... maybe useful one day with menus */
1364 Pixmap PGraphicsCreateTranslucent(
1365 Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
1366 int x, int y, int width, int height)
1367 {
1368 Pixmap r = None;
1369 int gx = x, gy = y, gh = height, gw = width;
1370 FvwmRenderAttributes t_fra;
1371 Pixmap root_pix = None;
1372 Pixmap dp = None;
1373 int dummy;
1374
1375 t_fra.added_alpha_percent = 100;
1376 t_fra.tint_percent = 0;
1377 t_fra.tint = 0;
1378 t_fra.mask = 0;
1379
1380 if (fra)
1381 {
1382 if (fra->mask & FRAM_HAVE_TINT)
1383 {
1384 t_fra.tint_percent = fra->tint_percent;
1385 t_fra.tint = fra->tint;
1386 t_fra.mask = FRAM_HAVE_TINT;
1387 }
1388 }
1389
1390 if (x >= DisplayWidth(dpy, DefaultScreen(dpy)))
1391 {
1392 goto bail;
1393 }
1394 if (y >= DisplayHeight(dpy, DefaultScreen(dpy)))
1395 {
1396 goto bail;
1397 }
1398 if (x < 0)
1399 {
1400 gx = 0;
1401 gw = width + x;
1402 if (gw <= 0)
1403 {
1404 goto bail;
1405 }
1406 }
1407 if (y < 0)
1408 {
1409 gy = 0;
1410 gh = gh+y;
1411 if (gh <= 0)
1412 {
1413 goto bail;
1414 }
1415 }
1416 if (gx + gw > DisplayWidth(dpy, DefaultScreen(dpy)))
1417 {
1418 gw = DisplayWidth(dpy, DefaultScreen(dpy)) - gx;
1419 }
1420 if (gy + gh > DisplayHeight(dpy, DefaultScreen(dpy)))
1421 {
1422 gh = DisplayHeight(dpy, DefaultScreen(dpy)) - gy;
1423 }
1424 {
1425 /* make a screen shoot */
1426 GC my_gc;
1427 unsigned long valuemask = GCSubwindowMode;
1428 XGCValues values;
1429
1430 values.subwindow_mode = IncludeInferiors;
1431 root_pix = XCreatePixmap(dpy, win, gw, gh, Pdepth);
1432 my_gc = fvwmlib_XCreateGC(dpy, win, 0, NULL);
1433 XChangeGC(dpy, my_gc, valuemask, &values);
1434 MyXGrabServer(dpy);
1435 XCopyArea(
1436 dpy, DefaultRootWindow(dpy), root_pix, my_gc,
1437 gx, gy, gw, gh, 0, 0);
1438 MyXUngrabServer(dpy);
1439 XFreeGC(dpy,my_gc);
1440 }
1441 if (XRenderSupport && FRenderGetExtensionSupported())
1442 {
1443 r = XCreatePixmap(dpy, win, gw, gh, Pdepth);
1444 if (FRenderRender(
1445 dpy, win, root_pix, None, None, Pdepth,
1446 t_fra.added_alpha_percent, t_fra.tint,
1447 t_fra.tint_percent, r, gc, None,
1448 0, 0, gw, gh, 0, 0, gw, gh, False))
1449 {
1450 goto bail;
1451 }
1452 XFreePixmap(dpy, r);
1453 r = None;
1454 }
1455 r = PCreateRenderPixmap(
1456 dpy, win, root_pix, None, None, Pdepth, 100,
1457 fra->tint, fra->tint_percent, True, win,
1458 gc, None, None, 0, 0, gw, gh, gx, gy, gw, gh,
1459 False, &dummy, &dummy, &dummy, &dp);
1460
1461 bail:
1462 if (root_pix)
1463 {
1464 XFreePixmap(dpy, root_pix);
1465 }
1466 if (dp)
1467 {
1468 XFreePixmap(dpy, dp);
1469 }
1470 return r;
1471 }
1472 #endif
1473
1474
1475 /* 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)1476 Pixmap PGraphicsCreateDitherPixmap(
1477 Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc,
1478 int in_width, int in_height, int out_width, int out_height)
1479 {
1480 return PCreateDitherPixmap(
1481 dpy, win, src, mask, depth, gc,
1482 in_width, in_height, out_width, out_height);
1483 }
1484