File pidgin-2.14.14-mingw-fixes.patch of Package mingw64-pidgin

# HG changeset patch
# User Ralf Habacker <ralf.habacker@freenet.de>
# Date 1761681841 -3600
#      Tue Oct 28 21:04:01 2025 +0100
# Branch release-2.x.y
# Node ID 61d53322cfd35eb3c17bff48d741f24e94db1d20
# Parent  eb22b625ecadbe889f2c1b4aad58813517981c2e
Apply changes required for mingw

diff -r eb22b625ecad -r 61d53322cfd3 configure.ac
--- a/configure.ac	Wed Jan 22 20:47:54 2025 -0600
+++ b/configure.ac	Tue Oct 28 21:04:01 2025 +0100
@@ -43,7 +43,7 @@
 
 AC_CANONICAL_HOST
 AC_CONFIG_HEADERS([config.h])
-AM_INIT_AUTOMAKE([1.9 -Wno-portability dist-bzip2])
+AM_INIT_AUTOMAKE([1.9 -Wno-portability dist-bzip2 subdir-objects])
 dnl TODO: Always use AM_SILENT_RULES when we depend on automake >= 1.11
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
@@ -77,10 +77,44 @@
 dnl Check for Sun compiler
 AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
 
+dnl ******************************
+dnl Win32
+dnl ******************************
+AC_MSG_CHECKING([for Win32])
+case "$host" in
+*-mingw*)
+	os_win32=yes
+	not_os_win32=no
+	NO_UNDEFINED='-no-undefined'
+	AVOID_VERSION='-avoid-version'
+	AC_CHECK_TOOL(WINDRES, windres)
+	PURPLE_LIBS='$(top_builddir)/libpurple/libpurple.la'
+	PIDGIN_LIBS='$(top_builddir)/pidgin/libpidgin.la'
+	;;
+*)
+	os_win32=no
+	not_os_win32=yes
+	NO_UNDEFINED=
+	AVOID_VERSION=
+	PURPLE_LIBS=
+	PIDGIN_LIBS=
+	;;
+esac
+AC_MSG_RESULT([$os_win32])
+AM_CONDITIONAL(OS_WIN32, [test $os_win32 = yes])
+AC_SUBST(NO_UNDEFINED)
+AC_SUBST(AVOID_VERSION)
+AC_SUBST(PURPLE_LIBS)
+AC_SUBST(PIDGIN_LIBS)
+
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h signal.h stdint.h regex.h)
+AC_CHECK_HEADERS(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h stdint.h)
+dnl signal.h is not good in mingw
+if test "$os_win32" != yes; then
+	AC_CHECK_HEADERS(signal.h regex.h)
+fi
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -105,6 +139,7 @@
 	AC_LIBOBJ(getopt1)
 ])
 
+if test "$os_win32" != yes; then
 dnl Check for inet_aton
 AC_CHECK_FUNC(inet_aton, , [AC_CHECK_LIB(resolv, inet_aton, ,
 				         [AC_MSG_ERROR([inet_aton not found])])])
@@ -112,6 +147,8 @@
 AC_CHECK_LIB(nsl, gethostent)
 AC_CHECK_FUNC(socket, ,
 	[AC_CHECK_LIB(socket, socket, , [AC_MSG_ERROR([socket not found])])])
+fi
+
 dnl If all goes well, by this point the previous two checks will have
 dnl pulled in -lsocket and -lnsl if we need them.
 AC_CHECK_FUNC(getaddrinfo,
@@ -121,6 +158,8 @@
 		[AC_DEFINE([HAVE_GETADDRINFO]) LIBS="-lsocket -lsnl $LIBS"], , , -lnsl)])
 AC_CHECK_FUNCS(inet_ntop)
 AC_CHECK_FUNCS(getifaddrs)
+
+if test "$os_win32" != yes; then
 dnl Check for socklen_t (in Unix98)
 AC_MSG_CHECKING(for socklen_t)
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -142,6 +181,7 @@
 		AC_DEFINE(socklen_t, int, [socklen_t size])
 	])
 ])
