diff options
Diffstat (limited to 'hw/xfree86/os-support/solaris/sun_kbd.c')
-rw-r--r-- | hw/xfree86/os-support/solaris/sun_kbd.c | 660 |
1 files changed, 0 insertions, 660 deletions
diff --git a/hw/xfree86/os-support/solaris/sun_kbd.c b/hw/xfree86/os-support/solaris/sun_kbd.c deleted file mode 100644 index 2cb1d13a8..000000000 --- a/hw/xfree86/os-support/solaris/sun_kbd.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany - * Copyright 1993 by David Dawes <dawes@XFree86.org> - * Copyright 1999 by David Holland <davidh@iquest.net) - * - * 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 Thomas Roell, David Dawes, and David Holland not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Thomas Roell, David Dawes, and - * David Holland make no representations about the suitability of this software - * for any purpose. It is provided "as is" without express or implied - * warranty. - * - * THOMAS ROELL, DAVID DAWES, AND DAVID HOLLAND DISCLAIM ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THOMAS ROELL, DAVID DAWES, OR DAVID HOLLAND - * 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. - */ -/* 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 "xf86.h" -#include "xf86Priv.h" -#include "xf86_OSlib.h" -#include "xf86OSKbd.h" -#include "sun_kbd.h" - -/* Define to provide support for using /dev/audio to ring the bell instead of - the keyboard beeper */ -#define AUDIO_BELL - -#ifdef AUDIO_BELL -#include <sys/audio.h> -#include <sys/uio.h> -#include <limits.h> -#include <math.h> -#include <poll.h> -#endif - -/*************************************************************************** - * Common implementation of routines shared by "keyboard" driver in sun_io.c - * and "kbd" driver (later on in this file) - */ - -#include <sys/stropts.h> -#include <sys/vuid_event.h> -#include <sys/kbd.h> - -_X_HIDDEN int -sunKbdOpen(const char *devName, pointer options) -{ - int kbdFD; - const char *kbdPath = NULL; - const char *defaultKbd = "/dev/kbd"; - - if (options != NULL) { - kbdPath = xf86SetStrOption(options, "Device", NULL); - } - if (kbdPath == NULL) { - kbdPath = defaultKbd; - } - - kbdFD = open(kbdPath, O_RDONLY | O_NONBLOCK); - - if (kbdFD == -1) { - xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", devName, kbdPath); - } else { - xf86MsgVerb(X_INFO, 3, "%s: Opened device \"%s\"\n", devName, kbdPath); - } - - if ((kbdPath != NULL) && (kbdPath != defaultKbd)) { - xfree(kbdPath); - } - return kbdFD; -} - - -/* - * Save initial keyboard state. This is called at the start of each server - * generation. - */ - -_X_HIDDEN int -sunKbdInit(sunKbdPrivPtr priv, int kbdFD, const char *devName, pointer options) -{ - int ktype, klayout, i; - const char *ktype_name; - - priv->kbdFD = kbdFD; - priv->devName = devName; - priv->otranslation = -1; - priv->odirect = -1; - - if (options != NULL) { - priv->strmod = xf86SetStrOption(options, "StreamsModule", NULL); - priv->audioDevName = xf86SetStrOption(options, "BellDevice", NULL); - - if (priv->audioDevName && (priv->audioDevName[0] == '\0')) { - xfree(priv->audioDevName); - priv->audioDevName = NULL; - } - } else { - priv->strmod = NULL; - priv->audioDevName = NULL; - } - - if (priv->strmod) { - SYSCALL(i = ioctl(priv->kbdFD, I_PUSH, priv->strmod)); - if (i < 0) { - xf86Msg(X_ERROR, - "%s: cannot push module '%s' onto keyboard device: %s\n", - priv->devName, priv->strmod, strerror(errno)); - } - } - - SYSCALL(i = ioctl(kbdFD, KIOCTYPE, &ktype)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Unable to determine keyboard type: %s\n", - devName, strerror(errno)); - return BadImplementation; - } - - SYSCALL(i = ioctl(kbdFD, KIOCLAYOUT, &klayout)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Unable to determine keyboard layout: %s\n", - devName, strerror(errno)); - return BadImplementation; - } - - switch (ktype) { - case KB_SUN3: - ktype_name = "Sun Type 3"; break; - case KB_SUN4: - ktype_name = "Sun Type 4/5/6"; break; - case KB_USB: - ktype_name = "USB"; break; - case KB_PC: - ktype_name = "PC"; break; - default: - ktype_name = "Unknown"; break; - } - - xf86Msg(X_PROBED, "%s: Keyboard type: %s (%d)\n", - devName, ktype_name, ktype); - xf86Msg(X_PROBED, "%s: Keyboard layout: %d\n", devName, klayout); - - priv->ktype = ktype; - priv->keyMap = sunGetKbdMapping(ktype); - priv->audioState = AB_INITIALIZING; - priv->oleds = sunKbdGetLeds(priv); - - return Success; -} - -_X_HIDDEN int -sunKbdOn(sunKbdPrivPtr priv) -{ - int ktrans, kdirect, i; - - SYSCALL(i = ioctl(priv->kbdFD, KIOCGDIRECT, &kdirect)); - if (i < 0) { - xf86Msg(X_ERROR, - "%s: Unable to determine keyboard direct setting: %s\n", - priv->devName, strerror(errno)); - return BadImplementation; - } - - priv->odirect = kdirect; - kdirect = 1; - - SYSCALL(i = ioctl(priv->kbdFD, KIOCSDIRECT, &kdirect)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Failed turning keyboard direct mode on: %s\n", - priv->devName, strerror(errno)); - return BadImplementation; - } - - /* Setup translation */ - - SYSCALL(i = ioctl(priv->kbdFD, KIOCGTRANS, &ktrans)); - if (i < 0) { - xf86Msg(X_ERROR, - "%s: Unable to determine keyboard translation mode: %s\n", - priv->devName, strerror(errno)); - return BadImplementation; - } - - priv->otranslation = ktrans; - ktrans = TR_UNTRANS_EVENT; - - SYSCALL(i = ioctl(priv->kbdFD, KIOCTRANS, &ktrans)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Failed setting keyboard translation mode: %s\n", - priv->devName, strerror(errno)); - return BadImplementation; - } - - return Success; -} - -_X_HIDDEN int -sunKbdOff(sunKbdPrivPtr priv) -{ - int i; - - /* restore original state */ - - sunKbdSetLeds(priv, priv->oleds); - - if (priv->otranslation != -1) { - SYSCALL(i = ioctl(priv->kbdFD, KIOCTRANS, &priv->otranslation)); - if (i < 0) { - xf86Msg(X_ERROR, - "%s: Unable to restore keyboard translation mode: %s\n", - priv->devName, strerror(errno)); - return BadImplementation; - } - priv->otranslation = -1; - } - - if (priv->odirect != -1) { - SYSCALL(i = ioctl(priv->kbdFD, KIOCSDIRECT, &priv->odirect)); - if (i < 0) { - xf86Msg(X_ERROR, - "%s: Unable to restore keyboard direct setting: %s\n", - priv->devName, strerror(errno)); - return BadImplementation; - } - priv->odirect = -1; - } - - if (priv->strmod) { - SYSCALL(i = ioctl(priv->kbdFD, I_POP, priv->strmod)); - if (i < 0) { - xf86Msg(X_WARNING, - "%s: cannot pop module '%s' off keyboard device: %s\n", - priv->devName, priv->strmod, strerror(errno)); - } - } - - return Success; -} - -#ifdef AUDIO_BELL - -/* Helper function to ring bell via audio device instead of keyboard beeper */ - -#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 */ - -static int -sunKbdAudioBell(sunKbdPrivPtr priv, 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; - } - - if ((priv == NULL) || (priv->audioDevName == NULL)) { - return -1; - } - - if (priv->audioState == AB_INITIALIZING) { - priv->audioState = AB_NORMAL; - lastFreq = 0; - bzero(silence, sizeof(silence)); - } - - audioFD = open(priv->audioDevName, O_WRONLY | O_NONBLOCK); - if (audioFD == -1) { - xf86Msg(X_ERROR, "%s: cannot open audio device \"%s\": %s\n", - priv->devName, priv->audioDevName, 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, - "%s: AUDIO_SETINFO failed on audio device \"%s\": %s\n", - priv->devName, priv->audioDevName, 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, - "%s: writev failed on audio device \"%s\": %s\n", - priv->devName, priv->audioDevName, - 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; -} - -#endif /* AUDIO_BELL */ - -_X_HIDDEN void -sunKbdSoundBell(sunKbdPrivPtr priv, int loudness, int pitch, int duration) -{ - int kbdCmd, i; - - if (loudness && pitch) - { -#ifdef AUDIO_BELL - if (priv->audioDevName != NULL) { - if (sunKbdAudioBell(priv, loudness, pitch, duration) == 0) { - return; - } - } -#endif - - kbdCmd = KBD_CMD_BELL; - - SYSCALL(i = ioctl (priv->kbdFD, KIOCCMD, &kbdCmd)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Failed to activate bell: %s\n", - priv->devName, strerror(errno)); - } - - usleep(duration * loudness * 20); - - kbdCmd = KBD_CMD_NOBELL; - SYSCALL(i = ioctl (priv->kbdFD, KIOCCMD, &kbdCmd)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Failed to deactivate bell: %s\n", - priv->devName, strerror(errno)); - } - } -} - -_X_HIDDEN void -sunKbdSetLeds(sunKbdPrivPtr priv, int leds) -{ - int i; - - SYSCALL(i = ioctl(priv->kbdFD, KIOCSLED, &leds)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Failed to set keyboard LED's: %s\n", - priv->devName, strerror(errno)); - } -} - -_X_HIDDEN int -sunKbdGetLeds(sunKbdPrivPtr priv) -{ - int i, leds = 0; - - SYSCALL(i = ioctl(priv->kbdFD, KIOCGLED, &leds)); - if (i < 0) { - xf86Msg(X_ERROR, "%s: Failed to get keyboard LED's: %s\n", - priv->devName, strerror(errno)); - } - return leds; -} - -/* ARGSUSED0 */ -_X_HIDDEN void -sunKbdSetRepeat(sunKbdPrivPtr priv, char rad) -{ - /* Nothing to do */ -} - -/*************************************************************************** - * Routines called from "kbd" driver via proc vectors filled in by - * xf86OSKbdPreInit(). - */ - - -static int -KbdInit(InputInfoPtr pInfo, int what) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - - return sunKbdInit(priv, pInfo->fd, pInfo->name, pInfo->options); -} - - -static int -KbdOn(InputInfoPtr pInfo, int what) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - - return sunKbdOn(priv); -} - -static int -KbdOff(InputInfoPtr pInfo, int what) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - - return sunKbdOff(priv); -} - - -static void -SoundKbdBell(InputInfoPtr pInfo, int loudness, int pitch, int duration) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - - sunKbdSoundBell(priv, loudness, pitch, duration); -} - -static void -SetKbdLeds(InputInfoPtr pInfo, int leds) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - int real_leds = sunKbdGetLeds(priv); - - real_leds &= ~(LED_CAPS_LOCK | LED_NUM_LOCK | LED_SCROLL_LOCK | LED_COMPOSE); - - if (leds & XLED1) real_leds |= LED_CAPS_LOCK; - if (leds & XLED2) real_leds |= LED_NUM_LOCK; - if (leds & XLED3) real_leds |= LED_SCROLL_LOCK; - if (leds & XLED4) real_leds |= LED_COMPOSE; - - sunKbdSetLeds(priv, real_leds); -} - -static int -GetKbdLeds(InputInfoPtr pInfo) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - int leds = 0; - int real_leds = sunKbdGetLeds(priv); - - if (real_leds & LED_CAPS_LOCK) leds |= XLED1; - if (real_leds & LED_NUM_LOCK) leds |= XLED2; - if (real_leds & LED_SCROLL_LOCK) leds |= XLED3; - if (real_leds & LED_COMPOSE) leds |= XLED4; - - return leds; -} - -static void -SetKbdRepeat(InputInfoPtr pInfo, char rad) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - - sunKbdSetRepeat(priv, rad); -} - -static void -KbdGetMapping (InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap) -{ - /* Should probably do something better here */ - xf86KbdGetMapping(pKeySyms, pModMap); -} - -static void -ReadInput(InputInfoPtr pInfo) -{ - KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - Firm_event event[64]; - int nBytes, i; - - /* I certainly hope its not possible to read partial events */ - - if ((nBytes = read(pInfo->fd, (char *)event, sizeof(event))) > 0) - { - for (i = 0; i < (nBytes / sizeof(Firm_event)); i++) { - pKbd->PostEvent(pInfo, priv->keyMap[event[i].id], - event[i].value == VKEY_DOWN ? TRUE : FALSE); - } - } -} - -static Bool -OpenKeyboard(InputInfoPtr pInfo) -{ - pInfo->fd = sunKbdOpen(pInfo->name, pInfo->options); - - if (pInfo->fd >= 0) { - pInfo->read_input = ReadInput; - return TRUE; - } else { - return FALSE; - } -} - -_X_EXPORT Bool -xf86OSKbdPreInit(InputInfoPtr pInfo) -{ - KbdDevPtr pKbd = pInfo->private; - - pKbd->KbdInit = KbdInit; - pKbd->KbdOn = KbdOn; - pKbd->KbdOff = KbdOff; - pKbd->Bell = SoundKbdBell; - pKbd->SetLeds = SetKbdLeds; - pKbd->GetLeds = GetKbdLeds; - pKbd->SetKbdRepeat = SetKbdRepeat; - pKbd->KbdGetMapping = KbdGetMapping; - - pKbd->RemapScanCode = NULL; - pKbd->GetSpecialKey = NULL; - pKbd->SpecialKey = NULL; - - pKbd->OpenKeyboard = OpenKeyboard; - - pKbd->vtSwitchSupported = FALSE; - pKbd->CustomKeycodes = FALSE; - - pKbd->private = xcalloc(sizeof(sunKbdPrivRec), 1); - if (pKbd->private == NULL) { - xf86Msg(X_ERROR,"can't allocate keyboard OS private data\n"); - return FALSE; - } else { - sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private; - priv->otranslation = -1; - priv->odirect = -1; - } - - return TRUE; -} |