OSDN Git Service

Remove terminal application.
authorJack Palevich <jackpal@google.com>
Sun, 2 Jan 2011 16:02:55 +0000 (08:02 -0800)
committerJack Palevich <jackpal@google.com>
Sun, 2 Jan 2011 16:02:55 +0000 (08:02 -0800)
It is being developed as an open source app here:

    https://github.com/jackpal/Android-Terminal-Emulator

And it can be installed from the Android Marketplace as:

    Android Terminal Emulator

Change-Id: Ie46d5f7e81d80cf8ef3f0b806a63227929fb1841

21 files changed:
apps/Term/Android.mk [deleted file]
apps/Term/AndroidManifest.xml [deleted file]
apps/Term/MODULE_LICENSE_APACHE2 [deleted file]
apps/Term/NOTICE [deleted file]
apps/Term/jni/Android.mk [deleted file]
apps/Term/jni/termExec.cpp [deleted file]
apps/Term/res/drawable-hdpi/app_terminal.png [deleted file]
apps/Term/res/drawable-hdpi/atari_small.png [deleted file]
apps/Term/res/drawable-mdpi/app_terminal.png [deleted file]
apps/Term/res/drawable-mdpi/atari_small.png [deleted file]
apps/Term/res/drawable/atari_small_notice.txt [deleted file]
apps/Term/res/layout/term_activity.xml [deleted file]
apps/Term/res/menu/main.xml [deleted file]
apps/Term/res/values/arrays.xml [deleted file]
apps/Term/res/values/attrs.xml [deleted file]
apps/Term/res/values/strings.xml [deleted file]
apps/Term/res/values/styles.xml [deleted file]
apps/Term/res/xml/preferences.xml [deleted file]
apps/Term/src/com/android/term/Exec.java [deleted file]
apps/Term/src/com/android/term/Term.java [deleted file]
apps/Term/src/com/android/term/TermPreferences.java [deleted file]

