X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Frendercontrol.cc;h=6386b035c86dc481d018ae93303ae396fa65c58e;hb=3147507622de5ab771c99a4bb636f55344f6cbd7;hp=90f99632426efb8db566ce2c58252ae45beeb1ae;hpb=8446eaedc7d42e54c9719ee0b2c115f5feab09ca;p=chaz%2Fopenbox diff --git a/otk/rendercontrol.cc b/otk/rendercontrol.cc index 90f99632..6386b035 100644 --- a/otk/rendercontrol.cc +++ b/otk/rendercontrol.cc @@ -13,19 +13,26 @@ #include "surface.hh" #include "font.hh" #include "ustring.hh" +#include "property.hh" extern "C" { -#ifdef HAVE_STDLIB_H -# include -#endif // HAVE_STDLIB_H +#ifdef HAVE_SYS_WAIT_H +# include +#endif // HAVE_SYS_WAIT_H + +#ifdef HAVE_UNISTD_H +# include +#endif // HAVE_UNISTD_H #include "../src/gettext.h" #define _(str) gettext(str) } +#include + namespace otk { -RenderControl *RenderControl::getRenderControl(int screen) +RenderControl *RenderControl::createRenderControl(int screen) { // get the visual on the screen and return the correct type of RenderControl int vclass = display->screenInfo(screen)->visual()->c_class; @@ -47,8 +54,10 @@ RenderControl *RenderControl::getRenderControl(int screen) RenderControl::RenderControl(int screen) : _screen(screen) + { printf("Initializing RenderControl\n"); + } RenderControl::~RenderControl() @@ -56,13 +65,6 @@ RenderControl::~RenderControl() printf("Destroying RenderControl\n"); } -void RenderControl::drawRoot(const RenderColor &color) const -{ - Window root = display->screenInfo(_screen)->rootWindow(); - XSetWindowBackground(**display, root, color.pixel()); - XClearWindow(**display, root); -} - void RenderControl::drawString(Surface& sf, const Font &font, int x, int y, const RenderColor &color, const ustring &string) const @@ -230,6 +232,9 @@ void RenderControl::drawGradientBackground( case RenderTexture::Vertical: verticalGradient(sf, texture); break; + case RenderTexture::Horizontal: + horizontalGradient(sf, texture); + break; case RenderTexture::Diagonal: diagonalGradient(sf, texture); break; @@ -285,12 +290,7 @@ void RenderControl::drawGradientBackground( } reduceDepth(sf, im); - - im->data = (char*) data; - sf.setPixmap(im); - - im->data = NULL; XDestroyImage(im); } @@ -324,6 +324,36 @@ void RenderControl::verticalGradient(Surface &sf, } } +void RenderControl::horizontalGradient(Surface &sf, + const RenderTexture &texture) const +{ + pixel32 *data = sf.pixelData(); + pixel32 current; + float dr, dg, db; + unsigned int r,g,b; + int w = sf.size().width(), h = sf.size().height(); + + dr = (float)(texture.secondary_color().red() - texture.color().red()); + dr/= (float)w; + + dg = (float)(texture.secondary_color().green() - texture.color().green()); + dg/= (float)w; + + db = (float)(texture.secondary_color().blue() - texture.color().blue()); + db/= (float)w; + + for (int x = 0; x < w; ++x, ++data) { + r = texture.color().red() + (int)(dr * x); + g = texture.color().green() + (int)(dg * x); + b = texture.color().blue() + (int)(db * x); + current = (r << default_red_shift) + + (g << default_green_shift) + + (b << default_blue_shift); + for (int y = 0; y < h; ++y) + *(data + y*w) = current; + } +} + void RenderControl::diagonalGradient(Surface &sf, const RenderTexture &texture) const { @@ -441,62 +471,50 @@ void RenderControl::drawImage(Surface &sf, int w, int h, unsigned long *data) const { pixel32 *bg = sf.pixelData(); - int x, y, c, sfw, sfh; + int c, sfw, sfh; unsigned int i, e, bgi; sfw = sf.size().width(); sfh = sf.size().height(); - x = (sfw - w) / 2; - y = (sfh - h) / 2; - - if (x < 0) x = 0; - if (y < 0) y = 0; - - // XXX SCALING!@!&*(@! to make it fit on the surface - int oldw = w, oldh = h; - unsigned long *olddata = data; - if (w > sfw) w = sfw; - if (h > sfh) h = sfh; - unsigned long newdata[w*h]; - if (w < oldw || h < oldh) { - double dx = oldw / (double)w; - double dy = oldh / (double)h; + + if (w && h) { + // scale it + unsigned long *olddata = data; + unsigned long newdata[sfw*sfh]; + double dx = w / (double)sfw; + double dy = h / (double)sfh; double px = 0.0; double py = 0.0; int iy = 0; - for (i = 0, c = 0, e = w*h; i < e; ++i) { + for (i = 0, c = 0, e = sfw*sfh; i < e; ++i) { newdata[i] = olddata[(int)px + iy]; - if (++c >= w) { + if (++c >= sfw) { c = 0; px = 0; py += dy; - iy = (int)py * oldw; + iy = (int)py * w; } else px += dx; } data = newdata; - } - - for (i = 0, c = 0, bgi = y * sfw + x, e = w*h; i < e; ++i, ++bgi) { - unsigned char alpha = data[i] >> 24; - unsigned char r = data[i] >> 16; - unsigned char g = data[i] >> 8; - unsigned char b = data[i]; - // background color - unsigned char bgr = bg[bgi] >> default_red_shift; - unsigned char bgg = bg[bgi] >> default_green_shift; - unsigned char bgb = bg[bgi] >> default_blue_shift; + // apply the alpha channel + for (i = 0, c = 0, e = sfw*sfh; i < e; ++i, ++bgi) { + unsigned char alpha = data[i] >> 24; + unsigned char r = data[i] >> 16; + unsigned char g = data[i] >> 8; + unsigned char b = data[i]; + + // background color + unsigned char bgr = bg[i] >> default_red_shift; + unsigned char bgg = bg[i] >> default_green_shift; + unsigned char bgb = bg[i] >> default_blue_shift; - r = bgr + (((r - bgr) * alpha) >> 8); - g = bgg + (((g - bgg) * alpha) >> 8); - b = bgb + (((b - bgb) * alpha) >> 8); + r = bgr + (((r - bgr) * alpha) >> 8); + g = bgg + (((g - bgg) * alpha) >> 8); + b = bgb + (((b - bgb) * alpha) >> 8); - bg[bgi] = (r << default_red_shift) | (g << default_green_shift) | - (b << default_blue_shift); - - if (++c >= w) { - c = 0; - bgi += sfw - w; + bg[i] = (r << default_red_shift) | (g << default_green_shift) | + (b << default_blue_shift); } } @@ -507,13 +525,72 @@ void RenderControl::drawImage(Surface &sf, int w, int h, im->byte_order = endian; reduceDepth(sf, im); + sf.setPixmap(im); + XDestroyImage(im); +} + +void RenderControl::drawImage(Surface &sf, Pixmap pixmap, Pixmap mask) const +{ + int junk, sfw, sfh, w, h, depth, mw, mh, mdepth; + Window wjunk; + const ScreenInfo *info = display->screenInfo(_screen); + GC mgc = 0; - im->data = (char*) bg; + assert(pixmap != None); - sf.setPixmap(im); + sfw = sf.size().width(); + sfh = sf.size().height(); - im->data = NULL; - XDestroyImage(im); + XGetGeometry(**display, pixmap, &wjunk, &junk, &junk, + (unsigned int*)&w, (unsigned int*)&h, + (unsigned int*)&junk, (unsigned int*)&depth); + if (mask != None) { + XGetGeometry(**display, mask, &wjunk, &junk, &junk, + (unsigned int*)&mw, (unsigned int*)&mh, + (unsigned int*)&junk, (unsigned int*)&mdepth); + if (mw != w || mh != h || mdepth != 1) + return; + } + + Pixmap p = XCreatePixmap(**display, info->rootWindow(), sfw, sfh, + info->depth()); + Pixmap m; + if (mask == None) + m = None; + else { + m = XCreatePixmap(**display, info->rootWindow(), sfw, sfh, 1); + XGCValues gcv; + gcv.subwindow_mode = IncludeInferiors; + gcv.graphics_exposures = false; + mgc = XCreateGC(**display, m, GCGraphicsExposures | + GCSubwindowMode, &gcv); + } + + // scale it + for (int y = sfh - 1; y >= 0; --y) { + int yy = y * h / sfh; + for (int x = sfw - 1; x >= 0; --x) { + int xx = x * w / sfw; + if (depth != info->depth()) { + XCopyPlane(**display, pixmap, p, DefaultGC(**display, _screen), + xx, yy, 1, 1, x, y, 1); + } else { + XCopyArea(**display, pixmap, p, DefaultGC(**display, _screen), + xx, yy, 1, 1, x, y); + } + if (mask != None) + XCopyArea(**display, mask, m, mgc, xx, yy, 1, 1, x, y); + } + } + + XSetClipMask(**display, DefaultGC(**display, _screen), m); + XSetClipOrigin(**display, DefaultGC(**display, _screen), 0, 0); + XCopyArea(**display, p, sf.pixmap(), DefaultGC(**display, _screen), 0, 0, + sfw, sfh, 0, 0); + XSetClipMask(**display, DefaultGC(**display, _screen), None); + + XFreePixmap(**display, p); + if (m != None) XFreePixmap(**display, m); } }