From 912c8b10fd67215dd44db16bd89c3eaab78cb038 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 12 Jan 2010 14:27:35 +1000 Subject: [PATCH] Implement support for keyboard bells. --- src/evdev.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- src/evdev.h | 4 ++++ 2 files changed, 53 insertions(+), 1 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 7e65c69..3cb2107 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -740,6 +740,38 @@ EvdevReadInput(InputInfoPtr pInfo) #define TestBit(bit, array) ((array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS))) static void +EvdevBellProc(int percent, DeviceIntPtr dev, pointer ctrl, int class) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + struct input_event event; + int pitch, duration; + + pitch = ((KeybdCtrl*)ctrl)->bell_pitch; + duration = ((KeybdCtrl*)ctrl)->bell_duration; + + if (TestBit(SND_TONE, pEvdev->snd_bitmask)) + event.code = SND_TONE; + else if (TestBit(SND_BELL, pEvdev->snd_bitmask)) + event.code = SND_BELL; + else + return; + + event.type = EV_SND; + event.value = pitch; + + if (write(pInfo->fd, &event, sizeof event) < 0) + return; + + /* FIXME: this should be a timer for higher duration values */ + usleep(duration); + event.value = 0; + write(pInfo->fd, &event, sizeof event); +} + + + +static void EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl) { /* Nothing to do, dix handles all settings */ @@ -1109,7 +1141,7 @@ EvdevAddKeyClass(DeviceIntPtr device) SetXkbOption(pInfo, "XkbOptions", &pEvdev->rmlvo.options); #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 5 - if (!InitKeyboardDeviceStruct(device, &pEvdev->rmlvo, NULL, EvdevKbdCtrl)) + if (!InitKeyboardDeviceStruct(device, &pEvdev->rmlvo, EvdevBellProc, EvdevKbdCtrl)) return !Success; #else if (!EvdevInitKeysyms(device)) @@ -1602,6 +1634,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare) unsigned long rel_bitmask[NLONGS(REL_CNT)] = {0}; unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0}; unsigned long led_bitmask[NLONGS(LED_CNT)] = {0}; + unsigned long snd_bitmask[NLONGS(SND_CNT)] = {0}; if (ioctl(pInfo->fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) { xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno)); @@ -1672,6 +1705,21 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare) goto error; } + len = ioctl(pInfo->fd, EVIOCGBIT(EV_SND, sizeof(snd_bitmask)), snd_bitmask); + if (len < 0) { + xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", + pInfo->name, strerror(errno)); + goto error; + } + + if (!compare) { + memcpy(pEvdev->snd_bitmask, snd_bitmask, len); + } else if (memcmp(pEvdev->snd_bitmask, snd_bitmask, len)) { + xf86Msg(X_ERROR, "%s: device snd_bitmask has changed\n", pInfo->name); + goto error; + } + + /* * Do not try to validate absinfo data since it is not expected * to be static, always refresh it in evdev structure. diff --git a/src/evdev.h b/src/evdev.h index 95d00db..1d30b84 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -53,6 +53,9 @@ #ifndef LED_CNT #define LED_CNT (LED_MAX+1) #endif +#ifndef SND_CNT +#define SND_CNT (SND_MAX+1) +#endif #define EVDEV_MAXBUTTONS 32 #define EVDEV_MAXQUEUE 32 @@ -170,6 +173,7 @@ typedef struct { unsigned long rel_bitmask[NLONGS(REL_CNT)]; unsigned long abs_bitmask[NLONGS(ABS_CNT)]; unsigned long led_bitmask[NLONGS(LED_CNT)]; + unsigned long snd_bitmask[NLONGS(SND_CNT)]; struct input_absinfo absinfo[ABS_CNT]; /* minor/major number */ -- 1.6.5.2