AndroWish: Documentation

This page is intended as a place to document the capabilities of the custom commands offered by the AndroWish, the Tcl/Tk port to Android (excellent work, chw!). In the true Wiki spirit you are invited to extend this documentation. (You may have, already (chw definitely has): this information was harvested from the AndroWish page!)

There are four Android-specific commands:

  1. borg - control and interact with the Android OS.
  2. rfcomm - transfer data over a Bluetooth serial port profile; akin to the TCL socket command.
  3. sdltk - exposure of the SDL2 (Simple DirectMedia Layer) Android-related API.
  4. usbserial - transfer data over USB-serial converters (FTDI, CDC, Prolific, and others)

Documentation is provided in the order specified.


Name

borg - control and interact with the Android OS.

Synopsis

borg cmd ?arg ...?

Description

This command integrates the capabilities of Tcl/Tk with an Android OS by way of several subcommands. These allow Tcl/Tk to go where it has never gone before by querying and controlling Bluetooth functionality, OS notifications (including device vibration and even speach), location information, etc.

Bluetooth-Related Commands

borg bluetooth devices
Returns a list suited for array set or dict create commands containing the Bluetooth address and friendly name of all paired Bluetooth devices.
borg bluetooth state
Returns the current Bluetooth state: on or off.
borg bluetooth scanmode
Returns the current Bluetooth scan mode (off, passive, visible, connectable, or on).
borg bluetooth myaddress
Returns the Bluetooth address of the local default Bluetooth adapter.
borg bluetooth remoteaddress address
Returns the friendly name for the given Bluetooth address.

USB-Related Commands

borg usbdevices
Returns a list suited for the array set or dict create commands containing the USB device name and vendor/product identifier of all currently connected USB devices.

Network-Related Commands

borg networkinfo
Returns the current state of the network: none, wifi, mobile gsm, etc.

Destkop-Related Commands

