image: merge draw_image_t and image_t

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-09-17 16:38:38 +02:00
parent fbf0a785d5
commit 6ac0c4130c
18 changed files with 142 additions and 180 deletions

View File

@ -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

View File

@ -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;

117
draw.c
View File

@ -22,7 +22,6 @@
#include <cairo-xcb.h>
#include "config.h"
#include <Imlib2.h>
#include <langinfo.h>
#include <iconv.h>
@ -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);
}

16
draw.h
View File

@ -27,6 +27,7 @@
#include <xcb/xcb.h>
#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);
}
}

View File

@ -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"

10
ewmh.c
View File

@ -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;
}

4
ewmh.h
View File

@ -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

108
image.c
View File

@ -19,6 +19,8 @@
*
*/
#include <Imlib2.h>
#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;
}

25
image.h
View File

@ -24,14 +24,19 @@
#include <lua.h>
#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

View File

@ -23,7 +23,7 @@
#define AWESOME_KEYBINDING_H
#include <xcb/xcb.h>
#include "lua.h"
#include "luaa.h"
typedef struct keybinding_t
{

View File

@ -21,9 +21,9 @@
#include <unistd.h>
#include "structs.h"
#include "keygrabber.h"
#include "keybinding.h"
#include "structs.h"
extern awesome_t globalconf;

View File

@ -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"

View File

View File

@ -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;

View File

@ -27,7 +27,7 @@
#include <xcb/xcb_property.h>
#include <ev.h>
#include "lua.h"
#include "luaa.h"
#include "layout.h"
#include "swindow.h"
#include "xscreen.h"

View File

@ -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
{

View File

@ -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;

View File

@ -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);