+fi
 
 dnl Some systems do not have sa_len field for struct sockaddr.
 AC_CHECK_MEMBER([struct sockaddr.sa_len],
@@ -292,6 +332,18 @@
 AM_CONDITIONAL(INSTALL_I18N, test "x$enable_i18n" = "xyes")
 
 dnl #######################################################################
+dnl # Check for Zlib
+dnl #######################################################################
+PKG_CHECK_MODULES([ZLIB],[zlib],[],[
+	AC_CHECK_HEADER(zlib.h, [ZLIB_CFLAGS=],
+		[AC_MSG_ERROR(zlib.h not found. install zlib)], [])
+	AC_CHECK_LIB(z, inflate, [ ZLIB_LIBS=-lz ],
+		[AC_MSG_ERROR(zlib not found or functional)], [])
+])
+AC_SUBST(ZLIB_CFLAGS)
+AC_SUBST(ZLIB_LIBS)
+
+dnl #######################################################################
 dnl # Check for GLib 2.16 (required)
 dnl #######################################################################
 PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [
@@ -306,8 +358,10 @@
 AC_SUBST(GLIB_CFLAGS)
 AC_SUBST(GLIB_LIBS)
 
+if test "$os_win32" != yes; then
 PKG_CHECK_MODULES(GIO_UNIX, [gio-unix-2.0 >= 2.26],
 			    AC_DEFINE(HAVE_GIOUNIX, 1, [Have gio-unix]), [])
+fi
 
 GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
 AC_SUBST(GLIB_GENMARSHAL)
@@ -1213,7 +1267,7 @@
 AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
 AM_CONDITIONAL(STATIC_SILC, test "x$static_silc" = "xyes" -a "x$have_silc" = "xyes")
 AM_CONDITIONAL(STATIC_SIMPLE, test "x$static_simple" = "xyes")
-AM_CONDITIONAL(STATIC_ZEPHYR, test "x$static_zephyr" = "xyes")
+AM_CONDITIONAL(STATIC_ZEPHYR, test "x$static_zephyr" = "xyes" -a "x$enable_zephyr" = "xyes")
 AC_SUBST(STATIC_LINK_LIBS)
 AC_DEFINE_UNQUOTED(STATIC_PROTO_INIT, $extern_init static void static_proto_init(void) { $load_proto },
 	[Loads static protocol plugin module initialization functions.])
@@ -1234,6 +1288,10 @@
 if test "x$silc10includes" != "xyes" -o "x$silc10client" != "xyes"; then
 	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc10//'`
 fi
+if test "x$enable_zephyr" != "xyes"; then
+	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/zephyr//'`
+fi
+
 AC_SUBST(DYNAMIC_PRPLS)
 for i in $DYNAMIC_PRPLS ; do
 	case $i in
@@ -2578,6 +2636,10 @@
 		   pidgin/plugins/perl/Makefile
 		   pidgin/plugins/perl/common/Makefile.PL
 		   pidgin/plugins/ticker/Makefile
+		   pidgin/plugins/win32/Makefile
+		   pidgin/plugins/win32/winprefs/Makefile
+		   pidgin/win32/pidgin_dll_rc.rc
+		   pidgin/win32/pidgin_exe_rc.rc
 		   libpurple/data/gconf/Makefile
 		   libpurple/data/purple.pc
 		   libpurple/data/purple-uninstalled.pc
@@ -2610,6 +2672,7 @@
 		   libpurple/tests/Makefile
 		   libpurple/purple.h
 		   libpurple/version.h
+		   libpurple/win32/libpurplerc.rc
 		   share/sounds/Makefile
 		   share/ca-certs/Makefile
 		   finch/finch.pc
diff -r eb22b625ecad -r 61d53322cfd3 finch/Makefile.am
--- a/finch/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/finch/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -79,9 +79,9 @@
 
 AM_CPPFLAGS = \
 	-DSTANDALONE \
-	-DGNTSEAL_ENABLE \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-DDATADIR=\"$(datadir)\" \
-	-DLIBDIR=\"$(libdir)/finch/\" \
+	-DLIBDIR=\"$(libdir)/finch/\" \	
 	-DLOCALEDIR=\"$(datadir)/locale\" \
 	-DSYSCONFDIR=\"$(sysconfdir)\" \
 	-I$(top_srcdir)/libpurple/ \
diff -r eb22b625ecad -r 61d53322cfd3 finch/finch.c
--- a/finch/finch.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/finch/finch.c	Tue Oct 28 21:04:01 2025 +0100
@@ -378,7 +378,7 @@
 	purple_plugins_add_search_path(path);
 	g_free(path);
 
-	purple_plugins_add_search_path(LIBDIR);
+	purple_plugins_add_search_path(FINCH_LIBDIR);
 
 	if (!purple_core_init(FINCH_UI))
 	{
diff -r eb22b625ecad -r 61d53322cfd3 finch/gntsound.c
--- a/finch/gntsound.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/finch/gntsound.c	Tue Oct 28 21:04:01 2025 +0100
@@ -616,7 +616,7 @@
 		if (!filename || !strlen(filename)) {
 			g_free(filename);
 			/* XXX Consider creating a constant for "sounds/purple" to be shared with Pidgin */
-			filename = g_build_filename(DATADIR, "sounds", "purple", sounds[event].def, NULL);
+			filename = g_build_filename(PURPLE_DATADIR, "sounds", "purple", sounds[event].def, NULL);
 		}
 
 		purple_sound_play_file(filename, NULL);
diff -r eb22b625ecad -r 61d53322cfd3 finch/libgnt/wms/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/libgnt/wms/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,40 @@
+wms = irssi.la
+if PURPLE_AVAILABLE
+# These custom wms depend on libpurple
+purple_wms = s.la
+else
+purple_wms =
+endif
+
+s_la_LDFLAGS             = -module -avoid-version
+irssi_la_LDFLAGS         = -module -avoid-version
+
+plugin_LTLIBRARIES = \
+	$(wms) \
+	$(purple_wms)
+ 
+plugindir = $(libdir)/gnt
+
+irssi_la_SOURCES = irssi.c
+irssi_la_LIBADD =  \
+  $(GLIB_LIBS) \
+  ../libgnt.la
+
+s_la_SOURCES = s.c
+s_la_LIBADD =  \
+  $(GLIB_LIBS) \
+  ../libgnt.la \
+  $(top_builddir)/libpurple/libpurple.la
+
+EXTRA_DIST = 
+
+AM_CPPFLAGS = \
+	-DPURPLE_DATADIR=\"$(datadir)\"
+	-I$(top_srcdir)/libpurple \
+	-I$(top_srcdir)/finch \
+	-I$(top_srcdir)/finch/libgnt \
+	$(DEBUG_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	$(GNT_CFLAGS) \
+	$(PLUGIN_CFLAGS)
+
diff -r eb22b625ecad -r 61d53322cfd3 finch/plugins/Makefile.am
--- a/finch/plugins/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/finch/plugins/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -39,7 +39,7 @@
 EXTRA_DIST = pietray.py
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_srcdir) \
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/Makefile.am
--- a/libpurple/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -15,21 +15,25 @@
 		data/purple-uninstalled.pc.in \
 		win32/global.mak \
 		win32/libc_interface.c \
-		win32/libc_interface.h \
-		win32/libc_internal.h \
 		win32/libpurplerc.rc.in \
 		win32/rules.mak \
 		win32/targets.mak \
+		win32/win32dep.c \
+		win32/giowin32.c
+		
+if !OS_WIN32
+EXTRA_DIST += \
+		win32/libc_interface.h \
+		win32/libc_internal.h \
 		win32/wpurpleerror.h \
-		win32/win32dep.c \
-		win32/giowin32.c \
 		win32/win32dep.h
+endif
 
 if USE_GCONFTOOL
 GCONF_DIR=data/gconf
 endif
 
-SUBDIRS = $(GCONF_DIR) plugins protocols ciphers . fuzzers tests example
+SUBDIRS = $(GCONF_DIR) ciphers . plugins protocols tests example
 
 purple_coresources = \
 	account.c \
@@ -94,6 +98,20 @@
 	xmlnode.c \
 	whiteboard.c
 
+if OS_WIN32
+purple_coresources += \
+	win32/giowin32.c \
+	win32/libc_interface.c \
+	win32/win32dep.c
+
+libpurple_win32_res = libpurple-win32-res.o
+libpurple_win32_res_ldflag = -Wl,$(libpurple_win32_res)
+
+libpurple-win32-res.o: win32/libpurplerc.rc
+	$(WINDRES) -I$(top_srcdir)/libpurple -i $< -o $@
+
+endif
+
 purple_builtsources = \
 	marshallers.c
 
@@ -164,6 +182,14 @@
 	codec.h \
 	enum-types.h
 
+if OS_WIN32
+purple_win32headers = \
+	libc_interface.h \
+	libc_internal.h \
+	wpurpleerror.h \
+	win32dep.h
+endif
+
 purple_builtheaders = purple.h version.h marshallers.h
 
 marshallers.h: marshallers.list
@@ -298,8 +324,15 @@
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = data/purple.pc
 
-libpurple_la_DEPENDENCIES = $(STATIC_LINK_LIBS)
-libpurple_la_LDFLAGS = -export-dynamic -version-info $(PURPLE_LT_VERSION_INFO) -no-undefined
+if OS_WIN32
+win32includedir=$(includedir)/libpurple/win32
+win32include_HEADERS = \
+	$(addprefix $(srcdir)/win32/, $(purple_win32headers))
+endif
+
+libpurple_la_DEPENDENCIES = $(STATIC_LINK_LIBS) $(libpurple_win32_res)
+libpurple_la_LDFLAGS = -export-dynamic -version-info $(PURPLE_LT_VERSION_INFO) $(AVOID_VERSION) \
+	$(NO_UNDEFINED) $(libpurple_win32_res_ldflag)
 libpurple_la_LIBADD = \
 	$(STATIC_LINK_LIBS) \
 	$(DBUS_LIBS) \
@@ -316,9 +349,14 @@
 	$(LIBM) \
 	ciphers/libpurple-ciphers.la
 
+if OS_WIN32
+libpurple_la_LIBADD += \
+	-lws2_32 -ldnsapi
+endif
+
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
-	-DLIBDIR=\"$(libdir)/purple-$(PURPLE_MAJOR_VERSION)/\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
+	-DPURPLE_LIBDIR=\"$(libdir)/purple-$(PURPLE_MAJOR_VERSION)/\" \
 	-DLOCALEDIR=\"$(datadir)/locale\" \
 	-DSYSCONFDIR=\"$(sysconfdir)\" \
 	$(GLIB_CFLAGS) \
@@ -333,6 +371,12 @@
 	$(IDN_CFLAGS) \
 	$(NETWORKMANAGER_CFLAGS)
 
+if OS_WIN32
+AM_CPPFLAGS += \
+	-DUSE_FHS \
+	-I$(top_srcdir)/libpurple/win32
+endif
+
 # INSTALL_SSL_CERTIFICATES is true when SSL_CERTIFICATES_DIR is empty.
 # We want to use SSL_CERTIFICATES_DIR when it's not empty.
 if ! INSTALL_SSL_CERTIFICATES
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/certificate.c
--- a/libpurple/certificate.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/certificate.c	Tue Oct 28 21:04:01 2025 +0100
@@ -921,15 +921,15 @@
 {
 	/* Attempt to point at the appropriate system path */
 	if (NULL == x509_ca_paths) {
-#ifdef _WIN32
-		x509_ca_paths = g_list_append(NULL, g_build_filename(DATADIR,
+#if defined(_WIN32) && !defined(USE_FHS)
+		x509_ca_paths = g_list_append(NULL, g_build_filename(PURPLE_DATADIR,
 						   "ca-certs", NULL));
 #else
 # ifdef SSL_CERTIFICATES_DIR
 		x509_ca_paths = g_list_append(NULL, g_strdup(SSL_CERTIFICATES_DIR));
 # endif
 		x509_ca_paths = g_list_append(x509_ca_paths,
-			g_build_filename(DATADIR, "purple", "ca-certs", NULL));
+			g_build_filename(PURPLE_DATADIR, "purple", "ca-certs", NULL));
 #endif
 	}
 
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/data/purple.pc.in
--- a/libpurple/data/purple.pc.in	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/data/purple.pc.in	Tue Oct 28 21:04:01 2025 +0100
@@ -13,5 +13,5 @@
 Description: libpurple is a GLib-based instant messenger library.
 Version: @VERSION@
 Requires: glib-2.0
-Cflags: -I${includedir}/libpurple
+Cflags: -I${includedir}/libpurple -I${includedir}/libpurple/win32
 Libs: -L${libdir} -lpurple
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/dnsquery.c
--- a/libpurple/dnsquery.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/dnsquery.c	Tue Oct 28 21:04:01 2025 +0100
@@ -746,7 +746,8 @@
 
 	query_data = data;
 
-#ifdef USE_IDN
+	
+#if defined(USE_IDN) && defined(HAVE_GETADDRINFO)
 	if (!dns_str_is_ascii(query_data->hostname)) {
 		rc = purple_network_convert_idn_to_ascii(query_data->hostname, &hostname);
 		if (rc != 0) {
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/example/Makefile.am
--- a/libpurple/example/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/example/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -12,11 +12,9 @@
 	$(top_builddir)/libpurple/libpurple.la
 
 AM_CPPFLAGS = \
-	-DSTANDALONE \
-	-DDATADIR=\"$(datadir)\" \
-	-DLIBDIR=\"$(libdir)/purple-$(PURPLE_MAJOR_VERSION)/\" \
 	-DLOCALEDIR=\"$(datadir)/locale\" \
 	-DSYSCONFDIR=\"$(sysconfdir)\" \
+	-DSTANDALONE \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_srcdir) \
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/example/nullclient.c
--- a/libpurple/example/nullclient.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/example/nullclient.c	Tue Oct 28 21:04:01 2025 +0100
@@ -308,7 +308,11 @@
 	account = purple_account_new(name, prpl);
 
 	/* Get the password for the account */
+#ifndef _WIN32
 	password = getpass("Password: ");
+#else
+	password = "password";
+#endif
 	purple_account_set_password(account, password);
 
 	/* It's necessary to enable the account first. */
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/plugin.c
--- a/libpurple/plugin.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/plugin.c	Tue Oct 28 21:04:01 2025 +0100
@@ -1186,7 +1186,7 @@
 purple_plugins_init(void) {
 	void *handle = purple_plugins_get_handle();
 
-	purple_plugins_add_search_path(LIBDIR);
+	purple_plugins_add_search_path(PURPLE_LIBDIR);
 
 	purple_signal_register(handle, "plugin-load",
 						 purple_marshal_VOID__POINTER,
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/plugins/Makefile.am
--- a/libpurple/plugins/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/plugins/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -24,27 +24,27 @@
 
 plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
 
-autoaccept_la_LDFLAGS       = -module -avoid-version
-buddynote_la_LDFLAGS        = -module -avoid-version
-ciphertest_la_LDFLAGS		= -module -avoid-version
-codeinline_la_LDFLAGS		= -module -avoid-version
-debug_example_la_LDFLAGS    = -module -avoid-version
-helloworld_la_LDFLAGS       = -module -avoid-version
-idle_la_LDFLAGS             = -module -avoid-version
-joinpart_la_LDFLAGS         = -module -avoid-version
-log_reader_la_LDFLAGS       = -module -avoid-version
-newline_la_LDFLAGS          = -module -avoid-version
-notify_example_la_LDFLAGS   = -module -avoid-version
-offlinemsg_la_LDFLAGS       = -module -avoid-version
-one_time_password_la_LDFLAGS	= -module -avoid-version
-pluginpref_example_la_LDFLAGS = -module -avoid-version
-psychic_la_LDFLAGS          = -module -avoid-version
-signals_test_la_LDFLAGS		= -module -avoid-version
-simple_la_LDFLAGS			= -module -avoid-version
-statenotify_la_LDFLAGS      = -module -avoid-version
+autoaccept_la_LDFLAGS       = -module -avoid-version $(NO_UNDEFINED)
+buddynote_la_LDFLAGS        = -module -avoid-version $(NO_UNDEFINED)
+ciphertest_la_LDFLAGS		= -module -avoid-version $(NO_UNDEFINED)
+codeinline_la_LDFLAGS		= -module -avoid-version $(NO_UNDEFINED)
+debug_example_la_LDFLAGS    = -module -avoid-version $(NO_UNDEFINED)
+helloworld_la_LDFLAGS       = -module -avoid-version $(NO_UNDEFINED)
+idle_la_LDFLAGS             = -module -avoid-version $(NO_UNDEFINED)
+joinpart_la_LDFLAGS         = -module -avoid-version $(NO_UNDEFINED)
+log_reader_la_LDFLAGS       = -module -avoid-version $(NO_UNDEFINED)
+newline_la_LDFLAGS          = -module -avoid-version $(NO_UNDEFINED)
+notify_example_la_LDFLAGS   = -module -avoid-version $(NO_UNDEFINED)
+offlinemsg_la_LDFLAGS       = -module -avoid-version $(NO_UNDEFINED)
+one_time_password_la_LDFLAGS	= -module -avoid-version $(NO_UNDEFINED)
+pluginpref_example_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+psychic_la_LDFLAGS          = -module -avoid-version $(NO_UNDEFINED)
+signals_test_la_LDFLAGS		= -module -avoid-version $(NO_UNDEFINED)
+simple_la_LDFLAGS			= -module -avoid-version $(NO_UNDEFINED)
+statenotify_la_LDFLAGS      = -module -avoid-version $(NO_UNDEFINED)
 
 # this can't be in a conditional otherwise automake 1.4 yells
-dbus_example_la_LDFLAGS     = -module -avoid-version
+dbus_example_la_LDFLAGS     = -module -avoid-version $(NO_UNDEFINED)
 
 if PLUGINS
 
@@ -90,29 +90,30 @@
 simple_la_SOURCES			= simple.c
 statenotify_la_SOURCES      = statenotify.c
 
-autoaccept_la_LIBADD        = $(GLIB_LIBS)
-buddynote_la_LIBADD         = $(GLIB_LIBS)
-ciphertest_la_LIBADD		= $(GLIB_LIBS)
-codeinline_la_LIBADD		= $(GLIB_LIBS)
-idle_la_LIBADD              = $(GLIB_LIBS)
-joinpart_la_LIBADD          = $(GLIB_LIBS)
-log_reader_la_LIBADD        = $(GLIB_LIBS)
-newline_la_LIBADD           = $(GLIB_LIBS)
-notify_example_la_LIBADD    = $(GLIB_LIBS)
-offlinemsg_la_LIBADD        = $(GLIB_LIBS)
-one_time_password_la_LIBADD = $(GLIB_LIBS)
-pluginpref_example_la_LIBADD = $(GLIB_LIBS)
-psychic_la_LIBADD           = $(GLIB_LIBS)
-signals_test_la_LIBADD		= $(GLIB_LIBS)
-simple_la_LIBADD			= $(GLIB_LIBS)
-statenotify_la_LIBADD       = $(GLIB_LIBS)
+
+autoaccept_la_LIBADD        = $(GLIB_LIBS) $(PURPLE_LIBS)
+buddynote_la_LIBADD         = $(GLIB_LIBS) $(PURPLE_LIBS)
+ciphertest_la_LIBADD		= $(GLIB_LIBS) $(PURPLE_LIBS)
+codeinline_la_LIBADD		= $(GLIB_LIBS) $(PURPLE_LIBS)
+idle_la_LIBADD              = $(GLIB_LIBS) $(PURPLE_LIBS)
+joinpart_la_LIBADD          = $(GLIB_LIBS) $(PURPLE_LIBS)
+log_reader_la_LIBADD        = $(GLIB_LIBS) $(PURPLE_LIBS)
+newline_la_LIBADD           = $(GLIB_LIBS) $(PURPLE_LIBS)
+notify_example_la_LIBADD    = $(GLIB_LIBS) $(PURPLE_LIBS)
+offlinemsg_la_LIBADD        = $(GLIB_LIBS) $(PURPLE_LIBS)
+one_time_password_la_LIBADD = $(GLIB_LIBS) $(PURPLE_LIBS)
+pluginpref_example_la_LIBADD = $(GLIB_LIBS) $(PURPLE_LIBS)
+psychic_la_LIBADD           = $(GLIB_LIBS) $(PURPLE_LIBS)
+signals_test_la_LIBADD		= $(GLIB_LIBS) $(PURPLE_LIBS)
+simple_la_LIBADD			= $(GLIB_LIBS) $(PURPLE_LIBS)
+statenotify_la_LIBADD       = $(GLIB_LIBS) $(PURPLE_LIBS)
 
 if ENABLE_DBUS
 
 CLEANFILES              = dbus-example-bindings.c
 dbus_example_la_SOURCES = dbus-example.c
 
-dbus_example_la_LIBADD      = $(GLIB_LIBS) $(DBUS_LIBS)
+dbus_example_la_LIBADD      = $(GLIB_LIBS) $(DBUS_LIBS) $(PURPLE_LIBS)
 
 .PHONY: always
 
@@ -140,7 +141,7 @@
 	startup.py
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	$(DEBUG_CFLAGS) \
@@ -148,6 +149,11 @@
 	$(PLUGIN_CFLAGS) \
 	$(DBUS_CFLAGS)
 
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
+
 #
 # This part allows people to build their own plugins in here.
 # Yes, it's a mess.
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/plugins/perl/Makefile.am
--- a/libpurple/plugins/perl/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/plugins/perl/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -165,7 +165,6 @@
 	-I$(top_srcdir) \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
-	-DLIBDIR=\"$(libdir)/purple-$(PURPLE_MAJOR_VERSION)\" \
 	$(DEBUG_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(PLUGIN_CFLAGS) \
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/plugins/ssl/Makefile.am
--- a/libpurple/plugins/ssl/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/plugins/ssl/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -3,10 +3,10 @@
 
 plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
 
-ssl_la_LDFLAGS        = -module -avoid-version
-ssl_gnutls_la_LDFLAGS = -module -avoid-version
-ssl_nss_la_LDFLAGS    = -module -avoid-version
-nss_prefs_la_LDFLAGS  = -module -avoid-version
+ssl_la_LDFLAGS        = -module -avoid-version $(NO_UNDEFINED)
+ssl_gnutls_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+ssl_nss_la_LDFLAGS    = -module -avoid-version $(NO_UNDEFINED)
+nss_prefs_la_LDFLAGS  = -module -avoid-version $(NO_UNDEFINED)
 
 if PLUGINS
 
@@ -43,15 +43,15 @@
 ssl_nss_la_SOURCES    = ssl-nss.c
 nss_prefs_la_SOURCES  = nss-prefs.c
 
-ssl_la_LIBADD        = $(GLIB_LIBS)
-ssl_gnutls_la_LIBADD = $(GLIB_LIBS) $(GNUTLS_LIBS)
-ssl_nss_la_LIBADD    = $(GLIB_LIBS) $(NSS_LIBS)
-nss_prefs_la_LIBADD  = $(GLIB_LIBS) $(NSS_LIBS)
+ssl_la_LIBADD        = $(GLIB_LIBS) $(PURPLE_LIBS)
+ssl_gnutls_la_LIBADD = $(GLIB_LIBS) $(GNUTLS_LIBS) $(PURPLE_LIBS)
+ssl_nss_la_LIBADD    = $(GLIB_LIBS) $(NSS_LIBS) $(PURPLE_LIBS)
+nss_prefs_la_LIBADD  = $(GLIB_LIBS) $(NSS_LIBS) $(PURPLE_LIBS)
 
 endif # PLUGINS
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-DLIBDIR=\"$(libdir)/libpurple\" \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
@@ -59,6 +59,12 @@
 	$(GLIB_CFLAGS) \
 	$(PLUGIN_CFLAGS)
 
+if OS_WIN32
+AM_CPPFLAGS += \
+	-DWIN32_LEAN_AND_MEAN \
+	-I$(top_srcdir)/libpurple/win32
+endif
+
 ssl_gnutls_la_CFLAGS = $(AM_CPPFLAGS) $(GNUTLS_CFLAGS)
 ssl_nss_la_CFLAGS = $(AM_CPPFLAGS) $(NSS_CFLAGS)
 nss_prefs_la_CFLAGS = $(AM_CPPFLAGS) $(NSS_CFLAGS)
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/plugins/tcl/Makefile.am
--- a/libpurple/plugins/tcl/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/plugins/tcl/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -1,13 +1,13 @@
 plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
 
-tcl_la_LDFLAGS = -module -avoid-version
+tcl_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 plugin_LTLIBRARIES = tcl.la
 
 tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_purple.h \
                  tcl_ref.c tcl_cmd.c
 
-tcl_la_LIBADD = $(GLIB_LIBS) $(TCL_LIBS) $(TK_LIBS)
+tcl_la_LIBADD = $(GLIB_LIBS) $(TCL_LIBS) $(TK_LIBS) $(PURPLE_LIBS)
 
 EXTRA_DIST = signal-test.tcl Makefile.mingw
 
@@ -20,3 +20,8 @@
 	$(PLUGIN_CFLAGS) \
 	$(TK_CFLAGS) \
 	$(TCL_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
\ No newline at end of file
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/bonjour/Makefile.am
--- a/libpurple/protocols/bonjour/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/bonjour/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -40,7 +40,7 @@
 st =
 pkg_LTLIBRARIES       = libbonjour.la
 libbonjour_la_SOURCES = $(BONJOURSOURCES)
-libbonjour_la_LIBADD  = $(GLIB_LIBS) $(LIBXML_LIBS) $(AVAHI_LIBS)
+libbonjour_la_LIBADD  = $(GLIB_LIBS) $(LIBXML_LIBS) $(AVAHI_LIBS) $(PURPLE_LIBS)
 
 endif
 
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/gg/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -96,6 +96,10 @@
 	$(GNUTLS_CFLAGS) \
 	-DGG_IGNORE_DEPRECATED
 
+if OS_WIN32
+INTGG_CFLAGS += -include win32dep.h
+endif
+
 endif
 
 GGSOURCES = \
@@ -113,7 +117,7 @@
 
 AM_CFLAGS = $(st)
 
-libgg_la_LDFLAGS = -module -avoid-version
+libgg_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if STATIC_GG
 
@@ -121,14 +125,14 @@
 noinst_LTLIBRARIES = libgg.la
 libgg_la_SOURCES = $(GGSOURCES)
 libgg_la_CFLAGS  = $(AM_CFLAGS)
-libgg_la_LIBADD  = $(LIBGADU_LIBS) $(INTGG_LIBS)
+libgg_la_LIBADD  = $(LIBGADU_LIBS) $(INTGG_LIBS) $(PURPLE_LIBS)
 
 else
 
 st =
 pkg_LTLIBRARIES = libgg.la
 libgg_la_SOURCES = $(GGSOURCES)
-libgg_la_LIBADD  = $(GLIB_LIBS) $(LIBGADU_LIBS) $(INTGG_LIBS)
+libgg_la_LIBADD  = $(GLIB_LIBS) $(LIBGADU_LIBS) $(INTGG_LIBS) $(PURPLE_LIBS)
 
 endif
 
@@ -139,3 +143,7 @@
 	$(INTGG_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(DEBUG_CFLAGS)
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/irc/Makefile.am
--- a/libpurple/protocols/irc/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/irc/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -13,7 +13,7 @@
 
 AM_CFLAGS = $(st)
 
-libirc_la_LDFLAGS = -module -avoid-version
+libirc_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if STATIC_IRC
 
@@ -27,7 +27,7 @@
 st =
 pkg_LTLIBRARIES   = libirc.la
 libirc_la_SOURCES = $(IRCSOURCES)
-libirc_la_LIBADD  = $(GLIB_LIBS) $(SASL_LIBS)
+libirc_la_LIBADD  = $(GLIB_LIBS) $(SASL_LIBS) $(PURPLE_LIBS)
 
 endif
 
@@ -36,3 +36,8 @@
 	-I$(top_builddir)/libpurple \
 	$(GLIB_CFLAGS) \
 	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/jabber/Makefile.am
--- a/libpurple/protocols/jabber/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/jabber/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -95,7 +95,8 @@
 
 AM_CFLAGS = $(st)
 
-libxmpp_la_LDFLAGS = -module -avoid-version
+libxmpp_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+libjabber_la_LDFLAGS = $(AVOID_VERSION) $(NO_UNDEFINED)
 
 if USE_CYRUS_SASL
 JABBERSOURCES += auth_cyrus.c
@@ -111,12 +112,20 @@
 else
 
 st =
-pkg_LTLIBRARIES      = libjabber.la libxmpp.la
+pkg_LTLIBRARIES      = libxmpp.la
+
+if OS_WIN32
+lib_LTLIBRARIES     = libjabber.la
+else
+pkg_LTLIBRARIES    += libjabber.la
+endif
+
 libjabber_la_SOURCES = $(JABBERSOURCES)
 libjabber_la_LIBADD  = $(GLIB_LIBS) $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS)\
 	$(FARSIGHT_LIBS) \
 	$(GSTREAMER_LIBS) \
-	$(GSTINTERFACES_LIBS)
+	$(GSTINTERFACES_LIBS) \
+	$(PURPLE_LIBS)
 
 libxmpp_la_SOURCES = libxmpp.c
 libxmpp_la_LIBADD = libjabber.la
@@ -133,3 +142,10 @@
 	$(FARSIGHT_CFLAGS) \
 	$(GSTREAMER_CFLAGS) \
 	$(GSTINTERFACES_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/libpurple/protocols/jabber/win32
+endif
+
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/msn/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/msn/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,107 @@
+EXTRA_DIST = \
+	directconn.c \
+	directconn.h \
+	Makefile.mingw
+
+pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+
+MSNSOURCES = \
+	cmdproc.c \
+	cmdproc.h \
+	command.c \
+	command.h \
+	contact.c\
+	contact.h\
+	directconn.c \
+	directconn.h \
+	error.c \
+	error.h \
+	group.c \
+	group.h \
+	history.c \
+	history.h \
+	httpconn.c \
+	httpconn.h \
+	msg.c \
+	msg.h \
+	msn.c \
+	msn.h \
+	nexus.c \
+	nexus.h \
+	notification.c \
+	notification.h \
+	object.c \
+	object.h \
+	oim.c\
+	oim.h\
+	p2p.c \
+	p2p.h \
+	page.c \
+	page.h \
+	servconn.c \
+	servconn.h \
+	session.c \
+	session.h \
+	slp.c \
+	slp.h \
+	slpcall.c \
+	slpcall.h \
+	slplink.c \
+	slplink.h \
+	slpmsg.c \
+	slpmsg.h \
+	slpmsg_part.c \
+	slpmsg_part.h \
+	soap.c \
+	soap.h \
+	state.c \
+	state.h \
+	sbconn.c \
+	sbconn.h \
+	switchboard.c \
+	switchboard.h \
+	table.c \
+	table.h \
+	tlv.c \
+	tlv.h \
+	transaction.c \
+	transaction.h \
+	user.c \
+	user.h \
+	userlist.c \
+	userlist.h \
+	xfer.c \
+	xfer.h \
+	msnutils.c \
+	msnutils.h
+
+AM_CFLAGS = $(st)
+
+libmsn_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+if STATIC_MSN
+
+st = -DPURPLE_STATIC_PRPL
+noinst_LTLIBRARIES = libmsn.la
+libmsn_la_SOURCES  = $(MSNSOURCES)
+libmsn_la_CFLAGS   = $(AM_CFLAGS)
+
+else
+
+st =
+pkg_LTLIBRARIES   = libmsn.la
+libmsn_la_SOURCES = $(MSNSOURCES)
+libmsn_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
+
+endif
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_builddir)/libpurple \
+	$(GLIB_CFLAGS) \
+	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/mxit/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/mxit/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,70 @@
+EXTRA_DIST = \
+	Makefile.mingw
+
+pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+
+MXITSOURCES = \
+	actions.c \
+	actions.h \
+	aes.c \
+	aes.h \
+	chunk.c \
+	chunk.h \
+	cipher.c \
+	cipher.h \
+	filexfer.c \
+	filexfer.h \
+	formcmds.c \
+	formcmds.h \
+	http.c \
+	http.h \
+	login.c \
+	login.h \
+	markup.c \
+	markup.h \
+	multimx.c \
+	multimx.h \
+	mxit.c \
+	mxit.h \
+	profile.c \
+	profile.h \
+	protocol.c \
+	protocol.h \
+	roster.c \
+	roster.h \
+	splashscreen.c \
+	splashscreen.h \
+	voicevideo.c \
+	voicevideo.h
+
+
+AM_CFLAGS = $(st)
+
+libmxit_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+if STATIC_MXIT
+
+st = -DPURPLE_STATIC_PRPL
+noinst_LTLIBRARIES = libmxit.la
+libmxit_la_SOURCES  = $(MXITSOURCES)
+libmxit_la_CFLAGS   = $(AM_CFLAGS)
+
+else
+
+st =
+pkg_LTLIBRARIES   = libmxit.la
+libmxit_la_SOURCES = $(MXITSOURCES)
+libmxit_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
+
+endif
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_builddir)/libpurple \
+	$(GLIB_CFLAGS) \
+	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/mxit/markup.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/mxit/markup.c	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,1259 @@
+/*
+ *					MXit Protocol libPurple Plugin
+ *
+ *			-- convert between MXit and libPurple markup --
+ *
+ *				Pieter Loubser	<libpurple@mxit.com>
+ *
+ *			(C) Copyright 2009	MXit Lifestyle (Pty) Ltd.
+ *				<http://www.mxitlifestyle.com>
+ *
+ * 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	"debug.h"
+
+#include	"protocol.h"
+#include	"mxit.h"
+#include	"markup.h"
+#include	"chunk.h"
+#include	"formcmds.h"
+#include	"roster.h"
+
+
+/* define this to enable emoticon (markup) debugging */
+#undef		MXIT_DEBUG_EMO
+/* define this to enable markup conversion debugging */
+#undef		MXIT_DEBUG_MARKUP
+
+
+#define		MXIT_FRAME_MAGIC		"MXF\x01"			/* mxit emoticon magic number */
+#define		MXIT_MAX_EMO_ID			16					/* maximum emoticon ID length */
+#define		COLORCODE_LEN			6					/* colour code ID length */
+
+
+/* HTML tag types */
+#define		MXIT_TAG_COLOR			0x01				/* font color tag */
+#define		MXIT_TAG_SIZE			0x02				/* font size tag */
+#define		MXIT_MAX_MSG_TAGS		90					/* maximum tags per message (pigdin hack work around) */
+
+/*
+ * a HTML tag object
+ */
+struct tag {
+	char	type;
+	char*	value;
+};
+
+
+#define		MXIT_VIBE_MSG_COLOR			"#9933FF"
+#define		MXIT_FAREWELL_MSG_COLOR		"#949494"
+
+
+/* vibes */
+static const char*	vibes[] = {
+	/* 0 */		N_( "Cool Vibrations" ),
+	/* 1 */		N_( "Purple Rain" ),
+	/* 2 */		N_( "Polite" ),
+	/* 3 */		N_( "Rock n Roll" ),
+	/* 4 */		N_( "Summer Slumber" ),
+	/* 5 */		N_( "Electric Razor" ),
+	/* 6 */		N_( "S.O.S" ),
+	/* 7 */		N_( "Jack Hammer" ),
+	/* 8 */		N_( "Bumble Bee" ),
+	/* 9 */		N_( "Ripple" )
+};
+
+
+
+#ifdef	MXIT_DEBUG_EMO
+/*------------------------------------------------------------------------
+ * Dump a byte buffer as hexadecimal to the console for debugging purposes.
+ *
+ *  @param buf				The data to dump
+ *  @param len				The length of the data
+ */
+static void hex_dump( const gchar* buf, int len )
+{
+	char		msg[256];
+	int			pos;
+	int			i;
+
+	purple_debug_info( MXIT_PLUGIN_ID, "Dumping data (%i bytes)\n", len );
+
+	memset( msg, 0x00, sizeof( msg ) );
+	pos = 0;
+
+	for ( i = 0; i < len; i++ ) {
+
+		if ( pos == 0 )
+			pos += sprintf( &msg[pos], "%04i:  ", i );
+
+		pos += sprintf( &msg[pos], "0x%02X ", buf[i] );
+
+		if ( i % 16 == 15 ) {
+			pos += sprintf( &msg[pos], "\n" );
+			purple_debug_info( MXIT_PLUGIN_ID, "%s", msg );
+			pos = 0;
+		}
+		else if ( i % 16 == 7 )
+			pos += sprintf( &msg[pos], " " );
+	}
+
+	if ( pos > 0 ) {
+		pos += sprintf( &msg[pos], "\n" );
+		purple_debug_info( MXIT_PLUGIN_ID, "%s", msg );
+		pos = 0;
+	}
+}
+#endif
+
+
+/*------------------------------------------------------------------------
+ * Adds a link to a message
+ *
+ *  @param mx				The Markup message object
+ *	@param replydata		This is the what will be returned when the link gets clicked
+ *	@param isStructured		Indicates that the reply is a structured reply
+ *	@param displaytext		This is the text for the link which will be displayed in the UI
+ */
+void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext )
+{
+#ifdef	MXIT_LINK_CLICK
+	gchar*	link	= NULL;
+	gchar*	link64	= NULL;
+
+	/*
+	 * The link content is encoded as follows:
+	 *  MXIT_LINK_KEY | ACCOUNT_USER | ACCOUNT_PROTO | REPLY_TO | REPLY_FORMAT | REPLY_DATA
+	 */
+	link = g_strdup_printf( "%s|%s|%s|%s|%i|%s",
+			MXIT_LINK_KEY,
+			purple_account_get_username( mx->session->acc ),
+			purple_account_get_protocol_id( mx->session->acc ),
+			mx->from,
+			isStructured ? 1 : 0,
+			replydata );
+	link64 = purple_base64_encode( (const unsigned char*) link, strlen( link ) );
+
+	g_string_append_printf( mx->msg, "<a href=\"%s%s\">%s</a>", MXIT_LINK_PREFIX, link64, displaytext );
+
+	g_free( link64 );
+	g_free( link );
+#else
+	g_string_append_printf( mx->msg, "<b>%s</b>", replydata );
+#endif
+}
+
+
+/*------------------------------------------------------------------------
+ * Extract an ASN.1 formatted length field from the data.
+ *
+ *  @param data				The source data
+ *  @param data_len			Length of data
+ *  @param size				The extracted length
+ *  @return					The number of bytes extracted
+ */
+static unsigned int asn_getlength( const gchar* data, gsize data_len, int* size )
+{
+	unsigned int	len		= 0;
+	unsigned char	bytes;
+	unsigned char	byte;
+	int				i;
+
+	if ( data_len < 1 ) {
+		/* missing first byte! */
+		return -1;
+	}
+
+	/* first byte specifies the number of bytes in the length */
+	bytes = ( data[0] & ~0x80 );
+	if ( bytes > sizeof( unsigned int ) ) {
+		/* file too big! */
+		return -1;
+	}
+	data++;
+
+	if ( data_len - 1 < bytes ) {
+		/* missing length! */
+		return -1;
+	}
+
+	/* parse out the actual length */
+	for ( i = 0; i < bytes; i++ ) {
+		byte = data[i];
+		len <<= 8;
+		len += byte;
+	}
+
+	*size = len;
+	return bytes + 1;
+}
+
+
+/*------------------------------------------------------------------------
+ * Extract an ASN.1 formatted UTF-8 string field from the data.
+ *
+ *  @param data				The source data
+ *  @param data_len			Length of data
+ *  @param type				Expected type of string
+ *  @param utf8				The extracted string.  Must be deallocated by caller.
+ *  @return					The number of bytes extracted
+ */
+static int asn_getUtf8( const gchar* data, gsize data_len, gchar type, char** utf8 )
+{
+	unsigned int len;
+	gchar *out_str;
+
+	if ( data_len < 2 ) {
+		/* missing type or length! */
+		return -1;
+	}
+
+	/* validate the field type [1 byte] */
+	if ( data[0] != type ) {
+		/* this is not a utf-8 string! */
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid UTF-8 encoded string in ASN data (got 0x%02X, expected 0x%02X)\n", data[0], type );
+		return -1;
+	}
+
+	len = data[1]; /* length field [1 byte] */
+	if ( data_len - 2 < len ) {
+		/* not enough bytes left in data! */
+		return -1;
+	}
+
+	out_str = g_malloc(len + 1);
+	memcpy(out_str, &data[2], len); /* data field */
+	out_str[len] = '\0';
+
+	*utf8 = out_str;
+
+	return ( len + 2 );
+}
+
+
+/*------------------------------------------------------------------------
+ * Free data associated with a Markup message object.
+ *
+ *  @param mx				The Markup message object
+ */
+static void free_markupdata( struct RXMsgData* mx )
+{
+	if ( mx ) {
+		if ( mx->msg )
+			g_string_free( mx->msg, TRUE );
+		if ( mx->from )
+			g_free( mx->from );
+		g_free( mx );
+	}
+}
+
+
+/*------------------------------------------------------------------------
+ * Split the message into smaller messages and send them one at a time
+ * to pidgin to be displayed on the UI
+ *
+ *  @param mx				The received message object
+ */
+static void mxit_show_split_message( struct RXMsgData* mx )
+{
+	GString*		msg		= NULL;
+	char*			ch		= NULL;
+	unsigned int	pos		= 0;
+	unsigned int	start	= 0;
+	unsigned int	l_nl	= 0;
+	unsigned int	l_sp	= 0;
+	unsigned int	l_gt	= 0;
+	unsigned int	stop	= 0;
+	int				tags	= 0;
+	gboolean		intag	= FALSE;
+
+	/*
+	 * awful hack to work around the awful hack in pidgin to work around GtkIMHtml's
+	 * inefficient rendering of messages with lots of formatting changes.
+	 * (reference: see the function pidgin_conv_write_conv() in gtkconv.c) the issue
+	 * is that when you have more than 100 '<' characters in the message passed to
+	 * pidgin, none of the markup (including links) are rendered and thus just dump
+	 * all the text as is to the conversation window. this message dump is very
+	 * confusing and makes it totally unusable. to work around this we will count
+	 * the amount of tags and if its more than the pidgin threshold, we will just
+	 * break the message up into smaller parts and send them separately to pidgin.
+	 * to the user it will look like multiple messages, but at least he will be able
+	 * to use and understand it.
+	 */
+
+	ch = mx->msg->str;
+	pos = start;
+	while ( ch[pos] ) {
+
+		if ( ch[pos] == '<' ) {
+			tags++;
+			intag = TRUE;
+		}
+		else if ( ch[pos] == '\n' ) {
+			l_nl = pos;
+		}
+		else if ( ch[pos] == '>' ) {
+			l_gt = pos;
+			intag = FALSE;
+		}
+		else if ( ch[pos] == ' ' ) {
+			/* ignore spaces inside tags */
+			if ( !intag )
+				l_sp = pos;
+		}
+		else if ( ( ch[pos] == 'w' ) && ( pos + 4 < mx->msg->len ) && ( memcmp( &ch[pos], "www.", 4 ) == 0 ) ) {
+			tags += 2;
+		}
+		else if ( ( ch[pos] == 'h' ) && ( pos + 8 < mx->msg->len ) && ( memcmp( &ch[pos], "http://", 7 ) == 0 ) ) {
+			tags += 2;
+		}
+
+		if ( tags > MXIT_MAX_MSG_TAGS ) {
+			/* we have reached the maximum amount of tags pidgin (gtk) can handle per message.
+			   so its time to send what we have and then start building a new message */
+
+			/* now find the right place to break the message */
+			if ( l_nl > start ) {
+				/* break at last '\n' char */
+				stop = l_nl;
+				ch[stop] = '\0';
+				msg = g_string_new( &ch[start] );
+				ch[stop] = '\n';
+			}
+			else if ( l_sp > start ) {
+				/* break at last ' ' char */
+				stop = l_sp;
+				ch[stop] = '\0';
+				msg = g_string_new( &ch[start] );
+				ch[stop] = ' ';
+			}
+			else {
+				/* break at the last '>' char */
+				char t;
+				stop = l_gt + 1;
+				t = ch[stop];
+				ch[stop] = '\0';
+				msg = g_string_new( &ch[start] );
+				ch[stop] = t;
+				stop--;
+			}
+
+			/* push message to pidgin */
+			serv_got_im( mx->session->con, mx->from, msg->str, mx->flags, mx->timestamp );
+			g_string_free( msg, TRUE );
+			msg = NULL;
+
+			/* next part need this flag set */
+			mx->flags |= PURPLE_MESSAGE_RAW;
+
+			tags = 0;
+			start = stop + 1;
+			pos = start;
+		}
+		else
+			pos++;
+	}
+
+	if ( start != pos ) {
+		/* send the last part of the message */
+
+		/* build the string */
+		ch[pos] = '\0';
+		msg = g_string_new( &ch[start] );
+		ch[pos] = '\n';
+
+		/* push message to pidgin */
+		serv_got_im( mx->session->con, mx->from, msg->str, mx->flags, mx->timestamp );
+		g_string_free( msg, TRUE );
+		msg = NULL;
+	}
+}
+
+
+/*------------------------------------------------------------------------
+ * Insert custom emoticons and inline images into the message (if there
+ * are any), then give the message to the UI to display to the user.
+ *
+ *  @param mx				The received message object
+ */
+void mxit_show_message( struct RXMsgData* mx )
+{
+	char*				pos;
+	int					start;
+	unsigned int		end;
+	int					emo_ofs;
+	char*				ii;
+	char				tag[64];
+	int*				img_id;
+
+	if ( mx->got_img ) {
+		/* search and replace all emoticon tags with proper image tags */
+
+		while ( ( pos = strstr( mx->msg->str, MXIT_II_TAG ) ) != NULL ) {
+			start = pos - mx->msg->str;					/* offset at which MXIT_II_TAG starts */
+			emo_ofs = start + strlen( MXIT_II_TAG );	/* offset at which EMO's ID starts */
+			end = emo_ofs + 1;							/* offset at which MXIT_II_TAG ends */
+
+			while ( ( end < mx->msg->len ) && ( mx->msg->str[end] != '>' ) )
+				end++;
+
+			if ( end == mx->msg->len )			/* end of emoticon tag not found */
+				break;
+
+			ii = g_strndup( &mx->msg->str[emo_ofs], end - emo_ofs );
+
+			/* remove inline image tag */
+			g_string_erase( mx->msg, start, ( end - start ) + 1 );
+
+			/* find the image entry */
+			img_id = (int*) g_hash_table_lookup( mx->session->iimages, ii );
+			if ( !img_id ) {
+				/* inline image not found, so we will just skip it */
+				purple_debug_error( MXIT_PLUGIN_ID, "inline image NOT found (%s)\n", ii );
+			}
+			else {
+				/* insert img tag */
+				g_snprintf( tag, sizeof( tag ), "<img id=\"%i\">", *img_id );
+				g_string_insert( mx->msg, start, tag );
+			}
+
+			g_free( ii );
+		}
+	}
+
+#ifdef MXIT_DEBUG_MARKUP
+	purple_debug_info( MXIT_PLUGIN_ID, "Markup RX (converted): '%s'\n", mx->msg->str );
+#endif
+
+	if ( mx->processed ) {
+		/* this message has already been taken care of, so just ignore it here */
+	}
+	else if ( mx->chatid < 0 ) {
+		/* normal chat message */
+		mxit_show_split_message( mx );
+	}
+	else {
+		/* this is a multimx message */
+		serv_got_chat_in( mx->session->con, mx->chatid, mx->from, mx->flags, mx->msg->str, mx->timestamp);
+	}
+
+	/* freeup resource */
+	free_markupdata( mx );
+}
+
+
+/*------------------------------------------------------------------------
+ * Extract the custom emoticon ID from the message.
+ *
+ *  @param message			The input data
+ *  @param emid				The extracted emoticon ID
+ */
+static void parse_emoticon_str( const char* message, char* emid )
+{
+	int		i;
+
+	for ( i = 0; ( message[i] != '\0' && message[i] != '}' && i < MXIT_MAX_EMO_ID ); i++ ) {
+		emid[i] = message[i];
+	}
+
+	if ( message[i] == '\0' ) {
+		/* end of message reached, ignore the tag */
+		emid[0] = '\0';
+	}
+	else if ( i == MXIT_MAX_EMO_ID ) {
+		/* invalid tag length, ignore the tag */
+		emid[0] = '\0';
+	}
+	else
+		emid[i] = '\0';
+}
+
+
+/*------------------------------------------------------------------------
+ * Callback function invoked when a custom emoticon request to the WAP site completes.
+ *
+ *  @param url_data
+ *  @param user_data		The Markup message object
+ *  @param url_text			The data returned from the WAP site
+ *  @param len				The length of the data returned
+ *  @param error_message	Descriptive error message
+ */
+static void emoticon_returned( PurpleUtilFetchUrlData* url_data, gpointer user_data, const gchar* url_text, gsize len, const gchar* error_message )
+{
+	struct RXMsgData*	mx			= (struct RXMsgData*) user_data;
+	const gchar*		data		= url_text;
+	unsigned int		pos			= 0;
+	int					id;
+	char*				str;
+	int					em_size		= 0;
+	char*				em_data		= NULL;
+	char*				em_id		= NULL;
+	int*				intptr		= NULL;
+	int					res;
+
+	purple_debug_info( MXIT_PLUGIN_ID, "emoticon_returned\n" );
+
+	/* remove request from the async outstanding calls list */
+	mx->session->async_calls = g_slist_remove( mx->session->async_calls, url_data );
+
+	if ( !url_text ) {
+		/* no reply from the WAP site */
+		purple_debug_error( MXIT_PLUGIN_ID, "Error contacting the MXit WAP site. Please try again later (emoticon).\n" );
+		goto done;
+	}
+
+#ifdef	MXIT_DEBUG_EMO
+	hex_dump( data, len );
+#endif
+
+	/* validate that the returned data starts with the magic constant that indicates it is a custom emoticon */
+	if ( len - pos < strlen( MXIT_FRAME_MAGIC ) || memcmp( MXIT_FRAME_MAGIC, &data[pos], strlen( MXIT_FRAME_MAGIC ) ) != 0 ) {
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (bad magic)\n" );
+		goto done;
+	}
+	pos += strlen( MXIT_FRAME_MAGIC );
+
+	/* validate the image frame desc byte */
+	if ( data[pos] != '\x6F' ) {
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (bad frame desc)\n" );
+		goto done;
+	}
+	pos++;
+
+	/* get the frame image data length */
+	res = asn_getlength( &data[pos], len - pos, &em_size );
+	if ( res <= 0 ) {
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (bad frame length)\n" );
+		goto done;
+	}
+	pos += res;
+#ifdef	MXIT_DEBUG_EMO
+	purple_debug_info( MXIT_PLUGIN_ID, "read the length '%i'\n", em_size );
+#endif
+
+	/* utf-8 (emoticon name) */
+	res = asn_getUtf8( &data[pos], len - pos, 0x0C, &str );
+	if ( res <= 0 ) {
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (bad name string)\n" );
+		goto done;
+	}
+	pos += res;
+#ifdef	MXIT_DEBUG_EMO
+	purple_debug_info( MXIT_PLUGIN_ID, "read the string '%s'\n", str );
+#endif
+	g_free( str );
+	str = NULL;
+
+	/* utf-8 (emoticon shortcut) */
+	res = asn_getUtf8( &data[pos], len - pos, 0x81, &str );
+	if ( res <= 0 ) {
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (bad shortcut string)\n" );
+		goto done;
+	}
+	pos += res;
+#ifdef	MXIT_DEBUG_EMO
+	purple_debug_info( MXIT_PLUGIN_ID, "read the string '%s'\n", str );
+#endif
+	em_id = str;
+
+	/* validate the image data type */
+	if ( len - pos < 1 || data[pos] != '\x82' ) {
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (bad data type)\n" );
+		g_free( em_id );
+		goto done;
+	}
+	pos++;
+
+	/* get the data length */
+	res = asn_getlength( &data[pos], len - pos, &em_size );
+	if ( res <= 0 ) {
+		/* bad frame length */
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (bad data length)\n" );
+		g_free( em_id );
+		goto done;
+	}
+	pos += res;
+#ifdef	MXIT_DEBUG_EMO
+	purple_debug_info( MXIT_PLUGIN_ID, "read the length '%i'\n", em_size );
+#endif
+
+	if ( len - pos < (gsize)em_size ) {
+		/* not enough bytes left in data! */
+		purple_debug_error( MXIT_PLUGIN_ID, "Invalid emoticon received from wapsite (data length too long)\n");
+		g_free( em_id );
+		goto done;
+	}
+
+	/* strip the mxit markup tags from the emoticon id (eg, .{XY} -> XY) */
+	if ( ( em_id[0] == '.' ) && ( em_id[1] == '{' ) ) {
+		char	emo[MXIT_MAX_EMO_ID + 1];
+
+		parse_emoticon_str( &em_id[2], emo );
+		strcpy( em_id, emo );
+	}
+
+	if ( g_hash_table_lookup( mx->session->iimages, em_id ) ) {
+		/* emoticon found in the table, so ignore this one */
+		g_free( em_id );
+		goto done;
+	}
+
+	/* make a copy of the data */
+	em_data = g_malloc( em_size );
+	memcpy( em_data, &data[pos], em_size );
+
+	/* we now have the emoticon, store it in the imagestore */
+	id = purple_imgstore_add_with_id( em_data, em_size, NULL );
+
+	/* map the mxit emoticon id to purple image id */
+	intptr = g_malloc( sizeof( int ) );
+	*intptr = id;
+	g_hash_table_insert( mx->session->iimages, em_id, intptr );
+
+	mx->flags |= PURPLE_MESSAGE_IMAGES;
+done:
+	mx->img_count--;
+	if ( ( mx->img_count == 0 ) && ( mx->converted ) ) {
+		/*
+		 * this was the last outstanding emoticon for this message,
+		 * so we can now display it to the user.
+		 */
+		mxit_show_message( mx );
+	}
+}
+
+
+/*------------------------------------------------------------------------
+ * Send a request to the MXit WAP site to download the specified emoticon.
+ *
+ *  @param mx				The Markup message object
+ *  @param id				The ID for the emoticon
+ */
+static void emoticon_request( struct RXMsgData* mx, const char* id )
+{
+	PurpleUtilFetchUrlData*	url_data;
+	const char*				wapserver;
+	char*					url;
+
+	purple_debug_info( MXIT_PLUGIN_ID, "sending request for emoticon '%s'\n", id );
+
+	wapserver = purple_account_get_string( mx->session->acc, MXIT_CONFIG_WAPSERVER, DEFAULT_WAPSITE );
+
+	/* reference: "libpurple/util.h" */
+	url = g_strdup_printf( "%s/res/?type=emo&mlh=%i&sc=%s&ts=%li", wapserver, MXIT_EMOTICON_SIZE, id, time( NULL ) );
+	url_data = purple_util_fetch_url_request( url, TRUE, NULL, TRUE, NULL, FALSE, emoticon_returned, mx );
+	if ( url_data )
+		mx->session->async_calls = g_slist_prepend( mx->session->async_calls, url_data );
+
+	g_free( url );
+}
+
+
+/*------------------------------------------------------------------------
+ * Parse a Vibe command.
+ *
+ *  @param mx				The Markup message object
+ *  @param message			The message text (which contains the vibe)
+ *  @return id				The length of the message to skip
+ */
+static int mxit_parse_vibe( struct RXMsgData* mx, const char* message )
+{
+	unsigned int	vibeid;
+
+	vibeid = message[2] - '0';
+
+	purple_debug_info( MXIT_PLUGIN_ID, "Vibe received (%i)\n", vibeid );
+
+	if ( vibeid > ( ARRAY_SIZE( vibes ) - 1 ) ) {
+		purple_debug_warning( MXIT_PLUGIN_ID, "Unsupported vibe received (%i)\n", vibeid );
+		/* unsupported vibe */
+		return 0;
+	}
+
+	g_string_append_printf( mx->msg, "<font color=\"%s\"><i>%s Vibe...</i></font>", MXIT_VIBE_MSG_COLOR, _( vibes[vibeid] ) );
+	return 2;
+}
+
+
+/*------------------------------------------------------------------------
+ * Extract the nickname from a chatroom message and display it nicely in
+ * libPurple-style (HTML) markup.
+ *
+ *  @param mx				The received message data object
+ *  @param message			The message text
+ *  @return					The length of the message to skip
+ */
+static int mxit_extract_chatroom_nick( struct RXMsgData* mx, char* message, int len, int msgflags )
+{
+	int		i;
+
+	if ( message[0] == '<' ) {
+		/*
+		 * The message MIGHT contains an embedded nickname.  But we can't
+		 * be sure unless we find the end-of-nickname sequence: (>\n)
+		 * Search for it....
+		 */
+		gboolean	found	= FALSE;
+
+		for ( i = 1; i < len; i++ ) {
+			if ( ( message[i] == '\n' ) && ( message[i-1] == '>' ) ) {
+				found = TRUE;
+				message[i-1] = '\0';	/* loose the '>' */
+				i++;					/* and skip the new-line */
+				break;
+			}
+		}
+
+		if ( found ) {
+			gchar*		nickname;
+
+			/*
+			 * The message definitely had an embedded nickname - generate a marked-up
+			 * message to be displayed.
+			 */
+			nickname = g_markup_escape_text( &message[1], -1 );
+
+			/* Remove any MXit escaping from nickname ("\X" --> "X") */
+			if ( msgflags & CP_MSG_MARKUP ) {
+				int	nicklen = strlen( nickname );
+				int	j, k;
+
+				for ( j = 0, k = 0; j < nicklen; j++ ) {
+					if ( nickname[j] == '\\' )
+						j++;
+
+					nickname[k] = nickname[j];
+					k++;
+				}
+
+				nickname[k] = '\0';		/* terminate string */
+			}
+
+			/* add nickname within some BOLD markup to the new converted message */
+			g_string_append_printf( mx->msg, "<b>%s:</b> ", nickname );
+
+			/* free up the resources */
+			g_free( nickname );
+
+			return i;
+		}
+	}
+
+	return 0;
+}
+
+
+
+/*------------------------------------------------------------------------
+ * Convert a message containing MXit protocol markup to libPurple-style (HTML) markup.
+ *
+ *  @param mx				The received message data object
+ *  @param message			The message text
+ *  @param len				The length of the message
+ */
+void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgtype, int msgflags )
+{
+	char		tmpstr1[128];
+	char*		ch;
+	int			i			= 0;
+
+	/* tags */
+	gboolean	tag_bold	= FALSE;
+	gboolean	tag_under	= FALSE;
+	gboolean	tag_italic	= FALSE;
+	int			font_size	= 0;
+
+#ifdef MXIT_DEBUG_MARKUP
+	purple_debug_info( MXIT_PLUGIN_ID, "Markup RX (original): '%s'\n", message );
+#endif
+
+
+	/*
+	 * supported MXit markup:
+	 * '*'			bold
+	 * '_'			underline
+	 * '/'			italics
+	 * '$'			highlight text
+	 * '.+' 		inc font size
+	 * '.-'			dec font size
+	 * '#XXXXXX'	foreground color
+	 * '.{XX}'		custom emoticon
+	 * '\'			escape the following character
+	 * '::'			MXit commands
+	 */
+
+
+	if ( is_mxit_chatroom_contact( mx->session, mx->from ) ) {
+		/* chatroom message, so we need to extract and skip the sender's nickname
+		 * which is embedded inside the message */
+		i = mxit_extract_chatroom_nick( mx, message, len, msgflags );
+	}
+
+	/* run through the message and check for custom emoticons and markup */
+	for ( ; i < len; i++ ) {
+		switch ( message[i] ) {
+
+
+			/* mxit markup parsing */
+			case '*' :
+					if ( !( msgflags & CP_MSG_MARKUP ) ) {
+						g_string_append_c( mx->msg, message[i] );
+						break;
+					}
+
+					/* bold markup */
+					if ( !tag_bold )
+						g_string_append( mx->msg, "<b>" );
+					else
+						g_string_append( mx->msg, "</b>" );
+					tag_bold = !tag_bold;
+					break;
+			case '_' :
+					if ( !( msgflags & CP_MSG_MARKUP ) ) {
+						g_string_append_c( mx->msg, message[i] );
+						break;
+					}
+
+					/* underscore markup */
+					if ( !tag_under )
+						g_string_append( mx->msg, "<u>" );
+					else
+						g_string_append( mx->msg, "</u>" );
+					tag_under = !tag_under;
+					break;
+			case '/' :
+					if ( !( msgflags & CP_MSG_MARKUP ) ) {
+						g_string_append_c( mx->msg, message[i] );
+						break;
+					}
+
+					/* italics markup */
+					if ( !tag_italic )
+						g_string_append( mx->msg, "<i>" );
+					else
+						g_string_append( mx->msg, "</i>" );
+					tag_italic = !tag_italic;
+					break;
+			case '$' :
+					if ( !( msgflags & CP_MSG_MARKUP ) ) {
+						g_string_append_c( mx->msg, message[i] );
+						break;
+					}
+					else if ( i + 1 >= len ) {
+						/* message too short for complete link */
+						g_string_append_c( mx->msg, '$' );
+						break;
+					}
+
+					/* find the end tag */
+					ch = strstr( &message[i + 1], "$" );
+					if ( ch ) {
+						/* end found */
+						*ch = '\0';
+						mxit_add_html_link( mx, &message[i + 1], FALSE, &message[i + 1] );
+						*ch = '$';
+						i += ( ch - &message[i + 1] ) + 1;
+					}
+					else {
+						g_string_append_c( mx->msg, message[i] );
+					}
+					/* highlight text */
+					break;
+			case '#' :
+					if ( !( msgflags & CP_MSG_MARKUP ) ) {
+						g_string_append_c( mx->msg, message[i] );
+						break;
+					}
+					else if ( i + COLORCODE_LEN >= len ) {
+						/* message too short for complete colour code */
+						g_string_append_c( mx->msg, '#' );
+						break;
+					}
+
+					/* foreground (text) color */
+					memcpy( tmpstr1, &message[i + 1], COLORCODE_LEN );
+					tmpstr1[ COLORCODE_LEN ] = '\0';			/* terminate string */
+					if ( strcmp( tmpstr1, "??????" ) == 0 ) {
+						/* need to reset the font */
+						g_string_append( mx->msg, "</font>" );
+						i += COLORCODE_LEN;
+					}
+					else if ( strspn( tmpstr1, "0123456789abcdefABCDEF") == COLORCODE_LEN ) {
+						/* definitely a numeric colour code */
+						g_string_append_printf( mx->msg, "<font color=\"#%s\">", tmpstr1 );
+						i += COLORCODE_LEN;
+					}
+					else {
+						/* not valid colour markup */
+						g_string_append_c( mx->msg, '#' );
+					}
+					break;
+			case '.' :
+					if ( i + 1 >= len ) {
+						/* message too short */
+						g_string_append_c( mx->msg, '.' );
+						break;
+					}
+
+					if ( ( msgflags & CP_MSG_EMOTICON ) && ( message[i+1] == '{' ) ) {
+						/* custom emoticon */
+						if ( i + 2 >= len ) {
+							/* message too short */
+							g_string_append_c( mx->msg, '.' );
+							break;
+						}
+
+						parse_emoticon_str( &message[i+2], tmpstr1 );
+						if ( tmpstr1[0] != '\0' ) {
+							mx->got_img = TRUE;
+
+							if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) {
+								/* emoticon found in the cache, so we do not have to request it from the WAPsite */
+							}
+							else {
+								/* request emoticon from the WAPsite */
+								mx->img_count++;
+								emoticon_request( mx, tmpstr1 );
+							}
+
+							g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 );
+							i += strlen( tmpstr1 ) + 2;
+						}
+						else
+							g_string_append_c( mx->msg, '.' );
+					}
+					else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '+' ) ) {
+						/* increment text size */
+						font_size++;
+						g_string_append_printf( mx->msg, "<font size=\"%+i\">", font_size );
+						i++;
+					}
+					else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '-' ) ) {
+						/* decrement text size */
+						font_size--;
+						g_string_append_printf( mx->msg, "<font size=\"%+i\">", font_size );
+						i++;
+					}
+					else
+						g_string_append_c( mx->msg, '.' );
+
+					break;
+			case '\\' :
+					if ( i + 1 >= len ) {
+						/* message too short for an escaped character */
+						g_string_append_c( mx->msg, '\\' );
+					}
+					else {
+						/* ignore the next character, because its been escaped */
+						g_string_append_c( mx->msg, message[i + 1] );
+						i++;
+					}
+					break;
+
+
+			/* command parsing */
+			case ':' :
+					if ( i + 1 >= len ) {
+						/* message too short */
+						g_string_append_c( mx->msg, ':' );
+						break;
+					}
+
+					if ( message[i+1] == '@' ) {
+						/* this is a vibe! */
+						int		size;
+
+						if ( i + 2 >= len ) {
+							/* message too short */
+							g_string_append_c( mx->msg, message[i] );
+							break;
+						}
+
+						size = mxit_parse_vibe( mx, &message[i] );
+						if ( size == 0 )
+							g_string_append_c( mx->msg, message[i] );
+						else
+							i += size;
+					}
+					else if ( msgtype != CP_MSGTYPE_COMMAND ) {
+						/* this is not a command message */
+						g_string_append_c( mx->msg, message[i] );
+					}
+					else if ( message[i+1] == ':' ) {
+						/* parse out the command */
+						int		size;
+
+						size = mxit_parse_command( mx, &message[i] );
+						if ( size == 0 )
+							g_string_append_c( mx->msg, ':' );
+						else
+							i += size;
+					}
+					else {
+						g_string_append_c( mx->msg, ':' );
+					}
+					break;
+
+
+			/* these aren't MXit markup, but are interpreted by libPurple */
+			case '<' :
+					g_string_append( mx->msg, "&lt;" );
+					break;
+			case '>' :
+					g_string_append( mx->msg, "&gt;" );
+					break;
+			case '&' :
+					g_string_append( mx->msg, "&amp;" );
+					break;
+			case '"' :
+					g_string_append( mx->msg, "&quot;" );
+					break;
+
+			default :
+					/* text */
+					g_string_append_c( mx->msg, message[i] );
+					break;
+		}
+	}
+
+	if ( msgflags & CP_MSG_FAREWELL ) {
+		/* this is a farewell message */
+		g_string_prepend( mx->msg, "<font color=\""MXIT_FAREWELL_MSG_COLOR"\"><i>" );
+		g_string_append( mx->msg, "</i></font>" );
+	}
+}
+
+
+/*------------------------------------------------------------------------
+ * Insert an inline image command.
+ *
+ *  @param mx				The message text as processed so far.
+ *  @oaram id				The imgstore ID of the inline image.
+ */
+static void inline_image_add( GString* mx, int id )
+{
+	PurpleStoredImage *image;
+	gconstpointer img_data;
+	gsize img_size;
+	gchar* enc;
+
+	image = purple_imgstore_find_by_id( id );
+	if ( image == NULL )
+		return;
+
+	img_data = purple_imgstore_get_data( image );
+	img_size = purple_imgstore_get_size( image );
+
+	enc = purple_base64_encode( img_data, img_size );
+
+	g_string_append( mx, "::op=img|dat=" );
+	g_string_append( mx, enc );
+	g_string_append_c( mx, ':' );
+
+	g_free( enc );
+}
+
+
+/*------------------------------------------------------------------------
+ * Convert libpurple (HTML) markup to MXit protocol markup (for sending to MXit).
+ * Any MXit markup codes in the original message also need to be escaped.
+ *
+ *  @param message			The message text containing libPurple (HTML) markup
+ *  @return					The message text containing MXit markup
+ */
+char* mxit_convert_markup_tx( const char* message, int* msgtype )
+{
+	GString*			mx;
+	struct tag*			tag;
+	GList*				entry;
+	GList*				tagstack	= NULL;
+	char*				reply;
+	char				color[8];
+	int					len			= strlen ( message );
+	int					i;
+
+#ifdef MXIT_DEBUG_MARKUP
+	purple_debug_info( MXIT_PLUGIN_ID, "Markup TX (original): '%s'\n", message );
+#endif
+
+	/*
+	 * libPurple uses the following HTML markup codes:
+	 *   Bold:			<b>...</b>
+	 *   Italics:		<i>...</i>
+	 *   Underline:		<u>...</u>
+	 *   Strikethrough:	<s>...</s>					(NO MXIT SUPPORT)
+	 *   Font size:		<font size="">...</font>
+	 *   Font type:		<font face="">...</font>	(NO MXIT SUPPORT)
+	 *   Font colour:	<font color=#">...</font>
+	 *   Links:			<a href="">...</a>
+	 *   Newline:		<br>
+	 *   Inline image:  <IMG ID="">
+	 * The following characters are also encoded:
+	 *   &amp;  &quot;  &lt;  &gt;
+	 */
+
+	/* new message data */
+	mx = g_string_sized_new( len );
+
+	/* run through the message and check for HTML markup */
+	for ( i = 0; i < len; i++ ) {
+
+		switch ( message[i] ) {
+			case '<' :
+				if ( purple_str_has_prefix( &message[i], "<b>" ) || purple_str_has_prefix( &message[i], "</b>" ) ) {
+					/* bold */
+					g_string_append_c( mx, '*' );
+				}
+				else if ( purple_str_has_prefix( &message[i], "<i>" ) || purple_str_has_prefix( &message[i], "</i>" ) ) {
+					/* italics */
+					g_string_append_c( mx, '/' );
+				}
+				else if ( purple_str_has_prefix( &message[i], "<u>" ) || purple_str_has_prefix( &message[i], "</u>" ) ) {
+					/* underline */
+					g_string_append_c( mx, '_' );
+				}
+				else if ( purple_str_has_prefix( &message[i], "<br>" ) ) {
+					/* newline */
+					g_string_append_c( mx, '\n' );
+				}
+				else if ( purple_str_has_prefix( &message[i], "<font size=" ) ) {
+					/* font size */
+					int fontsize;
+
+					tag = g_new0( struct tag, 1 );
+					tag->type = MXIT_TAG_SIZE;
+					tagstack = g_list_prepend( tagstack, tag );
+					// TODO: implement size control
+					if ( sscanf( &message[i+12], "%i", &fontsize ) ) {
+						purple_debug_info( MXIT_PLUGIN_ID, "Font size set to %i\n", fontsize );
+					}
+				}
+				else if ( purple_str_has_prefix( &message[i], "<font color=" ) ) {
+					/* font colour */
+					tag = g_new0( struct tag, 1 );
+					tag->type = MXIT_TAG_COLOR;
+					tagstack = g_list_append( tagstack, tag );
+					memset( color, 0x00, sizeof( color ) );
+					memcpy( color, &message[i + 13], 7 );
+					g_string_append( mx, color );
+				}
+				else if ( purple_str_has_prefix( &message[i], "</font>" ) ) {
+					/* end of font tag */
+					entry = g_list_last( tagstack );
+					if ( entry ) {
+						tag = entry->data;
+						if ( tag->type == MXIT_TAG_COLOR ) {
+							/* font color reset */
+							g_string_append( mx, "#??????" );
+						}
+						else if ( tag->type == MXIT_TAG_SIZE ) {
+							/* font size */
+							// TODO: implement size control
+						}
+						tagstack = g_list_remove( tagstack, tag );
+						g_free( tag );
+					}
+				}
+				else if ( purple_str_has_prefix( &message[i], "<IMG ID=" ) ) {
+					/* inline image */
+					int imgid;
+
+					if ( sscanf( &message[i+9], "%i", &imgid ) ) {
+						inline_image_add( mx, imgid );
+						*msgtype = CP_MSGTYPE_COMMAND;		/* inline image must be sent as a MXit command */
+					}
+				}
+
+				/* skip to end of tag ('>') */
+				for ( i++; ( i < len ) && ( message[i] != '>' ) ; i++ );
+
+				break;
+
+			case '*' :	/* MXit bold */
+			case '_' :	/* MXit underline */
+			case '/' :	/* MXit italic */
+			case '#' :	/* MXit font color */
+			case '$' :	/* MXit highlight text */
+			case '\\' :	/* MXit escape backslash */
+				g_string_append( mx, "\\" );				/* escape character */
+				g_string_append_c( mx, message[i] );		/* character to escape */
+				break;
+
+			case '.' : /* might be a MXit font size change, or custom emoticon */
+				if ( i + 1 < len ) {
+					if ( ( message[i+1] == '+' ) || ( message[i+1] == '-' ) )
+						g_string_append( mx, "\\." );		/* escape "." */
+					else
+						g_string_append_c( mx, '.' );
+				}
+				else
+					g_string_append_c( mx, '.' );
+				break;
+
+			default:
+				g_string_append_c( mx, message[i] );
+				break;
+		}
+	}
+
+	/* unescape HTML entities to their literal characters (reference: "libpurple/utils.h") */
+	reply = purple_unescape_html( mx->str );
+
+	g_string_free( mx, TRUE );
+
+#ifdef MXIT_DEBUG_MARKUP
+	purple_debug_info( MXIT_PLUGIN_ID, "Markup TX (converted): '%s'\n", reply );
+#endif
+
+	return reply;
+}
+
+
+/*------------------------------------------------------------------------
+ * Free an emoticon entry.
+ *
+ *  @param key				MXit emoticon ID
+ *  @param value			Imagestore ID for emoticon
+ *  @param user_data		NULL (unused)
+ *  @return					TRUE
+ */
+static gboolean emoticon_entry_free( gpointer key, gpointer value, gpointer user_data )
+{
+	int* imgid = value;
+
+	/* key is a string */
+	g_free( key );
+
+	/* value is 'id' in imagestore */
+	purple_imgstore_unref_by_id( *imgid );
+	g_free( value );
+
+	return TRUE;
+}
+
+
+/*------------------------------------------------------------------------
+ * Free all entries in the emoticon cache.
+ *
+ *  @param session			The MXit session object
+ */
+void mxit_free_emoticon_cache( struct MXitSession* session )
+{
+	g_hash_table_foreach_remove( session->iimages, emoticon_entry_free, NULL );
+	g_hash_table_destroy ( session->iimages );
+}
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/myspace/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/myspace/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,49 @@
+EXTRA_DIST = \
+	Makefile.mingw
+
+pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+
+MSIMSOURCES = markup.c \
+	  markup.h \
+	  message.c \
+	  message.h \
+	  myspace.c \
+	  myspace.h \
+	  persist.h \
+	  session.c \
+	  session.h \
+	  user.c \
+	  user.h \
+	  zap.c \
+	  zap.h
+
+AM_CFLAGS = $(st)
+
+libmyspace_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+if STATIC_MYSPACE
+
+st = -DPURPLE_STATIC_PRPL
+noinst_LTLIBRARIES    = libmyspace.la
+libmyspace_la_SOURCES = $(MSIMSOURCES)
+libmyspace_la_CFLAGS  = $(AM_CFLAGS)
+
+else
+
+st =
+pkg_LTLIBRARIES       = libmyspace.la
+libmyspace_la_SOURCES = $(MSIMSOURCES)
+libmyspace_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
+
+endif
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_builddir)/libpurple \
+	$(GLIB_CFLAGS) \
+	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/novell/Makefile.am
--- a/libpurple/protocols/novell/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/novell/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -28,7 +28,7 @@
 
 AM_CFLAGS = $(st)
 
