changeset 11331:64fadbf3810f

[gaim-migrate @ 13544] General polishing of DBus code, improving examples, removing obsolete files. committer: Tailor Script <tailor@pidgin.im>
author Piotr Zielinski <zielaj>
date Wed, 24 Aug 2005 02:34:40 +0000
parents d41a83d221b0
children 1d97f18595be
files src/Makefile.am src/dbus-analyze-functions.py src/dbus-analyze-types.py src/dbus-client-example.py src/dbus-client.c src/dbus-service-end.xml src/dbus-service.xml src/dbus-types.c src/dbus-types.h src/dbus-useful.c src/gaim-notifications-example.py src/gaim-remote.py src/gaim-send
diffstat 13 files changed, 215 insertions(+), 350 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/Makefile.am	Wed Aug 24 02:34:40 2005 +0000
@@ -153,7 +153,10 @@
 CLEANFILES    = \
 	dbus-bindings.c \
 	dbus-client-binding.c \
-	dbus-client-binding.h
+	dbus-client-binding.h \
+	gaim.service
+#	dbus-types.c 
+#	dbus-types.h 
 
 # gaim dbus server
 
@@ -162,12 +165,25 @@
 
 dbus_exported = dbus-useful.h dbus-define-api.h account.h blist.h connection.h conversation.h core.h roomlist.h status.h server.h
 
+#Although dbus-types.[ch] are generated automatically, they are
+#included in the distribution (and CVS) as normal source
+#files. Otherwise, we would have to compile the src directory before
+#the plugins directory, because some of the plugins depend on the
+#dbus-types.h.  On the other hand, gaim-remote from the src directory
+#requires libgaim-remote from the the plugins directory, which forces
+#us to compile the plugins directory before src.  
+
+# dbus-types.c: dbus-analyze-types.py $(gaim_coreheaders)
+# 	cat $(gaim_coreheaders) | $(PYTHON) dbus-analyze-types.py --pattern=GAIM_DBUS_DEFINE_TYPE\(%s\) > $@
+
+# dbus-types.h: dbus-analyze-types.py $(dbus_coreheaders)
+# 	cat $(gaim_coreheaders) | $(PYTHON) dbus-analyze-types.py --pattern=GAIM_DBUS_DECLARE_TYPE\(%s\) > $@
 
 dbus-bindings.c: dbus-analyze-functions.py $(dbus_exported)
 	cat $(dbus_exported) | $(PYTHON) dbus-analyze-functions.py > $@
 
-dbus-server.$(OBJEXT): dbus-bindings.c
-
+dbus-server.$(OBJEXT): dbus-bindings.c dbus-types.c dbus-types.h
+$(gaim_OBJECTS): dbus-types.h
 
 # libgaim-client
 
@@ -178,8 +194,9 @@
 gaim-client-bindings.c: dbus-analyze-functions.py $(dbus_exported)
 	cat $(dbus_exported) | $(PYTHON) dbus-analyze-functions.py --client > $@
 
-gaim-client-bindings.h: dbus-analyze-functions.py $(dbus_exported)
-	cat $(dbus_exported) | $(PYTHON) dbus-analyze-functions.py --client --headers > $@
+gaim-client-bindings.h: dbus-analyze-types.py dbus-analyze-functions.py $(gaim_coreheaders) $(dbus_exported)
+	cat $(gaim_coreheaders) | $(PYTHON) dbus-analyze-types.py --keyword=enum --verbatim > $@
+	cat $(dbus_exported) | $(PYTHON) dbus-analyze-functions.py --client --headers >> $@
 
 $(libgaim_client_la_OBJECTS): gaim-client-bindings.h gaim-client-bindings.c
 
@@ -198,8 +215,22 @@
 
 bin_PROGRAMS += gaim-client-example
 
-gaim-client-example.$(OBJEXT): gaim-client-bindings.h
+gaim-client-example.$(OBJEXT): gaim-client-bindings.h 
+
+# scripts
+
+bin_SCRIPTS = gaim-remote.py gaim-notifications-example.py gaim-send gaim-send-async
+
 
+# gaim.service
+
+gaim.service:
+	echo "[Gaim]" > $@
+	echo "Name=org.gaim.GaimService" >> $@
+	echo "Exec=$(bindir)/gaim" >> $@
+
+dbus_servicesdir = /usr/share/dbus-1
+dbus_services_DATA = gaim.service
 
 endif
 
