* Re: [9fans] keyboad maps revisited
@ 2002-02-08 15:53 Fco.J.Ballesteros
0 siblings, 0 replies; 3+ messages in thread
From: Fco.J.Ballesteros @ 2002-02-08 15:53 UTC (permalink / raw)
To: boyd, 9fans
: True, but I like the generality of being able to dynamically map.
Wouldn't pipefile be enough for those cases?
In any case, it's probably a matter of taste...
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [9fans] keyboad maps revisited
2002-02-08 15:42 Fco.J.Ballesteros
@ 2002-02-08 15:49 ` Boyd Roberts
0 siblings, 0 replies; 3+ messages in thread
From: Boyd Roberts @ 2002-02-08 15:49 UTC (permalink / raw)
To: 9fans
"Fco.J.Ballesteros" wrote:
> Although this does not permit using the same kernel for different keyboard
> layouts I think that most of the times that is not a problem.
True, but I like the generality of being able to dynamically map.
^ permalink raw reply [flat|nested] 3+ messages in thread
* [9fans] keyboad maps revisited
@ 2002-02-08 15:42 Fco.J.Ballesteros
2002-02-08 15:49 ` Boyd Roberts
0 siblings, 1 reply; 3+ messages in thread
From: Fco.J.Ballesteros @ 2002-02-08 15:42 UTC (permalink / raw)
To: 9fans
[-- Attachment #1: Type: text/plain, Size: 1585 bytes --]
Hi,
I changed the pc kbd.c to allow for keyboard maps (eg. spanish
keyboards) in a simple way. IMHO, this is enough to get users happy,
yet it does not complicate the kernel with another device.
The idea is simple:
— the kbtab*[]s are moved to a separate file: kbdus.c kbdsp.c etc.
— in the configuration file you specify one of kbdus, kbdsp, ... as an option.
— Besides, to aid in the construction of new kbd{us,sp,...}.c files
kbd.c is changed to let you know the scancodes that your keys generate
(press f1 to get the code for each key you press, press f2 to stop
scan code messages)
Although this does not permit using the same kernel for different keyboard
layouts I think that most of the times that is not a problem.
I tested it here and it works nicely.
BTW, I only send the kbdus.c map, since the kbdsp.c I used to test this
thing does not really match the spanish keyboard (yes, don't ask me why but I
use us keyboards despite being in Madrid). I'll make a kbdsp.c in a few
days if no one does it before, though.
The attached files are:
/sys/src/9/pc/kbd.c :
now including kbd.h, and playing the f1/f2 dump scancode game.
/sys/src/9/pc/kbd.h :
new, just w/ declarations for external kbmaps[]
/sys/src/9/pc/kbdus.c :
tables for the us keyboard (the ones in the distribution, actually)
/sys/src/9/pc/pcdisk
example of config file using kbdus.
hope this helps
PS: It would be great if those of us using non-us keyboards could contribute
kbd*.c maps so that new Plan 9 users could just borrow our tables.
[-- Attachment #2: kbd.c --]
[-- Type: text/plain, Size: 6057 bytes --]
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "io.h"
#include "fns.h"
#include "../port/error.h"
#include "kbd.h"
enum {
Data= 0x60, /* data port */
Status= 0x64, /* status port */
Inready= 0x01, /* input character ready */
Outbusy= 0x02, /* output busy */
Sysflag= 0x04, /* system flag */
Cmddata= 0x08, /* cmd==0, data==1 */
Inhibit= 0x10, /* keyboard/mouse inhibited */
Minready= 0x20, /* mouse character ready */
Rtimeout= 0x40, /* general timeout */
Parity= 0x80,
Cmd= 0x64, /* command port (write only) */
};
enum
{
/* controller command byte */
Cscs1= (1<<6), /* scan code set 1 */
Cauxdis= (1<<5), /* mouse disable */
Ckbddis= (1<<4), /* kbd disable */
Csf= (1<<2), /* system flag */
Cauxint= (1<<1), /* mouse interrupt enable */
Ckbdint= (1<<0), /* kbd interrupt enable */
};
#define Nscan 0x80
static Lock i8042lock;
static uchar ccc;
static void (*auxputc)(int, int);
static int dumpsc;
/*
* wait for output no longer busy
*/
static int
outready(void)
{
int tries;
for(tries = 0; (inb(Status) & Outbusy); tries++){
if(tries > 500)
return -1;
delay(2);
}
return 0;
}
/*
* wait for input
*/
static int
inready(void)
{
int tries;
for(tries = 0; !(inb(Status) & Inready); tries++){
if(tries > 500)
return -1;
delay(2);
}
return 0;
}
/*
* ask 8042 to reset the machine
*/
void
i8042reset(void)
{
ushort *s = KADDR(0x472);
int i, x;
*s = 0x1234; /* BIOS warm-boot flag */
/*
* newer reset the machine command
*/
outready();
outb(Cmd, 0xFE);
outready();
/*
* Pulse it by hand (old somewhat reliable)
*/
x = 0xDF;
for(i = 0; i < 5; i++){
x ^= 1;
outready();
outb(Cmd, 0xD1);
outready();
outb(Data, x); /* toggle reset */
delay(100);
}
}
int
i8042auxcmd(int cmd)
{
unsigned int c;
int tries;
c = 0;
tries = 0;
ilock(&i8042lock);
do{
if(tries++ > 2)
break;
if(outready() < 0)
break;
outb(Cmd, 0xD4);
if(outready() < 0)
break;
outb(Data, cmd);
if(outready() < 0)
break;
if(inready() < 0)
break;
c = inb(Data);
} while(c == 0xFE || c == 0);
iunlock(&i8042lock);
if(c != 0xFA){
print("i8042: %2.2ux returned to the %2.2ux command\n", c, cmd);
return -1;
}
return 0;
}
/*
* keyboard interrupt
*/
static void
i8042intr(Ureg*, void*)
{
int s, c, i, sc;
static int esc1, esc2;
static int alt, caps, ctl, num, shift;
static int collecting, nk;
static Rune kc[5];
int keyup;
/*
* get status
*/
lock(&i8042lock);
s = inb(Status);
if(!(s&Inready)){
unlock(&i8042lock);
return;
}
/*
* get the character
*/
sc = c = inb(Data);
unlock(&i8042lock);
/*
* if it's the aux port...
*/
if(s & Minready){
if(auxputc != nil)
auxputc(c, shift);
return;
}
/*
* e0's is the first of a 2 character sequence
*/
if(c == 0xe0){
esc1 = 1;
return;
} else if(c == 0xe1){
esc2 = 2;
return;
}
keyup = c&0x80;
c &= 0x7f;
if(c > Kbsize){
c |= keyup;
if(c != 0xFF) /* these come fairly often: CAPSLOCK U Y */
print("unknown key %ux\n", c);
return;
}
if(dumpsc){
print("kbd scan: 0x%ux\n", sc);
}
if(esc1){
c = kbtabesc1[c];
esc1 = 0;
} else if(esc2){
esc2--;
return;
} else if(shift)
c = kbtabshift[c];
else
c = kbtab[c];
if(caps && c<='z' && c>='a')
c += 'A' - 'a';
/*
* keyup only important for shifts
*/
if(keyup){
switch(c){
case Latin:
alt = 0;
break;
case Shift:
shift = 0;
break;
case Ctrl:
ctl = 0;
break;
}
return;
}
/*
* normal character
*/
if(!(c & (Spec|KF))){
if (dumpsc)
return;
if(ctl){
if(alt && c == Del)
exit(0);
c &= 0x1f;
}
if(!collecting){
kbdputc(kbdq, c);
return;
}
kc[nk++] = c;
c = latin1(kc, nk);
if(c < -1) /* need more keystrokes */
return;
if(c != -1) /* valid sequence */
kbdputc(kbdq, c);
else /* dump characters */
for(i=0; i<nk; i++)
kbdputc(kbdq, kc[i]);
nk = 0;
collecting = 0;
return;
} else {
switch(c){
case KF1:
dumpsc = 1;
return;
case KF2:
dumpsc = 0;
return;
case Caps:
caps ^= 1;
return;
case Num:
num ^= 1;
return;
case Shift:
shift = 1;
return;
case Latin:
alt = 1;
collecting = 1;
nk = 0;
return;
case Ctrl:
ctl = 1;
return;
}
}
kbdputc(kbdq, c);
}
void
i8042auxenable(void (*putc)(int, int))
{
char *err = "i8042: aux init failed\n";
/* enable kbd/aux xfers and interrupts */
ccc &= ~Cauxdis;
ccc |= Cauxint;
ilock(&i8042lock);
if(outready() < 0)
print(err);
outb(Cmd, 0x60); /* write control register */
if(outready() < 0)
print(err);
outb(Data, ccc);
if(outready() < 0)
print(err);
outb(Cmd, 0xA8); /* auxilliary device enable */
if(outready() < 0){
iunlock(&i8042lock);
return;
}
auxputc = putc;
intrenable(IrqAUX, i8042intr, 0, BUSUNKNOWN, "kbdaux");
iunlock(&i8042lock);
}
void
kbdinit(void)
{
int c;
kbdq = qopen(4*1024, 0, 0, 0);
if(kbdq == nil)
panic("kbdinit");
qnoblock(kbdq, 1);
ioalloc(Data, 1, 0, "kbd");
ioalloc(Cmd, 1, 0, "kbd");
intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN, "kbd");
/* wait for a quiescent controller */
while((c = inb(Status)) & (Outbusy | Inready))
if(c & Inready)
inb(Data);
/* get current controller command byte */
outb(Cmd, 0x20);
if(inready() < 0){
print("kbdinit: can't read ccc\n");
ccc = 0;
} else
ccc = inb(Data);
/* enable kbd xfers and interrupts */
/* disable mouse */
ccc &= ~Ckbddis;
ccc |= Csf | Ckbdint | Cscs1;
if(outready() < 0)
print("kbd init failed\n");
outb(Cmd, 0x60);
if(outready() < 0)
print("kbd init failed\n");
outb(Data, ccc);
outready();
}
[-- Attachment #3: kbd.h --]
[-- Type: text/plain, Size: 695 bytes --]
enum
{
Spec= 0x80,
PF= Spec|0x20, /* num pad function key */
View= Spec|0x00, /* view (shift window up) */
KF= 0xF000, /* function key (begin Unicode private space) */
Shift= Spec|0x60,
Break= Spec|0x61,
Ctrl= Spec|0x62,
Latin= Spec|0x63,
Caps= Spec|0x64,
Num= Spec|0x65,
Middle= Spec|0x66,
No= 0x00, /* peter */
Home= KF|13,
Up= KF|14,
Pgup= KF|15,
Print= KF|16,
Left= KF|17,
Right= KF|18,
End= '\r',
Down= View,
Pgdown= KF|19,
Ins= KF|20,
Del= 0x7F,
Scroll= KF|21,
KF1= KF|1,
KF2= KF|2,
};
#define Kbsize (0x7f*sizeof(Rune))
extern Rune kbtab[];
extern Rune kbtabshift[];
extern Rune kbtabesc1[];
[-- Attachment #4: kbdus.c --]
[-- Type: text/plain, Size: 2460 bytes --]
/*
* The codes at 0x79 and 0x81 are produed by the PFU Happy Hacking keyboard.
* A 'standard' keyboard doesn't produce anything above 0x58.
*/
#include "u.h"
#include "kbd.h"
Rune kbtab[] =
{
[0x00] No, 0x1b, '1', '2', '3', '4', '5', '6',
[0x08] '7', '8', '9', '0', '-', '=', '\b', '\t',
[0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
[0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's',
[0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v',
[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
[0x50] '2', '3', '0', '.', No, No, No, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, View, No, Up, No, No, No, No,
};
Rune kbtabshift[] =
{
[0x00] No, 0x1b, '!', '@', '#', '$', '%', '^',
[0x08] '&', '*', '(', ')', '_', '+', '\b', '\t',
[0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
[0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S',
[0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V',
[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
[0x50] '2', '3', '0', '.', No, No, No, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, Up, No, Up, No, No, No, No,
};
Rune kbtabesc1[] =
{
[0x00] No, No, No, No, No, No, No, No,
[0x08] No, No, No, No, No, No, No, No,
[0x10] No, No, No, No, No, No, No, No,
[0x18] No, No, No, No, '\n', Ctrl, No, No,
[0x20] No, No, No, No, No, No, No, No,
[0x28] No, No, Shift, No, No, No, No, No,
[0x30] No, No, No, No, No, '/', No, Print,
[0x38] Latin, No, No, No, No, No, No, No,
[0x40] No, No, No, No, No, No, Break, Home,
[0x48] Up, Pgup, No, Left, No, Right, No, End,
[0x50] Down, Pgdown, Ins, Del, No, No, No, No,
[0x58] No, No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, Up, No, No, No, No, No, No,
};
[-- Attachment #5: pcdisk --]
[-- Type: text/plain, Size: 641 bytes --]
dev
root
cons
arch
env
pipe
proc
mnt
srv
dup
rtc
ssl
bridge
loopback
kprof
ether netif
ip arp chandial ip ipaux iproute netlog nullmedium pktmedium ptclbsum386 inferno
draw screen vga vgax
mouse mouse
vga
sd
floppy dma
audio dma
i82365 cis
lpt
ns16552
link
apm apmjump
etherwavelan
ethermedium
loopbackmedium
pcmciamodem
misc
archmp mp apic
cfs.root
kfs.root
ppp.root
ipconfig.root
sdata pci sdscsi
kbdus
vgamach64xx +cur
ip
il
tcp
udp
rudp
ipifc
icmp
gre
ipmux
port
int cpuserver = 0;
boot boot #S/sdC0/
il
local
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2002-02-08 15:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-02-08 15:53 [9fans] keyboad maps revisited Fco.J.Ballesteros
-- strict thread matches above, loose matches on Subject: below --
2002-02-08 15:42 Fco.J.Ballesteros
2002-02-08 15:49 ` Boyd Roberts
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).