diff --git a/ewmh.c b/ewmh.c index e1dc9e27..4b4a874d 100644 --- a/ewmh.c +++ b/ewmh.c @@ -510,40 +510,16 @@ ewmh_window_icon_get_unchecked(xcb_window_t w) image_t * ewmh_window_icon_from_reply(xcb_get_property_reply_t *r) { - double alpha; - image_t *icon; - int size, i; uint32_t *data; - unsigned char *imgdata; if(!r || r->type != CARDINAL || r->format != 32 || r->length < 2 || !(data = (uint32_t *) xcb_get_property_value(r))) return NULL; - icon = p_new(image_t, 1); + if(data[0] && data[1]) + return image_new_from_argb32(data[0], data[1], data + 2); - icon->width = data[0]; - icon->height = data[1]; - size = icon->width * icon->height; - - if(!size) - { - p_delete(&icon); - p_delete(&r); - return NULL; - } - - icon->data = p_new(unsigned char, size * 4); - for(imgdata = icon->data, i = 2; i < size + 2; i++, imgdata += 4) - { - imgdata[3] = (data[i] >> 24) & 0xff; /* A */ - alpha = imgdata[3] / 255.0; - imgdata[2] = ((data[i] >> 16) & 0xff) * alpha; /* R */ - imgdata[1] = ((data[i] >> 8) & 0xff) * alpha; /* G */ - imgdata[0] = (data[i] & 0xff) * alpha; /* B */ - } - - return icon; + return NULL; } /** Get NET_WM_ICON. diff --git a/image.c b/image.c index 0400dc10..6739b208 100644 --- a/image.c +++ b/image.c @@ -19,10 +19,7 @@ * */ -#include - #include "structs.h" -#include "image.h" extern awesome_t globalconf; @@ -70,6 +67,63 @@ image_imlib_load_strerror(Imlib_Load_Error e) return "unknown error"; } +/** Recompute the ARGB32 data from an image. + * \param image The image. + * \return Data. + */ +static void +image_compute(image_t *image) +{ + int size, i; + uint32_t *data; + double alpha; + uint8_t *dataimg; + + imlib_context_set_image(image->image); + + data = imlib_image_get_data_for_reading_only(); + + image->width = imlib_image_get_width(); + image->height = imlib_image_get_height(); + + size = image->width * image->height; + + p_delete(&image->data); + image->data = dataimg = p_new(uint8_t, size * 4); + + for(i = 0; i < size; i++, dataimg += 4) + { + dataimg[3] = (data[i] >> 24) & 0xff; /* A */ + /* cairo wants pre-multiplied alpha */ + alpha = dataimg[3] / 255.0; + dataimg[2] = ((data[i] >> 16) & 0xff) * alpha; /* R */ + dataimg[1] = ((data[i] >> 8) & 0xff) * alpha; /* G */ + dataimg[0] = (data[i] & 0xff) * alpha; /* B */ + } +} + +/** Create a new image from ARGB32 data. + * \param width The image width. + * \param height The image height. + * \param data The image data. + * \return A brand new image. + */ +image_t * +image_new_from_argb32(int width, int height, uint32_t *data) +{ + Imlib_Image imimage; + image_t *image = NULL; + + if((imimage = imlib_create_image_using_data(width, height, data))) + { + image = p_new(image_t, 1); + image->image = imimage; + image_compute(image); + } + + return image; +} + /** Load an image from filename. * \param filename The image file to load. * \return A new image. @@ -77,10 +131,6 @@ image_imlib_load_strerror(Imlib_Load_Error e) image_t * image_new_from_file(const char *filename) { - int w, h, size, i; - uint32_t *data; - double alpha; - unsigned char *dataimg, *rdataimg; Imlib_Image imimage; Imlib_Load_Error e = IMLIB_LOAD_ERROR_NONE; image_t *image; @@ -94,34 +144,10 @@ image_new_from_file(const char *filename) return NULL; } - imlib_context_set_image(imimage); - - w = imlib_image_get_width(); - h = imlib_image_get_height(); - - size = w * h; - - data = imlib_image_get_data_for_reading_only(); - - rdataimg = dataimg = p_new(unsigned char, size * 4); - - for(i = 0; i < size; i++, dataimg += 4) - { - dataimg[3] = (data[i] >> 24) & 0xff; /* A */ - /* cairo wants pre-multiplied alpha */ - alpha = dataimg[3] / 255.0; - dataimg[2] = ((data[i] >> 16) & 0xff) * alpha; /* R */ - dataimg[1] = ((data[i] >> 8) & 0xff) * alpha; /* G */ - dataimg[0] = (data[i] & 0xff) * alpha; /* B */ - } - image = p_new(image_t, 1); + image->image = imimage; - image->data = rdataimg; - image->width = w; - image->height = h; - - imlib_free_image(); + image_compute(image); return image; } diff --git a/image.h b/image.h index 998dadb1..c1aa6fcc 100644 --- a/image.h +++ b/image.h @@ -23,6 +23,7 @@ #define AWESOME_IMAGE_H #include +#include #include "common/util.h" #include "common/refcount.h" @@ -31,12 +32,14 @@ typedef struct { /** Reference counter */ int refcount; + /** Imlib2 image */ + Imlib_Image image; /** Image width */ int width; /** Image height */ int height; /** Image data */ - void *data; + uint8_t *data; } image_t; static inline void @@ -44,6 +47,8 @@ image_delete(image_t **i) { if(*i) { + imlib_context_set_image((*i)->image); + imlib_free_image(); p_delete(&(*i)->data); p_delete(i); } @@ -52,6 +57,8 @@ image_delete(image_t **i) DO_RCNT(image_t, image, image_delete) image_t * image_new_from_file(const char *); +image_t * image_new_from_argb32(int, int, uint32_t *); +uint8_t * image_data_argb32_get(image_t *); int luaA_image_userdata_new(lua_State *, image_t *);