Em que o poeta compartilha seus nem tão vastos conhecimentos sobre alteração de keymaps no X. Em um post futuro, pretendo falar sobre as modificações que fiz em meu keymap e que achei úteis.
Keymaps no X funcionam da seguinte maneira: A cada tecla está associado um keycode, um número único para cada tecla. Ao pressionar (ou soltar) uma tecla, o X envia o keycode ao cliente que tem o foco do teclado. O cliente, então, pode fazer o que bem entender com esse keycode. Na maior parte dos casos, entretanto, o cliente utiliza-se da keymap table que o servidor X armazena para converter um keycode em um keysym, que dá o significado da tecla em questão. Por exemplo, ao pressionar a tecla Enter, o X repassa para o cliente o keycode 36 (em um teclado comum de PC), que normalmente está associado a um keysym Return na tabela de keymap. Você pode alterar a keymap table usando um programinha chamado xmodmap. Alternativamente, você pode usar alguma outra interface para realizar essa tarefa, como o programa gráfico XKeyCaps (que altera a keymap table em tempo real e gera um arquivo de configuração para o xmodmap).
A cada keycode está associado mais de um keysym; o keysym apropriado depende dos modificadores que estão ativos no momento em que a tecla é pressionada. Em geral, as teclas Shift e AltGr estão associadas a modificadores que influenciam na seleção do keysym (e.g., em um teclado ABNT2, o keycode 10 está associado aos keysyms 1, exclam (Shift+1) e onesuperior (AltGr+1)). [O Caps_Lock também controla um modificador, que não é o mesmo do Shift; mais informação adiante.]
Insatisfeitos com os poderes do xmodmap, o povo do X inventou o Xkb, um mecanismo mais flexível para a especificação de keymaps. Em tese, a criação do Xkb torna o xmodmap obsoleto, mas como disse um sábio:
In principle, Xkb is supposed to take over. In practice, there are only three people in the known universe who understand Xkb, and nobody is quite sure who they are.
O xmodmap, embora apresente o ocasional bug, é bem mais simples de usar do que o Xkb. (Os relatos de experiências com a migração do xmodmap para o Xkb que eu vejo por aí não são muito animadores.) Ainda não estudei o Xkb direito para poder dar instruções; talvez eu poste algo sobre ele no futuro. Para mais informações, vide links. Neste post, focarei no xmodmap.
Usualmente, o xmodmap lê de um arquivo uma série de comandos, um por linha, que indicam as alterações que se deseja realizar no keymap. O tipo de comando mais simples é da forma:
keycode número = keysym1 keysym2 ...
Esse comando associa os keysyms ao keycode especificado. Até 8 keysyms podem ser especificados em um comando keycode. O primeiro keysym é usado quando a tecla é pressionada sozinha. O segundo é usado quando a tecla é pressionada enquanto o Shift está ativo. O terceiro é usado quando Mode_switch está ativo (já chegamos lá); o quarto com Mode_switch+Shift; o quinto com ISO_Level3_Shift; o sexto com ISO_Level3_Shift+Shift.
No começo dos tempos, Mode_switch correspondia ao AltGr. Os quatro primeiros keysyms correspondiam à tecla pura, Shift, AltGr e AltGr+Shift. E o mundo era feliz.
Por algum diabo, em algum ponto da história o AltGr passou a ser mapeado como ISO_Level3_Shift na maior parte dos keymaps padrão do X. A conseqüência mais visível disso é que o terceiro e quarto keysym da tabela do xmodmap não fazem nada no keymap padrão. Conseqüentemente, se você pretende atribuir um keysym diferente para AltGr+alguma-coisa, você deve preencher as colunas 3 e 4 com algum valor tapa-buraco (e.g., NoSymbol, ou uma cópia das colunas 5 e 6, ou qualquer coisa).
Se o problema fosse só esse, seria apenas um pequeno inconveniente. O problema é que o tal ISO_Level3_Shift é uma invenção do Xkb que não interage muito bem com o xmodmap. Se uma tecla não possui um valor associado a ISO_Level3_Shift+tecla no keymap padrão, não é possível associar um valor a essa combinação via xmodmap; o X simplesmente ignorará o valor das colunas 5 e 6. Por exemplo, se você está usando um keymap us-intl (US Internacional) com AltGr mapeado para ISO_Level3_Shift, você conseguirá alterar o keysym da combinação AltGr+a, pois essa combinação existe no keymap original, mas você não conseguirá atribuir efetivamente um keysym a AltGr+j, pois essa combinação não possui mapeamento no us-intl. Da mesma forma, você não conseguirá mapear AltGr-↑.
A solução mais simples para esse problema é simplesmente remapear o AltGr para Mode_switch e ser feliz para sempre. O problema é que nesse caso você perde todos os mapeamentos com AltGr que possam existir originalmente no seu keymap padrão, pois eles estão associados ao ISO_Level3_Shift. Por exemplo, se você remapear o AltGr para Mode_switch em um layout ABNT2, você perderá o mapeamento padrão de AltGr+1 para ¹ e terá que remapeá-lo manualmente (ou com um script; vejamos mais adiante) se desejá-lo.
Evidentemente, isso só é um problema se você deseja usar o AltGr com alguma tecla não prevista no layout original.
A solução de remapear o AltGr não resolve o problema se você deseja ter tanto o Mode_switch quanto o ISO_Level3_Shift no mesmo teclado (permitindo associar seis keysyms por tecla). Nesse caso, você vai ter que arranjar um keymap do Xkb que mapeie todas as combinações desejadas com ISO_Level3_Shift. O keymap br(abnt2) parece servir bem para esse propósito. Em último caso, você pode experimentar alterar os arquivos /usr/share/X11/xkb/symbols/us e companhia e adicionar o que falta (mas nesse caso não teria mais por que usar o xmodmap, em tese (exceto pelo fato de que é mais prático alterar o teclado posteriormente via xmodmap do que alterando os arquivos de sistema)).
Quanto às colunas 7 e 8, elas aparentemente não servem para nada. Dizem as más línguas que elas deveriam conter o keysym associado à combinação Mode_switch+ISO_Level3_Shift+Shift+tecla, mas nunca consegui fazer funcionar. Tentar criar um modificador ISO_Level4_Shift ou ISO_Level5_Shift também não foi eficaz. (Por sinal, o keysym ISO_Level4_Shift não existe, mas ISO_Level5_Shift sim. Go figure.)
O X vem com um programinha supimpa chamado xev. Esse programa cria uma janela e reporta pela stdout (o terminal por onde você abriu o xev) todos os eventos que essa janela recebe. Assim, ao pressionar uma tecla, o xev imprimirá algo do tipo:
KeyPress event, serial 33, synthetic NO, window 0x2200001, root 0x69, subw 0x0, time 39264530, (38,371), root:(1137,799), state 0x0, keycode 98 (keysym 0xff52, Up), same_screen YES, XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False
Com isso, você consegue descobrir o keycode da tecla (para poder atribuir keysyms) e o keysym que ela gera atualmente (para poder atribuí-lo a outra tecla).
Se você deseja atribuir a uma tecla um keysym que ainda não existe no seu keymap e que você não sabe o nome (e.g., se você quiser atribuir o caractere ĉ à combinação Mode_switch+c), você pode:
Em alguns casos você não precisa saber o keycode de uma tecla para mapeá-la. O xmodmap reconhece o comando:
keysym keysym_velho = keysym1 keysym2 ...
Nesse caso, o xmodmap procura por todos keycodes que atualmente estão associados ao keysym_velho, e lhes atribui os valores novos. Isso é particularmente útil quando se deseja apenas associar valores novos às combinações com AltGr, sem alterar o valor puro da tecla:
! O primeiro par ccedilla/Ccedilla para o Mode_switch, o segundo para o ISO_Level3_Shift. keysym c = c C ccedilla Ccedilla ccedilla Ccedilla
Para modificações que alteram o valor puro da tecla, entretanto, usar o comando keysym pode não ser uma boa idéia. Suponha que você deseja trocar os parênteses e os colchetes de lugar no teclado:
keysym 9 = 9 bracketleft keysym 0 = 0 bracketright keysym bracketleft = parenleft braceleft keysym bracketright = parenright braceright
A aplicação dessas modificações no keymap original funciona (o xmodmap é esperto o suficiente para primeiro avaliar todos os lados esquerdos do =, e depois efetuar as mudanças, de modo que a alteração das duas primeiras linhas não interfere no funcionamento das duas últimas numa mesma execução). Porém, se esse arquivo de keymap for carregado uma segunda vez, catástrofes acontecem: as duas primeiras linhas fazem o que deveriam, mas as duas últimas associam parênteses a todas as teclas que atualmente estão mapeadas para colchetes, ou seja, as teclas 9 e 0! Como os comandos são avaliados na ordem, as duas últimas linhas sobrepõem o mapeamento de 9 e 0, de modo que tanto 9 e 0 quanto as teclas de colchetes agora contêm parênteses!
Evidentemente, o problema só surge se você carregar o arquivo duas vezes. Porém, enquanto você está experimentando com keymaps, você provavelmente vai querer fazer alterações e recarregar o arquivo de keymap diversas vezes sem ter que reiniciar o X. Em qualquer caso, parece melhor escrever um keymap que faz a coisa certa quando é carregado múltiplas vezes do que encontrar surpresas no futuro e levar mil instantes para entender o que está acontecendo.
Moral da história: só use o keysym para alterar valores secundários das teclas, e isso só se você tiver certeza de que keysym_velho só ocorre uma vez no keymap, ou que você queira realmente alterar todas as teclas associadas ao keysym_velho.
Remapear modificadores (Ctrl, Alt, Shift, Caps_Lock, JanelinhaFeliz, etc.) envolve alguns detalhes mais.
O X mantém uma tabela de modificadores; se você executar xmodmap sem parâmetros, ele imprimirá essa tabela. Essa tabela associa keycodes a modificadores. Os modificadores reconhecidos são control, shift (auto-explicativos), lock (correspondente ao Caps_Lock), e mod1 até mod5 (que não têm significado pré-definido). Sempre que você altera o mapeamento de uma tecla associada a modificadores, você deve lembrar de reajustar a tabela de modificadores também. Para controlar essa tabela, o xmodmap provê os comandos add, remove e clear.
add modifier_name = keysym ... adiciona as teclas associadas aos keysyms especificados à lista de teclas que ativam o modificador. Se você executar um comando do tipo add shift = a, o efeito será que a tecla A, além de funcionar como um A normal, também passará a funcionar como um Shift: se você segurar a tecla A enquanto digita outras teclas, o efeito será o mesmo de segurar Shift ao mesmo tempo que as outras teclas.
remove modifier_name = keysym ... desassocia todas as teclas associadas aos keysyms especificados do modificador em questão. clear modifier_name desassocia todas as teclas do modificador. O fato de que os comandos trabalham com keysyms mas a tabela trabalha com keycodes gera todo tipo de bizarrice na manipulação de keymaps. No geral, o mais simples, prático e indolor é, sempre que se remapeia teclas associadas a modificadores, limpar os modificadores em questão, fazer o remapeamento e adicionar as teclas novamente.
Exemplo: para inverter a posição usual do Ctrl da esquerda e do Caps_Lock:
clear lock clear control ! Keycodes do Ctrl e Caps_Lock obtidos com o xev. Os valores podem ser diferentes no ! seu teclado / versão do X. keycode 66 = Control_L keycode 37 = Caps_Lock add lock = Caps_Lock ! Não esqueça de readicionar o Ctrl da direita, que foi apagado no clear. add control = Control_L Control_R
Além do xmodmap arquivo, para carregar um arquivo com comandos, o xmodmap suporta algumas outras opções. Em primeiro lugar, usando - como arquivo, o xmodmap lê da stdin. Isso é primariamente útil se por alguma razão você quiser gerar um keymap por script e alimentá-lo ao xmodmap. Além disso, o xmodmap suporta uma opção -e comando, que permite executar um comando de keymap diretamente a partir da linha de comando. Por exemplo:
xmodmap -e 'keysym a = a A ae AE'
Cada comando consiste de apenas um comando de keymap, mas a opção -e pode ser repetida.
Outro comando útil é xmodmap -pke, que imprime o keymap atual no formato que o xmodmap lê. Assim, você pode salvar o keymap atual com xmodmap -pke >.xmodmaprc e carregá-lo posteriormente (em outra sessão do X) com xmodmap .xmodmaprc. Isso é útil se você fez diversas modificações no layout pela linha de comando e deseja salvar o estado atual sem ter que encontrar todos os comandos dados e agrupá-los em um arquivo. (O xmodmap -pke não imprime linhas add, remove e clear, entretanto.) Isso também é útil para salvar o keymap atual antes de começar a bagunçá-lo, para poder retornar a um estado consistente sem ter que reiniciar o X. Para isso, é bom criar um meio de invocar o xmodmap seu-teclado-original sem ter que usar o teclado (e.g., com um atalho no seu ambiente gráfico favorito).
Todas as modificações feitas na keymap table duram apenas até o servidor X morrer; na próxima inicialização, a tabela volta a ser o que era. Para tornar as modificações permanentes, você precisa carregá-las toda vez que sua sessão X inicia. Para isso, você deverá colocar o comando xmodmap ~/seu-arquivo-com-comandos-de-keymap em algum lugar que seja executado pelo seu ambiente gráfico na inicialização. Se você usa o xinit para carregar a interface gráfica, o arquivo é o .xinitrc, no seu home. Alguns ambientes gráficos carregam o .xsessionrc. Alguns permitem que você adicione comandos para serem executados na inicialização em alguma configuração do ambiente. Finalmente, se não estou enganado, o GNOME detecta por conta arquivos de nome .xmodmaprc e assemelhados na inicialização e pergunta se você deseja carregá-los na inicialização da primeira vez que os encontra.
Na transição do driver de teclado kbd para evdev (i.e., da época do Debian 4 para o Debian 5, embora ainda seja possível usar o driver kbd hoje em dia, desde que seja instalado o pacote xserver-xorg-input-kbd), algumas teclas mudaram de keycode. Em particular, o AltGr mudou de 113 para 108, e as setas e algumas outras teclas especiais também mudaram. Isso pode causar algum problema na hora de migrar de uma versão velha do X para uma mais recente.
Eu prometi links com informações sobre o Xkb. Eis o que eu encontrei (e ainda não li, mostly):
EOF.
Obrigado! :D
Muito obrigado, aprendi muito aqui.
Copyright © 2010-2024 Vítor De Araújo
O conteúdo deste blog, a menos que de outra forma especificado, pode ser utilizado segundo os termos da licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.
Powered by Blognir.
pj, 2012-08-30 20:30:57 -0300 #
Vitor, realmente vc é o cara!!! eu optei pelo awesome para usar com o debian e estava procurando uma documentação+softwares sobre configuração de teclados para hotkyes do meu net, e achei massa essa sua idéia de fazer um blog na sua home no public_html! há tempos tb que quero fazer um blog, eu cheguei até a criar um no softwarelivre.org, mas dessisti... eu acho que vc te imitar... =-P
Parabéns cara!!!