1b9325ec5Stsutsui/* $Xorg: sunKbd.c,v 1.3 2000/08/17 19:48:30 cpqbld Exp $ */ 2b9325ec5Stsutsui/*- 3b9325ec5Stsutsui * Copyright 1987 by the Regents of the University of California 4b9325ec5Stsutsui * 5b9325ec5Stsutsui * Permission to use, copy, modify, and distribute this 6b9325ec5Stsutsui * software and its documentation for any purpose and without 7b9325ec5Stsutsui * fee is hereby granted, provided that the above copyright 8b9325ec5Stsutsui * notice appear in all copies. The University of California 9b9325ec5Stsutsui * makes no representations about the suitability of this 10b9325ec5Stsutsui * software for any purpose. It is provided "as is" without 11b9325ec5Stsutsui * express or implied warranty. 12b9325ec5Stsutsui */ 13b9325ec5Stsutsui 14b9325ec5Stsutsui/************************************************************ 15b9325ec5StsutsuiCopyright 1987 by Sun Microsystems, Inc. Mountain View, CA. 16b9325ec5Stsutsui 17b9325ec5Stsutsui All Rights Reserved 18b9325ec5Stsutsui 19b9325ec5StsutsuiPermission to use, copy, modify, and distribute this 20b9325ec5Stsutsuisoftware and its documentation for any purpose and without 21b9325ec5Stsutsuifee is hereby granted, provided that the above copyright no- 22b9325ec5Stsutsuitice appear in all copies and that both that copyright no- 23b9325ec5Stsutsuitice and this permission notice appear in supporting docu- 24b9325ec5Stsutsuimentation, and that the names of Sun or The Open Group 25b9325ec5Stsutsuinot be used in advertising or publicity pertaining to 26b9325ec5Stsutsuidistribution of the software without specific prior 27b9325ec5Stsutsuiwritten permission. Sun and The Open Group make no 28b9325ec5Stsutsuirepresentations about the suitability of this software for 29b9325ec5Stsutsuiany purpose. It is provided "as is" without any express or 30b9325ec5Stsutsuiimplied warranty. 31b9325ec5Stsutsui 32b9325ec5StsutsuiSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 33b9325ec5StsutsuiINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- 34b9325ec5StsutsuiNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- 35b9325ec5StsutsuiABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 36b9325ec5StsutsuiANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 37b9325ec5StsutsuiPROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 38b9325ec5StsutsuiOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 39b9325ec5StsutsuiTHE USE OR PERFORMANCE OF THIS SOFTWARE. 40b9325ec5Stsutsui 41b9325ec5Stsutsui********************************************************/ 42b9325ec5Stsutsui/* $XFree86: xc/programs/Xserver/hw/sun/sunKbd.c,v 1.9 2003/11/17 22:20:36 dawes Exp $ */ 43b9325ec5Stsutsui 44b9325ec5Stsutsui#define NEED_EVENTS 45b9325ec5Stsutsui#include "sun.h" 46b9325ec5Stsutsui#include <X11/keysym.h> 47b9325ec5Stsutsui#include <X11/Sunkeysym.h> 48b9325ec5Stsutsui#include "mi.h" 49b9325ec5Stsutsui 50b9325ec5Stsutsui#include <X11/extensions/XKB.h> 51b9325ec5Stsutsui#include "xkbsrv.h" 52b9325ec5Stsutsui#include "xkbstr.h" 53b9325ec5Stsutsui 54cb17d216Stsutsui#ifdef __sun 55b9325ec5Stsutsui#define SUN_LED_MASK 0x0f 56cb17d216Stsutsui#else 57cb17d216Stsutsui#define SUN_LED_MASK 0x07 58cb17d216Stsutsui#endif 59b9325ec5Stsutsui#define MIN_KEYCODE 7 /* necessary to avoid the mouse buttons */ 60b9325ec5Stsutsui#define MAX_KEYCODE 255 /* limited by the protocol */ 61cb17d216Stsutsui#define NUM_KEYCODES (MAX_KEYCODE - MIN_KEYCODE + 1) 62b9325ec5Stsutsui#ifndef KB_SUN4 63b9325ec5Stsutsui#define KB_SUN4 4 64b9325ec5Stsutsui#endif 65b9325ec5Stsutsui 66cb17d216Stsutsui#define Meta_Mask Mod1Mask 67cb17d216Stsutsui#define Mode_switch_Mask Mod2Mask 68cb17d216Stsutsui#define Alt_Mask Mod3Mask 69cb17d216Stsutsui#define Num_Lock_Mask Mod4Mask 70cb17d216Stsutsui#define ScrollLockMask Mod5Mask 71cb17d216Stsutsui 72b9325ec5Stsutsui#define tvminus(tv, tv1, tv2) /* tv = tv1 - tv2 */ \ 73b9325ec5Stsutsui if ((tv1).tv_usec < (tv2).tv_usec) { \ 74b9325ec5Stsutsui (tv1).tv_usec += 1000000; \ 75b9325ec5Stsutsui (tv1).tv_sec -= 1; \ 76b9325ec5Stsutsui } \ 77b9325ec5Stsutsui (tv).tv_usec = (tv1).tv_usec - (tv2).tv_usec; \ 78b9325ec5Stsutsui (tv).tv_sec = (tv1).tv_sec - (tv2).tv_sec; 79b9325ec5Stsutsui 80b9325ec5Stsutsui#define tvplus(tv, tv1, tv2) /* tv = tv1 + tv2 */ \ 81b9325ec5Stsutsui (tv).tv_sec = (tv1).tv_sec + (tv2).tv_sec; \ 82b9325ec5Stsutsui (tv).tv_usec = (tv1).tv_usec + (tv2).tv_usec; \ 83b9325ec5Stsutsui if ((tv).tv_usec > 1000000) { \ 84b9325ec5Stsutsui (tv).tv_usec -= 1000000; \ 85b9325ec5Stsutsui (tv).tv_sec += 1; \ 86b9325ec5Stsutsui } 87b9325ec5Stsutsui 88cb17d216Stsutsuistatic void sunInitModMap(const KeySymsRec *, CARD8 *); 89b9325ec5Stsutsuistatic void SwapLKeys(KeySymsRec *); 90b9325ec5Stsutsuistatic void SetLights(KeybdCtrl *, int); 91b9325ec5Stsutsuistatic KeyCode LookupKeyCode(KeySym, XkbDescPtr, KeySymsPtr); 92b9325ec5Stsutsuistatic void pseudoKey(DeviceIntPtr, Bool, KeyCode); 93b9325ec5Stsutsuistatic void DoLEDs(DeviceIntPtr, KeybdCtrl *, sunKbdPrivPtr); 94b9325ec5Stsutsui 95b9325ec5StsutsuiDeviceIntPtr sunKeyboardDevice = NULL; 96b9325ec5Stsutsui 97b9325ec5Stsutsuivoid 98b9325ec5StsutsuisunKbdWait(void) 99b9325ec5Stsutsui{ 100b9325ec5Stsutsui static struct timeval lastChngKbdTransTv; 101b9325ec5Stsutsui struct timeval tv; 102b9325ec5Stsutsui struct timeval lastChngKbdDeltaTv; 103b9325ec5Stsutsui unsigned int lastChngKbdDelta; 104b9325ec5Stsutsui 105b9325ec5Stsutsui X_GETTIMEOFDAY(&tv); 106b9325ec5Stsutsui if (!lastChngKbdTransTv.tv_sec) 107b9325ec5Stsutsui lastChngKbdTransTv = tv; 108b9325ec5Stsutsui tvminus(lastChngKbdDeltaTv, tv, lastChngKbdTransTv); 109b9325ec5Stsutsui lastChngKbdDelta = TVTOMILLI(lastChngKbdDeltaTv); 110b9325ec5Stsutsui if (lastChngKbdDelta < 750) { 111b9325ec5Stsutsui unsigned wait; 112b9325ec5Stsutsui /* 113b9325ec5Stsutsui * We need to guarantee at least 750 milliseconds between 114b9325ec5Stsutsui * calls to KIOCTRANS. YUCK! 115b9325ec5Stsutsui */ 116b9325ec5Stsutsui wait = (750L - lastChngKbdDelta) * 1000L; 117b9325ec5Stsutsui usleep (wait); 118b9325ec5Stsutsui X_GETTIMEOFDAY(&tv); 119b9325ec5Stsutsui } 120b9325ec5Stsutsui lastChngKbdTransTv = tv; 121b9325ec5Stsutsui} 122b9325ec5Stsutsui 123b9325ec5Stsutsuistatic 124b9325ec5Stsutsuivoid SwapLKeys(KeySymsRec* keysyms) 125b9325ec5Stsutsui{ 126b9325ec5Stsutsui unsigned int i; 127b9325ec5Stsutsui KeySym k; 128b9325ec5Stsutsui 129b9325ec5Stsutsui for (i = 2; i < keysyms->maxKeyCode * keysyms->mapWidth; i++) 130b9325ec5Stsutsui if (keysyms->map[i] == XK_L1 || 131b9325ec5Stsutsui keysyms->map[i] == XK_L2 || 132b9325ec5Stsutsui keysyms->map[i] == XK_L3 || 133b9325ec5Stsutsui keysyms->map[i] == XK_L4 || 134b9325ec5Stsutsui keysyms->map[i] == XK_L5 || 135b9325ec5Stsutsui keysyms->map[i] == XK_L6 || 136b9325ec5Stsutsui keysyms->map[i] == XK_L7 || 137b9325ec5Stsutsui keysyms->map[i] == XK_L8 || 138b9325ec5Stsutsui keysyms->map[i] == XK_L9 || 139b9325ec5Stsutsui keysyms->map[i] == XK_L10) { 140b9325ec5Stsutsui /* yes, I could have done a clever two line swap! */ 141b9325ec5Stsutsui k = keysyms->map[i - 2]; 142b9325ec5Stsutsui keysyms->map[i - 2] = keysyms->map[i]; 143b9325ec5Stsutsui keysyms->map[i] = k; 144b9325ec5Stsutsui } 145b9325ec5Stsutsui} 146b9325ec5Stsutsui 147b9325ec5Stsutsuistatic void 148b9325ec5StsutsuiSetLights(KeybdCtrl* ctrl, int fd) 149b9325ec5Stsutsui{ 150b9325ec5Stsutsui#ifdef KIOCSLED 151b9325ec5Stsutsui static unsigned char led_tab[16] = { 152b9325ec5Stsutsui 0, 153cb17d216Stsutsui#ifdef __sun 154b9325ec5Stsutsui LED_NUM_LOCK, 155b9325ec5Stsutsui LED_SCROLL_LOCK, 156b9325ec5Stsutsui LED_SCROLL_LOCK | LED_NUM_LOCK, 157b9325ec5Stsutsui LED_COMPOSE, 158b9325ec5Stsutsui LED_COMPOSE | LED_NUM_LOCK, 159b9325ec5Stsutsui LED_COMPOSE | LED_SCROLL_LOCK, 160b9325ec5Stsutsui LED_COMPOSE | LED_SCROLL_LOCK | LED_NUM_LOCK, 161b9325ec5Stsutsui LED_CAPS_LOCK, 162b9325ec5Stsutsui LED_CAPS_LOCK | LED_NUM_LOCK, 163b9325ec5Stsutsui LED_CAPS_LOCK | LED_SCROLL_LOCK, 164b9325ec5Stsutsui LED_CAPS_LOCK | LED_SCROLL_LOCK | LED_NUM_LOCK, 165b9325ec5Stsutsui LED_CAPS_LOCK | LED_COMPOSE, 166b9325ec5Stsutsui LED_CAPS_LOCK | LED_COMPOSE | LED_NUM_LOCK, 167b9325ec5Stsutsui LED_CAPS_LOCK | LED_COMPOSE | LED_SCROLL_LOCK, 168b9325ec5Stsutsui LED_CAPS_LOCK | LED_COMPOSE | LED_SCROLL_LOCK | LED_NUM_LOCK 169cb17d216Stsutsui#else 170cb17d216Stsutsui LED_CAPS_LOCK, 171cb17d216Stsutsui LED_NUM_LOCK, 172cb17d216Stsutsui LED_NUM_LOCK | LED_CAPS_LOCK, 173cb17d216Stsutsui LED_SCROLL_LOCK, 174cb17d216Stsutsui LED_SCROLL_LOCK | LED_CAPS_LOCK, 175cb17d216Stsutsui LED_SCROLL_LOCK | LED_NUM_LOCK, 176cb17d216Stsutsui LED_SCROLL_LOCK | LED_NUM_LOCK | LED_CAPS_LOCK, 177cb17d216Stsutsui LED_COMPOSE, 178cb17d216Stsutsui LED_COMPOSE | LED_CAPS_LOCK, 179cb17d216Stsutsui LED_COMPOSE | LED_NUM_LOCK, 180cb17d216Stsutsui LED_COMPOSE | LED_NUM_LOCK | LED_CAPS_LOCK, 181cb17d216Stsutsui LED_COMPOSE | LED_SCROLL_LOCK, 182cb17d216Stsutsui LED_COMPOSE | LED_SCROLL_LOCK | LED_CAPS_LOCK, 183cb17d216Stsutsui LED_COMPOSE | LED_SCROLL_LOCK | LED_NUM_LOCK, 184cb17d216Stsutsui LED_COMPOSE | LED_SCROLL_LOCK | LED_NUM_LOCK | LED_CAPS_LOCK, 185cb17d216Stsutsui#endif 186b9325ec5Stsutsui }; 187cb17d216Stsutsui if (ioctl (fd, KIOCSLED, (caddr_t)&led_tab[ctrl->leds & SUN_LED_MASK]) == -1) 188cb17d216Stsutsui ErrorF("Failed to set keyboard lights"); 189b9325ec5Stsutsui#endif 190b9325ec5Stsutsui} 191b9325ec5Stsutsui 192b9325ec5Stsutsui 193b9325ec5Stsutsui/*- 194b9325ec5Stsutsui *----------------------------------------------------------------------- 195b9325ec5Stsutsui * sunBell -- 196b9325ec5Stsutsui * Ring the terminal/keyboard bell 197b9325ec5Stsutsui * 198b9325ec5Stsutsui * Results: 199b9325ec5Stsutsui * Ring the keyboard bell for an amount of time proportional to 200b9325ec5Stsutsui * "loudness." 201b9325ec5Stsutsui * 202b9325ec5Stsutsui * Side Effects: 203b9325ec5Stsutsui * None, really... 204b9325ec5Stsutsui * 205b9325ec5Stsutsui *----------------------------------------------------------------------- 206b9325ec5Stsutsui */ 207b9325ec5Stsutsui 208b9325ec5Stsutsuistatic void 209b9325ec5Stsutsuibell(int fd, int duration) 210b9325ec5Stsutsui{ 211b9325ec5Stsutsui int kbdCmd; /* Command to give keyboard */ 212b9325ec5Stsutsui 213b9325ec5Stsutsui kbdCmd = KBD_CMD_BELL; 214b9325ec5Stsutsui if (ioctl (fd, KIOCCMD, &kbdCmd) == -1) { 215b9325ec5Stsutsui Error("Failed to activate bell"); 216b9325ec5Stsutsui return; 217b9325ec5Stsutsui } 218b9325ec5Stsutsui if (duration) usleep (duration); 219b9325ec5Stsutsui kbdCmd = KBD_CMD_NOBELL; 220b9325ec5Stsutsui if (ioctl (fd, KIOCCMD, &kbdCmd) == -1) 221b9325ec5Stsutsui Error ("Failed to deactivate bell"); 222b9325ec5Stsutsui} 223b9325ec5Stsutsui 224b9325ec5Stsutsuistatic void 225b9325ec5StsutsuisunBell(int percent, DeviceIntPtr device, pointer ctrl, int unused) 226b9325ec5Stsutsui{ 227b9325ec5Stsutsui KeybdCtrl* kctrl = (KeybdCtrl*) ctrl; 228b9325ec5Stsutsui sunKbdPrivPtr pPriv = (sunKbdPrivPtr) device->public.devicePrivate; 229b9325ec5Stsutsui 230b9325ec5Stsutsui if (percent == 0 || kctrl->bell == 0) 231b9325ec5Stsutsui return; 232b9325ec5Stsutsui 233b9325ec5Stsutsui bell (pPriv->fd, kctrl->bell_duration * 1000); 234b9325ec5Stsutsui} 235b9325ec5Stsutsui 236b9325ec5Stsutsuivoid 237b9325ec5StsutsuiDDXRingBell(int volume, int pitch, int duration) 238b9325ec5Stsutsui{ 239b9325ec5Stsutsui DeviceIntPtr pKeyboard; 240b9325ec5Stsutsui sunKbdPrivPtr pPriv; 241b9325ec5Stsutsui 242b9325ec5Stsutsui pKeyboard = sunKeyboardDevice; 243b9325ec5Stsutsui if (pKeyboard != NULL) { 244b9325ec5Stsutsui pPriv = (sunKbdPrivPtr)pKeyboard->public.devicePrivate; 245b9325ec5Stsutsui bell(pPriv->fd, duration * 1000); 246b9325ec5Stsutsui } 247b9325ec5Stsutsui} 248b9325ec5Stsutsui 249b9325ec5Stsutsui 250cb17d216Stsutsui#ifdef __sun 251b9325ec5Stsutsui#define XLED_NUM_LOCK 0x1 252b9325ec5Stsutsui#define XLED_COMPOSE 0x4 253b9325ec5Stsutsui#define XLED_SCROLL_LOCK 0x2 254b9325ec5Stsutsui#define XLED_CAPS_LOCK 0x8 255cb17d216Stsutsui#else 256cb17d216Stsutsui#define XLED_NUM_LOCK 0x2 257cb17d216Stsutsui#define XLED_COMPOSE 0x8 258cb17d216Stsutsui#define XLED_SCROLL_LOCK 0x4 259cb17d216Stsutsui#define XLED_CAPS_LOCK 0x1 260cb17d216Stsutsui#endif 261b9325ec5Stsutsui 262b9325ec5Stsutsuistatic KeyCode 263b9325ec5StsutsuiLookupKeyCode(KeySym keysym, XkbDescPtr xkb, KeySymsPtr syms) 264b9325ec5Stsutsui{ 265b9325ec5Stsutsui KeyCode i; 266b9325ec5Stsutsui int ii, index = 0; 267b9325ec5Stsutsui 268b9325ec5Stsutsui for (i = xkb->min_key_code; i < xkb->max_key_code; i++) 269b9325ec5Stsutsui for (ii = 0; ii < syms->mapWidth; ii++) 270b9325ec5Stsutsui if (syms->map[index++] == keysym) 271b9325ec5Stsutsui return i; 272b9325ec5Stsutsui return 0; 273b9325ec5Stsutsui} 274b9325ec5Stsutsui 275b9325ec5Stsutsuistatic void 276b9325ec5StsutsuipseudoKey(DeviceIntPtr device, Bool down, KeyCode keycode) 277b9325ec5Stsutsui{ 278b9325ec5Stsutsui int bit; 279b9325ec5Stsutsui CARD8 modifiers; 280b9325ec5Stsutsui CARD16 mask; 281b9325ec5Stsutsui BYTE* kptr; 282b9325ec5Stsutsui 283b9325ec5Stsutsui kptr = &device->key->down[keycode >> 3]; 284b9325ec5Stsutsui bit = 1 << (keycode & 7); 285b9325ec5Stsutsui modifiers = device->key->xkbInfo->desc->map->modmap[keycode]; 286b9325ec5Stsutsui if (down) { 287b9325ec5Stsutsui /* fool dix into thinking this key is now "down" */ 288b9325ec5Stsutsui int i; 289b9325ec5Stsutsui *kptr |= bit; 290b9325ec5Stsutsui for (i = 0, mask = 1; modifiers; i++, mask <<= 1) 291b9325ec5Stsutsui if (mask & modifiers) { 292b9325ec5Stsutsui device->key->modifierKeyCount[i]++; 293b9325ec5Stsutsui modifiers &= ~mask; 294b9325ec5Stsutsui } 295b9325ec5Stsutsui } else { 296b9325ec5Stsutsui /* fool dix into thinking this key is now "up" */ 297b9325ec5Stsutsui if (*kptr & bit) { 298b9325ec5Stsutsui int i; 299b9325ec5Stsutsui *kptr &= ~bit; 300b9325ec5Stsutsui for (i = 0, mask = 1; modifiers; i++, mask <<= 1) 301b9325ec5Stsutsui if (mask & modifiers) { 302b9325ec5Stsutsui if (--device->key->modifierKeyCount[i] <= 0) { 303b9325ec5Stsutsui device->key->modifierKeyCount[i] = 0; 304b9325ec5Stsutsui } 305b9325ec5Stsutsui modifiers &= ~mask; 306b9325ec5Stsutsui } 307b9325ec5Stsutsui } 308b9325ec5Stsutsui } 309b9325ec5Stsutsui} 310b9325ec5Stsutsui 311b9325ec5Stsutsuistatic void 312b9325ec5StsutsuiDoLEDs( 313b9325ec5Stsutsui DeviceIntPtr device, /* Keyboard to alter */ 314b9325ec5Stsutsui KeybdCtrl* ctrl, 315b9325ec5Stsutsui sunKbdPrivPtr pPriv 316b9325ec5Stsutsui) 317b9325ec5Stsutsui{ 318b9325ec5Stsutsui XkbDescPtr xkb; 319b9325ec5Stsutsui KeySymsPtr syms; 320b9325ec5Stsutsui 321b9325ec5Stsutsui xkb = device->key->xkbInfo->desc; 322b9325ec5Stsutsui syms = XkbGetCoreMap(device); 323b9325ec5Stsutsui if (!syms) 324b9325ec5Stsutsui return; /* XXX */ 325b9325ec5Stsutsui 326b9325ec5Stsutsui if ((ctrl->leds & XLED_CAPS_LOCK) && !(pPriv->leds & XLED_CAPS_LOCK)) 327b9325ec5Stsutsui pseudoKey(device, TRUE, 328b9325ec5Stsutsui LookupKeyCode(XK_Caps_Lock, xkb, syms)); 329b9325ec5Stsutsui 330b9325ec5Stsutsui if (!(ctrl->leds & XLED_CAPS_LOCK) && (pPriv->leds & XLED_CAPS_LOCK)) 331b9325ec5Stsutsui pseudoKey(device, FALSE, 332b9325ec5Stsutsui LookupKeyCode(XK_Caps_Lock, xkb, syms)); 333b9325ec5Stsutsui 334b9325ec5Stsutsui if ((ctrl->leds & XLED_NUM_LOCK) && !(pPriv->leds & XLED_NUM_LOCK)) 335b9325ec5Stsutsui pseudoKey(device, TRUE, 336b9325ec5Stsutsui LookupKeyCode(XK_Num_Lock, xkb, syms)); 337b9325ec5Stsutsui 338b9325ec5Stsutsui if (!(ctrl->leds & XLED_NUM_LOCK) && (pPriv->leds & XLED_NUM_LOCK)) 339b9325ec5Stsutsui pseudoKey(device, FALSE, 340b9325ec5Stsutsui LookupKeyCode(XK_Num_Lock, xkb, syms)); 341b9325ec5Stsutsui 342b9325ec5Stsutsui if ((ctrl->leds & XLED_SCROLL_LOCK) && !(pPriv->leds & XLED_SCROLL_LOCK)) 343b9325ec5Stsutsui pseudoKey(device, TRUE, 344b9325ec5Stsutsui LookupKeyCode(XK_Scroll_Lock, xkb, syms)); 345b9325ec5Stsutsui 346b9325ec5Stsutsui if (!(ctrl->leds & XLED_SCROLL_LOCK) && (pPriv->leds & XLED_SCROLL_LOCK)) 347b9325ec5Stsutsui pseudoKey(device, FALSE, 348b9325ec5Stsutsui LookupKeyCode(XK_Scroll_Lock, xkb, syms)); 349b9325ec5Stsutsui 350b9325ec5Stsutsui if ((ctrl->leds & XLED_COMPOSE) && !(pPriv->leds & XLED_COMPOSE)) 351b9325ec5Stsutsui pseudoKey(device, TRUE, 352b9325ec5Stsutsui LookupKeyCode(SunXK_Compose, xkb, syms)); 353b9325ec5Stsutsui 354b9325ec5Stsutsui if (!(ctrl->leds & XLED_COMPOSE) && (pPriv->leds & XLED_COMPOSE)) 355b9325ec5Stsutsui pseudoKey(device, FALSE, 356b9325ec5Stsutsui LookupKeyCode(SunXK_Compose, xkb, syms)); 357b9325ec5Stsutsui 358cb17d216Stsutsui pPriv->leds = ctrl->leds & SUN_LED_MASK; 359b9325ec5Stsutsui SetLights (ctrl, pPriv->fd); 360b9325ec5Stsutsui xfree(syms->map); 361b9325ec5Stsutsui xfree(syms); 362b9325ec5Stsutsui} 363b9325ec5Stsutsui 364b9325ec5Stsutsui/*- 365b9325ec5Stsutsui *----------------------------------------------------------------------- 366b9325ec5Stsutsui * sunKbdCtrl -- 367b9325ec5Stsutsui * Alter some of the keyboard control parameters 368b9325ec5Stsutsui * 369b9325ec5Stsutsui * Results: 370b9325ec5Stsutsui * None. 371b9325ec5Stsutsui * 372b9325ec5Stsutsui * Side Effects: 373b9325ec5Stsutsui * Some... 374b9325ec5Stsutsui * 375b9325ec5Stsutsui *----------------------------------------------------------------------- 376b9325ec5Stsutsui */ 377b9325ec5Stsutsui 378b9325ec5Stsutsuistatic void 379b9325ec5StsutsuisunKbdCtrl(DeviceIntPtr device, KeybdCtrl* ctrl) 380b9325ec5Stsutsui{ 381b9325ec5Stsutsui sunKbdPrivPtr pPriv = (sunKbdPrivPtr) device->public.devicePrivate; 382b9325ec5Stsutsui 383b9325ec5Stsutsui if (pPriv->fd < 0) return; 384b9325ec5Stsutsui 385b9325ec5Stsutsui if (ctrl->click != pPriv->click) { 386b9325ec5Stsutsui int kbdClickCmd; 387b9325ec5Stsutsui 388b9325ec5Stsutsui pPriv->click = ctrl->click; 389b9325ec5Stsutsui kbdClickCmd = pPriv->click ? KBD_CMD_CLICK : KBD_CMD_NOCLICK; 390b9325ec5Stsutsui if (ioctl (pPriv->fd, KIOCCMD, &kbdClickCmd) == -1) 391b9325ec5Stsutsui Error("Failed to set keyclick"); 392b9325ec5Stsutsui } 393cb17d216Stsutsui if ((pPriv->type == KB_SUN4) && (pPriv->leds != (ctrl->leds & SUN_LED_MASK))) 394b9325ec5Stsutsui DoLEDs(device, ctrl, pPriv); 395b9325ec5Stsutsui} 396b9325ec5Stsutsui 397b9325ec5Stsutsui/*- 398b9325ec5Stsutsui *----------------------------------------------------------------------- 399b9325ec5Stsutsui * sunInitKbdNames -- 400b9325ec5Stsutsui * Handle the XKB initialization 401b9325ec5Stsutsui * 402b9325ec5Stsutsui * Results: 403b9325ec5Stsutsui * None. 404b9325ec5Stsutsui * 405b9325ec5Stsutsui * Comments: 406b9325ec5Stsutsui * This function needs considerable work, in conjunctions with 407b9325ec5Stsutsui * the need to add geometry descriptions of Sun Keyboards. 408b9325ec5Stsutsui * It would also be nice to have #defines for all the keyboard 409b9325ec5Stsutsui * layouts so that we don't have to have these hard-coded 410b9325ec5Stsutsui * numbers. 411b9325ec5Stsutsui * 412b9325ec5Stsutsui *----------------------------------------------------------------------- 413b9325ec5Stsutsui */ 414b9325ec5Stsutsuistatic void 415b9325ec5StsutsuisunInitKbdNames(XkbRMLVOSet *rmlvo, sunKbdPrivPtr pKbd) 416b9325ec5Stsutsui{ 417b9325ec5Stsutsui#if 0 /* XXX to be revisited later */ 418b9325ec5Stsutsui#ifndef XKBBUFSIZE 419b9325ec5Stsutsui#define XKBBUFSIZE 64 420b9325ec5Stsutsui#endif 421b9325ec5Stsutsui static char keycodesbuf[XKBBUFSIZE]; 422b9325ec5Stsutsui static char geometrybuf[XKBBUFSIZE]; 423b9325ec5Stsutsui static char symbolsbuf[XKBBUFSIZE]; 424b9325ec5Stsutsui 425b9325ec5Stsutsui names->keymap = NULL; 426b9325ec5Stsutsui names->compat = "compat/complete"; 427b9325ec5Stsutsui names->types = "types/complete"; 428b9325ec5Stsutsui names->keycodes = keycodesbuf; 429b9325ec5Stsutsui names->geometry = geometrybuf; 430b9325ec5Stsutsui names->symbols = symbolsbuf; 431b9325ec5Stsutsui (void) strcpy (keycodesbuf, "keycodes/"); 432b9325ec5Stsutsui (void) strcpy (geometrybuf, "geometry/"); 433b9325ec5Stsutsui (void) strcpy (symbolsbuf, "symbols/"); 434b9325ec5Stsutsui 435b9325ec5Stsutsui /* keycodes & geometry */ 436b9325ec5Stsutsui switch (pKbd->type) { 437b9325ec5Stsutsui case KB_SUN2: 438b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(type2)"); 439b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type2)"); 440b9325ec5Stsutsui (void) strcat (names->symbols, "us(sun2)"); 441b9325ec5Stsutsui break; 442b9325ec5Stsutsui case KB_SUN3: 443b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(type3)"); 444b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type3)"); 445b9325ec5Stsutsui (void) strcat (names->symbols, "us(sun3)"); 446b9325ec5Stsutsui break; 447b9325ec5Stsutsui case KB_SUN4: 448b9325ec5Stsutsui /* First, catch "fully known" models */ 449b9325ec5Stsutsui switch (pKbd->layout) { 450b9325ec5Stsutsui case 11: /* type4, Sweden */ 451b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type4_se)"); 452b9325ec5Stsutsui (void) strcat (names->keycodes, 453b9325ec5Stsutsui "sun(type4_se_swapctl)"); 454b9325ec5Stsutsui (void) strcat (names->symbols, 455b9325ec5Stsutsui "sun/se(sun4)+se(fixdollar)"); 456b9325ec5Stsutsui return; 457b9325ec5Stsutsui break; 458b9325ec5Stsutsui case 43: /* type5/5c, Sweden */ 459b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type5c_se)"); 460b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(type5_se)"); 461b9325ec5Stsutsui (void) strcat (names->symbols, 462b9325ec5Stsutsui "sun/se(sun5)+se(fixdollar)"); 463b9325ec5Stsutsui return; 464b9325ec5Stsutsui break; 465b9325ec5Stsutsui case 90: /* "Compact 1", Sweden (???) */ 466b9325ec5Stsutsui break; /* No specific mapping, yet */ 467b9325ec5Stsutsui default: 468b9325ec5Stsutsui break; 469b9325ec5Stsutsui } 470b9325ec5Stsutsui 471b9325ec5Stsutsui if (pKbd->layout == 19) { 472b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(US101A)"); 473b9325ec5Stsutsui (void) strcat (names->geometry, "pc101-NG"); /* XXX */ 474b9325ec5Stsutsui (void) strcat (names->symbols, "us(pc101)"); 475b9325ec5Stsutsui } else if (pKbd->layout < 33) { 476b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(type4)"); 477b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type4)"); 478b9325ec5Stsutsui if (sunSwapLkeys) 479b9325ec5Stsutsui (void) strcat (names->symbols, "sun/us(sun4ol)"); 480b9325ec5Stsutsui else 481b9325ec5Stsutsui (void) strcat (names->symbols, "sun/us(sun4)"); 482b9325ec5Stsutsui } else { 483b9325ec5Stsutsui switch (pKbd->layout) { 484b9325ec5Stsutsui case 33: case 80: /* U.S. */ 485b9325ec5Stsutsui case 47: case 94: /* Korea */ 486b9325ec5Stsutsui case 48: case 95: /* Taiwan */ 487b9325ec5Stsutsui case 49: case 96: /* Japan */ 488b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(type5)"); 489b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type5)"); 490b9325ec5Stsutsui break; 491b9325ec5Stsutsui case 34: case 81: /* U.S. Unix */ 492b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(type5)"); 493b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type5unix)"); 494b9325ec5Stsutsui break; 495b9325ec5Stsutsui default: 496b9325ec5Stsutsui (void) strcat (names->keycodes, "sun(type5_euro)"); 497b9325ec5Stsutsui (void) strcat (names->geometry, "sun(type5euro)"); 498b9325ec5Stsutsui } 499b9325ec5Stsutsui 500b9325ec5Stsutsui if (sunSwapLkeys) 501b9325ec5Stsutsui (void) strcat (names->symbols, "sun/us(sun5ol)"); 502b9325ec5Stsutsui else 503b9325ec5Stsutsui (void) strcat (names->symbols, "sun/us(sun5)"); 504b9325ec5Stsutsui } 505b9325ec5Stsutsui break; 506b9325ec5Stsutsui default: 507b9325ec5Stsutsui names->keycodes = names->geometry = NULL; 508b9325ec5Stsutsui break; 509b9325ec5Stsutsui } 510b9325ec5Stsutsui 511b9325ec5Stsutsui /* extra symbols */ 512b9325ec5Stsutsui 513b9325ec5Stsutsui if (pKbd->type == KB_SUN4) { 514b9325ec5Stsutsui switch (pKbd->layout) { 515b9325ec5Stsutsui case 4: case 36: case 83: 516b9325ec5Stsutsui case 5: case 37: case 84: 517b9325ec5Stsutsui case 6: case 38: case 85: 518b9325ec5Stsutsui case 8: case 40: case 87: 519b9325ec5Stsutsui case 9: case 41: case 88: 520b9325ec5Stsutsui case 10: case 42: case 89: 521b9325ec5Stsutsui/* case 11: case 43: case 90: */ /* handled earlier */ 522b9325ec5Stsutsui case 12: case 44: case 91: 523b9325ec5Stsutsui case 13: case 45: case 92: 524b9325ec5Stsutsui case 14: case 46: case 93: 525b9325ec5Stsutsui (void) strcat (names->symbols, "+iso9995-3(basic)"); break; 526b9325ec5Stsutsui } 527b9325ec5Stsutsui } 528b9325ec5Stsutsui 529b9325ec5Stsutsui if (pKbd->type == KB_SUN4) { 530b9325ec5Stsutsui switch (pKbd->layout) { 531b9325ec5Stsutsui case 0: case 1: case 33: case 34: case 80: case 81: 532b9325ec5Stsutsui break; 533b9325ec5Stsutsui case 3: 534b9325ec5Stsutsui (void) strcat (names->symbols, "+ca"); break; 535b9325ec5Stsutsui case 4: case 36: case 83: 536b9325ec5Stsutsui (void) strcat (names->symbols, "+dk"); break; 537b9325ec5Stsutsui case 5: case 37: case 84: 538b9325ec5Stsutsui (void) strcat (names->symbols, "+de"); break; 539b9325ec5Stsutsui case 6: case 38: case 85: 540b9325ec5Stsutsui (void) strcat (names->symbols, "+it"); break; 541b9325ec5Stsutsui case 8: case 40: case 87: 542b9325ec5Stsutsui (void) strcat (names->symbols, "+no"); break; 543b9325ec5Stsutsui case 9: case 41: case 88: 544b9325ec5Stsutsui (void) strcat (names->symbols, "+pt"); break; 545b9325ec5Stsutsui case 10: case 42: case 89: 546b9325ec5Stsutsui (void) strcat (names->symbols, "+es"); break; 547b9325ec5Stsutsui /* case 11: case 43: */ /* handled earlier */ 548b9325ec5Stsutsui case 90: 549b9325ec5Stsutsui (void) strcat (names->symbols, "+se"); break; 550b9325ec5Stsutsui case 12: case 44: case 91: 551b9325ec5Stsutsui (void) strcat (names->symbols, "+fr_CH"); break; 552b9325ec5Stsutsui case 13: case 45: case 92: 553b9325ec5Stsutsui (void) strcat (names->symbols, "+de_CH"); break; 554b9325ec5Stsutsui case 14: case 46: case 93: 555b9325ec5Stsutsui (void) strcat (names->symbols, "+gb"); break; /* s/b en_UK */ 556b9325ec5Stsutsui case 52: 557b9325ec5Stsutsui (void) strcat (names->symbols, "+pl"); break; 558b9325ec5Stsutsui case 53: 559b9325ec5Stsutsui (void) strcat (names->symbols, "+cs"); break; 560b9325ec5Stsutsui case 54: 561b9325ec5Stsutsui (void) strcat (names->symbols, "+ru"); break; 562b9325ec5Stsutsui#if 0 563b9325ec5Stsutsui /* don't have symbols defined for these yet, let them default */ 564b9325ec5Stsutsui case 2: 565b9325ec5Stsutsui (void) strcat (names->symbols, "+fr_BE"); break; 566b9325ec5Stsutsui case 7: case 39: case 86: 567b9325ec5Stsutsui (void) strcat (names->symbols, "+nl"); break; 568b9325ec5Stsutsui case 50: case 97: 569b9325ec5Stsutsui (void) strcat (names->symbols, "+fr_CA"); break; 570b9325ec5Stsutsui case 16: case 47: case 94: 571b9325ec5Stsutsui (void) strcat (names->symbols, "+ko"); break; 572b9325ec5Stsutsui case 17: case 48: case 95: 573b9325ec5Stsutsui (void) strcat (names->symbols, "+tw"); break; 574b9325ec5Stsutsui case 32: case 49: case 96: 575b9325ec5Stsutsui (void) strcat (names->symbols, "+jp"); break; 576b9325ec5Stsutsui case 51: 577b9325ec5Stsutsui (void) strcat (names->symbols, "+hu"); break; 578b9325ec5Stsutsui#endif 579b9325ec5Stsutsui /* 580b9325ec5Stsutsui * by setting the symbols to NULL XKB will use the symbols in 581b9325ec5Stsutsui * the "default" keymap. 582b9325ec5Stsutsui */ 583b9325ec5Stsutsui default: 584b9325ec5Stsutsui names->symbols = NULL; return; break; 585b9325ec5Stsutsui } 586b9325ec5Stsutsui } 587b9325ec5Stsutsui#else 588b9325ec5Stsutsui rmlvo->rules = "base"; 589cb17d216Stsutsui rmlvo->model = "empty"; 590cb17d216Stsutsui rmlvo->layout = "empty"; 591b9325ec5Stsutsui rmlvo->variant = NULL; 592b9325ec5Stsutsui rmlvo->options = NULL; 593b9325ec5Stsutsui#endif 594b9325ec5Stsutsui} 595b9325ec5Stsutsui 596b9325ec5Stsutsui/*- 597b9325ec5Stsutsui *----------------------------------------------------------------------- 598b9325ec5Stsutsui * sunKbdProc -- 599b9325ec5Stsutsui * Handle the initialization, etc. of a keyboard. 600b9325ec5Stsutsui * 601b9325ec5Stsutsui * Results: 602b9325ec5Stsutsui * None. 603b9325ec5Stsutsui * 604b9325ec5Stsutsui *----------------------------------------------------------------------- 605b9325ec5Stsutsui */ 606b9325ec5Stsutsui 607b9325ec5Stsutsuiint 608b9325ec5StsutsuisunKbdProc(DeviceIntPtr device, int what) 609b9325ec5Stsutsui{ 61085d6961bStsutsui DevicePtr pKeyboard = &device->public; 611b9325ec5Stsutsui sunKbdPrivPtr pPriv; 612b9325ec5Stsutsui KeybdCtrl* ctrl = &device->kbdfeed->ctrl; 613b9325ec5Stsutsui XkbRMLVOSet rmlvo; 614cb17d216Stsutsui CARD8 workingModMap[MAP_LENGTH]; 615b9325ec5Stsutsui 616b9325ec5Stsutsui static KeySymsRec *workingKeySyms; 617b9325ec5Stsutsui 618b9325ec5Stsutsui switch (what) { 619b9325ec5Stsutsui case DEVICE_INIT: 62085d6961bStsutsui if (pKeyboard != &sunKeyboardDevice->public) { 621b9325ec5Stsutsui ErrorF ("Cannot open non-system keyboard\n"); 622b9325ec5Stsutsui return (!Success); 623b9325ec5Stsutsui } 624b9325ec5Stsutsui 625b9325ec5Stsutsui if (!workingKeySyms) { 626b9325ec5Stsutsui workingKeySyms = &sunKeySyms[sunKbdPriv.type]; 627b9325ec5Stsutsui 628b9325ec5Stsutsui if (sunKbdPriv.type == KB_SUN4 && sunSwapLkeys) 629b9325ec5Stsutsui SwapLKeys(workingKeySyms); 630b9325ec5Stsutsui 631b9325ec5Stsutsui if (workingKeySyms->minKeyCode < MIN_KEYCODE) { 632b9325ec5Stsutsui workingKeySyms->minKeyCode += MIN_KEYCODE; 633b9325ec5Stsutsui workingKeySyms->maxKeyCode += MIN_KEYCODE; 634b9325ec5Stsutsui } 635b9325ec5Stsutsui if (workingKeySyms->maxKeyCode > MAX_KEYCODE) 636b9325ec5Stsutsui workingKeySyms->maxKeyCode = MAX_KEYCODE; 637b9325ec5Stsutsui 638cb17d216Stsutsui sunInitModMap(workingKeySyms, workingModMap); 639b9325ec5Stsutsui } 640b9325ec5Stsutsui 641b9325ec5Stsutsui pKeyboard->devicePrivate = (pointer)&sunKbdPriv; 642b9325ec5Stsutsui pKeyboard->on = FALSE; 643b9325ec5Stsutsui 644b9325ec5Stsutsui sunInitKbdNames(&rmlvo, pKeyboard->devicePrivate); 645b9325ec5Stsutsui#if 0 /* XXX needs more work for Xorg xkb */ 646cb17d216Stsutsui InitKeyboardDeviceStruct(device, &rmlvo, 647b9325ec5Stsutsui sunBell, sunKbdCtrl); 648b9325ec5Stsutsui#else 649cb17d216Stsutsui XkbSetRulesDflts(&rmlvo); 650b9325ec5Stsutsui InitKeyboardDeviceStruct(device, NULL, 651b9325ec5Stsutsui sunBell, sunKbdCtrl); 652b9325ec5Stsutsui XkbApplyMappingChange(device, workingKeySyms, 653b9325ec5Stsutsui workingKeySyms->minKeyCode, 654b9325ec5Stsutsui workingKeySyms->maxKeyCode - 655b9325ec5Stsutsui workingKeySyms->minKeyCode + 1, 656b9325ec5Stsutsui workingModMap, serverClient); 657b9325ec5Stsutsui#endif 658b9325ec5Stsutsui break; 659b9325ec5Stsutsui 660b9325ec5Stsutsui case DEVICE_ON: 661b9325ec5Stsutsui pPriv = (sunKbdPrivPtr)pKeyboard->devicePrivate; 662b9325ec5Stsutsui /* 663b9325ec5Stsutsui * Set the keyboard into "direct" mode and turn on 664b9325ec5Stsutsui * event translation. 665b9325ec5Stsutsui */ 666b9325ec5Stsutsui if (sunChangeKbdTranslation(pPriv->fd,TRUE) == -1) 667b9325ec5Stsutsui FatalError("Can't set keyboard translation\n"); 668b9325ec5Stsutsui AddEnabledDevice(pPriv->fd); 669b9325ec5Stsutsui pKeyboard->on = TRUE; 670b9325ec5Stsutsui break; 671b9325ec5Stsutsui 672b9325ec5Stsutsui case DEVICE_CLOSE: 673b9325ec5Stsutsui case DEVICE_OFF: 674b9325ec5Stsutsui pPriv = (sunKbdPrivPtr)pKeyboard->devicePrivate; 675b9325ec5Stsutsui if (pPriv->type == KB_SUN4) { 676b9325ec5Stsutsui /* dumb bug in Sun's keyboard! Turn off LEDS before resetting */ 677b9325ec5Stsutsui pPriv->leds = 0; 678b9325ec5Stsutsui ctrl->leds = 0; 679b9325ec5Stsutsui SetLights(ctrl, pPriv->fd); 680b9325ec5Stsutsui } 681b9325ec5Stsutsui /* 682b9325ec5Stsutsui * Restore original keyboard directness and translation. 683b9325ec5Stsutsui */ 684b9325ec5Stsutsui if (sunChangeKbdTranslation(pPriv->fd,FALSE) == -1) 685b9325ec5Stsutsui FatalError("Can't reset keyboard translation\n"); 686b9325ec5Stsutsui RemoveEnabledDevice(pPriv->fd); 687b9325ec5Stsutsui pKeyboard->on = FALSE; 688b9325ec5Stsutsui break; 689b9325ec5Stsutsui default: 690b9325ec5Stsutsui FatalError("Unknown keyboard operation\n"); 691b9325ec5Stsutsui } 692b9325ec5Stsutsui return Success; 693b9325ec5Stsutsui} 694b9325ec5Stsutsui 695cb17d216Stsutsui/*------------------------------------------------------------------------- 696cb17d216Stsutsui * sunInitModMap -- 697cb17d216Stsutsui * Initialize ModMap per specified KeyMap table. 698cb17d216Stsutsui * 699cb17d216Stsutsui * Results: 700cb17d216Stsutsui * None. 701cb17d216Stsutsui * 702cb17d216Stsutsui * Side Effects: 703cb17d216Stsutsui * None. 704cb17d216Stsutsui *-----------------------------------------------------------------------*/ 705cb17d216Stsutsuistatic void 706cb17d216StsutsuisunInitModMap( 707cb17d216Stsutsui const KeySymsRec *KeySyms, /* KeyMap data to set ModMap */ 708cb17d216Stsutsui CARD8 *ModMap /* ModMap to be initialized */ 709cb17d216Stsutsui) 710cb17d216Stsutsui{ 711cb17d216Stsutsui KeySym *k; 712cb17d216Stsutsui int i, min, max, width; 713cb17d216Stsutsui 714cb17d216Stsutsui for (i = 0; i < MAP_LENGTH; i++) 715cb17d216Stsutsui ModMap[i] = NoSymbol; 716cb17d216Stsutsui 717cb17d216Stsutsui min = KeySyms->minKeyCode; 718cb17d216Stsutsui max = KeySyms->maxKeyCode; 719cb17d216Stsutsui width = KeySyms->mapWidth; 720cb17d216Stsutsui for (i = min, k = KeySyms->map; i < max; i++, k += width) { 721cb17d216Stsutsui switch (*k) { 722cb17d216Stsutsui 723cb17d216Stsutsui case XK_Shift_L: 724cb17d216Stsutsui case XK_Shift_R: 725cb17d216Stsutsui ModMap[i] = ShiftMask; 726cb17d216Stsutsui break; 727cb17d216Stsutsui 728cb17d216Stsutsui case XK_Control_L: 729cb17d216Stsutsui case XK_Control_R: 730cb17d216Stsutsui ModMap[i] = ControlMask; 731cb17d216Stsutsui break; 732cb17d216Stsutsui 733cb17d216Stsutsui case XK_Caps_Lock: 734cb17d216Stsutsui ModMap[i] = LockMask; 735cb17d216Stsutsui break; 736cb17d216Stsutsui 737cb17d216Stsutsui case XK_Alt_L: 738cb17d216Stsutsui case XK_Alt_R: 739cb17d216Stsutsui ModMap[i] = Alt_Mask; 740cb17d216Stsutsui break; 741cb17d216Stsutsui 742cb17d216Stsutsui case XK_Num_Lock: 743cb17d216Stsutsui ModMap[i] = Num_Lock_Mask; 744cb17d216Stsutsui break; 745cb17d216Stsutsui 746cb17d216Stsutsui case XK_Scroll_Lock: 747cb17d216Stsutsui ModMap[i] = ScrollLockMask; 748cb17d216Stsutsui break; 749cb17d216Stsutsui 750cb17d216Stsutsui case XK_Meta_L: 751cb17d216Stsutsui case XK_Meta_R: 752cb17d216Stsutsui ModMap[i] = Meta_Mask; 753cb17d216Stsutsui break; 754cb17d216Stsutsui 755cb17d216Stsutsui case SunXK_AltGraph: 756cb17d216Stsutsui ModMap[i] = Mode_switch_Mask; 757cb17d216Stsutsui break; 758cb17d216Stsutsui } 759cb17d216Stsutsui } 760cb17d216Stsutsui} 761cb17d216Stsutsui 762b9325ec5Stsutsui/*- 763b9325ec5Stsutsui *----------------------------------------------------------------------- 764b9325ec5Stsutsui * sunKbdGetEvents -- 765b9325ec5Stsutsui * Return the events waiting in the wings for the given keyboard. 766b9325ec5Stsutsui * 767b9325ec5Stsutsui * Results: 768b9325ec5Stsutsui * A pointer to an array of Firm_events or (Firm_event *)0 if no events 769b9325ec5Stsutsui * The number of events contained in the array. 770b9325ec5Stsutsui * A boolean as to whether more events might be available. 771b9325ec5Stsutsui * 772b9325ec5Stsutsui * Side Effects: 773b9325ec5Stsutsui * None. 774b9325ec5Stsutsui *----------------------------------------------------------------------- 775b9325ec5Stsutsui */ 776b9325ec5Stsutsui 777b9325ec5StsutsuiFirm_event * 778b9325ec5StsutsuisunKbdGetEvents(int fd, Bool on, int *pNumEvents, Bool *pAgain) 779b9325ec5Stsutsui{ 780b9325ec5Stsutsui int nBytes; /* number of bytes of events available. */ 781b9325ec5Stsutsui static Firm_event evBuf[MAXEVENTS]; /* Buffer for Firm_events */ 782b9325ec5Stsutsui 783b9325ec5Stsutsui if ((nBytes = read (fd, evBuf, sizeof(evBuf))) == -1) { 784b9325ec5Stsutsui if (errno == EWOULDBLOCK) { 785b9325ec5Stsutsui *pNumEvents = 0; 786b9325ec5Stsutsui *pAgain = FALSE; 787b9325ec5Stsutsui } else { 788b9325ec5Stsutsui Error ("Reading keyboard"); 789b9325ec5Stsutsui FatalError ("Could not read the keyboard"); 790b9325ec5Stsutsui } 791b9325ec5Stsutsui } else { 792b9325ec5Stsutsui if (on) { 793b9325ec5Stsutsui *pNumEvents = nBytes / sizeof (Firm_event); 794b9325ec5Stsutsui *pAgain = (nBytes == sizeof (evBuf)); 795b9325ec5Stsutsui } else { 796b9325ec5Stsutsui *pNumEvents = 0; 797b9325ec5Stsutsui *pAgain = FALSE; 798b9325ec5Stsutsui } 799b9325ec5Stsutsui } 800b9325ec5Stsutsui return evBuf; 801b9325ec5Stsutsui} 802b9325ec5Stsutsui 803b9325ec5Stsutsui/*- 804b9325ec5Stsutsui *----------------------------------------------------------------------- 805b9325ec5Stsutsui * sunKbdEnqueueEvent -- 806b9325ec5Stsutsui * 807b9325ec5Stsutsui *----------------------------------------------------------------------- 808b9325ec5Stsutsui */ 809b9325ec5Stsutsui 810b9325ec5Stsutsuivoid 811b9325ec5StsutsuisunKbdEnqueueEvent(DeviceIntPtr device, Firm_event *fe) 812b9325ec5Stsutsui{ 813b9325ec5Stsutsui BYTE keycode; 814b9325ec5Stsutsui int type; 815b9325ec5Stsutsui int i, nevents; 816b9325ec5Stsutsui 817b9325ec5Stsutsui GetEventList(&sunEvents); 818b9325ec5Stsutsui keycode = (fe->id & 0x7f) + MIN_KEYCODE; 819b9325ec5Stsutsui 820b9325ec5Stsutsui type = ((fe->value == VKEY_UP) ? KeyRelease : KeyPress); 821b9325ec5Stsutsui nevents = GetKeyboardEvents(sunEvents, device, type, keycode); 822b9325ec5Stsutsui for (i = 0; i < nevents; i++) 823b9325ec5Stsutsui mieqEnqueue(device, (InternalEvent *)(sunEvents + i)->event); 824b9325ec5Stsutsui} 825b9325ec5Stsutsui 826b9325ec5Stsutsui 827b9325ec5Stsutsui/*- 828b9325ec5Stsutsui *----------------------------------------------------------------------- 829b9325ec5Stsutsui * sunChangeKbdTranslation 830b9325ec5Stsutsui * Makes operating system calls to set keyboard translation 831b9325ec5Stsutsui * and direction on or off. 832b9325ec5Stsutsui * 833b9325ec5Stsutsui * Results: 834b9325ec5Stsutsui * -1 if failure, else 0. 835b9325ec5Stsutsui * 836b9325ec5Stsutsui * Side Effects: 837b9325ec5Stsutsui * Changes kernel management of keyboard. 838b9325ec5Stsutsui * 839b9325ec5Stsutsui *----------------------------------------------------------------------- 840b9325ec5Stsutsui */ 841b9325ec5Stsutsuiint 842b9325ec5StsutsuisunChangeKbdTranslation(int fd, Bool makeTranslated) 843b9325ec5Stsutsui{ 844b9325ec5Stsutsui int tmp; 845b9325ec5Stsutsui#ifndef i386 /* { */ 846b9325ec5Stsutsui sigset_t hold_mask, old_mask; 847b9325ec5Stsutsui#else /* }{ */ 848b9325ec5Stsutsui int old_mask; 849b9325ec5Stsutsui#endif /* } */ 850b9325ec5Stsutsui int toread; 851b9325ec5Stsutsui char junk[8192]; 852b9325ec5Stsutsui 853b9325ec5Stsutsui#ifndef i386 /* { */ 854b9325ec5Stsutsui (void) sigfillset(&hold_mask); 855b9325ec5Stsutsui (void) sigprocmask(SIG_BLOCK, &hold_mask, &old_mask); 856b9325ec5Stsutsui#else /* }{ */ 857b9325ec5Stsutsui old_mask = sigblock (~0); 858b9325ec5Stsutsui#endif /* } */ 859b9325ec5Stsutsui sunKbdWait(); 860b9325ec5Stsutsui if (makeTranslated) { 861b9325ec5Stsutsui /* 862b9325ec5Stsutsui * Next set the keyboard into "direct" mode and turn on 863b9325ec5Stsutsui * event translation. If either of these fails, we can't go 864b9325ec5Stsutsui * on. 865b9325ec5Stsutsui */ 866b9325ec5Stsutsui tmp = 1; 867b9325ec5Stsutsui if (ioctl (fd, KIOCSDIRECT, &tmp) == -1) { 868b9325ec5Stsutsui Error ("Setting keyboard direct mode"); 869b9325ec5Stsutsui return -1; 870b9325ec5Stsutsui } 871b9325ec5Stsutsui tmp = TR_UNTRANS_EVENT; 872b9325ec5Stsutsui if (ioctl (fd, KIOCTRANS, &tmp) == -1) { 873b9325ec5Stsutsui Error ("Setting keyboard translation"); 874b9325ec5Stsutsui ErrorF ("sunChangeKbdTranslation: kbdFd=%d\n", fd); 875b9325ec5Stsutsui return -1; 876b9325ec5Stsutsui } 877b9325ec5Stsutsui } else { 878b9325ec5Stsutsui /* 879b9325ec5Stsutsui * Next set the keyboard into "indirect" mode and turn off 880b9325ec5Stsutsui * event translation. 881b9325ec5Stsutsui */ 882b9325ec5Stsutsui tmp = 0; 883b9325ec5Stsutsui (void)ioctl (fd, KIOCSDIRECT, &tmp); 884b9325ec5Stsutsui tmp = TR_ASCII; 885b9325ec5Stsutsui (void)ioctl (fd, KIOCTRANS, &tmp); 886b9325ec5Stsutsui } 887b9325ec5Stsutsui if (ioctl (fd, FIONREAD, &toread) != -1 && toread > 0) { 888b9325ec5Stsutsui while (toread) { 889b9325ec5Stsutsui tmp = toread; 890b9325ec5Stsutsui if (toread > sizeof (junk)) 891b9325ec5Stsutsui tmp = sizeof (junk); 892b9325ec5Stsutsui (void) read (fd, junk, tmp); 893b9325ec5Stsutsui toread -= tmp; 894b9325ec5Stsutsui } 895b9325ec5Stsutsui } 896b9325ec5Stsutsui#ifndef i386 /* { */ 897b9325ec5Stsutsui (void) sigprocmask(SIG_SETMASK, &old_mask, (sigset_t *)NULL); 898b9325ec5Stsutsui#else /* }{ */ 899b9325ec5Stsutsui sigsetmask (old_mask); 900b9325ec5Stsutsui#endif /* } */ 901b9325ec5Stsutsui return 0; 902b9325ec5Stsutsui} 903b9325ec5Stsutsui 904b9325ec5Stsutsui/*ARGSUSED*/ 905b9325ec5StsutsuiBool 906b9325ec5StsutsuiLegalModifier(unsigned int key, DeviceIntPtr pDev) 907b9325ec5Stsutsui{ 908b9325ec5Stsutsui return TRUE; 909b9325ec5Stsutsui} 910