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 }