Add penmount touchscreen configuration file
[profile/ivi/xorg-x11-server.git] / xkb / ddxBeep.c
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
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.
15
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.
24
25 ********************************************************/
26
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <X11/X.h>
33 #include <X11/Xproto.h>
34 #include <X11/keysym.h>
35 #include "inputstr.h"
36 #include "scrnintstr.h"
37 #include "windowstr.h"
38 #include <xkbsrv.h>
39 #include <X11/extensions/XI.h>
40
41 /*#define FALLING_TONE  1*/
42 /*#define RISING_TONE   1*/
43 #define FALLING_TONE    10
44 #define RISING_TONE     10
45 #define SHORT_TONE      50
46 #define SHORT_DELAY     60
47 #define LONG_TONE       75
48 #define VERY_LONG_TONE  100
49 #define LONG_DELAY      85
50 #define CLICK_DURATION  1
51
52 #define DEEP_PITCH      250
53 #define LOW_PITCH       500
54 #define MID_PITCH       1000
55 #define HIGH_PITCH      2000
56 #define CLICK_PITCH     1500
57
58 static  unsigned long   atomGeneration= 0;
59 static  Atom    featureOn;
60 static  Atom    featureOff;
61 static  Atom    featureChange;
62 static  Atom    ledOn;
63 static  Atom    ledOff;
64 static  Atom    ledChange;
65 static  Atom    slowWarn;
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;
75
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"
91
92 #define MAKE_ATOM(a)    MakeAtom(a,sizeof(a)-1,TRUE)
93
94 static void
95 _XkbDDXBeepInitAtoms(void)
96 {
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);
112     return;
113 }
114
115 static CARD32
116 _XkbDDXBeepExpire(OsTimerPtr timer,CARD32 now,pointer arg)
117 {
118 DeviceIntPtr    dev= (DeviceIntPtr)arg;
119 KbdFeedbackPtr  feed;
120 KeybdCtrl *     ctrl;
121 XkbSrvInfoPtr   xkbInfo;
122 CARD32          next;
123 int             pitch,duration;
124 int             oldPitch,oldDuration;
125 Atom            name;
126
127     if ((dev==NULL)||(dev->key==NULL)||(dev->key->xkbInfo==NULL)||
128         (dev->kbdfeed==NULL))
129         return 0;
130     if (atomGeneration!=serverGeneration) {
131         _XkbDDXBeepInitAtoms();
132         atomGeneration= serverGeneration;
133     }
134
135     feed= dev->kbdfeed;
136     ctrl= &feed->ctrl;
137     xkbInfo= dev->key->xkbInfo;
138     next= 0;
139     pitch= oldPitch= ctrl->bell_pitch;
140     duration= oldDuration= ctrl->bell_duration;
141     name= None;
142     switch (xkbInfo->beepType) {
143         default:
144             ErrorF("[xkb] Unknown beep type %d\n",xkbInfo->beepType);
145         case _BEEP_NONE:
146             duration= 0;
147             break;
148
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
152          * beeps for off.
153          */
154         case _BEEP_LED_ON:
155             if (name==None)     name= ledOn;
156             duration= SHORT_TONE;
157             pitch= HIGH_PITCH;
158             break;
159         case _BEEP_LED_OFF:
160             if (name==None)     name= ledOff;
161             duration= SHORT_TONE;
162             pitch= LOW_PITCH;
163             if (!doesPitch && xkbInfo->beepCount<1)
164                 next = SHORT_DELAY;         
165             break;
166
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
170          * beeps for off.
171          */
172         case _BEEP_FEATURE_ON:
173             if (name==None)     name= featureOn;
174             if (xkbInfo->beepCount<1) {
175                 pitch= LOW_PITCH;
176                 duration= VERY_LONG_TONE;
177                 if (doesPitch)
178                     next= SHORT_DELAY;
179             }
180             else {
181                 pitch= MID_PITCH;
182                 duration= SHORT_TONE;
183             }
184             break;
185
186         case _BEEP_FEATURE_OFF:
187             if (name==None)     name= featureOff;
188             if (xkbInfo->beepCount<1) {
189                 pitch= MID_PITCH;
190                 if (doesPitch)
191                      duration= VERY_LONG_TONE;
192                 else duration= SHORT_TONE;
193                 next= SHORT_DELAY;
194             }
195             else {
196                 pitch= LOW_PITCH;
197                 duration= SHORT_TONE;
198             }
199             break;
200
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 ]]]
204          */
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;
210             pitch= HIGH_PITCH;
211             if (xkbInfo->beepCount<1) {
212                 next= SHORT_DELAY;
213             }
214             break;
215
216         /* Three high-pitched beeps are the warning that SlowKeys
217          * is going to be turned on or off.
218          */       
219         case _BEEP_SLOW_WARN:
220             if (name==None)     name= slowWarn;
221             duration= SHORT_TONE;
222             pitch= HIGH_PITCH;
223             if (xkbInfo->beepCount<2)
224                 next= SHORT_DELAY;
225             break;
226
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.
231          */       
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;
239             pitch= CLICK_PITCH;
240             break;
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;
246             pitch= DEEP_PITCH;
247             break;
248
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.
254          */       
255         case _BEEP_STICKY_LATCH:
256             if (name==None)     name= stickyLatch;
257             duration= SHORT_TONE;
258             if (xkbInfo->beepCount<1) {
259                 next= SHORT_DELAY;
260                 pitch= LOW_PITCH;
261             }
262             else pitch= HIGH_PITCH;
263             break;
264         case _BEEP_STICKY_LOCK:
265             if (name==None)     name= stickyLock;
266             if (doesPitch) {
267                 duration= SHORT_TONE;
268                 pitch= HIGH_PITCH;
269             }
270             break;
271         case _BEEP_STICKY_UNLOCK:
272             if (name==None)     name= stickyUnlock;
273             duration= SHORT_TONE;
274             pitch= LOW_PITCH;
275             if (!doesPitch && xkbInfo->beepCount<1)
276                 next = SHORT_DELAY;         
277             break;
278     }
279     if (timer == NULL && duration>0) {
280         CARD32          starttime = GetTimeInMillis();
281         CARD32          elapsedtime;
282
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,
287                                                                         NULL);
288         }
289         else if (xkbInfo->desc->ctrls->enabled_ctrls&XkbAudibleBellMask) {
290             (*dev->kbdfeed->BellProc)(ctrl->bell,dev,(pointer)ctrl,KbdFeedbackClass);
291         }
292         ctrl->bell_duration= oldDuration;
293         ctrl->bell_pitch= oldPitch;
294         xkbInfo->beepCount++;
295
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. */
300
301         elapsedtime = GetTimeInMillis();
302         if (elapsedtime > starttime) { /* watch out for millisecond counter
303                                           overflow! */
304             elapsedtime -= starttime;
305         } else {
306             elapsedtime = 0;
307         }
308         if (elapsedtime < duration) {
309             next += duration - elapsedtime;
310         }
311
312     }
313     return next;
314 }
315
316 int
317 XkbDDXAccessXBeep(DeviceIntPtr dev,unsigned what,unsigned which)
318 {
319 XkbSrvInfoRec   *xkbInfo= dev->key->xkbInfo;
320 CARD32           next;
321
322     xkbInfo->beepType= what;
323     xkbInfo->beepCount= 0;
324     next= _XkbDDXBeepExpire(NULL,0,(pointer)dev);
325     if (next>0) {
326         xkbInfo->beepTimer= TimerSet(xkbInfo->beepTimer,
327                                         0, next,
328                                         _XkbDDXBeepExpire, (pointer)dev);
329     }
330     return 1;
331 }