# Changing keyboard layout & multiple keyboards

#### kamaz

##### Unicorn hunter
Keyboard remapping for fun and profit!

- Are you dissatified with default key bindings in Orbiter?

- Do you want to use a cheap keyboard / keypad in your simpit, but feel too limited by the default layout of controls?

- Would you like to use multiple keyboards?

- Would you like to send multiple key combos with a single key press?

If yes, then this program is for you!

Installation

The program is based on Oblitum Interception library, which performs a low-level keyboard interception using a kernel driver. For more information, see http://oblita.com/Interception.html

2. Run the command prompt as administrator: Start Menu > All Programs > Accessories > Command prompt, right click, Run as administrator

3. Navigate to the directory, where you downloaded install-interception.exe and run install-interception.exe /install

4. Reboot the system.

Tutorial

This tutorial assumes that you have 2 keyboards connected to your computer. We will remap the "x" key on the first keyboard to generate "foo" keystrokes, while the "x" key on the second keyboard will generate "bar".

First, start the program. If no parameters are given, it will start in interactive mode. (Use /help switch to learn more about command line parameters).

Code:
D:\intercept\Release>intercept

*** Keyboard Remapper v. 1
*** Based on Oblitum Interception http://oblita.com/Interception.html

Use /help for help on command-line options

Using configuration file D:\intercept\Release\keyremap.ini

The program configuration is kept in an .ini file referenced above. By default, it is keyremap.ini located in the current directory. To use another ini file, use /ini command line switch.

Let's list existing filters -- press "L" at the prompt:

