332 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			332 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
/************************************************************
 | 
						|
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,pointer 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,(pointer)ctrl,KbdFeedbackClass,name,None,
 | 
						|
									NULL);
 | 
						|
	}
 | 
						|
	else if (xkbInfo->desc->ctrls->enabled_ctrls&XkbAudibleBellMask) {
 | 
						|
	    (*dev->kbdfeed->BellProc)(ctrl->bell,dev,(pointer)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,(pointer)dev);
 | 
						|
    if (next>0) {
 | 
						|
	xkbInfo->beepTimer= TimerSet(xkbInfo->beepTimer,
 | 
						|
					0, next,
 | 
						|
					_XkbDDXBeepExpire, (pointer)dev);
 | 
						|
    }
 | 
						|
    return 1;
 | 
						|
}
 |