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, * holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization. * 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 $ */ /* $XFree86: xc/programs/Xserver/hw/darwin/darwin.c,v 1.55 2003/11/15 00:07:09 torrey Exp $ */
#include "X.h" #include "X.h"
@ -93,13 +93,16 @@ unsigned int darwinDesiredWidth = 0, darwinDesiredHeight = 0;
int darwinDesiredDepth = -1; int darwinDesiredDepth = -1;
int darwinDesiredRefresh = -1; int darwinDesiredRefresh = -1;
char *darwinKeymapFile = "USA.keymapping"; char *darwinKeymapFile = "USA.keymapping";
int darwinSyncKeymap = FALSE;
int darwinSwapAltMeta = FALSE;
// modifier masks for faking mouse buttons // modifier masks for faking mouse buttons
int darwinFakeMouse2Mask = NX_COMMANDMASK; int darwinFakeMouse2Mask = NX_COMMANDMASK;
int darwinFakeMouse3Mask = NX_ALTERNATEMASK; int darwinFakeMouse3Mask = NX_ALTERNATEMASK;
static DeviceIntPtr darwinPointer; // devices
static DeviceIntPtr darwinKeyboard; DeviceIntPtr darwinPointer = NULL;
DeviceIntPtr darwinKeyboard = NULL;
// Common pixmap formats // Common pixmap formats
static PixmapFormatRec formats[] = { static PixmapFormatRec formats[] = {
@ -538,7 +541,7 @@ static char * DarwinFindLibraryFile(
* DarwinParseModifierList * DarwinParseModifierList
* Parse a list of modifier names and return a corresponding modifier mask * 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 const char *constmodifiers) // string containing list of modifier names
{ {
int result = 0; int result = 0;
@ -781,6 +784,11 @@ int ddxProcessArgument( int argc, char *argv[], int i )
return 2; return 2;
} }
if ( !strcmp( argv[i], "-swapAltMeta" ) ) {
darwinSwapAltMeta = 1;
return 1;
}
if ( !strcmp( argv[i], "-keymap" ) ) { if ( !strcmp( argv[i], "-keymap" ) ) {
if ( i == argc-1 ) { if ( i == argc-1 ) {
FatalError( "-keymap must be followed by a filename\n" ); FatalError( "-keymap must be followed by a filename\n" );
@ -794,6 +802,16 @@ int ddxProcessArgument( int argc, char *argv[], int i )
return 1; 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 ( !strcmp( argv[i], "-size" ) ) {
if ( i >= argc-2 ) { if ( i >= argc-2 ) {
FatalError( "-size must be followed by two numbers\n" ); 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 * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * 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, * holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization. * 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 #ifndef _DARWIN_H
#define _DARWIN_H #define _DARWIN_H
@ -49,6 +49,7 @@ typedef struct {
// From darwin.c // From darwin.c
void DarwinPrintBanner(); void DarwinPrintBanner();
int DarwinParseModifierList(const char *constmodifiers);
void DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo); void DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo);
void xf86SetRootClip (ScreenPtr pScreen, BOOL enable); void xf86SetRootClip (ScreenPtr pScreen, BOOL enable);
@ -98,13 +99,17 @@ extern int darwinScreensFound;
extern io_connect_t darwinParamConnect; extern io_connect_t darwinParamConnect;
extern int darwinEventReadFD; extern int darwinEventReadFD;
extern int darwinEventWriteFD; extern int darwinEventWriteFD;
extern DeviceIntPtr darwinPointer;
extern DeviceIntPtr darwinKeyboard;
// User preferences // User preferences
extern int darwinMouseAccelChange; extern int darwinMouseAccelChange;
extern int darwinFakeButtons; extern int darwinFakeButtons;
extern int darwinFakeMouse2Mask; extern int darwinFakeMouse2Mask;
extern int darwinFakeMouse3Mask; extern int darwinFakeMouse3Mask;
extern int darwinSwapAltMeta;
extern char *darwinKeymapFile; extern char *darwinKeymapFile;
extern int darwinSyncKeymap;
extern unsigned int darwinDesiredWidth, darwinDesiredHeight; extern unsigned int darwinDesiredWidth, darwinDesiredHeight;
extern int darwinDesiredDepth; extern int darwinDesiredDepth;
extern int darwinDesiredRefresh; extern int darwinDesiredRefresh;

View File

@ -2,7 +2,7 @@
* Darwin event queue and event handling * 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. Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved.
This file is based on mieq.c by Keith Packard, 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 used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group. 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 #define NEED_EVENTS
#include "X.h" #include "X.h"
@ -44,6 +44,7 @@ in this Software without prior written authorization from The Open Group.
#include "mipointer.h" #include "mipointer.h"
#include "darwin.h" #include "darwin.h"
#include "darwinKeyboard.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/uio.h> #include <sys/uio.h>
@ -322,6 +323,23 @@ void ProcessInputEvents(void)
switch (xe.u.u.type) switch (xe.u.u.type)
{ {
case KeyPress: 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: case KeyRelease:
xe.u.u.detail += MIN_KEYCODE; xe.u.u.detail += MIN_KEYCODE;
(*darwinEventQueue.pKbd->processInputProc) (*darwinEventQueue.pKbd->processInputProc)

View File

@ -2,9 +2,9 @@
// //
// Keyboard support for the Darwin X Server // Keyboard support for the Darwin X Server
// //
// Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved. // Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved.
// Copyright (c) 2001-2003 Torrey T. Lyons. All Rights Reserved.
// Copyright (c) 2003 Apple Computer, Inc. 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 // The code to parse the Darwin keymap is derived from dumpkeymap.c
// by Eric Sunshine, which includes the following copyright: // 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 ); destroy_data_stream( keyMapStream );
xfree( keyMap.mapping ); 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; return TRUE;
} }
/* /*
* DarwinBuildModifierMaps * DarwinBuildModifierMaps
* Use the keyMap field of keyboard info structure to populate * Use the keyMap field of keyboard info structure to populate
@ -668,7 +651,6 @@ DarwinBuildModifierMaps(
{ {
int i; int i;
KeySym *k; KeySym *k;
int darwinSwapAltMeta = 0;
memset(info->modMap, NoSymbol, sizeof(info->modMap)); memset(info->modMap, NoSymbol, sizeof(info->modMap));
memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes)); memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes));
@ -766,10 +748,58 @@ DarwinBuildModifierMaps(
break; 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 * DarwinKeyboardInit
* Get the Darwin keyboard map and compute an equivalent * Get the Darwin keyboard map and compute an equivalent
@ -781,31 +811,89 @@ void DarwinKeyboardInit(
{ {
KeySymsRec keySyms; KeySymsRec keySyms;
memset( keyInfo.keyMap, 0, sizeof( keyInfo.keyMap ) );
// Open a shared connection to the HID System. // Open a shared connection to the HID System.
// Note that the Event Status Driver is really just a wrapper // Note that the Event Status Driver is really just a wrapper
// for a kIOHIDParamConnectType connection. // for a kIOHIDParamConnectType connection.
assert( darwinParamConnect = NXOpenEventStatus() ); assert( darwinParamConnect = NXOpenEventStatus() );
if (!DarwinParseNXKeyMapping(&keyInfo)) { DarwinLoadKeyboardMapping(&keySyms);
if (!DarwinModeReadSystemKeymap(&keyInfo)) {
FatalError("Could not build a valid keymap.");
}
}
DarwinBuildModifierMaps(&keyInfo); /* Initialize the seed, so we don't reload the keymap unnecessarily
(and possibly overwrite xinitrc changes) */
keySyms.map = keyInfo.keyMap; DarwinModeSystemKeymapSeed();
keySyms.mapWidth = GLYPHS_PER_KEY;
keySyms.minKeyCode = MIN_KEYCODE;
keySyms.maxKeyCode = MAX_KEYCODE;
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms, assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
keyInfo.modMap, DarwinModeBell, keyInfo.modMap, DarwinModeBell,
DarwinChangeKeyboardControl )); 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 // 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 * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -45,6 +45,8 @@ typedef struct darwinKeyboardInfo_struct {
unsigned char modifierKeycodes[32][2]; unsigned char modifierKeycodes[32][2];
} darwinKeyboardInfo; } darwinKeyboardInfo;
void DarwinKeyboardReload(DeviceIntPtr pDev);
unsigned int DarwinModeSystemKeymapSeed(void);
Bool DarwinModeReadSystemKeymap(darwinKeyboardInfo *info); Bool DarwinModeReadSystemKeymap(darwinKeyboardInfo *info);
#endif /* DARWIN_KEYBOARD_H */ #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 * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * 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 * DarwinModeReadSystemKeymap
* IOKit has no alternative to NXKeyMapping API. * IOKit has no alternative to NXKeyMapping API.

View File

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