зеркало из https://github.com/mozilla/pjs.git
Merge m-c to s-c.
This commit is contained in:
Коммит
c45bb3ed0f
|
@ -1,4 +1,5 @@
|
|||
#GONK_TOOLCHAIN_VERSION=0
|
||||
#TOOLCHAIN_HOST=linux-x86
|
||||
#export GONK_PRODUCT=generic
|
||||
#gonk="/home/cjones/mozilla/gonk-toolchain-$GONK_TOOLCHAIN_VERSION"
|
||||
|
||||
|
@ -10,6 +11,7 @@ ac_add_options --enable-application=b2g
|
|||
|
||||
ac_add_options --target=arm-android-eabi
|
||||
ac_add_options --with-gonk="$gonk"
|
||||
ac_add_options --with-gonk-toolchain-prefix="$gonk/prebuilt/$TOOLCHAIN_HOST/toolchain/arm-eabi-4.4.3/bin/arm-eabi-"
|
||||
ac_add_options --with-endian=little
|
||||
ac_add_options --disable-elf-hack
|
||||
ac_add_options --enable-debug-symbols
|
||||
|
|
|
@ -124,7 +124,7 @@ let libnetutils = (function () {
|
|||
|
||||
let makeRequestWrapper = function (c_fn) {
|
||||
return function (ifname) {
|
||||
let ret = c_fn(data.ifname,
|
||||
let ret = c_fn(ifname,
|
||||
ints.addressOfElement(0),
|
||||
ints.addressOfElement(1),
|
||||
ints.addressOfElement(2),
|
||||
|
|
|
@ -76,41 +76,35 @@
|
|||
var testsleftinround = 0;
|
||||
var currentround = "";
|
||||
|
||||
var _PBSvc = null;
|
||||
var _PrefSvc = null;
|
||||
var gPBSvc = null;
|
||||
var gPrefSvc = null;
|
||||
|
||||
function _getPBService() {
|
||||
if (_PBSvc)
|
||||
return _PBSvc;
|
||||
function _getServices() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
// not all apps will have the private browsing service.
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
_PBSvc = Components.classes["@mozilla.org/privatebrowsing;1"]
|
||||
.getService(Components.interfaces.nsIPrivateBrowsingService);
|
||||
return _PBSvc;
|
||||
} catch (e) {}
|
||||
return null;
|
||||
}
|
||||
function _getPrefService() {
|
||||
if (_PrefSvc)
|
||||
return _PrefSvc;
|
||||
gPBSvc = Components.classes["@mozilla.org/privatebrowsing;1"]
|
||||
.getService(Components.interfaces.nsIPrivateBrowsingService);
|
||||
} catch (ex) {
|
||||
SimpleTest.todo(false, "PB service is not available, will skip dependent tests");
|
||||
}
|
||||
|
||||
// not all apps will have the private browsing service.
|
||||
// Not all apps will have the preference service.
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
_PrefSvc = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService)
|
||||
.QueryInterface(Components.interfaces.nsIPrefBranch);
|
||||
return _PrefSvc;
|
||||
} catch (e) {}
|
||||
return null;
|
||||
gPrefSvc = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService)
|
||||
.QueryInterface(Components.interfaces.nsIPrefBranch);
|
||||
} catch (ex) {
|
||||
SimpleTest.todo(false, "Pref service is not available, won't be able to manage preferences");
|
||||
}
|
||||
}
|
||||
_getServices();
|
||||
|
||||
function startRound(round) {
|
||||
currentround = round;
|
||||
testsleftinround = NUM_TEST_FRAMES;
|
||||
dump("TESTS LEFT IN ROUND: " + testsleftinround + "\n");
|
||||
SimpleTest.info("TESTS LEFT IN ROUND " + currentround + ": " + testsleftinround);
|
||||
var frame = document.createElement("iframe");
|
||||
frame.setAttribute('id', 'ifr_bootstrap');
|
||||
frame.setAttribute('src', "https://example.com" + STSPATH +
|
||||
|
@ -149,9 +143,6 @@
|
|||
// check if the result (SECURE/INSECURE) is expected for this round/test
|
||||
// combo
|
||||
dump_STSState();
|
||||
dump( "*** in ROUND " + currentround +
|
||||
", test " + result[1] +
|
||||
" is " + result[0] + "\n");
|
||||
SimpleTest.is(result[0], testframes[result[1]].expected[currentround],
|
||||
"in ROUND " + currentround +
|
||||
", test " + result[1]);
|
||||
|
@ -159,7 +150,7 @@
|
|||
|
||||
// if this round is complete...
|
||||
if (testsleftinround < 1) {
|
||||
dump("DONE WITH ROUND " + currentround + "\n");
|
||||
SimpleTest.info("DONE WITH ROUND " + currentround);
|
||||
// remove all the iframes in the document
|
||||
document.body.removeChild(document.getElementById('ifr_bootstrap'));
|
||||
for (var test in testframes)
|
||||
|
@ -174,36 +165,37 @@
|
|||
|
||||
function test_sts_before_private_mode() {
|
||||
dump_STSState();
|
||||
dump("*** not in private browsing mode\n");
|
||||
SimpleTest.info("Not in private browsing mode");
|
||||
startRound('plain');
|
||||
}
|
||||
|
||||
function test_sts_in_private_mode() {
|
||||
dump_STSState();
|
||||
dump("*** Entering private browsing mode\n");
|
||||
SimpleTest.info("Entering private browsing mode ...");
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
_getPrefService().setBoolPref("browser.privatebrowsing.keep_current_session",
|
||||
true);
|
||||
_getPBService().privateBrowsingEnabled = true;
|
||||
dump("*** ... done\n");
|
||||
if (gPrefSvc)
|
||||
gPrefSvc.setBoolPref("browser.privatebrowsing.keep_current_session", true);
|
||||
gPBSvc.privateBrowsingEnabled = true;
|
||||
SimpleTest.info("... done");
|
||||
dump_STSState();
|
||||
startRound('subdom');
|
||||
}
|
||||
|
||||
function test_sts_after_exiting_private_mode() {
|
||||
dump_STSState();
|
||||
dump("*** Exiting private browsing mode\n");
|
||||
SimpleTest.info("Exiting private browsing mode ...");
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
_getPBService().privateBrowsingEnabled = false;
|
||||
_getPrefService().clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
dump("*** ... done\n");
|
||||
gPBSvc.privateBrowsingEnabled = false;
|
||||
if (gPrefSvc)
|
||||
gPrefSvc.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
SimpleTest.info("... done");
|
||||
dump_STSState();
|
||||
startRound('nosts');
|
||||
}
|
||||
|
||||
function clean_up_sts_state() {
|
||||
// erase all signs that this test ran.
|
||||
dump("*** Cleaning up STS data.\n");
|
||||
SimpleTest.info("Cleaning up STS data");
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
@ -221,43 +213,39 @@ function dump_STSState() {
|
|||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var stss = Components.classes["@mozilla.org/stsservice;1"]
|
||||
.getService(Components.interfaces.nsIStrictTransportSecurityService);
|
||||
dump("*** State of example.com: " + stss.isStsHost("example.com") + "\n");
|
||||
SimpleTest.info("State of example.com: " + stss.isStsHost("example.com"));
|
||||
}
|
||||
|
||||
// these are executed in the order presented.
|
||||
// 0. test that STS works before entering private browsing mode.
|
||||
// (load sts-bootstrapped "plain" tests)
|
||||
// ... clear any STS data ...
|
||||
var tests = [
|
||||
test_sts_before_private_mode,
|
||||
clean_up_sts_state
|
||||
];
|
||||
// 1. test that STS works in private browsing mode
|
||||
// (load sts-bootstrapped "subdomain" tests)
|
||||
// 2. test that after exiting private browsing, STS data is forgotten
|
||||
// (verified with non-sts-bootstrapped pages)
|
||||
var tests = [];
|
||||
{ // skip these tests if there's no private mode support
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
if ("@mozilla.org/privatebrowsing;1" in Components.classes) {
|
||||
tests = [
|
||||
test_sts_before_private_mode,
|
||||
clean_up_sts_state,
|
||||
test_sts_in_private_mode,
|
||||
test_sts_after_exiting_private_mode,
|
||||
clean_up_sts_state,
|
||||
];
|
||||
}
|
||||
// ... clear any STS data ...
|
||||
// Skip these tests if there is no private mode support.
|
||||
if (gPBSvc) {
|
||||
tests.concat([
|
||||
test_sts_in_private_mode,
|
||||
test_sts_after_exiting_private_mode,
|
||||
clean_up_sts_state
|
||||
]);
|
||||
}
|
||||
|
||||
function nextTest() {
|
||||
if (tests.length)
|
||||
SimpleTest.executeSoon(tests.shift());
|
||||
else
|
||||
SimpleTest.executeSoon(SimpleTest.finish);
|
||||
SimpleTest.executeSoon(tests.length ? tests.shift() : SimpleTest.finish);
|
||||
}
|
||||
|
||||
// listen for calls back from the sts-setting iframe and then
|
||||
// the verification frames.
|
||||
window.addEventListener("message", onMessageReceived, false);
|
||||
window.addEventListener('load', nextTest, false);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ CPPSRCS = \
|
|||
nsLookAndFeel.cpp \
|
||||
nsIdleServiceGonk.cpp \
|
||||
EventHub.cpp \
|
||||
Input.cpp \
|
||||
InputApplication.cpp \
|
||||
InputDispatcher.cpp \
|
||||
InputListener.cpp \
|
||||
|
@ -73,6 +74,12 @@ CPPSRCS = \
|
|||
KeyLayoutMap.cpp \
|
||||
PixelFormat.cpp \
|
||||
VirtualKeyMap.cpp \
|
||||
PropertyMap.cpp \
|
||||
Unicode.cpp \
|
||||
Timers.cpp \
|
||||
Tokenizer.cpp \
|
||||
String8.cpp \
|
||||
Static.cpp \
|
||||
$(NULL)
|
||||
|
||||
SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_BITSET_H
|
||||
#define UTILS_BITSET_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Contains some bit manipulation helpers.
|
||||
*/
|
||||
|
||||
namespace android {
|
||||
|
||||
// A simple set of 32 bits that can be individually marked or cleared.
|
||||
struct BitSet32 {
|
||||
uint32_t value;
|
||||
|
||||
inline BitSet32() : value(0) { }
|
||||
explicit inline BitSet32(uint32_t value) : value(value) { }
|
||||
|
||||
// Gets the value associated with a particular bit index.
|
||||
static inline uint32_t valueForBit(uint32_t n) { return 0x80000000 >> n; }
|
||||
|
||||
// Clears the bit set.
|
||||
inline void clear() { value = 0; }
|
||||
|
||||
// Returns the number of marked bits in the set.
|
||||
inline uint32_t count() const { return __builtin_popcount(value); }
|
||||
|
||||
// Returns true if the bit set does not contain any marked bits.
|
||||
inline bool isEmpty() const { return ! value; }
|
||||
|
||||
// Returns true if the bit set does not contain any unmarked bits.
|
||||
inline bool isFull() const { return value == 0xffffffff; }
|
||||
|
||||
// Returns true if the specified bit is marked.
|
||||
inline bool hasBit(uint32_t n) const { return value & valueForBit(n); }
|
||||
|
||||
// Marks the specified bit.
|
||||
inline void markBit(uint32_t n) { value |= valueForBit(n); }
|
||||
|
||||
// Clears the specified bit.
|
||||
inline void clearBit(uint32_t n) { value &= ~ valueForBit(n); }
|
||||
|
||||
// Finds the first marked bit in the set.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t firstMarkedBit() const { return __builtin_clz(value); }
|
||||
|
||||
// Finds the first unmarked bit in the set.
|
||||
// Result is undefined if all bits are marked.
|
||||
inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); }
|
||||
|
||||
// Finds the last marked bit in the set.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t lastMarkedBit() const { return 31 - __builtin_ctz(value); }
|
||||
|
||||
// Finds the first marked bit in the set and clears it. Returns the bit index.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t clearFirstMarkedBit() {
|
||||
uint32_t n = firstMarkedBit();
|
||||
clearBit(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Finds the first unmarked bit in the set and marks it. Returns the bit index.
|
||||
// Result is undefined if all bits are marked.
|
||||
inline uint32_t markFirstUnmarkedBit() {
|
||||
uint32_t n = firstUnmarkedBit();
|
||||
markBit(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Finds the last marked bit in the set and clears it. Returns the bit index.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t clearLastMarkedBit() {
|
||||
uint32_t n = lastMarkedBit();
|
||||
clearBit(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Gets the index of the specified bit in the set, which is the number of
|
||||
// marked bits that appear before the specified bit.
|
||||
inline uint32_t getIndexOfBit(uint32_t n) const {
|
||||
return __builtin_popcount(value & ~(0xffffffffUL >> n));
|
||||
}
|
||||
|
||||
inline bool operator== (const BitSet32& other) const { return value == other.value; }
|
||||
inline bool operator!= (const BitSet32& other) const { return value != other.value; }
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // UTILS_BITSET_H
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
// #define LOG_NDEBUG 0
|
||||
|
||||
#include "utils_Log.h"
|
||||
#include "EventHub.h"
|
||||
|
||||
#include <hardware_legacy/power.h>
|
||||
|
||||
#include <cutils/properties.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Timers.h"
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
|
|
|
@ -18,22 +18,22 @@
|
|||
#ifndef _RUNTIME_EVENT_HUB_H
|
||||
#define _RUNTIME_EVENT_HUB_H
|
||||
|
||||
#include "utils_Log.h"
|
||||
#include "Input.h"
|
||||
#include "Keyboard.h"
|
||||
#include "KeyLayoutMap.h"
|
||||
#include "KeyCharacterMap.h"
|
||||
#include "VirtualKeyMap.h"
|
||||
#include <utils/String8.h>
|
||||
#include "String8.h"
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/threads.h>
|
||||
#include <utils/List.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/PropertyMap.h>
|
||||
#include "PropertyMap.h"
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
|
||||
#include <linux/input.h>
|
||||
#include "linux_input.h"
|
||||
#include <sys/epoll.h>
|
||||
|
||||
/* Convenience constants. */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -21,13 +21,13 @@
|
|||
* Native input event structures.
|
||||
*/
|
||||
|
||||
#include <android/input.h>
|
||||
#include "android_input.h"
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Timers.h"
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/BitSet.h>
|
||||
#include "String8.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
class SkMatrix;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "InputApplication.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include "cutils_log.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "Input.h"
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/String8.h>
|
||||
#include "Timers.h"
|
||||
#include "String8.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
|
||||
#include "InputDispatcher.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <ui/PowerManager.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
|
|
@ -17,16 +17,17 @@
|
|||
#ifndef _UI_INPUT_DISPATCHER_H
|
||||
#define _UI_INPUT_DISPATCHER_H
|
||||
|
||||
#include "cutils_log.h"
|
||||
#include "Input.h"
|
||||
#include "InputTransport.h"
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Timers.h"
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
#include "String8.h"
|
||||
#include <utils/Looper.h>
|
||||
#include <utils/BitSet.h>
|
||||
#include "BitSet.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "InputListener.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include "cutils_log.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "InputReader.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include "cutils_log.h"
|
||||
#include "Keyboard.h"
|
||||
#include "VirtualKeyMap.h"
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
#include "DisplayInfo.h"
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Timers.h"
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/BitSet.h>
|
||||
#include "String8.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
|
||||
#include <cutils/ashmem.h>
|
||||
#include <cutils/log.h>
|
||||
#include "cutils_log.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
|
|
@ -33,9 +33,9 @@
|
|||
#include <semaphore.h>
|
||||
#include "Input.h"
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Timers.h"
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
#include "String8.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "InputWindow.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include "cutils_log.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "Input.h"
|
||||
#include "InputTransport.h"
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/String8.h>
|
||||
#include "Timers.h"
|
||||
#include "String8.h"
|
||||
|
||||
#include "SkRegion.h"
|
||||
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <android/keycodes.h>
|
||||
#include "utils_Log.h"
|
||||
#include "android_keycodes.h"
|
||||
#include "Keyboard.h"
|
||||
#include "KeyCharacterMap.h"
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Tokenizer.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Tokenizer.h"
|
||||
#include "Timers.h"
|
||||
|
||||
// Enables debug output for the parser.
|
||||
#define DEBUG_PARSER 0
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
#include "Input.h"
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Tokenizer.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Unicode.h>
|
||||
#include "Tokenizer.h"
|
||||
#include "String8.h"
|
||||
#include "Unicode.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
#define LOG_TAG "KeyLayoutMap"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <android/keycodes.h>
|
||||
#include "utils_Log.h"
|
||||
#include "android_keycodes.h"
|
||||
#include "Keyboard.h"
|
||||
#include "KeyLayoutMap.h"
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Tokenizer.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Tokenizer.h"
|
||||
#include "Timers.h"
|
||||
|
||||
// Enables debug output for the parser.
|
||||
#define DEBUG_PARSER 0
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <stdint.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Tokenizer.h>
|
||||
#include "Tokenizer.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "utils_Log.h"
|
||||
#include "Keyboard.h"
|
||||
#include "KeycodeLabels.h"
|
||||
#include "KeyLayoutMap.h"
|
||||
#include "KeyCharacterMap.h"
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Log.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
namespace android {
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include "Input.h"
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/PropertyMap.h>
|
||||
#include "String8.h"
|
||||
#include "PropertyMap.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#ifndef _UI_KEYCODE_LABELS_H
|
||||
#define _UI_KEYCODE_LABELS_H
|
||||
|
||||
#include <android/keycodes.h>
|
||||
#include "android_keycodes.h"
|
||||
|
||||
struct KeycodeLabel {
|
||||
const char *literal;
|
||||
|
|
|
@ -1,601 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "PointerController"
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
// Log debug messages about pointer updates
|
||||
#define DEBUG_POINTER_UPDATES 0
|
||||
|
||||
#include "PointerController.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <SkBitmap.h>
|
||||
#include <SkCanvas.h>
|
||||
#include <SkColor.h>
|
||||
#include <SkPaint.h>
|
||||
#include <SkXfermode.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// --- PointerController ---
|
||||
|
||||
// Time to wait before starting the fade when the pointer is inactive.
|
||||
static const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL = 15 * 1000 * 1000000LL; // 15 seconds
|
||||
static const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_SHORT = 3 * 1000 * 1000000LL; // 3 seconds
|
||||
|
||||
// Time to wait between animation frames.
|
||||
static const nsecs_t ANIMATION_FRAME_INTERVAL = 1000000000LL / 60;
|
||||
|
||||
// Time to spend fading out the spot completely.
|
||||
static const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms
|
||||
|
||||
// Time to spend fading out the pointer completely.
|
||||
static const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms
|
||||
|
||||
|
||||
// --- PointerController ---
|
||||
|
||||
PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
|
||||
const sp<Looper>& looper, const sp<SpriteController>& spriteController) :
|
||||
mPolicy(policy), mLooper(looper), mSpriteController(spriteController) {
|
||||
mHandler = new WeakMessageHandler(this);
|
||||
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
mLocked.animationPending = false;
|
||||
|
||||
mLocked.displayWidth = -1;
|
||||
mLocked.displayHeight = -1;
|
||||
mLocked.displayOrientation = DISPLAY_ORIENTATION_0;
|
||||
|
||||
mLocked.presentation = PRESENTATION_POINTER;
|
||||
mLocked.presentationChanged = false;
|
||||
|
||||
mLocked.inactivityTimeout = INACTIVITY_TIMEOUT_NORMAL;
|
||||
|
||||
mLocked.pointerFadeDirection = 0;
|
||||
mLocked.pointerX = 0;
|
||||
mLocked.pointerY = 0;
|
||||
mLocked.pointerAlpha = 0.0f; // pointer is initially faded
|
||||
mLocked.pointerSprite = mSpriteController->createSprite();
|
||||
mLocked.pointerIconChanged = false;
|
||||
|
||||
mLocked.buttonState = 0;
|
||||
|
||||
loadResources();
|
||||
}
|
||||
|
||||
PointerController::~PointerController() {
|
||||
mLooper->removeMessages(mHandler);
|
||||
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
mLocked.pointerSprite.clear();
|
||||
|
||||
for (size_t i = 0; i < mLocked.spots.size(); i++) {
|
||||
delete mLocked.spots.itemAt(i);
|
||||
}
|
||||
mLocked.spots.clear();
|
||||
mLocked.recycledSprites.clear();
|
||||
}
|
||||
|
||||
bool PointerController::getBounds(float* outMinX, float* outMinY,
|
||||
float* outMaxX, float* outMaxY) const {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
return getBoundsLocked(outMinX, outMinY, outMaxX, outMaxY);
|
||||
}
|
||||
|
||||
bool PointerController::getBoundsLocked(float* outMinX, float* outMinY,
|
||||
float* outMaxX, float* outMaxY) const {
|
||||
if (mLocked.displayWidth <= 0 || mLocked.displayHeight <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outMinX = 0;
|
||||
*outMinY = 0;
|
||||
switch (mLocked.displayOrientation) {
|
||||
case DISPLAY_ORIENTATION_90:
|
||||
case DISPLAY_ORIENTATION_270:
|
||||
*outMaxX = mLocked.displayHeight - 1;
|
||||
*outMaxY = mLocked.displayWidth - 1;
|
||||
break;
|
||||
default:
|
||||
*outMaxX = mLocked.displayWidth - 1;
|
||||
*outMaxY = mLocked.displayHeight - 1;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PointerController::move(float deltaX, float deltaY) {
|
||||
#if DEBUG_POINTER_UPDATES
|
||||
ALOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
|
||||
#endif
|
||||
if (deltaX == 0.0f && deltaY == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
|
||||
}
|
||||
|
||||
void PointerController::setButtonState(int32_t buttonState) {
|
||||
#if DEBUG_POINTER_UPDATES
|
||||
ALOGD("Set button state 0x%08x", buttonState);
|
||||
#endif
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
if (mLocked.buttonState != buttonState) {
|
||||
mLocked.buttonState = buttonState;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t PointerController::getButtonState() const {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
return mLocked.buttonState;
|
||||
}
|
||||
|
||||
void PointerController::setPosition(float x, float y) {
|
||||
#if DEBUG_POINTER_UPDATES
|
||||
ALOGD("Set pointer position to x=%0.3f, y=%0.3f", x, y);
|
||||
#endif
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
setPositionLocked(x, y);
|
||||
}
|
||||
|
||||
void PointerController::setPositionLocked(float x, float y) {
|
||||
float minX, minY, maxX, maxY;
|
||||
if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
|
||||
if (x <= minX) {
|
||||
mLocked.pointerX = minX;
|
||||
} else if (x >= maxX) {
|
||||
mLocked.pointerX = maxX;
|
||||
} else {
|
||||
mLocked.pointerX = x;
|
||||
}
|
||||
if (y <= minY) {
|
||||
mLocked.pointerY = minY;
|
||||
} else if (y >= maxY) {
|
||||
mLocked.pointerY = maxY;
|
||||
} else {
|
||||
mLocked.pointerY = y;
|
||||
}
|
||||
updatePointerLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::getPosition(float* outX, float* outY) const {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
*outX = mLocked.pointerX;
|
||||
*outY = mLocked.pointerY;
|
||||
}
|
||||
|
||||
void PointerController::fade(Transition transition) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
// Remove the inactivity timeout, since we are fading now.
|
||||
removeInactivityTimeoutLocked();
|
||||
|
||||
// Start fading.
|
||||
if (transition == TRANSITION_IMMEDIATE) {
|
||||
mLocked.pointerFadeDirection = 0;
|
||||
mLocked.pointerAlpha = 0.0f;
|
||||
updatePointerLocked();
|
||||
} else {
|
||||
mLocked.pointerFadeDirection = -1;
|
||||
startAnimationLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::unfade(Transition transition) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
// Always reset the inactivity timer.
|
||||
resetInactivityTimeoutLocked();
|
||||
|
||||
// Start unfading.
|
||||
if (transition == TRANSITION_IMMEDIATE) {
|
||||
mLocked.pointerFadeDirection = 0;
|
||||
mLocked.pointerAlpha = 1.0f;
|
||||
updatePointerLocked();
|
||||
} else {
|
||||
mLocked.pointerFadeDirection = 1;
|
||||
startAnimationLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::setPresentation(Presentation presentation) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
if (mLocked.presentation != presentation) {
|
||||
mLocked.presentation = presentation;
|
||||
mLocked.presentationChanged = true;
|
||||
|
||||
if (presentation != PRESENTATION_SPOT) {
|
||||
fadeOutAndReleaseAllSpotsLocked();
|
||||
}
|
||||
|
||||
updatePointerLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::setSpots(const PointerCoords* spotCoords,
|
||||
const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
|
||||
#if DEBUG_POINTER_UPDATES
|
||||
ALOGD("setSpots: idBits=%08x", spotIdBits.value);
|
||||
for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
|
||||
uint32_t id = idBits.firstMarkedBit();
|
||||
idBits.clearBit(id);
|
||||
const PointerCoords& c = spotCoords[spotIdToIndex[id]];
|
||||
ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", id,
|
||||
c.getAxisValue(AMOTION_EVENT_AXIS_X),
|
||||
c.getAxisValue(AMOTION_EVENT_AXIS_Y),
|
||||
c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
|
||||
}
|
||||
#endif
|
||||
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
mSpriteController->openTransaction();
|
||||
|
||||
// Add or move spots for fingers that are down.
|
||||
for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
|
||||
uint32_t id = idBits.clearFirstMarkedBit();
|
||||
const PointerCoords& c = spotCoords[spotIdToIndex[id]];
|
||||
const SpriteIcon& icon = c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) > 0
|
||||
? mResources.spotTouch : mResources.spotHover;
|
||||
float x = c.getAxisValue(AMOTION_EVENT_AXIS_X);
|
||||
float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y);
|
||||
|
||||
Spot* spot = getSpotLocked(id);
|
||||
if (!spot) {
|
||||
spot = createAndAddSpotLocked(id);
|
||||
}
|
||||
|
||||
spot->updateSprite(&icon, x, y);
|
||||
}
|
||||
|
||||
// Remove spots for fingers that went up.
|
||||
for (size_t i = 0; i < mLocked.spots.size(); i++) {
|
||||
Spot* spot = mLocked.spots.itemAt(i);
|
||||
if (spot->id != Spot::INVALID_ID
|
||||
&& !spotIdBits.hasBit(spot->id)) {
|
||||
fadeOutAndReleaseSpotLocked(spot);
|
||||
}
|
||||
}
|
||||
|
||||
mSpriteController->closeTransaction();
|
||||
}
|
||||
|
||||
void PointerController::clearSpots() {
|
||||
#if DEBUG_POINTER_UPDATES
|
||||
ALOGD("clearSpots");
|
||||
#endif
|
||||
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
fadeOutAndReleaseAllSpotsLocked();
|
||||
}
|
||||
|
||||
void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
if (mLocked.inactivityTimeout != inactivityTimeout) {
|
||||
mLocked.inactivityTimeout = inactivityTimeout;
|
||||
resetInactivityTimeoutLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::setDisplaySize(int32_t width, int32_t height) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
|
||||
mLocked.displayWidth = width;
|
||||
mLocked.displayHeight = height;
|
||||
|
||||
float minX, minY, maxX, maxY;
|
||||
if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
|
||||
mLocked.pointerX = (minX + maxX) * 0.5f;
|
||||
mLocked.pointerY = (minY + maxY) * 0.5f;
|
||||
} else {
|
||||
mLocked.pointerX = 0;
|
||||
mLocked.pointerY = 0;
|
||||
}
|
||||
|
||||
fadeOutAndReleaseAllSpotsLocked();
|
||||
updatePointerLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::setDisplayOrientation(int32_t orientation) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
if (mLocked.displayOrientation != orientation) {
|
||||
// Apply offsets to convert from the pixel top-left corner position to the pixel center.
|
||||
// This creates an invariant frame of reference that we can easily rotate when
|
||||
// taking into account that the pointer may be located at fractional pixel offsets.
|
||||
float x = mLocked.pointerX + 0.5f;
|
||||
float y = mLocked.pointerY + 0.5f;
|
||||
float temp;
|
||||
|
||||
// Undo the previous rotation.
|
||||
switch (mLocked.displayOrientation) {
|
||||
case DISPLAY_ORIENTATION_90:
|
||||
temp = x;
|
||||
x = mLocked.displayWidth - y;
|
||||
y = temp;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_180:
|
||||
x = mLocked.displayWidth - x;
|
||||
y = mLocked.displayHeight - y;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_270:
|
||||
temp = x;
|
||||
x = y;
|
||||
y = mLocked.displayHeight - temp;
|
||||
break;
|
||||
}
|
||||
|
||||
// Perform the new rotation.
|
||||
switch (orientation) {
|
||||
case DISPLAY_ORIENTATION_90:
|
||||
temp = x;
|
||||
x = y;
|
||||
y = mLocked.displayWidth - temp;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_180:
|
||||
x = mLocked.displayWidth - x;
|
||||
y = mLocked.displayHeight - y;
|
||||
break;
|
||||
case DISPLAY_ORIENTATION_270:
|
||||
temp = x;
|
||||
x = mLocked.displayHeight - y;
|
||||
y = temp;
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply offsets to convert from the pixel center to the pixel top-left corner position
|
||||
// and save the results.
|
||||
mLocked.pointerX = x - 0.5f;
|
||||
mLocked.pointerY = y - 0.5f;
|
||||
mLocked.displayOrientation = orientation;
|
||||
|
||||
updatePointerLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::setPointerIcon(const SpriteIcon& icon) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
mLocked.pointerIcon = icon.copy();
|
||||
mLocked.pointerIconChanged = true;
|
||||
|
||||
updatePointerLocked();
|
||||
}
|
||||
|
||||
void PointerController::handleMessage(const Message& message) {
|
||||
switch (message.what) {
|
||||
case MSG_ANIMATE:
|
||||
doAnimate();
|
||||
break;
|
||||
case MSG_INACTIVITY_TIMEOUT:
|
||||
doInactivityTimeout();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::doAnimate() {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
bool keepAnimating = false;
|
||||
mLocked.animationPending = false;
|
||||
nsecs_t frameDelay = systemTime(SYSTEM_TIME_MONOTONIC) - mLocked.animationTime;
|
||||
|
||||
// Animate pointer fade.
|
||||
if (mLocked.pointerFadeDirection < 0) {
|
||||
mLocked.pointerAlpha -= float(frameDelay) / POINTER_FADE_DURATION;
|
||||
if (mLocked.pointerAlpha <= 0.0f) {
|
||||
mLocked.pointerAlpha = 0.0f;
|
||||
mLocked.pointerFadeDirection = 0;
|
||||
} else {
|
||||
keepAnimating = true;
|
||||
}
|
||||
updatePointerLocked();
|
||||
} else if (mLocked.pointerFadeDirection > 0) {
|
||||
mLocked.pointerAlpha += float(frameDelay) / POINTER_FADE_DURATION;
|
||||
if (mLocked.pointerAlpha >= 1.0f) {
|
||||
mLocked.pointerAlpha = 1.0f;
|
||||
mLocked.pointerFadeDirection = 0;
|
||||
} else {
|
||||
keepAnimating = true;
|
||||
}
|
||||
updatePointerLocked();
|
||||
}
|
||||
|
||||
// Animate spots that are fading out and being removed.
|
||||
for (size_t i = 0; i < mLocked.spots.size(); i++) {
|
||||
Spot* spot = mLocked.spots.itemAt(i);
|
||||
if (spot->id == Spot::INVALID_ID) {
|
||||
spot->alpha -= float(frameDelay) / SPOT_FADE_DURATION;
|
||||
if (spot->alpha <= 0) {
|
||||
mLocked.spots.removeAt(i--);
|
||||
releaseSpotLocked(spot);
|
||||
} else {
|
||||
spot->sprite->setAlpha(spot->alpha);
|
||||
keepAnimating = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keepAnimating) {
|
||||
startAnimationLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::doInactivityTimeout() {
|
||||
fade(TRANSITION_GRADUAL);
|
||||
}
|
||||
|
||||
void PointerController::startAnimationLocked() {
|
||||
if (!mLocked.animationPending) {
|
||||
mLocked.animationPending = true;
|
||||
mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
mLooper->sendMessageDelayed(ANIMATION_FRAME_INTERVAL, mHandler, Message(MSG_ANIMATE));
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::resetInactivityTimeoutLocked() {
|
||||
mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
|
||||
|
||||
nsecs_t timeout = mLocked.inactivityTimeout == INACTIVITY_TIMEOUT_SHORT
|
||||
? INACTIVITY_TIMEOUT_DELAY_TIME_SHORT : INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL;
|
||||
mLooper->sendMessageDelayed(timeout, mHandler, MSG_INACTIVITY_TIMEOUT);
|
||||
}
|
||||
|
||||
void PointerController::removeInactivityTimeoutLocked() {
|
||||
mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
|
||||
}
|
||||
|
||||
void PointerController::updatePointerLocked() {
|
||||
mSpriteController->openTransaction();
|
||||
|
||||
mLocked.pointerSprite->setLayer(Sprite::BASE_LAYER_POINTER);
|
||||
mLocked.pointerSprite->setPosition(mLocked.pointerX, mLocked.pointerY);
|
||||
|
||||
if (mLocked.pointerAlpha > 0) {
|
||||
mLocked.pointerSprite->setAlpha(mLocked.pointerAlpha);
|
||||
mLocked.pointerSprite->setVisible(true);
|
||||
} else {
|
||||
mLocked.pointerSprite->setVisible(false);
|
||||
}
|
||||
|
||||
if (mLocked.pointerIconChanged || mLocked.presentationChanged) {
|
||||
mLocked.pointerSprite->setIcon(mLocked.presentation == PRESENTATION_POINTER
|
||||
? mLocked.pointerIcon : mResources.spotAnchor);
|
||||
mLocked.pointerIconChanged = false;
|
||||
mLocked.presentationChanged = false;
|
||||
}
|
||||
|
||||
mSpriteController->closeTransaction();
|
||||
}
|
||||
|
||||
PointerController::Spot* PointerController::getSpotLocked(uint32_t id) {
|
||||
for (size_t i = 0; i < mLocked.spots.size(); i++) {
|
||||
Spot* spot = mLocked.spots.itemAt(i);
|
||||
if (spot->id == id) {
|
||||
return spot;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PointerController::Spot* PointerController::createAndAddSpotLocked(uint32_t id) {
|
||||
// Remove spots until we have fewer than MAX_SPOTS remaining.
|
||||
while (mLocked.spots.size() >= MAX_SPOTS) {
|
||||
Spot* spot = removeFirstFadingSpotLocked();
|
||||
if (!spot) {
|
||||
spot = mLocked.spots.itemAt(0);
|
||||
mLocked.spots.removeAt(0);
|
||||
}
|
||||
releaseSpotLocked(spot);
|
||||
}
|
||||
|
||||
// Obtain a sprite from the recycled pool.
|
||||
sp<Sprite> sprite;
|
||||
if (! mLocked.recycledSprites.isEmpty()) {
|
||||
sprite = mLocked.recycledSprites.top();
|
||||
mLocked.recycledSprites.pop();
|
||||
} else {
|
||||
sprite = mSpriteController->createSprite();
|
||||
}
|
||||
|
||||
// Return the new spot.
|
||||
Spot* spot = new Spot(id, sprite);
|
||||
mLocked.spots.push(spot);
|
||||
return spot;
|
||||
}
|
||||
|
||||
PointerController::Spot* PointerController::removeFirstFadingSpotLocked() {
|
||||
for (size_t i = 0; i < mLocked.spots.size(); i++) {
|
||||
Spot* spot = mLocked.spots.itemAt(i);
|
||||
if (spot->id == Spot::INVALID_ID) {
|
||||
mLocked.spots.removeAt(i);
|
||||
return spot;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PointerController::releaseSpotLocked(Spot* spot) {
|
||||
spot->sprite->clearIcon();
|
||||
|
||||
if (mLocked.recycledSprites.size() < MAX_RECYCLED_SPRITES) {
|
||||
mLocked.recycledSprites.push(spot->sprite);
|
||||
}
|
||||
|
||||
delete spot;
|
||||
}
|
||||
|
||||
void PointerController::fadeOutAndReleaseSpotLocked(Spot* spot) {
|
||||
if (spot->id != Spot::INVALID_ID) {
|
||||
spot->id = Spot::INVALID_ID;
|
||||
startAnimationLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::fadeOutAndReleaseAllSpotsLocked() {
|
||||
for (size_t i = 0; i < mLocked.spots.size(); i++) {
|
||||
Spot* spot = mLocked.spots.itemAt(i);
|
||||
fadeOutAndReleaseSpotLocked(spot);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerController::loadResources() {
|
||||
mPolicy->loadPointerResources(&mResources);
|
||||
}
|
||||
|
||||
|
||||
// --- PointerController::Spot ---
|
||||
|
||||
void PointerController::Spot::updateSprite(const SpriteIcon* icon, float x, float y) {
|
||||
sprite->setLayer(Sprite::BASE_LAYER_SPOT + id);
|
||||
sprite->setAlpha(alpha);
|
||||
sprite->setTransformationMatrix(SpriteTransformationMatrix(scale, 0.0f, 0.0f, scale));
|
||||
sprite->setPosition(x, y);
|
||||
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
|
||||
if (icon != lastIcon) {
|
||||
lastIcon = icon;
|
||||
if (icon) {
|
||||
sprite->setIcon(*icon);
|
||||
sprite->setVisible(true);
|
||||
} else {
|
||||
sprite->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef _UI_POINTER_CONTROLLER_H
|
||||
#define _UI_POINTER_CONTROLLER_H
|
||||
|
||||
#include "SpriteController.h"
|
||||
|
||||
#include "DisplayInfo.h"
|
||||
#include "Input.h"
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Looper.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include <SkBitmap.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/**
|
||||
* Interface for tracking a mouse / touch pad pointer and touch pad spots.
|
||||
*
|
||||
* The spots are sprites on screen that visually represent the positions of
|
||||
* fingers
|
||||
*
|
||||
* The pointer controller is responsible for providing synchronization and for tracking
|
||||
* display orientation changes if needed.
|
||||
*/
|
||||
class PointerControllerInterface : public virtual RefBase {
|
||||
protected:
|
||||
PointerControllerInterface() { }
|
||||
virtual ~PointerControllerInterface() { }
|
||||
|
||||
public:
|
||||
/* Gets the bounds of the region that the pointer can traverse.
|
||||
* Returns true if the bounds are available. */
|
||||
virtual bool getBounds(float* outMinX, float* outMinY,
|
||||
float* outMaxX, float* outMaxY) const = 0;
|
||||
|
||||
/* Move the pointer. */
|
||||
virtual void move(float deltaX, float deltaY) = 0;
|
||||
|
||||
/* Sets a mask that indicates which buttons are pressed. */
|
||||
virtual void setButtonState(int32_t buttonState) = 0;
|
||||
|
||||
/* Gets a mask that indicates which buttons are pressed. */
|
||||
virtual int32_t getButtonState() const = 0;
|
||||
|
||||
/* Sets the absolute location of the pointer. */
|
||||
virtual void setPosition(float x, float y) = 0;
|
||||
|
||||
/* Gets the absolute location of the pointer. */
|
||||
virtual void getPosition(float* outX, float* outY) const = 0;
|
||||
|
||||
enum Transition {
|
||||
// Fade/unfade immediately.
|
||||
TRANSITION_IMMEDIATE,
|
||||
// Fade/unfade gradually.
|
||||
TRANSITION_GRADUAL,
|
||||
};
|
||||
|
||||
/* Fades the pointer out now. */
|
||||
virtual void fade(Transition transition) = 0;
|
||||
|
||||
/* Makes the pointer visible if it has faded out.
|
||||
* The pointer never unfades itself automatically. This method must be called
|
||||
* by the client whenever the pointer is moved or a button is pressed and it
|
||||
* wants to ensure that the pointer becomes visible again. */
|
||||
virtual void unfade(Transition transition) = 0;
|
||||
|
||||
enum Presentation {
|
||||
// Show the mouse pointer.
|
||||
PRESENTATION_POINTER,
|
||||
// Show spots and a spot anchor in place of the mouse pointer.
|
||||
PRESENTATION_SPOT,
|
||||
};
|
||||
|
||||
/* Sets the mode of the pointer controller. */
|
||||
virtual void setPresentation(Presentation presentation) = 0;
|
||||
|
||||
/* Sets the spots for the current gesture.
|
||||
* The spots are not subject to the inactivity timeout like the pointer
|
||||
* itself it since they are expected to remain visible for so long as
|
||||
* the fingers are on the touch pad.
|
||||
*
|
||||
* The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant.
|
||||
* For spotCoords, pressure != 0 indicates that the spot's location is being
|
||||
* pressed (not hovering).
|
||||
*/
|
||||
virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
|
||||
BitSet32 spotIdBits) = 0;
|
||||
|
||||
/* Removes all spots. */
|
||||
virtual void clearSpots() = 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Pointer resources.
|
||||
*/
|
||||
struct PointerResources {
|
||||
SpriteIcon spotHover;
|
||||
SpriteIcon spotTouch;
|
||||
SpriteIcon spotAnchor;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Pointer controller policy interface.
|
||||
*
|
||||
* The pointer controller policy is used by the pointer controller to interact with
|
||||
* the Window Manager and other system components.
|
||||
*
|
||||
* The actual implementation is partially supported by callbacks into the DVM
|
||||
* via JNI. This interface is also mocked in the unit tests.
|
||||
*/
|
||||
class PointerControllerPolicyInterface : public virtual RefBase {
|
||||
protected:
|
||||
PointerControllerPolicyInterface() { }
|
||||
virtual ~PointerControllerPolicyInterface() { }
|
||||
|
||||
public:
|
||||
virtual void loadPointerResources(PointerResources* outResources) = 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Tracks pointer movements and draws the pointer sprite to a surface.
|
||||
*
|
||||
* Handles pointer acceleration and animation.
|
||||
*/
|
||||
class PointerController : public PointerControllerInterface, public MessageHandler {
|
||||
protected:
|
||||
virtual ~PointerController();
|
||||
|
||||
public:
|
||||
enum InactivityTimeout {
|
||||
INACTIVITY_TIMEOUT_NORMAL = 0,
|
||||
INACTIVITY_TIMEOUT_SHORT = 1,
|
||||
};
|
||||
|
||||
PointerController(const sp<PointerControllerPolicyInterface>& policy,
|
||||
const sp<Looper>& looper, const sp<SpriteController>& spriteController);
|
||||
|
||||
virtual bool getBounds(float* outMinX, float* outMinY,
|
||||
float* outMaxX, float* outMaxY) const;
|
||||
virtual void move(float deltaX, float deltaY);
|
||||
virtual void setButtonState(int32_t buttonState);
|
||||
virtual int32_t getButtonState() const;
|
||||
virtual void setPosition(float x, float y);
|
||||
virtual void getPosition(float* outX, float* outY) const;
|
||||
virtual void fade(Transition transition);
|
||||
virtual void unfade(Transition transition);
|
||||
|
||||
virtual void setPresentation(Presentation presentation);
|
||||
virtual void setSpots(const PointerCoords* spotCoords,
|
||||
const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
|
||||
virtual void clearSpots();
|
||||
|
||||
void setDisplaySize(int32_t width, int32_t height);
|
||||
void setDisplayOrientation(int32_t orientation);
|
||||
void setPointerIcon(const SpriteIcon& icon);
|
||||
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
|
||||
|
||||
private:
|
||||
static const size_t MAX_RECYCLED_SPRITES = 12;
|
||||
static const size_t MAX_SPOTS = 12;
|
||||
|
||||
enum {
|
||||
MSG_ANIMATE,
|
||||
MSG_INACTIVITY_TIMEOUT,
|
||||
};
|
||||
|
||||
struct Spot {
|
||||
static const uint32_t INVALID_ID = 0xffffffff;
|
||||
|
||||
uint32_t id;
|
||||
sp<Sprite> sprite;
|
||||
float alpha;
|
||||
float scale;
|
||||
float x, y;
|
||||
|
||||
inline Spot(uint32_t id, const sp<Sprite>& sprite)
|
||||
: id(id), sprite(sprite), alpha(1.0f), scale(1.0f),
|
||||
x(0.0f), y(0.0f), lastIcon(NULL) { }
|
||||
|
||||
void updateSprite(const SpriteIcon* icon, float x, float y);
|
||||
|
||||
private:
|
||||
const SpriteIcon* lastIcon;
|
||||
};
|
||||
|
||||
mutable Mutex mLock;
|
||||
|
||||
sp<PointerControllerPolicyInterface> mPolicy;
|
||||
sp<Looper> mLooper;
|
||||
sp<SpriteController> mSpriteController;
|
||||
sp<WeakMessageHandler> mHandler;
|
||||
|
||||
PointerResources mResources;
|
||||
|
||||
struct Locked {
|
||||
bool animationPending;
|
||||
nsecs_t animationTime;
|
||||
|
||||
int32_t displayWidth;
|
||||
int32_t displayHeight;
|
||||
int32_t displayOrientation;
|
||||
|
||||
InactivityTimeout inactivityTimeout;
|
||||
|
||||
Presentation presentation;
|
||||
bool presentationChanged;
|
||||
|
||||
int32_t pointerFadeDirection;
|
||||
float pointerX;
|
||||
float pointerY;
|
||||
float pointerAlpha;
|
||||
sp<Sprite> pointerSprite;
|
||||
SpriteIcon pointerIcon;
|
||||
bool pointerIconChanged;
|
||||
|
||||
int32_t buttonState;
|
||||
|
||||
Vector<Spot*> spots;
|
||||
Vector<sp<Sprite> > recycledSprites;
|
||||
} mLocked;
|
||||
|
||||
bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
|
||||
void setPositionLocked(float x, float y);
|
||||
|
||||
void handleMessage(const Message& message);
|
||||
void doAnimate();
|
||||
void doInactivityTimeout();
|
||||
|
||||
void startAnimationLocked();
|
||||
|
||||
void resetInactivityTimeoutLocked();
|
||||
void removeInactivityTimeoutLocked();
|
||||
void updatePointerLocked();
|
||||
|
||||
Spot* getSpotLocked(uint32_t id);
|
||||
Spot* createAndAddSpotLocked(uint32_t id);
|
||||
Spot* removeFirstFadingSpotLocked();
|
||||
void releaseSpotLocked(Spot* spot);
|
||||
void fadeOutAndReleaseSpotLocked(Spot* spot);
|
||||
void fadeOutAndReleaseAllSpotsLocked();
|
||||
|
||||
void loadResources();
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_POINTER_CONTROLLER_H
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "PropertyMap"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils_Log.h"
|
||||
#include "PropertyMap.h"
|
||||
|
||||
// Enables debug output for the parser.
|
||||
#define DEBUG_PARSER 0
|
||||
|
||||
// Enables debug output for parser performance.
|
||||
#define DEBUG_PARSER_PERFORMANCE 0
|
||||
|
||||
|
||||
namespace android {
|
||||
|
||||
static const char* WHITESPACE = " \t\r";
|
||||
static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r=";
|
||||
|
||||
|
||||
// --- PropertyMap ---
|
||||
|
||||
PropertyMap::PropertyMap() {
|
||||
}
|
||||
|
||||
PropertyMap::~PropertyMap() {
|
||||
}
|
||||
|
||||
void PropertyMap::clear() {
|
||||
mProperties.clear();
|
||||
}
|
||||
|
||||
void PropertyMap::addProperty(const String8& key, const String8& value) {
|
||||
mProperties.add(key, value);
|
||||
}
|
||||
|
||||
bool PropertyMap::hasProperty(const String8& key) const {
|
||||
return mProperties.indexOfKey(key) >= 0;
|
||||
}
|
||||
|
||||
bool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const {
|
||||
ssize_t index = mProperties.indexOfKey(key);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outValue = mProperties.valueAt(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const {
|
||||
int32_t intValue;
|
||||
if (!tryGetProperty(key, intValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outValue = intValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const {
|
||||
String8 stringValue;
|
||||
if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* end;
|
||||
int value = strtol(stringValue.string(), & end, 10);
|
||||
if (*end != '\0') {
|
||||
ALOGW("Property key '%s' has invalid value '%s'. Expected an integer.",
|
||||
key.string(), stringValue.string());
|
||||
return false;
|
||||
}
|
||||
outValue = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const {
|
||||
String8 stringValue;
|
||||
if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* end;
|
||||
float value = strtof(stringValue.string(), & end);
|
||||
if (*end != '\0') {
|
||||
ALOGW("Property key '%s' has invalid value '%s'. Expected a float.",
|
||||
key.string(), stringValue.string());
|
||||
return false;
|
||||
}
|
||||
outValue = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyMap::addAll(const PropertyMap* map) {
|
||||
for (size_t i = 0; i < map->mProperties.size(); i++) {
|
||||
mProperties.add(map->mProperties.keyAt(i), map->mProperties.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
status_t PropertyMap::load(const String8& filename, PropertyMap** outMap) {
|
||||
*outMap = NULL;
|
||||
|
||||
Tokenizer* tokenizer;
|
||||
status_t status = Tokenizer::open(filename, &tokenizer);
|
||||
if (status) {
|
||||
ALOGE("Error %d opening property file %s.", status, filename.string());
|
||||
} else {
|
||||
PropertyMap* map = new PropertyMap();
|
||||
if (!map) {
|
||||
ALOGE("Error allocating property map.");
|
||||
status = NO_MEMORY;
|
||||
} else {
|
||||
#if DEBUG_PARSER_PERFORMANCE
|
||||
nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
#endif
|
||||
Parser parser(map, tokenizer);
|
||||
status = parser.parse();
|
||||
#if DEBUG_PARSER_PERFORMANCE
|
||||
nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
|
||||
ALOGD("Parsed property file '%s' %d lines in %0.3fms.",
|
||||
tokenizer->getFilename().string(), tokenizer->getLineNumber(),
|
||||
elapsedTime / 1000000.0);
|
||||
#endif
|
||||
if (status) {
|
||||
delete map;
|
||||
} else {
|
||||
*outMap = map;
|
||||
}
|
||||
}
|
||||
delete tokenizer;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
// --- PropertyMap::Parser ---
|
||||
|
||||
PropertyMap::Parser::Parser(PropertyMap* map, Tokenizer* tokenizer) :
|
||||
mMap(map), mTokenizer(tokenizer) {
|
||||
}
|
||||
|
||||
PropertyMap::Parser::~Parser() {
|
||||
}
|
||||
|
||||
status_t PropertyMap::Parser::parse() {
|
||||
while (!mTokenizer->isEof()) {
|
||||
#if DEBUG_PARSER
|
||||
ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
|
||||
mTokenizer->peekRemainderOfLine().string());
|
||||
#endif
|
||||
|
||||
mTokenizer->skipDelimiters(WHITESPACE);
|
||||
|
||||
if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
|
||||
String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
|
||||
if (keyToken.isEmpty()) {
|
||||
ALOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().string());
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
mTokenizer->skipDelimiters(WHITESPACE);
|
||||
|
||||
if (mTokenizer->nextChar() != '=') {
|
||||
ALOGE("%s: Expected '=' between property key and value.",
|
||||
mTokenizer->getLocation().string());
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
mTokenizer->skipDelimiters(WHITESPACE);
|
||||
|
||||
String8 valueToken = mTokenizer->nextToken(WHITESPACE);
|
||||
if (valueToken.find("\\", 0) >= 0 || valueToken.find("\"", 0) >= 0) {
|
||||
ALOGE("%s: Found reserved character '\\' or '\"' in property value.",
|
||||
mTokenizer->getLocation().string());
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
mTokenizer->skipDelimiters(WHITESPACE);
|
||||
if (!mTokenizer->isEol()) {
|
||||
ALOGE("%s: Expected end of line, got '%s'.",
|
||||
mTokenizer->getLocation().string(),
|
||||
mTokenizer->peekRemainderOfLine().string());
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
if (mMap->hasProperty(keyToken)) {
|
||||
ALOGE("%s: Duplicate property value for key '%s'.",
|
||||
mTokenizer->getLocation().string(), keyToken.string());
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
mMap->addProperty(keyToken, valueToken);
|
||||
}
|
||||
|
||||
mTokenizer->nextLine();
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
} // namespace android
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_PROPERTY_MAP_H
|
||||
#define _UTILS_PROPERTY_MAP_H
|
||||
|
||||
#include <utils/KeyedVector.h>
|
||||
#include "String8.h"
|
||||
#include <utils/Errors.h>
|
||||
#include "Tokenizer.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Provides a mechanism for passing around string-based property key / value pairs
|
||||
* and loading them from property files.
|
||||
*
|
||||
* The property files have the following simple structure:
|
||||
*
|
||||
* # Comment
|
||||
* key = value
|
||||
*
|
||||
* Keys and values are any sequence of printable ASCII characters.
|
||||
* The '=' separates the key from the value.
|
||||
* The key and value may not contain whitespace.
|
||||
*
|
||||
* The '\' character is reserved for escape sequences and is not currently supported.
|
||||
* The '"" character is reserved for quoting and is not currently supported.
|
||||
* Files that contain the '\' or '"' character will fail to parse.
|
||||
*
|
||||
* The file must not contain duplicate keys.
|
||||
*
|
||||
* TODO Support escape sequences and quoted values when needed.
|
||||
*/
|
||||
class PropertyMap {
|
||||
public:
|
||||
/* Creates an empty property map. */
|
||||
PropertyMap();
|
||||
~PropertyMap();
|
||||
|
||||
/* Clears the property map. */
|
||||
void clear();
|
||||
|
||||
/* Adds a property.
|
||||
* Replaces the property with the same key if it is already present.
|
||||
*/
|
||||
void addProperty(const String8& key, const String8& value);
|
||||
|
||||
/* Returns true if the property map contains the specified key. */
|
||||
bool hasProperty(const String8& key) const;
|
||||
|
||||
/* Gets the value of a property and parses it.
|
||||
* Returns true and sets outValue if the key was found and its value was parsed successfully.
|
||||
* Otherwise returns false and does not modify outValue. (Also logs a warning.)
|
||||
*/
|
||||
bool tryGetProperty(const String8& key, String8& outValue) const;
|
||||
bool tryGetProperty(const String8& key, bool& outValue) const;
|
||||
bool tryGetProperty(const String8& key, int32_t& outValue) const;
|
||||
bool tryGetProperty(const String8& key, float& outValue) const;
|
||||
|
||||
/* Adds all values from the specified property map. */
|
||||
void addAll(const PropertyMap* map);
|
||||
|
||||
/* Gets the underlying property map. */
|
||||
inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; }
|
||||
|
||||
/* Loads a property map from a file. */
|
||||
static status_t load(const String8& filename, PropertyMap** outMap);
|
||||
|
||||
private:
|
||||
class Parser {
|
||||
PropertyMap* mMap;
|
||||
Tokenizer* mTokenizer;
|
||||
|
||||
public:
|
||||
Parser(PropertyMap* map, Tokenizer* tokenizer);
|
||||
~Parser();
|
||||
status_t parse();
|
||||
|
||||
private:
|
||||
status_t parseType();
|
||||
status_t parseKey();
|
||||
status_t parseKeyProperty();
|
||||
status_t parseModifier(const String8& token, int32_t* outMetaState);
|
||||
status_t parseCharacterLiteral(char16_t* outCharacter);
|
||||
};
|
||||
|
||||
KeyedVector<String8, String8> mProperties;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UTILS_PROPERTY_MAP_H
|
|
@ -1,481 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Sprites"
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include "SpriteController.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include <SkBitmap.h>
|
||||
#include <SkCanvas.h>
|
||||
#include <SkColor.h>
|
||||
#include <SkPaint.h>
|
||||
#include <SkXfermode.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// --- SpriteController ---
|
||||
|
||||
SpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer) :
|
||||
mLooper(looper), mOverlayLayer(overlayLayer) {
|
||||
mHandler = new WeakMessageHandler(this);
|
||||
|
||||
mLocked.transactionNestingCount = 0;
|
||||
mLocked.deferredSpriteUpdate = false;
|
||||
}
|
||||
|
||||
SpriteController::~SpriteController() {
|
||||
mLooper->removeMessages(mHandler);
|
||||
|
||||
if (mSurfaceComposerClient != NULL) {
|
||||
mSurfaceComposerClient->dispose();
|
||||
mSurfaceComposerClient.clear();
|
||||
}
|
||||
}
|
||||
|
||||
sp<Sprite> SpriteController::createSprite() {
|
||||
return new SpriteImpl(this);
|
||||
}
|
||||
|
||||
void SpriteController::openTransaction() {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
mLocked.transactionNestingCount += 1;
|
||||
}
|
||||
|
||||
void SpriteController::closeTransaction() {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
LOG_ALWAYS_FATAL_IF(mLocked.transactionNestingCount == 0,
|
||||
"Sprite closeTransaction() called but there is no open sprite transaction");
|
||||
|
||||
mLocked.transactionNestingCount -= 1;
|
||||
if (mLocked.transactionNestingCount == 0 && mLocked.deferredSpriteUpdate) {
|
||||
mLocked.deferredSpriteUpdate = false;
|
||||
mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES));
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::invalidateSpriteLocked(const sp<SpriteImpl>& sprite) {
|
||||
bool wasEmpty = mLocked.invalidatedSprites.isEmpty();
|
||||
mLocked.invalidatedSprites.push(sprite);
|
||||
if (wasEmpty) {
|
||||
if (mLocked.transactionNestingCount != 0) {
|
||||
mLocked.deferredSpriteUpdate = true;
|
||||
} else {
|
||||
mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl) {
|
||||
bool wasEmpty = mLocked.disposedSurfaces.isEmpty();
|
||||
mLocked.disposedSurfaces.push(surfaceControl);
|
||||
if (wasEmpty) {
|
||||
mLooper->sendMessage(mHandler, Message(MSG_DISPOSE_SURFACES));
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::handleMessage(const Message& message) {
|
||||
switch (message.what) {
|
||||
case MSG_UPDATE_SPRITES:
|
||||
doUpdateSprites();
|
||||
break;
|
||||
case MSG_DISPOSE_SURFACES:
|
||||
doDisposeSurfaces();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::doUpdateSprites() {
|
||||
// Collect information about sprite updates.
|
||||
// Each sprite update record includes a reference to its associated sprite so we can
|
||||
// be certain the sprites will not be deleted while this function runs. Sprites
|
||||
// may invalidate themselves again during this time but we will handle those changes
|
||||
// in the next iteration.
|
||||
Vector<SpriteUpdate> updates;
|
||||
size_t numSprites;
|
||||
{ // acquire lock
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
numSprites = mLocked.invalidatedSprites.size();
|
||||
for (size_t i = 0; i < numSprites; i++) {
|
||||
const sp<SpriteImpl>& sprite = mLocked.invalidatedSprites.itemAt(i);
|
||||
|
||||
updates.push(SpriteUpdate(sprite, sprite->getStateLocked()));
|
||||
sprite->resetDirtyLocked();
|
||||
}
|
||||
mLocked.invalidatedSprites.clear();
|
||||
} // release lock
|
||||
|
||||
// Create missing surfaces.
|
||||
bool surfaceChanged = false;
|
||||
for (size_t i = 0; i < numSprites; i++) {
|
||||
SpriteUpdate& update = updates.editItemAt(i);
|
||||
|
||||
if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) {
|
||||
update.state.surfaceWidth = update.state.icon.bitmap.width();
|
||||
update.state.surfaceHeight = update.state.icon.bitmap.height();
|
||||
update.state.surfaceDrawn = false;
|
||||
update.state.surfaceVisible = false;
|
||||
update.state.surfaceControl = obtainSurface(
|
||||
update.state.surfaceWidth, update.state.surfaceHeight);
|
||||
if (update.state.surfaceControl != NULL) {
|
||||
update.surfaceChanged = surfaceChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resize sprites if needed, inside a global transaction.
|
||||
bool haveGlobalTransaction = false;
|
||||
for (size_t i = 0; i < numSprites; i++) {
|
||||
SpriteUpdate& update = updates.editItemAt(i);
|
||||
|
||||
if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) {
|
||||
int32_t desiredWidth = update.state.icon.bitmap.width();
|
||||
int32_t desiredHeight = update.state.icon.bitmap.height();
|
||||
if (update.state.surfaceWidth < desiredWidth
|
||||
|| update.state.surfaceHeight < desiredHeight) {
|
||||
if (!haveGlobalTransaction) {
|
||||
SurfaceComposerClient::openGlobalTransaction();
|
||||
haveGlobalTransaction = true;
|
||||
}
|
||||
|
||||
status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight);
|
||||
if (status) {
|
||||
ALOGE("Error %d resizing sprite surface from %dx%d to %dx%d",
|
||||
status, update.state.surfaceWidth, update.state.surfaceHeight,
|
||||
desiredWidth, desiredHeight);
|
||||
} else {
|
||||
update.state.surfaceWidth = desiredWidth;
|
||||
update.state.surfaceHeight = desiredHeight;
|
||||
update.state.surfaceDrawn = false;
|
||||
update.surfaceChanged = surfaceChanged = true;
|
||||
|
||||
if (update.state.surfaceVisible) {
|
||||
status = update.state.surfaceControl->hide();
|
||||
if (status) {
|
||||
ALOGE("Error %d hiding sprite surface after resize.", status);
|
||||
} else {
|
||||
update.state.surfaceVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (haveGlobalTransaction) {
|
||||
SurfaceComposerClient::closeGlobalTransaction();
|
||||
}
|
||||
|
||||
// Redraw sprites if needed.
|
||||
for (size_t i = 0; i < numSprites; i++) {
|
||||
SpriteUpdate& update = updates.editItemAt(i);
|
||||
|
||||
if ((update.state.dirty & DIRTY_BITMAP) && update.state.surfaceDrawn) {
|
||||
update.state.surfaceDrawn = false;
|
||||
update.surfaceChanged = surfaceChanged = true;
|
||||
}
|
||||
|
||||
if (update.state.surfaceControl != NULL && !update.state.surfaceDrawn
|
||||
&& update.state.wantSurfaceVisible()) {
|
||||
sp<Surface> surface = update.state.surfaceControl->getSurface();
|
||||
Surface::SurfaceInfo surfaceInfo;
|
||||
status_t status = surface->lock(&surfaceInfo);
|
||||
if (status) {
|
||||
ALOGE("Error %d locking sprite surface before drawing.", status);
|
||||
} else {
|
||||
SkBitmap surfaceBitmap;
|
||||
ssize_t bpr = surfaceInfo.s * bytesPerPixel(surfaceInfo.format);
|
||||
surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config,
|
||||
surfaceInfo.w, surfaceInfo.h, bpr);
|
||||
surfaceBitmap.setPixels(surfaceInfo.bits);
|
||||
|
||||
SkCanvas surfaceCanvas;
|
||||
surfaceCanvas.setBitmapDevice(surfaceBitmap);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
|
||||
|
||||
if (surfaceInfo.w > uint32_t(update.state.icon.bitmap.width())) {
|
||||
paint.setColor(0); // transparent fill color
|
||||
surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
|
||||
surfaceInfo.w, update.state.icon.bitmap.height(), paint);
|
||||
}
|
||||
if (surfaceInfo.h > uint32_t(update.state.icon.bitmap.height())) {
|
||||
paint.setColor(0); // transparent fill color
|
||||
surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
|
||||
surfaceInfo.w, surfaceInfo.h, paint);
|
||||
}
|
||||
|
||||
status = surface->unlockAndPost();
|
||||
if (status) {
|
||||
ALOGE("Error %d unlocking and posting sprite surface after drawing.", status);
|
||||
} else {
|
||||
update.state.surfaceDrawn = true;
|
||||
update.surfaceChanged = surfaceChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set sprite surface properties and make them visible.
|
||||
bool haveTransaction = false;
|
||||
for (size_t i = 0; i < numSprites; i++) {
|
||||
SpriteUpdate& update = updates.editItemAt(i);
|
||||
|
||||
bool wantSurfaceVisibleAndDrawn = update.state.wantSurfaceVisible()
|
||||
&& update.state.surfaceDrawn;
|
||||
bool becomingVisible = wantSurfaceVisibleAndDrawn && !update.state.surfaceVisible;
|
||||
bool becomingHidden = !wantSurfaceVisibleAndDrawn && update.state.surfaceVisible;
|
||||
if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden
|
||||
|| (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
|
||||
| DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
|
||||
| DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
|
||||
status_t status;
|
||||
if (!haveTransaction) {
|
||||
SurfaceComposerClient::openGlobalTransaction();
|
||||
haveTransaction = true;
|
||||
}
|
||||
|
||||
if (wantSurfaceVisibleAndDrawn
|
||||
&& (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) {
|
||||
status = update.state.surfaceControl->setAlpha(update.state.alpha);
|
||||
if (status) {
|
||||
ALOGE("Error %d setting sprite surface alpha.", status);
|
||||
}
|
||||
}
|
||||
|
||||
if (wantSurfaceVisibleAndDrawn
|
||||
&& (becomingVisible || (update.state.dirty & (DIRTY_POSITION
|
||||
| DIRTY_HOTSPOT)))) {
|
||||
status = update.state.surfaceControl->setPosition(
|
||||
update.state.positionX - update.state.icon.hotSpotX,
|
||||
update.state.positionY - update.state.icon.hotSpotY);
|
||||
if (status) {
|
||||
ALOGE("Error %d setting sprite surface position.", status);
|
||||
}
|
||||
}
|
||||
|
||||
if (wantSurfaceVisibleAndDrawn
|
||||
&& (becomingVisible
|
||||
|| (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) {
|
||||
status = update.state.surfaceControl->setMatrix(
|
||||
update.state.transformationMatrix.dsdx,
|
||||
update.state.transformationMatrix.dtdx,
|
||||
update.state.transformationMatrix.dsdy,
|
||||
update.state.transformationMatrix.dtdy);
|
||||
if (status) {
|
||||
ALOGE("Error %d setting sprite surface transformation matrix.", status);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t surfaceLayer = mOverlayLayer + update.state.layer;
|
||||
if (wantSurfaceVisibleAndDrawn
|
||||
&& (becomingVisible || (update.state.dirty & DIRTY_LAYER))) {
|
||||
status = update.state.surfaceControl->setLayer(surfaceLayer);
|
||||
if (status) {
|
||||
ALOGE("Error %d setting sprite surface layer.", status);
|
||||
}
|
||||
}
|
||||
|
||||
if (becomingVisible) {
|
||||
status = update.state.surfaceControl->show(surfaceLayer);
|
||||
if (status) {
|
||||
ALOGE("Error %d showing sprite surface.", status);
|
||||
} else {
|
||||
update.state.surfaceVisible = true;
|
||||
update.surfaceChanged = surfaceChanged = true;
|
||||
}
|
||||
} else if (becomingHidden) {
|
||||
status = update.state.surfaceControl->hide();
|
||||
if (status) {
|
||||
ALOGE("Error %d hiding sprite surface.", status);
|
||||
} else {
|
||||
update.state.surfaceVisible = false;
|
||||
update.surfaceChanged = surfaceChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (haveTransaction) {
|
||||
SurfaceComposerClient::closeGlobalTransaction();
|
||||
}
|
||||
|
||||
// If any surfaces were changed, write back the new surface properties to the sprites.
|
||||
if (surfaceChanged) { // acquire lock
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
for (size_t i = 0; i < numSprites; i++) {
|
||||
const SpriteUpdate& update = updates.itemAt(i);
|
||||
|
||||
if (update.surfaceChanged) {
|
||||
update.sprite->setSurfaceLocked(update.state.surfaceControl,
|
||||
update.state.surfaceWidth, update.state.surfaceHeight,
|
||||
update.state.surfaceDrawn, update.state.surfaceVisible);
|
||||
}
|
||||
}
|
||||
} // release lock
|
||||
|
||||
// Clear the sprite update vector outside the lock. It is very important that
|
||||
// we do not clear sprite references inside the lock since we could be releasing
|
||||
// the last remaining reference to the sprite here which would result in the
|
||||
// sprite being deleted and the lock being reacquired by the sprite destructor
|
||||
// while already held.
|
||||
updates.clear();
|
||||
}
|
||||
|
||||
void SpriteController::doDisposeSurfaces() {
|
||||
// Collect disposed surfaces.
|
||||
Vector<sp<SurfaceControl> > disposedSurfaces;
|
||||
{ // acquire lock
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
disposedSurfaces = mLocked.disposedSurfaces;
|
||||
mLocked.disposedSurfaces.clear();
|
||||
} // release lock
|
||||
|
||||
// Release the last reference to each surface outside of the lock.
|
||||
// We don't want the surfaces to be deleted while we are holding our lock.
|
||||
disposedSurfaces.clear();
|
||||
}
|
||||
|
||||
void SpriteController::ensureSurfaceComposerClient() {
|
||||
if (mSurfaceComposerClient == NULL) {
|
||||
mSurfaceComposerClient = new SurfaceComposerClient();
|
||||
}
|
||||
}
|
||||
|
||||
sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height) {
|
||||
ensureSurfaceComposerClient();
|
||||
|
||||
sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface(
|
||||
String8("Sprite"), 0, width, height, PIXEL_FORMAT_RGBA_8888);
|
||||
if (surfaceControl == NULL || !surfaceControl->isValid()
|
||||
|| !surfaceControl->getSurface()->isValid()) {
|
||||
ALOGE("Error creating sprite surface.");
|
||||
return NULL;
|
||||
}
|
||||
return surfaceControl;
|
||||
}
|
||||
|
||||
|
||||
// --- SpriteController::SpriteImpl ---
|
||||
|
||||
SpriteController::SpriteImpl::SpriteImpl(const sp<SpriteController> controller) :
|
||||
mController(controller) {
|
||||
}
|
||||
|
||||
SpriteController::SpriteImpl::~SpriteImpl() {
|
||||
AutoMutex _m(mController->mLock);
|
||||
|
||||
// Let the controller take care of deleting the last reference to sprite
|
||||
// surfaces so that we do not block the caller on an IPC here.
|
||||
if (mLocked.state.surfaceControl != NULL) {
|
||||
mController->disposeSurfaceLocked(mLocked.state.surfaceControl);
|
||||
mLocked.state.surfaceControl.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::setIcon(const SpriteIcon& icon) {
|
||||
AutoMutex _l(mController->mLock);
|
||||
|
||||
uint32_t dirty;
|
||||
if (icon.isValid()) {
|
||||
icon.bitmap.copyTo(&mLocked.state.icon.bitmap, SkBitmap::kARGB_8888_Config);
|
||||
|
||||
if (!mLocked.state.icon.isValid()
|
||||
|| mLocked.state.icon.hotSpotX != icon.hotSpotX
|
||||
|| mLocked.state.icon.hotSpotY != icon.hotSpotY) {
|
||||
mLocked.state.icon.hotSpotX = icon.hotSpotX;
|
||||
mLocked.state.icon.hotSpotY = icon.hotSpotY;
|
||||
dirty = DIRTY_BITMAP | DIRTY_HOTSPOT;
|
||||
} else {
|
||||
dirty = DIRTY_BITMAP;
|
||||
}
|
||||
} else if (mLocked.state.icon.isValid()) {
|
||||
mLocked.state.icon.bitmap.reset();
|
||||
dirty = DIRTY_BITMAP | DIRTY_HOTSPOT;
|
||||
} else {
|
||||
return; // setting to invalid icon and already invalid so nothing to do
|
||||
}
|
||||
|
||||
invalidateLocked(dirty);
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::setVisible(bool visible) {
|
||||
AutoMutex _l(mController->mLock);
|
||||
|
||||
if (mLocked.state.visible != visible) {
|
||||
mLocked.state.visible = visible;
|
||||
invalidateLocked(DIRTY_VISIBILITY);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::setPosition(float x, float y) {
|
||||
AutoMutex _l(mController->mLock);
|
||||
|
||||
if (mLocked.state.positionX != x || mLocked.state.positionY != y) {
|
||||
mLocked.state.positionX = x;
|
||||
mLocked.state.positionY = y;
|
||||
invalidateLocked(DIRTY_POSITION);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::setLayer(int32_t layer) {
|
||||
AutoMutex _l(mController->mLock);
|
||||
|
||||
if (mLocked.state.layer != layer) {
|
||||
mLocked.state.layer = layer;
|
||||
invalidateLocked(DIRTY_LAYER);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::setAlpha(float alpha) {
|
||||
AutoMutex _l(mController->mLock);
|
||||
|
||||
if (mLocked.state.alpha != alpha) {
|
||||
mLocked.state.alpha = alpha;
|
||||
invalidateLocked(DIRTY_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::setTransformationMatrix(
|
||||
const SpriteTransformationMatrix& matrix) {
|
||||
AutoMutex _l(mController->mLock);
|
||||
|
||||
if (mLocked.state.transformationMatrix != matrix) {
|
||||
mLocked.state.transformationMatrix = matrix;
|
||||
invalidateLocked(DIRTY_TRANSFORMATION_MATRIX);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) {
|
||||
bool wasDirty = mLocked.state.dirty;
|
||||
mLocked.state.dirty |= dirty;
|
||||
|
||||
if (!wasDirty) {
|
||||
mController->invalidateSpriteLocked(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
|
@ -1,295 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef _UI_SPRITES_H
|
||||
#define _UI_SPRITES_H
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Looper.h>
|
||||
|
||||
#include <surfaceflinger/Surface.h>
|
||||
#include <surfaceflinger/SurfaceComposerClient.h>
|
||||
#include <surfaceflinger/ISurfaceComposer.h>
|
||||
|
||||
#include <SkBitmap.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Transformation matrix for a sprite.
|
||||
*/
|
||||
struct SpriteTransformationMatrix {
|
||||
inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
|
||||
inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) :
|
||||
dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { }
|
||||
|
||||
float dsdx;
|
||||
float dtdx;
|
||||
float dsdy;
|
||||
float dtdy;
|
||||
|
||||
inline bool operator== (const SpriteTransformationMatrix& other) {
|
||||
return dsdx == other.dsdx
|
||||
&& dtdx == other.dtdx
|
||||
&& dsdy == other.dsdy
|
||||
&& dtdy == other.dtdy;
|
||||
}
|
||||
|
||||
inline bool operator!= (const SpriteTransformationMatrix& other) {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Icon that a sprite displays, including its hotspot.
|
||||
*/
|
||||
struct SpriteIcon {
|
||||
inline SpriteIcon() : hotSpotX(0), hotSpotY(0) { }
|
||||
inline SpriteIcon(const SkBitmap& bitmap, float hotSpotX, float hotSpotY) :
|
||||
bitmap(bitmap), hotSpotX(hotSpotX), hotSpotY(hotSpotY) { }
|
||||
|
||||
SkBitmap bitmap;
|
||||
float hotSpotX;
|
||||
float hotSpotY;
|
||||
|
||||
inline SpriteIcon copy() const {
|
||||
SkBitmap bitmapCopy;
|
||||
bitmap.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config);
|
||||
return SpriteIcon(bitmapCopy, hotSpotX, hotSpotY);
|
||||
}
|
||||
|
||||
inline void reset() {
|
||||
bitmap.reset();
|
||||
hotSpotX = 0;
|
||||
hotSpotY = 0;
|
||||
}
|
||||
|
||||
inline bool isValid() const {
|
||||
return !bitmap.isNull() && !bitmap.empty();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* A sprite is a simple graphical object that is displayed on-screen above other layers.
|
||||
* The basic sprite class is an interface.
|
||||
* The implementation is provided by the sprite controller.
|
||||
*/
|
||||
class Sprite : public RefBase {
|
||||
protected:
|
||||
Sprite() { }
|
||||
virtual ~Sprite() { }
|
||||
|
||||
public:
|
||||
enum {
|
||||
// The base layer for pointer sprites.
|
||||
BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
|
||||
|
||||
// The base layer for spot sprites.
|
||||
BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
|
||||
};
|
||||
|
||||
/* Sets the bitmap that is drawn by the sprite.
|
||||
* The sprite retains a copy of the bitmap for subsequent rendering. */
|
||||
virtual void setIcon(const SpriteIcon& icon) = 0;
|
||||
|
||||
inline void clearIcon() {
|
||||
setIcon(SpriteIcon());
|
||||
}
|
||||
|
||||
/* Sets whether the sprite is visible. */
|
||||
virtual void setVisible(bool visible) = 0;
|
||||
|
||||
/* Sets the sprite position on screen, relative to the sprite's hot spot. */
|
||||
virtual void setPosition(float x, float y) = 0;
|
||||
|
||||
/* Sets the layer of the sprite, relative to the system sprite overlay layer.
|
||||
* Layer 0 is the overlay layer, > 0 appear above this layer. */
|
||||
virtual void setLayer(int32_t layer) = 0;
|
||||
|
||||
/* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
|
||||
virtual void setAlpha(float alpha) = 0;
|
||||
|
||||
/* Sets the sprite transformation matrix. */
|
||||
virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Displays sprites on the screen.
|
||||
*
|
||||
* This interface is used by PointerController and SpotController to draw pointers or
|
||||
* spot representations of fingers. It is not intended for general purpose use
|
||||
* by other components.
|
||||
*
|
||||
* All sprite position updates and rendering is performed asynchronously.
|
||||
*
|
||||
* Clients are responsible for animating sprites by periodically updating their properties.
|
||||
*/
|
||||
class SpriteController : public MessageHandler {
|
||||
protected:
|
||||
virtual ~SpriteController();
|
||||
|
||||
public:
|
||||
SpriteController(const sp<Looper>& looper, int32_t overlayLayer);
|
||||
|
||||
/* Creates a new sprite, initially invisible. */
|
||||
sp<Sprite> createSprite();
|
||||
|
||||
/* Opens or closes a transaction to perform a batch of sprite updates as part of
|
||||
* a single operation such as setPosition and setAlpha. It is not necessary to
|
||||
* open a transaction when updating a single property.
|
||||
* Calls to openTransaction() nest and must be matched by an equal number
|
||||
* of calls to closeTransaction(). */
|
||||
void openTransaction();
|
||||
void closeTransaction();
|
||||
|
||||
private:
|
||||
enum {
|
||||
MSG_UPDATE_SPRITES,
|
||||
MSG_DISPOSE_SURFACES,
|
||||
};
|
||||
|
||||
enum {
|
||||
DIRTY_BITMAP = 1 << 0,
|
||||
DIRTY_ALPHA = 1 << 1,
|
||||
DIRTY_POSITION = 1 << 2,
|
||||
DIRTY_TRANSFORMATION_MATRIX = 1 << 3,
|
||||
DIRTY_LAYER = 1 << 4,
|
||||
DIRTY_VISIBILITY = 1 << 5,
|
||||
DIRTY_HOTSPOT = 1 << 6,
|
||||
};
|
||||
|
||||
/* Describes the state of a sprite.
|
||||
* This structure is designed so that it can be copied during updates so that
|
||||
* surfaces can be resized and redrawn without blocking the client by holding a lock
|
||||
* on the sprites for a long time.
|
||||
* Note that the SkBitmap holds a reference to a shared (and immutable) pixel ref. */
|
||||
struct SpriteState {
|
||||
inline SpriteState() :
|
||||
dirty(0), visible(false),
|
||||
positionX(0), positionY(0), layer(0), alpha(1.0f),
|
||||
surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
|
||||
}
|
||||
|
||||
uint32_t dirty;
|
||||
|
||||
SpriteIcon icon;
|
||||
bool visible;
|
||||
float positionX;
|
||||
float positionY;
|
||||
int32_t layer;
|
||||
float alpha;
|
||||
SpriteTransformationMatrix transformationMatrix;
|
||||
|
||||
sp<SurfaceControl> surfaceControl;
|
||||
int32_t surfaceWidth;
|
||||
int32_t surfaceHeight;
|
||||
bool surfaceDrawn;
|
||||
bool surfaceVisible;
|
||||
|
||||
inline bool wantSurfaceVisible() const {
|
||||
return visible && alpha > 0.0f && icon.isValid();
|
||||
}
|
||||
};
|
||||
|
||||
/* Client interface for a sprite.
|
||||
* Requests acquire a lock on the controller, update local state and request the
|
||||
* controller to invalidate the sprite.
|
||||
* The real heavy lifting of creating, resizing and redrawing surfaces happens
|
||||
* asynchronously with no locks held except in short critical section to copy
|
||||
* the sprite state before the work and update the sprite surface control afterwards.
|
||||
*/
|
||||
class SpriteImpl : public Sprite {
|
||||
protected:
|
||||
virtual ~SpriteImpl();
|
||||
|
||||
public:
|
||||
SpriteImpl(const sp<SpriteController> controller);
|
||||
|
||||
virtual void setIcon(const SpriteIcon& icon);
|
||||
virtual void setVisible(bool visible);
|
||||
virtual void setPosition(float x, float y);
|
||||
virtual void setLayer(int32_t layer);
|
||||
virtual void setAlpha(float alpha);
|
||||
virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
|
||||
|
||||
inline const SpriteState& getStateLocked() const {
|
||||
return mLocked.state;
|
||||
}
|
||||
|
||||
inline void resetDirtyLocked() {
|
||||
mLocked.state.dirty = 0;
|
||||
}
|
||||
|
||||
inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
|
||||
int32_t width, int32_t height, bool drawn, bool visible) {
|
||||
mLocked.state.surfaceControl = surfaceControl;
|
||||
mLocked.state.surfaceWidth = width;
|
||||
mLocked.state.surfaceHeight = height;
|
||||
mLocked.state.surfaceDrawn = drawn;
|
||||
mLocked.state.surfaceVisible = visible;
|
||||
}
|
||||
|
||||
private:
|
||||
sp<SpriteController> mController;
|
||||
|
||||
struct Locked {
|
||||
SpriteState state;
|
||||
} mLocked; // guarded by mController->mLock
|
||||
|
||||
void invalidateLocked(uint32_t dirty);
|
||||
};
|
||||
|
||||
/* Stores temporary information collected during the sprite update cycle. */
|
||||
struct SpriteUpdate {
|
||||
inline SpriteUpdate() : surfaceChanged(false) { }
|
||||
inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
|
||||
sprite(sprite), state(state), surfaceChanged(false) {
|
||||
}
|
||||
|
||||
sp<SpriteImpl> sprite;
|
||||
SpriteState state;
|
||||
bool surfaceChanged;
|
||||
};
|
||||
|
||||
mutable Mutex mLock;
|
||||
|
||||
sp<Looper> mLooper;
|
||||
const int32_t mOverlayLayer;
|
||||
sp<WeakMessageHandler> mHandler;
|
||||
|
||||
sp<SurfaceComposerClient> mSurfaceComposerClient;
|
||||
|
||||
struct Locked {
|
||||
Vector<sp<SpriteImpl> > invalidatedSprites;
|
||||
Vector<sp<SurfaceControl> > disposedSurfaces;
|
||||
uint32_t transactionNestingCount;
|
||||
bool deferredSpriteUpdate;
|
||||
} mLocked; // guarded by mLock
|
||||
|
||||
void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
|
||||
void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
|
||||
|
||||
void handleMessage(const Message& message);
|
||||
void doUpdateSprites();
|
||||
void doDisposeSurfaces();
|
||||
|
||||
void ensureSurfaceComposerClient();
|
||||
sp<SurfaceControl> obtainSurface(int32_t width, int32_t height);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_SPRITES_H
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// All static variables go here, to control initialization and
|
||||
// destruction order in the library.
|
||||
|
||||
#include "Static.h"
|
||||
|
||||
#include <utils/BufferedTextOutput.h>
|
||||
#include "utils_Log.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
class LibUtilsFirstStatics
|
||||
{
|
||||
public:
|
||||
LibUtilsFirstStatics()
|
||||
{
|
||||
initialize_string8();
|
||||
initialize_string16();
|
||||
}
|
||||
|
||||
~LibUtilsFirstStatics()
|
||||
{
|
||||
terminate_string16();
|
||||
terminate_string8();
|
||||
}
|
||||
};
|
||||
|
||||
static LibUtilsFirstStatics gFirstStatics;
|
||||
int gDarwinCantLoadAllObjects = 1;
|
||||
|
||||
// ------------ Text output streams
|
||||
#if 0
|
||||
Vector<int32_t> gTextBuffers;
|
||||
|
||||
class LogTextOutput : public BufferedTextOutput
|
||||
{
|
||||
public:
|
||||
LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
|
||||
virtual ~LogTextOutput() { };
|
||||
|
||||
protected:
|
||||
virtual status_t writeLines(const struct iovec& vec, size_t N)
|
||||
{
|
||||
//android_writevLog(&vec, N); <-- this is now a no-op
|
||||
if (N != 1) ALOGI("WARNING: writeLines N=%d\n", N);
|
||||
ALOGI("%.*s", vec.iov_len, (const char*) vec.iov_base);
|
||||
return NO_ERROR;
|
||||
}
|
||||
};
|
||||
|
||||
class FdTextOutput : public BufferedTextOutput
|
||||
{
|
||||
public:
|
||||
FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
|
||||
virtual ~FdTextOutput() { };
|
||||
|
||||
protected:
|
||||
virtual status_t writeLines(const struct iovec& vec, size_t N)
|
||||
{
|
||||
writev(mFD, &vec, N);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
private:
|
||||
int mFD;
|
||||
};
|
||||
|
||||
static LogTextOutput gLogTextOutput;
|
||||
static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);
|
||||
static FdTextOutput gStderrTextOutput(STDERR_FILENO);
|
||||
|
||||
TextOutput& alog(gLogTextOutput);
|
||||
TextOutput& aout(gStdoutTextOutput);
|
||||
TextOutput& aerr(gStderrTextOutput);
|
||||
#endif
|
||||
} // namespace android
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// All static variables go here, to control initialization and
|
||||
// destruction order in the library.
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
|
||||
namespace android {
|
||||
// For TextStream.cpp
|
||||
//extern Vector<int32_t> gTextBuffers;
|
||||
|
||||
// For String8.cpp
|
||||
extern void initialize_string8();
|
||||
extern void terminate_string8();
|
||||
|
||||
// For String16.cpp
|
||||
extern void initialize_string16();
|
||||
extern void terminate_string16();
|
||||
|
||||
} // namespace android
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_STRING16_H
|
||||
#define ANDROID_STRING16_H
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/SharedBuffer.h>
|
||||
#include "Unicode.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
extern "C" {
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class String8;
|
||||
class TextOutput;
|
||||
|
||||
//! This is a string holding UTF-16 characters.
|
||||
class String16
|
||||
{
|
||||
public:
|
||||
String16();
|
||||
String16(const String16& o);
|
||||
String16(const String16& o,
|
||||
size_t len,
|
||||
size_t begin=0);
|
||||
explicit String16(const char16_t* o);
|
||||
explicit String16(const char16_t* o, size_t len);
|
||||
explicit String16(const String8& o);
|
||||
explicit String16(const char* o);
|
||||
explicit String16(const char* o, size_t len);
|
||||
|
||||
~String16();
|
||||
|
||||
inline const char16_t* string() const;
|
||||
inline size_t size() const;
|
||||
|
||||
inline const SharedBuffer* sharedBuffer() const;
|
||||
|
||||
void setTo(const String16& other);
|
||||
status_t setTo(const char16_t* other);
|
||||
status_t setTo(const char16_t* other, size_t len);
|
||||
status_t setTo(const String16& other,
|
||||
size_t len,
|
||||
size_t begin=0);
|
||||
|
||||
status_t append(const String16& other);
|
||||
status_t append(const char16_t* other, size_t len);
|
||||
|
||||
inline String16& operator=(const String16& other);
|
||||
|
||||
inline String16& operator+=(const String16& other);
|
||||
inline String16 operator+(const String16& other) const;
|
||||
|
||||
status_t insert(size_t pos, const char16_t* chrs);
|
||||
status_t insert(size_t pos,
|
||||
const char16_t* chrs, size_t len);
|
||||
|
||||
ssize_t findFirst(char16_t c) const;
|
||||
ssize_t findLast(char16_t c) const;
|
||||
|
||||
bool startsWith(const String16& prefix) const;
|
||||
bool startsWith(const char16_t* prefix) const;
|
||||
|
||||
status_t makeLower();
|
||||
|
||||
status_t replaceAll(char16_t replaceThis,
|
||||
char16_t withThis);
|
||||
|
||||
status_t remove(size_t len, size_t begin=0);
|
||||
|
||||
inline int compare(const String16& other) const;
|
||||
|
||||
inline bool operator<(const String16& other) const;
|
||||
inline bool operator<=(const String16& other) const;
|
||||
inline bool operator==(const String16& other) const;
|
||||
inline bool operator!=(const String16& other) const;
|
||||
inline bool operator>=(const String16& other) const;
|
||||
inline bool operator>(const String16& other) const;
|
||||
|
||||
inline bool operator<(const char16_t* other) const;
|
||||
inline bool operator<=(const char16_t* other) const;
|
||||
inline bool operator==(const char16_t* other) const;
|
||||
inline bool operator!=(const char16_t* other) const;
|
||||
inline bool operator>=(const char16_t* other) const;
|
||||
inline bool operator>(const char16_t* other) const;
|
||||
|
||||
inline operator const char16_t*() const;
|
||||
|
||||
private:
|
||||
const char16_t* mString;
|
||||
};
|
||||
|
||||
TextOutput& operator<<(TextOutput& to, const String16& val);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user servicable parts below.
|
||||
|
||||
inline int compare_type(const String16& lhs, const String16& rhs)
|
||||
{
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
inline int strictly_order_type(const String16& lhs, const String16& rhs)
|
||||
{
|
||||
return compare_type(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
inline const char16_t* String16::string() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
inline size_t String16::size() const
|
||||
{
|
||||
return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1;
|
||||
}
|
||||
|
||||
inline const SharedBuffer* String16::sharedBuffer() const
|
||||
{
|
||||
return SharedBuffer::bufferFromData(mString);
|
||||
}
|
||||
|
||||
inline String16& String16::operator=(const String16& other)
|
||||
{
|
||||
setTo(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String16& String16::operator+=(const String16& other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String16 String16::operator+(const String16& other) const
|
||||
{
|
||||
String16 tmp(*this);
|
||||
tmp += other;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline int String16::compare(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size());
|
||||
}
|
||||
|
||||
inline bool String16::operator<(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) < 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator<=(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) <= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator==(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator!=(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) != 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>=(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) >= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) > 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator<(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) < 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator<=(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) <= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator==(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) == 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator!=(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) != 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>=(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) >= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) > 0;
|
||||
}
|
||||
|
||||
inline String16::operator const char16_t*() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_STRING16_H
|
|
@ -0,0 +1,636 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
#include "String8.h"
|
||||
|
||||
#include "utils_Log.h"
|
||||
#include "Unicode.h"
|
||||
#include <utils/SharedBuffer.h>
|
||||
#include "String16.h"
|
||||
#include <utils/TextOutput.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
#include "Static.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define OS_PATH_SEPARATOR '/'
|
||||
|
||||
/*
|
||||
* Functions outside android is below the namespace android, since they use
|
||||
* functions and constants in android namespace.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
// Separator used by resource paths. This is not platform dependent contrary
|
||||
// to OS_PATH_SEPARATOR.
|
||||
#define RES_PATH_SEPARATOR '/'
|
||||
|
||||
static SharedBuffer* gEmptyStringBuf = NULL;
|
||||
static char* gEmptyString = NULL;
|
||||
|
||||
extern int gDarwinCantLoadAllObjects;
|
||||
int gDarwinIsReallyAnnoying;
|
||||
|
||||
static inline char* getEmptyString()
|
||||
{
|
||||
gEmptyStringBuf->acquire();
|
||||
return gEmptyString;
|
||||
}
|
||||
|
||||
void initialize_string8()
|
||||
{
|
||||
// HACK: This dummy dependency forces linking libutils Static.cpp,
|
||||
// which is needed to initialize String8/String16 classes.
|
||||
// These variables are named for Darwin, but are needed elsewhere too,
|
||||
// including static linking on any platform.
|
||||
gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;
|
||||
|
||||
SharedBuffer* buf = SharedBuffer::alloc(1);
|
||||
char* str = (char*)buf->data();
|
||||
*str = 0;
|
||||
gEmptyStringBuf = buf;
|
||||
gEmptyString = str;
|
||||
}
|
||||
|
||||
void terminate_string8()
|
||||
{
|
||||
SharedBuffer::bufferFromData(gEmptyString)->release();
|
||||
gEmptyStringBuf = NULL;
|
||||
gEmptyString = NULL;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static char* allocFromUTF8(const char* in, size_t len)
|
||||
{
|
||||
if (len > 0) {
|
||||
SharedBuffer* buf = SharedBuffer::alloc(len+1);
|
||||
ALOG_ASSERT(buf, "Unable to allocate shared buffer");
|
||||
if (buf) {
|
||||
char* str = (char*)buf->data();
|
||||
memcpy(str, in, len);
|
||||
str[len] = 0;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return getEmptyString();
|
||||
}
|
||||
|
||||
static char* allocFromUTF16(const char16_t* in, size_t len)
|
||||
{
|
||||
if (len == 0) return getEmptyString();
|
||||
|
||||
const ssize_t bytes = utf16_to_utf8_length(in, len);
|
||||
if (bytes < 0) {
|
||||
return getEmptyString();
|
||||
}
|
||||
|
||||
SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
|
||||
ALOG_ASSERT(buf, "Unable to allocate shared buffer");
|
||||
if (!buf) {
|
||||
return getEmptyString();
|
||||
}
|
||||
|
||||
char* str = (char*)buf->data();
|
||||
utf16_to_utf8(in, len, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static char* allocFromUTF32(const char32_t* in, size_t len)
|
||||
{
|
||||
if (len == 0) {
|
||||
return getEmptyString();
|
||||
}
|
||||
|
||||
const ssize_t bytes = utf32_to_utf8_length(in, len);
|
||||
if (bytes < 0) {
|
||||
return getEmptyString();
|
||||
}
|
||||
|
||||
SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
|
||||
ALOG_ASSERT(buf, "Unable to allocate shared buffer");
|
||||
if (!buf) {
|
||||
return getEmptyString();
|
||||
}
|
||||
|
||||
char* str = (char*) buf->data();
|
||||
utf32_to_utf8(in, len, str);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
String8::String8()
|
||||
: mString(getEmptyString())
|
||||
{
|
||||
}
|
||||
|
||||
String8::String8(const String8& o)
|
||||
: mString(o.mString)
|
||||
{
|
||||
SharedBuffer::bufferFromData(mString)->acquire();
|
||||
}
|
||||
|
||||
String8::String8(const char* o)
|
||||
: mString(allocFromUTF8(o, strlen(o)))
|
||||
{
|
||||
if (mString == NULL) {
|
||||
mString = getEmptyString();
|
||||
}
|
||||
}
|
||||
|
||||
String8::String8(const char* o, size_t len)
|
||||
: mString(allocFromUTF8(o, len))
|
||||
{
|
||||
if (mString == NULL) {
|
||||
mString = getEmptyString();
|
||||
}
|
||||
}
|
||||
|
||||
String8::String8(const String16& o)
|
||||
: mString(allocFromUTF16(o.string(), o.size()))
|
||||
{
|
||||
}
|
||||
|
||||
String8::String8(const char16_t* o)
|
||||
: mString(allocFromUTF16(o, strlen16(o)))
|
||||
{
|
||||
}
|
||||
|
||||
String8::String8(const char16_t* o, size_t len)
|
||||
: mString(allocFromUTF16(o, len))
|
||||
{
|
||||
}
|
||||
|
||||
String8::String8(const char32_t* o)
|
||||
: mString(allocFromUTF32(o, strlen32(o)))
|
||||
{
|
||||
}
|
||||
|
||||
String8::String8(const char32_t* o, size_t len)
|
||||
: mString(allocFromUTF32(o, len))
|
||||
{
|
||||
}
|
||||
|
||||
String8::~String8()
|
||||
{
|
||||
SharedBuffer::bufferFromData(mString)->release();
|
||||
}
|
||||
|
||||
String8 String8::format(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
String8 result(formatV(fmt, args));
|
||||
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
String8 String8::formatV(const char* fmt, va_list args)
|
||||
{
|
||||
String8 result;
|
||||
result.appendFormatV(fmt, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
void String8::clear() {
|
||||
SharedBuffer::bufferFromData(mString)->release();
|
||||
mString = getEmptyString();
|
||||
}
|
||||
|
||||
void String8::setTo(const String8& other)
|
||||
{
|
||||
SharedBuffer::bufferFromData(other.mString)->acquire();
|
||||
SharedBuffer::bufferFromData(mString)->release();
|
||||
mString = other.mString;
|
||||
}
|
||||
|
||||
status_t String8::setTo(const char* other)
|
||||
{
|
||||
const char *newString = allocFromUTF8(other, strlen(other));
|
||||
SharedBuffer::bufferFromData(mString)->release();
|
||||
mString = newString;
|
||||
if (mString) return NO_ERROR;
|
||||
|
||||
mString = getEmptyString();
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
status_t String8::setTo(const char* other, size_t len)
|
||||
{
|
||||
const char *newString = allocFromUTF8(other, len);
|
||||
SharedBuffer::bufferFromData(mString)->release();
|
||||
mString = newString;
|
||||
if (mString) return NO_ERROR;
|
||||
|
||||
mString = getEmptyString();
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
status_t String8::setTo(const char16_t* other, size_t len)
|
||||
{
|
||||
const char *newString = allocFromUTF16(other, len);
|
||||
SharedBuffer::bufferFromData(mString)->release();
|
||||
mString = newString;
|
||||
if (mString) return NO_ERROR;
|
||||
|
||||
mString = getEmptyString();
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
status_t String8::setTo(const char32_t* other, size_t len)
|
||||
{
|
||||
const char *newString = allocFromUTF32(other, len);
|
||||
SharedBuffer::bufferFromData(mString)->release();
|
||||
mString = newString;
|
||||
if (mString) return NO_ERROR;
|
||||
|
||||
mString = getEmptyString();
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
status_t String8::append(const String8& other)
|
||||
{
|
||||
const size_t otherLen = other.bytes();
|
||||
if (bytes() == 0) {
|
||||
setTo(other);
|
||||
return NO_ERROR;
|
||||
} else if (otherLen == 0) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
return real_append(other.string(), otherLen);
|
||||
}
|
||||
|
||||
status_t String8::append(const char* other)
|
||||
{
|
||||
return append(other, strlen(other));
|
||||
}
|
||||
|
||||
status_t String8::append(const char* other, size_t otherLen)
|
||||
{
|
||||
if (bytes() == 0) {
|
||||
return setTo(other, otherLen);
|
||||
} else if (otherLen == 0) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
return real_append(other, otherLen);
|
||||
}
|
||||
|
||||
status_t String8::appendFormat(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
status_t result = appendFormatV(fmt, args);
|
||||
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t String8::appendFormatV(const char* fmt, va_list args)
|
||||
{
|
||||
int result = NO_ERROR;
|
||||
int n = vsnprintf(NULL, 0, fmt, args);
|
||||
if (n != 0) {
|
||||
size_t oldLength = length();
|
||||
char* buf = lockBuffer(oldLength + n);
|
||||
if (buf) {
|
||||
vsnprintf(buf + oldLength, n + 1, fmt, args);
|
||||
} else {
|
||||
result = NO_MEMORY;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t String8::real_append(const char* other, size_t otherLen)
|
||||
{
|
||||
const size_t myLen = bytes();
|
||||
|
||||
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
|
||||
->editResize(myLen+otherLen+1);
|
||||
if (buf) {
|
||||
char* str = (char*)buf->data();
|
||||
mString = str;
|
||||
str += myLen;
|
||||
memcpy(str, other, otherLen);
|
||||
str[otherLen] = '\0';
|
||||
return NO_ERROR;
|
||||
}
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
char* String8::lockBuffer(size_t size)
|
||||
{
|
||||
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
|
||||
->editResize(size+1);
|
||||
if (buf) {
|
||||
char* str = (char*)buf->data();
|
||||
mString = str;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void String8::unlockBuffer()
|
||||
{
|
||||
unlockBuffer(strlen(mString));
|
||||
}
|
||||
|
||||
status_t String8::unlockBuffer(size_t size)
|
||||
{
|
||||
if (size != this->size()) {
|
||||
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
|
||||
->editResize(size+1);
|
||||
if (! buf) {
|
||||
return NO_MEMORY;
|
||||
}
|
||||
|
||||
char* str = (char*)buf->data();
|
||||
str[size] = 0;
|
||||
mString = str;
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
ssize_t String8::find(const char* other, size_t start) const
|
||||
{
|
||||
size_t len = size();
|
||||
if (start >= len) {
|
||||
return -1;
|
||||
}
|
||||
const char* s = mString+start;
|
||||
const char* p = strstr(s, other);
|
||||
return p ? p-mString : -1;
|
||||
}
|
||||
|
||||
void String8::toLower()
|
||||
{
|
||||
toLower(0, size());
|
||||
}
|
||||
|
||||
void String8::toLower(size_t start, size_t length)
|
||||
{
|
||||
const size_t len = size();
|
||||
if (start >= len) {
|
||||
return;
|
||||
}
|
||||
if (start+length > len) {
|
||||
length = len-start;
|
||||
}
|
||||
char* buf = lockBuffer(len);
|
||||
buf += start;
|
||||
while (length > 0) {
|
||||
*buf = tolower(*buf);
|
||||
buf++;
|
||||
length--;
|
||||
}
|
||||
unlockBuffer(len);
|
||||
}
|
||||
|
||||
void String8::toUpper()
|
||||
{
|
||||
toUpper(0, size());
|
||||
}
|
||||
|
||||
void String8::toUpper(size_t start, size_t length)
|
||||
{
|
||||
const size_t len = size();
|
||||
if (start >= len) {
|
||||
return;
|
||||
}
|
||||
if (start+length > len) {
|
||||
length = len-start;
|
||||
}
|
||||
char* buf = lockBuffer(len);
|
||||
buf += start;
|
||||
while (length > 0) {
|
||||
*buf = toupper(*buf);
|
||||
buf++;
|
||||
length--;
|
||||
}
|
||||
unlockBuffer(len);
|
||||
}
|
||||
|
||||
size_t String8::getUtf32Length() const
|
||||
{
|
||||
return utf8_to_utf32_length(mString, length());
|
||||
}
|
||||
|
||||
int32_t String8::getUtf32At(size_t index, size_t *next_index) const
|
||||
{
|
||||
return utf32_from_utf8_at(mString, length(), index, next_index);
|
||||
}
|
||||
|
||||
void String8::getUtf32(char32_t* dst) const
|
||||
{
|
||||
utf8_to_utf32(mString, length(), dst);
|
||||
}
|
||||
|
||||
TextOutput& operator<<(TextOutput& to, const String8& val)
|
||||
{
|
||||
to << val.string();
|
||||
return to;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Path functions
|
||||
|
||||
void String8::setPathName(const char* name)
|
||||
{
|
||||
setPathName(name, strlen(name));
|
||||
}
|
||||
|
||||
void String8::setPathName(const char* name, size_t len)
|
||||
{
|
||||
char* buf = lockBuffer(len);
|
||||
|
||||
memcpy(buf, name, len);
|
||||
|
||||
// remove trailing path separator, if present
|
||||
if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
|
||||
len--;
|
||||
|
||||
buf[len] = '\0';
|
||||
|
||||
unlockBuffer(len);
|
||||
}
|
||||
|
||||
String8 String8::getPathLeaf(void) const
|
||||
{
|
||||
const char* cp;
|
||||
const char*const buf = mString;
|
||||
|
||||
cp = strrchr(buf, OS_PATH_SEPARATOR);
|
||||
if (cp == NULL)
|
||||
return String8(*this);
|
||||
else
|
||||
return String8(cp+1);
|
||||
}
|
||||
|
||||
String8 String8::getPathDir(void) const
|
||||
{
|
||||
const char* cp;
|
||||
const char*const str = mString;
|
||||
|
||||
cp = strrchr(str, OS_PATH_SEPARATOR);
|
||||
if (cp == NULL)
|
||||
return String8("");
|
||||
else
|
||||
return String8(str, cp - str);
|
||||
}
|
||||
|
||||
String8 String8::walkPath(String8* outRemains) const
|
||||
{
|
||||
const char* cp;
|
||||
const char*const str = mString;
|
||||
const char* buf = str;
|
||||
|
||||
cp = strchr(buf, OS_PATH_SEPARATOR);
|
||||
if (cp == buf) {
|
||||
// don't include a leading '/'.
|
||||
buf = buf+1;
|
||||
cp = strchr(buf, OS_PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
if (cp == NULL) {
|
||||
String8 res = buf != str ? String8(buf) : *this;
|
||||
if (outRemains) *outRemains = String8("");
|
||||
return res;
|
||||
}
|
||||
|
||||
String8 res(buf, cp-buf);
|
||||
if (outRemains) *outRemains = String8(cp+1);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function for finding the start of an extension in a pathname.
|
||||
*
|
||||
* Returns a pointer inside mString, or NULL if no extension was found.
|
||||
*/
|
||||
char* String8::find_extension(void) const
|
||||
{
|
||||
const char* lastSlash;
|
||||
const char* lastDot;
|
||||
int extLen;
|
||||
const char* const str = mString;
|
||||
|
||||
// only look at the filename
|
||||
lastSlash = strrchr(str, OS_PATH_SEPARATOR);
|
||||
if (lastSlash == NULL)
|
||||
lastSlash = str;
|
||||
else
|
||||
lastSlash++;
|
||||
|
||||
// find the last dot
|
||||
lastDot = strrchr(lastSlash, '.');
|
||||
if (lastDot == NULL)
|
||||
return NULL;
|
||||
|
||||
// looks good, ship it
|
||||
return const_cast<char*>(lastDot);
|
||||
}
|
||||
|
||||
String8 String8::getPathExtension(void) const
|
||||
{
|
||||
char* ext;
|
||||
|
||||
ext = find_extension();
|
||||
if (ext != NULL)
|
||||
return String8(ext);
|
||||
else
|
||||
return String8("");
|
||||
}
|
||||
|
||||
String8 String8::getBasePath(void) const
|
||||
{
|
||||
char* ext;
|
||||
const char* const str = mString;
|
||||
|
||||
ext = find_extension();
|
||||
if (ext == NULL)
|
||||
return String8(*this);
|
||||
else
|
||||
return String8(str, ext - str);
|
||||
}
|
||||
|
||||
String8& String8::appendPath(const char* name)
|
||||
{
|
||||
// TODO: The test below will fail for Win32 paths. Fix later or ignore.
|
||||
if (name[0] != OS_PATH_SEPARATOR) {
|
||||
if (*name == '\0') {
|
||||
// nothing to do
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t len = length();
|
||||
if (len == 0) {
|
||||
// no existing filename, just use the new one
|
||||
setPathName(name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// make room for oldPath + '/' + newPath
|
||||
int newlen = strlen(name);
|
||||
|
||||
char* buf = lockBuffer(len+1+newlen);
|
||||
|
||||
// insert a '/' if needed
|
||||
if (buf[len-1] != OS_PATH_SEPARATOR)
|
||||
buf[len++] = OS_PATH_SEPARATOR;
|
||||
|
||||
memcpy(buf+len, name, newlen+1);
|
||||
len += newlen;
|
||||
|
||||
unlockBuffer(len);
|
||||
|
||||
return *this;
|
||||
} else {
|
||||
setPathName(name);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
String8& String8::convertToResPath()
|
||||
{
|
||||
#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
|
||||
size_t len = length();
|
||||
if (len > 0) {
|
||||
char * buf = lockBuffer(len);
|
||||
for (char * end = buf + len; buf < end; ++buf) {
|
||||
if (*buf == OS_PATH_SEPARATOR)
|
||||
*buf = RES_PATH_SEPARATOR;
|
||||
}
|
||||
unlockBuffer(len);
|
||||
}
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
}; // namespace android
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_STRING8_H
|
||||
#define ANDROID_STRING8_H
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/SharedBuffer.h>
|
||||
#include "Unicode.h"
|
||||
|
||||
#include <string.h> // for strcmp
|
||||
#include <stdarg.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
class String16;
|
||||
class TextOutput;
|
||||
|
||||
//! This is a string holding UTF-8 characters. Does not allow the value more
|
||||
// than 0x10FFFF, which is not valid unicode codepoint.
|
||||
class String8
|
||||
{
|
||||
public:
|
||||
String8();
|
||||
String8(const String8& o);
|
||||
explicit String8(const char* o);
|
||||
explicit String8(const char* o, size_t numChars);
|
||||
|
||||
explicit String8(const String16& o);
|
||||
explicit String8(const char16_t* o);
|
||||
explicit String8(const char16_t* o, size_t numChars);
|
||||
explicit String8(const char32_t* o);
|
||||
explicit String8(const char32_t* o, size_t numChars);
|
||||
~String8();
|
||||
|
||||
static inline const String8 empty();
|
||||
|
||||
static String8 format(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
static String8 formatV(const char* fmt, va_list args);
|
||||
|
||||
inline const char* string() const;
|
||||
inline size_t size() const;
|
||||
inline size_t length() const;
|
||||
inline size_t bytes() const;
|
||||
inline bool isEmpty() const;
|
||||
|
||||
inline const SharedBuffer* sharedBuffer() const;
|
||||
|
||||
void clear();
|
||||
|
||||
void setTo(const String8& other);
|
||||
status_t setTo(const char* other);
|
||||
status_t setTo(const char* other, size_t numChars);
|
||||
status_t setTo(const char16_t* other, size_t numChars);
|
||||
status_t setTo(const char32_t* other,
|
||||
size_t length);
|
||||
|
||||
status_t append(const String8& other);
|
||||
status_t append(const char* other);
|
||||
status_t append(const char* other, size_t numChars);
|
||||
|
||||
status_t appendFormat(const char* fmt, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
status_t appendFormatV(const char* fmt, va_list args);
|
||||
|
||||
// Note that this function takes O(N) time to calculate the value.
|
||||
// No cache value is stored.
|
||||
size_t getUtf32Length() const;
|
||||
int32_t getUtf32At(size_t index,
|
||||
size_t *next_index) const;
|
||||
void getUtf32(char32_t* dst) const;
|
||||
|
||||
inline String8& operator=(const String8& other);
|
||||
inline String8& operator=(const char* other);
|
||||
|
||||
inline String8& operator+=(const String8& other);
|
||||
inline String8 operator+(const String8& other) const;
|
||||
|
||||
inline String8& operator+=(const char* other);
|
||||
inline String8 operator+(const char* other) const;
|
||||
|
||||
inline int compare(const String8& other) const;
|
||||
|
||||
inline bool operator<(const String8& other) const;
|
||||
inline bool operator<=(const String8& other) const;
|
||||
inline bool operator==(const String8& other) const;
|
||||
inline bool operator!=(const String8& other) const;
|
||||
inline bool operator>=(const String8& other) const;
|
||||
inline bool operator>(const String8& other) const;
|
||||
|
||||
inline bool operator<(const char* other) const;
|
||||
inline bool operator<=(const char* other) const;
|
||||
inline bool operator==(const char* other) const;
|
||||
inline bool operator!=(const char* other) const;
|
||||
inline bool operator>=(const char* other) const;
|
||||
inline bool operator>(const char* other) const;
|
||||
|
||||
inline operator const char*() const;
|
||||
|
||||
char* lockBuffer(size_t size);
|
||||
void unlockBuffer();
|
||||
status_t unlockBuffer(size_t size);
|
||||
|
||||
// return the index of the first byte of other in this at or after
|
||||
// start, or -1 if not found
|
||||
ssize_t find(const char* other, size_t start = 0) const;
|
||||
|
||||
void toLower();
|
||||
void toLower(size_t start, size_t numChars);
|
||||
void toUpper();
|
||||
void toUpper(size_t start, size_t numChars);
|
||||
|
||||
/*
|
||||
* These methods operate on the string as if it were a path name.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set the filename field to a specific value.
|
||||
*
|
||||
* Normalizes the filename, removing a trailing '/' if present.
|
||||
*/
|
||||
void setPathName(const char* name);
|
||||
void setPathName(const char* name, size_t numChars);
|
||||
|
||||
/*
|
||||
* Get just the filename component.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "bar.c"
|
||||
*/
|
||||
String8 getPathLeaf(void) const;
|
||||
|
||||
/*
|
||||
* Remove the last (file name) component, leaving just the directory
|
||||
* name.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "/tmp/foo"
|
||||
* "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
|
||||
* "bar.c" --> ""
|
||||
*/
|
||||
String8 getPathDir(void) const;
|
||||
|
||||
/*
|
||||
* Retrieve the front (root dir) component. Optionally also return the
|
||||
* remaining components.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c")
|
||||
* "/tmp" --> "tmp" (remain = "")
|
||||
* "bar.c" --> "bar.c" (remain = "")
|
||||
*/
|
||||
String8 walkPath(String8* outRemains = NULL) const;
|
||||
|
||||
/*
|
||||
* Return the filename extension. This is the last '.' and any number
|
||||
* of characters that follow it. The '.' is included in case we
|
||||
* decide to expand our definition of what constitutes an extension.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> ".c"
|
||||
* "/tmp" --> ""
|
||||
* "/tmp/foo.bar/baz" --> ""
|
||||
* "foo.jpeg" --> ".jpeg"
|
||||
* "foo." --> ""
|
||||
*/
|
||||
String8 getPathExtension(void) const;
|
||||
|
||||
/*
|
||||
* Return the path without the extension. Rules for what constitutes
|
||||
* an extension are described in the comment for getPathExtension().
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "/tmp/foo/bar"
|
||||
*/
|
||||
String8 getBasePath(void) const;
|
||||
|
||||
/*
|
||||
* Add a component to the pathname. We guarantee that there is
|
||||
* exactly one path separator between the old path and the new.
|
||||
* If there is no existing name, we just copy the new name in.
|
||||
*
|
||||
* If leaf is a fully qualified path (i.e. starts with '/', it
|
||||
* replaces whatever was there before.
|
||||
*/
|
||||
String8& appendPath(const char* leaf);
|
||||
String8& appendPath(const String8& leaf) { return appendPath(leaf.string()); }
|
||||
|
||||
/*
|
||||
* Like appendPath(), but does not affect this string. Returns a new one instead.
|
||||
*/
|
||||
String8 appendPathCopy(const char* leaf) const
|
||||
{ String8 p(*this); p.appendPath(leaf); return p; }
|
||||
String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); }
|
||||
|
||||
/*
|
||||
* Converts all separators in this string to /, the default path separator.
|
||||
*
|
||||
* If the default OS separator is backslash, this converts all
|
||||
* backslashes to slashes, in-place. Otherwise it does nothing.
|
||||
* Returns self.
|
||||
*/
|
||||
String8& convertToResPath();
|
||||
|
||||
private:
|
||||
status_t real_append(const char* other, size_t numChars);
|
||||
char* find_extension(void) const;
|
||||
|
||||
const char* mString;
|
||||
};
|
||||
|
||||
TextOutput& operator<<(TextOutput& to, const String16& val);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user servicable parts below.
|
||||
|
||||
inline int compare_type(const String8& lhs, const String8& rhs)
|
||||
{
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
inline int strictly_order_type(const String8& lhs, const String8& rhs)
|
||||
{
|
||||
return compare_type(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
inline const String8 String8::empty() {
|
||||
return String8();
|
||||
}
|
||||
|
||||
inline const char* String8::string() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
inline size_t String8::length() const
|
||||
{
|
||||
return SharedBuffer::sizeFromData(mString)-1;
|
||||
}
|
||||
|
||||
inline size_t String8::size() const
|
||||
{
|
||||
return length();
|
||||
}
|
||||
|
||||
inline bool String8::isEmpty() const
|
||||
{
|
||||
return length() == 0;
|
||||
}
|
||||
|
||||
inline size_t String8::bytes() const
|
||||
{
|
||||
return SharedBuffer::sizeFromData(mString)-1;
|
||||
}
|
||||
|
||||
inline const SharedBuffer* String8::sharedBuffer() const
|
||||
{
|
||||
return SharedBuffer::bufferFromData(mString);
|
||||
}
|
||||
|
||||
inline String8& String8::operator=(const String8& other)
|
||||
{
|
||||
setTo(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8& String8::operator=(const char* other)
|
||||
{
|
||||
setTo(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8& String8::operator+=(const String8& other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8 String8::operator+(const String8& other) const
|
||||
{
|
||||
String8 tmp(*this);
|
||||
tmp += other;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline String8& String8::operator+=(const char* other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8 String8::operator+(const char* other) const
|
||||
{
|
||||
String8 tmp(*this);
|
||||
tmp += other;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline int String8::compare(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString);
|
||||
}
|
||||
|
||||
inline bool String8::operator<(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) < 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator<=(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) <= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator==(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) == 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator!=(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) != 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>=(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) >= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) > 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator<(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) < 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator<=(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) <= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator==(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) == 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator!=(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) != 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>=(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) >= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) > 0;
|
||||
}
|
||||
|
||||
inline String8::operator const char*() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_STRING8_H
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// Timer functions.
|
||||
//
|
||||
#include "utils_Log.h"
|
||||
#include "Timers.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_WIN32_THREADS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
nsecs_t systemTime(int clock)
|
||||
{
|
||||
#if defined(HAVE_POSIX_CLOCKS)
|
||||
static const clockid_t clocks[] = {
|
||||
CLOCK_REALTIME,
|
||||
CLOCK_MONOTONIC,
|
||||
CLOCK_PROCESS_CPUTIME_ID,
|
||||
CLOCK_THREAD_CPUTIME_ID
|
||||
};
|
||||
struct timespec t;
|
||||
t.tv_sec = t.tv_nsec = 0;
|
||||
clock_gettime(clocks[clock], &t);
|
||||
return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
|
||||
#else
|
||||
// we don't support the clocks here.
|
||||
struct timeval t;
|
||||
t.tv_sec = t.tv_usec = 0;
|
||||
gettimeofday(&t, NULL);
|
||||
return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)
|
||||
{
|
||||
int timeoutDelayMillis;
|
||||
if (timeoutTime > referenceTime) {
|
||||
uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime);
|
||||
if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) {
|
||||
timeoutDelayMillis = -1;
|
||||
} else {
|
||||
timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL;
|
||||
}
|
||||
} else {
|
||||
timeoutDelayMillis = 0;
|
||||
}
|
||||
return timeoutDelayMillis;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
* DurationTimer
|
||||
* ===========================================================================
|
||||
*/
|
||||
|
||||
using namespace android;
|
||||
|
||||
// Start the timer.
|
||||
void DurationTimer::start(void)
|
||||
{
|
||||
gettimeofday(&mStartWhen, NULL);
|
||||
}
|
||||
|
||||
// Stop the timer.
|
||||
void DurationTimer::stop(void)
|
||||
{
|
||||
gettimeofday(&mStopWhen, NULL);
|
||||
}
|
||||
|
||||
// Get the duration in microseconds.
|
||||
long long DurationTimer::durationUsecs(void) const
|
||||
{
|
||||
return (long) subtractTimevals(&mStopWhen, &mStartWhen);
|
||||
}
|
||||
|
||||
// Subtract two timevals. Returns the difference (ptv1-ptv2) in
|
||||
// microseconds.
|
||||
/*static*/ long long DurationTimer::subtractTimevals(const struct timeval* ptv1,
|
||||
const struct timeval* ptv2)
|
||||
{
|
||||
long long stop = ((long long) ptv1->tv_sec) * 1000000LL +
|
||||
((long long) ptv1->tv_usec);
|
||||
long long start = ((long long) ptv2->tv_sec) * 1000000LL +
|
||||
((long long) ptv2->tv_usec);
|
||||
return stop - start;
|
||||
}
|
||||
|
||||
// Add the specified amount of time to the timeval.
|
||||
/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec)
|
||||
{
|
||||
if (usec < 0) {
|
||||
ALOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// normalize tv_usec if necessary
|
||||
if (ptv->tv_usec >= 1000000) {
|
||||
ptv->tv_sec += ptv->tv_usec / 1000000;
|
||||
ptv->tv_usec %= 1000000;
|
||||
}
|
||||
|
||||
ptv->tv_usec += usec % 1000000;
|
||||
if (ptv->tv_usec >= 1000000) {
|
||||
ptv->tv_usec -= 1000000;
|
||||
ptv->tv_sec++;
|
||||
}
|
||||
ptv->tv_sec += usec / 1000000;
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// Timer functions.
|
||||
//
|
||||
#ifndef _LIBS_UTILS_TIMERS_H
|
||||
#define _LIBS_UTILS_TIMERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// C API
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int64_t nsecs_t; // nano-seconds
|
||||
|
||||
static inline nsecs_t seconds_to_nanoseconds(nsecs_t secs)
|
||||
{
|
||||
return secs*1000000000;
|
||||
}
|
||||
|
||||
static inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs)
|
||||
{
|
||||
return secs*1000000;
|
||||
}
|
||||
|
||||
static inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs)
|
||||
{
|
||||
return secs*1000;
|
||||
}
|
||||
|
||||
static inline nsecs_t nanoseconds_to_seconds(nsecs_t secs)
|
||||
{
|
||||
return secs/1000000000;
|
||||
}
|
||||
|
||||
static inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs)
|
||||
{
|
||||
return secs/1000000;
|
||||
}
|
||||
|
||||
static inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs)
|
||||
{
|
||||
return secs/1000;
|
||||
}
|
||||
|
||||
static inline nsecs_t s2ns(nsecs_t v) {return seconds_to_nanoseconds(v);}
|
||||
static inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);}
|
||||
static inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);}
|
||||
static inline nsecs_t ns2s(nsecs_t v) {return nanoseconds_to_seconds(v);}
|
||||
static inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);}
|
||||
static inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);}
|
||||
|
||||
static inline nsecs_t seconds(nsecs_t v) { return s2ns(v); }
|
||||
static inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); }
|
||||
static inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }
|
||||
|
||||
enum {
|
||||
SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock
|
||||
SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
|
||||
SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock
|
||||
SYSTEM_TIME_THREAD = 3 // high-resolution per-thread clock
|
||||
};
|
||||
|
||||
// return the system-time according to the specified clock
|
||||
#ifdef __cplusplus
|
||||
nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
|
||||
#else
|
||||
nsecs_t systemTime(int clock);
|
||||
#endif // def __cplusplus
|
||||
|
||||
/**
|
||||
* Returns the number of milliseconds to wait between the reference time and the timeout time.
|
||||
* If the timeout is in the past relative to the reference time, returns 0.
|
||||
* If the timeout is more than INT_MAX milliseconds in the future relative to the reference time,
|
||||
* such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay.
|
||||
* Otherwise, returns the difference between the reference time and timeout time
|
||||
* rounded up to the next millisecond.
|
||||
*/
|
||||
int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// C++ API
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace android {
|
||||
/*
|
||||
* Time the duration of something.
|
||||
*
|
||||
* Includes some timeval manipulation functions.
|
||||
*/
|
||||
class DurationTimer {
|
||||
public:
|
||||
DurationTimer() {}
|
||||
~DurationTimer() {}
|
||||
|
||||
// Start the timer.
|
||||
void start();
|
||||
// Stop the timer.
|
||||
void stop();
|
||||
// Get the duration in microseconds.
|
||||
long long durationUsecs() const;
|
||||
|
||||
// Subtract two timevals. Returns the difference (ptv1-ptv2) in
|
||||
// microseconds.
|
||||
static long long subtractTimevals(const struct timeval* ptv1,
|
||||
const struct timeval* ptv2);
|
||||
|
||||
// Add the specified amount of time to the timeval.
|
||||
static void addToTimeval(struct timeval* ptv, long usec);
|
||||
|
||||
private:
|
||||
struct timeval mStartWhen;
|
||||
struct timeval mStopWhen;
|
||||
};
|
||||
|
||||
}; // android
|
||||
#endif // def __cplusplus
|
||||
|
||||
#endif // _LIBS_UTILS_TIMERS_H
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Tokenizer"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "utils_Log.h"
|
||||
#include "Tokenizer.h"
|
||||
|
||||
// Enables debug output for the tokenizer.
|
||||
#define DEBUG_TOKENIZER 0
|
||||
|
||||
|
||||
namespace android {
|
||||
|
||||
static inline bool isDelimiter(char ch, const char* delimiters) {
|
||||
return strchr(delimiters, ch) != NULL;
|
||||
}
|
||||
|
||||
Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length) :
|
||||
mFilename(filename), mFileMap(fileMap),
|
||||
mBuffer(buffer), mLength(length), mCurrent(buffer), mLineNumber(1) {
|
||||
}
|
||||
|
||||
Tokenizer::~Tokenizer() {
|
||||
if (mFileMap) {
|
||||
mFileMap->release();
|
||||
} else {
|
||||
delete[] mBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
status_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) {
|
||||
*outTokenizer = NULL;
|
||||
|
||||
int result = NO_ERROR;
|
||||
int fd = ::open(filename.string(), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
result = -errno;
|
||||
ALOGE("Error opening file '%s', %s.", filename.string(), strerror(errno));
|
||||
} else {
|
||||
struct stat stat;
|
||||
if (fstat(fd, &stat)) {
|
||||
result = -errno;
|
||||
ALOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno));
|
||||
} else {
|
||||
size_t length = size_t(stat.st_size);
|
||||
|
||||
FileMap* fileMap = new FileMap();
|
||||
char* buffer;
|
||||
if (fileMap->create(NULL, fd, 0, length, true)) {
|
||||
fileMap->advise(FileMap::SEQUENTIAL);
|
||||
buffer = static_cast<char*>(fileMap->getDataPtr());
|
||||
} else {
|
||||
fileMap->release();
|
||||
fileMap = NULL;
|
||||
|
||||
// Fall back to reading into a buffer since we can't mmap files in sysfs.
|
||||
// The length we obtained from stat is wrong too (it will always be 4096)
|
||||
// so we must trust that read will read the entire file.
|
||||
buffer = new char[length];
|
||||
ssize_t nrd = read(fd, buffer, length);
|
||||
if (nrd < 0) {
|
||||
result = -errno;
|
||||
ALOGE("Error reading file '%s', %s.", filename.string(), strerror(errno));
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
} else {
|
||||
length = size_t(nrd);
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
*outTokenizer = new Tokenizer(filename, fileMap, buffer, length);
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String8 Tokenizer::getLocation() const {
|
||||
String8 result;
|
||||
result.appendFormat("%s:%d", mFilename.string(), mLineNumber);
|
||||
return result;
|
||||
}
|
||||
|
||||
String8 Tokenizer::peekRemainderOfLine() const {
|
||||
const char* end = getEnd();
|
||||
const char* eol = mCurrent;
|
||||
while (eol != end) {
|
||||
char ch = *eol;
|
||||
if (ch == '\n') {
|
||||
break;
|
||||
}
|
||||
eol += 1;
|
||||
}
|
||||
return String8(mCurrent, eol - mCurrent);
|
||||
}
|
||||
|
||||
String8 Tokenizer::nextToken(const char* delimiters) {
|
||||
#if DEBUG_TOKENIZER
|
||||
ALOGD("nextToken");
|
||||
#endif
|
||||
const char* end = getEnd();
|
||||
const char* tokenStart = mCurrent;
|
||||
while (mCurrent != end) {
|
||||
char ch = *mCurrent;
|
||||
if (ch == '\n' || isDelimiter(ch, delimiters)) {
|
||||
break;
|
||||
}
|
||||
mCurrent += 1;
|
||||
}
|
||||
return String8(tokenStart, mCurrent - tokenStart);
|
||||
}
|
||||
|
||||
void Tokenizer::nextLine() {
|
||||
#if DEBUG_TOKENIZER
|
||||
ALOGD("nextLine");
|
||||
#endif
|
||||
const char* end = getEnd();
|
||||
while (mCurrent != end) {
|
||||
char ch = *(mCurrent++);
|
||||
if (ch == '\n') {
|
||||
mLineNumber += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tokenizer::skipDelimiters(const char* delimiters) {
|
||||
#if DEBUG_TOKENIZER
|
||||
ALOGD("skipDelimiters");
|
||||
#endif
|
||||
const char* end = getEnd();
|
||||
while (mCurrent != end) {
|
||||
char ch = *mCurrent;
|
||||
if (ch == '\n' || !isDelimiter(ch, delimiters)) {
|
||||
break;
|
||||
}
|
||||
mCurrent += 1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_TOKENIZER_H
|
||||
#define _UTILS_TOKENIZER_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/FileMap.h>
|
||||
#include "String8.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
/**
|
||||
* A simple tokenizer for loading and parsing ASCII text files line by line.
|
||||
*/
|
||||
class Tokenizer {
|
||||
Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length);
|
||||
|
||||
public:
|
||||
~Tokenizer();
|
||||
|
||||
/**
|
||||
* Opens a file and maps it into memory.
|
||||
*
|
||||
* Returns NO_ERROR and a tokenizer for the file, if successful.
|
||||
* Otherwise returns an error and sets outTokenizer to NULL.
|
||||
*/
|
||||
static status_t open(const String8& filename, Tokenizer** outTokenizer);
|
||||
|
||||
/**
|
||||
* Returns true if at the end of the file.
|
||||
*/
|
||||
inline bool isEof() const { return mCurrent == getEnd(); }
|
||||
|
||||
/**
|
||||
* Returns true if at the end of the line or end of the file.
|
||||
*/
|
||||
inline bool isEol() const { return isEof() || *mCurrent == '\n'; }
|
||||
|
||||
/**
|
||||
* Gets the name of the file.
|
||||
*/
|
||||
inline String8 getFilename() const { return mFilename; }
|
||||
|
||||
/**
|
||||
* Gets a 1-based line number index for the current position.
|
||||
*/
|
||||
inline int32_t getLineNumber() const { return mLineNumber; }
|
||||
|
||||
/**
|
||||
* Formats a location string consisting of the filename and current line number.
|
||||
* Returns a string like "MyFile.txt:33".
|
||||
*/
|
||||
String8 getLocation() const;
|
||||
|
||||
/**
|
||||
* Gets the character at the current position.
|
||||
* Returns null at end of file.
|
||||
*/
|
||||
inline char peekChar() const { return isEof() ? '\0' : *mCurrent; }
|
||||
|
||||
/**
|
||||
* Gets the remainder of the current line as a string, excluding the newline character.
|
||||
*/
|
||||
String8 peekRemainderOfLine() const;
|
||||
|
||||
/**
|
||||
* Gets the character at the current position and advances past it.
|
||||
* Returns null at end of file.
|
||||
*/
|
||||
inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); }
|
||||
|
||||
/**
|
||||
* Gets the next token on this line stopping at the specified delimiters
|
||||
* or the end of the line whichever comes first and advances past it.
|
||||
* Also stops at embedded nulls.
|
||||
* Returns the token or an empty string if the current character is a delimiter
|
||||
* or is at the end of the line.
|
||||
*/
|
||||
String8 nextToken(const char* delimiters);
|
||||
|
||||
/**
|
||||
* Advances to the next line.
|
||||
* Does nothing if already at the end of the file.
|
||||
*/
|
||||
void nextLine();
|
||||
|
||||
/**
|
||||
* Skips over the specified delimiters in the line.
|
||||
* Also skips embedded nulls.
|
||||
*/
|
||||
void skipDelimiters(const char* delimiters);
|
||||
|
||||
private:
|
||||
Tokenizer(const Tokenizer& other); // not copyable
|
||||
|
||||
String8 mFilename;
|
||||
FileMap* mFileMap;
|
||||
char* mBuffer;
|
||||
size_t mLength;
|
||||
|
||||
const char* mCurrent;
|
||||
int32_t mLineNumber;
|
||||
|
||||
inline const char* getEnd() const { return mBuffer + mLength; }
|
||||
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UTILS_TOKENIZER_H
|
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
#include "Unicode.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_WINSOCK
|
||||
# undef nhtol
|
||||
# undef htonl
|
||||
# undef nhtos
|
||||
# undef htons
|
||||
|
||||
# ifdef HAVE_LITTLE_ENDIAN
|
||||
# define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
|
||||
# define htonl(x) ntohl(x)
|
||||
# define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
|
||||
# define htons(x) ntohs(x)
|
||||
# else
|
||||
# define ntohl(x) (x)
|
||||
# define htonl(x) (x)
|
||||
# define ntohs(x) (x)
|
||||
# define htons(x) (x)
|
||||
# endif
|
||||
#else
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
static const char32_t kByteMask = 0x000000BF;
|
||||
static const char32_t kByteMark = 0x00000080;
|
||||
|
||||
// Surrogates aren't valid for UTF-32 characters, so define some
|
||||
// constants that will let us screen them out.
|
||||
static const char32_t kUnicodeSurrogateHighStart = 0x0000D800;
|
||||
static const char32_t kUnicodeSurrogateHighEnd = 0x0000DBFF;
|
||||
static const char32_t kUnicodeSurrogateLowStart = 0x0000DC00;
|
||||
static const char32_t kUnicodeSurrogateLowEnd = 0x0000DFFF;
|
||||
static const char32_t kUnicodeSurrogateStart = kUnicodeSurrogateHighStart;
|
||||
static const char32_t kUnicodeSurrogateEnd = kUnicodeSurrogateLowEnd;
|
||||
static const char32_t kUnicodeMaxCodepoint = 0x0010FFFF;
|
||||
|
||||
// Mask used to set appropriate bits in first byte of UTF-8 sequence,
|
||||
// indexed by number of bytes in the sequence.
|
||||
// 0xxxxxxx
|
||||
// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000
|
||||
// 110yyyyx 10xxxxxx
|
||||
// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0
|
||||
// 1110yyyy 10yxxxxx 10xxxxxx
|
||||
// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0
|
||||
// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
|
||||
// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0
|
||||
static const char32_t kFirstByteMark[] = {
|
||||
0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// UTF-32
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return number of UTF-8 bytes required for the character. If the character
|
||||
* is invalid, return size of 0.
|
||||
*/
|
||||
static inline size_t utf32_codepoint_utf8_length(char32_t srcChar)
|
||||
{
|
||||
// Figure out how many bytes the result will require.
|
||||
if (srcChar < 0x00000080) {
|
||||
return 1;
|
||||
} else if (srcChar < 0x00000800) {
|
||||
return 2;
|
||||
} else if (srcChar < 0x00010000) {
|
||||
if ((srcChar < kUnicodeSurrogateStart) || (srcChar > kUnicodeSurrogateEnd)) {
|
||||
return 3;
|
||||
} else {
|
||||
// Surrogates are invalid UTF-32 characters.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Max code point for Unicode is 0x0010FFFF.
|
||||
else if (srcChar <= kUnicodeMaxCodepoint) {
|
||||
return 4;
|
||||
} else {
|
||||
// Invalid UTF-32 character.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the source character to <dstP>.
|
||||
|
||||
static inline void utf32_codepoint_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes)
|
||||
{
|
||||
dstP += bytes;
|
||||
switch (bytes)
|
||||
{ /* note: everything falls through. */
|
||||
case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
|
||||
case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
|
||||
case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
|
||||
case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
|
||||
}
|
||||
}
|
||||
|
||||
size_t strlen32(const char32_t *s)
|
||||
{
|
||||
const char32_t *ss = s;
|
||||
while ( *ss )
|
||||
ss++;
|
||||
return ss-s;
|
||||
}
|
||||
|
||||
size_t strnlen32(const char32_t *s, size_t maxlen)
|
||||
{
|
||||
const char32_t *ss = s;
|
||||
while ((maxlen > 0) && *ss) {
|
||||
ss++;
|
||||
maxlen--;
|
||||
}
|
||||
return ss-s;
|
||||
}
|
||||
|
||||
static inline int32_t utf32_at_internal(const char* cur, size_t *num_read)
|
||||
{
|
||||
const char first_char = *cur;
|
||||
if ((first_char & 0x80) == 0) { // ASCII
|
||||
*num_read = 1;
|
||||
return *cur;
|
||||
}
|
||||
cur++;
|
||||
char32_t mask, to_ignore_mask;
|
||||
size_t num_to_read = 0;
|
||||
char32_t utf32 = first_char;
|
||||
for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80;
|
||||
(first_char & mask);
|
||||
num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
|
||||
// 0x3F == 00111111
|
||||
utf32 = (utf32 << 6) + (*cur++ & 0x3F);
|
||||
}
|
||||
to_ignore_mask |= mask;
|
||||
utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1)));
|
||||
|
||||
*num_read = num_to_read;
|
||||
return static_cast<int32_t>(utf32);
|
||||
}
|
||||
|
||||
int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index)
|
||||
{
|
||||
if (index >= src_len) {
|
||||
return -1;
|
||||
}
|
||||
size_t dummy_index;
|
||||
if (next_index == NULL) {
|
||||
next_index = &dummy_index;
|
||||
}
|
||||
size_t num_read;
|
||||
int32_t ret = utf32_at_internal(src + index, &num_read);
|
||||
if (ret >= 0) {
|
||||
*next_index = index + num_read;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len)
|
||||
{
|
||||
if (src == NULL || src_len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t ret = 0;
|
||||
const char32_t *end = src + src_len;
|
||||
while (src < end) {
|
||||
ret += utf32_codepoint_utf8_length(*src++);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst)
|
||||
{
|
||||
if (src == NULL || src_len == 0 || dst == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char32_t *cur_utf32 = src;
|
||||
const char32_t *end_utf32 = src + src_len;
|
||||
char *cur = dst;
|
||||
while (cur_utf32 < end_utf32) {
|
||||
size_t len = utf32_codepoint_utf8_length(*cur_utf32);
|
||||
utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len);
|
||||
cur += len;
|
||||
}
|
||||
*cur = '\0';
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// UTF-16
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
int strcmp16(const char16_t *s1, const char16_t *s2)
|
||||
{
|
||||
char16_t ch;
|
||||
int d = 0;
|
||||
|
||||
while ( 1 ) {
|
||||
d = (int)(ch = *s1++) - (int)*s2++;
|
||||
if ( d || !ch )
|
||||
break;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
|
||||
{
|
||||
char16_t ch;
|
||||
int d = 0;
|
||||
|
||||
while ( n-- ) {
|
||||
d = (int)(ch = *s1++) - (int)*s2++;
|
||||
if ( d || !ch )
|
||||
break;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
char16_t *strcpy16(char16_t *dst, const char16_t *src)
|
||||
{
|
||||
char16_t *q = dst;
|
||||
const char16_t *p = src;
|
||||
char16_t ch;
|
||||
|
||||
do {
|
||||
*q++ = ch = *p++;
|
||||
} while ( ch );
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
size_t strlen16(const char16_t *s)
|
||||
{
|
||||
const char16_t *ss = s;
|
||||
while ( *ss )
|
||||
ss++;
|
||||
return ss-s;
|
||||
}
|
||||
|
||||
|
||||
char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
|
||||
{
|
||||
char16_t *q = dst;
|
||||
const char16_t *p = src;
|
||||
char ch;
|
||||
|
||||
while (n) {
|
||||
n--;
|
||||
*q++ = ch = *p++;
|
||||
if ( !ch )
|
||||
break;
|
||||
}
|
||||
|
||||
*q = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
size_t strnlen16(const char16_t *s, size_t maxlen)
|
||||
{
|
||||
const char16_t *ss = s;
|
||||
|
||||
/* Important: the maxlen test must precede the reference through ss;
|
||||
since the byte beyond the maximum may segfault */
|
||||
while ((maxlen > 0) && *ss) {
|
||||
ss++;
|
||||
maxlen--;
|
||||
}
|
||||
return ss-s;
|
||||
}
|
||||
|
||||
int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
|
||||
{
|
||||
const char16_t* e1 = s1+n1;
|
||||
const char16_t* e2 = s2+n2;
|
||||
|
||||
while (s1 < e1 && s2 < e2) {
|
||||
const int d = (int)*s1++ - (int)*s2++;
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
return n1 < n2
|
||||
? (0 - (int)*s2)
|
||||
: (n1 > n2
|
||||
? ((int)*s1 - 0)
|
||||
: 0);
|
||||
}
|
||||
|
||||
int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
|
||||
{
|
||||
const char16_t* e1 = s1H+n1;
|
||||
const char16_t* e2 = s2N+n2;
|
||||
|
||||
while (s1H < e1 && s2N < e2) {
|
||||
const char16_t c2 = ntohs(*s2N);
|
||||
const int d = (int)*s1H++ - (int)c2;
|
||||
s2N++;
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
return n1 < n2
|
||||
? (0 - (int)ntohs(*s2N))
|
||||
: (n1 > n2
|
||||
? ((int)*s1H - 0)
|
||||
: 0);
|
||||
}
|
||||
|
||||
void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst)
|
||||
{
|
||||
if (src == NULL || src_len == 0 || dst == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char16_t* cur_utf16 = src;
|
||||
const char16_t* const end_utf16 = src + src_len;
|
||||
char *cur = dst;
|
||||
while (cur_utf16 < end_utf16) {
|
||||
char32_t utf32;
|
||||
// surrogate pairs
|
||||
if ((*cur_utf16 & 0xFC00) == 0xD800) {
|
||||
utf32 = (*cur_utf16++ - 0xD800) << 10;
|
||||
utf32 |= *cur_utf16++ - 0xDC00;
|
||||
utf32 += 0x10000;
|
||||
} else {
|
||||
utf32 = (char32_t) *cur_utf16++;
|
||||
}
|
||||
const size_t len = utf32_codepoint_utf8_length(utf32);
|
||||
utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len);
|
||||
cur += len;
|
||||
}
|
||||
*cur = '\0';
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// UTF-8
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
ssize_t utf8_length(const char *src)
|
||||
{
|
||||
const char *cur = src;
|
||||
size_t ret = 0;
|
||||
while (*cur != '\0') {
|
||||
const char first_char = *cur++;
|
||||
if ((first_char & 0x80) == 0) { // ASCII
|
||||
ret += 1;
|
||||
continue;
|
||||
}
|
||||
// (UTF-8's character must not be like 10xxxxxx,
|
||||
// but 110xxxxx, 1110xxxx, ... or 1111110x)
|
||||
if ((first_char & 0x40) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t mask, to_ignore_mask;
|
||||
size_t num_to_read = 0;
|
||||
char32_t utf32 = 0;
|
||||
for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;
|
||||
num_to_read < 5 && (first_char & mask);
|
||||
num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
|
||||
if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx
|
||||
return -1;
|
||||
}
|
||||
// 0x3F == 00111111
|
||||
utf32 = (utf32 << 6) + (*cur++ & 0x3F);
|
||||
}
|
||||
// "first_char" must be (110xxxxx - 11110xxx)
|
||||
if (num_to_read == 5) {
|
||||
return -1;
|
||||
}
|
||||
to_ignore_mask |= mask;
|
||||
utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));
|
||||
if (utf32 > kUnicodeMaxCodepoint) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret += num_to_read;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
|
||||
{
|
||||
if (src == NULL || src_len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t ret = 0;
|
||||
const char16_t* const end = src + src_len;
|
||||
while (src < end) {
|
||||
if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
|
||||
&& (*++src & 0xFC00) == 0xDC00) {
|
||||
// surrogate pairs are always 4 bytes.
|
||||
ret += 4;
|
||||
src++;
|
||||
} else {
|
||||
ret += utf32_codepoint_utf8_length((char32_t) *src++);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 1-4 based on the number of leading bits.
|
||||
*
|
||||
* 1111 -> 4
|
||||
* 1110 -> 3
|
||||
* 110x -> 2
|
||||
* 10xx -> 1
|
||||
* 0xxx -> 1
|
||||
*/
|
||||
static inline size_t utf8_codepoint_len(uint8_t ch)
|
||||
{
|
||||
return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
|
||||
}
|
||||
|
||||
static inline void utf8_shift_and_mask(uint32_t* codePoint, const uint8_t byte)
|
||||
{
|
||||
*codePoint <<= 6;
|
||||
*codePoint |= 0x3F & byte;
|
||||
}
|
||||
|
||||
size_t utf8_to_utf32_length(const char *src, size_t src_len)
|
||||
{
|
||||
if (src == NULL || src_len == 0) {
|
||||
return 0;
|
||||
}
|
||||
size_t ret = 0;
|
||||
const char* cur;
|
||||
const char* end;
|
||||
size_t num_to_skip;
|
||||
for (cur = src, end = src + src_len, num_to_skip = 1;
|
||||
cur < end;
|
||||
cur += num_to_skip, ret++) {
|
||||
const char first_char = *cur;
|
||||
num_to_skip = 1;
|
||||
if ((first_char & 0x80) == 0) { // ASCII
|
||||
continue;
|
||||
}
|
||||
int32_t mask;
|
||||
|
||||
for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst)
|
||||
{
|
||||
if (src == NULL || src_len == 0 || dst == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* cur = src;
|
||||
const char* const end = src + src_len;
|
||||
char32_t* cur_utf32 = dst;
|
||||
while (cur < end) {
|
||||
size_t num_read;
|
||||
*cur_utf32++ = static_cast<char32_t>(utf32_at_internal(cur, &num_read));
|
||||
cur += num_read;
|
||||
}
|
||||
*cur_utf32 = 0;
|
||||
}
|
||||
|
||||
static inline uint32_t utf8_to_utf32_codepoint(const uint8_t *src, size_t length)
|
||||
{
|
||||
uint32_t unicode;
|
||||
|
||||
switch (length)
|
||||
{
|
||||
case 1:
|
||||
return src[0];
|
||||
case 2:
|
||||
unicode = src[0] & 0x1f;
|
||||
utf8_shift_and_mask(&unicode, src[1]);
|
||||
return unicode;
|
||||
case 3:
|
||||
unicode = src[0] & 0x0f;
|
||||
utf8_shift_and_mask(&unicode, src[1]);
|
||||
utf8_shift_and_mask(&unicode, src[2]);
|
||||
return unicode;
|
||||
case 4:
|
||||
unicode = src[0] & 0x07;
|
||||
utf8_shift_and_mask(&unicode, src[1]);
|
||||
utf8_shift_and_mask(&unicode, src[2]);
|
||||
utf8_shift_and_mask(&unicode, src[3]);
|
||||
return unicode;
|
||||
default:
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
//printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
|
||||
}
|
||||
|
||||
ssize_t utf8_to_utf16_length(const uint8_t* u8str, size_t u8len)
|
||||
{
|
||||
const uint8_t* const u8end = u8str + u8len;
|
||||
const uint8_t* u8cur = u8str;
|
||||
|
||||
/* Validate that the UTF-8 is the correct len */
|
||||
size_t u16measuredLen = 0;
|
||||
while (u8cur < u8end) {
|
||||
u16measuredLen++;
|
||||
int u8charLen = utf8_codepoint_len(*u8cur);
|
||||
uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8charLen);
|
||||
if (codepoint > 0xFFFF) u16measuredLen++; // this will be a surrogate pair in utf16
|
||||
u8cur += u8charLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that we ended where we thought we would and the output UTF-16
|
||||
* will be exactly how long we were told it would be.
|
||||
*/
|
||||
if (u8cur != u8end) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return u16measuredLen;
|
||||
}
|
||||
|
||||
char16_t* utf8_to_utf16_no_null_terminator(const uint8_t* u8str, size_t u8len, char16_t* u16str)
|
||||
{
|
||||
const uint8_t* const u8end = u8str + u8len;
|
||||
const uint8_t* u8cur = u8str;
|
||||
char16_t* u16cur = u16str;
|
||||
|
||||
while (u8cur < u8end) {
|
||||
size_t u8len = utf8_codepoint_len(*u8cur);
|
||||
uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len);
|
||||
|
||||
// Convert the UTF32 codepoint to one or more UTF16 codepoints
|
||||
if (codepoint <= 0xFFFF) {
|
||||
// Single UTF16 character
|
||||
*u16cur++ = (char16_t) codepoint;
|
||||
} else {
|
||||
// Multiple UTF16 characters with surrogates
|
||||
codepoint = codepoint - 0x10000;
|
||||
*u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);
|
||||
*u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
|
||||
}
|
||||
|
||||
u8cur += u8len;
|
||||
}
|
||||
return u16cur;
|
||||
}
|
||||
|
||||
void utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str) {
|
||||
char16_t* end = utf8_to_utf16_no_null_terminator(u8str, u8len, u16str);
|
||||
*end = 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UNICODE_H
|
||||
#define ANDROID_UNICODE_H
|
||||
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
// char32_t and char16_t are built-in types as of c++0x.
|
||||
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
|
||||
typedef uint32_t char32_t;
|
||||
typedef uint16_t char16_t;
|
||||
#endif
|
||||
|
||||
// Standard string functions on char16_t strings.
|
||||
int strcmp16(const char16_t *, const char16_t *);
|
||||
int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
|
||||
size_t strlen16(const char16_t *);
|
||||
size_t strnlen16(const char16_t *, size_t);
|
||||
char16_t *strcpy16(char16_t *, const char16_t *);
|
||||
char16_t *strncpy16(char16_t *, const char16_t *, size_t);
|
||||
|
||||
// Version of comparison that supports embedded nulls.
|
||||
// This is different than strncmp() because we don't stop
|
||||
// at a nul character and consider the strings to be different
|
||||
// if the lengths are different (thus we need to supply the
|
||||
// lengths of both strings). This can also be used when
|
||||
// your string is not nul-terminated as it will have the
|
||||
// equivalent result as strcmp16 (unlike strncmp16).
|
||||
int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
|
||||
|
||||
// Version of strzcmp16 for comparing strings in different endianness.
|
||||
int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
|
||||
|
||||
// Standard string functions on char32_t strings.
|
||||
size_t strlen32(const char32_t *);
|
||||
size_t strnlen32(const char32_t *, size_t);
|
||||
|
||||
/**
|
||||
* Measure the length of a UTF-32 string in UTF-8. If the string is invalid
|
||||
* such as containing a surrogate character, -1 will be returned.
|
||||
*/
|
||||
ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len);
|
||||
|
||||
/**
|
||||
* Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not
|
||||
* large enough to store the string, the part of the "src" string is stored
|
||||
* into "dst" as much as possible. See the examples for more detail.
|
||||
* Returns the size actually used for storing the string.
|
||||
* dst" is not null-terminated when dst_len is fully used (like strncpy).
|
||||
*
|
||||
* Example 1
|
||||
* "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
|
||||
* "src_len" == 2
|
||||
* "dst_len" >= 7
|
||||
* ->
|
||||
* Returned value == 6
|
||||
* "dst" becomes \xE3\x81\x82\xE3\x81\x84\0
|
||||
* (note that "dst" is null-terminated)
|
||||
*
|
||||
* Example 2
|
||||
* "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
|
||||
* "src_len" == 2
|
||||
* "dst_len" == 5
|
||||
* ->
|
||||
* Returned value == 3
|
||||
* "dst" becomes \xE3\x81\x82\0
|
||||
* (note that "dst" is null-terminated, but \u3044 is not stored in "dst"
|
||||
* since "dst" does not have enough size to store the character)
|
||||
*
|
||||
* Example 3
|
||||
* "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
|
||||
* "src_len" == 2
|
||||
* "dst_len" == 6
|
||||
* ->
|
||||
* Returned value == 6
|
||||
* "dst" becomes \xE3\x81\x82\xE3\x81\x84
|
||||
* (note that "dst" is NOT null-terminated, like strncpy)
|
||||
*/
|
||||
void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst);
|
||||
|
||||
/**
|
||||
* Returns the unicode value at "index".
|
||||
* Returns -1 when the index is invalid (equals to or more than "src_len").
|
||||
* If returned value is positive, it is able to be converted to char32_t, which
|
||||
* is unsigned. Then, if "next_index" is not NULL, the next index to be used is
|
||||
* stored in "next_index". "next_index" can be NULL.
|
||||
*/
|
||||
int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the UTF-8 length of UTF-16 string "src".
|
||||
*/
|
||||
ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len);
|
||||
|
||||
/**
|
||||
* Converts a UTF-16 string to UTF-8. The destination buffer must be large
|
||||
* enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added
|
||||
* NULL terminator.
|
||||
*/
|
||||
void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst);
|
||||
|
||||
/**
|
||||
* Returns the length of "src" when "src" is valid UTF-8 string.
|
||||
* Returns 0 if src is NULL or 0-length string. Returns -1 when the source
|
||||
* is an invalid string.
|
||||
*
|
||||
* This function should be used to determine whether "src" is valid UTF-8
|
||||
* characters with valid unicode codepoints. "src" must be null-terminated.
|
||||
*
|
||||
* If you are going to use other utf8_to_... functions defined in this header
|
||||
* with string which may not be valid UTF-8 with valid codepoint (form 0 to
|
||||
* 0x10FFFF), you should use this function before calling others, since the
|
||||
* other functions do not check whether the string is valid UTF-8 or not.
|
||||
*
|
||||
* If you do not care whether "src" is valid UTF-8 or not, you should use
|
||||
* strlen() as usual, which should be much faster.
|
||||
*/
|
||||
ssize_t utf8_length(const char *src);
|
||||
|
||||
/**
|
||||
* Measure the length of a UTF-32 string.
|
||||
*/
|
||||
size_t utf8_to_utf32_length(const char *src, size_t src_len);
|
||||
|
||||
/**
|
||||
* Stores a UTF-32 string converted from "src" in "dst". "dst" must be large
|
||||
* enough to store the entire converted string as measured by
|
||||
* utf8_to_utf32_length plus space for a NULL terminator.
|
||||
*/
|
||||
void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst);
|
||||
|
||||
/**
|
||||
* Returns the UTF-16 length of UTF-8 string "src".
|
||||
*/
|
||||
ssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen);
|
||||
|
||||
/**
|
||||
* Convert UTF-8 to UTF-16 including surrogate pairs.
|
||||
* Returns a pointer to the end of the string (where a null terminator might go
|
||||
* if you wanted to add one).
|
||||
*/
|
||||
char16_t* utf8_to_utf16_no_null_terminator(const uint8_t* src, size_t srcLen, char16_t* dst);
|
||||
|
||||
/**
|
||||
* Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer
|
||||
* must be large enough to hold the result as measured by utf8_to_utf16_length
|
||||
* plus an added NULL terminator.
|
||||
*/
|
||||
void utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst);
|
||||
|
||||
}
|
||||
|
||||
#undef __STDC_LIMIT_MACROS
|
||||
#endif
|
|
@ -18,11 +18,11 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "utils_Log.h"
|
||||
#include "VirtualKeyMap.h"
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Tokenizer.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "Tokenizer.h"
|
||||
#include "Timers.h"
|
||||
|
||||
// Enables debug output for the parser.
|
||||
#define DEBUG_PARSER 0
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
#include "Input.h"
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Tokenizer.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Unicode.h>
|
||||
#include "Tokenizer.h"
|
||||
#include "String8.h"
|
||||
#include "Unicode.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
|
@ -0,0 +1,848 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_INPUT_H
|
||||
#define _ANDROID_INPUT_H
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* IMPORTANT NOTICE:
|
||||
*
|
||||
* This file is part of Android's set of stable system headers
|
||||
* exposed by the Android NDK (Native Development Kit).
|
||||
*
|
||||
* Third-party source AND binary code relies on the definitions
|
||||
* here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
|
||||
*
|
||||
* - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
|
||||
* - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
|
||||
* - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
|
||||
* - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structures and functions to receive and process input events in
|
||||
* native code.
|
||||
*
|
||||
* NOTE: These functions MUST be implemented by /system/lib/libui.so
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include "android_keycodes.h"
|
||||
#include <android/looper.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Key states (may be returned by queries about the current state of a
|
||||
* particular key code, scan code or switch).
|
||||
*/
|
||||
enum {
|
||||
/* The key state is unknown or the requested key itself is not supported. */
|
||||
AKEY_STATE_UNKNOWN = -1,
|
||||
|
||||
/* The key is up. */
|
||||
AKEY_STATE_UP = 0,
|
||||
|
||||
/* The key is down. */
|
||||
AKEY_STATE_DOWN = 1,
|
||||
|
||||
/* The key is down but is a virtual key press that is being emulated by the system. */
|
||||
AKEY_STATE_VIRTUAL = 2
|
||||
};
|
||||
|
||||
/*
|
||||
* Meta key / modifer state.
|
||||
*/
|
||||
enum {
|
||||
/* No meta keys are pressed. */
|
||||
AMETA_NONE = 0,
|
||||
|
||||
/* This mask is used to check whether one of the ALT meta keys is pressed. */
|
||||
AMETA_ALT_ON = 0x02,
|
||||
|
||||
/* This mask is used to check whether the left ALT meta key is pressed. */
|
||||
AMETA_ALT_LEFT_ON = 0x10,
|
||||
|
||||
/* This mask is used to check whether the right ALT meta key is pressed. */
|
||||
AMETA_ALT_RIGHT_ON = 0x20,
|
||||
|
||||
/* This mask is used to check whether one of the SHIFT meta keys is pressed. */
|
||||
AMETA_SHIFT_ON = 0x01,
|
||||
|
||||
/* This mask is used to check whether the left SHIFT meta key is pressed. */
|
||||
AMETA_SHIFT_LEFT_ON = 0x40,
|
||||
|
||||
/* This mask is used to check whether the right SHIFT meta key is pressed. */
|
||||
AMETA_SHIFT_RIGHT_ON = 0x80,
|
||||
|
||||
/* This mask is used to check whether the SYM meta key is pressed. */
|
||||
AMETA_SYM_ON = 0x04,
|
||||
|
||||
/* This mask is used to check whether the FUNCTION meta key is pressed. */
|
||||
AMETA_FUNCTION_ON = 0x08,
|
||||
|
||||
/* This mask is used to check whether one of the CTRL meta keys is pressed. */
|
||||
AMETA_CTRL_ON = 0x1000,
|
||||
|
||||
/* This mask is used to check whether the left CTRL meta key is pressed. */
|
||||
AMETA_CTRL_LEFT_ON = 0x2000,
|
||||
|
||||
/* This mask is used to check whether the right CTRL meta key is pressed. */
|
||||
AMETA_CTRL_RIGHT_ON = 0x4000,
|
||||
|
||||
/* This mask is used to check whether one of the META meta keys is pressed. */
|
||||
AMETA_META_ON = 0x10000,
|
||||
|
||||
/* This mask is used to check whether the left META meta key is pressed. */
|
||||
AMETA_META_LEFT_ON = 0x20000,
|
||||
|
||||
/* This mask is used to check whether the right META meta key is pressed. */
|
||||
AMETA_META_RIGHT_ON = 0x40000,
|
||||
|
||||
/* This mask is used to check whether the CAPS LOCK meta key is on. */
|
||||
AMETA_CAPS_LOCK_ON = 0x100000,
|
||||
|
||||
/* This mask is used to check whether the NUM LOCK meta key is on. */
|
||||
AMETA_NUM_LOCK_ON = 0x200000,
|
||||
|
||||
/* This mask is used to check whether the SCROLL LOCK meta key is on. */
|
||||
AMETA_SCROLL_LOCK_ON = 0x400000,
|
||||
};
|
||||
|
||||
/*
|
||||
* Input events.
|
||||
*
|
||||
* Input events are opaque structures. Use the provided accessors functions to
|
||||
* read their properties.
|
||||
*/
|
||||
struct AInputEvent;
|
||||
typedef struct AInputEvent AInputEvent;
|
||||
|
||||
/*
|
||||
* Input event types.
|
||||
*/
|
||||
enum {
|
||||
/* Indicates that the input event is a key event. */
|
||||
AINPUT_EVENT_TYPE_KEY = 1,
|
||||
|
||||
/* Indicates that the input event is a motion event. */
|
||||
AINPUT_EVENT_TYPE_MOTION = 2
|
||||
};
|
||||
|
||||
/*
|
||||
* Key event actions.
|
||||
*/
|
||||
enum {
|
||||
/* The key has been pressed down. */
|
||||
AKEY_EVENT_ACTION_DOWN = 0,
|
||||
|
||||
/* The key has been released. */
|
||||
AKEY_EVENT_ACTION_UP = 1,
|
||||
|
||||
/* Multiple duplicate key events have occurred in a row, or a complex string is
|
||||
* being delivered. The repeat_count property of the key event contains the number
|
||||
* of times the given key code should be executed.
|
||||
*/
|
||||
AKEY_EVENT_ACTION_MULTIPLE = 2
|
||||
};
|
||||
|
||||
/*
|
||||
* Key event flags.
|
||||
*/
|
||||
enum {
|
||||
/* This mask is set if the device woke because of this key event. */
|
||||
AKEY_EVENT_FLAG_WOKE_HERE = 0x1,
|
||||
|
||||
/* This mask is set if the key event was generated by a software keyboard. */
|
||||
AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,
|
||||
|
||||
/* This mask is set if we don't want the key event to cause us to leave touch mode. */
|
||||
AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,
|
||||
|
||||
/* This mask is set if an event was known to come from a trusted part
|
||||
* of the system. That is, the event is known to come from the user,
|
||||
* and could not have been spoofed by a third party component. */
|
||||
AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
|
||||
|
||||
/* This mask is used for compatibility, to identify enter keys that are
|
||||
* coming from an IME whose enter key has been auto-labelled "next" or
|
||||
* "done". This allows TextView to dispatch these as normal enter keys
|
||||
* for old applications, but still do the appropriate action when
|
||||
* receiving them. */
|
||||
AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10,
|
||||
|
||||
/* When associated with up key events, this indicates that the key press
|
||||
* has been canceled. Typically this is used with virtual touch screen
|
||||
* keys, where the user can slide from the virtual key area on to the
|
||||
* display: in that case, the application will receive a canceled up
|
||||
* event and should not perform the action normally associated with the
|
||||
* key. Note that for this to work, the application can not perform an
|
||||
* action for a key until it receives an up or the long press timeout has
|
||||
* expired. */
|
||||
AKEY_EVENT_FLAG_CANCELED = 0x20,
|
||||
|
||||
/* This key event was generated by a virtual (on-screen) hard key area.
|
||||
* Typically this is an area of the touchscreen, outside of the regular
|
||||
* display, dedicated to "hardware" buttons. */
|
||||
AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,
|
||||
|
||||
/* This flag is set for the first key repeat that occurs after the
|
||||
* long press timeout. */
|
||||
AKEY_EVENT_FLAG_LONG_PRESS = 0x80,
|
||||
|
||||
/* Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long
|
||||
* press action was executed while it was down. */
|
||||
AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,
|
||||
|
||||
/* Set for AKEY_EVENT_ACTION_UP when this event's key code is still being
|
||||
* tracked from its initial down. That is, somebody requested that tracking
|
||||
* started on the key down and a long press has not caused
|
||||
* the tracking to be canceled. */
|
||||
AKEY_EVENT_FLAG_TRACKING = 0x200,
|
||||
|
||||
/* Set when a key event has been synthesized to implement default behavior
|
||||
* for an event that the application did not handle.
|
||||
* Fallback key events are generated by unhandled trackball motions
|
||||
* (to emulate a directional keypad) and by certain unhandled key presses
|
||||
* that are declared in the key map (such as special function numeric keypad
|
||||
* keys when numlock is off). */
|
||||
AKEY_EVENT_FLAG_FALLBACK = 0x400,
|
||||
};
|
||||
|
||||
/*
|
||||
* Motion event actions.
|
||||
*/
|
||||
|
||||
/* Bit shift for the action bits holding the pointer index as
|
||||
* defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK.
|
||||
*/
|
||||
#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8
|
||||
|
||||
enum {
|
||||
/* Bit mask of the parts of the action code that are the action itself.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_MASK = 0xff,
|
||||
|
||||
/* Bits in the action code that represent a pointer index, used with
|
||||
* AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP. Shifting
|
||||
* down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
|
||||
* index where the data for the pointer going up or down can be found.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_POINTER_INDEX_MASK = 0xff00,
|
||||
|
||||
/* A pressed gesture has started, the motion contains the initial starting location.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_DOWN = 0,
|
||||
|
||||
/* A pressed gesture has finished, the motion contains the final release location
|
||||
* as well as any intermediate points since the last down or move event.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_UP = 1,
|
||||
|
||||
/* A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
|
||||
* AMOTION_EVENT_ACTION_UP). The motion contains the most recent point, as well as
|
||||
* any intermediate points since the last down or move event.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_MOVE = 2,
|
||||
|
||||
/* The current gesture has been aborted.
|
||||
* You will not receive any more points in it. You should treat this as
|
||||
* an up event, but not perform any action that you normally would.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_CANCEL = 3,
|
||||
|
||||
/* A movement has happened outside of the normal bounds of the UI element.
|
||||
* This does not provide a full gesture, but only the initial location of the movement/touch.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_OUTSIDE = 4,
|
||||
|
||||
/* A non-primary pointer has gone down.
|
||||
* The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_POINTER_DOWN = 5,
|
||||
|
||||
/* A non-primary pointer has gone up.
|
||||
* The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_POINTER_UP = 6,
|
||||
|
||||
/* A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
|
||||
* The motion contains the most recent point, as well as any intermediate points since
|
||||
* the last hover move event.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_HOVER_MOVE = 7,
|
||||
|
||||
/* The motion event contains relative vertical and/or horizontal scroll offsets.
|
||||
* Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
|
||||
* and AMOTION_EVENT_AXIS_HSCROLL.
|
||||
* The pointer may or may not be down when this event is dispatched.
|
||||
* This action is always delivered to the winder under the pointer, which
|
||||
* may not be the window currently touched.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_SCROLL = 8,
|
||||
|
||||
/* The pointer is not down but has entered the boundaries of a window or view.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_HOVER_ENTER = 9,
|
||||
|
||||
/* The pointer is not down but has exited the boundaries of a window or view.
|
||||
*/
|
||||
AMOTION_EVENT_ACTION_HOVER_EXIT = 10,
|
||||
};
|
||||
|
||||
/*
|
||||
* Motion event flags.
|
||||
*/
|
||||
enum {
|
||||
/* This flag indicates that the window that received this motion event is partly
|
||||
* or wholly obscured by another visible window above it. This flag is set to true
|
||||
* even if the event did not directly pass through the obscured area.
|
||||
* A security sensitive application can check this flag to identify situations in which
|
||||
* a malicious application may have covered up part of its content for the purpose
|
||||
* of misleading the user or hijacking touches. An appropriate response might be
|
||||
* to drop the suspect touches or to take additional precautions to confirm the user's
|
||||
* actual intent.
|
||||
*/
|
||||
AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Motion event edge touch flags.
|
||||
*/
|
||||
enum {
|
||||
/* No edges intersected */
|
||||
AMOTION_EVENT_EDGE_FLAG_NONE = 0,
|
||||
|
||||
/* Flag indicating the motion event intersected the top edge of the screen. */
|
||||
AMOTION_EVENT_EDGE_FLAG_TOP = 0x01,
|
||||
|
||||
/* Flag indicating the motion event intersected the bottom edge of the screen. */
|
||||
AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,
|
||||
|
||||
/* Flag indicating the motion event intersected the left edge of the screen. */
|
||||
AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04,
|
||||
|
||||
/* Flag indicating the motion event intersected the right edge of the screen. */
|
||||
AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08
|
||||
};
|
||||
|
||||
/*
|
||||
* Constants that identify each individual axis of a motion event.
|
||||
* Refer to the documentation on the MotionEvent class for descriptions of each axis.
|
||||
*/
|
||||
enum {
|
||||
AMOTION_EVENT_AXIS_X = 0,
|
||||
AMOTION_EVENT_AXIS_Y = 1,
|
||||
AMOTION_EVENT_AXIS_PRESSURE = 2,
|
||||
AMOTION_EVENT_AXIS_SIZE = 3,
|
||||
AMOTION_EVENT_AXIS_TOUCH_MAJOR = 4,
|
||||
AMOTION_EVENT_AXIS_TOUCH_MINOR = 5,
|
||||
AMOTION_EVENT_AXIS_TOOL_MAJOR = 6,
|
||||
AMOTION_EVENT_AXIS_TOOL_MINOR = 7,
|
||||
AMOTION_EVENT_AXIS_ORIENTATION = 8,
|
||||
AMOTION_EVENT_AXIS_VSCROLL = 9,
|
||||
AMOTION_EVENT_AXIS_HSCROLL = 10,
|
||||
AMOTION_EVENT_AXIS_Z = 11,
|
||||
AMOTION_EVENT_AXIS_RX = 12,
|
||||
AMOTION_EVENT_AXIS_RY = 13,
|
||||
AMOTION_EVENT_AXIS_RZ = 14,
|
||||
AMOTION_EVENT_AXIS_HAT_X = 15,
|
||||
AMOTION_EVENT_AXIS_HAT_Y = 16,
|
||||
AMOTION_EVENT_AXIS_LTRIGGER = 17,
|
||||
AMOTION_EVENT_AXIS_RTRIGGER = 18,
|
||||
AMOTION_EVENT_AXIS_THROTTLE = 19,
|
||||
AMOTION_EVENT_AXIS_RUDDER = 20,
|
||||
AMOTION_EVENT_AXIS_WHEEL = 21,
|
||||
AMOTION_EVENT_AXIS_GAS = 22,
|
||||
AMOTION_EVENT_AXIS_BRAKE = 23,
|
||||
AMOTION_EVENT_AXIS_DISTANCE = 24,
|
||||
AMOTION_EVENT_AXIS_TILT = 25,
|
||||
AMOTION_EVENT_AXIS_GENERIC_1 = 32,
|
||||
AMOTION_EVENT_AXIS_GENERIC_2 = 33,
|
||||
AMOTION_EVENT_AXIS_GENERIC_3 = 34,
|
||||
AMOTION_EVENT_AXIS_GENERIC_4 = 35,
|
||||
AMOTION_EVENT_AXIS_GENERIC_5 = 36,
|
||||
AMOTION_EVENT_AXIS_GENERIC_6 = 37,
|
||||
AMOTION_EVENT_AXIS_GENERIC_7 = 38,
|
||||
AMOTION_EVENT_AXIS_GENERIC_8 = 39,
|
||||
AMOTION_EVENT_AXIS_GENERIC_9 = 40,
|
||||
AMOTION_EVENT_AXIS_GENERIC_10 = 41,
|
||||
AMOTION_EVENT_AXIS_GENERIC_11 = 42,
|
||||
AMOTION_EVENT_AXIS_GENERIC_12 = 43,
|
||||
AMOTION_EVENT_AXIS_GENERIC_13 = 44,
|
||||
AMOTION_EVENT_AXIS_GENERIC_14 = 45,
|
||||
AMOTION_EVENT_AXIS_GENERIC_15 = 46,
|
||||
AMOTION_EVENT_AXIS_GENERIC_16 = 47,
|
||||
|
||||
// NOTE: If you add a new axis here you must also add it to several other files.
|
||||
// Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
|
||||
};
|
||||
|
||||
/*
|
||||
* Constants that identify buttons that are associated with motion events.
|
||||
* Refer to the documentation on the MotionEvent class for descriptions of each button.
|
||||
*/
|
||||
enum {
|
||||
AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0,
|
||||
AMOTION_EVENT_BUTTON_SECONDARY = 1 << 1,
|
||||
AMOTION_EVENT_BUTTON_TERTIARY = 1 << 2,
|
||||
AMOTION_EVENT_BUTTON_BACK = 1 << 3,
|
||||
AMOTION_EVENT_BUTTON_FORWARD = 1 << 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* Constants that identify tool types.
|
||||
* Refer to the documentation on the MotionEvent class for descriptions of each tool type.
|
||||
*/
|
||||
enum {
|
||||
AMOTION_EVENT_TOOL_TYPE_UNKNOWN = 0,
|
||||
AMOTION_EVENT_TOOL_TYPE_FINGER = 1,
|
||||
AMOTION_EVENT_TOOL_TYPE_STYLUS = 2,
|
||||
AMOTION_EVENT_TOOL_TYPE_MOUSE = 3,
|
||||
AMOTION_EVENT_TOOL_TYPE_ERASER = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* Input sources.
|
||||
*
|
||||
* Refer to the documentation on android.view.InputDevice for more details about input sources
|
||||
* and their correct interpretation.
|
||||
*/
|
||||
enum {
|
||||
AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
|
||||
|
||||
AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
|
||||
AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
|
||||
AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
|
||||
AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
|
||||
AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010,
|
||||
};
|
||||
|
||||
enum {
|
||||
AINPUT_SOURCE_UNKNOWN = 0x00000000,
|
||||
|
||||
AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
|
||||
AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
|
||||
AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,
|
||||
AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
|
||||
AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
|
||||
AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
|
||||
AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
|
||||
AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
|
||||
AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
|
||||
|
||||
AINPUT_SOURCE_ANY = 0xffffff00,
|
||||
};
|
||||
|
||||
/*
|
||||
* Keyboard types.
|
||||
*
|
||||
* Refer to the documentation on android.view.InputDevice for more details.
|
||||
*/
|
||||
enum {
|
||||
AINPUT_KEYBOARD_TYPE_NONE = 0,
|
||||
AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1,
|
||||
AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* Constants used to retrieve information about the range of motion for a particular
|
||||
* coordinate of a motion event.
|
||||
*
|
||||
* Refer to the documentation on android.view.InputDevice for more details about input sources
|
||||
* and their correct interpretation.
|
||||
*
|
||||
* DEPRECATION NOTICE: These constants are deprecated. Use AMOTION_EVENT_AXIS_* constants instead.
|
||||
*/
|
||||
enum {
|
||||
AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X,
|
||||
AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y,
|
||||
AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE,
|
||||
AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE,
|
||||
AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR,
|
||||
AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR,
|
||||
AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR,
|
||||
AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR,
|
||||
AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION,
|
||||
} __attribute__ ((deprecated));
|
||||
|
||||
|
||||
/*
|
||||
* Input event accessors.
|
||||
*
|
||||
* Note that most functions can only be used on input events that are of a given type.
|
||||
* Calling these functions on input events of other types will yield undefined behavior.
|
||||
*/
|
||||
|
||||
/*** Accessors for all input events. ***/
|
||||
|
||||
/* Get the input event type. */
|
||||
int32_t AInputEvent_getType(const AInputEvent* event);
|
||||
|
||||
/* Get the id for the device that an input event came from.
|
||||
*
|
||||
* Input events can be generated by multiple different input devices.
|
||||
* Use the input device id to obtain information about the input
|
||||
* device that was responsible for generating a particular event.
|
||||
*
|
||||
* An input device id of 0 indicates that the event didn't come from a physical device;
|
||||
* other numbers are arbitrary and you shouldn't depend on the values.
|
||||
* Use the provided input device query API to obtain information about input devices.
|
||||
*/
|
||||
int32_t AInputEvent_getDeviceId(const AInputEvent* event);
|
||||
|
||||
/* Get the input event source. */
|
||||
int32_t AInputEvent_getSource(const AInputEvent* event);
|
||||
|
||||
/*** Accessors for key events only. ***/
|
||||
|
||||
/* Get the key event action. */
|
||||
int32_t AKeyEvent_getAction(const AInputEvent* key_event);
|
||||
|
||||
/* Get the key event flags. */
|
||||
int32_t AKeyEvent_getFlags(const AInputEvent* key_event);
|
||||
|
||||
/* Get the key code of the key event.
|
||||
* This is the physical key that was pressed, not the Unicode character. */
|
||||
int32_t AKeyEvent_getKeyCode(const AInputEvent* key_event);
|
||||
|
||||
/* Get the hardware key id of this key event.
|
||||
* These values are not reliable and vary from device to device. */
|
||||
int32_t AKeyEvent_getScanCode(const AInputEvent* key_event);
|
||||
|
||||
/* Get the meta key state. */
|
||||
int32_t AKeyEvent_getMetaState(const AInputEvent* key_event);
|
||||
|
||||
/* Get the repeat count of the event.
|
||||
* For both key up an key down events, this is the number of times the key has
|
||||
* repeated with the first down starting at 0 and counting up from there. For
|
||||
* multiple key events, this is the number of down/up pairs that have occurred. */
|
||||
int32_t AKeyEvent_getRepeatCount(const AInputEvent* key_event);
|
||||
|
||||
/* Get the time of the most recent key down event, in the
|
||||
* java.lang.System.nanoTime() time base. If this is a down event,
|
||||
* this will be the same as eventTime.
|
||||
* Note that when chording keys, this value is the down time of the most recently
|
||||
* pressed key, which may not be the same physical key of this event. */
|
||||
int64_t AKeyEvent_getDownTime(const AInputEvent* key_event);
|
||||
|
||||
/* Get the time this event occurred, in the
|
||||
* java.lang.System.nanoTime() time base. */
|
||||
int64_t AKeyEvent_getEventTime(const AInputEvent* key_event);
|
||||
|
||||
/*** Accessors for motion events only. ***/
|
||||
|
||||
/* Get the combined motion event action code and pointer index. */
|
||||
int32_t AMotionEvent_getAction(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the motion event flags. */
|
||||
int32_t AMotionEvent_getFlags(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the state of any meta / modifier keys that were in effect when the
|
||||
* event was generated. */
|
||||
int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the button state of all buttons that are pressed. */
|
||||
int32_t AMotionEvent_getButtonState(const AInputEvent* motion_event);
|
||||
|
||||
/* Get a bitfield indicating which edges, if any, were touched by this motion event.
|
||||
* For touch events, clients can use this to determine if the user's finger was
|
||||
* touching the edge of the display. */
|
||||
int32_t AMotionEvent_getEdgeFlags(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the time when the user originally pressed down to start a stream of
|
||||
* position events, in the java.lang.System.nanoTime() time base. */
|
||||
int64_t AMotionEvent_getDownTime(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the time when this specific event was generated,
|
||||
* in the java.lang.System.nanoTime() time base. */
|
||||
int64_t AMotionEvent_getEventTime(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the X coordinate offset.
|
||||
* For touch events on the screen, this is the delta that was added to the raw
|
||||
* screen coordinates to adjust for the absolute position of the containing windows
|
||||
* and views. */
|
||||
float AMotionEvent_getXOffset(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the precision of the Y coordinates being reported.
|
||||
* For touch events on the screen, this is the delta that was added to the raw
|
||||
* screen coordinates to adjust for the absolute position of the containing windows
|
||||
* and views. */
|
||||
float AMotionEvent_getYOffset(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the precision of the X coordinates being reported.
|
||||
* You can multiply this number with an X coordinate sample to find the
|
||||
* actual hardware value of the X coordinate. */
|
||||
float AMotionEvent_getXPrecision(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the precision of the Y coordinates being reported.
|
||||
* You can multiply this number with a Y coordinate sample to find the
|
||||
* actual hardware value of the Y coordinate. */
|
||||
float AMotionEvent_getYPrecision(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the number of pointers of data contained in this event.
|
||||
* Always >= 1. */
|
||||
size_t AMotionEvent_getPointerCount(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the pointer identifier associated with a particular pointer
|
||||
* data index in this event. The identifier tells you the actual pointer
|
||||
* number associated with the data, accounting for individual pointers
|
||||
* going up and down since the start of the current gesture. */
|
||||
int32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the tool type of a pointer for the given pointer index.
|
||||
* The tool type indicates the type of tool used to make contact such as a
|
||||
* finger or stylus, if known. */
|
||||
int32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the original raw X coordinate of this event.
|
||||
* For touch events on the screen, this is the original location of the event
|
||||
* on the screen, before it had been adjusted for the containing window
|
||||
* and views. */
|
||||
float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the original raw X coordinate of this event.
|
||||
* For touch events on the screen, this is the original location of the event
|
||||
* on the screen, before it had been adjusted for the containing window
|
||||
* and views. */
|
||||
float AMotionEvent_getRawY(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current X coordinate of this event for the given pointer index.
|
||||
* Whole numbers are pixels; the value may have a fraction for input devices
|
||||
* that are sub-pixel precise. */
|
||||
float AMotionEvent_getX(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current Y coordinate of this event for the given pointer index.
|
||||
* Whole numbers are pixels; the value may have a fraction for input devices
|
||||
* that are sub-pixel precise. */
|
||||
float AMotionEvent_getY(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current pressure of this event for the given pointer index.
|
||||
* The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
|
||||
* although values higher than 1 may be generated depending on the calibration of
|
||||
* the input device. */
|
||||
float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current scaled value of the approximate size for the given pointer index.
|
||||
* This represents some approximation of the area of the screen being
|
||||
* pressed; the actual value in pixels corresponding to the
|
||||
* touch is normalized with the device specific range of values
|
||||
* and scaled to a value between 0 and 1. The value of size can be used to
|
||||
* determine fat touch events. */
|
||||
float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current length of the major axis of an ellipse that describes the touch area
|
||||
* at the point of contact for the given pointer index. */
|
||||
float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current length of the minor axis of an ellipse that describes the touch area
|
||||
* at the point of contact for the given pointer index. */
|
||||
float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current length of the major axis of an ellipse that describes the size
|
||||
* of the approaching tool for the given pointer index.
|
||||
* The tool area represents the estimated size of the finger or pen that is
|
||||
* touching the device independent of its actual touch area at the point of contact. */
|
||||
float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current length of the minor axis of an ellipse that describes the size
|
||||
* of the approaching tool for the given pointer index.
|
||||
* The tool area represents the estimated size of the finger or pen that is
|
||||
* touching the device independent of its actual touch area at the point of contact. */
|
||||
float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the current orientation of the touch area and tool area in radians clockwise from
|
||||
* vertical for the given pointer index.
|
||||
* An angle of 0 degrees indicates that the major axis of contact is oriented
|
||||
* upwards, is perfectly circular or is of unknown orientation. A positive angle
|
||||
* indicates that the major axis of contact is oriented to the right. A negative angle
|
||||
* indicates that the major axis of contact is oriented to the left.
|
||||
* The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
|
||||
* (finger pointing fully right). */
|
||||
float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index);
|
||||
|
||||
/* Get the value of the request axis for the given pointer index. */
|
||||
float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
|
||||
int32_t axis, size_t pointer_index);
|
||||
|
||||
/* Get the number of historical points in this event. These are movements that
|
||||
* have occurred between this event and the previous event. This only applies
|
||||
* to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.
|
||||
* Historical samples are indexed from oldest to newest. */
|
||||
size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event);
|
||||
|
||||
/* Get the time that a historical movement occurred between this event and
|
||||
* the previous event, in the java.lang.System.nanoTime() time base. */
|
||||
int64_t AMotionEvent_getHistoricalEventTime(AInputEvent* motion_event,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical raw X coordinate of this event for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* For touch events on the screen, this is the original location of the event
|
||||
* on the screen, before it had been adjusted for the containing window
|
||||
* and views.
|
||||
* Whole numbers are pixels; the value may have a fraction for input devices
|
||||
* that are sub-pixel precise. */
|
||||
float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical raw Y coordinate of this event for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* For touch events on the screen, this is the original location of the event
|
||||
* on the screen, before it had been adjusted for the containing window
|
||||
* and views.
|
||||
* Whole numbers are pixels; the value may have a fraction for input devices
|
||||
* that are sub-pixel precise. */
|
||||
float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical X coordinate of this event for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* Whole numbers are pixels; the value may have a fraction for input devices
|
||||
* that are sub-pixel precise. */
|
||||
float AMotionEvent_getHistoricalX(AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical Y coordinate of this event for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* Whole numbers are pixels; the value may have a fraction for input devices
|
||||
* that are sub-pixel precise. */
|
||||
float AMotionEvent_getHistoricalY(AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical pressure of this event for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
|
||||
* although values higher than 1 may be generated depending on the calibration of
|
||||
* the input device. */
|
||||
float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the current scaled value of the approximate size for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* This represents some approximation of the area of the screen being
|
||||
* pressed; the actual value in pixels corresponding to the
|
||||
* touch is normalized with the device specific range of values
|
||||
* and scaled to a value between 0 and 1. The value of size can be used to
|
||||
* determine fat touch events. */
|
||||
float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical length of the major axis of an ellipse that describes the touch area
|
||||
* at the point of contact for the given pointer index that
|
||||
* occurred between this event and the previous motion event. */
|
||||
float AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical length of the minor axis of an ellipse that describes the touch area
|
||||
* at the point of contact for the given pointer index that
|
||||
* occurred between this event and the previous motion event. */
|
||||
float AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical length of the major axis of an ellipse that describes the size
|
||||
* of the approaching tool for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* The tool area represents the estimated size of the finger or pen that is
|
||||
* touching the device independent of its actual touch area at the point of contact. */
|
||||
float AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical length of the minor axis of an ellipse that describes the size
|
||||
* of the approaching tool for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* The tool area represents the estimated size of the finger or pen that is
|
||||
* touching the device independent of its actual touch area at the point of contact. */
|
||||
float AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical orientation of the touch area and tool area in radians clockwise from
|
||||
* vertical for the given pointer index that
|
||||
* occurred between this event and the previous motion event.
|
||||
* An angle of 0 degrees indicates that the major axis of contact is oriented
|
||||
* upwards, is perfectly circular or is of unknown orientation. A positive angle
|
||||
* indicates that the major axis of contact is oriented to the right. A negative angle
|
||||
* indicates that the major axis of contact is oriented to the left.
|
||||
* The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
|
||||
* (finger pointing fully right). */
|
||||
float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index,
|
||||
size_t history_index);
|
||||
|
||||
/* Get the historical value of the request axis for the given pointer index
|
||||
* that occurred between this event and the previous motion event. */
|
||||
float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,
|
||||
int32_t axis, size_t pointer_index, size_t history_index);
|
||||
|
||||
|
||||
/*
|
||||
* Input queue
|
||||
*
|
||||
* An input queue is the facility through which you retrieve input
|
||||
* events.
|
||||
*/
|
||||
struct AInputQueue;
|
||||
typedef struct AInputQueue AInputQueue;
|
||||
|
||||
/*
|
||||
* Add this input queue to a looper for processing. See
|
||||
* ALooper_addFd() for information on the ident, callback, and data params.
|
||||
*/
|
||||
void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
|
||||
int ident, ALooper_callbackFunc callback, void* data);
|
||||
|
||||
/*
|
||||
* Remove the input queue from the looper it is currently attached to.
|
||||
*/
|
||||
void AInputQueue_detachLooper(AInputQueue* queue);
|
||||
|
||||
/*
|
||||
* Returns true if there are one or more events available in the
|
||||
* input queue. Returns 1 if the queue has events; 0 if
|
||||
* it does not have events; and a negative value if there is an error.
|
||||
*/
|
||||
int32_t AInputQueue_hasEvents(AInputQueue* queue);
|
||||
|
||||
/*
|
||||
* Returns the next available event from the queue. Returns a negative
|
||||
* value if no events are available or an error has occurred.
|
||||
*/
|
||||
int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent);
|
||||
|
||||
/*
|
||||
* Sends the key for standard pre-dispatching -- that is, possibly deliver
|
||||
* it to the current IME to be consumed before the app. Returns 0 if it
|
||||
* was not pre-dispatched, meaning you can process it right now. If non-zero
|
||||
* is returned, you must abandon the current event processing and allow the
|
||||
* event to appear again in the event queue (if it does not get consumed during
|
||||
* pre-dispatching).
|
||||
*/
|
||||
int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event);
|
||||
|
||||
/*
|
||||
* Report that dispatching has finished with the given event.
|
||||
* This must be called after receiving an event with AInputQueue_get_event().
|
||||
*/
|
||||
void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ANDROID_INPUT_H
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_KEYCODES_H
|
||||
#define _ANDROID_KEYCODES_H
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* IMPORTANT NOTICE:
|
||||
*
|
||||
* This file is part of Android's set of stable system headers
|
||||
* exposed by the Android NDK (Native Development Kit).
|
||||
*
|
||||
* Third-party source AND binary code relies on the definitions
|
||||
* here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
|
||||
*
|
||||
* - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
|
||||
* - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
|
||||
* - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
|
||||
* - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Key codes.
|
||||
*/
|
||||
enum {
|
||||
AKEYCODE_UNKNOWN = 0,
|
||||
AKEYCODE_SOFT_LEFT = 1,
|
||||
AKEYCODE_SOFT_RIGHT = 2,
|
||||
AKEYCODE_HOME = 3,
|
||||
AKEYCODE_BACK = 4,
|
||||
AKEYCODE_CALL = 5,
|
||||
AKEYCODE_ENDCALL = 6,
|
||||
AKEYCODE_0 = 7,
|
||||
AKEYCODE_1 = 8,
|
||||
AKEYCODE_2 = 9,
|
||||
AKEYCODE_3 = 10,
|
||||
AKEYCODE_4 = 11,
|
||||
AKEYCODE_5 = 12,
|
||||
AKEYCODE_6 = 13,
|
||||
AKEYCODE_7 = 14,
|
||||
AKEYCODE_8 = 15,
|
||||
AKEYCODE_9 = 16,
|
||||
AKEYCODE_STAR = 17,
|
||||
AKEYCODE_POUND = 18,
|
||||
AKEYCODE_DPAD_UP = 19,
|
||||
AKEYCODE_DPAD_DOWN = 20,
|
||||
AKEYCODE_DPAD_LEFT = 21,
|
||||
AKEYCODE_DPAD_RIGHT = 22,
|
||||
AKEYCODE_DPAD_CENTER = 23,
|
||||
AKEYCODE_VOLUME_UP = 24,
|
||||
AKEYCODE_VOLUME_DOWN = 25,
|
||||
AKEYCODE_POWER = 26,
|
||||
AKEYCODE_CAMERA = 27,
|
||||
AKEYCODE_CLEAR = 28,
|
||||
AKEYCODE_A = 29,
|
||||
AKEYCODE_B = 30,
|
||||
AKEYCODE_C = 31,
|
||||
AKEYCODE_D = 32,
|
||||
AKEYCODE_E = 33,
|
||||
AKEYCODE_F = 34,
|
||||
AKEYCODE_G = 35,
|
||||
AKEYCODE_H = 36,
|
||||
AKEYCODE_I = 37,
|
||||
AKEYCODE_J = 38,
|
||||
AKEYCODE_K = 39,
|
||||
AKEYCODE_L = 40,
|
||||
AKEYCODE_M = 41,
|
||||
AKEYCODE_N = 42,
|
||||
AKEYCODE_O = 43,
|
||||
AKEYCODE_P = 44,
|
||||
AKEYCODE_Q = 45,
|
||||
AKEYCODE_R = 46,
|
||||
AKEYCODE_S = 47,
|
||||
AKEYCODE_T = 48,
|
||||
AKEYCODE_U = 49,
|
||||
AKEYCODE_V = 50,
|
||||
AKEYCODE_W = 51,
|
||||
AKEYCODE_X = 52,
|
||||
AKEYCODE_Y = 53,
|
||||
AKEYCODE_Z = 54,
|
||||
AKEYCODE_COMMA = 55,
|
||||
AKEYCODE_PERIOD = 56,
|
||||
AKEYCODE_ALT_LEFT = 57,
|
||||
AKEYCODE_ALT_RIGHT = 58,
|
||||
AKEYCODE_SHIFT_LEFT = 59,
|
||||
AKEYCODE_SHIFT_RIGHT = 60,
|
||||
AKEYCODE_TAB = 61,
|
||||
AKEYCODE_SPACE = 62,
|
||||
AKEYCODE_SYM = 63,
|
||||
AKEYCODE_EXPLORER = 64,
|
||||
AKEYCODE_ENVELOPE = 65,
|
||||
AKEYCODE_ENTER = 66,
|
||||
AKEYCODE_DEL = 67,
|
||||
AKEYCODE_GRAVE = 68,
|
||||
AKEYCODE_MINUS = 69,
|
||||
AKEYCODE_EQUALS = 70,
|
||||
AKEYCODE_LEFT_BRACKET = 71,
|
||||
AKEYCODE_RIGHT_BRACKET = 72,
|
||||
AKEYCODE_BACKSLASH = 73,
|
||||
AKEYCODE_SEMICOLON = 74,
|
||||
AKEYCODE_APOSTROPHE = 75,
|
||||
AKEYCODE_SLASH = 76,
|
||||
AKEYCODE_AT = 77,
|
||||
AKEYCODE_NUM = 78,
|
||||
AKEYCODE_HEADSETHOOK = 79,
|
||||
AKEYCODE_FOCUS = 80, // *Camera* focus
|
||||
AKEYCODE_PLUS = 81,
|
||||
AKEYCODE_MENU = 82,
|
||||
AKEYCODE_NOTIFICATION = 83,
|
||||
AKEYCODE_SEARCH = 84,
|
||||
AKEYCODE_MEDIA_PLAY_PAUSE= 85,
|
||||
AKEYCODE_MEDIA_STOP = 86,
|
||||
AKEYCODE_MEDIA_NEXT = 87,
|
||||
AKEYCODE_MEDIA_PREVIOUS = 88,
|
||||
AKEYCODE_MEDIA_REWIND = 89,
|
||||
AKEYCODE_MEDIA_FAST_FORWARD = 90,
|
||||
AKEYCODE_MUTE = 91,
|
||||
AKEYCODE_PAGE_UP = 92,
|
||||
AKEYCODE_PAGE_DOWN = 93,
|
||||
AKEYCODE_PICTSYMBOLS = 94,
|
||||
AKEYCODE_SWITCH_CHARSET = 95,
|
||||
AKEYCODE_BUTTON_A = 96,
|
||||
AKEYCODE_BUTTON_B = 97,
|
||||
AKEYCODE_BUTTON_C = 98,
|
||||
AKEYCODE_BUTTON_X = 99,
|
||||
AKEYCODE_BUTTON_Y = 100,
|
||||
AKEYCODE_BUTTON_Z = 101,
|
||||
AKEYCODE_BUTTON_L1 = 102,
|
||||
AKEYCODE_BUTTON_R1 = 103,
|
||||
AKEYCODE_BUTTON_L2 = 104,
|
||||
AKEYCODE_BUTTON_R2 = 105,
|
||||
AKEYCODE_BUTTON_THUMBL = 106,
|
||||
AKEYCODE_BUTTON_THUMBR = 107,
|
||||
AKEYCODE_BUTTON_START = 108,
|
||||
AKEYCODE_BUTTON_SELECT = 109,
|
||||
AKEYCODE_BUTTON_MODE = 110,
|
||||
AKEYCODE_ESCAPE = 111,
|
||||
AKEYCODE_FORWARD_DEL = 112,
|
||||
AKEYCODE_CTRL_LEFT = 113,
|
||||
AKEYCODE_CTRL_RIGHT = 114,
|
||||
AKEYCODE_CAPS_LOCK = 115,
|
||||
AKEYCODE_SCROLL_LOCK = 116,
|
||||
AKEYCODE_META_LEFT = 117,
|
||||
AKEYCODE_META_RIGHT = 118,
|
||||
AKEYCODE_FUNCTION = 119,
|
||||
AKEYCODE_SYSRQ = 120,
|
||||
AKEYCODE_BREAK = 121,
|
||||
AKEYCODE_MOVE_HOME = 122,
|
||||
AKEYCODE_MOVE_END = 123,
|
||||
AKEYCODE_INSERT = 124,
|
||||
AKEYCODE_FORWARD = 125,
|
||||
AKEYCODE_MEDIA_PLAY = 126,
|
||||
AKEYCODE_MEDIA_PAUSE = 127,
|
||||
AKEYCODE_MEDIA_CLOSE = 128,
|
||||
AKEYCODE_MEDIA_EJECT = 129,
|
||||
AKEYCODE_MEDIA_RECORD = 130,
|
||||
AKEYCODE_F1 = 131,
|
||||
AKEYCODE_F2 = 132,
|
||||
AKEYCODE_F3 = 133,
|
||||
AKEYCODE_F4 = 134,
|
||||
AKEYCODE_F5 = 135,
|
||||
AKEYCODE_F6 = 136,
|
||||
AKEYCODE_F7 = 137,
|
||||
AKEYCODE_F8 = 138,
|
||||
AKEYCODE_F9 = 139,
|
||||
AKEYCODE_F10 = 140,
|
||||
AKEYCODE_F11 = 141,
|
||||
AKEYCODE_F12 = 142,
|
||||
AKEYCODE_NUM_LOCK = 143,
|
||||
AKEYCODE_NUMPAD_0 = 144,
|
||||
AKEYCODE_NUMPAD_1 = 145,
|
||||
AKEYCODE_NUMPAD_2 = 146,
|
||||
AKEYCODE_NUMPAD_3 = 147,
|
||||
AKEYCODE_NUMPAD_4 = 148,
|
||||
AKEYCODE_NUMPAD_5 = 149,
|
||||
AKEYCODE_NUMPAD_6 = 150,
|
||||
AKEYCODE_NUMPAD_7 = 151,
|
||||
AKEYCODE_NUMPAD_8 = 152,
|
||||
AKEYCODE_NUMPAD_9 = 153,
|
||||
AKEYCODE_NUMPAD_DIVIDE = 154,
|
||||
AKEYCODE_NUMPAD_MULTIPLY = 155,
|
||||
AKEYCODE_NUMPAD_SUBTRACT = 156,
|
||||
AKEYCODE_NUMPAD_ADD = 157,
|
||||
AKEYCODE_NUMPAD_DOT = 158,
|
||||
AKEYCODE_NUMPAD_COMMA = 159,
|
||||
AKEYCODE_NUMPAD_ENTER = 160,
|
||||
AKEYCODE_NUMPAD_EQUALS = 161,
|
||||
AKEYCODE_NUMPAD_LEFT_PAREN = 162,
|
||||
AKEYCODE_NUMPAD_RIGHT_PAREN = 163,
|
||||
AKEYCODE_VOLUME_MUTE = 164,
|
||||
AKEYCODE_INFO = 165,
|
||||
AKEYCODE_CHANNEL_UP = 166,
|
||||
AKEYCODE_CHANNEL_DOWN = 167,
|
||||
AKEYCODE_ZOOM_IN = 168,
|
||||
AKEYCODE_ZOOM_OUT = 169,
|
||||
AKEYCODE_TV = 170,
|
||||
AKEYCODE_WINDOW = 171,
|
||||
AKEYCODE_GUIDE = 172,
|
||||
AKEYCODE_DVR = 173,
|
||||
AKEYCODE_BOOKMARK = 174,
|
||||
AKEYCODE_CAPTIONS = 175,
|
||||
AKEYCODE_SETTINGS = 176,
|
||||
AKEYCODE_TV_POWER = 177,
|
||||
AKEYCODE_TV_INPUT = 178,
|
||||
AKEYCODE_STB_POWER = 179,
|
||||
AKEYCODE_STB_INPUT = 180,
|
||||
AKEYCODE_AVR_POWER = 181,
|
||||
AKEYCODE_AVR_INPUT = 182,
|
||||
AKEYCODE_PROG_RED = 183,
|
||||
AKEYCODE_PROG_GREEN = 184,
|
||||
AKEYCODE_PROG_YELLOW = 185,
|
||||
AKEYCODE_PROG_BLUE = 186,
|
||||
AKEYCODE_APP_SWITCH = 187,
|
||||
AKEYCODE_BUTTON_1 = 188,
|
||||
AKEYCODE_BUTTON_2 = 189,
|
||||
AKEYCODE_BUTTON_3 = 190,
|
||||
AKEYCODE_BUTTON_4 = 191,
|
||||
AKEYCODE_BUTTON_5 = 192,
|
||||
AKEYCODE_BUTTON_6 = 193,
|
||||
AKEYCODE_BUTTON_7 = 194,
|
||||
AKEYCODE_BUTTON_8 = 195,
|
||||
AKEYCODE_BUTTON_9 = 196,
|
||||
AKEYCODE_BUTTON_10 = 197,
|
||||
AKEYCODE_BUTTON_11 = 198,
|
||||
AKEYCODE_BUTTON_12 = 199,
|
||||
AKEYCODE_BUTTON_13 = 200,
|
||||
AKEYCODE_BUTTON_14 = 201,
|
||||
AKEYCODE_BUTTON_15 = 202,
|
||||
AKEYCODE_BUTTON_16 = 203,
|
||||
AKEYCODE_LANGUAGE_SWITCH = 204,
|
||||
AKEYCODE_MANNER_MODE = 205,
|
||||
AKEYCODE_3D_MODE = 206,
|
||||
AKEYCODE_CONTACTS = 207,
|
||||
AKEYCODE_CALENDAR = 208,
|
||||
AKEYCODE_MUSIC = 209,
|
||||
AKEYCODE_CALCULATOR = 210,
|
||||
|
||||
// NOTE: If you add a new keycode here you must also add it to several other files.
|
||||
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ANDROID_KEYCODES_H
|
|
@ -0,0 +1,554 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// C/C++ logging functions. See the logging documentation for API details.
|
||||
//
|
||||
// We'd like these to be available from C code (in case we import some from
|
||||
// somewhere), so this has a C interface.
|
||||
//
|
||||
// The output will be correct when the log file is shared between multiple
|
||||
// threads and/or multiple processes so long as the operating system
|
||||
// supports O_APPEND. These calls have mutex-protected data structures
|
||||
// and so are NOT reentrant. Do not use LOG in a signal handler.
|
||||
//
|
||||
#ifndef _LIBS_CUTILS_LOG_H
|
||||
#define _LIBS_CUTILS_LOG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <cutils/uio.h>
|
||||
#include <cutils/logd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Normally we strip ALOGV (VERBOSE messages) from release builds.
|
||||
* You can modify this (for example with "#define LOG_NDEBUG 0"
|
||||
* at the top of your source file) to change that behavior.
|
||||
*/
|
||||
#ifndef LOG_NDEBUG
|
||||
#ifdef NDEBUG
|
||||
#define LOG_NDEBUG 1
|
||||
#else
|
||||
#define LOG_NDEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the local tag used for the following simplified
|
||||
* logging macros. You can change this preprocessor definition
|
||||
* before using the other macros to change the tag.
|
||||
*/
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG NULL
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Simplified macro to send a verbose log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGV
|
||||
#if LOG_NDEBUG
|
||||
#define ALOGV(...) ((void)0)
|
||||
#else
|
||||
#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGV
|
||||
#define LOGV ALOGV
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
|
||||
|
||||
#ifndef ALOGV_IF
|
||||
#if LOG_NDEBUG
|
||||
#define ALOGV_IF(cond, ...) ((void)0)
|
||||
#else
|
||||
#define ALOGV_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGV_IF
|
||||
#define LOGV_IF ALOGV_IF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a debug log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGD
|
||||
#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGD
|
||||
#define LOGD ALOGD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALOGD_IF
|
||||
#define ALOGD_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGD_IF
|
||||
#define LOGD_IF ALOGD_IF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an info log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGI
|
||||
#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGI
|
||||
#define LOGI ALOGI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALOGI_IF
|
||||
#define ALOGI_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGI_IF
|
||||
#define LOGI_IF ALOGI_IF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a warning log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGW
|
||||
#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGW
|
||||
#define LOGW ALOGW
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALOGW_IF
|
||||
#define ALOGW_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGW_IF
|
||||
#define LOGW_IF ALOGW_IF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an error log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGE
|
||||
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGE
|
||||
#define LOGE ALOGE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALOGE_IF
|
||||
#define ALOGE_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOGE_IF
|
||||
#define LOGE_IF ALOGE_IF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* verbose priority.
|
||||
*/
|
||||
#ifndef IF_ALOGV
|
||||
#if LOG_NDEBUG
|
||||
#define IF_ALOGV() if (false)
|
||||
#else
|
||||
#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG)
|
||||
#endif
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef IF_LOGV
|
||||
#define IF_LOGV IF_ALOGV
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* debug priority.
|
||||
*/
|
||||
#ifndef IF_ALOGD
|
||||
#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG)
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef IF_LOGD
|
||||
#define IF_LOGD IF_ALOGD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* info priority.
|
||||
*/
|
||||
#ifndef IF_ALOGI
|
||||
#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG)
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef IF_LOGI
|
||||
#define IF_LOGI IF_ALOGI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* warn priority.
|
||||
*/
|
||||
#ifndef IF_ALOGW
|
||||
#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG)
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef IF_LOGW
|
||||
#define IF_LOGW IF_ALOGW
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* error priority.
|
||||
*/
|
||||
#ifndef IF_ALOGE
|
||||
#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG)
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef IF_LOGE
|
||||
#define IF_LOGE IF_ALOGE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Simplified macro to send a verbose system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGV
|
||||
#if LOG_NDEBUG
|
||||
#define SLOGV(...) ((void)0)
|
||||
#else
|
||||
#define SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
|
||||
|
||||
#ifndef SLOGV_IF
|
||||
#if LOG_NDEBUG
|
||||
#define SLOGV_IF(cond, ...) ((void)0)
|
||||
#else
|
||||
#define SLOGV_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a debug system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGD
|
||||
#define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGD_IF
|
||||
#define SLOGD_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an info system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGI
|
||||
#define SLOGI(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGI_IF
|
||||
#define SLOGI_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a warning system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGW
|
||||
#define SLOGW(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGW_IF
|
||||
#define SLOGW_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an error system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGE
|
||||
#define SLOGE(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGE_IF
|
||||
#define SLOGE_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Log a fatal error. If the given condition fails, this stops program
|
||||
* execution like a normal assertion, but also generating the given message.
|
||||
* It is NOT stripped from release builds. Note that the condition test
|
||||
* is -inverted- from the normal assert() semantics.
|
||||
*/
|
||||
#ifndef LOG_ALWAYS_FATAL_IF
|
||||
#define LOG_ALWAYS_FATAL_IF(cond, ...) \
|
||||
( (CONDITION(cond)) \
|
||||
? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
#ifndef LOG_ALWAYS_FATAL
|
||||
#define LOG_ALWAYS_FATAL(...) \
|
||||
( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
|
||||
* are stripped out of release builds.
|
||||
*/
|
||||
#if LOG_NDEBUG
|
||||
|
||||
#ifndef LOG_FATAL_IF
|
||||
#define LOG_FATAL_IF(cond, ...) ((void)0)
|
||||
#endif
|
||||
#ifndef LOG_FATAL
|
||||
#define LOG_FATAL(...) ((void)0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef LOG_FATAL_IF
|
||||
#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
|
||||
#endif
|
||||
#ifndef LOG_FATAL
|
||||
#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assertion that generates a log message when the assertion fails.
|
||||
* Stripped out of release builds. Uses the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOG_ASSERT
|
||||
#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
|
||||
//#define ALOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond)
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOG_ASSERT
|
||||
#define LOG_ASSERT ALOG_ASSERT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Basic log message macro.
|
||||
*
|
||||
* Example:
|
||||
* ALOG(LOG_WARN, NULL, "Failed with error %d", errno);
|
||||
*
|
||||
* The second argument may be NULL or "" to indicate the "global" tag.
|
||||
*/
|
||||
#ifndef ALOG
|
||||
#define ALOG(priority, tag, ...) \
|
||||
LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef LOG
|
||||
#define LOG ALOG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Log macro that allows you to specify a number for the priority.
|
||||
*/
|
||||
#ifndef LOG_PRI
|
||||
#define LOG_PRI(priority, tag, ...) \
|
||||
android_printLog(priority, tag, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Log macro that allows you to pass in a varargs ("args" is a va_list).
|
||||
*/
|
||||
#ifndef LOG_PRI_VA
|
||||
#define LOG_PRI_VA(priority, tag, fmt, args) \
|
||||
android_vprintLog(priority, NULL, tag, fmt, args)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional given a desired logging priority and tag.
|
||||
*/
|
||||
#ifndef IF_ALOG
|
||||
#define IF_ALOG(priority, tag) \
|
||||
if (android_testLog(ANDROID_##priority, tag))
|
||||
// Temporary measure for code still using old LOG macros.
|
||||
#ifndef IF_LOG
|
||||
#define IF_LOG IF_ALOG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Event logging.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Event log entry types. These must match up with the declarations in
|
||||
* java/android/android/util/EventLog.java.
|
||||
*/
|
||||
typedef enum {
|
||||
EVENT_TYPE_INT = 0,
|
||||
EVENT_TYPE_LONG = 1,
|
||||
EVENT_TYPE_STRING = 2,
|
||||
EVENT_TYPE_LIST = 3,
|
||||
} AndroidEventLogType;
|
||||
|
||||
|
||||
#ifndef LOG_EVENT_INT
|
||||
#define LOG_EVENT_INT(_tag, _value) { \
|
||||
int intBuf = _value; \
|
||||
(void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, \
|
||||
sizeof(intBuf)); \
|
||||
}
|
||||
#endif
|
||||
#ifndef LOG_EVENT_LONG
|
||||
#define LOG_EVENT_LONG(_tag, _value) { \
|
||||
long long longBuf = _value; \
|
||||
(void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, \
|
||||
sizeof(longBuf)); \
|
||||
}
|
||||
#endif
|
||||
#ifndef LOG_EVENT_STRING
|
||||
#define LOG_EVENT_STRING(_tag, _value) \
|
||||
((void) 0) /* not implemented -- must combine len with string */
|
||||
#endif
|
||||
/* TODO: something for LIST */
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
*
|
||||
* The stuff in the rest of this file should not be used directly.
|
||||
*/
|
||||
|
||||
#define android_printLog(prio, tag, fmt...) \
|
||||
__android_log_print(prio, tag, fmt)
|
||||
|
||||
#define android_vprintLog(prio, cond, tag, fmt...) \
|
||||
__android_log_vprint(prio, tag, fmt)
|
||||
|
||||
/* XXX Macros to work around syntax errors in places where format string
|
||||
* arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
|
||||
* (happens only in debug builds).
|
||||
*/
|
||||
|
||||
/* Returns 2nd arg. Used to substitute default value if caller's vararg list
|
||||
* is empty.
|
||||
*/
|
||||
#define __android_second(dummy, second, ...) second
|
||||
|
||||
/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
|
||||
* returns nothing.
|
||||
*/
|
||||
#define __android_rest(first, ...) , ## __VA_ARGS__
|
||||
|
||||
#define android_printAssert(cond, tag, fmt...) \
|
||||
__android_log_assert(cond, tag, \
|
||||
__android_second(0, ## fmt, NULL) __android_rest(fmt))
|
||||
|
||||
#define android_writeLog(prio, tag, text) \
|
||||
__android_log_write(prio, tag, text)
|
||||
|
||||
#define android_bWriteLog(tag, payload, len) \
|
||||
__android_log_bwrite(tag, payload, len)
|
||||
#define android_btWriteLog(tag, type, payload, len) \
|
||||
__android_log_btwrite(tag, type, payload, len)
|
||||
|
||||
// TODO: remove these prototypes and their users
|
||||
#define android_testLog(prio, tag) (1)
|
||||
#define android_writevLog(vec,num) do{}while(0)
|
||||
#define android_write1Log(str,len) do{}while (0)
|
||||
#define android_setMinPriority(tag, prio) do{}while(0)
|
||||
//#define android_logToCallback(func) do{}while(0)
|
||||
#define android_logToFile(tag, file) (0)
|
||||
#define android_logToFd(tag, fd) (0)
|
||||
|
||||
typedef enum {
|
||||
LOG_ID_MAIN = 0,
|
||||
LOG_ID_RADIO = 1,
|
||||
LOG_ID_EVENTS = 2,
|
||||
LOG_ID_SYSTEM = 3,
|
||||
|
||||
LOG_ID_MAX
|
||||
} log_id_t;
|
||||
|
||||
/*
|
||||
* Send a simple string to the log.
|
||||
*/
|
||||
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
|
||||
int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _LIBS_CUTILS_LOG_H
|
|
@ -0,0 +1,815 @@
|
|||
/****************************************************************************
|
||||
****************************************************************************
|
||||
***
|
||||
*** This header was automatically generated from a Linux kernel header
|
||||
*** of the same name, to make information necessary for userspace to
|
||||
*** call into the kernel available to libc. It contains only constants,
|
||||
*** structures, and macros generated from the original header, and thus,
|
||||
*** contains no copyrightable information.
|
||||
***
|
||||
*** To edit the content of this header, modify the corresponding
|
||||
*** source file (e.g. under external/kernel-headers/original/) then
|
||||
*** run bionic/libc/kernel/tools/update_all.py
|
||||
***
|
||||
*** Any manual change here will be lost the next time this script will
|
||||
*** be run. You've been warned!
|
||||
***
|
||||
****************************************************************************
|
||||
****************************************************************************/
|
||||
#ifndef _INPUT_H
|
||||
#define _INPUT_H
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/types.h>
|
||||
struct input_event {
|
||||
struct timeval time;
|
||||
__u16 type;
|
||||
__u16 code;
|
||||
__s32 value;
|
||||
};
|
||||
#define EV_VERSION 0x010001
|
||||
struct input_id {
|
||||
__u16 bustype;
|
||||
__u16 vendor;
|
||||
__u16 product;
|
||||
__u16 version;
|
||||
};
|
||||
struct input_absinfo {
|
||||
__s32 value;
|
||||
__s32 minimum;
|
||||
__s32 maximum;
|
||||
__s32 fuzz;
|
||||
__s32 flat;
|
||||
__s32 resolution;
|
||||
};
|
||||
struct input_keymap_entry {
|
||||
#define INPUT_KEYMAP_BY_INDEX (1 << 0)
|
||||
__u8 flags;
|
||||
__u8 len;
|
||||
__u16 index;
|
||||
__u32 keycode;
|
||||
__u8 scancode[32];
|
||||
};
|
||||
#define EVIOCGVERSION _IOR('E', 0x01, int)
|
||||
#define EVIOCGID _IOR('E', 0x02, struct input_id)
|
||||
#define EVIOCGREP _IOR('E', 0x03, unsigned int[2])
|
||||
#define EVIOCSREP _IOW('E', 0x03, unsigned int[2])
|
||||
#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2])
|
||||
#define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
|
||||
#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2])
|
||||
#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
|
||||
#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len)
|
||||
#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len)
|
||||
#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len)
|
||||
#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len)
|
||||
#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len)
|
||||
#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len)
|
||||
#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len)
|
||||
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len)
|
||||
#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len)
|
||||
#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo)
|
||||
#define EVIOCSABS(abs) _IOW('E', 0xc0 + abs, struct input_absinfo)
|
||||
#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect))
|
||||
#define EVIOCRMFF _IOW('E', 0x81, int)
|
||||
#define EVIOCGEFFECTS _IOR('E', 0x84, int)
|
||||
#define EVIOCGRAB _IOW('E', 0x90, int)
|
||||
#define INPUT_PROP_POINTER 0x00
|
||||
#define INPUT_PROP_DIRECT 0x01
|
||||
#define INPUT_PROP_BUTTONPAD 0x02
|
||||
#define INPUT_PROP_SEMI_MT 0x03
|
||||
#define INPUT_PROP_MAX 0x1f
|
||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||
#define EV_SYN 0x00
|
||||
#define EV_KEY 0x01
|
||||
#define EV_REL 0x02
|
||||
#define EV_ABS 0x03
|
||||
#define EV_MSC 0x04
|
||||
#define EV_SW 0x05
|
||||
#define EV_LED 0x11
|
||||
#define EV_SND 0x12
|
||||
#define EV_REP 0x14
|
||||
#define EV_FF 0x15
|
||||
#define EV_PWR 0x16
|
||||
#define EV_FF_STATUS 0x17
|
||||
#define EV_MAX 0x1f
|
||||
#define EV_CNT (EV_MAX+1)
|
||||
#define SYN_REPORT 0
|
||||
#define SYN_CONFIG 1
|
||||
#define SYN_MT_REPORT 2
|
||||
#define SYN_DROPPED 3
|
||||
#define KEY_RESERVED 0
|
||||
#define KEY_ESC 1
|
||||
#define KEY_1 2
|
||||
#define KEY_2 3
|
||||
#define KEY_3 4
|
||||
#define KEY_4 5
|
||||
#define KEY_5 6
|
||||
#define KEY_6 7
|
||||
#define KEY_7 8
|
||||
#define KEY_8 9
|
||||
#define KEY_9 10
|
||||
#define KEY_0 11
|
||||
#define KEY_MINUS 12
|
||||
#define KEY_EQUAL 13
|
||||
#define KEY_BACKSPACE 14
|
||||
#define KEY_TAB 15
|
||||
#define KEY_Q 16
|
||||
#define KEY_W 17
|
||||
#define KEY_E 18
|
||||
#define KEY_R 19
|
||||
#define KEY_T 20
|
||||
#define KEY_Y 21
|
||||
#define KEY_U 22
|
||||
#define KEY_I 23
|
||||
#define KEY_O 24
|
||||
#define KEY_P 25
|
||||
#define KEY_LEFTBRACE 26
|
||||
#define KEY_RIGHTBRACE 27
|
||||
#define KEY_ENTER 28
|
||||
#define KEY_LEFTCTRL 29
|
||||
#define KEY_A 30
|
||||
#define KEY_S 31
|
||||
#define KEY_D 32
|
||||
#define KEY_F 33
|
||||
#define KEY_G 34
|
||||
#define KEY_H 35
|
||||
#define KEY_J 36
|
||||
#define KEY_K 37
|
||||
#define KEY_L 38
|
||||
#define KEY_SEMICOLON 39
|
||||
#define KEY_APOSTROPHE 40
|
||||
#define KEY_GRAVE 41
|
||||
#define KEY_LEFTSHIFT 42
|
||||
#define KEY_BACKSLASH 43
|
||||
#define KEY_Z 44
|
||||
#define KEY_X 45
|
||||
#define KEY_C 46
|
||||
#define KEY_V 47
|
||||
#define KEY_B 48
|
||||
#define KEY_N 49
|
||||
#define KEY_M 50
|
||||
#define KEY_COMMA 51
|
||||
#define KEY_DOT 52
|
||||
#define KEY_SLASH 53
|
||||
#define KEY_RIGHTSHIFT 54
|
||||
#define KEY_KPASTERISK 55
|
||||
#define KEY_LEFTALT 56
|
||||
#define KEY_SPACE 57
|
||||
#define KEY_CAPSLOCK 58
|
||||
#define KEY_F1 59
|
||||
#define KEY_F2 60
|
||||
#define KEY_F3 61
|
||||
#define KEY_F4 62
|
||||
#define KEY_F5 63
|
||||
#define KEY_F6 64
|
||||
#define KEY_F7 65
|
||||
#define KEY_F8 66
|
||||
#define KEY_F9 67
|
||||
#define KEY_F10 68
|
||||
#define KEY_NUMLOCK 69
|
||||
#define KEY_SCROLLLOCK 70
|
||||
#define KEY_KP7 71
|
||||
#define KEY_KP8 72
|
||||
#define KEY_KP9 73
|
||||
#define KEY_KPMINUS 74
|
||||
#define KEY_KP4 75
|
||||
#define KEY_KP5 76
|
||||
#define KEY_KP6 77
|
||||
#define KEY_KPPLUS 78
|
||||
#define KEY_KP1 79
|
||||
#define KEY_KP2 80
|
||||
#define KEY_KP3 81
|
||||
#define KEY_KP0 82
|
||||
#define KEY_KPDOT 83
|
||||
#define KEY_ZENKAKUHANKAKU 85
|
||||
#define KEY_102ND 86
|
||||
#define KEY_F11 87
|
||||
#define KEY_F12 88
|
||||
#define KEY_RO 89
|
||||
#define KEY_KATAKANA 90
|
||||
#define KEY_HIRAGANA 91
|
||||
#define KEY_HENKAN 92
|
||||
#define KEY_KATAKANAHIRAGANA 93
|
||||
#define KEY_MUHENKAN 94
|
||||
#define KEY_KPJPCOMMA 95
|
||||
#define KEY_KPENTER 96
|
||||
#define KEY_RIGHTCTRL 97
|
||||
#define KEY_KPSLASH 98
|
||||
#define KEY_SYSRQ 99
|
||||
#define KEY_RIGHTALT 100
|
||||
#define KEY_LINEFEED 101
|
||||
#define KEY_HOME 102
|
||||
#define KEY_UP 103
|
||||
#define KEY_PAGEUP 104
|
||||
#define KEY_LEFT 105
|
||||
#define KEY_RIGHT 106
|
||||
#define KEY_END 107
|
||||
#define KEY_DOWN 108
|
||||
#define KEY_PAGEDOWN 109
|
||||
#define KEY_INSERT 110
|
||||
#define KEY_DELETE 111
|
||||
#define KEY_MACRO 112
|
||||
#define KEY_MUTE 113
|
||||
#define KEY_VOLUMEDOWN 114
|
||||
#define KEY_VOLUMEUP 115
|
||||
#define KEY_POWER 116
|
||||
#define KEY_KPEQUAL 117
|
||||
#define KEY_KPPLUSMINUS 118
|
||||
#define KEY_PAUSE 119
|
||||
#define KEY_SCALE 120
|
||||
#define KEY_KPCOMMA 121
|
||||
#define KEY_HANGEUL 122
|
||||
#define KEY_HANGUEL KEY_HANGEUL
|
||||
#define KEY_HANJA 123
|
||||
#define KEY_YEN 124
|
||||
#define KEY_LEFTMETA 125
|
||||
#define KEY_RIGHTMETA 126
|
||||
#define KEY_COMPOSE 127
|
||||
#define KEY_STOP 128
|
||||
#define KEY_AGAIN 129
|
||||
#define KEY_PROPS 130
|
||||
#define KEY_UNDO 131
|
||||
#define KEY_FRONT 132
|
||||
#define KEY_COPY 133
|
||||
#define KEY_OPEN 134
|
||||
#define KEY_PASTE 135
|
||||
#define KEY_FIND 136
|
||||
#define KEY_CUT 137
|
||||
#define KEY_HELP 138
|
||||
#define KEY_MENU 139
|
||||
#define KEY_CALC 140
|
||||
#define KEY_SETUP 141
|
||||
#define KEY_SLEEP 142
|
||||
#define KEY_WAKEUP 143
|
||||
#define KEY_FILE 144
|
||||
#define KEY_SENDFILE 145
|
||||
#define KEY_DELETEFILE 146
|
||||
#define KEY_XFER 147
|
||||
#define KEY_PROG1 148
|
||||
#define KEY_PROG2 149
|
||||
#define KEY_WWW 150
|
||||
#define KEY_MSDOS 151
|
||||
#define KEY_COFFEE 152
|
||||
#define KEY_SCREENLOCK KEY_COFFEE
|
||||
#define KEY_DIRECTION 153
|
||||
#define KEY_CYCLEWINDOWS 154
|
||||
#define KEY_MAIL 155
|
||||
#define KEY_BOOKMARKS 156
|
||||
#define KEY_COMPUTER 157
|
||||
#define KEY_BACK 158
|
||||
#define KEY_FORWARD 159
|
||||
#define KEY_CLOSECD 160
|
||||
#define KEY_EJECTCD 161
|
||||
#define KEY_EJECTCLOSECD 162
|
||||
#define KEY_NEXTSONG 163
|
||||
#define KEY_PLAYPAUSE 164
|
||||
#define KEY_PREVIOUSSONG 165
|
||||
#define KEY_STOPCD 166
|
||||
#define KEY_RECORD 167
|
||||
#define KEY_REWIND 168
|
||||
#define KEY_PHONE 169
|
||||
#define KEY_ISO 170
|
||||
#define KEY_CONFIG 171
|
||||
#define KEY_HOMEPAGE 172
|
||||
#define KEY_REFRESH 173
|
||||
#define KEY_EXIT 174
|
||||
#define KEY_MOVE 175
|
||||
#define KEY_EDIT 176
|
||||
#define KEY_SCROLLUP 177
|
||||
#define KEY_SCROLLDOWN 178
|
||||
#define KEY_KPLEFTPAREN 179
|
||||
#define KEY_KPRIGHTPAREN 180
|
||||
#define KEY_NEW 181
|
||||
#define KEY_REDO 182
|
||||
#define KEY_F13 183
|
||||
#define KEY_F14 184
|
||||
#define KEY_F15 185
|
||||
#define KEY_F16 186
|
||||
#define KEY_F17 187
|
||||
#define KEY_F18 188
|
||||
#define KEY_F19 189
|
||||
#define KEY_F20 190
|
||||
#define KEY_F21 191
|
||||
#define KEY_F22 192
|
||||
#define KEY_F23 193
|
||||
#define KEY_F24 194
|
||||
#define KEY_PLAYCD 200
|
||||
#define KEY_PAUSECD 201
|
||||
#define KEY_PROG3 202
|
||||
#define KEY_PROG4 203
|
||||
#define KEY_DASHBOARD 204
|
||||
#define KEY_SUSPEND 205
|
||||
#define KEY_CLOSE 206
|
||||
#define KEY_PLAY 207
|
||||
#define KEY_FASTFORWARD 208
|
||||
#define KEY_BASSBOOST 209
|
||||
#define KEY_PRINT 210
|
||||
#define KEY_HP 211
|
||||
#define KEY_CAMERA 212
|
||||
#define KEY_SOUND 213
|
||||
#define KEY_QUESTION 214
|
||||
#define KEY_EMAIL 215
|
||||
#define KEY_CHAT 216
|
||||
#define KEY_SEARCH 217
|
||||
#define KEY_CONNECT 218
|
||||
#define KEY_FINANCE 219
|
||||
#define KEY_SPORT 220
|
||||
#define KEY_SHOP 221
|
||||
#define KEY_ALTERASE 222
|
||||
#define KEY_CANCEL 223
|
||||
#define KEY_BRIGHTNESSDOWN 224
|
||||
#define KEY_BRIGHTNESSUP 225
|
||||
#define KEY_MEDIA 226
|
||||
#define KEY_SWITCHVIDEOMODE 227
|
||||
#define KEY_KBDILLUMTOGGLE 228
|
||||
#define KEY_KBDILLUMDOWN 229
|
||||
#define KEY_KBDILLUMUP 230
|
||||
#define KEY_SEND 231
|
||||
#define KEY_REPLY 232
|
||||
#define KEY_FORWARDMAIL 233
|
||||
#define KEY_SAVE 234
|
||||
#define KEY_DOCUMENTS 235
|
||||
#define KEY_BATTERY 236
|
||||
#define KEY_BLUETOOTH 237
|
||||
#define KEY_WLAN 238
|
||||
#define KEY_UWB 239
|
||||
#define KEY_UNKNOWN 240
|
||||
#define KEY_VIDEO_NEXT 241
|
||||
#define KEY_VIDEO_PREV 242
|
||||
#define KEY_BRIGHTNESS_CYCLE 243
|
||||
#define KEY_BRIGHTNESS_ZERO 244
|
||||
#define KEY_DISPLAY_OFF 245
|
||||
#define KEY_WIMAX 246
|
||||
#define KEY_RFKILL 247
|
||||
#define BTN_MISC 0x100
|
||||
#define BTN_0 0x100
|
||||
#define BTN_1 0x101
|
||||
#define BTN_2 0x102
|
||||
#define BTN_3 0x103
|
||||
#define BTN_4 0x104
|
||||
#define BTN_5 0x105
|
||||
#define BTN_6 0x106
|
||||
#define BTN_7 0x107
|
||||
#define BTN_8 0x108
|
||||
#define BTN_9 0x109
|
||||
#define BTN_MOUSE 0x110
|
||||
#define BTN_LEFT 0x110
|
||||
#define BTN_RIGHT 0x111
|
||||
#define BTN_MIDDLE 0x112
|
||||
#define BTN_SIDE 0x113
|
||||
#define BTN_EXTRA 0x114
|
||||
#define BTN_FORWARD 0x115
|
||||
#define BTN_BACK 0x116
|
||||
#define BTN_TASK 0x117
|
||||
#define BTN_JOYSTICK 0x120
|
||||
#define BTN_TRIGGER 0x120
|
||||
#define BTN_THUMB 0x121
|
||||
#define BTN_THUMB2 0x122
|
||||
#define BTN_TOP 0x123
|
||||
#define BTN_TOP2 0x124
|
||||
#define BTN_PINKIE 0x125
|
||||
#define BTN_BASE 0x126
|
||||
#define BTN_BASE2 0x127
|
||||
#define BTN_BASE3 0x128
|
||||
#define BTN_BASE4 0x129
|
||||
#define BTN_BASE5 0x12a
|
||||
#define BTN_BASE6 0x12b
|
||||
#define BTN_DEAD 0x12f
|
||||
#define BTN_GAMEPAD 0x130
|
||||
#define BTN_A 0x130
|
||||
#define BTN_B 0x131
|
||||
#define BTN_C 0x132
|
||||
#define BTN_X 0x133
|
||||
#define BTN_Y 0x134
|
||||
#define BTN_Z 0x135
|
||||
#define BTN_TL 0x136
|
||||
#define BTN_TR 0x137
|
||||
#define BTN_TL2 0x138
|
||||
#define BTN_TR2 0x139
|
||||
#define BTN_SELECT 0x13a
|
||||
#define BTN_START 0x13b
|
||||
#define BTN_MODE 0x13c
|
||||
#define BTN_THUMBL 0x13d
|
||||
#define BTN_THUMBR 0x13e
|
||||
#define BTN_DIGI 0x140
|
||||
#define BTN_TOOL_PEN 0x140
|
||||
#define BTN_TOOL_RUBBER 0x141
|
||||
#define BTN_TOOL_BRUSH 0x142
|
||||
#define BTN_TOOL_PENCIL 0x143
|
||||
#define BTN_TOOL_AIRBRUSH 0x144
|
||||
#define BTN_TOOL_FINGER 0x145
|
||||
#define BTN_TOOL_MOUSE 0x146
|
||||
#define BTN_TOOL_LENS 0x147
|
||||
#define BTN_TOUCH 0x14a
|
||||
#define BTN_STYLUS 0x14b
|
||||
#define BTN_STYLUS2 0x14c
|
||||
#define BTN_TOOL_DOUBLETAP 0x14d
|
||||
#define BTN_TOOL_TRIPLETAP 0x14e
|
||||
#define BTN_TOOL_QUADTAP 0x14f
|
||||
#define BTN_WHEEL 0x150
|
||||
#define BTN_GEAR_DOWN 0x150
|
||||
#define BTN_GEAR_UP 0x151
|
||||
#define KEY_OK 0x160
|
||||
#define KEY_SELECT 0x161
|
||||
#define KEY_GOTO 0x162
|
||||
#define KEY_CLEAR 0x163
|
||||
#define KEY_POWER2 0x164
|
||||
#define KEY_OPTION 0x165
|
||||
#define KEY_INFO 0x166
|
||||
#define KEY_TIME 0x167
|
||||
#define KEY_VENDOR 0x168
|
||||
#define KEY_ARCHIVE 0x169
|
||||
#define KEY_PROGRAM 0x16a
|
||||
#define KEY_CHANNEL 0x16b
|
||||
#define KEY_FAVORITES 0x16c
|
||||
#define KEY_EPG 0x16d
|
||||
#define KEY_PVR 0x16e
|
||||
#define KEY_MHP 0x16f
|
||||
#define KEY_LANGUAGE 0x170
|
||||
#define KEY_TITLE 0x171
|
||||
#define KEY_SUBTITLE 0x172
|
||||
#define KEY_ANGLE 0x173
|
||||
#define KEY_ZOOM 0x174
|
||||
#define KEY_MODE 0x175
|
||||
#define KEY_KEYBOARD 0x176
|
||||
#define KEY_SCREEN 0x177
|
||||
#define KEY_PC 0x178
|
||||
#define KEY_TV 0x179
|
||||
#define KEY_TV2 0x17a
|
||||
#define KEY_VCR 0x17b
|
||||
#define KEY_VCR2 0x17c
|
||||
#define KEY_SAT 0x17d
|
||||
#define KEY_SAT2 0x17e
|
||||
#define KEY_CD 0x17f
|
||||
#define KEY_TAPE 0x180
|
||||
#define KEY_RADIO 0x181
|
||||
#define KEY_TUNER 0x182
|
||||
#define KEY_PLAYER 0x183
|
||||
#define KEY_TEXT 0x184
|
||||
#define KEY_DVD 0x185
|
||||
#define KEY_AUX 0x186
|
||||
#define KEY_MP3 0x187
|
||||
#define KEY_AUDIO 0x188
|
||||
#define KEY_VIDEO 0x189
|
||||
#define KEY_DIRECTORY 0x18a
|
||||
#define KEY_LIST 0x18b
|
||||
#define KEY_MEMO 0x18c
|
||||
#define KEY_CALENDAR 0x18d
|
||||
#define KEY_RED 0x18e
|
||||
#define KEY_GREEN 0x18f
|
||||
#define KEY_YELLOW 0x190
|
||||
#define KEY_BLUE 0x191
|
||||
#define KEY_CHANNELUP 0x192
|
||||
#define KEY_CHANNELDOWN 0x193
|
||||
#define KEY_FIRST 0x194
|
||||
#define KEY_LAST 0x195
|
||||
#define KEY_AB 0x196
|
||||
#define KEY_NEXT 0x197
|
||||
#define KEY_RESTART 0x198
|
||||
#define KEY_SLOW 0x199
|
||||
#define KEY_SHUFFLE 0x19a
|
||||
#define KEY_BREAK 0x19b
|
||||
#define KEY_PREVIOUS 0x19c
|
||||
#define KEY_DIGITS 0x19d
|
||||
#define KEY_TEEN 0x19e
|
||||
#define KEY_TWEN 0x19f
|
||||
#define KEY_VIDEOPHONE 0x1a0
|
||||
#define KEY_GAMES 0x1a1
|
||||
#define KEY_ZOOMIN 0x1a2
|
||||
#define KEY_ZOOMOUT 0x1a3
|
||||
#define KEY_ZOOMRESET 0x1a4
|
||||
#define KEY_WORDPROCESSOR 0x1a5
|
||||
#define KEY_EDITOR 0x1a6
|
||||
#define KEY_SPREADSHEET 0x1a7
|
||||
#define KEY_GRAPHICSEDITOR 0x1a8
|
||||
#define KEY_PRESENTATION 0x1a9
|
||||
#define KEY_DATABASE 0x1aa
|
||||
#define KEY_NEWS 0x1ab
|
||||
#define KEY_VOICEMAIL 0x1ac
|
||||
#define KEY_ADDRESSBOOK 0x1ad
|
||||
#define KEY_MESSENGER 0x1ae
|
||||
#define KEY_DISPLAYTOGGLE 0x1af
|
||||
#define KEY_SPELLCHECK 0x1b0
|
||||
#define KEY_LOGOFF 0x1b1
|
||||
#define KEY_DOLLAR 0x1b2
|
||||
#define KEY_EURO 0x1b3
|
||||
#define KEY_FRAMEBACK 0x1b4
|
||||
#define KEY_FRAMEFORWARD 0x1b5
|
||||
#define KEY_CONTEXT_MENU 0x1b6
|
||||
#define KEY_MEDIA_REPEAT 0x1b7
|
||||
#define KEY_10CHANNELSUP 0x1b8
|
||||
#define KEY_10CHANNELSDOWN 0x1b9
|
||||
#define KEY_IMAGES 0x1ba
|
||||
#define KEY_DEL_EOL 0x1c0
|
||||
#define KEY_DEL_EOS 0x1c1
|
||||
#define KEY_INS_LINE 0x1c2
|
||||
#define KEY_DEL_LINE 0x1c3
|
||||
#define KEY_FN 0x1d0
|
||||
#define KEY_FN_ESC 0x1d1
|
||||
#define KEY_FN_F1 0x1d2
|
||||
#define KEY_FN_F2 0x1d3
|
||||
#define KEY_FN_F3 0x1d4
|
||||
#define KEY_FN_F4 0x1d5
|
||||
#define KEY_FN_F5 0x1d6
|
||||
#define KEY_FN_F6 0x1d7
|
||||
#define KEY_FN_F7 0x1d8
|
||||
#define KEY_FN_F8 0x1d9
|
||||
#define KEY_FN_F9 0x1da
|
||||
#define KEY_FN_F10 0x1db
|
||||
#define KEY_FN_F11 0x1dc
|
||||
#define KEY_FN_F12 0x1dd
|
||||
#define KEY_FN_1 0x1de
|
||||
#define KEY_FN_2 0x1df
|
||||
#define KEY_FN_D 0x1e0
|
||||
#define KEY_FN_E 0x1e1
|
||||
#define KEY_FN_F 0x1e2
|
||||
#define KEY_FN_S 0x1e3
|
||||
#define KEY_FN_B 0x1e4
|
||||
#define KEY_BRL_DOT1 0x1f1
|
||||
#define KEY_BRL_DOT2 0x1f2
|
||||
#define KEY_BRL_DOT3 0x1f3
|
||||
#define KEY_BRL_DOT4 0x1f4
|
||||
#define KEY_BRL_DOT5 0x1f5
|
||||
#define KEY_BRL_DOT6 0x1f6
|
||||
#define KEY_BRL_DOT7 0x1f7
|
||||
#define KEY_BRL_DOT8 0x1f8
|
||||
#define KEY_BRL_DOT9 0x1f9
|
||||
#define KEY_BRL_DOT10 0x1fa
|
||||
#define KEY_NUMERIC_0 0x200
|
||||
#define KEY_NUMERIC_1 0x201
|
||||
#define KEY_NUMERIC_2 0x202
|
||||
#define KEY_NUMERIC_3 0x203
|
||||
#define KEY_NUMERIC_4 0x204
|
||||
#define KEY_NUMERIC_5 0x205
|
||||
#define KEY_NUMERIC_6 0x206
|
||||
#define KEY_NUMERIC_7 0x207
|
||||
#define KEY_NUMERIC_8 0x208
|
||||
#define KEY_NUMERIC_9 0x209
|
||||
#define KEY_NUMERIC_STAR 0x20a
|
||||
#define KEY_NUMERIC_POUND 0x20b
|
||||
#define KEY_CAMERA_FOCUS 0x210
|
||||
#define KEY_WPS_BUTTON 0x211
|
||||
#define KEY_TOUCHPAD_TOGGLE 0x212
|
||||
#define KEY_TOUCHPAD_ON 0x213
|
||||
#define KEY_TOUCHPAD_OFF 0x214
|
||||
#define KEY_CAMERA_ZOOMIN 0x215
|
||||
#define KEY_CAMERA_ZOOMOUT 0x216
|
||||
#define KEY_CAMERA_UP 0x217
|
||||
#define KEY_CAMERA_DOWN 0x218
|
||||
#define KEY_CAMERA_LEFT 0x219
|
||||
#define KEY_CAMERA_RIGHT 0x21a
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||
#define BTN_TRIGGER_HAPPY3 0x2c2
|
||||
#define BTN_TRIGGER_HAPPY4 0x2c3
|
||||
#define BTN_TRIGGER_HAPPY5 0x2c4
|
||||
#define BTN_TRIGGER_HAPPY6 0x2c5
|
||||
#define BTN_TRIGGER_HAPPY7 0x2c6
|
||||
#define BTN_TRIGGER_HAPPY8 0x2c7
|
||||
#define BTN_TRIGGER_HAPPY9 0x2c8
|
||||
#define BTN_TRIGGER_HAPPY10 0x2c9
|
||||
#define BTN_TRIGGER_HAPPY11 0x2ca
|
||||
#define BTN_TRIGGER_HAPPY12 0x2cb
|
||||
#define BTN_TRIGGER_HAPPY13 0x2cc
|
||||
#define BTN_TRIGGER_HAPPY14 0x2cd
|
||||
#define BTN_TRIGGER_HAPPY15 0x2ce
|
||||
#define BTN_TRIGGER_HAPPY16 0x2cf
|
||||
#define BTN_TRIGGER_HAPPY17 0x2d0
|
||||
#define BTN_TRIGGER_HAPPY18 0x2d1
|
||||
#define BTN_TRIGGER_HAPPY19 0x2d2
|
||||
#define BTN_TRIGGER_HAPPY20 0x2d3
|
||||
#define BTN_TRIGGER_HAPPY21 0x2d4
|
||||
#define BTN_TRIGGER_HAPPY22 0x2d5
|
||||
#define BTN_TRIGGER_HAPPY23 0x2d6
|
||||
#define BTN_TRIGGER_HAPPY24 0x2d7
|
||||
#define BTN_TRIGGER_HAPPY25 0x2d8
|
||||
#define BTN_TRIGGER_HAPPY26 0x2d9
|
||||
#define BTN_TRIGGER_HAPPY27 0x2da
|
||||
#define BTN_TRIGGER_HAPPY28 0x2db
|
||||
#define BTN_TRIGGER_HAPPY29 0x2dc
|
||||
#define BTN_TRIGGER_HAPPY30 0x2dd
|
||||
#define BTN_TRIGGER_HAPPY31 0x2de
|
||||
#define BTN_TRIGGER_HAPPY32 0x2df
|
||||
#define BTN_TRIGGER_HAPPY33 0x2e0
|
||||
#define BTN_TRIGGER_HAPPY34 0x2e1
|
||||
#define BTN_TRIGGER_HAPPY35 0x2e2
|
||||
#define BTN_TRIGGER_HAPPY36 0x2e3
|
||||
#define BTN_TRIGGER_HAPPY37 0x2e4
|
||||
#define BTN_TRIGGER_HAPPY38 0x2e5
|
||||
#define BTN_TRIGGER_HAPPY39 0x2e6
|
||||
#define BTN_TRIGGER_HAPPY40 0x2e7
|
||||
#define KEY_MIN_INTERESTING KEY_MUTE
|
||||
#define KEY_MAX 0x2ff
|
||||
#define KEY_CNT (KEY_MAX+1)
|
||||
#define REL_X 0x00
|
||||
#define REL_Y 0x01
|
||||
#define REL_Z 0x02
|
||||
#define REL_RX 0x03
|
||||
#define REL_RY 0x04
|
||||
#define REL_RZ 0x05
|
||||
#define REL_HWHEEL 0x06
|
||||
#define REL_DIAL 0x07
|
||||
#define REL_WHEEL 0x08
|
||||
#define REL_MISC 0x09
|
||||
#define REL_MAX 0x0f
|
||||
#define REL_CNT (REL_MAX+1)
|
||||
#define ABS_X 0x00
|
||||
#define ABS_Y 0x01
|
||||
#define ABS_Z 0x02
|
||||
#define ABS_RX 0x03
|
||||
#define ABS_RY 0x04
|
||||
#define ABS_RZ 0x05
|
||||
#define ABS_THROTTLE 0x06
|
||||
#define ABS_RUDDER 0x07
|
||||
#define ABS_WHEEL 0x08
|
||||
#define ABS_GAS 0x09
|
||||
#define ABS_BRAKE 0x0a
|
||||
#define ABS_HAT0X 0x10
|
||||
#define ABS_HAT0Y 0x11
|
||||
#define ABS_HAT1X 0x12
|
||||
#define ABS_HAT1Y 0x13
|
||||
#define ABS_HAT2X 0x14
|
||||
#define ABS_HAT2Y 0x15
|
||||
#define ABS_HAT3X 0x16
|
||||
#define ABS_HAT3Y 0x17
|
||||
#define ABS_PRESSURE 0x18
|
||||
#define ABS_DISTANCE 0x19
|
||||
#define ABS_TILT_X 0x1a
|
||||
#define ABS_TILT_Y 0x1b
|
||||
#define ABS_TOOL_WIDTH 0x1c
|
||||
#define ABS_VOLUME 0x20
|
||||
#define ABS_MISC 0x28
|
||||
#define ABS_MT_SLOT 0x2f
|
||||
#define ABS_MT_TOUCH_MAJOR 0x30
|
||||
#define ABS_MT_TOUCH_MINOR 0x31
|
||||
#define ABS_MT_WIDTH_MAJOR 0x32
|
||||
#define ABS_MT_WIDTH_MINOR 0x33
|
||||
#define ABS_MT_ORIENTATION 0x34
|
||||
#define ABS_MT_POSITION_X 0x35
|
||||
#define ABS_MT_POSITION_Y 0x36
|
||||
#define ABS_MT_TOOL_TYPE 0x37
|
||||
#define ABS_MT_BLOB_ID 0x38
|
||||
#define ABS_MT_TRACKING_ID 0x39
|
||||
#define ABS_MT_PRESSURE 0x3a
|
||||
#define ABS_MT_DISTANCE 0x3b
|
||||
#define ABS_MAX 0x3f
|
||||
#define ABS_CNT (ABS_MAX+1)
|
||||
#define SW_LID 0x00
|
||||
#define SW_TABLET_MODE 0x01
|
||||
#define SW_HEADPHONE_INSERT 0x02
|
||||
#define SW_RFKILL_ALL 0x03
|
||||
#define SW_RADIO SW_RFKILL_ALL
|
||||
#define SW_MICROPHONE_INSERT 0x04
|
||||
#define SW_DOCK 0x05
|
||||
#define SW_LINEOUT_INSERT 0x06
|
||||
#define SW_JACK_PHYSICAL_INSERT 0x07
|
||||
#define SW_VIDEOOUT_INSERT 0x08
|
||||
#define SW_CAMERA_LENS_COVER 0x09
|
||||
#define SW_KEYPAD_SLIDE 0x0a
|
||||
#define SW_FRONT_PROXIMITY 0x0b
|
||||
#define SW_ROTATE_LOCK 0x0c
|
||||
#define SW_MAX 0x0f
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
#define MSC_SERIAL 0x00
|
||||
#define MSC_PULSELED 0x01
|
||||
#define MSC_GESTURE 0x02
|
||||
#define MSC_RAW 0x03
|
||||
#define MSC_SCAN 0x04
|
||||
#define MSC_MAX 0x07
|
||||
#define MSC_CNT (MSC_MAX+1)
|
||||
#define LED_NUML 0x00
|
||||
#define LED_CAPSL 0x01
|
||||
#define LED_SCROLLL 0x02
|
||||
#define LED_COMPOSE 0x03
|
||||
#define LED_KANA 0x04
|
||||
#define LED_SLEEP 0x05
|
||||
#define LED_SUSPEND 0x06
|
||||
#define LED_MUTE 0x07
|
||||
#define LED_MISC 0x08
|
||||
#define LED_MAIL 0x09
|
||||
#define LED_CHARGING 0x0a
|
||||
#define LED_MAX 0x0f
|
||||
#define LED_CNT (LED_MAX+1)
|
||||
#define REP_DELAY 0x00
|
||||
#define REP_PERIOD 0x01
|
||||
#define REP_MAX 0x01
|
||||
#define REP_CNT (REP_MAX+1)
|
||||
#define SND_CLICK 0x00
|
||||
#define SND_BELL 0x01
|
||||
#define SND_TONE 0x02
|
||||
#define SND_MAX 0x07
|
||||
#define SND_CNT (SND_MAX+1)
|
||||
#define ID_BUS 0
|
||||
#define ID_VENDOR 1
|
||||
#define ID_PRODUCT 2
|
||||
#define ID_VERSION 3
|
||||
#define BUS_PCI 0x01
|
||||
#define BUS_ISAPNP 0x02
|
||||
#define BUS_USB 0x03
|
||||
#define BUS_HIL 0x04
|
||||
#define BUS_BLUETOOTH 0x05
|
||||
#define BUS_VIRTUAL 0x06
|
||||
#define BUS_ISA 0x10
|
||||
#define BUS_I8042 0x11
|
||||
#define BUS_XTKBD 0x12
|
||||
#define BUS_RS232 0x13
|
||||
#define BUS_GAMEPORT 0x14
|
||||
#define BUS_PARPORT 0x15
|
||||
#define BUS_AMIGA 0x16
|
||||
#define BUS_ADB 0x17
|
||||
#define BUS_I2C 0x18
|
||||
#define BUS_HOST 0x19
|
||||
#define BUS_GSC 0x1A
|
||||
#define BUS_ATARI 0x1B
|
||||
#define BUS_SPI 0x1C
|
||||
#define MT_TOOL_FINGER 0
|
||||
#define MT_TOOL_PEN 1
|
||||
#define MT_TOOL_MAX 1
|
||||
#define FF_STATUS_STOPPED 0x00
|
||||
#define FF_STATUS_PLAYING 0x01
|
||||
#define FF_STATUS_MAX 0x01
|
||||
struct ff_replay {
|
||||
__u16 length;
|
||||
__u16 delay;
|
||||
};
|
||||
struct ff_trigger {
|
||||
__u16 button;
|
||||
__u16 interval;
|
||||
};
|
||||
struct ff_envelope {
|
||||
__u16 attack_length;
|
||||
__u16 attack_level;
|
||||
__u16 fade_length;
|
||||
__u16 fade_level;
|
||||
};
|
||||
struct ff_constant_effect {
|
||||
__s16 level;
|
||||
struct ff_envelope envelope;
|
||||
};
|
||||
struct ff_ramp_effect {
|
||||
__s16 start_level;
|
||||
__s16 end_level;
|
||||
struct ff_envelope envelope;
|
||||
};
|
||||
struct ff_condition_effect {
|
||||
__u16 right_saturation;
|
||||
__u16 left_saturation;
|
||||
__s16 right_coeff;
|
||||
__s16 left_coeff;
|
||||
__u16 deadband;
|
||||
__s16 center;
|
||||
};
|
||||
struct ff_periodic_effect {
|
||||
__u16 waveform;
|
||||
__u16 period;
|
||||
__s16 magnitude;
|
||||
__s16 offset;
|
||||
__u16 phase;
|
||||
struct ff_envelope envelope;
|
||||
__u32 custom_len;
|
||||
__s16 *custom_data;
|
||||
};
|
||||
struct ff_rumble_effect {
|
||||
__u16 strong_magnitude;
|
||||
__u16 weak_magnitude;
|
||||
};
|
||||
struct ff_effect {
|
||||
__u16 type;
|
||||
__s16 id;
|
||||
__u16 direction;
|
||||
struct ff_trigger trigger;
|
||||
struct ff_replay replay;
|
||||
union {
|
||||
struct ff_constant_effect constant;
|
||||
struct ff_ramp_effect ramp;
|
||||
struct ff_periodic_effect periodic;
|
||||
struct ff_condition_effect condition[2];
|
||||
struct ff_rumble_effect rumble;
|
||||
} u;
|
||||
};
|
||||
#define FF_RUMBLE 0x50
|
||||
#define FF_PERIODIC 0x51
|
||||
#define FF_CONSTANT 0x52
|
||||
#define FF_SPRING 0x53
|
||||
#define FF_FRICTION 0x54
|
||||
#define FF_DAMPER 0x55
|
||||
#define FF_INERTIA 0x56
|
||||
#define FF_RAMP 0x57
|
||||
#define FF_EFFECT_MIN FF_RUMBLE
|
||||
#define FF_EFFECT_MAX FF_RAMP
|
||||
#define FF_SQUARE 0x58
|
||||
#define FF_TRIANGLE 0x59
|
||||
#define FF_SINE 0x5a
|
||||
#define FF_SAW_UP 0x5b
|
||||
#define FF_SAW_DOWN 0x5c
|
||||
#define FF_CUSTOM 0x5d
|
||||
#define FF_WAVEFORM_MIN FF_SQUARE
|
||||
#define FF_WAVEFORM_MAX FF_CUSTOM
|
||||
#define FF_GAIN 0x60
|
||||
#define FF_AUTOCENTER 0x61
|
||||
#define FF_MAX 0x7f
|
||||
#define FF_CNT (FF_MAX+1)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// C/C++ logging functions. See the logging documentation for API details.
|
||||
//
|
||||
// We'd like these to be available from C code (in case we import some from
|
||||
// somewhere), so this has a C interface.
|
||||
//
|
||||
// The output will be correct when the log file is shared between multiple
|
||||
// threads and/or multiple processes so long as the operating system
|
||||
// supports O_APPEND. These calls have mutex-protected data structures
|
||||
// and so are NOT reentrant. Do not use LOG in a signal handler.
|
||||
//
|
||||
#ifndef _LIBS_UTILS_LOG_H
|
||||
#define _LIBS_UTILS_LOG_H
|
||||
|
||||
#include "cutils_log.h"
|
||||
|
||||
#endif // _LIBS_UTILS_LOG_H
|
|
@ -678,7 +678,8 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
|||
for (int i = 0; i < event_count; i++)
|
||||
mHandlers[events[i].data.u32].run();
|
||||
|
||||
mDispatcher->dispatchOnce();
|
||||
if (mDispatcher.get())
|
||||
mDispatcher->dispatchOnce();
|
||||
|
||||
// NativeEventCallback always schedules more if it needs it
|
||||
// so we can coalesce these.
|
||||
|
|
Загрузка…
Ссылка в новой задаче