Initial Commit
[packages] / xemacs-packages / xwem / lisp / xwem-smartmods.el
1 ;;; xwem-smartmods.el --- Smart modifiers for XWEM.
2
3 ;; Copyright (C) 2003-2005 by XWEM Org.
4
5 ;; Author: Zajcev Evgeny <zevlg@yandex.ru>
6 ;; Created: Fri Dec 12 18:42:05 MSK 2003
7 ;; Keywords: xwem, xlib
8 ;; X-CVS: $Id: xwem-smartmods.el,v 1.6 2005-04-04 19:54:15 lg Exp $
9
10 ;; This file is part of XWEM.
11
12 ;; XWEM is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; XWEM is distributed in the hope that it will be useful, but WITHOUT
18 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20 ;; License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING.  If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 ;; 02111-1307, USA.
26
27 ;;; Synched up with: Not in FSF
28
29 ;;; Commentary:
30
31 ;; XWEM minor mode.
32
33 ;;; Code:
34 \f
35
36 ;; Smart modifiers:
37
38 ;;  smart modifiers are modifiers which can work as normal modifiers
39 ;;  and as key if it is not used with some other key(when you just
40 ;;  click[press and release modifier]).
41
42 (require 'xwem-load)
43 (require 'xlib-xtest)
44 (require 'xwem-keyboard)
45
46 (defcustom xwem-smart-mods-alist (list (cons XK-Control-L XK-Space))
47   "*Alist of smart modifiers list in form \(MOD-SYM . KEY-SYM\)."
48   :type '(repeat (cons number number))
49   :group 'xwem-keyboard)
50
51 (defcustom xwem-sm-mode-line "SmartMods"
52   "*String to show when smart modifiers mode is on."
53   :type 'string
54   :group 'xwem-modes)
55
56 ;;; Internal variables
57
58 (defvar xwem-smart-modifiers nil
59   "List of smart mods generated from `xwem-smart-mods-alist'.
60 Internal variable, do not modify.")
61
62 (defvar xwem-sm-global-mode nil
63   "Non-nil mean smart modifiers mode enabled globally.
64 Use `xwem-sm-global-mode' to toggle global smart mods mode.")
65
66 (defvar xwem-sm-mode nil
67   "Non-nil mean smart modifiers mode is enabled.
68 Use `xwem-sm-mode' command to toggle smart mods mode.")
69 (xwem-make-variable-client-local 'xwem-sm-mode)
70
71 \f
72 ;;; Functions
73 (defun xwem-sm-install-grab (&optional xwin)
74   "Begin to grab smart modifiers."
75   (unless xwin
76     (setq xwin (xwem-rootwin)))
77   (setq xwem-smart-modifiers
78         (mapcar (lambda (sm)
79                   (let ((rc (cons (car (xwem-kbd-xksym->xkcode (car sm)))
80                                   (car (xwem-kbd-xksym->xkcode (cdr sm))))))
81                     (XGrabKey (xwem-dpy) (car rc) 0 xwin nil nil X-GrabModeSync)
82                     rc))
83                 xwem-smart-mods-alist)))
84
85 (defun xwem-sm-uninstall-grab (&optional xwin)
86   "Stop grabbing smart modifiers."
87   (unless xwin
88     (setq xwin (xwem-rootwin)))
89   (mapc (lambda (sm)
90           (XUngrabKey (xwem-dpy) (car sm) 0 xwin))
91         xwem-smart-modifiers))
92
93 (defun xwem-sm-init (&optional xwin)
94   "Enter smartmods mode."
95   (unless xwin
96     (setq xwin (xwem-rootwin)))
97
98   (xwem-sm-install-grab xwin)
99   (X-Win-EventHandler-add-new xwin 'xwem-sm-keypress 0 (list X-KeyPress))
100
101   (setq xwem-sm-mode 1))
102
103 (defun xwem-sm-fini (&optional xwin)
104   "Exit smartmods mode."
105   (unless xwin
106     (setq xwin (xwem-rootwin)))
107
108   (X-Win-EventHandler-rem xwin 'xwem-sm-keypress)
109   (xwem-sm-uninstall-grab xwin)
110
111   (setq xwem-sm-mode nil))
112
113 ;; Event handlers
114 (defun xwem-sm-keypress (xdpy win xev)
115   "Handle keypress of smart modifier."
116   (let ((sm (assq (X-Event-xkey-keycode xev) xwem-smart-modifiers)))
117     (when sm
118       (XGrabKeyboard (xwem-dpy) (xwem-rootwin) nil
119                      X-GrabModeSync X-GrabModeSync)
120       (XAllowEvents (xwem-dpy) X-SyncBoth)
121
122       ;; Skip non-keyboard/pointer events
123       (setq xev (xwem-next-event nil
124                                  (list X-KeyPress X-KeyRelease
125                                        X-ButtonPress X-ButtonRelease
126                                        X-MotionNotify)))
127       
128       (when (and (= (X-Event-type xev) X-KeyRelease)
129                  (setq sm (assq (X-Event-xkey-keycode xev)
130                                 xwem-smart-modifiers)))
131         ;; Send smart keycode
132         (xwem-key-send-xtest-internal
133          (list (cons X-Xtest-KeyPress (cdr sm))
134                (cons X-Xtest-KeyRelease (cdr sm)))))
135
136       (XAllowEvents (xwem-dpy) X-ReplayKeyboard)
137       (XUngrabKeyboard (xwem-dpy))
138       (XUngrabPointer (xwem-dpy))
139       )))
140
141 ;;;###autoload(autoload 'xwem-sm-mode "xwem-smartmods" nil t)
142 (define-xwem-command xwem-sm-mode (client &optional arg)
143   "Toggle smart modifiers mode for CLIENT.
144 With positive ARG - turn it on.
145 With negative ARG - turn it off.
146 Without ARG - toggle."
147   (xwem-interactive (list (xwem-cl-selected)
148                           xwem-prefix-arg))
149
150   (cond ((null arg)
151          (if xwem-sm-mode
152              (xwem-sm-fini (xwem-cl-xwin client))
153            (xwem-sm-init (xwem-cl-xwin client))))
154         ((and (> arg 0)
155               (not xwem-sm-mode))
156          (xwem-sm-init (xwem-cl-xwin client)))
157         ((and (< arg 0)
158               xwem-sm-mode)
159          (xwem-sm-fini (xwem-cl-xwin client)))))
160
161 ;;;###autoload(autoload 'xwem-sm-global-mode "xwem-smartmods" nil t)
162 (define-xwem-command xwem-sm-global-mode (arg)
163   "Toggle global smart modifiers mode.
164 With positive ARG - turn it on.
165 With negative ARG - turn it off.
166 Without ARG - toggle."
167   (xwem-interactive "P")
168
169   (cond ((null arg)
170          (if xwem-sm-mode
171              (xwem-sm-fini)
172            (xwem-sm-init)))
173         ((and (> arg 0)
174               (not xwem-sm-mode))
175          (xwem-sm-init))
176         ((and (< arg 0)
177               xwem-sm-mode)
178          (xwem-sm-fini))))
179
180 \f
181 ;;; On-load actions
182 (add-to-list 'xwem-minor-mode-alist
183              '(xwem-sm-mode xwem-sm-mode-line))
184
185 \f
186 (provide 'xwem-smartmods)
187
188 ;;; xwem-smartmods.el ends here