Merge "Add unit tests for some text-message functions" into studio-1.4-dev
diff --git a/Makefile b/Makefile
index 2a0e132..c4f3e40 100644
--- a/Makefile
+++ b/Makefile
@@ -50,6 +50,7 @@
 BUILD_HOST_EXECUTABLE     := $(BUILD_SYSTEM)/host_executable.make
 BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/host_static_library.make
 BUILD_HOST_SHARED_LIBRARY := $(BUILD_SYSTEM)/host_shared_library.make
+PREBUILT_STATIC_LIBRARY := $(BUILD_SYSTEM)/prebuilt_static_library.make
 
 DEPENDENCY_DIRS :=
 
diff --git a/Makefile.android b/Makefile.android
index 26d62e3..b6e149b 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -184,7 +184,8 @@
     $(eval LOCAL_NO_DEFAULT_COMPILER_FLAGS := true) \
     $(eval LOCAL_MODULE := $1) \
     $(eval LOCAL_MODULE_CLASS := STATIC_LIBRARIES) \
-    $(eval LOCAL_MODULE_BITS := 32)
+    $(eval LOCAL_MODULE_BITS := 32) \
+    $(eval LOCAL_BUILD_FILE := $(BUILD_HOST_STATIC_LIBRARY))
 
 start-emulator64-library = \
     $(call start-emulator-library, $1) \
@@ -193,13 +194,25 @@
 # Used with start-emulator-library
 end-emulator-library = \
     $(eval $(end-emulator-module-ev)) \
-    $(call include-if-bitness-$(LOCAL_MODULE_BITS), $(BUILD_HOST_STATIC_LIBRARY))
+
+define-emulator-prebuilt-library = \
+    $(call start-emulator-library,$1) \
+    $(eval LOCAL_BUILD_FILE := $(PREBUILT_STATIC_LIBRARY)) \
+    $(eval LOCAL_SRC_FILES := $2) \
+    $(eval $(end-emulator-module-ev)) \
+
+define-emulator64-prebuilt-library = \
+    $(call start-emulator64-library,$1) \
+    $(eval LOCAL_BUILD_FILE := $(PREBUILT_STATIC_LIBRARY)) \
+    $(eval LOCAL_SRC_FILES := $2) \
+    $(eval $(end-emulator-module-ev)) \
 
 # A variant of start-emulator-library to start the definition of a host
 # program instead. Use with end-emulator-program
 start-emulator-program = \
     $(call start-emulator-library,$1) \
-    $(eval LOCAL_MODULE_CLASS := EXECUTABLES)
+    $(eval LOCAL_MODULE_CLASS := EXECUTABLES) \
+    $(eval LOCAL_BUILD_FILE := $(BUILD_HOST_EXECUTABLE))
 
 start-emulator64-program = \
     $(call start-emulator-program, $1) \
@@ -209,7 +222,6 @@
 end-emulator-program = \
     $(eval LOCAL_LDLIBS += $(QEMU_SYSTEM_LDLIBS)) \
     $(eval $(end-emulator-module-ev)) \
-    $(call include-if-bitness-$(LOCAL_MODULE_BITS), $(BUILD_HOST_EXECUTABLE))
 
 define end-emulator-module-ev
 LOCAL_CC := $$(call my-host-tool,CC)
@@ -241,6 +253,7 @@
     -m$$(LOCAL_MODULE_BITS) \
     $$(filter-out -m32 -m64, $$(LOCAL_LDFLAGS))
 
+$$(call include-if-bitness-$$(LOCAL_MODULE_BITS), $$(LOCAL_BUILD_FILE))
 endef
 
 # The common libraries
diff --git a/Makefile.common b/Makefile.common
index a6ebd80..4bbc7a0 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -46,6 +46,8 @@
   $(eval LOCAL_GENERATED_SOURCES += $(QEMU_HW_CONFIG_DEFS_H))\
   $(eval LOCAL_C_INCLUDES += $(QEMU_HW_CONFIG_DEFS_INCLUDES))
 
+EMULATOR_USE_SDL2 := $(strip $(filter true,$(EMULATOR_USE_SDL2)))
+
 ##############################################################################
 ##############################################################################
 ###
@@ -232,6 +234,13 @@
 common_LOCAL_SRC_FILES =
 common_LOCAL_CFLAGS += $(EMULATOR_COMMON_CFLAGS)
 
+EMULATOR_LIBUI_CFLAGS :=
+EMULATOR_LIBUI_LDLIBS :=
+EMULATOR_LIBUI_LDFLAGS :=
+EMULATOR_LIBUI_LDFLAGS_64 :=
+EMULATOR_LIBUI_STATIC_LIBRARIES :=
+EMULATOR_LIBUI_STATIC_LIBRARIES_64 :=
+
 ###########################################################
 # Libpng configuration
 #
@@ -248,22 +257,30 @@
 # SDL-related definitions
 #
 
-SDL2_DIR := distrib/sdl2-2.0.3
-include $(LOCAL_PATH)/$(SDL2_DIR)/sources.make
+ifdef EMULATOR_USE_SDL2
+    SDL2_DIR := distrib/sdl2-2.0.3
+    include $(LOCAL_PATH)/$(SDL2_DIR)/sources.make
 
