/** Load a solid background. */ void LoadSolidBackground(BackgroundNode *bp) { XColor c; ParseColor(bp->value, &c); /* Create the window. */ bp->window = JXCreateSimpleWindow(display, rootWindow, 0, 0, rootWidth, rootHeight, 0, 0, 0); /* Create the pixmap. */ bp->pixmap = JXCreatePixmap(display, bp->window, 1, 1, rootDepth); JXSetForeground(display, rootGC, c.pixel); JXDrawPoint(display, bp->pixmap, rootGC, 0, 0); }
/** Get a scaled icon. */ ScaledIconNode *GetScaledIcon(IconNode *icon, long fg, int rwidth, int rheight) { XColor color; XImage *image; ScaledIconNode *np; GC maskGC; int x, y; int scalex, scaley; /* Fixed point. */ int srcx, srcy; /* Fixed point. */ int ratio; /* Fixed point. */ int nwidth, nheight; unsigned char *data; Assert(icon); Assert(icon->image); if(rwidth == 0) { rwidth = icon->image->width; } if(rheight == 0) { rheight = icon->image->height; } ratio = (icon->image->width << 16) / icon->image->height; nwidth = Min(rwidth, (rheight * ratio) >> 16); nheight = Min(rheight, (nwidth << 16) / ratio); nwidth = (nheight * ratio) >> 16; if(nwidth < 1) { nwidth = 1; } if(nheight < 1) { nheight = 1; } /* Check if this size already exists. * Note that XRender scales on the fly. */ for(np = icon->nodes; np; np = np->next) { #ifdef USE_XRENDER if(np->imagePicture != None) { np->width = nwidth; np->height = nheight; return np; } #endif if(np->width == nwidth && np->height == nheight) { if(!icon->image->bitmap || np->fg == fg) { return np; } } } /* See if we can use XRender to create the icon. */ #ifdef USE_XRENDER if(haveRender) { np = CreateScaledRenderIcon(icon, fg, nwidth, nheight); /* Don't keep the image data around after creating the icon. */ Release(icon->image->data); icon->image->data = NULL; return np; } #endif /* Create a new ScaledIconNode the old-fashioned way. */ np = Allocate(sizeof(ScaledIconNode)); np->fg = fg; np->width = nwidth; np->height = nheight; np->next = icon->nodes; #ifdef USE_XRENDER np->imagePicture = None; #endif icon->nodes = np; /* Create a mask. */ np->mask = JXCreatePixmap(display, rootWindow, nwidth, nheight, 1); maskGC = JXCreateGC(display, np->mask, 0, NULL); JXSetForeground(display, maskGC, 0); JXFillRectangle(display, np->mask, maskGC, 0, 0, nwidth, nheight); JXSetForeground(display, maskGC, 1); /* Create a temporary XImage for scaling. */ image = JXCreateImage(display, rootVisual, rootDepth, ZPixmap, 0, NULL, nwidth, nheight, 8, 0); image->data = Allocate(sizeof(unsigned long) * nwidth * nheight); /* Determine the scale factor. */ scalex = (icon->image->width << 16) / nwidth; scaley = (icon->image->height << 16) / nheight; data = icon->image->data; srcy = 0; for(y = 0; y < nheight; y++) { const int yindex = (srcy >> 16) * icon->image->width; srcx = 0; for(x = 0; x < nwidth; x++) { if(icon->image->bitmap) { const int index = yindex + (srcx >> 16); const int offset = index >> 3; const int mask = 1 << (index & 7); if(data[offset] & mask) { JXDrawPoint(display, np->mask, maskGC, x, y); XPutPixel(image, x, y, fg); } } else { const int yindex = (srcy >> 16) * icon->image->width; const int index = 4 * (yindex + (srcx >> 16)); color.red = data[index + 1]; color.red |= color.red << 8; color.green = data[index + 2]; color.green |= color.green << 8; color.blue = data[index + 3]; color.blue |= color.blue << 8; GetColor(&color); XPutPixel(image, x, y, color.pixel); if(data[index] >= 128) { JXDrawPoint(display, np->mask, maskGC, x, y); } } srcx += scalex; } srcy += scaley; }