exp: client host and demo app using wasm/wasmtime
diff --git a/apps/client/hello/call_host/Cargo.lock b/apps/client/hello/call_host/Cargo.lock
new file mode 100644
index 0000000..73c86ce
--- /dev/null
+++ b/apps/client/hello/call_host/Cargo.lock
@@ -0,0 +1,53 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "call_host"
+version = "0.1.0"
+dependencies = [
+ "tui",
+ "wasi",
+]
+
+[[package]]
+name = "cassowary"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
+
+[[package]]
+name = "tui"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96fe69244ec2af261bced1d9046a6fee6c8c2a6b0228e59e5ba39bc8ba4ed729"
+dependencies = [
+ "bitflags",
+ "cassowary",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
diff --git a/apps/client/hello/call_host/Cargo.toml b/apps/client/hello/call_host/Cargo.toml
new file mode 100644
index 0000000..6b4f30b
--- /dev/null
+++ b/apps/client/hello/call_host/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "call_host"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+tui = {version = "0.18.0", default-features = false}
+wasi = "0.11.0+wasi-snapshot-preview1"
diff --git a/apps/client/hello/call_host/src/lib.rs b/apps/client/hello/call_host/src/lib.rs
new file mode 100644
index 0000000..417445c
--- /dev/null
+++ b/apps/client/hello/call_host/src/lib.rs
@@ -0,0 +1,117 @@
+use std::error;
+use tui::{
+    layout::{Alignment},
+    widgets::{Block, BorderType, Borders},
+    Terminal,
+};
+
+
+use core::result::Result;
+use std::io::Error;
+use tui::backend::Backend;
+use tui::buffer::Cell;
+use tui::layout::Rect;
+
+extern "C" {
+    fn cursorHide();
+    fn cursorShow();
+    fn cursorSet(x: u16, y: u16);
+    fn clearScreen();
+    fn getSize() -> (i32, i32, i32, i32);
+    fn flush();
+    fn draw(x: u16, y: u16);
+}
+
+struct HostBackend {}
+
+impl Backend for HostBackend {
+    fn draw<'a, I>(&mut self, content: I) -> Result<(), Error>
+    where
+        I: Iterator<Item = (u16, u16, &'a Cell)>,
+    {
+	for i in content {
+	    let x: u16 = i.0;
+	    let y: u16 = i.1;
+	    unsafe { draw(x, y) }
+	}
+        Ok(())
+    }
+
+    fn hide_cursor(&mut self) -> Result<(), Error> {
+	unsafe { cursorHide() }
+        Ok(())
+    }
+
+    fn show_cursor(&mut self) -> Result<(), Error> {
+	unsafe { cursorShow() }
+        Ok(())
+    }
+
+    fn get_cursor(&mut self) -> Result<(u16, u16), Error> {
+        Ok((100, 100))
+    }
+
+    fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), Error> {
+	unsafe { cursorSet(x, y) }
+        Ok(())
+    }
+
+    fn clear(&mut self) -> Result<(), Error> {
+	unsafe { clearScreen() }
+        Ok(())
+    }
+
+    fn size(&self) -> Result<Rect, Error> {
+	let ws: (i32, i32, i32, i32);
+	unsafe { ws = getSize(); }
+        Ok(Rect {
+            x: ws.0 as u16,
+            y: ws.1 as u16,
+            width: ws.2 as u16,
+            height: ws.3 as u16,
+        })
+        // Ok(Rect {
+        //     x: 0,
+        //     y: 0,
+        //     width: 50,
+        //     height: 50,
+        // })
+    }
+
+    fn flush(&mut self) -> Result<(), Error> {
+	unsafe { flush() }
+        Ok(())
+    }
+}
+
+fn main() -> Result<(), Box<dyn error::Error>> {
+    let backend = HostBackend{};
+    let mut terminal = Terminal::new(backend)?;
+    let mut i: i32 = 0;
+    loop {
+	terminal.draw(|f| {
+	    let size = f.size();
+	    let block = Block::default()
+		.borders(Borders::ALL)
+		.title("Main block with round corners")
+		.title_alignment(Alignment::Center)
+		.border_type(BorderType::Rounded);
+	    f.render_widget(block, size);
+	})?;
+	i = i + 1;
+	if i > 1000 {
+	    break;
+	}
+    }
+    terminal.show_cursor()?;
+
+    Ok(())
+}
+
+struct Unused<T>(T);
+
+#[no_mangle]
+pub extern "C" fn run() {
+    // unsafe { cursorSet(10, 10) }
+    Unused(main());
+}