-SDL2_STATIC_LIBRARIES := emulator_libSDL2
-SDL2_STATIC_LIBRARIES_64 := emulator_lib64SDL2
+    SDL2_STATIC_LIBRARIES := emulator_libSDL2
+    SDL2_STATIC_LIBRARIES_64 := emulator_lib64SDL2
 
-EMULATOR_LIBUI_CFLAGS += $(SDL2_CFLAGS) $(foreach inc,$(SDL2_INCLUDES),-I$(inc))
-EMULATOR_LIBUI_LDLIBS += $(SDL2_LDLIBS)
-EMULATOR_SDL_STATIC_LIBRARIES := $(SDL2_STATIC_LIBRARIES)
-EMULATOR_SDL_STATIC_LIBRARIES_64 := $(SDL2_STATIC_LIBRARIES_64)
-EMULATOR_SDL_LDLIBS := $(SDL2_LDLIBS)
+    EMULATOR_LIBUI_CFLAGS += $(SDL2_CFLAGS) $(foreach inc,$(SDL2_INCLUDES),-I$(inc))
+    EMULATOR_LIBUI_LDLIBS += $(SDL2_LDLIBS)
+    EMULATOR_LIBUI_STATIC_LIBRARIES := $(SDL2_STATIC_LIBRARIES)
+    EMULATOR_LIBUI_STATIC_LIBRARIES_64 := $(SDL2_STATIC_LIBRARIES_64)
+    EMULATOR_SDL_LDLIBS := $(SDL2_LDLIBS)
 
-# The following is needed by SDL_LoadObject
-ifneq ($(HOST_OS),windows)
-    EMULATOR_LIBUI_LDLIBS += -ldl
-endif
+    ifeq ($(HOST_OS),windows)
+        # Special exception for Windows: -lmingw32 must appear before libSDLmain
+        # on the link command-line, because it depends on _WinMain@16 which is
+        # exported by the latter.
+        EMULATOR_LIBUI_LDFLAGS += -lmingw32
+        EMULATOR_LIBUI_LDFLAGS_64 += -lmingw32
+    else
+        # The following is needed by SDL_LoadObject
+        EMULATOR_LIBUI_LDLIBS += -ldl
+    endif
+endif  # EMULATOR_USE_SDL2
 
 # the skin support sources
 #
@@ -282,10 +299,13 @@
                 scaler.c \
                 ui.c \
 
+ifdef EMULATOR_USE_SDL2
 SKIN_SOURCES += event-sdl2.c \
                 surface-sdl2.c \
                 winsys-sdl2.c \
 
+endif  # EMULATOR_USE_SDL2
+
 common_LOCAL_SRC_FILES += $(SKIN_SOURCES:%=android/skin/%)
 
 common_LOCAL_SRC_FILES += \
diff --git a/Makefile.target b/Makefile.target
index 614b0a3..67d355c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -269,17 +269,17 @@
 ###
 ###
 
+common_LOCAL_LDFLAGS =
+common_LOCAL_LDFLAGS_64 =
 common_LOCAL_LDLIBS =
 common_LOCAL_CFLAGS =
 common_LOCAL_SRC_FILES =
 
+common_LOCAL_LDFLAGS += \
+    $(EMULATOR_LIBUI_LDFLAGS)
 
-common_LOCAL_STATIC_LIBRARIES := \
-    emulator-libui \
-    emulator-libqemu \
-    emulator-target-$(EMULATOR_TARGET_CPU) \
-    emulator-common \
-    emulator-zlib
+common_LOCAL_LDFLAGS_64 += \
+    $(EMULATOR_LIBUI_LDFLAGS_64)
 
 common_LOCAL_LDLIBS += \
     $(EMULATOR_COMMON_LDLIBS) \
@@ -342,9 +342,9 @@
     emulator-libsparse \
     emulator-libselinux \
     emulator-zlib \
-    $(EMULATOR_SDL_STATIC_LIBRARIES)
+    $(EMULATOR_LIBUI_STATIC_LIBRARIES)
 
-LOCAL_LDLIBS += $(common_LOCAL_LDLIBS) $(EMULATOR_SDL_LDLIBS)
+LOCAL_LDLIBS += $(common_LOCAL_LDLIBS)
 LOCAL_LDFLAGS += $(common_LOCAL_LDFLAGS)
 LOCAL_CFLAGS += $(common_LOCAL_CFLAGS)
 LOCAL_SRC_FILES += $(common_LOCAL_SRC_FILES)
@@ -353,10 +353,6 @@
 
 ifeq ($(HOST_OS),windows)
   $(eval $(call insert-windows-icon))
-  # Special exception for Windows: -lmingw32 must appear before libSDLmain
-  # on the link command-line, because it depends on _WinMain@16 which is
-  # exported by the latter.
-  LOCAL_LDFLAGS += -lmingw32
 endif
 
 $(call end-emulator-program)
@@ -374,9 +370,10 @@
     emulator64-libsparse \
     emulator64-libselinux \
     emulator64-zlib \
-    $(EMULATOR_SDL_STATIC_LIBRARIES_64)
+    $(EMULATOR_LIBUI_STATIC_LIBRARIES_64)
 
