make icons use pixel32 data, and image_draw takes pixel32 data.
client.c gets pixmap icons as a backup to netwm ones, and they are converted into pixel32 data.
This commit is contained in:
parent
f41d06f583
commit
a18c1697b1
7 changed files with 255 additions and 36 deletions
|
@ -1142,6 +1142,9 @@ void client_update_wmhints(Client *self)
|
||||||
it->data);
|
it->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the WM_HINTS can contain an icon */
|
||||||
|
client_update_icons(self);
|
||||||
|
|
||||||
/* because the self->transient flag wont change from this call,
|
/* because the self->transient flag wont change from this call,
|
||||||
we don't need to update the window's type and such, only its
|
we don't need to update the window's type and such, only its
|
||||||
transient_for, and the transients lists of other windows in
|
transient_for, and the transients lists of other windows in
|
||||||
|
@ -1317,11 +1320,23 @@ void client_update_icons(Client *self)
|
||||||
/* store the icons */
|
/* store the icons */
|
||||||
i = 0;
|
i = 0;
|
||||||
for (j = 0; j < self->nicons; ++j) {
|
for (j = 0; j < self->nicons; ++j) {
|
||||||
|
guint x, y, t;
|
||||||
|
|
||||||
w = self->icons[j].width = data[i++];
|
w = self->icons[j].width = data[i++];
|
||||||
h = self->icons[j].height = data[i++];
|
h = self->icons[j].height = data[i++];
|
||||||
self->icons[j].data =
|
|
||||||
g_memdup(&data[i], w * h * sizeof(gulong));
|
self->icons[j].data = g_new(pixel32, w * h);
|
||||||
i += w * h;
|
for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) {
|
||||||
|
if (x >= w) {
|
||||||
|
x = 0;
|
||||||
|
++y;
|
||||||
|
}
|
||||||
|
self->icons[j].data[t] =
|
||||||
|
(((data[i] >> 24) & 0xff) << default_alpha_offset) +
|
||||||
|
(((data[i] >> 16) & 0xff) << default_red_offset) +
|
||||||
|
(((data[i] >> 8) & 0xff) << default_green_offset) +
|
||||||
|
(((data[i] >> 0) & 0xff) << default_blue_offset);
|
||||||
|
}
|
||||||
g_assert(i <= num);
|
g_assert(i <= num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1331,13 +1346,34 @@ void client_update_icons(Client *self)
|
||||||
if (num == 2) {
|
if (num == 2) {
|
||||||
self->nicons++;
|
self->nicons++;
|
||||||
self->icons = g_new(Icon, self->nicons);
|
self->icons = g_new(Icon, self->nicons);
|
||||||
/* XXX WHAT IF THIS FAILS YOU TWIT!@!*()@ */
|
if (!render_pixmap_to_rgba(data[0], data[1],
|
||||||
render_pixmap_to_rgba(data[0], data[1],
|
|
||||||
&self->icons[self->nicons-1].width,
|
&self->icons[self->nicons-1].width,
|
||||||
&self->icons[self->nicons-1].height,
|
&self->icons[self->nicons-1].height,
|
||||||
&self->icons[self->nicons-1].data);
|
&self->icons[self->nicons-1].data)) {
|
||||||
|
g_free(&self->icons[self->nicons-1]);
|
||||||
|
self->nicons--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
} else {
|
||||||
|
XWMHints *hints;
|
||||||
|
|
||||||
|
if ((hints = XGetWMHints(ob_display, self->window))) {
|
||||||
|
if (hints->flags & IconPixmapHint) {
|
||||||
|
self->nicons++;
|
||||||
|
self->icons = g_new(Icon, self->nicons);
|
||||||
|
if (!render_pixmap_to_rgba(hints->icon_pixmap,
|
||||||
|
(hints->flags & IconMaskHint ?
|
||||||
|
hints->icon_mask : None),
|
||||||
|
&self->icons[self->nicons-1].width,
|
||||||
|
&self->icons[self->nicons-1].height,
|
||||||
|
&self->icons[self->nicons-1].data)){
|
||||||
|
g_free(&self->icons[self->nicons-1]);
|
||||||
|
self->nicons--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(hints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->frame)
|
if (self->frame)
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "geom.h"
|
#include "geom.h"
|
||||||
#include "stacking.h"
|
#include "stacking.h"
|
||||||
|
#include "render/color.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
@ -16,7 +18,7 @@ struct Group;
|
||||||
/*! Holds an icon in ARGB format */
|
/*! Holds an icon in ARGB format */
|
||||||
typedef struct Icon {
|
typedef struct Icon {
|
||||||
int width, height;
|
int width, height;
|
||||||
gulong *data;
|
pixel32 *data;
|
||||||
} Icon;
|
} Icon;
|
||||||
|
|
||||||
/*! The MWM Hints as retrieved from the window property
|
/*! The MWM Hints as retrieved from the window property
|
||||||
|
|
135
render/color.c
135
render/color.c
|
@ -1,5 +1,6 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include <string.h>
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "../kernel/openbox.h"
|
#include "../kernel/openbox.h"
|
||||||
|
@ -82,9 +83,9 @@ void reduce_depth(pixel32 *data, XImage *im)
|
||||||
r = (data[x] >> default_red_offset) & 0xFF;
|
r = (data[x] >> default_red_offset) & 0xFF;
|
||||||
g = (data[x] >> default_green_offset) & 0xFF;
|
g = (data[x] >> default_green_offset) & 0xFF;
|
||||||
b = (data[x] >> default_blue_offset) & 0xFF;
|
b = (data[x] >> default_blue_offset) & 0xFF;
|
||||||
p32[x] = (r << render_red_offset)
|
p32[x] = (r << render_red_shift)
|
||||||
+ (g << render_green_offset)
|
+ (g << render_green_shift)
|
||||||
+ (b << render_blue_offset);
|
+ (b << render_blue_shift);
|
||||||
}
|
}
|
||||||
data += im->width;
|
data += im->width;
|
||||||
p32 += im->width;
|
p32 += im->width;
|
||||||
|
@ -125,6 +126,7 @@ void reduce_depth(pixel32 *data, XImage *im)
|
||||||
g_message("your bit depth is currently unhandled\n");
|
g_message("your bit depth is currently unhandled\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XColor *pickColor(int r, int g, int b)
|
XColor *pickColor(int r, int g, int b)
|
||||||
{
|
{
|
||||||
r = (r & 0xff) >> (8-pseudo_bpc);
|
r = (r & 0xff) >> (8-pseudo_bpc);
|
||||||
|
@ -132,3 +134,130 @@ XColor *pickColor(int r, int g, int b)
|
||||||
b = (b & 0xff) >> (8-pseudo_bpc);
|
b = (b & 0xff) >> (8-pseudo_bpc);
|
||||||
return &pseudo_colors[(r << (2*pseudo_bpc)) + (g << (1*pseudo_bpc)) + b];
|
return &pseudo_colors[(r << (2*pseudo_bpc)) + (g << (1*pseudo_bpc)) + b];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void swap_byte_order(XImage *im)
|
||||||
|
{
|
||||||
|
int x, y, di;
|
||||||
|
|
||||||
|
g_message("SWAPPING BYTE ORDER");
|
||||||
|
|
||||||
|
di = 0;
|
||||||
|
for (y = 0; y < im->height; ++y) {
|
||||||
|
for (x = 0; x < im->height; ++x) {
|
||||||
|
char *c = &im->data[di + x * im->bits_per_pixel / 8];
|
||||||
|
char t;
|
||||||
|
|
||||||
|
switch (im->bits_per_pixel) {
|
||||||
|
case 32:
|
||||||
|
t = c[2];
|
||||||
|
c[2] = c[3];
|
||||||
|
c[3] = t;
|
||||||
|
case 16:
|
||||||
|
t = c[0];
|
||||||
|
c[0] = c[1];
|
||||||
|
c[1] = t;
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_message("your bit depth is currently unhandled\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
di += im->bytes_per_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (im->byte_order == LSBFirst)
|
||||||
|
im->byte_order = MSBFirst;
|
||||||
|
else
|
||||||
|
im->byte_order = LSBFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increase_depth(pixel32 *data, XImage *im)
|
||||||
|
{
|
||||||
|
int r, g, b;
|
||||||
|
int x,y;
|
||||||
|
pixel32 *p32 = (pixel32 *) im->data;
|
||||||
|
pixel16 *p16 = (pixel16 *) im->data;
|
||||||
|
unsigned char *p8 = (unsigned char *)im->data;
|
||||||
|
|
||||||
|
if (im->byte_order != render_endian)
|
||||||
|
swap_byte_order(im);
|
||||||
|
|
||||||
|
switch (im->bits_per_pixel) {
|
||||||
|
case 32:
|
||||||
|
for (y = 0; y < im->height; y++) {
|
||||||
|
for (x = 0; x < im->width; x++) {
|
||||||
|
r = (p32[x] >> render_red_offset) & 0xff;
|
||||||
|
g = (p32[x] >> render_green_offset) & 0xff;
|
||||||
|
b = (p32[x] >> render_blue_offset) & 0xff;
|
||||||
|
data[x] = (r << default_red_offset)
|
||||||
|
+ (g << default_green_offset)
|
||||||
|
+ (b << default_blue_offset)
|
||||||
|
+ (0xff << default_alpha_offset);
|
||||||
|
}
|
||||||
|
data += im->width;
|
||||||
|
p32 += im->bytes_per_line/4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
for (y = 0; y < im->height; y++) {
|
||||||
|
for (x = 0; x < im->width; x++) {
|
||||||
|
r = (p16[x] & render_red_mask) >> render_red_offset <<
|
||||||
|
render_red_shift;
|
||||||
|
g = (p16[x] & render_green_mask) >> render_green_offset <<
|
||||||
|
render_green_shift;
|
||||||
|
b = (p16[x] & render_blue_mask) >> render_blue_offset <<
|
||||||
|
render_blue_shift;
|
||||||
|
data[x] = (r << default_red_offset)
|
||||||
|
+ (g << default_green_offset)
|
||||||
|
+ (b << default_blue_offset)
|
||||||
|
+ (0xff << default_alpha_offset);
|
||||||
|
}
|
||||||
|
data += im->width;
|
||||||
|
p16 += im->bytes_per_line/2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
g_assert(render_visual->class != TrueColor);
|
||||||
|
for (y = 0; y < im->height; y++) {
|
||||||
|
for (x = 0; x < im->width; x++) {
|
||||||
|
XColor icolor;
|
||||||
|
int ii, r, g, b;
|
||||||
|
gulong dev, closest = 0xffffffff, close = 0;
|
||||||
|
|
||||||
|
icolor.pixel = p8[x];
|
||||||
|
XQueryColor(ob_display, render_colormap, &icolor);
|
||||||
|
|
||||||
|
/* find the nearest color match */
|
||||||
|
for (ii = 0; ii < pseudo_ncolors(); ii++) {
|
||||||
|
/* find deviations */
|
||||||
|
r = (pseudo_colors[ii].red - icolor.red) & 0xff;
|
||||||
|
g = (pseudo_colors[ii].green - icolor.green) & 0xff;
|
||||||
|
b = (pseudo_colors[ii].blue - icolor.blue) & 0xff;
|
||||||
|
/* find a weighted absolute deviation */
|
||||||
|
dev = (r * r) * (0xff - (icolor.red & 0xff)) +
|
||||||
|
(g * g) * (0xff - (icolor.green & 0xff)) +
|
||||||
|
(b * b) * (0xff - (icolor.blue & 0xff));
|
||||||
|
|
||||||
|
if (dev < closest) {
|
||||||
|
closest = dev;
|
||||||
|
close = ii;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data[x] =
|
||||||
|
(pseudo_colors[close].red & 0xff <<
|
||||||
|
default_red_offset) +
|
||||||
|
(pseudo_colors[close].green & 0xff <<
|
||||||
|
default_green_offset) +
|
||||||
|
(pseudo_colors[close].blue & 0xff <<
|
||||||
|
default_blue_offset) +
|
||||||
|
(0xff << default_alpha_offset);
|
||||||
|
}
|
||||||
|
data += im->width;
|
||||||
|
p8 += im->bytes_per_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_message("your bit depth is currently unhandled\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -25,12 +25,14 @@ typedef u_int16_t pixel16;
|
||||||
#define default_red_offset 0
|
#define default_red_offset 0
|
||||||
#define default_green_offset 8
|
#define default_green_offset 8
|
||||||
#define default_blue_offset 16
|
#define default_blue_offset 16
|
||||||
#define endian MSBFirst
|
#define default_alpha_offset 24
|
||||||
|
#define render_endian MSBFirst
|
||||||
#else
|
#else
|
||||||
|
#define default_alpha_offset 24
|
||||||
#define default_red_offset 16
|
#define default_red_offset 16
|
||||||
#define default_green_offset 8
|
#define default_green_offset 8
|
||||||
#define default_blue_offset 0
|
#define default_blue_offset 0
|
||||||
#define endian LSBFirst
|
#define render_endian LSBFirst
|
||||||
#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
|
#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,6 +50,7 @@ color_rgb *color_parse(char *colorname);
|
||||||
color_rgb *color_new(int r, int g, int b);
|
color_rgb *color_new(int r, int g, int b);
|
||||||
void color_free(color_rgb *in);
|
void color_free(color_rgb *in);
|
||||||
void reduce_depth(pixel32 *data, XImage *im);
|
void reduce_depth(pixel32 *data, XImage *im);
|
||||||
|
void increase_depth(pixel32 *data, XImage *im);
|
||||||
|
|
||||||
extern int render_red_offset;
|
extern int render_red_offset;
|
||||||
extern int render_green_offset;
|
extern int render_green_offset;
|
||||||
|
@ -57,6 +60,11 @@ extern int render_red_shift;
|
||||||
extern int render_green_shift;
|
extern int render_green_shift;
|
||||||
extern int render_blue_shift;
|
extern int render_blue_shift;
|
||||||
|
|
||||||
|
extern int render_red_mask;
|
||||||
|
extern int render_green_mask;
|
||||||
|
extern int render_blue_mask;
|
||||||
|
|
||||||
extern int pseudo_bpc;
|
extern int pseudo_bpc;
|
||||||
|
#define pseudo_ncolors() (1 << (pseudo_bpc * 3))
|
||||||
extern XColor *pseudo_colors;
|
extern XColor *pseudo_colors;
|
||||||
#endif /* __color_h */
|
#endif /* __color_h */
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
void image_draw(pixel32 *target, TextureRGBA *rgba, Rect *position,
|
void image_draw(pixel32 *target, TextureRGBA *rgba, Rect *position,
|
||||||
Rect *surarea)
|
Rect *surarea)
|
||||||
{
|
{
|
||||||
gulong *draw = rgba->data;
|
pixel32 *draw = rgba->data;
|
||||||
guint c, i, e, t, sfw, sfh;
|
guint c, i, e, t, sfw, sfh;
|
||||||
sfw = position->width;
|
sfw = position->width;
|
||||||
sfh = position->height;
|
sfh = position->height;
|
||||||
|
@ -50,10 +50,10 @@ void image_draw(pixel32 *target, TextureRGBA *rgba, Rect *position,
|
||||||
for (i = 0, c = 0, t = position->x, e = sfw*sfh; i < e; ++i, ++t) {
|
for (i = 0, c = 0, t = position->x, e = sfw*sfh; i < e; ++i, ++t) {
|
||||||
guchar alpha, r, g, b, bgr, bgg, bgb;
|
guchar alpha, r, g, b, bgr, bgg, bgb;
|
||||||
|
|
||||||
alpha = draw[i] >> 24;
|
alpha = draw[i] >> default_alpha_offset;
|
||||||
r = draw[i] >> 16;
|
r = draw[i] >> default_red_offset;
|
||||||
g = draw[i] >> 8;
|
g = draw[i] >> default_green_offset;
|
||||||
b = draw[i];
|
b = draw[i] >> default_blue_offset;
|
||||||
|
|
||||||
if (c >= sfw) {
|
if (c >= sfw) {
|
||||||
c = 0;
|
c = 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@ Visual *render_visual;
|
||||||
Colormap render_colormap;
|
Colormap render_colormap;
|
||||||
int render_red_offset = 0, render_green_offset = 0, render_blue_offset = 0;
|
int render_red_offset = 0, render_green_offset = 0, render_blue_offset = 0;
|
||||||
int render_red_shift, render_green_shift, render_blue_shift;
|
int render_red_shift, render_green_shift, render_blue_shift;
|
||||||
|
int render_red_mask, render_green_mask, render_blue_mask;
|
||||||
|
|
||||||
void render_startup(void)
|
void render_startup(void)
|
||||||
{
|
{
|
||||||
|
@ -87,9 +88,9 @@ void truecolor_startup(void)
|
||||||
ZPixmap, 0, NULL, 1, 1, 32, 0);
|
ZPixmap, 0, NULL, 1, 1, 32, 0);
|
||||||
g_assert(timage != NULL);
|
g_assert(timage != NULL);
|
||||||
/* find the offsets for each color in the visual's masks */
|
/* find the offsets for each color in the visual's masks */
|
||||||
red_mask = timage->red_mask;
|
render_red_mask = red_mask = timage->red_mask;
|
||||||
green_mask = timage->green_mask;
|
render_green_mask = green_mask = timage->green_mask;
|
||||||
blue_mask = timage->blue_mask;
|
render_blue_mask = blue_mask = timage->blue_mask;
|
||||||
|
|
||||||
render_red_offset = 0;
|
render_red_offset = 0;
|
||||||
render_green_offset = 0;
|
render_green_offset = 0;
|
||||||
|
@ -117,7 +118,7 @@ void pseudocolor_startup(void)
|
||||||
/* determine the number of colors and the bits-per-color */
|
/* determine the number of colors and the bits-per-color */
|
||||||
pseudo_bpc = 2; /* XXX THIS SHOULD BE A USER OPTION */
|
pseudo_bpc = 2; /* XXX THIS SHOULD BE A USER OPTION */
|
||||||
g_assert(pseudo_bpc >= 1);
|
g_assert(pseudo_bpc >= 1);
|
||||||
_ncolors = 1 << (pseudo_bpc * 3);
|
_ncolors = pseudo_ncolors();
|
||||||
|
|
||||||
if (_ncolors > 1 << render_depth) {
|
if (_ncolors > 1 << render_depth) {
|
||||||
g_warning("PseudoRenderControl: Invalid colormap size. Resizing.\n");
|
g_warning("PseudoRenderControl: Invalid colormap size. Resizing.\n");
|
||||||
|
@ -166,7 +167,9 @@ void pseudocolor_startup(void)
|
||||||
g = (pseudo_colors[i].green - icolors[ii].green) & 0xff;
|
g = (pseudo_colors[i].green - icolors[ii].green) & 0xff;
|
||||||
b = (pseudo_colors[i].blue - icolors[ii].blue) & 0xff;
|
b = (pseudo_colors[i].blue - icolors[ii].blue) & 0xff;
|
||||||
/* find a weighted absolute deviation */
|
/* find a weighted absolute deviation */
|
||||||
dev = (r * r) + (g * g) + (b * b);
|
dev = (r * r) * (0xff - (icolors[ii].red & 0xff)) +
|
||||||
|
(g * g) * (0xff - (icolors[ii].green & 0xff)) +
|
||||||
|
(b * b) * (0xff - (icolors[ii].blue & 0xff));
|
||||||
|
|
||||||
if (dev < closest) {
|
if (dev < closest) {
|
||||||
closest = dev;
|
closest = dev;
|
||||||
|
@ -400,23 +403,23 @@ void appearance_free(Appearance *a)
|
||||||
|
|
||||||
void pixel32_to_pixmap(pixel32 *in, Pixmap out, int x, int y, int w, int h)
|
void pixel32_to_pixmap(pixel32 *in, Pixmap out, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
unsigned char *scratch;
|
pixel32 *scratch;
|
||||||
XImage *im = NULL;
|
XImage *im = NULL;
|
||||||
im = XCreateImage(ob_display, render_visual, render_depth,
|
im = XCreateImage(ob_display, render_visual, render_depth,
|
||||||
ZPixmap, 0, NULL, w, h, 32, 0);
|
ZPixmap, 0, NULL, w, h, 32, 0);
|
||||||
g_assert(im != NULL);
|
g_assert(im != NULL);
|
||||||
im->byte_order = endian;
|
im->byte_order = render_endian;
|
||||||
/* this malloc is a complete waste of time on normal 32bpp
|
/* this malloc is a complete waste of time on normal 32bpp
|
||||||
as reduce_depth just sets im->data = data and returns
|
as reduce_depth just sets im->data = data and returns
|
||||||
*/
|
*/
|
||||||
scratch = malloc(im->width * im->height * sizeof(pixel32));
|
scratch = g_new(pixel32, im->width * im->height);
|
||||||
im->data = (char*) scratch;
|
im->data = (char*) scratch;
|
||||||
reduce_depth(in, im);
|
reduce_depth(in, im);
|
||||||
XPutImage(ob_display, out, DefaultGC(ob_display, ob_screen),
|
XPutImage(ob_display, out, DefaultGC(ob_display, ob_screen),
|
||||||
im, 0, 0, x, y, w, h);
|
im, 0, 0, x, y, w, h);
|
||||||
im->data = NULL;
|
im->data = NULL;
|
||||||
XDestroyImage(im);
|
XDestroyImage(im);
|
||||||
free(scratch);
|
g_free(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void appearance_minsize(Appearance *l, int *w, int *h)
|
void appearance_minsize(Appearance *l, int *w, int *h)
|
||||||
|
@ -468,9 +471,50 @@ void appearance_minsize(Appearance *l, int *w, int *h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_pixmap_to_rgba(Pixmap pmap, Pixmap mask,
|
gboolean render_pixmap_to_rgba(Pixmap pmap, Pixmap mask,
|
||||||
int *w, int *h, gulong **data)
|
int *w, int *h, pixel32 **data)
|
||||||
{
|
{
|
||||||
*w = *h = 0;
|
Window xr;
|
||||||
*data = NULL;
|
int xx, xy;
|
||||||
|
guint pw, ph, mw, mh, xb, xd, i, x, y, di;
|
||||||
|
XImage *xi, *xm = NULL;
|
||||||
|
|
||||||
|
if (!XGetGeometry(ob_display, pmap, &xr, &xx, &xy, &pw, &ph, &xb, &xd))
|
||||||
|
return FALSE;
|
||||||
|
if (mask) {
|
||||||
|
if (!XGetGeometry(ob_display, mask, &xr, &xx, &xy, &mw, &mh, &xb, &xd))
|
||||||
|
return FALSE;
|
||||||
|
if (pw != mw || ph != mh || xd != 1)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xi = XGetImage(ob_display, pmap, 0, 0, pw, ph, 0xffffffff, ZPixmap);
|
||||||
|
if (!xi)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (mask) {
|
||||||
|
xm = XGetImage(ob_display, mask, 0, 0, mw, mh, 0xffffffff, ZPixmap);
|
||||||
|
if (!xm)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = g_new(pixel32, pw * ph);
|
||||||
|
increase_depth(*data, xi);
|
||||||
|
|
||||||
|
if (mask) {
|
||||||
|
/* apply transparency from the mask */
|
||||||
|
di = 0;
|
||||||
|
for (i = 0, y = 0; y < ph; ++y) {
|
||||||
|
for (x = 0; x < pw; ++x, ++i) {
|
||||||
|
if (!((((unsigned)xm->data[di + x / 8]) >> (x % 8)) & 0x1))
|
||||||
|
(*data)[i] &= ~(0xff << default_alpha_offset);
|
||||||
|
}
|
||||||
|
di += xm->bytes_per_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*w = pw;
|
||||||
|
*h = ph;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,11 +112,11 @@ typedef struct TextureMask {
|
||||||
typedef struct TextureRGBA {
|
typedef struct TextureRGBA {
|
||||||
guint width;
|
guint width;
|
||||||
guint height;
|
guint height;
|
||||||
unsigned long *data;
|
pixel32 *data;
|
||||||
/* cached scaled so we don't have to scale often */
|
/* cached scaled so we don't have to scale often */
|
||||||
guint cwidth;
|
guint cwidth;
|
||||||
guint cheight;
|
guint cheight;
|
||||||
unsigned long *cache;
|
pixel32 *cache;
|
||||||
} TextureRGBA;
|
} TextureRGBA;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@ -159,7 +159,7 @@ void pixel32_to_pixmap(pixel32 *in, Pixmap out, int x, int y, int w, int h);
|
||||||
|
|
||||||
void appearance_minsize(Appearance *l, int *w, int *h);
|
void appearance_minsize(Appearance *l, int *w, int *h);
|
||||||
|
|
||||||
void render_pixmap_to_rgba(Pixmap pmap, Pixmap mask,
|
gboolean render_pixmap_to_rgba(Pixmap pmap, Pixmap mask,
|
||||||
int *w, int *h, gulong **data);
|
int *w, int *h, pixel32 **data);
|
||||||
|
|
||||||
#endif /*__render_h*/
|
#endif /*__render_h*/
|
||||||
|
|
Loading…
Reference in a new issue