diff options
Diffstat (limited to 'metawatch')
| -rw-r--r-- | metawatch/metawatch.cpp | 202 | ||||
| -rw-r--r-- | metawatch/metawatch.h | 77 | ||||
| -rw-r--r-- | metawatch/metawatchplugin.cpp | 2 | ||||
| -rw-r--r-- | metawatch/metawatchplugin.h | 2 | 
4 files changed, 207 insertions, 76 deletions
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;  | 
