1 ;;; xwem-recover.el --- Autorecovery tool for xwem.
3 ;; Copyright (C) 2004,2005 by XWEM Org.
5 ;; Author: Zajcev Evgeny <zevlg@yandex.ru>
6 ;; Created: Sat Sep 11 23:20:23 GMT 2004
7 ;; Keywords: xlib, xwem
8 ;; X-CVS: $Id: xwem-recover.el,v 1.2 2005-04-04 19:54:15 lg Exp $
10 ;; This file is part of XWEM.
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)
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.
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
27 ;;; Synched up with: Not in FSF
31 ;; Sometimes xlib desyncronises with X server. In such circumstatces
32 ;; only restarting helps. This tool tries to recover xlib from
33 ;; desyncronisation. Desync may occur because XEmacs can block
34 ;; whenever he want, and there no visible way to control it.
36 ;; xwem-recover installs x error hooks and if many x errors occurs in
37 ;; a little time it starts recovering routines.
39 ;; Any time you are feeling that something wrong, you can use
40 ;; `xwem-recover-do-recover' command to force recovering.
46 (defgroup xwem-recover nil
47 "Group to customize xwem recovering tool."
48 :prefix "xwem-recover-"
51 (defcustom xwem-recover-parameter '(12 . 3)
52 "*How many errors allowed without recovering.
53 car specifies number of errors, cdr specifies time in seconds."
54 :type '(cons number number)
57 ;;; Internal variables
59 (defvar xwem-recover-mode nil
60 "Non-nil mean we are in recovering mode.
61 Use `xwem-recover-turn-on', `xwem-recover-turn-off' and
62 `xwem-recover-toggle' to change mode.")
64 (defvar xwem-recover-errors nil
65 "List of times when X error occurs.
69 (define-xwem-deffered xwem-recover-real-recover ()
70 "Do real recovering routines."
71 (setf (X-Dpy-snd-queue (xwem-dpy)) nil)
72 (setf (X-Dpy-message-buffer (xwem-dpy)) "")
73 (setf (X-Dpy-evq (xwem-dpy)) nil))
75 ;;;###autoload(autoload 'xwem-recover-do-recover "xwem-recover" "" t)
76 (define-xwem-command xwem-recover-do-recover (xdpy)
77 "Recover XDPY from desyncronisation with X server."
78 (xwem-interactive (list (xwem-dpy)))
80 (flet ((old-x-dpy-filter (proc out)))
81 (fset 'old-x-dpy-filter (symbol-function 'X-Dpy-filter))
82 (flet ((X-Dpy-filter (proc out)
83 ;; Skip any data on XDPY, but continue processing on
85 (unless (eq (X-Dpy-proc xdpy) proc)
86 (old-x-dpy-filter proc out))))
87 (while (accept-process-output (X-Dpy-proc xdpy) 2))
89 ;; At this point all pending readed, so do cleanup things. This
90 ;; is not 100% will work. In some circumstances this will only
92 (xwem-recover-real-recover)
95 (defun xwem-recover-xerr-hook (xdpy xerr)
96 "Called when on display XDPY X error XERR occured.
97 Check excedance of `xwem-recover-parameter' and if it seems like xlib
98 got desyncronised with X server, start recovering routines."
100 (let ((ct (current-time)))
101 (setq xwem-recover-errors (nreverse xwem-recover-errors))
102 (while (and xwem-recover-errors
103 (> (itimer-time-difference ct (car xwem-recover-errors))
104 (cdr xwem-recover-parameter)))
105 (setq xwem-recover-errors (cdr xwem-recover-errors)))
106 (setq xwem-recover-errors
107 (cons ct (nreverse xwem-recover-errors)))
109 ;; Check (car xwem-recover-errors) is not exceeded
110 (when (or (> (length xwem-recover-errors) (car xwem-recover-parameter))
111 ;; Also recover when error code isn't recognized
112 (not (memq (X-Event-xerror-code xerr)
113 '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 128 255))))
114 (xwem-message 'alarm "Recovering from desyncronisation .. (errors = %d)\n"
115 (length xwem-recover-errors))
116 (xwem-recover-do-recover xdpy))
119 ;;;###autoload(autoload 'xwem-recover-turn-on "xwem-recover" "" t)
120 (define-xwem-command xwem-recover-turn-on ()
121 "Enable xwem recovering mode."
124 (unless xwem-recover-mode
125 (pushnew 'xwem-recover-xerr-hook (X-Dpy-error-hooks (xwem-dpy)))
126 (setq xwem-recover-mode t)))
128 ;;;###autoload(autoload 'xwem-recover-turn-off "xwem-recover" "" t)
129 (define-xwem-command xwem-recover-turn-off ()
130 "Turn off xwem recovering mode."
133 (when xwem-recover-mode
134 (setf (X-Dpy-error-hooks (xwem-dpy))
135 (delq 'xwem-recover-xerr-hook (X-Dpy-error-hooks (xwem-dpy))))
136 (setq xwem-recover-mode nil)))
138 ;;;###autoload(autoload 'xwem-recover-toggle "xwem-recover" "" t)
139 (define-xwem-command xwem-recover-toggle (arg)
140 "Toggle xwem recovering mode.
141 With positive ARG turn it on, with negative turn it off.
142 If ARG is ommited - toggle it."
143 (xwem-interactive "P")
146 (if xwem-recover-mode
147 (xwem-recover-turn-off)
148 (xwem-recover-turn-on)))
149 ((< (prefix-numeric-value arg) 0)
150 (xwem-recover-turn-off))
151 (t (xwem-recover-turn-on))))
154 (provide 'xwem-recover)
156 ;;; xwem-recover.el ends here