]> git.proxmox.com Git - mirror_novnc.git/blobdiff - tests/test.keyboard.js
Use standard DOM identifiers for physical keys
[mirror_novnc.git] / tests / test.keyboard.js
index 2ac65af3993156746738144d7b2264bda851345b..aa96142094032477d95798eea078a09d2834cd6a 100644 (file)
@@ -1,76 +1,78 @@
-// requires local modules: input, keyboard, keysymdef
 var assert = chai.assert;
 var expect = chai.expect;
 
+import keysyms from '../core/input/keysymdef.js';
+import * as KeyboardUtil from '../core/input/util.js';
+
 /* jshint newcap: false, expr: true */
 describe('Key Event Pipeline Stages', function() {
     "use strict";
     describe('Decode Keyboard Events', function() {
         it('should pass events to the next stage', function(done) {
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
                 expect(evt).to.be.an.object;
                 done();
-            }).keydown({keyCode: 0x41});
+            }).keydown({code: 'KeyA', keyCode: 0x41});
         });
         it('should pass the right keysym through', function(done) {
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                expect(evt.keysym).to.be.deep.equal(keysyms.lookup(0x61));
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                expect(evt.keysym).to.be.deep.equal(0x61);
                 done();
-            }).keypress({keyCode: 0x41});
+            }).keypress({code: 'KeyA', keyCode: 0x41});
         });
         it('should pass the right keyid through', function(done) {
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                expect(evt).to.have.property('keyId', 0x41);
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                expect(evt).to.have.property('code', 'KeyA');
                 done();
-            }).keydown({keyCode: 0x41});
+            }).keydown({code: 'KeyA', keyCode: 0x41});
         });
         it('should not sync modifiers on a keypress', function() {
             // Firefox provides unreliable modifier state on keypress events
             var count = 0;
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
                 ++count;
-            }).keypress({keyCode: 0x41, ctrlKey: true});
+            }).keypress({code: 'KeyA', keyCode: 0x41, ctrlKey: true});
             expect(count).to.be.equal(1);
         });
         it('should sync modifiers if necessary', function(done) {
             var count = 0;
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
                 switch (count) {
                 case 0: // fake a ctrl keydown
-                    expect(evt).to.be.deep.equal({keysym: keysyms.lookup(0xffe3), type: 'keydown'});
+                    expect(evt).to.be.deep.equal({keysym: 0xffe3, type: 'keydown'});
                     ++count;
                     break;
                 case 1:
-                    expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown', keysym: keysyms.lookup(0x61)});
+                    expect(evt).to.be.deep.equal({code: 'KeyA', type: 'keydown', keysym: 0x61});
                     done();
                     break;
                 }
-            }).keydown({keyCode: 0x41, ctrlKey: true});
+            }).keydown({code: 'KeyA', keyCode: 0x41, ctrlKey: true});
         });
         it('should forward keydown events with the right type', function(done) {
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown'});
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                expect(evt).to.be.deep.equal({code: 'KeyA', type: 'keydown'});
                 done();
-            }).keydown({keyCode: 0x41});
+            }).keydown({code: 'KeyA', keyCode: 0x41});
         });
         it('should forward keyup events with the right type', function(done) {
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keyup'});
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keyup'});
                 done();
-            }).keyup({keyCode: 0x41});
+            }).keyup({code: 'KeyA', keyCode: 0x41});
         });
         it('should forward keypress events with the right type', function(done) {
-            KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keypress'});
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keypress'});
                 done();
-            }).keypress({keyCode: 0x41});
+            }).keypress({code: 'KeyA', keyCode: 0x41});
         });
         it('should generate stalls if a char modifier is down while a key is pressed', function(done) {
             var count = 0;
-            KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
+            KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
                 switch (count) {
                 case 0: // fake altgr
-                    expect(evt).to.be.deep.equal({keysym: keysyms.lookup(0xfe03), type: 'keydown'});
+                    expect(evt).to.be.deep.equal({keysym: 0xfe03, type: 'keydown'});
                     ++count;
                     break;
                 case 1: // stall before processing the 'a' keydown
@@ -80,19 +82,19 @@ describe('Key Event Pipeline Stages', function() {
                 case 2: // 'a'
                     expect(evt).to.be.deep.equal({
                         type: 'keydown',
-                        keyId: 0x41,
-                        keysym: keysyms.lookup(0x61)
+                        code: 'KeyA',
+                        keysym: 0x61
                     });
 
                     done();
                     break;
                 }
-            }).keydown({keyCode: 0x41, altGraphKey: true});
+            }).keydown({code: 'KeyA', keyCode: 0x41, altGraphKey: true});
 
         });
         describe('suppress the right events at the right time', function() {
             it('should suppress anything while a shortcut modifier is down', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
 
                 obj.keydown({keyCode: 0x11}); // press ctrl
                 expect(obj.keydown({keyCode: 'A'.charCodeAt()})).to.be.true;
@@ -102,7 +104,7 @@ describe('Key Event Pipeline Stages', function() {
                 expect(obj.keydown({keyCode: 0xde})).to.be.true; // Ø key on DK
             });
             it('should suppress non-character keys', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
 
                 expect(obj.keydown({keyCode: 0x08}), 'a').to.be.true;
                 expect(obj.keydown({keyCode: 0x09}), 'b').to.be.true;
@@ -110,20 +112,20 @@ describe('Key Event Pipeline Stages', function() {
                 expect(obj.keydown({keyCode: 0x12}), 'e').to.be.true;
             });
             it('should not suppress shift', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
 
                 expect(obj.keydown({keyCode: 0x10}), 'd').to.be.false;
             });
             it('should generate event for shift keydown', function() {
                 var called = false;
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
                     expect(evt).to.have.property('keysym');
                     called = true;
                 }).keydown({keyCode: 0x10});
                 expect(called).to.be.true;
             });
             it('should not suppress character keys', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
 
                 expect(obj.keydown({keyCode: 'A'.charCodeAt()})).to.be.false;
                 expect(obj.keydown({keyCode: ' '.charCodeAt()})).to.be.false;
@@ -132,7 +134,7 @@ describe('Key Event Pipeline Stages', function() {
                 expect(obj.keydown({keyCode: 0xde})).to.be.false; // Ø key on DK
             });
             it('should not suppress if a char modifier is down', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {});
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {});
 
                 obj.keydown({keyCode: 0xe1}); // press altgr
                 expect(obj.keydown({keyCode: 'A'.charCodeAt()})).to.be.false;
@@ -144,7 +146,7 @@ describe('Key Event Pipeline Stages', function() {
         });
         describe('Keypress and keyup events', function() {
             it('should always suppress event propagation', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
 
                 expect(obj.keypress({keyCode: 'A'.charCodeAt()})).to.be.true;
                 expect(obj.keypress({keyCode: 0x3c})).to.be.true; // < key on DK Windows
@@ -155,7 +157,7 @@ describe('Key Event Pipeline Stages', function() {
                 expect(obj.keyup({keyCode: 0x11})).to.be.true;
             });
             it('should never generate stalls', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
                     expect(evt.type).to.not.be.equal('stall');
                 });
 
@@ -171,7 +173,7 @@ describe('Key Event Pipeline Stages', function() {
         describe('mark events if a char modifier is down', function() {
             it('should not mark modifiers on a keydown event', function() {
                 var times_called = 0;
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
                     switch (times_called++) {
                     case 0: //altgr
                         break;
@@ -182,20 +184,20 @@ describe('Key Event Pipeline Stages', function() {
                 });
 
                 obj.keydown({keyCode: 0xe1}); // press altgr
-                obj.keydown({keyCode: 'A'.charCodeAt()});
+                obj.keydown({code: 'KeyA', keyCode: 0x41});
             });
 
             it('should indicate on events if a single-key char modifier is down', function(done) {
                 var times_called = 0;
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
                     switch (times_called++) {
                     case 0: //altgr
                         break;
                     case 1: // 'a'
                         expect(evt).to.be.deep.equal({
                             type: 'keypress',
-                            keyId: 'A'.charCodeAt(),
-                            keysym: keysyms.lookup('a'.charCodeAt()),
+                            code: 'KeyA',
+                            keysym: 0x61,
                             escape: [0xfe03]
                         });
                         done();
@@ -204,11 +206,11 @@ describe('Key Event Pipeline Stages', function() {
                 });
 
                 obj.keydown({keyCode: 0xe1}); // press altgr
-                obj.keypress({keyCode: 'A'.charCodeAt()});
+                obj.keypress({code: 'KeyA', keyCode: 0x41});
             });
             it('should indicate on events if a multi-key char modifier is down', function(done) {
                 var times_called = 0;
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xffe9, 0xffe3]), function(evt) {
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xffe9, 0xffe3]), function(evt) {
                     switch (times_called++) {
                     case 0: //ctrl
                         break;
@@ -217,8 +219,8 @@ describe('Key Event Pipeline Stages', function() {
                     case 2: // 'a'
                         expect(evt).to.be.deep.equal({
                             type: 'keypress',
-                            keyId: 'A'.charCodeAt(),
-                            keysym: keysyms.lookup('a'.charCodeAt()),
+                            code: 'KeyA',
+                            keysym: 0x61,
                             escape: [0xffe9, 0xffe3]
                         });
                         done();
@@ -228,10 +230,10 @@ describe('Key Event Pipeline Stages', function() {
 
                 obj.keydown({keyCode: 0x11}); // press ctrl
                 obj.keydown({keyCode: 0x12}); // press alt
-                obj.keypress({keyCode: 'A'.charCodeAt()});
+                obj.keypress({code: 'KeyA', keyCode: 0x41});
             });
             it('should not consider a char modifier to be down on the modifier key itself', function() {
-                var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
+                var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
                     expect(evt).to.not.have.property('escape');
                 });
 
@@ -241,50 +243,50 @@ describe('Key Event Pipeline Stages', function() {
         });
         describe('add/remove keysym', function() {
             it('should remove keysym from keydown if a char key and no modifier', function() {
-                KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                    expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown'});
-                }).keydown({keyCode: 0x41});
+                KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                    expect(evt).to.be.deep.equal({code: 'KeyA', type: 'keydown'});
+                }).keydown({code: 'KeyA', keyCode: 0x41});
             });
             it('should not remove keysym from keydown if a shortcut modifier is down', function() {
                 var times_called = 0;
-                KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
+                KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
                     switch (times_called++) {
                     case 1:
-                        expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keydown'});
+                        expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keydown'});
                         break;
                     }
-                }).keydown({keyCode: 0x41, ctrlKey: true});
+                }).keydown({code: 'KeyA', keyCode: 0x41, ctrlKey: true});
                 expect(times_called).to.be.equal(2);
             });
             it('should not remove keysym from keydown if a char modifier is down', function() {
                 var times_called = 0;
-                KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
+                KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
                     switch (times_called++) {
                     case 2:
-                        expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keydown'});
+                        expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keydown'});
                         break;
                     }
-                }).keydown({keyCode: 0x41, altGraphKey: true});
+                }).keydown({code: 'KeyA', keyCode: 0x41, altGraphKey: true});
                 expect(times_called).to.be.equal(3);
             });
             it('should not remove keysym from keydown if key is noncharacter', function() {
-                KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                    expect(evt, 'bacobjpace').to.be.deep.equal({keyId: 0x09, keysym: keysyms.lookup(0xff09), type: 'keydown'});
+                KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                    expect(evt, 'tab').to.be.deep.equal({code: 'Tab', keysym: 0xff09, type: 'keydown'});
                 }).keydown({keyCode: 0x09});
 
-                KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                    expect(evt, 'ctrl').to.be.deep.equal({keyId: 0x11, keysym: keysyms.lookup(0xffe3), type: 'keydown'});
+                KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                    expect(evt, 'ctrl').to.be.deep.equal({code: 'ControlLeft', keysym: 0xffe3, type: 'keydown'});
                 }).keydown({keyCode: 0x11});
             });
             it('should never remove keysym from keypress', function() {
-                KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                    expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keypress'});
-                }).keypress({keyCode: 0x41});
+                KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                    expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keypress'});
+                }).keypress({code: 'KeyA', keyCode: 0x41});
             });
             it('should never remove keysym from keyup', function() {
-                KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
-                    expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keyup'});
-                }).keyup({keyCode: 0x41});
+                KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
+                    expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keyup'});
+                }).keyup({code: 'KeyA', keyCode: 0x41});
             });
         });
         // on keypress, keyup(?), always set keysym
