From: <ro...@us...> - 2006-06-17 02:11:38
|
Revision: 16272 Author: roast Date: 2006-06-16 19:11:13 -0700 (Fri, 16 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16272&view=rev Log Message: ----------- merged with svn trunk, r16271 Modified Paths: -------------- branches/soc-2006-file-loggers/Makefile.mingw branches/soc-2006-file-loggers/config.h.mingw branches/soc-2006-file-loggers/configure.ac branches/soc-2006-file-loggers/gaim-installer.nsi branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO branches/soc-2006-file-loggers/plugins/tcl/Makefile.am branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw branches/soc-2006-file-loggers/plugins/tcl/tcl.c branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c branches/soc-2006-file-loggers/src/Makefile.am branches/soc-2006-file-loggers/src/Makefile.mingw branches/soc-2006-file-loggers/src/gtkblist.c branches/soc-2006-file-loggers/src/gtkdialogs.c branches/soc-2006-file-loggers/src/gtkutils.h branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.am branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.mingw branches/soc-2006-file-loggers/src/protocols/jabber/auth.c branches/soc-2006-file-loggers/src/protocols/jabber/buddy.c branches/soc-2006-file-loggers/src/protocols/jabber/chat.c branches/soc-2006-file-loggers/src/protocols/jabber/disco.c branches/soc-2006-file-loggers/src/protocols/jabber/iq.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c branches/soc-2006-file-loggers/src/protocols/jabber/jabber.h branches/soc-2006-file-loggers/src/protocols/jabber/message.c branches/soc-2006-file-loggers/src/protocols/jabber/oob.c branches/soc-2006-file-loggers/src/protocols/jabber/parser.c branches/soc-2006-file-loggers/src/protocols/jabber/presence.c branches/soc-2006-file-loggers/src/protocols/jabber/roster.c branches/soc-2006-file-loggers/src/protocols/jabber/si.c branches/soc-2006-file-loggers/src/protocols/jabber/xdata.c branches/soc-2006-file-loggers/src/protocols/msn/userlist.c branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.c branches/soc-2006-file-loggers/src/xmlnode.c branches/soc-2006-file-loggers/src/xmlnode.h Modified: branches/soc-2006-file-loggers/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272) @@ -12,6 +12,7 @@ GAIM_SOUNDS = ./sounds GAIM_INSTALL_DIR = ./win32-install-dir GTKSPELL_TOP = ../win32-dev/gtkspell-2.0.6/gtkspell +LIBXML2_DIR = ../win32-dev/libxml2 IDLETRACK_TOP = $(GAIM_SRC)/win32/IdleTracker GTKRC_TOP = ../win32-dev/gtkrc OSCAR = $(GAIM_PROTOS)/oscar @@ -33,7 +34,8 @@ VERSION := $(shell cat ./VERSION) NEEDED_DLLS = $(GTKSPELL_TOP)/libgtkspell.dll \ - $(IDLETRACK_TOP)/idletrack.dll + $(IDLETRACK_TOP)/idletrack.dll \ + $(LIBXML2_DIR)/bin/libxml2.dll SOUNDS = $(GAIM_SOUNDS)/alert.wav \ $(GAIM_SOUNDS)/login.wav \ Modified: branches/soc-2006-file-loggers/config.h.mingw =================================================================== --- branches/soc-2006-file-loggers/config.h.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/config.h.mingw 2006-06-17 02:11:13 UTC (rev 16272) @@ -635,6 +635,8 @@ <inttypes.h> don't define. */ /* #undef uintmax_t */ +#define HAVE_LIBXML 1 + /* * Following are added for Win32 version of Gaim */ Modified: branches/soc-2006-file-loggers/configure.ac =================================================================== --- branches/soc-2006-file-loggers/configure.ac 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/configure.ac 2006-06-17 02:11:13 UTC (rev 16272) @@ -171,6 +171,18 @@ AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for making sounds]) fi +dnl ################# +dnl # LibXML2 +dnl ################# +enable_libxml2=yes +PKG_CHECK_MODULES(LIBXML, libxml-2.0, ,enable_libxml2=no) +AC_SUBST(LIBXML_CFLAGS) +AC_SUBST(LIBXML_LIBS) +AC_ARG_ENABLE(libxml,[ --disable-libxml compile without libxml2 support],enable_libxml2=no) +if test "x$enable_libxml2" = "xyes"; then + AC_DEFINE(HAVE_LIBXML, 1, [Use libxml2 for xml parsing]) +fi + dnl ####################################################################### dnl # Check for Meanwhile headers (for Sametime) dnl ####################################################################### @@ -306,8 +318,8 @@ dnl ####################################################################### dnl # Check for Gadu-Gadu client includes and libraries dnl ####################################################################### -AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the GaduGadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"]) -AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the GaduGadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"]) +AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the Gadu-Gadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"]) +AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the Gadu-Gadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"]) GADU_CFLAGS="" GADU_LIBS="" if test -n "$with_gadu_includes" || test -n "$with_gadu_libs"; then @@ -1060,7 +1072,7 @@ dnl These two are inverses of each other <-- stolen from evolution! AC_ARG_ENABLE(gnutls, - [ --enable-gnutls=[yes,no] attempt to use GNUTLS for SSL support (preferred) [default=yes]], + [ --enable-gnutls=[yes,no] attempt to use GnuTLS for SSL support (preferred) [default=yes]], [enable_gnutls="$enableval"], [enable_gnutls="yes"]) @@ -1072,14 +1084,14 @@ msg_ssl="None (MSN will not work without SSL!)" dnl # -dnl # Check for GNUTLS if it's specified. +dnl # Check for GnuTLS if it's specified. dnl # if test "x$enable_gnutls" != "xno"; then enable_gnutls="no" prefix=`eval echo $prefix` AC_ARG_WITH(gnutls-includes, - [ --with-gnutls-includes=PREFIX location of GNUTLS includes.], + [ --with-gnutls-includes=PREFIX location of GnuTLS includes.], [ with_gnutls_includes="$withval" ], [ with_gnutls_includes="$prefix/include" ]) @@ -1088,7 +1100,7 @@ if test "x$with_gnutls_includes" != "xno"; then CPPFLAGS_save="$CPPFLAGS" - AC_MSG_CHECKING(for GNUTLS includes) + AC_MSG_CHECKING(for GnuTLS includes) AC_MSG_RESULT("") CPPFLAGS="$CPPFLAGS -I$with_gnutls_includes" @@ -1104,12 +1116,12 @@ GNUTLS_CFLAGS="" fi else - AC_MSG_CHECKING(for GNUTLS includes) + AC_MSG_CHECKING(for GnuTLS includes) AC_MSG_RESULT(no) fi AC_ARG_WITH(gnutls-libs, - [ --with-gnutls-libs=PREFIX location of GNUTLS libraries.], + [ --with-gnutls-libs=PREFIX location of GnuTLS libraries.], [ with_gnutls_libs="$withval" ]) if test "x$with_gnutls_libs" != "xno" -a \ @@ -1122,7 +1134,7 @@ *) with_gnutls_libs="-L$with_gnutls_libs" ;; esac - AC_CACHE_CHECK([for GNUTLS libraries], gnutls_libs, + AC_CACHE_CHECK([for GnuTLS libraries], gnutls_libs, [ LDFLAGS="$LDFLAGS $with_gnutls_libs -lgnutls -lgcrypt" AC_TRY_LINK_FUNC(gnutls_init, gnutls_libs="yes", gnutls_libs="no") @@ -1130,9 +1142,9 @@ ]) if test "x$gnutls_libs" != "xno"; then - AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GNUTLS]) + AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS]) AC_DEFINE(HAVE_SSL) - msg_gnutls="GNUTLS" + msg_gnutls="GnuTLS" GNUTLS_LIBS="$with_gnutls_libs -lgnutls -lgcrypt" enable_gnutls="yes" @@ -1141,7 +1153,7 @@ GNUTLS_LIBS="" fi else - AC_MSG_CHECKING(for GNUTLS libraries) + AC_MSG_CHECKING(for GnuTLS libraries) AC_MSG_RESULT(no) fi else @@ -1156,7 +1168,7 @@ dnl # -dnl # Check for NSS if it's specified, or if GNUTLS checks failed. +dnl # Check for NSS if it's specified, or if GnuTLS checks failed. dnl # if test "x$enable_nss" != "xno"; then @@ -1785,6 +1797,7 @@ eval echo DBUS servies directory........ : $DBUS_SERVICES_DIR fi echo Build with Cyrus SASL support. : $enable_cyrus_sasl +echo Build with libxml2 support.... : $enable_libxml2 echo Has you....................... : yes echo echo Modified: branches/soc-2006-file-loggers/gaim-installer.nsi =================================================================== --- branches/soc-2006-file-loggers/gaim-installer.nsi 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/gaim-installer.nsi 2006-06-17 02:11:13 UTC (rev 16272) @@ -744,6 +744,7 @@ Delete "$INSTDIR\idletrack.dll" Delete "$INSTDIR\libgtkspell.dll" Delete "$INSTDIR\libmeanwhile-1.dll" + Delete "$INSTDIR\libxml2.dll" Delete "$INSTDIR\nspr4.dll" Delete "$INSTDIR\nss3.dll" Delete "$INSTDIR\nssckbi.dll" Modified: branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO =================================================================== --- branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO 2006-06-17 02:11:13 UTC (rev 16272) @@ -4,10 +4,8 @@ Version 0.60 of Gaim brings up all themable smileys. In the preferences dialog, a user can choose from a selection of looks his smileys will take. This guide is to serve as a reference to those interested in creating third-party smiley themes. -(SME: I'm doing this at 6:30AM; I'm tired, but I can't sleep. Someone make sure I fix this up to make sure it all makes sense when I'm not tired anymore. Right now it's mostly just unassembled thoughts) +Your theme should be contained in a single directory. This directory will be installed in the Gaim smiley theme directory ($HOME/.gaim/smileys/). This directory will contain a file called `theme' that specifies the theme metadata and image files that are used by the theme. The format of the `theme' file is as follows. -Your theme should be contained in a single directory. This directory will be installed in the Gaim smiley theme directory (SME: There should probably be a $HOME/.gaim/smileys/ that the theme could go in too.). This directory will contain a file called `theme' that specifies the theme and image (SME: And possibly sound) files that are used by the theme. The format of the `theme' file is as follows. - The beginning of the file contains some metainformation about the theme in the format Key=Value @@ -19,10 +17,16 @@ Author - The author's name Following this meta-information are "sml" groups. A "sml" group is a group of smileys that will be shown together. For example, each protocol has its own "sml" group (MSN, Yahoo, Gadu-Gadu, etc.). The name of the group is surrounded in square brackets, and each line beneath it (until the next sml group or the end of the file) defines a smiley. -Each line of the group starts with a filename of the icon (SME: Or sound?) followed by a space-delimited list of the characters that represent it. +Each line of the group starts with a filename of the icon followed by a space-delimited list of the characters that represent it. Example: [AIM/ICQ] smiley.png :) :-) In the smiley selector UI, each icon will only be shown once, and the first string representing it will be used. To keep a smiley out of the selector altogether, make the first two characters of the line "! " followed by the filename and emoticons. + +As of 2.0.0beta2, spaces and backslashes in the "list of characters" (see above) must be escaped by prepending them with a backslash. For example, to define a smiley that is represented by ":-/" and ":-\", use: + +[AIM/ICQ] +think.png :-/ :-\\ + Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-17 02:11:13 UTC (rev 16272) @@ -4,7 +4,8 @@ plugin_LTLIBRARIES = tcl.la -tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h +tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h \ + tcl_ref.c EXTRA_DIST = signal-test.tcl Makefile.mingw Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272) @@ -63,6 +63,7 @@ C_SRC = tcl.c \ tcl_cmds.c \ tcl_glib.c \ + tcl_ref.c \ tcl_signals.c Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -50,6 +50,15 @@ Tcl_Interp *interp; }; +GaimStringref *GaimTclRefAccount; +GaimStringref *GaimTclRefConnection; +GaimStringref *GaimTclRefConversation; +GaimStringref *GaimTclRefPointer; +GaimStringref *GaimTclRefPresence; +GaimStringref *GaimTclRefStatus; +GaimStringref *GaimTclRefStatusAttr; +GaimStringref *GaimTclRefStatusType; + static GHashTable *tcl_plugins = NULL; GaimPlugin *_tcl_plugin; @@ -123,8 +132,12 @@ Tcl_CreateObjCommand(interp, "::gaim::debug", tcl_cmd_debug, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::notify", tcl_cmd_notify, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::prefs", tcl_cmd_prefs, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::presence", tcl_cmd_presence, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::send_im", tcl_cmd_send_im, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::signal", tcl_cmd_signal, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status", tcl_cmd_status, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status_attr", tcl_cmd_status_attr, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status_type", tcl_cmd_status_type, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::unload", tcl_cmd_unload, (ClientData)NULL, NULL); return 0; @@ -329,6 +342,17 @@ return FALSE; tcl_glib_init(); tcl_signal_init(); + gaim_tcl_ref_init(); + + GaimTclRefAccount = gaim_stringref_new("Account"); + GaimTclRefConnection = gaim_stringref_new("Connection"); + GaimTclRefConversation = gaim_stringref_new("Conversation"); + GaimTclRefPointer = gaim_stringref_new("Pointer"); + GaimTclRefPresence = gaim_stringref_new("Presence"); + GaimTclRefStatus = gaim_stringref_new("Status"); + GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr"); + GaimTclRefStatusType = gaim_stringref_new("StatusType"); + tcl_plugins = g_hash_table_new(g_direct_hash, g_direct_equal); #ifdef HAVE_TK @@ -343,6 +367,15 @@ g_hash_table_destroy(tcl_plugins); tcl_plugins = NULL; + gaim_stringref_unref(GaimTclRefAccount); + gaim_stringref_unref(GaimTclRefConnection); + gaim_stringref_unref(GaimTclRefConversation); + gaim_stringref_unref(GaimTclRefPointer); + gaim_stringref_unref(GaimTclRefPresence); + gaim_stringref_unref(GaimTclRefStatus); + gaim_stringref_unref(GaimTclRefStatusAttr); + gaim_stringref_unref(GaimTclRefStatusType); + return TRUE; } Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -35,61 +35,91 @@ #include "tcl_gaim.h" -static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp); -static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp); -static gboolean tcl_validate_gc(GaimConnection *gc); +static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp); +static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp); +static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp); -static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp) +static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimAccount *account; GList *cur; + + account = gaim_tcl_ref_get(interp, obj, GaimTclRefAccount); + + if (account == NULL) + return NULL; + for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { if (account == cur->data) - return TRUE; + return account; } if (interp != NULL) Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); - return FALSE; + return NULL; } -static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp) +static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimConversation *convo; GList *cur; + convo = gaim_tcl_ref_get(interp, obj, GaimTclRefConversation); + + if (convo == NULL) + return NULL; + for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { if (convo == cur->data) - return TRUE; + return convo; } if (interp != NULL) Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); - return FALSE; + return NULL; } -static gboolean tcl_validate_gc(GaimConnection *gc) +static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimConnection *gc; GList *cur; + + gc = gaim_tcl_ref_get(interp, obj, GaimTclRefConnection); + + if (gc == NULL) + return NULL; + for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { if (gc == cur->data) - return TRUE; + return gc; } - return FALSE; + return NULL; } int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; - const char *cmds[] = { "alias", "connect", "connection", "disconnect", "find", - "handle", "isconnected", "list", - "protocol", "username", NULL }; - enum { CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, - CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE, - CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, - CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_USERNAME } cmd; + const char *cmds[] = { "alias", "connect", "connection", "disconnect", + "enabled", "find", "handle", "isconnected", + "list", "presence", "protocol", "status", + "status_type", "status_types", "username", + NULL }; + enum { CMD_ACCOUNT_ALIAS, + CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, + CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND, + CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, + CMD_ACCOUNT_PRESENCE, CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS, + CMD_ACCOUNT_STATUS_TYPE, CMD_ACCOUNT_STATUS_TYPES, + CMD_ACCOUNT_USERNAME } cmd; const char *listopts[] = { "-all", "-online", NULL }; enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt; const char *alias; - GList *cur; + const GList *cur; GaimAccount *account; + GaimStatus *status; + GaimStatusType *status_type; + GaimValue *value; + char *attr_id; int error; + int b, i; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); @@ -105,8 +135,7 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; alias = gaim_account_get_alias(account); Tcl_SetStringObj(result, alias ? (char *)alias : "", -1); @@ -116,40 +145,61 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; if (!gaim_account_is_connected(account)) gaim_account_connect(account); - Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefConnection, + gaim_account_get_connection(account))); break; case CMD_ACCOUNT_CONNECTION: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; - Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefConnection, + gaim_account_get_connection(account))); break; case CMD_ACCOUNT_DISCONNECT: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; gaim_account_disconnect(account); break; + case CMD_ACCOUNT_ENABLED: + if (objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?enabled?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetBooleanObj(result, + gaim_account_get_enabled(account, + gaim_core_get_ui())); + } else { + if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &b)) != TCL_OK) + return TCL_ERROR; + gaim_account_set_enabled(account, gaim_core_get_ui(), b); + } + break; case CMD_ACCOUNT_FIND: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "username protocol"); return TCL_ERROR; } - Tcl_SetIntObj(result, (int)gaim_accounts_find(Tcl_GetString(objv[2]), - Tcl_GetString(objv[3]))); + account = gaim_accounts_find(Tcl_GetString(objv[2]), + Tcl_GetString(objv[3])); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefAccount, account)); break; case CMD_ACCOUNT_HANDLE: if (objc != 2) { @@ -163,8 +213,7 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetBooleanObj(result, gaim_account_is_connected(account)); break; @@ -183,28 +232,140 @@ account = cur->data; if (listopt == CMD_ACCOUNTLIST_ONLINE && !gaim_account_is_connected(account)) continue; - elem = Tcl_NewIntObj((int)account); + elem = gaim_tcl_ref_new(GaimTclRefAccount, account); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); break; + case CMD_ACCOUNT_PRESENCE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefPresence, + gaim_account_get_presence(account))); + break; case CMD_ACCOUNT_PROTOCOL: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetStringObj(result, (char *)gaim_account_get_protocol_id(account), -1); break; + case CMD_ACCOUNT_STATUS: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?status_id name value ...?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_account_get_active_status(account))); + } else { + GList *l = NULL; + if (objc % 2) { + Tcl_SetStringObj(result, "name without value setting status", -1); + return TCL_ERROR; + } + status = gaim_account_get_status(account, Tcl_GetString(objv[3])); + if (status == NULL) { + Tcl_SetStringObj(result, "invalid status for account", -1); + return TCL_ERROR; + } + for (i = 4; i < objc; i += 2) { + attr_id = Tcl_GetString(objv[i]); + value = gaim_status_get_attr_value(status, attr_id); + if (value == NULL) { + Tcl_SetStringObj(result, "invalid attribute for account", -1); + return TCL_ERROR; + } + switch (gaim_value_get_type(value)) { + case GAIM_TYPE_BOOLEAN: + error = Tcl_GetBooleanFromObj(interp, objv[i + 1], &b); + if (error != TCL_OK) + return error; + l = g_list_append(l, attr_id); + l = g_list_append(l, GINT_TO_POINTER(b)); + break; + case GAIM_TYPE_INT: + error = Tcl_GetIntFromObj(interp, objv[i + 1], &b); + if (error != TCL_OK) + return error; + l = g_list_append(l, attr_id); + l = g_list_append(l, GINT_TO_POINTER(b)); + break; + case GAIM_TYPE_STRING: + l = g_list_append(l, attr_id); + l = g_list_append(l, Tcl_GetString(objv[i + 1])); + break; + default: + Tcl_SetStringObj(result, "unknown GaimValue type", -1); + return TCL_ERROR; + } + } + gaim_account_set_status_list(account, Tcl_GetString(objv[3]), TRUE, l); + g_list_free(l); + } + break; + case CMD_ACCOUNT_STATUS_TYPE: + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?statustype? ?-primitive primitive?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 4) { + status_type = gaim_account_get_status_type(account, + Tcl_GetString(objv[3])); + } else { + GaimStatusPrimitive primitive; + if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { + Tcl_SetStringObj(result, "bad option \"", -1); + Tcl_AppendObjToObj(result, objv[3]); + Tcl_AppendToObj(result, + "\": should be -primitive", -1); + return TCL_ERROR; + } + primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4])); + status_type = gaim_account_get_status_type_with_primitive(account, + primitive); + } + if (status_type == NULL) { + Tcl_SetStringObj(result, "status type not found", -1); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatusType, + status_type)); + break; + case CMD_ACCOUNT_STATUS_TYPES: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_account_get_status_types(account); cur != NULL; + cur = g_list_next(cur)) { + Tcl_ListObjAppendElement(interp, list, + gaim_tcl_ref_new(GaimTclRefStatusType, + cur->data)); + } + Tcl_SetObjResult(interp, list); + break; case CMD_ACCOUNT_USERNAME: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetStringObj(result, (char *)gaim_account_get_username(account), -1); break; @@ -227,10 +388,8 @@ type = Tcl_GetString(elems[0]); name = Tcl_GetString(elems[1]); - if (Tcl_GetIntFromObj(interp, elems[2], (int *)&account) != TCL_OK) + if ((account = tcl_validate_account(elems[2], interp)) == NULL) return NULL; - if (!tcl_validate_account(account, interp)) - return NULL; if (!strcmp(type, "buddy")) { node = (GaimBlistNode *)gaim_find_buddy(account, name); @@ -301,15 +460,11 @@ Tcl_SetStringObj(result, "invalid buddy", -1); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, elems[2], (int *)&account)) != TCL_OK) + if ((account = tcl_validate_account(elems[2], interp)) == NULL) return TCL_ERROR; - if (!tcl_validate_account(account, interp)) - return TCL_ERROR; serv_get_info(gaim_account_get_connection(account), Tcl_GetString(elems[1])); } else { - if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; serv_get_info(gaim_account_get_connection(account), Tcl_GetString(objv[3])); } @@ -351,7 +506,7 @@ tclbud = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1)); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1)); - Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)bud->account)); + Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, bud->account)); Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud); } if (count) { @@ -368,7 +523,7 @@ tclbud = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1)); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1)); - Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)cnode->account)); + Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, cnode->account)); Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud); break; default: @@ -409,23 +564,19 @@ Tcl_WrongNumArgs(interp, 2, objv, "gc"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); - if (error || !tcl_validate_gc(gc)) { - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) return TCL_ERROR; - } - Tcl_SetIntObj(result, (int)gaim_connection_get_account(gc)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefAccount, + gaim_connection_get_account(gc))); break; case CMD_CONN_DISPLAYNAME: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "gc"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); - if (error || !tcl_validate_gc(gc)) { - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) return TCL_ERROR; - } Tcl_SetStringObj(result, (char *)gaim_connection_get_display_name(gc), -1); break; case CMD_CONN_HANDLE: @@ -442,7 +593,7 @@ } list = Tcl_NewListObj(0, NULL); for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { - elem = Tcl_NewIntObj((int)cur->data); + elem = gaim_tcl_ref_new(GaimTclRefConnection, cur->data); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); @@ -483,15 +634,12 @@ return TCL_ERROR; } account = NULL; - if ((error = Tcl_GetIntFromObj(interp, objv[2], - (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, Tcl_GetString(objv[3]), account); - Tcl_SetIntObj(result, (int)convo); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo)); break; case CMD_CONV_HANDLE: if (objc != 2) { @@ -503,7 +651,7 @@ case CMD_CONV_LIST: list = Tcl_NewListObj(0, NULL); for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { - elem = Tcl_NewIntObj((int)cur->data); + elem = gaim_tcl_ref_new(GaimTclRefConversation, cur->data); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); @@ -538,24 +686,20 @@ Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[argsused++], (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL) return TCL_ERROR; convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused])); - Tcl_SetIntObj(result, (int)convo); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo)); break; case CMD_CONV_WRITE: if (objc != 6) { Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&convo)) != TCL_OK) - return error; + if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) + return TCL_ERROR; if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK) return error; - if (!tcl_validate_conversation(convo, interp)) - return TCL_ERROR; from = Tcl_GetString(objv[4]); what = Tcl_GetString(objv[5]); @@ -799,25 +943,224 @@ return TCL_OK; } +int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "account", "active_status", "available", + "chat_user", "context", "conversation", "idle", + "login", "online", "status", "statuses", NULL }; + enum { CMD_PRESENCE_ACCOUNT, CMD_PRESENCE_ACTIVE_STATUS, + CMD_PRESENCE_AVAILABLE, CMD_PRESENCE_CHAT_USER, + CMD_PRESENCE_CONTEXT, CMD_PRESENCE_CONVERSATION, + CMD_PRESENCE_IDLE, CMD_PRESENCE_LOGIN, CMD_PRESENCE_ONLINE, + CMD_PRESENCE_STATUS, CMD_PRESENCE_STATUSES } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + Tcl_Obj *list, *elem; + GaimPresence *presence; + const GList *cur; + int error, idle, idle_time, login_time; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_PRESENCE_ACCOUNT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefAccount, + gaim_presence_get_account(presence))); + break; + case CMD_PRESENCE_ACTIVE_STATUS: + if (objc != 3 && objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "presence [?status_id? | ?-primitive primitive?]"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_presence_get_active_status(presence))); + } else if (objc == 4) { + Tcl_SetBooleanObj(result, + gaim_presence_is_status_active(presence, + Tcl_GetString(objv[3]))); + } else { + GaimStatusPrimitive primitive; + if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { + Tcl_SetStringObj(result, "bad option \"", -1); + Tcl_AppendObjToObj(result, objv[3]); + Tcl_AppendToObj(result, + "\": should be -primitive", -1); + return TCL_ERROR; + } + primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4])); + if (primitive == GAIM_STATUS_UNSET) { + Tcl_SetStringObj(result, "invalid primitive ", -1); + Tcl_AppendObjToObj(result, objv[4]); + return TCL_ERROR; + } + Tcl_SetBooleanObj(result, gaim_presence_is_status_primitive_active(presence, primitive)); + break; + } + break; + case CMD_PRESENCE_AVAILABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_presence_is_available(presence)); + break; + case CMD_PRESENCE_CHAT_USER: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_presence_get_chat_user(presence), -1); + break; + case CMD_PRESENCE_CONTEXT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + switch (gaim_presence_get_context(presence)) { + case GAIM_PRESENCE_CONTEXT_UNSET: + Tcl_SetStringObj(result, "unset", -1); + break; + case GAIM_PRESENCE_CONTEXT_ACCOUNT: + Tcl_SetStringObj(result, "account", -1); + break; + case GAIM_PRESENCE_CONTEXT_CONV: + Tcl_SetStringObj(result, "conversation", -1); + break; + case GAIM_PRESENCE_CONTEXT_BUDDY: + Tcl_SetStringObj(result, "buddy", -1); + break; + } + break; + case CMD_PRESENCE_CONVERSATION: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, + gaim_presence_get_conversation(presence))); + break; + case CMD_PRESENCE_IDLE: + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, "presence ?idle? ?time?"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + if (gaim_presence_is_idle(presence)) { + idle_time = gaim_presence_get_idle_time (presence); + Tcl_SetIntObj(result, idle_time); + } else { + result = Tcl_NewListObj(0, NULL); + Tcl_SetObjResult(interp, result); + } + break; + } + if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &idle)) != TCL_OK) + return TCL_ERROR; + if (objc == 4) { + gaim_presence_set_idle(presence, idle, time(NULL)); + } else if (objc == 5) { + if ((error = Tcl_GetIntFromObj(interp, + objv[4], + &idle_time)) != TCL_OK) + return TCL_ERROR; + gaim_presence_set_idle(presence, idle, idle_time); + } + break; + case CMD_PRESENCE_LOGIN: + if (objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "presence ?time?"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetIntObj(result, gaim_presence_get_login_time(presence)); + } else { + if ((error == Tcl_GetIntFromObj(interp, + objv[3], + &login_time)) != TCL_OK) + return TCL_ERROR; + gaim_presence_set_login_time(presence, login_time); + } + break; + case CMD_PRESENCE_ONLINE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_presence_is_online(presence)); + break; + case CMD_PRESENCE_STATUS: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "presence status_id"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_presence_get_status(presence, + Tcl_GetString(objv[3])))); + break; + case CMD_PRESENCE_STATUSES: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_presence_get_statuses(presence); cur != NULL; + cur = g_list_next(cur)) { + elem = gaim_tcl_ref_new(GaimTclRefStatus, cur->data); + Tcl_ListObjAppendElement(interp, list, elem); + } + Tcl_SetObjResult(interp, list); + break; + } + + return TCL_OK; +} + int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { GaimConnection *gc; char *who, *text; - int error; - Tcl_Obj *result; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "gc who text"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[1], (int *)&gc)) != TCL_OK) - return error; - if (!tcl_validate_gc(gc)) { - result = Tcl_GetObjResult(interp); - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[1], interp)) == NULL) return TCL_ERROR; - } who = Tcl_GetString(objv[2]); text = Tcl_GetString(objv[3]); @@ -856,6 +1199,7 @@ return error; } handler->signal = objv[3]; + Tcl_IncrRefCount(handler->signal); handler->args = objv[4]; handler->proc = objv[5]; handler->interp = interp; @@ -868,7 +1212,7 @@ break; case CMD_SIGNAL_DISCONNECT: if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "signal"); + Tcl_WrongNumArgs(interp, 2, objv, "instance signal"); return TCL_ERROR; } if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&instance)) != TCL_OK) @@ -880,6 +1224,265 @@ return TCL_OK; } +int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "attr", "type", NULL }; + enum { CMD_STATUS_ATTR, CMD_STATUS_TYPE } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatus *status; + GaimStatusType *status_type; + GaimValue *value; + const char *attr; + int error, v; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_ATTR: + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "status attr_id ?value?"); + return TCL_ERROR; + } + if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) + return TCL_ERROR; + attr = Tcl_GetString(objv[3]); + value = gaim_status_get_attr_value(status, attr); + if (value == NULL) { + Tcl_SetStringObj(result, "no such attribute", -1); + return TCL_ERROR; + } + switch (gaim_value_get_type(value)) { + case GAIM_TYPE_BOOLEAN: + if (objc == 4) { + Tcl_SetBooleanObj(result, gaim_value_get_boolean(value)); + } else { + if ((error = Tcl_GetBooleanFromObj(interp, objv[4], &v)) != TCL_OK) + return error; + gaim_status_set_attr_boolean(status, attr, v); + } + break; + case GAIM_TYPE_INT: + if (objc == 4) { + Tcl_SetIntObj(result, gaim_value_get_int(value)); + } else { + if ((error = Tcl_GetIntFromObj(interp, objv[4], &v)) != TCL_OK) + return error; + gaim_status_set_attr_int(status, attr, v ); + } + break; + case GAIM_TYPE_STRING: + if (objc == 4) + Tcl_SetStringObj(result, gaim_value_get_string(value), -1); + else + gaim_status_set_attr_string(status, attr, Tcl_GetString(objv[4])); + break; + default: + Tcl_SetStringObj(result, "attribute has unknown type", -1); + return TCL_ERROR; + } + break; + case CMD_STATUS_TYPE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "status"); + return TCL_ERROR; + } + if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) + return TCL_ERROR; + status_type = gaim_status_get_type(status); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefStatusType, + status_type)); + break; + } + + return TCL_OK; +} + +int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "id", "name", NULL }; + enum { CMD_STATUS_ATTR_ID, CMD_STATUS_ATTR_NAME } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatusAttr *attr; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_ATTR_ID: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "attr"); + return TCL_ERROR; + } + if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_attr_get_id(attr), -1); + break; + case CMD_STATUS_ATTR_NAME: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "attr"); + return TCL_ERROR; + } + if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_attr_get_name(attr), -1); + break; + } + + return TCL_OK; +} + +int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id", + "independent", "name", "primary_attr", + "primitive", "saveable", "user_settable", + NULL }; + enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS, + CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE, + CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT, + CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR, + CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE, + CMD_STATUS_TYPE_USER_SETTABLE } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatusType *status_type; + Tcl_Obj *list, *elem; + const GList *cur; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_TYPE_AVAILABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_available(status_type)); + break; + case CMD_STATUS_TYPE_ATTR: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype attr"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatusAttr, + gaim_status_type_get_attr(status_type, + Tcl_GetStringFromObj(objv[3], NULL)))); + break; + case CMD_STATUS_TYPE_ATTRS: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_status_type_get_attrs(status_type); + cur != NULL; cur = g_list_next(cur)) { + elem = gaim_tcl_ref_new(GaimTclRefStatusAttr, cur->data); + Tcl_ListObjAppendElement(interp, list, elem); + } + Tcl_SetObjResult(interp, list); + break; + case CMD_STATUS_TYPE_EXCLUSIVE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_exclusive(status_type)); + break; + case CMD_STATUS_TYPE_ID: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_id(status_type), -1); + break; + case CMD_STATUS_TYPE_INDEPENDENT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_independent(status_type)); + break; + case CMD_STATUS_TYPE_NAME: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_name(status_type), -1); + break; + case CMD_STATUS_TYPE_PRIMITIVE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_primitive_get_id_from_type(gaim_status_type_get_primitive(status_type)), -1); + break; + case CMD_STATUS_TYPE_PRIMARY_ATTR: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_primary_attr(status_type), -1); + break; + case CMD_STATUS_TYPE_SAVEABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_saveable(status_type)); + break; + case CMD_STATUS_TYPE_USER_SETTABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_user_settable(status_type)); + break; + } + + return TCL_OK; +} + static gboolean unload_self(gpointer data) { GaimPlugin *plugin = data; Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-17 02:11:13 UTC (rev 16272) @@ -28,6 +28,7 @@ #include "internal.h" #include "plugin.h" #include "value.h" +#include "stringref.h" struct tcl_signal_handler { Tcl_Obj *signal; @@ -46,6 +47,16 @@ extern GaimPlugin *_tcl_plugin; +/* Capitalized this way because these are "types" */ +extern GaimStringref *GaimTclRefAccount; +extern GaimStringref *GaimTclRefConnection; +extern GaimStringref *GaimTclRefConversation; +extern GaimStringref *GaimTclRefPointer; +extern GaimStringref *GaimTclRefPresence; +extern GaimStringref *GaimTclRefStatus; +extern GaimStringref *GaimTclRefStatusAttr; +extern GaimStringref *GaimTclRefStatusType; + GaimPlugin *tcl_interp_get_plugin(Tcl_Interp *interp); void tcl_signal_init(void); @@ -54,6 +65,10 @@ gboolean tcl_signal_connect(struct tcl_signal_handler *handler); void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *interp); +void gaim_tcl_ref_init(void); +void *gaim_tcl_ref_get(Tcl_Interp *interp, Tcl_Obj *obj, GaimStringref *type); +Tcl_Obj *gaim_tcl_ref_new(GaimStringref *type, void *value); + Tcl_ObjCmdProc tcl_cmd_account; Tcl_ObjCmdProc tcl_cmd_signal_connect; Tcl_ObjCmdProc tcl_cmd_buddy; @@ -63,8 +78,12 @@ Tcl_ObjCmdProc tcl_cmd_debug; Tcl_ObjCmdProc tcl_cmd_notify; Tcl_ObjCmdProc tcl_cmd_prefs; +Tcl_ObjCmdProc tcl_cmd_presence; Tcl_ObjCmdProc tcl_cmd_send_im; Tcl_ObjCmdProc tcl_cmd_signal; +Tcl_ObjCmdProc tcl_cmd_status; +Tcl_ObjCmdProc tcl_cmd_status_attr; +Tcl_ObjCmdProc tcl_cmd_status_type; Tcl_ObjCmdProc tcl_cmd_unload; #endif /* _GAIM_TCL_GAIM_H_ */ Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -1,7 +1,7 @@ /* * Tcl/Glib glue * - * Copyright (C) 2003, 2004 Ethan Blanton <ebl...@cs...> + * Copyright (C) 2003, 2004, 2006 Ethan Blanton <ebl...@cs...> * * This file is dual-licensed under the two sets of terms below. You may * use, redistribute, or modify it pursuant to either the set of conditions @@ -157,8 +157,8 @@ GIOChannel *channel; GIOCondition cond = 0; - if (g_hash_table_lookup(tcl_file_handlers, (gpointer)fd)) - tcl_delete_file_handler(fd); + if (g_hash_table_lookup(tcl_file_handlers, GINT_TO_POINTER(fd))) + tcl_delete_file_handler(fd); if (mask & TCL_READABLE) cond |= G_IO_IN; @@ -176,7 +176,7 @@ tfh->source = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, tcl_file_callback, tfh, g_free); g_io_channel_unref(channel); - g_hash_table_insert(tcl_file_handlers, (gpointer)fd, tfh); + g_hash_table_insert(tcl_file_handlers, GINT_TO_POINTER(fd), tfh); Tcl_ServiceAll(); } @@ -189,7 +189,7 @@ return; g_source_remove(tfh->source); - g_hash_table_remove(tcl_file_handlers, (gpointer)fd); + g_hash_table_remove(tcl_file_handlers, GINT_TO_POINTER(fd)); Tcl_ServiceAll(); } @@ -241,7 +241,7 @@ return 0; } - tfh = g_hash_table_lookup(tcl_file_handlers, (gpointer)fev->fd); + tfh = g_hash_table_lookup(tcl_file_handlers, GINT_TO_POINTER(fev->fd)); if (tfh == NULL) return 1; Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c =================================================================== --- branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-17 02:11:13 UTC (rev 16272) @@ -48,7 +48,8 @@ return; Tcl_DecrRefCount(handler->signal); - Tcl_DecrRefCount(handler->namespace); + if (handler->namespace) + Tcl_DecrRefCount(handler->namespace); g_free(handler); } @@ -86,7 +87,6 @@ (void *)handler)) return FALSE; - Tcl_IncrRefCount(handler->signal); handler->namespace = new_cb_namespace (); Tcl_IncrRefCount(handler->namespace); proc = g_string_new(""); @@ -134,6 +134,22 @@ tcl_callbacks = g_list_remove_all(tcl_callbacks, NULL); } +static GaimStringref *ref_type(GaimSubType type) +{ + switch (type) { + case GAIM_SUBTYPE_ACCOUNT: + return GaimTclRefAccount; + case GAIM_SUBTYPE_CONNECTION: + return GaimTclRefConnection; + case GAIM_SUBTYPE_CONVERSATION: + return GaimTclRefConversation; + case GAIM_SUBTYPE_STATUS: + return GaimTclRefStatus; + default: + return NULL; + } +} + static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handler) { GString *name, *val; @@ -170,14 +186,9 @@ case GAIM_TYPE_OBJECT: case GAIM_TYPE_BOXED: /* These are all "pointer" types to us */ - if (gaim_value_is_outgoing(handler->argtypes[i])) { - vals[i] = va_arg(args, void **); - Tcl_LinkVar(handler->interp, name->str, - vals[i], TCL_LINK_INT); - arg = Tcl_NewStringObj(name->str, -1); - } else { - arg = Tcl_NewIntObj((int)va_arg(args, void *)); - } + if (gaim_value_is_outgoing(handler->argtypes[i])) + gaim_debug_error("tcl", "pointer types do not currently support outgoing arguments\n"); + arg = gaim_tcl_ref_new(GaimTclRefPointer, va_arg(args, void *)); break; case GAIM_TYPE_BOOLEAN: if (gaim_value_is_outgoing(handler->argtypes[i])) { @@ -258,6 +269,11 @@ case GAIM_SUBTYPE_ACCOUNT: case GAIM_SUBTYPE_CONNECTION: case GAIM_SUBTYPE_CONVERSATION: + case GAIM_SUBTYPE_STATUS: + if (gaim_value_is_outgoing(handler->argtypes[i])) + gaim_debug_error("tcl", "pointer subtypes do not currently support outgoing arguments\n"); + arg = gaim_tcl_ref_new(ref_type(gaim_value_get_subtype(handler->argtypes[i])), va_arg(args, void *)); + break; case GAIM_SUBTYPE_PLUGIN: case GAIM_SUBTYPE_XFER: /* pointers again */ @@ -281,24 +297,40 @@ node = va_arg(args, GaimBlistNode *); switch (node->type) { case GAIM_BLIST_GROUP_NODE: - g_string_printf(val, "group {%s}", ((GaimGroup *)node)->name); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("group", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimGroup *)node)->name, -1)); break; case GAIM_BLIST_CONTACT_NODE: /* g_string_printf(val, "contact {%s}", Contact Name? ); */ + arg = Tcl_NewStringObj("contact", -1); break; case GAIM_BLIST_BUDDY_NODE: - g_string_printf(val, "buddy {%s} %lu", ((GaimBuddy *)node)->name, - (unsigned long)((GaimBuddy *)node)->account); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("buddy", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimBuddy *)node)->name, -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + gaim_tcl_ref_new(GaimTclRefAccount, + ((GaimBuddy *)node)->account)); break; case GAIM_BLIST_CHAT_NODE: - g_string_printf(val, "chat {%s} %lu", ((GaimChat *)node)->alias, - (unsigned long)((GaimChat *)node)->account); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("chat", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimChat *)node)->alias, -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + gaim_tcl_ref_new(GaimTclRefAccount, + ((GaimChat *)node)->account)); break; case GAIM_BLIST_OTHER_NODE: - g_string_printf(val, "other"); + arg = Tcl_NewStringObj("other", -1); break; } - arg = Tcl_NewStringObj(val->str, -1); break; } } @@ -329,8 +361,10 @@ for (i = 0; i < handler->nargs; i++) { g_string_printf(name, "%s::arg%d", Tcl_GetString(handler->namespace), i); - if (gaim_value_is_outgoing(handler->argtypes[i])) + if (gaim_value_is_outgoing(handler->argtypes[i]) + && gaim_value_get_type(handler->argtypes[i]) != GAIM_TYPE_SUBTYPE) Tcl_UnlinkVar(handler->interp, name->str); + /* We basically only have to deal with strings on the * way out */ switch (gaim_value_get_type(handler->argtypes[i])) { Modified: branches/soc-2006-file-loggers/src/Makefile.am =================================================================== --- branches/soc-2006-file-loggers/src/Makefile.am 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/src/Makefile.am 2006-06-17 02:11:13 UTC (rev 16272) @@ -347,7 +347,8 @@ $(SM_LIBS) \ $(INTLLIBS) \ $(GTKSPELL_LIBS) \ - $(STARTUP_NOTIFICATION_LIBS) + $(STARTUP_NOTIFICATION_LIBS) \ + $(LIBXML_LIBS) AM_CPPFLAGS = \ -DBR_PTHREADS=0 \ @@ -361,4 +362,5 @@ $(GTK_CFLAGS) \ $(DBUS_CFLAGS) \ $(GTKSPELL_CFLAGS) \ - $(STARTUP_NOTIFICATION_CFLAGS) + $(STARTUP_NOTIFICATION_CFLAGS) \ + $(LIBXML_CFLAGS) Modified: branches/soc-2006-file-loggers/src/Makefile.mingw =================================================================== --- branches/soc-2006-file-loggers/src/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271) +++ branches/soc-2006-file-loggers/sr... [truncated message content] |