;;; client.el --- ;; ;; Copyright (C) 2010, 2011 Jan Moringen ;; ;; Author: Jan Moringen ;; Keywords: telepathy, communication, instant messaging ;; ;; 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 3 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, see . ;;; Commentary: ;; ;;; History: ;; ;; 0.1 - Initial version ;;; Code: ;; (require 'dbus) (require 'telepathy/util) ;;; ;; (defconst telepathy-client-introspection-data " " "") ;;; ;; (defvar telepathy-client-handlers (make-hash-table :test 'equal) "") (defun telepathy-client-handler-services () "" (let ((result)) (maphash (lambda (key value) (push key result)) telepathy-client-handlers) result)) (defun telepathy-client-add-handler (service handler &optional client) "" (unless client (setq client "Emacs")) (unless (zerop (hash-table-count telepathy-client-handlers)) (telepathy-client-unregister client)) (puthash service handler telepathy-client-handlers) (telepathy-client-register client)) (defun telepathy-client-remove-handler (service &optional client) "" (unless client (setq client "Emacs")) (unless (zerop (hash-table-count telepathy-client-handlers)) (telepathy-client-unregister client)) (remhash service telepathy-client-handlers) (unless (zerop (hash-table-count telepathy-client-handlers)) (telepathy-client-register client))) ;;; ;; (defun telepath-client-channel-handler (account connection-path channels &rest args) "" (dolist (channel-data channels) (let* ((connection (telepathy-make-remote-proxy-from-path :session connection-path)) ;; Analyze the properties of the channel. (channel-properties (second channel-data)) (contact-handle (telepathy-prop-get telepathy-key-target-handle channel-properties)) (contact (telepathy-make-contact connection contact-handle)) (service (telepathy-prop-get telepathy-key-service channel-properties)) (handler (gethash service telepathy-client-handlers)) ;; Obtain object path of channel object. (channel-path (first channel-data)) (channel-service (let ((bla (telepathy-path->service channel-path))) (substring bla 0 (position ?. bla :from-end t)))) (channel-object (dbus-proxy-make-remote-proxy :session channel-service channel-path nil 'telepathy-tube))) ;; TODO could be a different kind of channel (oset channel-object :contact contact) (message "Channel") (message " Path %s" channel-path) (message " Service %s" service) (message " Contact %s" contact) (funcall handler channel-object))) :ignore) (defun telepathy-client-register (name) "" ;; Create a DBus object to handle tube requests. (let ((service (format "org.freedesktop.Telepathy.Client.%s" name)) (path (format "/org/freedesktop/Telepathy/Client/%s" name))) ;; Install introspection information. (lexical-let ((introspection-data (format telepathy-client-introspection-data name))) (dbus-register-method :session service path "org.freedesktop.DBus.Introspectable" "Introspect" (lambda (&rest args) introspection-data) t)) ;; don't request the name, yet ;; Register all properties belonging to the handler object. (dolist (name-and-value `(("HandlerChannelFilter" ,(mapcar #'telepathy-client-make-channel-filter (telepathy-client-handler-services))) ("BypassApproval" t) ;; TODO was nil ("Capabilities" (:array :signature "as")) ("HandledChannels" (:array :signature "ao")))) (destructuring-bind (name value) name-and-value (dbus-register-property :session service path "org.freedesktop.Telepathy.Client.Handler" name :read value nil t))) ;; don't request the name, yet ;; TODO store the dbus objects for unregistering? (dbus-register-method :session service path "org.freedesktop.Telepathy.Client.Handler" "HandleChannels" #'telepath-client-channel-handler t) ;; don't request the name, yet (dbus-register-property :session service path "org.freedesktop.Telepathy.Client" "Interfaces" :read '("org.freedesktop.Telepathy.Client.Handler") nil t) ;; don't request the name, yet ;; Now that everything is in place, request the name. (dbus-call-method :session dbus-service-dbus dbus-path-dbus dbus-interface-dbus "RequestName" service 0))) ;; (/org/freedesktop/Telepathy/Connection/gabble/jabber/scymtym_2dtest_40jabber_2eorg_2fbe153d1c/StreamTubeChannel_2_1273735221 ;; ((org.freedesktop.Telepathy.Channel.InitiatorID ;; (address@hidden)) ;; (org.freedesktop.Telepathy.Channel.TargetHandleType ;; (1)) ;; (org.freedesktop.Telepathy.Channel.TargetHandle ;; (2)) ;; (org.freedesktop.Telepathy.Channel.TargetID ;; (address@hidden)) ;; (org.freedesktop.Telepathy.Channel.Requested ;; (nil)) ;; (org.freedesktop.Telepathy.Channel.Type.StreamTube.SupportedSocketTypes ;; (((0 (0 3)) (2 (0 1)) (3 (0 1))))) ;; (org.freedesktop.Telepathy.Channel.Type.StreamTube.Service ;; (org.gnu.emacs.rudel.announce)) ;; (org.freedesktop.Telepathy.Channel.Interface.Tube.Parameters ;; (nil)) ;; (org.freedesktop.Telepathy.Channel.ChannelType ;; (org.freedesktop.Telepathy.Channel.Type.StreamTube)) ;; (org.freedesktop.Telepathy.Channel.InitiatorHandle ;; (2)) ;; (org.freedesktop.Telepathy.Channel.Interfaces ;; ((org.freedesktop.Telepathy.Channel.Interface.Tube))))) (defun telepathy-client-unregister (name) "" (dbus-unregister-service :session (format "org.freedesktop.Telepathy.Client.%s" name))) ;;; Helper functions ;; (defun telepathy-client-make-channel-filter (service) "" `((:dict-entry "org.freedesktop.Telepathy.Channel.ChannelType" (:variant :string "org.freedesktop.Telepathy.Channel.Type.StreamTube")) (:dict-entry "org.freedesktop.Telepathy.Channel.TargetHandleType" (:variant :uint32 1)) (:dict-entry "org.freedesktop.Telepathy.Channel.Requested" (:variant :boolean nil)) (:dict-entry "org.freedesktop.Telepathy.Channel.Type.StreamTube.Service" (:variant :string ,service)) )) (provide 'telepathy/client) ;;; client.el ends here