@@ -293,81 +295,81 @@ describe('Key Event Pipeline Stages', function() {
 
     describe('Verify that char modifiers are active', function() {
         it('should pass keydown events through if there is no stall', function(done) {
-            var obj = VerifyCharModifier(function(evt){
-                expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
+                expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x41});
                 done();
-            })({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+            })({type: 'keydown', code: 'KeyA', keysym: 0x41});
         });
         it('should pass keyup events through if there is no stall', function(done) {
-            var obj = VerifyCharModifier(function(evt){
-                expect(evt).to.deep.equal({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
+                expect(evt).to.deep.equal({type: 'keyup', code: 'KeyA', keysym: 0x41});
                 done();
-            })({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+            })({type: 'keyup', code: 'KeyA', keysym: 0x41});
         });
         it('should pass keypress events through if there is no stall', function(done) {
-            var obj = VerifyCharModifier(function(evt){
-                expect(evt).to.deep.equal({type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
+                expect(evt).to.deep.equal({type: 'keypress', code: 'KeyA', keysym: 0x41});
                 done();
-            })({type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+            })({type: 'keypress', code: 'KeyA', keysym: 0x41});
         });
         it('should not pass stall events through', function(done){
-            var obj = VerifyCharModifier(function(evt){
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
                 // should only be called once, for the keydown
-                expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+                expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x41});
                 done();
             });
 
             obj({type: 'stall'});
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x41});
         });
         it('should merge keydown and keypress events if they come after a stall', function(done) {
             var next_called = false;
-            var obj = VerifyCharModifier(function(evt){
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
                 // should only be called once, for the keydown
                 expect(next_called).to.be.false;
                 next_called = true;
-                expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x44)});
+                expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x44});
                 done();
             });
 
             obj({type: 'stall'});
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
-            obj({type: 'keypress', keyId: 0x43, keysym: keysyms.lookup(0x44)});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
+            obj({type: 'keypress', code: 'KeyC', keysym: 0x44});
             expect(next_called).to.be.false;
         });
         it('should preserve modifier attribute when merging if keysyms differ', function(done) {
             var next_called = false;
-            var obj = VerifyCharModifier(function(evt){
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
                 // should only be called once, for the keydown
                 expect(next_called).to.be.false;
                 next_called = true;
-                expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x44), escape: [0xffe3]});
+                expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x44, escape: [0xffe3]});
                 done();
             });
 
             obj({type: 'stall'});
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
-            obj({type: 'keypress', keyId: 0x43, keysym: keysyms.lookup(0x44), escape: [0xffe3]});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
+            obj({type: 'keypress', code: 'KeyC', keysym: 0x44, escape: [0xffe3]});
             expect(next_called).to.be.false;
         });
         it('should not preserve modifier attribute when merging if keysyms are the same', function() {
-            var obj = VerifyCharModifier(function(evt){
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
                 expect(evt).to.not.have.property('escape');
             });
 
             obj({type: 'stall'});
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
-            obj({type: 'keypress', keyId: 0x43, keysym: keysyms.lookup(0x42), escape: [0xffe3]});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
+            obj({type: 'keypress', code: 'KeyC', keysym: 0x42, escape: [0xffe3]});
         });
         it('should not merge keydown and keypress events if there is no stall', function(done) {
             var times_called = 0;
-            var obj = VerifyCharModifier(function(evt){
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
                 switch(times_called) {
                 case 0:
-                    expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
+                    expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42});
                     break;
                 case 1:
-                    expect(evt).to.deep.equal({type: 'keypress', keyId: 0x43, keysym: keysyms.lookup(0x44)});
+                    expect(evt).to.deep.equal({type: 'keypress', code: 'KeyC', keysym: 0x44});
                     done();
                     break;
                 }
@@ -375,21 +377,21 @@ describe('Key Event Pipeline Stages', function() {
                 ++times_called;
             });
 
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
-            obj({type: 'keypress', keyId: 0x43, keysym: keysyms.lookup(0x44)});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
+            obj({type: 'keypress', code: 'KeyC', keysym: 0x44});
         });
         it('should not merge keydown and keypress events if separated by another event', function(done) {
             var times_called = 0;
-            var obj = VerifyCharModifier(function(evt){
+            var obj = KeyboardUtil.VerifyCharModifier(function(evt){
                 switch(times_called) {
                 case 0:
-                    expect(evt,1).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
+                    expect(evt,1).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42});
                     break;
                 case 1:
-                    expect(evt,2).to.deep.equal({type: 'keyup', keyId: 0x43, keysym: keysyms.lookup(0x44)});
+                    expect(evt,2).to.deep.equal({type: 'keyup', code: 'KeyC', keysym: 0x44});
                     break;
                 case 2:
-                    expect(evt,3).to.deep.equal({type: 'keypress', keyId: 0x45, keysym: keysyms.lookup(0x46)});
+                    expect(evt,3).to.deep.equal({type: 'keypress', code: 'KeyE', keysym: 0x46});
                     done();
                     break;
                 }
@@ -398,43 +400,43 @@ describe('Key Event Pipeline Stages', function() {
             });
 
             obj({type: 'stall'});
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
-            obj({type: 'keyup', keyId: 0x43, keysym: keysyms.lookup(0x44)});
-            obj({type: 'keypress', keyId: 0x45, keysym: keysyms.lookup(0x46)});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
+            obj({type: 'keyup', code: 'KeyC', keysym: 0x44});
+            obj({type: 'keypress', code: 'KeyE', keysym: 0x46});
         });
     });
 
     describe('Track Key State', function() {
         it('should do nothing on keyup events if no keys are down', function() {
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 expect(true).to.be.false;
             });
-            obj({type: 'keyup', keyId: 0x41});
+            obj({type: 'keyup', code: 'KeyA'});
         });
         it('should insert into the queue on keydown if no keys are down', function() {
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                 expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                 }
                 elem = null;
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keydown', code: 'KeyA', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keyup', keyId: 0x41};
+            elem = {type: 'keyup', code: 'KeyA'};
             obj(elem);
             expect(elem).to.be.null;
             expect(times_called).to.be.equal(2);