--- a/src/dbus-analyze-functions.py	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/dbus-analyze-functions.py	Wed Aug 24 02:34:40 2005 +0000
@@ -1,43 +1,41 @@
-# This programs takes a C header file as the input and produces:
-#
-# with option --mode=xml:  xml dbus specification 
-# with option --mode=c:    C wrappers 
-#
-
 import re
 import string
 import sys
 
 
-# list of object types
-
-# objecttypes = []
-
-# for objecttype in file("dbus-auto-structs.txt"):
-#     objecttypes.append(objecttype.strip())
-
-# a dictionary of simple types
-# each TYPE maps into a pair (dbus-type-name, compatible-c-type-name)
-# if compatible-c-type-name is None then it is the same as TYPE
-
-# simpletypes = {
-#     "int" : ("i", None),
-#     "gint" : ("i", None),
-#     "guint" : ("u", None),
-#     "gboolean" : ("i", "int")
-#     }
-
-
+# types translated into "int"
 simpletypes = ["int", "gint", "guint", "gboolean"]
 
-# for enum in file("dbus-auto-enums.txt"):
-#     simpletypes[enum.strip()] = ("i", "int")
+# List "excluded" contains functions that shouldn't be exported via
+# DBus.  If you remove a function from this list, please make sure
+# that it does not break "make" with the configure option
+# "--enable-dbus" turned on.
+
+excluded = [\
+    # I don't remember why this function is excluded; something to do
+    # with the fact that it takes a (const) GList as a parameter.
+    "gaim_presence_add_list",
+
+    # these two macros are excluded because they occur both as
+    # macros and as enum constants, which breaks libgaim-client.
+    "GAIM_CONV_IM",
+    "GAIM_CONV_CHAT",
 
-# functions that shouldn't be exported 
+    # These functions are excluded because they involve value of the
+    # type GaimConvPlacementFunc, which is a pointer to a function and
+    # (currently?) can't be translated into a DBus type.  Normally,
+    # functions with untranslatable types are skipped, but this script
+    # assumes that all non-pointer type names beginning with "Gaim"
+    # are enums, which is not true in this case.
+    "gaim_conv_placement_add_fnc",
+    "gaim_conv_placement_get_fnc",
+    "gaim_conv_placement_get_current_func",
+    "gaim_conv_placement_set_current_func",
+    ]
 
-excluded = ["gaim_conv_placement_add_fnc",
-            "gaim_presence_add_list"]
-
+# This is a list of functions that return a GList* whose elements are
+# string, not pointers to objects.  Don't put any functions here, it
+# won't work.
 stringlists = []
 
 pointer = "#pointer#"
@@ -208,18 +206,9 @@
             print "typedef struct _%s %s;" % (type[0], type[0])
             self.knowntypes.append(type[0])
 
-    # fixme: import the definitions of the enumerations from gaim
-    # header files
-    def definegaimenum(self, type):
-        if (self.headersonly) and (type[0] not in self.knowntypes) \
-               and (type[0] not in simpletypes):
-            print "typedef int %s;" % type[0]
-            self.knowntypes.append(type[0])
-       
     def inputsimple(self, type, name):
         self.paramshdr.append("%s %s" % (type[0], name))
         self.inputparams.append(("G_TYPE_INT", name))
-        self.definegaimenum(type)
 
     def inputvalist(self, type, name):
         self.paramshdr.append("va_list %s_NULL" % name)
@@ -257,7 +246,6 @@
         self.decls.append("%s %s = 0;" % (type[0], name))
         self.outputparams.append(("G_TYPE_INT", name))
         self.returncode.append("return %s;" % name);
-        self.definegaimenum(type)
 
     # we could add "const" to the return type but this would probably
     # be a nuisance
--- a/src/dbus-analyze-types.py	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/dbus-analyze-types.py	Wed Aug 24 02:34:40 2005 +0000
@@ -18,45 +18,54 @@
 import re
 import sys
 
-keyword = "struct"
-pattern = "%s"
+options = {}
+
+def toprint(match, line):
+    if verbatim:
+        return line
+    else:
+        return pattern % match
 
 for arg in sys.argv[1:]:
     if arg[0:2] == "--":
         mylist = arg[2:].split("=",1)
         command = mylist[0]
         if len(mylist) > 1:
-            value = mylist[1]
+            options[command] = mylist[1]
         else:
