Add option for XDarwin to track system keyboard layout changes as they

occur (John Harper and Torrey T. Lyons).
This commit is contained in:
Torrey Lyons 2004-09-22 23:38:33 +00:00
parent 1b3fa4d53b
commit 35a3bf13a8
7 changed files with 280 additions and 132 deletions

View File

@ -29,7 +29,7 @@
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
/* $XdotOrg: xc/programs/Xserver/hw/darwin/darwin.c,v 1.3 2004/07/30 18:22:12 torrey Exp $ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/darwin.c,v 1.4 2004/08/11 23:53:36 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwin.c,v 1.55 2003/11/15 00:07:09 torrey Exp $ */
#include "X.h"
@ -93,13 +93,16 @@ unsigned int darwinDesiredWidth = 0, darwinDesiredHeight = 0;
int darwinDesiredDepth = -1;
int darwinDesiredRefresh = -1;
char *darwinKeymapFile = "USA.keymapping";
int darwinSyncKeymap = FALSE;
int darwinSwapAltMeta = FALSE;
// modifier masks for faking mouse buttons
int darwinFakeMouse2Mask = NX_COMMANDMASK;
int darwinFakeMouse3Mask = NX_ALTERNATEMASK;
static DeviceIntPtr darwinPointer;
static DeviceIntPtr darwinKeyboard;
// devices
DeviceIntPtr darwinPointer = NULL;
DeviceIntPtr darwinKeyboard = NULL;
// Common pixmap formats
static PixmapFormatRec formats[] = {
@ -538,7 +541,7 @@ static char * DarwinFindLibraryFile(
* DarwinParseModifierList
* Parse a list of modifier names and return a corresponding modifier mask
*/
static int DarwinParseModifierList(
int DarwinParseModifierList(
const char *constmodifiers) // string containing list of modifier names
{
int result = 0;
@ -781,6 +784,11 @@ int ddxProcessArgument( int argc, char *argv[], int i )
return 2;
}
if ( !strcmp( argv[i], "-swapAltMeta" ) ) {
darwinSwapAltMeta = 1;
return 1;
}
if ( !strcmp( argv[i], "-keymap" ) ) {
if ( i == argc-1 ) {
FatalError( "-keymap must be followed by a filename\n" );
@ -794,6 +802,16 @@ int ddxProcessArgument( int argc, char *argv[], int i )
return 1;
}
if ( !strcmp( argv[i], "+synckeymap" ) ) {
darwinSyncKeymap = TRUE;
return 1;
}
if ( !strcmp( argv[i], "-synckeymap" ) ) {
darwinSyncKeymap = FALSE;
return 1;
}
if ( !strcmp( argv[i], "-size" ) ) {
if ( i >= argc-2 ) {
FatalError( "-size must be followed by two numbers\n" );

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Torrey T. Lyons. All Rights Reserved.
* Copyright (c) 2001-2004 Torrey T. Lyons. 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"),
@ -23,7 +23,7 @@
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/darwin.h,v 1.19 2003/10/16 23:50:08 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwin.h,v 1.20 2003/11/15 00:07:09 torrey Exp $ */
#ifndef _DARWIN_H
#define _DARWIN_H
@ -49,6 +49,7 @@ typedef struct {
// From darwin.c
void DarwinPrintBanner();
int DarwinParseModifierList(const char *constmodifiers);
void DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo);
void xf86SetRootClip (ScreenPtr pScreen, BOOL enable);
@ -98,13 +99,17 @@ extern int darwinScreensFound;
extern io_connect_t darwinParamConnect;
extern int darwinEventReadFD;
extern int darwinEventWriteFD;
extern DeviceIntPtr darwinPointer;
extern DeviceIntPtr darwinKeyboard;
// User preferences
extern int darwinMouseAccelChange;
extern int darwinFakeButtons;
extern int darwinFakeMouse2Mask;
extern int darwinFakeMouse3Mask;
extern int darwinSwapAltMeta;
extern char *darwinKeymapFile;
extern int darwinSyncKeymap;
extern unsigned int darwinDesiredWidth, darwinDesiredHeight;
extern int darwinDesiredDepth;
extern int darwinDesiredRefresh;

View File

@ -2,7 +2,7 @@
* Darwin event queue and event handling
*/
/*
Copyright (c) 2002 Torrey T. Lyons. All Rights Reserved.
Copyright (c) 2002-2004 Torrey T. Lyons. All Rights Reserved.
Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved.
This file is based on mieq.c by Keith Packard,
@ -29,7 +29,7 @@ Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
/* $XFree86$ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinEvents.c,v 1.6 2004/03/31 22:29:09 torrey Exp $ */
#define NEED_EVENTS
#include "X.h"
@ -44,6 +44,7 @@ in this Software without prior written authorization from The Open Group.
#include "mipointer.h"
#include "darwin.h"
#include "darwinKeyboard.h"
#include <sys/types.h>
#include <sys/uio.h>
@ -322,6 +323,23 @@ void ProcessInputEvents(void)
switch (xe.u.u.type)
{
case KeyPress:
if (old_flags == 0
&& darwinSyncKeymap && darwinKeymapFile == NULL)
{
/* See if keymap has changed. */
static unsigned int last_seed;
unsigned int this_seed;
this_seed = DarwinModeSystemKeymapSeed();
if (this_seed != last_seed)
{
last_seed = this_seed;
DarwinKeyboardReload(darwinKeyboard);
}
}
/* fall through */
case KeyRelease:
xe.u.u.detail += MIN_KEYCODE;
(*darwinEventQueue.pKbd->processInputProc)

View File

@ -2,9 +2,9 @@
//
// Keyboard support for the Darwin X Server
//
// Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved.
// Copyright (c) 2001-2003 Torrey T. Lyons. All Rights Reserved.
// Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved.
// Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
// Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved.
//
// The code to parse the Darwin keymap is derived from dumpkeymap.c
// by Eric Sunshine, which includes the following copyright:
@ -38,7 +38,7 @@
//
//=============================================================================
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinKeyboard.c,v 1.18 2003/05/14 05:27:55 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinKeyboard.c,v 1.21 2004/04/01 00:05:22 torrey Exp $ */
/*
===========================================================================
@ -636,27 +636,10 @@ Bool DarwinParseNXKeyMapping(
destroy_data_stream( keyMapStream );
xfree( keyMap.mapping );
#ifdef DUMP_DARWIN_KEYMAP
ErrorF("Darwin -> X converted keyboard map\n");
for (i = 0, k = info->keyMap; 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
return TRUE;
}
/*
* DarwinBuildModifierMaps
* Use the keyMap field of keyboard info structure to populate
@ -668,7 +651,6 @@ DarwinBuildModifierMaps(
{
int i;
KeySym *k;
int darwinSwapAltMeta = 0;
memset(info->modMap, NoSymbol, sizeof(info->modMap));
memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes));
@ -766,10 +748,58 @@ DarwinBuildModifierMaps(
break;
}
}
#if ALT_IS_MODE_SWITCH
if (k[0] == XK_Alt_L)
k[0] = XK_Mode_switch;
#endif
}
}
/*
* DarwinLoadKeyboardMapping
* Load the keyboard map from a file or system and convert
* it to an equivalent X keyboard map and modifier map.
*/
static void
DarwinLoadKeyboardMapping(KeySymsRec *keySyms)
{
memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
if (!DarwinParseNXKeyMapping(&keyInfo)) {
if (!DarwinModeReadSystemKeymap(&keyInfo)) {
FatalError("Could not build a valid keymap.");
}
}
DarwinBuildModifierMaps(&keyInfo);
#ifdef DUMP_DARWIN_KEYMAP
ErrorF("Darwin -> X converted keyboard map\n");
for (i = 0, k = info->keyMap; 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 = keyInfo.keyMap;
keySyms->mapWidth = GLYPHS_PER_KEY;
keySyms->minKeyCode = MIN_KEYCODE;
keySyms->maxKeyCode = MAX_KEYCODE;
}
/*
* DarwinKeyboardInit
* Get the Darwin keyboard map and compute an equivalent
@ -781,31 +811,89 @@ void DarwinKeyboardInit(
{
KeySymsRec keySyms;
memset( keyInfo.keyMap, 0, sizeof( keyInfo.keyMap ) );
// Open a shared connection to the HID System.
// Note that the Event Status Driver is really just a wrapper
// for a kIOHIDParamConnectType connection.
assert( darwinParamConnect = NXOpenEventStatus() );
if (!DarwinParseNXKeyMapping(&keyInfo)) {
if (!DarwinModeReadSystemKeymap(&keyInfo)) {
FatalError("Could not build a valid keymap.");
}
}
DarwinLoadKeyboardMapping(&keySyms);
DarwinBuildModifierMaps(&keyInfo);
keySyms.map = keyInfo.keyMap;
keySyms.mapWidth = GLYPHS_PER_KEY;
keySyms.minKeyCode = MIN_KEYCODE;
keySyms.maxKeyCode = MAX_KEYCODE;
/* Initialize the seed, so we don't reload the keymap unnecessarily
(and possibly overwrite xinitrc changes) */
DarwinModeSystemKeymapSeed();
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
keyInfo.modMap, DarwinModeBell,
DarwinChangeKeyboardControl ));
}
/* Borrowed from dix/devices.c */
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;
DarwinLoadKeyboardMapping(&keySyms);
if (SetKeySymsMap(&pDev->key->curKeySyms, &keySyms)) {
/* now try to update modifiers. */
memmove(pDev->key->modifierMap, keyInfo.modMap, MAP_LENGTH);
InitModMap(pDev->key);
}
SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
SendMappingNotify(MappingModifier, 0, 0, 0);
}
//-----------------------------------------------------------------------------
// Modifier translation functions
//

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
* Copyright (c) 2003-2004 Torrey T. Lyons. 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"),
@ -45,6 +45,8 @@ typedef struct darwinKeyboardInfo_struct {
unsigned char modifierKeycodes[32][2];
} darwinKeyboardInfo;
void DarwinKeyboardReload(DeviceIntPtr pDev);
unsigned int DarwinModeSystemKeymapSeed(void);
Bool DarwinModeReadSystemKeymap(darwinKeyboardInfo *info);
#endif /* DARWIN_KEYBOARD_H */

View File

@ -4,7 +4,7 @@
*
**************************************************************/
/*
* Copyright (c) 2001-2003 Torrey T. Lyons. All Rights Reserved.
* Copyright (c) 2001-2004 Torrey T. Lyons. 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"),
@ -104,6 +104,17 @@ int DarwinModeProcessArgument(
}
/*
* DarwinModeSystemKeymapSeed
* Changes to NXKeyMapping are not tracked.
*/
unsigned int
DarwinModeSystemKeymapSeed(void)
{
return 0;
}
/*
* DarwinModeReadSystemKeymap
* IOKit has no alternative to NXKeyMapping API.

View File

@ -148,7 +148,7 @@ const static struct {
};
unsigned int
DarwinSystemKeymapSeed (void)
DarwinModeSystemKeymapSeed (void)
{
static unsigned int seed;
@ -373,6 +373,12 @@ DarwinModeReadSystemKeymap (darwinKeyboardInfo *info)
#else /* !HAS_KL_API */
unsigned int
DarwinModeSystemKeymapSeed (void)
{
return 0;
}
Bool
DarwinModeReadSystemKeymap (darwinKeyboardInfo *info)
{