371 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			371 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
| /* $Xorg: ddxBeep.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */
 | |
| /************************************************************
 | |
| 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.
 | |
| 
 | |
| ********************************************************/
 | |
| /* $XFree86: xc/programs/Xserver/xkb/ddxBeep.c,v 3.9 2002/12/05 21:59:00 paulo Exp $ */
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include <stdio.h>
 | |
| #define	NEED_EVENTS 1
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xproto.h>
 | |
| #include <X11/keysym.h>
 | |
| #include "inputstr.h"
 | |
| #include "scrnintstr.h"
 | |
| #include "windowstr.h"
 | |
| #include <X11/extensions/XKBsrv.h>
 | |
| #include <X11/extensions/XI.h>
 | |
| 
 | |
| #if (defined(__osf__) && defined(__alpha))
 | |
| #include <sys/sysinfo.h>
 | |
| #include <alpha/hal_sysinfo.h>
 | |
| #include <alpha/prom.h>
 | |
| #endif
 | |
| 
 | |
| /*#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);
 | |
| #if (defined(__osf__) && defined(__alpha))
 | |
|     /* [[[ WDW - Some bells do not allow for pitch changes.
 | |
|      * Maybe this could become part of the keymap? ]]]
 | |
|      */
 | |
|     {
 | |
| 	char keyboard[8];
 | |
| 
 | |
| 	/* Find the class of keyboard being used.
 | |
| 	 */
 | |
| 	keyboard[0] = '\0';
 | |
| 	if (-1 == getsysinfo(GSI_KEYBOARD, 
 | |
| 			     keyboard, sizeof(keyboard), 
 | |
| 			     0, NULL))
 | |
| 	    keyboard[0] = '\0';
 | |
| 
 | |
| 	if ((strcmp(keyboard,"LK201") == 0) ||
 | |
| 	    (strcmp(keyboard,"LK401") == 0) ||
 | |
| 	    (strcmp(keyboard,"LK421") == 0) ||
 | |
| 	    (strcmp(keyboard,"LK443") == 0))
 | |
| 	    doesPitch = 0;
 | |
|     }
 | |
| #else
 | |
| #if defined(sun)
 | |
|     doesPitch = 0;
 | |
| #endif
 | |
| #endif
 | |
|     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;
 | |
| #ifdef DEBUG
 | |
|     if (xkbDebugFlags>1)
 | |
| 	ErrorF("beep: %d (count= %d)\n",xkbInfo->beepType,xkbInfo->beepCount);
 | |
| #endif
 | |
|     name= None;
 | |
|     switch (xkbInfo->beepType) {
 | |
| 	default:
 | |
| 	    ErrorF("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;
 | |
| }
 |