Skip to content

Instantly share code, notes, and snippets.

@klutzy
Created December 6, 2013 07:45
Show Gist options
  • Save klutzy/7820031 to your computer and use it in GitHub Desktop.
Save klutzy/7820031 to your computer and use it in GitHub Desktop.
Rust with Emscripten and win32.js
// From rust get `libstd/libc.rs` to the working dir.
// From rust-windows <https://github.com/klutzy/rust-windows>
// copy whole `ll/` dir to the working dir and
// patch some code: (TODO)
// From win32.js <https://github.com/klutzy/win32.js>, copy
// `library_win32.js` and `window.js` to working dir.
//
// emscripten uses le32-unknown-nacl triple but rustc doesn't know it now.
// So just use similar target instead.
// Here I use `win32` because libc.rs needs it.
// `rustc hello.rs --target=i686-unknown-win32 --emit-llvm -S`
// `emcc hello.js hello.ll --js-library library_win32.js --pre-js window.js`
#[no_std];
#[feature(macro_rules, globs)];
pub mod option {
pub enum Option<T> {
None,
Some(T),
}
}
pub mod ptr {
pub fn mut_null<T>() -> *mut T {
unsafe { super::transmute(0) }
}
pub fn null<T>() -> *T {
unsafe { super::transmute(0) }
}
}
pub mod libc;
pub mod std {
pub mod libc {
pub use super::super::libc::*;
}
}
pub mod ll {
pub use self::platform::*;
pub use self::windef::*;
pub use self::all::*;
pub use self::font::*;
pub mod platform;
pub mod windef;
pub mod all;
pub mod font;
}
extern "rust-intrinsic" {
pub fn transmute<A, B>(a: A) -> B;
}
// win32.js-specific
extern "C" {
fn emscripten_win32_loop();
}
unsafe fn as_ptr(a: &[u16]) -> *u16 {
let (a, _b): (*u16, uint) = transmute(a);
a
}
pub static WS_CHILD: u32 = 0x40000000;
pub static WS_OVERLAPPEDWINDOW: u32 = 0xcf0000;
pub static WS_VISIBLE: u32 = 0x10000000;
pub static HELLO: &'static [u16] = &[0x48u16, 0x45u16, 0x4cu16, 0x4cu16, 0x4fu16, 0x0u16];
pub static EDIT: &'static [u16] = &[0x45u16, 0x44u16, 0x49u16, 0x54u16, 0x0u16];
pub static BUTTON: &'static [u16] = &[0x42u16, 0x55u16, 0x54u16, 0x54u16, 0x4fu16, 0x4eu16, 0x0u16];
pub static cls_name: &'static [u16] = &[0x48u16, 0x65u16, 0x6cu16, 0x6cu16, 0x6fu16, 0x0u16]; // Hello
// TODO TLS
extern "stdcall" fn wnd_proc(wnd: ll::HWND, msg: ll::UINT, wparam: ll::WPARAM, lparam: ll::LPARAM) -> ll::c_long {
unsafe {
match msg {
0x0001 => { // WM_CREATE
return 0;
}
0x0111 => { // WM_COMMAND
if wparam & 0xFF == 101 {
let msg = [0, ..100];
//ll::GetWindowText(hello_edit, as_ptr(msg), 100);
ll::MessageBoxW(wnd, as_ptr(HELLO), as_ptr(HELLO), 0);
}
}
0x000F => { // WM_PAINT
let rgb_res: [ll::BYTE, ..32] = [0 as ll::BYTE, ..32];
let ps = ll::PAINTSTRUCT {
hdc: ptr::mut_null(),
fErase: 0 as ll::BOOL,
rcPaint: ll::RECT {
left: 0 as ll::LONG, top: 0 as ll::LONG,
right: 0 as ll::LONG, bottom: 0 as ll::LONG,
},
fRestore: 0 as ll::BOOL,
fIncUpdate: 0 as ll::BOOL,
rgbReserved: &rgb_res,
};
let hdc = ll::BeginPaint(wnd, &ps);
ll::TextOutW(hdc, 100, 300, transmute(as_ptr(HELLO)), 8);
ll::EndPaint(wnd, &ps);
return 0;
}
0x0002 => { // WM_DESTROY
ll::PostQuitMessage(0);
return 0;
}
_ => {
}
}
ll::DefWindowProcW(wnd, msg, wparam, lparam)
}
}
unsafe fn WinMain(inst: ll::HINSTANCE, _: ll::HINSTANCE, cmd_line: *u8, cmd_show: libc::c_int) {
let cls_p = as_ptr(cls_name);
let cls = ll::WNDCLASS {
style: 0,
lpfnWndProc: wnd_proc as *ll::c_void,
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: inst,
hIcon: ptr::mut_null(),
hCursor: ptr::mut_null(),
hbrBackground: ptr::mut_null(),
lpszMenuName: ptr::null(),
lpszClassName: cls_p,
};
let _res = ll::RegisterClassW(&cls);
let main_win = ll::CreateWindowExW(0, cls_p, cls_p, WS_OVERLAPPEDWINDOW,
-1, -1, 700, 500, ptr::mut_null(), ptr::mut_null(), inst, ptr::mut_null());
let hello_edit = ll::CreateWindowExW(0, as_ptr(EDIT), cls_p,
WS_CHILD | WS_VISIBLE, 0, 0, 100, 30, main_win, ptr::mut_null(), inst, ptr::mut_null());
let hello_button = ll::CreateWindowExW(0, as_ptr(BUTTON), cls_p,
WS_CHILD | WS_VISIBLE, 120, 0, 100, 30, main_win, transmute(101), inst, ptr::mut_null());
ll::ShowWindow(main_win, cmd_show);
emscripten_win32_loop();
}
fn main() {
unsafe { WinMain(ptr::mut_null(), ptr::mut_null(), ptr::null(), 0); }
}
#[lang="start"]
fn start(_: *u8, _: int, _: **u8) -> int {
main();
0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment