remove tox, www

This commit is contained in:
Kai Tetzlaff 2009-03-29 21:24:39 +02:00
parent 37fb8b74f2
commit 80459bbecd
19 changed files with 0 additions and 2795 deletions

View File

@ -1,31 +0,0 @@
libexec_PROGRAMS=tox
tox_SOURCES=main.c tox.c tox-session.c tox.h tox-session.h \
$(BUILT_SOURCES)
EXTRA_DIST=tox-object.xml tox-session.xml tox-marshal.list
BUILT_SOURCES=tox-object-glue.h tox-session-glue.h tox-marshal.c tox-marshal.h
tox-object-glue.h : tox-object.xml
$(DBUS_BINDING_TOOL) --mode=glib-server --output=$@ --prefix=tox $(srcdir)/tox-object.xml
tox-session-glue.h : tox-session.xml
$(DBUS_BINDING_TOOL) --mode=glib-server --output=$@ --prefix=tox_session $(srcdir)/tox-session.xml
tox-marshal.c : tox-marshal.list
$(GLIB_GENMARSHAL) --prefix=tox_marshal $(srcdir)/tox-marshal.list --header --body > $@.tmp
mv $@.tmp $@
tox-marshal.h : tox-marshal.list
$(GLIB_GENMARSHAL) --prefix=tox_marshal $(srcdir)/tox-marshal.list --header > $@.tmp
mv $@.tmp $@
dbusservicedir=$(datadir)/dbus-1/services
dbusservice_DATA=tox.service
EXTRA_DIST+=tox.service.in
CLEANFILES=tox.service
tox.service: tox.service.in config.status
sed -e "s,@""libexecdir@,$(libexecdir)," $(srcdir)/tox.service.in > $@
dist_lisp_LISP=jabber-tox.el

View File

@ -1,98 +0,0 @@
Tox (Talk Over XMPP, or something) is a utility for adding Jingle
functionality to a Jabber client, primarily voice communication. It
interfaces to the Jabber client using DBus.
To actually get it to compile, you need the Farsight library. If you
use Debian, the packages "libfarsight0.1-dev" and
"gstreamer0.10-plugins-farsight" and their dependencies should be
enough. If you need to compile them yourself, look for Farsight at
http://farsight.freedesktop.org/ and Libjingle at
http://tapioca-voip.sourceforge.net/. Do _not_ use Google's
libjingle.
The DBus interface is described below. From this you should be able
to piece together a Jingle client. Good luck!
Tox registers the well-known name net.sourceforge.emacs-jabber.Tox
(NB: hyphen, not underscore) on the session bus.
/net/sourceforge/emacs_jabber/Tox (NB: underscore, not hyphen) is the
path to the main object.
This object has one method in the interface
net.sourceforge.emacs_jabber.Tox (NB: underscore, not hyphen):
object_path CreateSession(byte direction)
Creates an audio session. direction is 1 for "send only", 2 for
"receive only", and 3 for "send and receive". The path to the new
session is returned.
The session object in turn has methods in the interface
net.sourceforge.emacs_jabber.ToxSession (NB: underscore, not hyphen):
void Destroy()
Destroys the session.
void SetDefaultAudioSink()
Create an "autoaudiosink" GStreamer element and connect it to the
session. This usually means that you will hear things in your
speakers.
void SetOggVorbisAudioSource(string filename)
Set the named Ogg Vorbis file as audio source, i.e. what to send
over the session.
void AddRemoteCandidate(array components)
Add a transport candidate of the remote party, consisting of the
given components. "components" is an array of structs with
signature "(susqsssyyss)" and meaning:
- Candidate ID
- Component (starting from 1)
- IP number (as a string)
- Port number
- Protocol ("tcp" or "udp")
- Protocol subtype (only "RTP" supported)
- Protocol profile (only "AVP" supported)
- Preference, between 0 and 100
- Type. 0 means local, 1 means derived (e.g. through
STUN), 2 means relay
- Username (may be empty)
- Password (may be empty)
signal NewNativeCandidate(array components)
Signalled when a new local candidate has been determined. The
argument is the same as to AddRemoteCandidate.
signal NativeCandidatesPrepared(array components)
Signalled when the local candidates have been determined, and are
ready to send to the other party. The argument is the same as to
AddRemoteCandidate.
void SetRemoteCodecs(array codecs)
Set the codecs that the remote party claims to support. codecs is
an array of structs with signature "(isyuua{ss})" and meaning:
- numeric identifier
- codec name
- media type: 0 is audio, 1 is video
- clock rate
- number of channels
- optional parameters
array GetLocalCodecs()
Get the codecs supported by this implementation. The return value
is of the same type as the argument to SetRemoteCodecs.
array GetCodecIntersection()
Get the intersection of supported codecs of remote and local
parties. The return value is like the argument to SetRemoteCodecs.

View File

