dwm

Kris's build of dwm
git clone git clone https://git.krisyotam.com/krisyotam/dwm.git
Log | Files | Refs | README | LICENSE

bar_winicon.c (4300B)


      1 static uint32_t prealpha(uint32_t p) {
      2 	uint8_t a = p >> 24u;
      3 	uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
      4 	uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
      5 	return (rb & 0xFF00FFu) | (g & 0x00FF00u) | (a << 24u);
      6 }
      7 
      8 Picture
      9 geticonprop(Window win, unsigned int *picw, unsigned int *pich)
     10 {
     11 	int format;
     12 	unsigned long n, extra, *p = NULL;
     13 	Atom real;
     14 
     15 	if (XGetWindowProperty(dpy, win, netatom[NetWMIcon], 0L, LONG_MAX, False, AnyPropertyType,
     16 						   &real, &format, &n, &extra, (unsigned char **)&p) != Success)
     17 		return None;
     18 	if (n == 0 || format != 32) { XFree(p); return None; }
     19 
     20 	unsigned long *bstp = NULL;
     21 	uint32_t w, h, sz;
     22 	{
     23 		unsigned long *i; const unsigned long *end = p + n;
     24 		uint32_t bstd = UINT32_MAX, d, m;
     25 		for (i = p; i < end - 1; i += sz) {
     26 			if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
     27 			if ((sz = w * h) > end - i) break;
     28 			if ((m = w > h ? w : h) >= ICONSIZE && (d = m - ICONSIZE) < bstd) { bstd = d; bstp = i; }
     29 		}
     30 		if (!bstp) {
     31 			for (i = p; i < end - 1; i += sz) {
     32 				if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
     33 				if ((sz = w * h) > end - i) break;
     34 				if ((d = ICONSIZE - (w > h ? w : h)) < bstd) { bstd = d; bstp = i; }
     35 			}
     36 		}
     37 		if (!bstp) { XFree(p); return None; }
     38 	}
     39 
     40 	if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p); return None; }
     41 
     42 	uint32_t icw, ich;
     43 	if (w <= h) {
     44 		ich = ICONSIZE; icw = w * ICONSIZE / h;
     45 		if (icw == 0) icw = 1;
     46 	}
     47 	else {
     48 		icw = ICONSIZE; ich = h * ICONSIZE / w;
     49 		if (ich == 0) ich = 1;
     50 	}
     51 	*picw = icw; *pich = ich;
     52 
     53 	uint32_t i, *bstp32 = (uint32_t *)bstp;
     54 	for (sz = w * h, i = 0; i < sz; ++i) bstp32[i] = prealpha(bstp[i]);
     55 
     56 	Picture ret = drw_picture_create_resized(drw, (char *)bstp, w, h, icw, ich);
     57 	XFree(p);
     58 
     59 	return ret;
     60 }
     61 
     62 Picture
     63 drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) {
     64 	Pixmap pm;
     65 	Picture pic;
     66 	GC gc;
     67 
     68 	if (srcw <= (dstw << 1u) && srch <= (dsth << 1u)) {
     69 		XImage img = {
     70 			srcw, srch, 0, ZPixmap, src,
     71 			ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
     72 			32, 0, 32,
     73 			0, 0, 0
     74 		};
     75 		XInitImage(&img);
     76 
     77 		pm = XCreatePixmap(drw->dpy, drw->root, srcw, srch, 32);
     78 		gc = XCreateGC(drw->dpy, pm, 0, NULL);
     79 		XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, srcw, srch);
     80 		XFreeGC(drw->dpy, gc);
     81 
     82 		pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
     83 		XFreePixmap(drw->dpy, pm);
     84 
     85 		XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, NULL, 0);
     86 		XTransform xf;
     87 		xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0;
     88 		xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / dsth; xf.matrix[1][2] = 0;
     89 		xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536;
     90 		XRenderSetPictureTransform(drw->dpy, pic, &xf);
     91 	} else {
     92 		Imlib_Image origin = imlib_create_image_using_data(srcw, srch, (DATA32 *)src);
     93 		if (!origin) return None;
     94 		imlib_context_set_image(origin);
     95 		imlib_image_set_has_alpha(1);
     96 		Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, srcw, srch, dstw, dsth);
     97 		imlib_free_image_and_decache();
     98 		if (!scaled) return None;
     99 		imlib_context_set_image(scaled);
    100 		imlib_image_set_has_alpha(1);
    101 
    102 		XImage img = {
    103 		    dstw, dsth, 0, ZPixmap, (char *)imlib_image_get_data_for_reading_only(),
    104 		    ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
    105 		    32, 0, 32,
    106 		    0, 0, 0
    107 		};
    108 		XInitImage(&img);
    109 
    110 		pm = XCreatePixmap(drw->dpy, drw->root, dstw, dsth, 32);
    111 		gc = XCreateGC(drw->dpy, pm, 0, NULL);
    112 		XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, dstw, dsth);
    113 		imlib_free_image_and_decache();
    114 		XFreeGC(drw->dpy, gc);
    115 
    116 		pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
    117 		XFreePixmap(drw->dpy, pm);
    118 	}
    119 
    120 	return pic;
    121 }
    122 
    123 void
    124 drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic)
    125 {
    126 	if (!drw)
    127 		return;
    128 	XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h);
    129 }
    130 
    131 void
    132 freeicon(Client *c)
    133 {
    134 	if (c->icon) {
    135 		XRenderFreePicture(dpy, c->icon);
    136 		c->icon = None;
    137 	}
    138 }
    139 
    140 void
    141 updateicon(Client *c)
    142 {
    143 	freeicon(c);
    144 	c->icon = geticonprop(c->win, &c->icw, &c->ich);
    145 }