summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--finch/finchui.c (renamed from finch/gntui.c)92
-rw-r--r--finch/finchui.h (renamed from finch/gntui.h)27
-rw-r--r--finch/libfinch.c45
-rw-r--r--finch/meson.build4
-rw-r--r--libpurple/core.c57
-rw-r--r--libpurple/core.h31
-rw-r--r--libpurple/meson.build6
-rw-r--r--libpurple/plugins/kwallet/purplekwallet.cpp8
-rw-r--r--libpurple/protocols/jabber/bosh.c8
-rw-r--r--libpurple/protocols/jabber/iq.c10
-rw-r--r--libpurple/protocols/jabber/jabber.c8
-rw-r--r--libpurple/purplecoreuiops.c48
-rw-r--r--libpurple/purplecoreuiops.h75
-rw-r--r--libpurple/purplepath.c6
-rw-r--r--libpurple/purpleui.c425
-rw-r--r--libpurple/purpleui.h201
-rw-r--r--libpurple/purpleuiinfo.c326
-rw-r--r--libpurple/purpleuiinfo.h143
-rw-r--r--libpurple/tests/test_ui.c59
-rw-r--r--pidgin/gtkconv.h2
-rw-r--r--pidgin/libpidgin.c194
-rw-r--r--pidgin/meson.build2
-rw-r--r--pidgin/pidginapplication.c12
-rw-r--r--pidgin/pidgincore.h12
-rw-r--r--pidgin/pidginui.c263
-rw-r--r--pidgin/pidginui.h60
-rw-r--r--po/POTFILES.in3
27 files changed, 1145 insertions, 982 deletions
diff --git a/finch/gntui.c b/finch/finchui.c
index f0f15a1563..f4af9330fd 100644
--- a/finch/gntui.c
+++ b/finch/finchui.c
@@ -1,5 +1,6 @@
/*
- * finch
+ * Finch - Universal Text Chat Client
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
*
* Finch is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
@@ -16,17 +17,16 @@
* 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/>.
*/
-#include <config.h>
+#include <glib.h>
+#include <glib/gi18n.h>
-#include <glib/gi18n-lib.h>
+#define G_SETTINGS_ENABLE_BACKEND
+#include <gio/gsettingsbackend.h>
-#include <purple.h>
-
-#include "gntui.h"
+#include "finchui.h"
#include "finchnotifications.h"
#include "gntaccount.h"
@@ -34,15 +34,25 @@
#include "gntconn.h"
#include "gntconv.h"
#include "gntdebug.h"
-#include "gntxfer.h"
#include "gntmedia.h"
#include "gntnotify.h"
#include "gntplugin.h"
#include "gntprefs.h"
+#include "gntprefs.h"
#include "gntrequest.h"
#include "gntroomlist.h"
#include "gntstatus.h"
+#include "gntxfer.h"
+
+struct _FinchUi {
+ PurpleUi parent;
+};
+G_DEFINE_TYPE(FinchUi, finch_ui, PURPLE_TYPE_UI)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
static gboolean
finch_history_init(GError **error) {
PurpleHistoryManager *manager = NULL;
@@ -74,9 +84,16 @@ finch_history_init(GError **error) {
return purple_history_manager_set_active(manager, id, error);
}
-void
-finch_ui_init(void)
-{
+/******************************************************************************
+ * PurpleUi Implementation
+ *****************************************************************************/
+static void
+finch_ui_prefs_init(G_GNUC_UNUSED PurpleUi *ui) {
+ finch_prefs_init();
+}
+
+static void
+finch_ui_start(G_GNUC_UNUSED PurpleUi *ui) {
GError *error = NULL;
finch_debug_init();
@@ -144,9 +161,8 @@ finch_ui_init(void)
#ifdef STANDALONE
}
-void
-finch_ui_uninit(void)
-{
+static void
+finch_ui_stop(G_GNUC_UNUSED PurpleUi *ui) {
purple_accounts_set_ui_ops(NULL);
finch_accounts_uninit();
@@ -182,3 +198,49 @@ finch_ui_uninit(void)
#endif /* _WIN32 */
#endif /* STANDALONE */
}
+
+static gpointer
+finch_ui_get_settings_backend(G_GNUC_UNUSED PurpleUi *ui) {
+ GSettingsBackend *backend = NULL;
+ char *config = NULL;
+
+ config = g_build_filename(purple_config_dir(), "finch3.ini", NULL);
+ backend = g_keyfile_settings_backend_new(config, "/", NULL);
+
+ g_free(config);
+
+ return backend;
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+finch_ui_init(G_GNUC_UNUSED FinchUi *ui) {
+}
+
+static void
+finch_ui_class_init(FinchUiClass *klass) {
+ PurpleUiClass *ui_class = PURPLE_UI_CLASS(klass);
+
+ ui_class->prefs_init = finch_ui_prefs_init;
+ ui_class->start = finch_ui_start;
+ ui_class->stop = finch_ui_stop;
+ ui_class->get_settings_backend = finch_ui_get_settings_backend;
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleUi *
+finch_ui_new(void) {
+ return g_object_new(
+ FINCH_TYPE_UI,
+ "id", "finch3",
+ "name", _("Finch"),
+ "version", VERSION,
+ "website", "https://pidgin.im",
+ "support-website", "https://pidgin.im/contact/",
+ "client-type", "console",
+ NULL);
+}
diff --git a/finch/gntui.h b/finch/finchui.h
index 36597cae56..4913707067 100644
--- a/finch/gntui.h
+++ b/finch/finchui.h
@@ -1,5 +1,6 @@
/*
- * finch
+ * Finch - Universal Text Chat Client
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
*
* Finch is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
@@ -16,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(FINCH_GLOBAL_HEADER_INSIDE) && !defined(FINCH_COMPILATION)
@@ -27,10 +27,25 @@
#ifndef FINCH_UI_H
#define FINCH_UI_H
-#include "gnt.h"
+#include <purple.h>
-void finch_ui_init(void);
-void finch_ui_uninit(void);
+G_BEGIN_DECLS
+
+#define FINCH_TYPE_UI (finch_ui_get_type())
+G_DECLARE_FINAL_TYPE(FinchUi, finch_ui, FINCH, UI, PurpleUi)
+
+/**
+ * finch_ui_new:
+ *
+ * Creates the [class@Purple.Ui] for finch.
+ *
+ * Note: This isn't really useful outside of Finch itself.
+ *
+ * Since: 3.0.0
+ */
+PurpleUi *finch_ui_new(void);
+
+G_END_DECLS
#endif /* FINCH_UI_H */
diff --git a/finch/libfinch.c b/finch/libfinch.c
index 191a9eb9e4..d978d34289 100644
--- a/finch/libfinch.c
+++ b/finch/libfinch.c
@@ -26,54 +26,19 @@
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
-#define G_SETTINGS_ENABLE_BACKEND
-#include <gio/gsettingsbackend.h>
-
#include <locale.h>
#include <purple.h>
+#include "finchui.h"
#include "gntdebug.h"
#include "gntidle.h"
#include "gntprefs.h"
-#include "gntui.h"
#include "libfinch.h"
#include "config.h"
#include "package_revision.h"
-static void
-finch_quit(void)
-{
- finch_ui_uninit();
-}
-
-static gpointer
-finch_get_settings_backend(void) {
- GSettingsBackend *backend = NULL;
- char *config = NULL;
-
- config = g_build_filename(purple_config_dir(), "finch3.ini", NULL);
- backend = g_keyfile_settings_backend_new(config, "/", NULL);
-
- g_free(config);
-
- return backend;
-}
-
-static PurpleCoreUiOps core_ops = {
- .ui_prefs_init = finch_prefs_init,
- .ui_init = finch_ui_init,
- .quit = finch_quit,
- .get_settings_backend = finch_get_settings_backend,
-};
-
-static PurpleCoreUiOps *
-gnt_core_get_ui_ops(void)
-{
- return &core_ops;
-}
-
static gboolean
start_with_debugwin(gpointer null)
{
@@ -106,7 +71,6 @@ finch_plugins_init(void) {
static int
init_libpurple(int argc, char **argv)
{
- PurpleUiInfo *ui_info = NULL;
gboolean opt_nologin = FALSE;
gboolean opt_version = FALSE;
gboolean opt_debug = FALSE;
@@ -196,14 +160,9 @@ init_libpurple(int argc, char **argv)
g_timeout_add(0, start_with_debugwin, NULL);
}
- purple_core_set_ui_ops(gnt_core_get_ui_ops());
purple_idle_set_ui(finch_idle_new());
- ui_info = purple_ui_info_new("finch3", _("Finch"), VERSION,
- "https://pidgin.im",
- "https://developer.pidgin.im", "console");
-
- if (!purple_core_init(ui_info))
+ if (!purple_core_init(finch_ui_new()))
{
fprintf(stderr,
"Initialization of the Purple core failed. Dumping core.\n"
diff --git a/finch/meson.build b/finch/meson.build
index e6b7bcca12..56d5af6ab6 100644
--- a/finch/meson.build
+++ b/finch/meson.build
@@ -79,6 +79,7 @@ enable_consoleui = true
libfinch_SOURCES = [
'finchnotifications.c',
+ 'finchui.c',
'gntaccount.c',
'gntblist.c',
'gntconn.c',
@@ -93,7 +94,6 @@ libfinch_SOURCES = [
'gntrequest.c',
'gntroomlist.c',
'gntstatus.c',
- 'gntui.c',
'gntxfer.c',
package_revision,
'libfinch.c'
@@ -101,6 +101,7 @@ libfinch_SOURCES = [
libfinch_headers = [
'finchnotifications.h',
+ 'finchui.h',
'gntaccount.h',
'gntblist.h',
'gntconn.h',
@@ -115,7 +116,6 @@ libfinch_headers = [
'gntrequest.h',
'gntroomlist.h',
'gntstatus.h',
- 'gntui.h',
'gntxfer.h',
'libfinch.h'
]
diff --git a/libpurple/core.c b/libpurple/core.c
index b13e719730..f665a0b989 100644
--- a/libpurple/core.c
+++ b/libpurple/core.c
@@ -54,26 +54,25 @@
struct PurpleCore
{
- PurpleUiInfo *ui_info;
+ PurpleUi *ui;
void *reserved;
};
-static PurpleCoreUiOps *_ops = NULL;
static PurpleCore *_core = NULL;
static GSettingsBackend *settings_backend = NULL;
static void
purple_core_print_version(void)
{
- PurpleUiInfo *ui_info = purple_core_get_ui_info();
+ PurpleUi *ui = purple_core_get_ui();
const gchar *ui_name = NULL;
const gchar *ui_version = NULL;
gchar *ui_full_name = NULL;
- if(PURPLE_IS_UI_INFO(ui_info)) {
- ui_name = purple_ui_info_get_name(ui_info);
- ui_version = purple_ui_info_get_version(ui_info);
+ if(PURPLE_IS_UI(ui)) {
+ ui_name = purple_ui_get_name(ui);
+ ui_version = purple_ui_get_version(ui);
}
if (ui_name) {
@@ -93,11 +92,10 @@ purple_core_print_version(void)
}
gboolean
-purple_core_init(PurpleUiInfo *ui_info) {
- PurpleCoreUiOps *ops;
+purple_core_init(PurpleUi *ui) {
PurpleCore *core;
- g_return_val_if_fail(PURPLE_IS_UI_INFO(ui_info), FALSE);
+ g_return_val_if_fail(PURPLE_IS_UI(ui), FALSE);
g_return_val_if_fail(purple_get_core() == NULL, FALSE);
bindtextdomain(PACKAGE, PURPLE_LOCALEDIR);
@@ -107,11 +105,9 @@ purple_core_init(PurpleUiInfo *ui_info) {
#endif
_core = core = g_new0(PurpleCore, 1);
- core->ui_info = ui_info;
+ core->ui = ui;
core->reserved = NULL;
- ops = purple_core_get_ui_ops();
-
/* This monster is to work around a bug that was fixed in glib 2.73.3. Once
* we require glib 2.74.0 this should be removed.
*/
@@ -143,15 +139,12 @@ purple_core_init(PurpleUiInfo *ui_info) {
/* The prefs subsystem needs to be initialized before static protocols
* for protocol prefs to work. */
purple_prefs_init();
- settings_backend = ops->get_settings_backend();
+
+ settings_backend = purple_ui_get_settings_backend(core->ui);
purple_debug_init();
- if (ops != NULL) {
- if (ops->ui_prefs_init != NULL) {
- ops->ui_prefs_init();
- }
- }
+ purple_ui_prefs_init(core->ui);
purple_notification_manager_startup();
@@ -197,8 +190,7 @@ purple_core_init(PurpleUiInfo *ui_info) {
*/
purple_network_discover_my_ip();
- if (ops != NULL && ops->ui_init != NULL)
- ops->ui_init();
+ purple_ui_start(core->ui);
/* Load the buddy list after UI init */
purple_blist_boot();
@@ -211,7 +203,6 @@ purple_core_init(PurpleUiInfo *ui_info) {
void
purple_core_quit(void)
{
- PurpleCoreUiOps *ops;
PurpleCore *core = purple_get_core();
PurpleCredentialManager *credential_manager = NULL;
PurpleHistoryManager *history_manager = NULL;
@@ -249,9 +240,7 @@ purple_core_quit(void)
_purple_image_store_uninit();
purple_network_uninit();
- ops = purple_core_get_ui_ops();
- if (ops != NULL && ops->quit != NULL)
- ops->quit();
+ purple_ui_stop(core->ui);
/* Everything after prefs_uninit must not try to read any prefs */
g_clear_object(&settings_backend);
@@ -275,7 +264,7 @@ purple_core_quit(void)
purple_signals_uninit();
- g_clear_object(&core->ui_info);
+ g_clear_object(&core->ui);
g_free(core);
#ifdef _WIN32
@@ -310,19 +299,7 @@ purple_core_get_settings_backend(void) {
return settings_backend;
}
-void
-purple_core_set_ui_ops(PurpleCoreUiOps *ops)
-{
- _ops = ops;
-}
-
-PurpleCoreUiOps *
-purple_core_get_ui_ops(void)
-{
- return _ops;
-}
-
-PurpleUiInfo *
-purple_core_get_ui_info(void) {
- return _core->ui_info;
+PurpleUi *
+purple_core_get_ui(void) {
+ return _core->ui;
}
diff --git a/libpurple/core.h b/libpurple/core.h
index 5f1ca11f65..514c5219ea 100644
--- a/libpurple/core.h
+++ b/libpurple/core.h
@@ -29,7 +29,7 @@
#include <glib.h>
#include <glib-object.h>
-#include <libpurple/purplecoreuiops.h>
+#include <libpurple/purpleui.h>
typedef struct PurpleCore PurpleCore;
@@ -37,7 +37,7 @@ G_BEGIN_DECLS
/**
* purple_core_init:
- * @ui_info: (transfer full): The [class@UiInfo] of the UI using the core.
+ * @ui: (transfer full): The [class@Purple.Ui] of the UI using the core.
*
* Initializes the core of purple.
*
@@ -45,7 +45,7 @@ G_BEGIN_DECLS
*
* Returns: %TRUE if successful, or %FALSE otherwise.
*/
-gboolean purple_core_init(PurpleUiInfo *ui_info);
+gboolean purple_core_init(PurpleUi *ui);
/**
* purple_core_quit:
@@ -112,30 +112,13 @@ PurpleCore *purple_get_core(void);
gpointer purple_core_get_settings_backend(void);
/**
- * purple_core_set_ui_ops:
- * @ops: A UI ops structure for the core.
+ * purple_core_get_ui:
*
- * Sets the UI ops for the core.
- */
-void purple_core_set_ui_ops(PurpleCoreUiOps *ops);
-
-/**
- * purple_core_get_ui_ops:
- *
- * Returns the UI ops for the core.
- *
- * Returns: The core's UI ops structure.
- */
-PurpleCoreUiOps *purple_core_get_ui_ops(void);
-
-/**
- * purple_core_get_ui_info:
- *
- * Returns a #PurpleUiInfo that contains information about the user interface.
+ * Gets the [class@Purple.Ui] that is running.
*
- * Returns: (transfer none): A #PurpleUiInfo instance.
+ * Returns: (transfer none): The ui.
*/
-PurpleUiInfo *purple_core_get_ui_info(void);
+PurpleUi *purple_core_get_ui(void);
G_END_DECLS
diff --git a/libpurple/meson.build b/libpurple/meson.build
index 592b09cb41..9c2df2169b 100644
--- a/libpurple/meson.build
+++ b/libpurple/meson.build
@@ -50,7 +50,6 @@ purple_coresources = [
'purpleconversation.c',
'purpleconversationmanager.c',
'purpleconversationuiops.c',
- 'purplecoreuiops.c',
'purplecredentialmanager.c',
'purplecredentialprovider.c',
'purpledebugui.c',
@@ -88,7 +87,7 @@ purple_coresources = [
'purplesqlite3.c',
'purplesqlitehistoryadapter.c',
'purpletags.c',
- 'purpleuiinfo.c',
+ 'purpleui.c',
'purplewhiteboard.c',
'purplewhiteboardmanager.c',
'purplewhiteboarduiops.c',
@@ -155,7 +154,6 @@ purple_coreheaders = [
'purpleconversation.h',
'purpleconversationmanager.h',
'purpleconversationuiops.h',
- 'purplecoreuiops.h',
'purplecredentialmanager.h',
'purplecredentialprovider.h',
'purpledebugui.h',
@@ -194,7 +192,7 @@ purple_coreheaders = [
'purplesqlite3.h',
'purplesqlitehistoryadapter.h',
'purpletags.h',
- 'purpleuiinfo.h',
+ 'purpleui.h',
'purplewhiteboard.h',
'purplewhiteboardmanager.h',
'purplewhiteboardops.h',
diff --git a/libpurple/plugins/kwallet/purplekwallet.cpp b/libpurple/plugins/kwallet/purplekwallet.cpp
index e00fb00a8f..7ae63230c6 100644
--- a/libpurple/plugins/kwallet/purplekwallet.cpp
+++ b/libpurple/plugins/kwallet/purplekwallet.cpp
@@ -53,12 +53,12 @@ G_DEFINE_DYNAMIC_TYPE(PurpleKWalletProvider, purple_kwallet_provider,
*****************************************************************************/
static QString
purple_kwallet_get_ui_name(void) {
- PurpleUiInfo *ui_info = NULL;
+ PurpleUi *ui = NULL;
QString ui_name = NULL;
- ui_info = purple_core_get_ui_info();
- if(PURPLE_IS_UI_INFO(ui_info)) {
- ui_name = purple_ui_info_get_name(ui_info);
+ ui = purple_core_get_ui();
+ if(PURPLE_IS_UI(ui)) {
+ ui_name = purple_ui_get_name(ui);
}
if(ui_name.isEmpty()) {
diff --git a/libpurple/protocols/jabber/bosh.c b/libpurple/protocols/jabber/bosh.c
index 83e04df988..15f4c5cb6e 100644
--- a/libpurple/protocols/jabber/bosh.c
+++ b/libpurple/protocols/jabber/bosh.c
@@ -65,13 +65,13 @@ jabber_bosh_connection_send_now(PurpleJabberBOSHConnection *conn);
void
jabber_bosh_init(void)
{
- PurpleUiInfo *ui_info = purple_core_get_ui_info();
+ PurpleUi *ui = purple_core_get_ui();
const gchar *ui_name = NULL;
const gchar *ui_version = NULL;
- if(PURPLE_IS_UI_INFO(ui_info)) {
- ui_name = purple_ui_info_get_name(ui_info);
- ui_version = purple_ui_info_get_version(ui_info);
+ if(PURPLE_IS_UI(ui)) {
+ ui_name = purple_ui_get_name(ui);
+ ui_version = purple_ui_get_version(ui);
}
if(ui_name) {
diff --git a/libpurple/protocols/jabber/iq.c b/libpurple/protocols/jabber/iq.c
index 184819016d..a87105b3e8 100644
--- a/libpurple/protocols/jabber/iq.c
+++ b/libpurple/protocols/jabber/iq.c
@@ -224,7 +224,7 @@ static void jabber_iq_version_parse(JabberStream *js, const char *from,
PurpleXmlNode *query;
if(type == JABBER_IQ_GET) {
- PurpleUiInfo *ui_info;
+ PurpleUi *ui;
const char *ui_name = NULL, *ui_version = NULL;
iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:version");
@@ -234,11 +234,11 @@ static void jabber_iq_version_parse(JabberStream *js, const char *from,
query = purple_xmlnode_get_child(iq->node, "query");
- ui_info = purple_core_get_ui_info();
+ ui = purple_core_get_ui();
- if(PURPLE_IS_UI_INFO(ui_info)) {
- ui_name = purple_ui_info_get_name(ui_info);
- ui_version = purple_ui_info_get_version(ui_info);
+ if(PURPLE_IS_UI(ui)) {
+ ui_name = purple_ui_get_name(ui);
+ ui_version = purple_ui_get_version(ui);
}
if(NULL != ui_name && NULL != ui_version) {
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index dc04dd43c5..e807faa7d4 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -3679,7 +3679,7 @@ xmpp_uri_handler(const char *proto, const char *user, GHashTable *params,
static void
jabber_do_init(void)
{
- PurpleUiInfo *ui_info = purple_core_get_ui_info();
+ PurpleUi *ui = purple_core_get_ui();
const gchar *ui_type;
const gchar *type = "pc"; /* default client type, if unknown or
unspecified */
@@ -3713,7 +3713,7 @@ jabber_do_init(void)
jabber_cmds = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, cmds_free_func);
- ui_type = ui_info ? purple_ui_info_get_client_type(ui_info) : NULL;
+ ui_type = ui ? purple_ui_get_client_type(ui) : NULL;
if (ui_type) {
if (purple_strequal(ui_type, "pc") ||
purple_strequal(ui_type, "console") ||
@@ -3725,8 +3725,8 @@ jabber_do_init(void)
}
}
- if (ui_info)
- ui_name = purple_ui_info_get_name(ui_info);
+ if (ui)
+ ui_name = purple_ui_get_name(ui);
if (ui_name == NULL)
ui_name = PACKAGE;
diff --git a/libpurple/purplecoreuiops.c b/libpurple/purplecoreuiops.c
deleted file mode 100644
index 0fe8819eed..0000000000
--- a/libpurple/purplecoreuiops.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * 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 "purplecoreuiops.h"
-
-static PurpleCoreUiOps *
-purple_core_ui_ops_copy(PurpleCoreUiOps *ops)
-{
- PurpleCoreUiOps *ops_new;
-
- g_return_val_if_fail(ops != NULL, NULL);
-
- ops_new = g_new(PurpleCoreUiOps, 1);
- *ops_new = *ops;
-
- return ops_new;
-}
-
-GType
-purple_core_ui_ops_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- type = g_boxed_type_register_static("PurpleCoreUiOps",
- (GBoxedCopyFunc)purple_core_ui_ops_copy,
- (GBoxedFreeFunc)g_free);
- }
-
- return type;
-}
-
-
diff --git a/libpurple/purplecoreuiops.h b/libpurple/purplecoreuiops.h
deleted file mode 100644
index 576918da8b..0000000000
--- a/libpurple/purplecoreuiops.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * 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_CORE_UIOPS_H
-#define PURPLE_CORE_UIOPS_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include <libpurple/purpleuiinfo.h>
-
-#define PURPLE_TYPE_CORE_UI_OPS (purple_core_ui_ops_get_type())
-typedef struct _PurpleCoreUiOps PurpleCoreUiOps;
-
-G_BEGIN_DECLS
-
-/**
- * PurpleCoreUiOps:
- * @ui_prefs_init: Called just after the preferences subsystem is initialized;
- * the UI could use this callback to add some preferences it
- * needs to be in place when other subsystems are initialized.
- * @ui_init: Called after all of libpurple has been initialized. The UI
- * should use this hook to set all other necessary
- * <link linkend="chapter-ui-ops"><literal>UiOps structures</literal></link>.
- * @quit: Called after most of libpurple has been uninitialized.
- * @get_settings_backend: Called to get the [class@Gio.SettingsBackend] that
- * the UI is using.
- *
- * Callbacks that fire at different points of the initialization and teardown
- * of libpurple, along with a hook to return descriptive information about the
- * UI.
- */
-struct _PurpleCoreUiOps {
- /*< public >*/
- void (*ui_prefs_init)(void);
- void (*ui_init)(void);
-
- void (*quit)(void);
-
- gpointer (*get_settings_backend)(void);
-
- /*< private >*/
- gpointer reserved[4];
-};
-
-/**
- * purple_core_ui_ops_get_type:
- *
- * Returns: The #GType for the #PurpleCoreUiOps boxed structure.
- */
-GType purple_core_ui_ops_get_type(void);
-
-
-G_END_DECLS
-
-#endif /* PURPLE_CORE_UIOPS_H */
diff --git a/libpurple/purplepath.c b/libpurple/purplepath.c
index 54f736fd59..473d2e898a 100644
--- a/libpurple/purplepath.c
+++ b/libpurple/purplepath.c
@@ -19,7 +19,7 @@
#include <libpurple/purplepath.h>
#include <libpurple/core.h>
-#include <libpurple/purpleuiinfo.h>
+#include <libpurple/purpleui.h>
#ifdef _WIN32
# include "win32/win32dep.h"
@@ -43,10 +43,10 @@ purple_xdg_dir(gchar **xdg_dir, const gchar *xdg_base_dir,
{
if (!*xdg_dir) {
if (!custom_user_dir) {
- PurpleUiInfo *info = purple_core_get_ui_info();
+ PurpleUi *ui = purple_core_get_ui();
const gchar *id = NULL;
- id = purple_ui_info_get_id(info);
+ id = purple_ui_get_id(ui);
if(id == NULL) {
id = "purple";
}
diff --git a/libpurple/purpleui.c b/libpurple/purpleui.c
new file mode 100644
index 0000000000..b6545a704c
--- /dev/null
+++ b/libpurple/purpleui.c
@@ -0,0 +1,425 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * 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 "purpleui.h"
+
+typedef struct {
+ char *id;
+ char *name;
+ char *version;
+ char *website;
+ char *support_website;
+ char *client_type;
+} PurpleUiPrivate;
+
+enum {
+ PROP_0,
+ PROP_ID,
+ PROP_NAME,
+ PROP_VERSION,
+ PROP_WEBSITE,
+ PROP_SUPPORT_WEBSITE,
+ PROP_CLIENT_TYPE,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleUi, purple_ui, G_TYPE_OBJECT)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_ui_set_id(PurpleUi *ui, const char *id) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ priv = purple_ui_get_instance_private(ui);
+
+ g_free(priv->id);
+ priv->id = g_strdup(id);
+
+ g_object_notify_by_pspec(G_OBJECT(ui), properties[PROP_ID]);
+}
+
+static void
+purple_ui_set_name(PurpleUi *ui, const char *name) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ priv = purple_ui_get_instance_private(ui);
+
+ g_free(priv->name);
+ priv->name = g_strdup(name);
+
+ g_object_notify_by_pspec(G_OBJECT(ui), properties[PROP_NAME]);
+}
+
+static void
+purple_ui_set_version(PurpleUi *ui, const char *version) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ priv = purple_ui_get_instance_private(ui);
+
+ g_free(priv->version);
+ priv->version = g_strdup(version);
+
+ g_object_notify_by_pspec(G_OBJECT(ui), properties[PROP_VERSION]);
+}
+
+static void
+purple_ui_set_website(PurpleUi *ui, const char *website) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ priv = purple_ui_get_instance_private(ui);
+
+ g_free(priv->website);
+ priv->website = g_strdup(website);
+
+ g_object_notify_by_pspec(G_OBJECT(ui), properties[PROP_WEBSITE]);
+}
+
+static void
+purple_ui_set_support_website(PurpleUi *ui, const char *support_website) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ priv = purple_ui_get_instance_private(ui);
+
+ g_free(priv->support_website);
+ priv->support_website = g_strdup(support_website);
+
+ g_object_notify_by_pspec(G_OBJECT(ui), properties[PROP_SUPPORT_WEBSITE]);
+}
+
+static void
+purple_ui_set_client_type(PurpleUi *ui, const char *client_type) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ priv = purple_ui_get_instance_private(ui);
+
+ g_free(priv->client_type);
+ priv->client_type = g_strdup(client_type);
+
+ g_object_notify_by_pspec(G_OBJECT(ui), properties[PROP_CLIENT_TYPE]);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+purple_ui_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleUi *ui = PURPLE_UI(obj);
+
+ switch(param_id) {
+ case PROP_ID:
+ g_value_set_string(value, purple_ui_get_id(ui));
+ break;
+ case PROP_NAME:
+ g_value_set_string(value, purple_ui_get_name(ui));
+ break;
+ case PROP_VERSION:
+ g_value_set_string(value, purple_ui_get_version(ui));
+ break;
+ case PROP_WEBSITE:
+ g_value_set_string(value, purple_ui_get_website(ui));
+ break;
+ case PROP_SUPPORT_WEBSITE:
+ g_value_set_string(value, purple_ui_get_support_website(ui));
+ break;
+ case PROP_CLIENT_TYPE:
+ g_value_set_string(value, purple_ui_get_client_type(ui));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_ui_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleUi *ui = PURPLE_UI(obj);
+
+ switch(param_id) {
+ case PROP_ID:
+ purple_ui_set_id(ui, g_value_get_string(value));
+ break;
+ case PROP_NAME:
+ purple_ui_set_name(ui, g_value_get_string(value));
+ break;
+ case PROP_VERSION:
+ purple_ui_set_version(ui, g_value_get_string(value));
+ break;
+ case PROP_WEBSITE:
+ purple_ui_set_website(ui, g_value_get_string(value));
+ break;
+ case PROP_SUPPORT_WEBSITE:
+ purple_ui_set_support_website(ui, g_value_get_string(value));
+ break;
+ case PROP_CLIENT_TYPE:
+ purple_ui_set_client_type(ui, g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_ui_finalize(GObject *obj) {
+ PurpleUiPrivate *priv = purple_ui_get_instance_private(PURPLE_UI(obj));
+
+ g_clear_pointer(&priv->id, g_free);
+ g_clear_pointer(&priv->name, g_free);
+ g_clear_pointer(&priv->version, g_free);
+ g_clear_pointer(&priv->website, g_free);
+ g_clear_pointer(&priv->support_website, g_free);
+ g_clear_pointer(&priv->client_type, g_free);
+
+ G_OBJECT_CLASS(purple_ui_parent_class)->finalize(obj);
+}
+
+static void
+purple_ui_init(G_GNUC_UNUSED PurpleUi *ui) {
+}
+
+static void
+purple_ui_class_init(PurpleUiClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->get_property = purple_ui_get_property;
+ obj_class->set_property = purple_ui_set_property;
+ obj_class->finalize = purple_ui_finalize;
+
+ /**
+ * PurpleUi:id:
+ *
+ * The identifier of the user interface. This is used in places where a
+ * constant string is need to represent the user interface.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_ID] = g_param_spec_string(
+ "id", "id",
+ "The identifier of the user interface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleUi:name:
+ *
+ * The name of the user interface. This is used in places where it will be
+ * displayed to users, so it should be translated.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_NAME] = g_param_spec_string(
+ "name", "name",
+ "The name of the user interface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleUi:version:
+ *
+ * The version number of the user interface.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_VERSION] = g_param_spec_string(
+ "version", "version",
+ "The version of the user interface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleUi:website:
+ *
+ * The website of the user interface. This should be the main website.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_WEBSITE] = g_param_spec_string(
+ "website", "website",
+ "The website of the user interface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleUi:support-website:
+ *
+ * The support website of the user interface. This should link to a page
+ * that specifically directs users how to get support for your user
+ * interface.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_SUPPORT_WEBSITE] = g_param_spec_string(
+ "support-website", "support-website",
+ "The support website of the user interface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleUi:client-type:
+ *
+ * The client type of the user interface. Common values include `bot`,
+ * `console`, `mobile`, `pc`, `web`, etc.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_CLIENT_TYPE] = g_param_spec_string(
+ "client-type", "client-type",
+ "The client type of the user interface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+const char *
+purple_ui_get_id(PurpleUi *ui) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_UI(ui), NULL);
+
+ priv = purple_ui_get_instance_private(ui);
+
+ return priv->id;
+}
+
+const char *
+purple_ui_get_name(PurpleUi *ui) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_UI(ui), NULL);
+
+ priv = purple_ui_get_instance_private(ui);
+
+ return priv->name;
+}
+
+const char *
+purple_ui_get_version(PurpleUi *ui) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_UI(ui), NULL);
+
+ priv = purple_ui_get_instance_private(ui);
+
+ return priv->version;
+}
+
+const char *
+purple_ui_get_website(PurpleUi *ui) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_UI(ui), NULL);
+
+ priv = purple_ui_get_instance_private(ui);
+
+ return priv->website;
+}
+
+const char *
+purple_ui_get_support_website(PurpleUi *ui) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_UI(ui), NULL);
+
+ priv = purple_ui_get_instance_private(ui);
+
+ return priv->support_website;
+}
+
+const char *
+purple_ui_get_client_type(PurpleUi *ui) {
+ PurpleUiPrivate *priv = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_UI(ui), NULL);
+
+ priv = purple_ui_get_instance_private(ui);
+
+ return priv->client_type;
+}
+
+void
+purple_ui_prefs_init(PurpleUi *ui) {
+ PurpleUiClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ klass = PURPLE_UI_GET_CLASS(ui);
+ if(klass != NULL && klass->prefs_init != NULL) {
+ klass->prefs_init(ui);
+ }
+}
+
+void
+purple_ui_start(PurpleUi *ui) {
+ PurpleUiClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ klass = PURPLE_UI_GET_CLASS(ui);
+ if(klass != NULL && klass->start != NULL) {
+ klass->start(ui);
+ }
+}
+
+void
+purple_ui_stop(PurpleUi *ui) {
+ PurpleUiClass *klass = NULL;
+
+ g_return_if_fail(PURPLE_IS_UI(ui));
+
+ klass = PURPLE_UI_GET_CLASS(ui);
+ if(klass != NULL && klass->stop != NULL) {
+ klass->stop(ui);
+ }
+}
+
+gpointer
+purple_ui_get_settings_backend(PurpleUi *ui) {
+ PurpleUiClass *klass = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_UI(ui), NULL);
+
+ klass = PURPLE_UI_GET_CLASS(ui);
+ if(klass != NULL && klass->get_settings_backend != NULL) {
+ return klass->get_settings_backend(ui);
+ }
+
+ return NULL;
+}
diff --git a/libpurple/purpleui.h b/libpurple/purpleui.h
new file mode 100644
index 0000000000..2bd92210fc
--- /dev/null
+++ b/libpurple/purpleui.h
@@ -0,0 +1,201 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * 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_UI_H
+#define PURPLE_UI_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PURPLE_TYPE_UI (purple_ui_get_type())
+G_DECLARE_DERIVABLE_TYPE(PurpleUi, purple_ui, PURPLE, UI, GObject)
+
+/**
+ * PurpleUi:
+ *
+ * An abstract class representing a user interface. All user interfaces must
+ * create a subclass of this and pass it to [func@Purple.Core.init].
+ *
+ * Since: 3.0.0
+ */
+
+/**
+ * PurpleUiClass:
+ * @prefs_init: This function is called to initialize the ui's preferences.
+ * This is slowly being phased out for @get_settings_backend, but
+ * is still required.
+ * @start: Called when libpurple is done with its initialization when the user
+ * interface should start telling libpurple about the rest of the user
+ * interface's interfaces.
+ * @stop: Called after most of libpurple has been uninitialized.
+ * @get_settings_backend: Called to get the [class@Gio.SettingsBackend] that
+ * the UI is using.
+ *
+ * The base class for all user interfaces which is used to identify themselves
+ * to libpurple when calling [func@Purple.core_init].
+ *
+ * Since: 3.0.0
+ */
+struct _PurpleUiClass {
+ /*< private >*/
+ GObjectClass parent;
+
+ /*< public >*/
+ void (*prefs_init)(PurpleUi *ui);
+ void (*start)(PurpleUi *ui);
+ void (*stop)(PurpleUi *ui);
+
+ gpointer (*get_settings_backend)(PurpleUi *ui);
+
+ /*< private >*/
+ gpointer reserved[4];
+};
+
+/**
+ * purple_ui_get_id:
+ * @ui: The instance.
+ *
+ * Gets the id for the user interface.
+ *
+ * Returns: id of the user interface.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_ui_get_id(PurpleUi *ui);
+
+/**
+ * purple_ui_get_name:
+ * @ui: The instance.
+ *
+ * Gets the name of @ui. This should be translated.
+ *
+ * Returns: The name of the user interface.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_ui_get_name(PurpleUi *ui);
+
+/**
+ * purple_ui_get_version:
+ * @ui: The instance.
+ *
+ * Gets the version of @ui.
+ *
+ * Returns: The version of the user interface.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_ui_get_version(PurpleUi *ui);
+
+/**
+ * purple_ui_get_website:
+ * @ui: The instance.
+ *
+ * Gets the website from @ui.
+ *
+ * Returns: (nullable): The website URI of the user interface or %NULL.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_ui_get_website(PurpleUi *ui);
+
+/**
+ * purple_ui_get_support_website:
+ * @ui: The instance.
+ *
+ * Gets the support website from @ui.
+ *
+ * Returns: (nullable): The support website URI of the user interface or %NULL.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_ui_get_support_website(PurpleUi *ui);
+
+/**
+ * purple_ui_get_client_type:
+ * @ui: The instance.
+ *
+ * Gets the client type from @ui.
+ *
+ * Returns: (transfer none): The client type of the user interface.
+ *
+ * Since: 3.0.0
+ */
+const char *purple_ui_get_client_type(PurpleUi *ui);
+
+/**
+ * purple_ui_prefs_init:
+ * @ui: The instance.
+ *
+ * Tells @ui that it should be initializing its preferences.
+ *
+ * Note: This should only be called by libpurple.
+ *
+ * Since: 3.0.0
+ */
+void purple_ui_prefs_init(PurpleUi *ui);
+
+/**
+ * purple_ui_start:
+ * @ui: The instance.
+ *
+ * Tells @ui that libpurple is done initializing and that @ui should continue
+ * its initialization.
+ *
+ * Note: This should only be called by libpurple.
+ *
+ * Since: 3.0.0
+ */
+void purple_ui_start(PurpleUi *ui);
+
+/**
+ * purple_ui_stop:
+ * @ui: The instance.
+ *
+ * Tells @ui that libpurple is done shutting down.
+ *
+ * Note: This should only be called by libpurple.
+ *
+ * Since: 3.0.0
+ */
+void purple_ui_stop(PurpleUi *ui);
+
+/**
+ * purple_ui_get_settings_backend:
+ * @ui: The instance:
+ *
+ * Get the [class@Gio.SettingsBackend] that @ui is using for its settings.
+ *
+ * Note: This should only be called by libpurple.
+ *
+ * Returns: (transfer full): The settings that @ui is using.
+ *
+ * Since: 3.0.0
+ */
+gpointer purple_ui_get_settings_backend(PurpleUi *ui);
+
+
+G_END_DECLS
+
+#endif /* PURPLE_UI_H */
diff --git a/libpurple/purpleuiinfo.c b/libpurple/purpleuiinfo.c
deleted file mode 100644
index 403b0860aa..0000000000
--- a/libpurple/purpleuiinfo.c
+++ /dev/null
@@ -1,326 +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 "purpleuiinfo.h"
-
-struct _PurpleUiInfo {
- GObject parent;
-
- gchar *id;
- gchar *name;
- gchar *version;
- gchar *website;
- gchar *support_website;
- gchar *client_type;
-};
-
-enum {
- PROP_0,
- PROP_ID,
- PROP_NAME,
- PROP_VERSION,
- PROP_WEBSITE,
- PROP_SUPPORT_WEBSITE,
- PROP_CLIENT_TYPE,
- N_PROPERTIES
-};
-static GParamSpec *properties[N_PROPERTIES] = { NULL, };
-
-/******************************************************************************
- * Helpers
- *****************************************************************************/
-static void
-purple_ui_info_set_id(PurpleUiInfo *info, const gchar *id) {
- g_free(info->id);
- info->id = g_strdup(id);
-}
-
-static void
-purple_ui_info_set_name(PurpleUiInfo *info, const gchar *name) {
- g_free(info->name);
- info->name = g_strdup(name);
-}
-
-static void
-purple_ui_info_set_version(PurpleUiInfo *info, const gchar *version) {
- g_free(info->version);
- info->version = g_strdup(version);
-}
-
-static void
-purple_ui_info_set_website(PurpleUiInfo *info, const gchar *website) {
- g_free(info->website);
- info->website = g_strdup(website);
-}
-
-static void
-purple_ui_info_set_support_website(PurpleUiInfo *info,
- const gchar *support_website)
-{
- g_free(info->support_website);
- info->support_website = g_strdup(support_website);
-}
-
-static void
-purple_ui_info_set_client_type(PurpleUiInfo *info, const gchar *client_type) {
- g_free(info->client_type);
- info->client_type = g_strdup(client_type);
-}
-
-/******************************************************************************
- * GObject Implementation
- *****************************************************************************/
-G_DEFINE_TYPE(PurpleUiInfo, purple_ui_info, G_TYPE_OBJECT);
-
-static void
-purple_ui_info_get_property(GObject *obj, guint param_id, GValue *value,
- GParamSpec *pspec)
-{
- PurpleUiInfo *info = PURPLE_UI_INFO(obj);
-
- switch(param_id) {
- case PROP_ID:
- g_value_set_string(value, purple_ui_info_get_id(info));
- break;
- case PROP_NAME:
- g_value_set_string(value, purple_ui_info_get_name(info));
- break;
- case PROP_VERSION:
- g_value_set_string(value, purple_ui_info_get_version(info));
- break;
- case PROP_WEBSITE:
- g_value_set_string(value, purple_ui_info_get_website(info));
- break;
- case PROP_SUPPORT_WEBSITE:
- g_value_set_string(value, purple_ui_info_get_support_website(info));
- break;
- case PROP_CLIENT_TYPE:
- g_value_set_string(value, purple_ui_info_get_client_type(info));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
- }
-}
-
-static void
-purple_ui_info_set_property(GObject *obj, guint param_id, const GValue *value,
- GParamSpec *pspec)
-{
- PurpleUiInfo *info = PURPLE_UI_INFO(obj);
-
- switch(param_id) {
- case PROP_ID:
- purple_ui_info_set_id(info, g_value_get_string(value));
- break;
- case PROP_NAME:
- purple_ui_info_set_name(info, g_value_get_string(value));
- break;
- case PROP_VERSION:
- purple_ui_info_set_version(info, g_value_get_string(value));
- break;
- case PROP_WEBSITE:
- purple_ui_info_set_website(info, g_value_get_string(value));
- break;
- case PROP_SUPPORT_WEBSITE:
- purple_ui_info_set_support_website(info,
- g_value_get_string(value));
- break;
- case PROP_CLIENT_TYPE:
- purple_ui_info_set_client_type(info, g_value_get_string(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
- }
-}
-
-static void
-purple_ui_info_init(PurpleUiInfo *info) {
-}
-
-static void
-purple_ui_info_finalize(GObject *obj) {
- PurpleUiInfo *info = PURPLE_UI_INFO(obj);
-
- g_clear_pointer(&info->id, g_free);
- g_clear_pointer(&info->name, g_free);
- g_clear_pointer(&info->version, g_free);
- g_clear_pointer(&info->website, g_free);
- g_clear_pointer(&info->support_website, g_free);
- g_clear_pointer(&info->client_type, g_free);
-
- G_OBJECT_CLASS(purple_ui_info_parent_class)->finalize(obj);
-}
-
-static void
-purple_ui_info_class_init(PurpleUiInfoClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
- obj_class->get_property = purple_ui_info_get_property;
- obj_class->set_property = purple_ui_info_set_property;
- obj_class->finalize = purple_ui_info_finalize;
-
- /**
- * PurpleUiInfo:id:
- *
- * The identifier of the user interface.
- *
- * Since: 3.0.0
- */
- properties[PROP_ID] =
- g_param_spec_string("id", "id", "The identifier of the user interface",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleUiInfo:name:
- *
- * The name of the user interface.
- *
- * Since: 3.0.0
- */
- properties[PROP_NAME] =
- g_param_spec_string("name", "name", "The name of the user interface",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleUiInfo:version:
- *
- * The version of the user interface.
- *
- * Since: 3.0.0
- */
- properties[PROP_VERSION] =
- g_param_spec_string("version", "version",
- "The version of the user interface",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleUiInfo:website:
- *
- * The website of the user interface.
- *
- * Since: 3.0.0
- */
- properties[PROP_WEBSITE] =
- g_param_spec_string("website", "website",
- "The website of the user interface",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleUiInfo:support-website:
- *
- * The support website of the user interface.
- *
- * Since: 3.0.0
- */
- properties[PROP_SUPPORT_WEBSITE] =
- g_param_spec_string("support-website", "support-website",
- "The support website of the user interface",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * PurpleUiInfo:client-type:
- *
- * The client type of the user interface.
- *
- * Since: 3.0.0
- */
- properties[PROP_CLIENT_TYPE] =
- g_param_spec_string("client-type", "client-type",
- "The client type of the user interface",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
-}
-
-/******************************************************************************
- * Public API
- *****************************************************************************/
-PurpleUiInfo *
-purple_ui_info_new(const gchar *id, const gchar *name,
- const gchar *version, const gchar *website,
- const gchar *support_website, const gchar *client_type)
-{
- return g_object_new(PURPLE_TYPE_UI_INFO,
- "id", id,
- "name", name,
- "version", version,
- "website", website,
- "support-website", support_website,
- "client-type", client_type,
- NULL);
-}
-
-const gchar *
-purple_ui_info_get_id(PurpleUiInfo *info) {
- g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL);
-
- return info->id;
-}
-
-const gchar *
-purple_ui_info_get_name(PurpleUiInfo *info) {
- g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL);
-
- return info->name;
-}
-
-const gchar *
-purple_ui_info_get_version(PurpleUiInfo *info) {
- g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL);
-
- return info->version;
-}
-
-const gchar *
-purple_ui_info_get_website(PurpleUiInfo *info) {
- g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL);
-
- return info->website;
-}
-
-const gchar *
-purple_ui_info_get_support_website(PurpleUiInfo *info) {
- g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL);
-
- return info->support_website;
-}
-
-const gchar *
-purple_ui_info_get_client_type(PurpleUiInfo *info) {
- g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL);
-
- return info->client_type;
-}
diff --git a/libpurple/purpleuiinfo.h b/libpurple/purpleuiinfo.h
deleted file mode 100644
index 8a72ab9a8a..0000000000
--- a/libpurple/purpleuiinfo.h
+++ /dev/null
@@ -1,143 +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_UI_INFO_H
-#define PURPLE_UI_INFO_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define PURPLE_TYPE_UI_INFO (purple_ui_info_get_type())
-
-/**
- * PurpleUiInfo:
- *
- * #PurpleUiInfo keeps track of basic information about the user interface.
- */
-G_DECLARE_FINAL_TYPE(PurpleUiInfo, purple_ui_info, PURPLE, UI_INFO, GObject)
-
-/**
- * purple_ui_info_new:
- * @id: The identifier.
- * @name: The name, which will be displayed.
- * @version: The version.
- * @website: The website.
- * @support_website: The support website.
- * @client_type: The client type.
- *
- * Creates a new #PurpleUiInfo with the given values. If you only want to set
- * a few of these, you should use g_object_new() directly.
- *
- * Returns: (transfer full): The newly created #PurpleUiInfo instance.
- *
- * Since: 3.0.0
- */
-PurpleUiInfo *purple_ui_info_new(const gchar *id,
- const gchar *name,
- const gchar *version,
- const gchar *website,
- const gchar *support_website,
- const gchar *client_type);
-
-/**
- * purple_ui_info_get_id:
- * @info: The instance.
- *
- * Gets the identifier from @info.
- *
- * Returns: The identifier from @info.
- *
- * Since: 3.0.0
- */
-const gchar *purple_ui_info_get_id(PurpleUiInfo *info);
-
-/**
- * purple_ui_info_get_name:
- * @info: The #PurpleUiInfo instance.
- *
- * Gets the name from @info.
- *
- * Returns: The name from @info.
- *
- * Since: 3.0.0
- */
-const gchar *purple_ui_info_get_name(PurpleUiInfo *info);
-
-/**
- * purple_ui_info_get_version:
- * @info: The #PurpleUiInfo instance.
- *
- * Gets the version from @info.
- *
- * Returns: The version from @info.
- *
- * Since: 3.0.0
- */
-const gchar *purple_ui_info_get_version(PurpleUiInfo *info);
-
-/**
- * purple_ui_info_get_website:
- * @info: The #PurpleUiInfo instance.
- *
- * Gets the website from @info.
- *
- * Returns: The website for @info.
- *
- * Since: 3.0.0
- */
-const gchar *purple_ui_info_get_website(PurpleUiInfo *info);
-
-/**
- * purple_ui_info_get_support_website:
- * @info: The #PurpleUiInfo instance.
- *
- * Gets the support website from @info.
- *
- * Returns: The support website from @info.
- *
- * Since: 3.0.0
- */
-const gchar *purple_ui_info_get_support_website(PurpleUiInfo *info);
-
-/**
- * purple_ui_info_get_client_type:
- * @info: The #PurpleUiInfo instance.
- *
- * Gets the client type from @info. For example: 'bot', 'console', 'mobile',
- * 'pc', 'web', etc.
- *
- * Returns: The client type of @info.
- *
- * Since: 3.0.0
- */
-const gchar *purple_ui_info_get_client_type(PurpleUiInfo *info);
-
-G_END_DECLS
-
-#endif /* PURPLE_UI_INFO_H */
-
diff --git a/libpurple/tests/test_ui.c b/libpurple/tests/test_ui.c
index f172462678..30f30daf73 100644
--- a/libpurple/tests/test_ui.c
+++ b/libpurple/tests/test_ui.c
@@ -58,21 +58,51 @@ static PurpleConversationUiOps test_conv_uiops = {
.write_conv = test_write_conv
};
+/******************************************************************************
+ * PurpleUi Implementation
+ *****************************************************************************/
+struct _TestPurpleUi {
+ PurpleUi parent;
+};
+
+G_DECLARE_FINAL_TYPE(TestPurpleUi, test_purple_ui, TEST_PURPLE, UI, PurpleUi)
+
+G_DEFINE_TYPE(TestPurpleUi, test_purple_ui, PURPLE_TYPE_UI)
+
static void
-test_ui_init(void)
-{
+test_purple_ui_start(G_GNUC_UNUSED PurpleUi *ui) {
purple_conversations_set_ui_ops(&test_conv_uiops);
}
static gpointer
-test_ui_get_settings_backend(void) {
+test_purple_ui_get_settings_backend(G_GNUC_UNUSED PurpleUi *ui) {
return g_memory_settings_backend_new();
}
-static PurpleCoreUiOps test_core_uiops = {
- .ui_init = test_ui_init,
- .get_settings_backend = test_ui_get_settings_backend,
-};
+static void
+test_purple_ui_init(G_GNUC_UNUSED TestPurpleUi *ui) {
+}
+
+static void
+test_purple_ui_class_init(TestPurpleUiClass *klass) {
+ PurpleUiClass *ui_class = PURPLE_UI_CLASS(klass);
+
+ ui_class->start = test_purple_ui_start;
+ ui_class->get_settings_backend = test_purple_ui_get_settings_backend;
+}
+
+static PurpleUi *
+test_purple_ui_new(void) {
+ return g_object_new(
+ test_purple_ui_get_type(),
+ "id", "test",
+ "name", "Test-UI",
+ "version", VERSION,
+ "website", PURPLE_WEBSITE,
+ "support-website", PURPLE_WEBSITE,
+ "client-type", "test",
+ NULL);
+}
static gboolean
test_ui_init_history(GError **error) {
@@ -101,7 +131,7 @@ test_ui_init_history(GError **error) {
void
test_ui_purple_init(void) {
- PurpleUiInfo *ui_info = NULL;
+ PurpleUi *ui = NULL;
GError *error = NULL;
#ifndef _WIN32
@@ -116,21 +146,12 @@ test_ui_purple_init(void) {
/* set the magic PURPLE_PLUGINS_SKIP environment variable */
g_setenv("PURPLE_PLUGINS_SKIP", "1", TRUE);
- /* Set the core-uiops, which is used to
- * - initialize the ui specific preferences.
- * - initialize the debug ui.
- * - initialize the ui components for all the modules.
- * - uninitialize the ui components for all the modules when the core terminates.
- */
- purple_core_set_ui_ops(&test_core_uiops);
-
- ui_info = purple_ui_info_new("test", "Test-UI", VERSION, PURPLE_WEBSITE,
- PURPLE_WEBSITE, "test");
+ ui = test_purple_ui_new();
/* Now that all the essential stuff has been set, let's try to init the core. It's
* necessary to provide a non-NULL name for the current ui to the core. This name
* is used by stuff that depends on this ui, for example the ui-specific plugins. */
- if (!purple_core_init(ui_info)) {
+ if (!purple_core_init(ui)) {
/* Initializing the core failed. Terminate. */
fprintf(stderr,
"libpurple initialization failed. Dumping core.\n"
diff --git a/pidgin/gtkconv.h b/pidgin/gtkconv.h
index f76d207271..cc075264c7 100644
--- a/pidgin/gtkconv.h
+++ b/pidgin/gtkconv.h
@@ -26,6 +26,8 @@
#ifndef _PIDGIN_CONVERSATION_H_
#define _PIDGIN_CONVERSATION_H_
+#include <gtk/gtk.h>
+
typedef struct _PidginConversation PidginConversation;
enum {
diff --git a/pidgin/libpidgin.c b/pidgin/libpidgin.c
index 81a8d35237..24d089e2d2 100644
--- a/pidgin/libpidgin.c
+++ b/pidgin/libpidgin.c
@@ -30,31 +30,12 @@
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
-#define G_SETTINGS_ENABLE_BACKEND
-#include <gio/gsettingsbackend.h>
-
#include <locale.h>
#include <purple.h>
-#include "gtkaccount.h"
-#include "gtkblist.h"
-#include "gtkconn.h"
-#include "gtkxfer.h"
-#include "gtkidle.h"
-#include "gtkmedia.h"
-#include "gtknotify.h"
-#include "gtkprivacy.h"
-#include "gtkrequest.h"
-#include "gtkroomlist.h"
-#include "gtkutils.h"
-#include "gtkwhiteboard.h"
#include "pidginapplication.h"
#include "pidgincore.h"
-#include "pidgindebug.h"
-#include "pidginplugininfo.h"
-#include "pidginprefs.h"
-#include "pidginprivate.h"
#ifndef _WIN32
#include <signal.h>
@@ -154,181 +135,6 @@ mainloop_sighandler(GIOChannel *source, GIOCondition cond, gpointer data)
}
#endif /* !_WIN32 */
-static void
-purple_ui_add_protocol_theme_paths(PurpleProtocol *protocol) {
- GdkDisplay *display = NULL;
- GtkIconTheme *theme = NULL;
- const gchar *path = NULL;
-
- display = gdk_display_get_default();
-
- theme = gtk_icon_theme_get_for_display(display);
-
- path = purple_protocol_get_icon_search_path(protocol);
- if(path != NULL) {
- gtk_icon_theme_add_search_path(theme, path);
- }
-
- path = purple_protocol_get_icon_resource_path(protocol);
- if(path != NULL) {
- gtk_icon_theme_add_resource_path(theme, path);
- }
-}
-
-static void
-purple_ui_protocol_foreach_theme_cb(PurpleProtocol *protocol, gpointer data) {
- purple_ui_add_protocol_theme_paths(protocol);
-}
-
-static void
-purple_ui_protocol_registered_cb(PurpleProtocolManager *manager,
- PurpleProtocol *protocol)
-{
- purple_ui_add_protocol_theme_paths(protocol);
-}
-
-static gboolean
-pidgin_history_init(GError **error) {
- PurpleHistoryManager *manager = NULL;
- PurpleHistoryAdapter *adapter = NULL;
- gchar *filename = NULL;
- const gchar *id = NULL;
-
- manager = purple_history_manager_get_default();
-
- /* Attempt to create the config_dir. We don't care about the result as the
- * logging adapter will fail with a better error than us failing to create
- * the directory.
- */
- g_mkdir_with_parents(purple_config_dir(), 0700);
-
- filename = g_build_filename(purple_config_dir(), "history.db", NULL);
- adapter = purple_sqlite_history_adapter_new(filename);
- g_free(filename);
-
- id = purple_history_adapter_get_id(adapter);
- if(!purple_history_manager_register(manager, adapter, error)) {
- g_clear_object(&adapter);
-
- return FALSE;
- }
-
- /* The manager adds a ref to the adapter on registration, so we can remove
- * our reference.
- */
- g_clear_object(&adapter);
-
- return purple_history_manager_set_active(manager, id, error);
-}
-
-static void
-pidgin_ui_init(void)
-{
- PurpleProtocolManager *protocol_manager = NULL;
- GdkDisplay *display = NULL;
- GtkIconTheme *theme = NULL;
- GError *error = NULL;
- gchar *path;
-
- pidgin_debug_init();
-
- display = gdk_display_get_default();
- theme = gtk_icon_theme_get_for_display(display);
-
- path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons", NULL);
- gtk_icon_theme_add_search_path(theme, path);
- g_free(path);
-
- /* Add a callback for when a protocol is registered to add its icon paths
- * if it was found after initial startup.
- */
- protocol_manager = purple_protocol_manager_get_default();
- g_signal_connect(protocol_manager, "registered",
- G_CALLBACK(purple_ui_protocol_registered_cb), NULL);
-
- /* Add the icon paths for all the protocols that libpurple found at start
- * up.
- */
- purple_protocol_manager_foreach(protocol_manager,
- purple_ui_protocol_foreach_theme_cb, NULL);
-
- if(!pidgin_history_init(&error)) {
- g_critical("failed to initialize the history api: %s",
- error != NULL ? error->message : "unknown");
- g_clear_error(&error);
- }
-
- /* Set the UI operation structures. */
- purple_xfers_set_ui_ops(pidgin_xfers_get_ui_ops());
- purple_blist_set_ui(PIDGIN_TYPE_BUDDY_LIST);
- purple_notify_set_ui_ops(pidgin_notify_get_ui_ops());
- purple_request_set_ui_ops(pidgin_request_get_ui_ops());
- purple_connections_set_ui_ops(pidgin_connections_get_ui_ops());
- purple_whiteboard_set_ui_ops(pidgin_whiteboard_get_ui_ops());
- purple_idle_set_ui(pidgin_idle_new());
-
- pidgin_accounts_init();
- pidgin_connection_init();
- pidgin_request_init();
- pidgin_blist_init();
- pidgin_conversations_init();
- pidgin_commands_init();
- pidgin_privacy_init();
- pidgin_xfers_init();
- pidgin_roomlist_init();
- pidgin_medias_init();
- pidgin_notify_init();
-}
-
-static void
-pidgin_quit(void)
-{
- /* Uninit */
-
- /* Be sure to close all windows that are not attached to anything
- * (e.g., the debug window), or they may access things after they are
- * shut down. */
- pidgin_notify_uninit();
- pidgin_commands_uninit();
- pidgin_conversations_uninit();
- pidgin_blist_uninit();
- pidgin_request_uninit();
- pidgin_connection_uninit();
- pidgin_accounts_uninit();
- pidgin_xfers_uninit();
- pidgin_debug_window_hide();
- pidgin_debug_uninit();
-
- /* and end it all... */
- g_application_quit(g_application_get_default());
-}
-
-static gpointer
-pidgin_get_settings_backend(void) {
- GSettingsBackend *backend = NULL;
- char *config = NULL;
-
- config = g_build_filename(purple_config_dir(), "pidgin3.ini", NULL);
- backend = g_keyfile_settings_backend_new(config, "/", NULL);
-
- g_free(config);
-
- return backend;
-}
-
-static PurpleCoreUiOps core_ops = {
- .ui_prefs_init = pidgin_prefs_init,
- .ui_init = pidgin_ui_init,
- .quit = pidgin_quit,
- .get_settings_backend = pidgin_get_settings_backend,
-};
-
-PurpleCoreUiOps *
-pidgin_core_get_ui_ops(void)
-{
- return &core_ops;
-}
-
#ifndef _WIN32
static void
pidgin_setup_error_handler(void)
diff --git a/pidgin/meson.build b/pidgin/meson.build
index 67550c9e45..5b6560c53f 100644
--- a/pidgin/meson.build
+++ b/pidgin/meson.build
@@ -61,6 +61,7 @@ libpidgin_SOURCES = [
'pidginstatusprimitivechooser.c',
'pidginstatusprimitivestore.c',
'pidgintalkatu.c',
+ 'pidginui.c',
'prefs/pidginprefs.c',
'prefs/pidginawayprefs.c',
'prefs/pidginconversationprefs.c',
@@ -129,6 +130,7 @@ libpidgin_headers = [
'pidginstatusprimitivechooser.h',
'pidginstatusprimitivestore.h',
'pidgintalkatu.h',
+ 'pidginui.h',
]
libpidgin_prefs_headers = [
diff --git a/pidgin/pidginapplication.c b/pidgin/pidginapplication.c
index 3e534a0281..5180d81255 100644
--- a/pidgin/pidginapplication.c
+++ b/pidgin/pidginapplication.c
@@ -52,9 +52,10 @@
#include "pidginmooddialog.h"
#include "pidginpluginsdialog.h"
#include "pidginpluginsmenu.h"
+#include "pidginprefs.h"
#include "pidginstatuseditor.h"
#include "pidginstatusmanager.h"
-#include "pidginprefs.h"
+#include "pidginui.h"
struct _PidginApplication {
GtkApplication parent;
@@ -745,7 +746,6 @@ pidgin_application_window_added(GtkApplication *application,
static void
pidgin_application_startup(GApplication *application) {
PurpleAccountManager *manager = NULL;
- PurpleUiInfo *ui_info = NULL;
GList *active_accounts = NULL;
gpointer handle = NULL;
@@ -780,13 +780,7 @@ pidgin_application_startup(GApplication *application) {
winpidgin_init();
#endif
- purple_core_set_ui_ops(pidgin_core_get_ui_ops());
-
- ui_info = purple_ui_info_new("pidgin3", PIDGIN_NAME, VERSION,
- "https://pidgin.im",
- "https://developer.pidgin.im", "pc");
-
- if(!purple_core_init(ui_info)) {
+ if(!purple_core_init(pidgin_ui_new())) {
fprintf(stderr,
_("Initialization of the libpurple core failed. Aborting!\n"
"Please report this!\n"));
diff --git a/pidgin/pidgincore.h b/pidgin/pidgincore.h
index ea73ae5d24..46d8b85a0d 100644
--- a/pidgin/pidgincore.h
+++ b/pidgin/pidgincore.h
@@ -61,17 +61,5 @@
*/
int pidgin_start(int argc, char *argv[]);
-/**
- * pidgin_core_get_ui_ops:
- *
- * Gets the #PurpleCoreUiOps that Pidgin sets up. You probably don't want to
- * call this.
- *
- * Returns: The #PurpleCoreUiOps for Pidgin.
- *
- * Since: 3.0.0
- */
-PurpleCoreUiOps *pidgin_core_get_ui_ops(void);
-
#endif /* PIDGIN_CORE_H */
diff --git a/pidgin/pidginui.c b/pidgin/pidginui.c
new file mode 100644
index 0000000000..88e514e751
--- /dev/null
+++ b/pidgin/pidginui.c
@@ -0,0 +1,263 @@
+/*
+ * Pidgin - Internet Messenger
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Pidgin 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 <glib.h>
+#include <glib/gi18n.h>
+
+#define G_SETTINGS_ENABLE_BACKEND
+#include <gio/gsettingsbackend.h>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "pidginui.h"
+
+#include "gtkaccount.h"
+#include "gtkblist.h"
+#include "gtkconn.h"
+#include "gtkconv.h"
+#include "gtkidle.h"
+#include "gtkmedia.h"
+#include "gtknotify.h"
+#include "gtkprivacy.h"
+#include "gtkroomlist.h"
+#include "gtkrequest.h"
+#include "gtkwhiteboard.h"
+#include "gtkxfer.h"
+#include "pidgincore.h"
+#include "pidgindebug.h"
+#include "pidginprefs.h"
+#include "pidginprivate.h"
+
+struct _PidginUi {
+ PurpleUi parent;
+};
+
+G_DEFINE_TYPE(PidginUi, pidgin_ui, PURPLE_TYPE_UI)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static gboolean
+pidgin_history_init(GError **error) {
+ PurpleHistoryManager *manager = NULL;
+ PurpleHistoryAdapter *adapter = NULL;
+ gchar *filename = NULL;
+ const gchar *id = NULL;
+
+ manager = purple_history_manager_get_default();
+
+ /* Attempt to create the config_dir. We don't care about the result as the
+ * logging adapter will fail with a better error than us failing to create
+ * the directory.
+ */
+ g_mkdir_with_parents(purple_config_dir(), 0700);
+
+ filename = g_build_filename(purple_config_dir(), "history.db", NULL);
+ adapter = purple_sqlite_history_adapter_new(filename);
+ g_free(filename);
+
+ id = purple_history_adapter_get_id(adapter);
+ if(!purple_history_manager_register(manager, adapter, error)) {
+ g_clear_object(&adapter);
+
+ return FALSE;
+ }
+
+ /* The manager adds a ref to the adapter on registration, so we can remove
+ * our reference.
+ */
+ g_clear_object(&adapter);
+
+ return purple_history_manager_set_active(manager, id, error);
+}
+
+static void
+pidgin_ui_add_protocol_theme_paths(PurpleProtocol *protocol) {
+ GdkDisplay *display = NULL;
+ GtkIconTheme *theme = NULL;
+ const gchar *path = NULL;
+
+ display = gdk_display_get_default();
+
+ theme = gtk_icon_theme_get_for_display(display);
+
+ path = purple_protocol_get_icon_search_path(protocol);
+ if(path != NULL) {
+ gtk_icon_theme_add_search_path(theme, path);
+ }
+
+ path = purple_protocol_get_icon_resource_path(protocol);
+ if(path != NULL) {
+ gtk_icon_theme_add_resource_path(theme, path);
+ }
+}
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+pidgin_ui_protocol_foreach_theme_cb(PurpleProtocol *protocol,
+ G_GNUC_UNUSED gpointer data)
+{
+ pidgin_ui_add_protocol_theme_paths(protocol);
+}
+
+static void
+pidgin_ui_protocol_registered_cb(G_GNUC_UNUSED PurpleProtocolManager *manager,
+ PurpleProtocol *protocol)
+{
+ pidgin_ui_add_protocol_theme_paths(protocol);
+}
+
+/******************************************************************************
+ * PurpleUi Implementation
+ *****************************************************************************/
+static void
+pidgin_ui_prefs_init(G_GNUC_UNUSED PurpleUi *ui) {
+ pidgin_prefs_init();
+}
+
+static void
+pidgin_ui_start(G_GNUC_UNUSED PurpleUi *ui) {
+ PurpleProtocolManager *protocol_manager = NULL;
+ GdkDisplay *display = NULL;
+ GtkIconTheme *theme = NULL;
+ GError *error = NULL;
+ gchar *path;
+
+ pidgin_debug_init();
+
+ display = gdk_display_get_default();
+ theme = gtk_icon_theme_get_for_display(display);
+
+ path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons", NULL);
+ gtk_icon_theme_add_search_path(theme, path);
+ g_free(path);
+
+ /* Add a callback for when a protocol is registered to add its icon paths
+ * if it was found after initial startup.
+ */
+ protocol_manager = purple_protocol_manager_get_default();
+ g_signal_connect(protocol_manager, "registered",
+ G_CALLBACK(pidgin_ui_protocol_registered_cb), NULL);
+
+ /* Add the icon paths for all the protocols that libpurple found at start
+ * up.
+ */
+ purple_protocol_manager_foreach(protocol_manager,
+ pidgin_ui_protocol_foreach_theme_cb, NULL);
+
+ if(!pidgin_history_init(&error)) {
+ g_critical("failed to initialize the history api: %s",
+ error != NULL ? error->message : "unknown");
+ g_clear_error(&error);
+ }
+
+ /* Set the UI operation structures. */
+ purple_xfers_set_ui_ops(pidgin_xfers_get_ui_ops());
+ purple_blist_set_ui(PIDGIN_TYPE_BUDDY_LIST);
+ purple_notify_set_ui_ops(pidgin_notify_get_ui_ops());
+ purple_request_set_ui_ops(pidgin_request_get_ui_ops());
+ purple_connections_set_ui_ops(pidgin_connections_get_ui_ops());
+ purple_whiteboard_set_ui_ops(pidgin_whiteboard_get_ui_ops());
+ purple_idle_set_ui(pidgin_idle_new());
+
+ pidgin_accounts_init();
+ pidgin_connection_init();
+ pidgin_request_init();
+ pidgin_blist_init();
+ pidgin_conversations_init();
+ pidgin_commands_init();
+ pidgin_privacy_init();
+ pidgin_xfers_init();
+ pidgin_roomlist_init();
+ pidgin_medias_init();
+ pidgin_notify_init();
+}
+
+static void
+pidgin_ui_stop(G_GNUC_UNUSED PurpleUi *ui) {
+ /* Be sure to close all windows that are not attached to anything
+ * (e.g., the debug window), or they may access things after they are
+ * shut down. */
+ pidgin_notify_uninit();
+ pidgin_commands_uninit();
+ pidgin_conversations_uninit();
+ pidgin_blist_uninit();
+ pidgin_request_uninit();
+ pidgin_connection_uninit();
+ pidgin_accounts_uninit();
+ pidgin_xfers_uninit();
+ pidgin_debug_window_hide();
+ pidgin_debug_uninit();
+
+ /* and end it all... */
+ g_application_quit(g_application_get_default());
+}
+
+static gpointer
+pidgin_ui_get_settings_backend(G_GNUC_UNUSED PurpleUi *ui) {
+ GSettingsBackend *backend = NULL;
+ char *config = NULL;
+
+ config = g_build_filename(purple_config_dir(), "pidgin3.ini", NULL);
+ backend = g_keyfile_settings_backend_new(config, "/", NULL);
+
+ g_free(config);
+
+ return backend;
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+pidgin_ui_init(G_GNUC_UNUSED PidginUi *ui) {
+}
+
+static void
+pidgin_ui_class_init(PidginUiClass *klass) {
+ PurpleUiClass *ui_class = PURPLE_UI_CLASS(klass);
+
+ ui_class->prefs_init = pidgin_ui_prefs_init;
+ ui_class->start = pidgin_ui_start;
+ ui_class->stop = pidgin_ui_stop;
+ ui_class->get_settings_backend = pidgin_ui_get_settings_backend;
+}
+
+/******************************************************************************
+ * Public UI
+ *****************************************************************************/
+PurpleUi *
+pidgin_ui_new(void) {
+ return g_object_new(
+ PIDGIN_TYPE_UI,
+ "id", "pidgin3",
+ "name", PIDGIN_NAME,
+ "version", VERSION,
+ "website", "https://pidgin.im",
+ "support-website", "https://pidgin.im/contact/",
+ "client-type", "pc",
+ NULL);
+}
diff --git a/pidgin/pidginui.h b/pidgin/pidginui.h
new file mode 100644
index 0000000000..915b165610
--- /dev/null
+++ b/pidgin/pidginui.h
@@ -0,0 +1,60 @@
+/*
+ * Pidgin - Internet Messenger
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Pidgin 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(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION)
+# error "only <pidgin.h> may be included directly"
+#endif
+
+#ifndef PIDGIN_UI_H
+#define PIDGIN_UI_H
+
+#include <glib.h>
+
+#include <purple.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PidginUi:
+ *
+ * Is a subclass of [class@Purple.Ui] that identifies Pidgin to libpurple.
+ *
+ * Since: 3.0.0
+ */
+
+#define PIDGIN_TYPE_UI (pidgin_ui_get_type())
+G_DECLARE_FINAL_TYPE(PidginUi, pidgin_ui, PIDGIN, UI, PurpleUi)
+
+/**
+ * pidgin_ui_new:
+ *
+ * Creates the new [class@Pidgin.Ui] instance.
+ *
+ * Note: there's not much use for this outside of Pidgin's internal code.
+ *
+ * Returns: (transfer full): The new instance.
+ */
+PurpleUi *pidgin_ui_new(void);
+
+G_END_DECLS
+
+#endif /* PIDGIN_UI_H */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e7ae75de87..b7b6681a4b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -188,7 +188,6 @@ libpurple/purplecontact.c
libpurple/purpleconversation.c
libpurple/purpleconversationmanager.c
libpurple/purpleconversationuiops.c
-libpurple/purplecoreuiops.c
libpurple/purplecredentialmanager.c
libpurple/purplecredentialprovider.c
libpurple/purpledebugui.c
@@ -219,7 +218,7 @@ libpurple/purpleprotocolroomlist.c
libpurple/purpleprotocolserver.c
libpurple/purpleprotocolwhiteboard.c
libpurple/purplesqlitehistoryadapter.c
-libpurple/purpleuiinfo.c
+libpurple/purpleui.c
libpurple/purplewhiteboard.c
libpurple/purplewhiteboardmanager.c
libpurple/purplewhiteboarduiops.c