#include "surface.hh"
#include "font.hh"
#include "ustring.hh"
+#include "property.hh"
extern "C" {
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif // HAVE_SYS_WAIT_H
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif // HAVE_UNISTD_H
#include "../src/gettext.h"
#define _(str) gettext(str)
}
+#include <cstdlib>
+
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;
RenderControl::RenderControl(int screen)
: _screen(screen)
+
{
printf("Initializing RenderControl\n");
+
}
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
}
reduceDepth(sf, im);
-
- im->data = (char*) data;
-
sf.setPixmap(im);
-
- im->data = NULL;
XDestroyImage(im);
}
unsigned long *data) const
{
pixel32 *bg = sf.pixelData();
- int startx, x, y, c;
- unsigned int i, e;
- x = (sf.size().width() - w) / 2;
- y = (sf.size().height() - h) / 2;
-
- if (x < 0) x = 0;
- if (y < 0) y = 0;
-
- // XX SCALING!@!&*(@! to make it fit on the surface
-
- startx = x;
-
- for (i = 0, c = 0, e = w*h; i < e; ++i) {
- 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;
+ int c, sfw, sfh;
+ unsigned int i, e, bgi;
+ sfw = sf.size().width();
+ sfh = sf.size().height();
+
+ 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 = sfw*sfh; i < e; ++i) {
+ newdata[i] = olddata[(int)px + iy];
+ if (++c >= sfw) {
+ c = 0;
+ px = 0;
+ py += dy;
+ iy = (int)py * w;
+ } else
+ px += dx;
+ }
+ data = newdata;
+
+ // 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;
-
- bg[i] = (r << default_red_shift) | (g << default_green_shift) |
- (b << default_blue_shift);
-
- if (++c >= w) {
- ++y;
- x = startx;
- c = 0;
- } else
- ++x;
+ r = bgr + (((r - bgr) * alpha) >> 8);
+ g = bgg + (((g - bgg) * alpha) >> 8);
+ b = bgb + (((b - bgb) * alpha) >> 8);
+
+ bg[i] = (r << default_red_shift) | (g << default_green_shift) |
+ (b << default_blue_shift);
+ }
}
const ScreenInfo *info = display->screenInfo(_screen);
im->byte_order = endian;
reduceDepth(sf, im);
+ sf.setPixmap(im);
+ XDestroyImage(im);
+}
- im->data = (char*) bg;
+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;
+
+ assert(pixmap != None);
+
+ sfw = sf.size().width();
+ sfh = sf.size().height();
+
+ 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;
+ }
- sf.setPixmap(im);
+ 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);
+ }
- im->data = NULL;
- XDestroyImage(im);
+ // 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);
}
}