;;; xlib-tray.el --- XEMBED support.

;; Copyright (C) 2003-2005 by XWEM Org.

;; Author: Zajcev Evgeny <zevlg@yandex.ru>
;; Created: Tue Dec  9 14:14:07 MSK 2003
;; Keywords: xlib, xwem
;; X-CVS: $Id: xlib-tray.el,v 1.8 2005-04-04 19:55:29 lg Exp $

;; This file is part of XWEM.

;; XWEM 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, or (at your option)
;; any later version.

;; XWEM 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 XEmacs; see the file COPYING.  If not, write to the Free
;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
;; 02111-1307, USA.

;;; Synched up with: Not in FSF

;;; Commentary:

;;

;;; Code:

(require 'xlib-xlib)

;;; Constants
(defconst X-Tray-dock-req 0 "Dock place request.")
(defconst X-Tray-message 1 "Message from dock app.")
(defconst X-Tray-cancel-message 2 "Cancels message.")
(defconst X-Tray-run-lisp 3 "Evaluate emacs lisp string")

(defconst X-Tray-Atom-System-Tray 0)
(defconst X-Tray-Atom-System-Tray-Opcode 1)
(defconst X-Tray-Atom-Xembed-Info 2)
(defconst X-Tray-Atom-Xembed 3)
(defconst X-Tray-Atom-Manager 4)
(defconst X-Tray-Atom-Net-System-Tray-Message-Data 5)
(defconst X-Tray-Atom-Kde-System-Tray 6)


;;; Functions
(defun XTrayInit (xdpy win)
  "Initialize atoms for interaction with system tray."
  (let ((atoms (make-vector 10 nil)))

    (aset atoms X-Tray-Atom-System-Tray (XInternAtom xdpy "_NET_SYSTEM_TRAY_S0" nil))
    (aset atoms X-Tray-Atom-System-Tray-Opcode (XInternAtom xdpy "_NET_SYSTEM_TRAY_OPCODE" nil))
    (aset atoms X-Tray-Atom-Xembed-Info (XInternAtom xdpy "_XEMBED_INFO" nil))
    (aset atoms X-Tray-Atom-Xembed (XInternAtom xdpy "_XEMBED" nil))
    (aset atoms X-Tray-Atom-Manager (XInternAtom xdpy "MANAGER" nil))
    (aset atoms X-Tray-Atom-Net-System-Tray-Message-Data (XInternAtom xdpy "_NET_SYSTEM_TRAY_MESSAGE_DATA" nil))
    (aset atoms X-Tray-Atom-Kde-System-Tray (XInternAtom xdpy "_KDE_NET_SYSTEM_TRAY_WINDOWS" nil))
    
    (X-Dpy-put-property xdpy 'tray-atoms atoms)

    (XTrayFindDock xdpy win)))

(defun XTrayGetAtom (xdpy atom-code)
  (let ((atoms (X-Dpy-get-property xdpy 'tray-atoms)))
    (when (vectorp atoms)
      (aref atoms atom-code))))

(defun XTrayFindDock (xdpy win)
  (let (dock)

    (setq dock (XGetSelectionOwner xdpy (XTrayGetAtom xdpy X-Tray-Atom-System-Tray)))
    (unless (X-Win-p dock)
      (XSelectInput xdpy (XDefaultRootWindow xdpy) XM-StructureNotify))

    (when (X-Win-p dock)
      (XTraySendOpcode xdpy dock dock X-Tray-dock-req (X-Win-id win)))))

(defun XTraySendOpcode (xdpy dock win message &optional data1 data2 data3)
  (let (xev)
    ;; TODO:
    ;;   * Fill xclient event XEV
    (setq xev (X-Create-message
	       (list [1 X-ClientMessage] ;type
		     [1 32]		;format
		     [2 0]		;seq
		     [4 (X-Win-id win)] ;window
		     [4 (X-Atom-id (XTrayGetAtom xdpy X-Tray-Atom-System-Tray-Opcode))]
		     
		     [4 X-CurrentTime]
		     [4 message]
		     [4 data1]
		     [4 data2]
		     [4 data3])))

    (XSendEvent xdpy dock nil XM-NoEvent xev)
    ))

(defun XTraySendMessageData (xdpy dock win data)
  (let (xev)
    (setq xev (X-Create-message
	       (list [1 X-ClientMessage] ;type
		     [1 8]		;format
		     [2 0]		;seq
		     [4 (X-Win-id win)] ;window
		     [4 (X-Atom-id (XTrayGetAtom xdpy X-Tray-Atom-Net-System-Tray-Message-Data))]

		     [20 data])))

    (XSendEvent xdpy dock nil XM-NoEvent xev)
    (XSync xdpy)
    ))

(defun XTraySetXembedInfo (xdpy win flags)
  (XChangeProperty xdpy win (XTrayGetAtom xdpy X-Tray-Atom-Xembed-Info)
		   XA-cardinal 32 X-PropModeReplace (X-Create-message (list [4 1] ; max supported xembed version
									    [4 flags]))))

(defun XTrayMapWindow (xdpy win)
  (XTraySetXembedInfo xdpy win 1))

(defun XTrayUnmapWindow (xdpy win)
  (XTraySetXembedInfo xdpy win 0))

(defun XTrayHandleEvent (xdpy win xev)
  (X-Event-CASE xev
    (:X-ClientMessage
     (X-Dpy-log xdpy 'x-tray "got client message"))

    (:X-PropertyNotify
     (X-Dpy-log xdpy 'x-tray "got property notify"))))

(defun XTraySendMessage (xdpy dock win opcode msg)
  (let ((id 1234))			; TODO: should be unique
    (XTraySendOpcode xdpy dock win opcode 0 (length msg) id)

    (while (> (length msg) 20)
      (XTraySendMessageData xdpy dock win (substring msg 0 20))
      (setq msg (substring msg 20)))
    
    (when (> (length msg) 0)
      (XTraySendMessageData xdpy dock win msg))))
      
(defun XTrayInitSessionInfo (xdpy win cmd)
  ;; TODO: write me
  )


(provide 'xlib-tray)

;;; xlib-tray.el ends here