-            value = None
-            
-    if command == "pattern":
-        pattern = value
-    if command == "keyword":
-        keyword = value
-        
+            options[command] = None
+
+keyword = options.get("keyword", "struct")
+pattern = options.get("pattern", "%s")
+verbatim = options.has_key("verbatim")
 
 structregexp1 = re.compile(r"^(typedef\s+)?%s\s+\w+\s+(\w+)\s*;" % keyword)
 structregexp2 = re.compile(r"^(typedef\s+)?%s" % keyword)
 structregexp3 = re.compile(r"^}\s+(\w+)\s*;")
 
+print "/* Generated by %s.  Do not edit! */" % sys.argv[0]
+
 myinput = iter(sys.stdin)
 
 for line in myinput:
     match = structregexp1.match(line)
     if match is not None:
-        print pattern % match.group(2)
+        print toprint(match.group(2), line)
         continue
 
     match = structregexp2.match(line)
     if match is not None:
         while True:
+            if verbatim:
+                print line.rstrip()
             line = myinput.next()
             match = structregexp3.match(line)
             if match is not None:
-                print pattern % match.group(1)
+                print toprint(match.group(1), line)
                 break
             if line[0] not in [" ", "\t", "{", "\n"]:
+                if verbatim:
+                    print line
                 break
         
 
