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>
33 #include <X11/Xproto.h>
34 #include <X11/keysym.h>
36 #include "scrnintstr.h"
37 #include "windowstr.h"
39 #include <X11/extensions/XI.h>
41 /*#define FALLING_TONE 1*/
42 /*#define RISING_TONE 1*/
43 #define FALLING_TONE 10
44 #define RISING_TONE 10
46 #define SHORT_DELAY 60
48 #define VERY_LONG_TONE 100
50 #define CLICK_DURATION 1
52 #define DEEP_PITCH 250
54 #define MID_PITCH 1000
55 #define HIGH_PITCH 2000
56 #define CLICK_PITCH 1500
58 static unsigned long atomGeneration= 0;
59 static Atom featureOn;
60 static Atom featureOff;
61 static Atom featureChange;
64 static Atom ledChange;
66 static Atom slowPress;
67 static Atom slowReject;
68 static Atom slowAccept;
69 static Atom slowRelease;
70 static Atom stickyLatch;
71 static Atom stickyLock;
72 static Atom stickyUnlock;
73 static Atom bounceReject;
74 static char doesPitch = 1;
76 #define FEATURE_ON "AX_FeatureOn"
77 #define FEATURE_OFF "AX_FeatureOff"
78 #define FEATURE_CHANGE "AX_FeatureChange"
79 #define LED_ON "AX_IndicatorOn"
80 #define LED_OFF "AX_IndicatorOff"
81 #define LED_CHANGE "AX_IndicatorChange"
82 #define SLOW_WARN "AX_SlowKeysWarning"
83 #define SLOW_PRESS "AX_SlowKeyPress"
84 #define SLOW_REJECT "AX_SlowKeyReject"
85 #define SLOW_ACCEPT "AX_SlowKeyAccept"
86 #define SLOW_RELEASE "AX_SlowKeyRelease"
87 #define STICKY_LATCH "AX_StickyLatch"
88 #define STICKY_LOCK "AX_StickyLock"
89 #define STICKY_UNLOCK "AX_StickyUnlock"
90 #define BOUNCE_REJECT "AX_BounceKeyReject"
92 #define MAKE_ATOM(a) MakeAtom(a,sizeof(a)-1,TRUE)
95 _XkbDDXBeepInitAtoms(void)
97 featureOn= MAKE_ATOM(FEATURE_ON);
98 featureOff= MAKE_ATOM(FEATURE_OFF);
99 featureChange= MAKE_ATOM(FEATURE_CHANGE);
100 ledOn= MAKE_ATOM(LED_ON);
101 ledOff= MAKE_ATOM(LED_OFF);
102 ledChange= MAKE_ATOM(LED_CHANGE);
103 slowWarn= MAKE_ATOM(SLOW_WARN);
104 slowPress= MAKE_ATOM(SLOW_PRESS);
105 slowReject= MAKE_ATOM(SLOW_REJECT);
106 slowAccept= MAKE_ATOM(SLOW_ACCEPT);
107 slowRelease= MAKE_ATOM(SLOW_RELEASE);
108 stickyLatch= MAKE_ATOM(STICKY_LATCH);
109 stickyLock= MAKE_ATOM(STICKY_LOCK);
110 stickyUnlock= MAKE_ATOM(STICKY_UNLOCK);
111 bounceReject= MAKE_ATOM(BOUNCE_REJECT);
116 _XkbDDXBeepExpire(OsTimerPtr timer,CARD32 now,pointer arg)
118 DeviceIntPtr dev= (DeviceIntPtr)arg;
121 XkbSrvInfoPtr xkbInfo;
124 int oldPitch,oldDuration;
127 if ((dev==NULL)||(dev->key==NULL)||(dev->key->xkbInfo==NULL)||
128 (dev->kbdfeed==NULL))
130 if (atomGeneration!=serverGeneration) {
131 _XkbDDXBeepInitAtoms();
132 atomGeneration= serverGeneration;
137 xkbInfo= dev->key->xkbInfo;
139 pitch= oldPitch= ctrl->bell_pitch;
140 duration= oldDuration= ctrl->bell_duration;
142 switch (xkbInfo->beepType) {
144 ErrorF("[xkb] Unknown beep type %d\n",xkbInfo->beepType);
149 /* When an LED is turned on, we want a high-pitched beep.
150 * When the LED it turned off, we want a low-pitched beep.
151 * If we cannot do pitch, we want a single beep for on and two
155 if (name==None) name= ledOn;
156 duration= SHORT_TONE;
160 if (name==None) name= ledOff;
161 duration= SHORT_TONE;
163 if (!doesPitch && xkbInfo->beepCount<1)
167 /* When a Feature is turned on, we want an up-siren.
168 * When a Feature is turned off, we want a down-siren.
169 * If we cannot do pitch, we want a single beep for on and two
172 case _BEEP_FEATURE_ON:
173 if (name==None) name= featureOn;
174 if (xkbInfo->beepCount<1) {
176 duration= VERY_LONG_TONE;
182 duration= SHORT_TONE;
186 case _BEEP_FEATURE_OFF:
187 if (name==None) name= featureOff;
188 if (xkbInfo->beepCount<1) {
191 duration= VERY_LONG_TONE;
192 else duration= SHORT_TONE;
197 duration= SHORT_TONE;
201 /* Two high beeps indicate an LED or Feature changed
202 * state, but that another LED or Feature is also on.
203 * [[[WDW - This is not in AccessDOS ]]]
205 case _BEEP_LED_CHANGE:
206 if (name==None) name= ledChange;
207 case _BEEP_FEATURE_CHANGE:
208 if (name==None) name= featureChange;
209 duration= SHORT_TONE;
211 if (xkbInfo->beepCount<1) {
216 /* Three high-pitched beeps are the warning that SlowKeys
217 * is going to be turned on or off.
219 case _BEEP_SLOW_WARN:
220 if (name==None) name= slowWarn;
221 duration= SHORT_TONE;
223 if (xkbInfo->beepCount<2)
227 /* Click on SlowKeys press and accept.
228 * Deep pitch when a SlowKey or BounceKey is rejected.
229 * [[[WDW - Rejects are not in AccessDOS ]]]
230 * If we cannot do pitch, we want single beeps.
232 case _BEEP_SLOW_PRESS:
233 if (name==None) name= slowPress;
234 case _BEEP_SLOW_ACCEPT:
235 if (name==None) name= slowAccept;
236 case _BEEP_SLOW_RELEASE:
237 if (name==None) name= slowRelease;
238 duration= CLICK_DURATION;
241 case _BEEP_BOUNCE_REJECT:
242 if (name==None) name= bounceReject;
243 case _BEEP_SLOW_REJECT:
244 if (name==None) name= slowReject;
245 duration= SHORT_TONE;
249 /* Low followed by high pitch when a StickyKey is latched.
250 * High pitch when a StickyKey is locked.
251 * Low pitch when unlocked.
252 * If we cannot do pitch, two beeps for latch, nothing for
253 * lock, and two for unlock.
255 case _BEEP_STICKY_LATCH:
256 if (name==None) name= stickyLatch;
257 duration= SHORT_TONE;
258 if (xkbInfo->beepCount<1) {
262 else pitch= HIGH_PITCH;
264 case _BEEP_STICKY_LOCK:
265 if (name==None) name= stickyLock;
267 duration= SHORT_TONE;
271 case _BEEP_STICKY_UNLOCK:
272 if (name==None) name= stickyUnlock;
273 duration= SHORT_TONE;
275 if (!doesPitch && xkbInfo->beepCount<1)
279 if (timer == NULL && duration>0) {
280 CARD32 starttime = GetTimeInMillis();
283 ctrl->bell_duration= duration;
284 ctrl->bell_pitch= pitch;
285 if (xkbInfo->beepCount==0) {
286 XkbHandleBell(0,0,dev,ctrl->bell,(pointer)ctrl,KbdFeedbackClass,name,None,
289 else if (xkbInfo->desc->ctrls->enabled_ctrls&XkbAudibleBellMask) {
290 (*dev->kbdfeed->BellProc)(ctrl->bell,dev,(pointer)ctrl,KbdFeedbackClass);
292 ctrl->bell_duration= oldDuration;
293 ctrl->bell_pitch= oldPitch;
294 xkbInfo->beepCount++;
296 /* Some DDX schedule the beep and return immediately, others don't
297 return until the beep is completed. We measure the time and if
298 it's less than the beep duration, make sure not to schedule the
299 next beep until after the current one finishes. */
301 elapsedtime = GetTimeInMillis();
302 if (elapsedtime > starttime) { /* watch out for millisecond counter
304 elapsedtime -= starttime;
308 if (elapsedtime < duration) {
309 next += duration - elapsedtime;
317 XkbDDXAccessXBeep(DeviceIntPtr dev,unsigned what,unsigned which)
319 XkbSrvInfoRec *xkbInfo= dev->key->xkbInfo;
322 xkbInfo->beepType= what;
323 xkbInfo->beepCount= 0;
324 next= _XkbDDXBeepExpire(NULL,0,(pointer)dev);
326 xkbInfo->beepTimer= TimerSet(xkbInfo->beepTimer,
328 _XkbDDXBeepExpire, (pointer)dev);