auto merge of #4306 : michaelwu/servo/gonk-port-three, r=glennw

Trying again since critic didn't notice https://github.com/servo/servo/pull/4294 .
This commit is contained in:
bors-servo 2014-12-09 14:42:57 -07:00
commit cbbbf4fbb5
9 changed files with 2120 additions and 0 deletions

3
ports/gonk/.cargo/config Normal file
View file

@ -0,0 +1,3 @@
[target.arm-linux-androideabi]
ar = "arm-linux-androideabi-ar"
linker = "arm-linux-androideabi-g++"

652
ports/gonk/Cargo.lock generated Normal file
View file

@ -0,0 +1,652 @@
[root]
name = "b2s"
version = "0.0.1"
dependencies = [
"compositing 0.0.1",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"msg 0.0.1",
"script 0.0.1",
"servo 0.0.1",
"util 0.0.1",
]
[[package]]
name = "azure"
version = "0.1.0"
source = "git+https://github.com/servo/rust-azure#d323c3c7c248d3d5a2d46a6a5ee61c6e92aec0b0"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
"core_text 0.1.0 (git+https://github.com/servo/rust-core-text)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"skia-sys 0.0.20130412 (git+https://github.com/servo/skia)",
"xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
]
[[package]]
name = "canvas"
version = "0.0.1"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"util 0.0.1",
]
[[package]]
name = "cgl"
version = "0.0.1"
source = "git+https://github.com/servo/rust-cgl#7b7090729f65e2287c3d80651df02e547911b119"
dependencies = [
"gleam 0.0.1 (git+https://github.com/servo/gleam)",
]
[[package]]
name = "compositing"
version = "0.0.1"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
"core_text 0.1.0 (git+https://github.com/servo/rust-core-text)",
"devtools 0.0.1",
"devtools_traits 0.0.1",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"gfx 0.0.1",
"gleam 0.0.1 (git+https://github.com/servo/gleam)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1",
"msg 0.0.1",
"net 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"script_traits 0.0.1",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "cookie"
version = "0.0.1"
source = "git+https://github.com/servo/cookie-rs#30520767a95b92e39265aaf6822db515b2418f1d"
dependencies = [
"openssl 0.0.1 (git+https://github.com/servo/rust-openssl)",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
]
[[package]]
name = "core_foundation"
version = "0.1.0"
source = "git+https://github.com/servo/rust-core-foundation#6fa0b908f3912e20d081193e83bf5a9aa958fb83"
[[package]]
name = "core_graphics"
version = "0.1.0"
source = "git+https://github.com/servo/rust-core-graphics#9434e2bda65d259f825104170b5fa6cc6dbaf5a9"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
]
[[package]]
name = "core_text"
version = "0.1.0"
source = "git+https://github.com/servo/rust-core-text#85784007b6fa1b8f9614059edcd0429b2bd69a11"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
]
[[package]]
name = "cssparser"
version = "0.1.0"
source = "git+https://github.com/servo/rust-cssparser#cbbfd66f794bd019bbdeaefc88b29eff455b62e5"
dependencies = [
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
]
[[package]]
name = "devtools"
version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"msg 0.0.1",
"util 0.0.1",
]
[[package]]
name = "devtools_traits"
version = "0.0.1"
dependencies = [
"msg 0.0.1",
]
[[package]]
name = "egl"
version = "0.1.0"
source = "git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220"
[[package]]
name = "encoding"
version = "0.2.0"
source = "git+https://github.com/lifthrasiir/rust-encoding#a06637cc6d0da37c12c68661e2ee9ca1999764a4"
dependencies = [
"encoding-index-japanese 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
"encoding-index-korean 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
"encoding-index-simpchinese 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
"encoding-index-singlebyte 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
"encoding-index-tradchinese 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
]
[[package]]
name = "encoding-index-japanese"
version = "1.0.20140915"
source = "git+https://github.com/lifthrasiir/rust-encoding#a06637cc6d0da37c12c68661e2ee9ca1999764a4"
[[package]]
name = "encoding-index-korean"
version = "1.0.20140915"
source = "git+https://github.com/lifthrasiir/rust-encoding#a06637cc6d0da37c12c68661e2ee9ca1999764a4"
[[package]]
name = "encoding-index-simpchinese"
version = "1.0.20140915"
source = "git+https://github.com/lifthrasiir/rust-encoding#a06637cc6d0da37c12c68661e2ee9ca1999764a4"
[[package]]
name = "encoding-index-singlebyte"
version = "1.0.20140915"
source = "git+https://github.com/lifthrasiir/rust-encoding#a06637cc6d0da37c12c68661e2ee9ca1999764a4"
[[package]]
name = "encoding-index-tradchinese"
version = "1.0.20140915"
source = "git+https://github.com/lifthrasiir/rust-encoding#a06637cc6d0da37c12c68661e2ee9ca1999764a4"
[[package]]
name = "expat-sys"
version = "2.1.0"
source = "git+https://github.com/servo/libexpat#da2ddaf78cbef836b8790807bb76b357c58df3a1"
[[package]]
name = "fontconfig"
version = "0.1.0"
source = "git+https://github.com/servo/rust-fontconfig#f42ff5cbd0404fe4d2cd64e8d9bb6307bad8fd7c"
dependencies = [
"fontconfig-sys 2.11.1 (git+https://github.com/servo/libfontconfig)",
]
[[package]]
name = "fontconfig-sys"
version = "2.11.1"
source = "git+https://github.com/servo/libfontconfig#fcc324d2c8175d2e8e8c0aab032c03a404809f6d"
dependencies = [
"expat-sys 2.1.0 (git+https://github.com/servo/libexpat)",
"freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)",
]
[[package]]
name = "freetype"
version = "0.1.0"
source = "git+https://github.com/servo/rust-freetype#e55b06110fb2d74a2db68ead740db7e98fb98060"
[[package]]
name = "freetype-sys"
version = "2.4.11"
source = "git+https://github.com/servo/libfreetype2#5b6499164106f094937565595c7b96d07de55521"
[[package]]
name = "geom"
version = "0.1.0"
source = "git+https://github.com/servo/rust-geom#e5e74911ac6d3201009879b72499d6c681302611"
[[package]]
name = "gfx"
version = "0.0.1"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
"core_text 0.1.0 (git+https://github.com/servo/rust-core-text)",
"fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"msg 0.0.1",
"net 0.0.1",
"plugins 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"script_traits 0.0.1",
"stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
"style 0.0.1",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "gl_common"
version = "0.0.1"
source = "git+https://github.com/bjz/gl-rs.git#79cd3b3f9f19aa0e39f6af572fc8673a6d9760bc"
[[package]]
name = "gl_generator"
version = "0.0.1"
source = "git+https://github.com/bjz/gl-rs.git#79cd3b3f9f19aa0e39f6af572fc8673a6d9760bc"
dependencies = [
"gl_common 0.0.1 (git+https://github.com/bjz/gl-rs.git)",
"khronos_api 0.0.1 (git+https://github.com/bjz/gl-rs.git)",
"rust-xml 0.1.0 (git+https://github.com/netvl/rust-xml)",
]
[[package]]
name = "gleam"
version = "0.0.1"
source = "git+https://github.com/servo/gleam#aaea38be25ce9de6e1e8620fa5b554669ac6475c"
dependencies = [
"gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)",
]
[[package]]
name = "glx"
version = "0.0.1"
source = "git+https://github.com/servo/rust-glx#7126ffa09fcfcc9f85f1406f3b5db729f5fdb7c3"
dependencies = [
"gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)",
]
[[package]]
name = "green"
version = "0.0.1"
source = "git+https://github.com/servo/green-rs?ref=servo#9300d7e7dc73680c7446d78b10a309095636e64d"
[[package]]
name = "harfbuzz"
version = "0.1.0"
source = "git+https://github.com/servo/rust-harfbuzz#8aab215463214647b7a81f66011da552bbb1121c"
[[package]]
name = "html5ever"
version = "0.0.0"
source = "git+https://github.com/servo/html5ever?ref=servo#87c7e8b710391338b2463652be835f498923653c"
dependencies = [
"html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever?ref=servo)",
"phf 0.0.0 (git+https://github.com/sfackler/rust-phf)",
"phf_mac 0.0.0 (git+https://github.com/sfackler/rust-phf)",
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
]
[[package]]
name = "html5ever_macros"
version = "0.0.0"
source = "git+https://github.com/servo/html5ever?ref=servo#87c7e8b710391338b2463652be835f498923653c"
[[package]]
name = "hyper"
version = "0.0.1"
source = "git+https://github.com/servo/hyper?ref=servo#dd9d1830f35f7a8371b1b3bcb2d3e9cf2763f33f"
dependencies = [
"cookie 0.0.1 (git+https://github.com/servo/cookie-rs)",
"mime 0.0.1 (git+https://github.com/hyperium/mime.rs)",
"move-acceptor 0.0.1 (git+https://github.com/reem/rust-move-acceptor)",
"openssl 0.0.1 (git+https://github.com/servo/rust-openssl)",
"typeable 0.0.3 (git+https://github.com/reem/rust-typeable)",
"unsafe-any 0.1.1 (git+https://github.com/reem/rust-unsafe-any)",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
]
[[package]]
name = "io_surface"
version = "0.1.0"
source = "git+https://github.com/servo/rust-io-surface#691cbccc320c4fb9b75e215da9b0b82539d729bd"
dependencies = [
"cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"gleam 0.0.1 (git+https://github.com/servo/gleam)",
]
[[package]]
name = "js"
version = "0.1.0"
source = "git+https://github.com/servo/rust-mozjs#2a7acd8c04949796c71145db61b7868128e497f2"
dependencies = [
"green 0.0.1 (git+https://github.com/servo/green-rs?ref=servo)",
"mozjs-sys 0.0.0 (git+https://github.com/servo/mozjs)",
"rustuv 0.0.1 (git+https://github.com/servo/green-rs?ref=servo)",
]
[[package]]
name = "khronos_api"
version = "0.0.1"
source = "git+https://github.com/bjz/gl-rs.git#79cd3b3f9f19aa0e39f6af572fc8673a6d9760bc"
[[package]]
name = "layers"
version = "0.1.0"
source = "git+https://github.com/servo/rust-layers#b068d2a96d54bf173b548aece36f5ea4ef9353cf"
dependencies = [
"cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"gleam 0.0.1 (git+https://github.com/servo/gleam)",
"glx 0.0.1 (git+https://github.com/servo/rust-glx)",
"io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)",
"xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
]
[[package]]
name = "layout"
version = "0.0.1"
dependencies = [
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"gfx 0.0.1",
"layout_traits 0.0.1",
"net 0.0.1",
"plugins 0.0.1",
"script 0.0.1",
"script_traits 0.0.1",
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
"style 0.0.1",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "layout_traits"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
"msg 0.0.1",
"net 0.0.1",
"script_traits 0.0.1",
"util 0.0.1",
]
[[package]]
name = "lazy_static"
version = "0.1.0"
source = "git+https://github.com/Kimundi/lazy-static.rs#62976cb611c5396e11315ae64c9c389576240eb7"
[[package]]
name = "libressl-pnacl-sys"
version = "2.0.2"
source = "git+https://github.com/DiamondLovesYou/libressl-pnacl-sys.git#8e9349e0280b069bfab247a2202cd10b8beae154"
dependencies = [
"pnacl-build-helper 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mime"
version = "0.0.1"
source = "git+https://github.com/hyperium/mime.rs#5264e04655974f85c8d6581395cc24597266c653"
[[package]]
name = "move-acceptor"
version = "0.0.1"
source = "git+https://github.com/reem/rust-move-acceptor#25c5c33a83f605fdd0f3d37d2589e2b0b4e6cbd1"
[[package]]
name = "mozjs-sys"
version = "0.0.0"
source = "git+https://github.com/servo/mozjs#0dd618fcc78fe7aa64e4e2a3b0f7f0d8a2f0f08a"
[[package]]
name = "msg"
version = "0.0.1"
dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)",
"io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "net"
version = "0.0.1"
dependencies = [
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "openssl"
version = "0.0.1"
source = "git+https://github.com/servo/rust-openssl#0a3cace0265fe286b505508aa6e5096fc94a6896"
dependencies = [
"libressl-pnacl-sys 2.0.2 (git+https://github.com/DiamondLovesYou/libressl-pnacl-sys.git)",
"openssl-sys 0.0.1 (git+https://github.com/servo/rust-openssl)",
]
[[package]]
name = "openssl-sys"
version = "0.0.1"
source = "git+https://github.com/servo/rust-openssl#0a3cace0265fe286b505508aa6e5096fc94a6896"
dependencies = [
"pkg-config 0.1.0 (git+https://github.com/alexcrichton/pkg-config-rs)",
]
[[package]]
name = "phf"
version = "0.0.0"
source = "git+https://github.com/sfackler/rust-phf#18a5ecc028055c3dbd650cc5a064b6fb033d82ef"
dependencies = [
"xxhash 0.0.1 (git+https://github.com/Jurily/rust-xxhash)",
]
[[package]]
name = "phf_mac"
version = "0.0.0"
source = "git+https://github.com/sfackler/rust-phf#18a5ecc028055c3dbd650cc5a064b6fb033d82ef"
dependencies = [
"xxhash 0.0.1 (git+https://github.com/Jurily/rust-xxhash)",
]
[[package]]
name = "pkg-config"
version = "0.1.0"
source = "git+https://github.com/alexcrichton/pkg-config-rs#9b3b44a2e1a8ccc70c3f701aeb5154ad79e665e9"
[[package]]
name = "plugins"
version = "0.0.1"
[[package]]
name = "pnacl-build-helper"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "png"
version = "0.1.0"
source = "git+https://github.com/servo/rust-png#b0b4acde0080dd475dee93615276bfc19207a21e"
dependencies = [
"png-sys 1.6.3 (git+https://github.com/servo/libpng?ref=servo)",
]
[[package]]
name = "png-sys"
version = "1.6.3"
source = "git+https://github.com/servo/libpng?ref=servo#d01f32b4eb86904695efe7fc02b574f902e21a98"
[[package]]
name = "rust-xml"
version = "0.1.0"
source = "git+https://github.com/netvl/rust-xml#d6c57380a300b94f7e7881979dbe5459dbe4ca06"
[[package]]
name = "rustuv"
version = "0.0.1"
source = "git+https://github.com/servo/green-rs?ref=servo#9300d7e7dc73680c7446d78b10a309095636e64d"
dependencies = [
"green 0.0.1 (git+https://github.com/servo/green-rs?ref=servo)",
"tls 0.0.1 (git+https://github.com/alexcrichton/tls-rs)",
]
[[package]]
name = "script"
version = "0.0.1"
dependencies = [
"canvas 0.0.1",
"cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)",
"devtools_traits 0.0.1",
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"gfx 0.0.1",
"html5ever 0.0.0 (git+https://github.com/servo/html5ever?ref=servo)",
"hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)",
"js 0.1.0 (git+https://github.com/servo/rust-mozjs)",
"msg 0.0.1",
"net 0.0.1",
"plugins 0.0.1",
"script_traits 0.0.1",
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
"style 0.0.1",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
"uuid 0.0.1 (git+https://github.com/rust-lang/uuid)",
]
[[package]]
name = "script_traits"
version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"msg 0.0.1",
"net 0.0.1",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "servo"
version = "0.0.1"
dependencies = [
"compositing 0.0.1",
"gfx 0.0.1",
"layout 0.0.1",
"msg 0.0.1",
"net 0.0.1",
"script 0.0.1",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "skia-sys"
version = "0.0.20130412"
source = "git+https://github.com/servo/skia#79aa9354837bc195b83fa041b9632ea628e6f7d0"
dependencies = [
"expat-sys 2.1.0 (git+https://github.com/servo/libexpat)",
"freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)",
]
[[package]]
name = "stb_image"
version = "0.1.0"
source = "git+https://github.com/servo/rust-stb-image#74488fef4740acf287ff5dc248d65cc74033467a"
[[package]]
name = "string_cache"
version = "0.0.0"
source = "git+https://github.com/servo/string-cache#ae950525434b642eff5f4904f5e0c76cd6ea99b9"
dependencies = [
"lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)",
"phf 0.0.0 (git+https://github.com/sfackler/rust-phf)",
"phf_mac 0.0.0 (git+https://github.com/sfackler/rust-phf)",
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
"xxhash 0.0.1 (git+https://github.com/Jurily/rust-xxhash)",
]
[[package]]
name = "string_cache_macros"
version = "0.0.0"
source = "git+https://github.com/servo/string-cache#ae950525434b642eff5f4904f5e0c76cd6ea99b9"
dependencies = [
"lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)",
]
[[package]]
name = "style"
version = "0.0.1"
dependencies = [
"cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)",
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)",
"plugins 0.0.1",
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
"util 0.0.1",
]
[[package]]
name = "task_info"
version = "0.0.1"
[[package]]
name = "tls"
version = "0.0.1"
source = "git+https://github.com/alexcrichton/tls-rs#e5e240c35e2c3401ea750ee61221d917398c5ef1"
[[package]]
name = "typeable"
version = "0.0.3"
source = "git+https://github.com/reem/rust-typeable#db8975daaa3889871f67eea11baeaefd8e706eaf"
[[package]]
name = "unsafe-any"
version = "0.1.1"
source = "git+https://github.com/reem/rust-unsafe-any#eb3fe87bea85f375b8fcefa0cdecfd131fae9624"
[[package]]
name = "url"
version = "0.1.0"
source = "git+https://github.com/servo/rust-url#8a61b7654ab5378b488225a1d8a9cbbbcbd38894"
dependencies = [
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
]
[[package]]
name = "util"
version = "0.0.1"
dependencies = [
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
"task_info 0.0.1",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
]
[[package]]
name = "uuid"
version = "0.0.1"
source = "git+https://github.com/rust-lang/uuid#7c5af48d4f9074717199e05a1895f42b9fb1c1f0"
[[package]]
name = "xlib"
version = "0.1.0"
source = "git+https://github.com/servo/rust-xlib#58ec3847b592aeabdcfeb6a2d02033d3a2c7f427"
[[package]]
name = "xxhash"
version = "0.0.1"
source = "git+https://github.com/Jurily/rust-xxhash#7e4174e780af0cfb29a5e53ede0b987adca16396"

31
ports/gonk/Cargo.toml Normal file
View file

@ -0,0 +1,31 @@
[package]
name = "b2s"
version = "0.0.1"
authors = ["The Servo Project Developers"]
build = "make -f makefile.cargo"
[dependencies.compositing]
path = "../../components/compositing"
[dependencies.geom]
git = "https://github.com/servo/rust-geom"
[dependencies.layers]
git = "https://github.com/servo/rust-layers"
[dependencies.msg]
path = "../../components/msg"
[dependencies.script]
path = "../../components/script"
[dependencies.servo]
path = "../../components/servo"
default-features = false
[dependencies.util]
path = "../../components/util"
[dependencies.egl]
git = "https://github.com/servo/rust-egl"

25
ports/gonk/makefile.cargo Normal file
View file

@ -0,0 +1,25 @@
ifeq (androideabi,$(findstring androideabi,$(TARGET)))
CXX := $(TARGET)-g++
AR := $(TARGET)-ar
CFLAGS := -fPIC -O2
else
CXX ?= g++
AR ?= ar
endif
CSRC := src/native_window_glue.cpp
OBJS := $(CSRC:%.cpp=$(OUT_DIR)/%.o)
.PHONY: all
all: $(OUT_DIR)/libnative_window_glue.a
$(OUT_DIR)/%.o: %.cpp
mkdir -p `dirname $@` && $(CXX) $< -o $@ -c $(CXXFLAGS) $(CPPFLAGS)
$(OUT_DIR)/libnative_window_glue.a: $(OBJS)
$(AR) rcs $@ $<

242
ports/gonk/src/input.rs Normal file
View file

@ -0,0 +1,242 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::path::Path;
use std::mem::size_of;
use std::mem::transmute;
use std::mem::zeroed;
use std::os::errno;
use geom::point::TypedPoint2D;
use libc::c_int;
use libc::c_long;
use libc::time_t;
use libc::open;
use libc::read;
use libc::O_RDONLY;
use compositing::windowing::WindowEvent;
use compositing::windowing::ScrollWindowEvent;
use compositing::windowing::ZoomWindowEvent;
use compositing::windowing::MouseWindowMouseDownEvent;
use compositing::windowing::MouseWindowMouseUpEvent;
use compositing::windowing::MouseWindowClickEvent;
use compositing::windowing::MouseWindowEventClass;
extern {
// XXX: no variadic form in std libs?
fn ioctl(fd: c_int, req: c_int, ...) -> c_int;
}
#[repr(C)]
struct linux_input_event {
sec: time_t,
msec: c_long,
evt_type: u16,
code: u16,
value: i32,
}
#[repr(C)]
struct linux_input_absinfo {
value: i32,
minimum: i32,
maximum: i32,
fuzz: i32,
flat: i32,
resolution: i32,
}
const IOC_NONE: c_int = 0;
const IOC_WRITE: c_int = 1;
const IOC_READ: c_int = 2;
fn ioc(dir: c_int, ioctype: c_int, nr: c_int, size: c_int) -> c_int {
dir << 30 | size << 16 | ioctype << 8 | nr
}
fn ev_ioc_g_abs(abs: u16) -> c_int {
ioc(IOC_READ, 'E' as c_int, (0x40 + abs) as i32, size_of::<linux_input_absinfo>() as i32)
}
const EV_SYN: u16 = 0;
const EV_ABS: u16 = 3;
const EV_REPORT: u16 = 0;
const ABS_MT_SLOT: u16 = 0x2F;
const ABS_MT_TOUCH_MAJOR: u16 = 0x30;
const ABS_MT_TOUCH_MINOR: u16 = 0x31;
const ABS_MT_WIDTH_MAJOR: u16 = 0x32;
const ABS_MT_WIDTH_MINOR: u16 = 0x33;
const ABS_MT_ORIENTATION: u16 = 0x34;
const ABS_MT_POSITION_X: u16 = 0x35;
const ABS_MT_POSITION_Y: u16 = 0x36;
const ABS_MT_TRACKING_ID: u16 = 0x39;
struct input_slot {
tracking_id: i32,
x: i32,
y: i32,
}
fn dist(x1: i32, x2: i32, y1: i32, y2: i32) -> f32 {
let deltaX = (x2 - x1) as f32;
let deltaY = (y2 - y1) as f32;
(deltaX * deltaX + deltaY * deltaY).sqrt()
}
fn read_input_device(device_path: &Path,
sender: &Sender<Option<WindowEvent>>) {
// XXX we really want to use std::io:File but it currently doesn't expose
// the raw FD which is necessary for ioctl.
let device = unsafe { device_path.as_str().unwrap().with_c_str(|s| open(s, O_RDONLY, 0)) };
if device == -1 {
panic!("Couldn't open {}", device_path.as_str().unwrap());
}
let mut xInfo: linux_input_absinfo = unsafe { zeroed() };
let mut yInfo: linux_input_absinfo = unsafe { zeroed() };
unsafe {
let ret = ioctl(device, ev_ioc_g_abs(ABS_MT_POSITION_X), &xInfo);
if ret < 0 {
println!("Couldn't get ABS_MT_POSITION_X info {} {}", ret, errno());
}
}
unsafe {
let ret = ioctl(device, ev_ioc_g_abs(ABS_MT_POSITION_Y), &yInfo);
if ret < 0 {
println!("Couldn't get ABS_MT_POSITION_Y info {} {}", ret, errno());
}
}
let touchWidth = xInfo.maximum - xInfo.minimum;
let touchHeight = yInfo.maximum - yInfo.minimum;
println!("xMin: {}, yMin: {}, touchWidth: {}, touchHeight: {}", xInfo.minimum, yInfo.minimum, touchWidth, touchHeight);
// XXX: Why isn't size_of treated as constant?
// let buf: [u8, ..(16 * size_of::<linux_input_event>())];
let mut buf: [u8, ..(16 * 16)] = unsafe { zeroed() };
let mut slots: [input_slot, ..10] = unsafe { zeroed() };
for slot in slots.iter_mut() {
slot.tracking_id = -1;
}
let mut last_x = 0;
let mut last_y = 0;
let mut first_x = 0;
let mut first_y = 0;
let mut last_dist: f32 = 0f32;
let mut touch_count: i32 = 0;
let mut current_slot: uint = 0;
// XXX: Need to use the real dimensions of the screen
let screen_dist = dist(0, 480, 854, 0);
loop {
let read = unsafe { read(device, transmute(buf.as_mut_ptr()), buf.len() as u32) };
if read < 0 {
println!("Couldn't read device! error {}", read);
return;
}
assert!(read % (size_of::<linux_input_event>() as i32) == 0,
"Unexpected input device read length!");
let count = read / (size_of::<linux_input_event>() as i32);
let events: *mut linux_input_event = unsafe { transmute(buf.as_mut_ptr()) };
let mut tracking_updated = false;
for idx in range(0, count as int) {
let event: &linux_input_event = unsafe { transmute(events.offset(idx)) };
match (event.evt_type, event.code) {
(EV_SYN, EV_REPORT) => {
let slotA = &slots[0];
if tracking_updated {
tracking_updated = false;
if slotA.tracking_id == -1 {
println!("Touch up");
let delta_x = slotA.x - first_x;
let delta_y = slotA.y - first_y;
let dist = delta_x * delta_x + delta_y * delta_y;
if dist < 16 {
let click_pt = TypedPoint2D(slotA.x as f32, slotA.y as f32);
println!("Dispatching click!");
sender.send(Some(MouseWindowEventClass(MouseWindowMouseDownEvent(0, click_pt))));
sender.send(Some(MouseWindowEventClass(MouseWindowMouseUpEvent(0, click_pt))));
sender.send(Some(MouseWindowEventClass(MouseWindowClickEvent(0, click_pt))));
}
} else {
println!("Touch down");
last_x = slotA.x;
last_y = slotA.y;
first_x = slotA.x;
first_y = slotA.y;
if touch_count >= 2 {
let slotB = &slots[1];
last_dist = dist(slotA.x, slotB.x, slotA.y, slotB.y);
}
}
} else {
println!("Touch move x: {}, y: {}", slotA.x, slotA.y);
sender.send(Some(ScrollWindowEvent(TypedPoint2D((slotA.x - last_x) as f32, (slotA.y - last_y) as f32), TypedPoint2D(slotA.x, slotA.y))));
last_x = slotA.x;
last_y = slotA.y;
if touch_count >= 2 {
let slotB = &slots[1];
let cur_dist = dist(slotA.x, slotB.x, slotA.y, slotB.y);
println!("Zooming {} {} {} {}", cur_dist, last_dist, screen_dist, ((screen_dist + (cur_dist - last_dist))/screen_dist));
sender.send(Some(ZoomWindowEvent((screen_dist + (cur_dist - last_dist))/screen_dist)));
last_dist = cur_dist;
}
}
},
(EV_SYN, _) => println!("Unknown SYN code {}", event.code),
(EV_ABS, ABS_MT_SLOT) => {
if (event.value as uint) < slots.len() {
current_slot = event.value as uint;
} else {
println!("Invalid slot! {}", event.value);
}
},
(EV_ABS, ABS_MT_TOUCH_MAJOR) => (),
(EV_ABS, ABS_MT_TOUCH_MINOR) => (),
(EV_ABS, ABS_MT_WIDTH_MAJOR) => (),
(EV_ABS, ABS_MT_WIDTH_MINOR) => (),
(EV_ABS, ABS_MT_ORIENTATION) => (),
(EV_ABS, ABS_MT_POSITION_X) => {
slots[current_slot].x = event.value - xInfo.minimum;
},
(EV_ABS, ABS_MT_POSITION_Y) => {
slots[current_slot].y = event.value - yInfo.minimum;
},
(EV_ABS, ABS_MT_TRACKING_ID) => {
let current_id = slots[current_slot].tracking_id;
if current_id != event.value &&
(current_id == -1 || event.value == -1) {
tracking_updated = true;
if event.value == -1 {
touch_count -= 1;
} else {
touch_count += 1;
}
}
slots[current_slot].tracking_id = event.value;
},
(EV_ABS, _) => println!("Unknown ABS code {}", event.code),
(_, _) => println!("Unknown event type {}", event.evt_type),
}
}
}
}
pub fn run_input_loop(event_sender: &Sender<Option<WindowEvent>>) {
let sender = event_sender.clone();
spawn(proc () {
// XXX need to scan all devices and read every one.
let touchinputdev = Path::new("/dev/input/event0");
read_input_device(&touchinputdev, &sender);
});
}

176
ports/gonk/src/lib.rs Normal file
View file

@ -0,0 +1,176 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#![comment = "The Servo Parallel Browser Project"]
#![license = "MPL"]
#![feature(globs, macro_rules, phase, thread_local)]
#![deny(unused_imports)]
#![deny(unused_variables)]
#[phase(plugin, link)]
extern crate log;
extern crate compositing;
extern crate devtools;
extern crate rustuv;
extern crate "net" as servo_net;
extern crate "msg" as servo_msg;
#[phase(plugin, link)]
extern crate "util" as servo_util;
extern crate script;
extern crate layout;
extern crate green;
extern crate gfx;
extern crate libc;
extern crate native;
extern crate rustrt;
extern crate url;
use compositing::CompositorEventListener;
use compositing::windowing::{WindowEvent, WindowMethods};
#[cfg(not(test))]
use compositing::{CompositorProxy, CompositorTask, Constellation};
#[cfg(not(test))]
use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};
#[cfg(not(test))]
use script::dom::bindings::codegen::RegisterBindings;
#[cfg(not(test))]
use servo_net::image_cache_task::ImageCacheTask;
#[cfg(not(test))]
use servo_net::storage_task::StorageTaskFactory;
#[cfg(not(test))]
use servo_net::resource_task::new_resource_task;
#[cfg(not(test))]
use gfx::font_cache_task::FontCacheTask;
#[cfg(not(test))]
use servo_util::time::TimeProfiler;
#[cfg(not(test))]
use servo_util::memory::MemoryProfiler;
#[cfg(not(test))]
use servo_util::opts;
#[cfg(not(test))]
use servo_util::taskpool::TaskPool;
#[cfg(not(test))]
use green::GreenTaskBuilder;
#[cfg(not(test))]
use std::os;
#[cfg(not(test))]
use std::rc::Rc;
#[cfg(not(test))]
use std::task::TaskBuilder;
pub struct Browser<Window> {
pool: green::SchedPool,
compositor: Box<CompositorEventListener + 'static>,
}
impl<Window> Browser<Window> where Window: WindowMethods + 'static {
#[cfg(not(test))]
pub fn new(window: Option<Rc<Window>>) -> Browser<Window> {
use rustuv::EventLoop;
fn event_loop() -> Box<green::EventLoop + Send> {
box EventLoop::new().unwrap() as Box<green::EventLoop + Send>
}
::servo_util::opts::set_experimental_enabled(opts::get().enable_experimental);
let opts = opts::get();
RegisterBindings::RegisterProxyHandlers();
let mut pool_config = green::PoolConfig::new();
pool_config.event_loop_factory = event_loop;
let mut pool = green::SchedPool::new(pool_config);
let shared_task_pool = TaskPool::new(8);
let (compositor_proxy, compositor_receiver) =
WindowMethods::create_compositor_channel(&window);
let time_profiler_chan = TimeProfiler::create(opts.time_profiler_period);
let memory_profiler_chan = MemoryProfiler::create(opts.memory_profiler_period);
let devtools_chan = opts.devtools_port.map(|port| {
devtools::start_server(port)
});
let opts_clone = opts.clone();
let time_profiler_chan_clone = time_profiler_chan.clone();
let (result_chan, result_port) = channel();
let compositor_proxy_for_constellation = compositor_proxy.clone_compositor_proxy();
TaskBuilder::new()
.green(&mut pool)
.spawn(proc() {
let opts = &opts_clone;
// Create a Servo instance.
let resource_task = new_resource_task(opts.user_agent.clone());
// If we are emitting an output file, then we need to block on
// image load or we risk emitting an output file missing the
// image.
let image_cache_task = if opts.output_file.is_some() {
ImageCacheTask::new_sync(resource_task.clone(), shared_task_pool)
} else {
ImageCacheTask::new(resource_task.clone(), shared_task_pool)
};
let font_cache_task = FontCacheTask::new(resource_task.clone());
let storage_task = StorageTaskFactory::new();
let constellation_chan = Constellation::<layout::layout_task::LayoutTask,
script::script_task::ScriptTask>::start(
compositor_proxy_for_constellation,
resource_task,
image_cache_task,
font_cache_task,
time_profiler_chan_clone,
devtools_chan,
storage_task);
// Send the URL command to the constellation.
let cwd = os::getcwd();
for url in opts.urls.iter() {
let url = match url::Url::parse(url.as_slice()) {
Ok(url) => url,
Err(url::RelativeUrlWithoutBase)
=> url::Url::from_file_path(&cwd.join(url.as_slice())).unwrap(),
Err(_) => panic!("URL parsing failed"),
};
let ConstellationChan(ref chan) = constellation_chan;
chan.send(InitLoadUrlMsg(url));
}
// Send the constallation Chan as the result
result_chan.send(constellation_chan);
});
let constellation_chan = result_port.recv();
debug!("preparing to enter main loop");
let compositor = CompositorTask::create(window,
compositor_proxy,
compositor_receiver,
constellation_chan,
time_profiler_chan,
memory_profiler_chan);
Browser {
pool: pool,
compositor: compositor,
}
}
pub fn handle_event(&mut self, event: WindowEvent) -> bool {
self.compositor.handle_event(event)
}
pub fn repaint_synchronously(&mut self) {
self.compositor.repaint_synchronously()
}
pub fn shutdown(mut self) {
self.compositor.shutdown();
self.pool.shutdown();
}
}

85
ports/gonk/src/main.rs Normal file
View file

@ -0,0 +1,85 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#![comment = "The Servo Parallel Browser Project"]
#![license = "MPL"]
#![deny(unused_imports)]
#![deny(unused_variables)]
#![allow(non_snake_case)]
extern crate servo;
extern crate native;
extern crate time;
extern crate "util" as servo_util;
extern crate compositing;
extern crate geom;
extern crate libc;
extern crate msg;
extern crate gleam;
extern crate layers;
extern crate egl;
use servo_util::opts;
use servo_util::rtinstrument;
use servo::Browser;
use compositing::windowing::IdleWindowEvent;
use std::os;
mod window;
mod input;
struct BrowserWrapper {
browser: Browser<window::Window>,
}
#[start]
#[allow(dead_code)]
fn start(argc: int, argv: *const *const u8) -> int {
native::start(argc, argv, proc() {
if opts::from_cmdline_args(os::args().as_slice()) {
let window = if opts::get().headless {
None
} else {
Some(window::Window::new())
};
let mut browser = BrowserWrapper {
browser: Browser::new(window.clone()),
};
match window {
None => (),
Some(ref window) => input::run_input_loop(&window.event_send)
}
loop {
let should_continue = match window {
None => browser.browser.handle_event(IdleWindowEvent),
Some(ref window) => {
match window.wait_events() {
Some(evt) => browser.browser.handle_event(evt),
None => browser.browser.handle_event(IdleWindowEvent),
}
}
};
if !should_continue {
break
}
}
let BrowserWrapper {
browser
} = browser;
browser.shutdown();
rtinstrument::teardown();
}
})
}

View file

@ -0,0 +1,74 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdarg.h>
#include <stdio.h>
#include "system/window.h"
struct GonkNativeWindow {
ANativeWindow window;
int (*set_usage)(struct ANativeWindow* window, int usage);
int (*set_format)(struct ANativeWindow* window, int format);
int (*set_transform)(struct ANativeWindow* window, int transform);
int (*set_dimensions)(struct ANativeWindow* window, int w, int h);
int (*api_connect)(struct ANativeWindow* window, int api);
int (*api_disconnect)(struct ANativeWindow* window, int api);
};
// Rust doesn't support implementing variadic functions, so handle that here
extern "C" int
gnw_perform(struct ANativeWindow* window, int op, ...) {
GonkNativeWindow *gnw = (GonkNativeWindow *)window;
va_list ap;
switch (op) {
case NATIVE_WINDOW_SET_USAGE: {
int usage;
va_start(ap, op);
usage = va_arg(ap, int);
va_end(ap);
return gnw->set_usage(window, usage);
}
case NATIVE_WINDOW_SET_BUFFERS_FORMAT: {
int format;
va_start(ap, op);
format = va_arg(ap, int);
va_end(ap);
return gnw->set_format(window, format);
}
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: {
int transform;
va_start(ap, op);
transform = va_arg(ap, int);
va_end(ap);
return gnw->set_transform(window, transform);
}
case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: {
int w, h;
va_start(ap, op);
w = va_arg(ap, int);
h = va_arg(ap, int);
va_end(ap);
return gnw->set_dimensions(window, w, h);
}
case NATIVE_WINDOW_API_CONNECT: {
int api;
va_start(ap, op);
api = va_arg(ap, int);
va_end(ap);
return gnw->api_connect(window, api);
}
case NATIVE_WINDOW_API_DISCONNECT: {
int api;
va_start(ap, op);
api = va_arg(ap, int);
va_end(ap);
return gnw->api_disconnect(window, api);
}
default:
printf("Unsupported GonkNativeWindow operation! %d\n", op);
return -1;
}
}

832
ports/gonk/src/window.rs Normal file
View file

@ -0,0 +1,832 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! A windowing implementation using gonk interfaces.
use compositing::compositor_task::{mod, CompositorProxy, CompositorReceiver};
use compositing::windowing::{WindowEvent, WindowMethods};
use geom::scale_factor::ScaleFactor;
use geom::size::TypedSize2D;
use layers::geometry::DevicePixel;
use layers::platform::surface::NativeGraphicsMetadata;
use libc::c_int;
use msg::compositor_msg::{Blank, IdlePaintState};
use msg::compositor_msg::{ReadyState, PaintState};
use std::cell::Cell;
use std::comm::Receiver;
use std::rc::Rc;
use std::mem::transmute;
use std::mem::size_of;
use std::mem::zeroed;
use std::ptr;
use servo_util::geometry::ScreenPx;
use gleam::gl;
use egl::egl::EGLConfig;
use egl::egl::EGLDisplay;
use egl::egl::EGLContext;
use egl::egl::EGLSurface;
use egl::egl::EGLint;
use egl::egl;
use libc::size_t;
use libc::c_void;
use libc::c_char;
use libc::close;
const GRALLOC_USAGE_HW_TEXTURE: c_int = 0x00000100;
const GRALLOC_USAGE_HW_RENDER: c_int = 0x00000200;
const GRALLOC_USAGE_HW_2D: c_int = 0x00000400;
const GRALLOC_USAGE_HW_COMPOSER: c_int = 0x00000800;
const GRALLOC_USAGE_HW_FB: c_int = 0x00001000;
// system/core/include/cutils/native_handle.h
#[repr(C)]
pub struct native_handle {
version: c_int,
numFds: c_int,
numInts: c_int,
data: [c_int, ..0],
}
// system/core/include/system/window.h
#[repr(C)]
pub struct ANativeBase {
magic: u32,
version: u32,
reserved: [int, ..4],
incRef: extern fn(*mut ANativeBase),
decRef: extern fn(*mut ANativeBase),
}
#[repr(C)]
pub struct ANativeWindowBuffer {
common: ANativeBase,
width: c_int,
height: c_int,
stride: c_int,
format: c_int,
usage: c_int,
reserved: [*mut c_void, ..2],
handle: *const native_handle,
reserved_proc: [*mut c_void, ..8],
}
#[repr(C)]
pub struct ANativeWindow {
common: ANativeBase,
flags: u32,
minSwapInterval: c_int,
maxSwapInterval: c_int,
xdpi: f32,
ydpi: f32,
oem: [int, ..4],
setSwapInterval: extern fn(*mut ANativeWindow, c_int) -> c_int,
//dequeueBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut *mut ANativeWindowBuffer) -> c_int,
//lockBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer) -> c_int,
//queueBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer) -> c_int,
dequeueBuffer_DEPRECATED: int,
lockBuffer_DEPRECATED: int,
queueBuffer_DEPRECATED: int,
query: extern fn(*const ANativeWindow, c_int, *mut c_int) -> c_int,
perform: extern fn(*mut ANativeWindow, c_int, ...) -> c_int,
//cancelBuffer_DEPRECATED: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer) -> c_int,
cancelBuffer_DEPRECATED: int,
dequeueBuffer: extern fn(*mut ANativeWindow, *mut *mut ANativeWindowBuffer, *mut c_int) -> c_int,
queueBuffer: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer, c_int) -> c_int,
cancelBuffer: extern fn(*mut ANativeWindow, *mut ANativeWindowBuffer, c_int) -> c_int,
}
// hardware/libhardware/include/hardware/hardware.h
#[repr(C)]
pub struct hw_module_methods {
open: extern fn(*const hw_module, *const c_char, *mut *const hw_device) -> c_int,
}
#[repr(C)]
pub struct hw_module {
tag: u32,
module_api_version: u16,
hal_api_version: u16,
id: *const c_char,
name: *const c_char,
author: *const c_char,
methods: *mut hw_module_methods,
dso: *mut u32,
reserved: [u32, ..(32-7)],
}
#[repr(C)]
pub struct hw_device {
tag: u32,
version: u32,
module: *mut hw_module,
reserved: [u32, ..12],
close: extern fn(*mut hw_device) -> c_int,
}
#[link(name = "hardware")]
extern {
fn hw_get_module(id: *const c_char, module: *mut *const hw_module) -> c_int;
}
// hardware/libhardware/include/hardware/hwcomposer.h
#[repr(C)]
pub struct hwc_color {
r: u8,
g: u8,
b: u8,
a: u8,
}
#[repr(C)]
pub struct hwc_rect {
left: c_int,
top: c_int,
right: c_int,
bottom: c_int,
}
#[repr(C)]
pub struct hwc_region {
numRects: i32,
rects: *const hwc_rect,
}
const HWC_FRAMEBUFFER: i32 = 0;
const HWC_OVERLAY: i32 = 1;
const HWC_BACKGROUND: i32 = 2;
const HWC_FRAMEBUFFER_TARGET: i32 = 3;
const HWC_BLIT: i32 = 4;
const HWC_SKIP_LAYER: u32 = 1;
#[repr(C)]
pub struct hwc_layer {
compositionType: i32,
hints: u32,
flags: u32,
handle: *const native_handle,
transform: u32,
blending: i32,
sourceCrop: hwc_rect, // If HWC 1.3, then this takes floats
displayFrame: hwc_rect,
visibleRegionScreen: hwc_region,
acquireFenceFd: c_int,
releaseFenceFd: c_int,
planeAlpha: u8,
pad: [u8, ..3],
reserved: [i32, ..(24 - 19)],
}
#[repr(C)]
pub struct hwc_display_contents {
retireFenceFd: c_int,
// HWC 1.0 not supported
outbuf: *const u32,
outbufAcquireFenceFd: c_int,
flags: u32,
numHwLayers: size_t,
hwLayers: [hwc_layer, ..2],
}
#[repr(C)]
pub struct hwc_procs {
invalidate: extern fn(*const hwc_procs),
vsync: extern fn(*const hwc_procs, c_int, i64),
hotplug: extern fn(*const hwc_procs, c_int, c_int),
}
const HWC_DISPLAY_NO_ATTRIBUTE: u32 = 0;
const HWC_DISPLAY_VSYNC_PERIOD: u32 = 1;
const HWC_DISPLAY_WIDTH: u32 = 2;
const HWC_DISPLAY_HEIGHT: u32 = 3;
const HWC_DISPLAY_DPI_X: u32 = 4;
const HWC_DISPLAY_DPI_Y: u32 = 5;
#[repr(C)]
pub struct hwc_composer_device {
common: hw_device,
prepare: extern fn(*mut hwc_composer_device, size_t, *mut *mut hwc_display_contents) -> c_int,
set: extern fn(*mut hwc_composer_device, size_t, *mut *mut hwc_display_contents) -> c_int,
eventControl: extern fn(*mut hwc_composer_device, c_int, c_int, c_int) -> c_int,
blank: extern fn(*mut hwc_composer_device, c_int, c_int) -> c_int,
query: extern fn(*mut hwc_composer_device, c_int, *mut c_int) -> c_int,
registerProcs: extern fn(*mut hwc_composer_device, *const hwc_procs),
dump: extern fn(*mut hwc_composer_device, *const c_char, c_int),
getDisplayConfigs: extern fn(*mut hwc_composer_device, c_int, *mut u32, *mut size_t) -> c_int,
getDisplayAttributes: extern fn(*mut hwc_composer_device, c_int, u32, *const u32, *mut i32) -> c_int,
reserved: [*mut c_void, ..4],
}
// system/core/include/system/graphics.h
#[repr(C)]
pub struct android_ycbcr {
y: *mut c_void,
cb: *mut c_void,
cr: *mut c_void,
ystride: size_t,
cstride: size_t,
chroma_step: size_t,
reserved: [u32, ..8],
}
// hardware/libhardware/include/hardware/gralloc.h
#[repr(C)]
pub struct gralloc_module {
common: hw_module,
registerBuffer: extern fn(*const gralloc_module, *const native_handle) -> c_int,
unregisterBuffer: extern fn(*const gralloc_module, *const native_handle) -> c_int,
lock: extern fn(*const gralloc_module, *const native_handle, c_int, c_int, c_int, c_int, *mut *mut c_void) -> c_int,
unlock: extern fn(*const gralloc_module, *const native_handle) -> c_int,
perform: extern fn(*const gralloc_module, c_int, ...) -> c_int,
lock_ycbcr: extern fn(*const gralloc_module, *const native_handle, c_int, c_int, c_int, c_int, c_int, *mut android_ycbcr) -> c_int,
reserved: [*mut c_void, ..6],
}
#[repr(C)]
pub struct alloc_device {
common: hw_device,
allocSize: extern fn(*mut alloc_device, c_int, c_int, c_int, c_int, *mut *const native_handle, *mut c_int, c_int) -> c_int,
alloc: extern fn(*mut alloc_device, c_int, c_int, c_int, c_int, *mut *const native_handle, *mut c_int) -> c_int,
free: extern fn(*mut alloc_device, *const native_handle) -> c_int,
dump: Option<extern fn(*mut alloc_device, *mut c_char, c_int)>,
reserved: [*mut c_void, ..7],
}
#[repr(C)]
pub struct GonkNativeWindow {
window: ANativeWindow,
set_usage: extern fn(*mut GonkNativeWindow, c_int) -> c_int,
set_format: extern fn(*mut GonkNativeWindow, c_int) -> c_int,
set_transform: extern fn(*mut GonkNativeWindow, c_int) -> c_int,
set_dimensions: extern fn(*mut GonkNativeWindow, c_int, c_int) -> c_int,
api_connect: extern fn(*mut GonkNativeWindow, c_int) -> c_int,
api_disconnect: extern fn(*mut GonkNativeWindow, c_int) -> c_int,
count: i32,
alloc_dev: *mut alloc_device,
hwc_dev: *mut hwc_composer_device,
width: i32,
height: i32,
format: c_int,
usage: c_int,
last_fence: c_int,
last_idx: i32,
bufs: [Option<*mut GonkNativeWindowBuffer>, ..2],
fences: [c_int, ..2],
}
impl ANativeBase {
fn magic(a: char, b: char, c: char, d: char) -> u32 {
a as u32 << 24 | b as u32 << 16 | c as u32 << 8 | d as u32
}
}
#[repr(C)]
pub struct GonkNativeWindowBuffer {
buffer: ANativeWindowBuffer,
count: i32,
}
#[link(name = "native_window_glue", kind = "static")]
extern {
fn gnw_perform(win: *mut ANativeWindow, op: c_int, ...) -> c_int;
}
#[link(name = "suspend")]
extern {
fn autosuspend_disable();
}
#[allow(unused_variables)]
extern fn setSwapInterval(base: *mut ANativeWindow,
interval: c_int) -> c_int {
0
}
const NATIVE_WINDOW_WIDTH: c_int = 0;
const NATIVE_WINDOW_HEIGHT: c_int = 1;
const NATIVE_WINDOW_FORMAT: c_int = 2;
const NATIVE_WINDOW_DEFAULT_WIDTH: c_int = 6;
const NATIVE_WINDOW_DEFAULT_HEIGHT: c_int = 7;
const NATIVE_WINDOW_TRANSFORM_HINT: c_int = 8;
extern fn query(base: *const ANativeWindow,
what: c_int, value: *mut c_int) -> c_int {
unsafe {
let window: &GonkNativeWindow = transmute(base);
match what {
NATIVE_WINDOW_WIDTH => { *value = window.width; 0 }
NATIVE_WINDOW_HEIGHT => { *value = window.height; 0 }
NATIVE_WINDOW_FORMAT => { *value = window.format; 0 }
NATIVE_WINDOW_DEFAULT_WIDTH => { *value = window.width; 0 }
NATIVE_WINDOW_DEFAULT_HEIGHT => { *value = window.height; 0 }
NATIVE_WINDOW_TRANSFORM_HINT => { *value = 0; 0 }
_ => { println!("Unsupported query - {}", what); -1 }
}
}
}
extern fn dequeueBuffer(base: *mut ANativeWindow, buf: *mut *mut ANativeWindowBuffer, fence: *mut c_int) -> c_int {
unsafe {
let window: &mut GonkNativeWindow = transmute(base);
for idx in range(0, window.bufs.len()) {
if idx == window.last_idx as uint {
continue;
}
match window.bufs[idx] {
Some(entry) => {
(*buf) = transmute(entry);
window.bufs[idx] = None;
*fence = window.fences[idx];
window.fences[idx] = -1;
return 0;
},
None => (),
}
}
}
-1
}
extern fn queueBuffer(base: *mut ANativeWindow, buf: *mut ANativeWindowBuffer, fence: c_int) -> c_int {
unsafe {
let window: &mut GonkNativeWindow = transmute(base);
for idx in range(0, window.bufs.len()) {
match window.bufs[idx] {
Some(_) => (),
None => {
window.last_idx = idx as i32;
window.bufs[idx] = Some(transmute(buf));
window.fences[idx] = window.draw(buf, fence);
return 0;
},
}
}
}
-1
}
extern fn cancelBuffer(base: *mut ANativeWindow, buf: *mut ANativeWindowBuffer, fence: c_int) -> c_int {
unsafe {
let window: &mut GonkNativeWindow = transmute(base);
for idx in range(0, window.bufs.len()) {
match window.bufs[idx] {
Some(_) => (),
None => {
window.bufs[idx] = Some(transmute(buf));
window.fences[idx] = -1;
close(fence);
return 0;
},
}
}
}
-1
}
extern fn set_usage(window: *mut GonkNativeWindow,
usage: c_int) -> c_int {
println!("Setting usage flags to {}", usage);
unsafe {
(*window).usage = usage;
(*window).bufs[0] = Some(GonkNativeWindowBuffer::new((*window).alloc_dev, (*window).width, (*window).height, (*window).format, (*window).usage));
(*window).bufs[1] = Some(GonkNativeWindowBuffer::new((*window).alloc_dev, (*window).width, (*window).height, (*window).format, (*window).usage));
}
0
}
extern fn set_format(window: *mut GonkNativeWindow,
format: c_int) -> c_int {
println!("Setting format to {}", format);
unsafe {
(*window).format = format;
}
0
}
extern fn set_transform(_: *mut GonkNativeWindow,
_: c_int) -> c_int {
0
}
extern fn set_dimensions(_: *mut GonkNativeWindow,
_: c_int, _: c_int) -> c_int {
0
}
#[allow(unused_variables)]
extern fn api_connect(window: *mut GonkNativeWindow,
api: c_int) -> c_int {
0
}
#[allow(unused_variables)]
extern fn api_disconnect(window: *mut GonkNativeWindow,
api: c_int) -> c_int {
0
}
extern fn gnw_incRef(base: *mut ANativeBase) {
let mut win: &mut GonkNativeWindow = unsafe { transmute(base) };
win.count += 1;
}
extern fn gnw_decRef(base: *mut ANativeBase) {
let mut win: &mut GonkNativeWindow = unsafe { transmute(base) };
win.count -= 1;
if win.count == 0 {
unsafe { transmute::<_, Box<GonkNativeWindow>>(base) };
}
}
impl GonkNativeWindow {
pub fn new(alloc_dev: *mut alloc_device, hwc_dev: *mut hwc_composer_device, width: i32, height: i32, usage: c_int) -> *mut GonkNativeWindow {
let mut win = box GonkNativeWindow {
window: ANativeWindow {
common: ANativeBase {
magic: ANativeBase::magic('_', 'w', 'n', 'd'),
version: size_of::<ANativeBase>() as u32,
reserved: unsafe { zeroed() },
incRef: gnw_incRef,
decRef: gnw_decRef,
},
flags: 0,
minSwapInterval: 0,
maxSwapInterval: 0,
xdpi: 0f32,
ydpi: 0f32,
oem: unsafe { zeroed() },
setSwapInterval: setSwapInterval,
dequeueBuffer_DEPRECATED: 0,
lockBuffer_DEPRECATED: 0,
queueBuffer_DEPRECATED: 0,
query: query,
perform: unsafe { transmute(gnw_perform) },
cancelBuffer_DEPRECATED: 0,
dequeueBuffer: dequeueBuffer,
queueBuffer: queueBuffer,
cancelBuffer: cancelBuffer,
},
set_usage: set_usage,
set_format: set_format,
set_transform: set_transform,
set_dimensions: set_dimensions,
api_connect: api_connect,
api_disconnect: api_disconnect,
count: 1,
alloc_dev: alloc_dev,
hwc_dev: hwc_dev,
width: width,
height: height,
format: 0,
usage: usage,
last_fence: -1,
last_idx: -1,
bufs: unsafe { zeroed() },
fences: [-1, -1],
};
unsafe { transmute(win) }
}
fn draw(&mut self, buf: *mut ANativeWindowBuffer, fence: c_int) -> c_int {
let gonkbuf: &mut GonkNativeWindowBuffer = unsafe { transmute(buf) };
let rect = hwc_rect {
left: 0, top: 0, right: gonkbuf.buffer.width, bottom: gonkbuf.buffer.height
};
let mut list = hwc_display_contents {
retireFenceFd: -1,
outbuf: ptr::null(),
outbufAcquireFenceFd: -1,
flags: 1, /* HWC_GEOMETRY_CHANGED */
numHwLayers: 2,
hwLayers: [
hwc_layer {
compositionType: HWC_FRAMEBUFFER,
hints: 0,
flags: HWC_SKIP_LAYER,
handle: ptr::null(),
transform: 0,
blending: 0,
sourceCrop: hwc_rect {
left: 0, top: 0, right: 0, bottom: 0
},
displayFrame: hwc_rect {
left: 0, top: 0, right: 0, bottom: 0
},
visibleRegionScreen: hwc_region {
numRects: 0,
rects: ptr::null(),
},
acquireFenceFd: -1,
releaseFenceFd: -1,
planeAlpha: 0xFF,
pad: [0, 0, 0],
reserved: [0, 0, 0, 0, 0],
},
hwc_layer {
compositionType: HWC_FRAMEBUFFER_TARGET,
hints: 0,
flags: 0,
handle: gonkbuf.buffer.handle,
transform: 0,
blending: 0,
sourceCrop: rect,
displayFrame: rect,
visibleRegionScreen: hwc_region {
numRects: 1,
rects: &rect,
},
acquireFenceFd: fence,
releaseFenceFd: -1,
planeAlpha: 0xFF,
pad: [0, 0, 0],
reserved: [0, 0, 0, 0, 0],
},
],
};
unsafe {
let mut displays: [*mut hwc_display_contents, ..3] = [ &mut list, ptr::null_mut(), ptr::null_mut(), ];
let _ = ((*self.hwc_dev).prepare)(self.hwc_dev, displays.len() as size_t, transmute(displays.as_mut_ptr()));
let _ = ((*self.hwc_dev).set)(self.hwc_dev, displays.len() as size_t, transmute(displays.as_mut_ptr()));
if list.retireFenceFd >= 0 {
close(list.retireFenceFd);
}
}
list.hwLayers[1].releaseFenceFd
}
}
extern fn gnwb_incRef(base: *mut ANativeBase) {
let mut buf: &mut GonkNativeWindowBuffer = unsafe { transmute(base) };
buf.count += 1;
}
extern fn gnwb_decRef(base: *mut ANativeBase) {
let mut buf: &mut GonkNativeWindowBuffer = unsafe { transmute(base) };
buf.count -= 1;
if buf.count == 0 {
unsafe { transmute::<_, Box<GonkNativeWindowBuffer>>(base) };
}
}
impl GonkNativeWindowBuffer {
pub fn new(dev: *mut alloc_device, width: i32, height: i32, format: c_int, usage: c_int) -> *mut GonkNativeWindowBuffer {
let mut buf = box GonkNativeWindowBuffer {
buffer: ANativeWindowBuffer {
common: ANativeBase {
magic: ANativeBase::magic('_', 'b', 'f', 'r'),
version: size_of::<ANativeBase>() as u32,
reserved: unsafe { zeroed() },
incRef: gnwb_incRef,
decRef: gnwb_decRef,
},
width: width,
height: height,
stride: 0,
format: format,
usage: usage,
reserved: unsafe { zeroed() },
handle: ptr::null(),
reserved_proc: unsafe { zeroed() },
},
count: 1,
};
let ret = unsafe { ((*dev).alloc)(dev, width, height, format, usage, &mut buf.buffer.handle, &mut buf.buffer.stride) };
assert!(ret == 0, "Failed to allocate gralloc buffer!");
unsafe { transmute(buf) }
}
}
/// The type of a window.
pub struct Window {
event_recv: Receiver<Option<WindowEvent>>,
pub event_send: Sender<Option<WindowEvent>>,
width: i32,
height: i32,
native_window: *mut GonkNativeWindow,
dpy: EGLDisplay,
ctx: EGLContext,
surf: EGLSurface,
ready_state: Cell<ReadyState>,
paint_state: Cell<PaintState>,
}
impl Window {
/// Creates a new window.
pub fn new() -> Rc<Window> {
let mut hwc_mod = ptr::null();
unsafe {
let ret = "hwcomposer".with_c_str(|s| hw_get_module(s, &mut hwc_mod));
assert!(ret == 0, "Failed to get HWC module!");
}
let mut hwc_device: *mut hwc_composer_device;
unsafe {
let mut device = ptr::null();
let ret = "composer".with_c_str(|s| ((*(*hwc_mod).methods).open)(hwc_mod, s, &mut device));
assert!(ret == 0, "Failed to get HWC device!");
hwc_device = transmute(device);
// Require HWC 1.1 or newer
// XXX add HAL version function/macro
assert!((*hwc_device).common.version > (1 << 8), "HWC too old!");
}
let attrs: [u32, ..4] = [
HWC_DISPLAY_WIDTH,
HWC_DISPLAY_HEIGHT,
HWC_DISPLAY_DPI_X,
HWC_DISPLAY_NO_ATTRIBUTE];
let mut values: [i32, ..4] = [0, 0, 0, 0];
unsafe {
// In theory, we should check the return code.
// However, there are HALs which implement this wrong.
let _ = ((*hwc_device).getDisplayAttributes)(hwc_device, 0, 0, attrs.as_ptr(), values.as_mut_ptr());
}
let mut gralloc_mod = ptr::null();
let mut alloc_dev: *mut alloc_device;
unsafe {
let mut device = ptr::null();
let ret1 = "gralloc".with_c_str(|s| hw_get_module(s, &mut gralloc_mod));
assert!(ret1 == 0, "Failed to get gralloc moudle!");
let ret2 = "gpu0".with_c_str(|s| ((*(*gralloc_mod).methods).open)(gralloc_mod, s, &mut device));
assert!(ret2 == 0, "Failed to get gralloc moudle!");
alloc_dev = transmute(device);
}
let width = values[0];
let height = values[1];
let dpy = egl::GetDisplay(unsafe { transmute(egl::EGL_DEFAULT_DISPLAY) });
let ret1 = {
let mut major: i32 = 0;
let mut minor: i32 = 0;
egl::Initialize(dpy, &mut major, &mut minor)
};
assert!(ret1 == 1, "Failed to initialize EGL!");
let conf_attr =
[egl::EGL_SURFACE_TYPE, egl::EGL_WINDOW_BIT,
egl::EGL_RENDERABLE_TYPE, egl::EGL_OPENGL_ES2_BIT,
egl::EGL_RED_SIZE, 8,
egl::EGL_GREEN_SIZE, 8,
egl::EGL_BLUE_SIZE, 8,
egl::EGL_ALPHA_SIZE, 0,
egl::EGL_NONE, 0];
let mut config: EGLConfig = unsafe { transmute(0i) };
let mut num_config: EGLint = 0;
let ret2 = unsafe {
egl::ChooseConfig(dpy, transmute(conf_attr.as_ptr()), &mut config, 1, &mut num_config)
};
assert!(ret2 == 1, "Failed to choose a config");
let usage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER;
let native_window = GonkNativeWindow::new(alloc_dev, hwc_device, width, height, usage);
let eglwindow = unsafe { egl::CreateWindowSurface(dpy, config, transmute(native_window), ptr::null()) };
let ctx_attr =
[egl::EGL_CONTEXT_CLIENT_VERSION, 2,
egl::EGL_NONE, 0];
let ctx = unsafe {
egl::CreateContext(dpy, config, transmute(egl::EGL_NO_CONTEXT), transmute(ctx_attr.as_ptr()))
};
if ctx == unsafe { transmute(egl::EGL_NO_CONTEXT) } { panic!("Failed to create a context!") }
unsafe {
autosuspend_disable();
((*hwc_device).blank)(hwc_device, 0, 0);
}
let ret3 = egl::MakeCurrent(dpy, eglwindow, eglwindow, ctx);
assert!(ret3 == 1, "Failed to make current!");
unsafe {
autosuspend_disable();
((*hwc_device).blank)(hwc_device, 0, 0);
}
unsafe {
gl::ClearColor(1f32, 1f32, 1f32, 1f32);
gl::Clear(gl::COLOR_BUFFER_BIT);
}
egl::SwapBuffers(dpy, eglwindow);
let (tx, rx) = channel();
// Create our window object.
let window = Window {
event_recv: rx,
event_send: tx,
width: width,
height: height,
native_window: native_window,
dpy: dpy,
ctx: ctx,
surf: eglwindow,
ready_state: Cell::new(Blank),
paint_state: Cell::new(IdlePaintState),
};
Rc::new(window)
}
pub fn wait_events(&self) -> Option<WindowEvent> {
self.event_recv.recv()
}
}
impl Drop for Window {
fn drop (&mut self) {
unsafe {
((*self.native_window).window.common.decRef)(&mut (*self.native_window).window.common);
}
}
}
impl WindowMethods for Window {
/// Returns the size of the window in hardware pixels.
fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint> {
TypedSize2D(self.width as uint, self.height as uint)
}
/// Returns the size of the window in density-independent "px" units.
fn size(&self) -> TypedSize2D<ScreenPx, f32> {
TypedSize2D(self.width as f32, self.height as f32)
}
/// Presents the window to the screen (perhaps by page flipping).
fn present(&self) {
let _ = egl::SwapBuffers(self.dpy, self.surf);
}
/// Sets the ready state.
fn set_ready_state(&self, ready_state: ReadyState) {
self.ready_state.set(ready_state);
}
/// Sets the paint state.
fn set_paint_state(&self, paint_state: PaintState) {
self.paint_state.set(paint_state);
}
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
ScaleFactor(1.0)
}
fn native_metadata(&self) -> NativeGraphicsMetadata {
NativeGraphicsMetadata {
display: self.dpy,
}
}
fn create_compositor_channel(window: &Option<Rc<Window>>)
-> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) {
let (sender, receiver) = channel();
(box GonkCompositorProxy {
sender: sender,
event_sender: window.as_ref().unwrap().event_send.clone(),
} as Box<CompositorProxy+Send>,
box receiver as Box<CompositorReceiver>)
}
}
struct GonkCompositorProxy {
sender: Sender<compositor_task::Msg>,
event_sender: Sender<Option<WindowEvent>>,
}
impl CompositorProxy for GonkCompositorProxy {
fn send(&mut self, msg: compositor_task::Msg) {
// Send a message and kick the OS event loop awake.
self.sender.send(msg);
self.event_sender.send(None);
}
fn clone_compositor_proxy(&self) -> Box<CompositorProxy+Send> {
box GonkCompositorProxy {
sender: self.sender.clone(),
event_sender: self.event_sender.clone(),
} as Box<CompositorProxy+Send>
}
}