|
Packit |
79f644 |
/*
|
|
Packit |
79f644 |
* Copyright (C) 2007-2013 Collabora Ltd.
|
|
Packit |
79f644 |
* Copyright (C) 2005-2006 Imendio AB
|
|
Packit |
79f644 |
* Copyright (C) 2006 Xavier Claessens <xavier.claessens@gmail.com>
|
|
Packit |
79f644 |
* Copyright (C) 2009 Steve Frécinaux <code@istique.net>
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* Authors: Marco Barisione <marco.barisione@collabora.co.uk>
|
|
Packit |
79f644 |
* Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
|
|
Packit |
79f644 |
* Sjoerd Simons <sjoerd.simons@collabora.co.uk>
|
|
Packit |
79f644 |
* Xavier Claessens <xavier.claessens@collabora.co.uk>
|
|
Packit |
79f644 |
* Mikael Hallendal <micke@imendio.com>
|
|
Packit |
79f644 |
* Richard Hult <richard@imendio.com>
|
|
Packit |
79f644 |
* Martyn Russell <martyn@imendio.com>
|
|
Packit |
79f644 |
* Steve Frécinaux <code@istique.net>
|
|
Packit |
79f644 |
* Emanuele Aina <emanuele.aina@collabora.co.uk>
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
79f644 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
79f644 |
* License as published by the Free Software Foundation; either
|
|
Packit |
79f644 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
79f644 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
79f644 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
79f644 |
* Lesser General Public License for more details.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
79f644 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
79f644 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include "config.h"
|
|
Packit |
79f644 |
#include "tpaw-utils.h"
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include <glib/gi18n-lib.h>
|
|
Packit |
79f644 |
#include <gtk/gtk.h>
|
|
Packit |
79f644 |
#ifdef GDK_WINDOWING_X11
|
|
Packit |
79f644 |
#include <gdk/gdkx.h>
|
|
Packit |
79f644 |
#endif
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#define DEBUG_FLAG TPAW_DEBUG_OTHER
|
|
Packit |
79f644 |
#include "tpaw-debug.h"
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#define TPAW_RECT_IS_ON_SCREEN(x,y,w,h) ((x) + (w) > 0 && \
|
|
Packit |
79f644 |
(y) + (h) > 0 && \
|
|
Packit |
79f644 |
(x) < gdk_screen_width () && \
|
|
Packit |
79f644 |
(y) < gdk_screen_height ())
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* Change the RequestedPresence of a newly created account to ensure that it
|
|
Packit |
79f644 |
* is actually connected. */
|
|
Packit |
79f644 |
void
|
|
Packit |
79f644 |
tpaw_connect_new_account (TpAccount *account,
|
|
Packit |
79f644 |
TpAccountManager *account_manager)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
TpConnectionPresenceType presence;
|
|
Packit |
79f644 |
gchar *status, *message;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* only force presence if presence was offline, unknown or unset */
|
|
Packit |
79f644 |
presence = tp_account_get_requested_presence (account, NULL, NULL);
|
|
Packit |
79f644 |
switch (presence)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_UNSET:
|
|
Packit |
79f644 |
presence = tp_account_manager_get_most_available_presence (
|
|
Packit |
79f644 |
account_manager, &status, &message);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (presence == TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
|
|
Packit |
79f644 |
/* Global presence is offline; we force it so user doesn't have to
|
|
Packit |
79f644 |
* manually change the presence to connect his new account. */
|
|
Packit |
79f644 |
presence = TP_CONNECTION_PRESENCE_TYPE_AVAILABLE;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
tp_account_request_presence_async (account, presence,
|
|
Packit |
79f644 |
status, NULL, NULL, NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_free (status);
|
|
Packit |
79f644 |
g_free (message);
|
|
Packit |
79f644 |
break;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE:
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_AWAY:
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY:
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_HIDDEN:
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_BUSY:
|
|
Packit |
79f644 |
case TP_CONNECTION_PRESENCE_TYPE_ERROR:
|
|
Packit |
79f644 |
default:
|
|
Packit |
79f644 |
/* do nothing if the presence is not offline */
|
|
Packit |
79f644 |
break;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gchar *
|
|
Packit |
79f644 |
tpaw_protocol_icon_name (const gchar *protocol)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (!tp_strdiff (protocol, "yahoojp"))
|
|
Packit |
79f644 |
/* Yahoo Japan uses the same icon as Yahoo */
|
|
Packit |
79f644 |
protocol = "yahoo";
|
|
Packit |
79f644 |
else if (!tp_strdiff (protocol, "simple"))
|
|
Packit |
79f644 |
/* SIMPLE uses the same icon as SIP */
|
|
Packit |
79f644 |
protocol = "sip";
|
|
Packit |
79f644 |
else if (!tp_strdiff (protocol, "skype-dbus") ||
|
|
Packit |
79f644 |
!tp_strdiff (protocol, "skype-x11") ||
|
|
Packit |
79f644 |
!tp_strdiff (protocol, "skypeweb"))
|
|
Packit |
79f644 |
protocol = "skype";
|
|
Packit |
79f644 |
else if (!tp_strdiff (protocol, "sms"))
|
|
Packit |
79f644 |
return g_strdup ("phone");
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return g_strdup_printf ("im-%s", protocol);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
const char *
|
|
Packit |
79f644 |
tpaw_protocol_name_to_display_name (const gchar *proto_name)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
int i;
|
|
Packit |
79f644 |
static struct {
|
|
Packit |
79f644 |
const gchar *proto;
|
|
Packit |
79f644 |
const gchar *display;
|
|
Packit |
79f644 |
gboolean translated;
|
|
Packit |
79f644 |
} names[] = {
|
|
Packit |
79f644 |
{ "jabber", "Jabber", FALSE },
|
|
Packit |
79f644 |
{ "msn", "Windows Live (MSN)", FALSE, },
|
|
Packit |
79f644 |
{ "local-xmpp", N_("People Nearby"), TRUE },
|
|
Packit |
79f644 |
{ "irc", "IRC", FALSE },
|
|
Packit |
79f644 |
{ "icq", "ICQ", FALSE },
|
|
Packit |
79f644 |
{ "aim", "AIM", FALSE },
|
|
Packit |
79f644 |
{ "yahoo", "Yahoo!", FALSE },
|
|
Packit |
79f644 |
{ "yahoojp", N_("Yahoo! Japan"), TRUE },
|
|
Packit |
79f644 |
{ "groupwise", "GroupWise", FALSE },
|
|
Packit |
79f644 |
{ "sip", "SIP", FALSE },
|
|
Packit |
79f644 |
{ "gadugadu", "Gadu-Gadu", FALSE },
|
|
Packit |
79f644 |
{ "mxit", "Mxit", FALSE },
|
|
Packit |
79f644 |
{ "myspace", "Myspace", FALSE },
|
|
Packit |
79f644 |
{ "sametime", "Sametime", FALSE },
|
|
Packit |
79f644 |
{ "skype-dbus", "Skype (D-BUS)", FALSE },
|
|
Packit |
79f644 |
{ "skype-x11", "Skype (X11)", FALSE },
|
|
Packit |
79f644 |
{ "skypeweb", "Skype", FALSE },
|
|
Packit |
79f644 |
{ "zephyr", "Zephyr", FALSE },
|
|
Packit |
79f644 |
{ "facebook", "Facebook Messenger", FALSE },
|
|
Packit |
79f644 |
{ NULL, NULL }
|
|
Packit |
79f644 |
};
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
for (i = 0; names[i].proto != NULL; i++)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (!tp_strdiff (proto_name, names[i].proto))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (names[i].translated)
|
|
Packit |
79f644 |
return gettext (names[i].display);
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
return names[i].display;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return proto_name;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
const char *
|
|
Packit |
79f644 |
tpaw_service_name_to_display_name (const gchar *service_name)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
int i;
|
|
Packit |
79f644 |
static struct {
|
|
Packit |
79f644 |
const gchar *service;
|
|
Packit |
79f644 |
const gchar *display;
|
|
Packit |
79f644 |
gboolean translated;
|
|
Packit |
79f644 |
} names[] = {
|
|
Packit |
79f644 |
{ "google-talk", N_("Google Talk"), FALSE },
|
|
Packit |
79f644 |
{ NULL, NULL }
|
|
Packit |
79f644 |
};
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
for (i = 0; names[i].service != NULL; i++)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (!tp_strdiff (service_name, names[i].service))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
if (names[i].translated)
|
|
Packit |
79f644 |
return gettext (names[i].display);
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
return names[i].display;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return service_name;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gboolean
|
|
Packit |
79f644 |
tpaw_xml_validate_from_resource (xmlDoc *doc,
|
|
Packit |
79f644 |
const gchar *dtd_resourcename)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GBytes *resourcecontents;
|
|
Packit |
79f644 |
gconstpointer resourcedata;
|
|
Packit |
79f644 |
gsize resourcesize;
|
|
Packit |
79f644 |
xmlParserInputBufferPtr buffer;
|
|
Packit |
79f644 |
xmlValidCtxt cvp;
|
|
Packit |
79f644 |
xmlDtd *dtd;
|
|
Packit |
79f644 |
GError *error = NULL;
|
|
Packit |
79f644 |
gboolean ret;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
DEBUG ("Loading dtd resource %s", dtd_resourcename);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
resourcecontents = g_resources_lookup_data (dtd_resourcename, G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
|
|
Packit |
79f644 |
if (error != NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_warning ("Unable to load dtd resource '%s': %s", dtd_resourcename, error->message);
|
|
Packit |
79f644 |
g_error_free (error);
|
|
Packit |
79f644 |
return FALSE;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
resourcedata = g_bytes_get_data (resourcecontents, &resourcesize);
|
|
Packit |
79f644 |
buffer = xmlParserInputBufferCreateStatic (resourcedata, resourcesize, XML_CHAR_ENCODING_UTF8);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
memset (&cvp, 0, sizeof (cvp));
|
|
Packit |
79f644 |
dtd = xmlIOParseDTD (NULL, buffer, XML_CHAR_ENCODING_UTF8);
|
|
Packit |
79f644 |
ret = xmlValidateDtd (&cvp, doc, dtd);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
xmlFreeDtd (dtd);
|
|
Packit |
79f644 |
g_bytes_unref (resourcecontents);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return ret;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* Takes care of moving the window to the current workspace. */
|
|
Packit |
79f644 |
void
|
|
Packit |
79f644 |
tpaw_window_present_with_time (GtkWindow *window,
|
|
Packit |
79f644 |
guint32 timestamp)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GdkWindow *gdk_window;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_if_fail (GTK_IS_WINDOW (window));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* Move the window to the current workspace before trying to show it.
|
|
Packit |
79f644 |
* This is the behaviour people expect when clicking on the statusbar icon. */
|
|
Packit |
79f644 |
gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (gdk_window)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
gint x, y;
|
|
Packit |
79f644 |
gint w, h;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#ifdef GDK_WINDOWING_X11
|
|
Packit |
79f644 |
/* Has no effect if the WM has viewports, like compiz */
|
|
Packit |
79f644 |
if (GDK_IS_X11_WINDOW (gdk_window))
|
|
Packit |
79f644 |
gdk_x11_window_move_to_current_desktop (gdk_window);
|
|
Packit |
79f644 |
#endif
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* If window is still off-screen, hide it to force it to
|
|
Packit |
79f644 |
* reposition on the current workspace. */
|
|
Packit |
79f644 |
gtk_window_get_position (window, &x, &y);
|
|
Packit |
79f644 |
gtk_window_get_size (window, &w, &h);
|
|
Packit |
79f644 |
if (!TPAW_RECT_IS_ON_SCREEN (x, y, w, h))
|
|
Packit |
79f644 |
gtk_widget_hide (GTK_WIDGET (window));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (timestamp == GDK_CURRENT_TIME)
|
|
Packit |
79f644 |
gtk_window_present (window);
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
gtk_window_present_with_time (window, timestamp);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
void
|
|
Packit |
79f644 |
tpaw_window_present (GtkWindow *window)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
tpaw_window_present_with_time (window, gtk_get_current_event_time ());
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
GtkWindow *
|
|
Packit |
79f644 |
tpaw_get_toplevel_window (GtkWidget *widget)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GtkWidget *toplevel;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
toplevel = gtk_widget_get_toplevel (widget);
|
|
Packit |
79f644 |
if (GTK_IS_WINDOW (toplevel) &&
|
|
Packit |
79f644 |
gtk_widget_is_toplevel (toplevel))
|
|
Packit |
79f644 |
return GTK_WINDOW (toplevel);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return NULL;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/** tpaw_make_absolute_url_len:
|
|
Packit |
79f644 |
* @url: an url
|
|
Packit |
79f644 |
* @len: a length
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* Same as #tpaw_make_absolute_url but for a limited string length
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
gchar *
|
|
Packit |
79f644 |
tpaw_make_absolute_url_len (const gchar *url,
|
|
Packit |
79f644 |
guint len)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_return_val_if_fail (url != NULL, NULL);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (g_str_has_prefix (url, "help:") ||
|
|
Packit |
79f644 |
g_str_has_prefix (url, "mailto:") ||
|
|
Packit |
79f644 |
strstr (url, ":/"))
|
|
Packit |
79f644 |
return g_strndup (url, len);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (strstr (url, "@"))
|
|
Packit |
79f644 |
return g_strdup_printf ("mailto:%.*s", len, url);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return g_strdup_printf ("http://%.*s", len, url);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/** tpaw_make_absolute_url:
|
|
Packit |
79f644 |
* @url: an url
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* The URL opening code can't handle schemeless strings, so we try to be
|
|
Packit |
79f644 |
* smart and add http if there is no scheme or doesn't look like a mail
|
|
Packit |
79f644 |
* address. This should work in most cases, and let us click on strings
|
|
Packit |
79f644 |
* like "www.gnome.org".
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* Returns: a newly allocated url with proper mailto: or http:// prefix, use
|
|
Packit |
79f644 |
* g_free when your are done with it
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
gchar *
|
|
Packit |
79f644 |
tpaw_make_absolute_url (const gchar *url)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
return tpaw_make_absolute_url_len (url, strlen (url));
|
|
Packit |
79f644 |
}
|