/* * _NET_WM_ICON helpers for slide puzzle game * Copyright © 2022 Nick Bowler * * 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 3 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, see . */ #include #include #include #include #if !X_DISPLAY_MISSING # include # include #endif #include "ewmhicon.h" #include "colour.h" #include "icon.h" enum { ICON_16x16, ICON_24x24, ICON_32x32, ICON_48x48, ICON_MAX }; /* * Allocate storage for the EWMH _NET_WM_ICON array. The sizes array is * populated with pointers to the beginning of each icon's pixel data. For * example, sizes[ICON_24x24] points to the first pixel of the 24x24 image. * * The returned value can then be passed to XChangeProperty to set the icon, * (use EWMH_ICON_NELEM for the number of elements) and must be freed by the * caller. */ static void *ewmh_icon_alloc(unsigned long **sizes) { unsigned long *buf; buf = calloc(sizeof *buf, EWMH_ICON_NELEM); if (buf) { sizes[ICON_16x16] = buf; *sizes[ICON_16x16]++ = 16; *sizes[ICON_16x16]++ = 16; sizes[ICON_24x24] = sizes[ICON_16x16] + 16*16; *sizes[ICON_24x24]++ = 24; *sizes[ICON_24x24]++ = 24; sizes[ICON_32x32] = sizes[ICON_24x24] + 24*24; *sizes[ICON_32x32]++ = 32; *sizes[ICON_32x32]++ = 32; sizes[ICON_48x48] = sizes[ICON_32x32] + 32*32; *sizes[ICON_48x48]++ = 48; *sizes[ICON_48x48]++ = 48; } return buf; } static unsigned long scale16to8(unsigned x) { return x*0xfful / 0xffff; } static unsigned long wm_pixel(const XColor *c) { return 0xff000000 | scale16to8(c->red) << 16 | scale16to8(c->green) << 8 | scale16to8(c->blue); } static void do_remap(void *icon, unsigned size, const XColor *map) { unsigned char *index = icon; unsigned long *argb = icon; unsigned i, count = size*size; for (i = 0; i < count; i++) { argb[count-i-1] = wm_pixel(map + index[count-i-1]); } } void *ewmh_icon_generate(const unsigned long *seq, const XColor *map) { unsigned long *buf, *sizes[ICON_MAX]; unsigned i, j; buf = ewmh_icon_alloc(sizes); if (!buf) return NULL; for (i = 0; i < 9; i++) { unsigned x = i%3, y = i/3; icon_tile16((void *)sizes[ICON_16x16], seq[i], x, y); icon_tile24((void *)sizes[ICON_24x24], seq[i], x, y); icon_tile32((void *)sizes[ICON_32x32], seq[i], x, y); icon_tile48((void *)sizes[ICON_48x48], seq[i], x, y); } for (i = 0; i < ICON_MAX; i++) { /* Produces the sequence 16, 24, 32, 48 */ unsigned size = 16 + (1u< 0 && bytes_after > 0); return 0; } #endif