-LOCAL_LDLIBS += $(common_LOCAL_LDLIBS) $(EMULATOR_SDL_LDLIBS)
+LOCAL_LDLIBS += $(common_LOCAL_LDLIBS)
+LOCAL_LDFLAGS += $(common_LOCAL_LDFLAGS_64)
 LOCAL_CFLAGS += $(common_LOCAL_CFLAGS)
 LOCAL_SRC_FILES += $(common_LOCAL_SRC_FILES)
 $(call gen-hx-header,qemu-options.hx,qemu-options.def,vl-android.c qemu-options.h)
diff --git a/Makefile.tests b/Makefile.tests
index cb781fa..adb3975 100644
--- a/Makefile.tests
+++ b/Makefile.tests
@@ -51,6 +51,7 @@
   android/utils/file_data_unittest.cpp \
   android/utils/format_unittest.cpp \
   android/utils/host_bitness_unittest.cpp \
+  android/utils/path_unittest.cpp \
   android/utils/property_file_unittest.cpp \
   android/utils/win32_cmdline_quote_unittest.cpp \
   android/utils/x86_cpuid_unittest.cpp \
diff --git a/android-configure.sh b/android-configure.sh
index e896df5..6c599ac 100755
--- a/android-configure.sh
+++ b/android-configure.sh
@@ -719,6 +719,8 @@
 echo "CONFIG_ALSA       := $PROBE_ALSA" >> $config_mk
 echo "CONFIG_OSS        := $PROBE_OSS" >> $config_mk
 echo "CONFIG_PULSEAUDIO := $PROBE_PULSEAUDIO" >> $config_mk
+echo "EMULATOR_USE_SDL2 := true" >> $config_mk
+
 if [ $OPTION_DEBUG = yes ] ; then
     echo "BUILD_DEBUG_EMULATOR := true" >> $config_mk
 fi
@@ -764,6 +766,7 @@
 echo "#define CONFIG_SLIRP    1" >> $config_h
 echo "#define CONFIG_SKINS    1" >> $config_h
 echo "#define CONFIG_TRACE    1" >> $config_h
+echo "#define CONFIG_SDL      1" >> $config_h
 
 case "$HOST_OS" in
     windows)
diff --git a/android-rebuild.sh b/android-rebuild.sh
index efecaf0..a7f0a9a 100755
--- a/android-rebuild.sh
+++ b/android-rebuild.sh
@@ -112,16 +112,19 @@
     EXPECTED_64BIT_FILE_TYPE="PE32\+ executable \(console\) x86-64"
     EXPECTED_EMULATOR_BITNESS=32
     EXPECTED_EMULATOR_FILE_TYPE=$EXPECTED_32BIT_FILE_TYPE
+    TARGET_OS=windows
 elif [ "$HOST_OS" = "Darwin" ]; then
     EXPECTED_32BIT_FILE_TYPE="Mach-O executable i386"
     EXPECTED_64BIT_FILE_TYPE="Mach-O 64-bit executable x86_64"
     EXPECTED_EMULATOR_BITNESS=64
     EXPECTED_EMULATOR_FILE_TYPE=$EXPECTED_64BIT_FILE_TYPE
+    TARGET_OS=darwin
 else
     EXPECTED_32BIT_FILE_TYPE="ELF 32-bit LSB +executable, Intel 80386"
     EXPECTED_64BIT_FILE_TYPE="ELF 32-bit LSB +executable, x86-64"
     EXPECTED_EMULATOR_BITNESS=32
     EXPECTED_EMULATOR_FILE_TYPE=$EXPECTED_32BIT_FILE_TYPE
+    TARGET_OS=linux
 fi
 
 # Build the binaries from sources.
@@ -154,12 +157,7 @@
 QEMU_ANDROID_HOSTS=
 QEMU_ANDROID_BINARIES=
 if [ -d "$PREBUILTS_DIR/qemu-android" ]; then
-    HOST_PREFIX=
-    if [ "$MINGW" ]; then
-        HOST_PREFIX=windows
-    else
-        HOST_PREFIX=$HOST_SYSTEM
-    fi
+    HOST_PREFIX=$TARGET_OS
     if [ "$HOST_PREFIX" ]; then
         QEMU_ANDROID_BINARIES=$(cd "$PREBUILTS_DIR"/qemu-android && ls $HOST_PREFIX-*/qemu-system-* 2>/dev/null || true)
     fi