@@ -443,240 +445,240 @@ describe('Key Event Pipeline Stages', function() {
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                     expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                 }
                 elem = null;
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keypress', code: 'KeyA', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keyup', keyId: 0x41};
+            elem = {type: 'keyup', code: 'KeyA'};
             obj(elem);
             expect(elem).to.be.null;
             expect(times_called).to.be.equal(2);
         });
-        it('should add keysym to last key entry if keyId matches', function() {
+        it('should add keysym to last key entry if code matches', function() {
             // this implies that a single keyup will release both keysyms
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                     expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                     elem = null;
                 }
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keypress', code: 'KeyA', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x43)};
-            keysymsdown[keysyms.lookup(0x43).keysym] = true;
+            elem = {type: 'keypress', code: 'KeyA', keysym: 0x43};
+            keysymsdown[0x43] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keyup', keyId: 0x41};
+            elem = {type: 'keyup', code: 'KeyA'};
             obj(elem);
             expect(times_called).to.be.equal(4);
         });
-        it('should create new key entry if keyId matches and keysym does not', function() {
+        it('should create new key entry if code matches and keysym does not', function() {
             // this implies that a single keyup will release both keysyms
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                     expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                     elem = null;
                 }
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x43)};
-            keysymsdown[keysyms.lookup(0x43).keysym] = true;
+            elem = {type: 'keydown', code: 'Unidentified', keysym: 0x43};
+            keysymsdown[0x43] = true;
             obj(elem);
             expect(times_called).to.be.equal(2);
             expect(elem).to.be.null;
-            elem = {type: 'keyup', keyId: 0};
+            elem = {type: 'keyup', code: 'Unidentified'};
             obj(elem);
             expect(times_called).to.be.equal(3);
-            elem = {type: 'keyup', keyId: 0};
+            elem = {type: 'keyup', code: 'Unidentified'};
             obj(elem);
             expect(times_called).to.be.equal(4);
         });