Code:
(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?: l

(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?:

Predictably, there are none, because we are just starting. If you do that at the end of the tutorial, the output will look like that:

Code:
(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?: l

(1) x -> foo keyboard 1
(2) x -> bar keyboard 2

(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?:

Okay, let's remap the "X" key on the first keyboard, so pressing it will be equivalent to pressing F,O,O. Select the "Add" option by pressing "A":

Code:
(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?: a

Defining filter

Press key which will trigger the combo

Press "X" on the first keyboard.

Code:
  Trigger key: [X]↓
Keyboard: HID\VID_046D&PID_C22D&REV_0165&MI_00

The macro will trigger when pressing (↓) the "X" key on keyboard with Device ID HID\VID_046D&PID_C22D&REV_0165&MI_00.

Now, time to define what the macro does:

Code:
Enter combo for this trigger, end with Esc
(Empty combo will inhibit trigger key)

Press F,O,O followed by Esc:

Code:
[F]↓ [F]↑ [O]↓ [O]↑ [O]↓ [O]↑

Both pressing (↓) and releasing (↑) keys is recorded.

Pressing just Esc (i.e. defining empty combo) will have an effect of disabling the key. This can be useful e.g. to prevent accidentally pressing the Windows key while playing.

Enter macro description...

Code:
Enter filter label: x -> foo keyboard 1

The program now displays new macro definition for you to check:

Code:
  Trigger key: [X]↓
Keyboard: HID\VID_046D&PID_C22D&REV_0165&MI_00
Combo: [F]↓ [F]↑ [O]↓ [O]↑ [O]↓ [O]↑
Label: [x -> foo keyboard 1]

(S)ave filter or (C)ancel?:

Pressing "S" will save the new definition to the INI file.

Now, let us remap the "X" key on the second keyboard. Press "A" to define a new filter...

Code:
(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?: a

Defining filter

Press key which will trigger the combo

Press "X" again, but this time on the second keyboard:

Code:
  Trigger key: [X]↓
Keyboard: HID\VID_046E&PID_55A5&REV_0120&MI_00

Notice that the device identifier is different than in the first macro!

Enter the B,A,R,Esc combo, does not matter which keyboard you use...

Code:
Enter combo for this trigger, end with Esc
(Empty combo will inhibit trigger key)

[B]↓ [B]↑ [A]↓ [A]↑ [R]↓ [R]↑

Set macro label and save...

Code:
Enter filter label: x -> bar keyboard 2

Trigger key: [X]↓
Keyboard: HID\VID_046E&PID_55A5&REV_0120&MI_00
Combo: [B]↓ [B]↑ [A]↓ [A]↑ [R]↓ [R]↑
Label: [x -> bar keyboard 2]

(S)ave filter or (C)ancel?: s

Time to activate our setup, press "Y" in the main menu:

Code:
(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?: y

Keyboard filters activated.
Please close this window to restore normal behavior.
To activate filters on startup, add /apply to the command line.

Running filters...

Now, start notepad. Press "x" on the first keyboard. You should see that "foo" gets input instead of "x". Now, press "x" on the second keyboard. This should result in inputting "bar". All other keys should work normally.

Your new key assignments will remain active as long as the program is running.

#### Attachments

• intercept.zip
48.9 KB · Views: 428
• intercept.png
62.4 KB · Views: 166

#### AHKPPRO

##### New member
Excellent!

This is absolutely great - very easy to configure and 100% reliable, unlike other methods for remapping multiple keyboards, like HidMacros.

I have a few questions on the format of the .ini file, however. Say I have an entry like this:

Code:
[o] ; = w
device=ACPI\PNP0303
trigger=18,0,0
combo=11,0,0|11,0,1
This remaps o to w. I have realized that 0 or 1 following the second comma means key down or up, respectively, but here are my questions:

1. How can I remap or send extended keys like the left Windows key? I've tried setting the 0 after the first comma to 1, but that doesn't seem to work as an identifier for extended keys. See here for what I would like to send:
Code:
ext Scan    VK
E0 5B(91)  5B(91)             LeftWin

2. Is there any way to use Virtual Keycodes instead of scancodes?

Many thanks!

#### kamaz

##### Unicorn hunter
I have a user!

You of course CAN remap extended key. I'm not sure why you want to edit the INI yourself, if you can set mappings from within the program. Just press the key you want to remap. The session below is how I have remapped the left windows key to the sequence a,l,a:

Code:
(L)ist filters, (S)how/(A)dd/(R)emove filter, appl(Y) filters or (Q)uit?: a

Defining filter

Press key which will trigger the combo

Trigger key: [Left Windows]↓
Keyboard: HID\VID_046E&PID_55A5&REV_0120&MI_00

Enter combo for this trigger, end with Esc
(Empty combo will inhibit trigger key)

[A]↓ [A]↑ [L]↓ [L]↑ [A]↓ [A]↑

Enter filter label: ala

Trigger key: [Left Windows]↓
Keyboard: HID\VID_046E&PID_55A5&REV_0120&MI_00
Combo: [A]↓ [A]↑ [L]↓ [L]↑ [A]↓ [A]↑
Label: [ala]

(S)ave filter or (C)ancel?: s

This has produced the following in the INI file:

Code:
[ala]
device=HID\VID_046E&PID_55A5&REV_0120&MI_00
trigger=5b,0,2
combo=1e,0,0|1e,0,1|26,0,0|26,0,1|1e,0,0|1e,0,1

I have then selected apply filters, and it worked

Frankly, I am not 100% sure what the codes actually mean -- I simply dump the data structure that the interception driver returns

One key the program does not allow you to use in remapping is Esc, because it's used to terminate the keystroke sequence. But if you put 01 code in the ini file, then remapping to/from Esc will probably work

Last edited:

#### blixel

##### Donator
Donator
I was just shopping around online for a USB numeric keypad so I could have a small device that would give me an extra set of keys for Orbiter. (So I can map the commonly used ALT and CTRL key combos to one key stroke.) So it sounds like this is what I'll need to make that work.

#### Ripley

##### Tutorial translator
Donator
Sounds cool!
Are we talking about USB keyboards/keypads only, or with every kind of connection?

What about keypresses with modifiers, like "CTRL+T"?
Should I just record the macro as in "CTRL(↓) T(↓) T(↑) CTRL(↑)"?

Last edited:

#### kamaz

##### Unicorn hunter
Sounds cool!
Are we talking about USB keyboards/keypads only, or with every kind of connection?

I've tested only with USB keyboards. Theoretically though, it should work with anything.

What about keypresses with modifiers, like "CTRL+T"?
Should I just record the macro as in "CTRL(↓) T(↓) T(↑) CTRL(↑)"?

Yes!

#### gefliptemens

##### New member
Wow!

This is absolutely great, the first tool I've come across to do the job reliable!

Thank you so much, you've done an amazing job on this!:thumbup:

Now all I have to do is learn some C to modify it to my needs : P

#### geoffff

##### New member

I found that the Interception installer link you provided here is old, and does not work with Windows 8.1. The latest installer on github does work, and can be found here (download the "Interception.zip" link):

Anyway, thank you so much for posting this! This tool does a much better job than HID macros for keeping track of USB keyboards that are unplugged and then reattached.

-- Geoff

#### Grey

##### New member
Thank you

I know its an old thread, but even in 2016 this is a relevant thread.
For over 10 years I have been off and on trying to get a usb numpad to work separate from the numpad on the keyboard.
I thank you for the thread, thank you for the original author, thank you to the site for this thread, as without this thread I would still be waiting.

#### tripleg58

##### New member
This does not work if keyboards have same HID!!!!!!!!!!!!!!!!!!!!!!!

#### facelesssoul

##### New member
I just wanted to thank the OP for the program. I bought a 7 button mouse, only to discover that the 'extra' buttons are actually mapped as keyboard multimedia keys!

After a little search around the web, this forum post was the only thing that was relevant so now I can map the multimedia mouse keys to keyboard keys as well as use an old keyboard as a 'pedal' AND I was introduced to this simulator

Thanks again to the OP and I hope that this post is not counted as a necro as it will help many others with the same situation.

#### AlbertNew

##### New member
This does not work if keyboards have same HID!!!!!!!!!!!!!!!!!!!!!!!

Aah, you're right. Is there a fix guys?

#### sebcbien

##### New member
Hello,
First, thanks for this amazing piece of software, it works perfectly !:thumbup:

I'm a new user here, and sorry for necropost but my question is really related to this post.

Do you know if I can use the numlock to "shift" the numpad ?
I would like to double the keys of my numpad using the numlock, but my tests have failed until now, with or without numlock, the key "7" for example returns always "7"

Seb

#### Summoner

##### New member
Is there a way to have this launched at system startup that doesn't require leaving a command window open?

I've put a batch file to launch it in my startup folder; which covers the first half of what I want, but leaves the command window visible.

#### x0a

##### New member
Is there a way to introduce a delay between each key press/unpress?

#### Summoner

##### New member
Is there a way to introduce a delay between each key press/unpress?

The setup tool creates entries in the .ini file that trigger the keyup event immediately after the key down. You can decompose those so the keyup isn't sent until you actually lift the key.

I didn't save a before version of my .ini file; but this is what the split apart up/down mappings I'm using look like:

Code:
[left command to alt down]
device=HID\VID_05AC&PID_027C&REV_0927&MI_01&Col01
trigger=5b,0,2
combo=38,0,0
[left command to alt up]
device=HID\VID_05AC&PID_027C&REV_0927&MI_01&Col01
trigger=5b,0,3
combo=38,0,1

#### dannyrb

##### New member
I landed here after googling how to accomplish something like this, although my reason is different.

I'm also bumping up against the unique HID issue. I think the original program needs to be recompiled to use the dynamic device id instead of the hardware ID to overcome conflicts.

I'll try to take a stab and share if I land on something that works. My background is C#/JavaScript, but hopefully I can muddle through.

#### dannyrb

##### New member
I didn't want to leave y'all hanging. Although, most of you are likely far gone from here. Hopefully this helps some other lost/wayward soul that has this very specific problem also plaguing them. The bit of code you need to change to work around the conflicting HID issue:

C++:
char *Interception::GetDeviceName(void)
{
wchar_t hardware_id[500];
size_t length = interception_get_hardware_id(context, device, hardware_id, sizeof(hardware_id));
if(length > 0 && length < sizeof(hardware_id)) {
// Old: Hardware ID as a string
// wcstombs(deviceName, hardware_id, 4096);
// return deviceName;

// New: Device number as a string
std::string str = std::to_string(device);
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
return cstr;
}
return NULL;
}

^ See above. This means we'll key off the device's dynamic ID instead of its hardware id.

I'm a new user, so it may not let me attach my solution. If it doesn't you only need to make the above change and rebuild. I used "Visual Studio Community 2015" to build the console app. Newer versions had difficulty migrating the solution (hence the 2015 version of Visual Studio). If my zip uploads, please note:

• The .exe in the root is the original .exe that uses Hardware ID
• The .exe in the "Releases" folder is the updated version that uses the Dynamic ID
• There is a configuration file in the Releases folder that you're free to delete.
EDIT: First attempt blocked. Trying w/ just the Release folder:

#### Attachments

• intercept-device-id.zip
368.7 KB · Views: 3
Last edited: