First import
[xorg_rtime.git] / xorg-server-1.4 / xkb / ddxBeep.c
blob331357ded92311673d062180c85bc30a830f95ab
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
31 #include <stdio.h>
32 #define NEED_EVENTS 1
33 #include <X11/X.h>
34 #include <X11/Xproto.h>
35 #include <X11/keysym.h>
36 #include "inputstr.h"
37 #include "scrnintstr.h"
38 #include "windowstr.h"
39 #include <xkbsrv.h>
40 #include <X11/extensions/XI.h>
42 /*#define FALLING_TONE 1*/
43 /*#define RISING_TONE 1*/
44 #define FALLING_TONE 10
45 #define RISING_TONE 10
46 #define SHORT_TONE 50
47 #define SHORT_DELAY 60
48 #define LONG_TONE 75
49 #define VERY_LONG_TONE 100
50 #define LONG_DELAY 85
51 #define CLICK_DURATION 1
53 #define DEEP_PITCH 250
54 #define LOW_PITCH 500
55 #define MID_PITCH 1000
56 #define HIGH_PITCH 2000
57 #define CLICK_PITCH 1500
59 static unsigned long atomGeneration= 0;
60 static Atom featureOn;
61 static Atom featureOff;
62 static Atom featureChange;
63 static Atom ledOn;
64 static Atom ledOff;
65 static Atom ledChange;
66 static Atom slowWarn;
67 static Atom slowPress;
68 static Atom slowReject;
69 static Atom slowAccept;
70 static Atom slowRelease;
71 static Atom stickyLatch;
72 static Atom stickyLock;
73 static Atom stickyUnlock;
74 static Atom bounceReject;
75 static char doesPitch = 1;
77 #define FEATURE_ON "AX_FeatureOn"
78 #define FEATURE_OFF "AX_FeatureOff"
79 #define FEATURE_CHANGE "AX_FeatureChange"
80 #define LED_ON "AX_IndicatorOn"
81 #define LED_OFF "AX_IndicatorOff"
82 #define LED_CHANGE "AX_IndicatorChange"
83 #define SLOW_WARN "AX_SlowKeysWarning"
84 #define SLOW_PRESS "AX_SlowKeyPress"
85 #define SLOW_REJECT "AX_SlowKeyReject"
86 #define SLOW_ACCEPT "AX_SlowKeyAccept"
87 #define SLOW_RELEASE "AX_SlowKeyRelease"
88 #define STICKY_LATCH "AX_StickyLatch"
89 #define STICKY_LOCK "AX_StickyLock"
90 #define STICKY_UNLOCK "AX_StickyUnlock"
91 #define BOUNCE_REJECT "AX_BounceKeyReject"
93 #define MAKE_ATOM(a) MakeAtom(a,sizeof(a)-1,True)
95 static void
96 _XkbDDXBeepInitAtoms(void)
98 featureOn= MAKE_ATOM(FEATURE_ON);
99 featureOff= MAKE_ATOM(FEATURE_OFF);
100 featureChange= MAKE_ATOM(FEATURE_CHANGE);
101 ledOn= MAKE_ATOM(LED_ON);
102 ledOff= MAKE_ATOM(LED_OFF);
103 ledChange= MAKE_ATOM(LED_CHANGE);
104 slowWarn= MAKE_ATOM(SLOW_WARN);
105 slowPress= MAKE_ATOM(SLOW_PRESS);
106 slowReject= MAKE_ATOM(SLOW_REJECT);
107 slowAccept= MAKE_ATOM(SLOW_ACCEPT);
108 slowRelease= MAKE_ATOM(SLOW_RELEASE);
109 stickyLatch= MAKE_ATOM(STICKY_LATCH);
110 stickyLock= MAKE_ATOM(STICKY_LOCK);
111 stickyUnlock= MAKE_ATOM(STICKY_UNLOCK);
112 bounceReject= MAKE_ATOM(BOUNCE_REJECT);
113 return;
116 static CARD32
117 _XkbDDXBeepExpire(OsTimerPtr timer,CARD32 now,pointer arg)
119 DeviceIntPtr dev= (DeviceIntPtr)arg;
120 KbdFeedbackPtr feed;
121 KeybdCtrl * ctrl;
122 XkbSrvInfoPtr xkbInfo;
123 CARD32 next;
124 int pitch,duration;
125 int oldPitch,oldDuration;
126 Atom name;
128 if ((dev==NULL)||(dev->key==NULL)||(dev->key->xkbInfo==NULL)||
129 (dev->kbdfeed==NULL))
130 return 0;
131 if (atomGeneration!=serverGeneration) {
132 _XkbDDXBeepInitAtoms();
133 atomGeneration= serverGeneration;
136 feed= dev->kbdfeed;
137 ctrl= &feed->ctrl;
138 xkbInfo= dev->key->xkbInfo;
139 next= 0;
140 pitch= oldPitch= ctrl->bell_pitch;
141 duration= oldDuration= ctrl->bell_duration;
142 #ifdef DEBUG
143 if (xkbDebugFlags>1)
144 ErrorF("beep: %d (count= %d)\n",xkbInfo->beepType,xkbInfo->beepCount);
145 #endif
146 name= None;
147 switch (xkbInfo->beepType) {
148 default:
149 ErrorF("Unknown beep type %d\n",xkbInfo->beepType);
150 case _BEEP_NONE:
151 duration= 0;
152 break;
154 /* When an LED is turned on, we want a high-pitched beep.
155 * When the LED it turned off, we want a low-pitched beep.
156 * If we cannot do pitch, we want a single beep for on and two
157 * beeps for off.
159 case _BEEP_LED_ON:
160 if (name==None) name= ledOn;
161 duration= SHORT_TONE;
162 pitch= HIGH_PITCH;
163 break;
164 case _BEEP_LED_OFF:
165 if (name==None) name= ledOff;
166 duration= SHORT_TONE;
167 pitch= LOW_PITCH;
168 if (!doesPitch && xkbInfo->beepCount<1)
169 next = SHORT_DELAY;
170 break;
172 /* When a Feature is turned on, we want an up-siren.
173 * When a Feature is turned off, we want a down-siren.
174 * If we cannot do pitch, we want a single beep for on and two
175 * beeps for off.
177 case _BEEP_FEATURE_ON:
178 if (name==None) name= featureOn;
179 if (xkbInfo->beepCount<1) {
180 pitch= LOW_PITCH;
181 duration= VERY_LONG_TONE;
182 if (doesPitch)
183 next= SHORT_DELAY;
185 else {
186 pitch= MID_PITCH;
187 duration= SHORT_TONE;
189 break;
191 case _BEEP_FEATURE_OFF:
192 if (name==None) name= featureOff;
193 if (xkbInfo->beepCount<1) {
194 pitch= MID_PITCH;
195 if (doesPitch)
196 duration= VERY_LONG_TONE;
197 else duration= SHORT_TONE;
198 next= SHORT_DELAY;
200 else {
201 pitch= LOW_PITCH;
202 duration= SHORT_TONE;
204 break;
206 /* Two high beeps indicate an LED or Feature changed
207 * state, but that another LED or Feature is also on.
208 * [[[WDW - This is not in AccessDOS ]]]
210 case _BEEP_LED_CHANGE:
211 if (name==None) name= ledChange;
212 case _BEEP_FEATURE_CHANGE:
213 if (name==None) name= featureChange;
214 duration= SHORT_TONE;
215 pitch= HIGH_PITCH;
216 if (xkbInfo->beepCount<1) {
217 next= SHORT_DELAY;
219 break;
221 /* Three high-pitched beeps are the warning that SlowKeys
222 * is going to be turned on or off.
224 case _BEEP_SLOW_WARN:
225 if (name==None) name= slowWarn;
226 duration= SHORT_TONE;
227 pitch= HIGH_PITCH;
228 if (xkbInfo->beepCount<2)
229 next= SHORT_DELAY;
230 break;
232 /* Click on SlowKeys press and accept.
233 * Deep pitch when a SlowKey or BounceKey is rejected.
234 * [[[WDW - Rejects are not in AccessDOS ]]]
235 * If we cannot do pitch, we want single beeps.
237 case _BEEP_SLOW_PRESS:
238 if (name==None) name= slowPress;
239 case _BEEP_SLOW_ACCEPT:
240 if (name==None) name= slowAccept;
241 case _BEEP_SLOW_RELEASE:
242 if (name==None) name= slowRelease;
243 duration= CLICK_DURATION;
244 pitch= CLICK_PITCH;
245 break;
246 case _BEEP_BOUNCE_REJECT:
247 if (name==None) name= bounceReject;
248 case _BEEP_SLOW_REJECT:
249 if (name==None) name= slowReject;
250 duration= SHORT_TONE;
251 pitch= DEEP_PITCH;
252 break;
254 /* Low followed by high pitch when a StickyKey is latched.
255 * High pitch when a StickyKey is locked.
256 * Low pitch when unlocked.
257 * If we cannot do pitch, two beeps for latch, nothing for
258 * lock, and two for unlock.
260 case _BEEP_STICKY_LATCH:
261 if (name==None) name= stickyLatch;
262 duration= SHORT_TONE;
263 if (xkbInfo->beepCount<1) {
264 next= SHORT_DELAY;
265 pitch= LOW_PITCH;
267 else pitch= HIGH_PITCH;
268 break;
269 case _BEEP_STICKY_LOCK:
270 if (name==None) name= stickyLock;
271 if (doesPitch) {
272 duration= SHORT_TONE;
273 pitch= HIGH_PITCH;
275 break;
276 case _BEEP_STICKY_UNLOCK:
277 if (name==None) name= stickyUnlock;
278 duration= SHORT_TONE;
279 pitch= LOW_PITCH;
280 if (!doesPitch && xkbInfo->beepCount<1)
281 next = SHORT_DELAY;
282 break;
284 if (timer == NULL && duration>0) {
285 CARD32 starttime = GetTimeInMillis();
286 CARD32 elapsedtime;
288 ctrl->bell_duration= duration;
289 ctrl->bell_pitch= pitch;
290 if (xkbInfo->beepCount==0) {
291 XkbHandleBell(0,0,dev,ctrl->bell,(pointer)ctrl,KbdFeedbackClass,name,None,
292 NULL);
294 else if (xkbInfo->desc->ctrls->enabled_ctrls&XkbAudibleBellMask) {
295 (*dev->kbdfeed->BellProc)(ctrl->bell,dev,(pointer)ctrl,KbdFeedbackClass);
297 ctrl->bell_duration= oldDuration;
298 ctrl->bell_pitch= oldPitch;
299 xkbInfo->beepCount++;
301 /* Some DDX schedule the beep and return immediately, others don't
302 return until the beep is completed. We measure the time and if
303 it's less than the beep duration, make sure not to schedule the
304 next beep until after the current one finishes. */
306 elapsedtime = GetTimeInMillis();
307 if (elapsedtime > starttime) { /* watch out for millisecond counter
308 overflow! */
309 elapsedtime -= starttime;
310 } else {
311 elapsedtime = 0;
313 if (elapsedtime < duration) {
314 next += duration - elapsedtime;
318 return next;
322 XkbDDXAccessXBeep(DeviceIntPtr dev,unsigned what,unsigned which)
324 XkbSrvInfoRec *xkbInfo= dev->key->xkbInfo;
325 CARD32 next;
327 xkbInfo->beepType= what;
328 xkbInfo->beepCount= 0;
329 next= _XkbDDXBeepExpire(NULL,0,(pointer)dev);
330 if (next>0) {
331 xkbInfo->beepTimer= TimerSet(xkbInfo->beepTimer,
332 0, next,
333 _XkbDDXBeepExpire, (pointer)dev);
335 return 1;