static void set_window_icon() { fs_log("setting _NET_WM_ICON from icon images\n"); int max_size = (16 * 16 + 32 * 32 + 48 * 48 + 64 * 64 + 128 * 128) * \ sizeof(unsigned long); // add space for width, height cardinals max_size += 2 * 5 * sizeof(unsigned long); unsigned long *icon_data = (unsigned long *) g_malloc(max_size); unsigned long *op = icon_data; int card_count = 0; int sizes[] = {128, 64, 48, 32, 16, 0}; for(int *size = sizes; *size; size++) { char *rel = g_strdup_printf("icons/hicolor/%dx%d/apps/fs-uae.png", *size, *size); char *path = fs_get_data_file(rel); g_free(rel); if (!path) { fs_log("did not find icon for %dx%d\n", *size, *size); continue; } fs_image *image = fs_image_new_from_file(path); if (!image) { fs_log("could not load icon from %s\n", path); continue; } g_free(path); //printf("%d\n", image->width); int pixel_count = image->width * image->height; unsigned char *p = image->data; *op++ = image->width; *op++ = image->height; for (int i = 0; i < pixel_count; i++) { //*op = 0xffff0000; *op = (((unsigned long) p[3]) << 24) | (p[0] << 16) | (p[1] << 8) | p[2]; p += 4; op++; } card_count += 2 + pixel_count; fs_unref(image); // FIXME } Atom _NET_WM_ICON = XInternAtom(g_display, "_NET_WM_ICON", False); XChangeProperty(g_display, g_window, _NET_WM_ICON, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) icon_data, card_count); g_free(icon_data); }
static void load_atlas_texture(fs_image *atlas_image, int texture_id, const char *name) { char *path = fs_emu_theme_get_resource(name); if (!path) { fs_emu_warning("Could not find resource %s\n", name); return; } fs_image *image = fs_image_new_from_file(path); if (!image) { fs_emu_warning("error loading texture \"%s\"\n", name); return; } fs_emu_log("loaded sub-texture from \"%s\"\n", path); // find needed number of cells int cw = (image->width + 7) / 8; int ch = (image->height + 7) / 8; // adding 1 to get some spacing between cells if (cw < 128) { cw++; } if (ch < 128) { ch++; } // try to find space for it in the texture atlas using a simple // brute-force search int cx = 0; int cy = 0; int ok = 0; for (cy = 0; cy <= 128 - ch; cy++) { for (cx = 0; cx <= 128 - cw; cx++) { if (check_placement(cx, cy, cw, ch)) { ok = 1; break; } } if (ok) { break; } } if (!ok) { fs_emu_warning("could not find space for \"%s\"\n", name); //printf("%d %d %d %d\n", cx * 8, cy * 8, cw * 8, ch * 8); return; } // mark cells as used for (int y = cy; y < cy + ch; y++) { for (int x = cx; x < cx + cw; x++) { g_cells[y][x] = 1; } } //printf("%d %d %d %d\n", cx * 8, cy * 8, cw * 8, ch * 8); // copy sub-texture into texture, also converting to pre-multiplied // alpha, and BGRA if needed. Also copy border pixels to pixels outside // border to fix unwanted bilinear filtering effects int dx = cx * 8; int dy = cy * 8; int ds = atlas_image->width * 4; // stride unsigned char *dst = atlas_image->data + \ (dy * atlas_image->width + dx) * 4; unsigned char *sp = image->data; for (int y = 0; y < image->height; y++) { #if 1 if (y == 0 && dy > 0) { // repeat first line unsigned char *dp = dst - ds; for (int x = 0; x < image->width; x++) { copy_pixel(&dp, &sp); } sp -= image->width * 4; } #endif unsigned char *dp = dst; for (int x = 0; x < image->width; x++) { copy_pixel(&dp, &sp); } dst += 1024 * 4; // stride #if 1 if (y == image->height - 1 && dy + y - 1 < atlas_image->height - 1) { // repeat last line sp -= image->width * 4; unsigned char *dp = dst; for (int x = 0; x < image->width; x++) { copy_pixel(&dp, &sp); } } #endif } // repeat left and right borders uint32_t *idata = (uint32_t *) atlas_image->data; int iwidth = atlas_image->width; int y1 = dy; int y2 = dy + image->height - 1; if (y1 > 0) { y1 -= 1; } if (y2 < atlas_image->height - 1) { y2 += 1; } if (dx > 0) { for (int y = y1; y <= y2; y++) { idata[y * iwidth + dx - 1] = idata[y * iwidth + dx]; } } if (dx + image->width - 1 < atlas_image->width - 1) { for (int y = y1; y <= y2; y++) { idata[y * iwidth + dx + image->width - 1 + 1] = \ idata[y * iwidth + dx + image->width - 1]; } } // register texture coordinates g_entries[texture_id].x = cx * 8; g_entries[texture_id].y = cy * 8; g_entries[texture_id].w = image->width; g_entries[texture_id].h = image->height; // and finally free the sub-texture image fs_unref(image); }