diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e2da26be..d9c0858a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ set(AWE_SRCS ${SOURCE_DIR}/keybinding.c ${SOURCE_DIR}/keygrabber.c ${SOURCE_DIR}/layout.c - ${SOURCE_DIR}/lua.c + ${SOURCE_DIR}/luaa.c ${SOURCE_DIR}/mouse.c ${SOURCE_DIR}/screen.c ${SOURCE_DIR}/stack.c diff --git a/client.c b/client.c index 5e0dae127..00d15699f 100644 --- a/client.c +++ b/client.c @@ -32,7 +32,7 @@ #include "widget.h" #include "screen.h" #include "titlebar.h" -#include "lua.h" +#include "luaa.h" #include "mouse.h" #include "systray.h" #include "statusbar.h" @@ -361,7 +361,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, { xcb_get_property_cookie_t ewmh_icon_cookie; client_t *c; - draw_image_t *icon; + image_t *icon; const uint32_t select_input_val[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY @@ -393,10 +393,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, c->geometry.height = c->f_geometry.height = c->m_geometry.height = wgeom->height; client_setborder(c, wgeom->border_width); if((icon = ewmh_window_icon_get_reply(ewmh_icon_cookie))) - { - c->icon = image_new(icon); - image_ref(&c->icon); - } + c->icon = image_ref(&icon); /* we honor size hints by default */ c->honorsizehints = true; diff --git a/draw.c b/draw.c index 1850ab164..16be6a01c 100644 --- a/draw.c +++ b/draw.c @@ -22,7 +22,6 @@ #include #include "config.h" -#include #include #include @@ -225,8 +224,8 @@ draw_markup_on_element(markup_parser_data_t *p, const char *elem, break; case A_TK_IMAGE: if(data->bg_image) - draw_image_delete(&data->bg_image); - data->bg_image = draw_image_new(*values); + image_delete(&data->bg_image); + data->bg_image = image_new_from_file(*values); break; case A_TK_ALIGN: data->bg_align = draw_align_fromstr(*values, -1); @@ -767,116 +766,6 @@ draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h, cairo_surface_destroy(source); } -static const char * -draw_imlib_load_strerror(Imlib_Load_Error e) -{ - switch(e) - { - case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST: - return "no such file or directory"; - case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY: - return "file is a directory"; - case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ: - return "read permission denied"; - case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT: - return "no loader for file format"; - case IMLIB_LOAD_ERROR_PATH_TOO_LONG: - return "path too long"; - case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT: - return "path component non existant"; - case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY: - return "path compoment not a directory"; - case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE: - return "path points oustide address space"; - case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS: - return "too many symbolic links"; - case IMLIB_LOAD_ERROR_OUT_OF_MEMORY: - return "out of memory"; - case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS: - return "out of file descriptors"; - case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE: - return "write permission denied"; - case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE: - return "out of disk space"; - case IMLIB_LOAD_ERROR_UNKNOWN: - return "unknown error, that's really bad"; - case IMLIB_LOAD_ERROR_NONE: - return "no error, oops"; - } - - return "unknown error"; -} - - -/** Load an image from filename. - * \param filename The image file to load. - * \return A new image. - */ -draw_image_t * -draw_image_new(const char *filename) -{ - int w, h, size, i; - DATA32 *data; - double alpha; - unsigned char *dataimg, *rdataimg; - Imlib_Image imimage; - Imlib_Load_Error e = IMLIB_LOAD_ERROR_NONE; - draw_image_t *image; - - if(!filename) - return NULL; - - if(!(imimage = imlib_load_image_with_error_return(filename, &e))) - { - warn("cannot load image %s: %s", filename, draw_imlib_load_strerror(e)); - 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(draw_image_t, 1); - - image->data = rdataimg; - image->width = w; - image->height = h; - - imlib_free_image(); - - return image; -} - -/** Delete an image. - * \param image The image to delete. - */ -void -draw_image_delete(draw_image_t **image) -{ - if (*image) - { - p_delete(&(*image)->data); - p_delete(image); - } -} - /** Draw an image to a draw context. * \param ctx Draw context to draw to. * \param x X coordinate. @@ -885,7 +774,7 @@ draw_image_delete(draw_image_t **image) * \param image The image to draw. */ void -draw_image(draw_context_t *ctx, int x, int y, int wanted_h, draw_image_t *image) +draw_image(draw_context_t *ctx, int x, int y, int wanted_h, image_t *image) { draw_image_from_argb_data(ctx, x, y, image->width, image->height, wanted_h, image->data); } diff --git a/draw.h b/draw.h index 332e1c2b6..ea274e5cf 100644 --- a/draw.h +++ b/draw.h @@ -27,6 +27,7 @@ #include +#include "image.h" #include "common/array.h" #include "common/list.h" #include "common/buffer.h" @@ -99,13 +100,6 @@ typedef struct xcolor_t bg; } draw_context_t; -typedef struct -{ - void *data; - size_t width; - size_t height; -} draw_image_t; - draw_context_t * draw_context_new(int, int, int, xcb_drawable_t, const xcolor_t *, const xcolor_t*); @@ -162,7 +156,7 @@ typedef struct } bg_margin; bool has_bg_color; xcolor_t bg_color; - draw_image_t *bg_image; + image_t *bg_image; alignment_t bg_align; bool bg_resize; struct @@ -189,9 +183,7 @@ void draw_graph(draw_context_t *, area_t, int *, int *, int, position_t, vector_ const xcolor_t *, const xcolor_t *, const xcolor_t *); void draw_graph_line(draw_context_t *, area_t, int *, int, position_t, vector_t, const xcolor_t *, const xcolor_t *, const xcolor_t *); -draw_image_t *draw_image_new(const char *); -void draw_image_delete(draw_image_t **); -void draw_image(draw_context_t *, int, int, int, draw_image_t *); +void draw_image(draw_context_t *, int, int, int, image_t *); void draw_rotate(draw_context_t *, xcb_drawable_t, xcb_drawable_t, int, int, int, int, double, int, int); area_t draw_text_extents(int, font_t *, const char *, ssize_t, draw_parser_data_t *); alignment_t draw_align_fromstr(const char *, ssize_t); @@ -227,7 +219,7 @@ draw_parser_data_wipe(draw_parser_data_t *pdata) { pango_attr_list_unref(pdata->attr_list); p_delete(&pdata->text); - draw_image_delete(&pdata->bg_image); + image_unref(&pdata->bg_image); } } diff --git a/event.c b/event.c index c84287571..e36951580 100644 --- a/event.c +++ b/event.c @@ -35,7 +35,7 @@ #include "titlebar.h" #include "keybinding.h" #include "keygrabber.h" -#include "lua.h" +#include "luaa.h" #include "systray.h" #include "statusbar.h" #include "screen.h" diff --git a/ewmh.c b/ewmh.c index ae8f5facc..e1dc9e27b 100644 --- a/ewmh.c +++ b/ewmh.c @@ -507,11 +507,11 @@ ewmh_window_icon_get_unchecked(xcb_window_t w) _NET_WM_ICON, CARDINAL, 0, UINT32_MAX); } -draw_image_t * +image_t * ewmh_window_icon_from_reply(xcb_get_property_reply_t *r) { double alpha; - draw_image_t *icon; + image_t *icon; int size, i; uint32_t *data; unsigned char *imgdata; @@ -520,7 +520,7 @@ ewmh_window_icon_from_reply(xcb_get_property_reply_t *r) !(data = (uint32_t *) xcb_get_property_value(r))) return NULL; - icon = p_new(draw_image_t, 1); + icon = p_new(image_t, 1); icon->width = data[0]; icon->height = data[1]; @@ -550,11 +550,11 @@ ewmh_window_icon_from_reply(xcb_get_property_reply_t *r) * \param cookie The cookie. * \return A draw_image_t structure which must be deleted after usage. */ -draw_image_t * +image_t * ewmh_window_icon_get_reply(xcb_get_property_cookie_t cookie) { xcb_get_property_reply_t *r = xcb_get_property_reply(globalconf.connection, cookie, NULL); - draw_image_t *icon = ewmh_window_icon_from_reply(r); + image_t *icon = ewmh_window_icon_from_reply(r); p_delete(&r); return icon; } diff --git a/ewmh.h b/ewmh.h index 481d0883a..aa219b5bd 100644 --- a/ewmh.h +++ b/ewmh.h @@ -36,8 +36,8 @@ void ewmh_check_client_hints(client_t *); void ewmh_update_workarea(int); void ewmh_client_strut_update(client_t *, xcb_get_property_reply_t *); xcb_get_property_cookie_t ewmh_window_icon_get_unchecked(xcb_window_t); -draw_image_t *ewmh_window_icon_from_reply(xcb_get_property_reply_t *); -draw_image_t *ewmh_window_icon_get_reply(xcb_get_property_cookie_t); +image_t *ewmh_window_icon_from_reply(xcb_get_property_reply_t *); +image_t *ewmh_window_icon_get_reply(xcb_get_property_cookie_t); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/image.c b/image.c index 9539f0953..0400dc107 100644 --- a/image.c +++ b/image.c @@ -19,6 +19,8 @@ * */ +#include + #include "structs.h" #include "image.h" @@ -28,6 +30,102 @@ DO_LUA_NEW(extern, image_t, image, "image", image_ref) DO_LUA_GC(image_t, image, "image", image_unref) DO_LUA_EQ(image_t, image, "image") +static const char * +image_imlib_load_strerror(Imlib_Load_Error e) +{ + switch(e) + { + case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST: + return "no such file or directory"; + case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY: + return "file is a directory"; + case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ: + return "read permission denied"; + case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT: + return "no loader for file format"; + case IMLIB_LOAD_ERROR_PATH_TOO_LONG: + return "path too long"; + case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT: + return "path component non existant"; + case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY: + return "path compoment not a directory"; + case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE: + return "path points oustide address space"; + case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS: + return "too many symbolic links"; + case IMLIB_LOAD_ERROR_OUT_OF_MEMORY: + return "out of memory"; + case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS: + return "out of file descriptors"; + case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE: + return "write permission denied"; + case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE: + return "out of disk space"; + case IMLIB_LOAD_ERROR_UNKNOWN: + return "unknown error, that's really bad"; + case IMLIB_LOAD_ERROR_NONE: + return "no error, oops"; + } + + return "unknown error"; +} + +/** Load an image from filename. + * \param filename The image file to load. + * \return A new image. + */ +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; + + if(!filename) + return NULL; + + if(!(imimage = imlib_load_image_with_error_return(filename, &e))) + { + warn("cannot load image %s: %s", filename, image_imlib_load_strerror(e)); + 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->data = rdataimg; + image->width = w; + image->height = h; + + imlib_free_image(); + + return image; +} + /** Create a new image object. * \param L The Lua stack. * \return The number of elements pushed on stack. @@ -39,14 +137,10 @@ static int luaA_image_new(lua_State *L) { const char *filename = luaL_checkstring(L, 2); - draw_image_t *dimg; + image_t *image; - if((dimg = draw_image_new(filename))) - { - image_t *image = p_new(image_t, 1); - image->image = dimg; + if((image = image_new_from_file(filename))) return luaA_image_userdata_new(L, image); - } return 0; } @@ -62,7 +156,7 @@ luaA_image_tostring(lua_State *L) { image_t **p = luaA_checkudata(L, 1, "image"); lua_pushfstring(L, "[image udata(%p) width(%d) height(%d)]", *p, - (*p)->image->width, (*p)->image->height); + (*p)->width, (*p)->height); return 1; } diff --git a/image.h b/image.h index 2d90badea..998dadb1e 100644 --- a/image.h +++ b/image.h @@ -24,14 +24,19 @@ #include -#include "draw.h" +#include "common/util.h" #include "common/refcount.h" typedef struct { /** Reference counter */ int refcount; - draw_image_t *image; + /** Image width */ + int width; + /** Image height */ + int height; + /** Image data */ + void *data; } image_t; static inline void @@ -39,26 +44,16 @@ image_delete(image_t **i) { if(*i) { - draw_image_delete(&(*i)->image); + p_delete(&(*i)->data); p_delete(i); } } DO_RCNT(image_t, image, image_delete) -int luaA_image_userdata_new(lua_State *, image_t *); +image_t * image_new_from_file(const char *); -/** Create a new image from a draw_image_t object. - * \param i The image data. - * \return A image_t object. - */ -static inline image_t * -image_new(draw_image_t *i) -{ - image_t *image = p_new(image_t, 1); - image->image = i; - return image; -} +int luaA_image_userdata_new(lua_State *, image_t *); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/keybinding.h b/keybinding.h index 6f3116a17..d84866ca7 100644 --- a/keybinding.h +++ b/keybinding.h @@ -23,7 +23,7 @@ #define AWESOME_KEYBINDING_H #include -#include "lua.h" +#include "luaa.h" typedef struct keybinding_t { diff --git a/keygrabber.c b/keygrabber.c index 50bb6c6f1..4fd0efdc7 100644 --- a/keygrabber.c +++ b/keygrabber.c @@ -21,9 +21,9 @@ #include +#include "structs.h" #include "keygrabber.h" #include "keybinding.h" -#include "structs.h" extern awesome_t globalconf; diff --git a/lua.c b/luaa.c similarity index 99% rename from lua.c rename to luaa.c index 6f409f75d..e8c3392ee 100644 --- a/lua.c +++ b/luaa.c @@ -41,7 +41,7 @@ #include "awesome-version-internal.h" #include "ewmh.h" #include "config.h" -#include "lua.h" +#include "luaa.h" #include "tag.h" #include "client.h" #include "screen.h" diff --git a/lua.h b/luaa.h similarity index 100% rename from lua.h rename to luaa.h diff --git a/property.c b/property.c index 825581347..f4e0504e8 100644 --- a/property.c +++ b/property.c @@ -289,16 +289,11 @@ property_handle_net_wm_icon(void *data, if(c) { - draw_image_t *icon; + image_t *icon; image_unref(&c->icon); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); - if((icon = ewmh_window_icon_from_reply(reply))) - { - c->icon = image_new(icon); - image_ref(&c->icon); - } - else - c->icon = NULL; + icon = ewmh_window_icon_from_reply(reply); + c->icon = icon ? image_ref(&icon) : NULL; } return 0; diff --git a/structs.h b/structs.h index 137103908..be573b4fe 100644 --- a/structs.h +++ b/structs.h @@ -27,7 +27,7 @@ #include #include -#include "lua.h" +#include "luaa.h" #include "layout.h" #include "swindow.h" #include "xscreen.h" diff --git a/widgets/imagebox.c b/widgets/imagebox.c index 7d6fb2eaf..7d5abf659 100644 --- a/widgets/imagebox.c +++ b/widgets/imagebox.c @@ -54,13 +54,13 @@ imagebox_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), if(d->image) { w->area.height = ctx->height; - w->area.width = ((double) ctx->height / (double) d->image->image->height) * d->image->image->width; + w->area.width = ((double) ctx->height / (double) d->image->height) * d->image->width; w->area.x = widget_calculate_offset(ctx->width, w->area.width, offset, w->widget->align); - draw_image(ctx, w->area.x, w->area.y, ctx->height, d->image->image); + draw_image(ctx, w->area.x, w->area.y, ctx->height, d->image); } else { diff --git a/widgets/taglist.c b/widgets/taglist.c index 69772ba93..715036ae3 100644 --- a/widgets/taglist.c +++ b/widgets/taglist.c @@ -22,7 +22,7 @@ #include "client.h" #include "widget.h" #include "tag.h" -#include "lua.h" +#include "luaa.h" #include "common/tokenize.h" extern awesome_t globalconf; diff --git a/widgets/tasklist.c b/widgets/tasklist.c index de949210e..d2ca7db0b 100644 --- a/widgets/tasklist.c +++ b/widgets/tasklist.c @@ -113,7 +113,7 @@ tasklist_draw_item(draw_context_t *ctx, tasklist_object_data_t *odata, int width_mod, int pos, int i) { draw_parser_data_t pdata, *parser_data; - draw_image_t *image; + image_t *image; area_t area; tasklist_data_t *d = w->widget->data; int icon_width = 0; @@ -144,7 +144,7 @@ tasklist_draw_item(draw_context_t *ctx, if(odata->client_labels.tab[i].client->icon) { - image = odata->client_labels.tab[i].client->icon->image; + image = odata->client_labels.tab[i].client->icon; icon_width = ((double) ctx->height / (double) image->height) * image->width; draw_image(ctx, w->area.x + odata->box_width * i, w->area.y, ctx->height, image);