hterm: Don't trap media keys by default.

Intrudces a new preference to trap media keys and convert them to the
Chrome OS keyboard equivalent (e.g. Back is F1). By default this is
turned off, so that media keys perform their media function on Chrome
OS.

BUG=chromium:226752
TEST=Manually tested that w/ the pref on, media keys have the same
behavior, and w/ the pref off (default), media keys have media
behavior. Saw the same hex output for the media keys:
F1: 0x1b 4f 50
F2: 0x1b 4f 51
F3: 0x1b 4f 52
F4: 0x1b 4f 53
F5: 0x1b 5b 31 35 7e
F6: 0x1b 5b 31 37 7e
F7: 0x1b 5b 31 38 7e
F8: 0x1b 5b 31 39 7e
F9: 0x1b 5b 32 30 7e
F10: 0x1b 5b 32 31 7e

Change-Id: I72b49fe7a66547750243fd0e31adf953b1293125
Reviewed-on: https://gerrit.chromium.org/gerrit/47358
Reviewed-by: Robert Ginda <rginda@chromium.org>
Commit-Queue: Andrew de los Reyes <adlr@chromium.org>
Tested-by: Andrew de los Reyes <adlr@chromium.org>
diff --git a/hterm/doc/changelog.txt b/hterm/doc/changelog.txt
index a4ec02e..c7c4ecf 100644
--- a/hterm/doc/changelog.txt
+++ b/hterm/doc/changelog.txt
@@ -1,6 +1,7 @@
-1.3, 2013-04-04, Keyboard fix
+1.3, 2013-04-04, Keyboard fixes
 
 * BUG=chromium:174410, Fix to allow Alt-Backspace to send Meta-Backspace
+* BUG=chromium:226752, Don't trap media keys (e.g. Mute) by default.
 
 1.2, 2013-03-19, Fix bell regression.
 
diff --git a/hterm/js/hterm_keyboard.js b/hterm/js/hterm_keyboard.js
index 272e1a5..12efd00 100644
--- a/hterm/js/hterm_keyboard.js
+++ b/hterm/js/hterm_keyboard.js
@@ -121,6 +121,12 @@
    * the altBackspaceIsMetaBackspace preference above.
    */
   this.altIsPressed = false;
+
+  /**
+   * If true, Chrome OS media keys will be mapped to their F-key equivalent.
+   * E.g. "Back" will be mapped to F1. If false, Chrome will handle the keys.
+   */
+  this.mediaKeysAreFKeys = false;
 };
 
 /**
diff --git a/hterm/js/hterm_keyboard_keymap.js b/hterm/js/hterm_keyboard_keymap.js
index c430256..5cb4fda 100644
--- a/hterm/js/hterm_keyboard_keymap.js
+++ b/hterm/js/hterm_keyboard_keymap.js
@@ -172,6 +172,16 @@
   // Call a method on the keymap instance.
   function c(m) { return function (e, k) { return this[m](e, k) } }
 
+  // Ignore if not trapping media keys
+  function med(fn) {
+    return function(e, k) {
+      if (!self.keyboard.mediaKeysAreFKeys) {
+        return hterm.Keyboard.KeyActions.PASS;
+      }
+      return resolve(fn, e, k);
+    };
+  }
+
   var ESC = '\x1b';
   var CSI = '\x1b[';
   var SS3 = '\x1bO';
@@ -317,16 +327,16 @@
     [110, '[KP.]', DEFAULT, DEFAULT, DEFAULT, DEFAULT],
 
     // Chrome OS keyboard top row.
-    [166, '[BACK]',   mod(SS3 + 'P', CSI + 'P'), DEFAULT, CSI + "23~", DEFAULT],
-    [167, '[FWD]',    mod(SS3 + 'Q', CSI + 'Q'), DEFAULT, CSI + "24~", DEFAULT],
-    [168, '[RELOAD]', mod(SS3 + 'R', CSI + 'R'), DEFAULT, CSI + "25~", DEFAULT],
-    [183, '[FSCR]',   mod(SS3 + 'S', CSI + 'S'), DEFAULT, CSI + "26~", DEFAULT],
-    [182, '[WINS]',   CSI + '15~',               DEFAULT, CSI + "28~", DEFAULT],
-    [216, '[BRIT-]',  CSI + '17~',               DEFAULT, CSI + "29~", DEFAULT],
-    [217, '[BRIT+]',  CSI + '18~',               DEFAULT, CSI + "31~", DEFAULT],
-    [173, '[MUTE]',   CSI + '19~',               DEFAULT, CSI + "32~", DEFAULT],
-    [174, '[VOL-]',   CSI + '20~',               DEFAULT, CSI + "33~", DEFAULT],
-    [175, '[VOL+]',   CSI + '21~',               DEFAULT, CSI + "34~", DEFAULT]
+    [166, '[BACK]',   med(mod(SS3+'P', CSI+'P')), DEFAULT, CSI+"23~", DEFAULT],
+    [167, '[FWD]',    med(mod(SS3+'Q', CSI+'Q')), DEFAULT, CSI+"24~", DEFAULT],
+    [168, '[RELOAD]', med(mod(SS3+'R', CSI+'R')), DEFAULT, CSI+"25~", DEFAULT],
+    [183, '[FSCR]',   med(mod(SS3+'S', CSI+'S')), DEFAULT, CSI+"26~", DEFAULT],
+    [182, '[WINS]',   med(CSI + '15~'),           DEFAULT, CSI+"28~", DEFAULT],
+    [216, '[BRIT-]',  med(CSI + '17~'),           DEFAULT, CSI+"29~", DEFAULT],
+    [217, '[BRIT+]',  med(CSI + '18~'),           DEFAULT, CSI+"31~", DEFAULT],
+    [173, '[MUTE]',   med(CSI + '19~'),           DEFAULT, CSI+"32~", DEFAULT],
+    [174, '[VOL-]',   med(CSI + '20~'),           DEFAULT, CSI+"33~", DEFAULT],
+    [175, '[VOL+]',   med(CSI + '21~'),           DEFAULT, CSI+"34~", DEFAULT]
   );
 };
 
diff --git a/hterm/js/hterm_preference_manager.js b/hterm/js/hterm_preference_manager.js
index c3c85f0..6d1cff6 100644
--- a/hterm/js/hterm_preference_manager.js
+++ b/hterm/js/hterm_preference_manager.js
@@ -170,6 +170,12 @@
     ['max-string-sequence', 100000],
 
     /**
+     * If true, convert media keys to their Fkey equivalent. If false, let
+     * Chrome handle the keys.
+     */
+    ['media-keys-are-fkeys', false],
+
+    /**
      * Set whether the meta key sends a leading escape or not.
      */
     ['meta-sends-escape', true],
diff --git a/hterm/js/hterm_terminal.js b/hterm/js/hterm_terminal.js
index c91254e..7140339 100644
--- a/hterm/js/hterm_terminal.js
+++ b/hterm/js/hterm_terminal.js
@@ -277,6 +277,10 @@
       terminal.vt.maxStringSequence = v;
     },
 
+    'media-keys-are-fkeys': function(v) {
+      terminal.keyboard.mediaKeysAreFKeys = v;
+    },
+
     'meta-sends-escape': function(v) {
       terminal.keyboard.metaSendsEscape = v;
     },