diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2009-07-25 17:48:02 -0700 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2009-07-25 17:48:02 -0700 |
commit | 6cfe67b3b6c6827a1fca860a36bbb8cda6d2056b (patch) | |
tree | 256687529fcf5e6adc8798878d899143077714de /android | |
parent | 2b8ea29e2bd12f876a4d06647e6077bf72de567e (diff) | |
parent | c5b127050f2dbed015d6b01703a33062d6910d4a (diff) | |
download | external_qemu-6cfe67b3b6c6827a1fca860a36bbb8cda6d2056b.zip external_qemu-6cfe67b3b6c6827a1fca860a36bbb8cda6d2056b.tar.gz external_qemu-6cfe67b3b6c6827a1fca860a36bbb8cda6d2056b.tar.bz2 |
Merge korg/donut into korg/master
Diffstat (limited to 'android')
-rw-r--r-- | android/android.h | 2 | ||||
-rw-r--r-- | android/avd/hardware-properties.ini | 7 | ||||
-rw-r--r-- | android/avd/hw-config-defs.h | 7 | ||||
-rw-r--r-- | android/boot-properties.c | 214 | ||||
-rw-r--r-- | android/boot-properties.h | 47 | ||||
-rw-r--r-- | android/build/common.sh | 515 | ||||
-rw-r--r-- | android/build/definitions.make | 20 | ||||
-rw-r--r-- | android/cmdline-option.c | 61 | ||||
-rw-r--r-- | android/cmdline-option.h | 8 | ||||
-rw-r--r-- | android/cmdline-options.h | 6 | ||||
-rw-r--r-- | android/help.c | 20 | ||||
-rw-r--r-- | android/hw-control.c | 7 | ||||
-rw-r--r-- | android/hw-lcd.c | 32 | ||||
-rw-r--r-- | android/hw-lcd.h | 23 | ||||
-rw-r--r-- | android/hw-qemud.c | 16 | ||||
-rw-r--r-- | android/hw-qemud.h | 32 | ||||
-rw-r--r-- | android/hw-sensors.c | 390 | ||||
-rw-r--r-- | android/main.c | 23 | ||||
-rw-r--r-- | android/skin/file.c | 1 | ||||
-rw-r--r-- | android/skin/window.c | 16 | ||||
-rw-r--r-- | android/utils/display-quartz.m | 111 | ||||
-rw-r--r-- | android/utils/display.c | 245 | ||||
-rw-r--r-- | android/utils/display.h | 31 |
23 files changed, 1265 insertions, 569 deletions
diff --git a/android/android.h b/android/android.h index 71a20f6..17c7c48 100644 --- a/android/android.h +++ b/android/android.h @@ -13,7 +13,7 @@ #define _qemu_android_h #define ANDROID_VERSION_MAJOR 1 -#define ANDROID_VERSION_MINOR 9 +#define ANDROID_VERSION_MINOR 10 #define CONFIG_SHAPER 1 diff --git a/android/avd/hardware-properties.ini b/android/avd/hardware-properties.ini index 60a7493..c655100 100644 --- a/android/avd/hardware-properties.ini +++ b/android/avd/hardware-properties.ini @@ -135,3 +135,10 @@ name = disk.cachePartition.size type = diskSize abstract = Cache partition size default = 66MB + +# LCD density +name = hw.lcd.density +type = integer +default = 160 +abstract = Abstracted LCD density +description = Must be one of 120, 160 or 240. A value used to roughly describe the density of the LCD screen for automatic resource/asset selection. diff --git a/android/avd/hw-config-defs.h b/android/avd/hw-config-defs.h index 3e7cec6..7fcf732 100644 --- a/android/avd/hw-config-defs.h +++ b/android/avd/hw-config-defs.h @@ -136,6 +136,13 @@ HWCFG_DISKSIZE( "Cache partition size", "") +HWCFG_INT( + hw_lcd_density, + "hw.lcd.density", + 160, + "Abstracted LCD density", + "Must be one of 120, 160 or 240. A value used to roughly describe the density of the LCD screen for automatic resource/asset selection.") + #undef HWCFG_INT #undef HWCFG_BOOL #undef HWCFG_DISKSIZE diff --git a/android/boot-properties.c b/android/boot-properties.c new file mode 100644 index 0000000..1c714e9 --- /dev/null +++ b/android/boot-properties.c @@ -0,0 +1,214 @@ +/* Copyright (C) 2009 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/boot-properties.h" +#include "android/utils/debug.h" +#include "android/utils/system.h" +#include "android/hw-qemud.h" +#include "android/globals.h" + +#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) + +/* define T_ACTIVE to 1 to debug transport communications */ +#define T_ACTIVE 0 + +#if T_ACTIVE +#define T(...) VERBOSE_PRINT(init,__VA_ARGS__) +#else +#define T(...) ((void)0) +#endif + +typedef struct BootProperty { + struct BootProperty* next; + char* property; + int length; +} BootProperty; + +static BootProperty* +boot_property_alloc( const char* name, int namelen, + const char* value, int valuelen ) +{ + int length = namelen + 1 + valuelen; + BootProperty* prop = android_alloc( sizeof(*prop) + length + 1 ); + char* p; + + prop->next = NULL; + prop->property = p = (char*)(prop + 1); + prop->length = length; + + memcpy( p, name, namelen ); + p += namelen; + *p++ = '='; + memcpy( p, value, valuelen ); + p += valuelen; + *p = '\0'; + + return prop; +} + +static BootProperty* _boot_properties; +static BootProperty** _boot_properties_tail = &_boot_properties; +static int _inited; + +/* this code supports the list of system properties that will + * be set on boot in the emulated system. + */ + +int +boot_property_add2( const char* name, int namelen, + const char* value, int valuelen ) +{ + BootProperty* prop; + + /* check the lengths + */ + if (namelen > PROPERTY_MAX_NAME) + return -1; + + if (valuelen > PROPERTY_MAX_VALUE) + return -2; + + /* check that there are not invalid characters in the + * property name + */ + const char* reject = " =$*?'\""; + int nn; + + for (nn = 0; nn < namelen; nn++) { + if (strchr(reject, name[nn]) != NULL) + return -3; + } + + /* init service if needed */ + if (!_inited) { + boot_property_init_service(); + _inited = 1; + } + + D("Adding boot property: '%.*s' = '%.*s'", + namelen, name, valuelen, value); + + /* add to the internal list */ + prop = boot_property_alloc(name, namelen, value, valuelen); + + *_boot_properties_tail = prop; + _boot_properties_tail = &prop->next; + + return 0; +} + + +int +boot_property_add( const char* name, const char* value ) +{ + int namelen = strlen(name); + int valuelen = strlen(value); + + return boot_property_add2(name, namelen, value, valuelen); +} + + + +#define SERVICE_NAME "boot-properties" + +static void +boot_property_client_recv( void* opaque, + uint8_t* msg, + int msglen, + QemudClient* client ) +{ + /* the 'list' command shall send all boot properties + * to the client, then close the connection. + */ + if (msglen == 4 && !memcmp(msg, "list", 4)) { + BootProperty* prop; + for (prop = _boot_properties; prop != NULL; prop = prop->next) { + qemud_client_send(client, (uint8_t*)prop->property, prop->length); + } + qemud_client_close(client); + return; + } + + /* unknown command ? */ + D("%s: ignoring unknown command: %.*s", __FUNCTION__, msglen, msg); +} + +static QemudClient* +boot_property_service_connect( void* opaque, + QemudService* serv, + int channel ) +{ + QemudClient* client; + + client = qemud_client_new( serv, channel, NULL, + boot_property_client_recv, + NULL ); + + qemud_client_set_framing(client, 1); + return client; +} + + +void +boot_property_init_service( void ) +{ + if (!_inited) { + QemudService* serv = qemud_service_register( SERVICE_NAME, + 1, NULL, + boot_property_service_connect ); + if (serv == NULL) { + derror("could not register '%s' service", SERVICE_NAME); + return; + } + D("registered '%s' qemud service", SERVICE_NAME); + } +} + + + +void +boot_property_parse_option( const char* param ) +{ + char* q = strchr(param,'='); + const char* name; + const char* value; + int namelen, valuelen, ret; + + if (q == NULL) { + dwarning("boot property missing (=) separator: %s", param); + return; + } + + name = param; + namelen = q - param; + + value = q+1; + valuelen = strlen(name) - (namelen+1); + + ret = boot_property_add2(name, namelen, value, valuelen); + if (ret < 0) { + switch (ret) { + case -1: + dwarning("boot property name too long: '%.*s'", + namelen, name); + break; + case -2: + dwarning("boot property value too long: '%.*s'", + valuelen, value); + break; + case -3: + dwarning("boot property name contains invalid chars: %.*s", + namelen, name); + break; + } + } +} diff --git a/android/boot-properties.h b/android/boot-properties.h new file mode 100644 index 0000000..6711c59 --- /dev/null +++ b/android/boot-properties.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2009 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ + +#ifndef _ANDROID_BOOT_PROPERTIES_H +#define _ANDROID_BOOT_PROPERTIES_H + +/* these values give the maximum length of system property + * names and values. They must match the corresponding definitions + * in the Android source tree (in system/core/include/cutils/properties.h) + */ +#define PROPERTY_MAX_NAME 32 +#define PROPERTY_MAX_VALUE 92 + +/* record a new boot system property, this must be performed before the + * VM is started. Returns 0 on success, or < 0 on error. + * Possible errors are: + * -1 property name too long + * -2 property value too long + * -3 invalid characters in property name + */ +int boot_property_add( const char* name, const char* value ); + +/* same as boot_property_add, but allows to use non-zero terminated strings. + */ +int boot_property_add2( const char* name, int namelen, + const char* value, int valuelen ); + +/* init the boot property QEMUD service. This must be performed before + * the VM is started. This is also performed automatically if you call + * boot_property_add(). + */ +void boot_property_init_service( void ); + +/* parse the parameter the list of -prop options passed on the command line + */ +void boot_property_parse_option( const char* param ); + +#endif /* _ANDROID_BOOT_PROPERTIES_H */ diff --git a/android/build/common.sh b/android/build/common.sh new file mode 100644 index 0000000..b22ef7d --- /dev/null +++ b/android/build/common.sh @@ -0,0 +1,515 @@ +# 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 file is included by other shell scripts; do not execute it directly. +# It contains common definitions. +# +PROGNAME=`basename $0` + +## Logging support +## +VERBOSE=yes +VERBOSE2=no + +log () +{ + if [ "$VERBOSE" = "yes" ] ; then + echo "$1" + fi +} + +log2 () +{ + if [ "$VERBOSE2" = "yes" ] ; then + echo "$1" + fi +} + +## Utilities +## + +# return the value of a given named variable +# $1: variable name +# +var_value () +{ + # find a better way to do that ? + local result + eval result="$`echo $1`" + echo $result +} + +# convert to uppercase +to_uppercase () +{ + echo $1 | tr "[:lower:]" "[:upper:]" +} + +## Normalize OS and CPU +## + +CPU=`uname -m` +case "$CPU" in + i?86) CPU=x86 + ;; + amd64) CPU=x86_64 + ;; + powerpc) CPU=ppc + ;; +esac + +log2 "CPU=$CPU" + +# at this point, the supported values for CPU are: +# x86 +# x86_64 +# ppc +# +# other values may be possible but haven't been tested +# + +EXE="" +OS=`uname -s` +case "$OS" in + Darwin) + OS=darwin-$CPU + ;; + Linux) + # note that building 32-bit binaries on x86_64 is handled later + OS=linux-$CPU + ;; + CYGWIN*|*_NT-*) + OS=windows + EXE=.exe + if [ "x$OSTYPE" = xcygwin ] ; then + OS=cygwin + HOST_CFLAGS="$CFLAGS -mno-cygwin" + HOST_LDFLAGS="$LDFLAGS -mno-cygwin" + fi + ;; +esac + +log2 "OS=$OS" +log2 "EXE=$EXE" + +# at this point, the value of OS should be one of the following: +# linux-x86 +# linux-x86_64 +# darwin-x86 +# darwin-ppc +# windows (MSys) +# cygwin +# +# Note that cygwin is treated as a special case because it behaves very differently +# for a few things +# +# other values may be possible but have not been tested + +# define HOST_OS as $OS without any cpu-specific suffix +# +case $OS in + linux-*) HOST_OS=linux + ;; + darwin-*) HOST_OS=darwin + ;; + *) HOST_OS=$OS +esac + +# define HOST_ARCH as the $CPU +HOST_ARCH=$CPU + +#### Toolchain support +#### + +# Various probes are going to need to run a small C program +TMPC=/tmp/android-$$-test.c +TMPO=/tmp/android-$$-test.o +TMPE=/tmp/android-$$-test$EXE +TMPL=/tmp/android-$$-test.log + +# cleanup temporary files +clean_temp () +{ + rm -f $TMPC $TMPO $TMPL $TMPE +} + +# cleanup temp files then exit with an error +clean_exit () +{ + clean_temp + exit 1 +} + +# this function should be called to enforce the build of 32-bit binaries on 64-bit systems +# that support it. +FORCE_32BIT=no +force_32bit_binaries () +{ + if [ $CPU = x86_64 ] ; then + FORCE_32BIT=yes + case $OS in + linux-x86_64) OS=linux-x86 ;; + darwin-x86_64) OS=darwin-x86 ;; + esac + HOST_ARCH=x86 + CPU=x86 + log "Check32Bits: Forcing generation of 32-bit binaries (--try-64 to disable)" + fi +} + +# Cygwin is normally not supported, unless you call this function +# +enable_cygwin () +{ + if [ $OS = cygwin ] ; then + CFLAGS="$CFLAGS -mno-cygwin" + LDFLAGS="$LDFLAGS -mno-cygwin" + OS=windows + HOST_OS=windows + fi +} + +# this function will setup the compiler and linker and check that they work as advertized +# note that you should call 'force_32bit_binaries' before this one if you want it to work +# as advertized. +# +setup_toolchain () +{ + if [ "$OS" = cygwin ] ; then + echo "Do not compile this program or library with Cygwin, use MSYS instead !!" + echo "As an experimental feature, you can try to --try-cygwin option to override this" + exit 2 + fi + + if [ -z "$CC" ] ; then + CC=gcc + if [ $CPU = "powerpc" ] ; then + CC=gcc-3.3 + fi + fi + + # check that we can compile a trivial C program with this compiler + cat > $TMPC <<EOF +int main(void) {} +EOF + + if [ $FORCE_32BIT = yes ] ; then + CFLAGS="$CFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + compile + if [ $? != 0 ] ; then + # sometimes, we need to also tell the assembler to generate 32-bit binaries + # this is highly dependent on your GCC installation (and no, we can't set + # this flag all the time) + CFLAGS="$CFLAGS -Wa,--32" + compile + fi + fi + + compile + if [ $? != 0 ] ; then + echo "your C compiler doesn't seem to work:" + cat $TMPL + clean_exit + fi + log "CC : compiler check ok ($CC)" + + # check that we can link the trivial program into an executable + if [ -z "$LD" ] ; then + LD=$CC + fi + link + if [ $? != 0 ] ; then + OLD_LD=$LD + LD=gcc + compile + link + if [ $? != 0 ] ; then + LD=$OLD_LD + echo "your linker doesn't seem to work:" + cat $TMPL + clean_exit + fi + fi + log "LD : linker check ok ($LD)" +} + +# try to compile the current source file in $TMPC into an object +# stores the error log into $TMPL +# +compile () +{ + log2 "Object : $CC -o $TMPO -c $CFLAGS $TMPC" + $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL +} + +# try to link the recently built file into an executable. error log in $TMPL +# +link() +{ + log2 "Link : $LD -o $TMPE $TMPO $LDFLAGS" + $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL +} + +# run a command +# +execute() +{ + log2 "Running: $*" + $* +} + +# perform a simple compile / link / run of the source file in $TMPC +compile_exec_run() +{ + log2 "RunExec : $CC -o $TMPE $CFLAGS $TMPC" + compile + if [ $? != 0 ] ; then + echo "Failure to compile test program" + cat $TMPC + cat $TMPL + clean_exit + fi + link + if [ $? != 0 ] ; then + echo "Failure to link test program" + cat $TMPC + echo "------" + cat $TMPL + clean_exit + fi + $TMPE +} + +## Feature test support +## + +# Each feature test allows us to check against a single target-specific feature +# We run the feature checks in a Makefile in order to be able to do them in +# parallel, and we also have some cached values in our output directory, just +# in case. +# +# check that a given C program in $TMPC can be compiled on the host system +# $1: variable name which will be set to "yes" or "no" depending on result +# you can define EXTRA_CFLAGS for extra C compiler flags +# for convenience, this variable will be unset by the function +# +feature_check_compile () +{ + local result_cc=yes + local OLD_CFLAGS + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $EXTRA_CFLAGS" + compile + if [ $? != 0 ] ; then + result_cc=no + fi + eval $1=$result_cc + EXTRA_CFLAGS= + CFLAGS=$OLD_CFLAGS +} + +# check that a given C program $TMPC can be linked on the host system +# $1: variable name which will be set to "yes" or "no" depending on result +# you can define EXTRA_CFLAGS for extra C compiler flags +# you can define EXTRA_LDFLAGS for extra linker flags +# for convenience, these variables will be unset by the function +# +feature_check_link () +{ + local result_cl=yes + local OLD_CFLAGS OLD_LDFLAGS + OLD_CFLAGS=$CFLAGS + OLD_LDFLAGS=$LDFLAGS + CFLAGS="$CFLAGS $EXTRA_CFLAGS" + LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" + compile + if [ $? != 0 ] ; then + result_cl=no + else + link + if [ $? != 0 ] ; then + result_cl=no + fi + fi + CFLAGS=$OLD_CFLAGS + LDFLAGS=$OLD_LDFLAGS + eval $1=$result_cl +} + +# check that a given C header file exists on the host system +# $1: variable name which will be set to "yes" or "no" depending on result +# $2: header name +# +# you can define EXTRA_CFLAGS for extra C compiler flags +# for convenience, this variable will be unset by the function. +# +feature_check_header () +{ + local result_ch + log2 "HeaderChk : $2" + echo "#include $2" > $TMPC + cat >> $TMPC <<EOF + int main(void) { return 0; } +EOF + feature_check_compile result_ch + eval $1=$result_ch + #eval result=$`echo $1` + #log "Host : $1=$result_ch" +} + +# run the test program that is in $TMPC and set its exit status +# in the $1 variable. +# you can define EXTRA_CFLAGS and EXTRA_LDFLAGS +# +feature_run_exec () +{ + local run_exec_result + local OLD_CFLAGS="$CFLAGS" + local OLD_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS $EXTRA_CFLAGS" + LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" + compile_exec_run + run_exec_result=$? + CFLAGS="$OLD_CFLAGS" + LDFLAGS="$OLD_LDFLAGS" + eval $1=$run_exec_result + log "Host : $1=$run_exec_result" +} + +## Android build system auto-detection +## + +# check whether we're running within the Android build system +# sets the variable IN_ANDROID_BUILD to either "yes" or "no" +# +# in case of success, defines ANDROID_TOP to point to the top +# of the Android source tree. +# +check_android_build () +{ + unset ANDROID_TOP + IN_ANDROID_BUILD=no + + if [ -z "$ANDROID_PRODUCT_OUT" ] ; then + return ; + fi + + ANDROID_TOP=`cd $ANDROID_PRODUCT_OUT/../../../.. && pwd` + log "ANDROID_TOP found at $ANDROID_TOP" + # $ANDROID_TOP/config/envsetup.make is for the old tree layout + # $ANDROID_TOP/build/envsetup.sh is for the new one + ANDROID_CONFIG_MK=$ANDROID_TOP/build/core/config.mk + if [ ! -f $ANDROID_CONFIG_MK ] ; then + ANDROID_CONFIG_MK=$ANDROID_TOP/config/envsetup.make + fi + if [ ! -f $ANDROID_CONFIG_MK ] ; then + echo "Weird: Cannot find build system root defaulting to non-Android build" + unset ANDROID_TOP + return + fi + # normalize ANDROID_TOP, we don't want a trailing / + ANDROID_TOPDIR=`dirname $ANDROID_TOP` + if [ "$ANDROID_TOPDIR" != "." ] ; then + ANDROID_TOP=$ANDROID_TOPDIR/`basename $ANDROID_TOP` + fi + IN_ANDROID_BUILD=yes +} + +# Get the value of an Android build variable as an absolute path. +# you should only call this if IN_ANDROID_BUILD is "yes" +# +get_android_abs_build_var () +{ + (cd $ANDROID_TOP && CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f $ANDROID_CONFIG_MK dumpvar-abs-$1) +} + +# Locate the Android prebuilt directory for your os +# you should only call this if IN_ANDROID_BUILD is "yes" +# +# This will set ANDROID_PREBUILT_HOST_TAG and ANDROID_PREBUILT +# +locate_android_prebuilt () +{ + # locate prebuilt directory + ANDROID_PREBUILT_HOST_TAG=$OS + case $OS in + linux-*) + # Linux is a special case because in the old tree layout + # we simply used 'Linux' as the prebuilt host tag, but + # are now using "linux-x86" in the new layout + # check which one should be used + # + if [ -d $ANDROID_TOP/prebuilt/Linux ] ; then + PREBUILT_HOST_TAG=Linux + fi + ;; + esac + ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG + if [ ! -d $ANDROID_PREBUILT ] ; then + # this can happen when building on x86_64 + case $OS in + linux-x86_64) + ANDROID_PREBUILT_HOST_TAG=linux-x86 + ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG + log "Forcing usage of 32-bit prebuilts" + force_32bit_binaries + ;; + *) + esac + if [ ! -d $ANDROID_PREBUILT ] ; then + echo "Can't find the prebuilt directory $ANDROID_PREBUILT in Android build" + exit 1 + fi + fi + log "Prebuilt : ANDROID_PREBUILT=$ANDROID_PREBUILT" +} + +## Build configuration file support +## you must define $config_mk before calling this function +## +create_config_mk () +{ + # create the directory if needed + local config_dir + config_mk=${config_mk:-objs/config.make} + config_dir=`dirname $config_mk` + mkdir -p $config_dir 2> $TMPL + if [ $? != 0 ] ; then + echo "Can't create directory for build config file: $config_dir" + cat $TMPL + clean_exit + fi + + # re-create the start of the configuration file + log "Generate : $config_mk" + + echo "# This file was autogenerated by $PROGNAME. Do not edit !" > $config_mk + echo "OS := $OS" >> $config_mk + echo "HOST_OS := $HOST_OS" >> $config_mk + echo "HOST_ARCH := $HOST_ARCH" >> $config_mk + echo "CC := $CC" >> $config_mk + echo "HOST_CC := $CC" >> $config_mk + echo "LD := $LD" >> $config_mk + echo "CFLAGS := $CFLAGS" >> $config_mk + echo "LDFLAGS := $LDFLAGS" >> $config_mk +} + +add_android_config_mk () +{ + echo "" >> $config_mk + echo "TARGET_ARCH := arm" >> $config_mk + echo "HOST_PREBUILT_TAG := $ANDROID_PREBUILT_HOST_TAG" >> $config_mk + echo "PREBUILT := $ANDROID_PREBUILT" >> $config_mk +} diff --git a/android/build/definitions.make b/android/build/definitions.make index cd03f89..4ba0d07 100644 --- a/android/build/definitions.make +++ b/android/build/definitions.make @@ -65,7 +65,7 @@ $$(OBJ): $$(SRC_PATH)/$$(SRC) @mkdir -p $$(dir $$(PRIVATE_OBJ)) @echo "Compile: $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC0)" $(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) -c -o $$(PRIVATE_OBJ) -MMD -MP -MF $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_SRC) - $(hide) $$(SRC_PATH)/android/build/mkdeps.sh $$(PRIVATE_OBJ) $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_OBJ).d + $(hide) $$(BUILD_SYSTEM)/mkdeps.sh $$(PRIVATE_OBJ) $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_OBJ).d endef # Compile an Objective-C source file @@ -85,7 +85,23 @@ $$(OBJ): $$(SRC_PATH)/$$(SRC) @mkdir -p $$(dir $$(PRIVATE_OBJ)) @echo "Compile: $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC0)" $(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) -c -o $$(PRIVATE_OBJ) -MMD -MP -MF $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_SRC) - $(hide) $$(SRC_PATH)/android/build/mkdeps.sh $$(PRIVATE_OBJ) $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_OBJ).d + $(hide) $$(BUILD_SYSTEM)/mkdeps.sh $$(PRIVATE_OBJ) $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_OBJ).d +endef + +# Install a file +# +define install-target +SRC:=$(1) +DST:=$(2) +$$(DST): PRIVATE_SRC := $$(SRC) +$$(DST): PRIVATE_DST := $$(DST) +$$(DST): PRIVATE_DST_NAME := $$(notdir $$(DST)) +$$(DST): PRIVATE_SRC_NAME := $$(SRC) +$$(DST): $$(SRC) + @mkdir -p $$(dir $$(PRIVATE_DST)) + @echo "Install: $$(PRIVATE_DST_NAME) <= $$(PRIVATE_SRC_NAME)" + $(hide) cp -f $$(PRIVATE_SRC) $$(PRIVATE_DST) +install: $$(DST) endef # for now, we only use prebuilt SDL libraries, so copy them diff --git a/android/cmdline-option.c b/android/cmdline-option.c index b773d9d..fb5aa23 100644 --- a/android/cmdline-option.c +++ b/android/cmdline-option.c @@ -1,6 +1,7 @@ #include "android/cmdline-option.h" #include "android/utils/debug.h" #include "android/utils/misc.h" +#include "android/utils/system.h" #include <stdlib.h> #include <stddef.h> #include <string.h> @@ -15,11 +16,16 @@ debug_tags[] = { static void parse_debug_tags( const char* tags ); void parse_env_debug_tags( void ); +enum { + OPTION_IS_FLAG = 0, + OPTION_IS_PARAM, + OPTION_IS_LIST, +}; typedef struct { const char* name; int var_offset; - int var_is_param; + int var_type; int var_is_config; } OptionInfo; @@ -28,10 +34,11 @@ typedef struct { static const OptionInfo option_keys[] = { -#define OPT_PARAM(_name,_template,_descr) OPTION(_name,1,0) -#define OPT_FLAG(_name,_descr) OPTION(_name,0,0) -#define CFG_PARAM(_name,_template,_descr) OPTION(_name,1,1) -#define CFG_FLAG(_name,_descr) OPTION(_name,0,1) +#define OPT_FLAG(_name,_descr) OPTION(_name,OPTION_IS_FLAG,0) +#define OPT_PARAM(_name,_template,_descr) OPTION(_name,OPTION_IS_PARAM,0) +#define OPT_LIST(_name,_template,_descr) OPTION(_name,OPTION_IS_LIST,0) +#define CFG_FLAG(_name,_descr) OPTION(_name,OPTION_IS_FLAG,1) +#define CFG_PARAM(_name,_template,_descr) OPTION(_name,OPTION_IS_PARAM,1) #include "android/cmdline-options.h" { NULL, 0, 0, 0 } }; @@ -145,15 +152,31 @@ android_parse_options( int *pargc, char** *pargv, AndroidOptions* opt ) if ( !strcmp( oo->name, arg2 ) ) { void* field = (char*)opt + oo->var_offset; - if (oo->var_is_param) { - /* parameter option */ + if (oo->var_type != OPTION_IS_FLAG) { + /* parameter/list option */ if (nargs == 0) { derror( "-%s must be followed by parameter (see -help-%s)", arg, arg ); exit(1); } nargs--; - ((char**)field)[0] = *aread++; + + if (oo->var_type == OPTION_IS_PARAM) + { + ((char**)field)[0] = *aread++; + } + else if (oo->var_type == OPTION_IS_LIST) + { + ParamList** head = (ParamList**)field; + ParamList* pl; + ANEW0(pl); + /* note: store list items in reverse order here + * the list is reversed later in this function. + */ + pl->param = *aread++; + pl->next = *head; + *head = pl; + } } else { /* flag option */ ((int*)field)[0] = 1; @@ -182,6 +205,28 @@ android_parse_options( int *pargc, char** *pargv, AndroidOptions* opt ) awrite[0] = NULL; + /* reverse any parameter list before exit. + */ + { + const OptionInfo* oo = option_keys; + + for ( ; oo->name; oo++ ) { + if ( oo->var_type == OPTION_IS_LIST ) { + ParamList** head = (ParamList**)((char*)opt + oo->var_offset); + ParamList* prev = NULL; + ParamList* cur = *head; + + while (cur != NULL) { + ParamList* next = cur->next; + cur->next = prev; + prev = cur; + cur = next; + } + *head = prev; + } + } + } + return 0; } diff --git a/android/cmdline-option.h b/android/cmdline-option.h index b87144d..90a7e64 100644 --- a/android/cmdline-option.h +++ b/android/cmdline-option.h @@ -12,9 +12,17 @@ #ifndef _ANDROID_OPTION_H #define _ANDROID_OPTION_H +/* a structure used to model a linked list of parameters + */ +typedef struct ParamList { + char* param; + struct ParamList* next; +} ParamList; + /* define a structure that will hold all option variables */ typedef struct { +#define OPT_LIST(n,t,d) ParamList* n; #define OPT_PARAM(n,t,d) char* n; #define OPT_FLAG(n,d) int n; #include "android/cmdline-options.h" diff --git a/android/cmdline-options.h b/android/cmdline-options.h index 5291177..0689e83 100644 --- a/android/cmdline-options.h +++ b/android/cmdline-options.h @@ -5,6 +5,9 @@ #ifndef OPT_PARAM #error OPT_PARAM is not defined #endif +#ifndef OPT_LIST +#error OPT_LIST is not defined +#endif #ifndef OPT_FLAG #error OPT_FLAG is not defined #endif @@ -128,6 +131,8 @@ OPT_PARAM( tcpdump, "<file>", "capture network packets to file" ) OPT_PARAM( bootchart, "<timeout>", "enable bootcharting") +OPT_LIST( prop, "<name>=<value>", "set system property on boot") + #ifdef CONFIG_NAND_LIMITS OPT_PARAM( nand_limits, "<nlimits>", "enforce NAND/Flash read/write thresholds" ) #endif @@ -137,3 +142,4 @@ OPT_PARAM( nand_limits, "<nlimits>", "enforce NAND/Flash read/write thresholds" #undef CFG_PARAM #undef OPT_FLAG #undef OPT_PARAM +#undef OPT_LIST diff --git a/android/help.c b/android/help.c index 391b63d..d01ccc9 100644 --- a/android/help.c +++ b/android/help.c @@ -5,6 +5,7 @@ #include "android/utils/debug.h" #include "android/utils/misc.h" #include "android/skin/keyset.h" +#include "android/boot-properties.h" #include "android/android.h" #include <stdint.h> #include "audio/audio.h" @@ -1281,6 +1282,24 @@ help_tcpdump(stralloc_t *out) ); } +static void +help_prop(stralloc_t *out) +{ + PRINTF( + " use '-prop <name>=<value>' to set a boot-time system property.\n" + " <name> must be a property name of at most %d characters, without any\n" + " space in it, and <value> must be a string of at most %d characters.\n\n", + PROPERTY_MAX_NAME, PROPERTY_MAX_VALUE ); + + PRINTF( + " the corresponding system property will be set at boot time in the\n" + " emulated system. This can be useful for debugging purposes.\n\n" + + " note that you can use several -prop options to define more than one\n" + " boot property.\n\n" + ); +} + #define help_no_skin NULL #define help_netspeed help_shaper #define help_netdelay help_shaper @@ -1307,6 +1326,7 @@ typedef struct { static const OptionHelp option_help[] = { #define OPT_FLAG(_name,_descr) { STRINGIFY(_name), NULL, _descr, help_##_name }, #define OPT_PARAM(_name,_template,_descr) { STRINGIFY(_name), _template, _descr, help_##_name }, +#define OPT_LIST OPT_PARAM #include "android/cmdline-options.h" { NULL, NULL, NULL, NULL } }; diff --git a/android/hw-control.c b/android/hw-control.c index a82a92a..d99f7e3 100644 --- a/android/hw-control.c +++ b/android/hw-control.c @@ -51,9 +51,10 @@ static void hw_control_do_query( HwControl* h, uint8_t* query, int querylen /* called when a qemud client sends a command */ static void -_hw_control_qemud_client_recv( void* opaque, - uint8_t* msg, - int msglen ) +_hw_control_qemud_client_recv( void* opaque, + uint8_t* msg, + int msglen, + QemudClient* client ) { hw_control_do_query(opaque, msg, msglen); } diff --git a/android/hw-lcd.c b/android/hw-lcd.c new file mode 100644 index 0000000..2c06d69 --- /dev/null +++ b/android/hw-lcd.c @@ -0,0 +1,32 @@ +/* Copyright (C) 2009 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/hw-lcd.h" +#include "android/boot-properties.h" +#include <stdio.h> + +void +hwLcd_setBootProperty(int density) +{ + char temp[8]; + + /* map density to one of our three values for now */ + if (density < (LCD_DENSITY_MIN + LCD_DENSITY_DEFAULT)/2) + density = LCD_DENSITY_MIN; + else if (density < (LCD_DENSITY_DEFAULT + LCD_DENSITY_MAX)/2) + density = LCD_DENSITY_DEFAULT; + else + density = LCD_DENSITY_MAX; + + snprintf(temp, sizeof temp, "%d", density); + boot_property_add("qemu.sf.lcd_density", temp); +} + diff --git a/android/hw-lcd.h b/android/hw-lcd.h new file mode 100644 index 0000000..b9fdb72 --- /dev/null +++ b/android/hw-lcd.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2009 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ +#ifndef _ANDROID_HW_LCD_H +#define _ANDROID_HW_LCD_H + +#define LCD_DENSITY_MIN 120 +#define LCD_DENSITY_DEFAULT 160 +#define LCD_DENSITY_MAX 240 + +/* Sets the boot property corresponding to the emulated abstract LCD density */ +extern void hwLcd_setBootProperty(int density); + +#endif /* _ANDROID_HW_LCD_H */ + diff --git a/android/hw-qemud.c b/android/hw-qemud.c index ba4ab42..efe6a99 100644 --- a/android/hw-qemud.c +++ b/android/hw-qemud.c @@ -545,7 +545,7 @@ qemud_client_recv( void* opaque, uint8_t* msg, int msglen ) /* no framing, things are simple */ if (!c->framing) { if (c->clie_recv) - c->clie_recv( c->clie_opaque, msg, msglen ); + c->clie_recv( c->clie_opaque, msg, msglen, c ); return; } @@ -566,7 +566,7 @@ qemud_client_recv( void* opaque, uint8_t* msg, int msglen ) if (c->clie_recv) c->clie_recv( c->clie_opaque, msg+FRAME_HEADER_SIZE, - msglen-FRAME_HEADER_SIZE); + msglen-FRAME_HEADER_SIZE, c ); return; } } @@ -606,7 +606,7 @@ qemud_client_recv( void* opaque, uint8_t* msg, int msglen ) if (c->clie_recv) - c->clie_recv( c->clie_opaque, c->payload->buff, c->payload->size ); + c->clie_recv( c->clie_opaque, c->payload->buff, c->payload->size, c ); AFREE(c->payload->buff); c->need_header = 1; @@ -893,9 +893,10 @@ qemud_multiplexer_disconnect( QemudMultiplexer* m, * (i.e. msg[msglen] is a valid memory read that returns '\0') */ static void -qemud_multiplexer_control_recv( void* opaque, - uint8_t* msg, - int msglen ) +qemud_multiplexer_control_recv( void* opaque, + uint8_t* msg, + int msglen, + QemudClient* client ) { QemudMultiplexer* mult = opaque; uint8_t* msgend = msg + msglen; @@ -1226,7 +1227,8 @@ typedef struct { * this simply sends the message through the charpipe to the user. */ static void -_qemud_char_client_recv( void* opaque, uint8_t* msg, int msglen ) +_qemud_char_client_recv( void* opaque, uint8_t* msg, int msglen, + QemudClient* client ) { CharDriverState* cs = opaque; qemu_chr_write(cs, msg, msglen); diff --git a/android/hw-qemud.h b/android/hw-qemud.h index 5b45a94..8aae74d 100644 --- a/android/hw-qemud.h +++ b/android/hw-qemud.h @@ -62,28 +62,58 @@ typedef struct QemudClient QemudClient; typedef struct QemudService QemudService; +/* A function that will be called when the client running in the emulated + * system has closed its connection to qemud. + */ typedef void (*QemudClientClose)( void* opaque ); -typedef void (*QemudClientRecv) ( void* opaque, uint8_t* msg, int msglen ); +/* A function that will be called when the client sends a message to the + * service through qemud. + */ +typedef void (*QemudClientRecv) ( void* opaque, uint8_t* msg, int msglen, QemudClient* client ); + +/* Register a new client for a given service. + * 'clie_opaque' will be sent as the first argument to 'clie_recv' and 'clie_close' + * 'clie_recv' and 'clie_close' are both optional and may be NULL. + * + * You should typically use this function within a QemudServiceConnect callback + * (see below). + */ extern QemudClient* qemud_client_new( QemudService* service, int channel_id, void* clie_opaque, QemudClientRecv clie_recv, QemudClientClose clie_close ); +/* Enable framing on a given client channel. + */ extern void qemud_client_set_framing( QemudClient* client, int enabled ); +/* Send a message to a given qemud client + */ extern void qemud_client_send ( QemudClient* client, const uint8_t* msg, int msglen ); + +/* Force-close the connection to a given qemud client. + */ extern void qemud_client_close( QemudClient* client ); +/* A function that will be called each time a new client in the emulated + * system tries to connect to a given qemud service. This should typically + * call qemud_client_new() to register a new client. + */ typedef QemudClient* (*QemudServiceConnect)( void* opaque, QemudService* service, int channel ); +/* Register a new qemud service. + * 'serv_opaque' is the first parameter to 'serv_connect' + */ extern QemudService* qemud_service_register( const char* serviceName, int max_clients, void* serv_opaque, QemudServiceConnect serv_connect ); +/* Sends a message to all clients of a given service. + */ extern void qemud_service_broadcast( QemudService* sv, const uint8_t* msg, int msglen ); diff --git a/android/hw-sensors.c b/android/hw-sensors.c index eb2cc78..1fa12dc 100644 --- a/android/hw-sensors.c +++ b/android/hw-sensors.c @@ -13,6 +13,7 @@ #include "android/hw-sensors.h" #include "android/utils/debug.h" #include "android/utils/misc.h" +#include "android/utils/system.h" #include "android/hw-qemud.h" #include "android/globals.h" #include "qemu-char.h" @@ -139,188 +140,172 @@ typedef struct { #define HEADER_SIZE 4 #define BUFFER_SIZE 512 +typedef struct HwSensorClient HwSensorClient; + typedef struct { - QemudService* service; - int32_t delay_ms; - uint32_t enabledMask; - QEMUTimer* timer; - Sensor sensors[MAX_SENSORS]; + QemudService* service; + Sensor sensors[MAX_SENSORS]; + HwSensorClient* clients; } HwSensors; -/* forward */ - -static void hw_sensors_receive( HwSensors* h, - uint8_t* query, - int querylen ); - -static void hw_sensors_timer_tick(void* opaque); - -/* Qemud service management */ +struct HwSensorClient { + HwSensorClient* next; + HwSensors* sensors; + QemudClient* client; + QEMUTimer* timer; + uint32_t enabledMask; + int32_t delay_ms; +}; static void -_hw_sensors_qemud_client_recv( void* opaque, uint8_t* msg, int msglen ) +_hwSensorClient_free( HwSensorClient* cl ) { - hw_sensors_receive(opaque, msg, msglen); -} + /* remove from sensors's list */ + if (cl->sensors) { + HwSensorClient** pnode = &cl->sensors->clients; + for (;;) { + HwSensorClient* node = *pnode; + if (node == NULL) + break; + if (node == cl) { + *pnode = cl->next; + break; + } + pnode = &node->next; + } + cl->next = NULL; + cl->sensors = NULL; + } -static QemudClient* -_hw_sensors_service_connect( void* opaque, QemudService* service, int channel ) -{ - HwSensors* sensors = opaque; - QemudClient* client = qemud_client_new(service, channel, - sensors, - _hw_sensors_qemud_client_recv, - NULL); - qemud_client_set_framing(client, 1); - return client; + /* close QEMUD client, if any */ + if (cl->client) { + qemud_client_close(cl->client); + cl->client = NULL; + } + /* remove timer, if any */ + if (cl->timer) { + qemu_del_timer(cl->timer); + qemu_free_timer(cl->timer); + cl->timer = NULL; + } + AFREE(cl); } -/* change the value of the emulated acceleration vector */ -static void -hw_sensors_set_acceleration( HwSensors* h, float x, float y, float z ) -{ - Sensor* s = &h->sensors[ANDROID_SENSOR_ACCELERATION]; - s->u.acceleration.x = x; - s->u.acceleration.y = y; - s->u.acceleration.z = z; -} +/* forward */ +static void _hwSensorClient_tick(void* opaque); -#if 0 /* not used yet */ -/* change the value of the emulated magnetic vector */ -static void -hw_sensors_set_magnetic_field( HwSensors* h, float x, float y, float z ) -{ - Sensor* s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD]; - s->u.magnetic.x = x; - s->u.magnetic.y = y; - s->u.magnetic.z = z; -} -/* change the values of the emulated orientation */ -static void -hw_sensors_set_orientation( HwSensors* h, float azimuth, float pitch, float roll ) +static HwSensorClient* +_hwSensorClient_new( HwSensors* sensors ) { - Sensor* s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD]; - s->u.orientation.azimuth = azimuth; - s->u.orientation.pitch = pitch; - s->u.orientation.roll = roll; -} + HwSensorClient* cl; -/* change the emulated temperature */ -static void -hw_sensors_set_temperature( HwSensors* h, float celsius ) -{ - Sensor* s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD]; - s->u.temperature.celsius = celsius; + ANEW0(cl); + + cl->sensors = sensors; + cl->enabledMask = 0; + cl->delay_ms = 1000; + cl->timer = qemu_new_timer(vm_clock, _hwSensorClient_tick, cl); + + cl->next = sensors->clients; + sensors->clients = cl; + + return cl; } -#endif -/* change the coarse orientation (landscape/portrait) of the emulated device */ +/* forward */ + +static void _hwSensorClient_receive( HwSensorClient* cl, + uint8_t* query, + int querylen ); + +/* Qemud service management */ + static void -hw_sensors_set_coarse_orientation( HwSensors* h, AndroidCoarseOrientation orient ) +_hwSensorClient_recv( void* opaque, uint8_t* msg, int msglen, + QemudClient* client ) { - /* The Android framework computes the orientation by looking at - * the accelerometer sensor (*not* the orientation sensor !) - * - * That's because the gravity is a constant 9.81 vector that - * can be determined quite easily. - * - * Also, for some reason, the framework code considers that the phone should - * be inclined by 30 degrees along the phone's X axis to be considered - * in its ideal "vertical" position - * - * If the phone is completely vertical, rotating it will not do anything ! - */ - const double g = 9.81; - const double cos_30 = 0.866025403784; - const double sin_30 = 0.5; + HwSensorClient* cl = opaque; - switch (orient) { - case ANDROID_COARSE_PORTRAIT: - hw_sensors_set_acceleration( h, 0., g*cos_30, g*sin_30 ); - break; - - case ANDROID_COARSE_LANDSCAPE: - hw_sensors_set_acceleration( h, g*cos_30, 0., g*sin_30 ); - break; - default: - ; - } + _hwSensorClient_receive(cl, msg, msglen); } - -/* initialize the sensors state */ static void -hw_sensors_init( HwSensors* h ) +_hwSensorClient_close( void* opaque ) { - h->service = qemud_service_register("sensors", 1, h, - _hw_sensors_service_connect ); - h->enabledMask = 0; - h->delay_ms = 1000; - h->timer = qemu_new_timer(vm_clock, hw_sensors_timer_tick, h); + HwSensorClient* cl = opaque; - hw_sensors_set_coarse_orientation(h, ANDROID_COARSE_PORTRAIT); + /* the client is already closed here */ + cl->client = NULL; + _hwSensorClient_free(cl); } /* send a one-line message to the HAL module through a qemud channel */ static void -hw_sensors_send( HwSensors* hw, const uint8_t* msg, int msglen ) +_hwSensorClient_send( HwSensorClient* cl, const uint8_t* msg, int msglen ) { D("%s: '%s'", __FUNCTION__, quote_bytes((const void*)msg, msglen)); - qemud_service_broadcast(hw->service, msg, msglen); + qemud_client_send(cl->client, msg, msglen); +} + +static int +_hwSensorClient_enabled( HwSensorClient* cl, int sensorId ) +{ + return (cl->enabledMask & (1 << sensorId)) != 0; } /* this function is called periodically to send sensor reports * to the HAL module, and re-arm the timer if necessary */ static void -hw_sensors_timer_tick( void* opaque ) +_hwSensorClient_tick( void* opaque ) { - HwSensors* h = opaque; - int64_t delay = h->delay_ms; - int64_t now_ns; - uint32_t mask = h->enabledMask; - Sensor* sensor; - char buffer[128]; - - sensor = &h->sensors[ANDROID_SENSOR_ACCELERATION]; - if (sensor->enabled) { + HwSensorClient* cl = opaque; + HwSensors* hw = cl->sensors; + int64_t delay = cl->delay_ms; + int64_t now_ns; + uint32_t mask = cl->enabledMask; + Sensor* sensor; + char buffer[128]; + + if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ACCELERATION)) { + sensor = &hw->sensors[ANDROID_SENSOR_ACCELERATION]; snprintf(buffer, sizeof buffer, "acceleration:%g:%g:%g", sensor->u.acceleration.x, sensor->u.acceleration.y, sensor->u.acceleration.z); - hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer)); + _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); } - sensor = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD]; - if (sensor->enabled) { + if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_MAGNETIC_FIELD)) { + sensor = &hw->sensors[ANDROID_SENSOR_MAGNETIC_FIELD]; snprintf(buffer, sizeof buffer, "magnetic-field:%g:%g:%g", sensor->u.magnetic.x, sensor->u.magnetic.y, sensor->u.magnetic.z); - hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer)); + _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); } - sensor = &h->sensors[ANDROID_SENSOR_ORIENTATION]; - if (sensor->enabled) { + if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ORIENTATION)) { + sensor = &hw->sensors[ANDROID_SENSOR_ORIENTATION]; snprintf(buffer, sizeof buffer, "orientation:%g:%g:%g", sensor->u.orientation.azimuth, sensor->u.orientation.pitch, sensor->u.orientation.roll); - hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer)); + _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); } - sensor = &h->sensors[ANDROID_SENSOR_TEMPERATURE]; - if (sensor->enabled) { + if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_TEMPERATURE)) { + sensor = &hw->sensors[ANDROID_SENSOR_TEMPERATURE]; snprintf(buffer, sizeof buffer, "temperature:%g", sensor->u.temperature.celsius); - hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer)); + _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); } now_ns = qemu_get_clock(vm_clock); snprintf(buffer, sizeof buffer, "sync:%lld", now_ns/1000); - hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer)); + _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer)); /* rearm timer, use a minimum delay of 20 ms, just to * be safe. @@ -332,13 +317,15 @@ hw_sensors_timer_tick( void* opaque ) delay = 20; delay *= 1000000LL; /* convert to nanoseconds */ - qemu_mod_timer(h->timer, now_ns + delay); + qemu_mod_timer(cl->timer, now_ns + delay); } /* handle incoming messages from the HAL module */ static void -hw_sensors_receive( HwSensors* hw, uint8_t* msg, int msglen ) +_hwSensorClient_receive( HwSensorClient* cl, uint8_t* msg, int msglen ) { + HwSensors* hw = cl->sensors; + D("%s: '%.*s'", __FUNCTION__, msglen, msg); /* "list-sensors" is used to get an integer bit map of @@ -348,15 +335,15 @@ hw_sensors_receive( HwSensors* hw, uint8_t* msg, int msglen ) if (msglen == 12 && !memcmp(msg, "list-sensors", 12)) { char buff[12]; int mask = 0; + int nn; - if (android_hw->hw_accelerometer) - mask |= (1 << ANDROID_SENSOR_ACCELERATION); - - /* XXX: TODO: Add other tests when we add the corresponding - * properties to hardware-properties.ini et al. */ + for (nn = 0; nn < MAX_SENSORS; nn++) { + if (hw->sensors[nn].enabled) + mask |= (1 << nn); + } snprintf(buff, sizeof buff, "%d", mask); - hw_sensors_send(hw, (const uint8_t*)buff, strlen(buff)); + _hwSensorClient_send(cl, (const uint8_t*)buff, strlen(buff)); return; } @@ -364,7 +351,7 @@ hw_sensors_receive( HwSensors* hw, uint8_t* msg, int msglen ) * the channel. It is used to exit a blocking read. */ if (msglen == 4 && !memcmp(msg, "wake", 4)) { - hw_sensors_send(hw, (const uint8_t*)"wake", 4); + _hwSensorClient_send(cl, (const uint8_t*)"wake", 4); return; } @@ -372,9 +359,9 @@ hw_sensors_receive( HwSensors* hw, uint8_t* msg, int msglen ) * between sensor events */ if (msglen > 10 && !memcmp(msg, "set-delay:", 10)) { - hw->delay_ms = atoi((const char*)msg+10); - if (hw->enabledMask != 0) - hw_sensors_timer_tick(hw); + cl->delay_ms = atoi((const char*)msg+10); + if (cl->enabledMask != 0) + _hwSensorClient_tick(cl); return; } @@ -384,7 +371,7 @@ hw_sensors_receive( HwSensors* hw, uint8_t* msg, int msglen ) */ if (msglen > 4 && !memcmp(msg, "set:", 4)) { char* q; - int id, enabled, oldEnabledMask = hw->enabledMask; + int id, enabled, oldEnabledMask = cl->enabledMask; msg += 4; q = strchr((char*)msg, ':'); if (q == NULL) { /* should not happen */ @@ -394,32 +381,27 @@ hw_sensors_receive( HwSensors* hw, uint8_t* msg, int msglen ) *q++ = 0; id = _sensorIdFromName((const char*)msg); - if (id < 0) { + if (id < 0 || id >= MAX_SENSORS) { D("%s: ignore unknown sensor name '%s'", __FUNCTION__, msg); return; } + if (!hw->sensors[id].enabled) { + D("%s: trying to set disabled %s sensor", __FUNCTION__, msg); + return; + } enabled = (q[0] == '1'); - hw->sensors[id].enabled = (char) enabled; if (enabled) - hw->enabledMask |= (1 << id); + cl->enabledMask |= (1 << id); else - hw->enabledMask &= ~(1 << id); - - D("%s: %s %s sensor", __FUNCTION__, - hw->sensors[id].enabled ? "enabling" : "disabling", msg); + cl->enabledMask &= ~(1 << id); - if (oldEnabledMask == 0 && enabled) { - /* we enabled our first sensor, start event reporting */ - D("%s: starting event reporting (mask=%04x)", __FUNCTION__, - hw->enabledMask); - } - else if (hw->enabledMask == 0 && !enabled) { - /* we disabled our last sensor, stop event reporting */ - D("%s: stopping event reporting", __FUNCTION__); + if (cl->enabledMask != oldEnabledMask) { + D("%s: %s %s sensor", __FUNCTION__, + (cl->enabledMask & (1 << id)) ? "enabling" : "disabling", msg); } - hw_sensors_timer_tick(hw); + _hwSensorClient_tick(cl); return; } @@ -427,6 +409,110 @@ hw_sensors_receive( HwSensors* hw, uint8_t* msg, int msglen ) } +static QemudClient* +_hwSensors_connect( void* opaque, QemudService* service, int channel ) +{ + HwSensors* sensors = opaque; + HwSensorClient* cl = _hwSensorClient_new(sensors); + QemudClient* client = qemud_client_new(service, channel, cl, + _hwSensorClient_recv, + _hwSensorClient_close); + qemud_client_set_framing(client, 1); + cl->client = client; + + return client; +} + +/* change the value of the emulated acceleration vector */ +static void +_hwSensors_setAcceleration( HwSensors* h, float x, float y, float z ) +{ + Sensor* s = &h->sensors[ANDROID_SENSOR_ACCELERATION]; + s->u.acceleration.x = x; + s->u.acceleration.y = y; + s->u.acceleration.z = z; +} + +#if 0 /* not used yet */ +/* change the value of the emulated magnetic vector */ +static void +_hwSensors_setMagneticField( HwSensors* h, float x, float y, float z ) +{ + Sensor* s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD]; + s->u.magnetic.x = x; + s->u.magnetic.y = y; + s->u.magnetic.z = z; +} + +/* change the values of the emulated orientation */ +static void +_hwSensors_setOrientation( HwSensors* h, float azimuth, float pitch, float roll ) +{ + Sensor* s = &h->sensors[ANDROID_SENSOR_ORIENTATION]; + s->u.orientation.azimuth = azimuth; + s->u.orientation.pitch = pitch; + s->u.orientation.roll = roll; +} + +/* change the emulated temperature */ +static void +_hwSensors_setTemperature( HwSensors* h, float celsius ) +{ + Sensor* s = &h->sensors[ANDROID_SENSOR_TEMPERATURE]; + s->u.temperature.celsius = celsius; +} +#endif + +/* change the coarse orientation (landscape/portrait) of the emulated device */ +static void +_hwSensors_setCoarseOrientation( HwSensors* h, AndroidCoarseOrientation orient ) +{ + /* The Android framework computes the orientation by looking at + * the accelerometer sensor (*not* the orientation sensor !) + * + * That's because the gravity is a constant 9.81 vector that + * can be determined quite easily. + * + * Also, for some reason, the framework code considers that the phone should + * be inclined by 30 degrees along the phone's X axis to be considered + * in its ideal "vertical" position + * + * If the phone is completely vertical, rotating it will not do anything ! + */ + const double g = 9.81; + const double cos_30 = 0.866025403784; + const double sin_30 = 0.5; + + switch (orient) { + case ANDROID_COARSE_PORTRAIT: + _hwSensors_setAcceleration( h, 0., g*cos_30, g*sin_30 ); + break; + + case ANDROID_COARSE_LANDSCAPE: + _hwSensors_setAcceleration( h, g*cos_30, 0., g*sin_30 ); + break; + default: + ; + } +} + + +/* initialize the sensors state */ +static void +_hwSensors_init( HwSensors* h ) +{ + h->service = qemud_service_register("sensors", 0, h, + _hwSensors_connect ); + + if (android_hw->hw_accelerometer) + h->sensors[ANDROID_SENSOR_ACCELERATION].enabled = 1; + + /* XXX: TODO: Add other tests when we add the corresponding + * properties to hardware-properties.ini et al. */ + + _hwSensors_setCoarseOrientation(h, ANDROID_COARSE_PORTRAIT); +} + static HwSensors _sensorsState[1]; void @@ -435,7 +521,7 @@ android_hw_sensors_init( void ) HwSensors* hw = _sensorsState; if (hw->service == NULL) { - hw_sensors_init(hw); + _hwSensors_init(hw); D("%s: sensors qemud service initialized", __FUNCTION__); } } @@ -445,6 +531,6 @@ extern void android_sensors_set_coarse_orientation( AndroidCoarseOrientation orient ) { android_hw_sensors_init(); - hw_sensors_set_coarse_orientation(_sensorsState, orient); + _hwSensors_setCoarseOrientation(_sensorsState, orient); } diff --git a/android/main.c b/android/main.c index 787d551..0712f32 100644 --- a/android/main.c +++ b/android/main.c @@ -50,14 +50,15 @@ #include "android/gps.h" #include "android/hw-qemud.h" #include "android/hw-kmsg.h" +#include "android/hw-lcd.h" #include "android/hw-control.h" #include "android/hw-sensors.h" +#include "android/boot-properties.h" #include "android/user-config.h" #include "android/utils/bufprint.h" #include "android/utils/dirscanner.h" #include "android/utils/path.h" #include "android/utils/timezone.h" -#include "android/utils/display.h" #include "android/cmdline-option.h" #include "android/help.h" @@ -393,7 +394,7 @@ qemulator_rotate_keycode( QEmulator* emulator, static int get_device_dpi( AndroidOptions* opts ) { - int dpi_device = DEFAULT_DEVICE_DPI; + int dpi_device = android_hw->hw_lcd_density; if (opts->dpi_device != NULL) { char* end; @@ -425,7 +426,7 @@ get_default_scale( AndroidOptions* opts ) /* we need to get the host dpi resolution ? */ int xdpi, ydpi; - if ( get_monitor_resolution( &xdpi, &ydpi ) < 0 ) { + if ( SDL_WM_GetMonitorDPI( &xdpi, &ydpi ) < 0 ) { fprintf(stderr, "could not get monitor DPI resolution from system. please use -dpi-monitor to specify one\n" ); exit(1); } @@ -2493,6 +2494,22 @@ int main(int argc, char **argv) } } + /* start the 'boot-properties service, and parse the -prop + * options, if any. + */ + boot_property_init_service(); + + hwLcd_setBootProperty(get_device_dpi(opts)); + + if (opts->prop != NULL) { + ParamList* pl = opts->prop; + for ( ; pl != NULL; pl = pl->next ) { + boot_property_parse_option(pl->param); + } + } + + /* Setup the kernel init options + */ { static char params[1024]; char *p = params, *end = p + sizeof(params); diff --git a/android/skin/file.c b/android/skin/file.c index b0cb9cf..3d5ea7f 100644 --- a/android/skin/file.c +++ b/android/skin/file.c @@ -125,6 +125,7 @@ static KeyInfo _keyinfo_table[] = { { "dpad-center", kKeyCodeDpadCenter }, { "soft-left", kKeyCodeSoftLeft }, { "soft-right", kKeyCodeSoftRight }, + { "search", kKeyCodeSearch }, { "volume-up", kKeyCodeVolumeUp }, { "volume-down", kKeyCodeVolumeDown }, { "power", kKeyCodePower }, diff --git a/android/skin/window.c b/android/skin/window.c index 7ce5759..674b594 100644 --- a/android/skin/window.c +++ b/android/skin/window.c @@ -14,7 +14,6 @@ #include "android/skin/scaler.h" #include "android/charmap.h" #include "android/utils/debug.h" -#include "android/utils/display.h" #include "android/hw-sensors.h" #include <SDL_syswm.h> #include "qemu-common.h" @@ -1107,12 +1106,19 @@ skin_window_resize( SkinWindow* window ) int fullscreen = window->fullscreen; if (fullscreen) { - if (get_nearest_monitor_rect(&window_x, &window_y, - &window_w, &window_h) < 0) { + SDL_Rect r; + if (SDL_WM_GetMonitorRect(&r) < 0) { fullscreen = 0; } else { - double x_scale = window_w * 1.0 / layout_w; - double y_scale = window_h * 1.0 / layout_h; + double x_scale, y_scale; + + window_x = r.x; + window_y = r.y; + window_w = r.w; + window_h = r.h; + + x_scale = window_w * 1.0 / layout_w; + y_scale = window_h * 1.0 / layout_h; scale = (x_scale <= y_scale) ? x_scale : y_scale; } diff --git a/android/utils/display-quartz.m b/android/utils/display-quartz.m deleted file mode 100644 index 594657e..0000000 --- a/android/utils/display-quartz.m +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2007-2008 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. -*/ - -/* this is the Quartz-specific implementation of - * <android/utils/display.h> - */ - -#include "android/utils/display.h" -#include "android/utils/debug.h" - -#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) - -#include <stdio.h> -#include <Cocoa/Cocoa.h> -#include <Carbon/Carbon.h> -#include <SDL_syswm.h> - -int -get_monitor_resolution( int *px_dpi, int *py_dpi ) -{ - fprintf(stderr, "emulator: FIXME: implement get_monitor_resolution on OS X\n" ); - return -1; -} - -int -get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) -{ - SDL_SysWMinfo info; - NSWindow* window; - - SDL_VERSION(&info.version); - if ( SDL_GetWMInfo(&info) < 0 ) { - D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError()); - return -1; - } - window = info.nsWindowPtr; - if (window == NULL) { - D( "%s: SDL_GetWMInfo() returned NULL NSWindow ptr", - __FUNCTION__ ); - return -1; - } - else - { - NSRect frame = [ window frame ]; - int fx1 = frame.origin.x; - int fy1 = frame.origin.y; - int fx2 = frame.size.width + fx1; - int fy2 = frame.size.height + fy1; - NSArray* screens = [ NSScreen screens ]; - unsigned int count = [ screens count ]; - int bestScreen = -1; - int bestArea = 0; - - unsigned int n; - printf( "window frame (%d,%d) (%d,%d)\n", fx1, fy1, fx2, fy2 ); - - /* we need to compute which screen has the most window pixels */ - for (n = 0; n < count; n++) { - NSScreen* screen = [ screens objectAtIndex: n ]; - NSRect vis = [ screen visibleFrame ]; - int vx1 = vis.origin.x; - int vy1 = vis.origin.y; - int vx2 = vis.size.width + vx1; - int vy2 = vis.size.height + vy1; - int cx1, cx2, cy1, cy2, cArea; - - //printf( "screen %d/%d frame (%d,%d) (%d,%d)\n", n+1, count, - // vx1, vy1, vx2, vy2 ); - - if (fx1 >= vx2 || vx1 >= fx2 || fy1 >= vy2 || vy1 >= fy2) - continue; - - cx1 = (fx1 < vx1) ? vx1 : fx1; - cx2 = (fx2 > vx2) ? vx2 : fx2; - cy1 = (fy1 < vy1) ? vy1 : fy1; - cy2 = (fy2 > vy2) ? vy2 : fy2; - - if (cx1 >= cx2 || cy1 >= cy2) - continue; - - cArea = (cx2-cx1)*(cy2-cy1); - - if (bestScreen < 0 || cArea > bestArea) { - bestScreen = n; - bestArea = cArea; - } - } - if (bestScreen < 0) - bestScreen = 0; - - { - NSScreen* screen = [ screens objectAtIndex: bestScreen ]; - NSRect vis = [ screen visibleFrame ]; - - *x = vis.origin.x; - *y = vis.origin.y; - *width = vis.size.width; - *height = vis.size.height; - } - return 0; - } -}; diff --git a/android/utils/display.c b/android/utils/display.c deleted file mode 100644 index e1ba507..0000000 --- a/android/utils/display.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright (C) 2007-2008 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/display.h" -#include "android/utils/debug.h" - -#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) - -/** HOST RESOLUTION SETTINGS - ** - ** return the main monitor's DPI resolution according to the host device - ** beware: this is not always reliable or even obtainable. - ** - ** returns 0 on success, or -1 in case of error (e.g. the system returns funky values) - **/ - -/** NOTE: the following code assumes that we exclusively use X11 on Linux, and Quartz on OS X - **/ - -#ifdef _WIN32 - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <SDL_syswm.h> - -int -get_monitor_resolution( int *px_dpi, int *py_dpi ) -{ - HDC displayDC = CreateDC( "DISPLAY", NULL, NULL, NULL ); - int xdpi, ydpi; - - if (displayDC == NULL) { - D( "%s: could not get display DC\n", __FUNCTION__ ); - return -1; - } - xdpi = GetDeviceCaps( displayDC, LOGPIXELSX ); - ydpi = GetDeviceCaps( displayDC, LOGPIXELSY ); - - /* sanity checks */ - if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) { - D( "%s: bad resolution: xpi=%d ydpi=%d", __FUNCTION__, - xdpi, ydpi ); - return -1; - } - - *px_dpi = xdpi; - *py_dpi = ydpi; - return 0; -} - -int -get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) -{ - SDL_SysWMinfo info; - HMONITOR monitor; - MONITORINFO monitorInfo; - - SDL_VERSION(&info.version); - - if ( !SDL_GetWMInfo(&info) ) { - D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError()); - return -1; - } - - monitor = MonitorFromWindow( info.window, MONITOR_DEFAULTTONEAREST ); - monitorInfo.cbSize = sizeof(monitorInfo); - GetMonitorInfo( monitor, &monitorInfo ); - - *x = monitorInfo.rcMonitor.left; - *y = monitorInfo.rcMonitor.top; - *width = monitorInfo.rcMonitor.right - *x; - *height = monitorInfo.rcMonitor.bottom - *y; - - D("%s: found (x,y,w,h)=(%d,%d,%d,%d)", __FUNCTION__, - *x, *y, *width, *height); - - return 0; -} - - -#elif defined __APPLE__ - -/* the real implementation is in display-quartz.m, but - * unfortunately, the Android build system doesn't know - * how to build Objective-C sources, so provide stubs - * here instead. - * - * CONFIG_NO_COCOA is set by Makefile.android - */ - -#ifdef CONFIG_NO_COCOA -int -get_monitor_resolution( int *px_dpi, int *py_dpi ) -{ - return -1; -} - -int -get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) -{ - return -1; -} -#endif /* CONFIG_NO_COCOA */ - -#else /* Linux and others */ -#include <SDL.h> -#include <SDL_syswm.h> -#include <dlfcn.h> -#include <X11/Xlib.h> -#define MM_PER_INCH 25.4 - -#define DYNLINK_FUNCTIONS \ - DYNLINK_FUNC(int,XDefaultScreen,(Display*)) \ - DYNLINK_FUNC(int,XDisplayWidth,(Display*,int)) \ - DYNLINK_FUNC(int,XDisplayWidthMM,(Display*,int)) \ - DYNLINK_FUNC(int,XDisplayHeight,(Display*,int)) \ - DYNLINK_FUNC(int,XDisplayHeightMM,(Display*,int)) \ - -#define DYNLINK_FUNCTIONS_INIT \ - x11_dynlink_init - -#include "dynlink.h" - -static int x11_lib_inited; -static void* x11_lib; - -int -x11_lib_init( void ) -{ - if (!x11_lib_inited) { - x11_lib_inited = 1; - - x11_lib = dlopen( "libX11.so", RTLD_NOW ); - - if (x11_lib == NULL) { - x11_lib = dlopen( "libX11.so.6", RTLD_NOW ); - } - if (x11_lib == NULL) { - D("%s: Could not find libX11.so on this machine", - __FUNCTION__); - return -1; - } - - if (x11_dynlink_init(x11_lib) < 0) { - D("%s: didn't find necessary symbols in libX11.so", - __FUNCTION__); - dlclose(x11_lib); - x11_lib = NULL; - } - } - return x11_lib ? 0 : -1; -} - - -int -get_monitor_resolution( int *px_dpi, int *py_dpi ) -{ - SDL_SysWMinfo info; - Display* display; - int screen; - int width, width_mm, height, height_mm, xdpi, ydpi; - - SDL_VERSION(&info.version); - - if ( !SDL_GetWMInfo(&info) ) { - D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError()); - return -1; - } - - if (x11_lib_init() < 0) - return -1; - - display = info.info.x11.display; - screen = FF(XDefaultScreen)(display); - - width = FF(XDisplayWidth)(display, screen); - width_mm = FF(XDisplayWidthMM)(display, screen); - height = FF(XDisplayHeight)(display, screen); - height_mm = FF(XDisplayHeightMM)(display, screen); - - if (width_mm <= 0 || height_mm <= 0) { - D( "%s: bad screen dimensions: width_mm = %d, height_mm = %d", - __FUNCTION__, width_mm, height_mm); - return -1; - } - - D( "%s: found screen width=%d height=%d width_mm=%d height_mm=%d", - __FUNCTION__, width, height, width_mm, height_mm ); - - xdpi = width * MM_PER_INCH / width_mm; - ydpi = height * MM_PER_INCH / height_mm; - - if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) { - D( "%s: bad resolution: xpi=%d ydpi=%d", __FUNCTION__, - xdpi, ydpi ); - return -1; - } - - *px_dpi = xdpi; - *py_dpi = ydpi; - - return 0; -} - -int -get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) -{ - SDL_SysWMinfo info; - Display* display; - int screen; - - SDL_VERSION(&info.version); - - if ( !SDL_GetWMInfo(&info) ) { - D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError()); - return -1; - } - - if (x11_lib_init() < 0) - return -1; - - display = info.info.x11.display; - screen = FF(XDefaultScreen)(display); - - *x = 0; - *y = 0; - *width = FF(XDisplayWidth)(display, screen); - *height = FF(XDisplayHeight)(display, screen); - - D("%s: found (x,y,w,h)=(%d,%d,%d,%d)", __FUNCTION__, - *x, *y, *width, *height); - - return 0; -} - -#endif diff --git a/android/utils/display.h b/android/utils/display.h deleted file mode 100644 index 7254aca..0000000 --- a/android/utils/display.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ - -#ifndef _ANDROID_UTILS_DISPLAY_H -#define _ANDROID_UTILS_DISPLAY_H - -/** HOST RESOLUTION SETTINGS - ** - ** return the main monitor's DPI resolution according to the host device - ** beware: this is not always reliable or even obtainable. - ** - ** returns 0 on success, or -1 in case of error (e.g. the system returns funky values) - **/ -extern int get_monitor_resolution( int *px_dpi, int *py_dpi ); - -/** return the size in pixels of the nearest monitor for the current window. - ** this is used to implement full-screen presentation mode. - **/ - -extern int get_nearest_monitor_rect( int *x, int *y, int *width, int *height ); - -#endif /* _ANDROID_UTILS_DISPLAY_H */ |