Skip to main content

Remapping Zoom on the Microsoft Natural Keyboard 4000 - Mac OS X

The Microsoft Natural Keyboard 4000 is pretty great, but the "Zoom" slider in the middle never seemed very useful to me - how often do I need to zoom in or out? I scroll much more often than I need to zoom, so it would be nice to remap to scroll instead.
 
Although Microsoft's control panel lets you remap the special function keys, it doesn't let you change the Zoom slider function. Luckily for Windows users there's a fairly simple xml file that you can edit to change the mapping (and there are plenty of explanations: SuperUser, Josh Highland, Joel Bennett, etc).

Unfortunately, the "commands.xml" config file doesn't exist on Mac OS X. Instead, there's a binary file for the configuration, which makes it tough to modify:
/Users/YOUR_NAME/Library/Preferences/com.microsoft.keyboard.pref

After a bit of reverse-engineering, I was able to remap the Zoom slider to the UP and DOWN keys (sadly, using the SCROLL mapping doesn't auto-repeat, so UP/DOWN was the best I could do).

Scrolling Instead of Zooming - The Easy Way:
The easiest way to get scrolling instead of zooming is to replace your com.microsoft.keyboard.pref file with a modified version:
  1. Make sure System Preferences is closed
  2. Download the modified pref file: com.microsoft.keyboard.pref
  3. Navigate to /Users/YOUR_NAME/Library/Preferences/
  4. Back up the com.microsoft.keyboard.pref file (e.g. rename it to com.microsoft.keyboard.pref.old)
  5. Move the modified pref file into that folder
  6. Open System Preferences, and open the Microsoft Keyboard preference panel (this causes the pref file to be reloaded)
If you're interested to see how the file was modified (or want to map the Zoom slider to something other than UP/DOWN), keep reading...

How to reverse-engineer the preferences: 
Since com.microsoft.keyboard.pref is a binary file, opening it with TextEdit or vim isn't going to be very useful. Instead, take a hex dump of the original configuration:

cd /Users/YOUR_NAME/Library/Preferences
xxd com.microsoft.keyboard.pref > prefsOrig.hex

Now we'll make some key mapping changes and see what parts of the pref file change. I changed the Open and Close buttons to do nothing.

Now we'll take another hex dump and compare the two:

xxd com.microsoft.keyboard.pref > prefMod.hex
diff prefOrig.hex prefMod.hex

which outputs:

182,183c182,183
< 0000b50: 0000 0000 0000 0000 0000 0000 0000 5400
< 0000b60: 0000 0000 0000 0000 0000 0000 0000 0000
---
> 0000b50: 0000 0000 0000 0000 0000 0000 0000 0000
> 0000b60: 0000 ff00 0000 0000 0000 0000 0000 0000
185c185
< 0000b80: 0000 0000 0000 5500 0000 0000 0000 0000
---
> 0000b80: 0000 0000 0000 0000 0000 ff00 0000 0000

Notice the changes:
  1. At 0x0000b5e, value 0x5400000000 becomes 0x00000000ff
  2. At 0x0000b86, value 0x5500000000 becomes 0x00000000ff
It looks like the 0xff signifies "None" mode, whereas the 0x54 and 0x55 probably specified the Open and Close functions that used to be there.

You can play around with this technique to figure out how the byte values change with different mappings. For example, let's make Open and Close map to zooming in and zooming out. The pref file diff now looks like:

182,183c182,183
< 0000b50: 0000 0000 0000 0000 0000 0000 0000 5400
< 0000b60: 0000 0000 0000 0000 0000 0000 0000 0000
---
> 0000b50: 0000 0000 0000 0000 0000 0000 0000 0800
> 0000b60: 0000 ff00 0000 0000 0000 0000 0000 0000
185c185
< 0000b80: 0000 0000 0000 5500 0000 0000 0000 0000
---
> 0000b80: 0000 0000 0000 0900 0000 ff00 0000 0000

The changes:
  1. At 0x0000b5e, value 0x5400000000 changes to 0x08000000ff
  2. At 0x0000b86, value 0x5500000000 changes to 0x09000000ff.

The next issue is figuring out which bytes correspond to the Zoom slider's key-mappings. The only control that the GUI provides is enable/disable, zoom speed, and zoom acceleration, so we can mess with those.



If you toggle "Enable zooming" you get a hex diff that looks like:

82,83c82,83
< 0000510: 0000 0000 0000 0000 0000 0000 0000 0800
< 0000520: 0000 0000 0000 0000 0000 0000 0000 0000
---
> 0000510: 0000 0000 0000 0000 0000 0000 0000 0000
> 0000520: 0000 ff00 0000 0000 0000 0000 0000 0000
85c85
< 0000540: 0000 0000 0000 0900 0000 0000 0000 0000
---
> 0000540: 0000 0000 0000 0000 0000 ff00 0000 0000

Notice the similarities to the diff when we changed Open/Close to None:
  1. At 0x000051e, the value 0x0800000000 changes to 0x00000000ff
  2. At 0x0000546, the value 0x0900000000 changes to 0x00000000ff
So it looks like disabling zooming is actually just switching 2 key mappings to None (0x00000000ff) - and now we know where the key mappings for the Zoom buttons are located (0x51e and 0x546)!
Again, we can play around with some other key mappings to figure out the byte values to map keys to the UP and DOWN actions (0x030000007e and 0x030000007d). Now, just apply these values to the prefOrig.hex file, at the addresses we found for the Zoom slider's mappings (0x51e and 0x546):

0000510: 0000 0000 0000 0000 0000 0000 0000 0300
0000520: 0000 7e00 0000 0000 0000 0000 0000 0000
0000530: 0000 0000 0000 0000 0000 0000 0000 0000
0000540: 0000 0000 0000 0300 0000 7d00 0000 0000

(If you want to make your Zoom slider do something other than UP/DOWN, you can replace 0x030000007e and 0x030000007d with different key mappings)

Finally, convert the modified hex dump back into a binary preference file:
xxd -r prefOrig.hex > com.microsoft.keyboard.pref

Now open the Microsoft Keyboard settings panel within System Preferences to get the driver to reload the pref file, and you're all done!

Comments

  1. It kernel panicked the first time, but works well now. Have you tried remapping the favorites buttons to next/previous song in iTunes?

    ReplyDelete
  2. Didn't work for me, have the intellipro thing 8.2 and Mountain Lion. Pref pane seems to be the same even after moving, didn't see any different options and enabling the zoom silider still zooms instead of scrolling.

    ReplyDelete
  3. Worked pretty fine, 10.8 + MS drivers 9.2

    ReplyDelete
  4. Worked liked a charm with your instructions. Thanks.

    10.8.2 + MS IntelliType Pro version 8.2.0 (v.305)

    ReplyDelete
  5. Is it possible to remap capslock for layout switch?

    ReplyDelete
  6. Thank you very much for this! I just got this keyboard and desperately wanted to have the zoom keys swap between windows. Problem is, Intellipoint won't let you use the backtick as a keystroke (WTF?).

    Solved this by going to Keyboard Shortcuts… and changing the shortcut for "Change focus to next window" to be Ctrl-Opt-Cmd-[ (Open square bracket, to avoid conflicts). Then changed the hex as above to "03 00 00 19 21" and "03 00 00 1B 21".

    Voila! Very happy!

    ReplyDelete
  7. The file is not accessible anymore :(

    ReplyDelete

Post a Comment

Popular posts from this blog

OpenSCAD Rendering Tricks, Part 3: Web viewer

This is my sixth post in a series about the  open source split-flap display  I’ve been designing in my free time. Check out a  video of the prototype . Posts in the series: Scripting KiCad Pcbnew exports Automated KiCad, OpenSCAD rendering using Travis CI Using UI automation to export KiCad schematics OpenSCAD Rendering Tricks, Part 1: Animated GIF OpenSCAD Rendering Tricks, Part 2: Laser Cutting OpenSCAD Rendering Tricks, Part 3: Web viewer One of my goals when building the split-flap display was to make sure it was easy to visualize the end product and look at the design in detail without having to download the full source or install any programs. It’s hard to get excited about a project you find online if you need to invest time and effort before you even know how it works or what it looks like. I’ve previously blogged about automatically exporting the schematics, PCB layout , and even an animated gif of the 3D model to make it easier to understand the project at a glanc

Using UI automation to export KiCad schematics

This is my third post in a series about the open source split-flap display I’ve been designing in my free time. I’ll hopefully write a bit more about the overall design process in the future, but for now wanted to start with some fairly technical posts about build automation on that project. Posts in the series: Scripting KiCad Pcbnew exports Automated KiCad, OpenSCAD rendering using Travis CI Using UI automation to export KiCad schematics OpenSCAD Rendering Tricks, Part 1: Animated GIF OpenSCAD Rendering Tricks, Part 2: Laser Cutting OpenSCAD Rendering Tricks, Part 3: Web viewer Since I’ve been designing the split-flap display as an open source project, I wanted to make sure that all of the different components were easily accessible and visible for someone new or just browsing the project. Today’s post continues the series on automatically rendering images to include in the project’s README, but this time we go beyond simple programmatic bindings to get what we want: the

Scripting KiCad Pcbnew exports

This is my first post in a series about the  open source split-flap display  I’ve been designing in my free time. Check out a  video of the prototype . Posts in the series: Scripting KiCad Pcbnew exports Automated KiCad, OpenSCAD rendering using Travis CI Using UI automation to export KiCad schematics OpenSCAD Rendering Tricks, Part 1: Animated GIF OpenSCAD Rendering Tricks, Part 2: Laser Cutting OpenSCAD Rendering Tricks, Part 3: Web viewer For the past few months I’ve been designing an open source split-flap display in my free time — the kind of retro electromechanical display that used to be in airports and train stations before LEDs and LCDs took over and makes that distinctive “tick tick tick tick” sound as the letters and numbers flip into place. I designed the electronics in KiCad, and one of the things I wanted to do was include a nice picture of the current state of the custom PCB design in the project’s README file. Of course, I could generate a snapshot of the