diff --git a/apps/Term/Android.mk b/apps/Term/Android.mk
deleted file mode 100644 (file)
index 9ff6c0d..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# This makefile shows how to build a shared library and an activity that
-# bundles the shared library and calls it using JNI.
-
-TOP_LOCAL_PATH:= $(call my-dir)
-
-# Build activity
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := eng
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := Term
-
-LOCAL_JNI_SHARED_LIBRARIES := libterm
-
-include $(BUILD_PACKAGE)
-
-# ============================================================
-
-# Also build all of the sub-targets under this one: the shared library.
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/apps/Term/AndroidManifest.xml b/apps/Term/AndroidManifest.xml
deleted file mode 100644 (file)
index 7084d2c..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.term">
-    <application android:icon="@drawable/app_terminal"
-                android:label="@string/application_terminal">
-        <activity android:name="Term"
-                android:theme="@style/Theme"
-                android:launchMode="singleInstance"
-                android:configChanges="keyboard|keyboardHidden|orientation"
-                android:windowSoftInputMode="adjustResize|stateVisible">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.TEST" />
-            </intent-filter>
-        </activity>
-        <activity android:name="TermPreferences"/>
-    </application>
-</manifest> 
diff --git a/apps/Term/MODULE_LICENSE_APACHE2 b/apps/Term/MODULE_LICENSE_APACHE2
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/apps/Term/NOTICE b/apps/Term/NOTICE
deleted file mode 100644 (file)
index c5b1efa..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/apps/Term/jni/Android.mk b/apps/Term/jni/Android.mk
deleted file mode 100644 (file)
index 2fe4a75..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# This makefile supplies the rules for building a library of JNI code for
-# use by our example of how to bundle a shared library with an APK.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := eng
-
-# This is the target being built.
-LOCAL_MODULE:= libterm
-
-
-# All of the source files that we will compile.
-LOCAL_SRC_FILES:= \
-  termExec.cpp
-
-# All of the shared libraries we link against.
-LOCAL_SHARED_LIBRARIES := \
-       libutils
-
-# No static libraries.
-LOCAL_STATIC_LIBRARIES :=
-
-# Also need the JNI headers.
-LOCAL_C_INCLUDES += \
-       $(JNI_H_INCLUDE)
-
-# No special compiler flags.
-LOCAL_CFLAGS +=
-
-# Don't prelink this library.  For more efficient code, you may want
-# to add this library to the prelink map and set this to true. However,
-# it's difficult to do this for applications that are not supplied as
-# part of a system image.
-
-LOCAL_PRELINK_MODULE := false
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/Term/jni/termExec.cpp b/apps/Term/jni/termExec.cpp
deleted file mode 100644 (file)
index a1edc95..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Exec"
-
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-#include "android_runtime/AndroidRuntime.h"
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <termios.h>
-
-static jclass class_fileDescriptor;
-static jfieldID field_fileDescriptor_descriptor;
-static jmethodID method_fileDescriptor_init;
-
-
-class String8 {
-public:
-    String8() {
-        mString = 0;
-    }
-    
-    ~String8() {
-        if (mString) {
-            free(mString);
-        }
-    }
-
-    void set(const char16_t* o, size_t numChars) {
-        if (mString) {
-            free(mString);
-        }
-        mString = (char*) malloc(numChars + 1);
-        for (size_t i = 0; i < numChars; i++) {
-            mString[i] = (char) o[i];
-        }
-        mString[numChars] = '\0';
-    }
-    
-    const char* string() {
-        return mString;
-    }
-private:
-    char* mString;
-};
-
-static int create_subprocess(const char *cmd, const char *arg0, const char *arg1,
-    int* pProcessId)
-{
-    char *devname;
-    int ptm;
-    pid_t pid;
-
-    ptm = open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
-    if(ptm < 0){
-        LOGE("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
-        return -1;
-    }
-    fcntl(ptm, F_SETFD, FD_CLOEXEC);
-
-    if(grantpt(ptm) || unlockpt(ptm) ||
-       ((devname = (char*) ptsname(ptm)) == 0)){
-        LOGE("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
-        return -1;
-    }
-    
-    pid = fork();
-    if(pid < 0) {
-        LOGE("- fork failed: %s -\n", strerror(errno));
-        return -1;
-    }
-
-    if(pid == 0){
-        close(ptm);
-
-        int pts;
-
-        setsid();
-        
-        pts = open(devname, O_RDWR);
-        if(pts < 0) exit(-1);
-
-        dup2(pts, 0);
-        dup2(pts, 1);
-        dup2(pts, 2);
-
-        execl(cmd, cmd, arg0, arg1, NULL);
-        exit(-1);
-    } else {
-        *pProcessId = (int) pid;
-        return ptm;
-    }
-}
-
-
-static jobject android_os_Exec_createSubProcess(JNIEnv *env, jobject clazz,
-    jstring cmd, jstring arg0, jstring arg1, jintArray processIdArray)
-{
-    const jchar* str = cmd ? env->GetStringCritical(cmd, 0) : 0;
-    String8 cmd_8;
-    if (str) {
-        cmd_8.set(str, env->GetStringLength(cmd));
-        env->ReleaseStringCritical(cmd, str);
-    }
-
-    str = arg0 ? env->GetStringCritical(arg0, 0) : 0;
-    const char* arg0Str = 0;
-    String8 arg0_8;
-    if (str) {
-        arg0_8.set(str, env->GetStringLength(arg0));
-        env->ReleaseStringCritical(arg0, str);
-        arg0Str = arg0_8.string();
-    }
-
-    str = arg1 ? env->GetStringCritical(arg1, 0) : 0;
-    const char* arg1Str = 0;
-    String8 arg1_8;
-    if (str) {
-        arg1_8.set(str, env->GetStringLength(arg1));
-        env->ReleaseStringCritical(arg1, str);
-        arg1Str = arg1_8.string();
-    }
-
-    int procId;
-    int ptm = create_subprocess(cmd_8.string(), arg0Str, arg1Str, &procId);
-    
-    if (processIdArray) {
-        int procIdLen = env->GetArrayLength(processIdArray);
-        if (procIdLen > 0) {
-            jboolean isCopy;
-    
-            int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
-            if (pProcId) {
-                *pProcId = procId;
-                env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
-            }
-        }
-    }
-    
-    jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);
-    
-    if (!result) {
-        LOGE("Couldn't create a FileDescriptor.");
-    }
-    else {
-        env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
-    }
-    
-    return result;
-}
-
-
-static void android_os_Exec_setPtyWindowSize(JNIEnv *env, jobject clazz,
-    jobject fileDescriptor, jint row, jint col, jint xpixel, jint ypixel)
-{
-    int fd;
-    struct winsize sz;
-
-    fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
-
-    if (env->ExceptionOccurred() != NULL) {
-        return;
-    }
-    
-    sz.ws_row = row;
-    sz.ws_col = col;
-    sz.ws_xpixel = xpixel;
-    sz.ws_ypixel = ypixel;
-    
-    ioctl(fd, TIOCSWINSZ, &sz);
-}
-
-static int android_os_Exec_waitFor(JNIEnv *env, jobject clazz,
-    jint procId) {
-    int status;
-    waitpid(procId, &status, 0);
-    int result = 0;
-    if (WIFEXITED(status)) {
-        result = WEXITSTATUS(status);
-    }
-    return result;
-}
-
-static void android_os_Exec_close(JNIEnv *env, jobject clazz, jobject fileDescriptor)
-{
-    int fd;
-    struct winsize sz;
-
-    fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
-
-    if (env->ExceptionOccurred() != NULL) {
-        return;
-    }
-    
-    close(fd);
-}
-
-
-static int register_FileDescriptor(JNIEnv *env)
-{
-    class_fileDescriptor = env->FindClass("java/io/FileDescriptor");
-
-    if (class_fileDescriptor == NULL) {
-        LOGE("Can't find java/io/FileDescriptor");
-        return -1;
-    }
-
-    field_fileDescriptor_descriptor = env->GetFieldID(class_fileDescriptor, "descriptor", "I");
-
-    if (field_fileDescriptor_descriptor == NULL) {
-        LOGE("Can't find FileDescriptor.descriptor");
-        return -1;
-    }
-
-    method_fileDescriptor_init = env->GetMethodID(class_fileDescriptor, "<init>", "()V");
-    if (method_fileDescriptor_init == NULL) {
-        LOGE("Can't find FileDescriptor.init");
-        return -1;
-     }
-     return 0;
-}
-
-
-static const char *classPathName = "com/android/term/Exec";
-
-static JNINativeMethod method_table[] = {
-    { "createSubprocess", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I)Ljava/io/FileDescriptor;",
-        (void*) android_os_Exec_createSubProcess },
-    { "setPtyWindowSize", "(Ljava/io/FileDescriptor;IIII)V",
-        (void*) android_os_Exec_setPtyWindowSize},
-    { "waitFor", "(I)I",
-        (void*) android_os_Exec_waitFor},
-    { "close", "(Ljava/io/FileDescriptor;)V",
-        (void*) android_os_Exec_close}
-};
-
-/*
- * Register several native methods for one class.
- */
-static int registerNativeMethods(JNIEnv* env, const char* className,
-    JNINativeMethod* gMethods, int numMethods)
-{
-    jclass clazz;
-
-    clazz = env->FindClass(className);
-    if (clazz == NULL) {
-        LOGE("Native registration unable to find class '%s'", className);
-        return JNI_FALSE;
-    }
-    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
-        LOGE("RegisterNatives failed for '%s'", className);
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-}
-
-/*
- * Register native methods for all classes we know about.
- *
- * returns JNI_TRUE on success.
- */
-static int registerNatives(JNIEnv* env)
-{
-  if (!registerNativeMethods(env, classPathName, method_table, 
-                 sizeof(method_table) / sizeof(method_table[0]))) {
-    return JNI_FALSE;
-  }
-
-  return JNI_TRUE;
-}
-
-
-// ----------------------------------------------------------------------------
-
-/*
- * This is called by the VM when the shared library is first loaded.
- */
-typedef union {
-    JNIEnv* env;
-    void* venv;
-} UnionJNIEnvToVoid;
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved) {
-    UnionJNIEnvToVoid uenv;
-    uenv.venv = NULL;
-    jint result = -1;
-    JNIEnv* env = NULL;
-    
-    LOGI("JNI_OnLoad");
-
-    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
-        LOGE("ERROR: GetEnv failed");
-        goto bail;
-    }
-    env = uenv.env;
-    
-    if ((result = register_FileDescriptor(env)) < 0) {
-        LOGE("ERROR: registerFileDescriptor failed");
-        goto bail;
-    }
-
-    if (registerNatives(env) != JNI_TRUE) {
-        LOGE("ERROR: registerNatives failed");
-        goto bail;
-    }
-    
-    result = JNI_VERSION_1_4;
-    
-bail:
-    return result;
-}
diff --git a/apps/Term/res/drawable-hdpi/app_terminal.png b/apps/Term/res/drawable-hdpi/app_terminal.png
deleted file mode 100755 (executable)
index 278b2a5..0000000
Binary files a/apps/Term/res/drawable-hdpi/app_terminal.png and /dev/null differ
diff --git a/apps/Term/res/drawable-hdpi/atari_small.png b/apps/Term/res/drawable-hdpi/atari_small.png
deleted file mode 100755 (executable)
index 8bdd624..0000000
Binary files a/apps/Term/res/drawable-hdpi/atari_small.png and /dev/null differ
diff --git a/apps/Term/res/drawable-mdpi/app_terminal.png b/apps/Term/res/drawable-mdpi/app_terminal.png
deleted file mode 100644 (file)
index 1ec3b4b..0000000
Binary files a/apps/Term/res/drawable-mdpi/app_terminal.png and /dev/null differ
diff --git a/apps/Term/res/drawable-mdpi/atari_small.png b/apps/Term/res/drawable-mdpi/atari_small.png
deleted file mode 100644 (file)
index 535e295..0000000
Binary files a/apps/Term/res/drawable-mdpi/atari_small.png and /dev/null differ
diff --git a/apps/Term/res/drawable/atari_small_notice.txt b/apps/Term/res/drawable/atari_small_notice.txt
deleted file mode 100644 (file)
index afa8539..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-COMMENT  Copyright (c) 1999, Thomas A. Fine
-COMMENT
-COMMENT  License to copy, modify, and distribute for both commercial and
-COMMENT  non-commercial use is herby granted, provided this notice
-COMMENT  is preserved.
-COMMENT
-COMMENT  Email to my last name at head.cfa.harvard.edu
-COMMENT  http://hea-www.harvard.edu/~fine/
-COMMENT
-COMMENT  Produced with bdfedit, a tcl/tk font editing program
-COMMENT  written by Thomas A. Fine
\ No newline at end of file
diff --git a/apps/Term/res/layout/term_activity.xml b/apps/Term/res/layout/term_activity.xml
deleted file mode 100644 (file)
index 6ce7719..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent" 
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <com.android.term.EmulatorView android:id="@+id/emulatorView"
-             android:layout_width="wrap_content"
-             android:layout_height="wrap_content"
-             android:layout_alignParentLeft="true"
-             />
-   
-</LinearLayout>
diff --git a/apps/Term/res/menu/main.xml b/apps/Term/res/menu/main.xml
deleted file mode 100644 (file)
index 5f6e9d8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_preferences"
-       android:title="@string/preferences" />
-    <item android:id="@+id/menu_reset"
-       android:title="@string/reset" />
-    <item android:id="@+id/menu_send_email"
-       android:title="@string/send_email" />
-    <item android:id="@+id/menu_special_keys"
-       android:title="@string/special_keys" />
-</menu>
diff --git a/apps/Term/res/values/arrays.xml b/apps/Term/res/values/arrays.xml
deleted file mode 100644 (file)
index b4857a2..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<resources>
-    <string-array name="entries_fontsize_preference">
-        <item>4 x 8 pixels</item>
-        <item>6 pt</item>
-        <item>7 pt</item>
-        <item>8 pt</item>
-        <item>9 pt</item>
-        <item>10 pt</item>
-        <item>12 pt</item>
-        <item>14 pt</item>
-        <item>16 pt</item>
-        <item>20 pt</item>
-    </string-array>
-
-       <!-- Do not localize entryvalues -->
-    <string-array name="entryvalues_fontsize_preference">
-        <item>0</item>
-        <item>6</item>
-        <item>7</item>
-        <item>8</item>
-        <item>9</item>
-        <item>10</item>
-        <item>12</item>
-        <item>14</item>
-        <item>16</item>
-        <item>20</item>  
-    </string-array>
-
-    <string-array name="entries_color_preference">
-        <item>Black text on white</item>
-        <item>White text on black</item>
-        <item>White text on blue</item>  
-    </string-array>
-
-       <!-- Do not localize entryvalues -->
-    <string-array name="entryvalues_color_preference">
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>  
-    </string-array>
-    
-    <string-array name="entries_controlkey_preference">
-        <item>Jog ball</item>
-        <item>\@ key</item>
-        <item>Left Alt key</item>
-        <item>Right Alt key</item>
-    </string-array>
-
-       <!-- Do not localize entryvalues -->
-    <string-array name="entryvalues_controlkey_preference">
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-        <item>3</item>
-    </string-array>
-</resources>
diff --git a/apps/Term/res/values/attrs.xml b/apps/Term/res/values/attrs.xml
deleted file mode 100644 (file)
index 3787d7e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<resources>
-     <declare-styleable name="EmulatorView">
-    </declare-styleable>
-</resources>
diff --git a/apps/Term/res/values/strings.xml b/apps/Term/res/values/strings.xml
deleted file mode 100644 (file)
index b5d622b..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
--->
-<resources>
-   <string name="application_terminal">Terminal Emulator</string>
-   <string name="preferences">Preferences</string>
-   <string name="reset">Reset term</string>
-   <string name="send_email">Email to</string>
-   <string name="special_keys">Special keys</string>
-
-   <!-- Preference dialog -->
-   <string name="text_preferences">Text</string>
-
-   <string name="title_fontsize_preference">Font size</string>
-   <string name="summary_fontsize_preference">Choose character height in points.</string>
-   <string name="dialog_title_fontsize_preference">Font size</string>
-
-   <string name="title_color_preference">Colors</string>
-   <string name="summary_color_preference">Choose text color.</string>
-   <string name="dialog_title_color_preference">Text color</string>
-
-   <string name="keyboard_preferences">Keyboard</string>
-   <string name="title_controlkey_preference">Control key</string>
-   <string name="summary_controlkey_preference">Choose control key.</string>
-   <string name="dialog_title_controlkey_preference">Control key</string>
-
-   <string name="shell_preferences">Shell</string>
-   <string name="title_shell_preference">Command line</string>
-   <string name="summary_shell_preference">Specify the shell command line.</string>
-   <string name="dialog_title_shell_preference">Shell</string>
-
-   <string name="title_initialcommand_preference">Initial command</string>
-   <string name="summary_initialcommand_preference">Sent to the shell when it starts.</string>
-   <string name="dialog_title_initialcommand_preference">Initial Command</string>
-
-   <!-- Don't localize these default values -->
-   <string name="default_value_fontsize_preference">10</string>
-   <string name="default_value_color_preference">2</string>
-   <string name="default_value_controlkey_preference">0</string>
-   <string name="default_value_shell_preference">/system/bin/sh -</string>
-   <string name="default_value_initialcommand_preference">export PATH=/data/local/bin:$PATH</string>
-</resources>
diff --git a/apps/Term/res/values/styles.xml b/apps/Term/res/values/styles.xml
deleted file mode 100644 (file)
index 0e59f4a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <style name="Theme" parent="@android:style/Theme.Light">
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowFrame">@null</item>
-    </style>
-</resources>
-
diff --git a/apps/Term/res/xml/preferences.xml b/apps/Term/res/xml/preferences.xml
deleted file mode 100644 (file)
index 7792153..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen
-        xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <PreferenceCategory
-            android:title="@string/text_preferences">
-
-        <ListPreference
-                android:key="fontsize"
-                android:defaultValue="@string/default_value_fontsize_preference"
-                android:title="@string/title_fontsize_preference"
-                android:summary="@string/summary_fontsize_preference"
-                android:entries="@array/entries_fontsize_preference"
-                android:entryValues="@array/entryvalues_fontsize_preference"
-                android:dialogTitle="@string/dialog_title_fontsize_preference" />
-
-        <ListPreference
-                android:key="color"
-                android:defaultValue="@string/default_value_color_preference"
-                android:title="@string/title_color_preference"
-                android:summary="@string/summary_color_preference"
-                android:entries="@array/entries_color_preference"
-                android:entryValues="@array/entryvalues_color_preference"
-                android:dialogTitle="@string/dialog_title_color_preference" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-            android:title="@string/keyboard_preferences">
-
-        <ListPreference
-                android:key="controlkey"
-                android:defaultValue="@string/default_value_controlkey_preference"
-                android:title="@string/title_controlkey_preference"
-                android:summary="@string/summary_controlkey_preference"
-                android:entries="@array/entries_controlkey_preference"
-                android:entryValues="@array/entryvalues_controlkey_preference"
-                android:dialogTitle="@string/dialog_title_controlkey_preference" />
-
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:title="@string/shell_preferences">
-
-    <EditTextPreference
-            android:key="shell"
-            android:defaultValue="@string/default_value_shell_preference"
-            android:title="@string/title_shell_preference"
-            android:summary="@string/summary_shell_preference"
-            android:dialogTitle="@string/dialog_title_shell_preference" />
-    <EditTextPreference
-            android:key="initialcommand"
-            android:defaultValue="@string/default_value_initialcommand_preference"
-            android:title="@string/title_initialcommand_preference"
-            android:summary="@string/summary_initialcommand_preference"
-            android:dialogTitle="@string/dialog_title_initialcommand_preference" />
-    </PreferenceCategory>
-</PreferenceScreen>
diff --git a/apps/Term/src/com/android/term/Exec.java b/apps/Term/src/com/android/term/Exec.java
deleted file mode 100644 (file)
index b53acfc..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.term;
-
-import java.io.FileDescriptor;
-
-/**
- * Utility methods for creating and managing a subprocess.
- * <p>
- * Note: The native methods access a package-private
- * java.io.FileDescriptor field to get and set the raw Linux
- * file descriptor. This might break if the implementation of
- * java.io.FileDescriptor is changed.
- */
-
-public class Exec
-{
-    static {
-        System.loadLibrary("term");
-    }
-
-    /**
-     * Create a subprocess. Differs from java.lang.ProcessBuilder in
-     * that a pty is used to communicate with the subprocess.
-     * <p>
-     * Callers are responsible for calling Exec.close() on the returned
-     * file descriptor.
-     *
-     * @param cmd The command to execute
-     * @param arg0 The first argument to the command, may be null
-     * @param arg1 the second argument to the command, may be null
-     * @param processId A one-element array to which the process ID of the
-     * started process will be written.
-     * @return the file descriptor of the started process.
-     *
-     */
-    public static native FileDescriptor createSubprocess(
-        String cmd, String arg0, String arg1, int[] processId);
-        
-    /**
-     * Set the widow size for a given pty. Allows programs
-     * connected to the pty learn how large their screen is.
-     */
-    public static native void setPtyWindowSize(FileDescriptor fd,
-       int row, int col, int xpixel, int ypixel);
-
-    /**
-     * Causes the calling thread to wait for the process associated with the
-     * receiver to finish executing.
-     *
-     * @return The exit value of the Process being waited on
-     *
-     */
-    public static native int waitFor(int processId);
-
-    /**
-     * Close a given file descriptor.
-     */
-    public static native void close(FileDescriptor fd);
-}
-
diff --git a/apps/Term/src/com/android/term/Term.java b/apps/Term/src/com/android/term/Term.java
deleted file mode 100644 (file)
index 6d3796a..0000000
+++ /dev/null
@@ -1,3274 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.term;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.preference.PreferenceManager;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.inputmethod.BaseInputConnection;
-import android.view.inputmethod.CompletionInfo;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.ExtractedText;
-import android.view.inputmethod.ExtractedTextRequest;
-import android.view.inputmethod.InputConnection;
-
-/**
- * A terminal emulator activity.
- */
-
-public class Term extends Activity {
-    /**
-     * Set to true to add debugging code and logging.
-     */
-    public static final boolean DEBUG = false;
-
-    /**
-     * Set to true to log each character received from the remote process to the
-     * android log, which makes it easier to debug some kinds of problems with
-     * emulating escape sequences and control codes.
-     */
-    public static final boolean LOG_CHARACTERS_FLAG = DEBUG && false;
-
-    /**
-     * Set to true to log unknown escape sequences.
-     */
-    public static final boolean LOG_UNKNOWN_ESCAPE_SEQUENCES = DEBUG && false;
-
-    /**
-     * The tag we use when logging, so that our messages can be distinguished
-     * from other messages in the log. Public because it's used by several
-     * classes.
-     */
-    public static final String LOG_TAG = "Term";
-
-    /**
-     * Our main view. Displays the emulated terminal screen.
-     */
-    private EmulatorView mEmulatorView;
-
-    /**
-     * The pseudo-teletype (pty) file descriptor that we use to communicate with
-     * another process, typically a shell.
-     */
-    private FileDescriptor mTermFd;
-
-    /**
-     * Used to send data to the remote process.
-     */
-    private FileOutputStream mTermOut;
-
-    /**
-     * A key listener that tracks the modifier keys and allows the full ASCII
-     * character set to be entered.
-     */
-    private TermKeyListener mKeyListener;
-
-    /**
-     * The name of our emulator view in the view resource.
-     */
-    private static final int EMULATOR_VIEW = R.id.emulatorView;
-
-    private int mFontSize = 9;
-    private int mColorId = 2;
-    private int mControlKeyId = 0;
-
-    private static final String FONTSIZE_KEY = "fontsize";
-    private static final String COLOR_KEY = "color";
-    private static final String CONTROLKEY_KEY = "controlkey";
-    private static final String SHELL_KEY = "shell";
-    private static final String INITIALCOMMAND_KEY = "initialcommand";
-
-    public static final int WHITE = 0xffffffff;
-    public static final int BLACK = 0xff000000;
-    public static final int BLUE = 0xff344ebd;
-
-    private static final int[][] COLOR_SCHEMES = {
-        {BLACK, WHITE}, {WHITE, BLACK}, {WHITE, BLUE}};
-
-    private static final int[] CONTROL_KEY_SCHEMES = {
-        KeyEvent.KEYCODE_DPAD_CENTER,
-        KeyEvent.KEYCODE_AT,
-        KeyEvent.KEYCODE_ALT_LEFT,
-        KeyEvent.KEYCODE_ALT_RIGHT
-    };
-    private static final String[] CONTROL_KEY_NAME = {
-        "Ball", "@", "Left-Alt", "Right-Alt"
-    };
-
-    private int mControlKeyCode;
-
-    private final static String DEFAULT_SHELL = "/system/bin/sh -";
-    private String mShell;
-
-    private final static String DEFAULT_INITIAL_COMMAND =
-        "export PATH=/data/local/bin:$PATH";
-    private String mInitialCommand;
-
-    private SharedPreferences mPrefs;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        Log.e(Term.LOG_TAG, "onCreate");
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-        readPrefs();
-
-        setContentView(R.layout.term_activity);
-
-        mEmulatorView = (EmulatorView) findViewById(EMULATOR_VIEW);
-
-        startListening();
-
-        mKeyListener = new TermKeyListener();
-
-        mEmulatorView.setFocusable(true);
-        mEmulatorView.setFocusableInTouchMode(true);
-        mEmulatorView.requestFocus();
-        mEmulatorView.register(mKeyListener);
-
-        updatePrefs();
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (mTermFd != null) {
-            Exec.close(mTermFd);
-            mTermFd = null;
-        }
-    }
-
-    private void startListening() {
-        int[] processId = new int[1];
-
-        createSubprocess(processId);
-        final int procId = processId[0];
-
-        final Handler handler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-            }
-        };
-
-        Runnable watchForDeath = new Runnable() {
-
-            public void run() {
-                Log.i(Term.LOG_TAG, "waiting for: " + procId);
-               int result = Exec.waitFor(procId);
-                Log.i(Term.LOG_TAG, "Subprocess exited: " + result);
-                handler.sendEmptyMessage(result);
-             }
-
-        };
-        Thread watcher = new Thread(watchForDeath);
-        watcher.start();
-
-        mTermOut = new FileOutputStream(mTermFd);
-
-        mEmulatorView.initialize(mTermFd, mTermOut);
-
-        sendInitialCommand();
-    }
-
-    private void sendInitialCommand() {
-        String initialCommand = mInitialCommand;
-        if (initialCommand == null || initialCommand.equals("")) {
-            initialCommand = DEFAULT_INITIAL_COMMAND;
-        }
-        if (initialCommand.length() > 0) {
-            write(initialCommand + '\r');
-        }
-    }
-
-    private void restart() {
-        startActivity(getIntent());
-        finish();
-    }
-
-    private void write(String data) {
-        try {
-            mTermOut.write(data.getBytes());
-            mTermOut.flush();
-        } catch (IOException e) {
-            // Ignore exception
-            // We don't really care if the receiver isn't listening.
-            // We just make a best effort to answer the query.
-        }
-    }
-
-    private void createSubprocess(int[] processId) {
-        String shell = mShell;
-        if (shell == null || shell.equals("")) {
-            shell = DEFAULT_SHELL;
-        }
-        ArrayList<String> args = parse(shell);
-        String arg0 = args.get(0);
-        String arg1 = null;
-        String arg2 = null;
-        if (args.size() >= 2) {
-            arg1 = args.get(1);
-        }
-        if (args.size() >= 3) {
-            arg2 = args.get(2);
-        }
-        mTermFd = Exec.createSubprocess(arg0, arg1, arg2, processId);
-    }
-
-    private ArrayList<String> parse(String cmd) {
-        final int PLAIN = 0;
-        final int WHITESPACE = 1;
-        final int INQUOTE = 2;
-        int state = WHITESPACE;
-        ArrayList<String> result =  new ArrayList<String>();
-        int cmdLen = cmd.length();
-        StringBuilder builder = new StringBuilder();
-        for (int i = 0; i < cmdLen; i++) {
-            char c = cmd.charAt(i);
-            if (state == PLAIN) {
-                if (Character.isWhitespace(c)) {
-                    result.add(builder.toString());
-                    builder.delete(0,builder.length());
-                    state = WHITESPACE;
-                } else if (c == '"') {
-                    state = INQUOTE;
-                } else {
-                    builder.append(c);
-                }
-            } else if (state == WHITESPACE) {
-                if (Character.isWhitespace(c)) {
-                    // do nothing
-                } else if (c == '"') {
-                    state = INQUOTE;
-                } else {
-                    state = PLAIN;
-                    builder.append(c);
-                }
-            } else if (state == INQUOTE) {
-                if (c == '\\') {
-                    if (i + 1 < cmdLen) {
-                        i += 1;
-                        builder.append(cmd.charAt(i));
-                    }
-                } else if (c == '"') {
-                    state = PLAIN;
-                } else {
-                    builder.append(c);
-                }
-            }
-        }
-        if (builder.length() > 0) {
-            result.add(builder.toString());
-        }
-        return result;
-    }
-
-    private void readPrefs() {
-        mFontSize = readIntPref(FONTSIZE_KEY, mFontSize, 20);
-        mColorId = readIntPref(COLOR_KEY, mColorId, COLOR_SCHEMES.length - 1);
-        mControlKeyId = readIntPref(CONTROLKEY_KEY, mControlKeyId,
-                CONTROL_KEY_SCHEMES.length - 1);
-        {
-            String newShell = readStringPref(SHELL_KEY, mShell);
-            if ((newShell == null) || ! newShell.equals(mShell)) {
-                if (mShell != null) {
-                    Log.i(Term.LOG_TAG, "New shell set. Restarting.");
-                    restart();
-                }
-                mShell = newShell;
-            }
-        }
-        {
-            String newInitialCommand = readStringPref(INITIALCOMMAND_KEY,
-                    mInitialCommand);
-            if ((newInitialCommand == null)
-                    || ! newInitialCommand.equals(mInitialCommand)) {
-                if (mInitialCommand != null) {
-                    Log.i(Term.LOG_TAG, "New initial command set. Restarting.");
-                    restart();
-                }
-                mInitialCommand = newInitialCommand;
-            }
-        }
-    }
-
-    private void updatePrefs() {
-        DisplayMetrics metrics = new DisplayMetrics();
-        getWindowManager().getDefaultDisplay().getMetrics(metrics);
-        mEmulatorView.setTextSize((int) (mFontSize * metrics.density));
-        setColors();
-        mControlKeyCode = CONTROL_KEY_SCHEMES[mControlKeyId];
-    }
-
-    private int readIntPref(String key, int defaultValue, int maxValue) {
-        int val;
-        try {
-            val = Integer.parseInt(
-                mPrefs.getString(key, Integer.toString(defaultValue)));
-        } catch (NumberFormatException e) {
-            val = defaultValue;
-        }
-        val = Math.max(0, Math.min(val, maxValue));
-        return val;
-    }
-
-    private String readStringPref(String key, String defaultValue) {
-        return mPrefs.getString(key, defaultValue);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        readPrefs();
-        updatePrefs();
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        mEmulatorView.updateSize();
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (handleControlKey(keyCode, true)) {
-            return true;
-        } else if (isSystemKey(keyCode, event)) {
-            // Don't intercept the system keys
-            return super.onKeyDown(keyCode, event);
-        } else if (handleDPad(keyCode, true)) {
-            return true;
-        }
-
-        // Translate the keyCode into an ASCII character.
-        int letter = mKeyListener.keyDown(keyCode, event);
-
-        if (letter >= 0) {
-            try {
-                mTermOut.write(letter);
-            } catch (IOException e) {
-                // Ignore I/O exceptions
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (handleControlKey(keyCode, false)) {
-            return true;
-        } else if (isSystemKey(keyCode, event)) {
-            // Don't intercept the system keys
-            return super.onKeyUp(keyCode, event);
-        } else if (handleDPad(keyCode, false)) {
-            return true;
-        }
-
-        mKeyListener.keyUp(keyCode);
-        return true;
-    }
-
-    private boolean handleControlKey(int keyCode, boolean down) {
-        if (keyCode == mControlKeyCode) {
-            mKeyListener.handleControlKey(down);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Handle dpad left-right-up-down events. Don't handle
-     * dpad-center, that's our control key.
-     * @param keyCode
-     * @param down
-     */
-    private boolean handleDPad(int keyCode, boolean down) {
-        if (keyCode < KeyEvent.KEYCODE_DPAD_UP ||
-                keyCode > KeyEvent.KEYCODE_DPAD_CENTER) {
-            return false;
-        }
-
-        if (down) {
-            try {
-                if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
-                    mTermOut.write('\r');
-                } else {
-                    char code;
-                    switch (keyCode) {
-                    case KeyEvent.KEYCODE_DPAD_UP:
-                        code = 'A';
-                        break;
-                    case KeyEvent.KEYCODE_DPAD_DOWN:
-                        code = 'B';
-                        break;
-                    case KeyEvent.KEYCODE_DPAD_LEFT:
-                        code = 'D';
-                        break;
-                    default:
-                    case KeyEvent.KEYCODE_DPAD_RIGHT:
-                        code = 'C';
-                        break;
-                    }
-                    mTermOut.write(27); // ESC
-                    if (mEmulatorView.getKeypadApplicationMode()) {
-                        mTermOut.write('O');
-                    } else {
-                        mTermOut.write('[');
-                    }
-                    mTermOut.write(code);
-                }
-            } catch (IOException e) {
-                // Ignore
-            }
-        }
-        return true;
-    }
-
-    private boolean isSystemKey(int keyCode, KeyEvent event) {
-        return event.isSystem();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.main, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        int id = item.getItemId();
-        if (id == R.id.menu_preferences) {
-            doPreferences();
-        } else if (id == R.id.menu_reset) {
-            doResetTerminal();
-        } else if (id == R.id.menu_send_email) {
-            doEmailTranscript();
-        } else if (id == R.id.menu_special_keys) {
-            doDocumentKeys();
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private void doPreferences() {
-        startActivity(new Intent(this, TermPreferences.class));
-    }
-
-    private void setColors() {
-        int[] scheme = COLOR_SCHEMES[mColorId];
-        mEmulatorView.setColors(scheme[0], scheme[1]);
-    }
-
-    private void doResetTerminal() {
-        restart();
-    }
-
-    private void doEmailTranscript() {
-        // Don't really want to supply an address, but
-        // currently it's required, otherwise we get an
-        // exception.
-        String addr = "user@example.com";
-        Intent intent =
-                new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"
-                        + addr));
-
-        intent.putExtra("body", mEmulatorView.getTranscriptText());
-        startActivity(intent);
-    }
-
-    private void doDocumentKeys() {
-        String controlKey = CONTROL_KEY_NAME[mControlKeyId];
-        new AlertDialog.Builder(this).
-            setTitle("Press " + controlKey + " and Key").
-            setMessage(controlKey + " Space ==> Control-@ (NUL)\n"
-                    + controlKey + " A..Z ==> Control-A..Z\n"
-                    + controlKey + " 1 ==> Control-[ (ESC)\n"
-                    + controlKey + " 5 ==> Control-_\n"
-                    + controlKey + " . ==> Control-\\\n"
-                    + controlKey + " 0 ==> Control-]\n"
-                    + controlKey + " 6 ==> Control-^").
-            show();
-     }
-}
-
-
-/**
- * An abstract screen interface. A terminal screen stores lines of text. (The
- * reason to abstract it is to allow different implementations, and to hide
- * implementation details from clients.)
- */
-interface Screen {
-
-    /**
-     * Set line wrap flag for a given row. Affects how lines are logically
-     * wrapped when changing screen size or converting to a transcript.
-     */
-    void setLineWrap(int row);
-
-    /**
-     * Store byte b into the screen at location (x, y)
-     *
-     * @param x X coordinate (also known as column)
-     * @param y Y coordinate (also known as row)
-     * @param b ASCII character to store
-     * @param foreColor the foreground color
-     * @param backColor the background color
-     */
-    void set(int x, int y, byte b, int foreColor, int backColor);
-
-    /**
-     * Scroll the screen down one line. To scroll the whole screen of a 24 line
-     * screen, the arguments would be (0, 24).
-     *
-     * @param topMargin First line that is scrolled.
-     * @param bottomMargin One line after the last line that is scrolled.
-     */
-    void scroll(int topMargin, int bottomMargin, int foreColor, int backColor);
-
-    /**
-     * Block copy characters from one position in the screen to another. The two
-     * positions can overlap. All characters of the source and destination must
-     * be within the bounds of the screen, or else an InvalidParemeterException
-     * will be thrown.
-     *
-     * @param sx source X coordinate
-     * @param sy source Y coordinate
-     * @param w width
-     * @param h height
-     * @param dx destination X coordinate
-     * @param dy destination Y coordinate
-     */
-    void blockCopy(int sx, int sy, int w, int h, int dx, int dy);
-
-    /**
-     * Block set characters. All characters must be within the bounds of the
-     * screen, or else and InvalidParemeterException will be thrown. Typically
-     * this is called with a "val" argument of 32 to clear a block of
-     * characters.
-     *
-     * @param sx source X
-     * @param sy source Y
-     * @param w width
-     * @param h height
-     * @param val value to set.
-     * @param foreColor the foreground color
-     * @param backColor the background color
-     */
-    void blockSet(int sx, int sy, int w, int h, int val, int foreColor, int
-            backColor);
-
-    /**
-     * Get the contents of the transcript buffer as a text string.
-     *
-     * @return the contents of the transcript buffer.
-     */
-    String getTranscriptText();
-
-    /**
-     * Resize the screen
-     * @param columns
-     * @param rows
-     */
-    void resize(int columns, int rows, int foreColor, int backColor);
-}
-
-
-/**
- * A TranscriptScreen is a screen that remembers data that's been scrolled. The
- * old data is stored in a ring buffer to minimize the amount of copying that
- * needs to be done. The transcript does its own drawing, to avoid having to
- * expose its internal data structures.
- */
-class TranscriptScreen implements Screen {
-
-    /**
-     * The width of the transcript, in characters. Fixed at initialization.
-     */
-    private int mColumns;
-
-    /**
-     * The total number of rows in the transcript and the screen. Fixed at
-     * initialization.
-     */
-    private int mTotalRows;
-
-    /**
-     * The number of rows in the active portion of the transcript. Doesn't
-     * include the screen.
-     */
-    private int mActiveTranscriptRows;
-
-    /**
-     * Which row is currently the topmost line of the transcript. Used to
-     * implement a circular buffer.
-     */
-    private int mHead;
-
-    /**
-     * The number of active rows, includes both the transcript and the screen.
-     */
-    private int mActiveRows;
-
-    /**
-     * The number of rows in the screen.
-     */
-    private int mScreenRows;
-
-    /**
-     * The data for both the screen and the transcript. The first mScreenRows *
-     * mLineWidth characters are the screen, the rest are the transcript.
-     * The low byte encodes the ASCII character, the high byte encodes the
-     * foreground and background colors, plus underline and bold.
-     */
-    private char[] mData;
-
-    /**
-     * The data's stored as color-encoded chars, but the drawing routines require chars, so we
-     * need a temporary buffer to hold a row's worth of characters.
-     */
-    private char[] mRowBuffer;
-
-    /**
-     * Flags that keep track of whether the current line logically wraps to the
-     * next line. This is used when resizing the screen and when copying to the
-     * clipboard or an email attachment
-     */
-
-    private boolean[] mLineWrap;
-
-    /**
-     * Create a transcript screen.
-     *
-     * @param columns the width of the screen in characters.
-     * @param totalRows the height of the entire text area, in rows of text.
-     * @param screenRows the height of just the screen, not including the
-     *        transcript that holds lines that have scrolled off the top of the
-     *        screen.
-     */
-    public TranscriptScreen(int columns, int totalRows, int screenRows,
-            int foreColor, int backColor) {
-        init(columns, totalRows, screenRows, foreColor, backColor);
-    }
-
-    private void init(int columns, int totalRows, int screenRows, int foreColor, int backColor) {
-        mColumns = columns;
-        mTotalRows = totalRows;
-        mActiveTranscriptRows = 0;
-        mHead = 0;
-        mActiveRows = screenRows;
-        mScreenRows = screenRows;
-        int totalSize = columns * totalRows;
-        mData = new char[totalSize];
-        blockSet(0, 0, mColumns, mScreenRows, ' ', foreColor, backColor);
-        mRowBuffer = new char[columns];
-        mLineWrap = new boolean[totalRows];
-        consistencyCheck();
-   }
-
-    /**
-     * Convert a row value from the public external coordinate system to our
-     * internal private coordinate system. External coordinate system:
-     * -mActiveTranscriptRows to mScreenRows-1, with the screen being
-     * 0..mScreenRows-1 Internal coordinate system: 0..mScreenRows-1 rows of
-     * mData are the visible rows. mScreenRows..mActiveRows - 1 are the
-     * transcript, stored as a circular buffer.
-     *
-     * @param row a row in the external coordinate system.
-     * @return The row corresponding to the input argument in the private
-     *         coordinate system.
-     */
-    private int externalToInternalRow(int row) {
-        if (row < -mActiveTranscriptRows || row >= mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-        if (row >= 0) {
-            return row; // This is a visible row.
-        }
-        return mScreenRows
-                + ((mHead + mActiveTranscriptRows + row) % mActiveTranscriptRows);
-    }
-
-    private int getOffset(int externalLine) {
-        return externalToInternalRow(externalLine) * mColumns;
-    }
-
-    private int getOffset(int x, int y) {
-        return getOffset(y) + x;
-    }
-
-    public void setLineWrap(int row) {
-        mLineWrap[externalToInternalRow(row)] = true;
-    }
-
-    /**
-     * Store byte b into the screen at location (x, y)
-     *
-     * @param x X coordinate (also known as column)
-     * @param y Y coordinate (also known as row)
-     * @param b ASCII character to store
-     * @param foreColor the foreground color
-     * @param backColor the background color
-     */
-    public void set(int x, int y, byte b, int foreColor, int backColor) {
-        mData[getOffset(x, y)] = encode(b, foreColor, backColor);
-    }
-
-    private char encode(int b, int foreColor, int backColor) {
-        return (char) ((foreColor << 12) | (backColor << 8) | b);
-    }
-
-    /**
-     * Scroll the screen down one line. To scroll the whole screen of a 24 line
-     * screen, the arguments would be (0, 24).
-     *
-     * @param topMargin First line that is scrolled.
-     * @param bottomMargin One line after the last line that is scrolled.
-     */
-    public void scroll(int topMargin, int bottomMargin, int foreColor,
-            int backColor) {
-        if (topMargin > bottomMargin - 2 || topMargin > mScreenRows - 2
-                || bottomMargin > mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-
-        // Adjust the transcript so that the last line of the transcript
-        // is ready to receive the newly scrolled data
-        consistencyCheck();
-        int expansionRows = Math.min(1, mTotalRows - mActiveRows);
-        int rollRows = 1 - expansionRows;
-        mActiveRows += expansionRows;
-        mActiveTranscriptRows += expansionRows;
-        if (mActiveTranscriptRows > 0) {
-            mHead = (mHead + rollRows) % mActiveTranscriptRows;
-        }
-        consistencyCheck();
-
-        // Block move the scroll line to the transcript
-        int topOffset = getOffset(topMargin);
-        int destOffset = getOffset(-1);
-        System.arraycopy(mData, topOffset, mData, destOffset, mColumns);
-
-        int topLine = externalToInternalRow(topMargin);
-        int destLine = externalToInternalRow(-1);
-        System.arraycopy(mLineWrap, topLine, mLineWrap, destLine, 1);
-
-        // Block move the scrolled data up
-        int numScrollChars = (bottomMargin - topMargin - 1) * mColumns;
-        System.arraycopy(mData, topOffset + mColumns, mData, topOffset,
-                numScrollChars);
-        int numScrollLines = (bottomMargin - topMargin - 1);
-        System.arraycopy(mLineWrap, topLine + 1, mLineWrap, topLine,
-                numScrollLines);
-
-        // Erase the bottom line of the scroll region
-        blockSet(0, bottomMargin - 1, mColumns, 1, ' ', foreColor, backColor);
-        mLineWrap[externalToInternalRow(bottomMargin-1)] = false;
-    }
-
-    private void consistencyCheck() {
-        checkPositive(mColumns);
-        checkPositive(mTotalRows);
-        checkRange(0, mActiveTranscriptRows, mTotalRows);
-        if (mActiveTranscriptRows == 0) {
-            checkEqual(mHead, 0);
-        } else {
-            checkRange(0, mHead, mActiveTranscriptRows-1);
-        }
-        checkEqual(mScreenRows + mActiveTranscriptRows, mActiveRows);
-        checkRange(0, mScreenRows, mTotalRows);
-
-        checkEqual(mTotalRows, mLineWrap.length);
-        checkEqual(mTotalRows*mColumns, mData.length);
-        checkEqual(mColumns, mRowBuffer.length);
-    }
-
-    private void checkPositive(int n) {
-        if (n < 0) {
-            throw new IllegalArgumentException("checkPositive " + n);
-        }
-    }
-
-    private void checkRange(int a, int b, int c) {
-        if (a > b || b > c) {
-            throw new IllegalArgumentException("checkRange " + a + " <= " + b + " <= " + c);
-        }
-    }
-
-    private void checkEqual(int a, int b) {
-        if (a != b) {
-            throw new IllegalArgumentException("checkEqual " + a + " == " + b);
-        }
-    }
-
-    /**
-     * Block copy characters from one position in the screen to another. The two
-     * positions can overlap. All characters of the source and destination must
-     * be within the bounds of the screen, or else an InvalidParemeterException
-     * will be thrown.
-     *
-     * @param sx source X coordinate
-     * @param sy source Y coordinate
-     * @param w width
-     * @param h height
-     * @param dx destination X coordinate
-     * @param dy destination Y coordinate
-     */
-    public void blockCopy(int sx, int sy, int w, int h, int dx, int dy) {
-        if (sx < 0 || sx + w > mColumns || sy < 0 || sy + h > mScreenRows
-                || dx < 0 || dx + w > mColumns || dy < 0
-                || dy + h > mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-        if (sy <= dy) {
-            // Move in increasing order
-            for (int y = 0; y < h; y++) {
-                int srcOffset = getOffset(sx, sy + y);
-                int dstOffset = getOffset(dx, dy + y);
-                System.arraycopy(mData, srcOffset, mData, dstOffset, w);
-            }
-        } else {
-            // Move in decreasing order
-            for (int y = 0; y < h; y++) {
-                int y2 = h - (y + 1);
-                int srcOffset = getOffset(sx, sy + y2);
-                int dstOffset = getOffset(dx, dy + y2);
-                System.arraycopy(mData, srcOffset, mData, dstOffset, w);
-            }
-        }
-    }
-
-    /**
-     * Block set characters. All characters must be within the bounds of the
-     * screen, or else and InvalidParemeterException will be thrown. Typically
-     * this is called with a "val" argument of 32 to clear a block of
-     * characters.
-     *
-     * @param sx source X
-     * @param sy source Y
-     * @param w width
-     * @param h height
-     * @param val value to set.
-     */
-    public void blockSet(int sx, int sy, int w, int h, int val,
-            int foreColor, int backColor) {
-        if (sx < 0 || sx + w > mColumns || sy < 0 || sy + h > mScreenRows) {
-            throw new IllegalArgumentException();
-        }
-        char[] data = mData;
-        char encodedVal = encode(val, foreColor, backColor);
-        for (int y = 0; y < h; y++) {
-            int offset = getOffset(sx, sy + y);
-            for (int x = 0; x < w; x++) {
-                data[offset + x] = encodedVal;
-            }
-        }
-    }
-
-    /**
-     * Draw a row of text. Out-of-bounds rows are blank, not errors.
-     *
-     * @param row The row of text to draw.
-     * @param canvas The canvas to draw to.
-     * @param x The x coordinate origin of the drawing
-     * @param y The y coordinate origin of the drawing
-     * @param renderer The renderer to use to draw the text
-     * @param cx the cursor X coordinate, -1 means don't draw it
-     */
-    public final void drawText(int row, Canvas canvas, float x, float y,
-            TextRenderer renderer, int cx) {
-
-        // Out-of-bounds rows are blank.
-        if (row < -mActiveTranscriptRows || row >= mScreenRows) {
-            return;
-        }
-
-        // Copy the data from the byte array to a char array so they can
-        // be drawn.
-
-        int offset = getOffset(row);
-        char[] rowBuffer = mRowBuffer;
-        char[] data = mData;
-        int columns = mColumns;
-        int lastColors = 0;
-        int lastRunStart = -1;
-        final int CURSOR_MASK = 0x10000;
-        for (int i = 0; i < columns; i++) {
-            char c = data[offset + i];
-            int colors = (char) (c & 0xff00);
-            if (cx == i) {
-                // Set cursor background color:
-                colors |= CURSOR_MASK;
-            }
-            rowBuffer[i] = (char) (c & 0x00ff);
-            if (colors != lastColors) {
-                if (lastRunStart >= 0) {
-                    renderer.drawTextRun(canvas, x, y, lastRunStart, rowBuffer,
-                            lastRunStart, i - lastRunStart,
-                            (lastColors & CURSOR_MASK) != 0,
-                            0xf & (lastColors >> 12), 0xf & (lastColors >> 8));
-                }
-                lastColors = colors;
-                lastRunStart = i;
-            }
-        }
-        if (lastRunStart >= 0) {
-            renderer.drawTextRun(canvas, x, y, lastRunStart, rowBuffer,
-                    lastRunStart, columns - lastRunStart,
-                    (lastColors & CURSOR_MASK) != 0,
-                    0xf & (lastColors >> 12), 0xf & (lastColors >> 8));
-        }
-     }
-
-    /**
-     * Get the count of active rows.
-     *
-     * @return the count of active rows.
-     */
-    public int getActiveRows() {
-        return mActiveRows;
-    }
-
-    /**
-     * Get the count of active transcript rows.
-     *
-     * @return the count of active transcript rows.
-     */
-    public int getActiveTranscriptRows() {
-        return mActiveTranscriptRows;
-    }
-
-    public String getTranscriptText() {
-        return internalGetTranscriptText(true);
-    }
-
-    private String internalGetTranscriptText(boolean stripColors) {
-        StringBuilder builder = new StringBuilder();
-        char[] rowBuffer = mRowBuffer;
-        char[] data = mData;
-        int columns = mColumns;
-        for (int row = -mActiveTranscriptRows; row < mScreenRows; row++) {
-            int offset = getOffset(row);
-            int lastPrintingChar = -1;
-            for (int column = 0; column < columns; column++) {
-                char c = data[offset + column];
-                if (stripColors) {
-                    c = (char) (c & 0xff);
-                }
-                if ((c & 0xff) != ' ') {
-                    lastPrintingChar = column;
-                }
-                rowBuffer[column] = c;
-            }
-            if (mLineWrap[externalToInternalRow(row)]) {
-                builder.append(rowBuffer, 0, columns);
-            } else {
-                builder.append(rowBuffer, 0, lastPrintingChar + 1);
-                builder.append('\n');
-            }
-        }
-        return builder.toString();
-    }
-
-    public void resize(int columns, int rows, int foreColor, int backColor) {
-        init(columns, mTotalRows, rows, foreColor, backColor);
-    }
-}
-
-/**
- * Renders text into a screen. Contains all the terminal-specific knowlege and
- * state. Emulates a subset of the X Window System xterm terminal, which in turn
- * is an emulator for a subset of the Digital Equipment Corporation vt100
- * terminal. Missing functionality: text attributes (bold, underline, reverse
- * video, color) alternate screen cursor key and keypad escape sequences.
- */
-class TerminalEmulator {
-
-    /**
-     * The cursor row. Numbered 0..mRows-1.
-     */
-    private int mCursorRow;
-
-    /**
-     * The cursor column. Numbered 0..mColumns-1.
-     */
-    private int mCursorCol;
-
-    /**
-     * The number of character rows in the terminal screen.
-     */
-    private int mRows;
-
-    /**
-     * The number of character columns in the terminal screen.
-     */
-    private int mColumns;
-
-    /**
-     * Used to send data to the remote process. Needed to implement the various
-     * "report" escape sequences.
-     */
-    private FileOutputStream mTermOut;
-
-    /**
-     * Stores the characters that appear on the screen of the emulated terminal.
-     */
-    private Screen mScreen;
-
-    /**
-     * Keeps track of the current argument of the current escape sequence.
-     * Ranges from 0 to MAX_ESCAPE_PARAMETERS-1. (Typically just 0 or 1.)
-     */
-    private int mArgIndex;
-
-    /**
-     * The number of parameter arguments. This name comes from the ANSI standard
-     * for terminal escape codes.
-     */
-    private static final int MAX_ESCAPE_PARAMETERS = 16;
-
-    /**
-     * Holds the arguments of the current escape sequence.
-     */
-    private int[] mArgs = new int[MAX_ESCAPE_PARAMETERS];
-
-    // Escape processing states:
-
-    /**
-     * Escape processing state: Not currently in an escape sequence.
-     */
-    private static final int ESC_NONE = 0;
-
-    /**
-     * Escape processing state: Have seen an ESC character
-     */
-    private static final int ESC = 1;
-
-    /**
-     * Escape processing state: Have seen ESC POUND
-     */
-    private static final int ESC_POUND = 2;
-
-    /**
-     * Escape processing state: Have seen ESC and a character-set-select char
-     */
-    private static final int ESC_SELECT_LEFT_PAREN = 3;
-
-    /**
-     * Escape processing state: Have seen ESC and a character-set-select char
-     */
-    private static final int ESC_SELECT_RIGHT_PAREN = 4;
-
-    /**
-     * Escape processing state: ESC [
-     */
-    private static final int ESC_LEFT_SQUARE_BRACKET = 5;
-
-    /**
-     * Escape processing state: ESC [ ?
-     */
-    private static final int ESC_LEFT_SQUARE_BRACKET_QUESTION_MARK = 6;
-
-    /**
-     * True if the current escape sequence should continue, false if the current
-     * escape sequence should be terminated. Used when parsing a single
-     * character.
-     */
-    private boolean mContinueSequence;
-
-    /**
-     * The current state of the escape sequence state machine.
-     */
-    private int mEscapeState;
-
-    /**
-     * Saved state of the cursor row, Used to implement the save/restore cursor
-     * position escape sequences.
-     */
-    private int mSavedCursorRow;
-
-    /**
-     * Saved state of the cursor column, Used to implement the save/restore
-     * cursor position escape sequences.
-     */
-    private int mSavedCursorCol;
-
-    // DecSet booleans
-
-    /**
-     * This mask indicates 132-column mode is set. (As opposed to 80-column
-     * mode.)
-     */
-    private static final int K_132_COLUMN_MODE_MASK = 1 << 3;
-
-    /**
-     * This mask indicates that origin mode is set. (Cursor addressing is
-     * relative to the absolute screen size, rather than the currently set top
-     * and bottom margins.)
-     */
-    private static final int K_ORIGIN_MODE_MASK = 1 << 6;
-
-    /**
-     * This mask indicates that wraparound mode is set. (As opposed to
-     * stop-at-right-column mode.)
-     */
-    private static final int K_WRAPAROUND_MODE_MASK = 1 << 7;
-
-    /**
-     * Holds multiple DECSET flags. The data is stored this way, rather than in
-     * separate booleans, to make it easier to implement the save-and-restore
-     * semantics. The various k*ModeMask masks can be used to extract and modify
-     * the individual flags current states.
-     */
-    private int mDecFlags;
-
-    /**
-     * Saves away a snapshot of the DECSET flags. Used to implement save and
-     * restore escape sequences.
-     */
-    private int mSavedDecFlags;
-
-    // Modes set with Set Mode / Reset Mode
-
-    /**
-     * True if insert mode (as opposed to replace mode) is active. In insert
-     * mode new characters are inserted, pushing existing text to the right.
-     */
-    private boolean mInsertMode;
-
-    /**
-     * Automatic newline mode. Configures whether pressing return on the
-     * keyboard automatically generates a return as well. Not currently
-     * implemented.
-     */
-    private boolean mAutomaticNewlineMode;
-
-    /**
-     * An array of tab stops. mTabStop[i] is true if there is a tab stop set for
-     * column i.
-     */
-    private boolean[] mTabStop;
-
-    // The margins allow portions of the screen to be locked.
-
-    /**
-     * The top margin of the screen, for scrolling purposes. Ranges from 0 to
-     * mRows-2.
-     */
-    private int mTopMargin;
-
-    /**
-     * The bottom margin of the screen, for scrolling purposes. Ranges from
-     * mTopMargin + 2 to mRows. (Defines the first row after the scrolling
-     * region.
-     */
-    private int mBottomMargin;
-
-    /**
-     * True if the next character to be emitted will be automatically wrapped to
-     * the next line. Used to disambiguate the case where the cursor is
-     * positioned on column mColumns-1.
-     */
-    private boolean mAboutToAutoWrap;
-
-    /**
-     * Used for debugging, counts how many chars have been processed.
-     */
-    private int mProcessedCharCount;
-
-    /**
-     * Foreground color, 0..7, mask with 8 for bold
-     */
-    private int mForeColor;
-
-    /**
-     * Background color, 0..7, mask with 8 for underline
-     */
-    private int mBackColor;
-
-    private boolean mInverseColors;
-
-    private boolean mbKeypadApplicationMode;
-
-    private boolean mAlternateCharSet;
-
-    /**
-     * Construct a terminal emulator that uses the supplied screen
-     *
-     * @param screen the screen to render characters into.
-     * @param columns the number of columns to emulate
-     * @param rows the number of rows to emulate
-     * @param termOut the output file descriptor that talks to the pseudo-tty.
-     */
-    public TerminalEmulator(Screen screen, int columns, int rows,
-            FileOutputStream termOut) {
-        mScreen = screen;
-        mRows = rows;
-        mColumns = columns;
-        mTabStop = new boolean[mColumns];
-        mTermOut = termOut;
-        reset();
-    }
-
-    public void updateSize(int columns, int rows) {
-        if (mRows == rows && mColumns == columns) {
-            return;
-        }
-        String transcriptText = mScreen.getTranscriptText();
-
-        mScreen.resize(columns, rows, mForeColor, mBackColor);
-
-        if (mRows != rows) {
-            mRows = rows;
-            mTopMargin = 0;
-            mBottomMargin = mRows;
-        }
-        if (mColumns != columns) {
-            int oldColumns = mColumns;
-            mColumns = columns;
-            boolean[] oldTabStop = mTabStop;
-            mTabStop = new boolean[mColumns];
-            int toTransfer = Math.min(oldColumns, columns);
-            System.arraycopy(oldTabStop, 0, mTabStop, 0, toTransfer);
-            while (mCursorCol >= columns) {
-                mCursorCol -= columns;
-                mCursorRow = Math.min(mBottomMargin-1, mCursorRow + 1);
-            }
-        }
-        mCursorRow = 0;
-        mCursorCol = 0;
-        mAboutToAutoWrap = false;
-
-        int end = transcriptText.length()-1;
-        while ((end >= 0) && transcriptText.charAt(end) == '\n') {
-            end--;
-        }
-        for(int i = 0; i <= end; i++) {
-            byte c = (byte) transcriptText.charAt(i);
-            if (c == '\n') {
-                setCursorCol(0);
-                doLinefeed();
-            } else {
-                emit(c);
-            }
-        }
-    }
-
-    /**
-     * Get the cursor's current row.
-     *
-     * @return the cursor's current row.
-     */
-    public final int getCursorRow() {
-        return mCursorRow;
-    }
-
-    /**
-     * Get the cursor's current column.
-     *
-     * @return the cursor's current column.
-     */
-    public final int getCursorCol() {
-        return mCursorCol;
-    }
-
-    public final boolean getKeypadApplicationMode() {
-        return mbKeypadApplicationMode;
-    }
-
-    private void setDefaultTabStops() {
-        for (int i = 0; i < mColumns; i++) {
-            mTabStop[i] = (i & 7) == 0 && i != 0;
-        }
-    }
-
-    /**
-     * Accept bytes (typically from the pseudo-teletype) and process them.
-     *
-     * @param buffer a byte array containing the bytes to be processed
-     * @param base the first index of the array to process
-     * @param length the number of bytes in the array to process
-     */
-    public void append(byte[] buffer, int base, int length) {
-        for (int i = 0; i < length; i++) {
-            byte b = buffer[base + i];
-            try {
-                if (Term.LOG_CHARACTERS_FLAG) {
-                    char printableB = (char) b;
-                    if (b < 32 || b > 126) {
-                        printableB = ' ';
-                    }
-                    Log.w(Term.LOG_TAG, "'" + Character.toString(printableB)
-                            + "' (" + Integer.toString(b) + ")");
-                }
-                process(b);
-                mProcessedCharCount++;
-            } catch (Exception e) {
-                Log.e(Term.LOG_TAG, "Exception while processing character "
-                        + Integer.toString(mProcessedCharCount) + " code "
-                        + Integer.toString(b), e);
-            }
-        }
-    }
-
-    private void process(byte b) {
-        switch (b) {
-        case 0: // NUL
-            // Do nothing
-            break;
-
-        case 7: // BEL
-            // Do nothing
-            break;
-
-        case 8: // BS
-            setCursorCol(Math.max(0, mCursorCol - 1));
-            break;
-
-        case 9: // HT
-            // Move to next tab stop, but not past edge of screen
-            setCursorCol(nextTabStop(mCursorCol));
-            break;
-
-        case 13:
-            setCursorCol(0);
-            break;
-
-        case 10: // CR
-        case 11: // VT
-        case 12: // LF
-            doLinefeed();
-            break;
-
-        case 14: // SO:
-            setAltCharSet(true);
-            break;
-
-        case 15: // SI:
-            setAltCharSet(false);
-            break;
-
-
-        case 24: // CAN
-        case 26: // SUB
-            if (mEscapeState != ESC_NONE) {
-                mEscapeState = ESC_NONE;
-                emit((byte) 127);
-            }
-            break;
-
-        case 27: // ESC
-            // Always starts an escape sequence
-            startEscapeSequence(ESC);
-            break;
-
-        case (byte) 0x9b: // CSI
-            startEscapeSequence(ESC_LEFT_SQUARE_BRACKET);
-            break;
-
-        default:
-            mContinueSequence = false;
-            switch (mEscapeState) {
-            case ESC_NONE:
-                if (b >= 32) {
-                    emit(b);
-                }
-                break;
-
-            case ESC:
-                doEsc(b);
-                break;
-
-            case ESC_POUND:
-                doEscPound(b);
-                break;
-
-            case ESC_SELECT_LEFT_PAREN:
-                doEscSelectLeftParen(b);
-                break;
-
-            case ESC_SELECT_RIGHT_PAREN:
-                doEscSelectRightParen(b);
-                break;
-
-            case ESC_LEFT_SQUARE_BRACKET:
-                doEscLeftSquareBracket(b);
-                break;
-
-            case ESC_LEFT_SQUARE_BRACKET_QUESTION_MARK:
-                doEscLSBQuest(b);
-                break;
-
-            default:
-                unknownSequence(b);
-                break;
-            }
-            if (!mContinueSequence) {
-                mEscapeState = ESC_NONE;
-            }
-            break;
-        }
-    }
-
-    private void setAltCharSet(boolean alternateCharSet) {
-        mAlternateCharSet = alternateCharSet;
-    }
-
-    private int nextTabStop(int cursorCol) {
-        for (int i = cursorCol; i < mColumns; i++) {
-            if (mTabStop[i]) {
-                return i;
-            }
-        }
-        return mColumns - 1;
-    }
-
-    private void doEscLSBQuest(byte b) {
-        int mask = getDecFlagsMask(getArg0(0));
-        switch (b) {
-        case 'h': // Esc [ ? Pn h - DECSET
-            mDecFlags |= mask;
-            break;
-
-        case 'l': // Esc [ ? Pn l - DECRST
-            mDecFlags &= ~mask;
-            break;
-
-        case 'r': // Esc [ ? Pn r - restore
-            mDecFlags = (mDecFlags & ~mask) | (mSavedDecFlags & mask);
-            break;
-
-        case 's': // Esc [ ? Pn s - save
-            mSavedDecFlags = (mSavedDecFlags & ~mask) | (mDecFlags & mask);
-            break;
-
-        default:
-            parseArg(b);
-            break;
-        }
-
-        // 132 column mode
-        if ((mask & K_132_COLUMN_MODE_MASK) != 0) {
-            // We don't actually set 132 cols, but we do want the
-            // side effect of clearing the screen and homing the cursor.
-            blockClear(0, 0, mColumns, mRows);
-            setCursorRowCol(0, 0);
-        }
-
-        // origin mode
-        if ((mask & K_ORIGIN_MODE_MASK) != 0) {
-            // Home the cursor.
-            setCursorPosition(0, 0);
-        }
-    }
-
-    private int getDecFlagsMask(int argument) {
-        if (argument >= 1 && argument <= 9) {
-            return (1 << argument);
-        }
-
-        return 0;
-    }
-
-    private void startEscapeSequence(int escapeState) {
-        mEscapeState = escapeState;
-        mArgIndex = 0;
-        for (int j = 0; j < MAX_ESCAPE_PARAMETERS; j++) {
-            mArgs[j] = -1;
-        }
-    }
-
-    private void doLinefeed() {
-        int newCursorRow = mCursorRow + 1;
-        if (newCursorRow >= mBottomMargin) {
-            scroll();
-            newCursorRow = mBottomMargin - 1;
-        }
-        setCursorRow(newCursorRow);
-    }
-
-    private void continueSequence() {
-        mContinueSequence = true;
-    }
-
-    private void continueSequence(int state) {
-        mEscapeState = state;
-        mContinueSequence = true;
-    }
-
-    private void doEscSelectLeftParen(byte b) {
-        doSelectCharSet(true, b);
-    }
-
-    private void doEscSelectRightParen(byte b) {
-        doSelectCharSet(false, b);
-    }
-
-    private void doSelectCharSet(boolean isG0CharSet, byte b) {
-        switch (b) {
-        case 'A': // United Kingdom character set
-            break;
-        case 'B': // ASCII set
-            break;
-        case '0': // Special Graphics
-            break;
-        case '1': // Alternate character set
-            break;
-        case '2':
-            break;
-        default:
-            unknownSequence(b);
-        }
-    }
-
-    private void doEscPound(byte b) {
-        switch (b) {
-        case '8': // Esc # 8 - DECALN alignment test
-            mScreen.blockSet(0, 0, mColumns, mRows, 'E',
-                    getForeColor(), getBackColor());
-            break;
-
-        default:
-            unknownSequence(b);
-            break;
-        }
-    }
-
-    private void doEsc(byte b) {
-        switch (b) {
-        case '#':
-            continueSequence(ESC_POUND);
-            break;
-
-        case '(':
-            continueSequence(ESC_SELECT_LEFT_PAREN);
-            break;
-
-        case ')':
-            continueSequence(ESC_SELECT_RIGHT_PAREN);
-            break;
-
-        case '7': // DECSC save cursor
-            mSavedCursorRow = mCursorRow;
-            mSavedCursorCol = mCursorCol;
-            break;
-
-        case '8': // DECRC restore cursor
-            setCursorRowCol(mSavedCursorRow, mSavedCursorCol);
-            break;
-
-        case 'D': // INDEX
-            doLinefeed();
-            break;
-
-        case 'E': // NEL
-            setCursorCol(0);
-            doLinefeed();
-            break;
-
-        case 'F': // Cursor to lower-left corner of screen
-            setCursorRowCol(0, mBottomMargin - 1);
-            break;
-
-        case 'H': // Tab set
-            mTabStop[mCursorCol] = true;
-            break;
-
-        case 'M': // Reverse index
-            if (mCursorRow == 0) {
-                mScreen.blockCopy(0, mTopMargin + 1, mColumns, mBottomMargin
-                        - (mTopMargin + 1), 0, mTopMargin);
-                blockClear(0, mBottomMargin - 1, mColumns);
-            } else {
-                mCursorRow--;
-            }
-
-            break;
-
-        case 'N': // SS2
-            unimplementedSequence(b);
-            break;
-
-        case '0': // SS3
-            unimplementedSequence(b);
-            break;
-
-        case 'P': // Device control string
-            unimplementedSequence(b);
-            break;
-
-        case 'Z': // return terminal ID
-            sendDeviceAttributes();
-            break;
-
-        case '[':
-            continueSequence(ESC_LEFT_SQUARE_BRACKET);
-            break;
-
-        case '=': // DECKPAM
-            mbKeypadApplicationMode = true;
-            break;
-
-        case '>' : // DECKPNM
-            mbKeypadApplicationMode = false;
-            break;
-
-        default:
-            unknownSequence(b);
-            break;
-        }
-    }
-
-    private void doEscLeftSquareBracket(byte b) {
-        switch (b) {
-        case '@': // ESC [ Pn @ - ICH Insert Characters
-        {
-            int charsAfterCursor = mColumns - mCursorCol;
-            int charsToInsert = Math.min(getArg0(1), charsAfterCursor);
-            int charsToMove = charsAfterCursor - charsToInsert;
-            mScreen.blockCopy(mCursorCol, mCursorRow, charsToMove, 1,
-                    mCursorCol + charsToInsert, mCursorRow);
-            blockClear(mCursorCol, mCursorRow, charsToInsert);
-        }
-            break;
-
-        case 'A': // ESC [ Pn A - Cursor Up
-            setCursorRow(Math.max(mTopMargin, mCursorRow - getArg0(1)));
-            break;
-
-        case 'B': // ESC [ Pn B - Cursor Down
-            setCursorRow(Math.min(mBottomMargin - 1, mCursorRow + getArg0(1)));
-            break;
-
-        case 'C': // ESC [ Pn C - Cursor Right
-            setCursorCol(Math.min(mColumns - 1, mCursorCol + getArg0(1)));
-            break;
-
-        case 'D': // ESC [ Pn D - Cursor Left
-            setCursorCol(Math.max(0, mCursorCol - getArg0(1)));
-            break;
-
-        case 'G': // ESC [ Pn G - Cursor Horizontal Absolute
-            setCursorCol(Math.min(Math.max(1, getArg0(1)), mColumns) - 1);
-            break;
-
-        case 'H': // ESC [ Pn ; H - Cursor Position
-            setHorizontalVerticalPosition();
-            break;
-
-        case 'J': // ESC [ Pn J - Erase in Display
-            switch (getArg0(0)) {
-            case 0: // Clear below
-                blockClear(mCursorCol, mCursorRow, mColumns - mCursorCol);
-                blockClear(0, mCursorRow + 1, mColumns,
-                        mBottomMargin - (mCursorRow + 1));
-                break;
-
-            case 1: // Erase from the start of the screen to the cursor.
-                blockClear(0, mTopMargin, mColumns, mCursorRow - mTopMargin);
-                blockClear(0, mCursorRow, mCursorCol + 1);
-                break;
-
-            case 2: // Clear all
-                blockClear(0, mTopMargin, mColumns, mBottomMargin - mTopMargin);
-                break;
-
-            default:
-                unknownSequence(b);
-                break;
-            }
-            break;
-
-        case 'K': // ESC [ Pn K - Erase in Line
-            switch (getArg0(0)) {
-            case 0: // Clear to right
-                blockClear(mCursorCol, mCursorRow, mColumns - mCursorCol);
-                break;
-
-            case 1: // Erase start of line to cursor (including cursor)
-                blockClear(0, mCursorRow, mCursorCol + 1);
-                break;
-
-            case 2: // Clear whole line
-                blockClear(0, mCursorRow, mColumns);
-                break;
-
-            default:
-                unknownSequence(b);
-                break;
-            }
-            break;
-
-        case 'L': // Insert Lines
-        {
-            int linesAfterCursor = mBottomMargin - mCursorRow;
-            int linesToInsert = Math.min(getArg0(1), linesAfterCursor);
-            int linesToMove = linesAfterCursor - linesToInsert;
-            mScreen.blockCopy(0, mCursorRow, mColumns, linesToMove, 0,
-                    mCursorRow + linesToInsert);
-            blockClear(0, mCursorRow, mColumns, linesToInsert);
-        }
-            break;
-
-        case 'M': // Delete Lines
-        {
-            int linesAfterCursor = mBottomMargin - mCursorRow;
-            int linesToDelete = Math.min(getArg0(1), linesAfterCursor);
-            int linesToMove = linesAfterCursor - linesToDelete;
-            mScreen.blockCopy(0, mCursorRow + linesToDelete, mColumns,
-                    linesToMove, 0, mCursorRow);
-            blockClear(0, mCursorRow + linesToMove, mColumns, linesToDelete);
-        }
-            break;
-
-        case 'P': // Delete Characters
-        {
-            int charsAfterCursor = mColumns - mCursorCol;
-            int charsToDelete = Math.min(getArg0(1), charsAfterCursor);
-            int charsToMove = charsAfterCursor - charsToDelete;
-            mScreen.blockCopy(mCursorCol + charsToDelete, mCursorRow,
-                    charsToMove, 1, mCursorCol, mCursorRow);
-            blockClear(mCursorCol + charsToMove, mCursorRow, charsToDelete);
-        }
-            break;
-
-        case 'T': // Mouse tracking
-            unimplementedSequence(b);
-            break;
-
-        case '?': // Esc [ ? -- start of a private mode set
-            continueSequence(ESC_LEFT_SQUARE_BRACKET_QUESTION_MARK);
-            break;
-
-        case 'c': // Send device attributes
-            sendDeviceAttributes();
-            break;
-
-        case 'd': // ESC [ Pn d - Vert Position Absolute
-            setCursorRow(Math.min(Math.max(1, getArg0(1)), mRows) - 1);
-            break;
-
-        case 'f': // Horizontal and Vertical Position
-            setHorizontalVerticalPosition();
-            break;
-
-        case 'g': // Clear tab stop
-            switch (getArg0(0)) {
-            case 0:
-                mTabStop[mCursorCol] = false;
-                break;
-
-            case 3:
-                for (int i = 0; i < mColumns; i++) {
-                    mTabStop[i] = false;
-                }
-                break;
-
-            default:
-                // Specified to have no effect.
-                break;
-            }
-            break;
-
-        case 'h': // Set Mode
-            doSetMode(true);
-            break;
-
-        case 'l': // Reset Mode
-            doSetMode(false);
-            break;
-
-        case 'm': // Esc [ Pn m - character attributes.
-            selectGraphicRendition();
-            break;
-
-        case 'r': // Esc [ Pn ; Pn r - set top and bottom margins
-        {
-            // The top margin defaults to 1, the bottom margin
-            // (unusually for arguments) defaults to mRows.
-            //
-            // The escape sequence numbers top 1..23, but we
-            // number top 0..22.
-            // The escape sequence numbers bottom 2..24, and
-            // so do we (because we use a zero based numbering
-            // scheme, but we store the first line below the
-            // bottom-most scrolling line.
-            // As a result, we adjust the top line by -1, but
-            // we leave the bottom line alone.
-            //
-            // Also require that top + 2 <= bottom
-
-            int top = Math.max(0, Math.min(getArg0(1) - 1, mRows - 2));
-            int bottom = Math.max(top + 2, Math.min(getArg1(mRows), mRows));
-            mTopMargin = top;
-            mBottomMargin = bottom;
-
-            // The cursor is placed in the home position
-            setCursorRowCol(mTopMargin, 0);
-        }
-            break;
-
-        default:
-            parseArg(b);
-            break;
-        }
-    }
-
-    private void selectGraphicRendition() {
-        for (int i = 0; i <= mArgIndex; i++) {
-            int code = mArgs[i];
-            if ( code < 0) {
-                if (mArgIndex > 0) {
-                    continue;
-                } else {
-                    code = 0;
-                }
-            }
-            if (code == 0) { // reset
-                mInverseColors = false;
-                mForeColor = 7;
-                mBackColor = 0;
-            } else if (code == 1) { // bold
-                mForeColor |= 0x8;
-            } else if (code == 4) { // underscore
-                mBackColor |= 0x8;
-            } else if (code == 7) { // inverse
-                mInverseColors = true;
-            } else if (code >= 30 && code <= 37) { // foreground color
-                mForeColor = (mForeColor & 0x8) | (code - 30);
-            } else if (code >= 40 && code <= 47) { // background color
-                mBackColor = (mBackColor & 0x8) | (code - 40);
-            } else {
-                if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-                    Log.w(Term.LOG_TAG, String.format("SGR unknown code %d", code));
-                }
-            }
-        }
-    }
-
-    private void blockClear(int sx, int sy, int w) {
-        blockClear(sx, sy, w, 1);
-    }
-
-    private void blockClear(int sx, int sy, int w, int h) {
-        mScreen.blockSet(sx, sy, w, h, ' ', getForeColor(), getBackColor());
-    }
-
-    private int getForeColor() {
-        return mInverseColors ?
-                ((mBackColor & 0x7) | (mForeColor & 0x8)) : mForeColor;
-    }
-
-    private int getBackColor() {
-        return mInverseColors ?
-                ((mForeColor & 0x7) | (mBackColor & 0x8)) : mBackColor;
-    }
-
-    private void doSetMode(boolean newValue) {
-        int modeBit = getArg0(0);
-        switch (modeBit) {
-        case 4:
-            mInsertMode = newValue;
-            break;
-
-        case 20:
-            mAutomaticNewlineMode = newValue;
-            break;
-
-        default:
-            unknownParameter(modeBit);
-            break;
-        }
-    }
-
-    private void setHorizontalVerticalPosition() {
-
-        // Parameters are Row ; Column
-
-        setCursorPosition(getArg1(1) - 1, getArg0(1) - 1);
-    }
-
-    private void setCursorPosition(int x, int y) {
-        int effectiveTopMargin = 0;
-        int effectiveBottomMargin = mRows;
-        if ((mDecFlags & K_ORIGIN_MODE_MASK) != 0) {
-            effectiveTopMargin = mTopMargin;
-            effectiveBottomMargin = mBottomMargin;
-        }
-        int newRow =
-                Math.max(effectiveTopMargin, Math.min(effectiveTopMargin + y,
-                        effectiveBottomMargin - 1));
-        int newCol = Math.max(0, Math.min(x, mColumns - 1));
-        setCursorRowCol(newRow, newCol);
-    }
-
-    private void sendDeviceAttributes() {
-        // This identifies us as a DEC vt100 with advanced
-        // video options. This is what the xterm terminal
-        // emulator sends.
-        byte[] attributes =
-                {
-                /* VT100 */
-                 (byte) 27, (byte) '[', (byte) '?', (byte) '1',
-                 (byte) ';', (byte) '2', (byte) 'c'
-
-                /* VT220
-                (byte) 27, (byte) '[', (byte) '?', (byte) '6',
-                (byte) '0',  (byte) ';',
-                (byte) '1',  (byte) ';',
-                (byte) '2',  (byte) ';',
-                (byte) '6',  (byte) ';',
-                (byte) '8',  (byte) ';',
-                (byte) '9',  (byte) ';',
-                (byte) '1',  (byte) '5', (byte) ';',
-                (byte) 'c'
-                */
-                };
-
-        write(attributes);
-    }
-
-    /**
-     * Send data to the shell process
-     * @param data
-     */
-    private void write(byte[] data) {
-        try {
-            mTermOut.write(data);
-            mTermOut.flush();
-        } catch (IOException e) {
-            // Ignore exception
-            // We don't really care if the receiver isn't listening.
-            // We just make a best effort to answer the query.
-        }
-    }
-
-    private void scroll() {
-        mScreen.scroll(mTopMargin, mBottomMargin,
-                getForeColor(), getBackColor());
-    }
-
-    /**
-     * Process the next ASCII character of a parameter.
-     *
-     * @param b The next ASCII character of the paramater sequence.
-     */
-    private void parseArg(byte b) {
-        if (b >= '0' && b <= '9') {
-            if (mArgIndex < mArgs.length) {
-                int oldValue = mArgs[mArgIndex];
-                int thisDigit = b - '0';
-                int value;
-                if (oldValue >= 0) {
-                    value = oldValue * 10 + thisDigit;
-                } else {
-                    value = thisDigit;
-                }
-                mArgs[mArgIndex] = value;
-            }
-            continueSequence();
-        } else if (b == ';') {
-            if (mArgIndex < mArgs.length) {
-                mArgIndex++;
-            }
-            continueSequence();
-        } else {
-            unknownSequence(b);
-        }
-    }
-
-    private int getArg0(int defaultValue) {
-        return getArg(0, defaultValue);
-    }
-
-    private int getArg1(int defaultValue) {
-        return getArg(1, defaultValue);
-    }
-
-    private int getArg(int index, int defaultValue) {
-        int result = mArgs[index];
-        if (result < 0) {
-            result = defaultValue;
-        }
-        return result;
-    }
-
-    private void unimplementedSequence(byte b) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            logError("unimplemented", b);
-        }
-        finishSequence();
-    }
-
-    private void unknownSequence(byte b) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            logError("unknown", b);
-        }
-        finishSequence();
-    }
-
-    private void unknownParameter(int parameter) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            StringBuilder buf = new StringBuilder();
-            buf.append("Unknown parameter");
-            buf.append(parameter);
-            logError(buf.toString());
-        }
-    }
-
-    private void logError(String errorType, byte b) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            StringBuilder buf = new StringBuilder();
-            buf.append(errorType);
-            buf.append(" sequence ");
-            buf.append(" EscapeState: ");
-            buf.append(mEscapeState);
-            buf.append(" char: '");
-            buf.append((char) b);
-            buf.append("' (");
-            buf.append(b);
-            buf.append(")");
-            boolean firstArg = true;
-            for (int i = 0; i <= mArgIndex; i++) {
-                int value = mArgs[i];
-                if (value >= 0) {
-                    if (firstArg) {
-                        firstArg = false;
-                        buf.append("args = ");
-                    }
-                    buf.append(String.format("%d; ", value));
-                }
-            }
-            logError(buf.toString());
-        }
-    }
-
-    private void logError(String error) {
-        if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) {
-            Log.e(Term.LOG_TAG, error);
-        }
-        finishSequence();
-    }
-
-    private void finishSequence() {
-        mEscapeState = ESC_NONE;
-    }
-
-    private boolean autoWrapEnabled() {
-        // Always enable auto wrap, because it's useful on a small screen
-        return true;
-        // return (mDecFlags & K_WRAPAROUND_MODE_MASK) != 0;
-    }
-
-    /**
-     * Send an ASCII character to the screen.
-     *
-     * @param b the ASCII character to display.
-     */
-    private void emit(byte b) {
-        boolean autoWrap = autoWrapEnabled();
-
-        if (autoWrap) {
-            if (mCursorCol == mColumns - 1 && mAboutToAutoWrap) {
-                mScreen.setLineWrap(mCursorRow);
-                mCursorCol = 0;
-                if (mCursorRow + 1 < mBottomMargin) {
-                    mCursorRow++;
-                } else {
-                    scroll();
-                }
-            }
-        }
-
-        if (mInsertMode) { // Move character to right one space
-            int destCol = mCursorCol + 1;
-            if (destCol < mColumns) {
-                mScreen.blockCopy(mCursorCol, mCursorRow, mColumns - destCol,
-                        1, destCol, mCursorRow);
-            }
-        }
-
-        mScreen.set(mCursorCol, mCursorRow, b, getForeColor(), getBackColor());
-
-        if (autoWrap) {
-            mAboutToAutoWrap = (mCursorCol == mColumns - 1);
-        }
-
-        mCursorCol = Math.min(mCursorCol + 1, mColumns - 1);
-    }
-
-    private void setCursorRow(int row) {
-        mCursorRow = row;
-        mAboutToAutoWrap = false;
-    }
-
-    private void setCursorCol(int col) {
-        mCursorCol = col;
-        mAboutToAutoWrap = false;
-    }
-
-    private void setCursorRowCol(int row, int col) {
-        mCursorRow = Math.min(row, mRows-1);
-        mCursorCol = Math.min(col, mColumns-1);
-        mAboutToAutoWrap = false;
-    }
-
-    /**
-     * Reset the terminal emulator to its initial state.
-     */
-    public void reset() {
-        mCursorRow = 0;
-        mCursorCol = 0;
-        mArgIndex = 0;
-        mContinueSequence = false;
-        mEscapeState = ESC_NONE;
-        mSavedCursorRow = 0;
-        mSavedCursorCol = 0;
-        mDecFlags = 0;
-        mSavedDecFlags = 0;
-        mInsertMode = false;
-        mAutomaticNewlineMode = false;
-        mTopMargin = 0;
-        mBottomMargin = mRows;
-        mAboutToAutoWrap = false;
-        mForeColor = 7;
-        mBackColor = 0;
-        mInverseColors = false;
-        mbKeypadApplicationMode = false;
-        mAlternateCharSet = false;
-        // mProcessedCharCount is preserved unchanged.
-        setDefaultTabStops();
-        blockClear(0, 0, mColumns, mRows);
-    }
-
-    public String getTranscriptText() {
-        return mScreen.getTranscriptText();
-    }
-}
-
-/**
- * Text renderer interface
- */
-
-interface TextRenderer {
-    int getCharacterWidth();
-    int getCharacterHeight();
-    void drawTextRun(Canvas canvas, float x, float y,
-            int lineOffset, char[] text,
-            int index, int count, boolean cursor, int foreColor, int backColor);
-}
-
-abstract class BaseTextRenderer implements TextRenderer {
-    protected int[] mForePaint = {
-            0xff000000, // Black
-            0xffff0000, // Red
-            0xff00ff00, // green
-            0xffffff00, // yellow
-            0xff0000ff, // blue
-            0xffff00ff, // magenta
-            0xff00ffff, // cyan
-            0xffffffff  // white -- is overridden by constructor
-    };
-    protected int[] mBackPaint = {
-            0xff000000, // Black -- is overridden by constructor
-            0xffcc0000, // Red
-            0xff00cc00, // green
-            0xffcccc00, // yellow
-            0xff0000cc, // blue
-            0xffff00cc, // magenta
-            0xff00cccc, // cyan
-            0xffffffff  // white
-    };
-    protected final static int mCursorPaint = 0xff808080;
-
-    public BaseTextRenderer(int forePaintColor, int backPaintColor) {
-        mForePaint[7] = forePaintColor;
-        mBackPaint[0] = backPaintColor;
-
-    }
-}
-
-class Bitmap4x8FontRenderer extends BaseTextRenderer {
-    private final static int kCharacterWidth = 4;
-    private final static int kCharacterHeight = 8;
-    private Bitmap mFont;
-    private int mCurrentForeColor;
-    private int mCurrentBackColor;
-    private float[] mColorMatrix;
-    private Paint mPaint;
-    private static final float BYTE_SCALE = 1.0f / 255.0f;
-
-    public Bitmap4x8FontRenderer(Resources resources,
-            int forePaintColor, int backPaintColor) {
-        super(forePaintColor, backPaintColor);
-        mFont = BitmapFactory.decodeResource(resources,
-                R.drawable.atari_small);
-        mPaint = new Paint();
-        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
-    }
-
-    public int getCharacterWidth() {
-        return kCharacterWidth;
-    }
-
-    public int getCharacterHeight() {
-        return kCharacterHeight;
-    }
-
-    public void drawTextRun(Canvas canvas, float x, float y,
-            int lineOffset, char[] text, int index, int count,
-            boolean cursor, int foreColor, int backColor) {
-        setColorMatrix(mForePaint[foreColor & 7],
-                cursor ? mCursorPaint : mBackPaint[backColor & 7]);
-        int destX = (int) x + kCharacterWidth * lineOffset;
-        int destY = (int) y;
-        Rect srcRect = new Rect();
-        Rect destRect = new Rect();
-        destRect.top = (destY - kCharacterHeight);
-        destRect.bottom = destY;
-        for(int i = 0; i < count; i++) {
-            char c = text[i + index];
-            if ((cursor || (c != 32)) && (c < 128)) {
-                int cellX = c & 31;
-                int cellY = (c >> 5) & 3;
-                int srcX = cellX * kCharacterWidth;
-                int srcY = cellY * kCharacterHeight;
-                srcRect.set(srcX, srcY,
-                        srcX + kCharacterWidth, srcY + kCharacterHeight);
-                destRect.left = destX;
-                destRect.right = destX + kCharacterWidth;
-                canvas.drawBitmap(mFont, srcRect, destRect, mPaint);
-            }
-            destX += kCharacterWidth;
-        }
-    }
-
-    private void setColorMatrix(int foreColor, int backColor) {
-        if ((foreColor != mCurrentForeColor)
-                || (backColor != mCurrentBackColor)
-                || (mColorMatrix == null)) {
-            mCurrentForeColor = foreColor;
-            mCurrentBackColor = backColor;
-            if (mColorMatrix == null) {
-                mColorMatrix = new float[20];
-                mColorMatrix[18] = 1.0f; // Just copy Alpha
-            }
-            for (int component = 0; component < 3; component++) {
-                int rightShift = (2 - component) << 3;
-                int fore = 0xff & (foreColor >> rightShift);
-                int back = 0xff & (backColor >> rightShift);
-                int delta = back - fore;
-                mColorMatrix[component * 6] = delta * BYTE_SCALE;
-                mColorMatrix[component * 5 + 4] = fore;
-            }
-            mPaint.setColorFilter(new ColorMatrixColorFilter(mColorMatrix));
-        }
-    }
-}
-
-class PaintRenderer extends BaseTextRenderer {
-    public PaintRenderer(int fontSize, int forePaintColor, int backPaintColor) {
-        super(forePaintColor, backPaintColor);
-        mTextPaint = new Paint();
-        mTextPaint.setTypeface(Typeface.MONOSPACE);
-        mTextPaint.setAntiAlias(true);
-        mTextPaint.setTextSize(fontSize);
-
-        mCharHeight = (int) Math.ceil(mTextPaint.getFontSpacing());
-        mCharAscent = (int) Math.ceil(mTextPaint.ascent());
-        mCharDescent = mCharHeight + mCharAscent;
-        mCharWidth = (int) mTextPaint.measureText(EXAMPLE_CHAR, 0, 1);
-    }
-
-    public void drawTextRun(Canvas canvas, float x, float y, int lineOffset,
-            char[] text, int index, int count,
-            boolean cursor, int foreColor, int backColor) {
-        if (cursor) {
-            mTextPaint.setColor(mCursorPaint);
-        } else {
-            mTextPaint.setColor(mBackPaint[backColor & 0x7]);
-        }
-        float left = x + lineOffset * mCharWidth;
-        canvas.drawRect(left, y + mCharAscent,
-                left + count * mCharWidth, y + mCharDescent,
-                mTextPaint);
-        boolean bold = ( foreColor & 0x8 ) != 0;
-        boolean underline = (backColor & 0x8) != 0;
-        if (bold) {
-            mTextPaint.setFakeBoldText(true);
-        }
-        if (underline) {
-            mTextPaint.setUnderlineText(true);
-        }
-        mTextPaint.setColor(mForePaint[foreColor & 0x7]);
-        canvas.drawText(text, index, count, left, y, mTextPaint);
-        if (bold) {
-            mTextPaint.setFakeBoldText(false);
-        }
-        if (underline) {
-            mTextPaint.setUnderlineText(false);
-        }
-    }
-
-    public int getCharacterHeight() {
-        return mCharHeight;
-    }
-
-    public int getCharacterWidth() {
-        return mCharWidth;
-    }
-
-
-    private Paint mTextPaint;
-    private int mCharWidth;
-    private int mCharHeight;
-    private int mCharAscent;
-    private int mCharDescent;
-    private static final char[] EXAMPLE_CHAR = {'X'};
-    }
-
-/**
- * A multi-thread-safe produce-consumer byte array.
- * Only allows one producer and one consumer.
- */
-
-class ByteQueue {
-    public ByteQueue(int size) {
-        mBuffer = new byte[size];
-    }
-
-    public int getBytesAvailable() {
-        synchronized(this) {
-            return mStoredBytes;
-        }
-    }
-
-    public int read(byte[] buffer, int offset, int length)
-        throws InterruptedException {
-        if (length + offset > buffer.length) {
-            throw
-                new IllegalArgumentException("length + offset > buffer.length");
-        }
-        if (length < 0) {
-            throw
-            new IllegalArgumentException("length < 0");
-
-        }
-        if (length == 0) {
-            return 0;
-        }
-        synchronized(this) {
-            while (mStoredBytes == 0) {
-                wait();
-            }
-            int totalRead = 0;
-            int bufferLength = mBuffer.length;
-            boolean wasFull = bufferLength == mStoredBytes;
-            while (length > 0 && mStoredBytes > 0) {
-                int oneRun = Math.min(bufferLength - mHead, mStoredBytes);
-                int bytesToCopy = Math.min(length, oneRun);
-                System.arraycopy(mBuffer, mHead, buffer, offset, bytesToCopy);
-                mHead += bytesToCopy;
-                if (mHead >= bufferLength) {
-                    mHead = 0;
-                }
-                mStoredBytes -= bytesToCopy;
-                length -= bytesToCopy;
-                offset += bytesToCopy;
-                totalRead += bytesToCopy;
-            }
-            if (wasFull) {
-                notify();
-            }
-            return totalRead;
-        }
-    }
-
-    public void write(byte[] buffer, int offset, int length)
-    throws InterruptedException {
-        if (length + offset > buffer.length) {
-            throw
-                new IllegalArgumentException("length + offset > buffer.length");
-        }
-        if (length < 0) {
-            throw
-            new IllegalArgumentException("length < 0");
-
-        }
-        if (length == 0) {
-            return;
-        }
-        synchronized(this) {
-            int bufferLength = mBuffer.length;
-            boolean wasEmpty = mStoredBytes == 0;
-            while (length > 0) {
-                while(bufferLength == mStoredBytes) {
-                    wait();
-                }
-                int tail = mHead + mStoredBytes;
-                int oneRun;
-                if (tail >= bufferLength) {
-                    tail = tail - bufferLength;
-                    oneRun = mHead - tail;
-                } else {
-                    oneRun = bufferLength - tail;
-                }
-                int bytesToCopy = Math.min(oneRun, length);
-                System.arraycopy(buffer, offset, mBuffer, tail, bytesToCopy);
-                offset += bytesToCopy;
-                mStoredBytes += bytesToCopy;
-                length -= bytesToCopy;
-            }
-            if (wasEmpty) {
-                notify();
-            }
-        }
-    }
-
-    private byte[] mBuffer;
-    private int mHead;
-    private int mStoredBytes;
-}
-/**
- * A view on a transcript and a terminal emulator. Displays the text of the
- * transcript and the current cursor position of the terminal emulator.
- */
-class EmulatorView extends View implements GestureDetector.OnGestureListener {
-
-    /**
-     * We defer some initialization until we have been layed out in the view
-     * hierarchy. The boolean tracks when we know what our size is.
-     */
-    private boolean mKnownSize;
-
-    /**
-     * Our transcript. Contains the screen and the transcript.
-     */
-    private TranscriptScreen mTranscriptScreen;
-
-    /**
-     * Number of rows in the transcript.
-     */
-    private static final int TRANSCRIPT_ROWS = 10000;
-
-    /**
-     * Total width of each character, in pixels
-     */
-    private int mCharacterWidth;
-
-    /**
-     * Total height of each character, in pixels
-     */
-    private int mCharacterHeight;
-
-    /**
-     * Used to render text
-     */
-    private TextRenderer mTextRenderer;
-
-    /**
-     * Text size. Zero means 4 x 8 font.
-     */
-    private int mTextSize;
-
-    /**
-     * Foreground color.
-     */
-    private int mForeground;
-
-    /**
-     * Background color.
-     */
-    private int mBackground;
-
-    /**
-     * Used to paint the cursor
-     */
-    private Paint mCursorPaint;
-
-    private Paint mBackgroundPaint;
-
-    /**
-     * Our terminal emulator. We use this to get the current cursor position.
-     */
-    private TerminalEmulator mEmulator;
-
-    /**
-     * The number of rows of text to display.
-     */
-    private int mRows;
-
-    /**
-     * The number of columns of text to display.
-     */
-    private int mColumns;
-
-    /**
-     * The number of columns that are visible on the display.
-     */
-
-    private int mVisibleColumns;
-
-    /**
-     * The top row of text to display. Ranges from -activeTranscriptRows to 0
-     */
-    private int mTopRow;
-
-    private int mLeftColumn;
-
-    private FileDescriptor mTermFd;
-    /**
-     * Used to receive data from the remote process.
-     */
-    private FileInputStream mTermIn;
-
-    private FileOutputStream mTermOut;
-
-    private ByteQueue mByteQueue;
-
-    /**
-     * Used to temporarily hold data received from the remote process. Allocated
-     * once and used permanently to minimize heap thrashing.
-     */
-    private byte[] mReceiveBuffer;
-
-    /**
-     * Our private message id, which we use to receive new input from the
-     * remote process.
-     */
-    private static final int UPDATE = 1;
-
-    /**
-     * Thread that polls for input from the remote process
-     */
-
-    private Thread mPollingThread;
-
-    private GestureDetector mGestureDetector;
-    private float mScrollRemainder;
-    private TermKeyListener mKeyListener;
-
-    /**
-     * Our message handler class. Implements a periodic callback.
-     */
-    private final Handler mHandler = new Handler() {
-        /**
-         * Handle the callback message. Call our enclosing class's update
-         * method.
-         *
-         * @param msg The callback message.
-         */
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == UPDATE) {
-                update();
-            }
-        }
-    };
-
-    public EmulatorView(Context context) {
-        super(context);
-        commonConstructor(context);
-    }
-
-    public void register(TermKeyListener listener) {
-        mKeyListener = listener;
-    }
-
-    public void setColors(int foreground, int background) {
-        mForeground = foreground;
-        mBackground = background;
-        updateText();
-    }
-
-    public String getTranscriptText() {
-        return mEmulator.getTranscriptText();
-    }
-
-    public void resetTerminal() {
-        mEmulator.reset();
-        invalidate();
-    }
-
-    @Override
-    public boolean onCheckIsTextEditor() {
-        return true;
-    }
-
-    @Override
-    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        return new BaseInputConnection(this, false) {
-
-            @Override
-            public boolean beginBatchEdit() {
-                return true;
-            }
-
-            @Override
-            public boolean clearMetaKeyStates(int states) {
-                return true;
-            }
-
-            @Override
-            public boolean commitCompletion(CompletionInfo text) {
-                return true;
-            }
-
-            @Override
-            public boolean commitText(CharSequence text, int newCursorPosition) {
-                sendText(text);
-                return true;
-            }
-
-            @Override
-            public boolean deleteSurroundingText(int leftLength, int rightLength) {
-                return true;
-            }
-
-            @Override
-            public boolean endBatchEdit() {
-                return true;
-            }
-
-            @Override
-            public boolean finishComposingText() {
-                return true;
-            }
-
-            @Override
-            public int getCursorCapsMode(int reqModes) {
-                return 0;
-            }
-
-            @Override
-            public ExtractedText getExtractedText(ExtractedTextRequest request,
-                    int flags) {
-                return null;
-            }
-
-            @Override
-            public CharSequence getTextAfterCursor(int n, int flags) {
-                return null;
-            }
-
-            @Override
-            public CharSequence getTextBeforeCursor(int n, int flags) {
-                return null;
-            }
-
-            @Override
-            public boolean performEditorAction(int actionCode) {
-                if(actionCode == EditorInfo.IME_ACTION_UNSPECIFIED) {
-                    // The "return" key has been pressed on the IME.
-                    sendText("\n");
-                    return true;
-                }
-                return false;
-            }
-
-            @Override
-            public boolean performContextMenuAction(int id) {
-                return true;
-            }
-
-            @Override
-            public boolean performPrivateCommand(String action, Bundle data) {
-                return true;
-            }
-
-            @Override
-            public boolean sendKeyEvent(KeyEvent event) {
-                if (event.getAction() == KeyEvent.ACTION_DOWN) {
-                    switch(event.getKeyCode()) {
-                    case KeyEvent.KEYCODE_DEL:
-                        sendChar(127);
-                        break;
-                    }
-                }
-                return true;
-            }
-
-            @Override
-            public boolean setComposingText(CharSequence text, int newCursorPosition) {
-                return true;
-            }
-
-            @Override
-            public boolean setSelection(int start, int end) {
-                return true;
-            }
-
-            private void sendChar(int c) {
-                try {
-                    mapAndSend(c);
-                } catch (IOException ex) {
-
-                }
-            }
-            private void sendText(CharSequence text) {
-                int n = text.length();
-                try {
-                    for(int i = 0; i < n; i++) {
-                        char c = text.charAt(i);
-                        mapAndSend(c);
-                    }
-                } catch (IOException e) {
-                }
-            }
-
-            private void mapAndSend(int c) throws IOException {
-                mTermOut.write(
-                        mKeyListener.mapControlChar(c));
-            }
-        };
-    }
-
-    public boolean getKeypadApplicationMode() {
-        return mEmulator.getKeypadApplicationMode();
-    }
-
-    public EmulatorView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public EmulatorView(Context context, AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a =
-                context.obtainStyledAttributes(android.R.styleable.View);
-        initializeScrollbars(a);
-        a.recycle();
-        commonConstructor(context);
-    }
-
-    private void commonConstructor(Context context) {
-        mTextRenderer = null;
-        mCursorPaint = new Paint();
-        mCursorPaint.setARGB(255,128,128,128);
-        mBackgroundPaint = new Paint();
-        mTopRow = 0;
-        mLeftColumn = 0;
-        mGestureDetector = new GestureDetector(context, this, null);
-        mGestureDetector.setIsLongpressEnabled(false);
-        setVerticalScrollBarEnabled(true);
-    }
-
-    @Override
-    protected int computeVerticalScrollRange() {
-        return mTranscriptScreen.getActiveRows();
-    }
-
-    @Override
-    protected int computeVerticalScrollExtent() {
-        return mRows;
-    }
-
-    @Override
-    protected int computeVerticalScrollOffset() {
-        return mTranscriptScreen.getActiveRows() + mTopRow - mRows;
-    }
-
-    /**
-     * Call this to initialize the view.
-     *
-     * @param termFd the file descriptor
-     * @param termOut the output stream for the pseudo-teletype
-     */
-    public void initialize(FileDescriptor termFd, FileOutputStream termOut) {
-        mTermOut = termOut;
-        mTermFd = termFd;
-        mTextSize = 10;
-        mForeground = Term.WHITE;
-        mBackground = Term.BLACK;
-        updateText();
-        mTermIn = new FileInputStream(mTermFd);
-        mReceiveBuffer = new byte[4 * 1024];
-        mByteQueue = new ByteQueue(4 * 1024);
-    }
-
-    /**
-     * Accept a sequence of bytes (typically from the pseudo-tty) and process
-     * them.
-     *
-     * @param buffer a byte array containing bytes to be processed
-     * @param base the index of the first byte in the buffer to process
-     * @param length the number of bytes to process
-     */
-    public void append(byte[] buffer, int base, int length) {
-        mEmulator.append(buffer, base, length);
-        ensureCursorVisible();
-        invalidate();
-    }
-
-    /**
-     * Page the terminal view (scroll it up or down by delta screenfulls.)
-     *
-     * @param delta the number of screens to scroll. Positive means scroll down,
-     *        negative means scroll up.
-     */
-    public void page(int delta) {
-        mTopRow =
-                Math.min(0, Math.max(-(mTranscriptScreen
-                        .getActiveTranscriptRows()), mTopRow + mRows * delta));
-        invalidate();
-    }
-
-    /**
-     * Page the terminal view horizontally.
-     *
-     * @param deltaColumns the number of columns to scroll. Positive scrolls to
-     *        the right.
-     */
-    public void pageHorizontal(int deltaColumns) {
-        mLeftColumn =
-                Math.max(0, Math.min(mLeftColumn + deltaColumns, mColumns
-                        - mVisibleColumns));
-        invalidate();
-    }
-
-    /**
-     * Sets the text size, which in turn sets the number of rows and columns
-     *
-     * @param fontSize the new font size, in pixels.
-     */
-    public void setTextSize(int fontSize) {
-        mTextSize = fontSize;
-        updateText();
-    }
-
-    // Begin GestureDetector.OnGestureListener methods
-
-    public boolean onSingleTapUp(MotionEvent e) {
-        return true;
-    }
-
-    public void onLongPress(MotionEvent e) {
-    }
-
-    public boolean onScroll(MotionEvent e1, MotionEvent e2,
-            float distanceX, float distanceY) {
-        distanceY += mScrollRemainder;
-        int deltaRows = (int) (distanceY / mCharacterHeight);
-        mScrollRemainder = distanceY - deltaRows * mCharacterHeight;
-        mTopRow =
-            Math.min(0, Math.max(-(mTranscriptScreen
-                    .getActiveTranscriptRows()), mTopRow + deltaRows));
-        invalidate();
-
-        return true;
-   }
-
-    public void onSingleTapConfirmed(MotionEvent e) {
-    }
-
-    public boolean onJumpTapDown(MotionEvent e1, MotionEvent e2) {
-       // Scroll to bottom
-       mTopRow = 0;
-       invalidate();
-       return true;
-    }
-
-    public boolean onJumpTapUp(MotionEvent e1, MotionEvent e2) {
-        // Scroll to top
-        mTopRow = -mTranscriptScreen.getActiveTranscriptRows();
-        invalidate();
-        return true;
-    }
-
-    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
-            float velocityY) {
-        // TODO: add animation man's (non animated) fling
-        mScrollRemainder = 0.0f;
-        onScroll(e1, e2, 2 * velocityX, -2 * velocityY);
-        return true;
-    }
-
-    public void onShowPress(MotionEvent e) {
-    }
-
-    public boolean onDown(MotionEvent e) {
-        mScrollRemainder = 0.0f;
-        return true;
-    }
-
-    // End GestureDetector.OnGestureListener methods
-
-    @Override public boolean onTouchEvent(MotionEvent ev) {
-        return mGestureDetector.onTouchEvent(ev);
-    }
-
-    private void updateText() {
-        if (mTextSize > 0) {
-            mTextRenderer = new PaintRenderer(mTextSize, mForeground,
-                    mBackground);
-        }
-        else {
-            mTextRenderer = new Bitmap4x8FontRenderer(getResources(),
-                    mForeground, mBackground);
-        }
-        mBackgroundPaint.setColor(mBackground);
-        mCharacterWidth = mTextRenderer.getCharacterWidth();
-        mCharacterHeight = mTextRenderer.getCharacterHeight();
-
-        if (mKnownSize) {
-            updateSize(getWidth(), getHeight());
-        }
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        updateSize(w, h);
-        if (!mKnownSize) {
-            mKnownSize = true;
-
-            // Set up a thread to read input from the
-            // pseudo-teletype:
-
-            mPollingThread = new Thread(new Runnable() {
-
-                public void run() {
-                    try {
-                        while(true) {
-                            int read = mTermIn.read(mBuffer);
-                            mByteQueue.write(mBuffer, 0, read);
-                            mHandler.sendMessage(
-                                    mHandler.obtainMessage(UPDATE));
-                        }
-                    } catch (IOException e) {
-                    } catch (InterruptedException e) {
-                    }
-                }
-                private byte[] mBuffer = new byte[4096];
-            });
-            mPollingThread.setName("Input reader");
-            mPollingThread.start();
-        }
-    }
-
-    private void updateSize(int w, int h) {
-        mColumns = w / mCharacterWidth;
-        mRows = h / mCharacterHeight;
-
-        // Inform the attached pty of our new size:
-        Exec.setPtyWindowSize(mTermFd, mRows, mColumns, w, h);
-
-
-        if (mTranscriptScreen != null) {
-            mEmulator.updateSize(mColumns, mRows);
-        } else {
-            mTranscriptScreen =
-                    new TranscriptScreen(mColumns, TRANSCRIPT_ROWS, mRows, 0, 7);
-            mEmulator =
-                    new TerminalEmulator(mTranscriptScreen, mColumns, mRows,
-                            mTermOut);
-        }
-
-        // Reset our paging:
-        mTopRow = 0;
-        mLeftColumn = 0;
-
-        invalidate();
-    }
-
-    void updateSize() {
-        if (mKnownSize) {
-            updateSize(getWidth(), getHeight());
-        }
-    }
-
-    /**
-     * Look for new input from the ptty, send it to the terminal emulator.
-     */
-    private void update() {
-        int bytesAvailable = mByteQueue.getBytesAvailable();
-        int bytesToRead = Math.min(bytesAvailable, mReceiveBuffer.length);
-        try {
-            int bytesRead = mByteQueue.read(mReceiveBuffer, 0, bytesToRead);
-            append(mReceiveBuffer, 0, bytesRead);
-        } catch (InterruptedException e) {
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        int w = getWidth();
-        int h = getHeight();
-        canvas.drawRect(0, 0, w, h, mBackgroundPaint);
-        mVisibleColumns = w / mCharacterWidth;
-        float x = -mLeftColumn * mCharacterWidth;
-        float y = mCharacterHeight;
-        int endLine = mTopRow + mRows;
-        int cx = mEmulator.getCursorCol();
-        int cy = mEmulator.getCursorRow();
-        for (int i = mTopRow; i < endLine; i++) {
-            int cursorX = -1;
-            if (i == cy) {
-                cursorX = cx;
-            }
-            mTranscriptScreen.drawText(i, canvas, x, y, mTextRenderer, cursorX);
-            y += mCharacterHeight;
-        }
-    }
-
-    private void ensureCursorVisible() {
-        mTopRow = 0;
-        if (mVisibleColumns > 0) {
-            int cx = mEmulator.getCursorCol();
-            int visibleCursorX = mEmulator.getCursorCol() - mLeftColumn;
-            if (visibleCursorX < 0) {
-                mLeftColumn = cx;
-            } else if (visibleCursorX >= mVisibleColumns) {
-                mLeftColumn = (cx - mVisibleColumns) + 1;
-            }
-        }
-    }
-}
-
-
-/**
- * An ASCII key listener. Supports control characters and escape. Keeps track of
- * the current state of the alt, shift, and control keys.
- */
-class TermKeyListener {
-    /**
-     * The state engine for a modifier key. Can be pressed, released, locked,
-     * and so on.
-     *
-     */
-    private class ModifierKey {
-
-        private int mState;
-
-        private static final int UNPRESSED = 0;
-
-        private static final int PRESSED = 1;
-
-        private static final int RELEASED = 2;
-
-        private static final int USED = 3;
-
-        private static final int LOCKED = 4;
-
-        /**
-         * Construct a modifier key. UNPRESSED by default.
-         *
-         */
-        public ModifierKey() {
-            mState = UNPRESSED;
-        }
-
-        public void onPress() {
-            switch (mState) {
-            case PRESSED:
-                // This is a repeat before use
-                break;
-            case RELEASED:
-                mState = LOCKED;
-                break;
-            case USED:
-                // This is a repeat after use
-                break;
-            case LOCKED:
-                mState = UNPRESSED;
-                break;
-            default:
-                mState = PRESSED;
-                break;
-            }
-        }
-
-        public void onRelease() {
-            switch (mState) {
-            case USED:
-                mState = UNPRESSED;
-                break;
-            case PRESSED:
-                mState = RELEASED;
-                break;
-            default:
-                // Leave state alone
-                break;
-            }
-        }
-
-        public void adjustAfterKeypress() {
-            switch (mState) {
-            case PRESSED:
-                mState = USED;
-                break;
-            case RELEASED:
-                mState = UNPRESSED;
-                break;
-            default:
-                // Leave state alone
-                break;
-            }
-        }
-
-        public boolean isActive() {
-            return mState != UNPRESSED;
-        }
-    }
-
-    private ModifierKey mAltKey = new ModifierKey();
-
-    private ModifierKey mCapKey = new ModifierKey();
-
-    private ModifierKey mControlKey = new ModifierKey();
-
-    /**
-     * Construct a term key listener.
-     *
-     */
-    public TermKeyListener() {
-    }
-
-    public void handleControlKey(boolean down) {
-        if (down) {
-            mControlKey.onPress();
-        } else {
-            mControlKey.onRelease();
-        }
-    }
-
-    public int mapControlChar(int ch) {
-        int result = ch;
-        if (mControlKey.isActive()) {
-            // Search is the control key.
-            if (result >= 'a' && result <= 'z') {
-                result = (char) (result - 'a' + '\001');
-            } else if (result == ' ') {
-                result = 0;
-            } else if ((result == '[') || (result == '1')) {
-                result = 27;
-            } else if ((result == '\\') || (result == '.')) {
-                result = 28;
-            } else if ((result == ']') || (result == '0')) {
-                result = 29;
-            } else if ((result == '^') || (result == '6')) {
-                result = 30; // control-^
-            } else if ((result == '_') || (result == '5')) {
-                result = 31;
-            }
-        }
-
-        if (result > -1) {
-            mAltKey.adjustAfterKeypress();
-            mCapKey.adjustAfterKeypress();
-            mControlKey.adjustAfterKeypress();
-        }
-        return result;
-    }
-
-    /**
-     * Handle a keyDown event.
-     *
-     * @param keyCode the keycode of the keyDown event
-     * @return the ASCII byte to transmit to the pseudo-teletype, or -1 if this
-     *         event does not produce an ASCII byte.
-     */
-    public int keyDown(int keyCode, KeyEvent event) {
-        int result = -1;
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_ALT_RIGHT:
-        case KeyEvent.KEYCODE_ALT_LEFT:
-            mAltKey.onPress();
-            break;
-
-        case KeyEvent.KEYCODE_SHIFT_LEFT:
-        case KeyEvent.KEYCODE_SHIFT_RIGHT:
-            mCapKey.onPress();
-            break;
-
-        case KeyEvent.KEYCODE_ENTER:
-            // Convert newlines into returns. The vt100 sends a
-            // '\r' when the 'Return' key is pressed, but our
-            // KeyEvent translates this as a '\n'.
-            result = '\r';
-            break;
-
-        case KeyEvent.KEYCODE_DEL:
-            // Convert DEL into 127 (instead of 8)
-            result = 127;
-            break;
-
-        default: {
-            result = event.getUnicodeChar(
-                   (mCapKey.isActive() ? KeyEvent.META_SHIFT_ON : 0) |
-                   (mAltKey.isActive() ? KeyEvent.META_ALT_ON : 0));
-            break;
-            }
-        }
-
-        result = mapControlChar(result);
-
-        return result;
-    }
-
-    /**
-     * Handle a keyUp event.
-     *
-     * @param keyCode the keyCode of the keyUp event
-     */
-    public void keyUp(int keyCode) {
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_ALT_LEFT:
-        case KeyEvent.KEYCODE_ALT_RIGHT:
-            mAltKey.onRelease();
-            break;
-        case KeyEvent.KEYCODE_SHIFT_LEFT:
-        case KeyEvent.KEYCODE_SHIFT_RIGHT:
-            mCapKey.onRelease();
-            break;
-        default:
-            // Ignore other keyUps
-            break;
-        }
-    }
-}
diff --git a/apps/Term/src/com/android/term/TermPreferences.java b/apps/Term/src/com/android/term/TermPreferences.java
deleted file mode 100644 (file)
index 3102963..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.term;
-
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-
-public class TermPreferences extends PreferenceActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Load the preferences from an XML resource
-        addPreferencesFromResource(R.xml.preferences);
-    }
-
-}