borg shortcut add name-of-shortcut script-to-run ?png-icon-as-base-64-string?
Adds an icon to the desktop, with the name-of-shortcut specified. The script, specified as script-to-run must use an absolute path must be readable by the user id under which the AndroWish package has been registered by the Android installer. The last (optional) parameter png-icon-as-base-64-string allows the icon graphic to be specified. If not provided, the AndroWish icon (Aladdin's lamp) is used.
borg shortcut delete name-of-shortcut
Deletes an icon from desktop (depends on Android launcher support).

Notification-Related Commands

borg notification add id title ?text icon action uri type categories component arguments?
Adds a notification with title and text into the Android notification area. The integer id, specified by the caller, is used to identify the notification for later modification or deletion. The optional parameters starting from action form an activity (see borg activity ...) to be carried out when the user clicks on the notification. The optional icon must be a PNG or JPG image encoded as base64 string.
borg notification delete ?id?
Deletes a notification identified that was created with the id specified. If no id is provided, all notifications are deleted.
borg vibrate ms
Turns the vibration motor on for integer ms milliseconds.
borg beep
Plays the notification sound.
borg speak text ?lang pitch rate?
Gets the Android to read out the string text. Optional parameter lang is the language code for the spoken language, e.g. en, en_US, de, es, etc. Optional parameters pitch and rate control the voice and speed as float values. For more information, see http://developer.android.com/reference/android/speech/tts/TextToSpeech.html
borg stopspeak
Stops speech output.
borg isspeaking
Returns true or false depending on state of speech output.
borg endspeak
Stops speech output and releases system resources.
borg toast text ?flag?
Displays a text notification text for a short period of time. The duration of that display is somewhat longer when flag is specified as true.
borg spinner on|off
Displays or withdraws a spinner (rotating symbol indicating busy state) depending on argument.

Location-Related Commands

borg location start ?minrate-in-ms? ?min-dist-in-m?
Begins acquiring location data via the Android OS (which may choose to use GPS, network info, etc.).
borg location stop
Ends location data acquisition.
borg location get
Returns the location data (as an array set form) where the key is the location source. Location updates trigger a virtual event <<LocationUpdate>> (currently untested) that is sent to all toplevel widgets. These toplevel event-handlers should, in turn, invoke borg location get to refresh their knowledge.

System-Related Commands

borg displaymetrics
Returns information about the display in form suitable for array set, e.g. display resolution, pixel density. See http://developer.android.com/reference/android/util/DisplayMetrics.html for details.
borg osbuildinfo
Returns information about the operating system and device in form suitable for array set, e.g. Android API level, version, device name, manufacturer etc. See http://developer.android.com/reference/android/os/Build.html for details.
borg queryfeatures
Returns information about features of the system (a lengthy list of strings) which is obtained from http://developer.android.com/reference/android/content/pm/PackageManager.html#getSystemAvailableFeatures( )
borg packageinfo ?name?
Returns information about installed packages or an individual package if its name is given. In the first case, a list with package names is returned, in the latter case a list of key value pairs with package information which can be used for array set or dict create.
borg log prio tag message
Writes the message message to Android's system log with priority prio (one of verbose, debug, info, warn, error, or fatal) and a user chosen prefix tag. These log messages can be displayed using adb logcat on the development system.

Sensor-related Commands

borg sensor list
Returns a list of the available sensors of the device. Each item is suitable for array set an contains the fields index (integer index of the sensor, used to identify it), type (sensor type, one of temperature, game_rotation_vector, geomagnetic_rotation_vector, gravity, gyroscope, gyroscope_uncalibrated, light, linear_acceleration, magnetic_field, magnetic_field_uncalibrated, orientation, pressure, proximity, relative_humidity, rotation_vector, step_counter, and step_detector), mindelay (minimum update interval in milliseconds), maxrange (maximum range, floating point), resolution (floating point), power (in mA, floating point), and name (name of the sensor). See http://developer.android.com/reference/android/hardware/Sensor.html for further details.
borg sensor enable|disable|state index
Turns the sensor identified by index on or off, or returns its state (0=off, 1=on). An enabled sensor generates <<SensorUpdate>> virtual events which are sent to toplevel windows. These events are either periodic updates or change notifications depending on the kind of sensor and its refresh rate. If a sensor is not read out using borg sensor get ... for a certain amount of time that sensor is automatically disabled to conserve battery power. If the application enters background (see virtual event <<WillEnterBackground>>) all enabled sensors are disabled and re-enabled again when the application comes back to foreground (see virtual event <<WillEnterForeground>>).
borg sensor get index
Returns the last value acquired from the sensor identified by index as a list suitable for array set containing the fields index (integer), enabled (sensor state, 0 or 1), maxrange (see above), resolution (see above), accuracy (the accuracy of this value), values (the sensor value, zero or more floating point numbers). See http://developer.android.com/reference/android/hardware/SensorEvent.html for further details.

Android Content (shared databases)

borg content query uri ?columns? ?where? ?whereargs? ?orderby?
Performs a query on an Android content provider given by uri and returns a cursor token (a Tcl command which deals with that cursor). The optional columns are a comma separated list of database columns to appear in the result set. The optional where and whereargs parameters form the SQL WHERE clause of the query. Question mark parameter markers in where are positionally substituted by the information from the whereargs list. The optional orderby is the SQL ORDERBY part of the query. Example:
  set cursor [borg content query content://settings/system]
  # initially, cursor points before first row
  while {[$cursor move 1]} {
      puts [$cursor getrow]
  }
borg content delete uri selection ?value ...?
Deletes rows from an Android content provider given by uri and returns the number of deleted rows. selection forms the SQL WHERE clause of the deletion where question mark parameter markers are substituted by value. Example:
  borg content delete content://settings/system name=? my_item
borg content insert uri key value ...
Inserts a row into an Android content provider given by uri and returns another URI which identifies the inserted row. key and value are pairs of column name and column value for the SQL INSERT operation. Example:
  borg content insert content://settings/system name my_item value "Some value"
  -> content://settings/system/4711
borg content update uri values ?selection? ?args?
Updates zero or more rows of an Android content provider given by uri and returns the number of updated rows. values is a list made up of a sequence of column names and column values. selection is the optional SQL WHERE clause with question mark parameter markers. The parameter markers are substituted by the values from args. Example:
  # system settings wants the name in the URI
  borg content update content://settings/system/my_item {value {New Value}}

Cursors from Android Content queries

When a borg content query returned a cursor token, this token is a Tcl command to deal with the query's result set:

$cursor close
Finishes the query and deletes the Tcl command.
$cursor columnnames
Returns a list of column names of the result set.
$cursor count
Returns the number of rows of the result set.
$cursor getblob index
Returns the indexth column (zero-based) of the current row of the result set as a base64 encoded string.
$cursor getdouble index
Returns the indexth column (zero-based) of the current row of the result set as a floating point number.
$cursor getint index
Returns the indexth column (zero-based) of the current row of the result set as a integer number.
$cursor getpos
Returns the index of the current row (zero-based).
$cursor getrow
Returns the current row as a Tcl list made up of strings. Blobs from the result set are converted into base64 encoded strings.
$cursor getstring index
Returns the indexth column (zero-based) of the current row of the result set as a string.
$cursor isnull index
Returns true when the indexth column (zero-based) of the current row of the result set is an SQL NULL value.
$cursor move pos
Relative move of the current row index. Negative pos goes backward.
$cursor moveto pos
Absolute move of the current row index.

Speech Recognition

borg speechrecognition intent args cmd
Use the speech recognition service. args is a parameter list to control the speech recognition (see http://developer.android.com/reference/android/speech/RecognizerIntent.html for details). cmd is invoked when the speech recognition is complete. That procedure receives the parameters retcode and data as in the callback for borg activity. data is a list of key value pairs suitable for array set.
borg speechrecognition callback cmd
Establishes cmd as global callback procedure receiving speech recognition events as described by the RecognitionListener interface (see http://developer.android.com/reference/android/speech/RecognitionListener.html for details). That procedure receives the parameters retcode and data as in the callback for borg activity. data is a list of key value pairs suitable for array set. There are up to two special keys present in data: type giving the event type (one of result, partialresult, ready, event. rms, end, begin) and value giving numeric values for certain event types (error code for error, audio level for rms).
borg speechrecognition start args
Starts the speech recognition. For args see the description in borg speechrecognition intent ....
borg speechrecognition cancel
Immediately cancels the speech recognition. No further events are reported through the global callback procedure.
borg speechrecognition stop
Stops the speech recognition. Events can be still reported through the global callback procedure.

General

borg withdraw
Hides the application window by putting it to the end of Android's activity stack. Can be useful when bound to the Back key (<Key-Break> on AndroWish). There's no opposite command, i.e. the application can be brought to front again only by user interaction.
borg onintent ?command?
Sets or gets the callback command which is evaluated when the application received an Android intent. When evaluating that command, the parameters action name, URI, MIME type, categories, arguments from the intent are appended. When the callback is set for the first time, it gets immediately evaluated with the parameters of the current (startup) intent.
borg queryactivites action ?uri type categories component?
Queries Android's activity manager for activities on the given intent parameters. categories and component are optional lists. The latter when non-empty must contain the two elements package name and class name.
borg queryservices action ?uri type categories component?
Queries Android's activity manager for services on the given intent parameters, similar to borg queryactivities.
borg querybroadcastreceivers action ?uri type categories component?
Queries Android's activity manager for broadcast receivers on the given intent parameters, similar to borg queryactivities.
borg screenorientation ?orient?
Queries or switches the screen orientation, orient can be one of unspecified, landscape, portrait, user, behind, sensor, nosensor, sensorlandscape, sensorportrait, reverselandscape, reverseportrait, fullsensor, userlandscape, userportrait, fulluser, or locked.
borg keyboardinfo
Returns information about the current keyboard configuration as a list suitable for array set with these fields: keyboard with possible values none, 12key, and qwerty, hidden and hard_hidden with values 0 (not hidden), 1, (hidden), and -1 (unknown). This can be read out any time. An update in keyboard configuration state is indicated by the virtual event <<KeyboardInfo>>.
borg alarm clear action ?uri type categories component?
Clears an alarm whose pattern matches the given intent parameters.
borg alarm set when repeat action ?uri type categories component arg ...?
Sets an alarm to fire at when (UN*X epoch, seconds) with repetition each repeat seconds, when repeat is greater than 0. The alarm sends an intent made up of the given intent parameters (action etc.). The component parameter is interpreted specially: when empty no component is set on the intent, when given as self the calling package/class is set as component for the intent (sending the intent to itself, i.e. the callback of borg onintent will receive it). In all other cases component must be a list with the two elements package name and class name. arg and following parameters are added to the intent as key value pairs of extra data.
borg alarm wakeup when repeat action ?uri type categories component arg ...?
Like borg alarm set but this type of alarm is able to wake up the device when suspended (device behavior depends on lock screen settings).
borg activity action uri type ?categories? ?component? ?arguments? ?callback?
This a very flexible command that allows extensive access to the Android OS and other applications. categories, component, and arguments are optional lists. callback is the name of the procedure that is evaluated when the activity action is complete. arguments are key-value pairs where the values are mapped to Java strings by default. If the key is a 2-element list made up of a data type indicator (int, byte, short, char, long, float, double, Uri) followed by the key, the value is converted to that data type. See below for some examples of this command.

borg activity Examples

Sample code to open a browser on this wiki:

    borg activity android.intent.action.VIEW https://wiki.tcl-lang.org text/html

Sample code to capture an image (only makes thumbnails):

    proc callback {retcode action uri mimetype categories data} {
        if {$retcode == -1} {
            # SUCCESS
            array set result $data
            if {[info exists result(data)]} {
                myphoto configure -data $result(data)
            }
        }
    }
    package require Img
    image create photo myphoto
    borg activity android.media.action.IMAGE_CAPTURE {} {} {} {} {} callback

Sample code to capture an image, which makes full size images but requires a file on external storage:

    proc callback {filename retcode action uri mimetype categories data} {
        if {$retcode == -1} {
            # SUCCESS
            myphoto configure -file $filename
            catch {file delete -force $filename}
        }
    }
    package require Img
    image create photo myphoto
    set filename [file join $env(EXTERNAL_FILES) myphoto.jpeg]
    borg activity android.media.action.IMAGE_CAPTURE {} {} {} {} \
       [list {Uri output} file://$filename] [list callback $filename]

Reading barcodes using the http://code.google.com/p/zxing barcode scanner (which needs to be be installed on your device):

    proc barcode_read {code action uri type cat data} {
        array set result $data
        if {[info exists result(SCAN_RESULT)]} {
            # that is the barcode
            # result(SCAN_RESULT_FORMAT) is the barcode format
        }
    }

    borg activity com.google.zxing.client.android.SCAN {} {} {} {} {} barcode_read

Name

rfcomm - transfer data over a Bluetooth serial port profile; akin to the TCL socket command.

Synopsis

This command is used to transfer data over Bluetooth's serial port profile (SPP or SP). The arguments used are nearly identical to the TCL socketcommand. It returns a client or server channel handle that may be used with gets, read, puts, and close. For client channels, the remote address must be given as a one- or two-element list: the first element is the Bluetooth address, and the (optional) second element is the UUID of the remote service. For server channels, the first element is the UUID, and the optional second element is the friendly name of the service. Server mode functionality has not yet been verified.


Name

sdltk - exposure of the SDL2 (Simple DirectMedia Layer) Android-related API.

Synopsis

This command is used to control portions of the Android system that the SDL2 framework exposes. Actual data processing for this framework is achieved by having handlers for virtual events.

Description

sdltk powerinfo
Returns a list of key-value pairs describing the state of the battery.
sdltk accelerometer on|off
Turns the device accelerometer on and off. Creates a top-level virtual event <<Accelerometer>>.
sdltk textinput ?on|off ?x y ?hint???
Returns the state of the virtual keyboard or switches the virtual keyboard on or off. The optional coordinate pair is a hint for the system where the insertion cursor is displayed in screen coordinates. This allows the system to pan the application's screen in order to display the insertion cursor when the virtual keyboard is active. The hint parameter is an integer which controls the kind of virtual keyboard to be displayed. Known values are 0 (normal keyboard), 2 (number input), 3 (phone number input), 4 (date/time input).
sdltk android
Returns true when running on Android, false otherwise, i.e. when built for normal Linux platforms.
sdltk touchtranslate ?flag?
Turns touchscreen event translation on or off, or reports the current translation state. When turned on, fast wipes with one finger are translated to mouse button 2 press/motion/release events to allow scrolling of listboxes, entries, and text widgets. Slow wipes still deliver mouse button 1 motion events. Holding down one finger for about a second is translated into mouse button 3 press for context menus. Pinch-to-zoom with two fingers is detected and reported as a virtual event named <<PinchToZoom>> with %X and %Y giving the root window coordinate of the center of the two fingers, %x the distance between the two fingers, and %y the angle measured in 64 times degrees CCW starting at 3 o'clock.
sdltk screensaver ?on|off?
Turns the screen saver on or off or reports current state of the screensaver.

Events

Using the sdltk framework usually requires liberal use of virtual event handlers. The virtual events include:

<<Accelerometer>>
Event associated with the accelerometer (activated with sdltk accelerometer on). %s is the accelerometer axis {1..3} and %x is the accelerometer value in the range {-32768...+32767}.
<<FingerDown>>
A touch event.
<<FingerUp>>
A touch completion event.
<<FingerMotion>>
A touch movement (sliding) event. The fields %x and %y are substituted with the finger position scaled to {0...9999}, %X and %Y with the difference scaled to {0...9999}, %t with the pressure scaled to {0...9999}, and %s with the finger identifier {1...10}. These substitutions are performed for all finger related touch events.

Events related to the APP life cycle

These events are direct translations from SDL events. They are reported to toplevel widgets only.

<<LowMemory>>
System is in low memory situation
<<Terminating>>
APP is terminating
<<WillEnterBackground>>
APP's screen will be put in background
<<DidEnterBackground>>
APP's screen is in the background
<<WillEnterForeground>>
APP's screen will be put in foreground
<<DidEnterForeground>>
APP's screen is in the foreground

Other events

These events are generated for/by certain borg related commands. They are reported to toplevel widgets only.

<<LocationUpdate>>
Location information has been updated and can be read out using borg location get.
<<NetworkInfo>>
Network state has changed and can be read out using borg networkinfo.
<<Bluetooth>>
Bluetooth state has changed and can be read out using borg bluetooth state.
<<SensorUpdate>>
A sensor can be read using borg sensor get .... The field %x identifies the sensor.
<<KeyboardInfo>>
The keyboard configuration did change and can be obtained by borg keyboardinfo.

Touchscreen related

<<PinchToZoom>>
Pinch-to-zoom with two fingers, see sdltk touchtranslate and the following sample code.
    proc showzoom {canvas rootx rooty dist angle state} {
        $canvas itemconf t -text "XY: $rootx,$rooty L: $dist P: $angle S: $state"
        $canvas delete a
        # state 0 -> zoom motion
        # state 1 -> zoom start
        # state 2 -> zoom end, 1st finger up
        # state 3 -> zoom end, 2nd finger up
        if {$state < 2} {
            set phi [expr {$angle / 64.0}]
            set x0 [expr {$rootx - [winfo rootx $canvas] - $dist / 2}]
            set x1 [expr {$x0 + $dist}]
            set y0 [expr {$rooty - [winfo rooty $canvas] - $dist / 2}]
            set y1 [expr {$y0 + $dist}]
            $canvas create arc $x0 $y0 $x1 $y1 -fill yellow -outline red -width 6 \
                -start [expr {330 - $phi}] -extent -300.0 -tags a
        }
    }

    wm attributes . -fullscreen 1
    canvas .c -bg black -bd 0 -highlightthickness 0
    pack .c -side top -fill both -expand 1 -padx 0 -pady 0
    set f [open [info script]]
    .c create text 30 120 -anchor nw -tag s -font {Courier 6} -text [read $f] \
        -fill gray50
    close $f
    .c create text 30 30 -anchor w -fill green -tag t -font {Helvetica 16} \
        -text "Try pinch-to-zoom with two fingers"
    button .c.x -text Exit -command {exit 0}
    .c create window 30 60 -anchor nw -tag x -window .c.x
    bind .c <<PinchToZoom>> {showzoom %W %X %Y %x %y %s}
<<Accelerometer>>
Following sample code illustrates using the 3 accelerometer axes.
    proc showaccel {canvas axis value} {
        set ix 0
        set iy 0
        if {$axis == 1} {
            set ix [expr {$value / 256}]
        } elseif {$axis == 2} {
            set iy [expr {$value / 256}]
        } elseif {$axis == 3} {
            set ::pos(t) [expr {($value / 256) % 360}]
        } else {
            return
        }
        if {![info exists ::pos(x)]} {
            set ::pos(x) [expr [winfo width $canvas] / 4]
            set ::pos(y) [expr [winfo height $canvas] / 4]
            set ::pos(t) 0
        }
        set ::pos(x) [expr {$::pos(x) + $ix}] 
        set ::pos(y) [expr {$::pos(y) + $iy}] 
        if {$::pos(x) < 50} {
            set ::pos(x) 50
        } elseif {$::pos(x) > [winfo width $canvas] - 50} {
            set ::pos(x) [expr {[winfo width $canvas] - 50}]
        }
        if {$::pos(y) < 50} {
            set ::pos(y) 50
        } elseif {$::pos(y) > [winfo height $canvas] - 50} {
            set ::pos(y) [expr {[winfo height $canvas] - 50}]
        }
        if {$axis == 3} {
            $canvas delete a
            set x0 [expr {$::pos(x) - 48}]
            set x1 [expr {$x0 + 96}]
            set y0 [expr {$::pos(y) - 48}]
            set y1 [expr {$y0 + 96}]
            $canvas create arc $x0 $y0 $x1 $y1 -fill yellow -outline red \
                -width 6 -start [expr {330 - $::pos(t)}] -extent -300.0 -tags a
        }
    }

    wm attributes . -fullscreen 1
    canvas .c -bg black -bd 0 -highlightthickness 0
    pack .c -side top -fill both -expand 1 -padx 0 -pady 0
    set f [open [info script]]
    .c create text 20 120 -anchor nw -tag s -font {Courier 5} -text [read $f] \
        -fill gray50
    close $f
    button .c.x -text Exit -command {exit 0}
    .c create window 30 60 -anchor nw -tag x -window .c.x
    bind . <<Accelerometer>> {showaccel .c %s %x}
    sdltk accelerometer on

Name

usbserial - transfer data over USB-serial converters

Synopsis

This command is used to transfer data over supported USB-serial converters (FTDI, CDC, Prolific, etc., see http://code.google.com/p/usb-serial-for-android/ for reference). When no further argument is given to the usbserial command, a list of supported USB device names is returned. When the USB device name of a supported USB-serial converter is given as argument, usbserial opens that USB device and returns a Tcl channel handle for it. That channel handle may be used with fconfigure, gets, read, puts, and close. The options -mode, -ttycontrol, and -ttystatus to fconfigure are supported by the channel. However, support for getting/setting control lines varies between different USB-serial converter chips.


Environment

Some environment variables in the env array are setup on early startup of AndroWish.

env(EXTERNAL_FILES)
App specific directory on external storage
env(EXTERNAL_STORAGE)
Path name of external storage (could be internal SD card)
env(EXTERNAL_STORAGE2)
Path name of external storage (real external SD card)
env(HOME)
App's home directory (internal storage)
env(INTERNAL_STORAGE)
App specific directory on internal storage (identical with $env(HOME))
env(LANG)
System language
env(LD_LIBRARY_PATH)
Load path for shared libraries including app specific directory
env(OBB_DIR)
On some Android versions extra stuff bundled with the app (unused as of 2014-02-05)
env(PACKAGE_CODE_PATH)
Path name of the app's APK
env(PACKAGE_NAME)
Package name where the app's main class comes from
env(PATH)
Path for exec(n) including app specific directory
env(TMPDIR)
Path name for temporary files

Revision History

2014-26-01 LWS - creation from AndroWish entries - with lots left out, possible misinterpretation, etc. A momentary editing collision with chw: sorry!
2014-02-02 LWS - updated borg shortcut add with info from AndroWish Feature Requests and modified a portion of the barcode reading example
2014-02-03 chw - updated sdltk command description, added more event descriptions
2014-02-05 chw - added borg toast command description
2014-02-06 chw - added description of environment variables
2014-02-08 chw - added description for borg displaymetrics and borg osbuildinfo
2014-02-11 chw - updated borg speak command description
2014-02-22 chw - added description for sdltk touchtranslate and <<PinchToZoom>>
2014-03-03 chw - added description for borg spinner and sdltk screensaver
2014-03-07 chw - improved <<Accelerometer>> description
2014-03-15 chw - added description for borg queryfeatures, borg packageinfo, and borg content
2014-03-24 chw - added description for borg withdraw
2014-04-30 chw - added description for borg alarm, borg speechrecognition, borg onintent, and borg query*
2014-05-12 chw - added <<Accelerometer>> sample code
2014-05-13 chw - added description for borg usbdevices and usbserial
2014-05-31 chw - added description for borg log, borg sensor, borg screenorientation, and borg notification
2014-06-21 chw - updated description of borg speechrecognition
2014-07-28 chw - updated description of borg keyboardinfo and <<KeyboardInfo>>