diff --git a/ports/gonk/.cargo/config b/ports/gonk/.cargo/config new file mode 100644 index 00000000000..e4951060177 --- /dev/null +++ b/ports/gonk/.cargo/config @@ -0,0 +1,3 @@ +[target.arm-linux-androideabi] +ar = "arm-linux-androideabi-ar" +linker = "arm-linux-androideabi-g++" diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock new file mode 100644 index 00000000000..677620ef843 --- /dev/null +++ b/ports/gonk/Cargo.lock @@ -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" + diff --git a/ports/gonk/Cargo.toml b/ports/gonk/Cargo.toml new file mode 100644 index 00000000000..a1fd09e3b0d --- /dev/null +++ b/ports/gonk/Cargo.toml @@ -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" diff --git a/ports/gonk/makefile.cargo b/ports/gonk/makefile.cargo new file mode 100644 index 00000000000..3c1dea6ad66 --- /dev/null +++ b/ports/gonk/makefile.cargo @@ -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 $@ $< diff --git a/ports/gonk/src/input.rs b/ports/gonk/src/input.rs new file mode 100644 index 00000000000..067d655ac40 --- /dev/null +++ b/ports/gonk/src/input.rs @@ -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::() 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>) { + // 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::())]; + 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::() as i32) == 0, + "Unexpected input device read length!"); + + let count = read / (size_of::() 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>) { + 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); + }); +} diff --git a/ports/gonk/src/lib.rs b/ports/gonk/src/lib.rs new file mode 100644 index 00000000000..9fa051d0e7d --- /dev/null +++ b/ports/gonk/src/lib.rs @@ -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 { + pool: green::SchedPool, + compositor: Box, +} + +impl Browser where Window: WindowMethods + 'static { + #[cfg(not(test))] + pub fn new(window: Option>) -> Browser { + use rustuv::EventLoop; + fn event_loop() -> Box { + box EventLoop::new().unwrap() as Box + } + + ::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::::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(); + } +} + diff --git a/ports/gonk/src/main.rs b/ports/gonk/src/main.rs new file mode 100644 index 00000000000..552658d94da --- /dev/null +++ b/ports/gonk/src/main.rs @@ -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, +} + +#[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(); + } + }) +} + diff --git a/ports/gonk/src/native_window_glue.cpp b/ports/gonk/src/native_window_glue.cpp new file mode 100644 index 00000000000..434f47f81d3 --- /dev/null +++ b/ports/gonk/src/native_window_glue.cpp @@ -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 +#include +#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; + } +} diff --git a/ports/gonk/src/window.rs b/ports/gonk/src/window.rs new file mode 100644 index 00000000000..8257ac85c66 --- /dev/null +++ b/ports/gonk/src/window.rs @@ -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, + 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>(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::() 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>(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::() 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>, + pub event_send: Sender>, + width: i32, + height: i32, + native_window: *mut GonkNativeWindow, + dpy: EGLDisplay, + ctx: EGLContext, + surf: EGLSurface, + + ready_state: Cell, + paint_state: Cell, +} + +impl Window { + /// Creates a new window. + pub fn new() -> Rc { + 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 { + 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 { + TypedSize2D(self.width as uint, self.height as uint) + } + + /// Returns the size of the window in density-independent "px" units. + fn size(&self) -> TypedSize2D { + 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 { + ScaleFactor(1.0) + } + + fn native_metadata(&self) -> NativeGraphicsMetadata { + NativeGraphicsMetadata { + display: self.dpy, + } + } + + fn create_compositor_channel(window: &Option>) + -> (Box, Box) { + let (sender, receiver) = channel(); + (box GonkCompositorProxy { + sender: sender, + event_sender: window.as_ref().unwrap().event_send.clone(), + } as Box, + box receiver as Box) + } +} + +struct GonkCompositorProxy { + sender: Sender, + event_sender: Sender>, +} + +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 { + box GonkCompositorProxy { + sender: self.sender.clone(), + event_sender: self.event_sender.clone(), + } as Box + } +} +