-libnovell_la_LDFLAGS = -module -avoid-version
+libnovell_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if STATIC_NOVELL
 
@@ -42,7 +42,7 @@
 st =
 pkg_LTLIBRARIES      = libnovell.la
 libnovell_la_SOURCES = $(NOVELLSOURCES)
-libnovell_la_LIBADD  = $(GLIB_LIBS)
+libnovell_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
 
 endif
 
@@ -51,3 +51,8 @@
 	-I$(top_builddir)/libpurple \
 	$(DEBUG_CFLAGS) \
 	$(GLIB_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/null/Makefile.am
--- a/libpurple/protocols/null/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/null/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -14,10 +14,15 @@
 st =
 pkg_LTLIBRARIES    = libnull.la
 libnull_la_SOURCES = $(NULLSOURCES)
-libnull_la_LIBADD  = $(GLIB_LIBS)
+libnull_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	$(GLIB_CFLAGS) \
 	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/oscar/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/oscar/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,94 @@
+EXTRA_DIST = \
+	COPYING \
+	AUTHORS \
+	Makefile.mingw
+
+pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+
+OSCARSOURCES = \
+	authorization.c     \
+	bstream.c           \
+	clientlogin.c       \
+	encoding.c          \
+	encoding.h          \
+	family_admin.c      \
+	family_alert.c      \
+	family_auth.c       \
+	family_bart.c       \
+	family_bos.c        \
+	family_buddy.c      \
+	family_chat.c       \
+	family_chatnav.c    \
+	family_icq.c        \
+	family_icbm.c       \
+	family_locate.c     \
+	family_oservice.c   \
+	family_popup.c      \
+	family_feedbag.c    \
+	family_stats.c      \
+	family_userlookup.c \
+	flap_connection.c   \
+	misc.c         \
+	msgcookie.c         \
+	odc.c               \
+	oft.c               \
+	oscar.c             \
+	oscar.h             \
+	oscarcommon.h       \
+	oscar_data.c        \
+	peer.c              \
+	peer.h              \
+	peer_proxy.c        \
+	rxhandlers.c        \
+	snac.c              \
+	snactypes.h         \
+	tlv.c               \
+	userinfo.c          \
+	util.c              \
+	visibility.c	    \
+	visibility.h
+
+AM_CFLAGS = $(st)
+
+libaim_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+libicq_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+liboscar_la_LDFLAGS = $(AVOID_VERSION) $(NO_UNDEFINED)
+if STATIC_OSCAR
+
+st = -DPURPLE_STATIC_PRPL
+noinst_LTLIBRARIES  = liboscar.la
+liboscar_la_SOURCES = $(OSCARSOURCES) libaim.c libicq.c
+liboscar_la_CFLAGS  = $(AM_CFLAGS)
+
+else
+
+st =
+pkg_LTLIBRARIES     = libaim.la libicq.la
+
+if OS_WIN32
+lib_LTLIBRARIES     = liboscar.la
+else
+pkg_LTLIBRARIES    += liboscar.la
+endif
+
+liboscar_la_SOURCES = $(OSCARSOURCES)
+liboscar_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
+
+libaim_la_SOURCES   = libaim.c
+libaim_la_LIBADD    = liboscar.la
+
+libicq_la_SOURCES   = libicq.c
+libicq_la_LIBADD    = liboscar.la
+
+endif
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_builddir)/libpurple \
+	$(GLIB_CFLAGS) \
+	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/sametime/Makefile.am
--- a/libpurple/protocols/sametime/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/sametime/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -24,8 +24,8 @@
 endif
 
 libsametime_la_SOURCES = $(SAMETIMESOURCES)
