#include "WINGsP.h"

#include <wraster.h>


WMPixmap*
WMRetainPixmap(WMPixmap *pixmap)
{
    if (pixmap)
        pixmap->refCount++;

    return pixmap;
}


void
WMReleasePixmap(WMPixmap *pixmap)
{
    wassertr(pixmap!=NULL);

    pixmap->refCount--;

    if (pixmap->refCount<1) {
        if (pixmap->pixmap)
            XFreePixmap(pixmap->screen->display, pixmap->pixmap);
        if (pixmap->mask)
            XFreePixmap(pixmap->screen->display, pixmap->mask);
        wfree(pixmap);
    }
}


WMPixmap*
WMCreatePixmap(WMScreen *scrPtr, int width, int height, int depth, Bool masked)
{
    WMPixmap *pixPtr;

    pixPtr = wmalloc(sizeof(WMPixmap));
    pixPtr->screen = scrPtr;
    pixPtr->width = width;
    pixPtr->height = height;
    pixPtr->depth = depth;
    pixPtr->refCount = 1;

    pixPtr->pixmap = XCreatePixmap(scrPtr->display, W_DRAWABLE(scrPtr),
                                   width, height, depth);
    if (masked) {
        pixPtr->mask = XCreatePixmap(scrPtr->display, W_DRAWABLE(scrPtr),
                                     width, height, 1);
    } else {
        pixPtr->mask = None;
    }

    return pixPtr;
}


WMPixmap*
WMCreatePixmapFromXPixmaps(WMScreen *scrPtr, Pixmap pixmap, Pixmap mask,
                           int width, int height, int depth)
{
    WMPixmap *pixPtr;

    pixPtr = wmalloc(sizeof(WMPixmap));
    pixPtr->screen = scrPtr;
    pixPtr->pixmap = pixmap;
    pixPtr->mask = mask;
    pixPtr->width = width;
    pixPtr->height = height;
    pixPtr->depth = depth;
    pixPtr->refCount = 1;

    return pixPtr;
}


WMPixmap*
WMCreatePixmapFromFile(WMScreen *scrPtr, char *fileName)
{
    WMPixmap *pixPtr;
    RImage *image;

    image = RLoadImage(scrPtr->rcontext, fileName, 0);
    if (!image)
        return NULL;

    pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 127);

    RReleaseImage(image);

    return pixPtr;
}


WMPixmap*
WMCreatePixmapFromRImage(WMScreen *scrPtr, RImage *image, int threshold)
{
    WMPixmap *pixPtr;
    Pixmap pixmap, mask;

    if (!RConvertImageMask(scrPtr->rcontext, image, &pixmap, &mask,
                           threshold)) {
        return NULL;
    }

    pixPtr = wmalloc(sizeof(WMPixmap));
    pixPtr->screen = scrPtr;
    pixPtr->pixmap = pixmap;
    pixPtr->mask = mask;
    pixPtr->width = image->width;
    pixPtr->height = image->height;
    pixPtr->depth = scrPtr->depth;
    pixPtr->refCount = 1;

    return pixPtr;
}


WMPixmap*
WMCreateBlendedPixmapFromRImage(WMScreen *scrPtr, RImage *image, RColor *color)
{
    WMPixmap *pixPtr;
    RImage *copy;

    copy = RCloneImage(image);
    if (!copy)
        return NULL;

    RCombineImageWithColor(copy, color);
    pixPtr = WMCreatePixmapFromRImage(scrPtr, copy, 0);
    RReleaseImage(copy);

    return pixPtr;
}


WMPixmap*
WMCreateBlendedPixmapFromFile(WMScreen *scrPtr, char *fileName, RColor *color)
{
    WMPixmap *pixPtr;
    RImage *image;


    image = RLoadImage(scrPtr->rcontext, fileName, 0);
    if (!image)
        return NULL;

    RCombineImageWithColor(image, color);

    pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 0);

    RReleaseImage(image);

    return pixPtr;
}


WMPixmap*
WMCreatePixmapFromXPMData(WMScreen *scrPtr, char **data)
{
    WMPixmap *pixPtr;
    RImage *image;

    image = RGetImageFromXPMData(scrPtr->rcontext, data);
    if (!image)
        return NULL;

    pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 127);

    RReleaseImage(image);

    return pixPtr;
}


Pixmap
WMGetPixmapXID(WMPixmap *pixmap)
{
    wassertrv(pixmap != NULL, None);

    return pixmap->pixmap;
}


Pixmap
WMGetPixmapMaskXID(WMPixmap *pixmap)
{
    wassertrv(pixmap != NULL, None);

    return pixmap->mask;
}


WMSize
WMGetPixmapSize(WMPixmap *pixmap)
{
    WMSize size = {0,0};

    wassertrv(pixmap != NULL, size);

    size.width = pixmap->width;
    size.height = pixmap->height;

    return size;
}


WMPixmap*
WMGetSystemPixmap(WMScreen *scr, int image)
{
    switch (image) {
    case WSIReturnArrow:
        return WMRetainPixmap(scr->buttonArrow);

    case WSIHighlightedReturnArrow:
        return WMRetainPixmap(scr->pushedButtonArrow);

    case WSIScrollerDimple:
        return WMRetainPixmap(scr->scrollerDimple);

    case WSIArrowLeft:
        return WMRetainPixmap(scr->leftArrow);

    case WSIHighlightedArrowLeft:
        return WMRetainPixmap(scr->hiLeftArrow);

    case WSIArrowRight:
        return WMRetainPixmap(scr->rightArrow);

    case WSIHighlightedArrowRight:
        return WMRetainPixmap(scr->hiRightArrow);

    case WSIArrowUp:
        return WMRetainPixmap(scr->upArrow);

    case WSIHighlightedArrowUp:
        return WMRetainPixmap(scr->hiUpArrow);

    case WSIArrowDown:
        return WMRetainPixmap(scr->downArrow);

    case WSIHighlightedArrowDown:
        return WMRetainPixmap(scr->hiDownArrow);

    case WSICheckMark:
        return WMRetainPixmap(scr->checkMark);

    default:
        return NULL;
    }
}



void
WMDrawPixmap(WMPixmap *pixmap, Drawable d, int x, int y)
{
    WMScreen *scr = pixmap->screen;

    XSetClipMask(scr->display, scr->clipGC, pixmap->mask);
    XSetClipOrigin(scr->display, scr->clipGC, x, y);

    XCopyArea(scr->display, pixmap->pixmap, d, scr->clipGC, 0, 0,
              pixmap->width, pixmap->height, x, y);
}



syntax highlighted by Code2HTML, v. 0.9.1