From 30e3d6eefdae5382fa35e91a0614c6b6bccdaab4 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Sun, 27 Jun 2021 20:42:37 -0500 Subject: [PATCH] (purple) Handle own status changes --- protocols/purple/PurpleApp.cpp | 102 ++++++++++++++++++++++++++-- protocols/purple/PurpleApp.h | 19 ++++++ protocols/purple/PurpleProtocol.cpp | 6 +- 3 files changed, 122 insertions(+), 5 deletions(-) diff --git a/protocols/purple/PurpleApp.cpp b/protocols/purple/PurpleApp.cpp index b4eaba7..08bafbb 100644 --- a/protocols/purple/PurpleApp.cpp +++ b/protocols/purple/PurpleApp.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -63,6 +64,9 @@ PurpleApp::MessageReceived(BMessage* msg) { switch (msg->what) { + case IM_MESSAGE: + ImMessage(msg); + break; case PURPLE_REQUEST_PROTOCOL_COUNT: { int64 thread_id; @@ -132,6 +136,28 @@ PurpleApp::MessageReceived(BMessage* msg) } +void +PurpleApp::ImMessage(BMessage* msg) +{ + switch (msg->FindInt32("im_what")) + { + case IM_SET_OWN_STATUS: + { + PurpleAccount* account = _AccountFromMessage(msg); + UserStatus status = (UserStatus)msg->FindInt32("status"); + PurpleStatusPrimitive prim = cardie_status_to_purple(status); + const char* primId = purple_primitive_get_id_from_type(prim); + + std::cout << "setting status to " << primId << "…\n"; + purple_account_set_status(account, primId, true); + break; + } + default: + msg->PrintToStream(); + } +} + + void PurpleApp::SendMessage(thread_id thread, BMessage msg) { @@ -425,10 +451,14 @@ void init_signals() { int handle; - purple_signal_connect(purple_connections_get_handle(), "signed-on", &handle, - PURPLE_CALLBACK(signal_signed_on), NULL); - purple_signal_connect(purple_connections_get_handle(), "connection-error", &handle, - PURPLE_CALLBACK(signal_connection_error), NULL); + + purple_signal_connect(purple_connections_get_handle(), "signed-on", + &handle, PURPLE_CALLBACK(signal_signed_on), NULL); + purple_signal_connect(purple_connections_get_handle(), "connection-error", + &handle, PURPLE_CALLBACK(signal_connection_error), NULL); + + purple_signal_connect(purple_connections_get_handle(), "account-status-changed", + &handle, PURPLE_CALLBACK(signal_account_status_changed), NULL); } @@ -451,6 +481,70 @@ signal_connection_error(PurpleConnection* gc, PurpleConnectionError err, } +static void +signal_account_status_changed(PurpleAccount* account, PurpleStatus* old, + PurpleStatus* cur) +{ + BMessage own(IM_MESSAGE); + own.AddInt32("im_what", IM_OWN_STATUS_SET); + own.AddInt32("status", purple_status_to_cardie(cur)); + ((PurpleApp*)be_app)->SendMessage(account, own); +} + + +PurpleStatusPrimitive +cardie_status_to_purple(UserStatus status) +{ + PurpleStatusPrimitive type = PURPLE_STATUS_UNSET; + switch (status) + { + case STATUS_ONLINE: + type = PURPLE_STATUS_AVAILABLE; + break; + case STATUS_AWAY: + type = PURPLE_STATUS_AWAY; + break; + case STATUS_DO_NOT_DISTURB: + type = PURPLE_STATUS_UNAVAILABLE; + break; + case STATUS_CUSTOM_STATUS: + type = PURPLE_STATUS_AVAILABLE; + break; + case STATUS_INVISIBLE: + type = PURPLE_STATUS_INVISIBLE; + break; + case STATUS_OFFLINE: + type = PURPLE_STATUS_OFFLINE; + break; + } + + return type; +} + + +UserStatus +purple_status_to_cardie(PurpleStatus* status) +{ + PurpleStatusPrimitive prim = + purple_status_type_get_primitive(purple_status_get_type(status)); + + switch (prim) + { + case PURPLE_STATUS_AWAY: + return STATUS_AWAY; + case PURPLE_STATUS_UNAVAILABLE: + return STATUS_DO_NOT_DISTURB; + break; + case PURPLE_STATUS_INVISIBLE: + return STATUS_INVISIBLE; + break; + case PURPLE_STATUS_OFFLINE: + return STATUS_OFFLINE; + } + return STATUS_ONLINE; +} + + static guint _purple_glib_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function, gpointer data) { diff --git a/protocols/purple/PurpleApp.h b/protocols/purple/PurpleApp.h index 462cc97..ef9c2e4 100644 --- a/protocols/purple/PurpleApp.h +++ b/protocols/purple/PurpleApp.h @@ -28,6 +28,7 @@ #include #include +#include typedef KeyMap Accounts; // Cardie username → Purple username @@ -48,6 +49,15 @@ typedef struct _PurpleGLibIOClosure { gpointer data; } PurpleGLibIOClosure; +struct _PurpleStatus +{ + PurpleStatusType *type; + PurplePresence *presence; + + gboolean active; + GHashTable *attr_values; +}; + typedef struct _ProtocolInfo { BString name; BString id; @@ -63,6 +73,8 @@ public: PurpleApp(); virtual void MessageReceived(BMessage* msg); + void ImMessage(BMessage* msg); + void SendMessage(thread_id thread, BMessage msg); void SendMessage(PurpleAccount* account, BMessage msg); @@ -93,6 +105,13 @@ static void signal_signed_on(PurpleConnection* gc); static void signal_connection_error(PurpleConnection* gc, PurpleConnectionError err, const gchar* desc); +// Account signals +static void signal_account_status_changed(PurpleAccount* account, + PurpleStatus* old, PurpleStatus* cur); + +PurpleStatusPrimitive cardie_status_to_purple(UserStatus status); +UserStatus purple_status_to_cardie(PurpleStatus* status); + static guint _purple_glib_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function, gpointer data); static gboolean _purple_glib_io_invoke(GIOChannel *source, diff --git a/protocols/purple/PurpleProtocol.cpp b/protocols/purple/PurpleProtocol.cpp index da9e025..97dc97e 100644 --- a/protocols/purple/PurpleProtocol.cpp +++ b/protocols/purple/PurpleProtocol.cpp @@ -174,7 +174,11 @@ PurpleProtocol::Shutdown() status_t PurpleProtocol::Process(BMessage* msg) { - return B_OK; + if (msg->what == IM_MESSAGE) { + _SendPrplMessage(msg); + return B_OK; + } + return B_ERROR; }