Source Code (Use browser search to find items of interest.)
Class Index
kcontrol'KBackgroundRenderer (./kdebase/kcontrol/display/bgrender.h:35)
class KBackgroundRenderer:
public QObject,
public KBackgroundSettings
{
Q_OBJECT
public:
KBackgroundRenderer(int desk, KConfig *config=0);
~KBackgroundRenderer();
void load(int desk);
void setPreview(QSize size);
void setTile(bool tile);
QImage *image();
bool isActive() { return m_State & Rendering; }
void cleanup();
public slots:
void start();
void stop();
signals:
void imageDone(int desk);
private slots:
void slotBackgroundDone(KProcess *);
void render();
void done();
private:
enum { Error, Wait, WaitUpdate, Done };
enum { Rendering = 1, BackgroundStarted = 2,
BackgroundDone = 4, WallpaperStarted = 8,
WallpaperDone = 0x10, AllDone = 0x20 };
QString buildCommand();
void tile(QImage *dst, QRect rect, QImage *src);
int doBackground(bool quit=false);
int doWallpaper(bool quit=false);
bool m_bPreview, m_bTile;
int m_State;
pid_t m_Pid;
QString m_Tempfile;
QSize m_Size, m_rSize;
QImage *m_pImage, *m_pBackground;
QTimer *m_pTimer;
KConfig *m_pConfig;
KStandardDirs *m_pDirs;
KShellProcess *m_pProc;
};
kcontrol'KBackgroundRenderer::KBackgroundRenderer() (./kdebase/kcontrol/display/bgrender.cc:43)
KBackgroundRenderer::KBackgroundRenderer(int desk, KConfig *config)
: KBackgroundSettings(desk, config)
{
m_State = 0;
if (config)
m_pConfig = config;
else
m_pConfig = new KConfig("kdesktoprc");
m_pDirs = KGlobal::dirs();
m_rSize = m_Size = QApplication::desktop()->size();
m_pBackground = 0L; m_pImage = 0L;
m_pProc = 0L;
m_bPreview = false;
m_bTile = false;
m_pTimer = new QTimer(this);
connect(m_pTimer, SIGNAL(timeout()), SLOT(render()));
kimgioRegister();
}
kcontrol'KBackgroundRenderer::~KBackgroundRenderer() (./kdebase/kcontrol/display/bgrender.cc:66)
KBackgroundRenderer::~KBackgroundRenderer()
{
delete m_pImage;
}
kcontrol'KBackgroundRenderer::tile() (./kdebase/kcontrol/display/bgrender.cc:72)
void KBackgroundRenderer::tile(QImage *dest, QRect rect, QImage *src)
{
rect &= dest->rect();
int x, y;
int h = rect.height(), w = rect.width();
int offx = rect.x(), offy = rect.y();
int sw = src->width(), sh = src->height();
for (y=offy; y<offy+h; y++)
for (x=offx; x<offx+w; x++)
dest->setPixel(x, y, src->pixel(x%sw, y%sh));
}
/*
* Build a command line to run the program.
*/
kcontrol'KBackgroundRenderer::buildCommand() (./kdebase/kcontrol/display/bgrender.cc:91)
QString KBackgroundRenderer::buildCommand()
{
QString num;
int pos = 0;
QString cmd;
if (m_bPreview)
cmd = previewCommand();
else
cmd = command();
if (cmd.isEmpty())
return QString();
while ((pos = cmd.find('%', pos)) != -1) {
if (pos == (int) (cmd.length() - 1))
break;
switch (cmd.at(pos+1).latin1()) {
case 'f':
cmd.replace(pos, 2, m_Tempfile);
pos += m_Tempfile.length() - 2;
break;
case 'x':
num.setNum(m_Size.width());
cmd.replace(pos, 2, num);
pos += num.length() - 2;
break;
case 'y':
num.setNum(m_Size.height());
cmd.replace(pos, 2, num);
pos += num.length() - 2;
break;
case '%':
cmd.replace(pos, 2, "%");
pos--;
break;
}
}
return cmd;
}
/*
* Create a background tile. If the background mode is `Program',
* this is asynchronous.
*/
kcontrol'KBackgroundRenderer::doBackground() (./kdebase/kcontrol/display/bgrender.cc:143)
int KBackgroundRenderer::doBackground(bool quit)
{
if (m_State & BackgroundDone)
return Done;
int wpmode = wallpaperMode();
int blmode = blendMode();
int bgmode = backgroundMode();
if ( (blmode == NoBlending) &&
((wpmode == Tiled) ||
(wpmode == Scaled) ||
(wpmode == CenterTiled)) ) {
// full screen wallpaper modes: background is not visible
m_State |= BackgroundDone;
return Done;
}
if (quit) {
if (bgmode == Program)
m_pProc->kill();
return Done;
}
int retval = Done;
QString file;
switch (bgmode) {
case Flat:
m_pBackground->create(10, 10, 32);
m_pBackground->fill(colorA().rgb());
break;
case Pattern:
{
file = m_pDirs->findResource("dtop_pattern", pattern());
if (file.isEmpty())
break;
m_pBackground->load(file);
if (m_pBackground->isNull())
break;
int w = m_pBackground->width();
int h = m_pBackground->height();
if ((w > m_Size.width()) || (h > m_Size.height())) {
w = QMIN(w, m_Size.width());
h = QMIN(h, m_Size.height());
*m_pBackground = m_pBackground->copy(0, 0, w, h);
}
KImageEffect::flatten(*m_pBackground, colorA(), colorB(), 0);
break;
}
case Program:
if (m_State & BackgroundStarted)
break;
m_State |= BackgroundStarted;
m_Tempfile = tmpnam(0L);
file = buildCommand();
if (file.isEmpty())
break;
m_pProc = new KShellProcess;
*m_pProc << file;
connect(m_pProc, SIGNAL(processExited(KProcess *)),
SLOT(slotBackgroundDone(KProcess *)));
m_pProc->start(KShellProcess::NotifyOnExit);
retval = Wait;
break;
case HorizontalGradient:
{
QSize size = m_Size;
size.setHeight(30);
*m_pBackground = KImageEffect::gradient(size, colorA(), colorB(),
KImageEffect::HorizontalGradient, 0);
break;
}
case VerticalGradient:
{
QSize size = m_Size;
size.setWidth(30);
*m_pBackground = KImageEffect::gradient(size, colorA(), colorB(),
KImageEffect::VerticalGradient, 0);
break;
}
case PyramidGradient:
*m_pBackground = KImageEffect::gradient(m_Size, colorA(), colorB(),
KImageEffect::PyramidGradient, 0);
break;
case PipeCrossGradient:
*m_pBackground = KImageEffect::gradient(m_Size, colorA(), colorB(),
KImageEffect::PipeCrossGradient, 0);
break;
case EllipticGradient:
*m_pBackground = KImageEffect::gradient(m_Size, colorA(), colorB(),
KImageEffect::EllipticGradient, 0);
break;
}
if (retval == Done)
m_State |= BackgroundDone;
return retval;
}
kcontrol'KBackgroundRenderer::doWallpaper() (./kdebase/kcontrol/display/bgrender.cc:252)
int KBackgroundRenderer::doWallpaper(bool quit)
{
if (m_State & WallpaperDone)
return Done;
if (quit)
// currently no asynch. wallpapers
return Done;
int wpmode = wallpaperMode();
int blmode = blendMode();
// Tiling is only possible if there's no blending
bool bTile = m_bTile;
if ((wpmode != NoWallpaper) && (blmode != NoBlending))
bTile = false;
QImage wp;
if (wpmode != NoWallpaper) {
if (currentWallpaper().isEmpty()) {
wpmode = NoWallpaper;
goto wp_out;
}
QString file = m_pDirs->findResource("wallpaper", currentWallpaper());
if (file.isEmpty()) {
wpmode = NoWallpaper;
goto wp_out;
}
wp.load(file);
if (wp.isNull()) {
wpmode = NoWallpaper;
goto wp_out;
}
wp = wp.convertDepth(32);
// If we're previewing, scale the wallpaper down to make the preview
// look more like the real desktop.
if (m_bPreview) {
int xs = wp.width() * m_Size.width() / m_rSize.width();
int ys = wp.height() * m_Size.height() / m_rSize.height();
wp = wp.smoothScale(xs, ys);
}
}
wp_out:
if ( m_pBackground->isNull()) {
m_pBackground->create(10, 10, 32);
m_pBackground->fill(colorA().rgb());
}
int ww = wp.width();
int wh = wp.height();
int retval = Done;
switch (wpmode) {
case NoWallpaper:
{
if (bTile)
*m_pImage = *m_pBackground;
else {
m_pImage->create(m_Size, 32);
tile(m_pImage, QRect(0, 0, m_Size.width(), m_Size.height()),
m_pBackground);
}
break;
}
case Tiled:
{
int w = m_Size.width();
int h = m_Size.height();
int y;
if (bTile && (ww <= w) && (wh <= h))
*m_pImage = wp;
else {
m_pImage->create(m_Size, 32);
tile(m_pImage, QRect(0, 0, w, QMIN(wh,h)), &wp);
if (h > wh)
for (y=wh; y<h; y++)
memcpy(m_pImage->scanLine(y), m_pImage->scanLine(y % wh),
m_pImage->bytesPerLine());
}
break;
}
case CenterTiled:
{
QSize size = m_Size;
if (bTile)
size = QSize(QMIN(m_Size.width(), wp.width()),
QMIN(m_Size.height(), wp.height()));
m_pImage->create(size, 32);
int w = size.width();
int h = size.height();
int xa = ww - ((m_Size.width() - ww) / 2) % ww;
int ya = wh - ((m_Size.height() - wh) / 2) % wh;
int x, y;
for (y=0; y < QMIN(wh,h); y++)
for (x=0; x < w; x++)
m_pImage->setPixel(x, y, wp.pixel((xa + x) % ww, (ya + y) % wh));
if (h > wh)
for (y=wh; y < h; y++)
memcpy(m_pImage->scanLine(y), m_pImage->scanLine(y % wh),
m_pImage->bytesPerLine());
break;
}
case Scaled:
*m_pImage = wp.smoothScale(m_Size.width(), m_Size.height());
break;
case Centred:
{
int w = m_Size.width();
int h = m_Size.height();
int xa = (w - ww) / 2;
int ya = (h - wh) / 2;
int y, offx, offy;
// Check if anchor point is not outside the screen
if (xa <= 0) {
offx = -xa; ww = w; xa = 0;
} else
offx = 0;
if (ya <= 0) {
offy = -ya; wh = h; ya = 0;
} else
offy = 0;
// Background is no tile?
if (m_pBackground->size() == m_Size) {
// if we blend, we need a deep copy
if (blmode != NoBlending)
*m_pImage = m_pBackground->copy();
else
*m_pImage = *m_pBackground;
if (m_pImage->depth()<32)
*m_pImage = m_pImage->convertDepth(32);
}
else {
int tw = w, th = h;
int bw = m_pBackground->width(), bh = m_pBackground->height();
if (bTile) {
tw = QMIN(bw * ((xa + ww + bw - 1) / bw), w);
th = QMIN(bh * ((ya + wh + bh - 1) / bh), h);
}
m_pImage->create(tw, th, 32);
// Fill the rectangles not covered by the centred image.
if (ya) {
tile(m_pImage, QRect(0, 0, tw, ya), m_pBackground);
tile(m_pImage, QRect(0, ya+wh, tw, th-ya-wh), m_pBackground);
}
if (xa) {
tile(m_pImage, QRect(0, ya, xa, wh), m_pBackground);
tile(m_pImage, QRect(xa+ww, ya, tw-xa-ww, wh), m_pBackground);
}
}
// And copy the centred image
for (y=0; y<wh; y++)
memcpy(m_pImage->scanLine(ya+y) + xa * sizeof(QRgb),
wp.scanLine(y+offy) + offx * sizeof(QRgb),
ww * sizeof(QRgb));
break;
}
case CentredMaxpect:
{
int w = m_Size.width();
int h = m_Size.height();
double sx = (double) w / ww;
double sy = (double) h / wh;
if (sx > sy) {
ww = (int) (sy*ww);
wh = h;
} else {
ww = w;
wh = (int) (sx*wh);
}
wp = wp.smoothScale(ww, wh);
int xa = (w - ww) / 2;
int ya = (h - wh) / 2;
int y;
if (m_pBackground->size() == m_Size) {
// if we blend, we need a deep copy
if (blmode != NoBlending)
*m_pImage = m_pBackground->copy();
else
*m_pImage = *m_pBackground;
if (m_pImage->depth()<32)
*m_pImage = m_pImage->convertDepth(32);
}
else {
int tw = w, th = h;
int bw = m_pBackground->width(), bh = m_pBackground->height();
if (bTile) {
tw = QMIN(bw * ((xa + ww + bw - 1) / bw), w);
th = QMIN(bh * ((ya + wh + bh - 1) / bh), h);
}
m_pImage->create(tw, th, 32);
if (ya) {
tile(m_pImage, QRect(0, 0, tw, ya), m_pBackground);
tile(m_pImage, QRect(0, ya+wh, tw, th-ya-wh), m_pBackground);
} else {
tile(m_pImage, QRect(0, 0, xa, th), m_pBackground);
tile(m_pImage, QRect(xa+ww, 0, tw-xa-ww, th), m_pBackground);
}
}
for (y=0; y<wh; y++)
memcpy(m_pImage->scanLine(ya+y) + xa * sizeof(QRgb),
wp.scanLine(y), wp.bytesPerLine());
break;
}
}
if (wpmode != NoWallpaper) {
int bal = blendBalance();
switch( blmode ) {
case HorizontalBlending:
KImageEffect::blend( *m_pImage, *m_pBackground,
KImageEffect::HorizontalGradient,
bal, 100 );
break;
case VerticalBlending:
KImageEffect::blend( *m_pImage, *m_pBackground,
KImageEffect::VerticalGradient,
100, bal );
break;
case PyramidBlending:
KImageEffect::blend( *m_pImage, *m_pBackground,
KImageEffect::PyramidGradient,
bal, bal );
break;
case PipeCrossBlending:
KImageEffect::blend( *m_pImage, *m_pBackground,
KImageEffect::PipeCrossGradient,
bal, bal );
break;
case EllipticBlending:
KImageEffect::blend( *m_pImage, *m_pBackground,
KImageEffect::EllipticGradient,
bal, bal );
break;
case IntensityBlending:
KImageEffect::modulate( *m_pImage, *m_pBackground, reverseBlending(),
KImageEffect::Intensity, bal, KImageEffect::All );
break;
case SaturateBlending:
KImageEffect::modulate( *m_pImage, *m_pBackground, reverseBlending(),
KImageEffect::Saturation, bal, KImageEffect::Gray );
break;
case ContrastBlending:
KImageEffect::modulate( *m_pImage, *m_pBackground, reverseBlending(),
KImageEffect::Contrast, bal, KImageEffect::All );
break;
case HueShiftBlending:
KImageEffect::modulate( *m_pImage, *m_pBackground, reverseBlending(),
KImageEffect::HueShift, bal, KImageEffect::Gray );
break;
}
}
if (retval == Done)
m_State |= WallpaperDone;
return retval;
}
kcontrol'KBackgroundRenderer::slotBackgroundDone() (./kdebase/kcontrol/display/bgrender.cc:546)
void KBackgroundRenderer::slotBackgroundDone(KProcess *)
{
qDebug("slotBackgroundDone");
m_State |= BackgroundDone;
if (m_pProc->normalExit() && !m_pProc->exitStatus())
m_pBackground->load(m_Tempfile);
unlink(m_Tempfile.latin1());
m_pTimer->start(0, true);
}
/*
* Starts the rendering process.
*/
kcontrol'KBackgroundRenderer::start() (./kdebase/kcontrol/display/bgrender.cc:563)
void KBackgroundRenderer::start()
{
if (m_pBackground == 0L)
m_pBackground = new QImage();
if (m_pImage == 0L)
m_pImage = new QImage();
m_State = Rendering;
m_pTimer->start(0, true);
}
/*
* This slot is connected to a timer event. It is called repeatedly until
* the rendering is done.
*/
kcontrol'KBackgroundRenderer::render() (./kdebase/kcontrol/display/bgrender.cc:579)
void KBackgroundRenderer::render()
{
if (!(m_State & Rendering))
return;
int ret;
if (!(m_State & BackgroundDone)) {
ret = doBackground();
if (ret != Wait)
m_pTimer->start(0, true);
return;
}
// No async wallpaper
doWallpaper();
done();
}
/*
* Rendering is finished.
*/
kcontrol'KBackgroundRenderer::done() (./kdebase/kcontrol/display/bgrender.cc:603)
void KBackgroundRenderer::done()
{
m_State |= AllDone;
emit imageDone(desk());
}
/*
* Stop the rendering.
*/
kcontrol'KBackgroundRenderer::stop() (./kdebase/kcontrol/display/bgrender.cc:613)
void KBackgroundRenderer::stop()
{
if (!(m_State & Rendering))
return;
doBackground(true);
doWallpaper(true);
m_State = 0;
}
/*
* Cleanup after rendering.
*/
kcontrol'KBackgroundRenderer::cleanup() (./kdebase/kcontrol/display/bgrender.cc:628)
void KBackgroundRenderer::cleanup()
{
delete m_pBackground; m_pBackground = 0L;
delete m_pImage; m_pImage = 0L;
delete m_pProc; m_pProc = 0L;
m_State = 0;
}
kcontrol'KBackgroundRenderer::setPreview() (./kdebase/kcontrol/display/bgrender.cc:637)
void KBackgroundRenderer::setPreview(QSize size)
{
if (size.isNull())
m_bPreview = false;
else {
m_bPreview = true;
m_Size = size;
}
}
kcontrol'KBackgroundRenderer::setTile() (./kdebase/kcontrol/display/bgrender.cc:648)
void KBackgroundRenderer::setTile(bool tile)
{
m_bTile = tile;
}
kcontrol'KBackgroundRenderer::image() (./kdebase/kcontrol/display/bgrender.cc:654)
QImage *KBackgroundRenderer::image()
{
if (m_State & AllDone)
return m_pImage;
return 0L;
}
kcontrol'KBackgroundRenderer::load() (./kdebase/kcontrol/display/bgrender.cc:662)
void KBackgroundRenderer::load(int desk)
{
if (m_State & Rendering)
stop();
cleanup();
m_bPreview = false;
m_bTile = false;
m_Size = m_rSize;
KBackgroundSettings::load(desk);
}