diff --git a/android/base/files/PathUtils.cpp b/android/base/files/PathUtils.cpp
index d0b35a6..469c6ad 100644
--- a/android/base/files/PathUtils.cpp
+++ b/android/base/files/PathUtils.cpp
@@ -144,7 +144,7 @@
         addSeparator = true;
         if (n == 0) {
             size_t prefixLen = rootPrefixSize(component.c_str(), hostType);
-            if (prefixLen > 0) {
+            if (prefixLen == component.size()) {
                 addSeparator = false;
             }
         }
diff --git a/android/base/files/PathUtils_unittest.cpp b/android/base/files/PathUtils_unittest.cpp
index 55a0b37..99c326c 100644
--- a/android/base/files/PathUtils_unittest.cpp
+++ b/android/base/files/PathUtils_unittest.cpp
@@ -279,6 +279,8 @@
         { { "foo", "bar", NULL }, { "foo/bar", "foo\\bar" } },
         { { ".", "foo", "..", NULL }, { "./foo/..", ".\\foo\\.." } },
         { { "C:", "foo", NULL }, { "C:/foo", "C:foo" } },
+        { { "/foo/bar", "lib", NULL }, { "/foo/bar/lib", "/foo/bar\\lib" } },
+        { { "\\foo\\bar", "lib", NULL }, { "\\foo\\bar/lib", "\\foo\\bar\\lib" } },
     };
     for (size_t n = 0; n < ARRAY_SIZE(kData); ++n) {
         StringVector components = componentListToVector(kData[n].input);
diff --git a/android/base/system/System.cpp b/android/base/system/System.cpp
index b1450bc..c575b3d 100644
--- a/android/base/system/System.cpp
+++ b/android/base/system/System.cpp
@@ -18,6 +18,7 @@
 #include "android/base/files/PathUtils.h"
 #include "android/base/memory/LazyInstance.h"
 #include "android/base/misc/StringUtils.h"
+#include "android/base/StringFormat.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -232,6 +233,16 @@
 const char* System::kLibSubDir = "lib";
 #endif
 
+#ifdef _WIN32
+// static
+const char* System::kLibrarySearchListEnvVarName = "PATH";
+#elif defined(__APPLE__)
+const char* System::kLibrarySearchListEnvVarName = "DYLD_LIBRARY_PATH";
+#else
+// static
+const char* System::kLibrarySearchListEnvVarName = "LD_LIBRARY_PATH";
+#endif
+
 // static
 System* System::setForTesting(System* system) {
     System* result = sSystemForTesting;
@@ -316,5 +327,23 @@
     return S_ISDIR(st.st_mode);
 }
 
+// static
+void System::addLibrarySearchDir(const char* path) {
+    System* system = System::get();
+    const char* varName = kLibrarySearchListEnvVarName;
+
+    const char* env = system->envGet(varName);
+    String libSearchPath = env ? env : "";
+    if (libSearchPath.size()) {
+        libSearchPath = StringFormat("%s%c%s",
+                                     path,
+                                     kPathSeparator,
+                                     libSearchPath.c_str());
+    } else {
+        libSearchPath = path;
+    }
+    system->envSet(varName, libSearchPath.c_str());
+}
+
 }  // namespace base
 }  // namespace android
diff --git a/android/base/system/System.h b/android/base/system/System.h
index decdee7..a7e55c2 100644
--- a/android/base/system/System.h
+++ b/android/base/system/System.h
@@ -51,13 +51,32 @@
     static const int kProgramBitness = 32;
 #endif
 
+    // The character used to separator directories in path-related
+    // environment variables.
+#ifdef _WIN32
+    static const char kPathSeparator = ';';
+#else
+    static const char kPathSeparator = ':';
+#endif
+
+    // Environment variable name corresponding to the library search
+    // list for shared libraries.
+    static const char* kLibrarySearchListEnvVarName;
+
     // Return the name of the sub-directory containing libraries
     // for the current platform, i.e. "lib" or "lib64" depending
     // on the value of kProgramBitness.
     static const char* kLibSubDir;
 
+    // Return program's bitness, either 32 or 64.
     static int getProgramBitness() { return kProgramBitness; }
 
+    // Prepend a new directory to the system's library search path. This
+    // only alters an environment variable like PATH or LD_LIBRARY_PATH,
+    // and thus typically takes effect only after spawning/executing a new
+    // process.
+    static void addLibrarySearchDir(const char* dirPath);
+
     // Retrieve the value of a given environment variable.
     // Equivalent to getenv().
     virtual const char* envGet(const char* varname) const = 0;
diff --git a/android/base/system/System_unittest.cpp b/android/base/system/System_unittest.cpp
index 806731e..60febb0 100644
--- a/android/base/system/System_unittest.cpp
+++ b/android/base/system/System_unittest.cpp
@@ -149,5 +149,12 @@
     }
 }
 
+TEST(System, addLibrarySearchDir) {
+    TestSystem testSys("/foo/bar", 32);
+    TestTempDir* testDir = testSys.getTempRoot();
+    ASSERT_TRUE(testDir->makeSubDir("lib"));
+    testSys.addLibrarySearchDir("lib");
+}
+
 }  // namespace base
 }  // namespace android
diff --git a/android/build/binary.make b/android/build/binary.make
index 0b17e77..a102e5f 100644
--- a/android/build/binary.make
+++ b/android/build/binary.make
@@ -25,7 +25,7 @@
 LOCAL_GENERATED_C_SOURCES := $(filter %.c,$(LOCAL_GENERATED_SOURCES))
 LOCAL_GENERATED_CXX_SOURCES := $(filter %$(LOCAL_CPP_EXTENSION),$(LOCAL_GENERATED_SOURCES))
 LOCAL_CXX_SOURCES := $(filter %$(LOCAL_CPP_EXTENSION),$(LOCAL_SRC_FILES))
-LOCAL_OBJC_SOURCES := $(filter %.m,$(LOCAL_SRC_FILES))
+LOCAL_OBJC_SOURCES := $(filter %.m %.mm,$(LOCAL_SRC_FILES))
 
 LOCAL_CFLAGS := $(strip $(patsubst %,-I%,$(LOCAL_C_INCLUDES)) $(LOCAL_CFLAGS))
 
