Merged pidgin/main into default
[pidgin-git.git] / libpurple / whiteboard.c
blobb6ef4f27e4a57632943413888948faf5002b92bb
1 /*
2 * purple
4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 #include "internal.h"
25 #include "glibcompat.h"
26 #include "whiteboard.h"
27 #include "protocol.h"
29 #define PURPLE_WHITEBOARD_GET_PRIVATE(obj) \
30 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_WHITEBOARD, PurpleWhiteboardPrivate))
32 typedef struct _PurpleWhiteboardPrivate PurpleWhiteboardPrivate;
34 /* Private data for a whiteboard */
35 struct _PurpleWhiteboardPrivate
37 int state; /* State of whiteboard session */
39 PurpleAccount *account; /* Account associated with this session */
40 char *who; /* Name of the remote user */
42 /* TODO Remove this and use protocol-specific subclasses. */
43 void *proto_data; /* Protocol specific data */
45 PurpleWhiteboardOps *protocol_ops; /* Protocol operations */
47 GList *draw_list; /* List of drawing elements/deltas to
48 send */
51 /* GObject Property enums */
52 enum
54 PROP_0,
55 PROP_STATE,
56 PROP_ACCOUNT,
57 PROP_WHO,
58 PROP_DRAW_LIST,
59 PROP_LAST
62 /******************************************************************************
63 * Globals
64 *****************************************************************************/
65 static GObjectClass *parent_class;
66 static GParamSpec *properties[PROP_LAST];
68 static PurpleWhiteboardUiOps *whiteboard_ui_ops = NULL;
69 /* static PurpleWhiteboardOps *whiteboard_protocol_ops = NULL; */
71 static GList *wb_list = NULL;
73 /*static gboolean auto_accept = TRUE; */
75 /******************************************************************************
76 * API
77 *****************************************************************************/
78 static PurpleWhiteboardUiOps *
79 purple_whiteboard_ui_ops_copy(PurpleWhiteboardUiOps *ops)
81 PurpleWhiteboardUiOps *ops_new;
83 g_return_val_if_fail(ops != NULL, NULL);
85 ops_new = g_new(PurpleWhiteboardUiOps, 1);
86 *ops_new = *ops;
88 return ops_new;
91 GType
92 purple_whiteboard_ui_ops_get_type(void)
94 static GType type = 0;
96 if (type == 0) {
97 type = g_boxed_type_register_static("PurpleWhiteboardUiOps",
98 (GBoxedCopyFunc)purple_whiteboard_ui_ops_copy,
99 (GBoxedFreeFunc)g_free);
102 return type;
105 void purple_whiteboard_set_ui_ops(PurpleWhiteboardUiOps *ops)
107 whiteboard_ui_ops = ops;
110 void purple_whiteboard_set_protocol_ops(PurpleWhiteboard *wb, PurpleWhiteboardOps *ops)
112 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
114 g_return_if_fail(priv != NULL);
116 priv->protocol_ops = ops;
119 PurpleAccount *purple_whiteboard_get_account(const PurpleWhiteboard *wb)
121 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
123 g_return_val_if_fail(priv != NULL, NULL);
125 return priv->account;
128 const char *purple_whiteboard_get_who(const PurpleWhiteboard *wb)
130 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
132 g_return_val_if_fail(priv != NULL, NULL);
134 return priv->who;
137 void purple_whiteboard_set_state(PurpleWhiteboard *wb, int state)
139 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
141 g_return_if_fail(priv != NULL);
143 priv->state = state;
145 g_object_notify_by_pspec(G_OBJECT(wb), properties[PROP_STATE]);
148 int purple_whiteboard_get_state(const PurpleWhiteboard *wb)
150 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
152 g_return_val_if_fail(priv != NULL, -1);
154 return priv->state;
157 void purple_whiteboard_start(PurpleWhiteboard *wb)
159 /* Create frontend for whiteboard */
160 if(whiteboard_ui_ops && whiteboard_ui_ops->create)
161 whiteboard_ui_ops->create(wb);
164 /* Looks through the list of whiteboard sessions for one that is between
165 * usernames 'me' and 'who'. Returns a pointer to a matching whiteboard
166 * session; if none match, it returns NULL.
168 PurpleWhiteboard *purple_whiteboard_get_session(const PurpleAccount *account, const char *who)
170 PurpleWhiteboard *wb;
171 PurpleWhiteboardPrivate *priv;
173 GList *l = wb_list;
175 /* Look for a whiteboard session between the local user and the remote user
177 while(l != NULL)
179 wb = l->data;
180 priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
182 if(priv->account == account && purple_strequal(priv->who, who))
183 return wb;
185 l = l->next;
188 return NULL;
191 void purple_whiteboard_draw_list_destroy(GList *draw_list)
193 g_list_free(draw_list);
196 gboolean purple_whiteboard_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
198 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
199 PurpleWhiteboardOps *protocol_ops;
201 g_return_val_if_fail(priv != NULL, FALSE);
203 protocol_ops = priv->protocol_ops;
205 if (protocol_ops && protocol_ops->get_dimensions)
207 protocol_ops->get_dimensions(wb, width, height);
208 return TRUE;
211 return FALSE;
214 void purple_whiteboard_set_dimensions(PurpleWhiteboard *wb, int width, int height)
216 if(whiteboard_ui_ops && whiteboard_ui_ops->set_dimensions)
217 whiteboard_ui_ops->set_dimensions(wb, width, height);
220 void purple_whiteboard_send_draw_list(PurpleWhiteboard *wb, GList *list)
222 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
223 PurpleWhiteboardOps *protocol_ops;
225 g_return_if_fail(priv != NULL);
227 protocol_ops = priv->protocol_ops;
229 if (protocol_ops && protocol_ops->send_draw_list)
230 protocol_ops->send_draw_list(wb, list);
233 void purple_whiteboard_draw_point(PurpleWhiteboard *wb, int x, int y, int color, int size)
235 if(whiteboard_ui_ops && whiteboard_ui_ops->draw_point)
236 whiteboard_ui_ops->draw_point(wb, x, y, color, size);
239 void purple_whiteboard_draw_line(PurpleWhiteboard *wb, int x1, int y1, int x2, int y2, int color, int size)
241 if(whiteboard_ui_ops && whiteboard_ui_ops->draw_line)
242 whiteboard_ui_ops->draw_line(wb, x1, y1, x2, y2, color, size);
245 void purple_whiteboard_clear(PurpleWhiteboard *wb)
247 if(whiteboard_ui_ops && whiteboard_ui_ops->clear)
248 whiteboard_ui_ops->clear(wb);
251 void purple_whiteboard_send_clear(PurpleWhiteboard *wb)
253 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
254 PurpleWhiteboardOps *protocol_ops;
256 g_return_if_fail(priv != NULL);
258 protocol_ops = priv->protocol_ops;
260 if (protocol_ops && protocol_ops->clear)
261 protocol_ops->clear(wb);
264 void purple_whiteboard_send_brush(PurpleWhiteboard *wb, int size, int color)
266 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
267 PurpleWhiteboardOps *protocol_ops;
269 g_return_if_fail(priv != NULL);
271 protocol_ops = priv->protocol_ops;
273 if (protocol_ops && protocol_ops->set_brush)
274 protocol_ops->set_brush(wb, size, color);
277 gboolean purple_whiteboard_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
279 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
280 PurpleWhiteboardOps *protocol_ops;
282 g_return_val_if_fail(priv != NULL, FALSE);
284 protocol_ops = priv->protocol_ops;
286 if (protocol_ops && protocol_ops->get_brush)
288 protocol_ops->get_brush(wb, size, color);
289 return TRUE;
291 return FALSE;
294 void purple_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color)
296 if (whiteboard_ui_ops && whiteboard_ui_ops->set_brush)
297 whiteboard_ui_ops->set_brush(wb, size, color);
300 GList *purple_whiteboard_get_draw_list(const PurpleWhiteboard *wb)
302 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
304 g_return_val_if_fail(priv != NULL, NULL);
306 return priv->draw_list;
309 void purple_whiteboard_set_draw_list(PurpleWhiteboard *wb, GList* draw_list)
311 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
313 g_return_if_fail(priv != NULL);
315 priv->draw_list = draw_list;
317 g_object_notify_by_pspec(G_OBJECT(wb), properties[PROP_DRAW_LIST]);
320 void purple_whiteboard_set_protocol_data(PurpleWhiteboard *wb, gpointer proto_data)
322 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
324 g_return_if_fail(priv != NULL);
326 priv->proto_data = proto_data;
329 gpointer purple_whiteboard_get_protocol_data(const PurpleWhiteboard *wb)
331 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
333 g_return_val_if_fail(priv != NULL, NULL);
335 return priv->proto_data;
338 void purple_whiteboard_set_ui_data(PurpleWhiteboard *wb, gpointer ui_data)
340 g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
342 wb->ui_data = ui_data;
345 gpointer purple_whiteboard_get_ui_data(const PurpleWhiteboard *wb)
347 g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), NULL);
349 return wb->ui_data;
352 /******************************************************************************
353 * GObject code
354 *****************************************************************************/
355 /* Set method for GObject properties */
356 static void
357 purple_whiteboard_set_property(GObject *obj, guint param_id, const GValue *value,
358 GParamSpec *pspec)
360 PurpleWhiteboard *wb = PURPLE_WHITEBOARD(obj);
361 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
363 switch (param_id) {
364 case PROP_STATE:
365 purple_whiteboard_set_state(wb, g_value_get_int(value));
366 break;
367 case PROP_ACCOUNT:
368 priv->account = g_value_get_object(value);
369 break;
370 case PROP_WHO:
371 priv->who = g_strdup(g_value_get_string(value));
372 break;
373 case PROP_DRAW_LIST:
374 purple_whiteboard_set_draw_list(wb, g_value_get_pointer(value));
375 break;
376 default:
377 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
378 break;
382 /* Get method for GObject properties */
383 static void
384 purple_whiteboard_get_property(GObject *obj, guint param_id, GValue *value,
385 GParamSpec *pspec)
387 PurpleWhiteboard *wb = PURPLE_WHITEBOARD(obj);
389 switch (param_id) {
390 case PROP_STATE:
391 g_value_set_int(value, purple_whiteboard_get_state(wb));
392 break;
393 case PROP_ACCOUNT:
394 g_value_set_object(value, purple_whiteboard_get_account(wb));
395 break;
396 case PROP_WHO:
397 g_value_set_string(value, purple_whiteboard_get_who(wb));
398 break;
399 case PROP_DRAW_LIST:
400 g_value_set_pointer(value, purple_whiteboard_get_draw_list(wb));
401 break;
402 default:
403 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
404 break;
408 /* Called when done constructing */
409 static void
410 purple_whiteboard_constructed(GObject *object)
412 PurpleWhiteboard *wb = PURPLE_WHITEBOARD(object);
413 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
414 PurpleProtocol *protocol;
416 parent_class->constructed(object);
418 protocol = purple_connection_get_protocol(
419 purple_account_get_connection(priv->account));
420 purple_whiteboard_set_protocol_ops(wb,
421 purple_protocol_get_whiteboard_ops(protocol));
423 /* Start up protocol specifics */
424 if(priv->protocol_ops && priv->protocol_ops->start)
425 priv->protocol_ops->start(wb);
427 wb_list = g_list_append(wb_list, wb);
430 /* GObject finalize function */
431 static void
432 purple_whiteboard_finalize(GObject *object)
434 PurpleWhiteboard *wb = PURPLE_WHITEBOARD(object);
435 PurpleWhiteboardPrivate *priv = PURPLE_WHITEBOARD_GET_PRIVATE(wb);
437 if(wb->ui_data)
439 /* Destroy frontend */
440 if(whiteboard_ui_ops && whiteboard_ui_ops->destroy)
441 whiteboard_ui_ops->destroy(wb);
444 /* Do protocol specific session ending procedures */
445 if(priv->protocol_ops && priv->protocol_ops->end)
446 priv->protocol_ops->end(wb);
448 wb_list = g_list_remove(wb_list, wb);
450 g_free(priv->who);
452 parent_class->finalize(object);
455 /* Class initializer function */
456 static void
457 purple_whiteboard_class_init(PurpleWhiteboardClass *klass)
459 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
461 parent_class = g_type_class_peek_parent(klass);
463 obj_class->finalize = purple_whiteboard_finalize;
464 obj_class->constructed = purple_whiteboard_constructed;
466 /* Setup properties */
467 obj_class->get_property = purple_whiteboard_get_property;
468 obj_class->set_property = purple_whiteboard_set_property;
470 g_type_class_add_private(klass, sizeof(PurpleWhiteboardPrivate));
472 properties[PROP_STATE] = g_param_spec_int("state", "State",
473 "State of the whiteboard.",
474 G_MININT, G_MAXINT, 0,
475 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
477 properties[PROP_ACCOUNT] = g_param_spec_object("account", "Account",
478 "The whiteboard's account.", PURPLE_TYPE_ACCOUNT,
479 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
480 G_PARAM_STATIC_STRINGS);
482 properties[PROP_WHO] = g_param_spec_string("who", "Who",
483 "Who you're drawing with.", NULL,
484 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
485 G_PARAM_STATIC_STRINGS);
487 properties[PROP_DRAW_LIST] = g_param_spec_pointer("draw-list", "Draw list",
488 "A list of points to draw to the buddy.",
489 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
491 g_object_class_install_properties(obj_class, PROP_LAST, properties);
494 GType
495 purple_whiteboard_get_type(void)
497 static GType type = 0;
499 if(type == 0) {
500 static const GTypeInfo info = {
501 sizeof(PurpleWhiteboardClass),
502 NULL,
503 NULL,
504 (GClassInitFunc)purple_whiteboard_class_init,
505 NULL,
506 NULL,
507 sizeof(PurpleWhiteboard),
509 NULL,
510 NULL,
513 type = g_type_register_static(G_TYPE_OBJECT, "PurpleWhiteboard",
514 &info, 0);
517 return type;
520 PurpleWhiteboard *purple_whiteboard_new(PurpleAccount *account, const char *who, int state)
522 PurpleWhiteboard *wb;
523 PurpleProtocol *protocol;
525 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
526 g_return_val_if_fail(who != NULL, NULL);
528 protocol = purple_protocols_find(purple_account_get_protocol_id(account));
530 g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
532 if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, FACTORY_IFACE, whiteboard_new))
533 wb = purple_protocol_factory_iface_whiteboard_new(protocol, account,
534 who, state);
535 else
536 wb = g_object_new(PURPLE_TYPE_WHITEBOARD,
537 "account", account,
538 "who", who,
539 "state", state,
540 NULL
543 g_return_val_if_fail(wb != NULL, NULL);
545 return wb;