--- a/src/dbus-client-example.py	Tue Aug 23 20:51:13 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-
-# this is an example of a client that communicates with gaim using DBUS
-#
-# requires Python 2.4 and PyGTK bindings
-#
-# note that all function names are resolved dynamically, no
-# gaim-specific library is needed
-
-import dbus
-import dbus.glib
-import dbus.decorators
-import gobject
-import os
-
-def receivedimmsg(account, name, message, conversation, flags):
-    buddy = gaim.GaimFindBuddy(account, name)
-    if buddy != 0:
-        alias = gaim.GaimBuddyGetAlias(buddy)
-    else:
-        alias = name
-
-    text = "%s says %s" % (alias, message)
-    code = os.spawnlp(os.P_WAIT, "xmessage", "xmessage", "-buttons",
-                      "'So what?','Show me',Close,Abuse", text)
-
-    if code == 101:                     # so what?
-        pass
-    if code == 102:                     # show me
-        window = gaim.GaimConversationGetWindow(conversation)
-        gaim.GaimConvWindowRaise(window)
-    if code == 103:                     # close 
-        gaim.GaimConversationDestroy(conversation)
-    if code == 104:                     # abuse
-        im = gaim.GaimConversationGetImData(conversation)
-        gaim.GaimConvImSend(im, "Go away you f...")
-                                 
-        
-def buddysignedon(buddyid):
-    alias = gaim.GaimBuddyGetAlias(buddyid)
-    text = "%s is online" % alias
-
-    code = os.spawnlp(os.P_WAIT, "xmessage", "xmessage", "-buttons",
-                      "'So what?','Let's talk'", text)
-
-    if code == 101:                     # so what?
-        pass
-    if code == 102:                     # let's talk
-        name = gaim.GaimBuddyGetName(buddyid)
-        account = gaim.GaimBuddyGetAccount(buddyid)
-        gaim.GaimConversationNew(1, account, name)
-    
-
-def talkto(buddyname, accountname, protocolname):
-    account = gaim.GaimAccountsFindConnected(accountname, protocolname)
-    if account != 0:                    
-        gaim.GaimConversationNew(1, account, buddyname)
-    
-
-bus = dbus.SessionBus()
-obj = bus.get_object("org.gaim.GaimService", "/org/gaim/GaimObject")
-gaim = dbus.Interface(obj, "org.gaim.GaimInterface")
-
-bus.add_signal_receiver(receivedimmsg,
-                        dbus_interface = "org.gaim.GaimInterface",
-                        signal_name = "ReceivedImMsg")
-bus.add_signal_receiver(buddysignedon,
-                        dbus_interface = "org.gaim.GaimInterface",
-                        signal_name = "BuddySignedOn")
-
-
-# Tell the remote object to emit the signal
-
-talkto("testone@localhost", "", "prpl-jabber")
-
-loop = gobject.MainLoop()
-loop.run()
-
-
--- a/src/dbus-client.c	Tue Aug 23 20:51:13 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * gaim
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-/* Do not use this program.  Use gaim-send instead. */
-
-#define DBUS_API_SUBJECT_TO_CHANGE
-
-#include <string.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
-#include <glib-object.h>
-
-#include "dbus-gaim.h"
-/* #include "dbus-client-bindings.c" */
-
-int
-main (int argc, char **argv)
-{
-	DBusGConnection *connection;
-	DBusGProxy *driver;
-	DBusGProxy *proxy;
-	GError *error;
-	guint32 result;
-	int i;
-
-    
-	g_type_init ();
-  
-	/* Connecting to dbus */
-
-	error = NULL;
-	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-
-	if (connection == NULL) {
-		g_assert (error != NULL);
-		g_critical("Failed to open connection to dbuso %s.", 
-			   error->message);
-		g_error_free(error);
-		return 1;
-	} 
-
-	g_message("Connected to dbus");
-
-	/* Create a proxy object for the "bus driver" */
-	
-	driver = dbus_g_proxy_new_for_name(connection,
-					   DBUS_SERVICE_DBUS,
-					   DBUS_PATH_DBUS,
-					   DBUS_INTERFACE_DBUS);
-
-
-	/* Activate gaim */ 
-
-	error = NULL;
-	org_freedesktop_DBus_start_service_by_name(driver, DBUS_SERVICE_GAIM, 0, 
-						   &result, &error);
-
-	if (error) {
-		g_critical("Failed to activate the gaim object: %s.", 
-			   error->message);
-		g_clear_error(&error);
-		return 1;
-	} 
-
-	g_message("Gaim object activated");
-
-
-	/* Create a proxy object for gaim */
-	
-	error = NULL;
-	proxy = dbus_g_proxy_new_for_name_owner (connection,
-						 DBUS_SERVICE_GAIM,
-						 DBUS_PATH_GAIM,
-						 DBUS_INTERFACE_GAIM,
-						 &error);
-  
-	if (proxy == NULL) {
-		g_assert(error);
-		g_critical("Failed to create proxy for name owner: %s.\n", 
-			   error->message);
-		g_clear_error(&error);
-		return 1;
-	}
-
-	g_message("Gaim proxy created");
-
-	/* Processing commands */
-
-	for(i=1; i<argc; i++) {
-		gboolean success = TRUE;
-		gchar *command = argv[i];
-		
-		error = NULL;
-		g_print("Executing command: %s ...\n", command);
-		
-		if (!strcmp(command, "quit")) 
-			success = org_gaim_GaimInterface_quit(proxy, &error);
-		else if (!strcmp(command, "ping")) 
-			success = org_gaim_GaimInterface_ping (proxy, &error);
-		else if (!strcmp(command, "connect")) 
-			success = org_gaim_GaimInterface_connect_all (proxy, &error);
-		else
-			g_print("Unknown command: %s.\n", command);
-		
-		if (!success) 
-			g_print ("Command %s failed: %s.\n", command, 
-				 error->message);
-
-		g_clear_error(&error);
-	}
-	
-	g_object_unref (G_OBJECT (proxy));
-	g_object_unref (G_OBJECT (driver));
-	g_print ("Successfully completed (%s).\n", argv[0]);
-  
-	return 0;
-}
--- a/src/dbus-service-end.xml	Tue Aug 23 20:51:13 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-
-  </interface>
-  
-
-  <interface name="org.freedesktop.DBus.Properties">
-    <!-- We implement properties ourselves rather than relying on
-	 GObject property access.  This is because currently in gaim
-	 we have one GObject that represents many dbus objects such as
-	 buddies, accounts, etc.  Not for long! -->
-
-<!--      <method name="Get"> > -->
-<!--        <arg type="s" name="interface_name" />  -->
-<!--        <arg type="s" name="property_name" />  -->
-<!--        <arg type="v" name="value" direction="out" />  -->
-<!--      </method>  -->
-   </interface> 
-</node>
-
--- a/src/dbus-service.xml	Tue Aug 23 20:51:13 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-
-<node name="/org/gaim/GaimObject">
-  <interface name="org.gaim.GaimInterface">
- 
-    <!-- autogenerated ... -->
-
--- a/src/dbus-types.c	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/dbus-types.c	Wed Aug 24 02:34:40 2005 +0000
@@ -1,3 +1,4 @@
+/* Generated by dbus-analyze-types.py.  Do not edit! */
 GAIM_DBUS_DEFINE_TYPE(GaimAccountUiOps)
 GAIM_DBUS_DEFINE_TYPE(GaimAccount)
 GAIM_DBUS_DEFINE_TYPE(GaimAccountOption)
--- a/src/dbus-types.h	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/dbus-types.h	Wed Aug 24 02:34:40 2005 +0000
@@ -1,3 +1,4 @@
+/* Generated by dbus-analyze-types.py.  Do not edit! */
 GAIM_DBUS_DECLARE_TYPE(GaimAccountUiOps)
 GAIM_DBUS_DECLARE_TYPE(GaimAccount)
 GAIM_DBUS_DECLARE_TYPE(GaimAccountOption)
