diff options
28 files changed, 180 insertions, 17 deletions
diff --git a/COPYING.fonts b/COPYING.fonts new file mode 100644 index 0000000..553fd08 --- /dev/null +++ b/COPYING.fonts @@ -0,0 +1,2 @@ +Please see https://www.qualcomm.com/font/legal before redistributing or using +the fonts in the saltoqd/res/ directory. diff --git a/saltoqd/global.h b/saltoqd/global.h new file mode 100644 index 0000000..2f02232 --- /dev/null +++ b/saltoqd/global.h @@ -0,0 +1,6 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +#define RES_PATH "/usr/share/saltoq/res" + +#endif // GLOBAL_H diff --git a/saltoqd/main.cpp b/saltoqd/main.cpp index 570f6c4..556c389 100644 --- a/saltoqd/main.cpp +++ b/saltoqd/main.cpp @@ -1,10 +1,18 @@ -#include <QtCore> -#include <QtDBus> +#include <QtGui/QGuiApplication> +#include <QtGui/QFontDatabase> +#include <QtDBus/QDBusConnection> +#include "global.h" #include "toqmanager.h" Q_DECL_EXPORT int main(int argc, char **argv) { - QCoreApplication app(argc, argv); + QGuiApplication app(argc, argv); + + QFontDatabase::addApplicationFont(RES_PATH "/Q-Light.otf"); + int id = QFontDatabase::addApplicationFont(RES_PATH "/Q-Regular.otf"); + qDebug() << QFontDatabase::applicationFontFamilies(id); + QFontDatabase::addApplicationFont(RES_PATH "/Q-Semibold.otf"); + QFontDatabase::addApplicationFont(RES_PATH "/Q-Bold.otf"); QScopedPointer<Settings> settings(new Settings("/apps/saltoq")); QScopedPointer<ToqManager> manager(new ToqManager(settings.data())); diff --git a/saltoqd/msolimageiohandler.cpp b/saltoqd/msolimageiohandler.cpp index e6a9065..5a18ff6 100644 --- a/saltoqd/msolimageiohandler.cpp +++ b/saltoqd/msolimageiohandler.cpp @@ -21,6 +21,17 @@ static inline QRgb decode_color(uchar p, uchar a = 255) return qRgba(p & 0xC0, (p & 0x30) << 2, (p & 0x0C) << 4, a); } +static inline uchar add_saturate(uchar val, int addend) +{ + int sum = val + addend; + return qMax(0, qMin(sum, 255)); +} + +static inline void add_saturate(uchar* val, int addend) +{ + *val = add_saturate(*val, addend); +} + } MSOLImageIOHandler::MSOLImageIOHandler() : QImageIOHandler() @@ -93,6 +104,7 @@ bool MSOLImageIOHandler::write(const QImage &image) const int line_size = width * pixel_size; QImage img = image.convertToFormat(alpha ? QImage::Format_ARGB32 : QImage::Format_RGB32); + img = ditherForMsol(img); uchar header[header_size] = { 0 }; strcpy(reinterpret_cast<char*>(&header[0]), "MSOL "); @@ -159,7 +171,8 @@ QVariant MSOLImageIOHandler::option(ImageOption option) const void MSOLImageIOHandler::setOption(ImageOption option, const QVariant &value) { - + Q_UNUSED(option); + Q_UNUSED(value); } QByteArray convertImageToMsol(const QImage &img) @@ -186,3 +199,47 @@ QImage convertMsolToImage(const QByteArray &msol) } return img; } + +QImage ditherForMsol(const QImage &src) +{ + Q_ASSERT(src.format() == QImage::Format_ARGB32 || src.format() == QImage::Format_RGB32); + const int width = src.width(), height = src.height(); + const int bytesPerLine = src.bytesPerLine(); + + QImage dst(src); + + // If we are on Big endian, then we must skip the first channel (=alpha). + // In LE, use the first three channels and skip the final one (=alpha). + const bool bigEndian = QSysInfo::ByteOrder == QSysInfo::BigEndian; + uchar *line = dst.bits() + (bigEndian ? 1 : 0); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + for (int chan = 0; chan < 3; chan++) { + const uchar val = line[x * 4 + chan]; + const uchar quant = add_saturate(val, 0x20) & 0xC0; + const int error = val - quant; + + line[x * 4 + chan] = quant; + + if (x + 1 < width) + add_saturate(&line[(x + 1) * 4 + chan], (error * 7) / 16); + + if (y + 1 < height) { + uchar *nextLine = line + bytesPerLine; + + if (x > 0) + add_saturate(&nextLine[(x - 1) * 4 + chan], (error * 3) / 16); + + add_saturate(&nextLine[x * 4 + chan], (error * 5) / 16); + + if (x + 1 < width) + add_saturate(&nextLine[(x + 1) * 4 + chan], (error * 1) / 16); + } + } + } + + line += bytesPerLine; + } + + return dst; +} diff --git a/saltoqd/msolimageiohandler.h b/saltoqd/msolimageiohandler.h index fbfb1b5..ad0120e 100644 --- a/saltoqd/msolimageiohandler.h +++ b/saltoqd/msolimageiohandler.h @@ -19,5 +19,6 @@ public: QByteArray convertImageToMsol(const QImage &img); QImage convertMsolToImage(const QByteArray &msol); +QImage ditherForMsol(const QImage &src); #endif // MSOLIMAGEIOHANDLER_H diff --git a/saltoqd/res/Q-Bold.otf b/saltoqd/res/Q-Bold.otf Binary files differnew file mode 100644 index 0000000..cb033f4 --- /dev/null +++ b/saltoqd/res/Q-Bold.otf diff --git a/saltoqd/res/Q-Light.otf b/saltoqd/res/Q-Light.otf Binary files differnew file mode 100644 index 0000000..457ba17 --- /dev/null +++ b/saltoqd/res/Q-Light.otf diff --git a/saltoqd/res/Q-Regular.otf b/saltoqd/res/Q-Regular.otf Binary files differnew file mode 100644 index 0000000..79fe9a3 --- /dev/null +++ b/saltoqd/res/Q-Regular.otf diff --git a/saltoqd/res/Q-Semibold.otf b/saltoqd/res/Q-Semibold.otf Binary files differnew file mode 100644 index 0000000..2644588 --- /dev/null +++ b/saltoqd/res/Q-Semibold.otf diff --git a/saltoqd/res/cardtemp0.png b/saltoqd/res/cardtemp0.png Binary files differnew file mode 100644 index 0000000..a434b53 --- /dev/null +++ b/saltoqd/res/cardtemp0.png diff --git a/saltoqd/res/cardtemp10.png b/saltoqd/res/cardtemp10.png Binary files differnew file mode 100644 index 0000000..16b77cf --- /dev/null +++ b/saltoqd/res/cardtemp10.png diff --git a/saltoqd/res/cardtemp20.png b/saltoqd/res/cardtemp20.png Binary files differnew file mode 100644 index 0000000..a166f20 --- /dev/null +++ b/saltoqd/res/cardtemp20.png diff --git a/saltoqd/res/cardtemp30.png b/saltoqd/res/cardtemp30.png Binary files differnew file mode 100644 index 0000000..781990d --- /dev/null +++ b/saltoqd/res/cardtemp30.png diff --git a/saltoqd/res/cardtemp40.png b/saltoqd/res/cardtemp40.png Binary files differnew file mode 100644 index 0000000..5cd5ad7 --- /dev/null +++ b/saltoqd/res/cardtemp40.png diff --git a/saltoqd/res/cardtempminus10.png b/saltoqd/res/cardtempminus10.png Binary files differnew file mode 100644 index 0000000..4d37871 --- /dev/null +++ b/saltoqd/res/cardtempminus10.png diff --git a/saltoqd/res/cardtempminus20.png b/saltoqd/res/cardtempminus20.png Binary files differnew file mode 100644 index 0000000..ae6f6f8 --- /dev/null +++ b/saltoqd/res/cardtempminus20.png diff --git a/saltoqd/res/icon_weathercurrentlocation.png b/saltoqd/res/icon_weathercurrentlocation.png Binary files differnew file mode 100644 index 0000000..0ebf63a --- /dev/null +++ b/saltoqd/res/icon_weathercurrentlocation.png diff --git a/saltoqd/res/temp0.png b/saltoqd/res/temp0.png Binary files differnew file mode 100644 index 0000000..e288a15 --- /dev/null +++ b/saltoqd/res/temp0.png diff --git a/saltoqd/res/temp10.png b/saltoqd/res/temp10.png Binary files differnew file mode 100644 index 0000000..09735c5 --- /dev/null +++ b/saltoqd/res/temp10.png diff --git a/saltoqd/res/temp20.png b/saltoqd/res/temp20.png Binary files differnew file mode 100644 index 0000000..18afc4b --- /dev/null +++ b/saltoqd/res/temp20.png diff --git a/saltoqd/res/temp30.png b/saltoqd/res/temp30.png Binary files differnew file mode 100644 index 0000000..1327fd2 --- /dev/null +++ b/saltoqd/res/temp30.png diff --git a/saltoqd/res/temp40.png b/saltoqd/res/temp40.png Binary files differnew file mode 100644 index 0000000..87004a9 --- /dev/null +++ b/saltoqd/res/temp40.png diff --git a/saltoqd/res/tempminus10.png b/saltoqd/res/tempminus10.png Binary files differnew file mode 100644 index 0000000..0ff04ca --- /dev/null +++ b/saltoqd/res/tempminus10.png diff --git a/saltoqd/res/tempminus20.png b/saltoqd/res/tempminus20.png Binary files differnew file mode 100644 index 0000000..786f177 --- /dev/null +++ b/saltoqd/res/tempminus20.png diff --git a/saltoqd/saltoqd.pro b/saltoqd/saltoqd.pro index 18322b0..1c40e7c 100644 --- a/saltoqd/saltoqd.pro +++ b/saltoqd/saltoqd.pro @@ -50,7 +50,8 @@ HEADERS += \ settingsmanager.h \ toqmanageradaptor.h \ msolimageiohandler.h \ - cardmanageradaptor.h + cardmanageradaptor.h \ + global.h DBUS_INTERFACES += com.nokia.profiled.xml org.nemomobile.voicecall.VoiceCallManager.xml org.nemomobile.voicecall.VoiceCall.xml QDBUSXML2CPP_INTERFACE_HEADER_FLAGS = -i voicecallmanager.h @@ -58,10 +59,14 @@ QDBUSXML2CPP_INTERFACE_HEADER_FLAGS = -i voicecallmanager.h target.path = /usr/bin INSTALLS += target -unit.path = /usr/lib/systemd/user/ +res.path = /usr/share/saltoq/res +res.files = res/Q-Bold.otf res/Q-Light.otf res/Q-Regular.otf res/Q-Semibold.otf res/*.png +INSTALLS += res + +unit.path = /usr/lib/systemd/user unit.files = saltoqd.service INSTALLS += unit -workaround.path = /usr/lib/systemd/system/ +workaround.path = /usr/lib/systemd/system workaround.files = saltoq-bt-sniff-subrate.service INSTALLS += workaround diff --git a/saltoqd/settings.h b/saltoqd/settings.h index bfc0dcb..4c1ef87 100644 --- a/saltoqd/settings.h +++ b/saltoqd/settings.h @@ -2,6 +2,7 @@ #define SETTINGS_H #include <MDConfGroup> +#include "global.h" class Settings : public MDConfGroup { diff --git a/saltoqd/weathermanager.cpp b/saltoqd/weathermanager.cpp index ce36f8c..82126d7 100644 --- a/saltoqd/weathermanager.cpp +++ b/saltoqd/weathermanager.cpp @@ -1,18 +1,93 @@ +#include <QtCore/QFile> +#include <QtCore/QStandardPaths> +#include <QtCore/QJsonArray> +#include <QtGui/QPainter> + #include "fmsmanager.h" +#include "msolimageiohandler.h" #include "weathermanager.h" +static QString getBackgroundImage(int temp) +{ + if (temp > 35) { + return "temp40.png"; + } else if (temp > 25) { + return "temp30.png"; + } else if (temp > 15) { + return "temp20.png"; + } else if (temp > 5) { + return "temp10.png"; + } else if (temp > -5) { + return "temp0.png"; + } else if (temp > -15) { + return "tempminus10.png"; + } else { + return "tempminus20.png"; + } +} + WeatherManager::WeatherManager(FmsManager *fms, ToqManager *toq) : - QObject(toq), _toq(toq), _fms(fms) + QObject(toq), _toq(toq), _fms(fms), + _file(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sailfish-weather/weather.json"), + _watcher(new QFileSystemWatcher(QStringList(_file), this)), + _refreshTimer(new QTimer(this)) { - connect(_toq, &ToqManager::connected, - this, &WeatherManager::handleToqConnected); + connect(_watcher, &QFileSystemWatcher::fileChanged, + _refreshTimer, static_cast<void (QTimer::*)()>(&QTimer::start)); + connect(_refreshTimer, &QTimer::timeout, + this, &WeatherManager::doRefresh); + + qDebug() << "Monitoring file" << _file; + + _refreshTimer->setSingleShot(true); + _refreshTimer->setInterval(2000); + _refreshTimer->start(); } -void WeatherManager::handleToqConnected() +QImage WeatherManager::constructImage(const QJsonObject &obj) { -#if 0 - qDebug() << "Putting file"; - QByteArray data(img_data, sizeof(img_data)); - _fms->updateFile("/apps/weather/99.img", data); -#endif + QJsonObject weather = obj["weather"].toObject(); + QString city = obj["city"].toString(); + int temp = weather["temperatureFeel"].toInt(); + QImage img(RES_PATH "/card" + getBackgroundImage(temp)); + + if (img.isNull()) { + qWarning() << "Invalid background image" << QString(RES_PATH "/card" + getBackgroundImage(temp)); + return img; + } + + QPainter p(&img); + p.setPen(QColor(230, 230, 230)); + p.setFont(QFont("Qualcomm", 22)); + p.drawText(10, 36, city); + + p.setFont(QFont("Qualcomm", 48)); + p.drawText(14, 110, QString::fromUtf8("%1 °C").arg(temp)); + + return img; +} + +void WeatherManager::doRefresh() +{ + QFile file(_file); + + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "Failed to open" << _file; + return; + } + + QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); + QJsonObject root = doc.object(); + QJsonObject currentLoc = root["currentLocation"].toObject(); + QJsonArray locs = root["savedLocations"].toArray(); + + int index = 1; + QImage img = constructImage(currentLoc); + _fms->updateFile(QString::fromLatin1("/apps/weather/%1.img").arg(index), convertImageToMsol(img)); + + for (const QJsonValue &value : locs) { + index++; + img = constructImage(value.toObject()); + _fms->updateFile(QString::fromLatin1("/apps/weather/%1.img").arg(index), convertImageToMsol(img)); + } } diff --git a/saltoqd/weathermanager.h b/saltoqd/weathermanager.h index 522f797..cc36c41 100644 --- a/saltoqd/weathermanager.h +++ b/saltoqd/weathermanager.h @@ -1,6 +1,8 @@ #ifndef WEATHERMANAGER_H #define WEATHERMANAGER_H +#include <QtCore/QFileSystemWatcher> +#include <QtGui/QImage> #include "toqmanager.h" class WeatherManager : public QObject @@ -9,12 +11,18 @@ class WeatherManager : public QObject public: explicit WeatherManager(FmsManager *fms, ToqManager *toq); +private: + QImage constructImage(const QJsonObject &obj); + private slots: - void handleToqConnected(); + void doRefresh(); private: ToqManager *_toq; FmsManager *_fms; + QString _file; + QFileSystemWatcher *_watcher; + QTimer *_refreshTimer; }; #endif // WEATHERMANAGER_H |