;;; xwem-mogu.el --- XWEM MOuse Grid Uberness. ;; Copyright (C) 2005 by XWEM Org. ;; Author: Zajcev Evgeny ;; Created: Thu Mar 3 22:24:27 MSK 2005 ;; Keywords: xwem, mouse, grid ;; 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: ;; When xwem-mogu is enabled whole screen is splited by set of ;; horizontal and vertical lines. Each vertical line has ;; corresponding and each horizontal line has corresponding ;; . Each intersection of horizontal and vertical lines ;; denotes NODE. Each node has unique identificator - cons cell in ;; form: ( . ). The closest node to pointer ;; location called MOUSE-NODE. Set of nodes of same called ;; NODE-VLINE. Set of nodes of same called NODE-HLINE. ;; Here is an ASCII Scheme: ;; 1 2 3 4 ;; a*----------*----------*----------* ;; | | | | ;; | | | | ;; | | | | ;; | | | | ;; | | | | ;; | | | | ;; b*----------o----------*----------* ;; | | | | ;; | | 7\ | | ;; | | | | ;; | | | | ;; | | | | ;; | | | | ;; c*----------*----------*----------* ;; ;; 7\ - Pointer ;; * - node ;; o - mouse-node ;;; Code: (require 'xlib-xlib) (require 'xlib-xshape) (require 'xwem-load) (require 'xwem-interactive) (defgroup xwem-mogu nil "Group to customize xwem mouse grid uberness." :prefix "xwem-mogu-" :group 'xwem-modes) (defcustom xwem-mogu-keep-pointer-offset nil "*Non-nil mean mouse offset is kept when mouse-node is moved." :type 'boolean :group 'xwem-mogu) (defcustom xwem-mogu-numbers-characters-visible-p t "*Non-nil mean s and s are visible." :type 'boolean :group 'xwem-mogu) (defcustom xwem-mogu-identificators-visible-p nil "*Non-nil identificators are shown for each node." :type 'boolean :group 'xwem-mogu) (defcustom xwem-mogu-numbers 8 "Maximum number of s." :type 'number :group 'xwem-mogu) (defcustom xwem-mogu-characters 6 "Maximum number of s." :type 'number :group 'xwem-mogu) (defcustom xwem-mogu-grid-width 1 "*Width of grid lines." :type 'number :group 'xwem-mogu) (defcustom xwem-mogu-grid-color "gray78" "Color for grid." :type 'color :group 'xwem-mogu) (defcustom xwem-mogu-node-color "gray50" "Color for nodes." :type 'color :group 'xwem-mogu) (defcustom xwem-mogu-mouse-node-color "red4" "Color for mouse-node." :type 'color :group 'xwem-mogu) (defcustom xwem-mogu-stack-rank '(((eval t) . (30 . 30))) "Stack ranks specification for xwem mogu." :type '(cons (sexp :tag "Client MATCH-SPEC") (cons (number :tag "Active") (number :tag "Inactive"))) :group 'xwem-mogu) (define-xwem-face xwem-mogu-face `(((grid) (:foreground ,xwem-mogu-grid-color)) ((node) (:foreground ,xwem-mogu-node-color)) ((mouse-node) (:foreground ,xwem-mogu-mouse-node-color))) "Face for use by xwem-mogu." :group 'xwem-mogu :group 'xwem-faces) (defcustom xwem-mogu-minor-mode-hook nil "Hooks to run when mogu mode is enabled or disabled. When running hooks value of `xwem-mogu-minor-mode' is non-nil when mogu minor mode is enabling. When running hooks value of `xwem-mogu-minor-mode' is nil when mogu minor mode is disabling." :type 'hook :group 'xwem-hooks :group 'xwem-mogu) (defvar xwem-mogu-minor-mode nil "Non-nil mean mogu minor mode is enabled.") (defvar xwem-mogu-xwin nil) (defmacro xwem-mogu-xmask (xwin) `(X-Win-get-prop ,xwin 'xwem-mogu-xmask)) (defsetf xwem-mogu-xmask (xwin) (xmask) `(X-Win-put-prop ,xwin 'xwem-mogu-xmask ,xmask)) (defmacro xwem-mogu-mouse-node (xwin) `(X-Win-get-prop ,xwin 'xwem-mogu-mouse-node)) (defsetf xwem-mogu-mouse-node (xwin) (mouse-node) `(X-Win-put-prop ,xwin 'xwem-mogu-mouse-node ,mouse-node)) ;;; Functions (defun xwem-mogu-redimentionize-grid () "`xwem-mogu-numbers' or `xwem-mogu-characters' changed, so handle it." ;; TODO: write me ) (defun xwem-mogu-query-mouse-node () "Return node that is most close to pointer location." (let* ((qp (XQueryPointer (xwem-dpy) xwem-mogu-xwin)) (x (nth 5 qp)) (y (nth 6 qp)) (wid-step (+ (/ (X-Geom-width (xwem-rootgeom)) xwem-mogu-numbers) xwem-mogu-grid-width)) (hei-step (+ (/ (X-Geom-height (xwem-rootgeom)) xwem-mogu-characters) xwem-mogu-grid-width)) (rx (/ x wid-step)) (ry (/ y hei-step)) (wr (% x wid-step)) (hr (% y hei-step))) (when (> wr (- wid-step wr)) (incf rx)) (when (> hr (- hei-step hr)) (incf ry)) ;(cons rx (int-to-char (+ ry (char-to-int ?a)))) (cons rx ry))) (defun xwem-mogu-create-grid () "Create xwem-mogu grid." ;; TODO: write me (unless xwem-mogu-xwin (let* ((wid (X-Geom-width (xwem-rootgeom))) (wid-step (/ wid xwem-mogu-numbers)) (hei (X-Geom-height (xwem-rootgeom))) (hei-step (/ hei xwem-mogu-characters))) (setq xwem-mogu-xwin (XCreateWindow (xwem-dpy) (xwem-rootwin) 0 0 wid hei 0 nil nil nil (make-X-Attr :override-redirect t :background-pixel (XAllocColor (xwem-dpy) (XDefaultColormap (xwem-dpy)) (xwem-make-color xwem-mogu-grid-color))))) ;; XXX Setup stack rank (xwem-misc-set-xwin-always-on-top xwem-mogu-xwin 100) ;; Create mask pixmap (setf (xwem-mogu-xmask xwem-mogu-xwin) (XCreatePixmap (xwem-dpy) (make-X-Pixmap :dpy (xwem-dpy) :id (X-Dpy-get-id (xwem-dpy))) xwem-mogu-xwin 1 wid hei)) (XFillRectangle (xwem-dpy) (xwem-mogu-xmask xwem-mogu-xwin) xwem-misc-mask-fgc 0 0 wid hei) (loop for xo from 0 to wid by (+ wid-step xwem-mogu-grid-width) do (loop for yo from 0 to hei by (+ hei-step xwem-mogu-grid-width) do (XFillRectangle (xwem-dpy) (xwem-mogu-xmask xwem-mogu-xwin) xwem-misc-mask-bgc (+ xo xwem-mogu-grid-width) (+ yo xwem-mogu-grid-width) wid-step hei-step))) (X-XShapeMask (xwem-dpy) xwem-mogu-xwin X-XShape-Bounding X-XShapeSet 0 0 (xwem-mogu-xmask xwem-mogu-xwin)) ;; Initialise mouse-node (setf (xwem-mogu-mouse-node xwem-mogu-xwin) (xwem-mogu-query-mouse-node)) ;; Show mouse grid (XMapWindow (xwem-dpy) xwem-mogu-xwin) xwem-mogu-xwin))) ;;; Commands: (define-xwem-command xwem-turn-on-mogu () "Enable mogu minor mode." (xwem-interactive) (unless xwem-mogu-minor-mode (if xwem-mogu-xwin (XMapWindow (xwem-dpy) xwem-mogu-xwin) (xwem-mogu-create-grid)) (xwem-turn-on-minor-mode nil 'xwem-mogu-minor-mode) (run-hooks 'xwem-mogu-minor-mode-hook))) (define-xwem-command xwem-turn-off-mogu () "Disable mogu minor mode." (xwem-interactive) (when xwem-mogu-minor-mode (XUnmapWindow (xwem-dpy) xwem-mogu-xwin) (xwem-turn-off-minor-mode nil 'xwem-mogu-minor-mode) (run-hooks 'xwem-mogu-minor-mode-hook))) (define-xwem-command xwem-mogu-minor-mode (arg) "Toggle mogu minor mode. If ARG is positive number - enable it. If ARG is negative number - disable it." (xwem-interactive "P") (if (or (and (numberp arg) (> arg 0)) (not xwem-mogu-minor-mode)) (xwem-turn-on-mogu) (xwem-turn-off-mogu))) (defun xwem-mogu-goto (id-x id-y) "Move to node with ID." (let* ((qp (XQueryPointer (xwem-dpy) xwem-mogu-xwin)) (x (nth 5 qp)) (y (nth 6 qp)) (wid-step (+ (/ (X-Geom-width (xwem-rootgeom)) xwem-mogu-numbers) xwem-mogu-grid-width)) (hei-step (+ (/ (X-Geom-height (xwem-rootgeom)) xwem-mogu-characters) xwem-mogu-grid-width)) wr hr) (if (not xwem-mogu-keep-pointer-offset) (setq wr 0 hr 0) (setq wr (% x wid-step) hr (% y hei-step)) (when (> wr (- wid-step wr)) (setq wr (- wr wid-step))) (when (> hr (- hei-step hr)) (setq hr (- hr hei-step)))) ;; Save new mouse-node (setf (xwem-mogu-mouse-node xwem-mogu-xwin) (cons id-x id-y)) (XWarpPointer (xwem-dpy) (xwem-rootwin) xwem-mogu-xwin 0 0 0 0 (+ (* wid-step id-x) wr) (+ (* hei-step id-y) hr)))) (defun xwem-mogu-move (direction arg) "Move in DIRECTION ARG times. DIRECTION is one of 'left, 'right, 'up or 'down. ARG is number." (let ((m-n (xwem-mogu-mouse-node xwem-mogu-xwin))) (ecase direction (left (if (< arg 0) (xwem-mogu-move 'right (- arg)) (xwem-mogu-goto (decf (car m-n) arg) (cdr m-n)))) (right (if (< arg 0) (xwem-mogu-move 'left (- arg)) (xwem-mogu-goto (incf (car m-n) arg) (cdr m-n)))) (up (if (< arg 0) (xwem-mogu-move 'down (- arg)) (xwem-mogu-goto (car m-n) (decf (cdr m-n) arg)))) (down (if (< arg 0) (xwem-mogu-move 'up (- arg)) (xwem-mogu-goto (car m-n) (incf (cdr m-n) arg)))) ))) (define-xwem-command xwem-mogu-right (arg) "Move forward ARG nodes." (xwem-interactive "p") (xwem-mogu-move 'right arg)) (define-xwem-command xwem-mogu-left (arg) "Move backward ARG nodes." (xwem-interactive "p") (xwem-mogu-move 'left arg)) (define-xwem-command xwem-mogu-up (arg) "Move up ARG nodes." (xwem-interactive "p") (xwem-mogu-move 'up arg)) (define-xwem-command xwem-mogu-down (arg) "Move down ARG nodes." (xwem-interactive "p") (xwem-mogu-move 'down arg)) (define-xwem-command xwem-mogu-hline-beginning () "Goto beginning of hline." (xwem-interactive) (xwem-mogu-goto 0 (cdr (xwem-mogu-mouse-node xwem-mogu-xwin)))) (define-xwem-command xwem-mogu-hline-end () "Goto end of hline." (xwem-interactive) (xwem-mogu-goto xwem-mogu-numbers (cdr (xwem-mogu-mouse-node xwem-mogu-xwin)))) (define-xwem-command xwem-mogu-vline-beginning () "Goto beginning of vline." (xwem-interactive) (xwem-mogu-goto (car (xwem-mogu-mouse-node xwem-mogu-xwin)) 0)) (define-xwem-command xwem-mogu-vline-end () "Goto end of vline." (xwem-interactive) (xwem-mogu-goto (car (xwem-mogu-mouse-node xwem-mogu-xwin)) xwem-mogu-characters)) (provide 'xwem-mogu) ;;; On-load actians (xwem-add-minor-mode 'xwem-mogu-minor-mode "Mogu") ;;; xwem-mogu.el ends here