You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(106) |
Oct
(334) |
Nov
(246) |
Dec
(145) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(42) |
Feb
(53) |
Mar
(232) |
Apr
(109) |
May
(137) |
Jun
(63) |
Jul
(26) |
Aug
(263) |
Sep
(193) |
Oct
(507) |
Nov
(440) |
Dec
(241) |
2003 |
Jan
(567) |
Feb
(195) |
Mar
(504) |
Apr
(481) |
May
(524) |
Jun
(522) |
Jul
(594) |
Aug
(502) |
Sep
(643) |
Oct
(508) |
Nov
(430) |
Dec
(377) |
2004 |
Jan
(361) |
Feb
(251) |
Mar
(219) |
Apr
(499) |
May
(461) |
Jun
(419) |
Jul
(314) |
Aug
(519) |
Sep
(416) |
Oct
(247) |
Nov
(305) |
Dec
(382) |
2005 |
Jan
(267) |
Feb
(282) |
Mar
(327) |
Apr
(338) |
May
(189) |
Jun
(400) |
Jul
(462) |
Aug
(530) |
Sep
(316) |
Oct
(523) |
Nov
(481) |
Dec
(650) |
2006 |
Jan
(536) |
Feb
(361) |
Mar
(287) |
Apr
(146) |
May
(101) |
Jun
(169) |
Jul
(221) |
Aug
(498) |
Sep
(300) |
Oct
(236) |
Nov
(209) |
Dec
(205) |
2007 |
Jan
(30) |
Feb
(23) |
Mar
(26) |
Apr
(15) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <dat...@us...> - 2006-10-08 17:44:20
|
Revision: 17450 http://svn.sourceforge.net/gaim/?rev=17450&view=rev Author: datallah Date: 2006-10-08 10:44:10 -0700 (Sun, 08 Oct 2006) Log Message: ----------- We're not using libiberty, so don't link to it. We don't need to define socklen_t in config.h (it is in ws2tcpip.h) (thanks nosnilmot) Modified Paths: -------------- trunk/config.h.mingw trunk/gtk/Makefile.mingw trunk/libgaim/Makefile.mingw Modified: trunk/config.h.mingw =================================================================== --- trunk/config.h.mingw 2006-10-08 09:47:23 UTC (rev 17449) +++ trunk/config.h.mingw 2006-10-08 17:44:10 UTC (rev 17450) @@ -629,7 +629,7 @@ /* #undef size_t */ /* socklen_t size */ -#define socklen_t int +/* #define socklen_t int */ /* Define to unsigned long or unsigned long long if <stdint.h> and <inttypes.h> don't define. */ Modified: trunk/gtk/Makefile.mingw =================================================================== --- trunk/gtk/Makefile.mingw 2006-10-08 09:47:23 UTC (rev 17449) +++ trunk/gtk/Makefile.mingw 2006-10-08 17:44:10 UTC (rev 17450) @@ -17,8 +17,6 @@ EXE_NAME := $(EXE_TARGET).exe WINAPP := -mwindows -# The Debug version of gaim is a console app, always having a console -CONSOLEAPP := -mconsole LDFLAGS := $(WINAPP) @@ -115,8 +113,7 @@ -lintl \ -lws2_32 \ -lwinmm \ - -lz \ - -liberty + -lz GTKGAIM_LIBS = \ $(LIBGAIM_LIBS) \ Modified: trunk/libgaim/Makefile.mingw =================================================================== --- trunk/libgaim/Makefile.mingw 2006-10-08 09:47:23 UTC (rev 17449) +++ trunk/libgaim/Makefile.mingw 2006-10-08 17:44:10 UTC (rev 17450) @@ -90,7 +90,6 @@ -lgmodule-2.0 \ -lintl \ -lws2_32 \ - -liberty \ -lxml2 include $(GAIM_COMMON_RULES) @@ -98,18 +97,20 @@ ## ## TARGET DEFINITIONS ## -.PHONY: all install clean +.PHONY: all install install_shallow clean all: $(TARGET).dll $(MAKE) -C $(GAIM_PROTOS_TOP) -f $(GAIM_WIN32_MAKEFILE) $(MAKE) -C $(GAIM_LIB_PLUGINS_TOP) -f $(GAIM_WIN32_MAKEFILE) -install: all $(GAIM_INSTALL_DIR) - $(MAKE) -C $(GAIM_PROTOS_TOP) -f $(GAIM_WIN32_MAKEFILE) install - $(MAKE) -C $(GAIM_LIB_PLUGINS_TOP) -f $(GAIM_WIN32_MAKEFILE) install +install_shallow: $(GAIM_INSTALL_DIR) $(TARGET).dll cp $(TARGET).dll $(GAIM_INSTALL_DIR) cp $(NEEDED_DLLS) $(GAIM_INSTALL_DIR) +install: install_shallow all + $(MAKE) -C $(GAIM_PROTOS_TOP) -f $(GAIM_WIN32_MAKEFILE) install + $(MAKE) -C $(GAIM_LIB_PLUGINS_TOP) -f $(GAIM_WIN32_MAKEFILE) install + ./win32/libgaimrc.rc: ./win32/libgaimrc.rc.in $(GAIM_TOP)/VERSION sed -e 's/@GAIM_VERSION@/$(GAIM_VERSION)/g' \ $@.in > $@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <amc...@us...> - 2006-10-08 09:47:28
|
Revision: 17449 http://svn.sourceforge.net/gaim/?rev=17449&view=rev Author: amc_grim Date: 2006-10-08 02:47:23 -0700 (Sun, 08 Oct 2006) Log Message: ----------- Patch from Kevin Stange to allow autogen/configure continue without libnm. Modified Paths: -------------- trunk/configure.ac Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2006-10-08 08:40:09 UTC (rev 17448) +++ trunk/configure.ac 2006-10-08 09:47:23 UTC (rev 17449) @@ -889,9 +889,14 @@ ]) dnl Check for libnm_glib; if we don't have it, oh well + LIBNM_CFLAGS="" + LIBNM_LIBS="" PKG_CHECK_MODULES(LIBNM, libnm_glib, [ AC_DEFINE(HAVE_LIBNM, 1, [Check to see if we have NetworkManager]) + ], + [ + AC_MSG_RESULT(no) ]) AC_SUBST(LIBNM_CFLAGS) AC_SUBST(LIBNM_LIBS) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-10-08 08:40:20
|
Revision: 17448 http://svn.sourceforge.net/gaim/?rev=17448&view=rev Author: seanegan Date: 2006-10-08 01:40:09 -0700 (Sun, 08 Oct 2006) Log Message: ----------- >From Paul Betts, NetworkManager integration. This will smartly disconnect and reconnect accounts according to network availability. Probably needs some more tweaking. Modified Paths: -------------- trunk/COPYRIGHT trunk/configure.ac trunk/gtk/gtkconn.c trunk/libgaim/Makefile.am trunk/libgaim/account.c trunk/libgaim/connection.h trunk/libgaim/network.c trunk/libgaim/network.h Modified: trunk/COPYRIGHT =================================================================== --- trunk/COPYRIGHT 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/COPYRIGHT 2006-10-08 08:40:09 UTC (rev 17448) @@ -22,6 +22,7 @@ Curtis Beattie Dave Bell Igor Belyi +Paul Betts Brian Bernas Jonas Birmé Eric Blade Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/configure.ac 2006-10-08 08:40:09 UTC (rev 17448) @@ -887,6 +887,14 @@ AC_MSG_RESULT(no) enable_dbus=no ]) + +dnl Check for libnm_glib; if we don't have it, oh well + PKG_CHECK_MODULES(LIBNM, libnm_glib, + [ + AC_DEFINE(HAVE_LIBNM, 1, [Check to see if we have NetworkManager]) + ]) + AC_SUBST(LIBNM_CFLAGS) + AC_SUBST(LIBNM_LIBS) fi dnl ####################################################################### Modified: trunk/gtk/gtkconn.c =================================================================== --- trunk/gtk/gtkconn.c 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/gtk/gtkconn.c 2006-10-08 08:40:09 UTC (rev 17448) @@ -101,13 +101,6 @@ } static void -gaim_gtk_connection_notice(GaimConnection *gc, - const char *text) -{ -} - - -static void free_auto_recon(gpointer data) { GaimAutoRecon *info = data; @@ -201,6 +194,32 @@ } } +static void gaim_gtk_connection_network_connected () +{ + GList *list = gaim_accounts_get_all_active(); + while (list) { + GaimAccount *account = (GaimAccount*)list->data; + GaimAutoRecon *info = g_hash_table_lookup(hash, account); + if (info) + free_auto_recon(info); + do_signon(account); + list = list->next; + } +} + +static void gaim_gtk_connection_network_disconnected () +{ + GList *l = gaim_accounts_get_all_active(); + while (l) { + GaimAccount *a = (GaimAccount*)l->data; + gaim_account_disconnect(a); + l = l->next; + } +} + +static void gaim_gtk_connection_notice(GaimConnection *gc, const char *text) +{ } + static GaimConnectionUiOps conn_ui_ops = { gaim_gtk_connection_connect_progress, @@ -208,6 +227,8 @@ gaim_gtk_connection_disconnected, gaim_gtk_connection_notice, gaim_gtk_connection_report_disconnect, + gaim_gtk_connection_network_connected, + gaim_gtk_connection_network_disconnected }; GaimConnectionUiOps * Modified: trunk/libgaim/Makefile.am =================================================================== --- trunk/libgaim/Makefile.am 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/libgaim/Makefile.am 2006-10-08 08:40:09 UTC (rev 17448) @@ -218,6 +218,7 @@ $(DBUS_LIBS) \ $(GLIB_LIBS) \ $(LIBXML_LIBS) \ + $(LIBNM_LIBS) \ $(STATIC_LINK_LIBS) \ $(INTLLIBS) \ -lm @@ -231,4 +232,5 @@ $(GLIB_CFLAGS) \ $(DEBUG_CFLAGS) \ $(DBUS_CFLAGS) \ - $(LIBXML_CFLAGS) + $(LIBXML_CFLAGS) \ + $(LIBNM_CFLAGS) Modified: trunk/libgaim/account.c =================================================================== --- trunk/libgaim/account.c 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/libgaim/account.c 2006-10-08 08:40:09 UTC (rev 17448) @@ -27,6 +27,7 @@ #include "core.h" #include "dbus-maybe.h" #include "debug.h" +#include "network.h" #include "notify.h" #include "pounce.h" #include "prefs.h" @@ -2242,6 +2243,13 @@ GList *l; GaimAccount *account; + /* If we're not connected to the Internet right now, we bail on this */ + if (!gaim_network_is_available()) + { + fprintf(stderr, "Network not connected; skipping reconnect\n"); + return; + } + for (l = gaim_accounts_get_all(); l != NULL; l = l->next) { account = (GaimAccount *)l->data; Modified: trunk/libgaim/connection.h =================================================================== --- trunk/libgaim/connection.h 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/libgaim/connection.h 2006-10-08 08:40:09 UTC (rev 17448) @@ -68,6 +68,8 @@ void (*disconnected)(GaimConnection *gc); void (*notice)(GaimConnection *gc, const char *text); void (*report_disconnect)(GaimConnection *gc, const char *text); + void (*network_connected)(); + void (*network_disconnected)(); } GaimConnectionUiOps; Modified: trunk/libgaim/network.c =================================================================== --- trunk/libgaim/network.c 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/libgaim/network.c 2006-10-08 08:40:09 UTC (rev 17448) @@ -42,6 +42,14 @@ #include "stun.h" #include "upnp.h" +#ifdef HAVE_LIBNM +#include <libnm_glib.h> + +libnm_glib_ctx *nm_context = NULL; +guint nm_callback_idx = 0; + +#endif + struct _GaimNetworkListenData { int listenfd; int socket_type; @@ -51,6 +59,10 @@ gpointer cb_data; }; +#ifdef HAVE_LIBNM +void nm_callback_func(libnm_glib_ctx* ctx, gpointer user_data); +#endif + const unsigned char * gaim_network_ip_atoi(const char *ip) { @@ -360,7 +372,61 @@ return ntohs(addr.sin_port); } +gboolean +gaim_network_is_available(void) +{ +#ifdef HAVE_LIBNM + /* Try NetworkManager first, maybe we'll get lucky */ + int libnm_retval = -1; + + if (nm_context) + { + if ((libnm_retval = libnm_glib_get_network_state(nm_context)) == LIBNM_NO_NETWORK_CONNECTION) + { + gaim_debug_warning("network", "NetworkManager not active or reports no connection (retval = %i)\n", libnm_retval); + return FALSE; + } + if (libnm_retval == LIBNM_ACTIVE_NETWORK_CONNECTION) return TRUE; + } +#endif + return TRUE; +} + +#ifdef HAVE_LIBNM void +nm_callback_func(libnm_glib_ctx* ctx, gpointer user_data) +{ + GList *l; + GaimAccount *account; + static libnm_glib_state prev = LIBNM_NO_DBUS; + libnm_glib_state current; + GaimConnectionUiOps *ui_ops = gaim_connections_get_ui_ops(); + + current = libnm_glib_get_network_state(ctx); + gaim_debug_info("network","Entering nm_callback_func!\n"); + + switch(current) + { + case LIBNM_ACTIVE_NETWORK_CONNECTION: + ui_ops->network_connected(); + prev = current; + break; + case LIBNM_NO_NETWORK_CONNECTION: + if (prev != LIBNM_ACTIVE_NETWORK_CONNECTION) + break; + ui_ops->network_disconnected(); + prev = current; + break; + case LIBNM_NO_DBUS: + case LIBNM_NO_NETWORKMANAGER: + case LIBNM_INVALID_CONTEXT: + default: + break; + } +} +#endif + +void gaim_network_init(void) { gaim_prefs_add_none ("/core/network"); @@ -371,4 +437,24 @@ gaim_prefs_add_int ("/core/network/ports_range_end", 2048); gaim_upnp_discover(NULL, NULL); + +#ifdef HAVE_LIBNM + nm_context = libnm_glib_init(); + if(nm_context) + nm_callback_idx = libnm_glib_register_callback(nm_context, nm_callback_func, NULL, g_main_context_default()); +#endif } + +void +gaim_network_uninit(void) +{ +#ifdef HAVE_LIBNM + /* FIXME: If anyone can think of a more clever way to shut down libnm without + * using a global variable + this function, please do. */ + if(nm_context && nm_callback_idx) + libnm_glib_unregister_callback(nm_context, nm_callback_idx); + + if(nm_context) + libnm_glib_shutdown(nm_context); +#endif +} Modified: trunk/libgaim/network.h =================================================================== --- trunk/libgaim/network.h 2006-10-08 04:31:39 UTC (rev 17447) +++ trunk/libgaim/network.h 2006-10-08 08:40:09 UTC (rev 17448) @@ -188,10 +188,24 @@ unsigned short gaim_network_get_port_from_fd(int fd); /** + * Detects if there is an available Internet connection. Note that this call + * could block for the amount of time specified in inet_detect_timeout, so + * using it in a UI thread may cause uncomfortableness + * + * @return TRUE if the Internet is available + */ +gboolean gaim_network_is_available(void); + +/** * Initializes the network subsystem. */ void gaim_network_init(void); +/** + * Shuts down the network subsystem. + */ +void gaim_network_uninit(void); + /*@}*/ #ifdef __cplusplus This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2006-10-08 04:31:46
|
Revision: 17447 http://svn.sourceforge.net/gaim/?rev=17447&view=rev Author: sadrul Date: 2006-10-07 21:31:39 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Add a "Use" button in the status dialog. This has been sitting here for a while. I can't remember why this was not commited ... seems to work fine. Modified Paths: -------------- trunk/console/gntstatus.c Modified: trunk/console/gntstatus.c =================================================================== --- trunk/console/gntstatus.c 2006-10-08 04:21:20 UTC (rev 17446) +++ trunk/console/gntstatus.c 2006-10-08 04:31:39 UTC (rev 17447) @@ -222,6 +222,25 @@ } static void +use_trans_status_cb(GntWidget *button, EditStatus *edit) +{ + const char *message; + GaimStatusPrimitive prim; + GaimSavedStatus *saved; + + message = gnt_entry_get_text(GNT_ENTRY(edit->message)); + prim = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(edit->type))); + + saved = gaim_savedstatus_find_transient_by_type_and_message(prim, message); + if (saved == NULL) { + saved = gaim_savedstatus_new(NULL, prim); + } + gaim_savedstatus_set_message(saved, message); + gaim_savedstatus_activate(saved); + gnt_widget_destroy(edit->window); +} + +static void save_savedstatus_cb(GntWidget *button, EditStatus *edit) { const char *title, *message; @@ -508,6 +527,11 @@ box = gnt_hbox_new(FALSE); gnt_box_add_widget(GNT_BOX(window), box); + /* Use */ + button = gnt_button_new(_("Use")); + gnt_box_add_widget(GNT_BOX(box), button); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(use_trans_status_cb), edit); + /* Save */ button = gnt_button_new(_("Save")); gnt_box_add_widget(GNT_BOX(box), button); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2006-10-08 04:21:24
|
Revision: 17446 http://svn.sourceforge.net/gaim/?rev=17446&view=rev Author: sadrul Date: 2006-10-07 21:21:20 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Patch #1571853 from Richard Nelson (wabz): "This patch removes the contact and all buddies when removing a contact, rather than just removing it from the blist (and having all the buddies show up next time gaim-text is opened)" Modified Paths: -------------- trunk/console/gntblist.c Modified: trunk/console/gntblist.c =================================================================== --- trunk/console/gntblist.c 2006-10-08 03:56:06 UTC (rev 17445) +++ trunk/console/gntblist.c 2006-10-08 04:21:20 UTC (rev 17446) @@ -31,6 +31,7 @@ #include <signal.h> #include <status.h> #include <util.h> +#include "debug.h" #include "gntgaim.h" #include "gntbox.h" @@ -56,6 +57,7 @@ GntWidget *tooltip; GaimBlistNode *tnode; /* Who is the tooltip being displayed for? */ + GaimBuddy *tagged; GntWidget *context; GaimBlistNode *cnode; @@ -340,7 +342,7 @@ field = gaim_request_field_string_new("alias", _("Alias"), alias, FALSE); gaim_request_field_group_add_field(group, field); - field = gaim_request_field_string_new("group", _("Group"), grp->name, FALSE); + field = gaim_request_field_string_new("group", _("Group"), grp ? grp->name : NULL, FALSE); gaim_request_field_group_add_field(group, field); gaim_request_fields(NULL, _("Add Chat"), NULL, @@ -719,7 +721,7 @@ static void gg_add_buddy(GaimGroup *grp, GaimBlistNode *selected) { - gaim_blist_request_add_buddy(NULL, NULL, grp->name, NULL); + gaim_blist_request_add_buddy(NULL, NULL, grp ? grp->name : NULL, NULL); } static void @@ -816,7 +818,24 @@ remove_context_menu(ggblist); } +/* Xerox'd from gtkdialogs.c:gaim_gtkdialogs_remove_contact_cb */ static void +remove_contact(GaimContact *contact) +{ + GaimBlistNode *bnode, *cnode; + GaimGroup *group; + + cnode = (GaimBlistNode *)contact; + group = (GaimGroup*)cnode->parent; + for (bnode = cnode->child; bnode; bnode = bnode->next) { + GaimBuddy *buddy = (GaimBuddy*)bnode; + if (gaim_account_is_connected(buddy->account)) + gaim_account_remove_buddy(buddy->account, buddy, group); + } + gaim_blist_remove_contact(contact); +} + +static void rename_blist_node(GaimBlistNode *node, const char *newname) { const char *name = newname; @@ -908,7 +927,7 @@ gg_blist_remove_node(GaimBlistNode *node) { if (GAIM_BLIST_NODE_IS_CONTACT(node)) { - gaim_blist_remove_contact((GaimContact*)node); + remove_contact((GaimContact*)node); } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { GaimBuddy *buddy = (GaimBuddy*)node; GaimGroup *group = gaim_buddy_get_group(buddy); @@ -928,9 +947,12 @@ const char *name, *sec = NULL; /* XXX: could be a contact */ - if (GAIM_BLIST_NODE_IS_CONTACT(node)) - name = gaim_contact_get_alias((GaimContact*)node); - else if (GAIM_BLIST_NODE_IS_BUDDY(node)) + if (GAIM_BLIST_NODE_IS_CONTACT(node)) { + GaimContact *c = (GaimContact*)node; + name = gaim_contact_get_alias(c); + if (c->totalsize > 1) + sec = _("Removing this contact will also remove all the buddies in the contact"); + } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) name = gaim_buddy_get_name((GaimBuddy*)node); else if (GAIM_BLIST_NODE_IS_CHAT(node)) name = gaim_chat_get_name((GaimChat*)node); @@ -954,6 +976,27 @@ } static void +gg_blist_tag_buddy(GaimBlistNode *node) +{ + ggblist->tagged = (GaimBuddy *)node; + gaim_debug_info("blist", "Tagged buddy\n"); +} + +static void +gg_blist_place_tagged(GaimBlistNode *node) +{ + if (GAIM_BLIST_NODE_IS_GROUP(node)) { + gaim_blist_add_buddy(ggblist->tagged, NULL, (GaimGroup *)node, NULL); + } else { + GaimContact *contact = (GaimContact *)node; + gaim_blist_add_buddy(ggblist->tagged, contact, + gaim_buddy_get_group(gaim_contact_get_priority_buddy(contact)), NULL); + } + ggblist->tagged = NULL; + gaim_debug_info("blist", "Placed buddy\n"); +} + +static void draw_context_menu(GGBlist *ggblist) { GaimBlistNode *node = NULL; @@ -971,8 +1014,6 @@ node = gnt_tree_get_selection_data(tree); - if (node == NULL) - return; if (ggblist->tooltip) remove_tooltip(ggblist); @@ -982,7 +1023,10 @@ gnt_widget_set_name(context, "context menu"); g_signal_connect(G_OBJECT(context), "activate", G_CALLBACK(context_menu_callback), ggblist); - if (GAIM_BLIST_NODE_IS_CONTACT(node)) { + if (!node) { + create_group_menu(GNT_TREE(context), NULL); + title = g_strdup(_("Buddy List")); + } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { create_buddy_menu(GNT_TREE(context), gaim_contact_get_priority_buddy((GaimContact*)node)); title = g_strdup(gaim_contact_get_alias((GaimContact*)node)); @@ -1003,10 +1047,20 @@ append_extended_menu(GNT_TREE(context), node); /* These are common for everything */ - add_custom_action(GNT_TREE(context), _("Rename"), - GAIM_CALLBACK(gg_blist_rename_node_cb), node); - add_custom_action(GNT_TREE(context), _("Remove"), - GAIM_CALLBACK(gg_blist_remove_node_cb), node); + if (node) { + add_custom_action(GNT_TREE(context), _("Rename"), + GAIM_CALLBACK(gg_blist_rename_node_cb), node); + add_custom_action(GNT_TREE(context), _("Remove"), + GAIM_CALLBACK(gg_blist_remove_node_cb), node); + if (ggblist->tagged && (GAIM_BLIST_NODE_IS_CONTACT(node) + || GAIM_BLIST_NODE_IS_GROUP(node))) { + add_custom_action(GNT_TREE(context), _("Place tagged"), + GAIM_CALLBACK(gg_blist_place_tagged), node); + } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { + add_custom_action(GNT_TREE(context), _("Tag"), + GAIM_CALLBACK(gg_blist_tag_buddy), node); + } + } window = gnt_vbox_new(FALSE); GNT_WIDGET_SET_FLAGS(window, GNT_WIDGET_TRANSIENT); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2006-10-08 03:56:11
|
Revision: 17445 http://svn.sourceforge.net/gaim/?rev=17445&view=rev Author: sadrul Date: 2006-10-07 20:56:06 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Patch #1569730 from Richard Nelson (wabz): "This patch adds a "Clear" button, timestamp and pause options, and stops it scrolling down if it's scrolled up." and "Also gives the debug window a name, so window managers can more easily have their way with it." These changes make the debug window a whole lot more usable. Modified Paths: -------------- trunk/console/gntdebug.c trunk/console/libgnt/gntcheckbox.c Modified: trunk/console/gntdebug.c =================================================================== --- trunk/console/gntdebug.c 2006-10-07 18:19:17 UTC (rev 17444) +++ trunk/console/gntdebug.c 2006-10-08 03:56:06 UTC (rev 17445) @@ -25,9 +25,13 @@ #include <gnt.h> #include <gntbox.h> #include <gnttextview.h> +#include <gntbutton.h> +#include <gntcheckbox.h> +#include <gntline.h> #include "gntdebug.h" #include "gntgaim.h" +#include "util.h" #include <stdio.h> #include <string.h> @@ -36,6 +40,8 @@ { GntWidget *window; GntWidget *tview; + gboolean paused; + gboolean timestamps; } debug; static gboolean @@ -62,15 +68,24 @@ gg_debug_print(GaimDebugLevel level, const char *category, const char *args) { - if (debug.window) + if (debug.window && !debug.paused) { + int pos = gnt_text_view_get_lines_below(GNT_TEXT_VIEW(debug.tview)); GntTextFormatFlags flag = GNT_TEXT_FLAG_NORMAL; + if (debug.timestamps) { + const char *mdate; + time_t mtime = time(NULL); + mdate = gaim_utf8_strftime("%H:%M:%S ", localtime(&mtime)); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), + mdate, flag); + } + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), category, GNT_TEXT_FLAG_BOLD); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), ": ", GNT_TEXT_FLAG_BOLD); - + switch (level) { case GAIM_DEBUG_WARNING: @@ -82,13 +97,14 @@ default: break; } - + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), args, flag); - gnt_text_view_scroll(GNT_TEXT_VIEW(debug.tview), 0); + if (pos <= 1) + gnt_text_view_scroll(GNT_TEXT_VIEW(debug.tview), 0); } } -static GaimDebugUiOps uiops = +static GaimDebugUiOps uiops = { gg_debug_print, }; @@ -105,24 +121,76 @@ } static void +clear_debug_win(GntWidget *w, GntTextView *tv) +{ + gnt_text_view_clear(tv); +} + +static void print_stderr(const char *string) { g_printerr("%s", string); } +static void +toggle_pause(GntWidget *w, gpointer n) +{ + debug.paused = !debug.paused; +} + +static void +toggle_timestamps(GntWidget *w, gpointer n) +{ + debug.timestamps = !debug.timestamps; + gaim_prefs_set_bool("/core/debug/timestamps", debug.timestamps); +} + void gg_debug_window_show() { + debug.paused = false; + debug.timestamps = gaim_prefs_get_bool("/core/debug/timestamps"); if (debug.window == NULL) { + GntWidget *wid, *box; debug.window = gnt_vbox_new(FALSE); gnt_box_set_toplevel(GNT_BOX(debug.window), TRUE); gnt_box_set_title(GNT_BOX(debug.window), _("Debug Window")); + gnt_box_set_pad(GNT_BOX(debug.window), 0); + gnt_box_set_alignment(GNT_BOX(debug.window), GNT_ALIGN_MID); debug.tview = gnt_text_view_new(); gnt_box_add_widget(GNT_BOX(debug.window), debug.tview); - /* XXX: Add checkboxes/buttons for Clear, Pause, Timestamps */ + gnt_box_add_widget(GNT_BOX(debug.window), gnt_line_new(FALSE)); + box = gnt_hbox_new(FALSE); + gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID); + + /* XXX: Setting the GROW_Y for the following widgets don't make sense. But right now + * it's necessary to make the width of the debug window resizable ... like I said, + * it doesn't make sense. The bug is likely in the packing in gntbox.c. + */ + wid = gnt_button_new(_("Clear")); + g_signal_connect(G_OBJECT(wid), "activate", G_CALLBACK(clear_debug_win), debug.tview); + GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y); + gnt_box_add_widget(GNT_BOX(box), wid); + + wid = gnt_check_box_new(_("Pause")); + g_signal_connect(G_OBJECT(wid), "toggled", G_CALLBACK(toggle_pause), NULL); + GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y); + gnt_box_add_widget(GNT_BOX(box), wid); + + wid = gnt_check_box_new(_("Timestamps")); + gnt_check_box_set_checked(GNT_CHECK_BOX(wid), debug.timestamps); + g_signal_connect(G_OBJECT(wid), "toggled", G_CALLBACK(toggle_timestamps), NULL); + GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y); + gnt_box_add_widget(GNT_BOX(box), wid); + + gnt_box_add_widget(GNT_BOX(debug.window), box); + GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_GROW_Y); + + gnt_widget_set_name(debug.window, "debug-window"); + g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL); g_signal_connect(G_OBJECT(debug.window), "key_pressed", G_CALLBACK(debug_window_kpress_cb), debug.tview); } Modified: trunk/console/libgnt/gntcheckbox.c =================================================================== --- trunk/console/libgnt/gntcheckbox.c 2006-10-07 18:19:17 UTC (rev 17444) +++ trunk/console/libgnt/gntcheckbox.c 2006-10-08 03:56:06 UTC (rev 17445) @@ -108,7 +108,10 @@ static void gnt_check_box_init(GTypeInstance *instance, gpointer class) { - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + GntWidget *widget = GNT_WIDGET(instance); + widget->priv.minh = 1; + widget->priv.minw = 4; + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); GNTDEBUG; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-10-07 18:19:24
|
Revision: 17444 http://svn.sourceforge.net/gaim/?rev=17444&view=rev Author: thekingant Date: 2006-10-07 11:19:17 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Patch from launchpad bug #64445, from Paul Schulz Fix some typos Modified Paths: -------------- trunk/doc/PERL-HOWTO.dox trunk/gtk/plugins/musicmessaging/musicmessaging.c trunk/libgaim/protocols/gg/gg.c trunk/libgaim/protocols/sametime/sametime.c Modified: trunk/doc/PERL-HOWTO.dox =================================================================== --- trunk/doc/PERL-HOWTO.dox 2006-10-07 17:25:21 UTC (rev 17443) +++ trunk/doc/PERL-HOWTO.dox 2006-10-07 18:19:17 UTC (rev 17444) @@ -518,7 +518,7 @@ @code sub timeout_cb { my $plugin = shift; - print "Timeout occured."; + print "Timeout occurred."; # Reschedule timeout Gaim::timeout_add($plugin, 10, \&timeout_cb, $plugin); Modified: trunk/gtk/plugins/musicmessaging/musicmessaging.c =================================================================== --- trunk/gtk/plugins/musicmessaging/musicmessaging.c 2006-10-07 17:25:21 UTC (rev 17443) +++ trunk/gtk/plugins/musicmessaging/musicmessaging.c 2006-10-07 18:19:17 UTC (rev 17444) @@ -523,7 +523,7 @@ if (!(g_spawn_async (".", args, NULL, 4, NULL, NULL, &(mmconv->pid), &spawn_error))) { gaim_notify_error(plugin_pointer, _("Error Running Editor"), - _("The following error has occured:"), spawn_error->message); + _("The following error has occurred:"), spawn_error->message); mmconv->started = FALSE; } else Modified: trunk/libgaim/protocols/gg/gg.c =================================================================== --- trunk/libgaim/protocols/gg/gg.c 2006-10-07 17:25:21 UTC (rev 17443) +++ trunk/libgaim/protocols/gg/gg.c 2006-10-07 18:19:17 UTC (rev 17444) @@ -713,7 +713,7 @@ if (h == NULL) { gaim_notify_error(account, NULL, - _("Unable to change password. Error occured.\n"), + _("Unable to change password. Error occurred.\n"), NULL); goto exit_err; } Modified: trunk/libgaim/protocols/sametime/sametime.c =================================================================== --- trunk/libgaim/protocols/sametime/sametime.c 2006-10-07 17:25:21 UTC (rev 17443) +++ trunk/libgaim/protocols/sametime/sametime.c 2006-10-07 18:19:17 UTC (rev 17444) @@ -1638,7 +1638,7 @@ /* fetch the global error value */ err = errno; - /* read problem occured if we're here, so we'll need to take care of + /* read problem occurred if we're here, so we'll need to take care of it and clean up internal state */ if(pd->socket) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nos...@us...> - 2006-10-07 17:25:28
|
Revision: 17443 http://svn.sourceforge.net/gaim/?rev=17443&view=rev Author: nosnilmot Date: 2006-10-07 10:25:21 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Fix Coverity CID 279 - Variable "name" tracked as NULL was passed to a function that dereferences it. Groups can't be renamed to NULL anyway. Modified Paths: -------------- trunk/console/gntblist.c Modified: trunk/console/gntblist.c =================================================================== --- trunk/console/gntblist.c 2006-10-07 17:21:31 UTC (rev 17442) +++ trunk/console/gntblist.c 2006-10-07 17:25:21 UTC (rev 17443) @@ -315,6 +315,7 @@ gaim_blist_add_group(grp, NULL); } gaim_blist_add_chat(chat, grp, NULL); + gaim_blist_alias_chat(chat, alias); } } @@ -833,7 +834,7 @@ serv_alias_buddy((GaimBuddy*)node); } else if (GAIM_BLIST_NODE_IS_CHAT(node)) gaim_blist_alias_chat((GaimChat*)node, name); - else if (GAIM_BLIST_NODE_IS_GROUP(node)) + else if (GAIM_BLIST_NODE_IS_GROUP(node) && (name != NULL)) gaim_blist_rename_group((GaimGroup*)node, name); else g_return_if_reached(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nos...@us...> - 2006-10-07 17:21:35
|
Revision: 17442 http://svn.sourceforge.net/gaim/?rev=17442&view=rev Author: nosnilmot Date: 2006-10-07 10:21:31 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Fix Coverity CID 276 - variable "list" tracked as NULL was dereferenced. Modified Paths: -------------- trunk/console/gntrequest.c Modified: trunk/console/gntrequest.c =================================================================== --- trunk/console/gntrequest.c 2006-10-07 17:15:58 UTC (rev 17441) +++ trunk/console/gntrequest.c 2006-10-07 17:21:31 UTC (rev 17442) @@ -286,7 +286,7 @@ iter = gaim_request_field_list_get_items(field); for (; iter; iter = iter->next) { - const char *text = list->data; + const char *text = iter->data; gpointer key = gaim_request_field_list_get_data(field, text); if (gnt_tree_get_choice(GNT_TREE(tree), key)) list = g_list_prepend(list, key); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nos...@us...> - 2006-10-07 17:16:10
|
Revision: 17441 http://svn.sourceforge.net/gaim/?rev=17441&view=rev Author: nosnilmot Date: 2006-10-07 10:15:58 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Fix Coverity CID 115 - "last_updated_utf8_string" may be NULL Modified Paths: -------------- trunk/libgaim/protocols/yahoo/yahoo_profile.c Modified: trunk/libgaim/protocols/yahoo/yahoo_profile.c =================================================================== --- trunk/libgaim/protocols/yahoo/yahoo_profile.c 2006-10-07 17:09:14 UTC (rev 17440) +++ trunk/libgaim/protocols/yahoo/yahoo_profile.c 2006-10-07 17:15:58 UTC (rev 17441) @@ -1167,15 +1167,17 @@ } } - /* see if Member Since is there, and if so, extract it. */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, - "Member Since:", 1, last_updated_utf8_string, - '\n', NULL, _("Member Since"), 0, NULL, yahoo_info_date_reformat); + if (last_updated_utf8_string != NULL) { + /* see if Member Since is there, and if so, extract it. */ + found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + "Member Since:", 1, last_updated_utf8_string, + '\n', NULL, _("Member Since"), 0, NULL, yahoo_info_date_reformat); - /* extract the Last Updated date and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, - last_updated_utf8_string, 1, " ", '\n', NULL, - _("Last Update"), 0, NULL, yahoo_info_date_reformat); + /* extract the Last Updated date and put it in */ + found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + last_updated_utf8_string, 1, " ", '\n', NULL, + _("Last Update"), 0, NULL, yahoo_info_date_reformat); + } } /* if (profile_state == PROFILE_STATE_DEFAULT) */ if(!found) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nos...@us...> - 2006-10-07 17:09:22
|
Revision: 17440 http://svn.sourceforge.net/gaim/?rev=17440&view=rev Author: nosnilmot Date: 2006-10-07 10:09:14 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Fix Coverity CID 291 - don't dereference conv before the NULL check Modified Paths: -------------- trunk/console/gntconv.c Modified: trunk/console/gntconv.c =================================================================== --- trunk/console/gntconv.c 2006-10-07 17:05:27 UTC (rev 17439) +++ trunk/console/gntconv.c 2006-10-07 17:09:14 UTC (rev 17440) @@ -234,11 +234,12 @@ char *title, *old_title; conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, account); - im = GAIM_CONV_IM(conv); if (!conv) return; + im = GAIM_CONV_IM(conv); + if (gaim_conv_im_get_typing_state(im) == GAIM_TYPING) { old_title = get_conversation_title(conv, account); title = g_strdup_printf(_("%s [%s]"), old_title, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nos...@us...> - 2006-10-07 17:05:35
|
Revision: 17439 http://svn.sourceforge.net/gaim/?rev=17439&view=rev Author: nosnilmot Date: 2006-10-07 10:05:27 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Fix Coverity CID 219 - don't pass NULL to strcmp Modified Paths: -------------- trunk/libgaim/protocols/silc/ops.c Modified: trunk/libgaim/protocols/silc/ops.c =================================================================== --- trunk/libgaim/protocols/silc/ops.c 2006-10-07 17:03:26 UTC (rev 17438) +++ trunk/libgaim/protocols/silc/ops.c 2006-10-07 17:05:27 UTC (rev 17439) @@ -890,8 +890,9 @@ if (b->account != gc->account) continue; f = gaim_blist_node_get_string(bnode, "public-key"); - if (!strcmp(f, buf)) + if (f && !strcmp(f, buf)) goto cont; + b = NULL; } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nos...@us...> - 2006-10-07 17:03:41
|
Revision: 17438 http://svn.sourceforge.net/gaim/?rev=17438&view=rev Author: nosnilmot Date: 2006-10-07 10:03:26 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Fix Coverity CID 144 - return value of "get_iter_from_node" should be checked Modified Paths: -------------- trunk/gtk/gtkblist.c Modified: trunk/gtk/gtkblist.c =================================================================== --- trunk/gtk/gtkblist.c 2006-10-07 17:01:58 UTC (rev 17437) +++ trunk/gtk/gtkblist.c 2006-10-07 17:03:26 UTC (rev 17438) @@ -907,8 +907,6 @@ GaimBlistNode *bnode; GtkTreePath *path; - struct _expand *ex = g_new0(struct _expand, 1); - if(!GAIM_BLIST_NODE_IS_CONTACT(node)) return; @@ -921,16 +919,19 @@ } /* This ensures that the bottom buddy is visible, i.e. not scrolled off the alignment */ - get_iter_from_node(node, &parent); - gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter, &parent, - gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &parent) -1); - path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); + if (get_iter_from_node(node, &parent)) { + struct _expand *ex = g_new0(struct _expand, 1); - /* Let the treeview draw so it knows where to scroll */ - ex->treeview = GTK_TREE_VIEW(gtkblist->treeview); - ex->path = path; - ex->node = node->child; - g_idle_add(scroll_to_expanded_cell, ex); + gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter, &parent, + gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &parent) -1); + path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); + + /* Let the treeview draw so it knows where to scroll */ + ex->treeview = GTK_TREE_VIEW(gtkblist->treeview); + ex->path = path; + ex->node = node->child; + g_idle_add(scroll_to_expanded_cell, ex); + } } static void This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nos...@us...> - 2006-10-07 17:02:19
|
Revision: 17437 http://svn.sourceforge.net/gaim/?rev=17437&view=rev Author: nosnilmot Date: 2006-10-07 10:01:58 -0700 (Sat, 07 Oct 2006) Log Message: ----------- Fix Coverity CIDs 141 & 142 - the return value of gtk_tree_selection_get_selected() should be checked to ensure something is selected. I also sensitized/desensitized the buttons as appropriate, which probably renders the return checking redundant, but I'm playing safe. Modified Paths: -------------- trunk/gtk/plugins/gevolution/add_buddy_dialog.c trunk/gtk/plugins/gevolution/assoc-buddy.c Modified: trunk/gtk/plugins/gevolution/add_buddy_dialog.c =================================================================== --- trunk/gtk/plugins/gevolution/add_buddy_dialog.c 2006-10-06 18:25:18 UTC (rev 17436) +++ trunk/gtk/plugins/gevolution/add_buddy_dialog.c 2006-10-07 17:01:58 UTC (rev 17437) @@ -95,7 +95,8 @@ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); - gtk_tree_selection_get_selected(selection, NULL, &iter); + if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) + return; gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, COLUMN_NAME, &fullname, @@ -343,7 +344,11 @@ static void selected_cb(GtkTreeSelection *sel, GevoAddBuddyDialog *dialog) { - gtk_widget_set_sensitive(dialog->select_button, TRUE); + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); + gtk_widget_set_sensitive(dialog->select_button, + gtk_tree_selection_get_selected(selection, NULL, NULL)); } static void Modified: trunk/gtk/plugins/gevolution/assoc-buddy.c =================================================================== --- trunk/gtk/plugins/gevolution/assoc-buddy.c 2006-10-06 18:25:18 UTC (rev 17436) +++ trunk/gtk/plugins/gevolution/assoc-buddy.c 2006-10-07 17:01:58 UTC (rev 17437) @@ -105,7 +105,11 @@ static void selected_cb(GtkTreeSelection *sel, GevoAssociateBuddyDialog *dialog) { - gtk_widget_set_sensitive(dialog->assoc_button, TRUE); + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); + gtk_widget_set_sensitive(dialog->assoc_button, + gtk_tree_selection_get_selected(selection, NULL, NULL)); } static void @@ -276,7 +280,8 @@ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); - gtk_tree_selection_get_selected(selection, NULL, &iter); + if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) + return; gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, COLUMN_NAME, &fullname, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lsc...@us...> - 2006-10-06 18:25:24
|
Revision: 17436 http://svn.sourceforge.net/gaim/?rev=17436&view=rev Author: lschiere Date: 2006-10-06 11:25:18 -0700 (Fri, 06 Oct 2006) Log Message: ----------- I considered preserving the long version, but this will do. Modified Paths: -------------- trunk/doc/gaims_funniest_home_convos.txt Modified: trunk/doc/gaims_funniest_home_convos.txt =================================================================== --- trunk/doc/gaims_funniest_home_convos.txt 2006-10-06 05:03:28 UTC (rev 17435) +++ trunk/doc/gaims_funniest_home_convos.txt 2006-10-06 18:25:18 UTC (rev 17436) @@ -397,3 +397,22 @@ (17:49:25) seanegan: hell yeah! (17:49:25) elb: awesome, thanks (17:49:28) elb: Kanon in D + +edited for brevity, and name changed. +(13:51:31) l33t_h4x0r: Is there such thing as a gaim ip sniffer for linux? +(13:51:40) LSchiere: no +(13:51:46) l33t_h4x0r: You sure? +(13:51:50) LSchiere: though if there were, I'd still say no +(13:51:55) l33t_h4x0r: Why? +(13:52:00) LSchiere: since there's no good reason to be looking for one +(13:55:12) l33t_h4x0r: Is...this a sensitive subject? +(13:55:29) seanegan: l33t_h4x0r: not as sensitive as someone's IP address, apparently. +(13:55:31) Err: no, "needing" to know what someone's IP is without asking them is totally sane, rational, and socially normal +(13:55:42) l33t_h4x0r: I want to use it for destruive purposes? +(13:55:50) l33t_h4x0r: Morally wrong. +(13:56:01) l33t_h4x0r: I'll admit, but a valid reason. +(13:57:04) l33t_h4x0r: Asking someone would give away my position... +(13:57:33) l33t_h4x0r: Arlight, nevermind. +(13:57:36) l33t_h4x0r left the room ("Leaving"). +(13:58:58) LSchiere: *amused* that's the first time in a while that the requester has *agreed* that there is no legit reason to want the feature +(13:59:19) Err: he was not the sharpest knife in the drawer This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dat...@us...> - 2006-10-06 05:03:49
|
Revision: 17435 http://svn.sourceforge.net/gaim/?rev=17435&view=rev Author: datallah Date: 2006-10-05 22:03:28 -0700 (Thu, 05 Oct 2006) Log Message: ----------- Fix the docklet on wingaim. What is the plan for the docklet prefs? Modified Paths: -------------- trunk/gaim-installer.nsi trunk/gtk/Makefile.am trunk/gtk/Makefile.mingw trunk/gtk/gtkdocklet.c trunk/gtk/gtkdocklet.h trunk/gtk/plugins/Makefile.mingw Added Paths: ----------- trunk/gtk/win32/gtkdocklet-win32.c Removed Paths: ------------- trunk/gtk/gtkdocklet-win32.c trunk/gtk/plugins/docklet/MinimizeToTray.c trunk/gtk/plugins/docklet/MinimizeToTray.h Modified: trunk/gaim-installer.nsi =================================================================== --- trunk/gaim-installer.nsi 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gaim-installer.nsi 2006-10-06 05:03:28 UTC (rev 17435) @@ -698,7 +698,6 @@ RMDir /r "$INSTDIR\locale" RMDir /r "$INSTDIR\pixmaps" RMDir /r "$INSTDIR\perlmod" - Delete "$INSTDIR\plugins\docklet.dll" Delete "$INSTDIR\plugins\extplacement.dll" Delete "$INSTDIR\plugins\gaimrc.dll" Delete "$INSTDIR\plugins\history.dll" Modified: trunk/gtk/Makefile.am =================================================================== --- trunk/gtk/Makefile.am 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/Makefile.am 2006-10-06 05:03:28 UTC (rev 17435) @@ -6,7 +6,10 @@ win32/IdleTracker/Makefile.mingw \ win32/IdleTracker/idletrack.c \ win32/IdleTracker/idletrack.h \ + win32/MinimizeToTray.h \ + win32/MinimizeToTray.c \ win32/gaimrc.rc.in \ + win32/gtkdocklet-win32.c \ win32/gtkgaimrc.rc.in \ win32/gtkwin32dep.c \ win32/gtkwin32dep.h \ Modified: trunk/gtk/Makefile.mingw =================================================================== --- trunk/gtk/Makefile.mingw 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/Makefile.mingw 2006-10-06 05:03:28 UTC (rev 17435) @@ -65,6 +65,7 @@ gtkdebug.c \ gtkdialogs.c \ gtkdnd-hints.c \ + gtkdocklet.c \ gtkeventloop.c \ gtkexpander.c \ gtkft.c \ @@ -89,6 +90,8 @@ gtkthemes.c \ gtkutils.c \ gtkwhiteboard.c \ + win32/MinimizeToTray.c \ + win32/gtkdocklet-win32.c \ win32/gtkwin32dep.c \ win32/untar.c \ win32/wspell.c @@ -129,7 +132,7 @@ ## ## TARGET DEFINITIONS ## -.PHONY: all install clean clean_exe +.PHONY: all install install_shallow clean clean_exe all: $(EXE_TARGET).exe $(GTKGAIM_TARGET).dll $(MAKE) -C $(GAIM_GTK_PLUGINS_TOP) -f $(GAIM_WIN32_MAKEFILE) @@ -139,13 +142,15 @@ -e 's/@ORIGINAL_FILENAME@/$(EXE_NAME)/' \ $@.in > $@ -install: all $(GAIM_INSTALL_DIR) +install_shallow: $(GAIM_INSTALL_DIR) $(EXE_TARGET).exe $(GTKGAIM_TARGET).dll + cp $(EXE_TARGET).exe $(GTKGAIM_TARGET).dll $(GAIM_INSTALL_DIR) + cp $(NEEDED_DLLS) $(GAIM_INSTALL_DIR) + +install: install_shallow all $(MAKE) -C $(GAIM_GTK_PLUGINS_TOP) -f $(GAIM_WIN32_MAKEFILE) install $(MAKE) -C $(GAIM_GTK_PIXMAPS_TOP) -f $(GAIM_WIN32_MAKEFILE) install $(MAKE) -C $(GAIM_GTK_SOUNDS_TOP) -f $(GAIM_WIN32_MAKEFILE) install $(MAKE) -C $(GAIM_GTK_IDLETRACK_TOP) -f $(GAIM_WIN32_MAKEFILE) install - cp $(EXE_TARGET).exe $(GTKGAIM_TARGET).dll $(GAIM_INSTALL_DIR) - cp $(NEEDED_DLLS) $(GAIM_INSTALL_DIR) ./win32/gtkgaimrc.rc: ./win32/gtkgaimrc.rc.in $(GAIM_TOP)/VERSION sed -e 's/@GAIM_VERSION@/$(GAIM_VERSION)/g' \ Deleted: trunk/gtk/gtkdocklet-win32.c =================================================================== --- trunk/gtk/gtkdocklet-win32.c 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/gtkdocklet-win32.c 2006-10-06 05:03:28 UTC (rev 17435) @@ -1,263 +0,0 @@ -/* - * System tray icon (aka docklet) plugin for Gaim - * - * Copyright (C) 2002-3 Robert McQueen <rob...@de...> - * Copyright (C) 2003 Herman Bloggs <her...@ya...> - * Inspired by a similar plugin by: - * John (J5) Palmieri <jo...@ma...> - * - * 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., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include <windows.h> -#include <gdk/gdkwin32.h> -#include <gdk/gdk.h> - -#include "internal.h" -#include "gtkblist.h" -#include "gtkprefs.h" -#include "debug.h" - -#include "gaim.h" -#include "gtkdialogs.h" - -#include "resource.h" -#include "MinimizeToTray.h" -#include "gtkwin32dep.h" -#include "docklet.h" - -/* - * DEFINES, MACROS & DATA TYPES - */ -#define WM_TRAYMESSAGE WM_USER /* User defined WM Message */ - -/* - * LOCALS - */ -static HWND systray_hwnd=0; -static HICON sysicon_disconn=0; -static HICON sysicon_conn=0; -static HICON sysicon_away=0; -static HICON sysicon_pend=0; -static HICON sysicon_awypend=0; -static HICON sysicon_blank=0; -static NOTIFYICONDATA wgaim_nid; - - -static LRESULT CALLBACK systray_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - static UINT taskbarRestartMsg; /* static here means value is kept across multiple calls to this func */ - - switch(msg) { - case WM_CREATE: - gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_CREATE\n"); - taskbarRestartMsg = RegisterWindowMessage("TaskbarCreated"); - break; - - case WM_TIMER: - gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_TIMER\n"); - break; - - case WM_DESTROY: - gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_DESTROY\n"); - break; - - case WM_TRAYMESSAGE: - { - int type = 0; - - /* We'll use Double Click - Single click over on linux */ - if( lparam == WM_LBUTTONDBLCLK ) - type = 1; - else if( lparam == WM_MBUTTONUP ) - type = 2; - else if( lparam == WM_RBUTTONUP ) - type = 3; - else - break; - - docklet_clicked(type); - break; - } - default: - if (msg == taskbarRestartMsg) { - /* explorer crashed and left us hanging... - This will put the systray icon back in it's place, when it restarts */ - Shell_NotifyIcon(NIM_ADD,&wgaim_nid); - } - break; - }/* end switch */ - - return DefWindowProc(hwnd, msg, wparam, lparam); -} - -/* Create hidden window to process systray messages */ -static HWND systray_create_hiddenwin() { - WNDCLASSEX wcex; - TCHAR wname[32]; - - strcpy(wname, "GaimWin"); - - wcex.cbSize = sizeof(WNDCLASSEX); - - wcex.style = 0; - wcex.lpfnWndProc = (WNDPROC)systray_mainmsg_handler; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = gtkwgaim_hinstance(); - wcex.hIcon = NULL; - wcex.hCursor = NULL, - wcex.hbrBackground = NULL; - wcex.lpszMenuName = NULL; - wcex.lpszClassName = wname; - wcex.hIconSm = NULL; - - RegisterClassEx(&wcex); - - /* Create the window */ - return (CreateWindow(wname, "", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, gtkwgaim_hinstance(), 0)); -} - -static void systray_init_icon(HWND hWnd, HICON icon) { - ZeroMemory(&wgaim_nid,sizeof(wgaim_nid)); - wgaim_nid.cbSize=sizeof(NOTIFYICONDATA); - wgaim_nid.hWnd=hWnd; - wgaim_nid.uID=0; - wgaim_nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP; - wgaim_nid.uCallbackMessage=WM_TRAYMESSAGE; - wgaim_nid.hIcon=icon; - lstrcpy(wgaim_nid.szTip, "Gaim"); - Shell_NotifyIcon(NIM_ADD,&wgaim_nid); - docklet_embedded(); -} - -static void systray_change_icon(HICON icon) { - wgaim_nid.hIcon = icon; - Shell_NotifyIcon(NIM_MODIFY,&wgaim_nid); -} - -static void systray_remove_nid(void) { - Shell_NotifyIcon(NIM_DELETE,&wgaim_nid); -} - -static void wgaim_tray_update_icon(DockletStatus icon) { - switch (icon) { - case DOCKLET_STATUS_OFFLINE: - systray_change_icon(sysicon_disconn); - break; - case DOCKLET_STATUS_CONNECTING: - break; - case DOCKLET_STATUS_ONLINE: - systray_change_icon(sysicon_conn); - break; - case DOCKLET_STATUS_ONLINE_PENDING: - systray_change_icon(sysicon_pend); - break; - case DOCKLET_STATUS_AWAY: - systray_change_icon(sysicon_away); - break; - case DOCKLET_STATUS_AWAY_PENDING: - systray_change_icon(sysicon_awypend); - break; - } -} - -static void wgaim_tray_blank_icon() { - systray_change_icon(sysicon_blank); -} - -static void wgaim_tray_set_tooltip(gchar *tooltip) { - if (tooltip) { - char *locenc = NULL; - locenc = g_locale_from_utf8(tooltip, -1, NULL, NULL, NULL); - lstrcpyn(wgaim_nid.szTip, locenc, sizeof(wgaim_nid.szTip)/sizeof(TCHAR)); - g_free(locenc); - } else { - lstrcpy(wgaim_nid.szTip, "Gaim"); - } - Shell_NotifyIcon(NIM_MODIFY, &wgaim_nid); -} - -void wgaim_tray_minimize(GaimGtkBuddyList *gtkblist) { - MinimizeWndToTray(GDK_WINDOW_HWND(gtkblist->window->window)); -} - -void wgaim_tray_maximize(GaimGtkBuddyList *gtkblist) { - RestoreWndFromTray(GDK_WINDOW_HWND(gtkblist->window->window)); -} - - -static void wgaim_tray_create() { - OSVERSIONINFO osinfo; - /* dummy window to process systray messages */ - systray_hwnd = systray_create_hiddenwin(); - - osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osinfo); - - /* Load icons, and init systray notify icon - * NOTE: Windows < XP only supports displaying 4-bit images in the Systray, - * 2K and ME will use the highest color depth that the desktop will support, - * but will scale it back to 4-bits for display. - * That is why we use custom 4-bit icons for pre XP Windowses */ - if ((osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion > 0) || - (osinfo.dwMajorVersion >= 6)) - { - sysicon_disconn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_OFFLINE_TRAY_ICON), IMAGE_ICON, 16, 16, 0); - sysicon_conn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_TRAY_ICON), IMAGE_ICON, 16, 16, 0); - sysicon_away = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAY_TRAY_ICON), IMAGE_ICON, 16, 16, 0); - sysicon_pend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_PEND_TRAY_ICON), IMAGE_ICON, 16, 16, 0); - sysicon_awypend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAYPEND_TRAY_ICON), IMAGE_ICON, 16, 16, 0); - } else { - sysicon_disconn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_OFFLINE_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); - sysicon_conn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); - sysicon_away = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAY_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); - sysicon_pend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_PEND_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); - sysicon_awypend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAYPEND_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); - } - sysicon_blank = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_BLANK_TRAY_ICON), IMAGE_ICON, 16, 16, 0); - - /* Create icon in systray */ - systray_init_icon(systray_hwnd, sysicon_disconn); - - gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-hiding", - &handle, GAIM_CALLBACK(wgaim_tray_minimize), NULL); - gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-unhiding", - &handle, GAIM_CALLBACK(wgaim_tray_maximize), NULL); - - gaim_debug(GAIM_DEBUG_INFO, "tray icon", "created\n"); -} - -static void wgaim_tray_destroy() { - gaim_signals_disconnect_by_handle(&handle); - systray_remove_nid(); - DestroyWindow(systray_hwnd); - docklet_remove(); -} - -static struct docklet_ui_ops wgaim_tray_ops = -{ - wgaim_tray_create, - wgaim_tray_destroy, - wgaim_tray_update_icon, - wgaim_tray_blank_icon, - wgaim_tray_set_tooltip, - NULL -}; - -/* Used by docklet's plugin load func */ -void docklet_ui_init() { - docklet_set_ui_ops(&wgaim_tray_ops); -} Modified: trunk/gtk/gtkdocklet.c =================================================================== --- trunk/gtk/gtkdocklet.c 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/gtkdocklet.c 2006-10-06 05:03:28 UTC (rev 17435) @@ -30,12 +30,10 @@ #include "prefs.h" #include "signals.h" #include "sound.h" -#include "version.h" #include "gtkaccount.h" #include "gtkblist.h" #include "gtkconv.h" -#include "gtkft.h" #include "gtkplugin.h" #include "gtkprefs.h" #include "gtksavedstatuses.h" @@ -43,8 +41,6 @@ #include "gtkutils.h" #include "gaimstock.h" #include "gtkdocklet.h" - -#include "gaim.h" #include "gtkdialogs.h" #ifndef DOCKLET_TOOLTIP_LINE_LIMIT @@ -256,11 +252,13 @@ /************************************************************************** * callbacks and signal handlers **************************************************************************/ +#if 0 static void gaim_quit_cb() { /* TODO: confirm quit while pending */ } +#endif static void docklet_update_status_cb(void *data) @@ -269,13 +267,6 @@ } static void -docklet_prefs_cb(const char *name, GaimPrefType type, - gconstpointer val, gpointer data) -{ - docklet_update_status(); -} - -static void docklet_conv_updated_cb(GaimConversation *conv, GaimConvUpdateType type) { if (type == GAIM_CONV_UPDATE_UNSEEN) @@ -602,26 +593,23 @@ return &i; } -void +void gaim_gtk_docklet_init() { void *conn_handle = gaim_connections_get_handle(); void *conv_handle = gaim_conversations_get_handle(); void *accounts_handle = gaim_accounts_get_handle(); - void *core_handle = gaim_get_core(); void *docklet_handle = gaim_gtk_docklet_get_handle(); - - gaim_debug(GAIM_DEBUG_INFO, "docklet", "plugin loaded\n"); - gaim_prefs_add_none("/plugins/gtk/docklet"); - gaim_prefs_add_string("/plugins/gtk/docklet/blink_im", "hidden"); - gaim_prefs_add_string("/plugins/gtk/docklet/blink_chat", "never"); - + gaim_prefs_add_none("/plugins/gtk/docklet"); + gaim_prefs_add_string("/plugins/gtk/docklet/blink_im", "hidden"); + gaim_prefs_add_string("/plugins/gtk/docklet/blink_chat", "never"); + docklet_ui_init(); if (ui_ops && ui_ops->create) ui_ops->create(); gaim_signal_connect(conn_handle, "signed-on", - docklet_handle, GAIM_CALLBACK(docklet_signed_on_cb), NULL); + docklet_handle, GAIM_CALLBACK(docklet_signed_on_cb), NULL); gaim_signal_connect(conn_handle, "signed-off", docklet_handle, GAIM_CALLBACK(docklet_signed_off_cb), NULL); gaim_signal_connect(accounts_handle, "account-status-changed", @@ -634,10 +622,11 @@ docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); gaim_signal_connect(conv_handle, "conversation-updated", docklet_handle, GAIM_CALLBACK(docklet_conv_updated_cb), NULL); +#if 0 + gaim_signal_connect(gaim_get_core(), "quitting", + docklet_handle, GAIM_CALLBACK(gaim_quit_cb), NULL); +#endif - gaim_signal_connect(core_handle, "quitting", - NULL, GAIM_CALLBACK(gaim_quit_cb), NULL); - /* gaim_prefs_connect_callback(plugin, "/plugins/gtk/docklet/blink_im", docklet_prefs_cb, NULL); gaim_prefs_connect_callback(plugin, "/plugins/gtk/docklet/blink_chat", @@ -653,6 +642,7 @@ ui_ops->destroy(); } +#if 0 static GtkWidget * plugin_config_frame(GaimPlugin *plugin) { @@ -686,9 +676,5 @@ gtk_widget_show_all(frame); return frame; } +#endif -static GaimGtkPluginUiInfo ui_info = -{ - plugin_config_frame, - 0 /* page_num (Reserved) */ -}; Modified: trunk/gtk/gtkdocklet.h =================================================================== --- trunk/gtk/gtkdocklet.h 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/gtkdocklet.h 2006-10-06 05:03:28 UTC (rev 17435) @@ -46,17 +46,17 @@ }; -/* functions in docklet.c */ +/* functions in gtkdocklet.c */ void gaim_gtk_docklet_clicked(int); void gaim_gtk_docklet_embedded(void); void gaim_gtk_docklet_remove(void); void gaim_gtk_docklet_set_ui_ops(struct docklet_ui_ops *); void gaim_gtk_docklet_unload(void); -void gaim_gtk_docklet_init(); -void gaim_gtk_docklet_uninit(); -void*gaim_gtk_docklet_get_handle(); +void gaim_gtk_docklet_init(void); +void gaim_gtk_docklet_uninit(void); +void*gaim_gtk_docklet_get_handle(void); -/* function in docklet-{x11,win32}.c */ +/* function in gtkdocklet-{x11,win32}.c */ void docklet_ui_init(void); #endif /* _GTKDOCKLET_H_ */ Modified: trunk/gtk/plugins/Makefile.mingw =================================================================== --- trunk/gtk/plugins/Makefile.mingw 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/plugins/Makefile.mingw 2006-10-06 05:03:28 UTC (rev 17435) @@ -7,7 +7,6 @@ GAIM_TOP := ../.. include $(GAIM_TOP)/libgaim/win32/global.mak -DOCKLET_PLUGIN := ./docklet GTKPERL_PLUGIN := ./perl TICKER_PLUGIN := ./ticker TRANSPARENCY_PLUGIN := ./win32/transparency @@ -58,14 +57,12 @@ .PHONY: all clean plugins install all: plugins - $(MAKE) -C $(DOCKLET_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) $(MAKE) -C $(GTKPERL_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) $(MAKE) -C $(TICKER_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) $(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) $(MAKE) -C $(WINPREFS_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) install: all $(GAIM_INSTALL_PLUGINS_DIR) - $(MAKE) -C $(DOCKLET_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) install $(MAKE) -C $(GTKPERL_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) install $(MAKE) -C $(TICKER_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) install $(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) install @@ -92,7 +89,6 @@ ## clean: rm -f *.o *.dll - $(MAKE) -C $(DOCKLET_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) clean $(MAKE) -C $(GTKPERL_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) clean $(MAKE) -C $(TICKER_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) clean $(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(GAIM_WIN32_MAKEFILE) clean Deleted: trunk/gtk/plugins/docklet/MinimizeToTray.c =================================================================== --- trunk/gtk/plugins/docklet/MinimizeToTray.c 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/plugins/docklet/MinimizeToTray.c 2006-10-06 05:03:28 UTC (rev 17435) @@ -1,119 +0,0 @@ -/* MinimizeToTray - * - * A couple of routines to show how to make it produce a custom caption - * animation to make it look like we are minimizing to and maximizing - * from the system tray - * - * These routines are public domain, but it would be nice if you dropped - * me a line if you use them! - * - * 1.0 29.06.2000 Initial version - * 1.1 01.07.2000 The window retains it's place in the Z-order of windows - * when minimized/hidden. This means that when restored/shown, it doesn't - * always appear as the foreground window unless we call SetForegroundWindow - * - * Copyright 2000 Matthew Ellis <m.t...@bi...> - */ -#define _WIN32_WINNT 0x0500 -#include <windows.h> -#include "MinimizeToTray.h" - -#define DEFAULT_RECT_WIDTH 150 -#define DEFAULT_RECT_HEIGHT 30 - -static void GetTrayWndRect(LPRECT lpTrayRect) { - APPBARDATA appBarData; - HWND hShellTrayWnd = FindWindowEx(NULL, NULL, TEXT("Shell_TrayWnd"), - NULL); - - if(hShellTrayWnd) { - HWND hTrayNotifyWnd = FindWindowEx(hShellTrayWnd, NULL, - TEXT("TrayNotifyWnd"), NULL); - - if(hTrayNotifyWnd) { - GetWindowRect(hTrayNotifyWnd,lpTrayRect); - return; - } - } - - appBarData.cbSize = sizeof(appBarData); - if(SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData)) { - switch(appBarData.uEdge) { - case ABE_LEFT: - case ABE_RIGHT: - lpTrayRect->top = appBarData.rc.bottom - 100; - lpTrayRect->bottom = appBarData.rc.bottom - 16; - lpTrayRect->left = appBarData.rc.left; - lpTrayRect->right = appBarData.rc.right; - break; - case ABE_TOP: - case ABE_BOTTOM: - lpTrayRect->top = appBarData.rc.top; - lpTrayRect->bottom = appBarData.rc.bottom; - lpTrayRect->left = appBarData.rc.right - 100; - lpTrayRect->right = appBarData.rc.right - 16; - break; - } - return; - } - - hShellTrayWnd = FindWindowEx(NULL, NULL, TEXT("Shell_TrayWnd"), NULL); - if(hShellTrayWnd) { - GetWindowRect(hShellTrayWnd, lpTrayRect); - if(lpTrayRect->right-lpTrayRect->left > DEFAULT_RECT_WIDTH) - lpTrayRect->left = lpTrayRect->right - DEFAULT_RECT_WIDTH; - if(lpTrayRect->bottom-lpTrayRect->top > DEFAULT_RECT_HEIGHT) - lpTrayRect->top=lpTrayRect->bottom - DEFAULT_RECT_HEIGHT; - - return; - } - - SystemParametersInfo(SPI_GETWORKAREA, 0, lpTrayRect, 0); - lpTrayRect->left = lpTrayRect->right - DEFAULT_RECT_WIDTH; - lpTrayRect->top = lpTrayRect->bottom - DEFAULT_RECT_HEIGHT; -} - -static BOOL GetDoAnimateMinimize(void) { - ANIMATIONINFO ai; - - ai.cbSize = sizeof(ai); - SystemParametersInfo(SPI_GETANIMATION, sizeof(ai), &ai, 0); - - return ai.iMinAnimate ? TRUE : FALSE; -} - -void MinimizeWndToTray(HWND hWnd) { - - if(!IsWindowVisible(hWnd)) - return; - - if(GetDoAnimateMinimize()) { - RECT rcFrom, rcTo; - - GetWindowRect(hWnd, &rcFrom); - GetTrayWndRect(&rcTo); - - DrawAnimatedRects(hWnd, IDANI_CAPTION, &rcFrom, &rcTo); - } - - ShowWindow(hWnd, SW_HIDE); -} - -void RestoreWndFromTray(HWND hWnd) { - - if(IsWindowVisible(hWnd)) - return; - - if(GetDoAnimateMinimize()) { - RECT rcFrom, rcTo; - GetTrayWndRect(&rcFrom); - GetWindowRect(hWnd, &rcTo); - - DrawAnimatedRects(hWnd, IDANI_CAPTION, &rcFrom, &rcTo); - } - - ShowWindow(hWnd, SW_SHOW); - SetActiveWindow(hWnd); - SetForegroundWindow(hWnd); -} - Deleted: trunk/gtk/plugins/docklet/MinimizeToTray.h =================================================================== --- trunk/gtk/plugins/docklet/MinimizeToTray.h 2006-10-06 00:10:34 UTC (rev 17434) +++ trunk/gtk/plugins/docklet/MinimizeToTray.h 2006-10-06 05:03:28 UTC (rev 17435) @@ -1,7 +0,0 @@ -#ifndef _MINIMIZE_TO_TRAY_H_ -#define _MINIMIZE_TO_TRAY_H_ - -void MinimizeWndToTray(HWND hWnd); -void RestoreWndFromTray(HWND hWnd); - -#endif /* _MINIMIZE_TO_TRAY_H_ */ Copied: trunk/gtk/win32/gtkdocklet-win32.c (from rev 17434, trunk/gtk/gtkdocklet-win32.c) =================================================================== --- trunk/gtk/win32/gtkdocklet-win32.c (rev 0) +++ trunk/gtk/win32/gtkdocklet-win32.c 2006-10-06 05:03:28 UTC (rev 17435) @@ -0,0 +1,258 @@ +/* + * System tray icon (aka docklet) plugin for Gaim + * + * Copyright (C) 2002-3 Robert McQueen <rob...@de...> + * Copyright (C) 2003 Herman Bloggs <her...@ya...> + * Inspired by a similar plugin by: + * John (J5) Palmieri <jo...@ma...> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <windows.h> +#include <gdk/gdkwin32.h> +#include <gdk/gdk.h> + +#include "internal.h" +#include "gtkblist.h" +#include "debug.h" + +#include "resource.h" +#include "MinimizeToTray.h" +#include "gtkwin32dep.h" +#include "gtkdocklet.h" + +/* + * DEFINES, MACROS & DATA TYPES + */ +#define WM_TRAYMESSAGE WM_USER /* User defined WM Message */ + +/* + * LOCALS + */ +static HWND systray_hwnd = 0; +static HICON sysicon_disconn = 0; +static HICON sysicon_conn = 0; +static HICON sysicon_away = 0; +static HICON sysicon_pend = 0; +static HICON sysicon_awypend = 0; +static HICON sysicon_blank = 0; +static NOTIFYICONDATA wgaim_nid; + + +static LRESULT CALLBACK systray_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + static UINT taskbarRestartMsg; /* static here means value is kept across multiple calls to this func */ + + switch(msg) { + case WM_CREATE: + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_CREATE\n"); + taskbarRestartMsg = RegisterWindowMessage("TaskbarCreated"); + break; + + case WM_TIMER: + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_TIMER\n"); + break; + + case WM_DESTROY: + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_DESTROY\n"); + break; + + case WM_TRAYMESSAGE: + { + int type = 0; + + /* We'll use Double Click - Single click over on linux */ + if(lparam == WM_LBUTTONDBLCLK) + type = 1; + else if(lparam == WM_MBUTTONUP) + type = 2; + else if(lparam == WM_RBUTTONUP) + type = 3; + else + break; + + gaim_gtk_docklet_clicked(type); + break; + } + default: + if (msg == taskbarRestartMsg) { + /* explorer crashed and left us hanging... + This will put the systray icon back in it's place, when it restarts */ + Shell_NotifyIcon(NIM_ADD, &wgaim_nid); + } + break; + }/* end switch */ + + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +/* Create hidden window to process systray messages */ +static HWND systray_create_hiddenwin() { + WNDCLASSEX wcex; + LPCTSTR wname; + + wname = TEXT("WingaimSystrayWinCls"); + + + wcex.cbSize = sizeof(wcex); + wcex.style = 0; + wcex.lpfnWndProc = systray_mainmsg_handler; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = gtkwgaim_hinstance(); + wcex.hIcon = NULL; + wcex.hCursor = NULL, + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = wname; + wcex.hIconSm = NULL; + + RegisterClassEx(&wcex); + + /* Create the window */ + return (CreateWindow(wname, "", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, gtkwgaim_hinstance(), 0)); +} + +static void systray_init_icon(HWND hWnd, HICON icon) { + ZeroMemory(&wgaim_nid, sizeof(wgaim_nid)); + wgaim_nid.cbSize = sizeof(NOTIFYICONDATA); + wgaim_nid.hWnd = hWnd; + wgaim_nid.uID = 0; + wgaim_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + wgaim_nid.uCallbackMessage = WM_TRAYMESSAGE; + wgaim_nid.hIcon = icon; + lstrcpy(wgaim_nid.szTip, "Gaim"); + Shell_NotifyIcon(NIM_ADD, &wgaim_nid); + gaim_gtk_docklet_embedded(); +} + +static void systray_change_icon(HICON icon) { + wgaim_nid.hIcon = icon; + Shell_NotifyIcon(NIM_MODIFY, &wgaim_nid); +} + +static void systray_remove_nid(void) { + Shell_NotifyIcon(NIM_DELETE, &wgaim_nid); +} + +static void wgaim_tray_update_icon(DockletStatus icon) { + switch (icon) { + case DOCKLET_STATUS_OFFLINE: + systray_change_icon(sysicon_disconn); + break; + case DOCKLET_STATUS_CONNECTING: + break; + case DOCKLET_STATUS_ONLINE: + systray_change_icon(sysicon_conn); + break; + case DOCKLET_STATUS_ONLINE_PENDING: + systray_change_icon(sysicon_pend); + break; + case DOCKLET_STATUS_AWAY: + systray_change_icon(sysicon_away); + break; + case DOCKLET_STATUS_AWAY_PENDING: + systray_change_icon(sysicon_awypend); + break; + } +} + +static void wgaim_tray_blank_icon() { + systray_change_icon(sysicon_blank); +} + +static void wgaim_tray_set_tooltip(gchar *tooltip) { + if (tooltip) { + char *locenc = NULL; + locenc = g_locale_from_utf8(tooltip, -1, NULL, NULL, NULL); + lstrcpyn(wgaim_nid.szTip, locenc, sizeof(wgaim_nid.szTip) / sizeof(TCHAR)); + g_free(locenc); + } else { + lstrcpy(wgaim_nid.szTip, "Gaim"); + } + Shell_NotifyIcon(NIM_MODIFY, &wgaim_nid); +} + +static void wgaim_tray_minimize(GaimGtkBuddyList *gtkblist) { + MinimizeWndToTray(GDK_WINDOW_HWND(gtkblist->window->window)); +} + +static void wgaim_tray_maximize(GaimGtkBuddyList *gtkblist) { + RestoreWndFromTray(GDK_WINDOW_HWND(gtkblist->window->window)); +} + + +static void wgaim_tray_create() { + OSVERSIONINFO osinfo; + /* dummy window to process systray messages */ + systray_hwnd = systray_create_hiddenwin(); + + osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osinfo); + + /* Load icons, and init systray notify icon + * NOTE: Windows < XP only supports displaying 4-bit images in the Systray, + * 2K and ME will use the highest color depth that the desktop will support, + * but will scale it back to 4-bits for display. + * That is why we use custom 4-bit icons for pre XP Windowses */ + if ((osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion > 0) || + (osinfo.dwMajorVersion >= 6)) + { + sysicon_disconn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_OFFLINE_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_conn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_away = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAY_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_pend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_PEND_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_awypend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAYPEND_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + } else { + sysicon_disconn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_OFFLINE_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_conn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_away = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAY_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_pend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_PEND_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_awypend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAYPEND_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + } + sysicon_blank = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_BLANK_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + + /* Create icon in systray */ + systray_init_icon(systray_hwnd, sysicon_disconn); + + gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-hiding", + gaim_gtk_docklet_get_handle(), GAIM_CALLBACK(wgaim_tray_minimize), NULL); + gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-unhiding", + gaim_gtk_docklet_get_handle(), GAIM_CALLBACK(wgaim_tray_maximize), NULL); + + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "created\n"); +} + +static void wgaim_tray_destroy() { + systray_remove_nid(); + DestroyWindow(systray_hwnd); + gaim_gtk_docklet_remove(); +} + +static struct docklet_ui_ops wgaim_tray_ops = +{ + wgaim_tray_create, + wgaim_tray_destroy, + wgaim_tray_update_icon, + wgaim_tray_blank_icon, + wgaim_tray_set_tooltip, + NULL +}; + +/* Used by docklet's plugin load func */ +void docklet_ui_init() { + gaim_gtk_docklet_set_ui_ops(&wgaim_tray_ops); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-10-06 00:10:38
|
Revision: 17434 http://svn.sourceforge.net/gaim/?rev=17434&view=rev Author: seanegan Date: 2006-10-05 17:10:34 -0700 (Thu, 05 Oct 2006) Log Message: ----------- I have a blist.xml with a lot of buddy_icon's set to files that don't exist. This could be the cause, but I doubt it. Modified Paths: -------------- trunk/libgaim/buddyicon.c Modified: trunk/libgaim/buddyicon.c =================================================================== --- trunk/libgaim/buddyicon.c 2006-10-05 23:24:00 UTC (rev 17433) +++ trunk/libgaim/buddyicon.c 2006-10-06 00:10:34 UTC (rev 17434) @@ -261,6 +261,9 @@ { gaim_debug_error("buddyicon", "Unable to create file %s: %s\n", filename, strerror(errno)); + g_free(filename); + g_free(random); + return; } g_free(filename); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-10-05 23:24:10
|
Revision: 17433 http://svn.sourceforge.net/gaim/?rev=17433&view=rev Author: seanegan Date: 2006-10-05 16:24:00 -0700 (Thu, 05 Oct 2006) Log Message: ----------- Depluginize the docklet. Modified Paths: -------------- trunk/gtk/Makefile.am trunk/gtk/gtkmain.c trunk/gtk/plugins/docklet/Makefile.am trunk/gtk/plugins/docklet/docklet.c trunk/libgaim/util.c Added Paths: ----------- trunk/gtk/docklet-x11.c trunk/gtk/docklet.h trunk/gtk/eggtrayicon.c trunk/gtk/eggtrayicon.h trunk/gtk/gtkdocklet-win32.c trunk/gtk/gtkdocklet-x11.c trunk/gtk/gtkdocklet.c trunk/gtk/gtkdocklet.h trunk/gtk/win32/MinimizeToTray.c trunk/gtk/win32/MinimizeToTray.h Removed Paths: ------------- trunk/gtk/plugins/docklet/docklet-win32.c trunk/gtk/plugins/docklet/docklet-x11.c trunk/gtk/plugins/docklet/docklet.h trunk/gtk/plugins/docklet/eggtrayicon.c trunk/gtk/plugins/docklet/eggtrayicon.h Modified: trunk/gtk/Makefile.am =================================================================== --- trunk/gtk/Makefile.am 2006-10-04 20:31:44 UTC (rev 17432) +++ trunk/gtk/Makefile.am 2006-10-05 23:24:00 UTC (rev 17433) @@ -59,6 +59,7 @@ bin_PROGRAMS = gaim gaim_SOURCES = \ + eggtrayicon.c \ gaimcombobox.c \ gaimstock.c \ gtkaccount.c \ @@ -73,6 +74,8 @@ gtkdebug.c \ gtkdialogs.c \ gtkdnd-hints.c \ + gtkdocklet.c \ + gtkdocklet-x11.c \ gtkeventloop.c \ gtkexpander.c \ gtkft.c \ @@ -100,6 +103,7 @@ gtkwhiteboard.c gaim_headers = \ + eggtrayicon.h \ gtkaccount.h \ gtkblist.h \ gtkcelllayout.h \ @@ -116,6 +120,7 @@ gtkdebug.h \ gtkdialogs.h \ gtkdnd-hints.h \ + gtkdocklet.h \ gtkeventloop.h \ gtkexpander.h \ gtkft.h \ Copied: trunk/gtk/docklet-x11.c (from rev 17432, trunk/gtk/plugins/docklet/docklet-x11.c) =================================================================== --- trunk/gtk/docklet-x11.c (rev 0) +++ trunk/gtk/docklet-x11.c 2006-10-05 23:24:00 UTC (rev 17433) @@ -0,0 +1,305 @@ +/* + * System tray icon (aka docklet) plugin for Gaim + * + * Copyright (C) 2002-3 Robert McQueen <rob...@de...> + * Copyright (C) 2003 Herman Bloggs <her...@ya...> + * Inspired by a similar plugin by: + * John (J5) Palmieri <jo...@ma...> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "internal.h" +#include "gtkgaim.h" +#include "debug.h" +#include "gaimstock.h" + +#include "gaim.h" +#include "gtkdialogs.h" + +#include "eggtrayicon.h" +#include "docklet.h" + +#define EMBED_TIMEOUT 5000 + +/* globals */ +static EggTrayIcon *docklet = NULL; +static GtkWidget *image = NULL; +static GtkTooltips *tooltips = NULL; +static GdkPixbuf *blank_icon = NULL; +static int embed_timeout = 0; + +/* protos */ +static void docklet_x11_create(void); + +static gboolean +docklet_x11_create_cb() +{ + docklet_x11_create(); + + return FALSE; /* for when we're called by the glib idle handler */ +} + +static void +docklet_x11_embedded_cb(GtkWidget *widget, void *data) +{ + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "embedded\n"); + + g_source_remove(embed_timeout); + embed_timeout = 0; + docklet_embedded(); +} + +static void +docklet_x11_destroyed_cb(GtkWidget *widget, void *data) +{ + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "destroyed\n"); + + docklet_remove(); + + g_object_unref(G_OBJECT(docklet)); + docklet = NULL; + + g_idle_add(docklet_x11_create_cb, &handle); +} + +static void +docklet_x11_clicked_cb(GtkWidget *button, GdkEventButton *event, void *data) +{ + if (event->type != GDK_BUTTON_PRESS) + return; + + docklet_clicked(event->button); +} + +static void +docklet_x11_update_icon(DockletStatus icon) +{ + const gchar *icon_name = NULL; + + g_return_if_fail(image != NULL); + + switch (icon) { + case DOCKLET_STATUS_OFFLINE: + icon_name = GAIM_STOCK_ICON_OFFLINE; + break; + case DOCKLET_STATUS_CONNECTING: + icon_name = GAIM_STOCK_ICON_CONNECT; + break; + case DOCKLET_STATUS_ONLINE: + icon_name = GAIM_STOCK_ICON_ONLINE; + break; + case DOCKLET_STATUS_ONLINE_PENDING: + icon_name = GAIM_STOCK_ICON_ONLINE_MSG; + break; + case DOCKLET_STATUS_AWAY: + icon_name = GAIM_STOCK_ICON_AWAY; + break; + case DOCKLET_STATUS_AWAY_PENDING: + icon_name = GAIM_STOCK_ICON_AWAY_MSG; + break; + } + + if(icon_name) + gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); + +#if 0 + GdkPixbuf *p; + GdkBitmap *mask = NULL; + + p = gtk_widget_render_icon(GTK_WIDGET(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); + + if (p && (gdk_pixbuf_get_colorspace(p) == GDK_COLORSPACE_RGB) && (gdk_pixbuf_get_bits_per_sample(p) == 8) + && (gdk_pixbuf_get_has_alpha(p)) && (gdk_pixbuf_get_n_channels(p) == 4)) { + int len = gdk_pixbuf_get_width(p) * gdk_pixbuf_get_height(p); + guchar *data = gdk_pixbuf_get_pixels(p); + guchar *bitmap = g_malloc((len / 8) + 1); + int i; + + for (i = 0; i < len; i++) + if (data[i*4 + 3] > 55) + bitmap[i/8] |= 1 << i % 8; + else + bitmap[i/8] &= ~(1 << i % 8); + + mask = gdk_bitmap_create_from_data(GDK_DRAWABLE(GTK_WIDGET(image)->window), bitmap, gdk_pixbuf_get_width(p), gdk_pixbuf_get_height(p)); + g_free(bitmap); + } + + if (mask) + gdk_window_shape_combine_mask(image->window, mask, 0, 0); + + g_object_unref(G_OBJECT(p)); +#endif +} + +static void +docklet_x11_blank_icon() +{ + if (!blank_icon) { + gint width, height; + + gtk_icon_size_lookup(GTK_ICON_SIZE_LARGE_TOOLBAR, &width, &height); + blank_icon = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); + gdk_pixbuf_fill(blank_icon, 0); + } + + gtk_image_set_from_pixbuf(GTK_IMAGE(image), blank_icon); +} + +static void +docklet_x11_set_tooltip(gchar *tooltip) +{ + if (!tooltips) + tooltips = gtk_tooltips_new(); + + /* image->parent is a GtkEventBox */ + if (tooltip) { + gtk_tooltips_enable(tooltips); + gtk_tooltips_set_tip(tooltips, image->parent, tooltip, NULL); + } else { + gtk_tooltips_set_tip(tooltips, image->parent, "", NULL); + gtk_tooltips_disable(tooltips); + } +} + +#if GTK_CHECK_VERSION(2,2,0) +static void +docklet_x11_position_menu(GtkMenu *menu, int *x, int *y, gboolean *push_in, + gpointer user_data) +{ + GtkWidget *widget = GTK_WIDGET(docklet); + GtkRequisition req; + gint menu_xpos, menu_ypos; + + gtk_widget_size_request(GTK_WIDGET(menu), &req); + gdk_window_get_origin(widget->window, &menu_xpos, &menu_ypos); + + menu_xpos += widget->allocation.x; + menu_ypos += widget->allocation.y; + + if (menu_ypos > gdk_screen_get_height(gtk_widget_get_screen(widget)) / 2) + menu_ypos -= req.height; + else + menu_ypos += widget->allocation.height; + + *x = menu_xpos; + *y = menu_ypos; + + *push_in = TRUE; +} +#endif + +static void +docklet_x11_destroy() +{ + g_return_if_fail(docklet != NULL); + + docklet_remove(); + + g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_x11_destroyed_cb), NULL); + gtk_widget_destroy(GTK_WIDGET(docklet)); + + g_object_unref(G_OBJECT(docklet)); + docklet = NULL; + + if (blank_icon) + g_object_unref(G_OBJECT(blank_icon)); + blank_icon = NULL; + + image = NULL; + + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "destroyed\n"); +} + +static gboolean +docklet_x11_embed_timeout_cb() +{ + /* The docklet was not embedded within the timeout. + * Remove it as a visibility manager, but leave the plugin + * loaded so that it can embed automatically if/when a notification + * area becomes available. + */ + gaim_debug_info("tray icon", "failed to embed within timeout\n"); + docklet_remove(); + + return FALSE; +} + +static void +docklet_x11_create() +{ + GtkWidget *box; + + if (docklet) { + /* if this is being called when a tray icon exists, it's because + something messed up. try destroying it before we proceed, + although docklet_refcount may be all hosed. hopefully won't happen. */ + gaim_debug(GAIM_DEBUG_WARNING, "tray icon", "trying to create icon but it already exists?\n"); + docklet_x11_destroy(); + } + + docklet = egg_tray_icon_new("Gaim"); + box = gtk_event_box_new(); + image = gtk_image_new(); + + g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(docklet_x11_embedded_cb), NULL); + g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_x11_destroyed_cb), NULL); + g_signal_connect(G_OBJECT(box), "button-press-event", G_CALLBACK(docklet_x11_clicked_cb), NULL); + + gtk_container_add(GTK_CONTAINER(box), image); + gtk_container_add(GTK_CONTAINER(docklet), box); + + if (!gtk_check_version(2,4,0)) + g_object_set(G_OBJECT(box), "visible-window", FALSE, NULL); + + gtk_widget_show_all(GTK_WIDGET(docklet)); + + /* ref the docklet before we bandy it about the place */ + g_object_ref(G_OBJECT(docklet)); + + /* This is a hack to avoid a race condition between the docklet getting + * embedded in the notification area and the gtkblist restoring its + * previous visibility state. If the docklet does not get embedded within + * the timeout, it will be removed as a visibility manager until it does + * get embedded. Ideally, we would only call docklet_embedded() when the + * icon was actually embedded. + */ + docklet_embedded(); + embed_timeout = g_timeout_add(EMBED_TIMEOUT, docklet_x11_embed_timeout_cb, NULL); + + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "created\n"); +} + +static struct docklet_ui_ops ui_ops = +{ + docklet_x11_create, + docklet_x11_destroy, + docklet_x11_update_icon, + docklet_x11_blank_icon, + docklet_x11_set_tooltip, +#if GTK_CHECK_VERSION(2,2,0) + docklet_x11_position_menu +#else + NULL +#endif +}; + +void +docklet_ui_init() +{ + docklet_set_ui_ops(&ui_ops); +} Copied: trunk/gtk/docklet.h (from rev 17432, trunk/gtk/plugins/docklet/docklet.h) =================================================================== --- trunk/gtk/docklet.h (rev 0) +++ trunk/gtk/docklet.h 2006-10-05 23:24:00 UTC (rev 17433) @@ -0,0 +1,61 @@ +/* + * System tray icon (aka docklet) plugin for Gaim + * + * Copyright (C) 2002-3 Robert McQueen <rob...@de...> + * Copyright (C) 2003 Herman Bloggs <her...@ya...> + * Inspired by a similar plugin by: + * John (J5) Palmieri <jo...@ma...> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _DOCKLET_H_ +#define _DOCKLET_H_ + +typedef enum +{ + DOCKLET_STATUS_OFFLINE, + DOCKLET_STATUS_ONLINE, + DOCKLET_STATUS_ONLINE_PENDING, + DOCKLET_STATUS_AWAY, + DOCKLET_STATUS_AWAY_PENDING, + DOCKLET_STATUS_CONNECTING +} DockletStatus; + +struct docklet_ui_ops +{ + void (*create)(void); + void (*destroy)(void); + void (*update_icon)(DockletStatus); + void (*blank_icon)(void); + void (*set_tooltip)(gchar *); + GtkMenuPositionFunc position_menu; +}; + +/* useful for setting idle callbacks that will be cleaned up */ +extern GaimPlugin *handle; + +/* functions in docklet.c */ +void docklet_clicked(int); +void docklet_embedded(void); +void docklet_remove(void); +void docklet_set_ui_ops(struct docklet_ui_ops *); +void docklet_unload(void); + +/* function in docklet-{x11,win32}.c */ +void docklet_ui_init(void); + +#endif /* _DOCKLET_H_ */ Copied: trunk/gtk/eggtrayicon.c (from rev 17432, trunk/gtk/plugins/docklet/eggtrayicon.c) =================================================================== --- trunk/gtk/eggtrayicon.c (rev 0) +++ trunk/gtk/eggtrayicon.c 2006-10-05 23:24:00 UTC (rev 17433) @@ -0,0 +1,572 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* eggtrayicon.c + * Copyright (C) 2002 Anders Carlsson <and...@gn...> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <config.h> +#include <string.h> + +#include "eggtrayicon.h" + +#include <gdk/gdkx.h> +#include <X11/Xatom.h> + +#define _(x) x +#define N_(x) x + +#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define SYSTEM_TRAY_BEGIN_MESSAGE 1 +#define SYSTEM_TRAY_CANCEL_MESSAGE 2 + +#define SYSTEM_TRAY_ORIENTATION_HORZ 0 +#define SYSTEM_TRAY_ORIENTATION_VERT 1 + +enum { + PROP_0, + PROP_ORIENTATION +}; + +static GtkPlugClass *parent_class = NULL; + +static void egg_tray_icon_init (EggTrayIcon *icon); +static void egg_tray_icon_class_init (EggTrayIconClass *klass); + +static void egg_tray_icon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void egg_tray_icon_realize (GtkWidget *widget); +static void egg_tray_icon_unrealize (GtkWidget *widget); + +static void egg_tray_icon_add (GtkContainer *container, + GtkWidget *widget); + +static void egg_tray_icon_update_manager_window (EggTrayIcon *icon, + gboolean dock_if_realized); +static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon); + +GType +egg_tray_icon_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + { + our_type = g_type_from_name("EggTrayIcon"); + + if (our_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EggTrayIconClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) egg_tray_icon_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EggTrayIcon), + 0, /* n_preallocs */ + (GInstanceInitFunc) egg_tray_icon_init, + NULL /* value_table */ + }; + + our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0); + } + else if (parent_class == NULL) + { + /* we're reheating the old class from a previous instance - engage ugly hack =( */ + egg_tray_icon_class_init((EggTrayIconClass *)g_type_class_peek(our_type)); + } + } + + return our_type; +} + +static void +egg_tray_icon_init (EggTrayIcon *icon) +{ + icon->stamp = 1; + icon->orientation = GTK_ORIENTATION_HORIZONTAL; + + gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); +} + +static void +egg_tray_icon_class_init (EggTrayIconClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *)klass; + GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; + GtkContainerClass *container_class = (GtkContainerClass *)klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->get_property = egg_tray_icon_get_property; + + widget_class->realize = egg_tray_icon_realize; + widget_class->unrealize = egg_tray_icon_unrealize; + + container_class->add = egg_tray_icon_add; + + g_object_class_install_property (gobject_class, + PROP_ORIENTATION, + g_param_spec_enum ("orientation", + _("Orientation"), + _("The orientation of the tray."), + GTK_TYPE_ORIENTATION, + GTK_ORIENTATION_HORIZONTAL, + G_PARAM_READABLE)); +} + +static void +egg_tray_icon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EggTrayIcon *icon = EGG_TRAY_ICON (object); + + switch (prop_id) + { + case PROP_ORIENTATION: + g_value_set_enum (value, icon->orientation); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +egg_tray_icon_get_orientation_property (EggTrayIcon *icon) +{ + Display *xdisplay; + Atom type; + int format; + union { + gulong *prop; + guchar *prop_ch; + } prop = { NULL }; + gulong nitems; + gulong bytes_after; + int error, result; + + g_return_if_fail(icon->manager_window != None); + +#if GTK_CHECK_VERSION(2,1,0) + xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); +#else + xdisplay = gdk_display; +#endif + + gdk_error_trap_push (); + type = None; + result = XGetWindowProperty (xdisplay, + icon->manager_window, + icon->orientation_atom, + 0, G_MAXLONG, FALSE, + XA_CARDINAL, + &type, &format, &nitems, + &bytes_after, &(prop.prop_ch)); + error = gdk_error_trap_pop (); + + if (error || result != Success) + return; + + if (type == XA_CARDINAL) + { + GtkOrientation orientation; + + orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ? + GTK_ORIENTATION_HORIZONTAL : + GTK_ORIENTATION_VERTICAL; + + if (icon->orientation != orientation) + { + icon->orientation = orientation; + + g_object_notify (G_OBJECT (icon), "orientation"); + } + } + + if (prop.prop) + XFree (prop.prop); +} + +static GdkFilterReturn +egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data) +{ + EggTrayIcon *icon = user_data; + XEvent *xev = (XEvent *)xevent; + + if (xev->xany.type == ClientMessage && + xev->xclient.message_type == icon->manager_atom && + xev->xclient.data.l[1] == icon->selection_atom) + { + egg_tray_icon_update_manager_window (icon, TRUE); + } + else if (xev->xany.window == icon->manager_window) + { + if (xev->xany.type == PropertyNotify && + xev->xproperty.atom == icon->orientation_atom) + { + egg_tray_icon_get_orientation_property (icon); + } + if (xev->xany.type == DestroyNotify) + { + egg_tray_icon_manager_window_destroyed (icon); + } + } + + return GDK_FILTER_CONTINUE; +} + +static void +egg_tray_icon_unrealize (GtkWidget *widget) +{ + EggTrayIcon *icon = EGG_TRAY_ICON (widget); + GdkWindow *root_window; + + if (icon->manager_window != None) + { + GdkWindow *gdkwin; + +#if GTK_CHECK_VERSION(2,1,0) + gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget), + icon->manager_window); +#else + gdkwin = gdk_window_lookup (icon->manager_window); +#endif + + gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); + } + +#if GTK_CHECK_VERSION(2,1,0) + root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); +#else + root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); +#endif + + gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon); + + if (GTK_WIDGET_CLASS (parent_class)->unrealize) + (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); +} + +static void +egg_tray_icon_send_manager_message (EggTrayIcon *icon, + long message, + Window window, + long data1, + long data2, + long data3) +{ + XClientMessageEvent ev; + Display *display; + + ev.type = ClientMessage; + ev.window = window; + ev.message_type = icon->system_tray_opcode_atom; + ev.format = 32; + ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window); + ev.data.l[1] = message; + ev.data.l[2] = data1; + ev.data.l[3] = data2; + ev.data.l[4] = data3; + +#if GTK_CHECK_VERSION(2,1,0) + display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); +#else + display = gdk_display; +#endif + + gdk_error_trap_push (); + XSendEvent (display, + icon->manager_window, False, NoEventMask, (XEvent *)&ev); + XSync (display, False); + gdk_error_trap_pop (); +} + +static void +egg_tray_icon_send_dock_request (EggTrayIcon *icon) +{ + egg_tray_icon_send_manager_message (icon, + SYSTEM_TRAY_REQUEST_DOCK, + icon->manager_window, + gtk_plug_get_id (GTK_PLUG (icon)), + 0, 0); +} + +static void +egg_tray_icon_update_manager_window (EggTrayIcon *icon, + gboolean dock_if_realized) +{ + Display *xdisplay; + + if (icon->manager_window != None) + return; + +#if GTK_CHECK_VERSION(2,1,0) + xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); +#else + xdisplay = gdk_display; +#endif + + XGrabServer (xdisplay); + + icon->manager_window = XGetSelectionOwner (xdisplay, + icon->selection_atom); + + if (icon->manager_window != None) + XSelectInput (xdisplay, + icon->manager_window, StructureNotifyMask|PropertyChangeMask); + + XUngrabServer (xdisplay); + XFlush (xdisplay); + + if (icon->manager_window != None) + { + GdkWindow *gdkwin; + +#if GTK_CHECK_VERSION(2,1,0) + gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), + icon->manager_window); +#else + gdkwin = gdk_window_lookup (icon->manager_window); +#endif + + gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon); + + if (dock_if_realized && GTK_WIDGET_REALIZED (icon)) + egg_tray_icon_send_dock_request (icon); + + egg_tray_icon_get_orientation_property (icon); + } +} + +static void +egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon) +{ + GdkWindow *gdkwin; + + g_return_if_fail (icon->manager_window != None); + +#if GTK_CHECK_VERSION(2,1,0) + gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), + icon->manager_window); +#else + gdkwin = gdk_window_lookup (icon->manager_window); +#endif + + gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); + + icon->manager_window = None; + + egg_tray_icon_update_manager_window (icon, TRUE); +} + +static gboolean +transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) +{ + gdk_window_clear_area (widget->window, event->area.x, event->area.y, + event->area.width, event->area.height); + return FALSE; +} + +static void +make_transparent_again (GtkWidget *widget, GtkStyle *previous_style, + gpointer user_data) +{ + gdk_window_set_back_pixmap(widget->window, NULL, TRUE); +} + +static void +make_transparent (GtkWidget *widget, gpointer user_data) +{ + if (GTK_WIDGET_NO_WINDOW (widget) || GTK_WIDGET_APP_PAINTABLE (widget)) + return; + + gtk_widget_set_app_paintable (widget, TRUE); + gtk_widget_set_double_buffered (widget, FALSE); + gdk_window_set_back_pixmap (widget->window, NULL, TRUE); + g_signal_connect (widget, "expose_event", + G_CALLBACK (transparent_expose_event), NULL); + g_signal_connect_after (widget, "style_set", + G_CALLBACK (make_transparent_again), NULL); +} + +static void +egg_tray_icon_realize (GtkWidget *widget) +{ + EggTrayIcon *icon = EGG_TRAY_ICON (widget); + gint screen; + Display *xdisplay; + char buffer[256]; + GdkWindow *root_window; + + if (GTK_WIDGET_CLASS (parent_class)->realize) + GTK_WIDGET_CLASS (parent_class)->realize (widget); + + make_transparent (widget, NULL); + +#if GTK_CHECK_VERSION(2,1,0) + screen = gdk_screen_get_number (gtk_widget_get_screen (widget)); + xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)); +#else + screen = XScreenNumberOfScreen (DefaultScreenOfDisplay (gdk_display)); + xdisplay = gdk_display; +#endif + + /* Now see if there's a manager window around */ + g_snprintf (buffer, sizeof (buffer), + "_NET_SYSTEM_TRAY_S%d", + screen); + + icon->selection_atom = XInternAtom (xdisplay, buffer, False); + + icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False); + + icon->system_tray_opcode_atom = XInternAtom (xdisplay, + "_NET_SYSTEM_TRAY_OPCODE", + False); + + icon->orientation_atom = XInternAtom (xdisplay, + "_NET_SYSTEM_TRAY_ORIENTATION", + False); + + egg_tray_icon_update_manager_window (icon, FALSE); + egg_tray_icon_send_dock_request (icon); + +#if GTK_CHECK_VERSION(2,1,0) + root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); +#else + root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); +#endif + + /* Add a root window filter so that we get changes on MANAGER */ + gdk_window_add_filter (root_window, + egg_tray_icon_manager_filter, icon); +} + +static void +egg_tray_icon_add (GtkContainer *container, GtkWidget *widget) +{ + g_signal_connect (widget, "realize", + G_CALLBACK (make_transparent), NULL); + GTK_CONTAINER_CLASS (parent_class)->add (container, widget); +} + +#if GTK_CHECK_VERSION(2,1,0) +EggTrayIcon * +egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL); +} +#endif + +EggTrayIcon* +egg_tray_icon_new (const gchar *name) +{ + return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL); +} + +guint +egg_tray_icon_send_message (EggTrayIcon *icon, + gint timeout, + const gchar *message, + gint len) +{ + guint stamp; + + g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0); + g_return_val_if_fail (timeout >= 0, 0); + g_return_val_if_fail (message != NULL, 0); + + if (icon->manager_window == None) + return 0; + + if (len < 0) + len = strlen (message); + + stamp = icon->stamp++; + + /* Get ready to send the message */ + egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, + (Window)gtk_plug_get_id (GTK_PLUG (icon)), + timeout, len, stamp); + + /* Now to send the actual message */ + gdk_error_trap_push (); + while (len > 0) + { + XClientMessageEvent ev; + Display *xdisplay; + +#if GTK_CHECK_VERSION(2,1,0) + xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); +#else + xdisplay = gdk_display; +#endif + + ev.type = ClientMessage; + ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); + ev.format = 8; + ev.message_type = XInternAtom (xdisplay, + "_NET_SYSTEM_TRAY_MESSAGE_DATA", False); + if (len > 20) + { + memcpy (&ev.data, message, 20); + len -= 20; + message += 20; + } + else + { + memcpy (&ev.data, message, len); + len = 0; + } + + XSendEvent (xdisplay, + icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev); + XSync (xdisplay, False); + } + gdk_error_trap_pop (); + + return stamp; +} + +void +egg_tray_icon_cancel_message (EggTrayIcon *icon, + guint id) +{ + g_return_if_fail (EGG_IS_TRAY_ICON (icon)); + g_return_if_fail (id > 0); + + egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE, + (Window)gtk_plug_get_id (GTK_PLUG (icon)), + id, 0, 0); +} + +GtkOrientation +egg_tray_icon_get_orientation (EggTrayIcon *icon) +{ + g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL); + + return icon->orientation; +} Copied: trunk/gtk/eggtrayicon.h (from rev 17432, trunk/gtk/plugins/docklet/eggtrayicon.h) =================================================================== --- trunk/gtk/eggtrayicon.h (rev 0) +++ trunk/gtk/eggtrayicon.h 2006-10-05 23:24:00 UTC (rev 17433) @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* eggtrayicon.h + * Copyright (C) 2002 Anders Carlsson <and...@gn...> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EGG_TRAY_ICON_H__ +#define __EGG_TRAY_ICON_H__ + +#include <gtk/gtkplug.h> +#include <gtk/gtkversion.h> +#include <gdk/gdkx.h> + +G_BEGIN_DECLS + +#define EGG_TYPE_TRAY_ICON (egg_tray_icon_get_type ()) +#define EGG_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon)) +#define EGG_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass)) +#define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON)) +#define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON)) +#define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass)) + +typedef struct _EggTrayIcon EggTrayIcon; +typedef struct _EggTrayIconClass EggTrayIconClass; + +struct _EggTrayIcon +{ + GtkPlug parent_instance; + + guint stamp; + + Atom selection_atom; + Atom manager_atom; + Atom system_tray_opcode_atom; + Atom orientation_atom; + Window manager_window; + + GtkOrientation orientation; +}; + +struct _EggTrayIconClass +{ + GtkPlugClass parent_class; +}; + +GType egg_tray_icon_get_type (void); + +#if GTK_CHECK_VERSION(2,1,0) +EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen *screen, + const gchar *name); +#endif + +EggTrayIcon *egg_tray_icon_new (const gchar *name); + +guint egg_tray_icon_send_message (EggTrayIcon *icon, + gint timeout, + const char *message, + gint len); +void egg_tray_icon_cancel_message (EggTrayIcon *icon, + guint id); + +GtkOrientation egg_tray_icon_get_orientation (EggTrayIcon *icon); + +G_END_DECLS + +#endif /* __EGG_TRAY_ICON_H__ */ Copied: trunk/gtk/gtkdocklet-win32.c (from rev 17432, trunk/gtk/plugins/docklet/docklet-win32.c) =================================================================== --- trunk/gtk/gtkdocklet-win32.c (rev 0) +++ trunk/gtk/gtkdocklet-win32.c 2006-10-05 23:24:00 UTC (rev 17433) @@ -0,0 +1,263 @@ +/* + * System tray icon (aka docklet) plugin for Gaim + * + * Copyright (C) 2002-3 Robert McQueen <rob...@de...> + * Copyright (C) 2003 Herman Bloggs <her...@ya...> + * Inspired by a similar plugin by: + * John (J5) Palmieri <jo...@ma...> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <windows.h> +#include <gdk/gdkwin32.h> +#include <gdk/gdk.h> + +#include "internal.h" +#include "gtkblist.h" +#include "gtkprefs.h" +#include "debug.h" + +#include "gaim.h" +#include "gtkdialogs.h" + +#include "resource.h" +#include "MinimizeToTray.h" +#include "gtkwin32dep.h" +#include "docklet.h" + +/* + * DEFINES, MACROS & DATA TYPES + */ +#define WM_TRAYMESSAGE WM_USER /* User defined WM Message */ + +/* + * LOCALS + */ +static HWND systray_hwnd=0; +static HICON sysicon_disconn=0; +static HICON sysicon_conn=0; +static HICON sysicon_away=0; +static HICON sysicon_pend=0; +static HICON sysicon_awypend=0; +static HICON sysicon_blank=0; +static NOTIFYICONDATA wgaim_nid; + + +static LRESULT CALLBACK systray_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + static UINT taskbarRestartMsg; /* static here means value is kept across multiple calls to this func */ + + switch(msg) { + case WM_CREATE: + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_CREATE\n"); + taskbarRestartMsg = RegisterWindowMessage("TaskbarCreated"); + break; + + case WM_TIMER: + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_TIMER\n"); + break; + + case WM_DESTROY: + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "WM_DESTROY\n"); + break; + + case WM_TRAYMESSAGE: + { + int type = 0; + + /* We'll use Double Click - Single click over on linux */ + if( lparam == WM_LBUTTONDBLCLK ) + type = 1; + else if( lparam == WM_MBUTTONUP ) + type = 2; + else if( lparam == WM_RBUTTONUP ) + type = 3; + else + break; + + docklet_clicked(type); + break; + } + default: + if (msg == taskbarRestartMsg) { + /* explorer crashed and left us hanging... + This will put the systray icon back in it's place, when it restarts */ + Shell_NotifyIcon(NIM_ADD,&wgaim_nid); + } + break; + }/* end switch */ + + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +/* Create hidden window to process systray messages */ +static HWND systray_create_hiddenwin() { + WNDCLASSEX wcex; + TCHAR wname[32]; + + strcpy(wname, "GaimWin"); + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = 0; + wcex.lpfnWndProc = (WNDPROC)systray_mainmsg_handler; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = gtkwgaim_hinstance(); + wcex.hIcon = NULL; + wcex.hCursor = NULL, + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = wname; + wcex.hIconSm = NULL; + + RegisterClassEx(&wcex); + + /* Create the window */ + return (CreateWindow(wname, "", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, gtkwgaim_hinstance(), 0)); +} + +static void systray_init_icon(HWND hWnd, HICON icon) { + ZeroMemory(&wgaim_nid,sizeof(wgaim_nid)); + wgaim_nid.cbSize=sizeof(NOTIFYICONDATA); + wgaim_nid.hWnd=hWnd; + wgaim_nid.uID=0; + wgaim_nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP; + wgaim_nid.uCallbackMessage=WM_TRAYMESSAGE; + wgaim_nid.hIcon=icon; + lstrcpy(wgaim_nid.szTip, "Gaim"); + Shell_NotifyIcon(NIM_ADD,&wgaim_nid); + docklet_embedded(); +} + +static void systray_change_icon(HICON icon) { + wgaim_nid.hIcon = icon; + Shell_NotifyIcon(NIM_MODIFY,&wgaim_nid); +} + +static void systray_remove_nid(void) { + Shell_NotifyIcon(NIM_DELETE,&wgaim_nid); +} + +static void wgaim_tray_update_icon(DockletStatus icon) { + switch (icon) { + case DOCKLET_STATUS_OFFLINE: + systray_change_icon(sysicon_disconn); + break; + case DOCKLET_STATUS_CONNECTING: + break; + case DOCKLET_STATUS_ONLINE: + systray_change_icon(sysicon_conn); + break; + case DOCKLET_STATUS_ONLINE_PENDING: + systray_change_icon(sysicon_pend); + break; + case DOCKLET_STATUS_AWAY: + systray_change_icon(sysicon_away); + break; + case DOCKLET_STATUS_AWAY_PENDING: + systray_change_icon(sysicon_awypend); + break; + } +} + +static void wgaim_tray_blank_icon() { + systray_change_icon(sysicon_blank); +} + +static void wgaim_tray_set_tooltip(gchar *tooltip) { + if (tooltip) { + char *locenc = NULL; + locenc = g_locale_from_utf8(tooltip, -1, NULL, NULL, NULL); + lstrcpyn(wgaim_nid.szTip, locenc, sizeof(wgaim_nid.szTip)/sizeof(TCHAR)); + g_free(locenc); + } else { + lstrcpy(wgaim_nid.szTip, "Gaim"); + } + Shell_NotifyIcon(NIM_MODIFY, &wgaim_nid); +} + +void wgaim_tray_minimize(GaimGtkBuddyList *gtkblist) { + MinimizeWndToTray(GDK_WINDOW_HWND(gtkblist->window->window)); +} + +void wgaim_tray_maximize(GaimGtkBuddyList *gtkblist) { + RestoreWndFromTray(GDK_WINDOW_HWND(gtkblist->window->window)); +} + + +static void wgaim_tray_create() { + OSVERSIONINFO osinfo; + /* dummy window to process systray messages */ + systray_hwnd = systray_create_hiddenwin(); + + osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osinfo); + + /* Load icons, and init systray notify icon + * NOTE: Windows < XP only supports displaying 4-bit images in the Systray, + * 2K and ME will use the highest color depth that the desktop will support, + * but will scale it back to 4-bits for display. + * That is why we use custom 4-bit icons for pre XP Windowses */ + if ((osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion > 0) || + (osinfo.dwMajorVersion >= 6)) + { + sysicon_disconn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_OFFLINE_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_conn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_away = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAY_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_pend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_PEND_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + sysicon_awypend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAYPEND_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + } else { + sysicon_disconn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_OFFLINE_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_conn = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_away = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAY_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_pend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_PEND_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + sysicon_awypend = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_AWAYPEND_TRAY_ICON_4BIT), IMAGE_ICON, 16, 16, 0); + } + sysicon_blank = (HICON)LoadImage(gtkwgaim_hinstance(), MAKEINTRESOURCE(GAIM_BLANK_TRAY_ICON), IMAGE_ICON, 16, 16, 0); + + /* Create icon in systray */ + systray_init_icon(systray_hwnd, sysicon_disconn); + + gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-hiding", + &handle, GAIM_CALLBACK(wgaim_tray_minimize), NULL); + gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-unhiding", + &handle, GAIM_CALLBACK(wgaim_tray_maximize), NULL); + + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "created\n"); +} + +static void wgaim_tray_destroy() { + gaim_signals_disconnect_by_handle(&handle); + systray_remove_nid(); + DestroyWindow(systray_hwnd); + docklet_remove(); +} + +static struct docklet_ui_ops wgaim_tray_ops = +{ + wgaim_tray_create, + wgaim_tray_destroy, + wgaim_tray_update_icon, + wgaim_tray_blank_icon, + wgaim_tray_set_tooltip, + NULL +}; + +/* Used by docklet's plugin load func */ +void docklet_ui_init() { + docklet_set_ui_ops(&wgaim_tray_ops); +} Copied: trunk/gtk/gtkdocklet-x11.c (from rev 17432, trunk/gtk/plugins/docklet/docklet-x11.c) =================================================================== --- trunk/gtk/gtkdocklet-x11.c (rev 0) +++ trunk/gtk/gtkdocklet-x11.c 2006-10-05 23:24:00 UTC (rev 17433) @@ -0,0 +1,305 @@ +/* + * System tray icon (aka docklet) plugin for Gaim + * + * Copyright (C) 2002-3 Robert McQueen <rob...@de...> + * Copyright (C) 2003 Herman Bloggs <her...@ya...> + * Inspired by a similar plugin by: + * John (J5) Palmieri <jo...@ma...> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "internal.h" +#include "gtkgaim.h" +#include "debug.h" +#include "gaimstock.h" + +#include "gaim.h" +#include "gtkdialogs.h" + +#include "eggtrayicon.h" +#include "gtkdocklet.h" + +#define EMBED_TIMEOUT 5000 + +/* globals */ +static EggTrayIcon *docklet = NULL; +static GtkWidget *image = NULL; +static GtkTooltips *tooltips = NULL; +static GdkPixbuf *blank_icon = NULL; +static int embed_timeout = 0; + +/* protos */ +static void docklet_x11_create(void); + +static gboolean +docklet_x11_create_cb() +{ + docklet_x11_create(); + + return FALSE; /* for when we're called by the glib idle handler */ +} + +static void +docklet_x11_embedded_cb(GtkWidget *widget, void *data) +{ + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "embedded\n"); + + g_source_remove(embed_timeout); + embed_timeout = 0; + gaim_gtk_docklet_embedded(); +} + +static void +docklet_x11_destroyed_cb(GtkWidget *widget, void *data) +{ + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "destroyed\n"); + + gaim_gtk_docklet_remove(); + + g_object_unref(G_OBJECT(docklet)); + docklet = NULL; + + g_idle_add(docklet_x11_create_cb, NULL); +} + +static void +docklet_x11_clicked_cb(GtkWidget *button, GdkEventButton *event, void *data) +{ + if (event->type != GDK_BUTTON_PRESS) + return; + + gaim_gtk_docklet_clicked(event->button); +} + +static void +docklet_x11_update_icon(DockletStatus icon) +{ + const gchar *icon_name = NULL; + + g_return_if_fail(image != NULL); + + switch (icon) { + case DOCKLET_STATUS_OFFLINE: + icon_name = GAIM_STOCK_ICON_OFFLINE; + break; + case DOCKLET_STATUS_CONNECTING: + icon_name = GAIM_STOCK_ICON_CONNECT; + break; + case DOCKLET_STATUS_ONLINE: + icon_name = GAIM_STOCK_ICON_ONLINE; + break; + case DOCKLET_STATUS_ONLINE_PENDING: + icon_name = GAIM_STOCK_ICON_ONLINE_MSG; + break; + case DOCKLET_STATUS_AWAY: + icon_name = GAIM_STOCK_ICON_AWAY; + break; + case DOCKLET_STATUS_AWAY_PENDING: + icon_name = GAIM_STOCK_ICON_AWAY_MSG; + break; + } + + if(icon_name) + gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); + +#if 0 + GdkPixbuf *p; + GdkBitmap *mask = NULL; + + p = gtk_widget_render_icon(GTK_WIDGET(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); + + if (p && (gdk_pixbuf_get_colorspace(p) == GDK_COLORSPACE_RGB) && (gdk_pixbuf_get_bits_per_sample(p) == 8) + && (gdk_pixbuf_get_has_alpha(p)) && (gdk_pixbuf_get_n_channels(p) == 4)) { + int len = gdk_pixbuf_get_width(p) * gdk_pixbuf_get_height(p); + guchar *data = gdk_pixbuf_get_pixels(p); + guchar *bitmap = g_malloc((len / 8) + 1); + int i; + + for (i = 0; i < len; i++) + if (data[i*4 + 3] > 55) + bitmap[i/8] |= 1 << i % 8; + else + bitmap[i/8] &= ~(1 << i % 8); + + mask = gdk_bitmap_create_from_data(GDK_DRAWABLE(GTK_WIDGET(image)->window), bitmap, gdk_pixbuf_get_width(p), gdk_pixbuf_get_height(p)); + g_free(bitmap); + } + + if (mask) + gdk_window_shape_combine_mask(image->window, mask, 0, 0); + + g_object_unref(G_OBJECT(p)); +#endif +} + +static void +docklet_x11_blank_icon() +{ + if (!blank_icon) { + gint width, height; + + gtk_icon_size_lookup(GTK_ICON_SIZE_LARGE_TOOLBAR, &width, &height); + blank_icon = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); + gdk_pixbuf_fill(blank_icon, 0); + } + + gtk_image_set_from_pixbuf(GTK_IMAGE(image), blank_icon); +} + +static void +docklet_x11_set_tooltip(gchar *tooltip) +{ + if (!tooltips) + tooltips = gtk_tooltips_new(); + + /* image->parent is a GtkEventBox */ + if (tooltip) { + gtk_tooltips_enable(tooltips); + gtk_tooltips_set_tip(tooltips, image->parent, tooltip, NULL); + } else { + gtk_tooltips_set_tip(tooltips, image->parent, "", NULL); + gtk_tooltips_disable(tooltips); + } +} + +#if GTK_CHECK_VERSION(2,2,0) +static void +docklet_x11_position_menu(GtkMenu *menu, int *x, int *y, gboolean *push_in, + gpointer user_data) +{ + GtkWidget *widget = GTK_WIDGET(docklet); + GtkRequisition req; + gint menu_xpos, menu_ypos; + + gtk_widget_size_request(GTK_WIDGET(menu), &req); + gdk_window_get_origin(widget->window, &menu_xpos, &menu_ypos); + + menu_xpos += widget->allocation.x; + menu_ypos += widget->allocation.y; + + if (menu_ypos > gdk_screen_get_height(gtk_widget_get_screen(widget)) / 2) + menu_ypos -= req.height; + else + menu_ypos += widget->allocation.height; + + *x = menu_xpos; + *y = menu_ypos; + + *push_in = TRUE; +} +#endif + +static void +docklet_x11_destroy() +{ + g_return_if_fail(docklet != NULL); + + gaim_gtk_docklet_remove(); + + g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_x11_destroyed_cb), NULL); + gtk_widget_destroy(GTK_WIDGET(docklet)); + + g_object_unref(G_OBJECT(docklet)); + docklet = NULL; + + if (blank_icon) + g_object_unref(G_OBJECT(blank_icon)); + blank_icon = NULL; + + image = NULL; + + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "destroyed\n"); +} + +static gboolean +docklet_x11_embed_timeout_cb() +{ + /* The docklet was not embedded within the timeout. + * Remove it as a visibility manager, but leave the plugin + * loaded so that it can embed automatically if/when a notification + * area becomes available. + */ + gaim_debug_info("tray icon", "failed to embed within timeout\n"); + gaim_gtk_docklet_remove(); + + return FALSE; +} + +static void +docklet_x11_create() +{ + GtkWidget *box; + + if (docklet) { + /* if this is being called when a tray icon exists, it's because + something messed up. try destroying it before we proceed, + although docklet_refcount may be all hosed. hopefully won't happen. */ + gaim_debug(GAIM_DEBUG_WARNING, "tray icon", "trying to create icon but it already exists?\n"); + docklet_x11_destroy(); + } + + docklet = egg_tray_icon_new("Gaim"); + box = gtk_event_box_new(); + image = gtk_image_new(); + + g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(docklet_x11_embedded_cb), NULL); + g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_x11_destroyed_cb), NULL); + g_signal_connect(G_OBJECT(box), "button-press-event", G_CALLBACK(docklet_x11_clicked_cb), NULL); + + gtk_container_add(GTK_CONTAINER(box), image); + gtk_container_add(GTK_CONTAINER(docklet), box); + + if (!gtk_check_version(2,4,0)) + g_object_set(G_OBJECT(box), "visible-window", FALSE, NULL); + + gtk_widget_show_all(GTK_WIDGET(docklet)); + + /* ref the docklet before we bandy it about the place */ + g_object_ref(G_OBJECT(docklet)); + + /* This is a hack to avoid a race condition between the docklet getting + * embedded in the notification area and the gtkblist restoring its + * previous visibility state. If the docklet does not get embedded within + * the timeout, it will be removed as a visibility manager until it does + * get embedded. Ideally, we would only call docklet_embedded() when the + * icon was actually embedded. + */ + gaim_gtk_docklet_embedded(); + embed_timeout = g_timeout_add(EMBED_TIMEOUT, docklet_x11_embed_timeout_cb, NULL); + + gaim_debug(GAIM_DEBUG_INFO, "tray icon", "created\n"); +} + +static struct docklet_ui_ops ui_ops = +{ + docklet_x11_create, + docklet_x11_destroy, + docklet_x11_update_icon, + docklet_x11_blank_icon, + docklet_x11_set_tooltip, +#if GTK_CHECK_VERSION(2,2,0) + docklet_x11_position_menu +#else + NULL +#endif +}; + +void +docklet_ui_init() +{ + gaim_gtk_docklet_set_ui_ops(&ui_ops); +} Copied: trunk/gtk/gtkdocklet.c (from rev 17432, trunk/gtk/plugins/docklet/docklet.c) =================================================================== --- trunk/gtk/gtkdocklet.c (rev 0) +++ trunk/gtk/gtkdocklet.c 2006-10-05 23:24:00 UTC (rev 17433) @@ -0,0 +1,694 @@ +/* + * System tray icon (aka docklet) plugin for Gaim + * + * Copyright (C) 2002-3 Robert McQueen <rob...@de...> + * Copyright (C) 2003 Herman Bloggs <her...@ya...> + * Inspired by a similar plugin by: + * John (J5) Palmieri <jo...@ma...> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include "internal.h" +#include "gtkgaim.h" + +#include "core.h" +#include "conversation.h" +#include "debug.h" +#include "prefs.h" +#include "signals.h" +#include "sound.h" +#include "version.h" + +#include "gtkaccount.h" +#include "gtkblist.h" +#include "gtkconv.h" +#include "gtkft.h" +#include "gtkplugin.h" +#include "gtkprefs.h" +#include "gtksavedstatuses.h" +#include "gtksound.h" +#include "gtkutils.h" +#include "gaimstock.h" +#include "gtkdocklet.h" + +#include "gaim.h" +#include "gtkdialogs.h" + +#ifndef DOCKLET_TOOLTIP_LINE_LIMIT +#define DOCKLET_TOOLTIP_LINE_LIMIT 5 +#endif + +/* globals */ +static struct docklet_ui_ops *ui_ops = NULL; +static DockletStatus status = DOCKLET_STATUS_OFFLINE; +static gboolean enable_join_chat = FALSE; +static guint docklet_blinking_timer = 0; +static gboolean visibility_manager = FALSE; + +/************************************************************************** + * docklet status and utility functions + **************************************************************************/ +static gboolean +docklet_blink_icon() +{ + static gboolean blinked = FALSE; + gboolean ret = FALSE; /* by default, don't keep blinking */ + + blinked = !blinked; + + switch (status) { + case DOCKLET_STATUS_ONLINE_PENDING: + case DOCKLET_STATUS_AWAY_PENDING: + if (blinked) { + if (ui_ops && ui_ops->blank_icon) + ui_ops->blank_icon(); + } else { + if (ui_ops && ui_ops->update_icon) + ui_ops->update_icon(status); + } + ret = TRUE; /* keep blinking */ + break; + default: + docklet_blinking_timer = 0; + blinked = FALSE; + break; + } + + return ret; +} + +static GList * +get_pending_list(guint max) +{ + const char *im = gaim_prefs_get_string("/plugins/gtk/docklet/blink_im"); + const char *chat = gaim_prefs_get_string("/plugins/gtk/docklet/blink_chat"); + GList *l_im = NULL; + GList *l_chat = NULL; + + if (im != NULL && strcmp(im, "always") == 0) { + l_im = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_IM, + GAIM_UNSEEN_TEXT, + FALSE, max); + } else if (im != NULL && strcmp(im, "hidden") == 0) { + l_im = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_IM, + GAIM_UNSEEN_TEXT, + TRUE, max); + } + + if (chat != NULL && strcmp(chat, "always") == 0) { + l_chat = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_CHAT, + GAIM_UNSEEN_TEXT, + FALSE, max); + } else if (chat != NULL && strcmp(chat, "nick") == 0) { + l_chat = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_CHAT, + GAIM_UNSEEN_NICK, + FALSE, max); + } + + if (l_im != NULL && l_chat != NULL) + return g_list_concat(l_im, l_chat); + else if (l_im != NULL) + return l_im; + else + return l_chat; +} + +static gboolean +docklet_update_status() +{ + GList *convs; + GList *l; + int count; + DockletStatus newstatus = DOCKLET_STATUS_OFFLINE; + gboolean pending = FALSE; + + /* determine if any ims have unseen messages */ + convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT); + + if (convs != NULL) { + pending = TRUE; + + /* set tooltip if messages are pending */ + if (ui_ops->set_tooltip) { + GString *tooltip_text = g_string_new(""); + for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) { + if (GAIM_IS_GTK_CONVERSATION(l->data)) { + GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION((GaimConversation *)l->data); + if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) + g_string_append(tooltip_text, _("Right-click for more unread messages...\n")); + else + g_string_append_printf(tooltip_text, + ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count), + gtkconv->unseen_count, + gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); + } + } + + /* get rid of the last newline */ + if (tooltip_text->len > 0) + tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1); + + ui_ops->set_tooltip(tooltip_text->str); + + g_string_free(tooltip_text, TRUE); + } + + g_list_free(convs); + + } else if (ui_ops->set_tooltip) { + ui_ops->set_tooltip(NULL); + } + + /* iterate through all accounts and determine which + * status to show in the tray icon based on the following + * ranks (highest encountered rank will be used): + * + * 1) OFFLINE + * 2) ONLINE + * 3) ONLINE_PENDING + * 4) AWAY + * 5) AWAY_PENDING + * 6) CONNECTING + */ + for(l = gaim_accounts_get_all(); l != NULL; l = l->next) { + DockletStatus tmpstatus = DOCKLET_STATUS_OFFLINE; + + GaimAccount *account = (GaimAccount*)l->data; + GaimStatus *account_status; + + if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) + continue; + + if (gaim_account_is_disconnected(account)) + continue; + + account_status = gaim_account_get_active_status(account); + + if (gaim_account_is_connecting(account)) { + tmpstatus = DOCKLET_STATUS_CONNECTING; + } else if (gaim_status_is_online(account_status)) { + if (!gaim_status_is_available(account_status)) { + if (pending) + tmpstatus = DOCKLET_STATUS_AWAY_PENDING; + else + tmpstatus = DOCKLET_STATUS_AWAY; + } + else { + if (pending) + tmpstatus = DOCKLET_STATUS_ONLINE_PENDING; + else + tmpstatus = DOCKLET_STATUS_ONLINE; + } + } + + if (tmpstatus > newstatus) + newstatus = tmpstatus; + } + + /* update the icon if we changed status */ + if (status != newstatus) { + status = newstatus; + + if (ui_ops && ui_ops->update_icon) + ui_ops->update_icon(status); + + /* and schedule the blinker function if messages are pending */ + if ((status == DOCKLET_STATUS_ONLINE_PENDING + || status == DOCKLET_STATUS_AWAY_PENDING) + && docklet_blinking_timer == 0) { + docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL); + } + } + + return FALSE; /* for when we're called by the glib idle handler */ +} + +static gboolean +online_account_supports_chat() +{ + GList *c = NULL; + c = gaim_connections_get_all(); + + while(c != NULL) { + GaimConnection *gc = c->data; + GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); + if (prpl_info != NULL && prpl_info->chat_info != NULL) + return TRUE; + c = c->next; + } + + return FALSE; +} + +/************************************************************************** + * callbacks and signal handlers + **************************************************************************/ +static void +gaim_quit_cb() +{ + /* TODO: confirm quit while pending */ +} + +static void +docklet_update_status_cb(void *data) +{ + docklet_update_status(); +} + +static void +docklet_prefs_cb(const char *name, GaimPrefType type, + gconstpointer val, gpointer data) +{ + docklet_update_status(); +} + +static void +docklet_conv_updated_cb(GaimConversation *conv, GaimConvUpdateType type) +{ + if (type == GAIM_CONV_UPDATE_UNSEEN) + docklet_update_status(); +} + +static void +docklet_signed_on_cb(GaimConnection *gc) +{ + if (!enable_join_chat) { + if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) + enable_join_chat = TRUE; + } + docklet_update_status(); +} + +static void +docklet_signed_off_cb(GaimConnection *gc) +{ + if (enable_join_chat) { + if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) + enable_join_chat = online_account_supports_chat(); + } + docklet_update_status(); +} + +/************************************************************************** + * docklet pop-up menu + **************************************************************************/ +static void +docklet_toggle_mute(GtkWidget *toggle, void *data) +{ + gaim_prefs_set_bool("/gaim/gtk/sound/mute", GTK_CHECK_MENU_ITEM(toggle)->active); +} + +static void +docklet_toggle_blist(GtkWidget *toggle, void *data) +{ + gaim_blist_set_visible(GTK_CHECK_MENU_ITEM(toggle)->active); +} + +#ifdef _WIN32 +/* This is a workaround for a bug in windows GTK+. Clicking outside of the + menu does not get rid of it, so instead we get rid of it as soon as the + pointer leaves the menu. */ +static gboolean +hide_docklet_menu(gpointer data) +{ + if (data != NULL) { + gtk_menu_popdown(GTK_MENU(data)); + } + return FALSE; +} + +static gboolean +docklet_menu_leave_enter(GtkWidget *menu, GdkEventCrossing *event, void *data) +{ + static guint hide_docklet_timer = 0; + if (event->type == GDK_LEAVE_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) { + gaim_debug(GAIM_DEBUG_INFO, "docklet", "menu leave-notify-event\n"); + /* Add some slop so that the menu doesn't annoyingly disappear when mousing around */ + if (hide_docklet_timer == 0) { + hide_docklet_timer = gaim_timeout_add(500, + hide_docklet_menu, menu); + } + } else if (event->type == GDK_ENTER_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) { + gaim_debug(GAIM_DEBUG_INFO, "docklet", "menu enter-notify-event\n"); + if (hide_docklet_timer != 0) { + /* Cancel the hiding if we reenter */ + + gaim_timeout_remove(hide_docklet_timer); + hide_docklet_timer = 0; + } + } + return FALSE; +} +#endif + +static void +show_custom_status_editor_cb(GtkMenuItem *menuitem, gpointer user_data) +{ + GaimSavedStatus *saved_status; + saved_status = gaim_savedstatus_get_current(); + gaim_gtk_status_editor_show(FALSE, + gaim_savedstatus_is_transient(saved_status) ? saved_status : NULL); +} + +static void +activate_status_primitive_cb(GtkMenuItem *menuitem, gpointer user_data) +{ + GaimStatusPrimitive primitive; + GaimSavedStatus *saved_status; + + primitive = GPOINTER_TO_INT(user_data); + + /* Try to lookup an already existing transient saved status */ + saved_status = gaim_savedstatus_find_transient_by_type_and_message(primitive, NULL); + + /* Create a new transient saved status if we weren't able to find one */ + if (saved_status == NULL) + saved_status = gaim_savedstatus_new(NULL, primitive); + + /* Set the status for each account */ + gaim_savedstatus_activate(saved_status); +} + +static void +activate_saved_status_cb(GtkMenuItem *menuitem, gpointer user_data) +{ + time_t creation_time; + GaimSavedStatus *saved_status; + + creation_time = GPOINTER_TO_INT(user_data); + saved_status = gaim_savedstatus_find_by_creation_time(creation_time); + if (saved_status != NULL) + gaim_savedstatus_activate(saved_status); +} + +static GtkWidget * +new_menu_item_with_gaim_icon(GtkWidget *menu, const char *str, GaimStatusPrimitive primitive, GtkSignalFunc sf, gpointer data, guint accel_key, guint accel_mods, char *mod) +{ + GtkWidget *menuitem; + GdkPixbuf *pixbuf; + GtkWidget *image; + + menuitem = gtk_image_menu_item_new_with_mnemonic(str); + + if (menu) + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + if (sf) + g_signal_connect(G_OBJECT(menuitem), "activate", sf, data); + + pixbuf = gaim_gtk_create... [truncated message content] |
From: <sa...@us...> - 2006-10-04 20:31:48
|
Revision: 17432 http://svn.sourceforge.net/gaim/?rev=17432&view=rev Author: sadrul Date: 2006-10-04 13:31:44 -0700 (Wed, 04 Oct 2006) Log Message: ----------- If exiting, print a more helpful error message. I once got an "Invalid file descriptor" (or something similar) once, which I don't know why would happen. Modified Paths: -------------- trunk/console/libgnt/gntmain.c Modified: trunk/console/libgnt/gntmain.c =================================================================== --- trunk/console/libgnt/gntmain.c 2006-10-04 19:05:22 UTC (rev 17431) +++ trunk/console/libgnt/gntmain.c 2006-10-04 20:31:44 UTC (rev 17432) @@ -772,7 +772,8 @@ if (rd < 0) { endwin(); - printf("ERROR!\n"); + printf("ERROR: %s\n", strerror(errno)); + printf("File descriptor is: %d\n\nGIOChannel is: %p", STDIN_FILENO, source); exit(1); } else if (rd == 0) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-10-04 19:05:26
|
Revision: 17431 http://svn.sourceforge.net/gaim/?rev=17431&view=rev Author: seanegan Date: 2006-10-04 12:05:22 -0700 (Wed, 04 Oct 2006) Log Message: ----------- drop shadow on those images Modified Paths: -------------- web/htdocs/sean/images/gtkimhtmlsmall.png web/htdocs/sean/images/gtkimhtmlsmaller.png Modified: web/htdocs/sean/images/gtkimhtmlsmall.png =================================================================== (Binary files differ) Modified: web/htdocs/sean/images/gtkimhtmlsmaller.png =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-10-04 18:39:44
|
Revision: 17430 http://svn.sourceforge.net/gaim/?rev=17430&view=rev Author: seanegan Date: 2006-10-04 11:39:39 -0700 (Wed, 04 Oct 2006) Log Message: ----------- I ?\226?\153?\161 <center> Modified Paths: -------------- web/htdocs/sean/posts/font-sizes.txt Modified: web/htdocs/sean/posts/font-sizes.txt =================================================================== --- web/htdocs/sean/posts/font-sizes.txt 2006-10-04 18:35:45 UTC (rev 17429) +++ web/htdocs/sean/posts/font-sizes.txt 2006-10-04 18:39:39 UTC (rev 17430) @@ -11,16 +11,16 @@ ensure their buddies' messages are always legible, but in Gaim 2.0.0, we've replaced this with a "Ignore incoming formatting" option, which also turns off colors and font styles.</p> - +<center> <img src='http://gaim.sf.net/sean/images/gtkimhtmlsmaller.png' align='center'/> - +</center> <p>I thought about adding a feature to let you easily adjust the size of the conversation font, but today, I submitted some code that I hope solves the root of the problem. In previous versions of Gaim, a "smaller" font was about 83% the size of the normal font, and the "smallest" was about 69%. I've changed these numbers to 95% and 85% respectively.</p> - +<center> <img src='http://gaim.sf.net/sean/images/gtkimhtmlsmall.png' align='center'/> - +</center> <p>If you've been bothered by fonts in Gaim being too small before, I hope you give this a try and let me know if this is a good solution.</p> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-10-04 18:35:52
|
Revision: 17429 http://svn.sourceforge.net/gaim/?rev=17429&view=rev Author: seanegan Date: 2006-10-04 11:35:45 -0700 (Wed, 04 Oct 2006) Log Message: ----------- Another blog post Added Paths: ----------- web/htdocs/sean/images/gtkimhtmlsmall.png web/htdocs/sean/images/gtkimhtmlsmaller.png web/htdocs/sean/posts/font-sizes.txt Added: web/htdocs/sean/images/gtkimhtmlsmall.png =================================================================== (Binary files differ) Property changes on: web/htdocs/sean/images/gtkimhtmlsmall.png ___________________________________________________________________ Name: svn:mime-type + image/png Added: web/htdocs/sean/images/gtkimhtmlsmaller.png =================================================================== (Binary files differ) Property changes on: web/htdocs/sean/images/gtkimhtmlsmaller.png ___________________________________________________________________ Name: svn:mime-type + image/png Added: web/htdocs/sean/posts/font-sizes.txt =================================================================== --- web/htdocs/sean/posts/font-sizes.txt (rev 0) +++ web/htdocs/sean/posts/font-sizes.txt 2006-10-04 18:35:45 UTC (rev 17429) @@ -0,0 +1,26 @@ +Font Sizes +<p>Another one of those questions I get asked several times a day is "how do I +make the font size in the conversation window larger." Like the buddy list +indentation I mentioned in earlier post to this blog, this is another thing +controlled by an obscure setting that has to be manually set in a text file +somewhere.</p> + +<p>It turns out that people asking this question almost always want one thing: +that when someone IMs them formatted text, that it not appear too small. In the +past, people have used the "Ignore incoming font sizes" option in Gaim to +ensure their buddies' messages are always legible, but in Gaim 2.0.0, we've +replaced this with a "Ignore incoming formatting" option, which also turns off +colors and font styles.</p> + +<img src='http://gaim.sf.net/sean/images/gtkimhtmlsmaller.png' align='center'/> + +<p>I thought about adding a feature to let you easily adjust the size of the +conversation font, but today, I submitted some code that I hope solves the +root of the problem. In previous versions of Gaim, a "smaller" font was about +83% the size of the normal font, and the "smallest" was about 69%. I've changed +these numbers to 95% and 85% respectively.</p> + +<img src='http://gaim.sf.net/sean/images/gtkimhtmlsmall.png' align='center'/> + +<p>If you've been bothered by fonts in Gaim being too small before, I hope +you give this a try and let me know if this is a good solution.</p> Property changes on: web/htdocs/sean/posts/font-sizes.txt ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-10-04 18:13:24
|
Revision: 17428 http://svn.sourceforge.net/gaim/?rev=17428&view=rev Author: seanegan Date: 2006-10-04 11:13:22 -0700 (Wed, 04 Oct 2006) Log Message: ----------- Make smaller fonts less small Modified Paths: -------------- trunk/gtk/gtkimhtml.c Modified: trunk/gtk/gtkimhtml.c =================================================================== --- trunk/gtk/gtkimhtml.c 2006-10-04 12:31:26 UTC (rev 17427) +++ trunk/gtk/gtkimhtml.c 2006-10-04 18:13:22 UTC (rev 17428) @@ -120,7 +120,7 @@ /* POINT_SIZE converts from AIM font sizes to a point size scale factor. */ #define MAX_FONT_SIZE 7 #define POINT_SIZE(x) (_point_sizes [MIN ((x > 0 ? x : 1), MAX_FONT_SIZE) - 1]) -static gdouble _point_sizes [] = { .69444444, .8333333, 1, 1.2, 1.44, 1.728, 2.0736}; +static gdouble _point_sizes [] = { .85, .95, 1, 1.2, 1.44, 1.728, 2.0736}; enum { TARGET_HTML, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fac...@us...> - 2006-10-04 12:31:39
|
Revision: 17427 http://svn.sourceforge.net/gaim/?rev=17427&view=rev Author: faceprint Date: 2006-10-04 05:31:26 -0700 (Wed, 04 Oct 2006) Log Message: ----------- fix this error Modified Paths: -------------- trunk/libgaim/protocols/jabber/si.c Modified: trunk/libgaim/protocols/jabber/si.c =================================================================== --- trunk/libgaim/protocols/jabber/si.c 2006-10-04 05:18:04 UTC (rev 17426) +++ trunk/libgaim/protocols/jabber/si.c 2006-10-04 12:31:26 UTC (rev 17427) @@ -135,7 +135,7 @@ if(!jsx->streamhosts) { JabberIq *iq = jabber_iq_new(jsx->js, JABBER_IQ_ERROR); - xmlnode *error, *condition; + xmlnode *error, *inf; if(jsx->iq_id) jabber_iq_set_id(iq, jsx->iq_id); @@ -144,9 +144,8 @@ error = xmlnode_new_child(iq->node, "error"); xmlnode_set_attrib(error, "code", "404"); xmlnode_set_attrib(error, "type", "cancel"); - condition = xmlnode_new_child(error, "condition"); - xmlnode_set_namespace(condition, "urn:ietf:params:xml:ns:xmpp-stanzas"); - xmlnode_new_child(condition, "item-not-found"); + inf = xmlnode_new_child(error, "item-not-found"); + xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas"); jabber_iq_send(iq); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dat...@us...> - 2006-10-04 05:18:08
|
Revision: 17426 http://svn.sourceforge.net/gaim/?rev=17426&view=rev Author: datallah Date: 2006-10-03 22:18:04 -0700 (Tue, 03 Oct 2006) Log Message: ----------- Added the ability to choose primitive statuses for Away/Idle and Startup, I also added pretty icons while I was at it. This was all pretty much ripped from the status box. It turns out this was a ton simpler than trying to reuse the statusbox itself. Modified Paths: -------------- trunk/gtk/gtksavedstatuses.c Modified: trunk/gtk/gtksavedstatuses.c =================================================================== --- trunk/gtk/gtksavedstatuses.c 2006-10-04 02:32:17 UTC (rev 17425) +++ trunk/gtk/gtksavedstatuses.c 2006-10-04 05:18:04 UTC (rev 17426) @@ -1537,19 +1537,61 @@ * Utilities * **************************************************************************/ +enum { + SS_MENU_ENTRY_TYPE_PRIMITIVE, + SS_MENU_ENTRY_TYPE_SAVEDSTATUS +}; + +enum { + /** _SSMenuEntryType */ + SS_MENU_TYPE_COLUMN, + + /** + * This is a GdkPixbuf (the other columns are strings). + * This column is visible. + */ + SS_MENU_ICON_COLUMN, + + /** The text displayed on the status box. This column is visible. */ + SS_MENU_TEXT_COLUMN, + + /* + * This value depends on SS_MENU_TYPE_COLUMN. For _SAVEDSTATUS types, + * this is the creation time. For _PRIMITIVE types, + * this is the GaimStatusPrimitive. + */ + SS_MENU_DATA_COLUMN, + + SS_MENU_NUM_COLUMNS +}; + static void status_menu_cb(GtkComboBox *widget, void(*callback)(GaimSavedStatus*)) { GtkTreeIter iter; - gchar *title = NULL; + int type; + gpointer data; + GaimSavedStatus *status = NULL; if (!gtk_combo_box_get_active_iter(widget, &iter)) return; gtk_tree_model_get(gtk_combo_box_get_model(widget), &iter, - STATUS_WINDOW_COLUMN_TITLE, &title, -1); - callback(gaim_savedstatus_find(title)); - g_free(title); + SS_MENU_TYPE_COLUMN, &type, + SS_MENU_DATA_COLUMN, &data, + -1); + + if (type == SS_MENU_ENTRY_TYPE_PRIMITIVE) + { + GaimStatusPrimitive primitive = GPOINTER_TO_INT(data); + status = gaim_savedstatus_find_transient_by_type_and_message(primitive, NULL); + if (status == NULL) + status = gaim_savedstatus_new(NULL, primitive); + } + else if (type == SS_MENU_ENTRY_TYPE_SAVEDSTATUS) + status = gaim_savedstatus_find_by_creation_time(GPOINTER_TO_INT(data)); + + callback(status); } static gint @@ -1561,26 +1603,93 @@ gaim_savedstatus_get_title(saved_status_b)); } +static gboolean gaim_gtk_status_menu_add_primitive(GtkListStore *model, GaimStatusPrimitive primitive, + GaimSavedStatus *current_status) +{ + GtkTreeIter iter; + gboolean currently_selected = FALSE; + GdkPixbuf *pixbuf = gaim_gtk_create_gaim_icon_with_status(primitive, 0.5); + + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, + SS_MENU_TYPE_COLUMN, SS_MENU_ENTRY_TYPE_PRIMITIVE, + SS_MENU_ICON_COLUMN, pixbuf, + SS_MENU_TEXT_COLUMN, gaim_primitive_get_name_from_type(primitive), + SS_MENU_DATA_COLUMN, GINT_TO_POINTER(primitive), + -1); + + if (gaim_savedstatus_is_transient(current_status) + && !gaim_savedstatus_has_substatuses(current_status) + && gaim_savedstatus_get_type(current_status) == primitive) + currently_selected = TRUE; + + return currently_selected; +} + GtkWidget *gaim_gtk_status_menu(GaimSavedStatus *current_status, GCallback callback) { GtkWidget *combobox; + GtkListStore *model; GList *sorted, *cur; - int i; + int i = 0; int index = -1; + GdkPixbuf *pixbuf, *emblem; + GtkTreeIter iter; + GtkCellRenderer *text_rend; + GtkCellRenderer *icon_rend; - combobox = gtk_combo_box_new_text(); + model = gtk_list_store_new(SS_MENU_NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER); + combobox = gtk_combo_box_new(); + + if (gaim_gtk_status_menu_add_primitive(model, GAIM_STATUS_AVAILABLE, current_status)) + index = i; + i++; + + if (gaim_gtk_status_menu_add_primitive(model, GAIM_STATUS_AWAY, current_status)) + index = i; + i++; + + if (gaim_gtk_status_menu_add_primitive(model, GAIM_STATUS_INVISIBLE, current_status)) + index = i; + i++; + + if (gaim_gtk_status_menu_add_primitive(model, GAIM_STATUS_OFFLINE, current_status)) + index = i; + i++; + sorted = g_list_copy((GList *)gaim_savedstatuses_get_all()); sorted = g_list_sort(sorted, saved_status_sort_alphabetically_func); - for (cur = sorted, i = 0; - cur != NULL; - cur = g_list_next(cur)) + for (cur = sorted; cur; cur = cur->next) { - GaimSavedStatus *status = (GaimSavedStatus *)cur->data; + GaimSavedStatus *status = (GaimSavedStatus *) cur->data; if (!gaim_savedstatus_is_transient(status)) { - gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), - gaim_savedstatus_get_title(status)); + /* Get an appropriate status icon */ + pixbuf = gaim_gtk_create_gaim_icon_with_status( + gaim_savedstatus_get_type(status), 0.5); + + /* Overlay a disk in the bottom left corner */ + emblem = gtk_widget_render_icon(GTK_WIDGET(combobox), + GTK_STOCK_SAVE, GTK_ICON_SIZE_MENU, "GtkGaimStatusMenu"); + if (emblem != NULL) + { + int width = gdk_pixbuf_get_width(pixbuf) / 2; + int height = gdk_pixbuf_get_height(pixbuf) / 2; + gdk_pixbuf_composite(emblem, pixbuf, 0, height, + width, height, 0, height, + 0.5, 0.5, GDK_INTERP_BILINEAR, 255); + g_object_unref(G_OBJECT(emblem)); + } + + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, + SS_MENU_TYPE_COLUMN, SS_MENU_ENTRY_TYPE_SAVEDSTATUS, + SS_MENU_ICON_COLUMN, pixbuf, + SS_MENU_TEXT_COLUMN, gaim_savedstatus_get_title(status), + SS_MENU_DATA_COLUMN, GINT_TO_POINTER(gaim_savedstatus_get_creation_time(status)), + -1); + if (status == current_status) index = i; i++; @@ -1588,6 +1697,16 @@ } g_list_free(sorted); + gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(model)); + + text_rend = gtk_cell_renderer_text_new(); + icon_rend = gtk_cell_renderer_pixbuf_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), icon_rend, FALSE); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), text_rend, TRUE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), icon_rend, "pixbuf", SS_MENU_ICON_COLUMN, NULL); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), text_rend, "markup", SS_MENU_TEXT_COLUMN, NULL); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), index); g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(status_menu_cb), callback); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |