Update Serbian translation from master branch
[wmaker-crm.git] / wrlib / xpixmap.c
blob9cb95257ed35fc2ac33637a3d4932c7687d4ce76
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"
33 #include "wr_i18n.h"
36 static int get_shifts(unsigned long mask)
38 int i = 0;
40 while (mask) {
41 mask >>= 1;
42 i++;
44 return i;
47 #define NORMALIZE_RED(pixel) ((rshift>0) ? ((pixel) & rmask) >> rshift \
48 : ((pixel) & rmask) << -rshift)
49 #define NORMALIZE_GREEN(pixel) ((gshift>0) ? ((pixel) & gmask) >> gshift \
50 : ((pixel) & gmask) << -gshift)
51 #define NORMALIZE_BLUE(pixel) ((bshift>0) ? ((pixel) & bmask) >> bshift \
52 : ((pixel) & bmask) << -bshift)
54 RImage *RCreateImageFromXImage(RContext * context, XImage * image, XImage * mask)
56 RImage *img;
57 int x, y;
58 unsigned long pixel;
59 unsigned char *data;
60 int rshift, gshift, bshift;
61 int rmask, gmask, bmask;
63 assert(image != NULL);
64 assert(image->format == ZPixmap);
65 assert(!mask || mask->format == ZPixmap);
67 img = RCreateImage(image->width, image->height, mask != NULL);
68 if (!img) {
69 return NULL;
72 /* I don't know why, but XGetImage() for pixmaps don't set the
73 * {red,green,blue}_mask values correctly.
75 if (context->depth == image->depth) {
76 rmask = context->visual->red_mask;
77 gmask = context->visual->green_mask;
78 bmask = context->visual->blue_mask;
79 } else {
80 rmask = image->red_mask;
81 gmask = image->green_mask;
82 bmask = image->blue_mask;
85 /* how many bits to shift to normalize the color into 8bpp */
86 rshift = get_shifts(rmask) - 8;
87 gshift = get_shifts(gmask) - 8;
88 bshift = get_shifts(bmask) - 8;
90 data = img->data;
92 if (image->depth == 1) {
93 for (y = 0; y < image->height; y++) {
94 for (x = 0; x < image->width; x++) {
95 pixel = XGetPixel(image, x, y);
96 if (pixel) {
97 *data++ = 0;
98 *data++ = 0;
99 *data++ = 0;
100 } else {
101 *data++ = 0xff;
102 *data++ = 0xff;
103 *data++ = 0xff;
105 if (mask)
106 data++;
109 } else {
110 for (y = 0; y < image->height; y++) {
111 for (x = 0; x < image->width; x++) {
112 pixel = XGetPixel(image, x, y);
113 *(data++) = NORMALIZE_RED(pixel);
114 *(data++) = NORMALIZE_GREEN(pixel);
115 *(data++) = NORMALIZE_BLUE(pixel);
116 if (mask)
117 data++;
122 #define MIN(a,b) ((a)<(b)?(a):(b))
123 if (mask) {
124 data = img->data + 3; /* Skip R, G & B */
125 for (y = 0; y < MIN(mask->height, image->height); y++) {
126 for (x = 0; x < MIN(mask->width, image->width); x++) {
127 if (mask->width <= image->width && XGetPixel(mask, x, y)) {
128 *data = 0xff;
129 } else {
130 *data = 0;
132 data += 4;
134 for (; x < image->width; x++) {
135 *data = 0;
136 data += 4;
139 for (; y < image->height; y++) {
140 for (x = 0; x < image->width; x++) {
141 *data = 0;
142 data += 4;
146 return img;
149 RImage *RCreateImageFromDrawable(RContext * context, Drawable drawable, Pixmap mask)
151 RImage *image;
152 XImage *pimg, *mimg;
153 unsigned int w, h, bar;
154 int foo;
155 Window baz;
157 assert(drawable != None);
159 if (!XGetGeometry(context->dpy, drawable, &baz, &foo, &foo, &w, &h, &bar, &bar)) {
160 fprintf(stderr, _("wrlib: invalid window or pixmap passed to RCreateImageFromDrawable\n"));
161 return NULL;
163 pimg = XGetImage(context->dpy, drawable, 0, 0, w, h, AllPlanes, ZPixmap);
165 if (!pimg) {
166 RErrorCode = RERR_XERROR;
167 return NULL;
169 mimg = NULL;
170 if (mask) {
171 if (XGetGeometry(context->dpy, mask, &baz, &foo, &foo, &w, &h, &bar, &bar)) {
172 mimg = XGetImage(context->dpy, mask, 0, 0, w, h, AllPlanes, ZPixmap);
176 image = RCreateImageFromXImage(context, pimg, mimg);
178 XDestroyImage(pimg);
179 if (mimg)
180 XDestroyImage(mimg);
182 return image;