MC's Journal

Tangentbordsmappningar i FreeBSD-konsollen (och några till X)

Ibland arbetar jag i FreeBSD:s konsoll. Ibland är det av nödvändighet, till exempel för att maskinen jag sitter vid saknar X eller för att X inte ännu blivit konfigurerat eller, gudinnan förbjude, för att jag supit sönder min X-installation!

Det finns också dagar då jag vill undvika X. Jag blir ibland irriterad på um... bloatware i allmänhet och då får X stryk av bara farten, inte nödvändigtvis för att X på sistone gjort sig mer förtjänt av det än andra program (Firefox... *host* OpenOffice.org!), men X gör det också möjligt att överhuvudtaget köra dessa bestar. Då går jag tillfälligt tillbaka till något slags terminalläge och stannar där ett tag. Ibland höjer det min produktivitet något enastående!

Naturligtvis vill jag i konsollen ha samma tangentbordsmappning som jag har i X, så jag har skapat en svensk tangentbordsmappning med mina specialare, måsvingar och hakparenteser på de svenska tecknen + AltGr:

Mappningen ger också sådana saker som ESC direkt till vänster om "1" och Control i stället för Caps Lock. Dessutom byter funktionstangenterna virtuell konsoll omodifierade.

Här är tangentbordsmappningen:

http://hack.org/mc/files/freebsd-sw.kbd

Ladda in den med:

% kbdcontrol -l freebsd-sw.kbd

direkt i en konsoll.

Så långt allt väl.

Nu för tiden använder jag förstås mitt Happy Hacking Keyboard även i FreeBSD-konsollen. Det är ju lite annorlunda, så jag skapade nya mappningar.

Här är min svenska mappning:

http://hack.org/mc/files/freebsd-hhkb-se.kbd

HHKB saknar emellertid en del av knapparna som finns på ett vanligt svensk tangentbord, så jag har stoppat in några tecken på andra ställen:

Motsvarande mappning för HHKB för X finns förresten här:

http://hack.org/mc/files/hhkb-se.xmodmap

Jag har också fixat en mappning för amerikanskt tangentbord (det som är tryckt på mitt HHKB), fast med svenska tecken på Alt + [\]:

http://hack.org/mc/files/freebsd-hhkb-us.kbd

Dito för X: http://hack.org/mc/files/hhkb-us.xmodmap

Här är samma sak, fast med svenska tecken per default på de tangenterna (originaltangenterna med höger Alt):

http://hack.org/mc/files/freebsd-hhkb-us-se.kbd

Dito för X: http://hack.org/mc/files/hhkb-us-se.xmodmap.

Scancodes

FreeBSD:s mapfiler använder scancodes för att ange vilken tangent som skall ge vilka tecken. Det kan vara svårt att veta vilken scancode en viss tangent ger.

När jag idag satt och jobbade med de här bråkade mitt HHKB och en del tangenter hade jag ingen aning om vad de gav för scancodes. Pinsamt nog insåg jag att jag inte hade någon aning om hur jag skulle ta reda på det annat än genom att modifiera kärnan! Det verkade som lätt overkill.

Jag googlade på det och hittade att många hade haft motsvarande problem, men såg inga bra svar. En del svar visade att de som svarade trodde att frågeställaren i själva verket körde X. Till slut hittade jag med lite kreativ googling (jag tror jag sökte på syscons scancode: syscons är namnet på FreeBSD:s konsoll-drivare) och hittade en rysk sida:

http://www.tsu.ru/~pascal/unix/syscons/

Jag kan inte alls läsa ryska, så jag förstod förstås inte ett smack, men såg också ett program:

http://www.tsu.ru/~pascal/unix/syscons/scancode.c

Här är källkoden:

#include <machine/console.h>
#include <ncurses.h>

main()
{ char c;

  initscr(); savetty(); raw(); noecho();
  if (ioctl(0, KDSKBMODE, K_CODE) < 0) perror(0);

  do {
   c = getchar();
   if ( c > 0) {
      printf("%d\n\r", c);
      fflush(stdout);
   }
  } while (c != 1);

  if (ioctl(0, KDSKBMODE, K_XLATE) < 0) perror(0);
  resetty();

  exit();
}

Det kompilerar tyvärr inte under en modern FreeBSD eller i alla fall inte under min 7.2:a. Jag greppade efter konstanterna som nämndes i koden och ändrade include-filerna med det här resultatet:

#include <sys/consio.h>
#include <sys/kbio.h>
#include <ncurses.h>

main()
{ char c;

  initscr(); savetty(); raw(); noecho();
  if (ioctl(0, KDSKBMODE, K_CODE) < 0) perror(0);

  do {
   c = getchar();
   if ( c > 0) {
  printf("%d\n\r", c);
  fflush(stdout);
   }
  } while (c != 1);

  if (ioctl(0, KDSKBMODE, K_XLATE) < 0) perror(0);
  resetty();

  exit(0);
}

och det fungerar!

Kompilera så här:

% gcc -o scancode scancode.c -lncurses

och kör så:

% ./scancode

ESC avslutar, förhoppningsvis. I alla fall om ESC genererar scancode 1 på ditt tangentbord också. Det vore nog bra att stoppa in en timer där i stället, som avslutar programmet om ingenting hänt på några sekunder.

På så sätt kunde jag få reda på att metatangenten (diamanten) på mitt HHKB genererade scancode 123. Tyvärr gjorde bara den vänstra det. Den högra gav ingen scancode alls! Jag får kanske leva med det.

Jag skrev faktiskt delar av det ovan även på engelska här:

http://hack.org/mc/writings/freebsd-kbd.html

speciellt eftersom det saknades information om scancodes i FreeBSD-konsollen på webben. Kanske kan det hjälpa åtminstone någon.