Updating to version 0.20.2
[wmaker-crm.git] / wrlib / xpixmap.c
blob9288523099b3085a1ad13259da365a8a6e2e1b98
1 /* xpixmap.c - Make RImage from Pixmap or XImage
2 *
3 * Raster graphics library
5 * Copyright (c) 1997 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library 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 GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <config.h>
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <assert.h>
32 #include "wraster.h"
36 static int
37 get_shifts(unsigned long mask)
39 int i=0;
41 while (mask) {
42 mask>>=1;
43 i++;
45 return i;
49 RImage*
50 RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
52 RImage *img;
53 int x, y;
54 unsigned long pixel;
55 unsigned char *r, *g, *b, *a;
56 int rshift, gshift, bshift;
57 int rmask, gmask, bmask;
59 assert(image!=NULL);
60 assert(image->format==ZPixmap);
61 assert(!mask || mask->format==ZPixmap);
63 img = RCreateImage(image->width, image->height, mask!=NULL);
64 if (!img) {
65 return NULL;
69 /* I don't know why, but XGetImage() for pixmaps don't set the
70 * {red,green,blue}_mask values correctly.
71 */
72 if (context->depth==image->depth) {
73 rmask = context->visual->red_mask;
74 gmask = context->visual->green_mask;
75 bmask = context->visual->blue_mask;
76 } else {
77 rmask = image->red_mask;
78 gmask = image->green_mask;
79 bmask = image->blue_mask;
82 /* how many bits to shift to normalize the color into 8bpp */
83 rshift = get_shifts(rmask) - 8;
84 gshift = get_shifts(gmask) - 8;
85 bshift = get_shifts(bmask) - 8;
87 r = img->data[0];
88 g = img->data[1];
89 b = img->data[2];
90 a = img->data[3];
92 #define NORMALIZE_RED(pixel) ((rshift>0) ? ((pixel) & rmask) >> rshift \
93 : ((pixel) & rmask) << -rshift)
94 #define NORMALIZE_GREEN(pixel) ((gshift>0) ? ((pixel) & gmask) >> gshift \
95 : ((pixel) & gmask) << -gshift)
96 #define NORMALIZE_BLUE(pixel) ((bshift>0) ? ((pixel) & bmask) >> bshift \
97 : ((pixel) & bmask) << -bshift)
99 if (image->depth==1) {
100 for (y = 0; y < image->height; y++) {
101 for (x = 0; x < image->width; x++) {
102 pixel = XGetPixel(image, x, y);
103 if (pixel) {
104 *(r++) = *(g++) = *(b++) = 0;
105 } else {
106 *(r++) = *(g++) = *(b++) = 0xff;
110 } else {
111 for (y = 0; y < image->height; y++) {
112 for (x = 0; x < image->width; x++) {
113 pixel = XGetPixel(image, x, y);
114 *(r++) = NORMALIZE_RED(pixel);
115 *(g++) = NORMALIZE_GREEN(pixel);
116 *(b++) = NORMALIZE_BLUE(pixel);
121 if (mask && a) {
122 for (y = 0; y < mask->height; y++) {
123 for (x = 0; x < mask->width; x++) {
124 if (XGetPixel(mask, x, y)) {
125 *(a++) = 0xff;
126 } else {
127 *(a++) = 0;
132 return img;
137 RImage*
138 RCreateImageFromDrawable(RContext *context, Drawable drawable, Pixmap mask)
140 RImage *image;
141 XImage *pimg, *mimg;
142 unsigned int w, h, bar;
143 int foo;
144 Window baz;
147 assert(drawable!=None);
149 if (!XGetGeometry(context->dpy, drawable, &baz, &foo, &foo,
150 &w, &h, &bar, &bar)) {
151 printf("wrlib:invalid window or pixmap passed to RCreateImageFromPixmap\n");
152 return NULL;
154 pimg = XGetImage(context->dpy, drawable, 0, 0, w, h, AllPlanes,
155 ZPixmap);
157 if (!pimg) {
158 RErrorCode = RERR_XERROR;
159 return NULL;
161 mimg = NULL;
162 if (mask) {
163 if (XGetGeometry(context->dpy, mask, &baz, &foo, &foo,
164 &w, &h, &bar, &bar)) {
165 mimg = XGetImage(context->dpy, mask, 0, 0, w, h, AllPlanes,
166 ZPixmap);
170 image = RCreateImageFromXImage(context, pimg, mimg);
172 XDestroyImage(pimg);
173 if (mimg)
174 XDestroyImage(mimg);
176 return image;