-        it('should merge key entry if keyIds are zero and keysyms match', function() {
+        it('should merge key entry if codes are zero and keysyms match', function() {
             // this implies that a single keyup will release both keysyms
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                     expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                     elem = null;
                 }
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(times_called).to.be.equal(2);
             expect(elem).to.be.null;
-            elem = {type: 'keyup', keyId: 0};
+            elem = {type: 'keyup', code: 'Unidentified'};
             obj(elem);
             expect(times_called).to.be.equal(3);
         });
-        it('should add keysym as separate entry if keyId does not match last event', function() {
+        it('should add keysym as separate entry if code does not match last event', function() {
             // this implies that separate keyups are required
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                     expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                     elem = null;
                 }
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keypress', code: 'KeyA', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keypress', keyId: 0x42, keysym: keysyms.lookup(0x43)};
-            keysymsdown[keysyms.lookup(0x43).keysym] = true;
+            elem = {type: 'keypress', code: 'KeyB', keysym: 0x43};
+            keysymsdown[0x43] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keyup', keyId: 0x41};
+            elem = {type: 'keyup', code: 'KeyA'};
             obj(elem);
             expect(times_called).to.be.equal(4);
-            elem = {type: 'keyup', keyId: 0x42};
+            elem = {type: 'keyup', code: 'KeyB'};
             obj(elem);
             expect(times_called).to.be.equal(4);
         });
-        it('should add keysym as separate entry if keyId does not match last event and first is zero', function() {
+        it('should add keysym as separate entry if code does not match last event and first is zero', function() {
             // this implies that separate keyups are required
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                     expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                     elem = null;
                 }
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0x42, keysym: keysyms.lookup(0x43)};
-            keysymsdown[keysyms.lookup(0x43).keysym] = true;
+            elem = {type: 'keydown', code: 'KeyB', keysym: 0x43};
+            keysymsdown[0x43] = true;
             obj(elem);
             expect(elem).to.be.null;
             expect(times_called).to.be.equal(2);
-            elem = {type: 'keyup', keyId: 0};
+            elem = {type: 'keyup', code: 'Unidentified'};
             obj(elem);
             expect(times_called).to.be.equal(3);
-            elem = {type: 'keyup', keyId: 0x42};
+            elem = {type: 'keyup', code: 'KeyB'};
             obj(elem);
             expect(times_called).to.be.equal(4);
         });
-        it('should add keysym as separate entry if keyId does not match last event and second is zero', function() {
+        it('should add keysym as separate entry if code does not match last event and second is zero', function() {
             // this implies that a separate keyups are required
             var times_called = 0;
             var elem = null;
             var keysymsdown = {};
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 ++times_called;
                 if (elem.type == 'keyup') {
                     expect(evt).to.have.property('keysym');
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
-                    delete keysymsdown[evt.keysym.keysym];
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
+                    delete keysymsdown[evt.keysym];
                 }
                 else {
                     expect(evt).to.be.deep.equal(elem);
-                    expect (keysymsdown[evt.keysym.keysym]).to.not.be.undefined;
+                    expect (keysymsdown[evt.keysym]).to.not.be.undefined;
                     elem = null;
                 }
             });
 
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)};
-            keysymsdown[keysyms.lookup(0x42).keysym] = true;
+            elem = {type: 'keydown', code: 'KeyA', keysym: 0x42};
+            keysymsdown[0x42] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x43)};
-            keysymsdown[keysyms.lookup(0x43).keysym] = true;
+            elem = {type: 'keydown', code: 'Unidentified', keysym: 0x43};
+            keysymsdown[0x43] = true;
             obj(elem);
             expect(elem).to.be.null;
