summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2006-11-01 23:10:26 +0200
committerDaniel Stone <daniels@endtroducing.fooishbar.org>2006-11-01 23:10:26 +0200
commit81728558a044fdde0e1d63da7b6314755f77296e (patch)
tree94e8bb0559aee194216164ee10b09446ca1570a0
parent3df454719f9cbf6a046cb7458019ec621b3b42ee (diff)
input: add non-keyboard bell ringing function
Add a generic 'ring the bell' function (console bell on Linux and BSD, /dev/audio on Solaris), and add DDX functions for this. Make this the core keyboard's bell. Port Xvfb and Xnest to this. Port XFree86 to this, with OS-specific hooks for Linux, BSD, and Solaris taken from foo_io.c in the old layer.
-rw-r--r--dix/devices.c6
-rw-r--r--hw/vfb/InitInput.c4
-rw-r--r--hw/xfree86/common/xf86Events.c5
-rw-r--r--hw/xfree86/os-support/bsd/Makefile.am1
-rw-r--r--hw/xfree86/os-support/bsd/bsd_bell.c81
-rw-r--r--hw/xfree86/os-support/linux/Makefile.am2
-rw-r--r--hw/xfree86/os-support/linux/lnx_bell.c43
-rw-r--r--hw/xfree86/os-support/solaris/Makefile.am2
-rw-r--r--hw/xfree86/os-support/solaris/sun_bell.c184
-rw-r--r--hw/xfree86/os-support/xf86_OSproc.h1
-rw-r--r--hw/xnest/Keyboard.c6
-rw-r--r--include/input.h6
12 files changed, 335 insertions, 6 deletions
diff --git a/dix/devices.c b/dix/devices.c
index a554f2f79..aa0486219 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -211,9 +211,11 @@ ActivateDevice(DeviceIntPtr dev)
}
static void
-CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer ctrl, int something)
+CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
{
- return;
+ KeybdCtrl *ctrl = arg;
+
+ DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
}
static void
diff --git a/hw/vfb/InitInput.c b/hw/vfb/InitInput.c
index 9cb1c02cb..99cf56c70 100644
--- a/hw/vfb/InitInput.c
+++ b/hw/vfb/InitInput.c
@@ -55,6 +55,10 @@ ProcessInputEvents()
miPointerUpdate();
}
+void DDXRingBell(int volume, int pitch, int duration)
+{
+}
+
#define VFB_MIN_KEY 8
#define VFB_MAX_KEY 255
KeySym map[MAP_LENGTH * LK201_GLYPHS_PER_KEY];
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 3df201aa7..4a9f36926 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -1128,6 +1128,11 @@ xf86ReloadInputDevs(int sig)
return;
}
+_X_EXPORT void
+DDXRingBell(int volume, int pitch, int duration) {
+ xf86OSRingBell(volume, pitch, duration);
+}
+
#ifdef WSCONS_SUPPORT
/* XXX Currently XKB is mandatory. */
diff --git a/hw/xfree86/os-support/bsd/Makefile.am b/hw/xfree86/os-support/bsd/Makefile.am
index 0a0bcab3e..e456328df 100644
--- a/hw/xfree86/os-support/bsd/Makefile.am
+++ b/hw/xfree86/os-support/bsd/Makefile.am
@@ -63,6 +63,7 @@ libbsd_la_SOURCES = \
bsd_VTsw.c \
bsd_init.c \
bsd_mouse.c \
+ bsd_bell.c \
$(ARCH_SOURCES) \
$(AGP_SOURCES) \
$(APM_SOURCES) \
diff --git a/hw/xfree86/os-support/bsd/bsd_bell.c b/hw/xfree86/os-support/bsd/bsd_bell.c
new file mode 100644
index 000000000..60c2ffc8b
--- /dev/null
+++ b/hw/xfree86/os-support/bsd/bsd_bell.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Rich Murphey and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Dawes make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID DAWES 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_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <termios.h>
+
+#include "xf86.h"
+#include "xf86Priv.h"
+
+#ifdef WSCONS_SUPPORT
+#define KBD_FD(i) ((i).kbdFd != -1 ? (i).kbdFd : (i).consoleFd)
+#endif
+
+_X_EXPORT void
+xf86OSRingBell(int loudness, int pitch, int duration)
+{
+#ifdef WSCONS_SUPPORT
+ struct wskbd_bell_data wsb;
+#endif
+
+ if (loudness && pitch)
+ {
+#ifdef PCCONS_SUPPORT
+ int data[2];
+#endif
+
+ switch (xf86Info.consType) {
+
+#ifdef PCCONS_SUPPORT
+ case PCCONS:
+ data[0] = pitch;
+ data[1] = (duration * loudness) / 50;
+ ioctl(xf86Info.consoleFd, CONSOLE_X_BELL, data);
+ break;
+#endif
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration*loudness/50)<<16));
+ break;
+#endif
+#if defined (WSCONS_SUPPORT)
+ case WSCONS:
+ wsb.which = WSKBD_BELL_DOALL;
+ wsb.pitch = pitch;
+ wsb.period = duration;
+ wsb.volume = loudness;
+ ioctl(KBD_FD(xf86Info), WSKBDIO_COMPLEXBELL,
+ &wsb);
+ break;
+#endif
+ }
+ }
+}
diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am
index fc4243b26..673a4e128 100644
--- a/hw/xfree86/os-support/linux/Makefile.am
+++ b/hw/xfree86/os-support/linux/Makefile.am
@@ -20,7 +20,7 @@ XORG_CFLAGS += -DHAVE_APM
endif
liblinux_la_SOURCES = lnx_init.c lnx_video.c lnx_mouse.c \
- lnx_pci.c lnx_agp.c lnx_kmod.c \
+ lnx_pci.c lnx_agp.c lnx_kmod.c lnx_bell.c \
$(srcdir)/../shared/bios_mmap.c \
$(srcdir)/../shared/VTsw_usl.c \
$(srcdir)/../shared/posix_tty.c \
diff --git a/hw/xfree86/os-support/linux/lnx_bell.c b/hw/xfree86/os-support/linux/lnx_bell.c
new file mode 100644
index 000000000..6ef881bf7
--- /dev/null
+++ b/hw/xfree86/os-support/linux/lnx_bell.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2006 Daniel Stone
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that this copyright notice and this permission notice appear in
+ * supporting electronic documentation.
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR AUTHORS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <sys/ioctl.h>
+#include <linux/kd.h>
+
+#include "xf86.h"
+#include "xf86Priv.h"
+
+_X_EXPORT void
+xf86OSRingBell(int loudness, int pitch, int duration)
+{
+ if (xf86Info.consoleFd == -1 || !pitch || !loudness)
+ return;
+
+ ioctl(xf86Info.consoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration * loudness / 50) << 16));
+}
diff --git a/hw/xfree86/os-support/solaris/Makefile.am b/hw/xfree86/os-support/solaris/Makefile.am
index 9c8607918..291c329ea 100644
--- a/hw/xfree86/os-support/solaris/Makefile.am
+++ b/hw/xfree86/os-support/solaris/Makefile.am
@@ -19,7 +19,7 @@ solaris-$(SOLARIS_INOUT_ARCH).il: solaris-${SOLARIS_INOUT_ARCH}.S
noinst_LTLIBRARIES = libsolaris.la
libsolaris_la_SOURCES = sun_bios.c sun_init.c \
- sun_mouse.c sun_vid.c $(AGP_SRC) \
+ sun_mouse.c sun_vid.c sun_bell.c $(AGP_SRC) \
$(srcdir)/../shared/libc_wrapper.c \
$(srcdir)/../shared/kmod_noop.c $(srcdir)/../shared/pm_noop.c \
$(srcdir)/../shared/posix_tty.c $(srcdir)/../shared/sigiostubs.c \
diff --git a/hw/xfree86/os-support/solaris/sun_bell.c b/hw/xfree86/os-support/solaris/sun_bell.c
new file mode 100644
index 000000000..369103f7b
--- /dev/null
+++ b/hw/xfree86/os-support/solaris/sun_bell.c
@@ -0,0 +1,184 @@
+/* Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <sys/audio.h>
+#include <sys/uio.h>
+#include <limits.h>
+#include <math.h>
+#include <poll.h>
+
+#include "xf86.h"
+#include "xf86Priv.h"
+
+#define BELL_RATE 48000 /* Samples per second */
+#define BELL_HZ 50 /* Fraction of a second i.e. 1/x */
+#define BELL_MS (1000/BELL_HZ) /* MS */
+#define BELL_SAMPLES (BELL_RATE / BELL_HZ)
+#define BELL_MIN 3 /* Min # of repeats */
+
+#define AUDIO_DEVICE "/dev/audio"
+
+_X_EXPORT int
+xf86OSRingBell(int loudness, int pitch, int duration)
+{
+ static short samples[BELL_SAMPLES];
+ static short silence[BELL_SAMPLES]; /* "The Sound of Silence" */
+ static int lastFreq;
+ int cnt;
+ int i;
+ int written;
+ int repeats;
+ int freq;
+ audio_info_t audioInfo;
+ struct iovec iov[IOV_MAX];
+ int iovcnt;
+ double ampl, cyclen, phase;
+ int audioFD;
+
+ if ((loudness <= 0) || (pitch <= 0) || (duration <= 0)) {
+ return 0;
+ }
+
+ lastFreq = 0;
+ bzero(silence, sizeof(silence));
+
+ audioFD = open(AUDIO_DEVICE, O_WRONLY | O_NONBLOCK);
+ if (audioFD == -1) {
+ xf86Msg(X_ERROR, "Bell: cannot open audio device \"%s\": %s\n",
+ AUDIO_DEVICE, strerror(errno));
+ return -1;
+ }
+
+ freq = pitch;
+ freq = min(freq, (BELL_RATE / 2) - 1);
+ freq = max(freq, 2 * BELL_HZ);
+
+ /*
+ * Ensure full waves per buffer
+ */
+ freq -= freq % BELL_HZ;
+
+ if (freq != lastFreq) {
+ lastFreq = freq;
+ ampl = 16384.0;
+
+ cyclen = (double) freq / (double) BELL_RATE;
+ phase = 0.0;
+
+ for (i = 0; i < BELL_SAMPLES; i++) {
+ samples[i] = (short) (ampl * sin(2.0 * M_PI * phase));
+ phase += cyclen;
+ if (phase >= 1.0)
+ phase -= 1.0;
+ }
+ }
+
+ repeats = (duration + (BELL_MS / 2)) / BELL_MS;
+ repeats = max(repeats, BELL_MIN);
+
+ loudness = max(0, loudness);
+ loudness = min(loudness, 100);
+
+#ifdef DEBUG
+ ErrorF("BELL : freq %d volume %d duration %d repeats %d\n",
+ freq, loudness, duration, repeats);
+#endif
+
+ AUDIO_INITINFO(&audioInfo);
+ audioInfo.play.encoding = AUDIO_ENCODING_LINEAR;
+ audioInfo.play.sample_rate = BELL_RATE;
+ audioInfo.play.channels = 2;
+ audioInfo.play.precision = 16;
+ audioInfo.play.gain = min(AUDIO_MAX_GAIN, AUDIO_MAX_GAIN * loudness / 100);
+
+ if (ioctl(audioFD, AUDIO_SETINFO, &audioInfo) < 0){
+ xf86Msg(X_ERROR,
+ "Bell: AUDIO_SETINFO failed on audio device \"%s\": %s\n",
+ AUDIO_DEVICE, strerror(errno));
+ close(audioFD);
+ return -1;
+ }
+
+ iovcnt = 0;
+
+ for (cnt = 0; cnt <= repeats; cnt++) {
+ iov[iovcnt].iov_base = (char *) samples;
+ iov[iovcnt++].iov_len = sizeof(samples);
+ if (cnt == repeats) {
+ /* Insert a bit of silence so that multiple beeps are distinct and
+ * not compressed into a single tone.
+ */
+ iov[iovcnt].iov_base = (char *) silence;
+ iov[iovcnt++].iov_len = sizeof(silence);
+ }
+ if ((iovcnt >= IOV_MAX) || (cnt == repeats)) {
+ written = writev(audioFD, iov, iovcnt);
+
+ if ((written < ((int)(sizeof(samples) * iovcnt)))) {
+ /* audio buffer was full! */
+
+ int naptime;
+
+ if (written == -1) {
+ if (errno != EAGAIN) {
+ xf86Msg(X_ERROR,
+ "Bell: writev failed on audio device \"%s\": %s\n",
+ AUDIO_DEVICE, strerror(errno));
+ close(audioFD);
+ return -1;
+ }
+ i = iovcnt;
+ } else {
+ i = ((sizeof(samples) * iovcnt) - written)
+ / sizeof(samples);
+ }
+ cnt -= i;
+
+ /* sleep a little to allow audio buffer to drain */
+ naptime = BELL_MS * i;
+ poll(NULL, 0, naptime);
+
+ i = ((sizeof(samples) * iovcnt) - written) % sizeof(samples);
+ iovcnt = 0;
+ if ((written != -1) && (i > 0)) {
+ iov[iovcnt].iov_base = ((char *) samples) + i;
+ iov[iovcnt++].iov_len = sizeof(samples) - i;
+ }
+ } else {
+ iovcnt = 0;
+ }
+ }
+ }
+
+ close(audioFD);
+ return 0;
+}
diff --git a/hw/xfree86/os-support/xf86_OSproc.h b/hw/xfree86/os-support/xf86_OSproc.h
index c987d755a..0311b8193 100644
--- a/hw/xfree86/os-support/xf86_OSproc.h
+++ b/hw/xfree86/os-support/xf86_OSproc.h
@@ -174,6 +174,7 @@ extern int xf86GetSerialModemState(int fd);
extern int xf86SerialModemSetBits(int fd, int bits);
extern int xf86SerialModemClearBits(int fd, int bits);
extern int xf86LoadKernelModule(const char *pathname);
+extern void xf86RingBell(int volume, int pitch, int duration);
/* AGP GART interface */
diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index 26a5ed3fb..0dacae70b 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -94,6 +94,12 @@ xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
}
void
+DDXRingBell(int volume, int pitch, int duration)
+{
+ XBell(xnestDisplay, volume);
+}
+
+void
xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
{
#if 0
diff --git a/include/input.h b/include/input.h
index 3fe694474..f2fe6d137 100644
--- a/include/input.h
+++ b/include/input.h
@@ -441,7 +441,9 @@ extern DeviceIntPtr LookupDeviceIntRec(
extern int NewInputDeviceRequest(
InputOption *options);
-extern DeviceIntPtr LookupDeviceIntRec(
- CARD8 deviceid);
+extern void DDXRingBell(
+ int volume,
+ int pitch,
+ int duration);
#endif /* INPUT_H */