@ -1,20 +0,0 @@
AC_INIT([Talk over XMPP], [0.0.0], [emacs-jabber-general@lists.sourceforge.net], [tox])
AM_INIT_AUTOMAKE([foreign dist-bzip2 -Wall -Werror])
AC_PROG_CC
AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool,
[$am_missing_run dbus-binding-tool])
AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal,
[$am_missing_run glib-genmarshal])
PKG_CHECK_MODULES(FARSIGHT, [farsight-0.1], [], AC_MSG_ERROR([farsight not found; see README]))
PKG_CHECK_MODULES(DBUS, [dbus-glib-1], [], AC_MSG_ERROR([dbus-glib not found; see README]))
AC_SUBST(AM_CFLAGS, "$FARSIGHT_CFLAGS $DBUS_CFLAGS")
AC_SUBST(LDADD, "$FARSIGHT_LIBS $DBUS_LIBS")
AM_PATH_LISPDIR
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@ -1,497 +0,0 @@
;; jabber-tox.el - Jingle support using TOX
;; Copyright (C) 2008 - Magnus Henoch - mange@freemail.hu
;; This file is (soon) a part of jabber.el.
;; 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
(require 'dbus)
(require 'fsm)
(require 'cl)
(require 'jabber-xml)
(defconst jingle-ns "urn:xmpp:jingle:0"
"Jingle namespace (XEP-0166)")
(defconst jingle-error-ns "urn:xmpp:jingle:errors:0"
"Jingle error namespace (XEP-0166)")
(defconst jingle-rtp-ns "urn:xmpp:jingle:apps:rtp:0"
"Jingle RTP Sessions namespace (XEP-0167)")
(defconst jingle-ice-udp-ns "urn:xmpp:jingle:transports:ice-udp:0"
"Jingle ICE namespace (XEP-0176)")
(defvar jingle-acct-sid-map (make-hash-table :test 'equal)
"Mapping from pairs of JIDs and Jingle SIDs to FSMs.
The JID is the full JID of the account using the session.")
(defconst tox-name "net.sourceforge.emacs-jabber.Tox"
"Well-known D-BUS name of the tox service.")
(defconst tox-path "/net/sourceforge/emacs_jabber/Tox"
"Well-known path of the main Tox object.")
(defconst tox-interface "net.sourceforge.emacs_jabber.Tox"
"Interface of main Tox object.")
(defconst tox-session-interface "net.sourceforge.emacs_jabber.ToxSession"
"Interface of ToxSession object.")
(defvar tox-my-ogg-answering-machine
(replace-regexp-in-string
"\n" ""
(shell-command-to-string "locate '*.ogg' | head -1"))
"The Ogg file to play to anyone who calls to us.
This should go away once we have hooked up everything properly,
with microphone and so on. (Or maybe not...)")
(define-fsm jingle
:start ((jc sid role jid) "Start a Jingle FSM.
\(Specifically, for Jingle Audio, as that's all we support for now.)
JC is the account we're using.
SID is a string, the session ID.
ROLE is either :initiator or :target.
JID is the full JID of the partner."
(let ((state-data (list :jc jc :jid jid :sid sid :role role)))
(setq state-data (jingle-create-tox-session fsm state-data))
(list
(ecase (plist-get state-data :role)
(:initiator
:initiate)
(:target
:wait-for-initiate))
state-data))))
(defun jingle-create-tox-session (fsm state-data)
"Helper function to create a Tox session.
Accepts, modifies, and returns STATE-DATA."
;; XXX: should this always be bidirectional?
(let* ((tox-session
(dbus-call-method :session tox-name tox-path tox-interface
"CreateSession"
:byte 3)) ;3=bidirectional stream
;; Find the codecs that we support
(our-codecs
(dbus-call-method :session tox-name tox-session tox-session-interface
"GetLocalCodecs")))
(setq state-data (plist-put state-data :tox-session tox-session))
(setq state-data (plist-put state-data :our-codecs our-codecs))
(fsm-debug-output "tox-session: %S, our-codecs: %S" tox-session our-codecs)
;; Set up the pipeline, so we can search for transport candidates.
(fsm-debug-output "About to call SetDefaultAudioSink")
(dbus-call-method :session tox-name tox-session tox-session-interface
"SetDefaultAudioSink")
(fsm-debug-output "About to call SetOggVorbisAudioSource")
(dbus-call-method :session tox-name tox-session tox-session-interface
"SetOggVorbisAudioSource"
tox-my-ogg-answering-machine)
;; There, now we just wait for the NativeCandidatesPrepared signal...
;; NO! Don't do like those dead people do! That signal will never
;; come. I don't know why, though...
(fsm-debug-output "About to register signal")
(dbus-register-signal :session tox-name tox-session tox-session-interface
"NativeCandidatesPrepared"
(lexical-let ((fsm fsm))
(lambda (components)
(fsm-send-sync
fsm
(cons :native-candidates-prepared components)))))
;; This is more like it. At least it will provide us with some
;; debugging information.
(dbus-register-signal :session tox-name tox-session tox-session-interface
"NewNativeCandidate"
(lexical-let ((fsm fsm))
(lambda (components)
(fsm-send-sync
fsm
(cons :new-native-candidate components)))))
;; And we also want to know about state changes.
(dbus-register-signal :session tox-name tox-session tox-session-interface
"StateChanged"
(lexical-let ((fsm fsm))
(lambda (state direction)
(fsm-send-sync
fsm
(list :state-changed state direction)))))
;; And about active candidate pairs.
(dbus-register-signal :session tox-name tox-session tox-session-interface
"NewActiveCandidatePair"
(lexical-let ((fsm fsm))
(lambda (native-candidate remote-candidate)
(fsm-send-sync
fsm
(list :new-active-candidate-pair
native-candidate remote-candidate)))))
(fsm-debug-output "Waiting")
state-data))
(define-enter-state jingle nil
(fsm state-data)
;; XXX: send termination stanza, if appropriate
;; clean up
(let ((tox-session (plist-get state-data :tox-session)))
(when tox-session
(ignore-errors
(dbus-call-method :session tox-name tox-session tox-session-interface
"Destroy"))))
(remhash (cons (jabber-connection-jid (plist-get state-data :jc))
(plist-get state-data :sid))
jingle-acct-sid-map)
(list nil nil))
(define-enter-state jingle :initiate
(fsm state-data)
(let ((jc (plist-get state-data :jc))
(jid (plist-get state-data :jid))
(sid (plist-get state-data :sid))
(payload-types (mapcar
(lambda (codec)
`(payload-type
((id . ,(number-to-string (nth 0 codec)))
(name . ,(nth 1 codec))
;; (nth 2 codec) is media type;
;; should we filter out
;; non-audio codecs? then
;; again, the value seems to be
;; bogus...
(clockrate . ,(number-to-string (nth 3 codec)))
,@(let ((channels (nth 4 codec)))
(unless (= channels 0)
`((channels . ,(number-to-string channels))))))
,@(mapcar
(lambda (param)
`(parameter
((name . ,(nth 0 param))
(value . ,(nth 1 param)))))
(nth 5 codec))))
(plist-get state-data :our-codecs))))
(jabber-send-iq jc jid "set"
`(jingle ((xmlns . ,jingle-ns)
(action . "session-initiate")
(initiator . ,(jabber-connection-jid jc))
(sid . ,sid))
(content
((creator . "initiator")
(name . "foo")
(senders . "initiator"))
(description
((xmlns . ,jingle-rtp-ns)
(media . "audio"))
,@payload-types)
(transport ((xmlns . ,jingle-ice-udp-ns)))))
(lambda (jc iq fsm)
(fsm-send-sync fsm (cons :iq-result iq)))
fsm
(lambda (jc iq fsm)
(fsm-send-sync fsm (cons :iq-error iq)))
fsm)
(list state-data nil)))
(define-state jingle :initiate
(fsm state-data event callback)
(case (car-safe event)
(:iq-result
;; Receiver provisionally accepted the session request. Move on
;; to PENDING.
(list :pending state-data))
(:iq-error
(message "Couldn't initiate Jingle audio session: %s"
(jabber-parse-error (jabber-iq-error (cdr event))))
(list nil state-data))
(:new-native-candidate
(let ((components (cdr event)))
(jingle-send-native-candidate state-data components)
(list :initiate state-data)))))
(define-state jingle :wait-for-initiate
(fsm state-data event callback)
(case (car-safe event)
(:iq-set
(let* ((jc (plist-get state-data :jc))
(iq (cdr event))
(from (jabber-xml-get-attribute iq 'from))
(id (jabber-xml-get-attribute iq 'id))
(jingle (jabber-iq-query iq))
(action (jabber-xml-get-attribute jingle 'action))
;; XXX: could be more than one...
(content (car (jabber-xml-get-children jingle 'content)))
;; XXX: is it really audio?
(audio-content (find jingle-rtp-ns (jabber-xml-node-children content)
:test 'string=
:key 'jabber-xml-get-xmlns))
(payload-types (jabber-xml-get-children audio-content 'payload-type)))
;; There are very few reasons for which we should not send an
;; acknowledgement here; see section 6.3.2 of XEP-0166.
;; Notably, we might want to check that there is a presence
;; subscription.
(jabber-send-iq jc from "result" ()
nil nil nil nil id)
(unless (string= action "session-initiate")
(fsm-debug-output "Action is %S. Why is it not \"session-initiate\"?" action))
(cond
;; Make sure audio is in the list of contents. We can
;; negotiate away other content types later.
((null audio-content)
(jingle-send-iq state-data "session-terminate"
'((reason () (unsupported-applications))))
(list nil state-data))
;; Make sure ICE is in the list of transports.
((not (member* jingle-ice-udp-ns
(jabber-xml-get-children content 'transport)
:test 'string=
:key 'jabber-xml-get-xmlns))
(jingle-send-iq state-data "session-terminate"
'((reason () (unsupported-transports))))
(list nil state-data))
(t
(let ((tox-session (plist-get state-data :tox-session))
(their-codecs (mapcar
(lambda (pt)
(jabber-xml-let-attributes
(id name clockrate channels) pt
(list :struct
:int32 (string-to-number id)
:string name
:byte 0
:uint32 (string-to-number clockrate)
:uint32 (if channels
(string-to-number channels)
1)
(cons
:array
(or
(mapcar
(lambda (param)
(jabber-xml-let-attributes
(name value) param
(list :dict-entry :string name :string value)))
(jabber-xml-get-children pt 'parameter))
(list :signature "{ss}"))))))
payload-types)))
(fsm-debug-output "Their codecs are %S" their-codecs)
;; Tell tox what codecs the remote side supports
(dbus-call-method
:session tox-name tox-session tox-session-interface
"SetRemoteCodecs"
;;'((array (struct int32 string byte uint32 uint32 (array (dict-entry string string)))))
their-codecs)
;; Check if we have any codecs in common
(let ((codec-intersection
(dbus-call-method
:session tox-name tox-session tox-session-interface
"GetCodecIntersection")))
(fsm-debug-output "The codec intersection is %S" codec-intersection)
(setq state-data
(plist-put
state-data
:codec-intersection codec-intersection))
(if codec-intersection
;; So, now we know that we stand a basic chance of fulfilling
;; the request. Let's move on to PENDING.
(list :pending state-data)
;; Or, it might turn out that we don't have any codecs
;; in common with our partner.
(jingle-send-iq state-data "session-terminate"
'((reason () (media-error))))
(list nil state-data))))))))))
;; Thu Jan 1 16:49:23 2009: Warning: event (:new-native-candidate ("L1" 1 "127.0.0.1" 33582 "udp" "RTP" "AVP" 100 0 "Pmc4YPYhJyGPWKIv" "GKQ5/XFIE0pp8+6y")) ignored in state jingle/:pending
;; Thu Jan 1 16:49:23 2009: Warning: event (:iq-set iq ((from . "legoscia@jabber.cd.chalmers.se/2868723341230824321901526") (to . "magnus.henoch@jabber.se/2635526438123082419775630") (type . "set") (id . "emacs-iq-18780.58883.21969")) (jingle ((xmlns . "urn:xmpp:jingle:0") (action . "transport-info") (initiator . "legoscia@jabber.cd.chalmers.se/2868723341230824321901526") (sid . "emacs-sid-18780.58881.712027")) (content ((creator . "initiator") (name . "foo")) (transport ((xmlns . "urn:xmpp:jingle:transports:ice-udp:0")) (candidate ((component . "1") (ip . "127.0.0.1") (port . "44319") (protocol . "udp") (priority . "100"))))))) ignored in state jingle/:pending
;; Thu Jan 1 16:50:07 2009: Warning: event (:state-changed 0 0) ignored in state jingle/:pending
(define-state jingle :pending
(fsm state-data event callback)
(case (car-safe event)
(:state-changed
(let ((state (car (assq (second event)
'((0 . :disconnected)
(1 . :connecting)
(2 . :connected)))))
(direction (car (assq (third event)
'((0 . nil)
(1 . :send-only)
(2 . :receive-only)
(3 . :send-and-receive))))))
(fsm-debug-output "Got :state-changed; new state %s, new direction %s"
state direction)
(case state
(0
;; Do we have enough information to send the termination stanza?
(list nil state-data)))
;; Still, not sure what we should do here...
))
(:new-native-candidate
(let ((components (cdr event)))
(jingle-send-native-candidate state-data components)
(list :pending state-data)))
(:iq-set
(fsm-debug-output "iq-set event is %S" event)
(let* ((jc (plist-get state-data :jc))
(iq (cdr event)))
(jabber-xml-let-attributes (action) (jabber-iq-query iq)
(fsm-debug-output "action is %S" action)
(cond
((string= action "transport-info")
(fsm-debug-output "transport-info is %S" iq)
(let ((tox-session (plist-get state-data :tox-session))
(candidates
(jabber-xml-get-children
(jabber-xml-path
iq
`(jingle content (,jingle-ice-udp-ns . "transport")))
'candidate)))
;; XXX: send iq error for no candidates
(when candidates
(fsm-debug-output "Adding remote candidate...")
(dbus-call-method :session tox-name tox-session tox-session-interface
"AddRemoteCandidate"
(mapcar
'jingle-parse-candidate
candidates))
;; XXX: iq result
(list :pending state-data)
)))
(t
;; XXX: send "bad-request" or something
)))))))
(defun jingle-send-iq (state-data action payload)
"Send a Jingle IQ stanza from within a Jingle FSM.
STATE-DATA is the state data plist of the FSM.
ACTION is the value of the action attribute of the <jingle/>
element.
PAYLOAD is a list of XML elements to include as children
of the <jingle/> element.
The recipient and the SID are determined from STATE-DATA."
(let ((jc (plist-get state-data :jc))
(jid (plist-get state-data :jid))
(role (plist-get state-data :role))
(sid (plist-get state-data :sid)))
(jabber-send-iq
jc jid "set"
`(jingle ((xmlns . ,jingle-ns)
(action . ,action)
(initiator
. ,(ecase role
(:initiator
(jabber-connection-jid jc))
(:target
jid)))
(sid . ,sid))
,@payload)
;; XXX: we probably want error checking, to see if our partner
;; went offline.
nil nil nil nil)))
(defun jingle-send-native-candidate (state-data candidate)
"Send a native candidate for ICE-UDP.
The CANDIDATE is a list of components, as provided by the
NewNativeCandidate signal of Tox."
;; XXX: check against XEP-0176
(jingle-send-iq state-data "transport-info"
`((content
((creator . "initiator")
(name . "foo"))
(transport
((xmlns . ,jingle-ice-udp-ns))
,@(mapcar
(lambda (c)
`(candidate
((id . ,(nth 0 c))
(component . ,(number-to-string (nth 1 c)))
;; foundation?
;; generation?
(ip . ,(nth 2 c))
;; network?
(port . ,(number-to-string (nth 3 c)))
(protocol . ,(nth 4 c))
;; (nth 5 c) is always "RTP"
;; (nth 6 c) is always "AVP"
(priority . ,(nth 7 c))
;; (nth 8 c) is type. how to translate it?
(username . ,(nth 9 c))
(password . ,(nth 10 c))
)))
candidate))))))
(defun jingle-parse-candidate (candidate)
"Parse an XEP-0176 <candidate/> element into DBus format.
Specifically, the signature is \"(susqsssyyss)\"."
;; XXX: check against XEP-0176 again
(jabber-xml-let-attributes
(id component foundation generation
ip port protocol priority type
username password)
candidate
(list :string id
:uint32 (string-to-number component)
:string ip
:uint16 (string-to-number port)
"udp" "RTP" "AVP"
:byte (string-to-number priority) ;XXX: priority is preference?
:byte 0 ;XXX: fix type
:string (or username "")
:string (or password ""))))
(add-to-list 'jabber-iq-set-xmlns-alist
(cons jingle-ns 'jabber-jingle-incoming-iq))
(defun jabber-jingle-incoming-iq (jc iq)
(jabber-xml-let-attributes
(sid action) (jabber-iq-query iq)
(unless (and sid action)
(jabber-signal-error "modify" 'bad-request))
(let ((fsm (gethash (cons (jabber-connection-jid jc) sid) jingle-acct-sid-map)))
(cond
(fsm
(fsm-send-sync fsm (cons :iq-set iq)))
((string= action "session-initiate")
(condition-case e
(setq fsm (start-jingle jc sid :target (jabber-xml-get-attribute iq 'from)))
(error
(jabber-signal-error "wait" 'internal-server-error
(concat "Couldn't accept Jingle session: "
(error-message-string e)))))
(puthash (cons (jabber-connection-jid jc) sid) fsm jingle-acct-sid-map)
(fsm-send-sync fsm (cons :iq-set iq)))
(t
(jabber-signal-error "modify" 'bad-request
(format "Session \"%s\" unknown" sid)
`((unknown-session ((xmlns . ,jingle-error-ns))))))))))
(defun jabber-jingle-start-audio-session (jc jid)
(interactive
(list (jabber-read-account)
(jabber-read-jid-completing "Voice call to: " nil nil nil 'full)))
(let* ((sid (apply 'format "emacs-sid-%d.%d.%d" (current-time)))
(fsm (start-jingle jc sid :initiator jid)))
(puthash (cons (jabber-connection-jid jc) sid) fsm jingle-acct-sid-map)))
(provide 'jabber-tox)

View File

@ -1,70 +0,0 @@
#include <farsight/farsight.h>
#include <dbus/dbus-glib.h>
#include <glib/gprintf.h>
#include <string.h>
#include "tox.h"
int
main(int argc, char *argv[])
{
GMainLoop *loop;
DBusGConnection *connection;
DBusGProxy *bus_proxy;
GError *error = NULL;
ToxObject *obj;
guint32 x;
g_type_init();
gst_init(&argc, &argv);
{
GLogLevelFlags fatal_mask;
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
/* not aborting on warnings because of:
farsight-rtp-WARNING **: Not enough information in rtp caps
*/
fatal_mask |= /*G_LOG_LEVEL_WARNING | */ G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask);
}
connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (connection == NULL) {
g_printerr("Failed to open connection to bus: %s\n",
error->message);
exit(1);
}
bus_proxy = dbus_g_proxy_new_for_name(connection, "org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus");
g_debug("About to request D-Bus name...\n");
if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error,
G_TYPE_STRING, "net.sourceforge.emacs-jabber.Tox",
G_TYPE_UINT,
/* these settings are good for debugging. we
should listen for the NameLost signal, though. */
DBUS_NAME_FLAG_ALLOW_REPLACEMENT
| DBUS_NAME_FLAG_REPLACE_EXISTING
| DBUS_NAME_FLAG_DO_NOT_QUEUE,
G_TYPE_INVALID,
G_TYPE_UINT, &x,
G_TYPE_INVALID)) {
g_printerr("Couldn't acquire name: %s\n", error->message);
exit(1);
}
else if (x != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
g_printerr("Couldn't acquire name: RequestName returned %u\n", x);
exit(1);
}
g_debug("D-Bus name acquired\n");
obj = g_object_new(TOX_TYPE_OBJECT, "dbus-connection", connection, NULL);
dbus_g_connection_register_g_object(connection, "/net/sourceforge/emacs_jabber/Tox", G_OBJECT(obj));
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
return 0;
}

View File

@ -1,3 +0,0 @@
VOID:BOXED
VOID:UCHAR,UCHAR
VOID:STRING,STRING

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name='/net/sourceforce/emacs_jabber/Tox'>
<!-- Note the underscore in the interface name!
Bus names can have hyphens, but interface names can't.
I guess that's a good way to distinguish them. -->
<interface name='net.sourceforge.emacs_jabber.Tox'>
<method name='CreateSession'>
<!-- 1: send only.
2: receive only.
3: send and receive.
-->
<arg name='direction' direction='in' type='y'/>
<arg name='session' type='o' direction='out'/>
</method>
</interface>
</node>

View File

@ -1,752 +0,0 @@
#include <glib.h>
#include <farsight/farsight.h>
#include <farsight/farsight-transport.h>
#include <dbus/dbus-glib.h>
#include <glib/gprintf.h>
#include <string.h>
#include "tox-session.h"
#include "tox-marshal.h"
G_DEFINE_TYPE(ToxSession, tox_session, G_TYPE_OBJECT)
typedef struct _ToxSessionPrivate {
FarsightSession *session;
/* for now, one stream is enough */
FarsightStream *stream;
int have_source, have_sink;
gboolean dispose_has_run;
} ToxSessionPrivate;
gboolean tox_session_destroy(ToxSession *obj, GError **error);
gboolean tox_session_set_default_audio_sink(ToxSession *obj, GError **error);
gboolean tox_session_set_ogg_vorbis_audio_source(ToxSession *obj, char *filename, GError **error);
gboolean tox_session_add_remote_candidate(ToxSession *obj, GPtrArray *candidate, GError **error);
gboolean tox_session_set_remote_codecs(ToxSession *obj, GPtrArray *codecs, GError **error);
gboolean tox_session_get_local_codecs(ToxSession *obj, GPtrArray **codecs, GError **error);
gboolean tox_session_get_codec_intersection(ToxSession *obj, GPtrArray **codecs, GError **error);
/* properties */
enum {
DIRECTION = 1
};
static void tox_session_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec);
/* signals */
enum {
NEW_NATIVE_CANDIDATE,
NATIVE_CANDIDATES_PREPARED,
STATE_CHANGED,
NEW_ACTIVE_CANDIDATE_PAIR,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
#include "tox-session-glue.h"
static GstElement *prepare_source(const char *filename);
static void new_pad(GstElement *, GstPad *, gpointer);
static GstElement *prepare_sink(void);
static void stream_done(ToxSession *);
static GValueArray * candidate_list_to_dbus_array(const GList *candidates);
static void tox_session_native_candidates_prepared(FarsightStream *stream, gpointer user_data);
static void tox_session_new_native_candidate(FarsightStream *stream, gchar *candidate_id, ToxSession *self);
static void tox_session_state_changed(FarsightStream *stream, gint state, gint direction, ToxSession *self);
static void tox_session_new_active_candidate_pair(FarsightStream *stream, gchar *native_candidate_id, gchar *remote_candidate_id, ToxSession *self);
void
tox_session_init(ToxSession *obj)
{
ToxSessionPrivate *priv;
priv = g_new0(ToxSessionPrivate, 1);
obj->priv = priv;
priv->session = farsight_session_factory_make("rtp");
g_assert(priv->session);
/* we need to know the direction to create a stream,
so we do that when that property is set.
*/
}
static GObjectClass *parent_class = NULL;
static void
tox_session_dispose(GObject *obj)
{
ToxSession *self = (ToxSession *)obj;
if (self->priv->dispose_has_run) {
return;
}
g_debug("in tox_session_dispose\n");
self->priv->dispose_has_run = TRUE;
if (self->priv->stream)
g_object_unref(self->priv->stream);
if (self->priv->session)
g_object_unref(self->priv->session);
self->priv->stream = NULL;
self->priv->session = NULL;
G_OBJECT_CLASS(parent_class)->dispose(obj);
}
static void
tox_session_finalize(GObject *obj)
{
ToxSession *self = (ToxSession *)obj;
g_debug("in tox_session_finalize\n");
g_free(self->priv);
G_OBJECT_CLASS(parent_class)->finalize(obj);
}
void
tox_session_class_init(ToxSessionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
GParamSpec *direction_param_spec;
gobject_class->dispose = tox_session_dispose;
gobject_class->finalize = tox_session_finalize;
gobject_class->set_property = tox_session_set_property;
direction_param_spec = g_param_spec_uint("direction",
"stream direction",
"1 means send-only, 2 means receive-only, 3 means both",
1,
3,
1,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property(gobject_class,
DIRECTION,
direction_param_spec);
signals[NEW_NATIVE_CANDIDATE] =
g_signal_new("new-native-candidate",
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
tox_marshal_VOID__BOXED,
G_TYPE_NONE,
1,
G_TYPE_VALUE_ARRAY);
signals[NATIVE_CANDIDATES_PREPARED] =
g_signal_new("native-candidates-prepared",
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
tox_marshal_VOID__BOXED,
G_TYPE_NONE,
1,
G_TYPE_VALUE_ARRAY);
signals[STATE_CHANGED] =
g_signal_new("state-changed",
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
tox_marshal_VOID__UCHAR_UCHAR,
G_TYPE_NONE,
2,
G_TYPE_UCHAR,
G_TYPE_UCHAR);
signals[NEW_ACTIVE_CANDIDATE_PAIR] =
g_signal_new("new-active-candidate-pair",
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
tox_marshal_VOID__STRING_STRING,
G_TYPE_NONE,
2,
G_TYPE_STRING,
G_TYPE_STRING);
dbus_g_object_type_install_info(TOX_TYPE_SESSION, &dbus_glib_tox_session_object_info);
parent_class = g_type_class_peek_parent (klass);
}
static void
tox_session_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec)
{
ToxSession *self = (ToxSession *)obj;
guint dir;
switch(property_id) {
case DIRECTION:
if (self->priv->stream)
g_object_unref(self->priv->stream);
/* Now we know the direction, so we create a stream. */
dir = g_value_get_uint(value);
self->priv->stream = farsight_session_create_stream(self->priv->session,
FARSIGHT_MEDIA_TYPE_AUDIO,
dir);
g_assert(self->priv->stream);
g_object_set(G_OBJECT(self->priv->stream), "transmitter", "libjingle", NULL);
/* XXX: should we set null source/sink here? */
switch (dir) {
case 1:
/* send-only, we need no sink */
self->priv->have_sink = 1;
break;
case 2:
/* receive-only, we need no source */
self->priv->have_source = 1;
break;
}
/* start preparing native candidates */
g_debug("About to prepare native candidates...\n");
g_signal_connect(self->priv->stream, "new-native-candidate",
(GCallback)tox_session_new_native_candidate, (gpointer)self);
g_signal_connect(self->priv->stream, "native-candidates-prepared",
(GCallback)tox_session_native_candidates_prepared, (gpointer)self);
/* but we can't actually do it until we have a pipeline.
so, we'll call stream_done when we do. */
/* Other signals we want to forward */
g_signal_connect(self->priv->stream, "state-changed",
(GCallback)tox_session_state_changed, (gpointer)self);
g_signal_connect(self->priv->stream, "new-active-candidate-pair",
(GCallback)tox_session_new_active_candidate_pair, (gpointer)self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
}
}
gboolean
tox_session_destroy(ToxSession *obj, GError **error)
{
g_object_unref(obj);
return TRUE;
}
gboolean
tox_session_set_default_audio_sink(ToxSession *obj, GError **error)
{
GstElement *sink = prepare_sink();
farsight_stream_set_sink(obj->priv->stream, sink);
obj->priv->have_sink = 1;
if (obj->priv->have_sink && obj->priv->have_source)
stream_done(obj);
return TRUE;
}
gboolean
tox_session_set_ogg_vorbis_audio_source(ToxSession *obj, char *filename, GError **error)
{
GstElement *source = prepare_source(filename);
farsight_stream_set_source(obj->priv->stream, source);
obj->priv->have_source = 1;
if (obj->priv->have_sink && obj->priv->have_source)
stream_done(obj);
return TRUE;
}
static GstElement *
prepare_source(const char *filename)
{
GstElement *bin, *filesrc, *demux, *decode;
bin = gst_bin_new("mysource");
filesrc = gst_element_factory_make("filesrc", "file-source");
g_object_set(G_OBJECT(filesrc), "location", filename, NULL);
demux = gst_element_factory_make("oggdemux", "ogg-parser");
decode = gst_element_factory_make("vorbisdec", "vorbis-decoder");
gst_element_link(filesrc, demux);
g_signal_connect(demux, "pad-added", G_CALLBACK(new_pad), decode);
gst_bin_add_many(GST_BIN(bin), filesrc, demux, decode, NULL);
return bin;
}
static void
new_pad(GstElement *demux, GstPad *pad, gpointer data)
{
GstElement *decode = (GstElement*)data;
GstPad *decoder_pad;
decoder_pad = gst_element_get_pad(decode, "sink");
gst_pad_link(pad, decoder_pad);
gst_object_unref(decoder_pad);
}
static GstElement *
prepare_sink(void)
{
GstElement *bin, *converter, *audiosink;
bin = gst_bin_new("mysink");
converter = gst_element_factory_make("audioconvert", "converter");
audiosink = gst_element_factory_make("autoaudiosink", "audiosink");
gst_element_link(converter, audiosink);
gst_bin_add_many(GST_BIN(bin), converter, audiosink, NULL);
return bin;
}
static void
stream_done(ToxSession *self)
{
farsight_stream_prepare_transports(self->priv->stream);
}
gboolean
tox_session_add_remote_candidate(ToxSession *self, GPtrArray *candidate, GError **error)
{
int i;
guint n;
GList *candidate_list;
candidate_list = NULL;
/* Here we convert the array of structs into a GList of
FarsightTransportInfo. The argument list is described in
tox-session.xml. */
for (i = 0; i < candidate->len; i++) {
GValueArray *component;
FarsightTransportInfo *info;
gchar *s;
component = g_ptr_array_index(candidate, i);
info = g_new0(FarsightTransportInfo, 1);
info->candidate_id =
g_value_dup_string(
g_value_array_get_nth(component, 0));
info->component =
g_value_get_uint(
g_value_array_get_nth(component, 1));
info->ip =
g_value_dup_string(
g_value_array_get_nth(component, 2));
info->port =
g_value_get_uint(
g_value_array_get_nth(component, 3));
s = g_value_dup_string(g_value_array_get_nth(component, 4));
if (strcmp(s, "tcp") == 0)
info->proto = FARSIGHT_NETWORK_PROTOCOL_TCP;
else if (strcmp(s, "udp") == 0)
info->proto = FARSIGHT_NETWORK_PROTOCOL_UDP;
else {
g_set_error(error, DBUS_GERROR,
DBUS_GERROR_REMOTE_EXCEPTION,
"Unexpected protocol '%s'",
s);
g_free(s);
g_free(info);
goto fail;
}
g_free(s);
/* this should be "RTP" */
info->proto_subtype =
g_value_dup_string(
g_value_array_get_nth(component, 5));
/* this should be "AVP" */
info->proto_profile =
g_value_dup_string(
g_value_array_get_nth(component, 6));
info->preference =
g_value_get_uint(
g_value_array_get_nth(component, 7))
* 0.01;
n = g_value_get_uint(g_value_array_get_nth(component, 8));
switch (n) {
case 0:
info->type = FARSIGHT_CANDIDATE_TYPE_LOCAL;
break;
case 1:
info->type = FARSIGHT_CANDIDATE_TYPE_DERIVED;
break;
case 2:
info->type = FARSIGHT_CANDIDATE_TYPE_RELAY;
break;
default:
g_set_error(error, DBUS_GERROR,
DBUS_GERROR_REMOTE_EXCEPTION,
"Unexpected type %u",
n);
g_free(info);
goto fail;
}
info->username = g_value_dup_string(
g_value_array_get_nth(component, 9));
info->password = g_value_dup_string(
g_value_array_get_nth(component, 10));
candidate_list = g_list_append(candidate_list, info);
}
farsight_stream_add_remote_candidate(self->priv->stream, candidate_list);
return TRUE;
fail:
farsight_transport_list_destroy(candidate_list);
return FALSE;
}
gboolean
tox_session_set_remote_codecs(ToxSession *obj, GPtrArray *codecs, GError **error)
{
GList *codec_list;
int i;
/* GList *j; */
codec_list = NULL;
for (i = 0; i < codecs->len; i++) {
GValueArray *codec_in;
FarsightCodec *codec_out;
codec_in = g_ptr_array_index(codecs, i);
codec_out = g_new0(FarsightCodec, 1);
codec_out->id = g_value_get_int(g_value_array_get_nth(codec_in, 0));
codec_out->encoding_name = g_value_dup_string(g_value_array_get_nth(codec_in, 1));
/* maybe check range of media_type... */
codec_out->media_type = g_value_get_uchar(g_value_array_get_nth(codec_in, 2));
codec_out->clock_rate = g_value_get_uint(g_value_array_get_nth(codec_in, 3));
codec_out->channels = g_value_get_uint(g_value_array_get_nth(codec_in, 4));
codec_list = g_list_append(codec_list, codec_out);
}
farsight_stream_set_remote_codecs(obj->priv->stream, codec_list);
/* should the elements be freed, or just the list itself? */
/*for (j = codec_list; j; j = g_list_next(j)) {
g_free(j->data);
}*/
g_list_free(codec_list);
return TRUE;
}
gboolean
tox_session_get_local_codecs(ToxSession *obj, GPtrArray **codecs, GError **error)
{
FarsightStream *stream;
const GList *codec_list;
GType hash_string_string;
stream = obj->priv->stream;
codec_list = farsight_stream_get_local_codecs(stream);
hash_string_string = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_STRING);
*codecs = g_ptr_array_sized_new(g_list_length(codec_list));
for (; codec_list; codec_list = g_list_next(codec_list)) {
GValueArray *codec_struct;
const FarsightCodec *codec;
GValue value;
GHashTable *parameters;
GList *p;
memset(&value, 0, sizeof value);
codec = (const FarsightCodec*)codec_list->data;
codec_struct = g_value_array_new(2);
g_value_init(&value, G_TYPE_INT);
g_value_set_int(&value, codec->id);
g_value_array_append(codec_struct, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, codec->encoding_name);
g_value_array_append(codec_struct, &value);
g_value_unset(&value);
/* XXX: why is this the same as id? */
g_value_init(&value, G_TYPE_UCHAR);
g_value_set_uchar(&value, codec->media_type);
g_value_array_append(codec_struct, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_UINT);
g_value_set_uint(&value, codec->clock_rate);
g_value_array_append(codec_struct, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_UINT);
g_value_set_uint(&value, codec->channels);
g_value_array_append(codec_struct, &value);
g_value_unset(&value);
/* optional parameters - this should be a hash table, I think */
/* parameters = g_hash_table_new(g_str_hash, g_str_equal); */
parameters = dbus_g_type_specialized_construct(hash_string_string);
for (p = codec->optional_params; p; p = g_list_next(p)) {
FarsightCodecParameter *param = p->data;
g_hash_table_insert(parameters, param->name, param->value);
}
g_value_init(&value, hash_string_string);
g_value_set_boxed(&value, parameters);
g_value_array_append(codec_struct, &value);
g_value_unset(&value);
g_hash_table_unref(parameters);
g_assert(codec_struct->n_values == 6);
g_ptr_array_add(*codecs, codec_struct);
g_debug("Local codec: %s\n", codec->encoding_name);
}
return TRUE;
}
gboolean
tox_session_get_codec_intersection(ToxSession *obj, GPtrArray **codecs, GError **error)
{
FarsightStream *stream;
GList *codec_list;
stream = obj->priv->stream;
codec_list = farsight_stream_get_codec_intersection(stream);
*codecs = g_ptr_array_sized_new(g_list_length(codec_list));
for (; codec_list; codec_list = g_list_next(codec_list)) {
GValueArray *codec_struct;
FarsightCodec *codec;
GValue *value;
codec = (FarsightCodec*)codec_list->data;
codec_struct = g_value_array_new(6);
value = g_new0(GValue, 1);
g_value_init(value, G_TYPE_INT);
g_value_set_int(value, codec->id);
g_value_array_append(codec_struct, value);
value = g_new0(GValue, 1);
g_value_init(value, G_TYPE_STRING);
g_value_set_string(value, codec->encoding_name);
g_value_array_append(codec_struct, value);
value = g_new0(GValue, 1);
g_value_init(value, G_TYPE_UCHAR);
g_value_set_uchar(value, codec->media_type);
g_value_array_append(codec_struct, value);
value = g_new0(GValue, 1);
g_value_init(value, G_TYPE_UINT);
g_value_set_uint(value, codec->clock_rate);
g_value_array_append(codec_struct, value);
value = g_new0(GValue, 1);
g_value_init(value, G_TYPE_UINT);
g_value_set_uint(value, codec->channels);
g_value_array_append(codec_struct, value);
/* XXX: do something about optional parameters */
value = g_new0(GValue, 1);
g_value_init(value, DBUS_TYPE_G_STRING_STRING_HASHTABLE);
g_value_set_boxed(value, g_hash_table_new(g_str_hash, g_str_equal));
g_value_array_append(codec_struct, value);
g_assert(codec_struct->n_values == 6);
g_ptr_array_add(*codecs, codec_struct);
}
return TRUE;
}
static void
tox_session_native_candidates_prepared(FarsightStream *stream, gpointer user_data)
{
ToxSession *self = (ToxSession *)user_data;
const GList *candidates;
GValueArray *array;
candidates = farsight_stream_get_native_candidate_list(stream);
array = candidate_list_to_dbus_array(candidates);
g_debug("Sending signal NativeCandidatesPrepared!\n");
g_signal_emit(self, signals[NATIVE_CANDIDATES_PREPARED], 0, array);
}
static void
tox_session_new_native_candidate(FarsightStream *stream, gchar *candidate_id, ToxSession *self)
{
GList *candidate =
farsight_stream_get_native_candidate (stream, candidate_id);
FarsightTransportInfo *trans = candidate->data;
GValueArray *array;
g_debug ("tox_session_new_native_candidate: New native candidate"
" with %d components, the first being: "
"<id: %s, "
"component: %d, "
"ip: %s port: %d "
"proto: %d, "
"proto_subtype: %s, "
"proto_profile: %s, "
"preference: %f, "
"type: %d "
"username: %s password: %s>",
g_list_length(candidate),
trans->candidate_id, trans->component,
trans->ip, trans->port, trans->proto, trans->proto_subtype,
trans->proto_profile, trans->preference,
trans->type, trans->username, trans->password);
array = candidate_list_to_dbus_array(candidate);
g_debug("Sending signal NewNativeCandidate!\n");
g_signal_emit(self, signals[NEW_NATIVE_CANDIDATE], 0, array);
}
static GValueArray *
candidate_list_to_dbus_array(const GList *candidates)
{
GValueArray *array;
array = g_value_array_new(1);
for (; candidates; candidates = g_list_next(candidates)) {
GValueArray *candidate;
FarsightTransportInfo *info;
GValue value;
info = (FarsightTransportInfo*)candidates->data;
candidate = g_value_array_new(11);
memset(&value, 0, sizeof value);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, info->candidate_id);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_UINT);
g_value_set_uint(&value, info->component);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, info->ip);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_UINT);
g_value_set_uint(&value, info->port);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
switch(info->proto) {
case FARSIGHT_NETWORK_PROTOCOL_UDP:
g_value_set_static_string(&value, "udp");
break;
case FARSIGHT_NETWORK_PROTOCOL_TCP:
g_value_set_static_string(&value, "tcp");
break;
default:
g_error("Unknown protocol value %u\n", info->proto);
}
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, info->proto_subtype);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, info->proto_profile);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_UINT);
g_value_set_uint(&value, (guint)(info->preference * 100));
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_UINT);
switch(info->type) {
case FARSIGHT_CANDIDATE_TYPE_LOCAL:
g_value_set_uint(&value, 0);
break;
case FARSIGHT_CANDIDATE_TYPE_DERIVED:
g_value_set_uint(&value, 1);
break;
case FARSIGHT_CANDIDATE_TYPE_RELAY:
g_value_set_uint(&value, 2);
break;
default:
g_error("Unknown candidate type %u\n", info->proto);
}
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, info->username);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, info->password);
g_value_array_append(candidate, &value);
g_value_unset(&value);
g_assert(candidate->n_values == 11);
g_value_init(&value, G_TYPE_VALUE_ARRAY);
/* apparently GValueArray is a "boxed" type */
g_value_set_boxed(&value, candidate);
g_value_array_append(array, &value);
g_value_unset(&value);
}
return array;
}
static void
tox_session_state_changed(FarsightStream *stream, gint state, gint direction, ToxSession *self)
{
g_signal_emit(self, signals[STATE_CHANGED], 0, state, direction);
}
static void
tox_session_new_active_candidate_pair(FarsightStream *stream, gchar *native_candidate_id, gchar *remote_candidate_id, ToxSession *self)
{
g_signal_emit(self, signals[NEW_ACTIVE_CANDIDATE_PAIR], 0, native_candidate_id, remote_candidate_id);
}

View File

@ -1,24 +0,0 @@
#ifndef __TOX_SESSION_H__
#define __TOX_SESSION_H__
typedef struct ToxSession
{
GObject parent;
struct _ToxSessionPrivate *priv;
} ToxSession;
typedef struct ToxSessionClass
{
GObjectClass parent;
} ToxSessionClass;
GType tox_session_get_type(void);
#define TOX_TYPE_SESSION (tox_session_get_type())
#define TOX_SESSION(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TOX_TYPE_SESSION, ToxSession))
#define TOX_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TOX_TYPE_SESSION, ToxSessionClass))
#define TOX_IS_SESSION(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TOX_TYPE_SESSION))
#define TOX_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TOX_TYPE_SESSION))
#define TOX_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TOX_TYPE_SESSION, ToxSessionClass))
#endif /* __TOX_SESSION_H__ */

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name='net.sourceforge.emacs_jabber.ToxSession'>
<method name='Destroy'/>
<method name='SetDefaultAudioSink'/>
<method name='SetOggVorbisAudioSource'>
<arg name='filename' direction='in' type='s'/>
</method>
<method name='AddRemoteCandidate'>
<arg name='transport' direction='in' type='a(susqsssyyss)'/>
<!-- Each element is a candidate component. (Usually each
candidate has only one component)
Struct members are:
- Candidate ID
- Component (starting from 1)
- IP number (as a string)
- Port number
- Protocol ("tcp" or "udp")
- Protocol subtype (only "RTP" supported)
- Protocol profile (only "AVP" supported)
- Preference, between 0 and 100
- Type. 0 means local, 1 means derived (e.g. through
STUN), 2 means relay
- Username (may be empty)
- Password (may be empty)
-->
</method>
<signal name="NewNativeCandidate">
<arg name="candidates" type="a(susqsssyyss)"/>
<!-- Argument as to AddRemoteCandidate -->
</signal>
<signal name="NativeCandidatesPrepared">
<arg name="candidates" type="a(susqsssyyss)"/>
<!-- Argument as to AddRemoteCandidate -->
</signal>
<method name='SetRemoteCodecs'>
<arg name='codec-list' direction='in' type='a(isyuua{ss})'/>
<!-- Each element is a codec. Struct members are:
- numeric identifier
- codec name
- media type: 0 is audio, 1 is video
- clock rate
- number of channels
- optional parameters
-->
</method>
<method name='GetLocalCodecs'>
<arg name='codec-list' direction='out' type='a(isyuua{ss})'/>
<!-- Argument as to SetRemoteCodecs -->
</method>
<method name='GetCodecIntersection'>
<arg name='codec-list' direction='out' type='a(isyuua{ss})'/>
<!-- Argument layout: see SetRemoteCodecs -->
</method>
<signal name="StateChanged">
<!-- state is one of:
0: disconnected
1: connecting
2: connected
-->
<arg name='newstate' type='y'/>
<!-- direction is one of:
0: nothing
1: send only.
2: receive only.
3: send and receive.
-->
<arg name='direction' type='y'/>
</signal>
<signal name="NewActiveCandidatePair">
<arg name="nativeCandidateId" type="s"/>
<arg name="removeCandidateId" type="s"/>
</signal>
</interface>
</node>

110
tox/tox.c
View File

@ -1,110 +0,0 @@
#include <dbus/dbus-glib.h>
#include <glib/gprintf.h>
#include "tox.h"
#include "tox-session.h"
typedef struct _ToxObjectPrivate {
guint session_counter;
DBusGConnection *connection;
} ToxObjectPrivate;
G_DEFINE_TYPE(ToxObject, tox_object, G_TYPE_OBJECT)
gboolean tox_create_session(ToxObject *obj, guint8 dir, char **ret, GError **error);
/* properties */
enum {
TOX_DBUS_CONNECTION = 1,
};
static void tox_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec);
static void tox_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec);
#include "tox-object-glue.h"
void
tox_object_init(ToxObject *obj)
{
obj->priv = g_new0(ToxObjectPrivate, 1);
}
void
tox_object_class_init(ToxObjectClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
GParamSpec *connection_param_spec;
gobject_class->set_property = tox_set_property;
gobject_class->get_property = tox_get_property;
connection_param_spec = g_param_spec_boxed("dbus-connection",
"D-Bus connection",
"Connection where new sessions are registered",
DBUS_TYPE_G_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_property(gobject_class,
TOX_DBUS_CONNECTION,
connection_param_spec);
dbus_g_object_type_install_info(TOX_TYPE_OBJECT, &dbus_glib_tox_object_info);
}
static void
tox_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec)
{
ToxObject *self = (ToxObject *)obj;
switch(property_id) {
case TOX_DBUS_CONNECTION:
/* XXX: this should be a weak ref */
/* hm? */
/* if (self->priv->connection) */
/* dbus_g_connection_unref(self->priv->connection); */
self->priv->connection = (DBusGConnection *)g_value_get_boxed(value);
/* dbus_g_connection_ref(self->priv->connection); */
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
}
}
static void
tox_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec)
{
ToxObject *self = (ToxObject *)obj;
switch(property_id) {
case TOX_DBUS_CONNECTION:
g_value_set_boxed(value, self->priv->connection);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
}
}
gboolean
tox_create_session(ToxObject *obj, guint8 dir, char **ret, GError **error)
{
guint session_number = ++obj->priv->session_counter;
DBusGConnection *connection = obj->priv->connection;
ToxSession *session;
if (dir < 1 || dir > 3) {
/* XXX: how to set the D-Bus error name? */
g_set_error(error, DBUS_GERROR,
DBUS_GERROR_REMOTE_EXCEPTION,
"Direction out of range (was %u, should be 1 <= dir <= 3)",
dir);
return FALSE;
}
session = g_object_new(TOX_TYPE_SESSION, "direction", dir, NULL);
*ret = g_strdup_printf("/net/sourceforge/emacs_jabber/Tox/%u", session_number);
dbus_g_connection_register_g_object(connection, *ret, G_OBJECT(session));
g_debug("CreateSession called, returning %s\n", *ret);
return TRUE;
}

View File

@ -1,24 +0,0 @@
#ifndef __TOX_H__
#define __TOX_H__
typedef struct ToxObject
{
GObject parent;
struct _ToxObjectPrivate *priv;
} ToxObject;
typedef struct ToxObjectClass
{
GObjectClass parent;
} ToxObjectClass;
GType tox_object_get_type(void);
#define TOX_TYPE_OBJECT (tox_object_get_type())
#define TOX_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TOX_TYPE_OBJECT, ToxObject))
#define TOX_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TOX_TYPE_OBJECT, ToxObjectClass))
#define TOX_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TOX_TYPE_OBJECT))
#define TOX_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TOX_TYPE_OBJECT))
#define TOX_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TOX_TYPE_OBJECT, ToxObjectClass))
#endif /* __TOX_H__ */

View File

@ -1,3 +0,0 @@
[D-BUS Service]
Name=net.sourceforge.emacs-jabber.Tox
Exec=@libexecdir@/tox

View File

@ -1,305 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
lang="en" xml:lang="en">
<head>
<title>jabber.el</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta name="generator" content="Org-mode"/>
<meta name="generated" content="2009/02/19 1:31:21 AM"/>
<meta name="author" content=""/>
<style type="text/css">
html {
font-family: Times, serif;
font-size: 12pt;
}
.title { text-align: center; }
.todo { color: red; }
.done { color: green; }
.timestamp { color: grey }
.timestamp-kwd { color: CadetBlue }
.tag { background-color:lightblue; font-weight:normal }
.target { background-color: lavender; }
pre {
border: 1pt solid #AEBDCC;
background-color: #F3F5F7;
padding: 5pt;
font-family: courier, monospace;
}
table { border-collapse: collapse; }
td, th {
vertical-align: top;
<!--border: 1pt solid #ADB9CC;-->
}
</style>
</head><body>
<h1 class="title">jabber.el</h1>
<a href="http://sourceforge.net">
<img border="0" src="http://sourceforge.net/sflogo.php?group_id=88346&amp;type=2" width="125" height="37" alt="SourceForge.net Logo" style="position: absolute; top: 0em; right: 0em;"></a>
jabber.el is a Jabber client for Emacs.
<div id="table-of-contents">
<h2>Table of Contents</h2>
<ul>
<li><a href="#sec-1">What is Jabber?</a></li>
<li><a href="#sec-2">What is jabber.el?</a></li>
<li><a href="#sec-3">Downloading and installing</a>
<ul>
<li><a href="#sec-4">Prepackaged</a></li>
<li><a href="#sec-5">Dependencies</a></li>
<li><a href="#sec-6">Downloading</a></li>
<li><a href="#sec-7">Using</a></li>
</ul>
</li>
<li><a href="#sec-8">Reporting bugs</a></li>
<li><a href="#sec-9">Latest source</a>
<ul>
<li><a href="#sec-10">CVS</a></li>
<li><a href="#sec-11">GNU Arch</a></li>
<li><a href="#sec-12">git</a></li>
</ul>
</li>
<li><a href="#sec-13">List of releases</a></li>
</ul>
</div>
<p>
<a name="impatient">&nbsp;</a>
For the impatient:
</p>
<ul>
<li>
Latest release: <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&package_id=92339&release_id=482983">0.7.1</a> (31-Jan-2007)
</li>
<li>
Latest pretest release: <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&package_id=278300&release_id=662240">0.7.93</a> (19-Feb-2009)
</li>
<li>
Full <a href="#list-of-releases">list of releases</a>, including lists of features and changes
</li>
</ul>
<p>External resources:
</p>
<ul>
<li>
<a href="http://sourceforge.net/projects/emacs-jabber/">Sourceforge project page</a>, containing:
<ul>
<li>
trackers for
<a href="http://sourceforge.net/tracker/?atid=586350&group_id=88346&func=browse">bugs</a>,
<a href="http://sourceforge.net/tracker/?atid=586353&group_id=88346&func=browse">feature requests</a>,
<a href="http://sourceforge.net/tracker/?atid=586352&group_id=88346&func=browse">patches</a> and
<a href="http://sourceforge.net/tracker/?atid=586351&group_id=88346&func=browse">support requests</a>, open for anonymous posters
</li>
<li>
<a href="http://sourceforge.net/forum/?group_id=88346">forums</a>, open for anonymous posters
</li>
</ul></li>
<li>
<a href="http://www.emacswiki.org/cgi-bin/wiki/JabberEl">the JabberEl page of EmacsWiki</a>
</li>
<li>
Mailing lists (also available at <a href="http://gmane.net">Gmane</a>):
<ul>
<li>
<a href="http://lists.sourceforge.net/lists/listinfo/emacs-jabber-general">emacs-jabber-general</a>, for posts by humans (also <a href="http://dir.gmane.org/gmane.emacs.jabber.general">gmane.emacs.jabber.general</a>)
</li>
<li>
<a href="http://lists.sourceforge.net/lists/listinfo/emacs-jabber-commit">emacs-jabber-commit</a>, read-only mailing list of CVS commits (also <a href="http://dir.gmane.org/gmane.emacs.jabber.scm">gmane.emacs.jabber.scm</a>)
</li>
<li>
<a href="http://lists.sourceforge.net/lists/listinfo/emacs-jabber-bugs">emacs-jabber-bugs</a>, read-only mailing list of bug tracker activity (also <a href="http://dir.gmane.org/gmane.emacs.jabber.bugs">gmane.emacs.jabber.bugs</a>)
</li>
</ul></li>
<li>
the Jabber chat room
<a href="xmpp:jabber.el@conference.jabber.se?join">jabber.el@conference.jabber.se</a>
</li>
<li>
the <a href="manual-0.7.1/">manual for jabber.el 0.7.1</a> (also included in the release files)
</li>
</ul>
<div class="outline-2">
<h2 id="sec-1">What is Jabber?</h2>
<p>
Jabber is an open instant messaging (IM) system, also known as XMPP.
It is described in <a href="http://www.xmpp.org/rfcs/">RFCs 3920-3923</a> and a series of <a href="http://www.xmpp.org/extensions/">XEPs</a> (XMPP Extension
Proposals). That is, unlike legacy IM systems (such as ICQ or MSN
Messenger), the protocol is published in the open, free for anyone to
implement. Therefore you shouldn't be surprised that there is a
Jabber client for Emacs, too. (If you are not of the Emacs
persuasion, see this <a href="http://www.jabber.org/software/clients.shtml">list of Jabber clients</a>.)
</p>
<p>
Jabber is, like e-mail, a decentralised system. A Jabber identifier
(JID) is of the form <code>username@server</code>, just like an e-mail address, and
every Jabber user whose server is open to Internet connections can
communicate with any other user. This is in stark contrast to the
legacy "walled-garden" IM systems, where you need a separate account
for each system to be able to communicate with its users. Note that
the <a href="http://talk.google.com">Google Talk</a> service is an XMPP service, so if you have a GMail
account, you already have a JID ending with <code>@gmail.com</code>.
</p>
<p>
In Jabber, you have a "roster", a list of contacts. You can see
which of them are online at the moment, and chat with them. (You can
also send messages to an offline contact, and the message will be
stored on the server for later delivery.) Jabber also supports
IRC-style chat rooms.
</p>
</div>
<div class="outline-2">
<h2 id="sec-2">What is jabber.el?</h2>
<p>
jabber.el is a Jabber client for Emacs. It may seem strange to have a
chat client in an editor, but consider that chatting is, after all,
just a special case of text editing.
</p>
</div>
<div class="outline-2">
<h2 id="sec-3">Downloading and installing</h2>
<div class="outline-3">
<h3 id="sec-4">Prepackaged</h3>
<p>
Note that jabber.el is available as <a href="http://packages.debian.org/emacs-jabber">emacs-jabber in Debian</a>, and in
<a href="http://packages.ubuntu.com/emacs-jabber">Ubuntu's "universe" section</a>.
</p>
</div>
<div class="outline-3">
<h3 id="sec-5">Dependencies</h3>
<p>
jabber.el requires either GNU Emacs 22, or GNU Emacs 21 combined with
Gnus 5.10. You should get these from your distribution, or from the
<a href="http://www.gnu.org/software/emacs/">Emacs</a> and <a href="http://gnus.org">Gnus</a> web sites.
</p>
<p>
However, if you want to connect to servers that use SRV records
(e.g. Google Talk), it is recommended to use either No Gnus or Gnus
5.13.
</p>
<p>
If you want encrypted connections (some servers, e.g. Google Talk,
require it), you need <a href="http://www.gnu.org/software/gnutls/">GnuTLS</a> installed.
</p>
</div>
<div class="outline-3">
<h3 id="sec-6">Downloading</h3>
<p>
Download the <a href="#impatient">latest release</a> and unpack it in a suitable location. Add
something like the following to your <code>.emacs</code> file:
</p>
<p>
<pre>
;; adjust this path:
(add-to-list 'load-path "/path/to/emacs-jabber")
;; For 0.7.1 and below:
(require 'jabber)
;; For 0.7.90 and above:
(require 'jabber-autoloads)
</pre>
</p>
<p>
Either evaluate those lines, or restart Emacs.
</p>
</div>
<div class="outline-3">
<h3 id="sec-7">Using</h3>
<p>
See the <a href="manual-0.7.1/Basic-operation.html">Basic Operation</a> in the manual.
</p>
</div>
</div>
<div class="outline-2">
<h2 id="sec-8">Reporting bugs</h2>
<p>
Bug reports can be sent either to the mailing list
<a href="http://lists.sourceforge.net/lists/listinfo/emacs-jabber-general">emacs-jabber-general</a> or to the <a href="http://sourceforge.net/tracker/?group_id=88346&atid=586350">bug tracker</a>.
</p>
</div>
<div class="outline-2">
<h2 id="sec-9">Latest source</h2>
<p>
jabber.el releases are, unfortunately, less frequent than they would
be in an ideal world. You can get the latest development version
using various version control systems.
</p>
<div class="outline-3">
<h3 id="sec-10">CVS</h3>
<p>
See <a href="http://sourceforge.net/cvs/?group_id=88346">the Sourceforge CVS page</a>. In short, run the following command:
</p>
<p>
<pre>
cvs -z3 -d:pserver:anonymous@emacs-jabber.cvs.sourceforge.net:/cvsroot/emacs-jabber co -P emacs-jabber
</pre>
</p>
</div>
<div class="outline-3">
<h3 id="sec-11">GNU Arch</h3>
<p>
The GNU Arch mirror is no longer being updated.
</p>
</div>
<div class="outline-3">
<h3 id="sec-12">git</h3>
<p>
<pre>
git-clone git://git.catap.ru/emacs-jabber.git
</pre>
</p>
</div>
</div>
<div class="outline-2">
<h2 id="sec-13">List of releases</h2>
<p>
The list of releases has been moved to a <a href="list-of-releases.html">separate page</a>.
</p>
</div>
<div id="postamble"><p class="date"> Date: 2009/02/19 1:31:21 AM</p>
</div></body>
</html>

View File

@ -1,149 +0,0 @@
#+TITLE: jabber.el
#+OPTIONS: num:nil author:nil skip:nil
#+BEGIN_HTML
<a href="http://sourceforge.net">
<img border="0" src="http://sourceforge.net/sflogo.php?group_id=88346&amp;type=2" width="125" height="37" alt="SourceForge.net Logo" style="position: absolute; top: 0em; right: 0em;"></a>
#+END_HTML
jabber.el is a Jabber client for Emacs.
[TABLE-OF-CONTENTS]
# <<impatient>>
For the impatient:
- Latest release: [[http://sourceforge.net/project/showfiles.php?group_id=88346&package_id=92339&release_id=482983][0.7.1]] (31-Jan-2007)
- Latest pretest release: [[http://sourceforge.net/project/showfiles.php?group_id=88346&package_id=278300&release_id=662240][0.7.93]] (19-Feb-2009)
- Full [[list-of-releases][list of releases]], including lists of features and changes
External resources:
- [[http://sourceforge.net/projects/emacs-jabber/][Sourceforge project page]], containing:
- trackers for
[[http://sourceforge.net/tracker/?atid=586350&group_id=88346&func=browse][bugs]],
[[http://sourceforge.net/tracker/?atid=586353&group_id=88346&func=browse][feature requests]],
[[http://sourceforge.net/tracker/?atid=586352&group_id=88346&func=browse][patches]] and
[[http://sourceforge.net/tracker/?atid=586351&group_id=88346&func=browse][support requests]], open for anonymous posters
- [[http://sourceforge.net/forum/?group_id=88346][forums]], open for anonymous posters
- [[http://www.emacswiki.org/cgi-bin/wiki/JabberEl][the JabberEl page of EmacsWiki]]
- Mailing lists (also available at [[http://gmane.net][Gmane]]):
- [[http://lists.sourceforge.net/lists/listinfo/emacs-jabber-general][emacs-jabber-general]], for posts by humans (also [[http://dir.gmane.org/gmane.emacs.jabber.general][gmane.emacs.jabber.general]])
- [[http://lists.sourceforge.net/lists/listinfo/emacs-jabber-commit][emacs-jabber-commit]], read-only mailing list of CVS commits (also [[http://dir.gmane.org/gmane.emacs.jabber.scm][gmane.emacs.jabber.scm]])
- [[http://lists.sourceforge.net/lists/listinfo/emacs-jabber-bugs][emacs-jabber-bugs]], read-only mailing list of bug tracker activity (also [[http://dir.gmane.org/gmane.emacs.jabber.bugs][gmane.emacs.jabber.bugs]])
- the Jabber chat room
#+HTML: <a href="xmpp:jabber.el@conference.jabber.se?join">jabber.el@conference.jabber.se</a>
- the [[file:manual-0.7.1/][manual for jabber.el 0.7.1]] (also included in the release files)
* What is Jabber?
Jabber is an open instant messaging (IM) system, also known as XMPP.
It is described in [[http://www.xmpp.org/rfcs/][RFCs 3920-3923]] and a series of [[http://www.xmpp.org/extensions/][XEPs]] (XMPP Extension
Proposals). That is, unlike legacy IM systems (such as ICQ or MSN
Messenger), the protocol is published in the open, free for anyone to
implement. Therefore you shouldn't be surprised that there is a
Jabber client for Emacs, too. (If you are not of the Emacs
persuasion, see this [[http://www.jabber.org/software/clients.shtml][list of Jabber clients]].)
Jabber is, like e-mail, a decentralised system. A Jabber identifier
(JID) is of the form =username@server=, just like an e-mail address, and
every Jabber user whose server is open to Internet connections can
communicate with any other user. This is in stark contrast to the
legacy "walled-garden" IM systems, where you need a separate account
for each system to be able to communicate with its users. Note that
the [[http://talk.google.com][Google Talk]] service is an XMPP service, so if you have a GMail
account, you already have a JID ending with =@gmail.com=.
In Jabber, you have a "roster", a list of contacts. You can see
which of them are online at the moment, and chat with them. (You can
also send messages to an offline contact, and the message will be
stored on the server for later delivery.) Jabber also supports
IRC-style chat rooms.
* What is jabber.el?
jabber.el is a Jabber client for Emacs. It may seem strange to have a
chat client in an editor, but consider that chatting is, after all,
just a special case of text editing.
* Downloading and installing
** Prepackaged
Note that jabber.el is available as [[http://packages.debian.org/emacs-jabber][emacs-jabber in Debian]], and in
[[http://packages.ubuntu.com/emacs-jabber][Ubuntu's "universe" section]].
** Dependencies
jabber.el requires either GNU Emacs 22, or GNU Emacs 21 combined with
Gnus 5.10. You should get these from your distribution, or from the
[[http://www.gnu.org/software/emacs/][Emacs]] and [[http://gnus.org][Gnus]] web sites.
However, if you want to connect to servers that use SRV records
(e.g. Google Talk), it is recommended to use either No Gnus or Gnus
5.13.
If you want encrypted connections (some servers, e.g. Google Talk,
require it), you need [[http://www.gnu.org/software/gnutls/][GnuTLS]] installed.
** Downloading
Download the [[impatient][latest release]] and unpack it in a suitable location. Add
something like the following to your =.emacs= file:
#+BEGIN_EXAMPLE
;; adjust this path:
(add-to-list 'load-path "/path/to/emacs-jabber")
;; For 0.7.1 and below:
(require 'jabber)
;; For 0.7.90 and above:
(require 'jabber-autoloads)
#+END_EXAMPLE
Either evaluate those lines, or restart Emacs.
** Using
See the [[file:manual-0.7.1/Basic-operation.html][Basic Operation]] in the manual.
* Reporting bugs
Bug reports can be sent either to the mailing list
[[http://lists.sourceforge.net/lists/listinfo/emacs-jabber-general][emacs-jabber-general]] or to the [[http://sourceforge.net/tracker/?group_id=88346&atid=586350][bug tracker]].
* Latest source
jabber.el releases are, unfortunately, less frequent than they would
be in an ideal world. You can get the latest development version
using various version control systems.
** CVS
See [[http://sourceforge.net/cvs/?group_id=88346][the Sourceforge CVS page]]. In short, run the following command:
#+BEGIN_EXAMPLE
cvs -z3 -d:pserver:anonymous@emacs-jabber.cvs.sourceforge.net:/cvsroot/emacs-jabber co -P emacs-jabber
#+END_EXAMPLE
** GNU Arch
The GNU Arch mirror is no longer being updated.
** git
#+BEGIN_EXAMPLE
git-clone git://git.catap.ru/emacs-jabber.git
#+END_EXAMPLE
* List of releases
The list of releases has been moved to a [[file:list-of-releases.org][separate page]].
# Local variables:
# mode: org
# eval: (progn (add-to-list 'org-link-types "xmpp") (org-make-link-regexps))
# End:

View File

@ -1,200 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
lang="en" xml:lang="en">
<head>
<title>List of releases - jabber.el</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta name="generator" content="Org-mode"/>
<meta name="generated" content="2009/01/31 3:00:13 AM"/>
<meta name="author" content=""/>
<style type="text/css">
html {
font-family: Times, serif;
font-size: 12pt;
}
.title { text-align: center; }
.todo { color: red; }
.done { color: green; }
.timestamp { color: grey }
.timestamp-kwd { color: CadetBlue }
.tag { background-color:lightblue; font-weight:normal }
.target { background-color: lavender; }
pre {
border: 1pt solid #AEBDCC;
background-color: #F3F5F7;
padding: 5pt;
font-family: courier, monospace;
}
table { border-collapse: collapse; }
td, th {
vertical-align: top;
<!--border: 1pt solid #ADB9CC;-->
}
</style>
</head><body>
<h1 class="title">List of releases - jabber.el</h1>
<a href="index.html">Back to main page</a>
<h3>version 0.7.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=482983">31-Jan-2007</a></h3>
<ul>
<li>STARTTLS</li>
<li>SRV records (requires No Gnus)</li>
<li>Message composition buffer</li>
<li>XMPP URIs are handled (see <a href="manual-0.7.1/XMPP-URIs.html">manual</a> for setup)</li>
<li>Autoaway</li>
<li>MUC improvements
<ul>
<li>Don't display alerts for your own messages</li>
<li>Presence changes are sent to MUC rooms too</li>
<li>Check room features before joining</li>
</ul>
<li>Avatars</li>
<li>File transfer</li>
<li>Sound files per contact for alerts</li>
<li>New function: jabber-send-directed-presence</li>
<li>Entity time supported (XEP-0090)</li>
<li>Last activity supported (XEP-0012)</li>
</ul>
<p>Read the <a href="manual-0.7.1/">manual</a>.</p>
<h3>version 0.7 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=381160">27-Dec-2005</a></h3>
<ul>
<li>SSL connections possible</li>
<li>Chat buffers rewritten</li>
<li>MUC improved</li>
<li>Global key bindings under C-x C-j</li>
<li>Vcard viewer and editor</li>
<li>Roster export</li>
<li>Message events (JEP-0022)</li>
<li>Easy way to define external notifiers</li>
<li>Activity mode improved</li>
<li>Roster display optimized</li>
<li>Optionally use per-contact history files</li>
<li>Jabber menu in menubar not enabled by default</li>
<li>Flyspell in chat buffers</li>
<li>Different time formats for instant and delayed messages</li>
<li>Chat buffers in inactive windows are scrolled</li>
<li>Roster is sorted by name also</li>
<li>Countless bugfixes</li>
</ul>
<p>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.7/">manual</a>.</p>
<h3>version 0.6.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=292750">27-Dec-2004</a></h3>
<ul>
<li>Now works with ejabberd</li>
<li>Message history (Mathias Dahl)</li>
<li>Backlogs</li>
<li>Activity tracking on the mode line (Carl Henrik Lunde)</li>
<li>Receive an alert when a specific person goes online (Mathias Dahl)</li>
<li>Support for /me in chats (Nolan Eakins)</li>
<li>Message alerts for current buffer can be disabled</li>
<li>Basic moderation support in MUC</li>
<li>MUC alerts are separated from ordinary message alerts</li>
</ul>
<p>Read the
<a href="http://emacs-jabber.sourceforge.net/manual-0.6.1/">manual</a>,
in which there is now a section on
<a href="http://emacs-jabber.sourceforge.net/manual-0.6.1/Protocol-support.html">protocol support</a>.</p>
<h3>version 0.6 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=275815">17-Oct-2004</a></h3>
<ul>
<li>Chat buffers no longer use the minibuffer, making it easier to use
ordinary editor commands and to pause writing halfway</li>
<li>The roster display and the chat buffer prompts are now customizable</li>
<li>The online status of the contact is displayed in the chat buffer
(Emacs only)</li>
<li>The connect function automatically sends presence after connecting</li>
<li>The names of the roster buffer and chat buffers are customizable</li>
<li>RET and C-k do what you would expect in the roster buffer</li>
</ul>
<p>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.6/">manual</a>.</p>
<h3>version 0.5.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=236857">08-May-2004</a></h3>
<ul>
<li>Nicknames are accepted whenever a JID is asked for.</li>
<li>Roster entry spacing is customizable (default is none)</li>
<li>Bug fix regarding mixed-case JIDs</li>
<li>Experimental code for receiving files - see the README</li>
<li>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.5.1/">manual</a></li>
</ul>
<h3>version 0.5 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=228471">03-April-2004</a></h3>
<ul>
<li>Modular design; plugins easier to write</li>
<li>Support for Ad-Hoc Commands and setting presence remotely</li>
<li><a href="manual-0.5/">Browse documentation here</a></li>
</ul>
<h3>version 0.4.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=217577">16-February-2004</a></h3>
<ul>
<li> XEmacs support - basically works, needs testing and care.</li>
<li> "Set status" menu fixed</li>
</ul>
<h3>version 0.4 - 05-February-2004</h3>
<ul>
<li> SHA-1 password hashing</li>
<li> customisation hooks</li>
<li> browsing improved</li>
<li> added service discovery</li>
<li> added in-band registration</li>
<li> added searching</li>
<li> <a href="/emacs-jabber/jabber.html">new manual</a></li>
</ul>
<h3>version 0.3 - 21-April-2002</h3>
<ul>
<li> improved groupchat support (thanks to nimrod for tip)</li>
<li> improved roster (buddy-list) display</li>
<li> infoquery rewritten - great improvement</li>
<li> improved minimal browsing support !</li>
<li> added customizable faces</li>
<li> added more customizable variables</li>
<li> more (helpful) comments in code</li>
<li> added explicit licensing (GPL, like emacs itself)</li>
</ul><br>
<h3>version 0.2 - 05-April-2002</h3>
<ul>
<li> added groupchat support !</li>
<li> added minimal browsing support !</li>
<li> fixed bug in chat mode</li>
<li> abolished message mode (i only use chat mode anyway)</li>
<li> fixed some problems with incoming xml</li>
<li> added a pull-down menu</li>
<li> added customizable variables</li>
</ul><br>
<br>
<h3>features currently missing (TODO)</h3>
<ul>
<li> global keymaps</li>
<li> logging (history)</li>
<li> overall exception handling</li>
<li> sanity checks (for incoming xml, and for myself :)</li>
<li> clickable URLs in messages</li>
<li> support for versions other than gnu-emacs-21 (older emacs, xemacs, jemacs)</li>
<li> and more...</li>
</ul><br>
<div id="postamble"><p class="date"> Date: 2009/01/31 3:00:13 AM</p>
</div></body>
</html>

View File

@ -1,167 +0,0 @@
#+TITLE: List of releases - jabber.el
#+OPTIONS: author:nil skip:nil
[[file:index.org][Back to main page]]
#+BEGIN_HTML
<h3>version 0.7.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=482983">31-Jan-2007</a></h3>
<ul>
<li>STARTTLS</li>
<li>SRV records (requires No Gnus)</li>
<li>Message composition buffer</li>
<li>XMPP URIs are handled (see <a href="manual-0.7.1/XMPP-URIs.html">manual</a> for setup)</li>
<li>Autoaway</li>
<li>MUC improvements
<ul>
<li>Don't display alerts for your own messages</li>
<li>Presence changes are sent to MUC rooms too</li>
<li>Check room features before joining</li>
</ul>
<li>Avatars</li>
<li>File transfer</li>
<li>Sound files per contact for alerts</li>
<li>New function: jabber-send-directed-presence</li>
<li>Entity time supported (XEP-0090)</li>
<li>Last activity supported (XEP-0012)</li>
</ul>
<p>Read the <a href="manual-0.7.1/">manual</a>.</p>
<h3>version 0.7 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=381160">27-Dec-2005</a></h3>
<ul>
<li>SSL connections possible</li>
<li>Chat buffers rewritten</li>
<li>MUC improved</li>
<li>Global key bindings under C-x C-j</li>
<li>Vcard viewer and editor</li>
<li>Roster export</li>
<li>Message events (JEP-0022)</li>
<li>Easy way to define external notifiers</li>
<li>Activity mode improved</li>
<li>Roster display optimized</li>
<li>Optionally use per-contact history files</li>
<li>Jabber menu in menubar not enabled by default</li>
<li>Flyspell in chat buffers</li>
<li>Different time formats for instant and delayed messages</li>
<li>Chat buffers in inactive windows are scrolled</li>
<li>Roster is sorted by name also</li>
<li>Countless bugfixes</li>
</ul>
<p>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.7/">manual</a>.</p>
<h3>version 0.6.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=292750">27-Dec-2004</a></h3>
<ul>
<li>Now works with ejabberd</li>
<li>Message history (Mathias Dahl)</li>
<li>Backlogs</li>
<li>Activity tracking on the mode line (Carl Henrik Lunde)</li>
<li>Receive an alert when a specific person goes online (Mathias Dahl)</li>
<li>Support for /me in chats (Nolan Eakins)</li>
<li>Message alerts for current buffer can be disabled</li>
<li>Basic moderation support in MUC</li>
<li>MUC alerts are separated from ordinary message alerts</li>
</ul>
<p>Read the
<a href="http://emacs-jabber.sourceforge.net/manual-0.6.1/">manual</a>,
in which there is now a section on
<a href="http://emacs-jabber.sourceforge.net/manual-0.6.1/Protocol-support.html">protocol support</a>.</p>
<h3>version 0.6 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=275815">17-Oct-2004</a></h3>
<ul>
<li>Chat buffers no longer use the minibuffer, making it easier to use
ordinary editor commands and to pause writing halfway</li>
<li>The roster display and the chat buffer prompts are now customizable</li>
<li>The online status of the contact is displayed in the chat buffer
(Emacs only)</li>
<li>The connect function automatically sends presence after connecting</li>
<li>The names of the roster buffer and chat buffers are customizable</li>
<li>RET and C-k do what you would expect in the roster buffer</li>
</ul>
<p>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.6/">manual</a>.</p>
<h3>version 0.5.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=236857">08-May-2004</a></h3>
<ul>
<li>Nicknames are accepted whenever a JID is asked for.</li>
<li>Roster entry spacing is customizable (default is none)</li>
<li>Bug fix regarding mixed-case JIDs</li>
<li>Experimental code for receiving files - see the README</li>
<li>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.5.1/">manual</a></li>
</ul>
<h3>version 0.5 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=228471">03-April-2004</a></h3>
<ul>
<li>Modular design; plugins easier to write</li>
<li>Support for Ad-Hoc Commands and setting presence remotely</li>
<li><a href="manual-0.5/">Browse documentation here</a></li>
</ul>
<h3>version 0.4.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=217577">16-February-2004</a></h3>
<ul>
<li> XEmacs support - basically works, needs testing and care.</li>
<li> "Set status" menu fixed</li>
</ul>
<h3>version 0.4 - 05-February-2004</h3>
<ul>
<li> SHA-1 password hashing</li>
<li> customisation hooks</li>
<li> browsing improved</li>
<li> added service discovery</li>
<li> added in-band registration</li>
<li> added searching</li>
<li> <a href="/emacs-jabber/jabber.html">new manual</a></li>
</ul>
<h3>version 0.3 - 21-April-2002</h3>
<ul>
<li> improved groupchat support (thanks to nimrod for tip)</li>
<li> improved roster (buddy-list) display</li>
<li> infoquery rewritten - great improvement</li>
<li> improved minimal browsing support !</li>
<li> added customizable faces</li>
<li> added more customizable variables</li>
<li> more (helpful) comments in code</li>
<li> added explicit licensing (GPL, like emacs itself)</li>
</ul><br>
<h3>version 0.2 - 05-April-2002</h3>
<ul>
<li> added groupchat support !</li>
<li> added minimal browsing support !</li>
<li> fixed bug in chat mode</li>
<li> abolished message mode (i only use chat mode anyway)</li>
<li> fixed some problems with incoming xml</li>
<li> added a pull-down menu</li>
<li> added customizable variables</li>
</ul><br>
<br>
<h3>features currently missing (TODO)</h3>
<ul>
<li> global keymaps</li>
<li> logging (history)</li>
<li> overall exception handling</li>
<li> sanity checks (for incoming xml, and for myself :)</li>
<li> clickable URLs in messages</li>
<li> support for versions other than gnu-emacs-21 (older emacs, xemacs, jemacs)</li>
<li> and more...</li>
</ul><br>
#+END_HTML
# Local variables:
# mode: org
# End:

View File

@ -1,217 +0,0 @@
<html>
<head>
<title>jabber.el</title>
</head>
<body>
<h1>jabber.el</h1><br>
<h2>a minimal jabber client for emacs</h2><br>
<!-- here are some <a href="http://intellectronica.net/emacs-jabber/screenshots/">screenshots</a>.<br>
<b>newsflash : jabber.el is no longer here. go to <a href="http://www.sf.net/projects/emacs-jabber">sourceforge</a> for the latest version</b>
<br>-->
<a href="http://sourceforge.net">
<img border="0" src="http://sourceforge.net/sflogo.php?group_id=88346&amp;type=2" width="125" height="37" alt="SourceForge.net Logo" style="position: absolute; top: 0em; right: 0em;"></a>
<p>see also <a href="http://www.emacswiki.org/cgi-bin/wiki/JabberEl">the
JabberEl page of EmacsWiki</a>, <a href="http://lists.sourceforge.net/lists/listinfo/emacs-jabber-general">
the mailing list</a> and <a href="xmpp:jabber.el@conference.jabber.se?join">the chat room</a> (it's <code>jabber.el@conference.jabber.se</code>, if your web browser is not configured for XMPP URIs).</p>
<p>if you use <a href="http://wiki.gnuarch.org">GNU Arch</a>, you can use the
Arch mirror of the CVS repository. these commands get it for you:</p>
<pre>tla register-archive http://www.dtek.chalmers.se/~henoch/archive-2005
tla get mange@freemail.hu--2005/emacs-jabber--cvs-head--0 emacs-jabber</pre>
<p>it's manually maintained, so bug Magnus (JID: <a href="xmpp:legoscia@jabber.cd.chalmers.se">legoscia@jabber.cd.chalmers.se</a>) if it
doesn't seem up to date.</p>
<h3>version 0.7.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=482983">31-Jan-2007</a></h3>
<ul>
<li>STARTTLS</li>
<li>SRV records (requires No Gnus)</li>
<li>Message composition buffer</li>
<li>XMPP URIs are handled (see <a href="manual-0.7.1/XMPP-URIs.html">manual</a> for setup)</li>
<li>Autoaway</li>
<li>MUC improvements
<ul>
<li>Don't display alerts for your own messages</li>
<li>Presence changes are sent to MUC rooms too</li>
<li>Check room features before joining</li>
</ul>
<li>Avatars</li>
<li>File transfer</li>
<li>Sound files per contact for alerts</li>
<li>New function: jabber-send-directed-presence</li>
<li>Entity time supported (XEP-0090)</li>
<li>Last activity supported (XEP-0012)</li>
</ul>
<p>Read the <a href="manual-0.7.1/">manual</a>.</p>
<h3>version 0.7 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=381160">27-Dec-2005</a></h3>
<ul>
<li>SSL connections possible</li>
<li>Chat buffers rewritten</li>
<li>MUC improved</li>
<li>Global key bindings under C-x C-j</li>
<li>Vcard viewer and editor</li>
<li>Roster export</li>
<li>Message events (JEP-0022)</li>
<li>Easy way to define external notifiers</li>
<li>Activity mode improved</li>
<li>Roster display optimized</li>
<li>Optionally use per-contact history files</li>
<li>Jabber menu in menubar not enabled by default</li>
<li>Flyspell in chat buffers</li>
<li>Different time formats for instant and delayed messages</li>
<li>Chat buffers in inactive windows are scrolled</li>
<li>Roster is sorted by name also</li>
<li>Countless bugfixes</li>
</ul>
<p>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.7/">manual</a>.</p>
<h3>version 0.6.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=292750">27-Dec-2004</a></h3>
<ul>
<li>Now works with ejabberd</li>
<li>Message history (Mathias Dahl)</li>
<li>Backlogs</li>
<li>Activity tracking on the mode line (Carl Henrik Lunde)</li>
<li>Receive an alert when a specific person goes online (Mathias Dahl)</li>
<li>Support for /me in chats (Nolan Eakins)</li>
<li>Message alerts for current buffer can be disabled</li>
<li>Basic moderation support in MUC</li>
<li>MUC alerts are separated from ordinary message alerts</li>
</ul>
<p>Read the
<a href="http://emacs-jabber.sourceforge.net/manual-0.6.1/">manual</a>,
in which there is now a section on
<a href="http://emacs-jabber.sourceforge.net/manual-0.6.1/Protocol-support.html">protocol support</a>.</p>
<h3>version 0.6 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=275815">17-Oct-2004</a></h3>
<ul>
<li>Chat buffers no longer use the minibuffer, making it easier to use
ordinary editor commands and to pause writing halfway</li>
<li>The roster display and the chat buffer prompts are now customizable</li>
<li>The online status of the contact is displayed in the chat buffer
(Emacs only)</li>
<li>The connect function automatically sends presence after connecting</li>
<li>The names of the roster buffer and chat buffers are customizable</li>
<li>RET and C-k do what you would expect in the roster buffer</li>
</ul>
<p>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.6/">manual</a>.</p>
<h3>version 0.5.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=236857">08-May-2004</a></h3>
<ul>
<li>Nicknames are accepted whenever a JID is asked for.</li>
<li>Roster entry spacing is customizable (default is none)</li>
<li>Bug fix regarding mixed-case JIDs</li>
<li>Experimental code for receiving files - see the README</li>
<li>Read the <a href="http://emacs-jabber.sourceforge.net/manual-0.5.1/">manual</a></li>
</ul>
<h3>version 0.5 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=228471">03-April-2004</a></h3>
<ul>
<li>Modular design; plugins easier to write</li>
<li>Support for Ad-Hoc Commands and setting presence remotely</li>
<li><a href="manual-0.5/">Browse documentation here</a></li>
</ul>
<h3>version 0.4.1 - <a href="http://sourceforge.net/project/showfiles.php?group_id=88346&amp;package_id=92339&amp;release_id=217577">16-February-2004</a></h3>
<ul>
<li> XEmacs support - basically works, needs testing and care.</li>
<li> "Set status" menu fixed</li>
</ul>
<h3>version 0.4 - 05-February-2004</h3>
<ul>
<li> SHA-1 password hashing</li>
<li> customisation hooks</li>
<li> browsing improved</li>
<li> added service discovery</li>
<li> added in-band registration</li>
<li> added searching</li>
<li> <a href="/emacs-jabber/jabber.html">new manual</a></li>
</ul>
<h3>version 0.3 - 21-April-2002</h3>
<ul>
<li> improved groupchat support (thanks to nimrod for tip)</li>
<li> improved roster (buddy-list) display</li>
<li> infoquery rewritten - great improvement</li>
<li> improved minimal browsing support !</li>
<li> added customizable faces</li>
<li> added more customizable variables</li>
<li> more (helpful) comments in code</li>
<li> added explicit licensing (GPL, like emacs itself)</li>
</ul><br>
<h3>version 0.2 - 05-April-2002</h3>
<ul>
<li> added groupchat support !</li>
<li> added minimal browsing support !</li>
<li> fixed bug in chat mode</li>
<li> abolished message mode (i only use chat mode anyway)</li>
<li> fixed some problems with incoming xml</li>
<li> added a pull-down menu</li>
<li> added customizable variables</li>
</ul><br>
<br>
<h3>features currently missing (TODO)</h3>
<ul>
<li> global keymaps</li>
<li> logging (history)</li>
<li> overall exception handling</li>
<li> sanity checks (for incoming xml, and for myself :)</li>
<li> clickable URLs in messages</li>
<li> support for versions other than gnu-emacs-21 (older emacs, xemacs, jemacs)</li>
<li> and more...</li>
</ul><br>
<br>
<h3>installation</h3>
<p>get the module <kbd>emacs-jabber</kbd> from <a href="http://sourceforge.net/cvs/?group_id=88346">Sourceforge CVS</a>.
additionally, if you don't have Gnus 5.10 (<kbd>M-x gnus-version</kbd> will tell), you will need <kbd>hex-util.el</kbd>
and <kbd>sha1-el.el</kbd> from <a href="http://quimby.gnus.org/cgi-bin/cvsweb.cgi/gnus/lisp/">Gnus CVS</a>.
copy these to a directory in your emacs load path.</p>
<p>in your .emacs file add the call <kbd>(require 'jabber)</kbd>. you can also use auto-load.</p>
<p>set your account details with <kbd>M-x jabber-customize</kbd>. then, type <kbd>M-x jabber-connect</kbd> to connect,
and <kbd>M-x jabber-send-presence</kbd> to send initial presence.</p>
<p>please note that the current version is dependant on gnu-emacs-21 - it depends on xml.el (which you can download separately) and on some newer functions.</p>
<h3>howto</h3>
<p>as jabber.el is still very young, you'll have to be rather emacs-savvy to use it (or at least have the willingness to learn a little).<br></p>
<p>to connect to the server, call <i>(<b>jabber-connect</b>)</i>.<br>
call it from the pull-down menu or call interactively : [M-x jabber-connect RET] and enter the parameters from the minibuffer.</p>
<p>after a successful connection, a new buffer should appear, named <b>*-jabber-*</b>. this buffer is your roster view. click any user with the mouse to start a 1-on-1 chat.</p>
<p>alternatively, you can also call <i>(<b>jabber-chat-with</b> jid)</i>.<br>
for example : (jabber-chat-with "object@magaf.org")<br>
or [M-x jabber-chat-with RET]. in that case you will be asked for a jid. use the TAB key to complete a partial jid from the roster. (nice, eh?)</p>
<p>to send a message, call <i>(<b>jabber-send-message</b> to body subject type)</i><br>
for example : (jabber-send-message "object@magaf.org" "hi there" "" "") will appear as an instant message.<br>
(jabber-send-message "object@magaf.org" "tom, you are the best" "the truth, nothing but the truth" "normal") too.<br>
(jabber-send-message "object@magaf.org" "hya" "" "chat") will appear as a 1-on-1 chat<br>
of course, this too can be called interactively : [M-x jabber-send-message RET] (with jid completion, like anywhere else).</p>
<p>to change your status, call <i>(<b>jabber-send-presence</b> show status)</i>.<br>
for example : (jabber-send-presence "" "Online") to appear online, or (jabber-send-presence "dnd" "copulating") to appear lucky.<br>
needless to say, this can be called from the minibuffer too. do [M-x jabber-send-presence RET] and enjoy TAB completion from "", "away", "xa", "dnd" or "chat" for the first parameter (show).</p>
<p>when a new chat message arrives, it is sent to the chat buffer ("*jabber-chat-:-user*"). if such a buffer does not exist it is created. in this buffer, all straight keystrokes are being captured for starting the reply command. to send a line, simply start typing...</p>
<p>all messages are converted to 1-on-1 chats (simply because i find that more convinient).</p>
<h3>contact</h3>
<p>jabber.el is written by <a href="http://intellectronica.net/object/">Tom Berger</a> (Jabber: object@jabber.org.uk) and
Magnus Henoch (Jabber: legoscia@jabber.cd.chalmers.se). feel free to contact us. you can also report bugs at the
<a href="http://sourceforge.net/projects/emacs-jabber/">Sourceforge project page</a>.</p>
</body>
</html>

View File

@ -1,14 +0,0 @@
#!/bin/sh
# In ~/.ssh/config, include the following
#
# Host emacs-jabber-www
# HostName web.sourceforge.net
# User SFUSERNAME,emacs-jabber
if [ ! -f index.org ]; then
echo "Error: must be run in www checkout root" 1>&2
exit 1
fi
rsync -v *.html emacs-jabber-www:htdocs/