summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ckitcallnotification/ckitcallprovider.cpp8
-rw-r--r--libsowatch/libsowatch.pro8
-rw-r--r--libsowatch/sowatch.h1
-rw-r--r--libsowatch/watch.h33
-rw-r--r--libsowatch/watchletplugininterface.cpp7
-rw-r--r--libsowatch/watchletplugininterface.h28
-rw-r--r--libsowatch/watchserver.cpp81
-rw-r--r--libsowatch/watchserver.h11
-rw-r--r--metawatch/metawatch.cpp202
-rw-r--r--metawatch/metawatch.h77
-rw-r--r--metawatch/metawatchplugin.cpp2
-rw-r--r--metawatch/metawatchplugin.h2
-rw-r--r--sowatch.pro2
-rw-r--r--sowatchd/daemon.cpp31
14 files changed, 390 insertions, 103 deletions
diff --git a/ckitcallnotification/ckitcallprovider.cpp b/ckitcallnotification/ckitcallprovider.cpp
index adcb6d5..90dab97 100644
--- a/ckitcallnotification/ckitcallprovider.cpp
+++ b/ckitcallnotification/ckitcallprovider.cpp
@@ -21,9 +21,17 @@ CKitCallProvider::~CKitCallProvider()
void CKitCallProvider::activeCallChanged()
{
QVariantMap info = _activeCall->value().toMap();
+ qDebug() << "active call changed" << info;
+ if (!info.contains("state")) {
+ qWarning() << "broken active call context property";
+ }
int state = info["state"].toInt();
if (state == 0) {
QString displayName = info["displayName"].toString();
+ if (displayName.isEmpty()) {
+ // Ignore call until display name is not empty.
+ return;
+ }
// "Incoming call"
if (_notification) {
_notification->changeDisplayName(displayName);
diff --git a/libsowatch/libsowatch.pro b/libsowatch/libsowatch.pro
index aefdadd..44458c2 100644
--- a/libsowatch/libsowatch.pro
+++ b/libsowatch/libsowatch.pro
@@ -27,7 +27,8 @@ SOURCES += \
watchplugininterface.cpp \
notification.cpp \
notificationplugininterface.cpp \
- notificationprovider.cpp
+ notificationprovider.cpp \
+ watchletplugininterface.cpp
HEADERS +=\
watchsimulator.h \
@@ -45,7 +46,8 @@ HEADERS +=\
watchplugininterface.h \
notification.h \
notificationplugininterface.h \
- notificationprovider.h
+ notificationprovider.h \
+ watchletplugininterface.h
install_headers.files = $$HEADERS
@@ -89,3 +91,5 @@ unix:!symbian {
+
+
diff --git a/libsowatch/sowatch.h b/libsowatch/sowatch.h
index e294ece..d8844bc 100644
--- a/libsowatch/sowatch.h
+++ b/libsowatch/sowatch.h
@@ -15,5 +15,6 @@
#include "watchlet.h"
#include "graphicswatchlet.h"
#include "declarativewatchlet.h"
+#include "watchletplugininterface.h"
#endif // SOWATCH_H
diff --git a/libsowatch/watch.h b/libsowatch/watch.h
index eabfa06..ee9bde7 100644
--- a/libsowatch/watch.h
+++ b/libsowatch/watch.h
@@ -3,6 +3,7 @@
#include <QtCore/QObject>
#include <QtCore/QDateTime>
+#include <QtCore/QStringList>
#include <QtGui/QPaintDevice>
#include <QtGui/QImage>
#include "notification.h"
@@ -21,18 +22,34 @@ public:
explicit Watch(QObject* parent = 0);
~Watch();
- /** Return a string identiyfying this watch's model. */
+ /** Return a string identifying this watch's model. */
virtual QString model() const = 0;
+
+ /** Names for all the buttons this watch has. Order is important. */
+ virtual QStringList buttons() const = 0;
+
/** Should return true if the watch is connected. */
virtual bool isConnected() const = 0;
-
/** Indicates if watch is too busy atm and we should limit frame rate. */
virtual bool busy() const = 0;
- /** Changes the current date/time on the watch. */
+ /** Gets the current date/time on the watch. */
virtual QDateTime dateTime() = 0;
+ /** Sets the current date/time on the watch. */
virtual void setDateTime(const QDateTime& dateTime) = 0;
+ /** Go back to the idle screen. */
+ virtual void displayIdleScreen() = 0;
+ /** A standard notification; it's up to the watch when to stop showing it. */
+ virtual void displayNotification(Notification* n) = 0;
+ /** Enter application mode. */
+ virtual void displayApplication() = 0;
+
+ /** Grabs a button from whatever is default function is for the current mode. */
+ virtual void grabButton(int button) = 0;
+ /** Restores a button to its default function. */
+ virtual void ungrabButton(int button) = 0;
+
/** Tells the watch to update the unread notifications count, if visible. */
virtual void updateNotificationCount(Notification::Type type, int count) = 0;
@@ -43,16 +60,10 @@ signals:
void disconnected();
/** The watch has returned to the idle screen by either inactivity or notification cleared/timeout. */
void idling();
+ /** A button has been pressed. */
void buttonPressed(int button);
+ /** A button has been pressed and then released. */
void buttonReleased(int button);
-
-public slots:
- /** Go back to the idle screen. */
- virtual void displayIdleScreen() = 0;
- /** A standard notification; it's up to the watch when to stop showing it. */
- virtual void displayNotification(Notification* n) = 0;
- /** Enter application mode. */
- virtual void displayApplication() = 0;
};
}
diff --git a/libsowatch/watchletplugininterface.cpp b/libsowatch/watchletplugininterface.cpp
new file mode 100644
index 0000000..c575236
--- /dev/null
+++ b/libsowatch/watchletplugininterface.cpp
@@ -0,0 +1,7 @@
+#include "watchletplugininterface.h"
+
+using namespace sowatch;
+
+WatchletPluginInterface::~WatchletPluginInterface()
+{
+}
diff --git a/libsowatch/watchletplugininterface.h b/libsowatch/watchletplugininterface.h
new file mode 100644
index 0000000..ad83dd4
--- /dev/null
+++ b/libsowatch/watchletplugininterface.h
@@ -0,0 +1,28 @@
+#ifndef SOWATCH_WATCHLETPLUGININTERFACE_H
+#define SOWATCH_WATCHLETPLUGININTERFACE_H
+
+#include <QtPlugin>
+#include <QtCore/QSettings>
+#include <QtCore/QStringList>
+#include "sowatch_global.h"
+
+namespace sowatch
+{
+
+class Watchlet;
+class WatchServer;
+
+class SOWATCH_EXPORT WatchletPluginInterface
+{
+public:
+ virtual ~WatchletPluginInterface();
+
+ virtual QStringList watchlets() = 0;
+ virtual Watchlet* getProvider(const QString& id, QSettings& settings, WatchServer *server) = 0;
+};
+
+}
+
+Q_DECLARE_INTERFACE(sowatch::WatchletPluginInterface, "com.javispedro.sowatch.WatchletPluginInterface")
+
+#endif // SOWATCH_WATCHLETPLUGININTERFACE_H
diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp
index d95d4fb..39802f9 100644
--- a/libsowatch/watchserver.cpp
+++ b/libsowatch/watchserver.cpp
@@ -9,11 +9,14 @@
using namespace sowatch;
WatchServer::WatchServer(Watch* watch, QObject* parent) :
- QObject(parent), _watch(watch), _currentWatchlet(0)
+ QObject(parent), _watch(watch),
+ _nextWatchletButton(-1),
+ _currentWatchlet(0), _currentWatchletIndex(-1)
{
connect(_watch, SIGNAL(connected()), SLOT(watchConnected()));
connect(_watch, SIGNAL(disconnected()), SLOT(watchDisconnected()));
connect(_watch, SIGNAL(idling()), SLOT(watchIdling()));
+ connect(_watch, SIGNAL(buttonPressed(int)), SLOT(watchButtonPress(int)));
}
Watch* WatchServer::watch()
@@ -21,6 +24,27 @@ Watch* WatchServer::watch()
return _watch;
}
+QString WatchServer::nextWatchletButton() const
+{
+ if (_nextWatchletButton >= 0) {
+ return _watch->buttons().at(_nextWatchletButton);
+ } else {
+ return QString();
+ }
+}
+
+void WatchServer::setNextWatchletButton(const QString& value)
+{
+ if (value.isEmpty()) {
+ _nextWatchletButton = -1;
+ return;
+ }
+ _nextWatchletButton = _watch->buttons().indexOf(value);
+ if (_nextWatchletButton < 0) {
+ qWarning() << "Invalid watch button" << value;
+ }
+}
+
void WatchServer::addProvider(NotificationProvider *provider)
{
provider->setParent(this);
@@ -33,6 +57,7 @@ void WatchServer::runWatchlet(const QString& id)
if (_currentWatchlet) {
closeWatchlet();
}
+ qDebug() << "activating watchlet" << id;
_currentWatchlet = _watchlets[id];
if (_watch->isConnected()) {
reactivateCurrentWatchlet();
@@ -41,11 +66,15 @@ void WatchServer::runWatchlet(const QString& id)
void WatchServer::closeWatchlet()
{
- Q_ASSERT(_currentWatchlet != 0);
- if (_watch->isConnected()) {
- _currentWatchlet->deactivate();
+ if (_currentWatchlet) {
+ if (_watch->isConnected()) {
+ _currentWatchlet->deactivate();
+ }
+ _currentWatchlet = 0;
+ if (_pendingNotifications.empty()) {
+ goToIdle();
+ }
}
- _currentWatchlet = 0;
}
void WatchServer::registerWatchlet(Watchlet *watchlet)
@@ -61,6 +90,20 @@ void WatchServer::reactivateCurrentWatchlet()
_currentWatchlet->activate();
}
+void WatchServer::nextWatchlet()
+{
+ QStringList watchlets = _watchlets.keys();
+ _currentWatchletIndex++;
+ qDebug() << "next watchlet" << _currentWatchletIndex;
+ if (_currentWatchletIndex >= watchlets.size()) {
+ _currentWatchletIndex = -1;
+ closeWatchlet();
+ } else {
+ QString watchlet = watchlets.at(_currentWatchletIndex);
+ runWatchlet(watchlet);
+ }
+}
+
void WatchServer::nextNotification()
{
if (!_watch->isConnected()) return;
@@ -70,7 +113,7 @@ void WatchServer::nextNotification()
} else if (_currentWatchlet) {
reactivateCurrentWatchlet();
} else {
- _watch->displayIdleScreen();
+ goToIdle();
}
}
@@ -83,12 +126,22 @@ uint WatchServer::getNotificationCount(Notification::Type type)
return count;
}
+void WatchServer::goToIdle()
+{
+ _watch->displayIdleScreen();
+ if (_nextWatchletButton >= 0) {
+ _watch->grabButton(_nextWatchletButton);
+ }
+}
+
void WatchServer::watchConnected()
{
if (!_pendingNotifications.isEmpty()) {
nextNotification();
} else if (_currentWatchlet) {
reactivateCurrentWatchlet();
+ } else {
+ goToIdle();
}
}
@@ -102,13 +155,27 @@ void WatchServer::watchDisconnected()
void WatchServer::watchIdling()
{
- qDebug() << "Watch idling";
+ qDebug() << "watch idling";
if (!_pendingNotifications.empty()) {
_pendingNotifications.dequeue();
nextNotification();
}
}
+void WatchServer::watchButtonPress(int button)
+{
+ if (button == _nextWatchletButton) {
+ if (_pendingNotifications.empty()) {
+ // No notifications: either app or idle mode.
+ nextWatchlet();
+ } else {
+ // Skip to next notification if any
+ _pendingNotifications.dequeue();
+ nextNotification();
+ }
+ }
+}
+
void WatchServer::notificationReceived(Notification *notification)
{
const Notification::Type type = notification->type();
diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h
index 1ece104..681c758 100644
--- a/libsowatch/watchserver.h
+++ b/libsowatch/watchserver.h
@@ -19,12 +19,16 @@ class SOWATCH_EXPORT WatchServer : public QObject
{
Q_OBJECT
Q_PROPERTY(Watch* watch READ watch CONSTANT)
+ Q_PROPERTY(QString nextWatchletButton READ nextWatchletButton WRITE setNextWatchletButton)
public:
explicit WatchServer(Watch* watch, QObject* parent = 0);
Watch* watch();
+ QString nextWatchletButton() const;
+ void setNextWatchletButton(const QString& value);
+
void addProvider(NotificationProvider* provider);
void runWatchlet(const QString& id);
@@ -33,6 +37,8 @@ public:
protected:
Watch* _watch;
+ char _nextWatchletButton;
+
QMap<QString, Watchlet*> _watchlets;
/** Stores current notifications, classified by type. */
@@ -40,17 +46,22 @@ protected:
QQueue<Notification*> _pendingNotifications;
Watchlet* _currentWatchlet;
+ char _currentWatchletIndex;
void registerWatchlet(Watchlet *watchlet);
void reactivateCurrentWatchlet();
+ void nextWatchlet();
void nextNotification();
uint getNotificationCount(Notification::Type type);
+ void goToIdle();
+
protected slots:
void watchConnected();
void watchDisconnected();
void watchIdling();
+ void watchButtonPress(int button);
void notificationReceived(Notification* notification);
void notificationChanged();
void notificationCleared();
diff --git a/metawatch/metawatch.cpp b/metawatch/metawatch.cpp
index 5e6a8fb..a429083 100644
--- a/metawatch/metawatch.cpp
+++ b/metawatch/metawatch.cpp
@@ -9,6 +9,13 @@ QTM_USE_NAMESPACE
#define SINGLE_LINE_UPDATE 0
+const char MetaWatch::watchToBtn[8] = {
+ 0, 1, 2, 3, -1, 4, 5, -1
+};
+const char MetaWatch::btnToWatch[8] = {
+ 0, 1, 2, 3, 5, 6, -1, -1
+};
+
const int MetaWatch::connectRetryTimes[] = {
5, 10, 30, 60, 120, 300
};
@@ -74,21 +81,17 @@ const quint16 MetaWatch::crcTable[256] = {
}
#endif
-MetaWatch::MetaWatch(const QBluetoothAddress& address, QObject *parent) :
+MetaWatch::MetaWatch(const QBluetoothAddress& address, QSettings* settings, QObject* parent) :
Watch(parent),
+ _nMails(0), _nCalls(0), _nIms(0), _nSms(0), _nMms(0),
+ _idleTimer(new QTimer(this)), _ringTimer(new QTimer(this)),
+ _currentMode(IdleMode), _paintMode(IdleMode),
_paintEngine(0),
- _address(address),
- _socket(0),
- _24hMode(true), _dayMonthOrder(true), _notificationTimeout(10),
- _connectRetries(0),
- _connected(false),
+ _connectRetries(0), _connected(false),
_connectTimer(new QTimer(this)),
_connectAlignedTimer(new QSystemAlignedTimer(this)),
- _sendTimer(new QTimer(this)),
- _currentMode(IdleMode),
- _paintMode(IdleMode),
- _nMails(0), _nCalls(0), _nIms(0), _nSms(0), _nMms(0),
- _idleTimer(new QTimer(this)), _ringTimer(new QTimer(this))
+ _address(address), _socket(0),
+ _sendTimer(new QTimer(this))
{
QImage baseImage(screenWidth, screenHeight, QImage::Format_MonoLSB);
baseImage.setColor(0, QColor(Qt::white).rgb());
@@ -97,13 +100,13 @@ MetaWatch::MetaWatch(const QBluetoothAddress& address, QObject *parent) :
_image[ApplicationMode] = baseImage;
_image[NotificationMode] = baseImage;
- _connectTimer->setSingleShot(true);
- _connectAlignedTimer->setSingleShot(true);
- connect(_connectTimer, SIGNAL(timeout()), SLOT(retryConnect()));
- connect(_connectAlignedTimer, SIGNAL(timeout()), SLOT(retryConnect()));
+ _buttonNames << "A" << "B" << "C" << "D" << "E" << "F";
- _sendTimer->setInterval(10);
- connect(_sendTimer, SIGNAL(timeout()), SLOT(timedSend()));
+ if (settings) {
+ _24hMode = settings->value("24hMode", false).toBool();
+ _dayMonthOrder = settings->value("DayMonthOrder", false).toBool();
+ _notificationTimeout = settings->value("NotificationTimeout", 10).toInt();
+ }
_idleTimer->setInterval(_notificationTimeout * 1000);
_idleTimer->setSingleShot(true);
@@ -112,6 +115,14 @@ MetaWatch::MetaWatch(const QBluetoothAddress& address, QObject *parent) :
_ringTimer->setInterval(2000);
connect(_ringTimer, SIGNAL(timeout()), SLOT(timedRing()));
+ _connectTimer->setSingleShot(true);
+ _connectAlignedTimer->setSingleShot(true);
+ connect(_connectTimer, SIGNAL(timeout()), SLOT(retryConnect()));
+ connect(_connectAlignedTimer, SIGNAL(timeout()), SLOT(retryConnect()));
+
+ _sendTimer->setInterval(10);
+ connect(_sendTimer, SIGNAL(timeout()), SLOT(timedSend()));
+
retryConnect();
}
@@ -161,6 +172,11 @@ QString MetaWatch::model() const
return "metawatch-digital";
}
+QStringList MetaWatch::buttons() const
+{
+ return _buttonNames;
+}
+
bool MetaWatch::isConnected() const
{
return _connected;
@@ -199,32 +215,6 @@ void MetaWatch::setDateTime(const QDateTime &dateTime)
send(msg);
}
-void MetaWatch::updateNotificationCount(Notification::Type type, int count)
-{
- switch (type) {
- case Notification::MissedCallNotification:
- _nCalls = count;
- break;
- case Notification::EmailNotification:
- _nMails = count;
- break;
- case Notification::ImNotification:
- _nIms = count;
- break;
- case Notification::SmsNotification:
- _nSms = count;
- break;
- case Notification::MmsNotification:
- _nMms = count;
- break;
- default:
- // Ignore
- break;
- }
-
- renderIdleCounts();
-}
-
void MetaWatch::displayIdleScreen()
{
_currentMode = IdleMode;
@@ -234,7 +224,6 @@ void MetaWatch::displayIdleScreen()
updateDisplay(IdleMode);
// Usually, idle screen is kept updated, so we can show it already.
qDebug() << "displayIdle";
-
}
void MetaWatch::displayNotification(Notification *n)
@@ -313,6 +302,42 @@ void MetaWatch::displayApplication()
qDebug() << "displayApplication";
}
+void MetaWatch::grabButton(int button)
+{
+ grabButton(_currentMode, (Button) button);
+}
+
+void MetaWatch::ungrabButton(int button)
+{
+ ungrabButton(_currentMode, (Button) button);
+}
+
+void MetaWatch::updateNotificationCount(Notification::Type type, int count)
+{
+ switch (type) {
+ case Notification::MissedCallNotification:
+ _nCalls = count;
+ break;
+ case Notification::EmailNotification:
+ _nMails = count;
+ break;
+ case Notification::ImNotification:
+ _nIms = count;
+ break;
+ case Notification::SmsNotification:
+ _nSms = count;
+ break;
+ case Notification::MmsNotification:
+ _nMms = count;
+ break;
+ default:
+ // Ignore
+ break;
+ }
+
+ renderIdleCounts();
+}
+
MetaWatch::Mode MetaWatch::currentMode() const
{
return _currentMode;
@@ -353,6 +378,18 @@ void MetaWatch::clear(Mode mode, bool black)
loadTemplate(mode, black ? 1 : 0);
}
+void MetaWatch::grabButton(Mode mode, Button button)
+{
+ enableButton(mode, button, PressOnly);
+ enableButton(mode, button, PressAndRelease);
+}
+
+void MetaWatch::ungrabButton(Mode mode, Button button)
+{
+ disableButton(mode, button, PressOnly);
+ disableButton(mode, button, PressAndRelease);
+}
+
void MetaWatch::renderIdleScreen()
{
QImage idle_call(QString(":/metawatch/graphics/idle_call.bmp"));
@@ -602,19 +639,66 @@ void MetaWatch::loadTemplate(Mode mode, int templ)
send(msg);
}
+void MetaWatch::enableButton(Mode mode, Button button, ButtonPress press)
+{
+ Message msg(EnableButton, QByteArray(5, 0));
+
+ Q_ASSERT(button >= 0 && button < 8);
+
+ msg.data[0] = mode;
+ msg.data[1] = btnToWatch[button];
+ msg.data[2] = press;
+ msg.data[3] = ButtonEvent;
+ msg.data[4] = 0x80 | ((press << 4) & 0x30) | (button & 0xF);
+
+ send(msg);
+}
+
+void MetaWatch::disableButton(Mode mode, Button button, ButtonPress press)
+{
+ Message msg(DisableButton, QByteArray(3, 0));
+
+ Q_ASSERT(button >= 0 && button < 8);
+
+ msg.data[0] = mode;
+ msg.data[1] = btnToWatch[button];
+ msg.data[2] = press;
+
+ send(msg);
+}
+
void MetaWatch::handleStatusChange(const Message &msg)
{
- qDebug() << "watch status changed" << msg.options << msg.data.at(0);
+ QString s;
+ qDebug() << "watch status changed" << s.sprintf("0x%hx", msg.options) << s.sprintf("0x%hx", msg.data.at(0));
}
void MetaWatch::handleButtonEvent(const Message &msg)
{
- if (msg.data.size() < 1) return;
- quint8 button = msg.data[0];
+ if (!(msg.options & 0x80)) {
+ // We didn't configure this button, reject.
+ return;
+ }
+
+ quint8 watchBtn = msg.options & 0xF;
+ ButtonPress press = (ButtonPress) ((msg.options & 0x30) >> 4);
+ int button = -1;
- qDebug() << "button event" << msg.data.size() << msg.options << msg.data.at(0);
+ if (watchBtn < 8) {
+ button = watchToBtn[watchBtn];
+ }
+ if (button == -1) {
+ qWarning() << "Unknown watch button" << watchBtn;
+ return;
+ }
+
+ qDebug() << "button event" << button << press;
- emit buttonPressed(button); // TODO This is completely broken
+ if (press == PressOnly) {
+ emit buttonPressed(button);
+ } else if (press == PressAndRelease) {
+ emit buttonReleased(button);
+ }
}
void MetaWatch::socketConnected()
@@ -628,11 +712,23 @@ void MetaWatch::socketConnected()
_partialReceived.data.clear();
_currentMode = IdleMode;
_paintMode = IdleMode;
- _buttonState = 0;
setDateTime(QDateTime::currentDateTime());
configureIdleSystemArea(false);
+ grabButton(ApplicationMode, BtnA);
+ grabButton(ApplicationMode, BtnB);
+ grabButton(ApplicationMode, BtnC);
+ grabButton(ApplicationMode, BtnD);
+ grabButton(ApplicationMode, BtnE);
+ grabButton(ApplicationMode, BtnF);
+ grabButton(NotificationMode, BtnA);
+ grabButton(NotificationMode, BtnB);
+ grabButton(NotificationMode, BtnC);
+ grabButton(NotificationMode, BtnD);
+ grabButton(NotificationMode, BtnE);
+ grabButton(NotificationMode, BtnF);
+
renderIdleScreen();
renderNotificationScreen();
@@ -673,12 +769,14 @@ void MetaWatch::socketData()
qint64 dataRead;
if (_partialReceived.type == 0) {
+ /* Still not received even the packet type */
+ /* Receive the full header, 4 bytes. */
if (_socket->bytesAvailable() < 4) return; /* Wait for more. */
char header[4];
dataRead = _socket->read(header, 4);
if (dataRead < 4 || header[0] != 0x01) {
- qWarning() << "TODO: Resync/Handle Garbage";
+ qWarning() << "TODO: Resync / Handle Garbage";
return;
}
@@ -686,6 +784,8 @@ void MetaWatch::socketData()
_partialReceived.data.resize(header[1] - 6);
_partialReceived.options = header[3];
}
+
+ /* Got the header; now, try to get the complete packet. */
if (_socket->bytesAvailable() < _partialReceived.data.size() + 2) {
return; /* Wait for more. */
}
diff --git a/metawatch/metawatch.h b/metawatch/metawatch.h
index da0f323..0a9123a 100644
--- a/metawatch/metawatch.h
+++ b/metawatch/metawatch.h
@@ -3,6 +3,7 @@
#include <QtCore/QQueue>
#include <QtCore/QTimer>
+#include <QtCore/QSettings>
#include <QtConnectivity/QBluetoothAddress>
#include <QtConnectivity/QBluetoothSocket>
#include <QtSystemInfo/QSystemAlignedTimer>
@@ -20,10 +21,9 @@ class MetaWatchPaintEngine;
class MetaWatch : public Watch
{
Q_OBJECT
- Q_ENUMS(MessageType Mode)
public:
- explicit MetaWatch(const QBluetoothAddress& address, QObject *parent = 0);
+ explicit MetaWatch(const QBluetoothAddress& address, QSettings* settings = 0, QObject *parent = 0);
~MetaWatch();
static const int screenWidth = 96;
@@ -66,28 +66,49 @@ public:
NotificationMode = 2
};
+ enum Button {
+ BtnA = 0,
+ BtnB,
+ BtnC,
+ BtnD,
+ BtnE,
+ BtnF
+ };
+
+ enum ButtonPress {
+ PressOnly = 0,
+ PressAndRelease = 1,
+ HoldAndRelease = 2,
+ LongHoldAndRelease = 3
+ };
+
QPaintEngine* paintEngine() const;
int metric(PaintDeviceMetric metric) const;
QString model() const;
+ QStringList buttons() const;
bool isConnected() const;
bool busy() const;
QDateTime dateTime();
void setDateTime(const QDateTime& dateTime);
- void updateNotificationCount(Notification::Type type, int count);
-
void displayIdleScreen();
void displayNotification(Notification *n);
void displayApplication();
+ void grabButton(int button);
+ void ungrabButton(int button);
+
+ void updateNotificationCount(Notification::Type type, int count);
Mode currentMode() const;
Mode paintTargetMode() const;
QImage* imageFor(Mode mode);
void clear(Mode mode, bool black = false);
void update(Mode mode, const QList<QRect>& rects = QList<QRect>());
+ void grabButton(Mode mode, Button button);
+ void ungrabButton(Mode mode, Button button);
void renderIdleScreen();
void renderIdleWeather();
@@ -97,18 +118,32 @@ public:
QImage iconForNotification(const Notification *n);
protected:
- mutable MetaWatchPaintEngine* _paintEngine;
- QImage _image[3];
-
- QBluetoothAddress _address;
- QBluetoothSocket* _socket;
-
- /* Some configurable stuff. */
+ // Some configurable stuff.
bool _24hMode : 1;
bool _dayMonthOrder : 1;
-
short _notificationTimeout;
+ // Notifications: Unread count
+ uint _nMails, _nCalls, _nIms, _nSms, _nMms;
+
+ // Notifications: timers
+ QTimer* _idleTimer;
+ QTimer* _ringTimer;
+
+ // Buttons
+ static const char watchToBtn[8];
+ static const char btnToWatch[8];
+ QStringList _buttonNames;
+
+ // Current watch state
+ Mode _currentMode;
+ Mode _paintMode;
+
+ // For QPaintDevice
+ mutable MetaWatchPaintEngine* _paintEngine;
+ QImage _image[3];
+
+ // Timers to retry the connection when the watch is not found.
static const int connectRetryTimesSize = 6;
static const int connectRetryTimes[connectRetryTimesSize];
short _connectRetries;
@@ -116,6 +151,11 @@ protected:
QTimer* _connectTimer;
QSystemAlignedTimer* _connectAlignedTimer;
+ // Connection stuff
+ QBluetoothAddress _address;
+ QBluetoothSocket* _socket;
+
+ // Base watch protocol stuff
struct Message {
MessageType type;
quint8 options;
@@ -129,17 +169,6 @@ protected:
QTimer* _sendTimer;
Message _partialReceived;
- Mode _currentMode;
- Mode _paintMode;
- quint8 _buttonState;
-
- // Notifications: Unread count
- uint _nMails, _nCalls, _nIms, _nSms, _nMms;
-
- // Notifications: timers
- QTimer* _idleTimer;
- QTimer* _ringTimer;
-
static const quint8 bitRevTable[16];
static const quint16 crcTable[256];
quint16 calcCrc(const QByteArray& data, int size);
@@ -156,6 +185,8 @@ protected:
void configureIdleSystemArea(bool entireScreen);
void updateDisplay(Mode mode, bool copy = true);
void loadTemplate(Mode mode, int templ);
+ void enableButton(Mode mode, Button button, ButtonPress press);
+ void disableButton(Mode mode, Button button, ButtonPress press);
void handleStatusChange(const Message& msg);
void handleButtonEvent(const Message& msg);
diff --git a/metawatch/metawatchplugin.cpp b/metawatch/metawatchplugin.cpp
index 6a97297..23a4f63 100644
--- a/metawatch/metawatchplugin.cpp
+++ b/metawatch/metawatchplugin.cpp
@@ -36,7 +36,7 @@ Watch* MetaWatchPlugin::getWatch(const QString& driver, QSettings& settings, QOb
{
if (driver == "metawatch-digital") {
QBluetoothAddress address(settings.value("address").toString());
- return new MetaWatch(address, parent);
+ return new MetaWatch(address, &settings, parent);
} else {
return 0;
}
diff --git a/metawatch/metawatchplugin.h b/metawatch/metawatchplugin.h
index 57b1029..6834247 100644
--- a/metawatch/metawatchplugin.h
+++ b/metawatch/metawatchplugin.h
@@ -15,7 +15,7 @@ public:
~MetaWatchPlugin();
virtual QStringList drivers();
- virtual Watch* getWatch(const QString& driver, QSettings& settings, QObject *parent = 0);
+ virtual Watch* getWatch(const QString& driver, QSettings& settings, QObject* parent = 0);
protected:
static bool fontsLoaded;
diff --git a/sowatch.pro b/sowatch.pro
index 0402176..db0228b 100644
--- a/sowatch.pro
+++ b/sowatch.pro
@@ -4,7 +4,7 @@ SUBDIRS = libsowatch \
sowatchd
!isEmpty(MEEGO_VERSION_MAJOR) {
- SUBDIRS += meegohandsetnotification ckitcallnotification
+ #SUBDIRS += meegohandsetnotification ckitcallnotification
}
unix:!symbian {
diff --git a/sowatchd/daemon.cpp b/sowatchd/daemon.cpp
index 645ecf6..26cbad0 100644
--- a/sowatchd/daemon.cpp
+++ b/sowatchd/daemon.cpp
@@ -3,6 +3,7 @@
#include <QtCore/QSettings>
#include <QtCore/QDir>
#include <sowatch.h>
+#include <testwatchlet.h>
#include "daemon.h"
using namespace sowatch;
@@ -108,6 +109,9 @@ void Daemon::initWatch(Watch* watch, QSettings& settings)
WatchServer* server = new WatchServer(watch, this);
_servers.append(server);
+ // Configure the server
+ server->setNextWatchletButton(settings.value("nextWatchletButton").toString());
+
// Initialize providers
size = settings.beginReadArray("notifications");
for (int i = 0; i < size; i++) {
@@ -120,25 +124,40 @@ void Daemon::initWatch(Watch* watch, QSettings& settings)
}
}
+ // Initialize test watchlets
+ new TestWatchlet(server);
+
settings.endArray();
}
void Daemon::loadWatchlets()
{
-#if 0
QDir dir(SOWATCH_WATCHLETS_DIR);
foreach (QString file, dir.entryList(QDir::Files)) {
+#if defined(Q_OS_UNIX)
+ // Temporary workaround for QtC deploy plugin issues
+ if (!file.endsWith(".so")) continue;
+#endif
QPluginLoader loader(dir.absoluteFilePath(file));
QObject *pluginObj = loader.instance();
if (pluginObj) {
- WatchPluginInterface *plugin = qobject_cast<WatchPluginInterface*>(pluginObj);
+#if 0
+ WatchletPluginInterface *plugin = qobject_cast<WatchletPluginInterface*>(pluginObj);
if (plugin) {
- QStringList drivers = plugin->drivers();
- foreach (const QString& driver, drivers) {
- _drivers[driver] = plugin;
+ QStringList providers = plugin->providers();
+ foreach (const QString& provider, providers) {
+ _providers[provider] = plugin;
}
+ } else {
+ qWarning() << "Invalid plugin" << file;
+ loader.unload();
}
+#endif
+ } else {
+ qWarning() << "Invalid plugin" << file << loader.errorString();
+ loader.unload();
}
}
-#endif
+
+ qDebug() << "loaded watchlets";
}