#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();
}
}