123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- /************************************************************
- Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ********************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <stdio.h>
- #include <X11/X.h>
- #include <X11/Xproto.h>
- #include <X11/keysym.h>
- #include "inputstr.h"
- #include "scrnintstr.h"
- #include "windowstr.h"
- #include <xkbsrv.h>
- #include <X11/extensions/XI.h>
- /*#define FALLING_TONE 1*/
- /*#define RISING_TONE 1*/
- #define FALLING_TONE 10
- #define RISING_TONE 10
- #define SHORT_TONE 50
- #define SHORT_DELAY 60
- #define LONG_TONE 75
- #define VERY_LONG_TONE 100
- #define LONG_DELAY 85
- #define CLICK_DURATION 1
- #define DEEP_PITCH 250
- #define LOW_PITCH 500
- #define MID_PITCH 1000
- #define HIGH_PITCH 2000
- #define CLICK_PITCH 1500
- static unsigned long atomGeneration = 0;
- static Atom featureOn;
- static Atom featureOff;
- static Atom featureChange;
- static Atom ledOn;
- static Atom ledOff;
- static Atom ledChange;
- static Atom slowWarn;
- static Atom slowPress;
- static Atom slowReject;
- static Atom slowAccept;
- static Atom slowRelease;
- static Atom stickyLatch;
- static Atom stickyLock;
- static Atom stickyUnlock;
- static Atom bounceReject;
- static char doesPitch = 1;
- #define FEATURE_ON "AX_FeatureOn"
- #define FEATURE_OFF "AX_FeatureOff"
- #define FEATURE_CHANGE "AX_FeatureChange"
- #define LED_ON "AX_IndicatorOn"
- #define LED_OFF "AX_IndicatorOff"
- #define LED_CHANGE "AX_IndicatorChange"
- #define SLOW_WARN "AX_SlowKeysWarning"
- #define SLOW_PRESS "AX_SlowKeyPress"
- #define SLOW_REJECT "AX_SlowKeyReject"
- #define SLOW_ACCEPT "AX_SlowKeyAccept"
- #define SLOW_RELEASE "AX_SlowKeyRelease"
- #define STICKY_LATCH "AX_StickyLatch"
- #define STICKY_LOCK "AX_StickyLock"
- #define STICKY_UNLOCK "AX_StickyUnlock"
- #define BOUNCE_REJECT "AX_BounceKeyReject"
- #define MAKE_ATOM(a) MakeAtom(a,sizeof(a)-1,TRUE)
- static void
- _XkbDDXBeepInitAtoms(void)
- {
- featureOn = MAKE_ATOM(FEATURE_ON);
- featureOff = MAKE_ATOM(FEATURE_OFF);
- featureChange = MAKE_ATOM(FEATURE_CHANGE);
- ledOn = MAKE_ATOM(LED_ON);
- ledOff = MAKE_ATOM(LED_OFF);
- ledChange = MAKE_ATOM(LED_CHANGE);
- slowWarn = MAKE_ATOM(SLOW_WARN);
- slowPress = MAKE_ATOM(SLOW_PRESS);
- slowReject = MAKE_ATOM(SLOW_REJECT);
- slowAccept = MAKE_ATOM(SLOW_ACCEPT);
- slowRelease = MAKE_ATOM(SLOW_RELEASE);
- stickyLatch = MAKE_ATOM(STICKY_LATCH);
- stickyLock = MAKE_ATOM(STICKY_LOCK);
- stickyUnlock = MAKE_ATOM(STICKY_UNLOCK);
- bounceReject = MAKE_ATOM(BOUNCE_REJECT);
- return;
- }
- static CARD32
- _XkbDDXBeepExpire(OsTimerPtr timer, CARD32 now, void *arg)
- {
- DeviceIntPtr dev = (DeviceIntPtr) arg;
- KbdFeedbackPtr feed;
- KeybdCtrl *ctrl;
- XkbSrvInfoPtr xkbInfo;
- CARD32 next;
- int pitch, duration;
- int oldPitch, oldDuration;
- Atom name;
- if ((dev == NULL) || (dev->key == NULL) || (dev->key->xkbInfo == NULL) ||
- (dev->kbdfeed == NULL))
- return 0;
- if (atomGeneration != serverGeneration) {
- _XkbDDXBeepInitAtoms();
- atomGeneration = serverGeneration;
- }
- feed = dev->kbdfeed;
- ctrl = &feed->ctrl;
- xkbInfo = dev->key->xkbInfo;
- next = 0;
- pitch = oldPitch = ctrl->bell_pitch;
- duration = oldDuration = ctrl->bell_duration;
- name = None;
- switch (xkbInfo->beepType) {
- default:
- ErrorF("[xkb] Unknown beep type %d\n", xkbInfo->beepType);
- case _BEEP_NONE:
- duration = 0;
- break;
- /* When an LED is turned on, we want a high-pitched beep.
- * When the LED it turned off, we want a low-pitched beep.
- * If we cannot do pitch, we want a single beep for on and two
- * beeps for off.
- */
- case _BEEP_LED_ON:
- if (name == None)
- name = ledOn;
- duration = SHORT_TONE;
- pitch = HIGH_PITCH;
- break;
- case _BEEP_LED_OFF:
- if (name == None)
- name = ledOff;
- duration = SHORT_TONE;
- pitch = LOW_PITCH;
- if (!doesPitch && xkbInfo->beepCount < 1)
- next = SHORT_DELAY;
- break;
- /* When a Feature is turned on, we want an up-siren.
- * When a Feature is turned off, we want a down-siren.
- * If we cannot do pitch, we want a single beep for on and two
- * beeps for off.
- */
- case _BEEP_FEATURE_ON:
- if (name == None)
- name = featureOn;
- if (xkbInfo->beepCount < 1) {
- pitch = LOW_PITCH;
- duration = VERY_LONG_TONE;
- if (doesPitch)
- next = SHORT_DELAY;
- }
- else {
- pitch = MID_PITCH;
- duration = SHORT_TONE;
- }
- break;
- case _BEEP_FEATURE_OFF:
- if (name == None)
- name = featureOff;
- if (xkbInfo->beepCount < 1) {
- pitch = MID_PITCH;
- if (doesPitch)
- duration = VERY_LONG_TONE;
- else
- duration = SHORT_TONE;
- next = SHORT_DELAY;
- }
- else {
- pitch = LOW_PITCH;
- duration = SHORT_TONE;
- }
- break;
- /* Two high beeps indicate an LED or Feature changed
- * state, but that another LED or Feature is also on.
- * [[[WDW - This is not in AccessDOS ]]]
- */
- case _BEEP_LED_CHANGE:
- if (name == None)
- name = ledChange;
- case _BEEP_FEATURE_CHANGE:
- if (name == None)
- name = featureChange;
- duration = SHORT_TONE;
- pitch = HIGH_PITCH;
- if (xkbInfo->beepCount < 1) {
- next = SHORT_DELAY;
- }
- break;
- /* Three high-pitched beeps are the warning that SlowKeys
- * is going to be turned on or off.
- */
- case _BEEP_SLOW_WARN:
- if (name == None)
- name = slowWarn;
- duration = SHORT_TONE;
- pitch = HIGH_PITCH;
- if (xkbInfo->beepCount < 2)
- next = SHORT_DELAY;
- break;
- /* Click on SlowKeys press and accept.
- * Deep pitch when a SlowKey or BounceKey is rejected.
- * [[[WDW - Rejects are not in AccessDOS ]]]
- * If we cannot do pitch, we want single beeps.
- */
- case _BEEP_SLOW_PRESS:
- if (name == None)
- name = slowPress;
- case _BEEP_SLOW_ACCEPT:
- if (name == None)
- name = slowAccept;
- case _BEEP_SLOW_RELEASE:
- if (name == None)
- name = slowRelease;
- duration = CLICK_DURATION;
- pitch = CLICK_PITCH;
- break;
- case _BEEP_BOUNCE_REJECT:
- if (name == None)
- name = bounceReject;
- case _BEEP_SLOW_REJECT:
- if (name == None)
- name = slowReject;
- duration = SHORT_TONE;
- pitch = DEEP_PITCH;
- break;
- /* Low followed by high pitch when a StickyKey is latched.
- * High pitch when a StickyKey is locked.
- * Low pitch when unlocked.
- * If we cannot do pitch, two beeps for latch, nothing for
- * lock, and two for unlock.
- */
- case _BEEP_STICKY_LATCH:
- if (name == None)
- name = stickyLatch;
- duration = SHORT_TONE;
- if (xkbInfo->beepCount < 1) {
- next = SHORT_DELAY;
- pitch = LOW_PITCH;
- }
- else
- pitch = HIGH_PITCH;
- break;
- case _BEEP_STICKY_LOCK:
- if (name == None)
- name = stickyLock;
- if (doesPitch) {
- duration = SHORT_TONE;
- pitch = HIGH_PITCH;
- }
- break;
- case _BEEP_STICKY_UNLOCK:
- if (name == None)
- name = stickyUnlock;
- duration = SHORT_TONE;
- pitch = LOW_PITCH;
- if (!doesPitch && xkbInfo->beepCount < 1)
- next = SHORT_DELAY;
- break;
- }
- if (timer == NULL && duration > 0) {
- CARD32 starttime = GetTimeInMillis();
- CARD32 elapsedtime;
- ctrl->bell_duration = duration;
- ctrl->bell_pitch = pitch;
- if (xkbInfo->beepCount == 0) {
- XkbHandleBell(0, 0, dev, ctrl->bell, (void *) ctrl,
- KbdFeedbackClass, name, None, NULL);
- }
- else if (xkbInfo->desc->ctrls->enabled_ctrls & XkbAudibleBellMask) {
- (*dev->kbdfeed->BellProc) (ctrl->bell, dev, (void *) ctrl,
- KbdFeedbackClass);
- }
- ctrl->bell_duration = oldDuration;
- ctrl->bell_pitch = oldPitch;
- xkbInfo->beepCount++;
- /* Some DDX schedule the beep and return immediately, others don't
- return until the beep is completed. We measure the time and if
- it's less than the beep duration, make sure not to schedule the
- next beep until after the current one finishes. */
- elapsedtime = GetTimeInMillis();
- if (elapsedtime > starttime) { /* watch out for millisecond counter
- overflow! */
- elapsedtime -= starttime;
- }
- else {
- elapsedtime = 0;
- }
- if (elapsedtime < duration) {
- next += duration - elapsedtime;
- }
- }
- return next;
- }
- int
- XkbDDXAccessXBeep(DeviceIntPtr dev, unsigned what, unsigned which)
- {
- XkbSrvInfoRec *xkbInfo = dev->key->xkbInfo;
- CARD32 next;
- xkbInfo->beepType = what;
- xkbInfo->beepCount = 0;
- next = _XkbDDXBeepExpire(NULL, 0, (void *) dev);
- if (next > 0) {
- xkbInfo->beepTimer = TimerSet(xkbInfo->beepTimer,
- 0, next,
- _XkbDDXBeepExpire, (void *) dev);
- }
- return 1;
- }
|