--- a/src/dbus-useful.c	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/dbus-useful.c	Wed Aug 24 02:34:40 2005 +0000
@@ -1,16 +1,16 @@
 #include <string.h>
 #include <glib.h>
 
+#include "dbus-useful.h"
 #include "conversation.h"
 #include "util.h"
 
 
-
 GaimAccount *
 gaim_accounts_find_ext(const char *name, const char *protocol_id, 
 		       gboolean (*account_test)(const GaimAccount *account))
 {
-    GaimAccount *result = NULL;
+    GList *result = NULL;
     GList *l;
     char *who;
     
@@ -51,25 +51,3 @@
 }
 
 
-/* DBusMessage *gaim_account_set_status_DBUS(DBusMessage *message_DBUS, DBusError *error_DBUS)  */
-/* { */
-/*     DBusMessage *reply; */
-/*     DBusMessageIter iter; */
-
-/*     dbus_int32_t account, active;     */
-/*     char *status_id; */
-    
-/*     dbus_message_iter_init(message, &iter); */
-/* const char *name; */
-/* const char *protocol; */
-
-/* dbus_message_get_args(message_DBUS, error_DBUS,  DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &protocol, DBUS_TYPE_INVALID); */
-/* CHECK_ERROR(error_DBUS); */
-/* NULLIFY(name); */
-/* NULLIFY(protocol); */
-/* GAIM_DBUS_POINTER_TO_ID(RESULT, gaim_accounts_find_any(name, protocol), error_DBUS); */
-/* reply_DBUS =  dbus_message_new_method_return (message_DBUS); */
-/* dbus_message_append_args(reply_DBUS,  DBUS_TYPE_INT32, &RESULT,  DBUS_TYPE_INVALID); */
-/* return reply_DBUS; */
-
-/* } */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gaim-notifications-example.py	Wed Aug 24 02:34:40 2005 +0000
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+
+# This is a simple gaim notification server.
+# It shows notifications when your buddy signs on or you get an IM message.
+#
+# This script requires Python 2.4 and PyGTK bindings
+#
+# Note that all function names are resolved dynamically, no
+# gaim-specific library is needed.
+
+import dbus
+import dbus.glib
+import dbus.decorators
+import gobject
+import os
+
+def ensureimconversation(conversation, account, name):
+    if conversation != 0:
+        return conversation
+    else:
+        # 1 = GAIM_CONV_IM 
+        return gaim.GaimConversationNew(1, account, name)
+
+def receivedimmsg(account, name, message, conversation, flags):
+    buddy = gaim.GaimFindBuddy(account, name)
+    if buddy != 0:
+        alias = gaim.GaimBuddyGetAlias(buddy)
+    else:
+        alias = name
+
+    text = "%s says %s" % (alias, message)
+    code = os.spawnlp(os.P_WAIT, "xmessage", "xmessage", "-buttons",
+                      "'So what?','Show me',Close,Abuse", text)
+
+    if code == 101:                     # so what?
+        pass
+    else:
+        conversation = ensureimconversation(conversation, account, name)
+
+    if code == 102:                     # show me
+        window = gaim.GaimConversationGetWindow(conversation)
+        gaim.GaimConvWindowRaise(window)
+
+    if code == 103:                     # close 
+        gaim.GaimConversationDestroy(conversation)
+
+    if code == 104:                     # abuse
+        im = gaim.GaimConversationGetImData(conversation)
+        gaim.GaimConvImSend(im, "Go away you f...")
+                                 
+        
+def buddysignedon(buddyid):
+    alias = gaim.GaimBuddyGetAlias(buddyid)
+    text = "%s is online" % alias
+
+    code = os.spawnlp(os.P_WAIT, "xmessage", "xmessage", "-buttons",
+                      "'So what?','Let's talk'", text)
+
+    if code == 101:                     # so what?
+        pass
+
+    if code == 102:                     # let's talk
+        name = gaim.GaimBuddyGetName(buddyid)
+        account = gaim.GaimBuddyGetAccount(buddyid)
+        gaim.GaimConversationNew(1, account, name)
+    
+
+bus = dbus.SessionBus()
+obj = bus.get_object("org.gaim.GaimService", "/org/gaim/GaimObject")
+gaim = dbus.Interface(obj, "org.gaim.GaimInterface")
+
+bus.add_signal_receiver(receivedimmsg,
+                        dbus_interface = "org.gaim.GaimInterface",
+                        signal_name = "ReceivedImMsg")
+
+bus.add_signal_receiver(buddysignedon,
+                        dbus_interface = "org.gaim.GaimInterface",
+                        signal_name = "BuddySignedOn")
+
+print """This is a simple gaim notification server.
+It shows notifications when your buddy signs on or you get an IM message."""
+
+loop = gobject.MainLoop()
+loop.run()
+
+
--- a/src/gaim-remote.py	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/gaim-remote.py	Wed Aug 24 02:34:40 2005 +0000
@@ -111,7 +111,7 @@
     elif command == "getinfo":
         account = findaccount(accountname, protocol)
         connection = cgaim.GaimAccountGetConnection(account)
