root/trunk/lisp/international/mw32mci.el

Revision 3788, 6.0 kB (checked in by miyoshi, 3 years ago)

* international/mw32mci.el: Removed redundant spaces.

* international/mw32misc.el
(mw32-charset-windows-font-info-alist): Ditto.

  • Property svn:eol-style set to LF
  • Property svn:executable set to
Line 
1 ;;;;; mw32mci.el ---- For MCI (Multimedia Control Interface).
2 ;;
3 ;;   Author MIYOSHI Masanori
4 ;;
5 ;;;;;
6 (defvar mw32-mci-notify-callback-alist nil)
7
8
9 (defun mw32-mci-add-notify-callback (device-id callback-func
10                                                &optional callback-arg)
11   "Add a callback function when a notify event rises."
12   (setq mw32-mci-notify-callback-alist
13         (cons (list device-id callback-func callback-arg)
14               mw32-mci-notify-callback-alist)))
15
16
17 (defun mw32-mci-remove-notify-callback (device-id callback-func)
18   "Remove a callback function."
19   (let ((elem (assoc device-id mw32-mci-notify-callback-alist)))
20     (while elem
21       (let ((func (nth 1 elem)))
22         (when (eq func callback-func)
23           (setq mw32-mci-notify-callback-alist
24                 (delq elem mw32-mci-notify-callback-alist)))
25         (setq elem (assoc device-id mw32-mci-notify-callback-alist))))))
26
27
28 (defun mw32-mci-notify-event-handler (device-id exit-state)
29   (let ((elem (assoc device-id mw32-mci-notify-callback-alist))
30         target-alist)
31     (while elem
32       (setq target-alist (cons elem target-alist))
33       (setq mw32-mci-notify-callback-alist
34             (delq elem mw32-mci-notify-callback-alist))
35       (setq elem (assoc device-id mw32-mci-notify-callback-alist)))
36     (setq elem (car target-alist))
37     (while elem
38       (let ((func (nth 1 elem))
39             (arg (nth 2 elem)))
40         (funcall func device-id exit-state arg)
41         (setq target-alist (cdr target-alist))
42         (setq elem (car target-alist))))))
43
44
45 (defun mw32-mci-handle-event (event)
46   (interactive "e")
47   (let ((event-type (nth 1 event))
48         (device-id (nth 2 event))
49         (event-arg (nth 3 event)))
50     (cond
51      ((eq event-type 'mw32-mci-notify)
52       (mw32-mci-notify-event-handler device-id event-arg)))))
53
54
55 ;; when mw32-mci event rises, handle it with mw32-mci-handle-event().
56 (define-key special-event-map [mw32-mci] 'mw32-mci-handle-event)
57
58
59 (defun mw32-mci-notify-func (device-id exit-state &optional arg)
60   (cond
61    ((eq exit-state 'mw32-mci-notify-successful)
62     (let (device-name tmp-file)
63       (cond
64        ((stringp arg)
65         (setq device-name arg))
66        ((listp arg)
67         (setq device-name (nth 0 arg))
68         (setq tmp-file (nth 1 arg))))
69       (when (stringp device-name)
70         (mw32-mci-send-string (format "close %s" device-name)))
71       (when (and (stringp tmp-file)
72                  (file-writable-p tmp-file))
73         (delete-file tmp-file))))
74    (t
75     (error "abnormal termination"))))
76
77
78 ;; Parse sound specification SOUND, and fill ATTRS with what is
79 ;; found.  Value is non-zero if SOUND Is a valid sound specification.
80 ;; A valid sound specification is a list starting with the symbol
81 ;; `sound'.  The rest of the list is a property list which may
82 ;; contain the following key/value pairs:
83
84 ;;    - `:file FILE'
85
86 ;;    FILE is the sound file to play.  If it isn't an absolute name,
87 ;;    it's searched under `data-directory'.
88
89 ;;    - `:data DATA'
90
91 ;;    DATA is a string containing sound data.  Either :file or :data
92 ;;    may be present, but not both.
93
94 ;;    - `:device DEVICE'
95
96 ;;    DEVICE is the name of the device to play on, e.g. "/dev/dsp2".
97 ;;    If not specified, a default device is used.
98
99 ;;    - `:volume VOL'
100
101 ;;    VOL must be an integer in the range [0, 100], or a float in the
102 ;;    range [0, 1].
103
104 (defun parse-sound (sound)
105   (catch 'invalid
106     (progn
107       ;; SOUND must be a list starting with the symbol `sound'.
108       (unless (and (consp sound)
109                    (eq (car sound) 'sound))
110         (throw 'invalid nil))
111       (setq sound (cdr sound))
112       (let ((file (plist-get sound :file))
113             (data (plist-get sound :data))
114             (device (plist-get sound :device))
115             (volume (plist-get sound :volume)))
116
117         ;; File name or data must be specified.
118         (unless (or (stringp file)
119                     (stringp data))
120           (throw 'invalid nil))
121
122         ;;  Volume must be in the range 0..100 or unspecified.
123         (when volume
124           (cond
125            ((integerp volume)
126             (if (or (< volume  0)
127                     (> volume 100))
128                 (throw 'invalid nil)))
129            ((floatp volume)
130             (if (or (< volume  0.0)
131                     (> volume 1.0))
132                 (throw 'invalid nil)))
133            (t
134             (throw 'invalid nil))))
135
136         ;; Device must be a string or unspecified.
137         (when (and device
138                    (not (stringp device)))
139           (throw 'invalid nil))))
140     t))
141
142
143 (defun play-sound (sound)
144   "Play sound SOUND.\n\
145 SOUND is a list of the form `(sound KEYWORD VALUE...)'.\n\
146 The following keywords are recognized:\n\
147 \n\
148   :file FILE.- read sound data from FILE.  If FILE isn't an\n\
149 absolute file name, it is searched in `data-directory'.\n\
150 \n\
151   :data DATA - read sound data from string DATA.\n\
152 \n\
153 Exactly one of :file or :data must be present.\n\
154 \n\
155   :volume VOL - set volume to VOL.  VOL must an integer in the\n\
156 range 0..100 or a float in the range 0..1.0.  If not specified,\n\
157 don't change the volume setting of the sound device.\n\
158 \n\
159   :device DEVICE - play sound on DEVICE.  If not specified,\n\
160 a system-dependent default device name is used."
161   ;; Parse the sound specification.  Give up if it is invalid.
162   (when (null (parse-sound sound))
163     (error "Invalid sound specification"))
164
165   (setq sound (cdr sound))
166   (let ((file (plist-get sound :file))
167         (data (plist-get sound :data))
168         (device (plist-get sound :device))
169         (volume (plist-get sound :volume))
170         (device-name (make-temp-name "waveaudio"))
171         tmp-file arg)
172     (if (stringp file)
173         (progn
174           (setq file (expand-file-name file data-directory))
175           (setq arg device-name))
176       (setq tmp-file (make-temp-file "waveaudio"))
177       (setq file (concat tmp-file ".wav"))
178       (rename-file tmp-file file)
179       (if (file-writable-p file)
180           (with-temp-buffer
181             (let ((coding-system-for-write 'binary))
182               (set-buffer-multibyte nil)
183               (princ data (current-buffer))
184               (write-file file)))
185         (error (format "cannot open %s" file)))
186       (setq arg (list device-name file)))
187     (let (result device-id)
188       (setq result
189             (mw32-mci-send-string (format "open \"%s\" alias %s"
190                                           file device-name)))
191       (when (numberp result)
192         (error (format "cannot open %s!" file)))
193       (setq device-id (string-to-number result))
194       (mw32-mci-send-string (format "play %s notify" device-name))
195       (mw32-mci-add-notify-callback device-id 'mw32-mci-notify-func arg))
196     ;; :volume and :device properties are ignored.
197     )
198   t)
Note: See TracBrowser for help on using the browser.