split up whiteboard.[ch] to separate files

Tue, 10 Nov 2020 03:30:53 -0600

author
Gary Kramlich <grim@reaperworld.com>
date
Tue, 10 Nov 2020 03:30:53 -0600
changeset 40595
d7e28f8a0994
parent 40594
e32ab786a04f
child 40596
e57d4b9303ee

split up whiteboard.[ch] to separate files

Separate the whiteboard objects to their own files and clean up the code a bit.

Testing Done:
Just compile, docs, and update-pot, the only in tree protocol that supports whiteboards right now is SILC which I can't easily build.

Reviewed at https://reviews.imfreedom.org/r/202/

doc/reference/libpurple/libpurple-docs.xml file | annotate | diff | comparison | revisions
libpurple/meson.build file | annotate | diff | comparison | revisions
libpurple/protocol.h file | annotate | diff | comparison | revisions
libpurple/purplewhiteboard.c file | annotate | diff | comparison | revisions
libpurple/purplewhiteboard.h file | annotate | diff | comparison | revisions
libpurple/purplewhiteboardops.h file | annotate | diff | comparison | revisions
libpurple/purplewhiteboarduiops.c file | annotate | diff | comparison | revisions
libpurple/purplewhiteboarduiops.h file | annotate | diff | comparison | revisions
libpurple/whiteboard.c file | annotate | diff | comparison | revisions
libpurple/whiteboard.h file | annotate | diff | comparison | revisions
po/POTFILES.in file | annotate | diff | comparison | revisions
--- a/doc/reference/libpurple/libpurple-docs.xml	Tue Nov 10 03:01:09 2020 -0600
+++ b/doc/reference/libpurple/libpurple-docs.xml	Tue Nov 10 03:30:53 2020 -0600
@@ -79,6 +79,9 @@
       <xi:include href="xml/purpleprotocolim.xml" />
       <xi:include href="xml/purpleprotocolmedia.xml" />
       <xi:include href="xml/purpleprotocolprivacy.xml" />
+      <xi:include href="xml/purplewhiteboard.xml" />
+      <xi:include href="xml/purplewhiteboardops.xml" />
+      <xi:include href="xml/purplewhiteboarduiops.xml" />
       <xi:include href="xml/purpleuiinfo.xml" />
       <xi:include href="xml/queuedoutputstream.xml" />
       <xi:include href="xml/signals.xml" />
@@ -127,7 +130,6 @@
 
         <xi:include href="xml/image.xml" />
         <xi:include href="xml/image-store.xml" />
-        <xi:include href="xml/whiteboard.xml" />
     </chapter>
 
     <chapter id="media">
--- a/libpurple/meson.build	Tue Nov 10 03:01:09 2020 -0600
+++ b/libpurple/meson.build	Tue Nov 10 03:30:53 2020 -0600
@@ -65,6 +65,8 @@
 	'purpleprotocolmedia.c',
 	'purpleprotocolprivacy.c',
 	'purpleuiinfo.c',
+	'purplewhiteboard.c',
+	'purplewhiteboarduiops.c',
 	'queuedoutputstream.c',
 	'request.c',
 	'request-datasheet.c',
@@ -86,7 +88,6 @@
 	'upnp.c',
 	'util.c',
 	'version.c',
-	'whiteboard.c',
 	'xfer.c',
 	'xmlnode.c'
 ]
@@ -152,6 +153,9 @@
 	'purpleprotocolmedia.h',
 	'purpleprotocolprivacy.h',
 	'purpleuiinfo.h',
+	'purplewhiteboard.h',
+	'purplewhiteboardops.h',
+	'purplewhiteboarduiops.h',
 	'queuedoutputstream.h',
 	'request.h',
 	'request-datasheet.h',
@@ -173,7 +177,6 @@
 	'trie.h',
 	'upnp.h',
 	'util.h',
-	'whiteboard.h',
 	'xfer.h',
 	'xmlnode.h',
 ]
--- a/libpurple/protocol.h	Tue Nov 10 03:01:09 2020 -0600
+++ b/libpurple/protocol.h	Tue Nov 10 03:30:53 2020 -0600
@@ -1,4 +1,6 @@
-/* purple
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
  *
  * Purple is the legal property of its developers, whose names are too numerous
  * to list here.  Please refer to the COPYRIGHT file distributed with this
@@ -15,8 +17,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
@@ -25,11 +26,14 @@
 
 #ifndef PURPLE_PROTOCOL_H
 #define PURPLE_PROTOCOL_H
+
 /**
  * SECTION:protocol
  * @section_id: libpurple-protocol
  * @short_description: <filename>protocol.h</filename>
  * @title: Protocol Object and Interfaces
+ *
+ * #PurpleProtocol is the base type for all protocols in libpurple.
  */
 
 #define PURPLE_TYPE_PROTOCOL            (purple_protocol_get_type())
@@ -56,9 +60,10 @@
 #include "plugins.h"
 #include "purpleaccountoption.h"
 #include "purpleaccountusersplit.h"
+#include "purplewhiteboard.h"
+#include "purplewhiteboardops.h"
 #include "roomlist.h"
 #include "status.h"
