This package turns the header and mode lines into a keyboard.  This
is mainly intended to be used in environments without a normal
keyboard, such as touch devices.  Concretely, the Android
application "Termux" provides a Linux terminal environment that
includes a terminal version of Emacs.

Activate:

Enable the mode in a single buffer using:

    M-x mode-line-keyboard-mode RET

For all buffers use:

    M-x mode-line-keyboard-global-mode RET

Alternatively, add the following line to your init file:

    (mode-line-keyboard-global-mode 1)

Usage:

When enabled, the mode line contains the string `KB>'.  If you
click on it, the header will look like:

    1/4 SHFT CTRL META SPC TAB RET <X X> 1 2 3 4 5 6 7 8 9 0

And the mode line will look like:

    1/2 a b c d e f g h ...

To type on the keyboard, simply click on the characters, modifiers,
and special keys.

The `1/4' indicates that this is one of four lines -- clicking on
it display the next line.  To hide the keyboard click on `<KB'
which (by default) is on the last mode line.

Clicking in the echo area inserts a space (unless the minibuffer is
active).

To avoid accidental point movement when the Mode Line Keyboard is
visible, you have to double click to move the point, triple click
to mark a word etc.

Dependencies:

This package require Emacs 26.  In earlier Emacs versions, plain
typing works OK.  However, when typing something more complex like
`C-x C-f', the function `read-key-sequence-vector' raises the error
`args-out-of-range'.

Tips:

When Emacs is used in a terminal, the `header-line' face by default
has the `:underline' property set.  As many terminal environments
today provide many colors, this doesn't look good, and it makes it
hard to distinguish between characters like `.' and `,'.

You can override this by using something like:

    (deftheme my-theme "Theme to make the header line more readable.")
    (custom-theme-set-faces
      'my-theme
      '(header-line ((((class color)) :inherit mode-line))))

Customization:

The variables `mode-line-keyboard-header-line-content' and
`mode-line-keyboard-mode-line-content' control what should be
displayed in the header and mode lines, respectively.

They are lists, and each entry in the list corresponds to one
concrete line.

Each entry can be one of the following:

  * `integer' -- A character
  * `(:range integer integer)' -- A range of characters
  * `(integer label)' -- A character, but display "label".
  * `(:shift integer integer)' -- A character and its shifted counterpart.
  * `(:toggle var func label)' -- A modifier (like `control').
  * `(func label)' -- Call `func' when "label" is clicked.
  * `:keyword' -- Looked up in `mode-line-keyboard-template-list'.

The variable `mode-line-keyboard-template-list' is a list.  Each
element is a list starting with a keyword followed by one or more
items that this keyword is substituted for.

Notes:

When this package in used, `mouse-movement' events are suppressed.
Normally, this is not a problem.  Without this, clicking on `ESC'
on the Mode Line Keyboard and subsequently moving the mouse would
trigger an error that `ESC <mouse-movement>' is undefined.  (Note,
this happens when moving the mouse after pressing `ESC' on the
keyboard as well, however, in practice this is seldom an issue in
that context.)

Known problems:

* In Termux, sometimes (especially at startup), clicking in the
  echo area to insert a space doesn't work (instead the message
  "Minibuffer window is not active").  It appears as though Termux
  sends the `ESC ... M' sequence (down mouse) but not `ESC ... m'
  (up mouse) -- or that Emacs doesn't pick it up.  (To test this,
  click in the echo area and then `C-h l'.)

* When clicking on a label such as `CTRL' or `KB>', this package
  calls `read-key' recursively.  This mean that if you repeatedly,
  say, show and hide the keyboard, many times you could run out of
  call stack.  (All calls return once you have typed a key.)  In
  practice, This should not be a problem, unless you are the
  nervous type.

* Inserting a space by clicking in the echo are result in a undo
  event by itself.  This is probably due to that there are two
  events seen by Emacs, one `down' event and one `up'.  (It would
  probably be possible to fix this by "swallowing" the down event,
  as done by other keys.)

* When typing fast it's easy to accidentally move the point.  (When
  the Mode Line Keyboard is visible, the user must double-click to
  move the point.  However, when typing fast the clicks are
  double-clicks, and if the click is outside the mode or header
  line, the double click will move the point.)

Future ideas:

* Caps lock support, at least for shift, but maybe for all
  modifiers.

* Today, it's possible to step through a number of keyboard lines.
  Howevever, there are no reasons to limit the layout to lines.
  One could imagine a tree structure, where some labels on the mode
  or header line would open new sublayouts.  This could be used,
  for example, to open a dedicated meny for parentheses or to
  support accented characters.

* Allow layouts to be major-mode specific.  For example, when
  writing C, curly braces maybe should be accessible than when
  writing Lisp.

* Provide a convenient mechanism for theme packages.  (I can't wait
  to see the kind of layouts users might come up with.)

* Better support for automatic detection and adaptation to native
  languages (e.g. swedish -- which is my native langugage -- we has
  three extra letter å, ä, and ö).

Implementation:

This package adds key binding for things `mode-line mouse-1' to
`input-decode-map'.  These bindings convert the events to plain
keys, or perform some other kind of action.  The header- and
mode-line strings used by Mode Line Keyboard has the property
`mode-line-keyboard-action'.  When the property is a vector
(typically containing a key) it is returned.  When it's a function,
it is called, this is for example used by the entries that add
modifiers.

Some of the Mode Line Keyboard functions call `read-key'.  This
will in turn tunnel whatever they read through `input-decode-map',
which could cause Mode Line Keyboard functions to be called.  This
could, of course, mean that the same function is called in a
bizarre kind of recursive way.

In some cases, this package tries to silence events.  This is done
by calling `read-key' and returning the next event.

Personal note:

When I first started writing this package I though it would be
"easy pick", and I planned to spend an evening or two one it.  Boy,
was I wrong.  The Emacs event system turned out to be very complex,
and it took a lot of time and energy to try to understand how it
works.  In addition, I ran into numerous bugs in Emacs along the
way.

In order to understand what happens when a key is pressed or when
something is clicked, I wrote the package `keymap-logger' that
instruments a number of system keymaps and log the result.

Tips:

When Emacs is used in a terminal, the `header-line' face by default
has the `:underline' property set.  As many terminal environments
today provide many colors, this doesn't look good, and it makes it
hard to distinguish between characters like `.' and `,'.

You can override this by using something like:

    (deftheme my-theme "Theme to make the header line more readable.")
    (custom-theme-set-faces
      'my-theme
      '(header-line ((((class color)) :inherit mode-line))))