-            elem = {type: 'keyup', keyId: 0x41};
+            elem = {type: 'keyup', code: 'KeyA'};
             obj(elem);
             expect(times_called).to.be.equal(3);
-            elem = {type: 'keyup', keyId: 0};
+            elem = {type: 'keyup', code: 'Unidentified'};
             obj(elem);
             expect(times_called).to.be.equal(4);
         });
         it('should pop matching key event on keyup', function() {
             var times_called = 0;
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 switch (times_called++) {
                     case 0:
                     case 1:
@@ -684,20 +686,20 @@ describe('Key Event Pipeline Stages', function() {
                         expect(evt.type).to.be.equal('keydown');
                         break;
                     case 3:
-                        expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x42, keysym: keysyms.lookup(0x62)});
+                        expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyB', keysym: 0x62});
                         break;
                 }
             });
 
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x61)});
-            obj({type: 'keydown', keyId: 0x42, keysym: keysyms.lookup(0x62)});
-            obj({type: 'keydown', keyId: 0x43, keysym: keysyms.lookup(0x63)});
-            obj({type: 'keyup', keyId: 0x42});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x61});
+            obj({type: 'keydown', code: 'KeyB', keysym: 0x62});
+            obj({type: 'keydown', code: 'KeyC', keysym: 0x63});
+            obj({type: 'keyup', code: 'KeyB'});
             expect(times_called).to.equal(4);
         });
