Ejemplo n.º 1
0
Archivo: x11.c Proyecto: engur/fs-uae
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);
}
Ejemplo n.º 2
0
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);
}