Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I would like to remap CapsLock to Esc when pressed by itself and Ctrl when pressed with another key without using X.

This is similar to a previous question ( Remap CapsLock to Escape and Control System Wide ) but I am specifically looking for a solution without X.

share|improve this question
    
What operating system would you like to do this in? –  paraxor Jul 20 '13 at 20:52
    
@evan Linux. Specifically Arch. The motivation is to transport my setup from my Macbook to my new machine. –  Casey Robinson Jul 20 '13 at 21:15
    
I'm pretty sure the only way to do this is by writing some kernel code. Why aren't you using X? –  Gilles Jul 20 '13 at 22:47
    
I am using a netbook to program and would rather not waste RAM on X to run a vim. –  Casey Robinson Jul 21 '13 at 12:16
1  
Wow, I almost asked this exact question. I'm using a Chromebook with a Debian chroot (CLI only) and hence no X11. –  hoosierEE Jan 27 at 15:39

2 Answers 2

up vote 2 down vote accepted
+50

This keymod program reads keyboard events from a /dev/input/eventX device and injects most directly back into the kernel using the /dev/uinput device. The caps lock behavior is special: if the key is pressed and released without touching another key, an Esc key is sent into the kernel. If another key is pressed while holding the caps lock, holding the (left) control key is emulated instead.

Since the program takes control over the specified event device, being able to access the computer using e.g. SSH can be very handy when testing this. For example, pausing this program (using ctrl-z for example) will make sure you can't use your keyboard anymore (it has taken control over it exclusively and is now no longer active).

share|improve this answer
    
Thanks for sharing your program. Kinda scary about the Ctrl-Z thing though... :) –  hoosierEE Feb 3 at 0:18
    
Should be better now, added a signal handler which releases the event device when ctrl-z is pressed. Still possible to get in trouble if you send SIGSTOP directly though. –  brm Feb 3 at 19:13
    
Excellent! Thanks for the program and explanation. –  Casey Robinson Feb 6 at 15:56

Linux Console Keymaps

To change the keymaps for the virtual terminals ( alt+f1 - alt+f6 ) you use loadkeys. This only effects the virtual terminal logins and will not change keymaping in X or X terminal apps like Xterm or urxvt.

The loadkeys command needs to be run as root or you will get the following error:
Couldn't get a file descriptor referring to the console

To swap escape and caps_lock you would do the following:

# echo keycode 58 = Escape | loadkeys -
# echo keycode 1 = Caps_Lock | loadkeys -

Another option is to remap the Caps_Lock to shift + Scroll Lock

# echo keycode 69 = Num_Lock  Caps_Lock | loadkeys -

The format of the keymaps can be a little confusing. It using a weighting system depending on which modifiers that are pressed. ( Ctrl, Alt, Shift, etc ). As an example from the man page for keymaps.

keycode 30 = a    A    VoidSymbol    VoidSymbol   VoidSymbol  .....

When the shift and a is pressed we do the action in the second column because shift has a weighting of 1. control on the other hand has a weighting of four.

This can cause problems when mapping modifiers. Take for instance if a keycodes first and only column is control as its action. Now the weighting since you pressed it is now 4 and when you release the key it the control is not show released because the 5th column action is now to be performed but it has no action defined. So the control key is never released.

This is why most modifiers have no other action assigned. If only one action is defined in the keyboard mapping then it is applied to all actions.

I have played around trying to work around this but have only ever got inconsistent results. Sometimes the modifier releases, sometimes it does not.

Clarification

Changing the Caps Lock to perform as either escape or as control works great with this method. Mapping to both, not so much.

IMPORTANT

If you screw up your keymap do the following to reset it.

# loadkeys -d

References

share|improve this answer
    
Great answer with plenty of explanations and examples. But it does not solve the problem. –  Casey Robinson Feb 6 at 16:09
    
Best I can tell you cannot get the desired results with the default keyboard mapping tools. –  rking Feb 7 at 3:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.