diff --git a/android/build/prebuilt_static_library.make b/android/build/prebuilt_static_library.make
new file mode 100644
index 0000000..7cc74e1
--- /dev/null
+++ b/android/build/prebuilt_static_library.make
@@ -0,0 +1,24 @@
+# Copyright (C) 2015 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.
+#
+
+#$(info PREBUILT_STATIC_LIBRARY $(LOCAL_MODULE) SRCS=$(LOCAL_SRC_FILES))
+LOCAL_BUILT_MODULE := $(call local-library-path,$(LOCAL_MODULE))
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_SRC_FILES)
+	@mkdir -p $(dir $@)
+	@echo "PrebuiltLibrary: $@"
+	$(hide) cp -f $< $@
+
+LIBRARIES += $(LOCAL_BUILT_MODULE)
diff --git a/android/config/config.h b/android/config/config.h
index d29f7b8..e26d28f 100644
--- a/android/config/config.h
+++ b/android/config/config.h
@@ -9,7 +9,6 @@
 #define CONFIG_NAND 1
 #define CONFIG_SHAPER 1
 #define CONFIG_SOFTMMU 1
-#define CONFIG_SDL 1
 #ifndef _WIN32
 #define CONFIG_NAND_LIMITS 1
 #endif
diff --git a/android/emulator-window.c b/android/emulator-window.c
index f018cd5..a40bb8a 100644
--- a/android/emulator-window.c
+++ b/android/emulator-window.c
@@ -185,6 +185,7 @@
 
         .keyboard_charmap = emulator->opts->charmap,
         .keyboard_raw_keys = emulator->opts->raw_keys != 0,
+        .win32_ignore_events = false,
     };
 
     write_window_name(my_ui_params.window_name,
diff --git a/android/main-emulator.c b/android/main-emulator.c
index 36b1561..3781eff 100644
--- a/android/main-emulator.c
+++ b/android/main-emulator.c
@@ -31,6 +31,7 @@
 #include <android/utils/bufprint.h>
 #include <android/utils/win32_cmdline_quote.h>
 #include <android/opengl/emugl_config.h>
+#include <android/avd/scanner.h>
 #include <android/avd/util.h>
 
 /* Required by android/utils/debug.h */
@@ -136,6 +137,19 @@
             continue;
         }
 