-#include "whiteboard.h"
 
 /**
  * PurpleProtocol:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplewhiteboard.c	Tue Nov 10 03:30:53 2020 -0600
@@ -0,0 +1,537 @@
+/*
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ *
+ */
+
+#include "internal.h"
+#include "purplewhiteboard.h"
+
+#include "purpleprotocolfactory.h"
+#include "purplewhiteboarduiops.h"
+#include "protocol.h"
+
+typedef struct {
+	int state;
+
+	PurpleAccount *account;
+	char *who;
+
+	/* TODO Remove this and use protocol-specific subclasses. */
+	void *proto_data;
+
+	PurpleWhiteboardOps *protocol_ops;
+
+	GList *draw_list;
+} PurpleWhiteboardPrivate;
+
+/* GObject Property enums */
+enum {
+	PROP_0,
+	PROP_STATE,
+	PROP_ACCOUNT,
+	PROP_WHO,
+	PROP_DRAW_LIST,
+	N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+G_DEFINE_TYPE_WITH_PRIVATE(PurpleWhiteboard, purple_whiteboard, G_TYPE_OBJECT)
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GList *wb_list = NULL;
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_whiteboard_set_account(PurpleWhiteboard *whiteboard,
+                              PurpleAccount *account)
+{
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	if(g_set_object(&priv->account, account)) {
+		g_object_notify_by_pspec(G_OBJECT(whiteboard),
+		                         properties[PROP_ACCOUNT]);
+	}
+}
+
+static void
+purple_whiteboard_set_who(PurpleWhiteboard *whiteboard, const gchar *who) {
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	g_clear_pointer(&priv->who, g_free);
+	priv->who = g_strdup(who);
+
+	g_object_notify_by_pspec(G_OBJECT(whiteboard), properties[PROP_WHO]);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+purple_whiteboard_set_property(GObject *obj, guint param_id,
+                               const GValue *value, GParamSpec *pspec)
+{
+	PurpleWhiteboard *whiteboard = PURPLE_WHITEBOARD(obj);
+
+	switch(param_id) {
+		case PROP_STATE:
+			purple_whiteboard_set_state(whiteboard, g_value_get_int(value));
+			break;
+		case PROP_ACCOUNT:
+			purple_whiteboard_set_account(whiteboard,
+			                              g_value_get_object(value));
+			break;
+		case PROP_WHO:
+			purple_whiteboard_set_who(whiteboard, g_value_get_string(value));
+			break;
+		case PROP_DRAW_LIST:
+			purple_whiteboard_set_draw_list(whiteboard,
+			                                g_value_get_pointer(value));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_whiteboard_get_property(GObject *obj, guint param_id, GValue *value,
+                               GParamSpec *pspec)
+{
+	PurpleWhiteboard *whiteboard = PURPLE_WHITEBOARD(obj);
+
+	switch (param_id) {
+		case PROP_STATE:
+			g_value_set_int(value, purple_whiteboard_get_state(whiteboard));
+			break;
+		case PROP_ACCOUNT:
+			g_value_set_object(value,
+			                   purple_whiteboard_get_account(whiteboard));
+			break;
+		case PROP_WHO:
+			g_value_set_string(value,
+			                   purple_whiteboard_get_who(whiteboard));
+			break;
+		case PROP_DRAW_LIST:
+			g_value_set_pointer(value,
+			                    purple_whiteboard_get_draw_list(whiteboard));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_whiteboard_init(PurpleWhiteboard *whiteboard) {
+}
+
+static void
+purple_whiteboard_constructed(GObject *object) {
+	PurpleWhiteboard *whiteboard = PURPLE_WHITEBOARD(object);
+	PurpleWhiteboardPrivate *priv = NULL;
+	PurpleProtocol *protocol = NULL;
+
+	G_OBJECT_CLASS(purple_whiteboard_parent_class)->constructed(object);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	protocol = purple_connection_get_protocol(
+				purple_account_get_connection(priv->account));
+	purple_whiteboard_set_protocol_ops(whiteboard,
+				purple_protocol_get_whiteboard_ops(protocol));
+
+	/* Start up protocol specifics */
+	if(priv->protocol_ops != NULL && priv->protocol_ops->start != NULL) {
+		priv->protocol_ops->start(whiteboard);
+	}
+
+	wb_list = g_list_append(wb_list, whiteboard);
+}
+
+static void
+purple_whiteboard_finalize(GObject *object) {
+	PurpleWhiteboard *whiteboard = PURPLE_WHITEBOARD(object);
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	if(whiteboard->ui_data) {
+		purple_whiteboard_ui_ops_destroy(whiteboard);
+	}
+
+	/* Do protocol specific session ending procedures */
+	if(priv->protocol_ops != NULL && priv->protocol_ops->end != NULL) {
+		priv->protocol_ops->end(whiteboard);
+	}
+
+	wb_list = g_list_remove(wb_list, whiteboard);
+
+	g_clear_object(&priv->account);
+	g_clear_pointer(&priv->who, g_free);
+
+	/* TODO: figure out how we need to clean up the drawlist */
+
+	G_OBJECT_CLASS(purple_whiteboard_parent_class)->finalize(object);
+}
+
+static void
+purple_whiteboard_class_init(PurpleWhiteboardClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+	obj_class->get_property = purple_whiteboard_get_property;
+	obj_class->set_property = purple_whiteboard_set_property;
+	obj_class->finalize = purple_whiteboard_finalize;
+	obj_class->constructed = purple_whiteboard_constructed;
+
+	properties[PROP_STATE] = g_param_spec_int(
+		"state", "State",
+		"State of the whiteboard.",
+		G_MININT, G_MAXINT, 0,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+	properties[PROP_ACCOUNT] = g_param_spec_object(
+		"account", "Account",
+		"The whiteboard's account.", PURPLE_TYPE_ACCOUNT,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+	properties[PROP_WHO] = g_param_spec_string(
+		"who", "Who",
+		"Who you're drawing with.", NULL,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+	properties[PROP_DRAW_LIST] = g_param_spec_pointer(
+		"draw-list", "Draw list",
+		"A list of points to draw to the buddy.",
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+void
+purple_whiteboard_set_protocol_ops(PurpleWhiteboard *whiteboard,
+                                   PurpleWhiteboardOps *ops)
+{
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	priv->protocol_ops = ops;
+}
+
+PurpleAccount *
+purple_whiteboard_get_account(PurpleWhiteboard *whiteboard) {
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), NULL);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	return priv->account;
+}
+
+const gchar *
+purple_whiteboard_get_who(PurpleWhiteboard *whiteboard) {
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), NULL);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	return priv->who;
+}
+
+void
+purple_whiteboard_set_state(PurpleWhiteboard *whiteboard, int state) {
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	priv->state = state;
+
+	g_object_notify_by_pspec(G_OBJECT(whiteboard), properties[PROP_STATE]);
+}
+
+gint
+purple_whiteboard_get_state(PurpleWhiteboard *whiteboard) {
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), -1);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	return priv->state;
+}
+
+void
+purple_whiteboard_start(PurpleWhiteboard *whiteboard) {
+	purple_whiteboard_ui_ops_create(whiteboard);
+}
+
+PurpleWhiteboard *
+purple_whiteboard_get_session(PurpleAccount *account, const gchar *who) {
+	PurpleWhiteboard *whiteboard = NULL;
+	PurpleWhiteboardPrivate *priv = NULL;
+	GList *l = NULL;
+
+	for(l = wb_list; l != NULL; l = l->next) {
+		whiteboard = PURPLE_WHITEBOARD(l->data);
+		priv = purple_whiteboard_get_instance_private(whiteboard);
+
+		if(priv->account == account && purple_strequal(priv->who, who)) {
+			return whiteboard;
+		}
+	}
+
+	return NULL;
+}
+
+void
+purple_whiteboard_draw_list_destroy(GList *draw_list) {
+	g_list_free(draw_list);
+}
+
+gboolean
+purple_whiteboard_get_dimensions(PurpleWhiteboard *whiteboard, gint *width,
+                                 gint *height)
+{
+	PurpleWhiteboardPrivate *priv = NULL;
+	PurpleWhiteboardOps *protocol_ops = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), FALSE);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+	protocol_ops = priv->protocol_ops;
+
+	if(protocol_ops != NULL && protocol_ops->get_dimensions != NULL) {
+		protocol_ops->get_dimensions(whiteboard, width, height);
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+void
+purple_whiteboard_set_dimensions(PurpleWhiteboard *whiteboard, gint width,
+                                 gint height)
+{
+	purple_whiteboard_ui_ops_set_dimensions(whiteboard, width, height);
+}
+
+void
+purple_whiteboard_send_draw_list(PurpleWhiteboard *whiteboard, GList *list) {
+	PurpleWhiteboardPrivate *priv = NULL;
+	PurpleWhiteboardOps *protocol_ops = NULL;
+
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+	protocol_ops = priv->protocol_ops;
+
+	if(protocol_ops != NULL && protocol_ops->send_draw_list != NULL) {
+		protocol_ops->send_draw_list(whiteboard, list);
+	}
+}
+
+void
+purple_whiteboard_draw_point(PurpleWhiteboard *whiteboard, gint x, gint y,
+                             gint color, gint size)
+{
+	purple_whiteboard_ui_ops_draw_point(whiteboard, x, y, color, size);
+}
+
+void
+purple_whiteboard_draw_line(PurpleWhiteboard *whiteboard, gint x1, gint y1,
+                            gint x2, gint y2, gint color, gint size)
+{
+	purple_whiteboard_ui_ops_draw_line(whiteboard, x1, y1, x2, y2, color,
+	                                   size);
+}
+
+void
+purple_whiteboard_clear(PurpleWhiteboard *whiteboard) {
+	purple_whiteboard_ui_ops_clear(whiteboard);
+}
+
+void
+purple_whiteboard_send_clear(PurpleWhiteboard *whiteboard) {
+	PurpleWhiteboardPrivate *priv = NULL;
+	PurpleWhiteboardOps *protocol_ops = NULL;
+
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+	protocol_ops = priv->protocol_ops;
+
+	if(protocol_ops != NULL && protocol_ops->clear != NULL) {
+		protocol_ops->clear(whiteboard);
+	}
+}
+
+void
+purple_whiteboard_send_brush(PurpleWhiteboard *whiteboard, gint size,
+                             gint color)
+{
+	PurpleWhiteboardPrivate *priv = NULL;
+	PurpleWhiteboardOps *protocol_ops = NULL;
+
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+	protocol_ops = priv->protocol_ops;
+
+	if(protocol_ops != NULL && protocol_ops->set_brush != NULL) {
+		protocol_ops->set_brush(whiteboard, size, color);
+	}
+}
+
+gboolean
+purple_whiteboard_get_brush(PurpleWhiteboard *whiteboard, gint *size,
+                            gint *color)
+{
+	PurpleWhiteboardPrivate *priv = NULL;
+	PurpleWhiteboardOps *protocol_ops = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), FALSE);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+	protocol_ops = priv->protocol_ops;
+
+	if(protocol_ops != NULL && protocol_ops->get_brush != NULL) {
+		protocol_ops->get_brush(whiteboard, size, color);
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+void
+purple_whiteboard_set_brush(PurpleWhiteboard *whiteboard, gint size,
+                            gint color)
+{
+	purple_whiteboard_ui_ops_set_brush(whiteboard, size, color);
+}
+
+GList *
+purple_whiteboard_get_draw_list(PurpleWhiteboard *whiteboard) {
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), NULL);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	return priv->draw_list;
+}
+
+void
+purple_whiteboard_set_draw_list(PurpleWhiteboard *whiteboard,
+                                GList* draw_list)
+{
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+	priv->draw_list = draw_list;
+
+	g_object_notify_by_pspec(G_OBJECT(whiteboard), properties[PROP_DRAW_LIST]);
+}
+
+void
+purple_whiteboard_set_protocol_data(PurpleWhiteboard *whiteboard,
+                                    gpointer proto_data)
+{
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+	priv->proto_data = proto_data;
+}
+
+gpointer
+purple_whiteboard_get_protocol_data(PurpleWhiteboard *whiteboard) {
+	PurpleWhiteboardPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), NULL);
+
+	priv = purple_whiteboard_get_instance_private(whiteboard);
+
+	return priv->proto_data;
+}
+
+void
+purple_whiteboard_set_ui_data(PurpleWhiteboard *whiteboard, gpointer ui_data) {
+	g_return_if_fail(PURPLE_IS_WHITEBOARD(whiteboard));
+
+	whiteboard->ui_data = ui_data;
+}
+
+gpointer
+purple_whiteboard_get_ui_data(PurpleWhiteboard *whiteboard) {
+	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(whiteboard), NULL);
+
+	return whiteboard->ui_data;
+}
+
+PurpleWhiteboard *
+purple_whiteboard_new(PurpleAccount *account, const gchar *who, gint state) {
+	PurpleWhiteboard *whiteboard = NULL;
+	PurpleProtocol *protocol = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
+	g_return_val_if_fail(who != NULL, NULL);
+
+	protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+
+	g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+
+	if(PURPLE_IS_PROTOCOL_FACTORY(protocol)) {
+		whiteboard = purple_protocol_factory_whiteboard_new(
+			PURPLE_PROTOCOL_FACTORY(protocol), account, who, state);
+	} else {
+		whiteboard = g_object_new(PURPLE_TYPE_WHITEBOARD,
+			"account", account,
+			"who",     who,
+			"state",   state,
+			NULL
+		);
+	}
+
+	return whiteboard;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplewhiteboard.h	Tue Nov 10 03:30:53 2020 -0600
@@ -0,0 +1,331 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_WHITEBOARD_H
+#define PURPLE_WHITEBOARD_H
+
+/**
+ * SECTION:purplewhiteboard
+ * @section_id: libpurple-purplewhiteboard
+ * @short_description: <filename>whiteboard.h</filename>
+ * @title: Whiteboard Object
+ *
+ * The #PurpleWhiteboard API describes all interactions with whiteboards or
+ * shared drawing spaces with other users.
+ */
+
+/**
+ * PURPLE_TYPE_WHITEBOARD:
+ *
+ * The standard _get_type macro for #PurpleWhiteboard.
+ */
+#define PURPLE_TYPE_WHITEBOARD (purple_whiteboard_get_type())
+typedef struct _PurpleWhiteboard PurpleWhiteboard;
+
+#include "account.h"
+
+#include <libpurple/purplewhiteboardops.h>
+
+/**
+ * PurpleWhiteboard:
+ * @ui_data: The UI data associated with this whiteboard. This is a convenience
+ *           field provided to the UIs -- it is not used by the libpurple core.
+ *
+ * A Whiteboard
+ */
+struct _PurpleWhiteboard {
+	GObject gparent;
+
+	/*< public >*/
+	gpointer ui_data;
+};
+
+G_BEGIN_DECLS
+
+/**
+ * purple_whiteboard_get_type:
+ * The standard _get_type function for #PurpleWhiteboard.
+ *
+ * Returns: The #GType for the #PurpleWhiteboard object.
+ */
+G_DECLARE_FINAL_TYPE(PurpleWhiteboard, purple_whiteboard, PURPLE, WHITEBOARD,
+                     GObject)
+
+/**
+ * purple_whiteboard_set_protocol_ops:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @ops: The #PurpleWhiteboardOps to set.
+ *
+ * Sets the protocol operations for @whiteboard.
+ */
+void purple_whiteboard_set_protocol_ops(PurpleWhiteboard *whiteboard, PurpleWhiteboardOps *ops);
+
+/**
+ * purple_whiteboard_new:
+ * @account: A #PurpleAccount instance.
+ * @who: Who you're drawing with.
+ * @state: The state.
+ *
+ * Creates a new whiteboard.
+ *
+ * Returns: (transfer full): The new #PurpleWhiteboard instance.
+ */
+PurpleWhiteboard *purple_whiteboard_new(PurpleAccount *account, const gchar *who, gint state);
+
+/**
+ * purple_whiteboard_get_account:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Gets the #PurpleAccount that @whiteboard is tied to.
+ *
+ * Returns: (transfer none): The #PurpleAccount for @whiteboard.
+ */
+PurpleAccount *purple_whiteboard_get_account(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_get_who:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Gets the name of who you're drawing with.
+ *
+ * Returns: The name of who you're drawing with.
+ */
+const gchar *purple_whiteboard_get_who(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_set_state:
+ * @whiteboard: The whiteboard.
+ * @state: The state
+ *
+ * Set the state of @whiteboard to @state.
+ */
+void purple_whiteboard_set_state(PurpleWhiteboard *whiteboard, gint state);
+
+/**
+ * purple_whiteboard_get_state:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Gets the state of @whiteboard.
+ *
+ * Returns: The state of the @whiteboard.
+ */
+gint purple_whiteboard_get_state(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_start:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Puts @whiteboard into the started state if it wasn't already.
+ */
+void purple_whiteboard_start(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_get_session:
+ * @account: A #PurpleAccount instance.
+ * @who: The name of the user you're drawing with.
+ *
+ * Finds a whiteboard from @account and @who.
+ *
+ * Returns: (transfer none): The #PurpleWhiteboard instance if found, otherwise
+ *          %NULL.
+ */
+PurpleWhiteboard *purple_whiteboard_get_session(PurpleAccount *account, const gchar *who);
+
+/**
+ * purple_whiteboard_draw_list_destroy:
+ * @draw_list: (element-type gint): The drawing list.
+ *
+ * Destroys a drawing list for a whiteboard
+ */
+void purple_whiteboard_draw_list_destroy(GList *draw_list);
+
+/**
+ * purple_whiteboard_get_dimensions:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @width: (nullable) (out): A return address for the width.
+ * @height: (nullable) (out): A return address for the height.
+ *
+ * Gets the dimension of a whiteboard.
+ *
+ * Returns: %TRUE if the values of @width and @height were set.
+ */
+gboolean purple_whiteboard_get_dimensions(PurpleWhiteboard *whiteboard, gint *width, gint *height);
+
+/**
+ * purple_whiteboard_set_dimensions:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @width: The new width.
+ * @height: The new height.
+ *
+ * Sets the dimensions for @whiteboard.
+ */
+void purple_whiteboard_set_dimensions(PurpleWhiteboard *whiteboard, gint width, gint height);
+
+/**
+ * purple_whiteboard_draw_point:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @x: The x coordinate.
+ * @y: The y coordinate.
+ * @color: The color to use.
+ * @size: The brush size.
+ *
+ * Draws a point on @whiteboard with the given parameters.
+ */
+void purple_whiteboard_draw_point(PurpleWhiteboard *whiteboard, gint x, gint y, gint color, gint size);
+
+/**
+ * purple_whiteboard_send_draw_list:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @list: (element-type gint): A GList of points.
+ *
+ * Send a list of points to draw.
+ */
+void purple_whiteboard_send_draw_list(PurpleWhiteboard *whiteboard, GList *list);
+
+/**
+ * purple_whiteboard_draw_line:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @x1: The top-left x coordinate.
+ * @y1: The top-left y coordinate.
+ * @x2: The bottom-right x coordinate.
+ * @y2: The bottom-right y coordinate.
+ * @color: The color to use.
+ * @size: The brush size.
+ *
+ * Draws a line on @whiteboard with the given parameters.
+ */
+void purple_whiteboard_draw_line(PurpleWhiteboard *whiteboard, gint x1, gint y1, gint x2, gint y2, gint color, gint size);
+
+/**
+ * purple_whiteboard_clear:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Clears the contents of @whiteboard.
+ */
+void purple_whiteboard_clear(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_send_clear:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Sends a request to the buddy to clear @whiteboard.
+ */
+void purple_whiteboard_send_clear(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_send_brush:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @size: The size of the brush.
+ * @color: The color of the brush.
+ *
+ * Sends a request to change the size and color of the brush.
+ */
+void purple_whiteboard_send_brush(PurpleWhiteboard *whiteboard, gint size, gint color);
+
+/**
+ * purple_whiteboard_get_brush:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @size: (nullable) (out): A return address for the size of the brush.
+ * @color: (nullable) (out): A return address for the color of the brush.
+ *
+ * Gets the size and color of the brush.
+ *
+ * Returns:	%TRUE if the size and color were set.
+ */
+gboolean purple_whiteboard_get_brush(PurpleWhiteboard *whiteboard, gint *size, gint *color);
+
+/**
+ * purple_whiteboard_set_brush:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @size: The size of the brush.
+ * @color: The color of the brush.
+ *
+ * Sets the size and color of the brush.
+ */
+void purple_whiteboard_set_brush(PurpleWhiteboard *whiteboard, gint size, gint color);
+
+/**
+ * purple_whiteboard_get_draw_list:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Gets the drawing list.
+ *
+ * Returns: (transfer none) (element-type gint): The drawing list.
+ */
+GList *purple_whiteboard_get_draw_list(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_set_draw_list:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @draw_list: (element-type gint): The drawing list.
+ *
+ * Sets the drawing list.
+ */
+void purple_whiteboard_set_draw_list(PurpleWhiteboard *whiteboard, GList* draw_list);
+
+/**
+ * purple_whiteboard_set_protocol_data:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @proto_data: The protocol data to set for the whiteboard.
+ *
+ * Sets the protocol data for @whiteboard.
+ */
+void purple_whiteboard_set_protocol_data(PurpleWhiteboard *whiteboard, gpointer proto_data);
+
+/**
+ * purple_whiteboard_get_protocol_data:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Gets the protocol data for a whiteboard.
+ *
+ * Returns: The protocol data for the whiteboard.
+ */
+gpointer purple_whiteboard_get_protocol_data(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_set_ui_data:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ * @ui_data: A pointer to associate with this whiteboard.
+ *
+ * Set the UI data associated with this whiteboard.
+ */
+void purple_whiteboard_set_ui_data(PurpleWhiteboard *whiteboard, gpointer ui_data);
+
+/**
+ * purple_whiteboard_get_ui_data:
+ * @whiteboard: The #PurpleWhiteboard instance.
+ *
+ * Get the UI data associated with @whiteboard.
+ *
+ * Returns: The UI data associated with @whiteboard.  This is a convenience
+ *          field provided to the UIs--it is not used by the libpurple core.
+ */
+gpointer purple_whiteboard_get_ui_data(PurpleWhiteboard *whiteboard);
+
+G_END_DECLS
+
+#endif /* PURPLE_WHITEBOARD_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplewhiteboardops.h	Tue Nov 10 03:30:53 2020 -0600
@@ -0,0 +1,77 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <pidgin.h> may be included directly"
+#endif
+
+#ifndef PURPLE_WHITEBOARD_OPS_H
+#define PURPLE_WHITEBOARD_OPS_H
+
+/**
+ * SECTION:purplewhiteboardops
+ * @section_id: libpurple-purplewhiteboardops
+ * @short_description: Whiteboard Protocol Operations
+ * @title: Whiteboard Protocol Operations
+ *
+ * #PurpleWhiteboardOps contains the protocol operations for whiteboards.
+ */
+
+#include <glib.h>
+
+typedef struct _PurpleWhiteboardOps PurpleWhiteboardOps;
+
+#include "purplewhiteboard.h"
+
+G_BEGIN_DECLS
+
+/**
+ * PurpleWhiteboardOps:
+ * @start:          start function
+ * @end:            end function
+ * @get_dimensions: get whiteboard dimensions
+ * @set_dimensions: set whiteboard dimensions
+ * @get_brush:      get the brush size and color
+ * @set_brush:      set the brush size and color
+ * @send_draw_list: send_draw_list function
+ * @clear:          clear whiteboard
+ *
+ * Whiteboard protocol operations
+ */
+struct _PurpleWhiteboardOps
+{
+	void (*start)(PurpleWhiteboard *wb);
+	void (*end)(PurpleWhiteboard *wb);
+	void (*get_dimensions)(const PurpleWhiteboard *wb, int *width, int *height);
+	void (*set_dimensions)(PurpleWhiteboard *wb, int width, int height);
+	void (*get_brush) (const PurpleWhiteboard *wb, int *size, int *color);
+	void (*set_brush) (PurpleWhiteboard *wb, int size, int color);
+	void (*send_draw_list)(PurpleWhiteboard *wb, GList *draw_list);
+	void (*clear)(PurpleWhiteboard *wb);
+
+	/*< private >*/
+	gpointer reserved[4];
+};
+
+G_END_DECLS
+
+#endif /* PURPLE_WHITEBOARD_OPS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplewhiteboarduiops.c	Tue Nov 10 03:30:53 2020 -0600
@@ -0,0 +1,112 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "purplewhiteboarduiops.h"
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static PurpleWhiteboardUiOps *ui_ops = NULL;
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static PurpleWhiteboardUiOps *
+purple_whiteboard_ui_ops_copy(PurpleWhiteboardUiOps *ops) {
+	PurpleWhiteboardUiOps *ops_new = NULL;
+
+	g_return_val_if_fail(ops != NULL, NULL);
+
+	ops_new = g_new(PurpleWhiteboardUiOps, 1);
+	*ops_new = *ops;
+
+	return ops_new;
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+G_DEFINE_BOXED_TYPE(PurpleWhiteboardUiOps, purple_whiteboard_ui_ops,
+                    purple_whiteboard_ui_ops_copy, g_free)
+
+void
+purple_whiteboard_set_ui_ops(PurpleWhiteboardUiOps *ops) {
+	ui_ops = ops;
+}
+
+void
+purple_whiteboard_ui_ops_create(PurpleWhiteboard *whiteboard) {
+	if(ui_ops != NULL && ui_ops->create != NULL) {
+		ui_ops->create(whiteboard);
+	}
+}
+
+void
+purple_whiteboard_ui_ops_destroy(PurpleWhiteboard *whiteboard) {
+	if(ui_ops != NULL && ui_ops->destroy != NULL) {
+		ui_ops->destroy(whiteboard);
+	}
+}
+
+void
+purple_whiteboard_ui_ops_set_dimensions(PurpleWhiteboard *whiteboard,
+                                        gint width, gint height)
+{
+	if(ui_ops != NULL && ui_ops->set_dimensions != NULL) {
+		ui_ops->set_dimensions(whiteboard, width, height);
+	}
+}
+
+void
+purple_whiteboard_ui_ops_set_brush(PurpleWhiteboard *whiteboard, gint size,
+                                   gint color)
+{
+	if(ui_ops != NULL && ui_ops->set_brush != NULL) {
+		ui_ops->set_brush(whiteboard, size, color);
+	}
+}
+
+void
+purple_whiteboard_ui_ops_draw_point(PurpleWhiteboard *whiteboard, gint x,
+                                    gint y, gint color, gint size)
+{
+	if(ui_ops != NULL && ui_ops->draw_point != NULL) {
+		ui_ops->draw_point(whiteboard, x, y, color, size);
+	}
+}
+
+void
+purple_whiteboard_ui_ops_draw_line(PurpleWhiteboard *whiteboard, gint x1,
+                                   gint y1, gint x2, gint y2, gint color,
+                                   gint size)
+{
+	if(ui_ops != NULL && ui_ops->draw_line != NULL) {
+		ui_ops->draw_line(whiteboard, x1, y1, x2, y2, color, size);
+	}
+}
+
+void
+purple_whiteboard_ui_ops_clear(PurpleWhiteboard *whiteboard) {
+	if(ui_ops != NULL && ui_ops->clear != NULL) {
+		ui_ops->clear(whiteboard);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplewhiteboarduiops.h	Tue Nov 10 03:30:53 2020 -0600
@@ -0,0 +1,166 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <pidgin.h> may be included directly"
+#endif
+
+#ifndef PURPLE_WHITEBOARD_UIOPS_H
+#define PURPLE_WHITEBOARD_UIOPS_H
+
+/**
+ * SECTION:purplewhiteboarduiops
+ * @section_id: libpurple-purplewhiteboarduiops
+ * @short_description: Whiteboard UI Operations
+ * @title: Whiteboard User Interface Operations
+ *
+ * #PurpleWhiteboardUiOps contains the user interface operations for
+ * whiteboards.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+/**
+ * PURPLE_TYPE_WHITEBOARD_UI_OPS:
+ *
+ * The standard _get_type macro for #PurpleWhiteboardUiOps.
+ */
+#define PURPLE_TYPE_WHITEBOARD_UI_OPS (purple_whiteboard_ui_ops_get_type())
+typedef struct _PurpleWhiteboardUiOps PurpleWhiteboardUiOps;
+
+#include <libpurple/purplewhiteboard.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PurpleWhiteboardUiOps:
+ * @create:         create whiteboard
+ * @destroy:        destroy whiteboard
+ * @set_dimensions: set whiteboard dimensions
+ * @set_brush:      set the size and color of the brush
+ * @draw_point:     draw a point
+ * @draw_line:      draw a line
+ * @clear:          clear whiteboard
+ *
+ * The PurpleWhiteboard UI Operations
+ */
+struct _PurpleWhiteboardUiOps
+{
+	void (*create)(PurpleWhiteboard *wb);
+	void (*destroy)(PurpleWhiteboard *wb);
+	void (*set_dimensions)(PurpleWhiteboard *wb, int width, int height);
+	void (*set_brush) (PurpleWhiteboard *wb, int size, int color);
+	void (*draw_point)(PurpleWhiteboard *wb, int x, int y,
+	                   int color, int size);
+	void (*draw_line)(PurpleWhiteboard *wb, int x1, int y1,
+	                  int x2, int y2,
+	                  int color, int size);
+	void (*clear)(PurpleWhiteboard *wb);
+
+	/*< private >*/
+	gpointer reserved[4];
+};
+
+GType purple_whiteboard_ui_ops_get_type(void);
+
+/**
+ * purple_whiteboard_set_ui_ops:
+ * @ops: The UI operations to set
+ *
+ * Sets the UI operations
+ */
+void purple_whiteboard_set_ui_ops(PurpleWhiteboardUiOps *ops);
+
+/**
+ * purple_whiteboard_ui_ops_create:
+ * @whiteboard: A #PurpleWhiteboard instance.
+ *
+ * Creates a user interface for @whiteboard.
+ */
+void purple_whiteboard_ui_ops_create(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_ui_ops_destroy:
+ * @whiteboard: A #PurpleWhiteboard instance.
+ *
+ * Destroys the user interface for @whiteboard.
+ */
+void purple_whiteboard_ui_ops_destroy(PurpleWhiteboard *whiteboard);
+
+/**
+ * purple_whiteboard_ui_ops_set_dimensions:
+ * @whiteboard: A #PurpleWhiteboard instance.
+ * @width: The new width.
+ * @height: The new height.
+ *
+ * Sets the user interface dimensions for @whiteboard.
+ */
+void purple_whiteboard_ui_ops_set_dimensions(PurpleWhiteboard *whiteboard, gint width, gint height);
+
+/**
+ * purple_whiteboard_ui_ops_set_brush:
+ * @whiteboard: A #PurpleWhiteboard instance.
+ * @size: The size of the brush.
+ * @color: The color to use.
+ *
+ * Sets the size and color of the active brush for @whiteboard.
+ */
+void purple_whiteboard_ui_ops_set_brush(PurpleWhiteboard *whiteboard, gint size, gint color);
+
+/**
+ * purple_whiteboard_ui_ops_draw_point:
+ * @whiteboard: A #PurpleWhiteboard instance.
+ * @x: The x coordinate.
+ * @y: The y coordinate.
+ * @color: The color of the point.
+ * @size: The size of the point.
+ *
+ * Draws a point on @whiteboard.
+ */
+void purple_whiteboard_ui_ops_draw_point(PurpleWhiteboard *whiteboard, gint x, gint y, gint color, gint size);
+
+/**
+ * purple_whiteboard_ui_ops_draw_line:
+ * @whiteboard: A #PurpleWhiteboard instance.
+ * @x1: The starting point's x coordinate.
+ * @y1: The starting point's y coordinate.
+ * @x2: The end point's x coordinate.
+ * @y2: The end point's y coordinate.
+ * @color: The color for the line.
+ * @size: The size of the line.
+ *
+ * Draws a line on @whiteboard.
+ */
+void purple_whiteboard_ui_ops_draw_line(PurpleWhiteboard *whiteboard, gint x1, gint y1, gint x2, gint y2, gint color, gint size);
+
+/**
+ * purple_whiteboard_ui_ops_clear:
+ * @whiteboard: A #PurpleWhiteboard instance.
+ *
+ * Clears all the contents of @whiteboard.
+ */
+void purple_whiteboard_ui_ops_clear(PurpleWhiteboard *whiteboard);
+
+G_END_DECLS
+
+#endif /* PURPLE_WHITEBOARD_UIOPS_H */
--- a/libpurple/whiteboard.c	Tue Nov 10 03:01:09 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,537 +0,0 @@
-/*
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- *
- */
-
-#include "internal.h"
-#include "whiteboard.h"
-#include "purpleprotocolfactory.h"
-#include "protocol.h"
-
-typedef struct _PurpleWhiteboardPrivate  PurpleWhiteboardPrivate;
-
-/* Private data for a whiteboard */
-struct _PurpleWhiteboardPrivate
-{
-	int state;                      /* State of whiteboard session          */
-
-	PurpleAccount *account;         /* Account associated with this session */
-	char *who;                      /* Name of the remote user              */
-
-	/* TODO Remove this and use protocol-specific subclasses. */
-	void *proto_data;               /* Protocol specific data               */
-
-	PurpleWhiteboardOps *protocol_ops; /* Protocol operations               */
-
-	GList *draw_list;               /* List of drawing elements/deltas to
-	                                   send                                 */
-};
-
-/* GObject Property enums */
-enum
-{
-	PROP_0,
-	PROP_STATE,
-	PROP_ACCOUNT,
-	PROP_WHO,
-	PROP_DRAW_LIST,
-	PROP_LAST
-};
-
-/******************************************************************************
- * Globals
- *****************************************************************************/
-static GParamSpec *properties[PROP_LAST];
-
-G_DEFINE_TYPE_WITH_PRIVATE(PurpleWhiteboard, purple_whiteboard, G_TYPE_OBJECT);
-
-static PurpleWhiteboardUiOps *whiteboard_ui_ops = NULL;
-/* static PurpleWhiteboardOps *whiteboard_protocol_ops = NULL; */
-
-static GList *wb_list = NULL;
-
-/*static gboolean auto_accept = TRUE; */
-
-/******************************************************************************
- * API
- *****************************************************************************/
-static PurpleWhiteboardUiOps *
-purple_whiteboard_ui_ops_copy(PurpleWhiteboardUiOps *ops)
-{
-	PurpleWhiteboardUiOps *ops_new;
-
-	g_return_val_if_fail(ops != NULL, NULL);
-
-	ops_new = g_new(PurpleWhiteboardUiOps, 1);
-	*ops_new = *ops;
-
-	return ops_new;
-}
-
-GType
-purple_whiteboard_ui_ops_get_type(void)
-{
-	static GType type = 0;
-
-	if (type == 0) {
-		type = g_boxed_type_register_static("PurpleWhiteboardUiOps",
-				(GBoxedCopyFunc)purple_whiteboard_ui_ops_copy,
-				(GBoxedFreeFunc)g_free);
-	}
-
-	return type;
-}
-
-void purple_whiteboard_set_ui_ops(PurpleWhiteboardUiOps *ops)
-{
-	whiteboard_ui_ops = ops;
-}
-
-void purple_whiteboard_set_protocol_ops(PurpleWhiteboard *wb, PurpleWhiteboardOps *ops)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	priv->protocol_ops = ops;
-}
-
-PurpleAccount *purple_whiteboard_get_account(PurpleWhiteboard *wb)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), NULL);
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	return priv->account;
-}
-
-const char *purple_whiteboard_get_who(PurpleWhiteboard *wb)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), NULL);
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	return priv->who;
-}
-
-void purple_whiteboard_set_state(PurpleWhiteboard *wb, int state)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	priv->state = state;
-
-	g_object_notify_by_pspec(G_OBJECT(wb), properties[PROP_STATE]);
-}
-
-int purple_whiteboard_get_state(PurpleWhiteboard *wb)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), -1);
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	return priv->state;
-}
-
-void purple_whiteboard_start(PurpleWhiteboard *wb)
-{
-	/* Create frontend for whiteboard */
-	if(whiteboard_ui_ops && whiteboard_ui_ops->create)
-		whiteboard_ui_ops->create(wb);
-}
-
-/* Looks through the list of whiteboard sessions for one that is between
- * usernames 'me' and 'who'.  Returns a pointer to a matching whiteboard
- * session; if none match, it returns NULL.
- */
-PurpleWhiteboard *purple_whiteboard_get_session(const PurpleAccount *account, const char *who)
-{
-	PurpleWhiteboard *wb;
-	PurpleWhiteboardPrivate *priv;
-
-	GList *l = wb_list;
-
-	/* Look for a whiteboard session between the local user and the remote user
-	 */
-	while(l != NULL)
-	{
-		wb = l->data;
-		priv = purple_whiteboard_get_instance_private(wb);
-
-		if(priv->account == account && purple_strequal(priv->who, who))
-			return wb;
-
-		l = l->next;
-	}
-
-	return NULL;
-}
-
-void purple_whiteboard_draw_list_destroy(GList *draw_list)
-{
-	g_list_free(draw_list);
-}
-
-gboolean purple_whiteboard_get_dimensions(PurpleWhiteboard *wb, int *width, int *height)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-	PurpleWhiteboardOps *protocol_ops;
-
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), FALSE);
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	protocol_ops = priv->protocol_ops;
-
-	if (protocol_ops && protocol_ops->get_dimensions)
-	{
-		protocol_ops->get_dimensions(wb, width, height);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-void purple_whiteboard_set_dimensions(PurpleWhiteboard *wb, int width, int height)
-{
-	if(whiteboard_ui_ops && whiteboard_ui_ops->set_dimensions)
-		whiteboard_ui_ops->set_dimensions(wb, width, height);
-}
-
-void purple_whiteboard_send_draw_list(PurpleWhiteboard *wb, GList *list)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-	PurpleWhiteboardOps *protocol_ops;
-
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	protocol_ops = priv->protocol_ops;
-
-	if (protocol_ops && protocol_ops->send_draw_list)
-		protocol_ops->send_draw_list(wb, list);
-}
-
-void purple_whiteboard_draw_point(PurpleWhiteboard *wb, int x, int y, int color, int size)
-{
-	if(whiteboard_ui_ops && whiteboard_ui_ops->draw_point)
-		whiteboard_ui_ops->draw_point(wb, x, y, color, size);
-}
-
-void purple_whiteboard_draw_line(PurpleWhiteboard *wb, int x1, int y1, int x2, int y2, int color, int size)
-{
-	if(whiteboard_ui_ops && whiteboard_ui_ops->draw_line)
-		whiteboard_ui_ops->draw_line(wb, x1, y1, x2, y2, color, size);
-}
-
-void purple_whiteboard_clear(PurpleWhiteboard *wb)
-{
-	if(whiteboard_ui_ops && whiteboard_ui_ops->clear)
-		whiteboard_ui_ops->clear(wb);
-}
-
-void purple_whiteboard_send_clear(PurpleWhiteboard *wb)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-	PurpleWhiteboardOps *protocol_ops;
-
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	protocol_ops = priv->protocol_ops;
-
-	if (protocol_ops && protocol_ops->clear)
-		protocol_ops->clear(wb);
-}
-
-void purple_whiteboard_send_brush(PurpleWhiteboard *wb, int size, int color)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-	PurpleWhiteboardOps *protocol_ops;
-
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	protocol_ops = priv->protocol_ops;
-
-	if (protocol_ops && protocol_ops->set_brush)
-		protocol_ops->set_brush(wb, size, color);
-}
-
-gboolean purple_whiteboard_get_brush(PurpleWhiteboard *wb, int *size, int *color)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-	PurpleWhiteboardOps *protocol_ops;
-
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), FALSE);
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	protocol_ops = priv->protocol_ops;
-
-	if (protocol_ops && protocol_ops->get_brush)
-	{
-		protocol_ops->get_brush(wb, size, color);
-		return TRUE;
-	}
-	return FALSE;
-}
-
-void purple_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color)
-{
-	if (whiteboard_ui_ops && whiteboard_ui_ops->set_brush)
-		whiteboard_ui_ops->set_brush(wb, size, color);
-}
-
-GList *purple_whiteboard_get_draw_list(PurpleWhiteboard *wb)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), NULL);
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	return priv->draw_list;
-}
-
-void purple_whiteboard_set_draw_list(PurpleWhiteboard *wb, GList* draw_list)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	priv->draw_list = draw_list;
-
-	g_object_notify_by_pspec(G_OBJECT(wb), properties[PROP_DRAW_LIST]);
-}
-
-void purple_whiteboard_set_protocol_data(PurpleWhiteboard *wb, gpointer proto_data)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	priv->proto_data = proto_data;
-}
-
-gpointer purple_whiteboard_get_protocol_data(PurpleWhiteboard *wb)
-{
-	PurpleWhiteboardPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), NULL);
-
-	priv = purple_whiteboard_get_instance_private(wb);
-	return priv->proto_data;
-}
-
-void purple_whiteboard_set_ui_data(PurpleWhiteboard *wb, gpointer ui_data)
-{
-	g_return_if_fail(PURPLE_IS_WHITEBOARD(wb));
-
-	wb->ui_data = ui_data;
-}
-
-gpointer purple_whiteboard_get_ui_data(PurpleWhiteboard *wb)
-{
-	g_return_val_if_fail(PURPLE_IS_WHITEBOARD(wb), NULL);
-
-	return wb->ui_data;
-}
-
-/******************************************************************************
- * GObject code
- *****************************************************************************/
-/* Set method for GObject properties */
-static void
-purple_whiteboard_set_property(GObject *obj, guint param_id, const GValue *value,
-		GParamSpec *pspec)
-{
-	PurpleWhiteboard *wb = PURPLE_WHITEBOARD(obj);
-	PurpleWhiteboardPrivate *priv =
-			purple_whiteboard_get_instance_private(wb);
-
-	switch (param_id) {
-		case PROP_STATE:
-			purple_whiteboard_set_state(wb, g_value_get_int(value));
-			break;
-		case PROP_ACCOUNT:
-			priv->account = g_value_get_object(value);
-			break;
-		case PROP_WHO:
-			priv->who = g_value_dup_string(value);
-			break;
-		case PROP_DRAW_LIST:
-			purple_whiteboard_set_draw_list(wb, g_value_get_pointer(value));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-/* Get method for GObject properties */
-static void
-purple_whiteboard_get_property(GObject *obj, guint param_id, GValue *value,
-		GParamSpec *pspec)
-{
-	PurpleWhiteboard *wb = PURPLE_WHITEBOARD(obj);
-
-	switch (param_id) {
-		case PROP_STATE:
-			g_value_set_int(value, purple_whiteboard_get_state(wb));
-			break;
-		case PROP_ACCOUNT:
-			g_value_set_object(value, purple_whiteboard_get_account(wb));
-			break;
-		case PROP_WHO:
-			g_value_set_string(value, purple_whiteboard_get_who(wb));
-			break;
-		case PROP_DRAW_LIST:
-			g_value_set_pointer(value, purple_whiteboard_get_draw_list(wb));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-static void
-purple_whiteboard_init(PurpleWhiteboard *wb)
-{
-}
-
-/* Called when done constructing */
-static void
-purple_whiteboard_constructed(GObject *object)
-{
-	PurpleWhiteboard *wb = PURPLE_WHITEBOARD(object);
-	PurpleWhiteboardPrivate *priv =
-			purple_whiteboard_get_instance_private(wb);
-	PurpleProtocol *protocol;
-
-	G_OBJECT_CLASS(purple_whiteboard_parent_class)->constructed(object);
-
-	protocol = purple_connection_get_protocol(
-				purple_account_get_connection(priv->account));
-	purple_whiteboard_set_protocol_ops(wb,
-				purple_protocol_get_whiteboard_ops(protocol));
-
-	/* Start up protocol specifics */
-	if(priv->protocol_ops && priv->protocol_ops->start)
-		priv->protocol_ops->start(wb);
-
-	wb_list = g_list_append(wb_list, wb);
-}
-
-/* GObject finalize function */
-static void
-purple_whiteboard_finalize(GObject *object)
-{
-	PurpleWhiteboard *wb = PURPLE_WHITEBOARD(object);
-	PurpleWhiteboardPrivate *priv =
-			purple_whiteboard_get_instance_private(wb);
-
-	if(wb->ui_data)
-	{
-		/* Destroy frontend */
-		if(whiteboard_ui_ops && whiteboard_ui_ops->destroy)
-			whiteboard_ui_ops->destroy(wb);
-	}
-
-	/* Do protocol specific session ending procedures */
-	if(priv->protocol_ops && priv->protocol_ops->end)
-		priv->protocol_ops->end(wb);
-
-	wb_list = g_list_remove(wb_list, wb);
-
-	g_free(priv->who);
-
-	G_OBJECT_CLASS(purple_whiteboard_parent_class)->finalize(object);
-}
-
-/* Class initializer function */
-static void
-purple_whiteboard_class_init(PurpleWhiteboardClass *klass)
-{
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
-	obj_class->finalize = purple_whiteboard_finalize;
-	obj_class->constructed = purple_whiteboard_constructed;
-
-	/* Setup properties */
-	obj_class->get_property = purple_whiteboard_get_property;
-	obj_class->set_property = purple_whiteboard_set_property;
-
-	properties[PROP_STATE] = g_param_spec_int("state", "State",
-				"State of the whiteboard.",
-				G_MININT, G_MAXINT, 0,
-				G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-	properties[PROP_ACCOUNT] = g_param_spec_object("account", "Account",
-				"The whiteboard's account.", PURPLE_TYPE_ACCOUNT,
-				G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
-				G_PARAM_STATIC_STRINGS);
-
-	properties[PROP_WHO] = g_param_spec_string("who", "Who",
-				"Who you're drawing with.", NULL,
-				G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
-				G_PARAM_STATIC_STRINGS);
-
-	properties[PROP_DRAW_LIST] = g_param_spec_pointer("draw-list", "Draw list",
-				"A list of points to draw to the buddy.",
-				G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
-	g_object_class_install_properties(obj_class, PROP_LAST, properties);
-}
-
-PurpleWhiteboard *purple_whiteboard_new(PurpleAccount *account, const char *who, int state)
-{
-	PurpleWhiteboard *wb;
-	PurpleProtocol *protocol;
-
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
-	g_return_val_if_fail(who != NULL, NULL);
-
-	protocol = purple_protocols_find(purple_account_get_protocol_id(account));
-
-	g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
-
-	if(PURPLE_IS_PROTOCOL_FACTORY(protocol)) {
-		wb = purple_protocol_factory_whiteboard_new(
-			PURPLE_PROTOCOL_FACTORY(protocol), account, who, state);
-	} else {
-		wb = g_object_new(PURPLE_TYPE_WHITEBOARD,
-			"account", account,
-			"who",     who,
-			"state",   state,
-			NULL
-		);
-	}
-
-	g_return_val_if_fail(wb != NULL, NULL);
-
-	return wb;
-}
--- a/libpurple/whiteboard.h	Tue Nov 10 03:01:09 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,424 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_WHITEBOARD_H
-#define PURPLE_WHITEBOARD_H
-
-/**
- * SECTION:whiteboard
- * @section_id: libpurple-whiteboard
- * @short_description: <filename>whiteboard.h</filename>
- * @title: Whiteboard Object
- *
- * The #PurpleWhiteboard API describes all interactions with whiteboards or
- * shared drawing spaces with other users.
- */
-
-/**
- * PURPLE_TYPE_WHITEBOARD:
- *
- * The standard _get_type macro for #PurpleWhiteboard.
- */
-#define PURPLE_TYPE_WHITEBOARD (purple_whiteboard_get_type())
-typedef struct _PurpleWhiteboard PurpleWhiteboard;
-
-/**
- * PURPLE_TYPE_WHITEBOARD_UI_OPS:
- *
- * The standard _get_type macro for #PurpleWhiteboardUiOps.
- */
-#define PURPLE_TYPE_WHITEBOARD_UI_OPS      (purple_whiteboard_ui_ops_get_type())
-
-typedef struct _PurpleWhiteboardUiOps PurpleWhiteboardUiOps;
-typedef struct _PurpleWhiteboardOps PurpleWhiteboardOps;
-
-#include "account.h"
-
-/**
- * PurpleWhiteboardUiOps:
- * @create:         create whiteboard
- * @destroy:        destory whiteboard
- * @set_dimensions: set whiteboard dimensions
- * @set_brush:      set the size and color of the brush
- * @draw_point:     draw a point
- * @draw_line:      draw a line
- * @clear:          clear whiteboard
- *
- * The PurpleWhiteboard UI Operations
- */
-struct _PurpleWhiteboardUiOps
-{
-	void (*create)(PurpleWhiteboard *wb);
-	void (*destroy)(PurpleWhiteboard *wb);
-	void (*set_dimensions)(PurpleWhiteboard *wb, int width, int height);
-	void (*set_brush) (PurpleWhiteboard *wb, int size, int color);
-	void (*draw_point)(PurpleWhiteboard *wb, int x, int y,
-	                   int color, int size);
-	void (*draw_line)(PurpleWhiteboard *wb, int x1, int y1,
-	                  int x2, int y2,
-	                  int color, int size);
-	void (*clear)(PurpleWhiteboard *wb);
-
-	/*< private >*/
-	void (*_purple_reserved1)(void);
-	void (*_purple_reserved2)(void);
-	void (*_purple_reserved3)(void);
-	void (*_purple_reserved4)(void);
-};
-
-/**
- * PurpleWhiteboardOps:
- * @start:          start function
- * @end:            end function
- * @get_dimensions: get whiteboard dimensions
- * @set_dimensions: set whiteboard dimensions
- * @get_brush:      get the brush size and color
- * @set_brush:      set the brush size and color
- * @send_draw_list: send_draw_list function
- * @clear:          clear whiteboard
- *
- * Whiteboard protocol operations
- */
-struct _PurpleWhiteboardOps
-{
-	void (*start)(PurpleWhiteboard *wb);
-	void (*end)(PurpleWhiteboard *wb);
-	void (*get_dimensions)(const PurpleWhiteboard *wb, int *width, int *height);
-	void (*set_dimensions)(PurpleWhiteboard *wb, int width, int height);
-	void (*get_brush) (const PurpleWhiteboard *wb, int *size, int *color);
-	void (*set_brush) (PurpleWhiteboard *wb, int size, int color);
-	void (*send_draw_list)(PurpleWhiteboard *wb, GList *draw_list);
-	void (*clear)(PurpleWhiteboard *wb);
-
-	/*< private >*/
-	void (*_purple_reserved1)(void);
-	void (*_purple_reserved2)(void);
-	void (*_purple_reserved3)(void);
-	void (*_purple_reserved4)(void);
-};
-
-/**
- * PurpleWhiteboard:
- * @ui_data: The UI data associated with this whiteboard. This is a convenience
- *           field provided to the UIs -- it is not used by the libpurple core.
- *
- * A Whiteboard
- */
-struct _PurpleWhiteboard
-{
-	GObject gparent;
-
-	/*< public >*/
-	gpointer ui_data;
-};
-
-G_BEGIN_DECLS
-
-/******************************************************************************/
-/* PurpleWhiteboard API                                                       */
-/******************************************************************************/
-
-/**
- * purple_whiteboard_get_type:
- *
- * The standard _get_type function for #PurpleWhiteboard.
- *
- * Returns: The #GType for the #PurpleWhiteboard object.
- */
-G_DECLARE_FINAL_TYPE(PurpleWhiteboard, purple_whiteboard, PURPLE, WHITEBOARD,
-                     GObject)
-
-/**
- * purple_whiteboard_ui_ops_get_type:
- *
- * The standard _get_type function for #PurpleWhiteboardUiOps.
- *
- * Returns: The #GType for the #PurpleWhiteboardUiOps boxed structure.
- */
-GType purple_whiteboard_ui_ops_get_type(void);
-
-/**
- * purple_whiteboard_set_ui_ops:
- * @ops: The UI operations to set
- *
- * Sets the UI operations
- */
-void purple_whiteboard_set_ui_ops(PurpleWhiteboardUiOps *ops);
-
-/**
- * purple_whiteboard_set_protocol_ops:
- * @wb:  The whiteboard for which to set the protocol operations
- * @ops: The protocol operations to set
- *
- * Sets the protocol operations for a whiteboard
- */
-void purple_whiteboard_set_protocol_ops(PurpleWhiteboard *wb, PurpleWhiteboardOps *ops);
-
-/**
- * purple_whiteboard_new:
- * @account: The account.
- * @who:     Who you're drawing with.
- * @state:   The state.
- *
- * Creates a new whiteboard
- *
- * Returns: The new whiteboard
- */
-PurpleWhiteboard *purple_whiteboard_new(PurpleAccount *account, const char *who, int state);
-
-/**
- * purple_whiteboard_get_account:
- * @wb: The whiteboard.
- *
- * Returns the whiteboard's account.
- *
- * Returns: (transfer none): The whiteboard's account.
- */
-PurpleAccount *purple_whiteboard_get_account(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_get_who:
- * @wb: The whiteboard
- *
- * Return who you're drawing with.
- *
- * Returns: Who you're drawing with.
- */
-const char *purple_whiteboard_get_who(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_set_state:
- * @wb:    The whiteboard.
- * @state: The state
- *
- * Set the state of the whiteboard.
- */
-void purple_whiteboard_set_state(PurpleWhiteboard *wb, int state);
-
-/**
- * purple_whiteboard_get_state:
- * @wb: The whiteboard.
- *
- * Return the state of the whiteboard.
- *
- * Returns: The state of the whiteboard.
- */
-int purple_whiteboard_get_state(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_start:
- * @wb: The whiteboard.
- *
- * Starts a whiteboard
- */
-void purple_whiteboard_start(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_get_session:
- * @account: The account.
- * @who:     The user.
- *
- * Finds a whiteboard from an account and user.
- *
- * Returns: (transfer none): The whiteboard if found, otherwise %NULL.
- */
-PurpleWhiteboard *purple_whiteboard_get_session(const PurpleAccount *account, const char *who);
-
-/**
- * purple_whiteboard_draw_list_destroy:
- * @draw_list: (element-type gint): The drawing list.
- *
- * Destorys a drawing list for a whiteboard
- */
-void purple_whiteboard_draw_list_destroy(GList *draw_list);
-
-/**
- * purple_whiteboard_get_dimensions:
- * @wb:     The whiteboard.
- * @width:  The width to be set.
- * @height: The height to be set.
- *
- * Gets the dimension of a whiteboard.
- *
- * Returns: TRUE if the values of width and height were set.
- */
-gboolean purple_whiteboard_get_dimensions(PurpleWhiteboard *wb, int *width, int *height);
-
-/**
- * purple_whiteboard_set_dimensions:
- * @wb:     The whiteboard.
- * @width:  The width.
- * @height: The height.
- *
- * Sets the dimensions for a whiteboard.
- */
-void purple_whiteboard_set_dimensions(PurpleWhiteboard *wb, int width, int height);
-
-/**
- * purple_whiteboard_draw_point:
- * @wb:    The whiteboard.
- * @x:     The x coordinate.
- * @y:     The y coordinate.
- * @color: The color to use.
- * @size:  The brush size.
- *
- * Draws a point on a whiteboard.
- */
-void purple_whiteboard_draw_point(PurpleWhiteboard *wb, int x, int y, int color, int size);
-
-/**
- * purple_whiteboard_send_draw_list:
- * @wb:                        The whiteboard
- * @list: (element-type gint): A GList of points
- *
- * Send a list of points to draw to the buddy.
- */
-void purple_whiteboard_send_draw_list(PurpleWhiteboard *wb, GList *list);
-
-/**
- * purple_whiteboard_draw_line:
- * @wb:    The whiteboard.
- * @x1:    The top-left x coordinate.
- * @y1:    The top-left y coordinate.
- * @x2:    The bottom-right x coordinate.
- * @y2:    The bottom-right y coordinate.
- * @color: The color to use.
- * @size:  The brush size.
- *
- * Draws a line on a whiteboard
- */
-void purple_whiteboard_draw_line(PurpleWhiteboard *wb, int x1, int y1, int x2, int y2, int color, int size);
-
-/**
- * purple_whiteboard_clear:
- * @wb: The whiteboard.
- *
- * Clears a whiteboard
- */
-void purple_whiteboard_clear(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_send_clear:
- * @wb: The whiteboard
- *
- * Sends a request to the buddy to clear the whiteboard.
- */
-void purple_whiteboard_send_clear(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_send_brush:
- * @wb:    The whiteboard
- * @size:  The size of the brush
- * @color: The color of the brush
- *
- * Sends a request to change the size and color of the brush.
- */
-void purple_whiteboard_send_brush(PurpleWhiteboard *wb, int size, int color);
-
-/**
- * purple_whiteboard_get_brush:
- * @wb:    The whiteboard
- * @size:  The size of the brush
- * @color: The color of the brush
- *
- * Gets the size and color of the brush.
- *
- * Returns:	TRUE if the size and color were set.
- */
-gboolean purple_whiteboard_get_brush(PurpleWhiteboard *wb, int *size, int *color);
-
-/**
- * purple_whiteboard_set_brush:
- * @wb:    The whiteboard
- * @size:  The size of the brush
- * @color: The color of the brush
- *
- * Sets the size and color of the brush.
- */
-void purple_whiteboard_set_brush(PurpleWhiteboard *wb, int size, int color);
-
-/**
- * purple_whiteboard_get_draw_list:
- * @wb: The whiteboard.
- *
- * Return the drawing list.
- *
- * Returns: (transfer none) (element-type gint): The drawing list
- */
-GList *purple_whiteboard_get_draw_list(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_set_draw_list:
- * @wb:                             The whiteboard
- * @draw_list: (element-type gint): The drawing list.
- *
- * Set the drawing list.
- */
-void purple_whiteboard_set_draw_list(PurpleWhiteboard *wb, GList* draw_list);
-
-/**
- * purple_whiteboard_set_protocol_data:
- * @wb:         The whiteboard.
- * @proto_data: The protocol data to set for the whiteboard.
- *
- * Sets the protocol data for a whiteboard.
- */
-void purple_whiteboard_set_protocol_data(PurpleWhiteboard *wb, gpointer proto_data);
-
-/**
- * purple_whiteboard_get_protocol_data:
- * @wb: The whiteboard.
- *
- * Gets the protocol data for a whiteboard.
- *
- * Returns: The protocol data for the whiteboard.
- */
-gpointer purple_whiteboard_get_protocol_data(PurpleWhiteboard *wb);
-
-/**
- * purple_whiteboard_set_ui_data:
- * @wb:      The whiteboard.
- * @ui_data: A pointer to associate with this whiteboard.
- *
- * Set the UI data associated with this whiteboard.
- */
-void purple_whiteboard_set_ui_data(PurpleWhiteboard *wb, gpointer ui_data);
-
-/**
- * purple_whiteboard_get_ui_data:
- * @wb: The whiteboard..
- *
- * Get the UI data associated with this whiteboard.
- *
- * Returns: The UI data associated with this whiteboard.  This is a
- *         convenience field provided to the UIs--it is not
- *         used by the libpurple core.
- */
-gpointer purple_whiteboard_get_ui_data(PurpleWhiteboard *wb);
-
-G_END_DECLS
-
-#endif /* PURPLE_WHITEBOARD_H */
--- a/po/POTFILES.in	Tue Nov 10 03:01:09 2020 -0600
+++ b/po/POTFILES.in	Tue Nov 10 03:30:53 2020 -0600
@@ -265,6 +265,8 @@
 libpurple/purpleprotocolim.c
 libpurple/purpleprotocolmedia.c
 libpurple/purpleprotocolprivacy.c
+libpurple/purplewhiteboard.c
+libpurple/purplewhiteboarduiops.c
 libpurple/queuedoutputstream.c
 libpurple/request.c
 libpurple/request-datasheet.c
@@ -298,7 +300,6 @@
 libpurple/upnp.c
 libpurple/util.c
 libpurple/version.c
-libpurple/whiteboard.c
 libpurple/win32/libc_interface.c
 libpurple/win32/win32dep.c
 libpurple/xfer.c

mercurial