diff --git a/config.c b/config.c index 24798f1a1..657f1ef08 100644 --- a/config.c +++ b/config.c @@ -354,6 +354,7 @@ config_parse(const char *confpatharg) CFG_SEC((char *) "focustitle", widget_opts, CFGF_TITLE | CFGF_MULTI), CFG_SEC((char *) "layoutinfo", widget_opts, CFGF_TITLE | CFGF_MULTI), CFG_SEC((char *) "iconbox", widget_iconbox_opts, CFGF_TITLE | CFGF_MULTI), + CFG_SEC((char *) "netwmicon", widget_opts, CFGF_TITLE | CFGF_MULTI), CFG_END() }; static cfg_opt_t tag_opts[] = diff --git a/config.mk b/config.mk index 22257cfae..60cdec5fb 100644 --- a/config.mk +++ b/config.mk @@ -6,8 +6,8 @@ RELEASE = "Productivity Breaker" # additional layouts LAYOUTS = layouts/tile.c layouts/floating.c layouts/max.c layouts/fibonacci.c - -WIDGETS = widgets/taglist.c widgets/layoutinfo.c widgets/textbox.c widgets/focustitle.c widgets/iconbox.c +# additional widgets +WIDGETS = widgets/taglist.c widgets/layoutinfo.c widgets/textbox.c widgets/focustitle.c widgets/iconbox.c widgets/netwmicon.c # paths PREFIX = /usr/local @@ -21,7 +21,7 @@ INCS = -I. -I/usr/include -I${X11INC} `pkg-config --cflags libconfuse xft cairo` LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 `pkg-config --libs libconfuse xft cairo` -lXext -lXrandr -lXinerama # flags -CFLAGS = -std=gnu99 -ggdb3 -pipe -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wwrite-strings -Wsign-compare -Wunused -Winit-self -Wpointer-arith -Wredundant-decls -Wmissing-prototypes -Wmissing-format-attribute -Wmissing-noreturn -O3 ${INCS} -DVERSION=\"${VERSION}\" -DRELEASE=\"${RELEASE}\" +CFLAGS = -std=gnu99 -ggdb3 -pipe -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wwrite-strings -Wsign-compare -Wunused -Winit-self -Wpointer-arith -Wredundant-decls -Wmissing-prototypes -Wmissing-format-attribute -Wmissing-noreturn -O0 ${INCS} -DVERSION=\"${VERSION}\" -DRELEASE=\"${RELEASE}\" LDFLAGS = -ggdb3 ${LIBS} CLIENTLDFLAGS = -ggdb3 diff --git a/draw.c b/draw.c index 33946a54b..831890f43 100644 --- a/draw.c +++ b/draw.c @@ -149,6 +149,22 @@ drawcircle(DrawCtx *ctx, int x, int y, int r, Bool filled, XColor color) cairo_surface_destroy(surface); } +void draw_image_from_argb_data(DrawCtx *ctx, int x, int y, int w, int h, unsigned char *data) +{ + cairo_surface_t *surface, *source; + cairo_t *cr; + + source = cairo_xlib_surface_create(ctx->display, ctx->drawable, ctx->visual, ctx->width, ctx->height); + surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, w, h, 0); + cr = cairo_create (source); + cairo_set_source_surface(cr, surface, x, y); + cairo_paint(cr); + + cairo_destroy(cr); + cairo_surface_destroy(source); + cairo_surface_destroy(surface); +} + void drawimage(DrawCtx *ctx, int x, int y, const char *filename) { diff --git a/draw.h b/draw.h index 3136074a1..bd0df42c2 100644 --- a/draw.h +++ b/draw.h @@ -42,6 +42,7 @@ void drawtext(DrawCtx *, int, int, int, int, XftFont *, const char *, XColor fg, void drawrectangle(DrawCtx *, int, int, int, int, Bool, XColor); void drawcircle(DrawCtx *, int, int, int, Bool, XColor); void drawimage(DrawCtx *, int, int, const char *); +void draw_image_from_argb_data(DrawCtx *, int, int, int, int, unsigned char *); int draw_get_image_width(const char *filename); Drawable draw_rotate(DrawCtx *, int, double, int, int); unsigned short textwidth(DrawCtx *, XftFont *, char *); diff --git a/widget.c b/widget.c index f88872ee3..6af297a04 100644 --- a/widget.c +++ b/widget.c @@ -33,6 +33,7 @@ const NameFuncLink WidgetList[] = {"focustitle", focustitle_new}, {"textbox", textbox_new}, {"iconbox", iconbox_new}, + {"netwmicon", netwmicon_new}, {NULL, NULL} }; diff --git a/widget.h b/widget.h index d1cf3788a..8d111650c 100644 --- a/widget.h +++ b/widget.h @@ -41,6 +41,7 @@ WidgetConstructor taglist_new; WidgetConstructor textbox_new; WidgetConstructor focustitle_new; WidgetConstructor iconbox_new; +WidgetConstructor netwmicon_new; UICB_PROTO(uicb_widget_tell); diff --git a/widgets/netwmicon.c b/widgets/netwmicon.c new file mode 100644 index 000000000..54e2ee561 --- /dev/null +++ b/widgets/netwmicon.c @@ -0,0 +1,105 @@ +/* + * iconbox.c - icon widget + * + * Copyright © 2007 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include "util.h" +#include "focus.h" +#include "layout.h" +#include "widget.h" + +extern AwesomeConf globalconf; + +static int +netwmicon_draw(Widget *widget, DrawCtx *ctx, int offset, + int used __attribute__ ((unused))) +{ + unsigned long *data, pixel; + Atom type; + int format, location, width, height, size, i; + unsigned long items, rest; + unsigned char *image, *imgdata; + VirtScreen vscreen = globalconf.screens[widget->statusbar->screen]; + Client *sel = focus_get_latest_client_for_tag(widget->statusbar->screen, + get_current_tag(widget->statusbar->screen)); + + if(!sel) + return 0; + + if(XGetWindowProperty(ctx->display, sel->win, + XInternAtom(ctx->display, "_NET_WM_ICON", False), + 0L, LONG_MAX, False, XA_CARDINAL, &type, &format, + &items, &rest, (unsigned char**) &data) != Success + || !data) + return 0; + + if(type != XA_CARDINAL || format != 32 || items < 2) + { + XFree(data); + return 0; + } + + width = data[0]; + height = data[1]; + size = width * height; + + if(!size) + { + XFree(data); + return 0; + } + + image = p_new(unsigned char, size * 4); + for(imgdata = image, i = 2; i < size + 2; i++, imgdata += 4) + { + pixel = data[i]; + imgdata[3] = (pixel >> 24) & 0xff; /* A */ + imgdata[0] = (pixel >> 16) & 0xff; /* R */ + imgdata[1] = (pixel >> 8) & 0xff; /* G */ + imgdata[2] = pixel & 0xff; /* B */ + } + + location = calculate_offset(vscreen.statusbar->width, + width, + offset, + widget->alignment); + + draw_image_from_argb_data(ctx, location, 0, width, height, image); + + p_delete(&image); + + XFree(data); + return width; +} + +Widget * +netwmicon_new(Statusbar *statusbar, cfg_t *config) +{ + Widget *w; + + w = p_new(Widget, 1); + common_new(w, statusbar, config); + w->draw = netwmicon_draw; + + return w; +} +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80