+        if (!strcmp(opt,"-list-avds")) {
+            AvdScanner* scanner = avdScanner_new(NULL);
+            for (;;) {
+                const char* name = avdScanner_next(scanner);
+                if (!name) {
+                    break;
+                }
+                printf("%s\n", name);
+            }
+            avdScanner_free(scanner);
+            exit(0);
+        }
+
         if (!avdName) {
             if (!strcmp(opt,"-avd") && nn+1 < argc) {
                 avdName = argv[nn+1];
diff --git a/android/main.c b/android/main.c
index 3b76058..89540ca 100755
--- a/android/main.c
+++ b/android/main.c
@@ -35,7 +35,6 @@
 
 #include "math.h"
 
-#include "android/avd/scanner.h"
 #include "android/config/config.h"
 
 #include "android/kernel/kernel_utils.h"
@@ -249,19 +248,6 @@
         exit(0);
     }
 
-    if (opts->list_avds) {
-        AvdScanner* scanner = avdScanner_new(NULL);
-        for (;;) {
-            const char* name = avdScanner_next(scanner);
-            if (!name) {
-                break;
-            }
-            printf("%s\n", name);
-        }
-        avdScanner_free(scanner);
-        exit(0);
-    }
-
     if (opts->snapshot_list) {
         if (opts->snapstorage == NULL) {
             /* Need to find the default snapstorage */
diff --git a/android/opengl/emugl_config.cpp b/android/opengl/emugl_config.cpp
index 4ae0efc..e53831e 100644
--- a/android/opengl/emugl_config.cpp
+++ b/android/opengl/emugl_config.cpp
@@ -179,38 +179,18 @@
     String newDirs = StringFormat("%s/%s",
                                   System::get()->getProgramDirectory().c_str(),
                                   libSubDir);
-#ifdef _WIN32
-    const char kPathSeparator = ';';
-#else
-    const char kPathSeparator = ':';
-#endif
-
     if (strcmp(config->backend, "host") != 0) {
         // If the backend is not 'host', we also need to add the
         // backend directory.
         String dir = sBackendList->getLibDirPath(config->backend);
         if (dir.size()) {
-            newDirs += kPathSeparator;
+            newDirs += System::kPathSeparator;
             newDirs += dir;
         }
     }
 
-#ifdef _WIN32
-    static const char kEnvPathVar[] = "PATH";
-#else  // !_WIN32
-    static const char kEnvPathVar[] = "LD_LIBRARY_PATH";
-#endif  // !_WIN32
-    String path = system->envGet(kEnvPathVar) ?: "";
-    if (path.size()) {
-        path = StringFormat("%s%c%s",
-                            newDirs.c_str(),
-                            kPathSeparator,
-                            path.c_str());
-    } else {
-        path = newDirs;
-    }
-    D("Setting %s=%s\n", kEnvPathVar, path.c_str());
-    system->envSet(kEnvPathVar, path.c_str());
+    D("Adding to the library search path: %s\n", newDirs.c_str());
+    system->addLibrarySearchDir(newDirs.c_str());
 
     if (!strcmp(config->backend, "host")) {
         // Nothing more to do for the 'host' backend.
diff --git a/android/skin/event.h b/android/skin/event.h
index 8605c1d..6566f8f 100644
--- a/android/skin/event.h
+++ b/android/skin/event.h
@@ -15,6 +15,10 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef enum {
     kEventKeyDown,
     kEventKeyUp,
@@ -69,4 +73,8 @@
 // Set/unset unicode translation for key events.
 extern void skin_event_enable_unicode(bool enabled);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif  // ANDROID_SKIN_EVENT_H
diff --git a/android/skin/surface.h b/android/skin/surface.h
index 3212099..cc6de7d 100644
--- a/android/skin/surface.h
+++ b/android/skin/surface.h
@@ -15,6 +15,10 @@
 #include "android/skin/region.h"
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* a SkinSurface models a 32-bit ARGB pixel image that can be blitted to or from
  */
 typedef struct SkinSurface  SkinSurface;
@@ -130,4 +134,8 @@
                                  SkinRect*     rect,
                                  uint32_t      argb_premul);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _ANDROID_SKIN_SURFACE_H */
diff --git a/android/skin/ui.c b/android/skin/ui.c
index 5db1d0e..96c973ae 100644
--- a/android/skin/ui.c
+++ b/android/skin/ui.c
@@ -26,6 +26,10 @@
 #include <stdbool.h>
 #include <stdio.h>
 
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
 #define  D(...)  do {  if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
 #define  DE(...) do { if (VERBOSE_CHECK(keys)) dprint(__VA_ARGS__); } while (0)
 
@@ -369,6 +373,21 @@
 bool skin_ui_process_events(SkinUI* ui) {
     SkinEvent ev;
 
+#ifdef _WIN32
+    if (ui->ui_params.win32_ignore_events) {
+        // In QT, Windows messages are received by the QT thread, which is
+        // the thread that creates all of its windows, so that should be
+        // okay. However, in GPU accelerated images, there's a native window
+        // that's created that represents the actual OpenGL output pane, and
+        // that window is created from this thread and not the QT thread. We
+        // need to keep its message queue from getting jammed up with
+        // messages, so we need to grab any messages we see and drop
+        // unnecessary ones on the floor.
+        MSG message;
+        PeekMessage(&message, NULL, 0, 0, PM_REMOVE);
+    }
+#endif  // _WIN32
+
     while(skin_event_poll(&ev)) {
         switch(ev.type) {
         case kEventVideoExpose:
diff --git a/android/skin/ui.h b/android/skin/ui.h
index 6f05fb2..055ea85 100644
--- a/android/skin/ui.h
+++ b/android/skin/ui.h
@@ -61,6 +61,8 @@
 // |keyboard_raw_keys| is true to start in raw key input mode. Default is
 // to start in Unicode mode. It's possible to toggle between modes at runtime
 // by using Ctrl-K.
+// |win32_ignore_events| is true to indicate that window events should be
+// ignored on Windows.
 typedef struct SkinUIParams {
     char window_name[64];
     int window_x;
@@ -74,6 +76,7 @@
 
     const char* keyboard_charmap;
     bool keyboard_raw_keys;
+    bool win32_ignore_events;
 
 } SkinUIParams;
 
diff --git a/android/skin/window.c b/android/skin/window.c
index b1de0b2..8178ac3 100644
--- a/android/skin/window.c
+++ b/android/skin/window.c
@@ -344,7 +344,7 @@
                 line[nn] = (unsigned)(ag | rb);
                 nn++;
             });
-            pixels += pitch;
+            pixels += (pitch / sizeof(uint32_t));
         }
     }
     else if (alpha > LCD_BRIGHTNESS_HIGH) /* 'superluminous' mode */
@@ -372,7 +372,7 @@
                 line[nn] = (unsigned)(ag | rb);
                 nn++;
             });
-            pixels += pitch;
+            pixels += (pitch / sizeof(uint32_t));
         }
     }
 }
@@ -585,8 +585,9 @@
 
     // Allocate a temporary buffer to get the potentially rotated / converted
     // content.
-    int dst_pitch = 4 * w;
-    uint8_t* dst_pixels = calloc(h, dst_pitch);
+    int sz = disp->datasize.h > disp->datasize.w ? disp->datasize.h : disp->datasize.w;
+    int dst_pitch = 4 * sz;
+    uint8_t* dst_pixels = calloc(sz, dst_pitch);
 
     SkinRect dst_r = {
         .pos.x = x,
diff --git a/android/skin/winsys.h b/android/skin/winsys.h
index a9e2c01..378e4c2 100644
--- a/android/skin/winsys.h
+++ b/android/skin/winsys.h
@@ -18,6 +18,10 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 // Enable/Disable relative mouse mode. Used for trackball emulation.
 // This hides the cursor and grabs the input.
 void skin_winsys_set_relative_mouse_mode(bool enabled);
@@ -61,4 +65,16 @@
 // Stop main window and quit program. Must be called from inside event loop.
 void skin_winsys_quit(void);
 
+typedef void (*StartFunction)(int argc, char** argv);
+
+// Spawn a thread and run the given function in it.
+void skin_winsys_spawn_thread(StartFunction f, int argc, char** argv);
+
+// Enter the main event handling loop for the UI subsystem.
+void skin_winsys_enter_main_loop(int argc, char** argv);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif  // ANDROID_SKIN_WINSYS_H
diff --git a/android/utils/path.c b/android/utils/path.c
index c88b5cc..a09537b 100644
--- a/android/utils/path.c
+++ b/android/utils/path.c
@@ -693,3 +693,51 @@
     /* Nothing, really */
     return NULL;
 }
