예제 #1
0
void X11Window::setMouseCursor(const std::string& file, const Point& hotSpot)
{
    std::stringstream fin;
    g_resources.loadFile(file, fin);

    apng_data apng;
    if(load_apng(fin, &apng) != 0) {
        g_logger.traceError(stdext::format("unable to load png file %s", file));
        return;
    }

    if(apng.bpp != 4) {
        g_logger.error("the cursor png must have 4 channels");
        free_apng(&apng);
        return;
    }

    if(apng.width != 32|| apng.height != 32) {
        g_logger.error("the cursor png must have 32x32 dimension");
        free_apng(&apng);
        return;
    }

    if(m_cursor != None)
        restoreMouseCursor();

    int width = apng.width;
    int height = apng.height;
    int numbits = width * height;
    int numbytes = (width * height)/8;

    XColor bg, fg;
    bg.red   = 255 << 8;
    bg.green = 255 << 8;
    bg.blue  = 255 << 8;
    fg.red   = 0;
    fg.green = 0;
    fg.blue  = 0;

    std::vector<uchar> mapBits(numbytes, 0);
    std::vector<uchar> maskBits(numbytes, 0);

    for(int i=0;i<numbits;++i) {
        uint32 rgba = stdext::readLE32(apng.pdata + i*4);
        if(rgba == 0xffffffff) { //white, background
            LSB_BIT_SET(maskBits, i);
        } else if(rgba == 0xff000000) { //black, foreground
            LSB_BIT_SET(mapBits, i);
            LSB_BIT_SET(maskBits, i);
        } //otherwise 0x00000000 => alpha
    }
    free_apng(&apng);

    Pixmap cp = XCreateBitmapFromData(m_display, m_window, (char*)&mapBits[0], width, height);
    Pixmap mp = XCreateBitmapFromData(m_display, m_window, (char*)&maskBits[0], width, height);
    m_cursor = XCreatePixmapCursor(m_display, cp, mp, &fg, &bg, hotSpot.x, hotSpot.y);
    XDefineCursor(m_display, m_window, m_cursor);
    XFreePixmap(m_display, cp);
    XFreePixmap(m_display, mp);
}
예제 #2
0
int X11Window::internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot)
{
    int width = image->getWidth();
    int height = image->getHeight();
    int numbits = width * height;
    int numbytes = (width * height)/8;

    XColor bg, fg;
    bg.red   = 255 << 8;
    bg.green = 255 << 8;
    bg.blue  = 255 << 8;
    fg.red   = 0;
    fg.green = 0;
    fg.blue  = 0;

    std::vector<uchar> mapBits(numbytes, 0);
    std::vector<uchar> maskBits(numbytes, 0);

    for(int i=0;i<numbits;++i) {
        uint32 rgba = stdext::readULE32(image->getPixelData() + i*4);
        if(rgba == 0xffffffff) { //white, background
            LSB_BIT_SET(maskBits, i);
        } else if(rgba == 0xff000000) { //black, foreground
            LSB_BIT_SET(mapBits, i);
            LSB_BIT_SET(maskBits, i);
        } //otherwise 0x00000000 => alpha
    }

    Pixmap cp = XCreateBitmapFromData(m_display, m_window, (char*)&mapBits[0], width, height);
    Pixmap mp = XCreateBitmapFromData(m_display, m_window, (char*)&maskBits[0], width, height);
    Cursor cursor = XCreatePixmapCursor(m_display, cp, mp, &fg, &bg, hotSpot.x, hotSpot.y);
    XFreePixmap(m_display, cp);
    XFreePixmap(m_display, mp);

    m_cursors.push_back(cursor);
    return m_cursors.size()-1;
}