-libsametime_la_LDFLAGS = -module -avoid-version
-libsametime_la_LIBADD = $(GLIB_LIBS) $(MEANWHILE_LIBS)
+libsametime_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+libsametime_la_LIBADD = $(GLIB_LIBS) $(MEANWHILE_LIBS) $(PURPLE_LIBS)
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/libpurple \
@@ -35,3 +35,7 @@
 	$(MEANWHILE_CFLAGS) \
 	-DG_LOG_DOMAIN=\"sametime\"
 
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/silc/Makefile.am
--- a/libpurple/protocols/silc/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/silc/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -19,7 +19,7 @@
 
 AM_CFLAGS = $(st)
 
-libsilcpurple_la_LDFLAGS = -module -avoid-version
+libsilcpurple_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if STATIC_SILC
 
@@ -34,7 +34,7 @@
 st = $(SILC_CFLAGS)
 pkg_LTLIBRARIES          = libsilcpurple.la
 libsilcpurple_la_SOURCES = $(SILCSOURCES)
-libsilcpurple_la_LIBADD  = $(GLIB_LIBS) $(SILC_LIBS)
+libsilcpurple_la_LIBADD  = $(GLIB_LIBS) $(SILC_LIBS) $(PURPLE_LIBS)
 
 endif
 
@@ -44,3 +44,8 @@
 	$(DEBUG_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(SILC_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/simple/Makefile.am
--- a/libpurple/protocols/simple/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/protocols/simple/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -11,7 +11,7 @@
 
 AM_CFLAGS = $(st)
 
-libsimple_la_LDFLAGS = -module -avoid-version
+libsimple_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if STATIC_SIMPLE
 
@@ -25,7 +25,7 @@
 st =
 pkg_LTLIBRARIES      = libsimple.la
 libsimple_la_SOURCES = $(SIMPLESOURCES)
-libsimple_la_LIBADD  = $(GLIB_LIBS)
+libsimple_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
 
 endif
 
@@ -34,3 +34,8 @@
 	-I$(top_builddir)/libpurple \
 	$(GLIB_CFLAGS) \
 	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/protocols/yahoo/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/yahoo/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,72 @@
+EXTRA_DIST = \
+	Makefile.mingw
+
+pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+
+YAHOOSOURCES = \
+	libymsg.c \
+	libymsg.h \
+	util.c \
+	yahoochat.h \
+	yahoochat.c \
+	yahoo_aliases.c \
+	yahoo_aliases.h \
+	yahoo_doodle.h \
+	yahoo_doodle.c \
+	yahoo_filexfer.h \
+	yahoo_filexfer.c \
+	yahoo_friend.h \
+	yahoo_friend.c \
+	yahoo_packet.h \
+	yahoo_packet.c \
+	yahoo_picture.c \
+	yahoo_picture.h \
+	yahoo_profile.c \
+	ycht.c \
+	ycht.h
+
+AM_CFLAGS = $(st)
+
+libyahoo_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+libyahoojp_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+libymsg_la_LDFLAGS = $(AVOID_VERSION) $(NO_UNDEFINED)
+
+if STATIC_YAHOO
+
+st = -DPURPLE_STATIC_PRPL
+noinst_LTLIBRARIES  = libymsg.la
+libymsg_la_SOURCES = $(YAHOOSOURCES) libyahoo.c libyahoojp.c
+libymsg_la_CFLAGS  = $(AM_CFLAGS)
+
+else
+
+st =
+pkg_LTLIBRARIES     = libyahoo.la libyahoojp.la
+
+if OS_WIN32
+lib_LTLIBRARIES     = libymsg.la
+else
+pkg_LTLIBRARIES    += libymsg.la
+endif
+
+libymsg_la_SOURCES = $(YAHOOSOURCES)
+libymsg_la_LIBADD  = $(GLIB_LIBS) $(PURPLE_LIBS)
+
+libyahoo_la_SOURCES = libyahoo.c
+libyahoo_la_LIBADD = libymsg.la
+
+libyahoojp_la_SOURCES = libyahoojp.c
+libyahoojp_la_LIBADD = libymsg.la
+
+endif
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_builddir)/libpurple \
+	$(GLIB_CFLAGS) \
+	$(DEBUG_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/win32/libc_interface.h
--- a/libpurple/win32/libc_interface.h	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/win32/libc_interface.h	Tue Oct 28 21:04:01 2025 +0100
@@ -23,6 +23,7 @@
 #ifndef _LIBC_INTERFACE_H_
 #define _LIBC_INTERFACE_H_
 #include <winsock2.h>
+#undef socklen_t
 #include <ws2tcpip.h>
 #include <io.h>
 #include <errno.h>
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/win32/libpurplerc.rc.in
--- a/libpurple/win32/libpurplerc.rc.in	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/win32/libpurplerc.rc.in	Tue Oct 28 21:04:01 2025 +0100
@@ -2,8 +2,8 @@
 #include "version.h"
 
 VS_VERSION_INFO VERSIONINFO
-  FILEVERSION PURPLE_MAJOR_VERSION,PURPLE_MINOR_VERSION,PURPLE_MICRO_VERSION,0
-  PRODUCTVERSION PURPLE_MAJOR_VERSION,PURPLE_MINOR_VERSION,PURPLE_MICRO_VERSION,0
+  FILEVERSION @PURPLE_MAJOR_VERSION@,@PURPLE_MINOR_VERSION@,@PURPLE_MICRO_VERSION@,0
+  PRODUCTVERSION @PURPLE_MAJOR_VERSION@,@PURPLE_MINOR_VERSION@,@PURPLE_MICRO_VERSION@,0
   FILEFLAGSMASK 0
   FILEFLAGS 0
   FILEOS VOS__WINDOWS32
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/win32/win32dep.c
--- a/libpurple/win32/win32dep.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/win32/win32dep.c	Tue Oct 28 21:04:01 2025 +0100
@@ -28,12 +28,18 @@
 
 #include "debug.h"
 #include "notify.h"
+#ifdef USE_FHS
+#include "version.h"
+#endif
 
 /*
  * LOCALS
  */
 static char *app_data_dir = NULL, *install_dir = NULL,
 	*lib_dir = NULL, *locale_dir = NULL;
+#ifdef USE_FHS
+static char *share_dir = NULL;
+#endif
 
 static HINSTANCE libpurpledll_hInstance = NULL;
 
@@ -153,13 +159,39 @@
 	return install_dir;
 }
 
+#ifdef USE_FHS
+const char *wpurple_share_dir(void) {
+	static gboolean initialized = FALSE;
+
+	if (!initialized) {
+		const char *inst_dir = wpurple_install_dir();
+		if (inst_dir != NULL) {
+			share_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S "share", inst_dir);
+			initialized = TRUE;
+		} else {
+			return NULL;
+		}
+	}
+
+	return share_dir;
+}
+#else
+const char *wpurple_share_dir(void) {
+	return wpurple_install_dir();
+}
+#endif
+
 const char *wpurple_lib_dir(void) {
 	static gboolean initialized = FALSE;
 
 	if (!initialized) {
 		const char *inst_dir = wpurple_install_dir();
 		if (inst_dir != NULL) {
+#ifdef USE_FHS
+			lib_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S "lib" G_DIR_SEPARATOR_S "purple-%i" , inst_dir, PURPLE_MAJOR_VERSION);
+#else
 			lib_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "plugins", inst_dir);
+#endif
 			initialized = TRUE;
 		} else {
 			return NULL;
@@ -175,7 +207,11 @@
 	if (!initialized) {
 		const char *inst_dir = wpurple_install_dir();
 		if (inst_dir != NULL) {
+#ifdef USE_FHS
+			locale_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S "share" G_DIR_SEPARATOR_S "locale", inst_dir);
+#else
 			locale_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "locale", inst_dir);
+#endif
 			initialized = TRUE;
 		} else {
 			return NULL;
@@ -375,6 +411,11 @@
 	lib_dir = NULL;
 	locale_dir = NULL;
 
+#ifdef USE_FHS
+	g_free(share_dir);
+	share_dir = NULL;	
+#endif
+
 	libpurpledll_hInstance = NULL;
 }
 