+
+char *
+path_escape_path(const char* src)
+{
+    if (!src) return NULL;
+
+    // Allocate for the maximum output size, including terminator
+    char *retStr = malloc(2 * strlen(src) + 1);
+    if (retStr == 0) return 0;
+
+    char *dst = retStr;
+    while (*src != '\0') {
+        switch (*src) {
+            case '=':  *dst++ = '%'; *dst++ = 'E'; break;
+            case ',':  *dst++ = '%'; *dst++ = 'C'; break;
+            case '%':  *dst++ = '%'; *dst++ = 'P'; break;
+            default:   *dst++ = *src;
+        }
+        src++;
+    }
+    *dst = '\0';
+    return retStr;
+}
+
+
+void
+path_unescape_path(char* str)
+{
+    char *src = str;
+    char *dst = str;
+
+    while (*src != '\0') {
+        if (*src != '%') {
+            *dst++ = *src++;
+        } else {
+            // Escaped character
+            src++;
+            switch (*src) {
+                case 'C': *dst++ = ','; src++; break;
+                case 'E': *dst++ = '='; src++; break;
+                case 'P': *dst++ = '%'; src++; break;
+
+                default:   ;   // Just drop the '%'
+            }
+        }
+    }
+    *dst = '\0';
+}
diff --git a/android/utils/path.h b/android/utils/path.h
index ac5fb09..8dd3892 100644
--- a/android/utils/path.h
+++ b/android/utils/path.h
@@ -28,7 +28,7 @@
 #  define  O_BINARY  0
 #endif
 
-/* define  PATH_SEP as a string containing the directory separateor */
+/* define  PATH_SEP as a string containing the directory separator */
 #ifdef _WIN32
 #  define  PATH_SEP   "\\"
 #  define  PATH_SEP_C '\\'
@@ -167,6 +167,27 @@
  */
 extern void*          path_load_file( const char*  path, size_t  *pSize );
 
+/* Modify the path to eliminate ',' and '=', which confuse parsers
+ * that look at strings with multiple parameters.
+ * This function makes these conversions: ',' --> '%' 'C'
+ *                                        '=' --> '%' 'E'
+ *                                        '%' --> '%' 'P'
+ *
+ * The returned string is on the heap. The caller is reponsible
+ * for freeing this memory.
+ */
+extern char*          path_escape_path( const char* src );
+
+/* Modify the path to restore ',' and '='.
+ * This function makes these conversions: '%' 'C' --> ','
+ *                                        '%' 'E' --> '='
+ *                                        '%' 'P' --> '%'
+ *
+ * Because this can only reduce the length of the string,
+ * this conversion is done in place.
+ */
+extern void           path_unescape_path( char* str );
+
 /* */
 ANDROID_END_HEADER
 
diff --git a/android/utils/path_unittest.cpp b/android/utils/path_unittest.cpp
new file mode 100644
index 0000000..adaa383
--- /dev/null
+++ b/android/utils/path_unittest.cpp
@@ -0,0 +1,51 @@
+// Copyright 2015 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+#include "android/utils/path.h"
+#include "gtest/gtest.h"
+
+namespace android {
+namespace path {
+
+TEST(Path, EscapePath) {
+    const char linuxInputPath[]    = "/Linux/style_with/various,special==character%s";
+    const char linuxOutputPath[]   = "/Linux/style_with/various%Cspecial%E%Echaracter%Ps";
+
+    const char windowsInputPath[]  = "C:\\Windows\\style:=with,,other%\\types of characters";
+    const char windowsOutputPath[] = "C:\\Windows\\style:%Ewith%C%Cother%P\\types of characters";
+
+    char *result;
+
+    // Escape Linux style paths
+    result = path_escape_path(linuxInputPath);
+    EXPECT_NE(result, (char*)NULL);
+    EXPECT_STREQ(linuxOutputPath, result);
+    
+    path_unescape_path(result);
+    EXPECT_NE(result, (char*)NULL);
+    EXPECT_STREQ(linuxInputPath, result);
+
+    free(result);
+
+    // Escape Windows style paths
+    result = path_escape_path(windowsInputPath);
+    EXPECT_NE(result, (char*)NULL);
+    EXPECT_STREQ(windowsOutputPath, result);
+    
+    path_unescape_path(result);
+    EXPECT_NE(result, (char*)NULL);
+    EXPECT_STREQ(windowsInputPath, result);
+
+    free(result);
+}
+
+}  // namespace path
+}  // namespace android
diff --git a/distrib/android-emugl/common.mk b/distrib/android-emugl/common.mk
index eae1373..ecbea78 100644
--- a/distrib/android-emugl/common.mk
+++ b/distrib/android-emugl/common.mk
@@ -32,8 +32,6 @@
 _emugl_modules :=
 _emugl_HOST_modules :=
 
-EMUGL_LOCAL_EXTRAS = $(end-emulator-module-ev)
-
 # do not use directly, see functions above instead
 emugl-begin-module = \
     $(eval include $(CLEAR_VARS)) \
@@ -44,7 +42,7 @@
     $(eval LOCAL_C_INCLUDES += $(EMUGL_COMMON_INCLUDES)) \
     $(eval LOCAL_CFLAGS += $(EMUGL_COMMON_CFLAGS)) \
     $(eval LOCAL_LDLIBS += -lstdc++) \