-        it('should pop the first zero keyevent on keyup with zero keyId', function() {
+        it('should pop the first zero keyevent on keyup with zero code', function() {
             var times_called = 0;
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 switch (times_called++) {
                     case 0:
                     case 1:
@@ -705,20 +707,20 @@ describe('Key Event Pipeline Stages', function() {
                         expect(evt.type).to.be.equal('keydown');
                         break;
                     case 3:
-                        expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: keysyms.lookup(0x61)});
+                        expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0x61});
                         break;
                 }
             });
 
-            obj({type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x61)});
-            obj({type: 'keydown', keyId: 0, keysym: keysyms.lookup(0x62)});
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x63)});
-            obj({type: 'keyup', keyId: 0x0});
+            obj({type: 'keydown', code: 'Unidentified', keysym: 0x61});
+            obj({type: 'keydown', code: 'Unidentified', keysym: 0x62});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x63});
+            obj({type: 'keyup', code: 'Unidentified'});
             expect(times_called).to.equal(4);
         });
-        it('should pop the last keyevents keysym if no match is found for keyId', function() {
+        it('should pop the last keyevents keysym if no match is found for code', function() {
             var times_called = 0;
-            var obj = TrackKeyState(function(evt) {
+            var obj = KeyboardUtil.TrackKeyState(function(evt) {
                 switch (times_called++) {
                     case 0:
                     case 1:
@@ -726,34 +728,34 @@ describe('Key Event Pipeline Stages', function() {
                         expect(evt.type).to.be.equal('keydown');
                         break;
                     case 3:
-                        expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x44, keysym: keysyms.lookup(0x63)});
+                        expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyD', keysym: 0x63});
                         break;
                 }
             });
 
-            obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x61)});
-            obj({type: 'keydown', keyId: 0x42, keysym: keysyms.lookup(0x62)});
-            obj({type: 'keydown', keyId: 0x43, keysym: keysyms.lookup(0x63)});
-            obj({type: 'keyup', keyId: 0x44});
+            obj({type: 'keydown', code: 'KeyA', keysym: 0x61});
+            obj({type: 'keydown', code: 'KeyB', keysym: 0x62});
+            obj({type: 'keydown', code: 'KeyC', keysym: 0x63});
+            obj({type: 'keyup', code: 'KeyD'});
             expect(times_called).to.equal(4);
         });
         describe('Firefox sends keypress even when keydown is suppressed', function() {
             it('should discard the keypress', function() {
                 var times_called = 0;
-                var obj = TrackKeyState(function(evt) {
+                var obj = KeyboardUtil.TrackKeyState(function(evt) {
                     expect(times_called).to.be.equal(0);
                     ++times_called;
                 });
 
-                obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
+                obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
                 expect(times_called).to.be.equal(1);
-                obj({type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x43)});
+                obj({type: 'keypress', code: 'KeyA', keysym: 0x43});
             });
         });
         describe('releaseAll', function() {
             it('should do nothing if no keys have been pressed', function() {
                 var times_called = 0;
-                var obj = TrackKeyState(function(evt) {
+                var obj = KeyboardUtil.TrackKeyState(function(evt) {
                     ++times_called;
                 });
                 obj({type: 'releaseall'});
@@ -761,18 +763,18 @@ describe('Key Event Pipeline Stages', function() {
             });
             it('should release the keys that have been pressed', function() {
                 var times_called = 0;
-                var obj = TrackKeyState(function(evt) {
+                var obj = KeyboardUtil.TrackKeyState(function(evt) {
                     switch (times_called++) {
                     case 2:
-                        expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: keysyms.lookup(0x41)});
+                        expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0x41});
                         break;
                     case 3:
-                        expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: keysyms.lookup(0x42)});
+                        expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0x42});
                         break;
                     }
                 });
-                obj({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
-                obj({type: 'keydown', keyId: 0x42, keysym: keysyms.lookup(0x42)});
+                obj({type: 'keydown', code: 'KeyA', keysym: 0x41});
+                obj({type: 'keydown', code: 'KeyB', keysym: 0x42});
                 expect(times_called).to.be.equal(2);
                 obj({type: 'releaseall'});
                 expect(times_called).to.be.equal(4);
@@ -787,54 +789,54 @@ describe('Key Event Pipeline Stages', function() {
         describe('Keydown', function() {
             it('should pass through when a char modifier is not down', function() {
                 var times_called = 0;
-                EscapeModifiers(function(evt) {
+                KeyboardUtil.EscapeModifiers(function(evt) {
                     expect(times_called).to.be.equal(0);
                     ++times_called;
-                    expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
-                })({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
+                    expect(evt).to.be.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42});
+                })({type: 'keydown', code: 'KeyA', keysym: 0x42});
                 expect(times_called).to.be.equal(1);
             });
             it('should generate fake undo/redo events when a char modifier is down', function() {
                 var times_called = 0;
-                EscapeModifiers(function(evt) {
+                KeyboardUtil.EscapeModifiers(function(evt) {
                     switch(times_called++) {
                     case 0:
-                        expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: keysyms.lookup(0xffe9)});
+                        expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0xffe9});
                         break;
                     case 1:
-                        expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: keysyms.lookup(0xffe3)});
+                        expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0xffe3});
                         break;
                     case 2:
-                        expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42), escape: [0xffe9, 0xffe3]});
+                        expect(evt).to.be.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42, escape: [0xffe9, 0xffe3]});
                         break;
                     case 3:
-                        expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0, keysym: keysyms.lookup(0xffe9)});
+                        expect(evt).to.be.deep.equal({type: 'keydown', code: 'Unidentified', keysym: 0xffe9});
                         break;
                     case 4:
-                        expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0, keysym: keysyms.lookup(0xffe3)});
+                        expect(evt).to.be.deep.equal({type: 'keydown', code: 'Unidentified', keysym: 0xffe3});
                         break;
                     }
