#define NEED_EVENTS
#include "sun.h"
#include "keysym.h"
#include "Sunkeysym.h"
#include "osdep.h"
#include "Xpoll.h"
#ifdef XKB
#include <X11/extensions/XKB.h>
#include <X11/extensions/XKBstr.h>
#include <X11/extensions/XKBsrv.h>
#endif
#define SUN_LED_MASK 0x0f
#define MIN_KEYCODE 7
#define MAX_KEYCODE 255
#ifndef KB_SUN4
#define KB_SUN4 4
#endif
#define AUTOREPEAT_INITIATE 400
#define AUTOREPEAT_DELAY 50
#define tvminus(tv, tv1, tv2) \
if ((tv1).tv_usec < (tv2).tv_usec) { \
(tv1).tv_usec += 1000000; \
(tv1).tv_sec -= 1; \
} \
(tv).tv_usec = (tv1).tv_usec - (tv2).tv_usec; \
(tv).tv_sec = (tv1).tv_sec - (tv2).tv_sec;
#define tvplus(tv, tv1, tv2) \
(tv).tv_sec = (tv1).tv_sec + (tv2).tv_sec; \
(tv).tv_usec = (tv1).tv_usec + (tv2).tv_usec; \
if ((tv).tv_usec > 1000000) { \
(tv).tv_usec -= 1000000; \
(tv).tv_sec += 1; \
}
extern KeySymsRec sunKeySyms[];
extern SunModmapRec* sunModMaps[];
long sunAutoRepeatInitiate = 1000 * AUTOREPEAT_INITIATE;
long sunAutoRepeatDelay = 1000 * AUTOREPEAT_DELAY;
static int autoRepeatKeyDown = 0;
static int autoRepeatReady;
static int autoRepeatFirst;
static struct timeval autoRepeatLastKeyDownTv;
static struct timeval autoRepeatDeltaTv;
void sunKbdWait()
{
static struct timeval lastChngKbdTransTv;
struct timeval tv;
struct timeval lastChngKbdDeltaTv;
unsigned int lastChngKbdDelta;
X_GETTIMEOFDAY(&tv);
if (!lastChngKbdTransTv.tv_sec)
lastChngKbdTransTv = tv;
tvminus(lastChngKbdDeltaTv, tv, lastChngKbdTransTv);
lastChngKbdDelta = TVTOMILLI(lastChngKbdDeltaTv);
if (lastChngKbdDelta < 750) {
unsigned wait;
wait = (750L - lastChngKbdDelta) * 1000L;
usleep (wait);
X_GETTIMEOFDAY(&tv);
}
lastChngKbdTransTv = tv;
}
static void SwapLKeys(keysyms)
KeySymsRec* keysyms;
{
unsigned int i;
KeySym k;
for (i = 2; i < keysyms->maxKeyCode * keysyms->mapWidth; i++)
if (keysyms->map[i] == XK_L1 ||
keysyms->map[i] == XK_L2 ||
keysyms->map[i] == XK_L3 ||
keysyms->map[i] == XK_L4 ||
keysyms->map[i] == XK_L5 ||
keysyms->map[i] == XK_L6 ||
keysyms->map[i] == XK_L7 ||
keysyms->map[i] == XK_L8 ||
keysyms->map[i] == XK_L9 ||
keysyms->map[i] == XK_L10) {
k = keysyms->map[i - 2];
keysyms->map[i - 2] = keysyms->map[i];
keysyms->map[i] = k;
}
}
static void SetLights (ctrl, fd)
KeybdCtrl* ctrl;
int fd;
{
#ifdef KIOCSLED
static unsigned char led_tab[16] = {
0,
LED_NUM_LOCK,
LED_SCROLL_LOCK,
LED_SCROLL_LOCK | LED_NUM_LOCK,
LED_COMPOSE,
LED_COMPOSE | LED_NUM_LOCK,
LED_COMPOSE | LED_SCROLL_LOCK,
LED_COMPOSE | LED_SCROLL_LOCK | LED_NUM_LOCK,
LED_CAPS_LOCK,
LED_CAPS_LOCK | LED_NUM_LOCK,
LED_CAPS_LOCK | LED_SCROLL_LOCK,
LED_CAPS_LOCK | LED_SCROLL_LOCK | LED_NUM_LOCK,
LED_CAPS_LOCK | LED_COMPOSE,
LED_CAPS_LOCK | LED_COMPOSE | LED_NUM_LOCK,
LED_CAPS_LOCK | LED_COMPOSE | LED_SCROLL_LOCK,
LED_CAPS_LOCK | LED_COMPOSE | LED_SCROLL_LOCK | LED_NUM_LOCK
};
if (ioctl (fd, KIOCSLED, (caddr_t)&led_tab[ctrl->leds & 0x0f]) == -1)
#if defined(PATCHED_CONSOLE)
Error("Failed to set keyboard lights");
#else
;
#endif
#endif
}
static void ModLight (device, on, led)
DeviceIntPtr device;
Bool on;
int led;
{
KeybdCtrl* ctrl = &device->kbdfeed->ctrl;
sunKbdPrivPtr pPriv = (sunKbdPrivPtr) device->public.devicePrivate;
if(on) {
ctrl->leds |= led;
pPriv->leds |= led;
} else {
ctrl->leds &= ~led;
pPriv->leds &= ~led;
}
SetLights (ctrl, pPriv->fd);
}
static void bell (
int fd,
int duration)
{
#if defined(PATCHED_CONSOLE)
int kbdCmd;
kbdCmd = KBD_CMD_BELL;
if (ioctl (fd, KIOCCMD, &kbdCmd) == -1) {
Error("Failed to activate bell");
return;
}
if (duration) usleep (duration);
kbdCmd = KBD_CMD_NOBELL;
if (ioctl (fd, KIOCCMD, &kbdCmd) == -1)
Error ("Failed to deactivate bell");
#endif
}
static void sunBell (
int percent,
DeviceIntPtr device,
pointer ctrl,
int unused)
{
KeybdCtrl* kctrl = (KeybdCtrl*) ctrl;
sunKbdPrivPtr pPriv = (sunKbdPrivPtr) device->public.devicePrivate;
if (percent == 0 || kctrl->bell == 0)
return;
bell (pPriv->fd, kctrl->bell_duration * 1000);
}
static void sunEnqueueEvent (xE)
xEvent* xE;
{
sigset_t holdmask;
(void) sigaddset (&holdmask, SIGIO);
(void) sigprocmask (SIG_BLOCK, &holdmask, (sigset_t*)NULL);
mieqEnqueue (xE);
(void) sigprocmask (SIG_UNBLOCK, &holdmask, (sigset_t*)NULL);
}
#define XLED_NUM_LOCK 0x1
#define XLED_COMPOSE 0x4
#define XLED_SCROLL_LOCK 0x2
#define XLED_CAPS_LOCK 0x8
static KeyCode LookupKeyCode (keysym, keysymsrec)
KeySym keysym;
KeySymsPtr keysymsrec;
{
KeyCode i;
int ii, index = 0;
for (i = keysymsrec->minKeyCode; i < keysymsrec->maxKeyCode; i++)
for (ii = 0; ii < keysymsrec->mapWidth; ii++)
if (keysymsrec->map[index++] == keysym)
return i;
}
static void pseudoKey(device, down, keycode)
DeviceIntPtr device;
Bool down;
KeyCode keycode;
{
int bit;
CARD8 modifiers;
CARD16 mask;
BYTE* kptr;
kptr = &device->key->down[keycode >> 3];
bit = 1 << (keycode & 7);
modifiers = device->key->modifierMap[keycode];
if (down) {
int i;
*kptr |= bit;
device->key->prev_state = device->key->state;
for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
if (mask & modifiers) {
device->key->modifierKeyCount[i]++;
device->key->state += mask;
modifiers &= ~mask;
}
} else {
if (*kptr & bit) {
int i;
*kptr &= ~bit;
device->key->prev_state = device->key->state;
for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
if (mask & modifiers) {
if (--device->key->modifierKeyCount[i] <= 0) {
device->key->state &= ~mask;
device->key->modifierKeyCount[i] = 0;
}
modifiers &= ~mask;
}
}
}
}
static void DoLEDs(device, ctrl, pPriv)
DeviceIntPtr device;
KeybdCtrl* ctrl;
sunKbdPrivPtr pPriv;
{
#ifdef XKB
if (noXkbExtension) {
#endif
if ((ctrl->leds & XLED_CAPS_LOCK) && !(pPriv->leds & XLED_CAPS_LOCK))
pseudoKey(device, TRUE,
LookupKeyCode(XK_Caps_Lock, &device->key->curKeySyms));
if (!(ctrl->leds & XLED_CAPS_LOCK) && (pPriv->leds & XLED_CAPS_LOCK))
pseudoKey(device, FALSE,
LookupKeyCode(XK_Caps_Lock, &device->key->curKeySyms));
if ((ctrl->leds & XLED_NUM_LOCK) && !(pPriv->leds & XLED_NUM_LOCK))
pseudoKey(device, TRUE,
LookupKeyCode(XK_Num_Lock, &device->key->curKeySyms));
if (!(ctrl->leds & XLED_NUM_LOCK) && (pPriv->leds & XLED_NUM_LOCK))
pseudoKey(device, FALSE,
LookupKeyCode(XK_Num_Lock, &device->key->curKeySyms));
if ((ctrl->leds & XLED_SCROLL_LOCK) && !(pPriv->leds & XLED_SCROLL_LOCK))
pseudoKey(device, TRUE,
LookupKeyCode(XK_Scroll_Lock, &device->key->curKeySyms));
if (!(ctrl->leds & XLED_SCROLL_LOCK) && (pPriv->leds & XLED_SCROLL_LOCK))
pseudoKey(device, FALSE,
LookupKeyCode(XK_Scroll_Lock, &device->key->curKeySyms));
if ((ctrl->leds & XLED_COMPOSE) && !(pPriv->leds & XLED_COMPOSE))
pseudoKey(device, TRUE,
LookupKeyCode(SunXK_Compose, &device->key->curKeySyms));
if (!(ctrl->leds & XLED_COMPOSE) && (pPriv->leds & XLED_COMPOSE))
pseudoKey(device, FALSE,
LookupKeyCode(SunXK_Compose, &device->key->curKeySyms));
#ifdef XKB
}
#endif
pPriv->leds = ctrl->leds & 0x0f;
SetLights (ctrl, pPriv->fd);
}
static void sunKbdCtrl (
DeviceIntPtr device,
KeybdCtrl* ctrl)
{
sunKbdPrivPtr pPriv = (sunKbdPrivPtr) device->public.devicePrivate;
if (pPriv->fd < 0) return;
if (ctrl->click != pPriv->click) {
int kbdClickCmd;
pPriv->click = ctrl->click;
#if defined(PATCHED_CONSOLE)
kbdClickCmd = pPriv->click ? KBD_CMD_CLICK : KBD_CMD_NOCLICK;
if (ioctl (pPriv->fd, KIOCCMD, &kbdClickCmd) == -1)
Error("Failed to set keyclick");
#endif
}
if (pPriv->type == KB_SUN4 && pPriv->leds != ctrl->leds & 0x0f)
DoLEDs(device, ctrl, pPriv);
}
#ifdef XKB
static void sunInitKbdNames (
XkbComponentNamesRec* names,
sunKbdPrivPtr pKbd)
{
#ifndef XKBBUFSIZE
#define XKBBUFSIZE 64
#endif
static char keycodesbuf[XKBBUFSIZE];
static char geometrybuf[XKBBUFSIZE];
static char symbolsbuf[XKBBUFSIZE];
names->keymap = NULL;
names->compat = "compat/complete";
names->types = "types/complete";
names->keycodes = keycodesbuf;
names->geometry = geometrybuf;
names->symbols = symbolsbuf;
(void) strcpy (keycodesbuf, "keycodes/");
(void) strcpy (geometrybuf, "geometry/");
(void) strcpy (symbolsbuf, "symbols/");
switch (pKbd->type) {
case KB_SUN2:
(void) strcat (names->keycodes, "sun(type2)");
(void) strcat (names->geometry, "sun(type2)");
(void) strcat (names->symbols, "us(sun2)");
break;
case KB_SUN3:
(void) strcat (names->keycodes, "sun(type3)");
(void) strcat (names->geometry, "sun(type3)");
(void) strcat (names->symbols, "us(sun3)");
break;
case KB_SUN4:
if (pKbd->layout == 19) {
(void) strcat (names->keycodes, "sun(US101A)");
(void) strcat (names->geometry, "pc101-NG");
(void) strcat (names->symbols, "us(pc101)");
} else if (pKbd->layout < 33) {
(void) strcat (names->keycodes, "sun(type4)");
(void) strcat (names->geometry, "sun(type4)");
if (sunSwapLkeys)
(void) strcat (names->symbols, "sun/us(sun4ol)");
else
(void) strcat (names->symbols, "sun/us(sun4)");
} else {
(void) strcat (names->keycodes, "sun(type5)");
if (pKbd->layout == 34 || pKbd->layout == 81)
(void) strcat (names->geometry, "sun(type5unix)");
else
(void) strcat (names->geometry, "sun(type5)");
if (sunSwapLkeys)
(void) strcat (names->symbols, "sun/us(sun5ol)");
else
(void) strcat (names->symbols, "sun/us(sun5)");
}
break;
default:
names->keycodes = names->geometry = NULL;
break;
}
if (pKbd->type == KB_SUN4) {
switch (pKbd->layout) {
case 0: case 1: case 33: case 34: case 80: case 81:
break;
case 3:
(void) strcat (names->symbols, "+ca"); break;
case 4: case 36: case 83:
(void) strcat (names->symbols, "+dk"); break;
case 5: case 37: case 84:
(void) strcat (names->symbols, "+de"); break;
case 6: case 38: case 85:
(void) strcat (names->symbols, "+it"); break;
case 8: case 40: case 87:
(void) strcat (names->symbols, "+no"); break;
case 9: case 41: case 88:
(void) strcat (names->symbols, "+pt"); break;
case 10: case 42: case 89:
(void) strcat (names->symbols, "+es"); break;
case 11: case 43: case 90:
(void) strcat (names->symbols, "+se"); break;
case 12: case 44: case 91:
(void) strcat (names->symbols, "+fr_CH"); break;
case 13: case 45: case 92:
(void) strcat (names->symbols, "+de_CH"); break;
case 14: case 46: case 93:
(void) strcat (names->symbols, "+gb"); break;
case 52:
(void) strcat (names->symbols, "+pl"); break;
case 53:
(void) strcat (names->symbols, "+cs"); break;
case 54:
(void) strcat (names->symbols, "+ru"); break;
#if 0
case 2:
(void) strcat (names->symbols, "+fr_BE"); break;
case 7: case 39: case 86:
(void) strcat (names->symbols, "+nl"); break;
case 50: case 97:
(void) strcat (names->symbols, "+fr_CA"); break;
case 16: case 47: case 94:
(void) strcat (names->symbols, "+ko"); break;
case 17: case 48: case 95:
(void) strcat (names->symbols, "+tw"); break;
case 32: case 49: case 96:
(void) strcat (names->symbols, "+jp"); break;
case 51:
(void) strcat (names->symbols, "+hu"); break;
#endif
default:
names->symbols = NULL; return; break;
}
}
}
#endif
int sunKbdProc (
DeviceIntPtr device,
int what)
{
static int once;
static struct termio kbdtty;
struct termio tty;
int i;
DevicePtr pKeyboard = (DevicePtr) device;
sunKbdPrivPtr pPriv;
KeybdCtrl* ctrl = &device->kbdfeed->ctrl;
extern int XkbDfltRepeatDelay, XkbDfltRepeatInterval;
static CARD8 *workingModMap = NULL;
static KeySymsRec *workingKeySyms;
switch (what) {
case DEVICE_INIT:
if (pKeyboard != LookupKeyboardDevice()) {
ErrorF ("Cannot open non-system keyboard\n");
return (!Success);
}
if (!workingKeySyms) {
workingKeySyms = &sunKeySyms[sunKbdPriv.type];
if (sunKbdPriv.type == KB_SUN4 && sunSwapLkeys)
SwapLKeys(workingKeySyms);
if (workingKeySyms->minKeyCode < MIN_KEYCODE) {
workingKeySyms->minKeyCode += MIN_KEYCODE;
workingKeySyms->maxKeyCode += MIN_KEYCODE;
}
if (workingKeySyms->maxKeyCode > MAX_KEYCODE)
workingKeySyms->maxKeyCode = MAX_KEYCODE;
}
if (!workingModMap) {
workingModMap=(CARD8 *)xalloc(MAP_LENGTH);
(void) memset(workingModMap, 0, MAP_LENGTH);
for(i=0; sunModMaps[sunKbdPriv.type][i].key != 0; i++)
workingModMap[sunModMaps[sunKbdPriv.type][i].key + MIN_KEYCODE] =
sunModMaps[sunKbdPriv.type][i].modifiers;
}
(void) memset ((void *) defaultKeyboardControl.autoRepeats,
~0, sizeof defaultKeyboardControl.autoRepeats);
#ifdef XKB
if (noXkbExtension) {
sunAutoRepeatInitiate = XkbDfltRepeatDelay * 1000;
sunAutoRepeatDelay = XkbDfltRepeatInterval * 1000;
#endif
autoRepeatKeyDown = 0;
#ifdef XKB
}
#endif
pKeyboard->devicePrivate = (pointer)&sunKbdPriv;
pKeyboard->on = FALSE;
#ifdef XKB
if (noXkbExtension) {
#endif
InitKeyboardDeviceStruct(pKeyboard,
workingKeySyms, workingModMap,
sunBell, sunKbdCtrl);
#ifdef XKB
} else {
XkbComponentNamesRec names;
sunInitKbdNames (&names, &sunKbdPriv);
XkbInitKeyboardDeviceStruct((DeviceIntPtr) pKeyboard, &names,
workingKeySyms, workingModMap,
sunBell, sunKbdCtrl);
}
#endif
break;
case DEVICE_ON:
pPriv = (sunKbdPrivPtr)pKeyboard->devicePrivate;
if (sunChangeKbdTranslation(pPriv->fd, TRUE) == -1)
FatalError("Can't set keyboard translation\n");
if (!once)
{
ioctl(pPriv->fd, TCGETA, &kbdtty);
once = 1;
}
tty = kbdtty;
tty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
tty.c_oflag = 0;
tty.c_cflag = CREAD | CS8;
tty.c_lflag = 0;
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 0;
if (ioctl(pPriv->fd, TCSETAW, &tty) < 0)
perror("ioctl TCSETAW");
AddEnabledDevice(pPriv->fd);
pKeyboard->on = TRUE;
break;
case DEVICE_CLOSE:
case DEVICE_OFF:
pPriv = (sunKbdPrivPtr)pKeyboard->devicePrivate;
if (pPriv->type == KB_SUN4) {
pPriv->leds = 0;
ctrl->leds = 0;
SetLights(ctrl, pPriv->fd);
}
if (sunChangeKbdTranslation(pPriv->fd,FALSE) == -1)
FatalError("Can't reset keyboard translation\n");
if (ioctl(pPriv->fd, TCSETAW, &kbdtty) < 0)
perror("ioctl TCSETAW");
pKeyboard->on = FALSE;
RemoveEnabledDevice(pPriv->fd);
break;
default:
FatalError("Unknown keyboard operation\n");
}
return Success;
}
Firm_event* sunKbdGetEvents (
int fd,
Bool on,
int* pNumEvents,
Bool* pAgain)
{
int nBytes;
static Firm_event evBuf[MAXEVENTS];
char buf[64];
if ((nBytes = read(fd, buf, sizeof(buf))) == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
{
*pNumEvents = 0;
if (errno == EINTR)
*pAgain = TRUE;
else
*pAgain = FALSE;
} else {
Error ("Reading keyboard");
FatalError ("Could not read the keyboard");
}
} else {
int i;
struct timeval now;
if (on) {
X_GETTIMEOFDAY(&now);
*pNumEvents = nBytes;
*pAgain = (nBytes == sizeof(buf));
for (i = 0; i < nBytes; i++)
{
evBuf[i].id = buf[i] & 0x7f;
evBuf[i].value = (buf[i] & 0x80) ? VKEY_UP : VKEY_DOWN;
evBuf[i].time = now;
}
} else {
*pNumEvents = 0;
*pAgain = FALSE;
}
}
return evBuf;
}
static xEvent autoRepeatEvent;
static int composeCount;
static Bool DoSpecialKeys(device, xE, fe)
DeviceIntPtr device;
xEvent* xE;
Firm_event* fe;
{
int shift_index, map_index, bit;
KeySym ksym;
BYTE* kptr;
sunKbdPrivPtr pPriv = (sunKbdPrivPtr)device->public.devicePrivate;
BYTE keycode = xE->u.u.detail;
CARD8 keyModifiers = device->key->modifierMap[keycode];
shift_index = 0;
if (device->key->state & ShiftMask)
shift_index ^= 1;
if (device->key->state & LockMask)
shift_index ^= 1;
map_index = (fe->id - 1) * device->key->curKeySyms.mapWidth;
ksym = device->key->curKeySyms.map[shift_index + map_index];
if (ksym == NoSymbol)
ksym = device->key->curKeySyms.map[map_index];
if (xE->u.u.type == KeyRelease
&& (ksym == XK_Num_Lock
|| ksym == XK_Scroll_Lock
|| ksym == SunXK_Compose
|| (keyModifiers & LockMask)))
return TRUE;
kptr = &device->key->down[keycode >> 3];
bit = 1 << (keycode & 7);
if ((*kptr & bit) &&
(ksym == XK_Num_Lock || ksym == XK_Scroll_Lock ||
ksym == SunXK_Compose || (keyModifiers & LockMask)))
xE->u.u.type = KeyRelease;
if (pPriv->type == KB_SUN4) {
if (ksym == XK_Num_Lock) {
ModLight (device, xE->u.u.type == KeyPress, XLED_NUM_LOCK);
} else if (ksym == XK_Scroll_Lock) {
ModLight (device, xE->u.u.type == KeyPress, XLED_SCROLL_LOCK);
} else if (ksym == SunXK_Compose) {
ModLight (device, xE->u.u.type == KeyPress, XLED_COMPOSE);
if (xE->u.u.type == KeyPress) composeCount = 2;
else composeCount = 0;
} else if (keyModifiers & LockMask) {
ModLight (device, xE->u.u.type == KeyPress, XLED_CAPS_LOCK);
}
if (xE->u.u.type == KeyRelease) {
if (composeCount > 0 && --composeCount == 0) {
pseudoKey(device, FALSE,
LookupKeyCode(SunXK_Compose, &device->key->curKeySyms));
ModLight (device, FALSE, XLED_COMPOSE);
}
}
}
if ((xE->u.u.type == KeyPress) && (keyModifiers == 0)) {
autoRepeatEvent = *xE;
autoRepeatFirst = TRUE;
autoRepeatKeyDown++;
autoRepeatLastKeyDownTv = fe->time;
}
return FALSE;
}
void sunKbdEnqueueEvent (
DeviceIntPtr device,
Firm_event *fe)
{
xEvent xE;
BYTE keycode;
CARD8 keyModifiers;
keycode = (fe->id & 0x7f) + MIN_KEYCODE;
keyModifiers = device->key->modifierMap[keycode];
#ifdef XKB
if (noXkbExtension) {
#endif
if (autoRepeatKeyDown && (keyModifiers == 0) &&
((fe->value == VKEY_DOWN) || (keycode == autoRepeatEvent.u.u.detail))) {
autoRepeatKeyDown = 0;
}
#ifdef XKB
}
#endif
xE.u.keyButtonPointer.time = TVTOMILLI(fe->time);
xE.u.u.type = ((fe->value == VKEY_UP) ? KeyRelease : KeyPress);
xE.u.u.detail = keycode;
#ifdef XKB
if (noXkbExtension) {
#endif
if (DoSpecialKeys(device, &xE, fe))
return;
#ifdef XKB
}
#endif
mieqEnqueue (&xE);
}
void sunEnqueueAutoRepeat ()
{
int delta;
int i, mask;
DeviceIntPtr device = (DeviceIntPtr)LookupKeyboardDevice();
KeybdCtrl* ctrl = &device->kbdfeed->ctrl;
sunKbdPrivPtr pPriv = (sunKbdPrivPtr) device->public.devicePrivate;
if (ctrl->autoRepeat != AutoRepeatModeOn) {
autoRepeatKeyDown = 0;
return;
}
i=(autoRepeatEvent.u.u.detail >> 3);
mask=(1 << (autoRepeatEvent.u.u.detail & 7));
if (!(ctrl->autoRepeats[i] & mask)) {
autoRepeatKeyDown = 0;
return;
}
delta = TVTOMILLI(autoRepeatDeltaTv);
autoRepeatFirst = FALSE;
autoRepeatEvent.u.keyButtonPointer.time += delta;
autoRepeatEvent.u.u.type = KeyRelease;
sunEnqueueEvent (&autoRepeatEvent);
autoRepeatEvent.u.u.type = KeyPress;
sunEnqueueEvent (&autoRepeatEvent);
if (ctrl->click) bell (pPriv->fd, 0);
tvplus(autoRepeatLastKeyDownTv, autoRepeatLastKeyDownTv,
autoRepeatDeltaTv);
}
int sunChangeKbdTranslation(
int fd,
Bool makeTranslated)
{
int tmp;
sigset_t hold_mask, old_mask;
int toread;
char junk[8192];
(void) sigfillset(&hold_mask);
(void) sigprocmask(SIG_BLOCK, &hold_mask, &old_mask);
if (makeTranslated) {
if (ioctl (fd, TIO_ENSCANMODE, &tmp) == -1) {
Error ("Setting keyboard translation TIO_ENSCANMODE");
ErrorF ("sunChangeKbdTranslation: kbdFd=%d\n", fd);
return -1;
}
} else {
if (ioctl (fd, TIO_DISSCANMODE, &tmp) == -1) {
Error ("Setting keyboard translation TIO_DISSCANMODE");
ErrorF ("sunChangeKbdTranslation: kbdFd=%d\n", fd);
}
}
if (ioctl (fd, FIONREAD, &toread) != -1 && toread > 0) {
while (toread) {
tmp = toread;
if (toread > sizeof (junk))
tmp = sizeof (junk);
(void) read (fd, junk, tmp);
toread -= tmp;
}
}
(void) sigprocmask(SIG_SETMASK, &old_mask, (sigset_t *)NULL);
return 0;
}
Bool LegalModifier(key, pDev)
unsigned int key;
DevicePtr pDev;
{
return TRUE;
}
void sunBlockHandler(nscreen, pbdata, pptv, pReadmask)
int nscreen;
pointer pbdata;
struct timeval **pptv;
pointer pReadmask;
{
KeybdCtrl* ctrl = &((DeviceIntPtr)LookupKeyboardDevice())->kbdfeed->ctrl;
static struct timeval artv = { 0, 0 };
if (!autoRepeatKeyDown)
return;
if (ctrl->autoRepeat != AutoRepeatModeOn)
return;
if (autoRepeatFirst == TRUE)
artv.tv_usec = sunAutoRepeatInitiate;
else
artv.tv_usec = sunAutoRepeatDelay;
*pptv = &artv;
}
void sunWakeupHandler(nscreen, pbdata, err, pReadmask)
int nscreen;
pointer pbdata;
unsigned long err;
pointer pReadmask;
{
KeybdCtrl* ctrl = &((DeviceIntPtr)LookupKeyboardDevice())->kbdfeed->ctrl;
struct timeval tv;
struct fd_set devicesWithInput;
struct fd_set device;
extern struct fd_set EnabledDevices;
XFD_ANDSET(&devicesWithInput, ((struct fd_set *) pReadmask), &EnabledDevices);
FD_ZERO(&device);
FD_SET(sunPtrPriv.fd, &device);
XFD_ANDSET(&device, &device, &devicesWithInput);
if (XFD_ANYSET(&device)) {
sigset_t newsigmask;
(void) sigemptyset (&newsigmask);
(void) sigaddset (&newsigmask, SIGIO);
(void) sigprocmask (SIG_BLOCK, &newsigmask, (sigset_t *)NULL);
sunEnqueueMseEvents();
(void) sigprocmask (SIG_UNBLOCK, &newsigmask, (sigset_t *)NULL);
}
#ifdef XKB
if (!noXkbExtension)
return;
#endif
if (ctrl->autoRepeat != AutoRepeatModeOn)
return;
if (autoRepeatKeyDown) {
X_GETTIMEOFDAY(&tv);
tvminus(autoRepeatDeltaTv, tv, autoRepeatLastKeyDownTv);
if (autoRepeatDeltaTv.tv_sec > 0 ||
(!autoRepeatFirst && autoRepeatDeltaTv.tv_usec >
sunAutoRepeatDelay) ||
(autoRepeatDeltaTv.tv_usec >
sunAutoRepeatInitiate))
autoRepeatReady++;
}
if (autoRepeatReady)
{
sunEnqueueAutoRepeat ();
autoRepeatReady = 0;
}
}