diff -r eb22b625ecad -r 61d53322cfd3 libpurple/win32/win32dep.h
--- a/libpurple/win32/win32dep.h	Wed Jan 22 20:47:54 2025 -0600
+++ b/libpurple/win32/win32dep.h	Tue Oct 28 21:04:01 2025 +0100
@@ -65,6 +65,7 @@
 const char *wpurple_install_dir(void);
 const char *wpurple_lib_dir(void);
 const char *wpurple_locale_dir(void);
+const char *wpurple_share_dir(void);
 const char *wpurple_data_dir(void);
 
 /* init / cleanup */
@@ -80,9 +81,14 @@
 /*
  *  Purple specific
  */
-#define DATADIR wpurple_install_dir()
-#define LIBDIR wpurple_lib_dir()
+#undef PURPLE_DATADIR
+#define PURPLE_DATADIR wpurple_share_dir()
+#undef PURPLE_LIBDIR
+#define PURPLE_LIBDIR wpurple_lib_dir()
+#undef LOCALEDIR
 #define LOCALEDIR wpurple_locale_dir()
+/* TODO: SYSCONFDIR should be the allusers AppData? */
+#undef SYSCONFDIR
 
 #ifdef __cplusplus
 }
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/Makefile.am
--- a/pidgin/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -7,19 +7,8 @@
 		data/pidgin.desktop.in \
 		data/pidgin.pc.in \
 		data/pidgin-uninstalled.pc.in \
