kbtrans_streams.c revision aecfc01d1bad84e66649703f7fc2926ef70b34ba
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Generic keyboard support: streams and administration.
*/
#define KEYMAP_SIZE_VARIABLE
#include <sys/vuid_event.h>
#include "kbtrans_lower.h"
#include "kbtrans_streams.h"
#ifdef DEBUG
int kbtrans_errmask;
int kbtrans_errlevel;
#endif
#define KB_NR_FUNCKEYS 12
/*
* Repeat rates set in static variables so they can be tweeked with
* debugger.
*/
static int kbtrans_repeat_rate;
static int kbtrans_repeat_delay;
/* Printing message on q overflow */
static int kbtrans_overflow_msg = 1;
/*
* This value corresponds approximately to max 10 fingers
*/
static int kbtrans_downs_size = 15;
/*
* modload support
*/
extern struct mod_ops mod_miscops;
&mod_miscops, /* Type of module */
"kbtrans (key translation)"
};
static struct modlinkage modlinkage = {
};
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
_fini(void)
{
return (mod_remove(&modlinkage));
}
int
{
}
/*
* Internal Function Prototypes
*/
static void kbtrans_set_translation_callback(struct kbtrans *);
static void kbtrans_reioctl(void *);
static void kbtrans_send_esc_event(char, struct kbtrans *);
ushort_t);
static void kbtrans_putbuf(char *, queue_t *);
static void kbtrans_cancelrpt(struct kbtrans *);
static void kbtrans_untrans_keyreleased_raw(struct kbtrans *,
static void kbtrans_trans_event_keyreleased(struct kbtrans *,
static void kbtrans_rpt(void *);
static void kbtrans_setled(struct kbtrans *);
static void kbtrans_flush(struct kbtrans *);
cred_t *);
/*
* Keyboard Translation Mode (TR_NONE)
*
* Functions to be called when keyboard translation is turned off
*/
struct keyboard_callback untrans_event_callback = {
NULL,
NULL,
NULL,
NULL,
NULL,
};
/*
* Keyboard Translation Mode (TR_ASCII)
*
* Functions to be called when ISO 8859/1 codes are reported
*/
struct keyboard_callback ascii_callback = {
NULL,
NULL,
};
/*
* Keyboard Translation Mode (TR_EVENT)
*
* Functions to be called when firm_events are reported.
*/
struct keyboard_callback trans_event_callback = {
NULL,
NULL,
};
/*
* kbtrans_streams_init:
* Initialize the stream, keytables, callbacks, etc.
*/
int
queue_t *q,
int sflag,
struct kbtrans_hardware *hw,
struct kbtrans_callbacks *hw_cb,
int initial_leds,
int initial_led_mask)
{
struct kbtrans_lower *lower;
int err;
/*
* Default to relatively generic tables.
*/
extern signed char kb_compose_map[];
extern struct compose_sequence_t kb_compose_table[];
extern struct fltaccent_sequence_t kb_fltaccent_table[];
extern char keystringtab[][KTAB_STRLEN];
extern unsigned char kb_numlock_table[];
/* Set these up only once so that they could be changed from adb */
if (!kbtrans_repeat_rate) {
}
/*
* Only allow open requests to succeed for privileged users. This
* necessary to prevent users from pushing the this module again
*/
if (err != 0) {
return (err);
}
switch (sflag) {
case MODOPEN:
break;
case CLONEOPEN:
"kbtrans_streams_init: Clone open not supported"));
return (EINVAL);
}
/* allocate keyboard state structure */
upper->kbtrans_streams_readq = q;
upper->kbtrans_overflow_cnt = 0;
/* Set the translation callback based on the translation type */
/*
* Set defaults for relatively generic tables.
*/
/*
* We have a generic default for the LED state, and let the
* hardware-specific driver supply overrides.
*/
lower->kbtrans_led_state = 0;
lower->kbtrans_togglemask = 0;
#if defined(SCROLLMASK)
#endif
/* Allocate dynamic memory for downs table */
"exiting"));
return (0);
}
/*
* kbtrans_streams_fini:
* Free structures and uninitialize the stream
*/
int
{
/*
* Since we're about to destroy our private data, turn off
* our open flag first, so we don't accept any more input
* and try to use that data.
*/
upper->kbtrans_streams_flags = 0;
/* clear all timeouts */
if (upper->kbtrans_streams_bufcallid) {
}
if (upper->kbtrans_streams_rptid) {
}
"exiting"));
return (0);
}
/*
* kbtrans_streams_releaseall :
* This function releases all the held keys.
*/
void
{
register int i;
/* Scan table of down key stations */
/* Key station not zero */
if (ke->key_station) {
/* kbtrans_keyreleased resets downs entry */
}
}
}
/*
* kbtrans_streams_message:
* keyboard module output queue put procedure: handles M_IOCTL
* messages.
*
* Return KBTRANS_MESSAGE_HANDLED if the message was handled by
* kbtrans and KBTRANS_MESSAGE_NOT_HANDLED otherwise. If
* KBTRANS_MESSAGE_HANDLED is returned, no further action is required.
* If KBTRANS_MESSAGE_NOT_HANDLED is returned, the hardware module
* is responsible for any action.
*/
{
enum kbtrans_message_response ret;
"kbtrans_streams_message entering"));
/*
* Process M_FLUSH, and some M_IOCTL, messages here; pass
* everything else down.
*/
case M_IOCTL:
break;
case M_FLUSH:
/*
* White lie: we say we didn't handle the message,
* so that it gets handled by our client.
*/
break;
default:
break;
}
"kbtrans_streams_message exiting\n"));
return (ret);
}
/*
* kbtrans_streams_key:
* When a key is pressed or released, the hardware module should
* call kbtrans, passing the key number and its new
* state. kbtrans is responsible for autorepeat handling;
* events, suppressing any hardware-generated autorepeat.
*/
void
{
struct kbtrans_lower *lower;
if (upper->kbtrans_streams_abortable) {
switch (upper->kbtrans_streams_abort_state) {
case ABORT_NORMAL:
if (state != KEY_PRESSED)
break;
return;
}
/* Shift key needs to be sent to upper immediately */
}
break;
case ABORT_ABORT1_RECEIVED:
if (state == KEY_PRESSED &&
abort_sequence_enter((char *)NULL);
return;
} else {
}
break;
if (state == KEY_PRESSED &&
abort_sequence_enter((char *)NULL);
return;
}
}
}
}
/*
* kbtrans_streams_set_keyboard:
* At any time after calling kbtrans_streams_init, the hardware
* module should make this call to report the id of the keyboard
* attached. id is the keyboard type, typically KB_SUN4,
* KB_PC, or KB_USB.
*/
void
int id,
struct keyboard *k)
{
}
/*
* kbtrans_streams_has_reset:
* At any time between kbtrans_streams_init and kbtrans_streams_fini,
* the hardware module can call this routine to report that the
* keyboard has been reset, e.g. by being unplugged and reattached.
*/
/*ARGSUSED*/
void
{
/*
* If this routine is implemented it should probably (a)
* simulate releases of all pressed keys and (b) call
* the hardware module to set the LEDs.
*/
}
/*
* kbtrans_streams_enable:
* This is the routine that is called back when the the stream is ready
* to take messages.
*/
void
{
/* Set the LED's */
}
/*
* kbtrans_streams_setled():
* This is the routine that is called to only update the led state
* in kbtrans.
*/
void
{
struct kbtrans_lower *lower;
#if defined(SCROLLMASK)
#endif
}
/*
* kbtrans_streams_set_queue:
* Set the overlying queue, to support multiplexors.
*/
void
{
upper->kbtrans_streams_readq = q;
}
/*
* kbtrans_streams_get_queue:
* Return the overlying queue.
*/
queue_t *
{
return (upper->kbtrans_streams_readq);
}
/*
* kbtrans_streams_untimeout
* Cancell all timeout
*/
void
{
/* clear all timeouts */
if (upper->kbtrans_streams_bufcallid) {
}
if (upper->kbtrans_streams_rptid) {
upper->kbtrans_streams_rptid = 0;
}
}
/*
* kbtrans_reioctl:
* This function is set up as call-back function should an ioctl fail
* to allocate required resources.
*/
static void
kbtrans_reioctl(void *arg)
{
/* not pending any more */
}
}
/*
* kbtrans_ioctl:
* process ioctls we recognize and own. Otherwise, pass it down.
*/
static enum kbtrans_message_response
{
register short new_translate;
register Vuid_addr_probe *addr_probe;
register short *addr_ptr;
int err = 0;
struct kbtrans_lower *lower;
int translate;
static int kiocgetkey, kiocsetkey;
case VUIDSFORMAT:
if (err != 0)
break;
break;
break;
case KIOCTRANS:
if (err != 0)
break;
break;
break;
case KIOCSLED:
if (err != 0)
break;
break;
case KIOCGLED:
ioctlrespsize = sizeof (int);
goto allocfailure;
}
break;
case VUIDGFORMAT:
ioctlrespsize = sizeof (int);
goto allocfailure;
}
break;
case KIOCGTRANS:
ioctlrespsize = sizeof (int);
goto allocfailure;
}
break;
case VUIDSADDR:
if (err != 0)
break;
switch (addr_probe->base) {
case ASCII_FIRST:
break;
case TOP_FIRST:
break;
case VKEY_FIRST:
break;
default:
}
}
break;
case VUIDGADDR:
if (err != 0)
break;
switch (addr_probe->base) {
case ASCII_FIRST:
break;
case TOP_FIRST:
break;
case VKEY_FIRST:
break;
default:
}
break;
case KIOCTRANSABLE:
if (err != 0)
break;
/*
* called during console setup in kbconfig()
* If set to false, means we are a serial keyboard,
* and we should pass all data up without modification.
*/
"Cannot translate keyboard using tables.\n"));
break;
case KIOCGTRANSABLE:
ioctlrespsize = sizeof (int);
goto allocfailure;
}
break;
case KIOCSCOMPAT:
if (err != 0)
break;
break;
case KIOCGCOMPAT:
ioctlrespsize = sizeof (int);
goto allocfailure;
}
break;
case KIOCSETKEY:
kiocsetkey++));
if (err != 0)
break;
/*
* Since this only affects any subsequent key presses,
* don't flush soft state. One might want to
* toggle the keytable entries dynamically.
*/
break;
case KIOCGETKEY:
kiocgetkey++));
if (err != 0)
break;
break;
case KIOCSKEY:
if (err != 0)
break;
/*
* Since this only affects any subsequent key presses,
* don't flush soft state. One might want to
* toggle the keytable entries dynamically.
*/
break;
case KIOCGKEY:
if (err != 0)
break;
break;
case KIOCSDIRECT:
break;
case KIOCGDIRECT:
ioctlrespsize = sizeof (int);
goto allocfailure;
}
break;
case KIOCTYPE:
ioctlrespsize = sizeof (int);
goto allocfailure;
}
break;
case CONSSETABORTENABLE:
/*
* Peek as it goes by; must be a TRANSPARENT ioctl.
*/
break;
}
/*
* Let the hardware module see it too.
*/
return (KBTRANS_MESSAGE_NOT_HANDLED);
case KIOCGRPTDELAY:
/*
* Report the autorepeat delay, unit in millisecond
*/
ioctlrespsize = sizeof (int);
goto allocfailure;
}
/* free msg to prevent memory leak */
break;
case KIOCSRPTDELAY:
/*
* Set the autorepeat delay
*/
if (err != 0)
break;
/* validate the input */
break;
}
if (kbtrans_repeat_delay <= 0)
kbtrans_repeat_delay = 1;
break;
case KIOCGRPTRATE:
/*
* Report the autorepeat rate
*/
ioctlrespsize = sizeof (int);
goto allocfailure;
}
/* free msg to prevent memory leak */
break;
case KIOCSRPTRATE:
/*
* Set the autorepeat rate
*/
if (err != 0)
break;
/* validate the input */
break;
}
if (kbtrans_repeat_rate <= 0)
kbtrans_repeat_rate = 1;
break;
default:
return (KBTRANS_MESSAGE_NOT_HANDLED);
} /* end switch */
if (err != 0) {
} else {
}
return (KBTRANS_MESSAGE_HANDLED);
/*
* We needed to allocate something to handle this "ioctl", but
* couldn't; save this "ioctl" and arrange to get called back when
* it's more likely that we can get what we need.
* If there's already one being saved, throw it out, since it
* must have timed out.
*/
if (upper->kbtrans_streams_bufcallid) {
}
/*
* This is a white lie... we *will* handle it, eventually.
*/
return (KBTRANS_MESSAGE_HANDLED);
}
/*
* kbtrans_flush:
* Flush data upstream
*/
static void
{
register queue_t *q;
/* Flush pending data already sent upstream */
/* Flush pending ups */
}
/*
* kbtrans_setled:
* Update the keyboard LEDs to match the current keyboard state.
*/
static void
{
}
/*
* kbtrans_rpt:
* If a key is held down, this function is set up to be called
* after kbtrans_repeat_rate time elapses.
*/
static void
kbtrans_rpt(void *arg)
{
"kbtrans_rpt: repeat key %X\n",
upper->kbtrans_streams_rptid = 0;
/*
* NB: polled code zaps kbtrans_repeatkey without cancelling
* timeout.
*/
if (lower->kbtrans_repeatkey != 0) {
}
}
/*
* kbtrans_cancelrpt:
* Cancel the repeating key
*/
static void
{
if (upper->kbtrans_streams_rptid != 0) {
upper->kbtrans_streams_rptid = 0;
}
}
/*
* kbtrans_send_esc_event:
* Send character up stream. Used for the case of
* sending strings upstream.
*/
static void
{
/*
* Pretend as if each cp pushed and released
* Calling kbtrans_queueevent avoids addr translation
* and pair base determination of kbtrans_keypressed.
*/
}
/*
* kbtrans_strsetwithdecimal:
* Used for expanding a function key to the ascii equivalent
*/
static char *
{
int hradix = 5;
char *bp;
int lowbit;
char *tab = "0123456789abcdef";
*(--bp) = '\0';
while (val) {
}
return (bp);
}
/*
* kbtrans_keypressed:
* Modify Firm event to be sent up the stream
*/
static void
{
register short id_addr;
/* Set pair values */
/*
* If CTRLed, find the ID that would have been used had it
* not been CTRLed.
*/
unsigned short *ke;
unsigned int mask;
return;
}
goto send;
}
}
send:
/* Adjust event id address for multiple keyboard/workstation support */
case ASCII_FIRST:
break;
case TOP_FIRST:
break;
case VKEY_FIRST:
break;
default:
break;
}
}
/*
* kbtrans_queuepress:
* Add keypress to the "downs" table
*/
static void
{
register int i;
" key=%d", key_station));
ke_free = 0;
/* Scan table of down key stations */
/* Keycode already down? */
(NULL, "kbtrans: Double "
"entry in downs table (%d,%d)!\n",
key_station, i));
goto add_event;
}
if (ke->key_station == 0)
}
if (ke_free) {
goto add_event;
}
}
/*
* kbtrans_keyreleased:
* Remove entry from the downs table
*/
static void
{
register int i;
key_station));
return;
}
/* Scan table of down key stations */
i++, ke++) {
/* Found? */
ke->key_station = 0;
}
}
/*
* Ignore if couldn't find because may be called twice
* for the same key station in the case of the kbtrans_rpt
* routine being called unnecessarily.
*/
}
/*
* kbtrans_putcode:
* Pass a keycode up the stream, if you can, otherwise throw it away.
*/
static void
{
/*
* If we can't send it up, then we just drop it.
*/
return;
}
/*
* Allocate a messsage block to send up.
*/
for keycode.");
return;
}
/*
* We will strip out any high order information here.
*/
/* NOTE the implicit cast here */
/*
* Send the message up.
*/
}
/*
* kbtrans_putbuf:
* Pass generated keycode sequence to upstream, if possible.
*/
static void
{
if (!canputnext(q)) {
} else {
"Can't allocate block for keycode");
} else {
while (*buf) {
buf++;
}
}
}
}
/*
* kbtrans_queueevent:
* Pass a VUID "firm event" up the stream, if you can.
*/
static void
{
register queue_t *q;
return;
if (!canputnext(q)) {
if (kbtrans_overflow_msg) {
"kbtrans: Buffer flushed when overflowed."));
}
} else {
block for event.");
} else {
}
}
}
/*
* kbtrans_set_translation_callback:
* This code sets the translation_callback pointer based on the
* translation mode.
*/
static void
{
switch (upper->kbtrans_streams_translate_mode) {
default:
case TR_ASCII:
break;
case TR_EVENT:
break;
case TR_UNTRANS_EVENT:
break;
}
}
/*
* kbtrans_untrans_keypressed_raw:
* This is the callback we get if we are in TR_UNTRANS_EVENT and a
* key is pressed. This code will just send the scancode up the
* stream.
*/
static void
{
/*
* fill in the event
*/
/*
* Send the event upstream.
*/
}
/*
* kbtrans_untrans_keyreleased_raw:
* This is the callback we get if we are in TR_UNTRANS_EVENT mode
* and a key is released. This code will just send the scancode up
* the stream.
*/
static void
{
/*
* Deal with a key released event.
*/
}
/*
* kbtrans_vt_compose:
* To compose the key sequences for virtual terminal switching.
*
* 'ALTL + F#' for 1-12 terminals
* 'ALTGR + F#' for 13-24 terminals
* 'ALT + UPARROW' for last terminal
* 'ALT + LEFTARROW' for previous terminal
* 'ALT + RIGHTARROW' for next terminal
*
* the vt switching message is encoded as:
*
* -------------------------------------------------------------
* | \033 | 'Q' | vtno + 'A' | opcode | 'z' | '\0' |
* -------------------------------------------------------------
*
* opcode:
* 'B' to switch to previous terminal
* 'F' to switch to next terminal
* 'L' to switch to last terminal
* 'H' to switch to the terminal as specified by vtno,
* which is from 1 to 24.
*
* Here keyid is the keycode of UPARROW, LEFTARROW, or RIGHTARROW
* when it is a kind of arrow key as indicated by is_arrow_key,
* otherwise it indicates a function key and keyid is the number
* corresponding to that function key.
*/
static void
{
char *bufp;
*bufp++ = 'Q';
if (is_arrow_key) {
*bufp++ = 'A';
switch (keyid) {
case UPARROW: /* last vt */
*bufp++ = 'L';
break;
case LEFTARROW: /* previous vt */
*bufp++ = 'B';
break;
case RIGHTARROW: /* next vt */
*bufp++ = 'F';
break;
default:
break;
}
} else {
/* this is funckey specifying vtno for switch */
KB_NR_FUNCKEYS + 'A';
*bufp++ = 'H';
}
*bufp++ = 'z';
*bufp = '\0';
/*
* Send the result upstream.
*/
}
/*
* kbtrans_ascii_keypressed:
* This is the code if we are in TR_ASCII mode and a key
* is pressed. This is where we will do any special processing that
* is specific to ASCII key translation.
*/
/* ARGSUSED */
static void
{
register char *cp;
register char *bufp;
char buf[14];
unsigned short keyid;
/*
* Based on the type of key, we may need to do some ASCII
* specific post processing. Note that the translated entry
* is constructed as the actual keycode plus entrytype. see
*/
switch (entrytype) {
case BUCKYBITS:
return;
case SHIFTKEYS:
}
return;
case FUNNY:
/*
* There is no ascii equivalent. We will ignore these
* keys
*/
return;
case FUNCKEYS:
/*
* keyid is the number correspoding to F#
* and its value is from 1 to 12.
*/
return;
}
}
/*
* We need to expand this key to get the ascii
* equivalent. These are the function keys (F1, F2 ...)
*/
sizeof (buf) - 5);
*bufp++ = '[';
while (*cp != '\0')
*bufp++ = 'z';
*bufp = '\0';
/*
* Send the result upstream.
*/
return;
case STRING:
keyid == RIGHTARROW ||
return;
}
}
/*
* These are the multi byte keys (Home, Up, Down ...)
*/
/*
* Copy the string from the keystringtable, and send it
* upstream a character at a time.
*/
while (*cp != '\0') {
cp++;
}
return;
case PADKEYS:
/*
* These are the keys on the keypad. Look up the
* answer in the kb_numlock_table and send it upstream.
*/
return;
case 0: /* normal character */
default:
break;
}
/*
* Send the byte upstream.
*/
}
#define KB_SCANCODE_ALT 0xe2
#define KB_SCANCODE_ALTGRAPH 0xe6
/*
* kbtrans_ascii_keyreleased:
* This is the function if we are in TR_ASCII mode and a key
* is released. ASCII doesn't have the concept of released keys,
* of vt switch key sequence.
*/
/* ARGSUSED */
static void
{
}
}
/*
* kbtrans_ascii_setup_repeat:
* This is the function if we are in TR_ASCII mode and the
* translation module has decided that a key needs to be repeated.
*/
/* ARGSUSED */
static void
{
/*
* Cancel any currently repeating keys. This will be a new
* key to repeat.
*/
/*
* Set the value of the key to be repeated.
*/
/*
* Start the timeout for repeating this key. kbtrans_rpt will
* be called to repeat the key.
*/
}
/*
* kbtrans_trans_event_keypressed:
* This is the function if we are in TR_EVENT mode and a key
* is pressed. This is where we will do any special processing that
* is specific to EVENT key translation.
*/
static void
{
register char *cp;
/*
* Based on the type of key, we may need to do some EVENT
* specific post processing.
*/
switch (entrytype) {
case SHIFTKEYS:
/*
* Relying on ordinal correspondence between
* vuid_event.h SHIFT_META-SHIFT_TOP &
* kbd.h METABIT-SYSTEMBIT in order to
* correctly translate entry into fe.id.
*/
return;
case BUCKYBITS:
/*
* Relying on ordinal correspondence between
* vuid_event.h SHIFT_CAPSLOCK-SHIFT_RIGHTCTRL &
* kbd.h CAPSLOCK-RIGHTCTRL in order to
* correctly translate entry into fe.id.
*/
return;
case FUNCKEYS:
/*
* Take advantage of the similar
* ordering of kbd.h function keys and
* vuid_event.h function keys to do a
* simple translation to achieve a
* mapping between the 2 different
* address spaces.
*/
/*
* Assume "up" table only generates
* shift changes.
*/
/*
* Function key events can be expanded
* by terminal emulator software to
* produce the standard escape sequence
* generated by the TR_ASCII case above
* if a function key event is not used
* by terminal emulator software
* directly.
*/
return;
case STRING:
/*
* These are the multi byte keys (Home, Up, Down ...)
*/
/*
* Copy the string from the keystringtable, and send it
* upstream a character at a time.
*/
while (*cp != '\0') {
cp++;
}
return;
case PADKEYS:
/*
* Take advantage of the similar
* ordering of kbd.h keypad keys and
* vuid_event.h keypad keys to do a
* simple translation to achieve a
* mapping between the 2 different
* address spaces.
*/
/*
* Assume "up" table only generates
* shift changes.
*/
/*
* Keypad key events can be expanded
* by terminal emulator software to
* produce the standard ascii character
* generated by the TR_ASCII case above
* if a keypad key event is not used
* by terminal emulator software
* directly.
*/
return;
case FUNNY:
/*
* These are not events.
*/
switch (entry) {
case IDLE:
case RESET:
case ERROR:
/*
* Something has happened. Mark all keys as released.
*/
break;
}
return;
case 0: /* normal character */
default:
break;
}
/*
* Send the event upstream.
*/
}
/*
* kbtrans_trans_event_keyreleased:
* This is the function if we are in TR_EVENT mode and a key
* is released.
*/
/* ARGSUSED */
static void
{
/*
* Mark the key as released and send an event upstream.
*/
}
/*
* kbtrans_trans_event_setup_repeat:
* This is the function if we are in TR_EVENT mode and the
* translation module has decided that a key needs to be repeated.
* We will set a timeout to retranslate the repeat key.
*/
static void
{
/*
* Function keys and keypad keys do not repeat when we are in
* EVENT mode.
*/
return;
}
/*
* Cancel any currently repeating keys. This will be a new
* key to repeat.
*/
/*
* Set the value of the key to be repeated.
*/
/*
* Start the timeout for repeating this key. kbtrans_rpt will
* be called to repeat the key.
*/
}
/*
* Administer the key tables.
*/
/*
* Old special codes.
*/
#define OLD_SHIFTKEYS 0x80
#define OLD_BUCKYBITS 0x90
#define OLD_FUNNY 0xA0
#define OLD_FA_UMLAUT 0xA9
#define OLD_FA_CFLEX 0xAA
#define OLD_FA_TILDE 0xAB
#define OLD_FA_CEDILLA 0xAC
#define OLD_FA_ACUTE 0xAD
#define OLD_FA_GRAVE 0xAE
#define OLD_ISOCHAR 0xAF
#define OLD_STRING 0xB0
#define OLD_LEFTFUNC 0xC0
#define OLD_RIGHTFUNC 0xD0
#define OLD_TOPFUNC 0xE0
#define OLD_BOTTOMFUNC 0xF0
/*
* Map old special codes to new ones.
* Indexed by ((old special code) >> 4) & 0x07; add (old special code) & 0x0F.
*/
static ushort_t special_old_to_new[] = {
};
/*
* kbtrans_setkey:
* Set individual keystation translation from old-style entry.
*/
static int
{
int strtabindex, i;
unsigned short *ke;
register int tablemask;
return (EINVAL);
return (EINVAL);
switch (tablemask) {
case KIOCABORT1:
case KIOCABORT1A:
case KIOCABORT2:
i = secpolicy_console(cr);
if (i != 0)
return (i);
switch (tablemask) {
case KIOCABORT1:
break;
case KIOCABORT1A:
break;
case KIOCABORT2:
break;
}
return (0);
}
if (tablemask & ALTGRAPHMASK)
return (EINVAL);
return (EINVAL);
}
/*
* There's nothing we need do with OLD_ISOCHAR.
*/
if (entry != OLD_ISOCHAR) {
if (entry & 0x80) {
else
entry =
+ (entry & 0x0F);
}
}
return (0);
}
/*
* Map new special codes to old ones.
* Indexed by (new special code) >> 8; add (new special code) & 0xFF.
*/
static uchar_t special_new_to_old[] = {
0, /* normal */
OLD_SHIFTKEYS, /* SHIFTKEYS */
OLD_BUCKYBITS, /* BUCKYBITS */
OLD_FUNNY, /* FUNNY */
OLD_FA_UMLAUT, /* FA_CLASS */
OLD_STRING, /* STRING */
OLD_LEFTFUNC, /* FUNCKEYS */
};
/*
* kbtrans_getkey:
* Get individual keystation translation as old-style entry.
*/
static int
{
int strtabindex;
unsigned short *ke;
return (EINVAL);
return (EINVAL);
switch (key->kio_tablemask) {
case KIOCABORT1:
return (0);
case KIOCABORT1A:
return (0);
case KIOCABORT2:
return (0);
}
key->kio_station);
return (EINVAL);
if (entry & 0xFF00)
+ (entry & 0x00FF);
else {
if (entry & 0x80)
else
}
}
return (0);
}
/*
* kbtrans_skey:
* Set individual keystation translation from new-style entry.
*/
static int
{
int strtabindex, i;
unsigned short *ke;
return (EINVAL);
}
return (EINVAL);
}
switch (key->kio_tablemask) {
case KIOCABORT1:
case KIOCABORT1A:
case KIOCABORT2:
i = secpolicy_console(cr);
if (i != 0)
return (i);
switch (key->kio_tablemask) {
case KIOCABORT1:
break;
case KIOCABORT1A:
break;
case KIOCABORT2:
break;
}
return (0);
}
key->kio_station);
return (EINVAL);
}
return (0);
}
/*
* kbtrans_gkey:
* Get individual keystation translation as new-style entry.
*/
static int
{
int strtabindex;
unsigned short *ke;
return (EINVAL);
return (EINVAL);
switch (key->kio_tablemask) {
case KIOCABORT1:
return (0);
case KIOCABORT1A:
return (0);
case KIOCABORT2:
return (0);
}
key->kio_station);
return (EINVAL);
}
return (0);
}