#undef DUMP_DARWIN_KEYMAP
#define ALT_IS_MODE_SWITCH 1
#include "darwin.h"
#include "darwin-keyboard.h"
#include <stdio.h>
#include <stdlib.h>
#include "darwin.h"
#include "quartz-audio.h"
#include <IOKit/hidsystem/IOLLEvent.h>
#include <IOKit/hidsystem/ev_keymap.h>
#include "keysym.h"
static darwin_keyboard_info info;
static void
DarwinChangeKeyboardControl (DeviceIntPtr device, KeybdCtrl *ctrl)
{
}
static void
build_modifier_maps (darwin_keyboard_info *info)
{
int i;
KeySym *k;
memset (info->mod_map, NoSymbol, sizeof (info->mod_map));
memset (info->modifier_keycodes, 0, sizeof (info->modifier_keycodes));
for (i = 0; i < NUM_KEYCODES; i++)
{
k = info->key_map + i * GLYPHS_PER_KEY;
switch (k[0])
{
case XK_Shift_L:
info->modifier_keycodes[NX_MODIFIERKEY_SHIFT][0] = i;
info->mod_map[MIN_KEYCODE + i] = ShiftMask;
break;
case XK_Shift_R:
info->modifier_keycodes[NX_MODIFIERKEY_SHIFT][1] = i;
info->mod_map[MIN_KEYCODE + i] = ShiftMask;
break;
case XK_Control_L:
info->modifier_keycodes[NX_MODIFIERKEY_CONTROL][0] = i;
info->mod_map[MIN_KEYCODE + i] = ControlMask;
break;
case XK_Control_R:
info->modifier_keycodes[NX_MODIFIERKEY_CONTROL][1] = i;
info->mod_map[MIN_KEYCODE + i] = ControlMask;
break;
case XK_Caps_Lock:
info->modifier_keycodes[NX_MODIFIERKEY_ALPHALOCK][0] = i;
info->mod_map[MIN_KEYCODE + i] = LockMask;
break;
case XK_Alt_L:
info->modifier_keycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
info->mod_map[MIN_KEYCODE + i] = Mod1Mask;
break;
case XK_Alt_R:
info->modifier_keycodes[NX_MODIFIERKEY_ALTERNATE][1] = i;
info->mod_map[MIN_KEYCODE + i] = Mod1Mask;
break;
case XK_Mode_switch:
info->mod_map[MIN_KEYCODE + i] = Mod1Mask;
break;
case XK_Meta_L:
info->modifier_keycodes[NX_MODIFIERKEY_COMMAND][0] = i;
info->mod_map[MIN_KEYCODE + i] = Mod2Mask;
break;
case XK_Meta_R:
info->modifier_keycodes[NX_MODIFIERKEY_COMMAND][1] = i;
info->mod_map[MIN_KEYCODE + i] = Mod2Mask;
break;
case XK_Num_Lock:
info->mod_map[MIN_KEYCODE + i] = Mod3Mask;
break;
}
if (darwinSwapAltMeta)
{
switch (k[0])
{
case XK_Alt_L:
k[0] = XK_Meta_L; break;
case XK_Alt_R:
k[0] = XK_Meta_R; break;
case XK_Meta_L:
k[0] = XK_Alt_L; break;
case XK_Meta_R:
k[0] = XK_Alt_R; break;
}
}
#if ALT_IS_MODE_SWITCH
if (k[0] == XK_Alt_L || k[0] == XK_Alt_R)
k[0] = XK_Mode_switch;
#endif
}
}
static void
load_keyboard_mapping (KeySymsRec *keysyms)
{
memset (info.key_map, 0, sizeof (info.key_map));
if (darwinKeymapFile == NULL
|| !DarwinParseKeymapFile (&info))
{
DarwinReadSystemKeymap (&info);
}
build_modifier_maps (&info);
#ifdef DUMP_DARWIN_KEYMAP
ErrorF("Darwin -> X converted keyboard map\n");
for (i = 0, k = map; i < NX_NUMKEYCODES; i++, k += GLYPHS_PER_KEY) {
int j;
ErrorF("0x%02x:", i);
for (j = 0; j < GLYPHS_PER_KEY; j++) {
if (k[j] == NoSymbol) {
ErrorF("\tNoSym");
} else {
ErrorF("\t0x%x", k[j]);
}
}
ErrorF("\n");
}
#endif
keysyms->map = info.key_map;
keysyms->mapWidth = GLYPHS_PER_KEY;
keysyms->minKeyCode = MIN_KEYCODE;
keysyms->maxKeyCode = MAX_KEYCODE;
}
void
DarwinKeyboardInit (DeviceIntPtr pDev)
{
KeySymsRec keysyms;
BellProcPtr bellProc;
load_keyboard_mapping (&keysyms);
DarwinSystemKeymapSeed ();
bellProc = QuartzBell;
InitKeyboardDeviceStruct ((DevicePtr) pDev, &keysyms, info.mod_map,
bellProc, DarwinChangeKeyboardControl);
}
static Bool
InitModMap(register KeyClassPtr keyc)
{
int i, j;
CARD8 keysPerModifier[8];
CARD8 mask;
if (keyc->modifierKeyMap != NULL)
xfree (keyc->modifierKeyMap);
keyc->maxKeysPerModifier = 0;
for (i = 0; i < 8; i++)
keysPerModifier[i] = 0;
for (i = 8; i < MAP_LENGTH; i++)
{
for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
{
if (mask & keyc->modifierMap[i])
{
if (++keysPerModifier[j] > keyc->maxKeysPerModifier)
keyc->maxKeysPerModifier = keysPerModifier[j];
}
}
}
keyc->modifierKeyMap = (KeyCode *)xalloc(8*keyc->maxKeysPerModifier);
if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier)
return (FALSE);
bzero((char *)keyc->modifierKeyMap, 8*(int)keyc->maxKeysPerModifier);
for (i = 0; i < 8; i++)
keysPerModifier[i] = 0;
for (i = 8; i < MAP_LENGTH; i++)
{
for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
{
if (mask & keyc->modifierMap[i])
{
keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) +
keysPerModifier[j]] = i;
keysPerModifier[j]++;
}
}
}
return TRUE;
}
void
DarwinKeyboardReload (DeviceIntPtr pDev)
{
KeySymsRec keysyms;
load_keyboard_mapping (&keysyms);
if (SetKeySymsMap (&pDev->key->curKeySyms, &keysyms))
{
memmove (pDev->key->modifierMap, info.mod_map, MAP_LENGTH);
InitModMap (pDev->key);
}
SendMappingNotify (MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
SendMappingNotify (MappingModifier, 0, 0, 0);
}
int
DarwinModifierNXKeyToNXKeycode (int key, int side)
{
return info.modifier_keycodes[key][side];
}
Bool
LegalModifier (unsigned int key, DevicePtr pDev)
{
return 1;
}