summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kamil Kozar <dkk089@gmail.com>2017-11-29 20:40:36 +0100
committerDaniel Kamil Kozar <dkk089@gmail.com>2017-11-29 20:40:36 +0100
commitb1538a9d1369dcd3155f8560c671d56112a2ccc3 (patch)
tree1e033d30c188360613b1c36372e94a097ce7300b
parent3b89b04945adfb72d82e59ba5695588fa65b8cb7 (diff)
parent5c3cf26f08de066f7631025d5113824ff2ce217a (diff)
downloadpidgin-b1538a9d1369dcd3155f8560c671d56112a2ccc3.tar.gz
merge
-rw-r--r--COPYRIGHT6
-rw-r--r--ChangeLog25
-rw-r--r--ChangeLog.API5
-rw-r--r--configure.ac30
-rw-r--r--finch/gntnotify.c13
-rw-r--r--finch/libgnt/gntmain.c32
-rw-r--r--finch/libgnt/gntwm.c30
-rw-r--r--libpurple/buddyicon.c8
-rw-r--r--libpurple/media/backend-fs2.c25
-rw-r--r--libpurple/protocols/irc/irc.c45
-rw-r--r--libpurple/protocols/irc/irc.h3
-rw-r--r--libpurple/protocols/jabber/bosh.c35
-rw-r--r--libpurple/protocols/jabber/jingle/rtp.c21
-rw-r--r--libpurple/tests/test_util.c22
-rw-r--r--libpurple/util.c11
-rw-r--r--libpurple/util.h11
-rw-r--r--libpurple/win32/libc_interface.c1
-rw-r--r--pidgin/Makefile.am2
-rw-r--r--pidgin/Makefile.mingw1
-rw-r--r--pidgin/gtkblist.c27
-rw-r--r--pidgin/gtkconv.c89
-rw-r--r--pidgin/gtkimhtml.c2
-rw-r--r--pidgin/gtknotify.c10
-rw-r--r--pidgin/gtkstyle.c70
-rw-r--r--pidgin/gtkstyle.h59
-rw-r--r--pidgin/plugins/Makefile.am4
-rw-r--r--pidgin/plugins/Makefile.mingw5
-rw-r--r--pidgin/plugins/transparency.c (renamed from pidgin/plugins/win32/transparency/win2ktrans.c)74
-rw-r--r--pidgin/plugins/win32/transparency/Makefile.mingw75
29 files changed, 443 insertions, 298 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index a8aff039e7..ca40a6678a 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -15,7 +15,7 @@ If concerns are raised as to the copyright holder of a particular
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 @@ Ho-seok Lee
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 @@ James McLaughlin
Torrey McMahon
Greg McNew
Robert McQueen
+Christof Meerwald
Mihály Mészáros
Robert Mibus
David Michael
@@ -619,6 +622,7 @@ The Written Word, Inc.
Kevin Wu Won
Pui Lam Wong
Justin Wood
+David Woodhouse
Ximian
Ma Xuan
Yonas Yanfa
diff --git a/ChangeLog b/ChangeLog
index fb59a51b95..ab71c17ba6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
diff --git a/ChangeLog.API b/ChangeLog.API
index 44d18bc452..223d529424 100644
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -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:
diff --git a/configure.ac b/configure.ac
index e81eda9572..71b9f7b6ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,10 +43,10 @@ AC_PREREQ([2.50])
#
# 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 @@ AC_ARG_WITH(gstreamer, [AS_HELP_STRING([--with-gstreamer=<version>],
[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 @@ Use --disable-gstreamer if you do not need GStreamer (sound) support.
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 @@ Use --disable-gstreamer if you do not need GStreamer (sound) support.
])
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 @@ Use --disable-gstreamer if you do not need GStreamer (sound) support.
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 @@ fi
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 @@ fi
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 @@ AC_ARG_ENABLE(farstream,
[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 @@ AC_ARG_ENABLE(vv,
[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 @@ AM_CONDITIONAL(USE_VV, test "x$enable_vv" != "xno")
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])
diff --git a/finch/gntnotify.c b/finch/gntnotify.c
index f32650d2b5..1ee752ee16 100644
--- a/finch/gntnotify.c
+++ b/finch/gntnotify.c
@@ -388,10 +388,11 @@ static void
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 @@ finch_notify_searchresults(PurpleConnection *gc, const char *title,
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 *
diff --git a/finch/libgnt/gntmain.c b/finch/libgnt/gntmain.c
index 71548df9b5..bccf021c02 100644
--- a/finch/libgnt/gntmain.c
+++ b/finch/libgnt/gntmain.c
@@ -407,10 +407,11 @@ raise:
#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 @@ sighandler(int sig)
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 @@ void gnt_init()
{
char *filename;
const char *locale;
+ struct sigaction act;
+#ifdef SIGWINCH
+ struct sigaction oact;
+#endif
if (channel)
return;
@@ -501,11 +505,25 @@ void gnt_init()
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)
diff --git a/finch/libgnt/gntwm.c b/finch/libgnt/gntwm.c
index 310d6c621c..705a487539 100644
--- a/finch/libgnt/gntwm.c
+++ b/finch/libgnt/gntwm.c
@@ -174,37 +174,37 @@ work_around_for_ncurses_bug(void)
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);
}
}
}
diff --git a/libpurple/buddyicon.c b/libpurple/buddyicon.c
index 7f5a290539..14e03c09b9 100644
--- a/libpurple/buddyicon.c
+++ b/libpurple/buddyicon.c
@@ -174,8 +174,12 @@ purple_buddy_icon_data_cache(PurpleStoredImage *img)
}
}
- 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);
}
diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
index fd658ce0c1..036efb1918 100644
--- a/libpurple/media/backend-fs2.c
+++ b/libpurple/media/backend-fs2.c
@@ -1151,7 +1151,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
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 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
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 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
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 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
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 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
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 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
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 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
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 @@ create_participant(PurpleMediaBackendFs2 *self, const gchar *name)
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")) {
diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c
index 2078985d90..133c4d1aa0 100644
--- a/libpurple/protocols/irc/irc.c
+++ b/libpurple/protocols/irc/irc.c
@@ -685,31 +685,38 @@ static void irc_input_cb_ssl(gpointer data, PurpleSslConnection *gsc,
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 @@ static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond)
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) {
diff --git a/libpurple/protocols/irc/irc.h b/libpurple/protocols/irc/irc.h
index fde35c42c7..f587790d60 100644
--- a/libpurple/protocols/irc/irc.h
+++ b/libpurple/protocols/irc/irc.h
@@ -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
diff --git a/libpurple/protocols/jabber/bosh.c b/libpurple/protocols/jabber/bosh.c
index af178c64bc..d80ecd6ac1 100644
--- a/libpurple/protocols/jabber/bosh.c
+++ b/libpurple/protocols/jabber/bosh.c
@@ -68,7 +68,6 @@ struct _PurpleBOSHConnection {
char *path;
guint16 port;
- gboolean pipelining;
gboolean ssl;
enum {
@@ -212,7 +211,6 @@ jabber_bosh_connection_init(JabberStream *js, const char *url)
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 @@ find_available_http_connection(PurpleBOSHConnection *conn)
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 @@ jabber_bosh_connection_send_keepalive(PurpleBOSHConnection *bosh)
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 @@ static void http_connection_disconnected(PurpleHTTPConnection *conn)
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 @@ jabber_bosh_http_connection_process(PurpleHTTPConnection *conn)
if (!g_ascii_strncasecmp(tmp, "close", strlen("close"))) {
conn->close = TRUE;
- jabber_bosh_disable_pipelining(conn->bosh);
}
}
diff --git a/libpurple/protocols/jabber/jingle/rtp.c b/libpurple/protocols/jabber/jingle/rtp.c
index 876b80fb36..05cb2cb1bb 100644
--- a/libpurple/protocols/jabber/jingle/rtp.c
+++ b/libpurple/protocols/jabber/jingle/rtp.c
@@ -950,6 +950,7 @@ jingle_rtp_initiate_media(JabberStream *js, const gchar *who,
JingleTransport *transport;
JabberBuddy *jb;
JabberBuddyResource *jbr;
+ gboolean ret = FALSE;
const gchar *transport_type;
gchar *resource = NULL, *me = NULL, *sid = NULL;
@@ -958,16 +959,15 @@ jingle_rtp_initiate_media(JabberStream *js, const gchar *who,
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 @@ jingle_rtp_initiate_media(JabberStream *js, const gchar *who,
} 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 @@ jingle_rtp_initiate_media(JabberStream *js, const gchar *who,
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_initiate_media(JabberStream *js, const gchar *who,
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
diff --git a/libpurple/tests/test_util.c b/libpurple/tests/test_util.c
index 303a056117..4239d9312c 100644
--- a/libpurple/tests/test_util.c
+++ b/libpurple/tests/test_util.c
@@ -232,6 +232,24 @@ START_TEST(test_strdup_withhtml)
}
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 @@ util_suite(void)
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;
}
diff --git a/libpurple/util.c b/libpurple/util.c
index 044a7acff0..ba7ad4b152 100644
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -4583,6 +4583,17 @@ purple_uri_list_extract_filenames(const gchar *uri_list)
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
**************************************************************************/
diff --git a/libpurple/util.h b/libpurple/util.h
index ede673e19e..d7ae1957ca 100644
--- a/libpurple/util.h
+++ b/libpurple/util.h
@@ -1330,6 +1330,17 @@ GList *purple_uri_list_extract_uris(const gchar *uri_list);
*/
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);
+
/*@}*/
/**************************************************************************
diff --git a/libpurple/win32/libc_interface.c b/libpurple/win32/libc_interface.c
index 96bea53568..ee772e8de5 100644
--- a/libpurple/win32/libc_interface.c
+++ b/libpurple/win32/libc_interface.c
@@ -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 */
diff --git a/pidgin/Makefile.am b/pidgin/Makefile.am
index 84d927ba59..09fa65ca39 100644
--- a/pidgin/Makefile.am
+++ b/pidgin/Makefile.am
@@ -81,6 +81,7 @@ pidgin_SOURCES = \
gtksourceview-marshal.c \
gtkstatus-icon-theme.c \
gtkstatusbox.c \
+ gtkstyle.c \
gtkthemes.c \
gtkutils.c \
gtkwhiteboard.c \
@@ -131,6 +132,7 @@ pidgin_headers = \
gtksourceview-marshal.h \
gtkstatus-icon-theme.h \
gtkstatusbox.h \
+ gtkstyle.h \
pidginstock.h \
gtkthemes.h \
gtkutils.h \
diff --git a/pidgin/Makefile.mingw b/pidgin/Makefile.mingw
index aa77ddabf2..664edd2176 100644
--- a/pidgin/Makefile.mingw
+++ b/pidgin/Makefile.mingw
@@ -89,6 +89,7 @@ PIDGIN_C_SRC = \
gtksourceundomanager.c \
gtkstatus-icon-theme.c \
gtkstatusbox.c \
+ gtkstyle.c \
gtkthemes.c \
gtkutils.c \
gtkwhiteboard.c \
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
index 125788e920..746da67efb 100644
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -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 @@ theme_font_get_face_default(PidginThemeFont *font, const char *def)
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 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased
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 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased
&& (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 @@ conversation_created_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
}
}
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 @@ static void pidgin_blist_show(PurpleBuddyList *list)
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 @@ static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *n
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>",
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index b98c6375ef..d04997e682 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -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 @@ pidgin_conversations_init(void)
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);
- }
+}
+
+/* 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);
}
+ gtk_rc_parse_string(str->str);
+ g_string_free(str, TRUE);
+ gtk_rc_reset_styles(settings);
}
void
@@ -9385,6 +9402,9 @@ pidgin_conv_window_new()
gtk_window_iconify(GTK_WINDOW(win->window));
#endif
+ /* Fix colours */
+ pidgin_conversations_set_tab_colors();
+
return win;
}
@@ -10252,6 +10272,9 @@ generate_nick_colors(guint *color_count, GdkColor background)
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;
diff --git a/pidgin/gtkimhtml.c b/pidgin/gtkimhtml.c
index 777db0bef4..283900c314 100644
--- a/pidgin/gtkimhtml.c
+++ b/pidgin/gtkimhtml.c
@@ -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 @@ gtk_imhtml_style_set(GtkWidget *widget, GtkStyle *prev_style)
} 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);
}
}
diff --git a/pidgin/gtknotify.c b/pidgin/gtknotify.c
index f1e1bae736..60d7dd8e1f 100644
--- a/pidgin/gtknotify.c
+++ b/pidgin/gtknotify.c
@@ -1044,7 +1044,7 @@ pidgin_notify_searchresults(PurpleConnection *gc, const char *title,
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 @@ pidgin_notify_uri(const char *uri)
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");
diff --git a/pidgin/gtkstyle.c b/pidgin/gtkstyle.c
new file mode 100644
index 0000000000..a1985fe700
--- /dev/null
+++ b/pidgin/gtkstyle.c
@@ -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);
+ }
+}
diff --git a/pidgin/gtkstyle.h b/pidgin/gtkstyle.h
new file mode 100644
index 0000000000..0b65a226f6
--- /dev/null
+++ b/pidgin/gtkstyle.h
@@ -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_ */
diff --git a/pidgin/plugins/Makefile.am b/pidgin/plugins/Makefile.am
index 3bb8c22402..bdf7a337d0 100644
--- a/pidgin/plugins/Makefile.am
+++ b/pidgin/plugins/Makefile.am
@@ -47,6 +47,7 @@ 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
@@ -68,6 +69,7 @@ plugin_LTLIBRARIES = \
themeedit.la \
timestamp.la \
timestamp_format.la \
+ transparency.la \
xmppconsole.la
if USE_VV
@@ -98,6 +100,7 @@ spellchk_la_SOURCES = spellchk.c
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 @@ 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)
diff --git a/pidgin/plugins/Makefile.mingw b/pidgin/plugins/Makefile.mingw
index f16f9f506d..22984d31f5 100644
--- a/pidgin/plugins/Makefile.mingw
+++ b/pidgin/plugins/Makefile.mingw
@@ -10,7 +10,6 @@ include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
DISCO_PLUGIN := ./disco
GTKPERL_PLUGIN := ./perl
TICKER_PLUGIN := ./ticker
-TRANSPARENCY_PLUGIN := ./win32/transparency
WINPREFS_PLUGIN := ./win32/winprefs
.SUFFIXES:
@@ -63,14 +62,12 @@ all: plugins
$(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 @@ plugins: \
themeedit.dll \
timestamp_format.dll \
timestamp.dll \
+ transparency.dll \
xmppconsole.dll
##
@@ -112,7 +110,6 @@ clean:
$(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)
diff --git a/pidgin/plugins/win32/transparency/win2ktrans.c b/pidgin/plugins/transparency.c
index 3fc80e7064..4ee7b9b57d 100644
--- a/pidgin/plugins/win32/transparency/win2ktrans.c
+++ b/pidgin/plugins/transparency.c
@@ -21,7 +21,6 @@
* 02111-1301, USA.
*
*/
-#include <gdk/gdkwin32.h>
#include "internal.h"
#include "core.h"
@@ -39,6 +38,8 @@
/*
* 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() \
@@ -58,15 +59,15 @@ typedef struct {
/*
* 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 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;
/*
@@ -76,31 +77,13 @@ static GSList *window_list = NULL;
/* 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);
+ gdk_window_set_opacity(window->window, alpha / 255.0);
+ gdk_window_set_keep_above(window->window, always_on_top);
} 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);
+ 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,
@@ -270,11 +253,6 @@ static void add_slider(GtkWidget *win) {
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;
@@ -290,22 +268,7 @@ static void remove_sliders() {
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;
@@ -518,7 +481,7 @@ static gboolean plugin_load(PurplePlugin *plugin) {
}
static gboolean plugin_unload(PurplePlugin *plugin) {
- purple_debug_info(WINTRANS_PLUGIN_ID, "Unloading win2ktrans plugin\n");
+ purple_debug_info(WINTRANS_PLUGIN_ID, "Unloading transparency plugin\n");
remove_convs_wintrans(TRUE);
@@ -703,8 +666,8 @@ static PurplePluginInfo info =
static void
init_plugin(PurplePlugin *plugin)
{
- purple_prefs_add_none("/plugins/gtk/win32");
- purple_prefs_add_none("/plugins/gtk/win32/wintrans");
+ 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);
@@ -714,6 +677,7 @@ init_plugin(PurplePlugin *plugin)
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)
diff --git a/pidgin/plugins/win32/transparency/Makefile.mingw b/pidgin/plugins/win32/transparency/Makefile.mingw
deleted file mode 100644
index f04d81ae4f..0000000000
--- a/pidgin/plugins/win32/transparency/Makefile.mingw
+++ /dev/null
@@ -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)