pidgin/pidgin

merge
trac-17174
2017-11-29, Daniel Kamil Kozar
93c0cd117e1d
merge
--- a/COPYRIGHT Wed Sep 20 01:38:28 2017 +0200
+++ b/COPYRIGHT Wed Nov 29 20:40:36 2017 +0100
@@ -15,7 +15,7 @@
piece of code, then that code should be traced through our version
control system to see from where it came and who has modified it.
-Copyright (C) 1998-2013 by the following:
+Copyright (C) 1998-2017 by the following:
Mark
Saleem Abdulrasool
@@ -310,9 +310,11 @@
Jean-Yves Lefort
Moses Lei
Ambrose C. Li
+Tom Li
Nicolas Lichtmaier
Wesley Lin
Shaun Lindsay
+Shivaram Lingamneni
Artem Litvinovich
Josh Littlefield
Daniel Ljungborg
@@ -351,6 +353,7 @@
Torrey McMahon
Greg McNew
Robert McQueen
+Christof Meerwald
Mihály Mészáros
Robert Mibus
David Michael
@@ -619,6 +622,7 @@
Kevin Wu Won
Pui Lam Wong
Justin Wood
+David Woodhouse
Ximian
Ma Xuan
Yonas Yanfa
--- a/ChangeLog Wed Sep 20 01:38:28 2017 +0200
+++ b/ChangeLog Wed Nov 29 20:40:36 2017 +0100
@@ -1,17 +1,40 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
-version 2.12.1 (??/??/????):
+version 2.13.0 (??/??/????):
libpurple:
* Unified string comparison. (PR #186) (Arkadiy Illarionov)
+ * Properlly shell escape URI's when opening them. (PR #271 Daniel Kamil Kozar)
+
+ libgnt:
+ * Fixed build against curses 6.0 with opaque structs set. (#16764 dimstar)
+ (PR #268 Daniel Kamil Kozar)
+ * Fixed a crash when resizing the window. (#16680 marcus) (PR #269 Daniel Kamil Kozar)
+
+ General:
+ * Fixed bashism in autotools. (#16836 lameventanas) (PR #267 Daniel Kamil Kozar)
XMPP:
* Show XEP-0066 OOB URLs in any message, not just headlines
+ * Fix a user after free (#17200 debarshiray) (PR #266 Ethan Blanton)
+ * Removed pipelining from BOSH connections (#17025 PR #295 Tom Li)
IRC:
* Fix "Registration timeout" on SASL auth with InspIRCd servers
(and possibly others not based on charybdis/ratbox/ircd-seven)
* Fix issues with plugins that modify outgoing messages
(such as the custom PART/QUIT feature of the IRC More plugin)
+ * Fix IRC buffer handling. (#12562 PR #272 Shivaram Lingamneni)
+
+ Pidgin:
+ * Better support for dark themes. (#12572 Alyssa Rosenzweig and Gary Kramlich)
+ * Fixed IPv6 links by not escaping []'s. (#16391 cyisfor) (PR #270 Daniel Kamil Kozar)
+ * Only write buddy icons to the cache if they're not already cached. (PR #276 David Woodhouse)
+ * Rejoin persistent chats after reconnect. (#15687 PR #285 Christof Meerwald)
+ * Made the WIN32 Transparency plugin work on all platforms. (#3124 PR #287 Daniel Kamil Kozar)
+ * Ensure search results buttons are labeled (Backport from de2d88e575ee)
+
+ Finch:
+ * Fix handling of search results (#17238 David Woodhouse)
version 2.12.0 (03/09/2017):
libpurple:
--- a/ChangeLog.API Wed Sep 20 01:38:28 2017 +0200
+++ b/ChangeLog.API Wed Nov 29 20:40:36 2017 +0100
@@ -1,5 +1,10 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
+version 2.13.0:
+ libpurple:
+ Added:
+ * purple_uri_escape_for_open
+
version 2.12.0:
libpurple:
Added:
--- a/configure.ac Wed Sep 20 01:38:28 2017 +0200
+++ b/configure.ac Wed Nov 29 20:40:36 2017 +0100
@@ -43,10 +43,10 @@
#
# Make sure to update finch/libgnt/configure.ac with libgnt version changes.
#
-m4_define([purple_lt_current], [12])
+m4_define([purple_lt_current], [13])
m4_define([purple_major_version], [2])
-m4_define([purple_minor_version], [12])
-m4_define([purple_micro_version], [1])
+m4_define([purple_minor_version], [13])
+m4_define([purple_micro_version], [0])
m4_define([purple_version_suffix], [devel])
m4_define([purple_version],
[purple_major_version.purple_minor_version.purple_micro_version])
@@ -748,7 +748,7 @@
[compile with GStreamer 0.10 or 1.0 interface (default: auto)])],
with_gstreamer="$withval", with_gstreamer="auto")
if test "x$enable_gst" != "xno"; then
- if test "x$with_gstreamer" == "xauto"; then
+ if test "x$with_gstreamer" = "xauto"; then
PKG_CHECK_MODULES(GSTREAMER, [gstreamer-1.0], [
AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
with_gstreamer="1.0"
@@ -772,7 +772,7 @@
fi
])
])
- elif test "x$with_gstreamer" == "x1.0"; then
+ elif test "x$with_gstreamer" = "x1.0"; then
PKG_CHECK_MODULES(GSTREAMER, [gstreamer-1.0], [
AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer 1.0 for playing sounds])
AC_SUBST(GSTREAMER_CFLAGS)
@@ -787,7 +787,7 @@
])
fi
])
- elif test "x$with_gstreamer" == "x0.10"; then
+ elif test "x$with_gstreamer" = "x0.10"; then
PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], [
AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer 0.10 for playing sounds])
AC_SUBST(GSTREAMER_CFLAGS)
@@ -807,14 +807,14 @@
fi
fi
-if test "x$with_gtk" == "x3" -a "x$with_gstreamer" == "x0.10"; then
+if test "x$with_gtk" = "x3" -a "x$with_gstreamer" = "x0.10"; then
AC_MSG_ERROR([WebKitGTK+ 3.0 cannot be mixed with GStreamer 0.10.
Please switch to WebKitGTK+ 2.0 or GStreamer 1.0.])
-elif test "x$with_gtk" == "x2" -a "x$with_gstreamer" == "x1.0"; then
+elif test "x$with_gtk" = "x2" -a "x$with_gstreamer" = "x1.0"; then
AC_MSG_ERROR([WebKitGTK+ 2.0 cannot be mixed with GStreamer 1.0.
Please switch to WebKitGTK+ 3.0 or GStreamer 0.10.])
fi
-if test "x$with_gstreamer" == "x0.10" -o "x$with_gstreamer" == "x1.0"; then
+if test "x$with_gstreamer" = "x0.10" -o "x$with_gstreamer" = "x1.0"; then
AC_SUBST(GSTREAMER_VER, [$with_gstreamer])
else
AC_SUBST(GSTREAMER_VER, "")
@@ -823,7 +823,7 @@
dnl #######################################################################
dnl # Check for GStreamer Video
dnl #######################################################################
-if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x1.0"; then
+if test "x$enable_gst" != "xno" -a "x$with_gstreamer" = "x1.0"; then
AC_ARG_ENABLE(gstreamer-video,
[AS_HELP_STRING([--disable-gstreamer-video], [compile without GStreamer 1.0 Video Overlay support])],
enable_gstvideo="$enableval", enable_gstvideo="yes")
@@ -843,7 +843,7 @@
dnl #######################################################################
dnl # Check for GStreamer Interfaces
dnl #######################################################################
-if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x0.10"; then
+if test "x$enable_gst" != "xno" -a "x$with_gstreamer" = "x0.10"; then
AC_ARG_ENABLE(gstreamer-interfaces,
[AS_HELP_STRING([--disable-gstreamer-interfaces], [compile without GStreamer 0.10 interface support])],
enable_gstinterfaces="$enableval", enable_gstinterfaces="yes")
@@ -867,7 +867,7 @@
[AS_HELP_STRING([--disable-farstream], [compile without farstream support])],
enable_farstream="$enableval", enable_farstream="yes")
if test "x$enable_farstream" != "xno"; then
- if test "x$with_gstreamer" == "x1.0"; then
+ if test "x$with_gstreamer" = "x1.0"; then
PKG_CHECK_MODULES(FARSTREAM, [farstream-0.2 >= 0.2.7], [
AC_SUBST(FARSTREAM_CFLAGS)
AC_SUBST(FARSTREAM_LIBS)
@@ -898,9 +898,9 @@
[AS_HELP_STRING([--disable-vv], [compile without voice and video support])],
enable_vv="$enableval", enable_vv="yes")
if test "x$enable_vv" != "xno"; then
- if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x1.0" -a "x$enable_gstvideo" != "xno" -a "x$enable_farstream" != "xno"; then
+ if test "x$enable_gst" != "xno" -a "x$with_gstreamer" = "x1.0" -a "x$enable_gstvideo" != "xno" -a "x$enable_farstream" != "xno"; then
AC_DEFINE(USE_VV, 1, [Use voice and video])
- elif test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x0.10" -a "x$enable_gstinterfaces" != "xno" -a "x$enable_farstream" != "xno"; then
+ elif test "x$enable_gst" != "xno" -a "x$with_gstreamer" = "x0.10" -a "x$enable_gstinterfaces" != "xno" -a "x$enable_farstream" != "xno"; then
AC_DEFINE(USE_VV, 1, [Use voice and video])
else
enable_vv="no"
@@ -918,7 +918,7 @@
dnl #######################################################################
dnl # Check for Raw data streams support in Farstream
dnl #######################################################################
-if test "x$enable_vv" != "xno" -a "x$with_gstreamer" == "x1.0"; then
+if test "x$enable_vv" != "xno" -a "x$with_gstreamer" = "x1.0"; then
AC_MSG_CHECKING(for raw data support in Farstream)
PKG_CHECK_MODULES(GSTAPP, [gstreamer-app-1.0], [
AC_DEFINE(USE_GSTAPP, 1, [Use GStreamer Video Overlay support])
--- a/finch/gntnotify.c Wed Sep 20 01:38:28 2017 +0200
+++ b/finch/gntnotify.c Wed Nov 29 20:40:36 2017 +0100
@@ -388,10 +388,11 @@
finch_notify_sr_new_rows(PurpleConnection *gc,
PurpleNotifySearchResults *results, void *data)
{
- GntTree *tree = GNT_TREE(data);
+ GntWindow *window = GNT_WINDOW(data);
+ GntTree *tree = GNT_TREE(g_object_get_data(G_OBJECT(window), "tree-widget"));
GList *o;
- /* XXX: Do I need to empty the tree here? */
+ gnt_tree_remove_all(GNT_TREE(tree));
for (o = results->rows; o; o = o->next)
{
@@ -483,12 +484,16 @@
gnt_box_add_widget(GNT_BOX(window), box);
- finch_notify_sr_new_rows(gc, results, tree);
+ g_object_set_data(G_OBJECT(window), "tree-widget", tree);
+ finch_notify_sr_new_rows(gc, results, window);
+
+ g_signal_connect(G_OBJECT(window), "destroy",
+ G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(PURPLE_NOTIFY_SEARCHRESULTS));
gnt_widget_show(window);
g_object_set_data(G_OBJECT(window), "notify-results", results);
- return tree;
+ return window;
}
static void *
--- a/finch/libgnt/gntmain.c Wed Sep 20 01:38:28 2017 +0200
+++ b/finch/libgnt/gntmain.c Wed Nov 29 20:40:36 2017 +0100
@@ -407,10 +407,11 @@
#ifdef SIGWINCH
static void (*org_winch_handler)(int);
+static void (*org_winch_handler_sa)(int, siginfo_t *, void *);
#endif
static void
-sighandler(int sig)
+sighandler(int sig, siginfo_t *info, void *data)
{
switch (sig) {
#ifdef SIGWINCH
@@ -419,16 +420,15 @@
g_idle_add((GSourceFunc)refresh_screen, NULL);
if (org_winch_handler)
org_winch_handler(sig);
- signal(SIGWINCH, sighandler);
+ if (org_winch_handler_sa)
+ org_winch_handler_sa(sig, info, data);
break;
#endif
case SIGCHLD:
clean_pid();
- signal(SIGCHLD, sighandler);
break;
case SIGINT:
ask_before_exit();
- signal(SIGINT, sighandler);
break;
}
}
@@ -456,6 +456,10 @@
{
char *filename;
const char *locale;
+ struct sigaction act;
+#ifdef SIGWINCH
+ struct sigaction oact;
+#endif
if (channel)
return;
@@ -501,11 +505,25 @@
werase(stdscr);
wrefresh(stdscr);
+ act.sa_sigaction = sighandler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO;
+
#ifdef SIGWINCH
- org_winch_handler = signal(SIGWINCH, sighandler);
+ org_winch_handler = NULL;
+ org_winch_handler_sa = NULL;
+ sigaction(SIGWINCH, &act, &oact);
+ if (oact.sa_flags & SA_SIGINFO)
+ {
+ org_winch_handler_sa = oact.sa_sigaction;
+ }
+ else if (oact.sa_handler != SIG_DFL && oact.sa_handler != SIG_IGN)
+ {
+ org_winch_handler = oact.sa_handler;
+ }
#endif
- signal(SIGCHLD, sighandler);
- signal(SIGINT, sighandler);
+ sigaction(SIGCHLD, &act, NULL);
+ sigaction(SIGINT, &act, NULL);
signal(SIGPIPE, SIG_IGN);
#if !GLIB_CHECK_VERSION(2, 36, 0)
--- a/finch/libgnt/gntwm.c Wed Sep 20 01:38:28 2017 +0200
+++ b/finch/libgnt/gntwm.c Wed Nov 29 20:40:36 2017 +0100
@@ -174,37 +174,37 @@
cchar_t ch;
PANEL *below = panel;
- sx = panel->win->_begx;
- ex = panel->win->_maxx + sx;
- sy = panel->win->_begy;
- ey = panel->win->_maxy + sy;
+ sx = getbegx(panel->win);
+ ex = getmaxx(panel->win) + sx;
+ sy = getbegy(panel->win);
+ ey = getmaxy(panel->win) + sy;
while ((below = panel_below(below)) != NULL) {
- if (sy > below->win->_begy + below->win->_maxy ||
- ey < below->win->_begy)
+ if (sy > getbegy(below->win) + getmaxy(below->win) ||
+ ey < getbegy(below->win))
continue;
- if (sx > below->win->_begx + below->win->_maxx ||
- ex < below->win->_begx)
+ if (sx > getbegx(below->win) + getmaxx(below->win) ||
+ ex < getbegx(below->win))
continue;
- for (y = MAX(sy, below->win->_begy); y <= MIN(ey, below->win->_begy + below->win->_maxy); y++) {
- if (mvwin_wch(below->win, y - below->win->_begy, sx - 1 - below->win->_begx, &ch) != OK)
+ for (y = MAX(sy, getbegy(below->win)); y <= MIN(ey, getbegy(below->win) + getmaxy(below->win)); y++) {
+ if (mvwin_wch(below->win, y - getbegy(below->win), sx - 1 - getbegx(below->win), &ch) != OK)
goto right;
w = widestringwidth(ch.chars);
if (w > 1 && (ch.attr & 1)) {
ch.chars[0] = ' ';
ch.attr &= ~ A_CHARTEXT;
- mvwadd_wch(below->win, y - below->win->_begy, sx - 1 - below->win->_begx, &ch);
- touchline(below->win, y - below->win->_begy, 1);
+ mvwadd_wch(below->win, y - getbegy(below->win), sx - 1 - getbegx(below->win), &ch);
+ touchline(below->win, y - getbegy(below->win), 1);
}
right:
- if (mvwin_wch(below->win, y - below->win->_begy, ex + 1 - below->win->_begx, &ch) != OK)
+ if (mvwin_wch(below->win, y - getbegy(below->win), ex + 1 - getbegx(below->win), &ch) != OK)
continue;
w = widestringwidth(ch.chars);
if (w > 1 && !(ch.attr & 1)) {
ch.chars[0] = ' ';
ch.attr &= ~ A_CHARTEXT;
- mvwadd_wch(below->win, y - below->win->_begy, ex + 1 - below->win->_begx, &ch);
- touchline(below->win, y - below->win->_begy, 1);
+ mvwadd_wch(below->win, y - getbegy(below->win), ex + 1 - getbegx(below->win), &ch);
+ touchline(below->win, y - getbegy(below->win), 1);
}
}
}
--- a/libpurple/buddyicon.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/buddyicon.c Wed Nov 29 20:40:36 2017 +0100
@@ -174,8 +174,12 @@
}
}
- purple_util_write_data_to_file_absolute(path, purple_imgstore_get_data(img),
- purple_imgstore_get_size(img));
+ if (!g_file_test(path, G_FILE_TEST_IS_REGULAR))
+ {
+ purple_util_write_data_to_file_absolute(path, purple_imgstore_get_data(img),
+ purple_imgstore_get_size(img));
+ }
+
g_free(path);
}
--- a/libpurple/media/backend-fs2.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/media/backend-fs2.c Wed Nov 29 20:40:36 2017 +0100
@@ -1151,7 +1151,7 @@
FsParticipant *participant;
PurpleMediaBackendFs2Session *session;
PurpleMediaBackendFs2Stream *media_stream;
- gchar *name;
+ const gchar *name;
value = gst_structure_get_value(structure, "stream");
stream = g_value_get_object(value);
@@ -1165,8 +1165,7 @@
local_candidate->foundation);
g_object_get(stream, "participant", &participant, NULL);
- g_object_get(participant, "cname", &name, NULL);
- g_object_unref(participant);
+ name = g_object_get_data(G_OBJECT(participant), "purple-name");
media_stream = get_stream(self, session->id, name);
media_stream->local_candidates = g_list_append(
@@ -1177,6 +1176,7 @@
g_signal_emit_by_name(self, "new-candidate",
session->id, name, candidate);
g_object_unref(candidate);
+ g_object_unref(participant);
} else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-local-candidates-prepared")) {
@@ -1187,18 +1187,18 @@
FsStream *stream;
FsParticipant *participant;
PurpleMediaBackendFs2Session *session;
- gchar *name;
value = gst_structure_get_value(structure, "stream");
stream = g_value_get_object(value);
session = get_session_from_fs_stream(self, stream);
g_object_get(stream, "participant", &participant, NULL);
- g_object_get(participant, "cname", &name, NULL);
- g_object_unref(participant);
g_signal_emit_by_name(self, "candidates-prepared",
- session->id, name);
+ session->id,
+ g_object_get_data(G_OBJECT(participant), "purple-name"));
+
+ g_object_unref(participant);
} else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-new-active-candidate-pair")) {
@@ -1212,7 +1212,6 @@
FsParticipant *participant;
PurpleMediaBackendFs2Session *session;
PurpleMediaCandidate *lcandidate, *rcandidate;
- gchar *name;
value = gst_structure_get_value(structure, "stream");
stream = g_value_get_object(value);
@@ -1222,8 +1221,6 @@
remote_candidate = g_value_get_boxed(value);
g_object_get(stream, "participant", &participant, NULL);
- g_object_get(participant, "cname", &name, NULL);
- g_object_unref(participant);
session = get_session_from_fs_stream(self, stream);
@@ -1231,8 +1228,11 @@
rcandidate = candidate_from_fs(remote_candidate);
g_signal_emit_by_name(self, "active-candidate-pair",
- session->id, name, lcandidate, rcandidate);
-
+ session->id,
+ g_object_get_data(G_OBJECT(participant), "purple-name"),
+ lcandidate, rcandidate);
+
+ g_object_unref(participant);
g_object_unref(lcandidate);
g_object_unref(rcandidate);
} else if (gst_structure_has_name(structure,
@@ -1959,6 +1959,9 @@
return FALSE;
}
+ g_object_set_data_full(G_OBJECT(participant), "purple-name",
+ g_strdup(name), g_free);
+
#ifndef HAVE_FARSIGHT
if (g_object_class_find_property(G_OBJECT_GET_CLASS(participant),
"cname")) {
--- a/libpurple/protocols/irc/irc.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/protocols/irc/irc.c Wed Nov 29 20:40:36 2017 +0100
@@ -685,31 +685,38 @@
return;
}
- if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) {
- irc->inbuflen += IRC_INITIAL_BUFSIZE;
- irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen);
- }
+ do {
+ // resize buffer upwards so we have at least IRC_BUFSIZE_INCREMENT
+ // bytes free in inbuf
+ if (irc->inbuflen < irc->inbufused + IRC_BUFSIZE_INCREMENT) {
+ if (irc->inbuflen + IRC_BUFSIZE_INCREMENT <= IRC_MAX_BUFSIZE) {
+ irc->inbuflen += IRC_BUFSIZE_INCREMENT;
+ irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen);
+ } else {
+ // discard unparseable data from the buffer
+ irc->inbufused = 0;
+ }
+ }
- len = purple_ssl_read(gsc, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1);
+ len = purple_ssl_read(gsc, irc->inbuf + irc->inbufused, irc->inbuflen - irc->inbufused - 1);
+ if (len > 0) {
+ read_input(irc, len);
+ }
+ } while (len > 0);
- if (len < 0 && errno == EAGAIN) {
- /* Try again later */
- return;
- } else if (len < 0) {
+ if (len < 0 && errno != EAGAIN) {
gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
g_strerror(errno));
purple_connection_error_reason (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
g_free(tmp);
- return;
} else if (len == 0) {
purple_connection_error_reason (gc,
PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
_("Server closed the connection"));
- return;
}
- read_input(irc, len);
+ /* else: len < 0 && errno == EAGAIN; this is fine, try again later */
}
static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond)
@@ -718,12 +725,18 @@
struct irc_conn *irc = gc->proto_data;
int len;
- if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) {
- irc->inbuflen += IRC_INITIAL_BUFSIZE;
- irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen);
+ /* see irc_input_cb_ssl */
+ if (irc->inbuflen < irc->inbufused + IRC_BUFSIZE_INCREMENT) {
+ if (irc->inbuflen + IRC_BUFSIZE_INCREMENT <= IRC_MAX_BUFSIZE) {
+ irc->inbuflen += IRC_BUFSIZE_INCREMENT;
+ irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen);
+ } else {
+ irc->inbufused = 0;
+ }
}
- len = read(irc->fd, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1);
+ len = read(irc->fd, irc->inbuf + irc->inbufused, irc->inbuflen - irc->inbufused - 1);
+
if (len < 0 && errno == EAGAIN) {
return;
} else if (len < 0) {
--- a/libpurple/protocols/irc/irc.h Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/protocols/irc/irc.h Wed Nov 29 20:40:36 2017 +0100
@@ -44,7 +44,8 @@
#define IRC_DEFAULT_QUIT "Leaving."
-#define IRC_INITIAL_BUFSIZE 1024
+#define IRC_BUFSIZE_INCREMENT 1024
+#define IRC_MAX_BUFSIZE 16384
#define IRC_MAX_MSG_SIZE 512
--- a/libpurple/protocols/jabber/bosh.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/protocols/jabber/bosh.c Wed Nov 29 20:40:36 2017 +0100
@@ -68,7 +68,6 @@
char *path;
guint16 port;
- gboolean pipelining;
gboolean ssl;
enum {
@@ -212,7 +211,6 @@
conn->port = port;
conn->path = g_strdup_printf("/%s", path);
g_free(path);
- conn->pipelining = TRUE;
if (purple_ip_address_is_valid(host))
js->serverFQDN = g_strdup(js->user->domain);
@@ -285,12 +283,6 @@
if (purple_debug_is_verbose())
debug_dump_http_connections(conn);
- /* Easy solution: Does everyone involved support pipelining? Hooray! Just use
- * one TCP connection! */
- if (conn->pipelining)
- return conn->connections[0]->state == HTTP_CONN_CONNECTED ?
- conn->connections[0] : NULL;
-
/* First loop, look for a connection that's ready */
for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
if (conn->connections[i] &&
@@ -465,27 +457,6 @@
send_timer_cb(bosh);
}
-static void
-jabber_bosh_disable_pipelining(PurpleBOSHConnection *bosh)
-{
- /* Do nothing if it's already disabled */
- if (!bosh->pipelining)
- return;
-
- purple_debug_info("jabber", "BOSH: Disabling pipelining on conn %p\n",
- bosh);
- bosh->pipelining = FALSE;
- if (bosh->connections[1] == NULL) {
- bosh->connections[1] = jabber_bosh_http_connection_init(bosh);
- http_connection_connect(bosh->connections[1]);
- } else {
- /* Shouldn't happen; this should be the only place pipelining
- * is turned off.
- */
- g_warn_if_reached();
- }
-}
-
static void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) {
xmlnode *child;
JabberStream *js = conn->js;
@@ -726,11 +697,6 @@
conn->requests = 0;
}
- if (conn->bosh->pipelining) {
- /* Hmmmm, fall back to multiple connections */
- jabber_bosh_disable_pipelining(conn->bosh);
- }
-
if (!had_requests)
/* If the server disconnected us without any requests, let's
* just wait until we have something to send before we reconnect
@@ -807,7 +773,6 @@
if (!g_ascii_strncasecmp(tmp, "close", strlen("close"))) {
conn->close = TRUE;
- jabber_bosh_disable_pipelining(conn->bosh);
}
}
--- a/libpurple/protocols/jabber/jingle/rtp.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/protocols/jabber/jingle/rtp.c Wed Nov 29 20:40:36 2017 +0100
@@ -950,6 +950,7 @@
JingleTransport *transport;
JabberBuddy *jb;
JabberBuddyResource *jbr;
+ gboolean ret = FALSE;
const gchar *transport_type;
gchar *resource = NULL, *me = NULL, *sid = NULL;
@@ -958,16 +959,15 @@
jb = jabber_buddy_find(js, who, FALSE);
if (!jb) {
purple_debug_error("jingle-rtp", "Could not find Jabber buddy\n");
- return FALSE;
+ goto out;
}
resource = jabber_get_resource(who);
jbr = jabber_buddy_find_resource(jb, resource);
- g_free(resource);
if (!jbr) {
purple_debug_error("jingle-rtp", "Could not find buddy's resource - %s\n", resource);
- return FALSE;
+ goto out;
}
if (jabber_resource_has_capability(jbr, JINGLE_TRANSPORT_ICEUDP)) {
@@ -977,7 +977,7 @@
} else {
purple_debug_error("jingle-rtp", "Resource doesn't support "
"the same transport types\n");
- return FALSE;
+ goto out;
}
/* set ourselves as initiator */
@@ -985,7 +985,6 @@
sid = jabber_get_next_id(js);
session = jingle_session_create(js, sid, me, who, TRUE);
- g_free(sid);
if (type & PURPLE_MEDIA_AUDIO) {
@@ -1005,13 +1004,17 @@
jingle_rtp_init_media(content);
}
- g_free(me);
-
if (jingle_rtp_get_media(session) == NULL) {
- return FALSE;
+ goto out;
}
- return TRUE;
+ ret = TRUE;
+
+out:
+ g_free(me);
+ g_free(resource);
+ g_free(sid);
+ return ret;
}
void
--- a/libpurple/tests/test_util.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/tests/test_util.c Wed Nov 29 20:40:36 2017 +0100
@@ -232,6 +232,24 @@
}
END_TEST
+START_TEST(test_uri_escape_for_open)
+{
+ /* make sure shell stuff is escaped... */
+ gchar *result = purple_uri_escape_for_open("https://$(xterm)");
+ assert_string_equal_free("https://%24%28xterm%29", result);
+
+ result = purple_uri_escape_for_open("https://`xterm`");
+ assert_string_equal_free("https://%60xterm%60", result);
+
+ result = purple_uri_escape_for_open("https://$((25 + 13))");
+ assert_string_equal_free("https://%24%28%2825%20+%2013%29%29", result);
+
+ /* ...but keep brackets so that ipv6 links can be opened. */
+ result = purple_uri_escape_for_open("https://[123:4567:89a::::]");
+ assert_string_equal_free("https://[123:4567:89a::::]", result);
+}
+END_TEST
+
Suite *
util_suite(void)
{
@@ -284,5 +302,9 @@
tcase_add_test(tc, test_strdup_withhtml);
suite_add_tcase(s, tc);
+ tc = tcase_create("escape_uri_for_open");
+ tcase_add_test(tc, test_uri_escape_for_open);
+ suite_add_tcase(s, tc);
+
return s;
}
--- a/libpurple/util.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/util.c Wed Nov 29 20:40:36 2017 +0100
@@ -4583,6 +4583,17 @@
return result;
}
+char *
+purple_uri_escape_for_open(const char *unescaped)
+{
+ /* Replace some special characters like $ with their percent-encoded value.
+ * This shouldn't be necessary because we shell-escape the entire arg before
+ * exec'ing the browser, however, we had a report that a URL containing
+ * $(xterm) was causing xterm to start on his system. This is obviously a
+ * bug on his system, but it's pretty easy for us to protect against it. */
+ return g_uri_escape_string(unescaped, "[]:;/%#,+?=&@", FALSE);
+}
+
/**************************************************************************
* UTF8 String Functions
**************************************************************************/
--- a/libpurple/util.h Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/util.h Wed Nov 29 20:40:36 2017 +0100
@@ -1330,6 +1330,17 @@
*/
GList *purple_uri_list_extract_filenames(const gchar *uri_list);
+/**
+ * This function escapes any characters that might be interpreted by the shell
+ * when executing a program to open a URI on some systems.
+ *
+ * @param unescaped The unescaped URI.
+ *
+ * @return A newly allocated string with any shell metacharacters replaced with
+ * their escaped equivalents.
+ */
+char *purple_uri_escape_for_open(const char *unescaped);
+
/*@}*/
/**************************************************************************
--- a/libpurple/win32/libc_interface.c Wed Sep 20 01:38:28 2017 +0200
+++ b/libpurple/win32/libc_interface.c Wed Nov 29 20:40:36 2017 +0100
@@ -31,6 +31,7 @@
#include "config.h"
#include "debug.h"
#include "libc_internal.h"
+#include "util.h"
#include <glib/gstdio.h>
/** This is redefined here because we can't include internal.h */
--- a/pidgin/Makefile.am Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/Makefile.am Wed Nov 29 20:40:36 2017 +0100
@@ -81,6 +81,7 @@
gtksourceview-marshal.c \
gtkstatus-icon-theme.c \
gtkstatusbox.c \
+ gtkstyle.c \
gtkthemes.c \
gtkutils.c \
gtkwhiteboard.c \
@@ -131,6 +132,7 @@
gtksourceview-marshal.h \
gtkstatus-icon-theme.h \
gtkstatusbox.h \
+ gtkstyle.h \
pidginstock.h \
gtkthemes.h \
gtkutils.h \
--- a/pidgin/Makefile.mingw Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/Makefile.mingw Wed Nov 29 20:40:36 2017 +0100
@@ -89,6 +89,7 @@
gtksourceundomanager.c \
gtkstatus-icon-theme.c \
gtkstatusbox.c \
+ gtkstyle.c \
gtkthemes.c \
gtkutils.c \
gtkwhiteboard.c \
--- a/pidgin/gtkblist.c Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/gtkblist.c Wed Nov 29 20:40:36 2017 +0100
@@ -60,6 +60,7 @@
#include "gtkstatusbox.h"
#include "gtkscrollbook.h"
#include "gtksmiley.h"
+#include "gtkstyle.h"
#include "gtkblist-theme.h"
#include "gtkblist-theme-loader.h"
#include "gtkutils.h"
@@ -4178,7 +4179,7 @@
gchar *
pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased)
{
- const char *name, *name_color, *name_font, *status_color, *status_font;
+ const char *name, *name_color, *name_font, *status_color, *status_font, *dim_grey;
char *text = NULL;
PurplePlugin *prpl;
PurplePluginProtocolInfo *prpl_info = NULL;
@@ -4281,13 +4282,15 @@
theme = pidgin_blist_get_theme();
name_color = NULL;
+ dim_grey = pidgin_style_is_dark(NULL) ? "light slate grey" : "dim grey";
+
if (theme) {
if (purple_presence_is_idle(presence)) {
namefont = statusfont = pidgin_blist_theme_get_idle_text_info(theme);
- name_color = "dim grey";
+ name_color = dim_grey;
} else if (!purple_presence_is_online(presence)) {
namefont = pidgin_blist_theme_get_offline_text_info(theme);
- name_color = "dim grey";
+ name_color = dim_grey;
statusfont = pidgin_blist_theme_get_status_text_info(theme);
} else if (purple_presence_is_available(presence)) {
namefont = pidgin_blist_theme_get_online_text_info(theme);
@@ -4301,14 +4304,14 @@
&& (purple_presence_is_idle(presence)
|| !purple_presence_is_online(presence)))
{
- name_color = "dim grey";
+ name_color = dim_grey;
}
}
name_color = theme_font_get_color_default(namefont, name_color);
name_font = theme_font_get_face_default(namefont, "");
- status_color = theme_font_get_color_default(statusfont, "dim grey");
+ status_color = theme_font_get_color_default(statusfont, dim_grey);
status_font = theme_font_get_face_default(statusfont, "");
if (aliased && selected) {
@@ -4726,6 +4729,15 @@
}
}
break;
+ default:
+ break;
+ }
+}
+
+static void
+chat_joined_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
+{
+ switch (conv->type) {
case PURPLE_CONV_TYPE_CHAT:
{
PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name);
@@ -6092,6 +6104,9 @@
purple_signal_connect(handle, "conversation-created", gtkblist,
PURPLE_CALLBACK(conversation_created_cb),
gtkblist);
+ purple_signal_connect(handle, "chat-joined", gtkblist,
+ PURPLE_CALLBACK(chat_joined_cb),
+ gtkblist);
gtk_widget_hide(gtkblist->headline_hbox);
@@ -6535,7 +6550,7 @@
textcolor = pidgin_theme_font_get_color_describe(pair);
else
/* If no theme them default to making idle buddy names grey */
- textcolor = "dim grey";
+ textcolor = pidgin_style_is_dark(NULL) ? "light slate grey" : "dim grey";
if (textcolor) {
idle = g_strdup_printf("<span color='%s' font_desc='%s'>%d:%02d</span>",
--- a/pidgin/gtkconv.c Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/gtkconv.c Wed Nov 29 20:40:36 2017 +0100
@@ -63,6 +63,7 @@
#include "gtkpounce.h"
#include "gtkprefs.h"
#include "gtkprivacy.h"
+#include "gtkstyle.h"
#include "gtkthemes.h"
#include "gtkutils.h"
#include "pidginstock.h"
@@ -8176,41 +8177,57 @@
purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle,
PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL);
- {
- /* Set default tab colors */
- GString *str = g_string_new(NULL);
- GtkSettings *settings = gtk_settings_get_default();
- GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now;
- struct {
- const char *stylename;
- const char *labelname;
- const char *color;
- } styles[] = {
- {"pidgin_tab_label_typing_default", "tab-label-typing", "#4e9a06"},
- {"pidgin_tab_label_typed_default", "tab-label-typed", "#c4a000"},
- {"pidgin_tab_label_attention_default", "tab-label-attention", "#006aff"},
- {"pidgin_tab_label_unreadchat_default", "tab-label-unreadchat", "#cc0000"},
- {"pidgin_tab_label_event_default", "tab-label-event", "#888a85"},
- {NULL, NULL, NULL}
- };
- int iter;
- for (iter = 0; styles[iter].stylename; iter++) {
- now = gtk_rc_get_style_by_paths(settings, styles[iter].labelname, NULL, G_TYPE_NONE);
- if (parent == now ||
- (parent && now && parent->rc_style == now->rc_style)) {
- g_string_append_printf(str, "style \"%s\" {\n"
- "fg[ACTIVE] = \"%s\"\n"
- "}\n"
- "widget \"*%s\" style \"%s\"\n",
- styles[iter].stylename,
- styles[iter].color,
- styles[iter].labelname, styles[iter].stylename);
- }
- }
- gtk_rc_parse_string(str->str);
- g_string_free(str, TRUE);
- gtk_rc_reset_styles(settings);
- }
+}
+
+/* Invalidate the first tab color set */
+static gboolean tab_color_fuse = TRUE;
+
+static void
+pidgin_conversations_set_tab_colors(void)
+{
+ /* Set default tab colors */
+ GString *str = g_string_new(NULL);
+ GtkSettings *settings = gtk_settings_get_default();
+ GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now;
+ struct {
+ const char *stylename;
+ const char *labelname;
+ const char *color;
+ } styles[] = {
+ {"pidgin_tab_label_typing_default", "tab-label-typing", "#4e9a06"},
+ {"pidgin_tab_label_typed_default", "tab-label-typed", "#c4a000"},
+ {"pidgin_tab_label_attention_default", "tab-label-attention", "#006aff"},
+ {"pidgin_tab_label_unreadchat_default", "tab-label-unreadchat", "#cc0000"},
+ {"pidgin_tab_label_event_default", "tab-label-event", "#888a85"},
+ {NULL, NULL, NULL}
+ };
+ int iter;
+
+ if(tab_color_fuse) {
+ tab_color_fuse = FALSE;
+ return;
+ }
+
+ for (iter = 0; styles[iter].stylename; iter++) {
+ now = gtk_rc_get_style_by_paths(settings, styles[iter].labelname, NULL, G_TYPE_NONE);
+ if (parent == now ||
+ (parent && now && parent->rc_style == now->rc_style)) {
+ GdkColor color;
+ gdk_color_parse(styles[iter].color, &color);
+ pidgin_style_adjust_contrast(gtk_widget_get_default_style(), &color);
+
+ g_string_append_printf(str, "style \"%s\" {\n"
+ "fg[ACTIVE] = \"%s\"\n"
+ "}\n"
+ "widget \"*%s\" style \"%s\"\n",
+ styles[iter].stylename,
+ gdk_color_to_string(&color),
+ styles[iter].labelname, styles[iter].stylename);
+ }
+ }
+ gtk_rc_parse_string(str->str);
+ g_string_free(str, TRUE);
+ gtk_rc_reset_styles(settings);
}
void
@@ -9385,6 +9402,9 @@
gtk_window_iconify(GTK_WINDOW(win->window));
#endif
+ /* Fix colours */
+ pidgin_conversations_set_tab_colors();
+
return win;
}
@@ -10252,6 +10272,9 @@
gdk_color_parse(DEFAULT_HIGHLIGHT_COLOR, &nick_highlight);
gdk_color_parse(DEFAULT_SEND_COLOR, &send_color);
+ pidgin_style_adjust_contrast(NULL, &nick_highlight);
+ pidgin_style_adjust_contrast(NULL, &send_color);
+
srand(background.red + background.green + background.blue + 1);
breakout_time = time(NULL) + 3;
--- a/pidgin/gtkimhtml.c Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/gtkimhtml.c Wed Nov 29 20:40:36 2017 +0100
@@ -44,6 +44,7 @@
#include "gtksourceiter.h"
#include "gtksourceundomanager.h"
#include "gtksourceview-marshal.h"
+#include "gtkstyle.h"
#include <gtk/gtk.h>
#include <glib.h>
#include <gdk/gdkkeysyms.h>
@@ -469,6 +470,7 @@
} else {
GdkColor defcolor;
gdk_color_parse(styles[i].def, &defcolor);
+ pidgin_style_adjust_contrast(gtk_widget_get_style(widget), &defcolor);
g_object_set(tag, "foreground-gdk", &defcolor, NULL);
}
}
--- a/pidgin/gtknotify.c Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/gtknotify.c Wed Nov 29 20:40:36 2017 +0100
@@ -1044,7 +1044,7 @@
switch (b->type) {
case PURPLE_NOTIFY_BUTTON_LABELED:
if(b->label) {
- button = gtk_button_new_with_label(b->label);
+ button = gtk_dialog_add_button(GTK_DIALOG(window), b->label, GTK_RESPONSE_NONE);
} else {
purple_debug_warning("gtknotify", "Missing button label\n");
}
@@ -1284,13 +1284,7 @@
GSList *argv = NULL, *argv_remote = NULL;
gchar **usercmd_argv = NULL;
- /* Replace some special characters like $ with their percent-encoded
- value. This shouldn't be necessary because we shell-escape the entire
- arg before exec'ing the browser, however, we had a report that a URL
- containing $(xterm) was causing xterm to start on his system. This is
- obviously a bug on his system, but it's pretty easy for us to protect
- against it. */
- uri_escaped = g_uri_escape_string(uri, ":;/%#,+?=&@", FALSE);
+ uri_escaped = purple_uri_escape_for_open(uri);
web_browser = purple_prefs_get_string(PIDGIN_PREFS_ROOT
"/browsers/browser");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/gtkstyle.c Wed Nov 29 20:40:36 2017 +0100
@@ -0,0 +1,70 @@
+/*
+ * @file gtkstyle.c GTK+ Style utility functions
+ * @ingroup pidgin
+ */
+
+/* pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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 "gtkstyle.h"
+
+/* Assume light mode */
+static gboolean dark_mode_cache = FALSE;
+
+gboolean
+pidgin_style_is_dark(GtkStyle *style) {
+ GdkColor bg;
+
+ if (!style) {
+ return dark_mode_cache;
+ }
+
+ bg = style->base[GTK_STATE_NORMAL];
+
+ if (bg.red != 0xFFFF || bg.green != 0xFFFF || bg.blue != 0xFFFF) {
+ dark_mode_cache = ((int) bg.red + (int) bg.green + (int) bg.blue) < (65536 * 3 / 2);
+ }
+
+ return dark_mode_cache;
+}
+
+void
+pidgin_style_adjust_contrast(GtkStyle *style, GdkColor *color) {
+ if (pidgin_style_is_dark(style)) {
+ gdouble r, g, b, h, s, v;
+
+ r = ((gdouble) color->red) / 65535.0;
+ g = ((gdouble) color->green) / 65535.0;
+ b = ((gdouble) color->blue) / 65535.0;
+
+ gtk_rgb_to_hsv(r, g, b, &h, &s, &v);
+
+ v += 0.3;
+ v = v > 1.0 ? 1.0 : v;
+ s = 0.7;
+
+ gtk_hsv_to_rgb(h, s, v, &r, &g, &b);
+
+ color->red = (guint16) (r * 65535.0);
+ color->green = (guint16) (g * 65535.0);
+ color->blue = (guint16) (b * 65535.0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/gtkstyle.h Wed Nov 29 20:40:36 2017 +0100
@@ -0,0 +1,59 @@
+/**
+ * @file gtkstyle.h GTK+ Style utility functions
+ * @ingroup pidgin
+ */
+
+/* pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+#ifndef _PIDGINSTYLE_H_
+#define _PIDGINSTYLE_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*@{*/
+
+/**
+ * Returns TRUE if dark mode is enabled and foreground colours should be invertred
+ *
+ * @param style The GtkStyle in use, or NULL to use a cached version.
+ *
+ * @return @c TRUE if dark mode, @c FALSE otherwise
+ */
+
+gboolean pidgin_style_is_dark(GtkStyle *style);
+
+/**
+ * Lighten a color if dark mode is enabled.
+ *
+ * @param style The GtkStyle in use.
+ *
+ * @param color Color to be lightened. Transformed color will be written here.
+ */
+
+void pidgin_style_adjust_contrast(GtkStyle *style, GdkColor *color);
+
+/*@}*/
+
+G_END_DECLS
+
+#endif /* _PIDGINSTYLE_H_ */
--- a/pidgin/plugins/Makefile.am Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/plugins/Makefile.am Wed Nov 29 20:40:36 2017 +0100
@@ -47,6 +47,7 @@
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
@@ -68,6 +69,7 @@
themeedit.la \
timestamp.la \
timestamp_format.la \
+ transparency.la \
xmppconsole.la
if USE_VV
@@ -98,6 +100,7 @@
themeedit_la_SOURCES = themeedit.c themeedit-icon.c themeedit-icon.h
timestamp_la_SOURCES = timestamp.c
timestamp_format_la_SOURCES = timestamp_format.c
+transparency_la_SOURCES = transparency.c
unity_la_SOURCES = unity.c
vvconfig_la_SOURCES = vvconfig.c
xmppconsole_la_SOURCES = xmppconsole.c
@@ -118,6 +121,7 @@
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)
--- a/pidgin/plugins/Makefile.mingw Wed Sep 20 01:38:28 2017 +0200
+++ b/pidgin/plugins/Makefile.mingw Wed Nov 29 20:40:36 2017 +0100
@@ -10,7 +10,6 @@
DISCO_PLUGIN := ./disco
GTKPERL_PLUGIN := ./perl
TICKER_PLUGIN := ./ticker
-TRANSPARENCY_PLUGIN := ./win32/transparency
WINPREFS_PLUGIN := ./win32/winprefs
.SUFFIXES:
@@ -63,14 +62,12 @@
$(MAKE) -C $(DISCO_PLUGIN) -f $(MINGW_MAKEFILE)
$(MAKE) -C $(GTKPERL_PLUGIN) -f $(MINGW_MAKEFILE)
$(MAKE) -C $(TICKER_PLUGIN) -f $(MINGW_MAKEFILE)
- $(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(MINGW_MAKEFILE)
$(MAKE) -C $(WINPREFS_PLUGIN) -f $(MINGW_MAKEFILE)
install: all $(PIDGIN_INSTALL_PLUGINS_DIR)
$(MAKE) -C $(DISCO_PLUGIN) -f $(MINGW_MAKEFILE) install
$(MAKE) -C $(GTKPERL_PLUGIN) -f $(MINGW_MAKEFILE) install
$(MAKE) -C $(TICKER_PLUGIN) -f $(MINGW_MAKEFILE) install
- $(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(MINGW_MAKEFILE) install
$(MAKE) -C $(WINPREFS_PLUGIN) -f $(MINGW_MAKEFILE) install
cp *.dll $(PIDGIN_INSTALL_PLUGINS_DIR)
@@ -102,6 +99,7 @@
themeedit.dll \
timestamp_format.dll \
timestamp.dll \
+ transparency.dll \
xmppconsole.dll
##
@@ -112,7 +110,6 @@
$(MAKE) -C $(DISCO_PLUGIN) -f $(MINGW_MAKEFILE) clean
$(MAKE) -C $(GTKPERL_PLUGIN) -f $(MINGW_MAKEFILE) clean
$(MAKE) -C $(TICKER_PLUGIN) -f $(MINGW_MAKEFILE) clean
- $(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(MINGW_MAKEFILE) clean
$(MAKE) -C $(WINPREFS_PLUGIN) -f $(MINGW_MAKEFILE) clean
include $(PIDGIN_COMMON_TARGETS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/plugins/transparency.c Wed Nov 29 20:40:36 2017 +0100
@@ -0,0 +1,683 @@
+/*
+ * Pidgin - Transparency plugin
+ *
+ * Copyright (C) 1998-2002, Rob Flynn <rob@marko.net>
+ * Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com>
+ * Copyright (C) 2005, Daniel Atallah <daniel_atallah@yahoo.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 "core.h"
+#include "prefs.h"
+#include "debug.h"
+
+#include "gtkconv.h"
+#include "gtkplugin.h"
+#include "gtkprefs.h"
+#include "gtkblist.h"
+#include "gtkutils.h"
+#include "signals.h"
+#include "version.h"
+
+/*
+ * MACROS & DEFINES
+ */
+/* The plugin name is left unchanged from its WinAPI days in order to keep it
+ * loading for users who were using it. */
+#define WINTRANS_PLUGIN_ID "gtk-win-trans"
+
+#define blist (purple_get_blist() \
+ ? (PIDGIN_BLIST(purple_get_blist()) \
+ ? ((PIDGIN_BLIST(purple_get_blist()))->window) \
+ : NULL) \
+ : NULL)
+
+/*
+ * DATA STRUCTS
+ */
+typedef struct {
+ GtkWidget *win;
+ GtkWidget *slider;
+} slider_win;
+
+/*
+ * LOCALS
+ */
+static const char *OPT_WINTRANS_IM_ENABLED= "/plugins/gtk/transparency/im_enabled";
+static const char *OPT_WINTRANS_IM_ALPHA = "/plugins/gtk/transparency/im_alpha";
+static const char *OPT_WINTRANS_IM_SLIDER = "/plugins/gtk/transparency/im_slider";
+static const char *OPT_WINTRANS_IM_ONFOCUS= "/plugins/gtk/transparency/im_solid_onfocus";
+static const char *OPT_WINTRANS_IM_ONTOP = "/plugins/gtk/transparency/im_always_on_top";
+static const char *OPT_WINTRANS_BL_ENABLED= "/plugins/gtk/transparency/bl_enabled";
+static const char *OPT_WINTRANS_BL_ALPHA = "/plugins/gtk/transparency/bl_alpha";
+static const char *OPT_WINTRANS_BL_ONFOCUS= "/plugins/gtk/transparency/bl_solid_onfocus";
+static const char *OPT_WINTRANS_BL_ONTOP = "/plugins/gtk/transparency/bl_always_on_top";
+static GSList *window_list = NULL;
+
+/*
+ * CODE
+ */
+
+/* Set window transparency level */
+static void set_wintrans(GtkWidget *window, int alpha, gboolean enabled,
+ gboolean always_on_top) {
+ if (enabled) {
+ gdk_window_set_opacity(window->window, alpha / 255.0);
+ gdk_window_set_keep_above(window->window, always_on_top);
+ } else {
+ gdk_window_set_opacity(window->window, 1);
+ gdk_window_set_keep_above(window->window, 0);
+ }
+}
+
+/* When a conv window is focused, if we're only transparent when unfocused,
+ * deal with transparency */
+static gboolean focus_conv_win_cb(GtkWidget *w, GdkEventFocus *e, gpointer d) {
+ if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED)
+ && purple_prefs_get_bool(OPT_WINTRANS_IM_ONFOCUS)) {
+ GtkWidget *window = (GtkWidget *) d;
+ if (e->in) { /* Focused */
+ set_wintrans(window, 0, FALSE,
+ purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
+ } else {
+ set_wintrans(window,
+ purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA),
+ TRUE,
+ purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
+ }
+ }
+ return FALSE;
+}
+
+/* When buddy list window is focused,
+ * if we're only transparent when unfocused, deal with transparency */
+static gboolean focus_blist_win_cb(GtkWidget *w, GdkEventFocus *e, gpointer d) {
+ if (purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED)
+ && purple_prefs_get_bool(OPT_WINTRANS_BL_ONFOCUS)) {
+ GtkWidget *window = (GtkWidget *) d;
+ if (e->in) { /* Focused */
+ set_wintrans(window, 0, FALSE,
+ purple_prefs_get_bool(OPT_WINTRANS_BL_ONTOP));
+ } else {
+ set_wintrans(window,
+ purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA),
+ TRUE,
+ purple_prefs_get_bool(OPT_WINTRANS_BL_ONTOP));
+ }
+ }
+ return FALSE;
+}
+
+static void change_alpha(GtkWidget *w, gpointer data) {
+ int alpha = gtk_range_get_value(GTK_RANGE(w));
+ purple_prefs_set_int(OPT_WINTRANS_IM_ALPHA, alpha);
+
+ /* If we're in no-transparency on focus mode,
+ * don't take effect immediately */
+ if (!purple_prefs_get_bool(OPT_WINTRANS_IM_ONFOCUS))
+ set_wintrans(GTK_WIDGET(data), alpha, TRUE,
+ purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
+}
+
+
+static GtkWidget *wintrans_slider(GtkWidget *win) {
+ GtkWidget *hbox;
+ GtkWidget *label, *slider;
+ GtkWidget *frame;
+
+ int imalpha = purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA);
+
+ frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
+ gtk_widget_show(frame);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+ label = gtk_label_new(_("Opacity:"));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
+ gtk_widget_show(hbox);
+
+ slider = gtk_hscale_new_with_range(50, 255, 1);
+ gtk_range_set_value(GTK_RANGE(slider), imalpha);
+ gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1);
+
+ /* On slider val change, update window's transparency level */
+ g_signal_connect(GTK_OBJECT(slider), "value-changed",
+ G_CALLBACK(change_alpha), win);
+
+ gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5);
+
+ /* Set the initial transparency level */
+ set_wintrans(win, imalpha, TRUE,
+ purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
+
+ gtk_widget_show_all(hbox);
+
+ return frame;
+}
+
+static slider_win* find_slidwin(GtkWidget *win) {
+ GSList *tmp = window_list;
+
+ while (tmp) {
+ if (((slider_win*) (tmp->data))->win == win)
+ return (slider_win*) tmp->data;
+ tmp = tmp->next;
+ }
+ return NULL;
+}
+
+/* Clean up transparency stuff for the conv window */
+static void cleanup_conv_window(PidginWindow *win) {
+ GtkWidget *window = win->window;
+ slider_win *slidwin = NULL;
+
+ /* Remove window from the window list */
+ purple_debug_info(WINTRANS_PLUGIN_ID,
+ "Conv window destroyed... removing from list\n");
+
+ if ((slidwin = find_slidwin(window))) {
+ window_list = g_slist_remove(window_list, slidwin);
+ g_free(slidwin);
+ }
+
+ /* Remove the focus cbs */
+ g_signal_handlers_disconnect_by_func(G_OBJECT(window),
+ G_CALLBACK(focus_conv_win_cb), window);
+}
+
+static void
+conversation_delete_cb(PurpleConversation *conv) {
+ PidginWindow *win = pidgin_conv_get_window(PIDGIN_CONVERSATION(conv));
+ /* If it is the last conversation in the window, cleanup */
+ if (win != NULL && pidgin_conv_window_get_gtkconv_count(win) == 1)
+ cleanup_conv_window(win);
+}
+
+static void set_blist_trans(GtkWidget *w, const char *pref) {
+ gboolean enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
+ purple_prefs_set_bool(pref, enabled);
+ if (blist) {
+ set_wintrans(blist, purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA),
+ purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED),
+ purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
+ }
+}
+
+static void add_slider(GtkWidget *win) {
+ GList *wl, *wl1;
+ GtkWidget *vbox = NULL;
+
+ /* Look up this window to see if it already has a slider */
+ if (!find_slidwin(win)) {
+ GtkWidget *slider_box = NULL;
+ slider_win *slidwin = NULL;
+ GtkRequisition slidereq;
+ gint width, height;
+
+ /* Get top vbox */
+ for (wl1 = wl = gtk_container_get_children(
+ GTK_CONTAINER(win));
+ wl != NULL;
+ wl = wl->next) {
+ if (GTK_IS_VBOX(GTK_OBJECT(wl->data)))
+ vbox = GTK_WIDGET(wl->data);
+ else {
+ purple_debug_error(WINTRANS_PLUGIN_ID,
+ "no vbox found\n");
+ return;
+ }
+ }
+ g_list_free(wl1);
+
+ slider_box = wintrans_slider(win);
+ /* Figure out how tall the slider wants to be */
+ gtk_widget_size_request(slider_box, &slidereq);
+ gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+ gtk_box_pack_start(GTK_BOX(vbox),
+ slider_box, FALSE, FALSE, 0);
+ /* Add window to list, to track that it has a slider */
+ slidwin = g_new0(slider_win, 1);
+ slidwin->win = win;
+ slidwin->slider = slider_box;
+ window_list = g_slist_append(window_list, slidwin);
+ }
+}
+
+static void remove_sliders() {
+ if (window_list) {
+ GSList *tmp = window_list;
+ while (tmp) {
+ slider_win *slidwin = (slider_win*) tmp->data;
+ if (slidwin != NULL &&
+ GTK_IS_WINDOW(slidwin->win)) {
+ gtk_widget_destroy(slidwin->slider);
+ }
+ g_free(slidwin);
+ tmp = tmp->next;
+ }
+ g_slist_free(window_list);
+ window_list = NULL;
+ }
+}
+
+/* Remove all transparency related aspects from conversation windows */
+static void remove_convs_wintrans(gboolean remove_signal) {
+ GList *wins;
+
+ for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
+ PidginWindow *win = wins->data;
+ GtkWidget *window = win->window;
+
+ if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED))
+ set_wintrans(window, 0, FALSE, FALSE);
+
+ /* Remove the focus cbs */
+ if (remove_signal)
+ g_signal_handlers_disconnect_by_func(G_OBJECT(window),
+ G_CALLBACK(focus_conv_win_cb), window);
+ }
+
+ remove_sliders();
+}
+
+static void set_conv_window_trans(PidginWindow *oldwin, PidginWindow *newwin) {
+ GtkWidget *win = newwin->window;
+
+ /* check prefs to see if we want trans */
+ if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED)) {
+ set_wintrans(win, purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA),
+ TRUE, purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
+
+ if (purple_prefs_get_bool(OPT_WINTRANS_IM_SLIDER)) {
+ add_slider(win);
+ }
+ }
+
+ /* If we're moving from one window to another,
+ * add the focus listeners to the new window if not already there */
+ if (oldwin != NULL && oldwin != newwin) {
+ if (pidgin_conv_window_get_gtkconv_count(newwin) == 0) {
+ g_signal_connect(G_OBJECT(win), "focus_in_event",
+ G_CALLBACK(focus_conv_win_cb), win);
+ g_signal_connect(G_OBJECT(win), "focus_out_event",
+ G_CALLBACK(focus_conv_win_cb), win);
+ }
+
+ /* If we've moved the last conversation, cleanup the window */
+ if (pidgin_conv_window_get_gtkconv_count(oldwin) == 1)
+ cleanup_conv_window(oldwin);
+ }
+}
+
+static void update_convs_wintrans(GtkWidget *toggle_btn, const char *pref) {
+ purple_prefs_set_bool(pref, gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(toggle_btn)));
+
+ if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED)) {
+ GList *wins;
+
+ for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
+ PidginWindow *win = wins->data;
+ set_conv_window_trans(NULL, win);
+ }
+
+ if (!purple_prefs_get_bool(OPT_WINTRANS_IM_SLIDER))
+ remove_sliders();
+ }
+ else
+ remove_convs_wintrans(FALSE);
+}
+
+static void
+conv_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type) {
+ PidginConversation *pconv = PIDGIN_CONVERSATION(conv);
+ PidginWindow *win = pidgin_conv_get_window(pconv);
+
+ if (type == PURPLE_CONV_UPDATE_UNSEEN && !pidgin_conv_is_hidden(pconv)
+ && pconv->unseen_state == PIDGIN_UNSEEN_NONE
+ && pidgin_conv_window_get_gtkconv_count(win) == 1) {
+ GtkWidget *window = win->window;
+ gboolean has_focus;
+
+ g_object_get(G_OBJECT(window), "has-toplevel-focus", &has_focus, NULL);
+
+ if (!has_focus || !purple_prefs_get_bool(OPT_WINTRANS_IM_ONFOCUS))
+ set_conv_window_trans(NULL, win);
+
+ if (g_signal_handler_find(G_OBJECT(window), G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(focus_conv_win_cb), NULL) == 0) {
+ g_signal_connect(G_OBJECT(window), "focus_in_event",
+ G_CALLBACK(focus_conv_win_cb), window);
+ g_signal_connect(G_OBJECT(window), "focus_out_event",
+ G_CALLBACK(focus_conv_win_cb), window);
+ }
+ }
+}
+
+static void
+new_conversation_cb(PurpleConversation *conv) {
+ PidginWindow *win = pidgin_conv_get_window(PIDGIN_CONVERSATION(conv));
+
+ /* If it is the first conversation in the window,
+ * add the sliders, and set transparency */
+ if (!pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv)) && pidgin_conv_window_get_gtkconv_count(win) == 1) {
+ GtkWidget *window = win->window;
+
+ set_conv_window_trans(NULL, win);
+
+ g_signal_connect(G_OBJECT(window), "focus_in_event",
+ G_CALLBACK(focus_conv_win_cb), window);
+ g_signal_connect(G_OBJECT(window), "focus_out_event",
+ G_CALLBACK(focus_conv_win_cb), window);
+ }
+}
+
+static void
+blist_created_cb(PurpleBuddyList *purple_blist, gpointer data) {
+ if (blist) {
+ if (purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED)) {
+ set_wintrans(blist,
+ purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA),
+ TRUE,
+ purple_prefs_get_bool(OPT_WINTRANS_BL_ONTOP));
+ }
+
+ g_signal_connect(G_OBJECT(blist), "focus_in_event",
+ G_CALLBACK(focus_blist_win_cb), blist);
+ g_signal_connect(G_OBJECT(blist), "focus_out_event",
+ G_CALLBACK(focus_blist_win_cb), blist);
+ }
+}
+
+static void alpha_change(GtkWidget *w, gpointer data) {
+ GList *wins;
+ int imalpha = gtk_range_get_value(GTK_RANGE(w));
+
+ for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
+ PidginWindow *win = wins->data;
+ set_wintrans(win->window, imalpha, TRUE,
+ purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
+ }
+}
+
+static void alpha_pref_set_int (GtkWidget *w, GdkEventFocus *e, const char *pref)
+{
+ int alpha = gtk_range_get_value(GTK_RANGE(w));
+ purple_prefs_set_int(pref, alpha);
+}
+
+static void bl_alpha_change(GtkWidget *w, gpointer data) {
+ if (blist)
+ change_alpha(w, blist);
+}
+
+static void update_existing_convs() {
+ GList *wins;
+
+ for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
+ PidginWindow *win = wins->data;
+ GtkWidget *window = win->window;
+
+ set_conv_window_trans(NULL, win);
+
+ g_signal_connect(G_OBJECT(window), "focus_in_event",
+ G_CALLBACK(focus_conv_win_cb), window);
+ g_signal_connect(G_OBJECT(window), "focus_out_event",
+ G_CALLBACK(focus_conv_win_cb), window);
+ }
+}
+
+/*
+ * EXPORTED FUNCTIONS
+ */
+static gboolean plugin_load(PurplePlugin *plugin) {
+
+ purple_signal_connect(purple_conversations_get_handle(),
+ "conversation-created", plugin,
+ PURPLE_CALLBACK(new_conversation_cb), NULL);
+
+ /* Set callback to remove window from the list, if the window is destroyed */
+ purple_signal_connect(purple_conversations_get_handle(),
+ "deleting-conversation", plugin,
+ PURPLE_CALLBACK(conversation_delete_cb), NULL);
+
+ purple_signal_connect(pidgin_conversations_get_handle(),
+ "conversation-dragging", plugin,
+ PURPLE_CALLBACK(set_conv_window_trans), NULL);
+
+ purple_signal_connect(purple_conversations_get_handle(),
+ "conversation-updated", plugin,
+ PURPLE_CALLBACK(conv_updated_cb), NULL);
+
+ update_existing_convs();
+
+ if (blist)
+ blist_created_cb(NULL, NULL);
+ else
+ purple_signal_connect(pidgin_blist_get_handle(),
+ "gtkblist-created", plugin,
+ PURPLE_CALLBACK(blist_created_cb), NULL);
+
+
+ return TRUE;
+}
+
+static gboolean plugin_unload(PurplePlugin *plugin) {
+ purple_debug_info(WINTRANS_PLUGIN_ID, "Unloading transparency plugin\n");
+
+ remove_convs_wintrans(TRUE);
+
+ if (blist) {
+ if (purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED))
+ set_wintrans(blist, 0, FALSE, FALSE);
+
+ /* Remove the focus cbs */
+ g_signal_handlers_disconnect_by_func(G_OBJECT(blist),
+ G_CALLBACK(focus_blist_win_cb), blist);
+ }
+
+ return TRUE;
+}
+
+static GtkWidget *get_config_frame(PurplePlugin *plugin) {
+ GtkWidget *ret;
+ GtkWidget *imtransbox, *bltransbox;
+ GtkWidget *hbox;
+ GtkWidget *label, *slider;
+ GtkWidget *button;
+ GtkWidget *trans_box;
+
+ ret = gtk_vbox_new(FALSE, 18);
+ gtk_container_set_border_width(GTK_CONTAINER (ret), 12);
+
+ /* IM Convo trans options */
+ imtransbox = pidgin_make_frame(ret, _("IM Conversation Windows"));
+ button = pidgin_prefs_checkbox(_("_IM window transparency"),
+ OPT_WINTRANS_IM_ENABLED, imtransbox);
+ g_signal_connect(GTK_OBJECT(button), "clicked",
+ G_CALLBACK(update_convs_wintrans),
+ (gpointer) OPT_WINTRANS_IM_ENABLED);
+
+ trans_box = gtk_vbox_new(FALSE, 18);
+ if (!purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED))
+ gtk_widget_set_sensitive(GTK_WIDGET(trans_box), FALSE);
+ gtk_widget_show(trans_box);
+
+ g_signal_connect(GTK_OBJECT(button), "clicked",
+ G_CALLBACK(pidgin_toggle_sensitive), trans_box);
+
+ button = pidgin_prefs_checkbox(_("_Show slider bar in IM window"),
+ OPT_WINTRANS_IM_SLIDER, trans_box);
+ g_signal_connect(GTK_OBJECT(button), "clicked",
+ G_CALLBACK(update_convs_wintrans),
+ (gpointer) OPT_WINTRANS_IM_SLIDER);
+
+ button = pidgin_prefs_checkbox(
+ _("Remove IM window transparency on focus"),
+ OPT_WINTRANS_IM_ONFOCUS, trans_box);
+
+ button = pidgin_prefs_checkbox(_("Always on top"), OPT_WINTRANS_IM_ONTOP,
+ trans_box);
+ g_signal_connect(GTK_OBJECT(button), "clicked",
+ G_CALLBACK(update_convs_wintrans),
+ (gpointer) OPT_WINTRANS_IM_ONTOP);
+
+ gtk_box_pack_start(GTK_BOX(imtransbox), trans_box, FALSE, FALSE, 5);
+
+ /* IM transparency slider */
+ hbox = gtk_hbox_new(FALSE, 5);
+
+ label = gtk_label_new(_("Opacity:"));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
+
+ slider = gtk_hscale_new_with_range(50, 255, 1);
+ gtk_range_set_value(GTK_RANGE(slider),
+ purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA));
+ gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1);
+
+ g_signal_connect(GTK_OBJECT(slider), "value-changed",
+ G_CALLBACK(alpha_change), NULL);
+ g_signal_connect(GTK_OBJECT(slider), "focus-out-event",
+ G_CALLBACK(alpha_pref_set_int),
+ (gpointer) OPT_WINTRANS_IM_ALPHA);
+
+ gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5);
+
+ gtk_widget_show_all(hbox);
+
+ gtk_box_pack_start(GTK_BOX(trans_box), hbox, FALSE, FALSE, 5);
+
+ /* Buddy List trans options */
+ bltransbox = pidgin_make_frame (ret, _("Buddy List Window"));
+ button = pidgin_prefs_checkbox(_("_Buddy List window transparency"),
+ OPT_WINTRANS_BL_ENABLED, bltransbox);
+ g_signal_connect(GTK_OBJECT(button), "clicked",
+ G_CALLBACK(set_blist_trans),
+ (gpointer) OPT_WINTRANS_BL_ENABLED);
+
+ trans_box = gtk_vbox_new(FALSE, 18);
+ if (!purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED))
+ gtk_widget_set_sensitive(GTK_WIDGET(trans_box), FALSE);
+ gtk_widget_show(trans_box);
+ g_signal_connect(GTK_OBJECT(button), "clicked",
+ G_CALLBACK(pidgin_toggle_sensitive), trans_box);
+ button = pidgin_prefs_checkbox(
+ _("Remove Buddy List window transparency on focus"),
+ OPT_WINTRANS_BL_ONFOCUS, trans_box);
+ button = pidgin_prefs_checkbox(_("Always on top"), OPT_WINTRANS_BL_ONTOP,
+ trans_box);
+ g_signal_connect(GTK_OBJECT(button), "clicked",
+ G_CALLBACK(set_blist_trans),
+ (gpointer) OPT_WINTRANS_BL_ONTOP);
+ gtk_box_pack_start(GTK_BOX(bltransbox), trans_box, FALSE, FALSE, 5);
+
+ /* IM transparency slider */
+ hbox = gtk_hbox_new(FALSE, 5);
+
+ label = gtk_label_new(_("Opacity:"));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
+
+ slider = gtk_hscale_new_with_range(50, 255, 1);
+ gtk_range_set_value(GTK_RANGE(slider),
+ purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA));
+
+ gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1);
+
+ g_signal_connect(GTK_OBJECT(slider), "value-changed",
+ G_CALLBACK(bl_alpha_change), NULL);
+ g_signal_connect(GTK_OBJECT(slider), "focus-out-event",
+ G_CALLBACK(alpha_pref_set_int),
+ (gpointer) OPT_WINTRANS_BL_ALPHA);
+
+ gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5);
+
+ gtk_widget_show_all(hbox);
+
+ gtk_box_pack_start(GTK_BOX(trans_box), hbox, FALSE, FALSE, 5);
+
+ gtk_widget_show_all(ret);
+ return ret;
+}
+
+static PidginPluginUiInfo ui_info =
+{
+ get_config_frame,
+ 0, /* page_num (Reserved) */
+
+ /* padding */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static PurplePluginInfo info =
+{
+ PURPLE_PLUGIN_MAGIC,
+ PURPLE_MAJOR_VERSION,
+ PURPLE_MINOR_VERSION,
+ PURPLE_PLUGIN_STANDARD, /**< type */
+ PIDGIN_PLUGIN_TYPE, /**< ui_requirement */
+ 0, /**< flags */
+ NULL, /**< dependencies */
+ PURPLE_PRIORITY_DEFAULT, /**< priority */
+ WINTRANS_PLUGIN_ID, /**< id */
+ N_("Transparency"), /**< name */
+ DISPLAY_VERSION, /**< version */
+ /** summary */
+ N_("Variable Transparency for the buddy list and conversations."),
+ /** description */
+ N_("This plugin enables variable alpha transparency on conversation windows and the buddy list."),
+ "Herman Bloggs <hermanator12002@yahoo.com>", /**< author */
+ PURPLE_WEBSITE, /**< homepage */
+ plugin_load, /**< load */
+ plugin_unload, /**< unload */
+ NULL, /**< destroy */
+ &ui_info, /**< ui_info */
+ NULL, /**< extra_info */
+ NULL, /**< prefs_info */
+ NULL, /**< actions */
+
+ /* padding */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static void
+init_plugin(PurplePlugin *plugin)
+{
+ purple_prefs_add_none("/plugins/gtk");
+ purple_prefs_add_none("/plugins/gtk/transparency");
+ purple_prefs_add_bool(OPT_WINTRANS_IM_ENABLED, FALSE);
+ purple_prefs_add_int(OPT_WINTRANS_IM_ALPHA, 255);
+ purple_prefs_add_bool(OPT_WINTRANS_IM_SLIDER, FALSE);
+ purple_prefs_add_bool(OPT_WINTRANS_IM_ONFOCUS, FALSE);
+ purple_prefs_add_bool(OPT_WINTRANS_IM_ONTOP, FALSE);
+ purple_prefs_add_bool(OPT_WINTRANS_BL_ENABLED, FALSE);
+ purple_prefs_add_int(OPT_WINTRANS_BL_ALPHA, 255);
+ purple_prefs_add_bool(OPT_WINTRANS_BL_ONFOCUS, FALSE);
+ purple_prefs_add_bool(OPT_WINTRANS_BL_ONTOP, FALSE);
+ purple_prefs_rename("/plugins/gtk/win32/wintrans", "/plugins/gtk/transparency");
+}
+
+PURPLE_INIT_PLUGIN(wintrans, init_plugin, info)
--- a/pidgin/plugins/win32/transparency/Makefile.mingw Wed Sep 20 01:38:28 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-#
-# Makefile.mingw
-#
-# Description: Makefile for win32trans plugin.
-#
-
-PIDGIN_TREE_TOP := ../../../..
-include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-
-TARGET = win2ktrans
-
-##
-## INCLUDE PATHS
-##
-INCLUDE_PATHS += -I. \
- -I$(GTK_TOP)/include \
- -I$(GTK_TOP)/include/gtk-2.0 \
- -I$(GTK_TOP)/include/glib-2.0 \
- -I$(GTK_TOP)/include/pango-1.0 \
- -I$(GTK_TOP)/include/atk-1.0 \
- -I$(GTK_TOP)/include/cairo \
- -I$(GTK_TOP)/lib/glib-2.0/include \
- -I$(GTK_TOP)/lib/gtk-2.0/include \
- -I$(PURPLE_TOP) \
- -I$(PURPLE_TOP)/win32 \
- -I$(PIDGIN_TOP) \
- -I$(PIDGIN_TOP)/win32 \
- -I$(PIDGIN_TREE_TOP)
-
-LIB_PATHS += -L$(GTK_TOP)/lib \
- -L$(PURPLE_TOP) \
- -L$(PIDGIN_TOP)
-
-##
-## SOURCES, OBJECTS
-##
-C_SRC = win2ktrans.c
-
-OBJECTS = $(C_SRC:%.c=%.o)
-
-##
-## LIBRARIES
-##
-LIBS = -lgtk-win32-2.0 \
- -lglib-2.0 \
- -lgdk-win32-2.0 \
- -lgmodule-2.0 \
- -lgobject-2.0 \
- -lintl \
- -lpidgin \
- -lpurple
-
-include $(PIDGIN_COMMON_RULES)
-
-##
-## TARGET DEFINITIONS
-##
-.PHONY: all install clean
-
-all: $(TARGET).dll
-
-install: all $(PIDGIN_INSTALL_PLUGINS_DIR)
- cp $(TARGET).dll $(PIDGIN_INSTALL_PLUGINS_DIR)
-
-$(TARGET).dll: $(PURPLE_DLL).a $(PIDGIN_DLL).a $(OBJECTS)
- $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET).dll
-
-##
-## CLEAN RULES
-##
-clean:
- rm -rf $(OBJECTS)
- rm -rf $(TARGET).dll
-
-include $(PIDGIN_COMMON_TARGETS)
--- a/pidgin/plugins/win32/transparency/win2ktrans.c Wed Sep 20 01:38:28 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,719 +0,0 @@
-/*
- * Pidgin - Transparency plugin
- *
- * Copyright (C) 1998-2002, Rob Flynn <rob@marko.net>
- * Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com>
- * Copyright (C) 2005, Daniel Atallah <daniel_atallah@yahoo.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 <gdk/gdkwin32.h>
-#include "internal.h"
-
-#include "core.h"
-#include "prefs.h"
-#include "debug.h"
-
-#include "gtkconv.h"
-#include "gtkplugin.h"
-#include "gtkprefs.h"
-#include "gtkblist.h"
-#include "gtkutils.h"
-#include "signals.h"
-#include "version.h"
-
-/*
- * MACROS & DEFINES
- */
-#define WINTRANS_PLUGIN_ID "gtk-win-trans"
-
-#define blist (purple_get_blist() \
- ? (PIDGIN_BLIST(purple_get_blist()) \
- ? ((PIDGIN_BLIST(purple_get_blist()))->window) \
- : NULL) \
- : NULL)
-
-/*
- * DATA STRUCTS
- */
-typedef struct {
- GtkWidget *win;
- GtkWidget *slider;
-} slider_win;
-
-/*
- * LOCALS
- */
-static const char *OPT_WINTRANS_IM_ENABLED= "/plugins/gtk/win32/wintrans/im_enabled";
-static const char *OPT_WINTRANS_IM_ALPHA = "/plugins/gtk/win32/wintrans/im_alpha";
-static const char *OPT_WINTRANS_IM_SLIDER = "/plugins/gtk/win32/wintrans/im_slider";
-static const char *OPT_WINTRANS_IM_ONFOCUS= "/plugins/gtk/win32/wintrans/im_solid_onfocus";
-static const char *OPT_WINTRANS_IM_ONTOP = "/plugins/gtk/win32/wintrans/im_always_on_top";
-static const char *OPT_WINTRANS_BL_ENABLED= "/plugins/gtk/win32/wintrans/bl_enabled";
-static const char *OPT_WINTRANS_BL_ALPHA = "/plugins/gtk/win32/wintrans/bl_alpha";
-static const char *OPT_WINTRANS_BL_ONFOCUS= "/plugins/gtk/win32/wintrans/bl_solid_onfocus";
-static const char *OPT_WINTRANS_BL_ONTOP = "/plugins/gtk/win32/wintrans/bl_always_on_top";
-static GSList *window_list = NULL;
-
-/*
- * CODE
- */
-
-/* Set window transparency level */
-static void set_wintrans(GtkWidget *window, int alpha, gboolean enabled,
- gboolean always_on_top) {
-
- HWND hWnd = GDK_WINDOW_HWND(window->window);
- LONG style = GetWindowLong(hWnd, GWL_EXSTYLE);
- if (enabled) {
- style |= WS_EX_LAYERED;
- } else {
- style &= ~WS_EX_LAYERED;
- }
- SetWindowLong(hWnd, GWL_EXSTYLE, style);
-
-
- if (enabled) {
- SetWindowPos(hWnd,
- always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST,
- 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- SetLayeredWindowAttributes(hWnd, 0, alpha, LWA_ALPHA);
- } else {
- /* Ask the window and its children to repaint */
- SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-
- RedrawWindow(hWnd, NULL, NULL,
- RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
- }
-
-}
-
-/* When a conv window is focused, if we're only transparent when unfocused,
- * deal with transparency */
-static gboolean focus_conv_win_cb(GtkWidget *w, GdkEventFocus *e, gpointer d) {
- if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED)
- && purple_prefs_get_bool(OPT_WINTRANS_IM_ONFOCUS)) {
- GtkWidget *window = (GtkWidget *) d;
- if (e->in) { /* Focused */
- set_wintrans(window, 0, FALSE,
- purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
- } else {
- set_wintrans(window,
- purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA),
- TRUE,
- purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
- }
- }
- return FALSE;
-}
-
-/* When buddy list window is focused,
- * if we're only transparent when unfocused, deal with transparency */
-static gboolean focus_blist_win_cb(GtkWidget *w, GdkEventFocus *e, gpointer d) {
- if (purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED)
- && purple_prefs_get_bool(OPT_WINTRANS_BL_ONFOCUS)) {
- GtkWidget *window = (GtkWidget *) d;
- if (e->in) { /* Focused */
- set_wintrans(window, 0, FALSE,
- purple_prefs_get_bool(OPT_WINTRANS_BL_ONTOP));
- } else {
- set_wintrans(window,
- purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA),
- TRUE,
- purple_prefs_get_bool(OPT_WINTRANS_BL_ONTOP));
- }
- }
- return FALSE;
-}
-
-static void change_alpha(GtkWidget *w, gpointer data) {
- int alpha = gtk_range_get_value(GTK_RANGE(w));
- purple_prefs_set_int(OPT_WINTRANS_IM_ALPHA, alpha);
-
- /* If we're in no-transparency on focus mode,
- * don't take effect immediately */
- if (!purple_prefs_get_bool(OPT_WINTRANS_IM_ONFOCUS))
- set_wintrans(GTK_WIDGET(data), alpha, TRUE,
- purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
-}
-
-
-static GtkWidget *wintrans_slider(GtkWidget *win) {
- GtkWidget *hbox;
- GtkWidget *label, *slider;
- GtkWidget *frame;
-
- int imalpha = purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA);
-
- frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
- gtk_widget_show(frame);
-
- hbox = gtk_hbox_new(FALSE, 5);
- gtk_container_add(GTK_CONTAINER(frame), hbox);
-
- label = gtk_label_new(_("Opacity:"));
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
- gtk_widget_show(hbox);
-
- slider = gtk_hscale_new_with_range(50, 255, 1);
- gtk_range_set_value(GTK_RANGE(slider), imalpha);
- gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1);
-
- /* On slider val change, update window's transparency level */
- g_signal_connect(GTK_OBJECT(slider), "value-changed",
- G_CALLBACK(change_alpha), win);
-
- gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5);
-
- /* Set the initial transparency level */
- set_wintrans(win, imalpha, TRUE,
- purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
-
- gtk_widget_show_all(hbox);
-
- return frame;
-}
-
-static slider_win* find_slidwin(GtkWidget *win) {
- GSList *tmp = window_list;
-
- while (tmp) {
- if (((slider_win*) (tmp->data))->win == win)
- return (slider_win*) tmp->data;
- tmp = tmp->next;
- }
- return NULL;
-}
-
-/* Clean up transparency stuff for the conv window */
-static void cleanup_conv_window(PidginWindow *win) {
- GtkWidget *window = win->window;
- slider_win *slidwin = NULL;
-
- /* Remove window from the window list */
- purple_debug_info(WINTRANS_PLUGIN_ID,
- "Conv window destroyed... removing from list\n");
-
- if ((slidwin = find_slidwin(window))) {
- window_list = g_slist_remove(window_list, slidwin);
- g_free(slidwin);
- }
-
- /* Remove the focus cbs */
- g_signal_handlers_disconnect_by_func(G_OBJECT(window),
- G_CALLBACK(focus_conv_win_cb), window);
-}
-
-static void
-conversation_delete_cb(PurpleConversation *conv) {
- PidginWindow *win = pidgin_conv_get_window(PIDGIN_CONVERSATION(conv));
- /* If it is the last conversation in the window, cleanup */
- if (win != NULL && pidgin_conv_window_get_gtkconv_count(win) == 1)
- cleanup_conv_window(win);
-}
-
-static void set_blist_trans(GtkWidget *w, const char *pref) {
- gboolean enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
- purple_prefs_set_bool(pref, enabled);
- if (blist) {
- set_wintrans(blist, purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA),
- purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED),
- purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
- }
-}
-
-static void add_slider(GtkWidget *win) {
- GList *wl, *wl1;
- GtkWidget *vbox = NULL;
-
- /* Look up this window to see if it already has a slider */
- if (!find_slidwin(win)) {
- GtkWidget *slider_box = NULL;
- slider_win *slidwin = NULL;
- GtkRequisition slidereq;
- gint width, height;
-
- /* Get top vbox */
- for (wl1 = wl = gtk_container_get_children(
- GTK_CONTAINER(win));
- wl != NULL;
- wl = wl->next) {
- if (GTK_IS_VBOX(GTK_OBJECT(wl->data)))
- vbox = GTK_WIDGET(wl->data);
- else {
- purple_debug_error(WINTRANS_PLUGIN_ID,
- "no vbox found\n");
- return;
- }
- }
- g_list_free(wl1);
-
- slider_box = wintrans_slider(win);
- /* Figure out how tall the slider wants to be */
- gtk_widget_size_request(slider_box, &slidereq);
- gtk_window_get_size(GTK_WINDOW(win), &width, &height);
- gtk_box_pack_start(GTK_BOX(vbox),
- slider_box, FALSE, FALSE, 0);
-#if 0 /*Now that we save window sizes, don't resize it or else it causes windows to grow*/
- /* Make window taller so we don't slowly collapse its message area */
- gtk_window_resize(GTK_WINDOW(win), width,
- (height + slidereq.height));
-#endif
- /* Add window to list, to track that it has a slider */
- slidwin = g_new0(slider_win, 1);
- slidwin->win = win;
- slidwin->slider = slider_box;
- window_list = g_slist_append(window_list, slidwin);
- }
-}
-
-static void remove_sliders() {
- if (window_list) {
- GSList *tmp = window_list;
- while (tmp) {
- slider_win *slidwin = (slider_win*) tmp->data;
- if (slidwin != NULL &&
- GTK_IS_WINDOW(slidwin->win)) {
-#if 0
- GtkRequisition slidereq;
- gint width, height;
- /* Figure out how tall the slider was */
- gtk_widget_size_request(
- slidwin->slider, &slidereq);
- gtk_window_get_size(
- GTK_WINDOW(slidwin->win),
- &width, &height);
-#endif
- gtk_widget_destroy(slidwin->slider);
-#if 0
- gtk_window_resize(
- GTK_WINDOW(slidwin->win),
- width, (height - slidereq.height));
-#endif
- }
- g_free(slidwin);
- tmp = tmp->next;
- }
- g_slist_free(window_list);
- window_list = NULL;
- }
-}
-
-/* Remove all transparency related aspects from conversation windows */
-static void remove_convs_wintrans(gboolean remove_signal) {
- GList *wins;
-
- for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
- PidginWindow *win = wins->data;
- GtkWidget *window = win->window;
-
- if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED))
- set_wintrans(window, 0, FALSE, FALSE);
-
- /* Remove the focus cbs */
- if (remove_signal)
- g_signal_handlers_disconnect_by_func(G_OBJECT(window),
- G_CALLBACK(focus_conv_win_cb), window);
- }
-
- remove_sliders();
-}
-
-static void set_conv_window_trans(PidginWindow *oldwin, PidginWindow *newwin) {
- GtkWidget *win = newwin->window;
-
- /* check prefs to see if we want trans */
- if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED)) {
- set_wintrans(win, purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA),
- TRUE, purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
-
- if (purple_prefs_get_bool(OPT_WINTRANS_IM_SLIDER)) {
- add_slider(win);
- }
- }
-
- /* If we're moving from one window to another,
- * add the focus listeners to the new window if not already there */
- if (oldwin != NULL && oldwin != newwin) {
- if (pidgin_conv_window_get_gtkconv_count(newwin) == 0) {
- g_signal_connect(G_OBJECT(win), "focus_in_event",
- G_CALLBACK(focus_conv_win_cb), win);
- g_signal_connect(G_OBJECT(win), "focus_out_event",
- G_CALLBACK(focus_conv_win_cb), win);
- }
-
- /* If we've moved the last conversation, cleanup the window */
- if (pidgin_conv_window_get_gtkconv_count(oldwin) == 1)
- cleanup_conv_window(oldwin);
- }
-}
-
-static void update_convs_wintrans(GtkWidget *toggle_btn, const char *pref) {
- purple_prefs_set_bool(pref, gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(toggle_btn)));
-
- if (purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED)) {
- GList *wins;
-
- for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
- PidginWindow *win = wins->data;
- set_conv_window_trans(NULL, win);
- }
-
- if (!purple_prefs_get_bool(OPT_WINTRANS_IM_SLIDER))
- remove_sliders();
- }
- else
- remove_convs_wintrans(FALSE);
-}
-
-static void
-conv_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type) {
- PidginConversation *pconv = PIDGIN_CONVERSATION(conv);
- PidginWindow *win = pidgin_conv_get_window(pconv);
-
- if (type == PURPLE_CONV_UPDATE_UNSEEN && !pidgin_conv_is_hidden(pconv)
- && pconv->unseen_state == PIDGIN_UNSEEN_NONE
- && pidgin_conv_window_get_gtkconv_count(win) == 1) {
- GtkWidget *window = win->window;
- gboolean has_focus;
-
- g_object_get(G_OBJECT(window), "has-toplevel-focus", &has_focus, NULL);
-
- if (!has_focus || !purple_prefs_get_bool(OPT_WINTRANS_IM_ONFOCUS))
- set_conv_window_trans(NULL, win);
-
- if (g_signal_handler_find(G_OBJECT(window), G_SIGNAL_MATCH_FUNC,
- 0, 0, NULL, G_CALLBACK(focus_conv_win_cb), NULL) == 0) {
- g_signal_connect(G_OBJECT(window), "focus_in_event",
- G_CALLBACK(focus_conv_win_cb), window);
- g_signal_connect(G_OBJECT(window), "focus_out_event",
- G_CALLBACK(focus_conv_win_cb), window);
- }
- }
-}
-
-static void
-new_conversation_cb(PurpleConversation *conv) {
- PidginWindow *win = pidgin_conv_get_window(PIDGIN_CONVERSATION(conv));
-
- /* If it is the first conversation in the window,
- * add the sliders, and set transparency */
- if (!pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv)) && pidgin_conv_window_get_gtkconv_count(win) == 1) {
- GtkWidget *window = win->window;
-
- set_conv_window_trans(NULL, win);
-
- g_signal_connect(G_OBJECT(window), "focus_in_event",
- G_CALLBACK(focus_conv_win_cb), window);
- g_signal_connect(G_OBJECT(window), "focus_out_event",
- G_CALLBACK(focus_conv_win_cb), window);
- }
-}
-
-static void
-blist_created_cb(PurpleBuddyList *purple_blist, gpointer data) {
- if (blist) {
- if (purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED)) {
- set_wintrans(blist,
- purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA),
- TRUE,
- purple_prefs_get_bool(OPT_WINTRANS_BL_ONTOP));
- }
-
- g_signal_connect(G_OBJECT(blist), "focus_in_event",
- G_CALLBACK(focus_blist_win_cb), blist);
- g_signal_connect(G_OBJECT(blist), "focus_out_event",
- G_CALLBACK(focus_blist_win_cb), blist);
- }
-}
-
-static void alpha_change(GtkWidget *w, gpointer data) {
- GList *wins;
- int imalpha = gtk_range_get_value(GTK_RANGE(w));
-
- for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
- PidginWindow *win = wins->data;
- set_wintrans(win->window, imalpha, TRUE,
- purple_prefs_get_bool(OPT_WINTRANS_IM_ONTOP));
- }
-}
-
-static void alpha_pref_set_int (GtkWidget *w, GdkEventFocus *e, const char *pref)
-{
- int alpha = gtk_range_get_value(GTK_RANGE(w));
- purple_prefs_set_int(pref, alpha);
-}
-
-static void bl_alpha_change(GtkWidget *w, gpointer data) {
- if (blist)
- change_alpha(w, blist);
-}
-
-static void update_existing_convs() {
- GList *wins;
-
- for (wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) {
- PidginWindow *win = wins->data;
- GtkWidget *window = win->window;
-
- set_conv_window_trans(NULL, win);
-
- g_signal_connect(G_OBJECT(window), "focus_in_event",
- G_CALLBACK(focus_conv_win_cb), window);
- g_signal_connect(G_OBJECT(window), "focus_out_event",
- G_CALLBACK(focus_conv_win_cb), window);
- }
-}
-
-/*
- * EXPORTED FUNCTIONS
- */
-static gboolean plugin_load(PurplePlugin *plugin) {
-
- purple_signal_connect(purple_conversations_get_handle(),
- "conversation-created", plugin,
- PURPLE_CALLBACK(new_conversation_cb), NULL);
-
- /* Set callback to remove window from the list, if the window is destroyed */
- purple_signal_connect(purple_conversations_get_handle(),
- "deleting-conversation", plugin,
- PURPLE_CALLBACK(conversation_delete_cb), NULL);
-
- purple_signal_connect(pidgin_conversations_get_handle(),
- "conversation-dragging", plugin,
- PURPLE_CALLBACK(set_conv_window_trans), NULL);
-
- purple_signal_connect(purple_conversations_get_handle(),
- "conversation-updated", plugin,
- PURPLE_CALLBACK(conv_updated_cb), NULL);
-
- update_existing_convs();
-
- if (blist)
- blist_created_cb(NULL, NULL);
- else
- purple_signal_connect(pidgin_blist_get_handle(),
- "gtkblist-created", plugin,
- PURPLE_CALLBACK(blist_created_cb), NULL);
-
-
- return TRUE;
-}
-
-static gboolean plugin_unload(PurplePlugin *plugin) {
- purple_debug_info(WINTRANS_PLUGIN_ID, "Unloading win2ktrans plugin\n");
-
- remove_convs_wintrans(TRUE);
-
- if (blist) {
- if (purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED))
- set_wintrans(blist, 0, FALSE, FALSE);
-
- /* Remove the focus cbs */
- g_signal_handlers_disconnect_by_func(G_OBJECT(blist),
- G_CALLBACK(focus_blist_win_cb), blist);
- }
-
- return TRUE;
-}
-
-static GtkWidget *get_config_frame(PurplePlugin *plugin) {
- GtkWidget *ret;
- GtkWidget *imtransbox, *bltransbox;
- GtkWidget *hbox;
- GtkWidget *label, *slider;
- GtkWidget *button;
- GtkWidget *trans_box;
-
- ret = gtk_vbox_new(FALSE, 18);
- gtk_container_set_border_width(GTK_CONTAINER (ret), 12);
-
- /* IM Convo trans options */
- imtransbox = pidgin_make_frame(ret, _("IM Conversation Windows"));
- button = pidgin_prefs_checkbox(_("_IM window transparency"),
- OPT_WINTRANS_IM_ENABLED, imtransbox);
- g_signal_connect(GTK_OBJECT(button), "clicked",
- G_CALLBACK(update_convs_wintrans),
- (gpointer) OPT_WINTRANS_IM_ENABLED);
-
- trans_box = gtk_vbox_new(FALSE, 18);
- if (!purple_prefs_get_bool(OPT_WINTRANS_IM_ENABLED))
- gtk_widget_set_sensitive(GTK_WIDGET(trans_box), FALSE);
- gtk_widget_show(trans_box);
-
- g_signal_connect(GTK_OBJECT(button), "clicked",
- G_CALLBACK(pidgin_toggle_sensitive), trans_box);
-
- button = pidgin_prefs_checkbox(_("_Show slider bar in IM window"),
- OPT_WINTRANS_IM_SLIDER, trans_box);
- g_signal_connect(GTK_OBJECT(button), "clicked",
- G_CALLBACK(update_convs_wintrans),
- (gpointer) OPT_WINTRANS_IM_SLIDER);
-
- button = pidgin_prefs_checkbox(
- _("Remove IM window transparency on focus"),
- OPT_WINTRANS_IM_ONFOCUS, trans_box);
-
- button = pidgin_prefs_checkbox(_("Always on top"), OPT_WINTRANS_IM_ONTOP,
- trans_box);
- g_signal_connect(GTK_OBJECT(button), "clicked",
- G_CALLBACK(update_convs_wintrans),
- (gpointer) OPT_WINTRANS_IM_ONTOP);
-
- gtk_box_pack_start(GTK_BOX(imtransbox), trans_box, FALSE, FALSE, 5);
-
- /* IM transparency slider */
- hbox = gtk_hbox_new(FALSE, 5);
-
- label = gtk_label_new(_("Opacity:"));
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
-
- slider = gtk_hscale_new_with_range(50, 255, 1);
- gtk_range_set_value(GTK_RANGE(slider),
- purple_prefs_get_int(OPT_WINTRANS_IM_ALPHA));
- gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1);
-
- g_signal_connect(GTK_OBJECT(slider), "value-changed",
- G_CALLBACK(alpha_change), NULL);
- g_signal_connect(GTK_OBJECT(slider), "focus-out-event",
- G_CALLBACK(alpha_pref_set_int),
- (gpointer) OPT_WINTRANS_IM_ALPHA);
-
- gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5);
-
- gtk_widget_show_all(hbox);
-
- gtk_box_pack_start(GTK_BOX(trans_box), hbox, FALSE, FALSE, 5);
-
- /* Buddy List trans options */
- bltransbox = pidgin_make_frame (ret, _("Buddy List Window"));
- button = pidgin_prefs_checkbox(_("_Buddy List window transparency"),
- OPT_WINTRANS_BL_ENABLED, bltransbox);
- g_signal_connect(GTK_OBJECT(button), "clicked",
- G_CALLBACK(set_blist_trans),
- (gpointer) OPT_WINTRANS_BL_ENABLED);
-
- trans_box = gtk_vbox_new(FALSE, 18);
- if (!purple_prefs_get_bool(OPT_WINTRANS_BL_ENABLED))
- gtk_widget_set_sensitive(GTK_WIDGET(trans_box), FALSE);
- gtk_widget_show(trans_box);
- g_signal_connect(GTK_OBJECT(button), "clicked",
- G_CALLBACK(pidgin_toggle_sensitive), trans_box);
- button = pidgin_prefs_checkbox(
- _("Remove Buddy List window transparency on focus"),
- OPT_WINTRANS_BL_ONFOCUS, trans_box);
- button = pidgin_prefs_checkbox(_("Always on top"), OPT_WINTRANS_BL_ONTOP,
- trans_box);
- g_signal_connect(GTK_OBJECT(button), "clicked",
- G_CALLBACK(set_blist_trans),
- (gpointer) OPT_WINTRANS_BL_ONTOP);
- gtk_box_pack_start(GTK_BOX(bltransbox), trans_box, FALSE, FALSE, 5);
-
- /* IM transparency slider */
- hbox = gtk_hbox_new(FALSE, 5);
-
- label = gtk_label_new(_("Opacity:"));
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
-
- slider = gtk_hscale_new_with_range(50, 255, 1);
- gtk_range_set_value(GTK_RANGE(slider),
- purple_prefs_get_int(OPT_WINTRANS_BL_ALPHA));
-
- gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1);
-
- g_signal_connect(GTK_OBJECT(slider), "value-changed",
- G_CALLBACK(bl_alpha_change), NULL);
- g_signal_connect(GTK_OBJECT(slider), "focus-out-event",
- G_CALLBACK(alpha_pref_set_int),
- (gpointer) OPT_WINTRANS_BL_ALPHA);
-
- gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5);
-
- gtk_widget_show_all(hbox);
-
- gtk_box_pack_start(GTK_BOX(trans_box), hbox, FALSE, FALSE, 5);
-
- gtk_widget_show_all(ret);
- return ret;
-}
-
-static PidginPluginUiInfo ui_info =
-{
- get_config_frame,
- 0, /* page_num (Reserved) */
-
- /* padding */
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static PurplePluginInfo info =
-{
- PURPLE_PLUGIN_MAGIC,
- PURPLE_MAJOR_VERSION,
- PURPLE_MINOR_VERSION,
- PURPLE_PLUGIN_STANDARD, /**< type */
- PIDGIN_PLUGIN_TYPE, /**< ui_requirement */
- 0, /**< flags */
- NULL, /**< dependencies */
- PURPLE_PRIORITY_DEFAULT, /**< priority */
- WINTRANS_PLUGIN_ID, /**< id */
- N_("Transparency"), /**< name */
- DISPLAY_VERSION, /**< version */
- /** summary */
- N_("Variable Transparency for the buddy list and conversations."),
- /** description */
- N_("This plugin enables variable alpha transparency on conversation windows and the buddy list."),
- "Herman Bloggs <hermanator12002@yahoo.com>", /**< author */
- PURPLE_WEBSITE, /**< homepage */
- plugin_load, /**< load */
- plugin_unload, /**< unload */
- NULL, /**< destroy */
- &ui_info, /**< ui_info */
- NULL, /**< extra_info */
- NULL, /**< prefs_info */
- NULL, /**< actions */
-
- /* padding */
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static void
-init_plugin(PurplePlugin *plugin)
-{
- purple_prefs_add_none("/plugins/gtk/win32");
- purple_prefs_add_none("/plugins/gtk/win32/wintrans");
- purple_prefs_add_bool(OPT_WINTRANS_IM_ENABLED, FALSE);
- purple_prefs_add_int(OPT_WINTRANS_IM_ALPHA, 255);
- purple_prefs_add_bool(OPT_WINTRANS_IM_SLIDER, FALSE);
- purple_prefs_add_bool(OPT_WINTRANS_IM_ONFOCUS, FALSE);
- purple_prefs_add_bool(OPT_WINTRANS_IM_ONTOP, FALSE);
- purple_prefs_add_bool(OPT_WINTRANS_BL_ENABLED, FALSE);
- purple_prefs_add_int(OPT_WINTRANS_BL_ALPHA, 255);
- purple_prefs_add_bool(OPT_WINTRANS_BL_ONFOCUS, FALSE);
- purple_prefs_add_bool(OPT_WINTRANS_BL_ONTOP, FALSE);
-}
-
-PURPLE_INIT_PLUGIN(wintrans, init_plugin, info)