Move key event generation out of the UI realm into neutral space.

Abstracted keycode event array into keycode_array.[hc],
Moved key to keycode translation into charmap.c

Change-Id: I4de0c9853fa93d675895fc361e62ee36c1c0a652
diff --git a/android/charmap.c b/android/charmap.c
index 08c0901..af4163a 100644
--- a/android/charmap.c
+++ b/android/charmap.c
@@ -733,3 +733,90 @@
       qemu_free(android_charmaps);
   }
 }
+
+const AKeyCharmap*
+android_get_charmap_by_name(const char* name) {
+    int nn;
+
+    if (name != NULL) {
+        // Find charmap by its name in the array of available charmaps.
+        for (nn = 0; nn < android_charmap_count; nn++) {
+            if (!strcmp(android_charmaps[nn]->name, name)) {
+                return android_charmaps[nn];
+            }
+        }
+    }
+    return NULL;
+}
+
+const AKeyCharmap*
+android_get_charmap_by_index(unsigned int index) {
+    return index < android_charmap_count ? android_charmaps[index] : NULL;
+}
+
+int
+android_charmap_reverse_map_unicode(const AKeyCharmap* cmap,
+                                    unsigned int unicode,
+                                    int  down,
+                                    AKeycodeBuffer* keycodes)
+{
+    int                 n;
+
+    if (unicode == 0)
+        return 0;
+
+    /* check base keys */
+    for (n = 0; n < cmap->num_entries; n++) {
+        if (cmap->entries[n].base == unicode) {
+            android_keycodes_add_key_event(keycodes, cmap->entries[n].code, down);
+            return 1;
+        }
+    }
+
+    /* check caps + keys */
+    for (n = 0; n < cmap->num_entries; n++) {
+        if (cmap->entries[n].caps == unicode) {
+            if (down) {
+                android_keycodes_add_key_event(keycodes, kKeyCodeCapLeft, down);
+            }
+            android_keycodes_add_key_event(keycodes, cmap->entries[n].code, down);
+            if (!down) {
+                android_keycodes_add_key_event(keycodes, kKeyCodeCapLeft, down);
+            }
+            return 2;
+        }
+    }
+
+    /* check fn + keys */
+    for (n = 0; n < cmap->num_entries; n++) {
+        if (cmap->entries[n].fn == unicode) {
+            if (down) {
+                android_keycodes_add_key_event(keycodes, kKeyCodeAltLeft, down);
+            }
+            android_keycodes_add_key_event(keycodes, cmap->entries[n].code, down);
+            if (!down) {
+                android_keycodes_add_key_event(keycodes, kKeyCodeAltLeft, down);
+            }
+            return 2;
+        }
+    }
+
+    /* check caps + fn + keys */
+    for (n = 0; n < cmap->num_entries; n++) {
+        if (cmap->entries[n].caps_fn == unicode) {
+            if (down) {
+                android_keycodes_add_key_event(keycodes, kKeyCodeAltLeft, down);
+                android_keycodes_add_key_event(keycodes, kKeyCodeCapLeft, down);
+            }
+            android_keycodes_add_key_event(keycodes, cmap->entries[n].code, down);
+            if (!down) {
+                android_keycodes_add_key_event(keycodes, kKeyCodeCapLeft, down);
+                android_keycodes_add_key_event(keycodes, kKeyCodeAltLeft, down);
+            }
+            return 3;
+        }
+    }
+
+    /* no match */
+    return 0;
+}
diff --git a/android/charmap.h b/android/charmap.h
index 3d34224..08b059d 100644
--- a/android/charmap.h
+++ b/android/charmap.h
@@ -13,6 +13,7 @@
 #define _android_charmap_h
 
 #include "android/keycode.h"
+#include "android/keycode-array.h"
 
 /* this defines a structure used to describe an Android keyboard charmap */
 typedef struct AKeyEntry {
@@ -33,12 +34,6 @@
     char              name[ AKEYCHARMAP_NAME_SIZE ];
 } AKeyCharmap;
 