-		win32/MinimizeToTray.h \
-		win32/MinimizeToTray.c \
 		win32/pidgin_dll_rc.rc.in \
 		win32/pidgin_exe_rc.rc.in \
-		win32/gtkdocklet-win32.c \
-		win32/gtkwin32dep.c \
-		win32/gtkwin32dep.h \
-		win32/resource.h \
-		win32/untar.c \
-		win32/untar.h \
-		win32/winpidgin.c \
-		win32/wspell.c \
-		win32/wspell.h \
 		win32/nsis/generate_gtk_zip.sh \
 		win32/nsis/rpm2zip.sh \
 		win32/nsis/pixmaps/pidgin-header.bmp \
@@ -31,13 +20,28 @@
 		win32/nsis/create_nsis_translations.pl \
 		win32/nsis/nsis_translations.desktop.in
 
+if !OS_WIN32
+EXTRA_DIST += \
+		win32/MinimizeToTray.c \
+		win32/MinimizeToTray.h \
+		win32/gtkdocklet-win32.c \
+		win32/gtkwin32dep.c \
+		win32/gtkwin32dep.h \
+		win32/resource.h \
+		win32/untar.c \
+		win32/untar.h \
+		win32/winpidgin.c \
+		win32/wspell.c \
+		win32/wspell.h
+endif
+
 if ENABLE_GTK
 
-SUBDIRS = pixmaps plugins
+SUBDIRS = . pixmaps plugins
 
 bin_PROGRAMS = pidgin
 
-pidgin_SOURCES = \
+common_SOURCES = \
 	pidginstock.c \
 	gtkaccount.c \
 	gtkblist.c \
@@ -51,7 +55,6 @@
 	gtkdialogs.c \
 	gtkdnd-hints.c \
 	gtkdocklet.c \
-	gtkdocklet-gtk.c \
 	gtkeventloop.c \
 	gtkft.c \
 	gtkicon-theme.c \
@@ -141,14 +144,30 @@
 	pidgintooltip.h \
 	pidgin.h
 
+if OS_WIN32
+pidgin_win32headers = \
+	gtkwin32dep.h
+pidgin_win32noinstheaders = \
+	MinimizeToTray.h \
+	resource.h \
+	untar.h \
+	wspell.h
+endif
+
 pidginincludedir=$(includedir)/pidgin
 pidgininclude_HEADERS = \
 	$(pidgin_headers)
 
+if OS_WIN32
+win32includedir=$(includedir)/pidgin/win32
+win32include_HEADERS = \
+	$(addprefix $(srcdir)/win32/, $(pidgin_win32headers))
+noinst_HEADERS = \
+	$(addprefix $(srcdir)/win32/, $(pidgin_win32noinstheaders))
+endif
 
 pidgin_DEPENDENCIES = @LIBOBJS@
-pidgin_LDFLAGS = -export-dynamic
-pidgin_LDADD = \
+common_LDADD = \
 	@LIBOBJS@ \
 	$(GLIB_LIBS) \
 	$(DBUS_LIBS) \
@@ -166,9 +185,47 @@
 	$(LIBM) \
 	$(top_builddir)/libpurple/libpurple.la
 
+if OS_WIN32
+lib_LTLIBRARIES = libpidgin.la
+
+pidgin_SOURCES = \
+	win32/pidgin_exe_rc.rc \
+	win32/winpidgin.c
+
+libpidgin_la_SOURCES = \
+	$(common_SOURCES) \
+	win32/MinimizeToTray.c \
+	win32/gtkdocklet-win32.c \
+	win32/gtkwin32dep.c \
+	win32/untar.c \
+	win32/wspell.c \
+	win32/pidgin_dll_rc.rc
+
+libpidgin_la_LDFLAGS = $(AVOID_VERSION) $(NO_UNDEFINED)
+libpidgin_la_LIBADD = $(common_LDADD) -lz -lwinmm -lgdi32
+
+pidgin_LDFLAGS = -mwindows
+pidgin_LDADD =
+	
+.rc.o:
+	$(WINDRES) $^ -o $@
+%.o : %.rc
+	$(WINDRES) -I$(top_srcdir)/pidgin -I$(top_srcdir)/pidgin/win32 -I$(top_srcdir)/libpurple -i $< -o $@
+
+else
+pidgin_SOURCES = \
+	$(common_SOURCES) \
+	gtkdocklet-gtk.c
+
+pidgin_CFLAGS = $(AM_CFLAGS)
+pidgin_LDFLAGS = -export-dynamic
+
+pidgin_LDADD = $(common_LDADD)
+endif
+
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
-	-DLIBDIR=\"$(libdir)/pidgin/\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
+	-DPIDGIN_LIBDIR=\"$(libdir)/pidgin/\" \
 	-DLOCALEDIR=\"$(datadir)/locale\" \
 	-DSYSCONFDIR=\"$(sysconfdir)\" \
 	-I$(top_builddir)/libpurple \
@@ -185,6 +242,14 @@
 	$(LIBXML_CFLAGS) \
 	$(INTGG_CFLAGS)
 
