Fix move command parsing.
[fvwm.git] / libs / Colorset.c
blobfb3fd47bbdb2dc305d697d9bd3335be524d3e905
1 /* -*-c-*- */
2 /* Fvwm colorset technology is Copyright (C) 1999 Joey Shutup
3 * http://www.streetmap.co.uk/streetmap.dll?Postcode2Map?BS24+9TZ
4 * You may use this code for any purpose, as long as the original copyright
5 * and this notice remains in the source code and all documentation
6 */
7 /* This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
24 #include <stdio.h>
25 #include <X11/Intrinsic.h>
27 #include "libs/fvwmlib.h"
28 #include "libs/FShape.h"
29 #include "libs/Colorset.h"
30 #include "libs/PictureBase.h"
31 #include "libs/Graphics.h"
32 #include "libs/Grab.h"
33 #include "libs/PictureGraphics.h"
34 #include "libs/XError.h"
36 /* globals */
37 colorset_t *Colorset = NULL;
38 int nColorsets = 0;
40 /* stretch the src rectangle to the dest ractangle keeping its aspect so that
41 * it fills the destination completely. */
42 static int get_aspect_dimensions(
43 int *ret_w, int *ret_h, int dest_w, int dest_h, int src_w, int src_h)
45 double ax;
46 double ay;
48 ax = (double)dest_w / (double)src_w;
49 ay = (double)dest_h / (double)src_h;
50 if (ax >= ay)
52 /* fit in x direction */
53 *ret_w = dest_w;
54 *ret_h = (src_h * dest_w) / src_w;
55 return 0;
57 else
59 /* fit in y direction */
60 *ret_w = (src_w * dest_h) / src_h;
61 *ret_h = dest_h;
62 return 1;
67 * AllocColorset() grows the size of the Colorset array to include set n
68 * colorset_t *Colorset will be altered
69 * returns the address of the member
71 void AllocColorset(int n)
73 /* do nothing if it already exists */
74 if (n < nColorsets)
76 return;
79 /* increment n to get the required array size, get a new array */
80 Colorset = (colorset_t *)saferealloc(
81 (char *)Colorset, ++n * sizeof(colorset_t));
83 /* zero out colorset 0
84 it's always defined so will be filled in during module startup */
85 if (n == 0)
87 memset(
88 &Colorset[nColorsets], 0,
89 (n - nColorsets) * sizeof(colorset_t));
91 else
93 /* copy colorset 0 into new members so that if undefined ones
94 * are referenced at least they don't give black on black */
95 for ( ; nColorsets < n; nColorsets++)
97 memcpy(
98 &Colorset[nColorsets], Colorset,
99 sizeof(colorset_t));
102 nColorsets = n;
104 return;
108 * DumpColorset() returns a char * to the colorset contents in printable form
110 static char csetbuf[256];
111 char *DumpColorset(int n, colorset_t *cs)
113 sprintf(csetbuf,
114 "Colorset "
115 "%x %lx %lx %lx %lx %lx %lx %lx %lx %lx "
116 "%x %x %x %x %x %x %x %x %x %x %x",
117 n, cs->fg, cs->bg, cs->hilite, cs->shadow, cs->fgsh, cs->tint,
118 cs->icon_tint, cs->pixmap, cs->shape_mask,
119 cs->fg_alpha_percent, cs->width, cs->height, cs->pixmap_type,
120 cs->shape_width, cs->shape_height, cs->shape_type,
121 cs->tint_percent, cs->do_dither_icon, cs->icon_tint_percent,
122 cs->icon_alpha_percent);
123 return csetbuf;
127 * LoadColorset() takes a strings and stuffs it into the array
129 int LoadColorset(char *line)
131 colorset_t *cs;
132 unsigned int n, chars;
133 Pixel fg, bg, hilite, shadow, fgsh, tint, icon_tint;
134 Pixmap pixmap;
135 Pixmap shape_mask;
136 unsigned int fg_alpha_percent, width, height, pixmap_type;
137 unsigned int shape_width, shape_height, shape_type;
138 unsigned int tint_percent, do_dither_icon, icon_tint_percent;
139 unsigned int icon_alpha_percent;
141 if (line == NULL)
143 return -1;
145 if (sscanf(line, "%x%n", &n, &chars) < 1)
147 return -1;
149 line += chars;
151 /* migo: if you modify this sscanf or other colorset definitions,
152 * please update perllib/FVWM/Tracker/Colorsets.pm too */
153 if (sscanf(line,
154 "%lx %lx %lx %lx %lx %lx %lx %lx %lx "
155 "%x %x %x %x %x %x %x %x %x %x %x",
156 &fg, &bg, &hilite, &shadow, &fgsh, &tint, &icon_tint,
157 &pixmap, &shape_mask, &fg_alpha_percent, &width, &height,
158 &pixmap_type, &shape_width, &shape_height, &shape_type,
159 &tint_percent, &do_dither_icon, &icon_tint_percent,
160 &icon_alpha_percent) != 20)
161 return -1;
163 AllocColorset(n);
164 cs = &Colorset[n];
165 cs->fg = fg;
166 cs->bg = bg;
167 cs->hilite = hilite;
168 cs->shadow = shadow;
169 cs->fgsh = fgsh;
170 cs->tint = tint;
171 cs->icon_tint = icon_tint;
172 cs->pixmap = pixmap;
173 cs->shape_mask = shape_mask;
174 cs->fg_alpha_percent = fg_alpha_percent;
175 cs->width = width;
176 cs->height = height;
177 cs->pixmap_type = pixmap_type;
178 cs->shape_width = shape_width;
179 cs->shape_height = shape_height;
180 cs->shape_type = shape_type;
181 cs->tint_percent = tint_percent;
182 cs->do_dither_icon = do_dither_icon;
183 cs->icon_tint_percent = icon_tint_percent;
184 cs->icon_alpha_percent = icon_alpha_percent;
186 return n;
189 /* scrolls a pixmap by x_off/y_off pixels, wrapping around at the edges. */
190 Pixmap ScrollPixmap(
191 Display *dpy, Pixmap p, GC gc, int x_off, int y_off, int width,
192 int height, unsigned int depth)
194 GC tgc;
195 XGCValues xgcv;
196 Pixmap p2;
198 if (p == None || p == ParentRelative || (x_off == 0 && y_off == 0))
200 return p;
202 tgc = fvwmlib_XCreateGC(dpy, p, 0, &xgcv);
203 if (tgc == None)
205 return p;
207 XCopyGC(dpy, gc, GCFunction | GCPlaneMask| GCSubwindowMode |
208 GCClipXOrigin | GCClipYOrigin | GCClipMask, tgc);
209 xgcv.tile = p;
210 xgcv.ts_x_origin = x_off;
211 xgcv.ts_y_origin = y_off;
212 xgcv.fill_style = FillTiled;
213 XChangeGC(
214 dpy, tgc, GCTile | GCTileStipXOrigin | GCTileStipYOrigin |
215 GCFillStyle, &xgcv);
216 p2 = XCreatePixmap(dpy, p, width, height, depth);
217 if (p2 == None)
219 return p;
221 XFillRectangle(dpy, p2, tgc, 0, 0, width, height);
222 XFreeGC(dpy, tgc);
224 return p2;
227 /* sets a window background from a colorset
228 * if width or height are zero the window size is queried
230 void SetWindowBackgroundWithOffset(
231 Display *dpy, Window win, int x_off, int y_off, int width, int height,
232 colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area)
234 Pixmap pixmap = None;
235 Pixmap mask = None;
236 XID junk;
238 if (0 == width || 0 == height)
240 if (!XGetGeometry(
241 dpy, win, &junk, (int *)&junk, (int *)&junk,
242 (unsigned int *)&width, (unsigned int *)&height,
243 (unsigned int *)&junk, (unsigned int *)&junk))
245 return;
249 if (FHaveShapeExtension && colorset->shape_mask)
251 mask = CreateBackgroundPixmap(
252 dpy, None, width, height, colorset, 1, None, True);
253 if (mask != None)
255 FShapeCombineMask(
256 dpy, win, FShapeBounding, 0, 0, mask,
257 FShapeSet);
258 XFreePixmap(dpy, mask);
261 if (!colorset->pixmap)
263 /* use the bg pixel */
264 XSetWindowBackground(dpy, win, colorset->bg);
265 if (clear_area)
267 XClearArea(dpy, win, 0, 0, width, height, True);
270 else
273 pixmap = CreateOffsetBackgroundPixmap(
274 dpy, win, x_off, y_off, width, height, colorset,
275 depth, gc, False);
276 if (pixmap)
278 XSetWindowBackgroundPixmap(dpy, win, pixmap);
279 if (clear_area)
281 XClearArea(dpy, win, 0, 0, width, height, True);
283 if (pixmap != ParentRelative)
285 XFreePixmap(dpy, pixmap);
290 return;
293 Bool UpdateBackgroundTransparency(
294 Display *dpy, Window win, int width, int height,
295 colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area)
297 if (!CSETS_IS_TRANSPARENT(colorset))
299 return False;
301 else if (!CSETS_IS_TRANSPARENT_PR_PURE(colorset))
303 SetWindowBackgroundWithOffset(
304 dpy, win, 0, 0, width, height, colorset, depth, gc,
305 True);
307 else
309 XClearArea(dpy, win, 0,0,0,0, clear_area);
312 return True;
315 void SetWindowBackground(
316 Display *dpy, Window win, int width, int height,
317 colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area)
319 SetWindowBackgroundWithOffset(
320 dpy, win, 0, 0, width, height, colorset, depth, gc, clear_area);
322 return;
325 void GetWindowBackgroundPixmapSize(
326 colorset_t *cs_t, int width, int height, int *w, int *h)
328 if (cs_t->pixmap == None)
330 *w = *h = 1;
332 else
334 *w = cs_t->width;
335 *h = cs_t->height;
336 switch (cs_t->pixmap_type)
338 case PIXMAP_STRETCH_ASPECT:
339 get_aspect_dimensions(
340 w, h, width, height, cs_t->width, cs_t->height);
341 break;
342 case PIXMAP_STRETCH_X:
343 *w = width;
344 break;
345 case PIXMAP_STRETCH_Y:
346 *h = height;
347 break;
348 default:
349 break;
354 static int is_bad_gc = 0;
355 static int BadGCErrorHandler(Display *dpy, XErrorEvent *error)
357 if (error->error_code == BadGC)
359 is_bad_gc = 1;
361 return 0;
363 else
365 int rc;
367 /* delegate error to original handler */
368 rc = ferror_call_next_error_handler(dpy, error);
370 return rc;
374 /* create a pixmap suitable for plonking on the background of a part of a
375 * window */
376 Pixmap CreateOffsetBackgroundPixmap(
377 Display *dpy, Window win, int x, int y, int width, int height,
378 colorset_t *colorset, unsigned int depth, GC gc, Bool is_shape_mask)
380 Pixmap pixmap = None;
381 Pixmap cs_pixmap = None;
382 XGCValues xgcv;
383 static GC shape_gc = None;
384 GC fill_gc = None; /* not static as dpy may change (FvwmBacker) */
385 int cs_width;
386 int cs_height;
387 Bool cs_keep_aspect;
388 Bool cs_stretch_x;
389 Bool cs_stretch_y;
391 if (colorset->pixmap == ParentRelative && !is_shape_mask &&
392 colorset->tint_percent > 0)
394 FvwmRenderAttributes fra;
396 fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT;
397 fra.tint = colorset->tint;
398 fra.tint_percent = colorset->tint_percent;
399 MyXGrabServer(dpy);
400 pixmap = PGraphicsCreateTransparency(
401 dpy, win, &fra, gc, x, y, width, height, True);
402 MyXUngrabServer(dpy);
403 if (pixmap == None)
405 return ParentRelative;
407 return pixmap;
409 else if (colorset->pixmap == ParentRelative && !is_shape_mask)
411 return ParentRelative;
413 else if (CSETS_IS_TRANSPARENT_ROOT(colorset) && colorset->pixmap
414 && !is_shape_mask)
416 int sx,sy;
417 int h,w;
418 XID dummy;
420 cs_pixmap = colorset->pixmap;
421 cs_width = colorset->width;
422 cs_height = colorset->height;
423 if (CSETS_IS_TRANSPARENT_ROOT_PURE(colorset))
425 /* check if it is still here */
426 XID dummy;
427 /* a priori we should grab the server, but this
428 * cause PositiveWrite error when you move a
429 * window with a transparent title bar */
430 if (!XGetGeometry(
431 dpy, colorset->pixmap, &dummy,
432 (int *)&dummy, (int *)&dummy,
433 (unsigned int *)&w, (unsigned int *)&h,
434 (unsigned int *)&dummy,
435 (unsigned int *)&dummy) ||
436 w != cs_width || h != cs_height)
438 return None;
441 XTranslateCoordinates(
442 dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy,
443 &dummy);
444 pixmap = XCreatePixmap(dpy, win, width, height, Pdepth);
445 if (!pixmap)
447 return None;
449 /* make sx and sy positif */
450 while (sx < 0)
452 sx = sx + cs_width;
454 while (sy < 0)
456 sy = sy + cs_height;
458 /* make sx and sy in (0,0,cs_width,cs_height) */
459 while (sx >= cs_width)
461 sx = sx - cs_width;
463 while (sy >= cs_height)
465 sy = sy - cs_height;
467 xgcv.fill_style = FillTiled;
468 xgcv.tile = cs_pixmap;
469 xgcv.ts_x_origin = cs_width-sx;
470 xgcv.ts_y_origin = cs_height-sy;
471 fill_gc = fvwmlib_XCreateGC(
472 dpy, win, GCTile | GCTileStipXOrigin |
473 GCTileStipYOrigin | GCFillStyle, &xgcv);
474 if (fill_gc == None)
476 XFreePixmap(dpy, pixmap);
477 return None;
479 XSync(dpy, False);
480 is_bad_gc = 0;
481 ferror_set_temp_error_handler(BadGCErrorHandler);
482 XFillRectangle(dpy, pixmap, fill_gc, 0, 0, width, height);
483 if (
484 is_bad_gc == 0 &&
485 CSETS_IS_TRANSPARENT_ROOT_PURE(colorset) &&
486 colorset->tint_percent > 0)
488 FvwmRenderAttributes fra;
490 fra.mask = FRAM_HAVE_TINT;
491 fra.tint = colorset->tint;
492 fra.tint_percent = colorset->tint_percent;
493 PGraphicsRenderPixmaps(
494 dpy, win, pixmap, None, None,
495 Pdepth, &fra, pixmap,
496 fill_gc, None, None,
497 0, 0, width, height,
498 0, 0, width, height, False);
500 XSync(dpy, False);
501 ferror_reset_temp_error_handler();
502 if (is_bad_gc == 1)
504 is_bad_gc = 0;
505 XFreePixmap(dpy, pixmap);
506 pixmap = None;
508 XFreeGC(dpy,fill_gc);
509 return pixmap;
511 if (!is_shape_mask)
513 cs_pixmap = colorset->pixmap;
514 cs_width = colorset->width;
515 cs_height = colorset->height;
516 cs_keep_aspect =
517 (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT);
518 cs_stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X)
519 || (colorset->pixmap_type == PIXMAP_STRETCH);
520 cs_stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y)
521 || (colorset->pixmap_type == PIXMAP_STRETCH);
523 else
525 /* In spite of the name, win contains the pixmap */
526 cs_pixmap = colorset->shape_mask;
527 win = colorset->shape_mask;
528 if (shape_gc == None)
530 xgcv.foreground = 1;
531 xgcv.background = 0;
532 /* create a gc for 1 bit depth */
533 shape_gc = fvwmlib_XCreateGC(
534 dpy, win, GCForeground|GCBackground, &xgcv);
536 gc = shape_gc;
537 cs_width = colorset->shape_width;
538 cs_height = colorset->shape_height;
539 cs_keep_aspect = (colorset->shape_type == SHAPE_STRETCH_ASPECT);
540 cs_stretch_x = !(colorset->shape_type == SHAPE_TILED);
541 cs_stretch_y = !(colorset->shape_type == SHAPE_TILED);
544 if (cs_pixmap == None)
546 xgcv.foreground = colorset->bg;
547 fill_gc = fvwmlib_XCreateGC(dpy, win, GCForeground, &xgcv);
548 /* create a solid pixmap - not very useful most of the time */
549 pixmap = XCreatePixmap(dpy, win, 1, 1, depth);
550 XFillRectangle(dpy, pixmap, fill_gc, 0, 0, 1, 1);
551 XFreeGC(dpy,fill_gc);
553 else if (cs_keep_aspect)
555 Bool trim_side;
556 int big_width, big_height;
557 Pixmap big_pixmap;
558 int x, y;
560 /* make a pixmap big enough to cover the destination but with
561 * the aspect ratio of the cs_pixmap */
562 trim_side = get_aspect_dimensions(
563 &big_width, &big_height, width, height, cs_width,
564 cs_height);
565 big_pixmap = CreateStretchPixmap(
566 dpy, cs_pixmap, cs_width, cs_height, depth, big_width,
567 big_height, gc);
569 /* work out where to trim */
570 x = trim_side ? (big_width - width) / 2 : 0;
571 y = trim_side ? 0 : (big_height - height) / 2;
573 pixmap = XCreatePixmap(dpy, cs_pixmap, width, height, depth);
574 if (pixmap && big_pixmap)
576 XCopyArea(
577 dpy, big_pixmap, pixmap, gc, x, y, width,
578 height, 0, 0);
580 if (big_pixmap)
582 XFreePixmap(dpy, big_pixmap);
585 else if (!cs_stretch_x && !cs_stretch_y)
587 /* it's a tiled pixmap, create an unstretched one */
588 if (!is_shape_mask)
590 pixmap = XCreatePixmap(
591 dpy, cs_pixmap, cs_width, cs_height, depth);
592 if (pixmap)
594 XCopyArea(
595 dpy, cs_pixmap, pixmap, gc, 0, 0,
596 cs_width, cs_height, 0, 0);
599 else
601 /* can't tile masks, create a tiled version of the
602 * mask */
603 pixmap = CreateTiledPixmap(
604 dpy, cs_pixmap, cs_width, cs_height, width,
605 height, 1, gc);
608 else if (!cs_stretch_x)
610 /* it's an HGradient */
611 pixmap = CreateStretchYPixmap(
612 dpy, cs_pixmap, cs_width, cs_height, depth, height, gc);
614 else if (!cs_stretch_y)
616 /* it's a VGradient */
617 pixmap = CreateStretchXPixmap(
618 dpy, cs_pixmap, cs_width, cs_height, depth, width, gc);
620 else
622 /* It's a full window pixmap */
623 pixmap = CreateStretchPixmap(
624 dpy, cs_pixmap, cs_width, cs_height, depth, width,
625 height, gc);
628 if (x != 0 || y != 0)
630 Pixmap p2;
632 p2 = ScrollPixmap(
633 dpy, pixmap, gc, x, y, width, height,
634 depth);
635 if (p2 != None && p2 != ParentRelative && p2 != pixmap)
637 XFreePixmap(dpy, pixmap);
638 pixmap = p2;
642 return pixmap;
645 /* create a pixmap suitable for plonking on the background of a window */
646 Pixmap CreateBackgroundPixmap(Display *dpy, Window win, int width, int height,
647 colorset_t *colorset, unsigned int depth,
648 GC gc, Bool is_shape_mask)
650 return CreateOffsetBackgroundPixmap(
651 dpy, win, 0, 0, width, height, colorset, depth, gc,
652 is_shape_mask);
655 /* Draws a colorset background into the specified rectangle in the target
656 * drawable. */
657 void SetRectangleBackground(
658 Display *dpy, Window win, int x, int y, int width, int height,
659 colorset_t *colorset, unsigned int depth, GC gc)
661 SetClippedRectangleBackground(
662 dpy, win, x, y, width, height, NULL, colorset, depth, gc);
664 return;
667 /* Draws a colorset background into the specified rectangle in the target
668 * drawable. */
669 void SetClippedRectangleBackground(
670 Display *dpy, Window win, int x, int y, int width, int height,
671 XRectangle *clip, colorset_t *colorset,
672 unsigned int depth, GC gc)
674 GC draw_gc;
675 Pixmap pixmap2;
676 Pixmap pixmap = None;
677 static int last_depth = -1;
678 static GC last_gc = None;
679 XGCValues xgcv;
680 Pixmap clipmask = None;
681 GC clip_gc = None;
682 Bool keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT);
683 Bool stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X)
684 || (colorset->pixmap_type == PIXMAP_STRETCH);
685 Bool stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y)
686 || (colorset->pixmap_type == PIXMAP_STRETCH);
687 int dest_x, dest_y, dest_w, dest_h;
689 if (clip)
691 dest_x = clip->x;
692 dest_y = clip->y;
693 dest_w = clip->width;
694 dest_h = clip->height;
696 else
698 dest_x = x;
699 dest_y = y;
700 dest_w = width;
701 dest_h = height;
703 if (CSETS_IS_TRANSPARENT_PR_TINT(colorset))
705 XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False);
706 PGraphicsTintRectangle(
707 dpy, win, colorset->tint, colorset->tint_percent,
708 win, True, gc, None, None,
709 dest_x, dest_y, dest_w, dest_h);
710 return;
712 if (CSETS_IS_TRANSPARENT_PR_PURE(colorset))
714 XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False);
715 /* don't do anything */
716 return;
718 if (CSETS_IS_TRANSPARENT_ROOT(colorset))
720 /* FIXME: optimize this ! */
721 x = y = 0;
722 width = width + dest_x;
723 height = height + dest_y;
725 /* minimize gc creation by remembering the last requested depth */
726 if (last_gc != None && depth != last_depth)
728 XFreeGC(dpy, last_gc);
729 last_gc = None;
731 if (last_gc == None)
733 last_gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv);
735 draw_gc = last_gc;
736 last_depth = depth;
738 if (FHaveShapeExtension && colorset->shape_mask != None)
740 clipmask = CreateBackgroundPixmap(
741 dpy, 0, width, height, colorset, 1, None, True);
742 if (clipmask)
744 /* create a GC for clipping */
745 xgcv.clip_x_origin = x;
746 xgcv.clip_y_origin = y;
747 xgcv.clip_mask = clipmask;
748 clip_gc = fvwmlib_XCreateGC(
749 dpy, win, GCClipXOrigin | GCClipYOrigin |
750 GCClipMask, &xgcv);
751 draw_gc = clip_gc;
755 if (!colorset->pixmap)
757 /* use the bg pixel */
758 XSetForeground(dpy, draw_gc, colorset->bg);
759 XFillRectangle(
760 dpy, win, draw_gc, dest_x, dest_y, dest_w, dest_h);
762 else
764 pixmap = CreateBackgroundPixmap(
765 dpy, win, width, height, colorset, depth, gc, False);
766 if (keep_aspect)
768 /* nothing to do */
770 if (stretch_x || stretch_y)
772 if (!stretch_x && colorset->width != width)
774 pixmap2 = CreateStretchXPixmap(
775 dpy, pixmap, colorset->width, height,
776 depth, width, gc);
777 XFreePixmap(dpy, pixmap);
778 pixmap = pixmap2;
780 if (!stretch_y && colorset->height != height)
782 pixmap2 = CreateStretchYPixmap(
783 dpy, pixmap, width, colorset->height,
784 depth, height, gc);
785 XFreePixmap(dpy, pixmap);
786 pixmap = pixmap2;
789 else
791 pixmap2 = CreateTiledPixmap(
792 dpy, pixmap, colorset->width, colorset->height,
793 width, height, depth, gc);
794 XFreePixmap(dpy, pixmap);
795 pixmap = pixmap2;
798 if (pixmap)
800 /* Copy the pixmap into the rectangle. */
801 XCopyArea(
802 dpy, pixmap, win, draw_gc,
803 dest_x - x, dest_y - y, dest_w, dest_h,
804 dest_x, dest_y);
805 XFreePixmap(dpy, pixmap);
809 if (FHaveShapeExtension)
811 if (clipmask != None)
813 XFreePixmap(dpy, clipmask);
815 if (clip_gc != None)
817 XFreeGC(dpy, clip_gc);
821 return;