-        gaim.ServGetInfo(connection, params["screenname"])
+        return gaim.ServGetInfo(connection, params["screenname"])
 
     elif command == "quit":
         return gaim.GaimCoreQuit()
@@ -151,25 +151,41 @@
                                 methodparams.append(int(value))
                             else:
                                 raise "Don't know how to handle type \"%s\"" % type
-                            return gaim.__getattr__(command)(*methodparams)
+                    return gaim.__getattr__(command)(*methodparams)
             raise "Unknown command: %s" % command
 
-def example_code_do_not_call():
-    execute("jabber:addbuddy?screenname=friend")
-    execute("setstatus?status=away&message=don't disturb")
+
+if len(sys.argv) == 1:
+    print """This program uses DBus to communicate with gaim.
+
+Usage:
 
-    account = execute("GaimAccountsFindConnected?name=&protocol=")
-    execute("GaimConversationNew?type=1&account=%i&name=testone@localhost" % account)
+    %s "command1" "command2" ...
+
+Each command is of one of the three types:
+
+    [protocol:]commandname?param1=value1&param2=value2&...
+    FunctionName?param1=value1&param2=value2&...
+    FunctionName(value1,value2,...)
 
-    execute("jabber:addbuddy?screenname=friend")
-    execute("jabber:goim?screenname=testone@localhost&message=hi")
+The second and third form are provided for completeness but their use
+is not recommended; use gaim-send or gaim-send-async instead.  The
+second form uses introspection to find out the parameter names and
+their types, therefore it is rather slow.
+
+Examples of commands:
 
-    execute("jabber:gochat?room=TestRoom&server=conference.localhost")
-    execute("jabber:goim?screenname=testone@localhost&message=hi")
+    jabber:goim?screenname=testone@localhost&message=hi
+    jabber:gochat?room=TestRoom&server=conference.localhost
+    jabber:getinfo?screenname=testone@localhost
+    jabber:addbuddy?screenname=my friend
 
-
+    setstatus?status=away&message=don't disturb
+    quit
 
-
+    GaimAccountsFindConnected?name=&protocol=prpl-jabber
+    GaimAccountFindConnected(,prpl-jabber)
+""" % sys.argv[0]
 
 for arg in sys.argv[1:]:
     print execute(arg)
--- a/src/gaim-send	Tue Aug 23 20:51:13 2005 +0000
+++ b/src/gaim-send	Wed Aug 24 02:34:40 2005 +0000
@@ -1,31 +1,28 @@
 #!/bin/bash
-# 
-# A little shell script for communicating with gaim using dbus
 
 METHOD_NAME=$1
 
 if test -z "$METHOD_NAME" 
 then
     cat <<EOF 
-This program uses dbus to talk to gaim.  If the gaim is not running and
-the dbus engine is set up correctly, a new instance of gaim will be started.
+This program calls gaim API functions using DBus and prints the return value.
+If you are not interested in the return value, use gaim-send-async.
 
-   Syntax: gaim-send method-name parameter1 parameter2 ..."
+Usage:
+
+   $0 method-name type1:parameter1 type2:parameter2 ...
 
 This shell script just invokes dbus-send, see man dbus-send for how 
 to specify the parameters.  
 
 Examples:
 
-   gaim-send Ping 
-   gaim-send Quit
-   gaim-send GetBuddyList
-   gaim-send GetBuddyProperty int32:5 string:alias
-   gaim-send StartIMConversation int32:5
+   $0 GaimAccountsFindConnected string: string:prpl-jabber
+   $0 GaimAccountsGetAll
+   $0 GaimCoreQuit
 
-See src/dbus-services.xml for the list of supported operations.  
+Use dbus-viewer to get the list of supported functions and their parameters.
 EOF
-
     exit 1
 fi