+	
+if OS_WIN32
+AM_CPPFLAGS += \
+	-DUSE_FHS \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32
+endif
+	
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = data/pidgin.pc
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/data/pidgin-2.pc.in
--- a/pidgin/data/pidgin-2.pc.in	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/data/pidgin-2.pc.in	Tue Oct 28 21:04:01 2025 +0100
@@ -13,3 +13,4 @@
 Version: @VERSION@
 Requires: gtk+-2.0 purple
 Cflags: -I${includedir}
+Libs: -L${libdir} -lpidgin
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/data/pidgin.pc.in
--- a/pidgin/data/pidgin.pc.in	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/data/pidgin.pc.in	Tue Oct 28 21:04:01 2025 +0100
@@ -12,5 +12,6 @@
 Description: Pidgin is a GTK2-based instant messenger application.
 Version: @VERSION@
 Requires: gtk+-2.0 purple
-Cflags: -I${includedir}/pidgin
+Cflags: -I${includedir}/pidgin -I${includedir}/pidgin/win32
+Libs: -L${libdir} -lpidgin
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkblist.c
--- a/pidgin/gtkblist.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkblist.c	Tue Oct 28 21:04:01 2025 +0100
@@ -3348,14 +3348,14 @@
 	char *path;
 
 	if (purple_strequal(mood, "busy")) {
-		path = g_build_filename(DATADIR, "pixmaps", "pidgin",
+		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin",
 		                        "status", "16", "busy.png", NULL);
 	} else if (purple_strequal(mood, "hiptop")) {
-		path = g_build_filename(DATADIR, "pixmaps", "pidgin",
+		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin",
 		                        "emblems", "16", "hiptop.png", NULL);
 	} else {
 		char *filename = g_strdup_printf("%s.png", mood);
-		path = g_build_filename(DATADIR, "pixmaps", "pidgin",
+		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin",
 		                        "emotes", "small", filename, NULL);
 		g_free(filename);
 	}
@@ -4003,7 +4003,7 @@
 		if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
 			/* This emblem comes from the small emoticon set now,
 			 * to reduce duplication. */
-			path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes",
+			path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emotes",
 						"small", "mobile.png", NULL);
 			return _pidgin_blist_get_cached_emblem(path);
 		}
@@ -4020,7 +4020,7 @@
 	g_return_val_if_fail(buddy != NULL, NULL);
 
 	if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) {
-		path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL);
+		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL);
 		return _pidgin_blist_get_cached_emblem(path);
 	}
 
@@ -4031,7 +4031,7 @@
 
 	if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
 		/* This emblem comes from the small emoticon set now, to reduce duplication. */
-		path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", "small", "mobile.png", NULL);
+		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emotes", "small", "mobile.png", NULL);
 		return _pidgin_blist_get_cached_emblem(path);
 	}
 
@@ -4039,17 +4039,17 @@
 	if (tune && purple_status_is_active(tune)) {
 		/* TODO: Replace "Tune" with generalized "Media" in 3.0. */
 		if (purple_status_get_attr_string(tune, "game") != NULL) {
-			path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "game.png", NULL);
+			path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emblems", "16", "game.png", NULL);
 			return _pidgin_blist_get_cached_emblem(path);
 		}
 		/* TODO: Replace "Tune" with generalized "Media" in 3.0. */
 		if (purple_status_get_attr_string(tune, "office") != NULL) {
-			path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "office.png", NULL);
+			path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emblems", "16", "office.png", NULL);
 			return _pidgin_blist_get_cached_emblem(path);
 		}
 		/* Regular old "tune" is the only one in all protocols. */
 		/* This emblem comes from the small emoticon set now, to reduce duplication. */
-		path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", "small", "music.png", NULL);
+		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emotes", "small", "music.png", NULL);
 		return _pidgin_blist_get_cached_emblem(path);
 	}
 
@@ -4076,7 +4076,7 @@
 		path = get_mood_icon_path(name);
 	} else {
 		filename = g_strdup_printf("%s.png", name);
-		path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL);
+		path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL);
 		g_free(filename);
 	}
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkdialogs.c
--- a/pidgin/gtkdialogs.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkdialogs.c	Tue Oct 28 21:04:01 2025 +0100
@@ -468,7 +468,7 @@
 	gtk_window_set_default_size(GTK_WINDOW(win), 450, 450);
 
 	/* Generate a logo with a version number */
-	filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "logo.png", NULL);
+	filename = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "logo.png", NULL);
 	pixbuf = pidgin_pixbuf_new_from_file(filename);
 	g_free(filename);
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkdnd-hints.c
--- a/pidgin/gtkdnd-hints.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkdnd-hints.c	Tue Oct 28 21:04:01 2025 +0100
@@ -121,7 +121,7 @@
 	for (i = 0; hint_windows[i].filename != NULL; i++) {
 		gchar *fname;
 
-		fname = g_build_filename(DATADIR, "pixmaps", "pidgin",
+		fname = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin",
 								 hint_windows[i].filename, NULL);
 
 		hint_windows[i].widget = dnd_hints_init_window(fname);
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkdocklet-gtk.c
--- a/pidgin/gtkdocklet-gtk.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkdocklet-gtk.c	Tue Oct 28 21:04:01 2025 +0100
@@ -289,6 +289,6 @@
 	}
 
 	gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
-		DATADIR G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "pidgin" G_DIR_SEPARATOR_S "tray");
+		PURPLE_DATADIR G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "pidgin" G_DIR_SEPARATOR_S "tray");
 }
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkmain.c
--- a/pidgin/gtkmain.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkmain.c	Tue Oct 28 21:04:01 2025 +0100
@@ -273,7 +273,7 @@
 #ifndef _WIN32
 	/* use the nice PNG icon for all the windows */
 	for(i=0; i<G_N_ELEMENTS(icon_sizes); i++) {
-		icon_path = g_build_filename(DATADIR, "icons", "hicolor", icon_sizes[i].dir, "apps", icon_sizes[i].filename, NULL);
+		icon_path = g_build_filename(PURPLE_DATADIR, "icons", "hicolor", icon_sizes[i].dir, "apps", icon_sizes[i].filename, NULL);
 		icon = pidgin_pixbuf_new_from_file(icon_path);
 		g_free(icon_path);
 		if (icon) {
@@ -821,7 +821,7 @@
 		fprintf(stderr, "Couldn't create plugins dir\n");
 	purple_plugins_add_search_path(search_path);
 	g_free(search_path);
-	purple_plugins_add_search_path(LIBDIR);
+	purple_plugins_add_search_path(PIDGIN_LIBDIR);
 
 	if (!purple_core_init(PIDGIN_UI)) {
 		fprintf(stderr,
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkprefs.c
--- a/pidgin/gtkprefs.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkprefs.c	Tue Oct 28 21:04:01 2025 +0100
@@ -555,7 +555,7 @@
 	/* refresh the list of themes in the manager */
 	purple_theme_manager_refresh();
 
-	tmp = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL);
+	tmp = g_build_filename(PURPLE_DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL);
 	pixbuf = pidgin_pixbuf_new_from_file_at_scale(tmp, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE);
 	g_free(tmp);
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtksound.c
--- a/pidgin/gtksound.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtksound.c	Tue Oct 28 21:04:01 2025 +0100
@@ -614,7 +614,7 @@
 			g_free(filename);
 
 			/* XXX Consider creating a constant for "sounds/purple" to be shared with Finch */
-			filename = g_build_filename(DATADIR, "sounds", "purple", sounds[event].def, NULL);
+			filename = g_build_filename(PURPLE_DATADIR, "sounds", "purple", sounds[event].def, NULL);
 		}
 
 		purple_sound_play_file(filename, NULL);
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkthemes.c
--- a/pidgin/gtkthemes.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkthemes.c	Tue Oct 28 21:04:01 2025 +0100
@@ -397,7 +397,7 @@
 
 	pidgin_smiley_themes_remove_non_existing();
 
-	probedirs[0] = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", NULL);
+	probedirs[0] = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "emotes", NULL);
 	probedirs[1] = g_build_filename(purple_user_dir(), "smileys", NULL);
 	probedirs[2] = 0;
 	for (l=0; probedirs[l]; l++) {
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/gtkutils.c
--- a/pidgin/gtkutils.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/gtkutils.c	Tue Oct 28 21:04:01 2025 +0100
@@ -607,7 +607,7 @@
 	 */
 	tmp = g_strconcat(protoname, ".png", NULL);
 
-	filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
+	filename = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "protocols",
 				    size == PIDGIN_PRPL_ICON_SMALL ? "16" :
 				    size == PIDGIN_PRPL_ICON_MEDIUM ? "22" : "48",
 				    tmp, NULL);
@@ -697,7 +697,7 @@
 		plugin = (PurplePlugin *)p->data;
 
 		if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) {
-			char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
+			char *filename = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "protocols",
 			                                  "16", "google-talk.png", NULL);
 			GtkWidget *item;
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/pidginstock.c
--- a/pidgin/pidginstock.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/pidginstock.c	Tue Oct 28 21:04:01 2025 +0100
@@ -241,7 +241,7 @@
 			return filename;
 		g_free(filename);
 	}
-	filename = g_build_filename(DATADIR, name, NULL);
+	filename = g_build_filename(PURPLE_DATADIR, name, NULL);
 	if (g_file_test(filename, G_FILE_TEST_EXISTS))
 		return filename;
 	g_free(filename);
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/Makefile.am
--- a/pidgin/plugins/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -1,4 +1,4 @@
-DIST_SUBDIRS = cap disco gestures gevolution musicmessaging perl ticker
+DIST_SUBDIRS = cap disco gestures gevolution musicmessaging perl ticker win32
 
 if BUILD_GEVOLUTION
 GEVOLUTION_DIR = gevolution
@@ -27,30 +27,35 @@
 	$(MUSICMESSAGING_DIR) \
 	$(PERL_DIR) \
 	disco \
-	ticker
+	ticker \
+	win32
 
+if OS_WIN32
+plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+else
 plugindir = $(libdir)/pidgin
+endif
 
-convcolors_la_LDFLAGS       = -module -avoid-version
-contact_priority_la_LDFLAGS = -module -avoid-version
-extplacement_la_LDFLAGS     = -module -avoid-version
-gtk_signals_test_la_LDFLAGS = -module -avoid-version
-gtkbuddynote_la_LDFLAGS     = -module -avoid-version
-history_la_LDFLAGS          = -module -avoid-version
-iconaway_la_LDFLAGS         = -module -avoid-version
-markerline_la_LDFLAGS       = -module -avoid-version
-notify_la_LDFLAGS           = -module -avoid-version
-pidginrc_la_LDFLAGS         = -module -avoid-version
-relnot_la_LDFLAGS           = -module -avoid-version
-sendbutton_la_LDFLAGS       = -module -avoid-version
-spellchk_la_LDFLAGS         = -module -avoid-version
-themeedit_la_LDFLAGS        = -module -avoid-version
-timestamp_la_LDFLAGS        = -module -avoid-version
-timestamp_format_la_LDFLAGS = -module -avoid-version
-transparency_la_LDFLAGS     = -module -avoid-version
-unity_la_LDFLAGS            = -module -avoid-version
-vvconfig_la_LDFLAGS         = -module -avoid-version
-xmppconsole_la_LDFLAGS      = -module -avoid-version
+convcolors_la_LDFLAGS       = -module -avoid-version $(NO_UNDEFINED)
+contact_priority_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+extplacement_la_LDFLAGS     = -module -avoid-version $(NO_UNDEFINED)
+gtk_signals_test_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+gtkbuddynote_la_LDFLAGS     = -module -avoid-version $(NO_UNDEFINED)
+history_la_LDFLAGS          = -module -avoid-version $(NO_UNDEFINED)
+iconaway_la_LDFLAGS         = -module -avoid-version $(NO_UNDEFINED)
+markerline_la_LDFLAGS       = -module -avoid-version $(NO_UNDEFINED)
+notify_la_LDFLAGS           = -module -avoid-version $(NO_UNDEFINED)
+pidginrc_la_LDFLAGS         = -module -avoid-version $(NO_UNDEFINED)
+relnot_la_LDFLAGS           = -module -avoid-version $(NO_UNDEFINED)
+sendbutton_la_LDFLAGS       = -module -avoid-version $(NO_UNDEFINED)
+spellchk_la_LDFLAGS         = -module -avoid-version $(NO_UNDEFINED)
+themeedit_la_LDFLAGS        = -module -avoid-version $(NO_UNDEFINED)
+timestamp_la_LDFLAGS        = -module -avoid-version $(NO_UNDEFINED)
+timestamp_format_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+transparency_la_LDFLAGS     = -module -avoid-version $(NO_UNDEFINED)
+unity_la_LDFLAGS            = -module -avoid-version $(NO_UNDEFINED)
+vvconfig_la_LDFLAGS         = -module -avoid-version $(NO_UNDEFINED)
+xmppconsole_la_LDFLAGS      = -module -avoid-version $(NO_UNDEFINED)
 
 if PLUGINS
 
@@ -105,41 +110,36 @@
 vvconfig_la_SOURCES         = vvconfig.c
 xmppconsole_la_SOURCES      = xmppconsole.c
 
-convcolors_la_LIBADD        = $(GTK_LIBS)
-contact_priority_la_LIBADD  = $(GTK_LIBS)
-extplacement_la_LIBADD      = $(GTK_LIBS)
-gtk_signals_test_la_LIBADD  = $(GTK_LIBS)
-gtkbuddynote_la_LIBADD      = $(GTK_LIBS)
-history_la_LIBADD           = $(GTK_LIBS)
-iconaway_la_LIBADD          = $(GTK_LIBS)
-markerline_la_LIBADD        = $(GTK_LIBS)
-notify_la_LIBADD            = $(GTK_LIBS)
-pidginrc_la_LIBADD          = $(GTK_LIBS)
-relnot_la_LIBADD            = $(GLIB_LIBS)
-sendbutton_la_LIBADD        = $(GTK_LIBS)
-spellchk_la_LIBADD          = $(GTK_LIBS)
-themeedit_la_LIBADD         = $(GTK_LIBS)
-timestamp_la_LIBADD         = $(GTK_LIBS)
-timestamp_format_la_LIBADD  = $(GTK_LIBS)
-transparency_la_LIBADD      = $(GTK_LIBS)
-unity_la_LIBADD             = $(GTK_LIBS) $(UNITY_LIBS)
-vvconfig_la_LIBADD          = $(GTK_LIBS) $(GSTREAMER_LIBS)
-xmppconsole_la_LIBADD       = $(GTK_LIBS)
+convcolors_la_LIBADD        = $(GTK_LIBS) $(PIDGIN_LIBS)
+contact_priority_la_LIBADD  = $(GTK_LIBS) $(PIDGIN_LIBS)
+extplacement_la_LIBADD      = $(GTK_LIBS) $(PIDGIN_LIBS)
+gtk_signals_test_la_LIBADD  = $(GTK_LIBS) $(PIDGIN_LIBS)
+gtkbuddynote_la_LIBADD      = $(GTK_LIBS) $(PIDGIN_LIBS)
+history_la_LIBADD           = $(GTK_LIBS) $(PIDGIN_LIBS)
+iconaway_la_LIBADD          = $(GTK_LIBS) $(PIDGIN_LIBS)
+markerline_la_LIBADD        = $(GTK_LIBS) $(PIDGIN_LIBS)
+notify_la_LIBADD            = $(GTK_LIBS) $(PIDGIN_LIBS)
+pidginrc_la_LIBADD          = $(GTK_LIBS) $(PIDGIN_LIBS)
+relnot_la_LIBADD            = $(GLIB_LIBS) $(PIDGIN_LIBS)
+sendbutton_la_LIBADD        = $(GTK_LIBS) $(PIDGIN_LIBS)
+spellchk_la_LIBADD          = $(GTK_LIBS) $(PIDGIN_LIBS)
+themeedit_la_LIBADD         = $(GTK_LIBS) $(PIDGIN_LIBS)
+timestamp_la_LIBADD         = $(GTK_LIBS) $(PIDGIN_LIBS)
+timestamp_format_la_LIBADD  = $(GTK_LIBS) $(PIDGIN_LIBS)
+transparency_la_LIBADD      = $(GTK_LIBS) $(PIDGIN_LIBS)
+unity_la_LIBADD             = $(GTK_LIBS) $(UNITY_LIBS) $(PIDGIN_LIBS)
+vvconfig_la_LIBADD          = $(GTK_LIBS) $(GSTREAMER_LIBS) $(PIDGIN_LIBS)
+xmppconsole_la_LIBADD       = $(GTK_LIBS) $(PIDGIN_LIBS)
 
 endif # PLUGINS
 
 EXTRA_DIST = \
