+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;
+ }
+
+ 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);
+}
+