wmaker: Replaced local 'extern' definition of wPreferences by proper header usage
[wmaker-crm.git] / wrlib / xpixmap.c
blob14bed08f59cd932e722016f04391882ecf4c8fbc
1 /* xpixmap.c - Make RImage from Pixmap or XImage
3 * Raster graphics library
5 * Copyright (c) 1997-2003 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., 51 Franklin St, Fifth Floor, Boston,
20 * MA 02110-1301, 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"
34 static int get_shifts(unsigned long mask)
36 int i = 0;
38 while (mask) {
39 mask >>= 1;
40 i++;
42 return i;
45 #define NORMALIZE_RED(pixel) ((rshift>0) ? ((pixel) & rmask) >> rshift \
46 : ((pixel) & rmask) << -rshift)
47 #define NORMALIZE_GREEN(pixel) ((gshift>0) ? ((pixel) & gmask) >> gshift \
48 : ((pixel) & gmask) << -gshift)
49 #define NORMALIZE_BLUE(pixel) ((bshift>0) ? ((pixel) & bmask) >> bshift \
50 : ((pixel) & bmask) << -bshift)
52 RImage *RCreateImageFromXImage(RContext * context, XImage * image, XImage * mask)
54 RImage *img;
55 int x, y;
56 unsigned long pixel;
57 unsigned char *data;
58 int rshift, gshift, bshift;
59 int rmask, gmask, bmask;
61 assert(image != NULL);
62 assert(image->format == ZPixmap);
63 assert(!mask || mask->format == ZPixmap);
65 img = RCreateImage(image->width, image->height, mask != NULL);
66 if (!img) {
67 return NULL;
70 /* I don't know why, but XGetImage() for pixmaps don't set the
71 * {red,green,blue}_mask values correctly.
73 if (context->depth == image->depth) {
74 rmask = context->visual->red_mask;
75 gmask = context->visual->green_mask;
76 bmask = context->visual->blue_mask;
77 } else {
78 rmask = image->red_mask;
79 gmask = image->green_mask;
80 bmask = image->blue_mask;
83 /* how many bits to shift to normalize the color into 8bpp */
84 rshift = get_shifts(rmask) - 8;
85 gshift = get_shifts(gmask) - 8;
86 bshift = get_shifts(bmask) - 8;
88 data = img->data;
90 if (image->depth == 1) {
91 for (y = 0; y < image->height; y++) {
92 for (x = 0; x < image->width; x++) {
93 pixel = XGetPixel(image, x, y);
94 if (pixel) {
95 *data++ = 0;
96 *data++ = 0;
97 *data++ = 0;
98 } else {
99 *data++ = 0xff;
100 *data++ = 0xff;
101 *data++ = 0xff;
103 if (mask)
104 data++;
107 } else {
108 for (y = 0; y < image->height; y++) {
109 for (x = 0; x < image->width; x++) {
110 pixel = XGetPixel(image, x, y);
111 *(data++) = NORMALIZE_RED(pixel);
112 *(data++) = NORMALIZE_GREEN(pixel);
113 *(data++) = NORMALIZE_BLUE(pixel);
114 if (mask)
115 data++;
120 #define MIN(a,b) ((a)<(b)?(a):(b))
121 if (mask) {
122 data = img->data + 3; /* Skip R, G & B */
123 for (y = 0; y < MIN(mask->height, image->height); y++) {
124 for (x = 0; x < MIN(mask->width, image->width); x++) {
125 if (mask->width <= image->width && XGetPixel(mask, x, y)) {
126 *data = 0xff;
127 } else {
128 *data = 0;
130 data += 4;
132 for (; x < image->width; x++) {
133 *data = 0;
134 data += 4;
137 for (; y < image->height; y++) {
138 for (x = 0; x < image->width; x++) {
139 *data = 0;
140 data += 4;
144 return img;
147 RImage *RCreateImageFromDrawable(RContext * context, Drawable drawable, Pixmap mask)
149 RImage *image;
150 XImage *pimg, *mimg;
151 unsigned int w, h, bar;
152 int foo;
153 Window baz;
155 assert(drawable != None);
157 if (!XGetGeometry(context->dpy, drawable, &baz, &foo, &foo, &w, &h, &bar, &bar)) {
158 printf("wrlib: invalid window or pixmap passed to RCreateImageFromPixmap\n");
159 return NULL;
161 pimg = XGetImage(context->dpy, drawable, 0, 0, w, h, AllPlanes, ZPixmap);
163 if (!pimg) {
164 RErrorCode = RERR_XERROR;
165 return NULL;
167 mimg = NULL;
168 if (mask) {
169 if (XGetGeometry(context->dpy, mask, &baz, &foo, &foo, &w, &h, &bar, &bar)) {
170 mimg = XGetImage(context->dpy, mask, 0, 0, w, h, AllPlanes, ZPixmap);
174 image = RCreateImageFromXImage(context, pimg, mimg);
176 XDestroyImage(pimg);
177 if (mimg)
178 XDestroyImage(mimg);
180 return image;