diff --git a/libpurple/core.h b/libpurple/core.h
--- a/libpurple/core.h
+++ b/libpurple/core.h
@@ -36,52 +36,13 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include <libpurple/purpleuiinfo.h>
-
-#define PURPLE_TYPE_CORE_UI_OPS (purple_core_ui_ops_get_type())
+#include <libpurple/purplecoreuiops.h>
 
 typedef struct PurpleCore PurpleCore;
-typedef struct _PurpleCoreUiOps PurpleCoreUiOps;
-
-/**
- * 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_ui_info:   Called by purple_core_get_ui_info(); should return the
- *                 information documented there.
- *
- * 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
-{
-	void (*ui_prefs_init)(void);
-	void (*ui_init)(void);
-
-	void (*quit)(void);
-
-	PurpleUiInfo *(*get_ui_info)(void);
-
-	/*< private >*/
-	gpointer reserved[4];
-};
 
 G_BEGIN_DECLS
 
 /**
- * purple_core_ui_ops_get_type:
- *
- * Returns: The #GType for the #PurpleCoreUiOps boxed structure.
- */
-GType purple_core_ui_ops_get_type(void);
-
-/**
  * purple_core_init:
  * @ui: The ID of the UI using the core. This should be a
  *           unique ID, registered with the purple team.
# HG changeset patch
# Node ID 649de7d69a14
# Parent  d861b10105fb
diff --git a/libpurple/core.c b/libpurple/core.c
--- a/libpurple/core.c
+++ b/libpurple/core.c
@@ -296,33 +296,6 @@
 	return _core;
 }
 
-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;
-}
-
 void
 purple_core_set_ui_ops(PurpleCoreUiOps *ops)
 {
diff --git a/libpurple/meson.build b/libpurple/meson.build
--- a/libpurple/meson.build
+++ b/libpurple/meson.build
@@ -48,6 +48,7 @@
 	'purpleconversation.c',
 	'purpleconversationmanager.c',
 	'purpleconversationuiops.c',
+	'purplecoreuiops.c',
 	'purplecredentialmanager.c',
 	'purplecredentialprovider.c',
 	'purpledebugui.c',
@@ -142,6 +143,7 @@
 	'purpleconversation.h',
 	'purpleconversationmanager.h',
 	'purpleconversationuiops.h',
+	'purplecoreuiops.h',
 	'purplecredentialmanager.h',
 	'purplecredentialprovider.h',
 	'purpledebugui.h',
diff --git a/libpurple/purplecoreuiops.h b/libpurple/purplecoreuiops.h
new file mode 100644
--- /dev/null
+++ b/libpurple/purplecoreuiops.h
@@ -0,0 +1,75 @@
+/*
+ * 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_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_ui_info:   Called by purple_core_get_ui_info(); should return the
+ *                 information documented there.
+ *
+ * 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
+{
+	void (*ui_prefs_init)(void);
+	void (*ui_init)(void);
+
+	void (*quit)(void);
+
+	PurpleUiInfo *(*get_ui_info)(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/purplecoreuiops.c b/libpurple/purplecoreuiops.c
new file mode 100644
--- /dev/null
+++ b/libpurple/purplecoreuiops.c
@@ -0,0 +1,48 @@
+/*
+ * 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/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -239,6 +239,7 @@
 libpurple/purplechatuser.c
 libpurple/purpleconversation.c
 libpurple/purpleconversationmanager.c
+libpurple/purplecoreuiops.c
 libpurple/purplecredentialmanager.c
 libpurple/purplecredentialprovider.c
 libpurple/purpledebugui.c
