summaryrefslogtreecommitdiffstats
path: root/src/xosd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xosd.cpp')
-rw-r--r--src/xosd.cpp226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/xosd.cpp b/src/xosd.cpp
new file mode 100644
index 0000000..656be2d
--- /dev/null
+++ b/src/xosd.cpp
@@ -0,0 +1,226 @@
+#include "xosd.h"
+
+#include <qpainter.h>
+#include <qbitmap.h>
+#include <qstring.h>
+#include <qfont.h>
+#include <qfontmetrics.h>
+
+#include <qwidget.h>
+#include <klocale.h>
+#include <netwm.h>
+#include <netwm_def.h>
+#include <kwin.h>
+
+#include <kdebug.h>
+
+xosd::xosd(QWidget *parent, const char *name) : QWidget(parent, name, WStyle_Customize | WRepaintNoErase | WStyle_NoBorder | WDestructiveClose | WResizeNoErase | WMouseNoMask | WStyle_StaysOnTop | WX11BypassWM)
+{
+ info = new NETWinInfo( qt_xdisplay(), winId(), qt_xrootwin(), NET::WMState);
+ info->setDesktop( NETWinInfo::OnAllDesktops );
+ hide();
+ KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
+ setCaption("kooldock xosd window");
+}
+
+xosd::~xosd()
+{
+}
+
+void xosd::setColor(QString color)
+{
+ fontColor=color;
+}
+
+void xosd::setShadowColor(QString color)
+{
+ shadowColor=color;
+}
+
+void xosd::setOrientation(int orientation, int w, int mh)
+{
+ fOrientation=orientation;
+ dw=w;
+ rdh=mh;
+ if (fCleaner==1)
+ {
+ //font is set, so program can get its height to prepare background buffer
+ QFontMetrics *metrics = new QFontMetrics(f);
+ h = metrics->height();
+
+ bgBuffer = QPixmap(dw, h);
+ maskBuffer = QPixmap(dw, h, true);
+ bgBuffer = QPixmap::grabWindow(qt_xrootwin(), 0, 0, dw, h);
+ lastX=0;
+ lastY=0;
+ }
+
+}
+
+//Enables/disables dynamic background
+void xosd::setClear(int nClean)
+{
+ fCleaner = nClean;
+}
+
+void xosd::setShadowOffset(int off)
+{
+ shadowOffset=off;
+}
+
+void xosd::setText(QString t)
+{
+ //setMask(QRegion(0,0,0,0));
+ // NOTICE: it appears that with WX11BypassWM, resize() doesn't flick the widget anymore :)
+ // so, setMask() is no more needed.
+ // -- Matias
+ resize(0,0);
+ text = t;
+ QFontMetrics *metrics = new QFontMetrics(f);
+ w = metrics->width(text);
+ w = w + shadowOffset + 5; // 5 pixels more
+ h = metrics->height();
+ yOffset = metrics->height()-metrics->descent();
+ update();
+}
+
+void xosd::setFont(QString font)
+{
+ f.setFamily(font);
+}
+
+void xosd::setItalic()
+{
+ f.setItalic(TRUE);
+}
+
+void xosd::setBold()
+{
+ f.setBold(TRUE);
+}
+
+void xosd::setSize(int size)
+{
+ f.setPointSize(size);
+ fontSize = size;
+}
+
+/*int xosd::w()
+{
+ QFontMetrics *metrics = new QFontMetrics(f);
+ return (metrics->width(text) + shadowOffset + 5);
+
+}
+
+int xosd::h()
+{
+ QFontMetrics *metrics = new QFontMetrics(f);
+ return metrics->height();
+}*/
+
+void xosd::paintEvent(QPaintEvent *)
+{
+ int i, j;
+
+ resize(w,h);
+
+ QPixmap pm(size());
+ QBitmap bm(size());
+ QPainter p;
+
+ //Drawing text
+ p.begin(&pm, this);
+ if (fCleaner==1)
+ {
+ //Dynamic background - look cleaner
+ bitBlt(&pm, 0, 0, &bgBuffer, lastX, 0, w, h);
+ }
+ else
+ {
+ //One colour background - work faster
+ p.fillRect (rect(), QColor(shadowColor));
+ }
+
+ p.setPen( QColor(shadowColor) );
+ p.setFont(f);
+ p.drawText(shadowOffset, yOffset + shadowOffset, text, AlignCenter); // draw shadow text
+
+ // now, draw normal text
+ p.setPen( QColor(fontColor) );
+
+ p.drawText(1, yOffset, text, AlignCenter); // draw front text
+
+ p.end();
+
+ //Drawing mask
+ p.begin(&bm, this);
+ // now we must draw the text with black color for making the mask
+ p.setPen( Qt::white );
+ p.fillRect (rect(), Qt::black);
+ p.setFont(f);
+ for (i=-fCleaner;i<=fCleaner;i++)
+ {
+ for (j=-fCleaner;j<=fCleaner;j++)
+ {
+ p.drawText(shadowOffset+i, yOffset + shadowOffset+j, text, AlignCenter); // shadow
+ p.drawText(1+i, yOffset+j, text, AlignCenter); // front
+ }
+ }
+ p.end();
+ bitBlt(this, 0, 0, &pm); // update the widget
+ if (fCleaner==1) bitBlt(&maskBuffer, 0, 0, &bm);
+
+ info->setState(NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager, NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager);
+ setMask(bm);
+}
+
+void xosd::move2(int x, int y)
+{
+
+ //bit block transfer don't work propertly with too less cursor position changes
+ if (abs(lastY-y)>2 || abs(lastX-x)>2)
+ {
+ if (fCleaner==1)
+ {
+ QPixmap tmpBuffer;
+ //window is not hidden
+ if (y!=rdh)
+ {
+ tmpBuffer = QPixmap::grabWindow(qt_xrootwin(), 0, y, dw, h);
+ if (lastY!=rdh)
+ {
+ //fill background covered with the text with cached version
+ if (fOrientation==0 ) //horizontal
+ {
+ bitBlt(&tmpBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::AndROP);//copying part, which hides only the text
+ bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::NotAndROP);//so the background won't be covered by
+ bitBlt(&tmpBuffer, lastX, 0, &bgBuffer, lastX, 0, w, h, Qt::OrROP);//currently visible text.
+ }
+ if (fOrientation==1) //vertical
+ {
+ if (y<lastY && (y+h)>lastY)
+ {
+ bitBlt(&tmpBuffer, lastX, lastY-y, &maskBuffer, 0, 0, w, h, Qt::AndROP);
+ bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::NotAndROP);
+ bitBlt(&tmpBuffer, lastX, lastY-y, &bgBuffer, lastX, 0, w, h, Qt::OrROP);
+ }
+ if (y>lastY && (y-lastY)<h)
+ {
+ bitBlt(&tmpBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::AndROP);
+ bitBlt(&bgBuffer, lastX, y-lastY, &maskBuffer, 0, 0, w, h, Qt::NotAndROP);
+ bitBlt(&tmpBuffer, lastX, 0, &bgBuffer, lastX, y-lastY, w, h, Qt::OrROP);
+ }
+ }
+ }
+
+ }
+ bitBlt(&bgBuffer,0,0,&tmpBuffer);
+ lastX=x;
+ paintEvent(NULL);
+ }
+
+ move(x,y);
+ lastX=x;
+ lastY=y;
+ }
+}