-                })({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42), escape: [0xffe9, 0xffe3]});
+                })({type: 'keydown', code: 'KeyA', keysym: 0x42, escape: [0xffe9, 0xffe3]});
                 expect(times_called).to.be.equal(5);
             });
         });
         describe('Keyup', function() {
             it('should pass through when a char modifier is down', function() {
                 var times_called = 0;
-                EscapeModifiers(function(evt) {
+                KeyboardUtil.EscapeModifiers(function(evt) {
                     expect(times_called).to.be.equal(0);
                     ++times_called;
-                    expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x42), escape: [0xfe03]});
-                })({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x42), escape: [0xfe03]});
+                    expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyA', keysym: 0x42, escape: [0xfe03]});
+                })({type: 'keyup', code: 'KeyA', keysym: 0x42, escape: [0xfe03]});
                 expect(times_called).to.be.equal(1);
             });
             it('should pass through when a char modifier is not down', function() {
                 var times_called = 0;
-                EscapeModifiers(function(evt) {
+                KeyboardUtil.EscapeModifiers(function(evt) {
                     expect(times_called).to.be.equal(0);
                     ++times_called;
-                    expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x42)});
-                })({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x42)});
+                    expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyA', keysym: 0x42});
+                })({type: 'keyup', code: 'KeyA', keysym: 0x42});
                 expect(times_called).to.be.equal(1);
             });
         });