summaryrefslogblamecommitdiffstats
path: root/src/maingui/backdrop.cpp
blob: db16b01097e4ac3a9d2edc10cfa2b16f7bac3999 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                     

                    






                         




                                     



                                         


                                         






















                                                                                                       




































































                                                                                                                         














                                                                



                                                                   



                                             







                                                    
#include "backdrop.h"
#include "../util.h"
#include "pwgui.h"

#include <QApplication>
#include <QDesktopWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
#include <QRgb>
#include <QLocalServer>
#include <QLocalSocket>
#include <sys/stat.h>

static const QString strTest("test");

Backdrop::Backdrop() :
			QWidget(NULL),
			screenshot(NULL),
			mainWindow(NULL),
			server(NULL),
			pwgui(NULL)
{
	QPixmap shot = QPixmap::grabWindow(QApplication::desktop()->winId());
	if (!shot.isNull() && shot.height() > 0) {
		QImage img = shot.toImage();
		if (img.format() != QImage::Format_RGB32) {
			img = img.convertToFormat(QImage::Format_RGB32);
		}
		for (int i = 0; i < img.height(); ++i) {
			uchar *line = img.scanLine(i);
			if (line == NULL)
				continue;
			QRgb *rgb = (QRgb*)line;
			for (int x = 0; x < img.width(); ++x) {
				const int val = (qRed(*rgb)*11 + qGreen(*rgb)*16 + qBlue(*rgb)*5) / 32;
				*rgb = qRgb(val, val, val);
				rgb++;
			}
		}
		shot = QPixmap::fromImage(img);
	}
	screenshot = new QPixmap(shot);
	this->resize(screenshot->width(), screenshot->height());
	this->setWindowFlags(Qt::Tool | Qt::CustomizeWindowHint | Qt::FramelessWindowHint);

	char sockPath[500];
	if (NULL != util_sockPath(-1, -1, sockPath, sizeof sockPath)) {
		QString path = QString::fromUtf8(sockPath);
		QFile::remove(path);
		server = new QLocalServer(this);
		if (server->listen(sockPath)) {
			chmod(sockPath, 0600);
			QObject::connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
		}
	}
	QObject::connect(QApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
}

QLocalSocket* Backdrop::getClient()
{
	QObject *sender = QObject::sender();
	if (sender == NULL || sender->property("test").toString() != strTest)
		return NULL;
	return (QLocalSocket*)sender;
}

void Backdrop::newConnection()
{
	QLocalSocket *client;
	while ((client = server->nextPendingConnection())) {
		client->setProperty("test", strTest);
		QObject::connect(client, SIGNAL(readyRead()), this, SLOT(incomingData()));
		QObject::connect(client, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(closeConnection()));
		QObject::connect(client, SIGNAL(disconnected()), this, SLOT(closeConnection()));
	}
}

void Backdrop::closeConnection()
{
	QLocalSocket *client = getClient();
	client->close();
	client->waitForDisconnected(50);
	client->deleteLater();
}

void Backdrop::incomingData()
{
	QLocalSocket *client = getClient();
	char buffer[100];
	while (client->canReadLine()) {
		if (client->readLine(buffer, sizeof buffer) > 0) {
			if (strcmp(buffer, "open") == 0) {
				if (pwgui == NULL) {
					pwgui = new PwGui(this);
				}
				if (pwgui->isVisible()) {
					client->write("busy\n");
				} else {
					pwgui->exec();
					if (pwgui->isCancelled()) {
						server->blockSignals(true);
						client->write("cancel\n");
						client->waitForBytesWritten(1000);
						client->close();
						client->waitForDisconnected(50);
						QApplication::exit(0);
					}
					// Got some credentials, send to back end
					client->write(pwgui->getUser().toUtf8() += '\0' += pwgui->getPassword() += '\0');
				}
			}
		}
	}
}

Backdrop::~Backdrop()
{
	delete screenshot;
}

void Backdrop::paintEvent(QPaintEvent * event)
{
	QPainter p(this);
	p.drawPixmap(event->rect(), *screenshot, event->rect());
}

void Backdrop::mouseReleaseEvent(QMouseEvent * event)
{
	if (pwgui != NULL && pwgui->isVisible()) {
		pwgui->raise();
		pwgui->activateWindow();
	} else if (mainWindow != NULL && mainWindow->isVisible()) {
		mainWindow->raise();
		mainWindow->activateWindow();
	}
}

void Backdrop::aboutToQuit()
{
	if (server != NULL) {
		QFile::remove(server->serverName());
		server->close();
	}
}