-    $(eval _EMUGL_INCLUDE_TYPE := $(BUILD_$2)) \
+    $(eval LOCAL_BUILD_FILE := $(BUILD_$2)) \
     $(eval LOCAL_MODULE_BITS := 32) \
     $(call _emugl-init-module,$1,$2,$3)
 
@@ -54,9 +52,8 @@
 
 # Used to end a module definition, see function definitions above
 emugl-end-module = \
-    $(eval $(EMUGL_LOCAL_EXTRAS)) \
-    $(call include-if-bitness-$(LOCAL_MODULE_BITS), $(_EMUGL_INCLUDE_TYPE))\
-    $(eval _EMUGL_INCLUDE_TYPE :=) \
+    $(eval $(end-emulator-module-ev)) \
+    $(eval LOCAL_BUILD_FILE :=) \
     $(eval _emugl_$(_emugl_HOST)modules += $(_emugl_MODULE))\
     $(if $(EMUGL_DEBUG),$(call emugl-dump-module))
 
diff --git a/distrib/android-emugl/host/libs/libOpenglRender/RenderServer.cpp b/distrib/android-emugl/host/libs/libOpenglRender/RenderServer.cpp
index d492709..7c91271 100644
--- a/distrib/android-emugl/host/libs/libOpenglRender/RenderServer.cpp
+++ b/distrib/android-emugl/host/libs/libOpenglRender/RenderServer.cpp
@@ -20,6 +20,8 @@
 #include "TcpStream.h"
 #ifndef _WIN32
 #include "UnixStream.h"
+#include <signal.h>
+#include <pthread.h>
 #endif
 #ifdef _WIN32
 #include "Win32PipeStream.h"
@@ -86,6 +88,12 @@
 {
     RenderThreadsSet threads;
 
+#ifndef _WIN32
+    sigset_t set;
+    sigfillset(&set);
+    pthread_sigmask(SIG_SETMASK, &set, NULL);
+#endif
+
     while(1) {
         SocketStream *stream = m_listenSock->accept();
         if (!stream) {
diff --git a/distrib/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp b/distrib/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp
index fe42871..1063230 100644
--- a/distrib/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp
+++ b/distrib/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp
@@ -21,6 +21,10 @@
 
 #include <stdarg.h>
 #include <stdio.h>
+#ifndef _WIN32
+#include <signal.h>
+#include <pthread.h>
+#endif
 
 #define DEBUG 0
 
@@ -245,6 +249,11 @@
 
     virtual intptr_t main() {
         D("Entering render window thread thread\n");
+#ifndef _WIN32
+        sigset_t set;
+        sigfillset(&set);
+        pthread_sigmask(SIG_SETMASK, &set, NULL);
+#endif
         bool running = true;
         while (running) {
             RenderWindowMessage msg;
diff --git a/hw/android/goldfish/nand.c b/hw/android/goldfish/nand.c
index faf1c5d..5589099 100644
--- a/hw/android/goldfish/nand.c
+++ b/hw/android/goldfish/nand.c
@@ -15,6 +15,7 @@
 #include "hw/android/goldfish/nand.h"
 #include "hw/android/goldfish/vmem.h"
 #include "hw/hw.h"
+#include "android/utils/path.h"
 #include "android/utils/tempfile.h"
 #include "android/qemu-debug.h"
 #include "android/android.h"
@@ -806,6 +807,8 @@
                     goto out_of_memory;
                 memcpy(initfilename, value, value_len);
                 initfilename[value_len] = '\0';
+                // Restore unusual characters that confuse parsing
+                path_unescape_path(initfilename);
             }
             else if(arg_match("file", arg, arg_len)) {
                 rwfilename = malloc(value_len + 1);
@@ -813,6 +816,8 @@
                     goto out_of_memory;
                 memcpy(rwfilename, value, value_len);
                 rwfilename[value_len] = '\0';
+                // Restore unusual characters that confuse parsing
+                path_unescape_path(rwfilename);
             }
             else {
                 goto bad_arg_and_value;
diff --git a/vl-android.c b/vl-android.c
index 2c19e50..e05386d 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -2042,8 +2042,14 @@
         need_make_empty = true;
     }
 
-    pstrcat(tmp, sizeof tmp, ",file=");
-    pstrcat(tmp, sizeof tmp, part_file);
+
+    // Escape special characters in the file name
+    char *escaped_part_file = path_escape_path(part_file);
+    if (escaped_part_file) {
+        pstrcat(tmp, sizeof tmp, ",file=");
+        pstrcat(tmp, sizeof tmp, escaped_part_file);
+        free(escaped_part_file);
+    }
 
     // Do we need to make the partition image empty?
     // Do not do it if there is an initial file though since it will
@@ -2065,8 +2071,12 @@
     }
 
     if (part_init_file) {
-        pstrcat(tmp, sizeof tmp, ",initfile=");
-        pstrcat(tmp, sizeof tmp, part_init_file);
+        char *escaped_part_init = path_escape_path(part_init_file);
+        if (escaped_part_init) {
+            pstrcat(tmp, sizeof tmp, ",initfile=");
+            pstrcat(tmp, sizeof tmp, escaped_part_init);
+            free(escaped_part_init);
+        }
     }
 
     if (part_type == ANDROID_PARTITION_TYPE_EXT4) {