-/* Array of charmaps available in the current emulator session. */
-extern const AKeyCharmap**  android_charmaps;
-
-/* Number of entries in android_charmaps array. */
-extern int                  android_charmap_count;
-
 /* Extracts charmap name from .kcm file name.
  * Charmap name, extracted by this routine is a name of the kcm file, trimmed
  * of file name extension, and shrinked (if necessary) to fit into the name
@@ -72,4 +67,27 @@
 /* Cleanups initialization performed in android_charmap_setup routine. */
 void android_charmap_done(void);
 
+/* Gets charmap descriptor by its name.
+ * This routine finds and returns pointer to a descriptor in the array of
+ * charmaps that matches given name. If no such descriptor has been found, this
+ * routine returns NULL.
+ */
+const AKeyCharmap* android_get_charmap_by_name(const char* name);
+
+/* Gets charmap descriptor by its index in the array of charmaps.
+ * If index is greater than charmap array size, this routine returns NULL.
+ */
+const AKeyCharmap* android_get_charmap_by_index(unsigned int index);
+
+/* Maps given unicode key character into a keycode and adds mapped keycode into
+ * keycode array. This routine uses charmap passed as cmap parameter to do the
+ * translation, and 'down' parameter to generate appropriate ('down' or 'up')
+ * keycode.
+ */
+int
+android_charmap_reverse_map_unicode(const AKeyCharmap* cmap,
+                                    unsigned int unicode,
+                                    int  down,
+                                    AKeycodeBuffer* keycodes);
+
 #endif /* _android_charmap_h */
diff --git a/android/console.c b/android/console.c
index c6b8a4e..8dc8c98 100644
--- a/android/console.c
+++ b/android/console.c
@@ -46,8 +46,9 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include "android/hw-events.h"
-#include "android/skin/keyboard.h"
 #include "user-events.h"
+#include "android/keycode-array.h"
+#include "android/charmap.h"
 
 #if defined(CONFIG_SLIRP)
 #include "libslirp.h"
