;;; xwem-smartmods.el --- Smart modifiers for XWEM.

;; Copyright (C) 2003 by Free Software Foundation, Inc.

;; Author: Zajcev Evgeny <zevlg@yandex.ru>
;; Created: Fri Dec 12 18:42:05 MSK 2003
;; Keywords: xwem, xlib
;; X-CVS: $Id: xwem-smartmods.el,v 1.1 2004/03/22 18:14:51 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:


;; Smart modifiers:
;;  smart modifiers is modifiers which can work as normal modifier and
;;  as key if it is not used with some other key(when you just
;;  click[press and release modifier]).
(defcustom xwem-use-smart-modifiers nil
  "*Non-nil mean use smart modifiers feature."
  :type 'boolean
  :group 'xwem-keyboard)

(defcustom xwem-kbd-smart-modifiers
  (list (vector XK-Control-L XK-Space nil nil))
  "Smart modifiers list in form [mod-sym key-sym mod-code key-code].
mod-code and key-code will be filled in `xwem-kbd-grab-smartmods'."
  :type 'list
  :group 'xwem-keyboard)

;; Variables
(defvar xwem-key-curr-smamod nil
  "Modifier that waits release.
Internal variable, do not modify.")


;;; Functions
(defun xwem-kbd-sm-install-grab ()
  "Begin to grab smart modifiers."
  (mapcar (lambda (el)
	    (aset el 2 (car (xwem-xksym2kcode (aref el 0))))
	    (aset el 3 (car (xwem-xksym2kcode (aref el 1))))
	    (XGrabKey (xwem-dpy) (aref el 2) 0 (xwem-rootwin)))
	  xwem-kbd-smart-modifiers)
  nil)

(defun xwem-kbd-sm-uninstall-grab ()
  "Stop grabbing smart modifiers."
  (mapcar (lambda (el)
	    (XUngrabKey (xwem-dpy) (aref el 2) 0 (xwem-rootwin)))
	  xwem-kbd-smart-modifiers)
  nil)

(defun xwem-kbd-sm-init ()
  "Initialize smart modifiers."
  (xwem-kbd-sm-install-grab)

  (X-Win-EventHandler-add-new (xwem-rootwin) 'xwem-kbd-sm-keypress 0 (list X-KeyPress))
  (X-Win-EventHandler-add-new (xwem-rootwin) 'xwem-kbd-sm-keyrelease 0 (list X-KeyRelease)))

(defun xwem-kbd-sm-fini ()
  "Finialize smart modifiers."
  (X-Win-EventHandler-rem (xwem-rootwin) 'xwem-kbd-sm-keypress)
  (X-Win-EventHandler-rem (xwem-rootwin) 'xwem-kbd-sm-keyrelease)

  (xwem-kbd-sm-uninstall-grab))

(defun xwem-kbd-sm-smartmodifier-p (kcode)
  "Return non-nil if key code KCODE is actually smart modifier.
I.e. if KCODE is in `xwem-kbd-smart-modifiers' list."
  (xwem-message 'error "`xwem-kbd-sm-smartmodifier-p' not implemented yet")
  nil)

;; Event handlers
(defun xwem-kbd-sm-keyrelease (xdpy win xev)
  "On XDPY and window WIN handle KeyRelease event XEV."
  ;; check for smart modifier
  (when (and xwem-key-curr-smamod
	     (= (X-Event-xkey-keycode xev) xwem-key-curr-smamod))
    (let ((smml xwem-kbd-smart-modifiers))
      (while smml
	(if (= xwem-key-curr-smamod (aref (car smml) 2))
	    (progn
	      ;; TODO:
	      ;;   * Grab keyboard in sync mode than XAllowEvent
	      ;;     with repeat keyboard.
	      (xwem-key-sendseq (list (cons X-Xtest-KeyPress (aref (car smml) 3))
				      (cons X-Xtest-KeyRelease (aref (car smml) 3))))
	      (setq xwem-key-curr-smamod nil)
	      (setq smml nil))
	  (setq smml (cdr smml))))))
  nil)


(defun xwem-kbd-sm-keypress (xdpy win xev)
  "Handle keypress of smart modifier."
  (if (and (xwem-kbd-sm-smartmodifier-p (X-Event-xkey-keycode xev))
	   (not xwem-kbd-now-grabbing))
      (setq xwem-key-curr-smamod kobcode)

    (setq xwem-key-curr-smamod nil)))



(provide 'xwem-smartmods)

;;; xwem-smartmods.el ends here
