1 /*
2    Drawpile - a collaborative drawing program.
3 
4    Copyright (C) 2013-2018 Calle Laakkonen
5 
6    Drawpile is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    Drawpile is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Drawpile.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef DP_NET_META_OPAQUE_H
20 #define DP_NET_META_OPAQUE_H
21 
22 #include "message.h"
23 
24 #include <QString>
25 #include <QList>
26 
27 namespace protocol {
28 
29 /**
30  * @brief Start/end drawing pointer laser trail
31  *
32  * This signals the beginning or the end of a laser pointer trail. The trail coordinates
33  * are sent with MovePointer messages.
34  *
35  * A nonzero persistence indicates the start of the trail and zero the end.
36  */
37 class LaserTrail : public Message {
38 public:
LaserTrail(uint8_t ctx,quint32 color,uint8_t persistence)39 	LaserTrail(uint8_t ctx, quint32 color, uint8_t persistence) : Message(MSG_LASERTRAIL, ctx), m_color(color), m_persistence(persistence) { }
40 	static LaserTrail *deserialize(uint8_t ctx, const uchar *data, uint len);
41 	static LaserTrail *fromText(uint8_t ctx, const Kwargs &kwargs);
42 
color()43 	quint32 color() const { return m_color; }
persistence()44 	uint8_t persistence() const { return m_persistence; }
45 
messageName()46 	QString messageName() const override { return QStringLiteral("laser"); }
47 
48 protected:
49 	int payloadLength() const override;
50 	int serializePayload(uchar *data) const override;
51 	Kwargs kwargs() const override;
52 
53 private:
54 	quint32 m_color;
55 	uint8_t m_persistence;
56 };
57 
58 /**
59  * @brief Move user pointer
60  *
61  * This is message is used to update the position of the user pointer when no
62  * actual drawing is taking place. It is also used to draw the "laser pointer" trail.
63  * Note. This is a META message, since this is used for a temporary visual effect only,
64  * and thus doesn't affect the actual canvas content.
65  */
66 class MovePointer : public Message {
67 public:
MovePointer(uint8_t ctx,int32_t x,int32_t y)68 	MovePointer(uint8_t ctx, int32_t x, int32_t y)
69 		: Message(MSG_MOVEPOINTER, ctx), m_x(x), m_y(y)
70 	{}
71 
72 	static MovePointer *deserialize(uint8_t ctx, const uchar *data, uint len);
73 	static MovePointer *fromText(uint8_t ctx, const Kwargs &kwargs);
74 
x()75 	int32_t x() const { return m_x; }
y()76 	int32_t y() const { return m_y; }
77 
messageName()78 	QString messageName() const override { return QStringLiteral("movepointer"); }
79 
80 protected:
81 	int payloadLength() const override;
82 	int serializePayload(uchar *data) const override;
83 	Kwargs kwargs() const override;
84 
85 private:
86 	int32_t m_x;
87 	int32_t m_y;
88 };
89 
90 /**
91  * @brief Set user specific locks
92  *
93  * This is an opaque meta command that contains a list of users to be locked.
94  * It can only be sent by session operators.
95  */
96 class UserACL : public Message {
97 public:
UserACL(uint8_t ctx,QList<uint8_t> ids)98 	UserACL(uint8_t ctx, QList<uint8_t> ids) : Message(MSG_USER_ACL, ctx), m_ids(ids) { }
99 
100 	static UserACL *deserialize(uint8_t ctx, const uchar *data, uint len);
101 	static UserACL *fromText(uint8_t ctx, const Kwargs &kwargs);
102 
ids()103 	QList<uint8_t> ids() const { return m_ids; }
104 
messageName()105 	QString messageName() const override { return QStringLiteral("useracl"); }
106 
107 protected:
108 	int payloadLength() const override;
109 	int serializePayload(uchar *data) const override;
110 	Kwargs kwargs() const override;
111 
112 private:
113 	QList<uint8_t> m_ids;
114 };
115 
116 /**
117  * @brief Change layer access control list
118  *
119  * This is an opaque meta command. It is used to set the general layer lock
120  * as well as give exclusive access to selected users.
121  *
122  * When the OWNLAYERS mode is set, any user can use this to change the ACLs on layers they themselves
123  * have created (identified by the ID prefix.)
124  *
125  * Using layer ID 0 sets or clears a general canvaswide lock. The tier and exclusive user list is not
126  * used in this case.
127  */
128 class LayerACL : public Message {
129 public:
LayerACL(uint8_t ctx,uint16_t id,bool locked,uint8_t tier,const QList<uint8_t> & exclusive)130 	LayerACL(uint8_t ctx, uint16_t id, bool locked, uint8_t tier, const QList<uint8_t> &exclusive)
131 		: LayerACL(ctx, id, (locked?0x80:0) | (tier&0x07), exclusive)
132 	{}
133 
134 	static LayerACL *deserialize(uint8_t ctx, const uchar *data, uint len);
135 	static LayerACL *fromText(uint8_t ctx, const Kwargs &kwargs);
136 
layer()137 	uint16_t layer() const override { return m_id; }
locked()138 	bool locked() const { return m_flags & 0x80; }
tier()139 	uint8_t tier() const { return m_flags & 0x07;}
exclusive()140 	const QList<uint8_t> exclusive() const { return m_exclusive; }
141 
messageName()142 	QString messageName() const override { return QStringLiteral("layeracl"); }
143 
144 protected:
145 	int payloadLength() const override;
146 	int serializePayload(uchar *data) const override;
147 	Kwargs kwargs() const override;
148 
149 private:
LayerACL(uint8_t ctx,uint16_t id,uint8_t flags,const QList<uint8_t> & exclusive)150 	LayerACL(uint8_t ctx, uint16_t id, uint8_t flags, const QList<uint8_t> &exclusive)
151 		: Message(MSG_LAYER_ACL, ctx), m_id(id), m_flags(flags), m_exclusive(exclusive)
152 	{}
153 
154 	uint16_t m_id;
155 	uint8_t m_flags;
156 	QList<uint8_t> m_exclusive;
157 };
158 
159 /**
160  * @brief Change feature access levels
161  *
162  * This is an opaque meta command.
163  */
164 class FeatureAccessLevels : public Message {
165 public:
166 	static const int FEATURES = 9; // Number of configurable features
167 
FeatureAccessLevels(uint8_t ctx,const uint8_t * featureTiers)168 	FeatureAccessLevels(uint8_t ctx, const uint8_t *featureTiers)
169 		: Message(MSG_FEATURE_LEVELS, ctx)
170 	{
171 		for(int i=0;i<FEATURES;++i)
172 			m_featureTiers[i] = featureTiers[i];
173 	}
174 
175 	static FeatureAccessLevels *deserialize(uint8_t ctx, const uchar *data, uint len);
176 	static FeatureAccessLevels *fromText(uint8_t ctx, const Kwargs &kwargs);
177 
featureTier(int featureIdx)178 	uint8_t featureTier(int featureIdx) const { Q_ASSERT(featureIdx>=0 && featureIdx<FEATURES); return m_featureTiers[featureIdx]; }
179 
messageName()180 	QString messageName() const override { return QStringLiteral("featureaccess"); }
181 
182 protected:
payloadLength()183 	int payloadLength() const override { return FEATURES; }
184 	int serializePayload(uchar *data) const override;
185 	Kwargs kwargs() const override;
186 
187 private:
188 	uint8_t m_featureTiers[FEATURES];
189 };
190 
191 /**
192  * @brief Set the default layer
193  *
194  * The default layer is the one new users default to when logging in.
195  * If no default layer is set, the newest layer will be selected by default.
196  */
197 class DefaultLayer : public Message {
198 public:
DefaultLayer(uint8_t ctx,uint16_t id)199 	DefaultLayer(uint8_t ctx, uint16_t id)
200 		: Message(MSG_LAYER_DEFAULT, ctx),
201 		m_id(id)
202 		{}
203 
204 	static DefaultLayer *deserialize(uint8_t ctx, const uchar *data, uint len);
205 	static DefaultLayer *fromText(uint8_t ctx, const Kwargs &kwargs);
206 
layer()207 	uint16_t layer() const override { return m_id; }
208 
messageName()209 	QString messageName() const override { return QStringLiteral("defaultlayer"); }
210 
211 protected:
212 	int payloadLength() const override;
213 	int serializePayload(uchar *data) const override;
214 	Kwargs kwargs() const override;
215 
216 private:
217 	uint16_t m_id;
218 };
219 
220 
221 }
222 
223 #endif
224