@@ -701,7 +702,7 @@
     netshaper_set_rate( slirp_shaper_out, qemu_net_upload_speed );
 
     if (android_modem) {
-        amodem_set_data_network_type( android_modem, 
+        amodem_set_data_network_type( android_modem,
                                     android_parse_network_type( args ) );
     }
     return 0;
@@ -1793,21 +1794,26 @@
 static int
 do_event_text( ControlClient  client, char*  args )
 {
-    SkinKeyboard*   keyboard;
+    AKeycodeBuffer keycodes;
     unsigned char*  p   = (unsigned char*) args;
     unsigned char*  end = p + strlen(args);
     int             textlen;
+    const AKeyCharmap* charmap;
 
     if (!args) {
         control_write( client, "KO: argument missing, try 'event text <message>'\r\n" );
         return -1;
     }
-    keyboard = android_emulator_get_keyboard();
-    if (keyboard == NULL) {
-        control_write( client, "KO: no keyboard active in current device layout/config\r\n" );
+
+    /* Get default charmap. */
+    charmap = android_get_charmap_by_index(0);
+    if (charmap == NULL) {
+        control_write( client, "KO: no character map active in current device layout/config\r\n" );
         return -1;
     }
 
+    keycodes.keycode_count = 0;
+
     /* un-secape message text into proper utf-8 (conversion happens in-site) */
     textlen = strlen((char*)p);
     textlen = sms_utf8_from_message_str( args, textlen, (unsigned char*)p, textlen );
@@ -1828,9 +1834,9 @@
         if (c <= 0)
             break;
 
-        skin_keyboard_process_unicode_event( keyboard, (unsigned)c, 1 );
-        skin_keyboard_process_unicode_event( keyboard, (unsigned)c, 0 );
-        skin_keyboard_flush( keyboard );
+        android_charmap_reverse_map_unicode( NULL, (unsigned)c, 1, &keycodes );
+        android_charmap_reverse_map_unicode( NULL, (unsigned)c, 0, &keycodes );
+        android_keycodes_flush( &keycodes );
     }
 
     return 0;
diff --git a/android/keycode-array.c b/android/keycode-array.c
new file mode 100644
index 0000000..cf7ec21
--- /dev/null
+++ b/android/keycode-array.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+
+#include <stdio.h>
+#include "android/utils/debug.h"
+#include "android/keycode-array.h"
+#include "user-events.h"
+
+void
+android_keycodes_add_key_event( AKeycodeBuffer* keycodes,
+                                unsigned       code,
+                                unsigned       down )
+{
+    if (code != 0 && keycodes->keycode_count < MAX_KEYCODES) {
+        keycodes->keycodes[(int)keycodes->keycode_count++] =
+                ( (code & 0x1ff) | (down ? 0x200 : 0) );
+    }
+}
+
+void
+android_keycodes_flush(AKeycodeBuffer* keycodes)
+{
+    if (keycodes->keycode_count > 0) {
+        if (VERBOSE_CHECK(keys)) {
+            int  nn;
+            printf(">> KEY" );
+            for (nn = 0; nn < keycodes->keycode_count; nn++) {
+                int  code = keycodes->keycodes[nn];
+                printf(" [0x%03x,%s]", (code & 0x1ff), (code & 0x200) ? "down" : " up " );
+            }
+            printf( "\n" );
+        }
+        user_event_keycodes(keycodes->keycodes, keycodes->keycode_count);
+        keycodes->keycode_count = 0;
+    }
+}
diff --git a/android/keycode-array.h b/android/keycode-array.h
new file mode 100644
index 0000000..5c97ad9
--- /dev/null
+++ b/android/keycode-array.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+#ifndef QEMU_ANDROID_KEYCODE_ARRAY_H
+#define QEMU_ANDROID_KEYCODE_ARRAY_H
+
+/* Contains declarations for routines that manage keycode sequence that needs
+ * to be transferred to the emulator core for further processing.
+ */
+
+/* Maximum number of keycodes kept in the array. */
+#define  MAX_KEYCODES   256*2
+
+/* Describes array of keycodes collected for transferring to the core. */
+typedef struct AKeycodeBuffer {
+    /* Number of keycodes collected in the array. */
+    int                 keycode_count;
+
+    /* Array of collected keycodes. */
+    int                 keycodes[ MAX_KEYCODES ];
+} AKeycodeBuffer;
+
+/* Adds a key event to the array of keycodes. */
+void
+android_keycodes_add_key_event( AKeycodeBuffer* keycodes,
+                                unsigned       code,
+                                unsigned       down );
+
+/* Flushes (transfers) collected keycodes to the core. */
+void
+android_keycodes_flush(AKeycodeBuffer* keycodes);
+
+#endif /* QEMU_ANDROID_KEYCODE_ARRAY_H */
diff --git a/android/qemulator.c b/android/qemulator.c
index 615f058..15cd668 100644
--- a/android/qemulator.c
+++ b/android/qemulator.c
@@ -15,7 +15,7 @@
 #include "android/utils/bufprint.h"
 #include "android/globals.h"
 #include "android/qemulator.h"
-#include "android/ui_core_protocol.h"
+#include "android/ui-core-protocol.h"
 
 #define  D(...)  do {  if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
 static double get_default_scale( AndroidOptions*  opts );
diff --git a/android/skin/keyboard.c b/android/skin/keyboard.c
index 00fa1df..8102e33 100644
--- a/android/skin/keyboard.c
+++ b/android/skin/keyboard.c
@@ -14,7 +14,8 @@
 #include "android/utils/bufprint.h"
 #include "android/utils/system.h"
 #include "android/android.h"
-#include "user-events.h"
+#include "android/keycode-array.h"
+#include "android/charmap.h"
 
 #define  DEBUG  1
 
@@ -37,7 +38,6 @@
 } LastKey;
 
 #define  MAX_LAST_KEYS  16
-#define  MAX_KEYCODES   256*2
 
 struct SkinKeyboard {
     const AKeyCharmap*  charmap;
@@ -45,7 +45,6 @@
     char                enabled;
     char                raw_keys;
     char                last_count;
-    int                 keycode_count;
 
     SkinRotation        rotation;
 
@@ -55,7 +54,8 @@
     void*               press_opaque;
 
     LastKey             last_keys[ MAX_LAST_KEYS ];
-    int                 keycodes[ MAX_KEYCODES ];
+
+    AKeycodeBuffer      keycodes;
 };
 
 
@@ -106,29 +106,14 @@
                              unsigned       code,
                              unsigned       down )
 {
-    if (code != 0 && kb->keycode_count < MAX_KEYCODES) {
-        //dprint("add keycode %d, down %d\n", code % 0x1ff, down );
-        kb->keycodes[(int)kb->keycode_count++] = ( (code & 0x1ff) | (down ? 0x200 : 0) );
-    }
+    android_keycodes_add_key_event(&kb->keycodes, code, down);
 }
 
 
 void
 skin_keyboard_flush( SkinKeyboard*  kb )
 {
-    if (kb->keycode_count > 0) {
-        if (VERBOSE_CHECK(keys)) {
-            int  nn;
-            printf(">> KEY" );
-            for (nn = 0; nn < kb->keycode_count; nn++) {
-                int  code = kb->keycodes[nn];
-                printf(" [0x%03x,%s]", (code & 0x1ff), (code & 0x200) ? "down" : " up " );
-            }
-            printf( "\n" );
-        }
-        user_event_keycodes(kb->keycodes, kb->keycode_count);
-        kb->keycode_count = 0;
-    }
+    android_keycodes_flush(&kb->keycodes);
 }
 
 
