#!/usr/bin/env ruby
# kcmconv.rb: Convert a legacy, binary key character map to ICS format.
#
# Author: Mike Kasick <mike@kasick.org>
# Date:   Sat, 21 Jan 2012 16:49:28 -0500
#
# Copyright (C) 2012  Michael P. Kasick
# 
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# Usage: ./kcmconv.rb input.kcm.bin > output.kcm

BEGIN {$VERBOSE = true}

# From "frameworks/base/core/res/res/values/attrs.xml".
KCMAP = {  0 => "UNKNOWN",
           1 => "SOFT_LEFT",
           2 => "SOFT_RIGHT",
           3 => "HOME",
           4 => "BACK",
           5 => "CALL",
           6 => "ENDCALL",
           7 => "0",
           8 => "1",
           9 => "2",
          10 => "3",
          11 => "4",
          12 => "5",
          13 => "6",
          14 => "7",
          15 => "8",
          16 => "9",
          17 => "STAR",
          18 => "POUND",
          19 => "DPAD_UP",
          20 => "DPAD_DOWN",
          21 => "DPAD_LEFT",
          22 => "DPAD_RIGHT",
          23 => "DPAD_CENTER",
          24 => "VOLUME_UP",
          25 => "VOLUME_DOWN",
          26 => "POWER",
          27 => "CAMERA",
          28 => "CLEAR",
          29 => "A",
          30 => "B",
          31 => "C",
          32 => "D",
          33 => "E",
          34 => "F",
          35 => "G",
          36 => "H",
          37 => "I",
          38 => "J",
          39 => "K",
          40 => "L",
          41 => "M",
          42 => "N",
          43 => "O",
          44 => "P",
          45 => "Q",
          46 => "R",
          47 => "S",
          48 => "T",
          49 => "U",
          50 => "V",
          51 => "W",
          52 => "X",
          53 => "Y",
          54 => "Z",
          55 => "COMMA",
          56 => "PERIOD",
          57 => "ALT_LEFT",
          58 => "ALT_RIGHT",
          59 => "SHIFT_LEFT",
          60 => "SHIFT_RIGHT",
          61 => "TAB",
          62 => "SPACE",
          63 => "SYM",
          64 => "EXPLORER",
          65 => "ENVELOPE",
          66 => "ENTER",
          67 => "DEL",
          68 => "GRAVE",
          69 => "MINUS",
          70 => "EQUALS",
          71 => "LEFT_BRACKET",
          72 => "RIGHT_BRACKET",
          73 => "BACKSLASH",
          74 => "SEMICOLON",
          75 => "APOSTROPHE",
          76 => "SLASH",
          77 => "AT",
          78 => "NUM",
          79 => "HEADSETHOOK",
          80 => "FOCUS",
          81 => "PLUS",
          82 => "MENU",
          83 => "NOTIFICATION",
          84 => "SEARCH",
          85 => "MEDIA_PLAY_PAUSE",
          86 => "MEDIA_STOP",
          87 => "MEDIA_NEXT",
          88 => "MEDIA_PREVIOUS",
          89 => "MEDIA_REWIND",
          90 => "MEDIA_FAST_FORWARD",
          91 => "MUTE",
          92 => "PAGE_UP",
          93 => "PAGE_DOWN",
          94 => "PICTSYMBOLS",
          95 => "SWITCH_CHARSET",
          96 => "BUTTON_A",
          97 => "BUTTON_B",
          98 => "BUTTON_C",
          99 => "BUTTON_X",
         100 => "BUTTON_Y",
         101 => "BUTTON_Z",
         102 => "BUTTON_L1",
         103 => "BUTTON_R1",
         104 => "BUTTON_L2",
         105 => "BUTTON_R2",
         106 => "BUTTON_THUMBL",
         107 => "BUTTON_THUMBR",
         108 => "BUTTON_START",
         109 => "BUTTON_SELECT",
         110 => "BUTTON_MODE"}

def conv(n)
	case n
	when 0;       "none"
	when 9;       "'\\t'"
	when 34;      "'\\\"'"
	when 39;      "'\\''"
	when 10;      "'\\n'"
	when 92;      "'\\\\'"
	when 32..126; "'#{n.chr}'"
	when 0..127;  raise n.to_s
	else          "\\u%04x" % n
	end
end

ARGF.read(32)

puts "type ALPHA"

while row = ARGF.read(16)
	cols = row.unpack('Vv*')

	keycode = KCMAP.fetch(cols[0])
	display = conv cols[1]
	number  = conv cols[2]
	base    = conv cols[3]
	caps    = conv cols[4]
	fn      = conv cols[5]
	caps_fn = conv cols[6]

#	$stderr.puts([keycode, display, number, base, caps, fn, caps_fn].join("\t"))

	puts <<-EOK

key #{keycode} {
    label:                              #{display}
    number:                             #{number}
    base:                               #{base}
    shift, capslock:                    #{caps}
    alt:                                #{fn}
    shift+alt, capslock+alt:            #{caps_fn}
}
	EOK
end