-	Makefile.mingw \
 	mailchk.c \
 	pidgininc.c \
-	raw.c \
-	win32/winprefs/gtkappbar.c \
-	win32/winprefs/gtkappbar.h \
-	win32/winprefs/Makefile.mingw \
-	win32/winprefs/winprefs.c
+	raw.c
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_srcdir)/pidgin \
@@ -149,6 +149,12 @@
 	$(GSTREAMER_CFLAGS) \
 	$(PLUGIN_CFLAGS)
 
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32
+endif
+
 #
 # This part allows people to build their own plugins in here.
 # Yes, it's a mess.
@@ -156,7 +162,7 @@
 SUFFIXES = .c .so
 .c.so:
 	$(LIBTOOL) --mode=compile $(CC) -DHAVE_CONFIG_H -I$(top_builddir) $(AM_CPPFLAGS) $(CFLAGS) -c $< -o tmp$@.lo $(PLUGIN_CFLAGS)
-	$(LIBTOOL) --mode=link    $(CC) $(CFLAGS) -o libtmp$@.la -rpath $(plugindir) tmp$@.lo $(LIBS) $(LDFLAGS) -module -avoid-version $(PLUGIN_LIBS)
+	$(LIBTOOL) --mode=link    $(CC) $(CFLAGS) -o libtmp$@.la -rpath $(plugindir) tmp$@.lo $(LIBS) $(LDFLAGS) -module -avoid-version $(NO_UNDEFINED) $(PLUGIN_LIBS)
 	@rm -f tmp$@.lo tmp$@.o libtmp$@.la
 	@cp .libs/libtmp$@*.so $@
 	@rm -rf .libs/libtmp$@.*
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/cap/Makefile.am
--- a/pidgin/plugins/cap/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/cap/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -18,7 +18,7 @@
 cap_la_LIBADD = $(GTK_LIBS) $(SQLITE3_LIBS)
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/pidgin \
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/disco/Makefile.am
--- a/pidgin/plugins/disco/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/disco/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -1,6 +1,10 @@
+if OS_WIN32
+plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+else
 plugindir = $(libdir)/pidgin
+endif
 
-xmppdisco_la_LDFLAGS = -module -avoid-version
+xmppdisco_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 EXTRA_DIST = \
         Makefile.mingw
@@ -15,14 +19,21 @@
 	xmppdisco.c \
 	xmppdisco.h
 
-xmppdisco_la_LIBADD = $(GTK_LIBS)
+xmppdisco_la_LIBADD = $(GTK_LIBS) $(PURPLE_LIBS) $(PIDGIN_LIBS)
 
 endif
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/pidgin \
 	$(DEBUG_CFLAGS) \
 	$(GTK_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32
+endif
+
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/disco/gtkdisco.c
--- a/pidgin/plugins/disco/gtkdisco.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/disco/gtkdisco.c	Tue Oct 28 21:04:01 2025 +0100
@@ -119,14 +119,14 @@
 
 	if (service->type == XMPP_DISCO_SERVICE_TYPE_GATEWAY && service->gateway_type) {
 		char *tmp = g_strconcat(service->gateway_type, ".png", NULL);
-		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", size, tmp, NULL);
+		filename = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "protocols", size, tmp, NULL);
 		g_free(tmp);
 #if 0
 	} else if (service->type == XMPP_DISCO_SERVICE_TYPE_USER) {
-		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "status", size, "person.png", NULL);
+		filename = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "status", size, "person.png", NULL);
 #endif
 	} else if (service->type == XMPP_DISCO_SERVICE_TYPE_CHAT)
-		filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "status", size, "chat.png", NULL);
+		filename = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "status", size, "chat.png", NULL);
 
 	if (filename) {
 		pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/gestures/Makefile.am
--- a/pidgin/plugins/gestures/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/gestures/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -1,6 +1,10 @@
+if OS_WIN32
+plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+else
 plugindir = $(libdir)/pidgin
+endif
 
-gestures_la_LDFLAGS = -module -avoid-version
+gestures_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if PLUGINS
 
@@ -13,14 +17,20 @@
 	stroke.c \
 	stroke-draw.c
 
-gestures_la_LIBADD = $(GTK_LIBS)
+gestures_la_LIBADD = $(GTK_LIBS) $(PURPLE_LIBS) $(PIDGIN_LIBS) $(GLIB_LIBS)
 
 endif
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/pidgin \
 	$(DEBUG_CFLAGS) \
 	$(GTK_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32
+endif
\ No newline at end of file
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/gevolution/Makefile.am
--- a/pidgin/plugins/gevolution/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/gevolution/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -1,6 +1,10 @@
+if OS_WIN32
+plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+else
 plugindir = $(libdir)/pidgin
+endif
 
-gevolution_la_LDFLAGS = -module -avoid-version
+gevolution_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if PLUGINS
 
@@ -15,15 +19,22 @@
 	new_person_dialog.c \
 	eds-utils.c
 
-gevolution_la_LIBADD = $(EVOLUTION_ADDRESSBOOK_LIBS) $(GTK_LIBS)
+gevolution_la_LIBADD = $(EVOLUTION_ADDRESSBOOK_LIBS) $(GTK_LIBS) $(PURPLE_LIBS) $(PIDGIN_LIBS) $(GLIB_LIBS)
 
 endif
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/pidgin \
 	$(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+	$(GLIB_CFLAGS) \
 	$(DEBUG_CFLAGS) \
 	$(GTK_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/musicmessaging/Makefile.am
--- a/pidgin/plugins/musicmessaging/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/musicmessaging/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -1,7 +1,11 @@
 EXTRA_DIST = \
 	music.png
 
+if OS_WIN32
+musicmessagingdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+else
 musicmessagingdir = $(libdir)/pidgin
+endif
 
 musicmessaging_la_LDFLAGS = -module -avoid-version
 
@@ -16,7 +20,7 @@
 musicmessaging_la_SOURCES = \
 	musicmessaging.c
 
-musicmessaging_la_LIBADD = $(GTK_LIBS) $(DBUS_LIBS)
+musicmessaging_la_LIBADD = $(GTK_LIBS) $(DBUS_LIBS) $(PURPLE_LIBS) $(PIDGIN_LIBS)
 
 CLEANFILES              = music-messaging-bindings.c
 
@@ -35,10 +39,16 @@
 endif
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_srcdir)/pidgin \
 	$(DEBUG_CFLAGS) \
 	$(GTK_CFLAGS) \
 	$(DBUS_CFLAGS)
+	
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/musicmessaging/musicmessaging.c
--- a/pidgin/plugins/musicmessaging/musicmessaging.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/musicmessaging/musicmessaging.c	Tue Oct 28 21:04:01 2025 +0100
@@ -548,11 +548,13 @@
 
 static void kill_editor (MMConversation *mmconv)
 {
+#ifndef _WIN32
 	if (mmconv->pid)
 	{
 		kill(mmconv->pid, SIGINT);
 		mmconv->pid = 0;
 	}
+#endif
 }
 
 static void init_conversation (PurpleConversation *conv)
@@ -595,7 +597,7 @@
 
 	g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(music_button_toggled), mmconv);
 
-	file_path = g_build_filename(DATADIR, "pixmaps", "purple", "buttons",
+	file_path = g_build_filename(PURPLE_DATADIR, "pixmaps", "purple", "buttons",
 										"music.png", NULL);
 	image = gtk_image_new_from_file(file_path);
 	g_free(file_path);
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/ticker/Makefile.am
--- a/pidgin/plugins/ticker/Makefile.am	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/ticker/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -1,9 +1,13 @@
 EXTRA_DIST = \
 		Makefile.mingw
 
+if OS_WIN32
+plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+else
 plugindir = $(libdir)/pidgin
+endif
 
-ticker_la_LDFLAGS = -module -avoid-version
+ticker_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
 
 if PLUGINS
 
@@ -14,14 +18,20 @@
 	gtkticker.h \
 	ticker.c
 
-ticker_la_LIBADD = $(GTK_LIBS)
+ticker_la_LIBADD = $(GTK_LIBS) $(PURPLE_LIBS) $(PIDGIN_LIBS)
 
 endif
 
 AM_CPPFLAGS = \
-	-DDATADIR=\"$(datadir)\" \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
 	-I$(top_srcdir)/libpurple \
 	-I$(top_builddir)/libpurple \
 	-I$(top_srcdir)/pidgin \
 	$(DEBUG_CFLAGS) \
 	$(GTK_CFLAGS)
+
+if OS_WIN32
+AM_CPPFLAGS += \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32
+endif
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/win32/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/plugins/win32/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,9 @@
+DIST_SUBDIRS = winprefs
+
+if OS_WIN32
+SUBDIRS = $(DIST_SUBDIRS)
+endif
+
+EXTRA_DIST = \
+	Makefile.mingw
+
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/win32/winprefs/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/plugins/win32/winprefs/Makefile.am	Tue Oct 28 21:04:01 2025 +0100
@@ -0,0 +1,35 @@
+EXTRA_DIST = \
+	gtkappbar.c \
+	gtkappbar.h \
+	winprefs.c \
+	Makefile.mingw
+
+if OS_WIN32
+plugindir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
+
+winprefs_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+if PLUGINS
+
+plugin_LTLIBRARIES = winprefs.la
+
+winprefs_la_SOURCES = \
+	gtkappbar.c \
+	gtkappbar.h \
+	winprefs.c
+
+winprefs_la_LIBADD = $(GTK_LIBS) $(PURPLE_LIBS) $(PIDGIN_LIBS)
+
+endif
+
+AM_CPPFLAGS = \
+	-DPURPLE_DATADIR=\"$(datadir)\" \
+	-I$(top_srcdir)/libpurple \
+	-I$(top_builddir)/libpurple \
+	-I$(top_srcdir)/pidgin \
+	-I$(top_srcdir)/libpurple/win32 \
+	-I$(top_srcdir)/pidgin/win32 \
+	$(DEBUG_CFLAGS) \
+	$(GTK_CFLAGS)
+
+endif
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/plugins/win32/winprefs/gtkappbar.c
--- a/pidgin/plugins/win32/winprefs/gtkappbar.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/plugins/win32/winprefs/gtkappbar.c	Tue Oct 28 21:04:01 2025 +0100
@@ -27,6 +27,7 @@
  *  - Move 'App on top' feature from Trans plugin to here
  *  - Bug: Multiple Show/Hide Desktop calls causes client area to disappear
  */
+#define WINVER 0x500
 #include <windows.h>
 #include <winver.h>
 #include <stdio.h>
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/win32/MinimizeToTray.c
--- a/pidgin/win32/MinimizeToTray.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/win32/MinimizeToTray.c	Tue Oct 28 21:04:01 2025 +0100
@@ -14,6 +14,7 @@
  *
  * Copyright 2000 Matthew Ellis <m.t.ellis@bigfoot.com>
  */
+#define _WIN32_WINNT 0x0501
 #include <windows.h>
 #include "MinimizeToTray.h"
 
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/win32/gtkdocklet-win32.c
--- a/pidgin/win32/gtkdocklet-win32.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/win32/gtkdocklet-win32.c	Tue Oct 28 21:04:01 2025 +0100
@@ -21,7 +21,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  * 02111-1301, USA.
  */
-#define _WIN32_IE 0x0500
+#define _WIN32_IE 0x0501
 #include <windows.h>
 #include <gdk/gdkwin32.h>
 #include <gdk/gdk.h>
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/win32/gtkwin32dep.h
--- a/pidgin/win32/gtkwin32dep.h	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/win32/gtkwin32dep.h	Tue Oct 28 21:04:01 2025 +0100
@@ -25,6 +25,10 @@
 #include <windows.h>
 #include <gtk/gtk.h>
 #include "conversation.h"
+#include "win32dep.h"
+
+#undef PIDGIN_LIBDIR
+#define PIDGIN_LIBDIR PURPLE_LIBDIR
 
 HINSTANCE winpidgin_dll_hinstance(void);
 HINSTANCE winpidgin_exe_hinstance(void);
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/win32/pidgin_exe_rc.rc.in
--- a/pidgin/win32/pidgin_exe_rc.rc.in	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/win32/pidgin_exe_rc.rc.in	Tue Oct 28 21:04:01 2025 +0100
@@ -3,8 +3,8 @@
 #include "version.h"
 
 VS_VERSION_INFO VERSIONINFO
-  FILEVERSION PURPLE_MAJOR_VERSION,PURPLE_MINOR_VERSION,PURPLE_MICRO_VERSION,0
-  PRODUCTVERSION PURPLE_MAJOR_VERSION,PURPLE_MINOR_VERSION,PURPLE_MICRO_VERSION,0
+  FILEVERSION @PURPLE_MAJOR_VERSION@,@PURPLE_MINOR_VERSION@,@PURPLE_MICRO_VERSION@,0
+  PRODUCTVERSION @PURPLE_MAJOR_VERSION@,@PURPLE_MINOR_VERSION@,@PURPLE_MICRO_VERSION@,0
   FILEFLAGSMASK 0
   FILEFLAGS 0
   FILEOS VOS__WINDOWS32
@@ -20,7 +20,7 @@
         VALUE "FileVersion", "@PIDGIN_VERSION@"
         VALUE "InternalName", "pidgin"
         VALUE "LegalCopyright", "Copyright (C) 1998-2010 The Pidgin developer community (See the COPYRIGHT file in the source distribution)."
-        VALUE "OriginalFilename", "@ORIGINAL_FILENAME@"
+        VALUE "OriginalFilename", "pidgin.exe"
         VALUE "ProductName", "Pidgin"
         VALUE "ProductVersion", "@PIDGIN_VERSION@"
       END
diff -r eb22b625ecad -r 61d53322cfd3 pidgin/win32/winpidgin.c
--- a/pidgin/win32/winpidgin.c	Wed Jan 22 20:47:54 2025 -0600
+++ b/pidgin/win32/winpidgin.c	Tue Oct 28 21:04:01 2025 +0100
@@ -316,11 +316,19 @@
 					posix = L"sr@Latn"; break;
 				case SUBLANG_SERBIAN_CYRILLIC:
 					posix = L"sr"; break;
+/* for some reason mingw-w64 doesn't have these definitions yet */
+#ifdef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
 				case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC:
+					posix = L"bs"; break;
+#endif
+#ifdef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
 				case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN:
 					posix = L"bs"; break;
+#endif
+#ifdef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
 				case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN:
 					posix = L"hr"; break;
+#endif
 			}
 			break;
 		case LANG_SWEDISH: posix = L"sv"; break;
@@ -699,7 +707,7 @@
 			return 0;
 
 	/* Now we are ready for Pidgin .. */
-	wcscat(pidgin_dir, L"\\pidgin.dll");
+	wcscat(pidgin_dir, L"\\libpidgin.dll");
 	wprintf(L"attempting to load '%ls'\n", pidgin_dir);
 	if ((hmod = LoadLibraryW(pidgin_dir)))
 		pidgin_main = (LPFNPIDGINMAIN) GetProcAddress(hmod, "pidgin_main");
@@ -713,7 +721,7 @@
 		BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND);
 		const wchar_t *err_msg = get_win32_error_message(dw);
 
-		_snwprintf(errbuf, 512, L"Error loading pidgin.dll.\nError: (%u) %ls%ls%ls",
+		_snwprintf(errbuf, 512, L"Error loading libpidgin.dll.\nError: (%u) %ls%ls%ls",
 			(UINT) dw, err_msg,
 			mod_not_found ? L"\n" : L"",
 			mod_not_found ? L"This probably means that GTK+ can't be found." : L"");
openSUSE Build Service is sponsored by