@@ -428,62 +413,8 @@
 int
 skin_keyboard_process_unicode_event( SkinKeyboard*  kb,  unsigned int  unicode, int  down )
 {
-    const AKeyCharmap*  cmap = kb->charmap;
-    int                 n;
-
-    if (unicode == 0)
-        return 0;
-
-    /* check base keys */
-    for (n = 0; n < cmap->num_entries; n++) {
-        if (cmap->entries[n].base == unicode) {
-            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
-            return 1;
-        }
-    }
-
-    /* check caps + keys */
-    for (n = 0; n < cmap->num_entries; n++) {
-        if (cmap->entries[n].caps == unicode) {
-            if (down)
-                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
-            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
-            if (!down)
-                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
-            return 2;
-        }
-    }
-
-    /* check fn + keys */
-    for (n = 0; n < cmap->num_entries; n++) {
-        if (cmap->entries[n].fn == unicode) {
-            if (down)
-                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
-            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
-            if (!down)
-                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
-            return 2;
-        }
-    }
-
-    /* check caps + fn + keys */
-    for (n = 0; n < cmap->num_entries; n++) {
-        if (cmap->entries[n].caps_fn == unicode) {
-            if (down) {
-                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
-                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
-            }
-            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
-            if (!down) {
-                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
-                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
-            }
-            return 3;
-        }
-    }
-
-    /* no match */
-    return 0;
+    return android_charmap_reverse_map_unicode(kb->charmap, unicode, down,
+                                               &kb->keycodes);
 }
 
 
@@ -584,23 +515,15 @@
                                        int  use_raw_keys)
 {
     SkinKeyboard*  kb;
-    int  nn;
 
     ANEW0(kb);
 
-    // Find charmap by its name in the array of available charmaps.
-    for (nn = 0; nn < android_charmap_count; nn++) {
-        if (!strcmp(android_charmaps[nn]->name, charmap_name)) {
-            kb->charmap = android_charmaps[nn];
-            break;
-        }
-    }
-
+    kb->charmap = android_get_charmap_by_name(charmap_name);
     if (!kb->charmap) {
         // Charmap name was not found. Default to the first charmap in the array.
+        kb->charmap = android_get_charmap_by_index(0);
         fprintf(stderr, "### warning, skin requires unknown '%s' charmap, reverting to '%s'\n",
-                charmap_name, android_charmaps[0]->name );
-        kb->charmap = android_charmaps[0];
+                charmap_name, kb->charmap->name );
     }
     kb->raw_keys = use_raw_keys;
     kb->enabled  = 0;
diff --git a/android/ui_core_protocol.c b/android/ui-core-protocol.c
similarity index 96%
rename from android/ui_core_protocol.c
rename to android/ui-core-protocol.c
index fec2f14..ec49b7e 100644
--- a/android/ui_core_protocol.c
+++ b/android/ui-core-protocol.c
@@ -20,7 +20,7 @@
  */
 
 #include "android/globals.h"
-#include "android/ui_core_protocol.h"
+#include "android/ui-core-protocol.h"
 
 int
 android_core_get_hw_lcd_density(void)
diff --git a/android/ui_core_protocol.h b/android/ui-core-protocol.h
similarity index 100%
rename from android/ui_core_protocol.h
rename to android/ui-core-protocol.h