#!/bin/sh -e
# Copyright (c) 2016 The crouton Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This adds support for Chromebook keyboard special keys.
#
# For example, we map Search+arrows to Page Up/Down/Home/End. This is
# done at the browser level in Chromium OS (i.e., not at the hardware
# or keymap level).
#
# The mapping of Search+F1-F10 is reversed compared to Chromium OS:
# Pressing the back key still produces F1, Search+F1 is required to
# generate XF86Back.
#
# We do this by adding an overlay, and using Super_L (Search key) as
# the overlay latch.
#
# An additional mapping is needed to make sure that Super_R is not
# sent when the Search key is released (this is a little strange,
# and I'm not sure why this happens).

REQUIRES='x11'
DESCRIPTION='Adds support for Chromebook keyboard special keys.'
#chrome os only
#. "${TARGETSDIR:="$PWD"}/common"

### Append to prepare.sh:
#debian only
#if [ "${DISTROAKA:-"$DISTRO"}" = 'debian' ]; then
#    # Make sure we start from a fresh package
#    apt-mark unhold xkb-data || true 2>/dev/null
#    apt-get -y install --reinstall xkb-data
#fi

XKBROOT='/usr/share/X11/xkb'
XKBROOTTMP="`mktemp -d crouton-xkb.XXXXXX --tmpdir=/tmp`"
#chrome os only
#addtrap "rm -rf --one-file-system '$XKBROOTTMP'"
mkdir -p "$XKBROOTTMP/compat" "$XKBROOTTMP/symbols" "$XKBROOTTMP/rules"

cat > "$XKBROOTTMP/compat/chromebook" <<END
// Overlay1_Enable is a latch key for overlay1

default partial xkb_compatibility "overlay"  {
	interpret Overlay1_Enable+AnyOfOrNone(all) {
		action= SetControls(controls=Overlay1);
	};
};
END

cat > "$XKBROOTTMP/symbols/chromebook" <<END
// This mapping assumes that inet(evdev) will also be sourced
partial
xkb_symbols "overlay" {
	key <RCTL> { [ Overlay1_Enable ], overlay1=<RCTL> };

	key <AB09> { overlay1=<INS> };

	key <LEFT> { overlay1=<HOME> };
	key <RGHT> { overlay1=<END> };
	key <UP>   { overlay1=<PGUP> };
	key <DOWN> { overlay1=<PGDN> };

	key <AE01> { overlay1=<FK01> };
	key <AE02> { overlay1=<FK02> };
	key <AE03> { overlay1=<FK03> };
	key <AE04> { overlay1=<FK04> };
	key <AE05> { overlay1=<FK05> };
	key <AE06> { overlay1=<FK06> };
	key <AE07> { overlay1=<FK07> };
	key <AE08> { overlay1=<FK08> };
	key <AE09> { overlay1=<FK09> };
	key <AE10> { overlay1=<FK10> };
	key <AE11> { overlay1=<FK11> };
	key <AE12> { overlay1=<FK12> };

	key <BKSP> { overlay1=<DELE> };

	key <RTSH> { overlay1=<CAPS> };

	// For some strange reason, some Super_R events are triggered when
	// the Search key is released (i.e. with overlay on).
	// This maps RWIN to a dummy key (<I253>), to make sure we catch it.
	// key <RWIN> { [ NoSymbol ], overlay1=<I253> };

	// Map dummy key to no symbol
	// key <I253> { [ NoSymbol ] };
};
END

awk '
# default: print line
1

# rules/base.ml1_c.part
/^! model[ \t]*layout\[1\][ \t]*=[ \t]*compat$/{
	found[1]++;
	print "  chromebook	*		=	complete+chromebook"
}

# rules/base.ml_c.part
/^! model[ \t]*layout[ \t]*=[ \t]*compat$/{
	found[2]++;
	print "  chromebook	*		=	complete+chromebook"
}

# rules/evdev.m_s.part
/^! model[ \t]*=[ \t]*symbols$/{
	found[3]++;
	print "  chromebook	=   +inet(evdev)+chromebook(overlay)"
}

END {
	for (i = 1; i <= 3; i++) {
		if (found[i] != 1) {
			print "Error: " FILENAME ": rule " i ": applied " found[i] " times" > "/dev/stderr"
			exit 1
		}
	}
}
' "$XKBROOT/rules/evdev" > "$XKBROOTTMP/rules/evdev"

# rules/base.xml.in
awk '
# default: print line
1

/^.*<modelList>$/{
	found++;
	print "    <model>";
	print "      <configItem>";
	print "        <name>chromebook</name>";
	print "        <description>Chromebook</description>";
	print "        <vendor>Google</vendor>";
	print "      </configItem>";
	print "    </model>"
}

END {
	if (found != 1) {
		print "Error: " FILENAME ": rule applied " found " times" > "/dev/stderr"
		exit 1
	}
}
' "$XKBROOT/rules/evdev.xml" > "$XKBROOTTMP/rules/evdev.xml"

awk '
# default: print line
1

/^! model$/{
	found++;
	print "  chromebook      Chromebook"
}

END {
	if (found != 1) {
		print "Error: " FILENAME ": rule applied " found " times" > "/dev/stderr"
		exit 1
	}
}
' "$XKBROOT/rules/evdev.lst" > "$XKBROOTTMP/rules/evdev.lst"

# Apply the modifications
cp -a "$XKBROOTTMP"/* "$XKBROOT"/

#debian only
#if [ "${DISTROAKA:-"$DISTRO"}" = 'debian' ]; then
#    # Hold xkb-data, so that it does not get updated
#    apt-mark hold xkb-data
#fi
