gl_generator-0.14.0/Cargo.toml.orig010064400007650000024000000013341354534553700153710ustar0000000000000000[package] name = "gl_generator" version = "0.14.0" authors = [ "Brendan Zabarauskas ", "Corey Richardson", "Arseny Kapoulkine", ] description = "Code generators for creating bindings to the Khronos OpenGL APIs." license = "Apache-2.0" documentation = "https://docs.rs/gl_generator" homepage = "https://github.com/brendanzab/gl-rs/" repository = "https://github.com/brendanzab/gl-rs/" readme = "README.md" categories = ["api-bindings", "rendering::graphics-api"] keywords = ["gl", "egl", "opengl", "khronos"] [lib] name = "gl_generator" path = "lib.rs" [features] unstable_generator_utils = [] [dependencies] khronos_api = { version = "3.1.0", path = "../khronos_api" } log = "0.4" xml-rs = "0.8" gl_generator-0.14.0/Cargo.toml0000644000000023520000000000000116250ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "gl_generator" version = "0.14.0" authors = ["Brendan Zabarauskas ", "Corey Richardson", "Arseny Kapoulkine"] description = "Code generators for creating bindings to the Khronos OpenGL APIs." homepage = "https://github.com/brendanzab/gl-rs/" documentation = "https://docs.rs/gl_generator" readme = "README.md" keywords = ["gl", "egl", "opengl", "khronos"] categories = ["api-bindings", "rendering::graphics-api"] license = "Apache-2.0" repository = "https://github.com/brendanzab/gl-rs/" [lib] name = "gl_generator" path = "lib.rs" [dependencies.khronos_api] version = "3.1.0" [dependencies.log] version = "0.4" [dependencies.xml-rs] version = "0.8" [features] unstable_generator_utils = [] gl_generator-0.14.0/generators/debug_struct_gen.rs010064400007650000024000000230351351110140300205150ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use registry::Registry; use std::io; #[allow(missing_copy_implementations)] pub struct DebugStructGenerator; impl super::Generator for DebugStructGenerator { fn write(&self, registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(write_header(dest)); try!(write_type_aliases(registry, dest)); try!(write_enums(registry, dest)); try!(write_fnptr_struct_def(dest)); try!(write_panicking_fns(registry, dest)); try!(write_struct(registry, dest)); try!(write_impl(registry, dest)); Ok(()) } } /// Creates a `__gl_imports` module which contains all the external symbols that we need for the /// bindings. fn write_header(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, r#" mod __gl_imports {{ pub use std::mem; pub use std::marker::Send; pub use std::os::raw; }} "# ) } /// Creates a `types` module which contains all the type aliases. /// /// See also `generators::gen_types`. fn write_type_aliases(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, r#" pub mod types {{ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)] "# )); try!(super::gen_types(registry.api, dest)); writeln!(dest, "}}") } /// Creates all the `` elements at the root of the bindings. fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { for enm in ®istry.enums { try!(super::gen_enum_item(enm, "types::", dest)); } Ok(()) } /// Creates a `FnPtr` structure which contains the store for a single binding. fn write_fnptr_struct_def(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, " #[allow(dead_code, missing_copy_implementations)] #[derive(Clone)] pub struct FnPtr {{ /// The function pointer that will be used when calling the function. f: *const __gl_imports::raw::c_void, /// True if the pointer points to a real function, false if points to a `panic!` fn. is_loaded: bool, }} impl FnPtr {{ /// Creates a `FnPtr` from a load attempt. fn new(ptr: *const __gl_imports::raw::c_void) -> FnPtr {{ if ptr.is_null() {{ FnPtr {{ f: missing_fn_panic as *const __gl_imports::raw::c_void, is_loaded: false }} }} else {{ FnPtr {{ f: ptr, is_loaded: true }} }} }} /// Returns `true` if the function has been successfully loaded. /// /// If it returns `false`, calling the corresponding function will fail. #[inline] #[allow(dead_code)] pub fn is_loaded(&self) -> bool {{ self.is_loaded }} }} " ) } /// Creates a `panicking` module which contains one function per GL command. /// /// These functions are the mocks that are called if the real function could not be loaded. fn write_panicking_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, "#[inline(never)] fn missing_fn_panic() -> ! {{ panic!(\"{api} function was not loaded\") }}", api = registry.api ) } /// Creates a structure which stores all the `FnPtr` of the bindings. /// /// The name of the struct corresponds to the namespace. fn write_struct(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, " #[allow(non_camel_case_types, non_snake_case, dead_code)] #[derive(Clone)] pub struct {api} {{", api = super::gen_struct_name(registry.api) )); for cmd in ®istry.cmds { if let Some(v) = registry.aliases.get(&cmd.proto.ident) { try!(writeln!(dest, "/// Fallbacks: {}", v.join(", "))); } try!(writeln!(dest, "pub {name}: FnPtr,", name = cmd.proto.ident)); } try!(writeln!(dest, "_priv: ()")); writeln!(dest, "}}") } /// Creates the `impl` of the structure created by `write_struct`. fn write_impl(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!(dest, "impl {api} {{ /// Load each OpenGL symbol using a custom load function. This allows for the /// use of functions like `glfwGetProcAddress` or `SDL_GL_GetProcAddress`. /// /// ~~~ignore /// let gl = Gl::load_with(|s| glfw.get_proc_address(s)); /// ~~~ #[allow(dead_code, unused_variables)] pub fn load_with(mut loadfn: F) -> {api} where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{ #[inline(never)] fn do_metaloadfn(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void, symbol: &'static str, symbols: &[&'static str]) -> *const __gl_imports::raw::c_void {{ let mut ptr = loadfn(symbol); if ptr.is_null() {{ for &sym in symbols {{ ptr = loadfn(sym); if !ptr.is_null() {{ break; }} }} }} ptr }} let mut metaloadfn = |symbol: &'static str, symbols: &[&'static str]| {{ do_metaloadfn(&mut loadfn, symbol, symbols) }}; {api} {{", api = super::gen_struct_name(registry.api))); for cmd in ®istry.cmds { try!(writeln!( dest, "{name}: FnPtr::new(metaloadfn(\"{symbol}\", &[{fallbacks}])),", name = cmd.proto.ident, symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident), fallbacks = match registry.aliases.get(&cmd.proto.ident) { Some(fbs) => fbs .iter() .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name))) .collect::>() .join(", "), None => format!(""), }, )) } try!(writeln!(dest, "_priv: ()")); try!(writeln!( dest, "}} }}" )); for cmd in ®istry.cmds { let idents = super::gen_parameters(cmd, true, false); let typed_params = super::gen_parameters(cmd, false, true); let println = format!( "println!(\"[OpenGL] {}({})\" {});", cmd.proto.ident, (0..idents.len()) .map(|_| "{:?}".to_string()) .collect::>() .join(", "), idents .iter() .zip(typed_params.iter()) .map(|(name, ty)| if ty.contains("GLDEBUGPROC") { format!(", \"\"") } else { format!(", {}", name) }).collect::>() .concat() ); try!(writeln!(dest, "#[allow(non_snake_case, unused_variables, dead_code)] #[inline] pub unsafe fn {name}(&self, {params}) -> {return_suffix} {{ \ {println} let r = __gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\ (self.{name}.f)({idents}); {print_err} r }}", name = cmd.proto.ident, params = super::gen_parameters(cmd, true, true).join(", "), typed_params = typed_params.join(", "), return_suffix = cmd.proto.ty, idents = idents.join(", "), println = println, print_err = if cmd.proto.ident != "GetError" && registry .cmds .iter() .find(|cmd| cmd.proto.ident == "GetError") .is_some() { format!(r#"match __gl_imports::mem::transmute::<_, extern "system" fn() -> u32> (self.GetError.f)() {{ 0 => (), r => println!("[OpenGL] ^ GL error triggered: {{}}", r) }}"#) } else { format!("") })) } writeln!( dest, "}} unsafe impl __gl_imports::Send for {api} {{}}", api = super::gen_struct_name(registry.api) ) } gl_generator-0.14.0/generators/global_gen.rs010064400007650000024000000221141351110140300172600ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use registry::Registry; use std::io; #[allow(missing_copy_implementations)] pub struct GlobalGenerator; impl super::Generator for GlobalGenerator { fn write(&self, registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(write_header(dest)); try!(write_metaloadfn(dest)); try!(write_type_aliases(registry, dest)); try!(write_enums(registry, dest)); try!(write_fns(registry, dest)); try!(write_fnptr_struct_def(dest)); try!(write_ptrs(registry, dest)); try!(write_fn_mods(registry, dest)); try!(write_panicking_fns(registry, dest)); try!(write_load_fn(registry, dest)); Ok(()) } } /// Creates a `__gl_imports` module which contains all the external symbols that we need for the /// bindings. fn write_header(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, r#" mod __gl_imports {{ pub use std::mem; pub use std::os::raw; }} "# ) } /// Creates the metaloadfn function for fallbacks fn write_metaloadfn(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, r#" #[inline(never)] fn metaloadfn(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void, symbol: &'static str, fallbacks: &[&'static str]) -> *const __gl_imports::raw::c_void {{ let mut ptr = loadfn(symbol); if ptr.is_null() {{ for &sym in fallbacks {{ ptr = loadfn(sym); if !ptr.is_null() {{ break; }} }} }} ptr }} "# ) } /// Creates a `types` module which contains all the type aliases. /// /// See also `generators::gen_types`. fn write_type_aliases(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, r#" pub mod types {{ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)] "# )); try!(super::gen_types(registry.api, dest)); writeln!( dest, " }} " ) } /// Creates all the `` elements at the root of the bindings. fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { for enm in ®istry.enums { try!(super::gen_enum_item(enm, "types::", dest)); } Ok(()) } /// Creates the functions corresponding to the GL commands. /// /// The function calls the corresponding function pointer stored in the `storage` module created /// by `write_ptrs`. fn write_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { for cmd in ®istry.cmds { if let Some(v) = registry.aliases.get(&cmd.proto.ident) { try!(writeln!(dest, "/// Fallbacks: {}", v.join(", "))); } try!(writeln!(dest, "#[allow(non_snake_case, unused_variables, dead_code)] #[inline] pub unsafe fn {name}({params}) -> {return_suffix} {{ \ __gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\ (storage::{name}.f)({idents}) \ }}", name = cmd.proto.ident, params = super::gen_parameters(cmd, true, true).join(", "), typed_params = super::gen_parameters(cmd, false, true).join(", "), return_suffix = cmd.proto.ty, idents = super::gen_parameters(cmd, true, false).join(", "), )); } Ok(()) } /// Creates a `FnPtr` structure which contains the store for a single binding. fn write_fnptr_struct_def(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!(dest, " #[allow(missing_copy_implementations)] pub struct FnPtr {{ /// The function pointer that will be used when calling the function. f: *const __gl_imports::raw::c_void, /// True if the pointer points to a real function, false if points to a `panic!` fn. is_loaded: bool, }} impl FnPtr {{ /// Creates a `FnPtr` from a load attempt. pub fn new(ptr: *const __gl_imports::raw::c_void) -> FnPtr {{ if ptr.is_null() {{ FnPtr {{ f: missing_fn_panic as *const __gl_imports::raw::c_void, is_loaded: false }} }} else {{ FnPtr {{ f: ptr, is_loaded: true }} }} }} }} ") } /// Creates a `storage` module which contains a static `FnPtr` per GL command in the registry. fn write_ptrs(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, "mod storage {{ #![allow(non_snake_case)] #![allow(non_upper_case_globals)] use super::__gl_imports::raw; use super::FnPtr;" )); for c in ®istry.cmds { try!(writeln!( dest, "pub static mut {name}: FnPtr = FnPtr {{ f: super::missing_fn_panic as *const raw::c_void, is_loaded: false }};", name = c.proto.ident )); } writeln!(dest, "}}") } /// Creates one module for each GL command. /// /// Each module contains `is_loaded` and `load_with` which interact with the `storage` module /// created by `write_ptrs`. fn write_fn_mods(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { for c in ®istry.cmds { let fallbacks = match registry.aliases.get(&c.proto.ident) { Some(v) => { let names = v .iter() .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name[..]))) .collect::>(); format!("&[{}]", names.join(", ")) }, None => "&[]".to_string(), }; let fnname = &c.proto.ident[..]; let symbol = super::gen_symbol_name(registry.api, &c.proto.ident[..]); let symbol = &symbol[..]; try!(writeln!(dest, r##" #[allow(non_snake_case)] pub mod {fnname} {{ use super::{{storage, metaloadfn}}; use super::__gl_imports::raw; use super::FnPtr; #[inline] #[allow(dead_code)] pub fn is_loaded() -> bool {{ unsafe {{ storage::{fnname}.is_loaded }} }} #[allow(dead_code)] pub fn load_with(mut loadfn: F) where F: FnMut(&'static str) -> *const raw::c_void {{ unsafe {{ storage::{fnname} = FnPtr::new(metaloadfn(&mut loadfn, "{symbol}", {fallbacks})) }} }} }} "##, fnname = fnname, fallbacks = fallbacks, symbol = symbol)); } Ok(()) } /// Creates a `missing_fn_panic` function. /// /// This function is the mock that is called if the real function could not be called. fn write_panicking_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, "#[inline(never)] fn missing_fn_panic() -> ! {{ panic!(\"{api} function was not loaded\") }} ", api = registry.api ) } /// Creates the `load_with` function. /// /// The function calls `load_with` in each module created by `write_fn_mods`. fn write_load_fn(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!(dest, " /// Load each OpenGL symbol using a custom load function. This allows for the /// use of functions like `glfwGetProcAddress` or `SDL_GL_GetProcAddress`. /// ~~~ignore /// gl::load_with(|s| glfw.get_proc_address(s)); /// ~~~ #[allow(dead_code)] pub fn load_with(mut loadfn: F) where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{ #[inline(never)] fn inner(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void) {{ ")); for c in ®istry.cmds { try!(writeln!( dest, "{cmd_name}::load_with(&mut *loadfn);", cmd_name = &c.proto.ident[..] )); } writeln!( dest, " }} inner(&mut loadfn) }} " ) } gl_generator-0.14.0/generators/mod.rs010064400007650000024000000072521351110140300157540ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use registry::{Cmd, Enum, Registry}; use std::io; use Api; pub mod debug_struct_gen; pub mod global_gen; pub mod static_gen; pub mod static_struct_gen; pub mod struct_gen; /// Trait for a bindings generator. /// /// See https://github.com/brendanzab/gl-rs/tree/master/gl_generator#generator-types pub trait Generator { /// Builds the GL bindings. fn write(&self, registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write; } pub fn gen_struct_name(api: Api) -> &'static str { match api { Api::Gl => "Gl", Api::Glx => "Glx", Api::Wgl => "Wgl", Api::Egl => "Egl", Api::GlCore => "GlCore", Api::Gles1 => "Gles1", Api::Gles2 => "Gles2", Api::Glsc2 => "Glsc2", } } /// This function generates a `const name: type = value;` item. pub fn gen_enum_item(enm: &Enum, types_prefix: &str, dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!(dest, "#[allow(dead_code, non_upper_case_globals)] pub const {ident}: {types_prefix}{ty} = {value}{cast_suffix};", ident = enm.ident, types_prefix = if enm.ty == "&'static str" { "" } else { types_prefix }, ty = enm.ty, value = enm.value, cast_suffix = match enm.cast { true => format!(" as {}{}", types_prefix, enm.ty), false => String::new(), }, ) } /// Generates all the type aliases for a namespace. /// /// Aliases are either `pub type = ...` or `#[repr(C)] pub struct ... { ... }` and contain all the /// things that we can't obtain from the XML files. pub fn gen_types(api: Api, dest: &mut W) -> io::Result<()> where W: io::Write, { if let Api::Egl = api { try!(writeln!(dest, "{}", include_str!("templates/types/egl.rs"))); return Ok(()); } try!(writeln!(dest, "{}", include_str!("templates/types/gl.rs"))); match api { Api::Glx => try!(writeln!(dest, "{}", include_str!("templates/types/glx.rs"))), Api::Wgl => try!(writeln!(dest, "{}", include_str!("templates/types/wgl.rs"))), _ => {}, } Ok(()) } /// Generates the list of Rust `Arg`s that a `Cmd` requires. pub fn gen_parameters(cmd: &Cmd, with_idents: bool, with_types: bool) -> Vec { cmd.params .iter() .map(|binding| { // returning if with_idents && with_types { format!("{}: {}", binding.ident, binding.ty) } else if with_types { format!("{}", binding.ty) } else if with_idents { format!("{}", binding.ident) } else { panic!() } }) .collect() } /// Generates the native symbol name of a `Cmd`. /// /// Example results: `"glClear"`, `"wglCreateContext"`, etc. pub fn gen_symbol_name(api: Api, cmd: &str) -> String { match api { Api::Gl | Api::GlCore | Api::Gles1 | Api::Gles2 | Api::Glsc2 => format!("gl{}", cmd), Api::Glx => format!("glX{}", cmd), Api::Wgl => format!("wgl{}", cmd), Api::Egl => format!("egl{}", cmd), } } gl_generator-0.14.0/generators/static_gen.rs010064400007650000024000000057211326014606600173330ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use registry::Registry; use std::io; #[allow(missing_copy_implementations)] pub struct StaticGenerator; impl super::Generator for StaticGenerator { fn write(&self, registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(write_header(dest)); try!(write_type_aliases(registry, dest)); try!(write_enums(registry, dest)); try!(write_fns(registry, dest)); Ok(()) } } /// Creates a `__gl_imports` module which contains all the external symbols that we need for the /// bindings. fn write_header(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, r#" mod __gl_imports {{ pub use std::mem; pub use std::os::raw; }} "# ) } /// Creates a `types` module which contains all the type aliases. /// /// See also `generators::gen_types`. fn write_type_aliases(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, r#" pub mod types {{ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)] "# )); try!(super::gen_types(registry.api, dest)); writeln!( dest, " }} " ) } /// Creates all the `` elements at the root of the bindings. fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { for enm in ®istry.enums { try!(super::gen_enum_item(enm, "types::", dest)); } Ok(()) } /// io::Writes all functions corresponding to the GL bindings. /// /// These are foreign functions, they don't have any content. fn write_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, " #[allow(non_snake_case, unused_variables, dead_code)] extern \"system\" {{" )); for cmd in ®istry.cmds { try!(writeln!( dest, "#[link_name=\"{symbol}\"] pub fn {name}({params}) -> {return_suffix};", symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident), name = cmd.proto.ident, params = super::gen_parameters(cmd, true, true).join(", "), return_suffix = cmd.proto.ty, )); } writeln!(dest, "}}") } gl_generator-0.14.0/generators/static_struct_gen.rs010064400007650000024000000110231326014606600207270ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use registry::Registry; use std::io; #[allow(missing_copy_implementations)] pub struct StaticStructGenerator; impl super::Generator for StaticStructGenerator { fn write(&self, registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(write_header(dest)); try!(write_type_aliases(registry, dest)); try!(write_enums(registry, dest)); try!(write_struct(registry, dest)); try!(write_impl(registry, dest)); try!(write_fns(registry, dest)); Ok(()) } } /// Creates a `__gl_imports` module which contains all the external symbols that we need for the /// bindings. fn write_header(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, r#" mod __gl_imports {{ pub use std::mem; pub use std::os::raw; }} "# ) } /// Creates a `types` module which contains all the type aliases. /// /// See also `generators::gen_types`. fn write_type_aliases(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, r#" pub mod types {{ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)] "# )); try!(super::gen_types(registry.api, dest)); writeln!(dest, "}}") } /// Creates all the `` elements at the root of the bindings. fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { for enm in ®istry.enums { try!(super::gen_enum_item(enm, "types::", dest)); } Ok(()) } /// Creates a stub structure. /// /// The name of the struct corresponds to the namespace. fn write_struct(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, " #[allow(non_camel_case_types, non_snake_case, dead_code)] #[derive(Copy, Clone)] pub struct {api};", api = super::gen_struct_name(registry.api), ) } /// Creates the `impl` of the structure created by `write_struct`. fn write_impl(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!(dest, "impl {api} {{ /// Stub function. #[allow(dead_code)] pub fn load_with(mut _loadfn: F) -> {api} where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{ {api} }}", api = super::gen_struct_name(registry.api), )); for cmd in ®istry.cmds { try!(writeln!( dest, "#[allow(non_snake_case)] // #[allow(unused_variables)] #[allow(dead_code)] #[inline] pub unsafe fn {name}(&self, {typed_params}) -> {return_suffix} {{ {name}({idents}) }}", name = cmd.proto.ident, typed_params = super::gen_parameters(cmd, true, true).join(", "), return_suffix = cmd.proto.ty, idents = super::gen_parameters(cmd, true, false).join(", "), )); } writeln!(dest, "}}") } /// io::Writes all functions corresponding to the GL bindings. /// /// These are foreign functions, they don't have any content. fn write_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, " #[allow(non_snake_case)] #[allow(unused_variables)] #[allow(dead_code)] extern \"system\" {{" )); for cmd in ®istry.cmds { try!(writeln!( dest, "#[link_name=\"{symbol}\"] fn {name}({params}) -> {return_suffix};", symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident), name = cmd.proto.ident, params = super::gen_parameters(cmd, true, true).join(", "), return_suffix = cmd.proto.ty, )); } writeln!(dest, "}}") } gl_generator-0.14.0/generators/struct_gen.rs010064400007650000024000000200731351110140300173460ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use registry::Registry; use std::io; #[allow(missing_copy_implementations)] pub struct StructGenerator; impl super::Generator for StructGenerator { fn write(&self, registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(write_header(dest)); try!(write_type_aliases(registry, dest)); try!(write_enums(registry, dest)); try!(write_fnptr_struct_def(dest)); try!(write_panicking_fns(registry, dest)); try!(write_struct(registry, dest)); try!(write_impl(registry, dest)); Ok(()) } } /// Creates a `__gl_imports` module which contains all the external symbols that we need for the /// bindings. fn write_header(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, r#" mod __gl_imports {{ pub use std::mem; pub use std::marker::Send; pub use std::os::raw; }} "# ) } /// Creates a `types` module which contains all the type aliases. /// /// See also `generators::gen_types`. fn write_type_aliases(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, r#" pub mod types {{ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)] "# )); try!(super::gen_types(registry.api, dest)); writeln!(dest, "}}") } /// Creates all the `` elements at the root of the bindings. fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { for enm in ®istry.enums { try!(super::gen_enum_item(enm, "types::", dest)); } Ok(()) } /// Creates a `FnPtr` structure which contains the store for a single binding. fn write_fnptr_struct_def(dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, " #[allow(dead_code, missing_copy_implementations)] #[derive(Clone)] pub struct FnPtr {{ /// The function pointer that will be used when calling the function. f: *const __gl_imports::raw::c_void, /// True if the pointer points to a real function, false if points to a `panic!` fn. is_loaded: bool, }} impl FnPtr {{ /// Creates a `FnPtr` from a load attempt. fn new(ptr: *const __gl_imports::raw::c_void) -> FnPtr {{ if ptr.is_null() {{ FnPtr {{ f: missing_fn_panic as *const __gl_imports::raw::c_void, is_loaded: false }} }} else {{ FnPtr {{ f: ptr, is_loaded: true }} }} }} /// Returns `true` if the function has been successfully loaded. /// /// If it returns `false`, calling the corresponding function will fail. #[inline] #[allow(dead_code)] pub fn is_loaded(&self) -> bool {{ self.is_loaded }} }} " ) } /// Creates a `panicking` module which contains one function per GL command. /// /// These functions are the mocks that are called if the real function could not be loaded. fn write_panicking_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { writeln!( dest, "#[inline(never)] fn missing_fn_panic() -> ! {{ panic!(\"{api} function was not loaded\") }}", api = registry.api ) } /// Creates a structure which stores all the `FnPtr` of the bindings. /// /// The name of the struct corresponds to the namespace. fn write_struct(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!( dest, " #[allow(non_camel_case_types, non_snake_case, dead_code)] #[derive(Clone)] pub struct {api} {{", api = super::gen_struct_name(registry.api) )); for cmd in ®istry.cmds { if let Some(v) = registry.aliases.get(&cmd.proto.ident) { try!(writeln!(dest, "/// Fallbacks: {}", v.join(", "))); } try!(writeln!(dest, "pub {name}: FnPtr,", name = cmd.proto.ident)); } try!(writeln!(dest, "_priv: ()")); writeln!(dest, "}}") } /// Creates the `impl` of the structure created by `write_struct`. fn write_impl(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write, { try!(writeln!(dest, "impl {api} {{ /// Load each OpenGL symbol using a custom load function. This allows for the /// use of functions like `glfwGetProcAddress` or `SDL_GL_GetProcAddress`. /// /// ~~~ignore /// let gl = Gl::load_with(|s| glfw.get_proc_address(s)); /// ~~~ #[allow(dead_code, unused_variables)] pub fn load_with(mut loadfn: F) -> {api} where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{ #[inline(never)] fn do_metaloadfn(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void, symbol: &'static str, symbols: &[&'static str]) -> *const __gl_imports::raw::c_void {{ let mut ptr = loadfn(symbol); if ptr.is_null() {{ for &sym in symbols {{ ptr = loadfn(sym); if !ptr.is_null() {{ break; }} }} }} ptr }} let mut metaloadfn = |symbol: &'static str, symbols: &[&'static str]| {{ do_metaloadfn(&mut loadfn, symbol, symbols) }}; {api} {{", api = super::gen_struct_name(registry.api))); for cmd in ®istry.cmds { try!(writeln!( dest, "{name}: FnPtr::new(metaloadfn(\"{symbol}\", &[{fallbacks}])),", name = cmd.proto.ident, symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident), fallbacks = match registry.aliases.get(&cmd.proto.ident) { Some(fbs) => fbs .iter() .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name))) .collect::>() .join(", "), None => format!(""), }, )) } try!(writeln!(dest, "_priv: ()")); try!(writeln!( dest, "}} }}" )); for cmd in ®istry.cmds { try!(writeln!(dest, "#[allow(non_snake_case, unused_variables, dead_code)] #[inline] pub unsafe fn {name}(&self, {params}) -> {return_suffix} {{ \ __gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\ (self.{name}.f)({idents}) \ }}", name = cmd.proto.ident, params = super::gen_parameters(cmd, true, true).join(", "), typed_params = super::gen_parameters(cmd, false, true).join(", "), return_suffix = cmd.proto.ty, idents = super::gen_parameters(cmd, true, false).join(", "), )) } writeln!( dest, "}} unsafe impl __gl_imports::Send for {api} {{}}", api = super::gen_struct_name(registry.api) ) } gl_generator-0.14.0/generators/templates/types/egl.rs010064400007650000024000000065631322232160000211140ustar0000000000000000// platform-specific aliases are unknown // IMPORTANT: these are alises to the same level of the bindings // the values must be defined by the user #[allow(dead_code)] pub type khronos_utime_nanoseconds_t = super::khronos_utime_nanoseconds_t; #[allow(dead_code)] pub type khronos_uint64_t = super::khronos_uint64_t; #[allow(dead_code)] pub type khronos_ssize_t = super::khronos_ssize_t; pub type EGLNativeDisplayType = super::EGLNativeDisplayType; #[allow(dead_code)] pub type EGLNativePixmapType = super::EGLNativePixmapType; #[allow(dead_code)] pub type EGLNativeWindowType = super::EGLNativeWindowType; pub type EGLint = super::EGLint; #[allow(dead_code)] pub type NativeDisplayType = super::NativeDisplayType; #[allow(dead_code)] pub type NativePixmapType = super::NativePixmapType; #[allow(dead_code)] pub type NativeWindowType = super::NativeWindowType; // EGL alises pub type Bool = EGLBoolean; // TODO: not sure pub type EGLBoolean = super::__gl_imports::raw::c_uint; pub type EGLenum = super::__gl_imports::raw::c_uint; pub type EGLAttribKHR = isize; pub type EGLAttrib = isize; pub type EGLConfig = *const super::__gl_imports::raw::c_void; pub type EGLContext = *const super::__gl_imports::raw::c_void; pub type EGLDeviceEXT = *const super::__gl_imports::raw::c_void; pub type EGLDisplay = *const super::__gl_imports::raw::c_void; pub type EGLSurface = *const super::__gl_imports::raw::c_void; pub type EGLClientBuffer = *const super::__gl_imports::raw::c_void; pub enum __eglMustCastToProperFunctionPointerType_fn {} pub type __eglMustCastToProperFunctionPointerType = *mut __eglMustCastToProperFunctionPointerType_fn; pub type EGLImageKHR = *const super::__gl_imports::raw::c_void; pub type EGLImage = *const super::__gl_imports::raw::c_void; pub type EGLOutputLayerEXT = *const super::__gl_imports::raw::c_void; pub type EGLOutputPortEXT = *const super::__gl_imports::raw::c_void; pub type EGLSyncKHR = *const super::__gl_imports::raw::c_void; pub type EGLSync = *const super::__gl_imports::raw::c_void; pub type EGLTimeKHR = khronos_utime_nanoseconds_t; pub type EGLTime = khronos_utime_nanoseconds_t; pub type EGLSyncNV = *const super::__gl_imports::raw::c_void; pub type EGLTimeNV = khronos_utime_nanoseconds_t; pub type EGLuint64NV = khronos_utime_nanoseconds_t; pub type EGLStreamKHR = *const super::__gl_imports::raw::c_void; pub type EGLuint64KHR = khronos_uint64_t; pub type EGLNativeFileDescriptorKHR = super::__gl_imports::raw::c_int; pub type EGLsizeiANDROID = khronos_ssize_t; pub type EGLSetBlobFuncANDROID = extern "system" fn(*const super::__gl_imports::raw::c_void, EGLsizeiANDROID, *const super::__gl_imports::raw::c_void, EGLsizeiANDROID) -> (); pub type EGLGetBlobFuncANDROID = extern "system" fn(*const super::__gl_imports::raw::c_void, EGLsizeiANDROID, *mut super::__gl_imports::raw::c_void, EGLsizeiANDROID) -> EGLsizeiANDROID; #[repr(C)] pub struct EGLClientPixmapHI { pData: *const super::__gl_imports::raw::c_void, iWidth: EGLint, iHeight: EGLint, iStride: EGLint, } gl_generator-0.14.0/generators/templates/types/gl.rs010064400007650000024000000111561354534535300207640ustar0000000000000000// Common types from OpenGL 1.1 pub type GLenum = super::__gl_imports::raw::c_uint; pub type GLboolean = super::__gl_imports::raw::c_uchar; pub type GLbitfield = super::__gl_imports::raw::c_uint; pub type GLvoid = super::__gl_imports::raw::c_void; pub type GLbyte = super::__gl_imports::raw::c_char; pub type GLshort = super::__gl_imports::raw::c_short; pub type GLint = super::__gl_imports::raw::c_int; pub type GLclampx = super::__gl_imports::raw::c_int; pub type GLubyte = super::__gl_imports::raw::c_uchar; pub type GLushort = super::__gl_imports::raw::c_ushort; pub type GLuint = super::__gl_imports::raw::c_uint; pub type GLsizei = super::__gl_imports::raw::c_int; pub type GLfloat = super::__gl_imports::raw::c_float; pub type GLclampf = super::__gl_imports::raw::c_float; pub type GLdouble = super::__gl_imports::raw::c_double; pub type GLclampd = super::__gl_imports::raw::c_double; pub type GLeglImageOES = *const super::__gl_imports::raw::c_void; pub type GLchar = super::__gl_imports::raw::c_char; pub type GLcharARB = super::__gl_imports::raw::c_char; #[cfg(target_os = "macos")] pub type GLhandleARB = *const super::__gl_imports::raw::c_void; #[cfg(not(target_os = "macos"))] pub type GLhandleARB = super::__gl_imports::raw::c_uint; pub type GLhalfARB = super::__gl_imports::raw::c_ushort; pub type GLhalf = super::__gl_imports::raw::c_ushort; // Must be 32 bits pub type GLfixed = GLint; pub type GLintptr = isize; pub type GLsizeiptr = isize; pub type GLint64 = i64; pub type GLuint64 = u64; pub type GLintptrARB = isize; pub type GLsizeiptrARB = isize; pub type GLint64EXT = i64; pub type GLuint64EXT = u64; pub enum __GLsync {} pub type GLsync = *const __GLsync; // compatible with OpenCL cl_context pub enum _cl_context {} pub enum _cl_event {} pub type GLDEBUGPROC = Option; pub type GLDEBUGPROCARB = Option; pub type GLDEBUGPROCKHR = Option; // GLES 1 types // "pub type GLclampx = i32;", // GLES 1/2 types (tagged for GLES 1) // "pub type GLbyte = i8;", // "pub type GLubyte = u8;", // "pub type GLfloat = GLfloat;", // "pub type GLclampf = GLfloat;", // "pub type GLfixed = i32;", // "pub type GLint64 = i64;", // "pub type GLuint64 = u64;", // "pub type GLintptr = intptr_t;", // "pub type GLsizeiptr = ssize_t;", // GLES 1/2 types (tagged for GLES 2 - attribute syntax is limited) // "pub type GLbyte = i8;", // "pub type GLubyte = u8;", // "pub type GLfloat = GLfloat;", // "pub type GLclampf = GLfloat;", // "pub type GLfixed = i32;", // "pub type GLint64 = i64;", // "pub type GLuint64 = u64;", // "pub type GLint64EXT = i64;", // "pub type GLuint64EXT = u64;", // "pub type GLintptr = intptr_t;", // "pub type GLsizeiptr = ssize_t;", // GLES 2 types (none currently) // Vendor extension types pub type GLDEBUGPROCAMD = Option; pub type GLhalfNV = super::__gl_imports::raw::c_ushort; pub type GLvdpauSurfaceNV = GLintptr; gl_generator-0.14.0/generators/templates/types/glx.rs010064400007650000024000000126071322232145000211360ustar0000000000000000pub type XID = super::__gl_imports::raw::c_ulong; pub type Bool = super::__gl_imports::raw::c_int; // Not sure if this is correct... pub enum Display {} pub type Font = XID; pub type Pixmap = XID; pub enum Visual {} // TODO: not sure pub type VisualID = super::__gl_imports::raw::c_ulong; // TODO: not sure pub type Window = XID; pub type GLXFBConfigID = XID; pub type GLXFBConfig = *const super::__gl_imports::raw::c_void; pub type GLXContextID = XID; pub type GLXContext = *const super::__gl_imports::raw::c_void; pub type GLXPixmap = XID; pub type GLXDrawable = XID; pub type GLXWindow = XID; pub type GLXPbuffer = XID; pub enum __GLXextFuncPtr_fn {} pub type __GLXextFuncPtr = *mut __GLXextFuncPtr_fn; pub type GLXVideoCaptureDeviceNV = XID; pub type GLXVideoDeviceNV = super::__gl_imports::raw::c_int; pub type GLXVideoSourceSGIX = XID; pub type GLXFBConfigIDSGIX = XID; pub type GLXFBConfigSGIX = *const super::__gl_imports::raw::c_void; pub type GLXPbufferSGIX = XID; #[repr(C)] pub struct XVisualInfo { pub visual: *mut Visual, pub visualid: VisualID, pub screen: super::__gl_imports::raw::c_int, pub depth: super::__gl_imports::raw::c_int, pub class: super::__gl_imports::raw::c_int, pub red_mask: super::__gl_imports::raw::c_ulong, pub green_mask: super::__gl_imports::raw::c_ulong, pub blue_mask: super::__gl_imports::raw::c_ulong, pub colormap_size: super::__gl_imports::raw::c_int, pub bits_per_rgb: super::__gl_imports::raw::c_int, } #[repr(C)] pub struct GLXPbufferClobberEvent { pub event_type: super::__gl_imports::raw::c_int, // GLX_DAMAGED or GLX_SAVED pub draw_type: super::__gl_imports::raw::c_int, // GLX_WINDOW or GLX_PBUFFER pub serial: super::__gl_imports::raw::c_ulong, // # of last request processed by server pub send_event: Bool, // true if this came for SendEvent request pub display: *const Display, // display the event was read from pub drawable: GLXDrawable, // XID of Drawable pub buffer_mask: super::__gl_imports::raw::c_uint, // mask indicating which buffers are affected pub aux_buffer: super::__gl_imports::raw::c_uint, // which aux buffer was affected pub x: super::__gl_imports::raw::c_int, pub y: super::__gl_imports::raw::c_int, pub width: super::__gl_imports::raw::c_int, pub height: super::__gl_imports::raw::c_int, pub count: super::__gl_imports::raw::c_int, // if nonzero, at least this many more } #[repr(C)] pub struct GLXBufferSwapComplete { pub type_: super::__gl_imports::raw::c_int, pub serial: super::__gl_imports::raw::c_ulong, // # of last request processed by server pub send_event: Bool, // true if this came from a SendEvent request pub display: *const Display, // Display the event was read from pub drawable: GLXDrawable, // drawable on which event was requested in event mask pub event_type: super::__gl_imports::raw::c_int, pub ust: i64, pub msc: i64, pub sbc: i64, } // typedef union __GLXEvent { // GLXPbufferClobberEvent glxpbufferclobber; // GLXBufferSwapComplete glxbufferswapcomplete; // long pad[24]; // } #[repr(C)] pub struct GLXBufferClobberEventSGIX { pub type_: super::__gl_imports::raw::c_int, pub serial: super::__gl_imports::raw::c_ulong, // # of last request processed by server pub send_event: Bool, // true if this came for SendEvent request pub display: *const Display, // display the event was read from pub drawable: GLXDrawable, // i.d. of Drawable pub event_type: super::__gl_imports::raw::c_int, // GLX_DAMAGED_SGIX or GLX_SAVED_SGIX pub draw_type: super::__gl_imports::raw::c_int, // GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX pub mask: super::__gl_imports::raw::c_uint, // mask indicating which buffers are affected pub x: super::__gl_imports::raw::c_int, pub y: super::__gl_imports::raw::c_int, pub width: super::__gl_imports::raw::c_int, pub height: super::__gl_imports::raw::c_int, pub count: super::__gl_imports::raw::c_int, // if nonzero, at least this many more } #[repr(C)] pub struct GLXHyperpipeNetworkSGIX { pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] pub networkId: super::__gl_imports::raw::c_int, } #[repr(C)] pub struct GLXHyperpipeConfigSGIX { pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] pub channel: super::__gl_imports::raw::c_int, pub participationType: super::__gl_imports::raw::c_uint, pub timeSlice: super::__gl_imports::raw::c_int, } #[repr(C)] pub struct GLXPipeRect { pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] pub srcXOrigin: super::__gl_imports::raw::c_int, pub srcYOrigin: super::__gl_imports::raw::c_int, pub srcWidth: super::__gl_imports::raw::c_int, pub srcHeight: super::__gl_imports::raw::c_int, pub destXOrigin: super::__gl_imports::raw::c_int, pub destYOrigin: super::__gl_imports::raw::c_int, pub destWidth: super::__gl_imports::raw::c_int, pub destHeight: super::__gl_imports::raw::c_int, } #[repr(C)] pub struct GLXPipeRectLimits { pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] pub XOrigin: super::__gl_imports::raw::c_int, pub YOrigin: super::__gl_imports::raw::c_int, pub maxHeight: super::__gl_imports::raw::c_int, pub maxWidth: super::__gl_imports::raw::c_int, } gl_generator-0.14.0/generators/templates/types/wgl.rs010064400007650000024000000071671322232145700211510ustar0000000000000000// From WinNT.h pub type CHAR = super::__gl_imports::raw::c_char; pub type HANDLE = PVOID; pub type LONG = super::__gl_imports::raw::c_long; pub type LPCSTR = *const super::__gl_imports::raw::c_char; pub type VOID = (); // #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name pub type HPBUFFERARB = *const super::__gl_imports::raw::c_void; pub type HPBUFFEREXT = *const super::__gl_imports::raw::c_void; pub type HVIDEOOUTPUTDEVICENV = *const super::__gl_imports::raw::c_void; pub type HPVIDEODEV = *const super::__gl_imports::raw::c_void; pub type HPGPUNV = *const super::__gl_imports::raw::c_void; pub type HGPUNV = *const super::__gl_imports::raw::c_void; pub type HVIDEOINPUTDEVICENV = *const super::__gl_imports::raw::c_void; // From Windef.h pub type BOOL = super::__gl_imports::raw::c_int; pub type BYTE = super::__gl_imports::raw::c_uchar; pub type COLORREF = DWORD; pub type FLOAT = super::__gl_imports::raw::c_float; pub type HDC = HANDLE; pub type HENHMETAFILE = HANDLE; pub type HGLRC = *const super::__gl_imports::raw::c_void; pub type INT = super::__gl_imports::raw::c_int; pub type PVOID = *const super::__gl_imports::raw::c_void; pub type LPVOID = *const super::__gl_imports::raw::c_void; pub enum __PROC_fn {} pub type PROC = *mut __PROC_fn; #[repr(C)] pub struct RECT { left: LONG, top: LONG, right: LONG, bottom: LONG, } pub type UINT = super::__gl_imports::raw::c_uint; pub type USHORT = super::__gl_imports::raw::c_ushort; pub type WORD = super::__gl_imports::raw::c_ushort; // From BaseTsd.h pub type INT32 = i32; pub type INT64 = i64; // From IntSafe.h pub type DWORD = super::__gl_imports::raw::c_ulong; // From Wingdi.h #[repr(C)] pub struct POINTFLOAT { pub x: FLOAT, pub y: FLOAT, } #[repr(C)] pub struct GLYPHMETRICSFLOAT { pub gmfBlackBoxX: FLOAT, pub gmfBlackBoxY: FLOAT, pub gmfptGlyphOrigin: POINTFLOAT, pub gmfCellIncX: FLOAT, pub gmfCellIncY: FLOAT, } pub type LPGLYPHMETRICSFLOAT = *const GLYPHMETRICSFLOAT; #[repr(C)] pub struct LAYERPLANEDESCRIPTOR { pub nSize: WORD, pub nVersion: WORD, pub dwFlags: DWORD, pub iPixelType: BYTE, pub cColorBits: BYTE, pub cRedBits: BYTE, pub cRedShift: BYTE, pub cGreenBits: BYTE, pub cGreenShift: BYTE, pub cBlueBits: BYTE, pub cBlueShift: BYTE, pub cAlphaBits: BYTE, pub cAlphaShift: BYTE, pub cAccumBits: BYTE, pub cAccumRedBits: BYTE, pub cAccumGreenBits: BYTE, pub cAccumBlueBits: BYTE, pub cAccumAlphaBits: BYTE, pub cDepthBits: BYTE, pub cStencilBits: BYTE, pub cAuxBuffers: BYTE, pub iLayerType: BYTE, pub bReserved: BYTE, pub crTransparent: COLORREF, } #[repr(C)] pub struct PIXELFORMATDESCRIPTOR { pub nSize: WORD, pub nVersion: WORD, pub dwFlags: DWORD, pub iPixelType: BYTE, pub cColorBits: BYTE, pub cRedBits: BYTE, pub cRedShift: BYTE, pub cGreenBits: BYTE, pub cGreenShift: BYTE, pub cBlueBits: BYTE, pub cBlueShift: BYTE, pub cAlphaBits: BYTE, pub cAlphaShift: BYTE, pub cAccumBits: BYTE, pub cAccumRedBits: BYTE, pub cAccumGreenBits: BYTE, pub cAccumBlueBits: BYTE, pub cAccumAlphaBits: BYTE, pub cDepthBits: BYTE, pub cStencilBits: BYTE, pub cAuxBuffers: BYTE, pub iLayerType: BYTE, pub bReserved: BYTE, pub dwLayerMask: DWORD, pub dwVisibleMask: DWORD, pub dwDamageMask: DWORD, } #[repr(C)] pub struct _GPU_DEVICE { cb: DWORD, DeviceName: [CHAR; 32], DeviceString: [CHAR; 128], Flags: DWORD, rcVirtualScreen: RECT, } pub struct GPU_DEVICE(_GPU_DEVICE); pub struct PGPU_DEVICE(*const _GPU_DEVICE); gl_generator-0.14.0/lib.rs010064400007650000024000000046001351110140300135640ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! An OpenGL bindings generator. It defines a function named `generate_bindings` which can be //! used to generate all constants and functions of a given OpenGL version. //! //! # Example //! //! In `build.rs`: //! //! ```no_run //! extern crate gl_generator; //! //! use gl_generator::{Registry, Api, Profile, Fallbacks, GlobalGenerator}; //! use std::env; //! use std::fs::File; //! use std::path::Path; //! //! fn main() { //! let dest = env::var("OUT_DIR").unwrap(); //! let mut file = File::create(&Path::new(&dest).join("gl_bindings.rs")).unwrap(); //! //! Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, []) //! .write_bindings(GlobalGenerator, &mut file) //! .unwrap(); //! } //! ``` //! //! In your project: //! //! ```ignore //! include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs")); //! ``` //! //! # About EGL //! //! When you generate bindings for EGL, the following platform-specific types must be declared //! *at the same level where you include the bindings*: //! //! - `khronos_utime_nanoseconds_t` //! - `khronos_uint64_t` //! - `khronos_ssize_t` //! - `EGLNativeDisplayType` //! - `EGLNativePixmapType` //! - `EGLNativeWindowType` //! - `EGLint` //! - `NativeDisplayType` //! - `NativePixmapType` //! - `NativeWindowType` //! #[macro_use] extern crate log; extern crate xml; #[cfg(feature = "unstable_generator_utils")] pub mod generators; #[cfg(not(feature = "unstable_generator_utils"))] mod generators; mod registry; pub use generators::debug_struct_gen::DebugStructGenerator; pub use generators::global_gen::GlobalGenerator; pub use generators::static_gen::StaticGenerator; pub use generators::static_struct_gen::StaticStructGenerator; pub use generators::struct_gen::StructGenerator; pub use generators::Generator; pub use registry::*; gl_generator-0.14.0/README.md010064400007650000024000000121201351110140300137230ustar0000000000000000# gl_generator [![Version](https://img.shields.io/crates/v/gl_generator.svg)](https://crates.io/crates/gl_generator) [![License](https://img.shields.io/crates/l/gl_generator.svg)](https://github.com/brendanzab/gl-rs/blob/master/LICENSE) [![Downloads](https://img.shields.io/crates/d/gl_generator.svg)](https://crates.io/crates/gl_generator) Code generators for creating bindings to the Khronos OpenGL APIs. ## Usage If you need a specific version of OpenGL, or you need a different API (OpenGL ES, EGL, WGL, GLX), or if you need certain extensions, you should use the `gl_generator` plugin instead. See [gfx_gl](https://github.com/gfx-rs/gfx_gl) for an example of using a custom gfx-rs loader for a project. Add this to your `Cargo.toml`: ```toml [build-dependencies] gl_generator = "0.5.0" ``` Under the `[package]` section, add: ```toml build = "build.rs" ``` Create a `build.rs` to pull your specific version/API: ```rust extern crate gl_generator; use gl_generator::{Registry, Api, Profile, Fallbacks, GlobalGenerator}; use std::env; use std::fs::File; use std::path::Path; fn main() { let dest = env::var("OUT_DIR").unwrap(); let mut file = File::create(&Path::new(&dest).join("bindings.rs")).unwrap(); Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, []) .write_bindings(GlobalGenerator, &mut file) .unwrap(); } ``` Then use it like this: ```rust mod gl { include!(concat!(env!("OUT_DIR"), "/bindings.rs")); } /// Simple loading example fn main() { let window = ...; // Assuming `window` is GLFW: initialize, and make current gl::load_with(|s| window.get_proc_address(s) as *const _); } ``` The `build.rs` file will generate all the OpenGL functions in a file named, `bindings.rs` plus all enumerations, and all types in the `types` submodule. ## Generator types ### Global generator The global generator is the one used by default by the `gl` crate. See above for more details. ### Struct generator The struct generator is a cleaner alternative to the global generator. The main difference is that you must call `gl::Gl::load_with` instead of `gl::load_with`, and this functions returns a struct of type `Gl`. The OpenGL functions are not static functions but member functions in this `Gl` struct. This is important when the GL functions are associated with the current context, as is true on Windows. The enumerations and types are still static and available in a similar way as in the global generator. ### Static generator The static generator generates plain old bindings. You don't need to load the functions. This generator should only be used only if the platform you are compiling for is guaranteed to support the requested API. Otherwise you will get a compilation error. For example, you can use it for WGL and OpenGL 1.1 on Windows or GLX and OpenGL 1.3 on Linux, because Windows and Linux are guaranteed to provide implementations for these APIs. You will need to manually provide the linkage. For example to use WGL or OpenGL 1.1 on Windows, you will need to add `#[link="OpenGL32.lib"] extern {}` somewhere in your code. ### Custom Generators The `gl_generator` can be extended with custom generators. This is a niche feature useful only in very rare cases. To create a custom generator, implement the `gl_generator::Generator` trait. See the source of the `gl_generator::generators` module for examples. Various utility functions are provided in the `generators` module, but the api is unstable, so it has been placed behind a feature flag. In access these functions, you will need to add the `"unstable_generator_utils"` feature to your `Cargo.toml`: ```toml [build-dependencies.gl_generator] version = "0.4.2" features = ["unstable_generator_utils"] ``` ## Extra features The global and struct generators will attempt to use fallbacks functions when they are available. For example, if `glGenFramebuffers` cannot be loaded it will also attempt to load `glGenFramebuffersEXT` as a fallback. ## Changelog ### v0.5.0 - Rename `Ns` to `API`, and expose at the top level - Remove the need for clients to depend on the `khronos_api` crate by determining the XML source based on the requested `API` - Use a `(u8, u8)` instead of a string for the target version number - Use a `Profile` enum instead of a string for the profile - Remove unused fields from `Registry` - Accept types satisfying `AsRef<[&str]>` for extension lists - Separate parsing and generation stages in API - Hide `registry::{Feature, Filter, Require, Remove, Extension}` types from the public API - Move `registry::{Fallbacks, Api, Profile}` types to top level module - Remove `GlxOpcode::type` field - Make `ty` fields on `Enum` and `Binding` take `Cow<'static, str>`s to reduce allocations ### v0.4.2 - Update crate metadata ### v0.4.1 - Upgrade `khronos_api` to v1.0.0 ### v0.4.0 - Upgrade `xml-rs` to v0.2.2 - Use `raw::c_void` for `GLvoid` - Remove `registry::{Group, EnumNs, CmdNs}` - Remove `groups` field from `registry::Registry` - Remove `is_safe` field from `registry::Cmd` - Remove `comment` field from `registry::{Require, Remove, GlxOpcode}` - Downgrade `khronos_api` to be a dev-dependency gl_generator-0.14.0/registry/mod.rs010064400007650000024000000122401351110140300154440ustar0000000000000000// Copyright 2015-2016 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. extern crate khronos_api; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet}; use std::fmt; use std::hash::{Hash, Hasher}; use std::io; use std::ops::{Add, AddAssign}; use Generator; mod parse; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Api { Gl, Glx, Wgl, Egl, GlCore, Gles1, Gles2, Glsc2, } impl fmt::Display for Api { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { Api::Gl => write!(fmt, "gl"), Api::Glx => write!(fmt, "glx"), Api::Wgl => write!(fmt, "wgl"), Api::Egl => write!(fmt, "egl"), Api::GlCore => write!(fmt, "glcore"), Api::Gles1 => write!(fmt, "gles1"), Api::Gles2 => write!(fmt, "gles2"), Api::Glsc2 => write!(fmt, "glsc2"), } } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Fallbacks { All, None, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Profile { Core, Compatibility, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Enum { pub ident: String, pub value: String, pub cast: bool, pub alias: Option, pub ty: Cow<'static, str>, } impl Hash for Enum { fn hash(&self, state: &mut H) { self.ident.hash(state); } } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Binding { pub ident: String, pub ty: Cow<'static, str>, pub group: Option, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Group { pub ident: String, pub enums_type: Option, pub enums: Vec, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Cmd { pub proto: Binding, pub params: Vec, pub alias: Option, pub vecequiv: Option, pub glx: Option, } impl Hash for Cmd { fn hash(&self, state: &mut H) { self.proto.ident.hash(state); } } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct GlxOpcode { pub opcode: String, pub name: Option, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Registry { pub api: Api, pub enums: BTreeSet, pub cmds: BTreeSet, pub aliases: BTreeMap>, pub groups: BTreeMap, } impl Registry { pub fn new<'a, Exts>( api: Api, version: (u8, u8), profile: Profile, fallbacks: Fallbacks, extensions: Exts, ) -> Registry where Exts: AsRef<[&'a str]>, { let (major, minor) = version; let extensions = extensions.as_ref().iter().map(<&str>::to_string).collect(); let filter = parse::Filter { api, fallbacks, extensions, version: format!("{}.{}", major, minor), profile, }; let src = match api { Api::Gl | Api::GlCore | Api::Gles1 | Api::Gles2 | Api::Glsc2 => khronos_api::GL_XML, Api::Glx => khronos_api::GLX_XML, Api::Wgl => khronos_api::WGL_XML, Api::Egl => khronos_api::EGL_XML, }; let mut registry = parse::from_xml(src, &filter, true); if filter.extensions.iter().any(|e| e.starts_with("GL_ANGLE_")) { registry += parse::from_xml(khronos_api::GL_ANGLE_EXT_XML, &filter, false); } if filter.extensions.iter().any(|e| e.starts_with("EGL_ANGLE_")) { registry += parse::from_xml(khronos_api::EGL_ANGLE_EXT_XML, &filter, false); } registry } pub fn write_bindings(&self, generator: G, output: &mut W) -> io::Result<()> where G: Generator, W: io::Write, { generator.write(&self, output) } /// Returns a set of all the types used in the supplied registry. This is useful /// for working out what conversions are needed for the specific registry. pub fn get_tys(&self) -> BTreeSet<&str> { let mut tys = BTreeSet::new(); for def in &self.cmds { tys.insert(def.proto.ty.as_ref()); for param in &def.params { tys.insert(param.ty.as_ref()); } } tys } } impl Add for Registry { type Output = Registry; fn add(mut self, other: Registry) -> Registry { self += other; self } } impl AddAssign for Registry { fn add_assign(&mut self, other: Self) { self.enums.extend(other.enums); self.cmds.extend(other.cmds); self.aliases.extend(other.aliases); } } gl_generator-0.14.0/registry/parse.rs010064400007650000024000001464311352746561600160430ustar0000000000000000// Copyright 2015 Brendan Zabarauskas and the gl-rs developers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. extern crate khronos_api; use std::borrow::Cow; use std::collections::btree_map::Entry; use std::collections::{BTreeMap, BTreeSet}; use std::io; use xml::attribute::OwnedAttribute; use xml::reader::XmlEvent; use xml::EventReader as XmlEventReader; use registry::{Binding, Cmd, Enum, GlxOpcode, Group, Registry}; use {Api, Fallbacks, Profile}; pub fn from_xml( src: R, filter: &Filter, require_feature: bool, ) -> Registry { XmlEventReader::new(src) .into_iter() .map(Result::unwrap) .filter_map(ParseEvent::from_xml) .parse(filter, require_feature) } #[derive(Debug, PartialEq, Eq)] struct Attribute { key: String, value: String, } impl Attribute { fn new(key: Key, value: Value) -> Attribute where Key: ToString, Value: ToString, { Attribute { key: key.to_string(), value: value.to_string(), } } } impl From for Attribute { fn from(attribute: OwnedAttribute) -> Attribute { Attribute::new(attribute.name.local_name, attribute.value) } } #[derive(Debug, PartialEq, Eq)] enum ParseEvent { Start(String, Vec), End(String), Text(String), } impl ParseEvent { fn from_xml(event: XmlEvent) -> Option { match event { XmlEvent::StartDocument { .. } => None, XmlEvent::EndDocument => None, XmlEvent::StartElement { name, attributes, .. } => { let attributes = attributes.into_iter().map(Attribute::from).collect(); Some(ParseEvent::Start(name.local_name, attributes)) }, XmlEvent::EndElement { name } => Some(ParseEvent::End(name.local_name)), XmlEvent::Characters(chars) => Some(ParseEvent::Text(chars)), XmlEvent::ProcessingInstruction { .. } => None, XmlEvent::CData(_) => None, XmlEvent::Comment(_) => None, XmlEvent::Whitespace(_) => None, } } } fn api_from_str(src: &str) -> Result, ()> { match src { "gl" => Ok(Some(Api::Gl)), "glx" => Ok(Some(Api::Glx)), "wgl" => Ok(Some(Api::Wgl)), "egl" => Ok(Some(Api::Egl)), "glcore" => Ok(Some(Api::GlCore)), "gles1" => Ok(Some(Api::Gles1)), "gles2" => Ok(Some(Api::Gles2)), "glsc2" => Ok(Some(Api::Glsc2)), "disabled" => Ok(None), _ => Err(()), } } fn profile_from_str(src: &str) -> Result { match src { "core" => Ok(Profile::Core), "compatibility" => Ok(Profile::Compatibility), _ => Err(()), } } fn underscore_numeric_prefix(src: &str) -> String { match src.chars().next() { Some(c) if c.is_numeric() => format!("_{}", src), Some(_) | None => src.to_string(), } } fn underscore_keyword(ident: String) -> String { match ident.as_ref() { "in" => "in_".to_string(), "ref" => "ref_".to_string(), "type" => "type_".to_string(), _ => ident, } } fn trim_str<'a>(s: &'a str, trim: &str) -> &'a str { if s.starts_with(trim) { &s[trim.len()..] } else { s } } fn trim_enum_prefix(ident: &str, api: Api) -> String { let ident = match api { Api::Gl | Api::GlCore | Api::Gles1 | Api::Gles2 | Api::Glsc2 => trim_str(ident, "GL_"), Api::Glx => trim_str(ident, "GLX_"), Api::Wgl => trim_str(ident, "WGL_"), Api::Egl => trim_str(ident, "EGL_"), }; underscore_numeric_prefix(ident) } fn make_enum(ident: String, ty: Option, value: String, alias: Option) -> Enum { let (ty, value, cast) = { if value.starts_with("((") && value.ends_with(")") { // Some enums have a value of the form `'((' type ')' expr ')'`. // nothing to see here.... // just brute forcing some paren matching... (ノ ◕ ◡ ◕)ノ *:・゚✧ let working = &value[2..value.len() - 1]; if let Some((i, _)) = working.match_indices(")").next() { let ty = working[..i].to_string(); let value = working[i + 1..].to_string(); (Cow::Owned(ty), value, true) } else { panic!("Unexpected value format: {}", value) } } else { let ty = match ty { Some(ref ty) if ty == "u" => "GLuint", Some(ref ty) if ty == "ull" => "GLuint64", Some(ty) => panic!("Unhandled enum type: {}", ty), None if value.starts_with("\"") => "&'static str", None if ident == "TRUE" || ident == "FALSE" => "GLboolean", None => "GLenum", }; (Cow::Borrowed(ty), value, false) } }; Enum { ident: ident, value: value, cast: cast, alias: alias, ty: ty, } } fn make_egl_enum(ident: String, ty: Option, value: String, alias: Option) -> Enum { let (ty, value, cast) = { if value.starts_with("EGL_CAST(") && value.ends_with(")") { // Handling "SpecialNumbers" in the egl.xml file // The values for these enums has the form `'EGL_CAST(' type ',' expr ')'`. let working = &value[9..value.len() - 1]; if let Some((i, _)) = working.match_indices(",").next() { let ty = working[..i].to_string(); let value = working[i + 1..].to_string(); (Cow::Owned(ty), value, true) } else { panic!("Unexpected value format: {}", value) } } else { match value.chars().next() { Some('-') | Some('0'..='9') => (), _ => panic!("Unexpected value format: {}", value), } let ty = match ty { Some(ref ty) if ty == "ull" => "EGLuint64KHR", Some(ty) => panic!("Unhandled enum type: {}", ty), None if value.starts_with('-') => "EGLint", None if ident == "TRUE" || ident == "FALSE" => "EGLBoolean", None => "EGLenum", }; (Cow::Borrowed(ty), value, false) } }; Enum { ident: ident, value: value, cast: cast, alias: alias, ty: ty, } } fn trim_cmd_prefix(ident: &str, api: Api) -> &str { match api { Api::Gl | Api::GlCore | Api::Gles1 | Api::Gles2 | Api::Glsc2 => trim_str(ident, "gl"), Api::Glx => trim_str(ident, "glX"), Api::Wgl => trim_str(ident, "wgl"), Api::Egl => trim_str(ident, "egl"), } } fn merge_map(a: &mut BTreeMap>, b: BTreeMap>) { for (k, v) in b { match a.entry(k) { Entry::Occupied(mut ent) => { ent.get_mut().extend(v); }, Entry::Vacant(ent) => { ent.insert(v); }, } } } #[derive(Clone)] struct Feature { pub api: Api, pub name: String, pub number: String, pub requires: Vec, pub removes: Vec, } #[derive(Clone)] struct Require { /// A reference to the earlier types, by name pub enums: Vec, /// A reference to the earlier types, by name pub commands: Vec, } #[derive(Clone)] struct Remove { // always Core, for now pub profile: Profile, /// A reference to the earlier types, by name pub enums: Vec, /// A reference to the earlier types, by name pub commands: Vec, } #[derive(Clone)] struct Extension { pub name: String, /// which apis this extension is defined for (see Feature.api) pub supported: Vec, pub requires: Vec, } pub struct Filter { pub api: Api, pub fallbacks: Fallbacks, pub extensions: BTreeSet, pub profile: Profile, pub version: String, } trait Parse: Sized + Iterator { fn parse(mut self, filter: &Filter, require_feature: bool) -> Registry { self.consume_start_element("registry"); let mut enums = Vec::new(); let mut cmds = Vec::new(); let mut features = Vec::new(); let mut extensions = Vec::new(); let mut aliases = BTreeMap::new(); let mut groups: BTreeMap = BTreeMap::new(); while let Some(event) = self.next() { match event { // ignores ParseEvent::Text(_) => (), ParseEvent::Start(ref name, _) if name == "comment" => self.skip_to_end("comment"), ParseEvent::Start(ref name, _) if name == "types" => self.skip_to_end("types"), // add group namespace ParseEvent::Start(ref name, _) if name == "groups" => { groups.extend(self.consume_groups(filter.api)); }, // add enum namespace ParseEvent::Start(ref name, ref attributes) if name == "enums" => { enums.extend(self.consume_enums(filter.api)); let enums_group = get_attribute(&attributes, "group"); let enums_type = get_attribute(&attributes, "type"); if let Some(group) = enums_group.and_then(|name| groups.get_mut(&name)) { group.enums_type = enums_type; } }, // add command namespace ParseEvent::Start(ref name, _) if name == "commands" => { let (new_cmds, new_aliases) = self.consume_cmds(filter.api); cmds.extend(new_cmds); merge_map(&mut aliases, new_aliases); }, ParseEvent::Start(ref name, ref attributes) if name == "feature" => { debug!("Parsing feature: {:?}", attributes); features.push(Feature::convert(&mut self, &attributes)); }, ParseEvent::Start(ref name, _) if name == "extensions" => loop { match self.next().unwrap() { ParseEvent::Start(ref name, ref attributes) if name == "extension" => { extensions.push(Extension::convert(&mut self, &attributes)); }, ParseEvent::End(ref name) if name == "extensions" => break, event => panic!("Unexpected message {:?}", event), } }, // finished building the registry ParseEvent::End(ref name) if name == "registry" => break, // error handling event => panic!("Expected , found: {:?}", event), } } let mut desired_enums = BTreeSet::new(); let mut desired_cmds = BTreeSet::new(); // find the features we want let mut found_feature = false; for feature in &features { // XXX: verify that the string comparison with <= actually works as desired if feature.api == filter.api && feature.number <= filter.version { for require in &feature.requires { desired_enums.extend(require.enums.iter().map(|x| x.clone())); desired_cmds.extend(require.commands.iter().map(|x| x.clone())); } for remove in &feature.removes { if remove.profile == filter.profile { for enm in &remove.enums { debug!("Removing {}", enm); desired_enums.remove(enm); } for cmd in &remove.commands { debug!("Removing {}", cmd); desired_cmds.remove(cmd); } } } } if feature.number == filter.version { found_feature = true; } } if !found_feature && require_feature { panic!("Did not find version {} in the registry", filter.version); } for extension in &extensions { if filter.extensions.contains(&extension.name) { if !extension.supported.contains(&filter.api) { panic!( "Requested {}, which doesn't support the {} API", extension.name, filter.api ); } for require in &extension.requires { desired_enums.extend(require.enums.iter().map(|x| x.clone())); desired_cmds.extend(require.commands.iter().map(|x| x.clone())); } } } let is_desired_enum = |e: &Enum| { desired_enums.contains(&("GL_".to_string() + &e.ident)) || desired_enums.contains(&("WGL_".to_string() + &e.ident)) || desired_enums.contains(&("GLX_".to_string() + &e.ident)) || desired_enums.contains(&("EGL_".to_string() + &e.ident)) }; let is_desired_cmd = |c: &Cmd| { desired_cmds.contains(&("gl".to_string() + &c.proto.ident)) || desired_cmds.contains(&("wgl".to_string() + &c.proto.ident)) || desired_cmds.contains(&("glX".to_string() + &c.proto.ident)) || desired_cmds.contains(&("egl".to_string() + &c.proto.ident)) }; Registry { api: filter.api, enums: enums.into_iter().filter(is_desired_enum).collect(), cmds: cmds.into_iter().filter(is_desired_cmd).collect(), aliases: if filter.fallbacks == Fallbacks::None { BTreeMap::new() } else { aliases }, groups, } } fn consume_characters(&mut self) -> String { match self.next().unwrap() { ParseEvent::Text(ch) => ch, event => panic!("Expected characters, found: {:?}", event), } } fn consume_start_element(&mut self, expected_name: &str) -> Vec { match self.next().unwrap() { ParseEvent::Start(name, attributes) => { if expected_name == name { attributes } else { panic!("Expected <{}>, found: <{}>", expected_name, name) } }, event => panic!("Expected <{}>, found: {:?}", expected_name, event), } } fn consume_end_element(&mut self, expected_name: &str) { match self.next().unwrap() { ParseEvent::End(ref name) if expected_name == name => (), event => panic!("Expected , found: {:?}", expected_name, event), } } fn skip_to_end(&mut self, expected_name: &str) { loop { match self.next().unwrap() { ParseEvent::End(ref name) if expected_name == name => break, _ => {}, } } } fn consume_two<'a, T: FromXml, U: FromXml>( &mut self, one: &'a str, two: &'a str, end: &'a str, ) -> (Vec, Vec) { debug!("consume_two: looking for {} and {} until {}", one, two, end); let mut ones = Vec::new(); let mut twos = Vec::new(); loop { match self.next().unwrap() { ParseEvent::Start(ref name, ref attributes) => { debug!("Found start element <{:?} {:?}>", name, attributes); debug!("one and two are {} and {}", one, two); let n = name.clone(); if one == n { ones.push(FromXml::convert(self, &attributes)); } else if "type" == n { // XXX: GL1.1 contains types, which we never care about anyway. // Make sure consume_two doesn't get used for things which *do* // care about type. warn!("Ignoring type!"); continue; } else if two == n { twos.push(FromXml::convert(self, &attributes)); } else { panic!("Unexpected element: <{:?} {:?}>", n, &attributes); } }, ParseEvent::End(ref name) => { debug!("Found end element ", name); if one == name || two == name { continue; } else if "type" == name { // XXX: GL1.1 contains types, which we never care about anyway. // Make sure consume_two doesn't get used for things which *do* // care about type. warn!("Ignoring type!"); continue; } else if end == name { return (ones, twos); } else { panic!("Unexpected end element {:?}", name); } }, event => panic!("Unexpected message {:?}", event), } } } fn consume_enums(&mut self, api: Api) -> Vec { let mut enums = Vec::new(); loop { match self.next().unwrap() { // ignores ParseEvent::Text(_) => {}, ParseEvent::Start(ref name, _) if name == "unused" => self.skip_to_end("unused"), // add enum definition ParseEvent::Start(ref name, ref attributes) if name == "enum" => { enums.push(self.consume_enum(api, attributes)); }, // finished building the namespace ParseEvent::End(ref name) if name == "enums" => break, // error handling event => panic!("Expected , found: {:?}", event), } } enums } fn consume_enum(&mut self, api: Api, attributes: &[Attribute]) -> Enum { let ident = trim_enum_prefix(&get_attribute(&attributes, "name").unwrap(), api).to_string(); let value = get_attribute(&attributes, "value").unwrap(); let alias = get_attribute(&attributes, "alias"); let ty = get_attribute(&attributes, "type"); self.consume_end_element("enum"); match api { Api::Egl => make_egl_enum(ident, ty, value, alias), _ => make_enum(ident, ty, value, alias), } } fn consume_groups(&mut self, api: Api) -> BTreeMap { let mut groups = BTreeMap::new(); loop { match self.next().unwrap() { ParseEvent::Start(ref name, ref attributes) if name == "group" => { let ident = get_attribute(&attributes, "name").unwrap(); let group = Group { ident: ident.clone(), enums_type: None, enums: self.consume_group_enums(api) }; groups.insert(ident, group); }, ParseEvent::End(ref name) if name == "groups" => break, event => panic!("Expected , found: {:?}", event), } } groups } fn consume_group_enums(&mut self, api: Api) -> Vec { let mut enums = Vec::new(); loop { match self.next().unwrap() { ParseEvent::Start(ref name, ref attributes) if name == "enum" => { let enum_name = get_attribute(&attributes, "name"); enums.push(trim_enum_prefix(&enum_name.unwrap(), api)); self.consume_end_element("enum"); }, ParseEvent::End(ref name) if name == "group" => break, event => panic!("Expected , found: {:?}", event), } } enums } fn consume_cmds(&mut self, api: Api) -> (Vec, BTreeMap>) { let mut cmds = Vec::new(); let mut aliases: BTreeMap> = BTreeMap::new(); loop { match self.next().unwrap() { // add command definition ParseEvent::Start(ref name, _) if name == "command" => { let new = self.consume_cmd(api); if let Some(ref v) = new.alias { match aliases.entry(v.clone()) { Entry::Occupied(mut ent) => { ent.get_mut().push(new.proto.ident.clone()); }, Entry::Vacant(ent) => { ent.insert(vec![new.proto.ident.clone()]); }, } } cmds.push(new); }, // finished building the namespace ParseEvent::End(ref name) if name == "commands" => break, // error handling event => panic!("Expected , found: {:?}", event), } } (cmds, aliases) } fn consume_cmd(&mut self, api: Api) -> Cmd { // consume command prototype self.consume_start_element("proto"); let mut proto = self.consume_binding("proto", &[]); proto.ident = trim_cmd_prefix(&proto.ident, api).to_string(); let mut params = Vec::new(); let mut alias = None; let mut vecequiv = None; let mut glx = None; loop { match self.next().unwrap() { ParseEvent::Start(ref name, ref attributes) if name == "param" => { params.push(self.consume_binding("param", attributes)); }, ParseEvent::Start(ref name, ref attributes) if name == "alias" => { alias = get_attribute(&attributes, "name"); alias = alias.map(|t| trim_cmd_prefix(&t, api).to_string()); self.consume_end_element("alias"); }, ParseEvent::Start(ref name, ref attributes) if name == "vecequiv" => { vecequiv = get_attribute(&attributes, "vecequiv"); self.consume_end_element("vecequiv"); }, ParseEvent::Start(ref name, ref attributes) if name == "glx" => { glx = Some(GlxOpcode { opcode: get_attribute(&attributes, "opcode").unwrap(), name: get_attribute(&attributes, "name"), }); self.consume_end_element("glx"); }, ParseEvent::End(ref name) if name == "command" => break, event => panic!("Expected , found: {:?}", event), } } Cmd { proto: proto, params: params, alias: alias, vecequiv: vecequiv, glx: glx, } } fn consume_binding(&mut self, outside_tag: &str, attributes: &[Attribute]) -> Binding { // consume type let mut ty = String::new(); loop { match self.next().unwrap() { ParseEvent::Text(text) => ty.push_str(&text), ParseEvent::Start(ref name, _) if name == "ptype" => (), ParseEvent::End(ref name) if name == "ptype" => (), ParseEvent::Start(ref name, _) if name == "name" => break, event => panic!("Expected binding, found: {:?}", event), } } // consume identifier let ident = underscore_keyword(self.consume_characters()); self.consume_end_element("name"); // consume the type suffix loop { match self.next().unwrap() { ParseEvent::Text(text) => ty.push_str(&text), ParseEvent::End(ref name) if name == outside_tag => break, event => panic!("Expected binding, found: {:?}", event), } } Binding { ident: ident, ty: to_rust_ty(ty), group: get_attribute(&attributes, "group"), } } } impl Parse for T where T: Sized + Iterator {} fn get_attribute(attribs: &[Attribute], key: &str) -> Option { attribs .iter() .find(|attrib| attrib.key == key) .map(|attrib| attrib.value.clone()) } trait FromXml { fn convert(parser: &mut P, a: &[Attribute]) -> Self; } impl FromXml for Require { fn convert(parser: &mut P, _: &[Attribute]) -> Require { debug!("Doing a FromXml on Require"); let (enums, commands) = parser.consume_two("enum", "command", "require"); Require { enums: enums, commands: commands, } } } impl FromXml for Remove { fn convert(parser: &mut P, a: &[Attribute]) -> Remove { debug!("Doing a FromXml on Remove"); let profile = get_attribute(a, "profile").unwrap(); let profile = profile_from_str(&profile).unwrap(); let (enums, commands) = parser.consume_two("enum", "command", "remove"); Remove { profile: profile, enums: enums, commands: commands, } } } impl FromXml for Feature { fn convert(parser: &mut P, a: &[Attribute]) -> Feature { debug!("Doing a FromXml on Feature"); let api = get_attribute(a, "api").unwrap(); let api = api_from_str(&api).unwrap().unwrap(); let name = get_attribute(a, "name").unwrap(); let number = get_attribute(a, "number").unwrap(); debug!("Found api = {}, name = {}, number = {}", api, name, number); let (require, remove) = parser.consume_two("require", "remove", "feature"); Feature { api: api, name: name, number: number, requires: require, removes: remove, } } } impl FromXml for Extension { fn convert(parser: &mut P, a: &[Attribute]) -> Extension { debug!("Doing a FromXml on Extension"); let name = get_attribute(a, "name").unwrap(); let supported = get_attribute(a, "supported") .unwrap() .split('|') .filter_map(|api| { api_from_str(api).unwrap_or_else(|()| panic!("unsupported API `{}`", api)) }) .collect::>(); let mut require = Vec::new(); loop { match parser.next().unwrap() { ParseEvent::Start(ref name, ref attributes) if name == "require" => { require.push(FromXml::convert(parser, &attributes)); }, ParseEvent::End(ref name) if name == "extension" => break, event => panic!("Unexpected message {:?}", event), } } Extension { name: name, supported: supported, requires: require, } } } impl FromXml for String { fn convert(_: &mut P, a: &[Attribute]) -> String { get_attribute(a, "name").unwrap() } } /// Converts a C style type definition to the Rust equivalent pub fn to_rust_ty>(ty: T) -> Cow<'static, str> { let ty = match ty.as_ref().trim() { // gl.xml types "GLDEBUGPROC" => "types::GLDEBUGPROC", "GLDEBUGPROCAMD" => "types::GLDEBUGPROCAMD", "GLDEBUGPROCARB" => "types::GLDEBUGPROCARB", "GLDEBUGPROCKHR" => "types::GLDEBUGPROCKHR", "GLbitfield" => "types::GLbitfield", "GLboolean" => "types::GLboolean", "GLbyte" => "types::GLbyte", "GLclampd" => "types::GLclampd", "GLclampf" => "types::GLclampf", "GLclampx" => "types::GLclampx", "GLdouble" => "types::GLdouble", "GLeglImageOES" => "types::GLeglImageOES", "GLenum" => "types::GLenum", "GLfixed" => "types::GLfixed", "GLfloat" => "types::GLfloat", "GLhalfNV" => "types::GLhalfNV", "GLhandleARB" => "types::GLhandleARB", "GLint" => "types::GLint", "GLint64" => "types::GLint64", "GLint64EXT" => "types::GLint64EXT", "GLintptr" => "types::GLintptr", "GLintptrARB" => "types::GLintptrARB", "GLshort" => "types::GLshort", "GLsizei" => "types::GLsizei", "GLsizeiptr" => "types::GLsizeiptr", "GLsizeiptrARB" => "types::GLsizeiptrARB", "GLsync" => "types::GLsync", "GLubyte" => "types::GLubyte", "GLuint" => "types::GLuint", "GLuint64" => "types::GLuint64", "GLuint64EXT" => "types::GLuint64EXT", "GLushort" => "types::GLushort", "GLvdpauSurfaceNV" => "types::GLvdpauSurfaceNV", "void" => "()", "GLboolean *" => "*mut types::GLboolean", "GLchar *" => "*mut types::GLchar", "const GLchar*" => "*const types::GLchar", "GLcharARB *" => "*mut types::GLcharARB", "GLdouble *" => "*mut types::GLdouble", "GLenum *" => "*mut types::GLenum", "GLfixed *" => "*mut types::GLfixed", "GLfloat *" => "*mut types::GLfloat", "GLhandleARB *" => "*mut types::GLhandleARB", "GLint *" => "*mut types::GLint", "GLint64 *" => "*mut types::GLint64", "GLint64EXT *" => "*mut types::GLint64EXT", "GLsizei *" => "*mut types::GLsizei", "GLubyte *" => "*mut types::GLubyte", "GLuint *" => "*mut types::GLuint", "GLuint [2]" => "*mut [types::GLuint; 2]", "GLuint64 *" => "*mut types::GLuint64", "GLuint64EXT *" => "*mut types::GLuint64EXT", "GLushort *" => "*mut types::GLushort", "GLvoid *" => "*mut types::GLvoid", "GLvoid **" => "*const *mut types::GLvoid", "void *" => "*mut __gl_imports::raw::c_void", "void **" => "*const *mut __gl_imports::raw::c_void", "const GLboolean *" => "*const types::GLboolean", "const GLbyte *" => "*const types::GLbyte", "const GLchar *" => "*const types::GLchar", "const GLcharARB *" => "*const types::GLcharARB", "const GLclampf *" => "*const types::GLclampf", "const GLdouble *" => "*const types::GLdouble", "const GLenum *" => "*const types::GLenum", "const GLfixed *" => "*const types::GLfixed", "const GLfloat" => "types::GLfloat", "const GLfloat *" => "*const types::GLfloat", "const GLhalfNV *" => "*const types::GLhalfNV", "const GLint *" => "*const types::GLint", "const GLint*" => "*const types::GLint", "const GLint64 *" => "*const types::GLint64", "const GLint64EXT *" => "*const types::GLint64EXT", "const GLintptr *" => "*const types::GLintptr", "const GLshort *" => "*const types::GLshort", "const GLsizei*" | "const GLsizei *" => "*const types::GLsizei", "const GLsizeiptr *" => "*const types::GLsizeiptr", "const GLubyte *" => "*const types::GLubyte", "const GLuint *" => "*const types::GLuint", "const GLuint64 *" => "*const types::GLuint64", "const GLuint64EXT *" => "*const types::GLuint64EXT", "const GLushort *" => "*const types::GLushort", "const GLvdpauSurfaceNV *" => "*const types::GLvdpauSurfaceNV", "const GLvoid *" => "*const types::GLvoid", "const void*" | "const void *" => "*const __gl_imports::raw::c_void", "const void **" => "*const *const __gl_imports::raw::c_void", "const void *const*" => "*const *const __gl_imports::raw::c_void", "const GLboolean **" => "*const *const types::GLboolean", "const GLchar **" => "*const *const types::GLchar", "const GLcharARB **" => "*const *const types::GLcharARB", "const GLvoid **" => "*const *const types::GLvoid", "const GLchar *const*" => "*const *const types::GLchar", "const GLvoid *const*" => "*const *const types::GLvoid", "struct _cl_context *" => "*const types::_cl_context", "struct _cl_event *" => "*const types::_cl_event", "GLuint[2]" => "[Gluint; 2]", // glx.xml types "Bool" => "types::Bool", "Colormap" => "types::Colormap", "DMbuffer" => "types::DMbuffer", "Font" => "types::Font", "GLXContext" => "types::GLXContext", "GLXContextID" => "types::GLXContextID", "GLXDrawable" => "types::GLXDrawable", "GLXFBConfig" => "types::GLXFBConfig", "GLXFBConfigSGIX" => "types::GLXFBConfigSGIX", "GLXPbuffer" => "types::GLXPbuffer", "GLXPbufferSGIX" => "types::GLXPbufferSGIX", "GLXPixmap" => "types::GLXPixmap", "GLXVideoCaptureDeviceNV" => "types::GLXVideoCaptureDeviceNV", "GLXVideoDeviceNV" => "types::GLXVideoDeviceNV", "GLXVideoSourceSGIX" => "types::GLXVideoSourceSGIX", "GLXWindow" => "types::GLXWindow", // "GLboolean" => "types::GLboolean", // "GLenum" => "types::GLenum", // "GLint" => "types::GLint", // "GLsizei" => "types::GLsizei", // "GLuint" => "types::GLuint", "Pixmap" => "types::Pixmap", "Status" => "types::Status", "VLNode" => "types::VLNode", "VLPath" => "types::VLPath", "VLServer" => "types::VLServer", "Window" => "types::Window", "__GLXextFuncPtr" => "types::__GLXextFuncPtr", "const GLXContext" => "const types::GLXContext", "float" => "__gl_imports::raw::c_float", "int" => "__gl_imports::raw::c_int", "int64_t" => "i64", "unsigned int" => "__gl_imports::raw::c_uint", "unsigned long" => "__gl_imports::raw::c_ulong", // "void " => "()", "DMparams *" => "*mut types::DMparams", "Display *" => "*mut types::Display", "GLXFBConfig *" => "*mut types::GLXFBConfig", "GLXFBConfigSGIX *" => "*mut types::GLXFBConfigSGIX", "GLXHyperpipeConfigSGIX *" => "*mut types::GLXHyperpipeConfigSGIX", "GLXHyperpipeNetworkSGIX *" => "*mut types::GLXHyperpipeNetworkSGIX", "GLXVideoCaptureDeviceNV *" => "*mut types::GLXVideoCaptureDeviceNV", "GLXVideoDeviceNV *" => "*mut types::GLXVideoDeviceNV", // "GLuint *" => "*mut types::GLuint", "XVisualInfo *" => "*mut types::XVisualInfo", // "const GLubyte *" => "*GLubyte", "const char *" => "*const __gl_imports::raw::c_char", "const int *" => "*const __gl_imports::raw::c_int", // "const void *" => "*const __gl_imports::raw::c_void", "int *" => "*mut __gl_imports::raw::c_int", "int32_t *" => "*mut i32", "int64_t *" => "*mut i64", "long *" => "*mut __gl_imports::raw::c_long", "unsigned int *" => "*mut __gl_imports::raw::c_uint", "unsigned long *" => "*mut __gl_imports::raw::c_ulong", // "void *" => "*mut __gl_imports::raw::c_void", // wgl.xml types "BOOL" => "types::BOOL", "DWORD" => "types::DWORD", "FLOAT" => "types::FLOAT", // "GLbitfield" => "types::GLbitfield", // "GLboolean" => "types::GLboolean", // "GLenum" => "types::GLenum", // "GLfloat" => "types::GLfloat", // "GLint" => "types::GLint", // "GLsizei" => "types::GLsizei", // "GLuint" => "types::GLuint", // "GLushort" => "types::GLushort", "HANDLE" => "types::HANDLE", "HDC" => "types::HDC", "HENHMETAFILE" => "types::HENHMETAFILE", "HGLRC" => "types::HGLRC", "HGPUNV" => "types::HGPUNV", "HPBUFFERARB" => "types::HPBUFFERARB", "HPBUFFEREXT" => "types::HPBUFFEREXT", "HPVIDEODEV" => "types::HPVIDEODEV", "HVIDEOINPUTDEVICENV" => "types::HVIDEOINPUTDEVICENV", "HVIDEOOUTPUTDEVICENV" => "types::HVIDEOOUTPUTDEVICENV", "INT" => "types::INT", "INT64" => "types::INT64", "LPCSTR" => "types::LPCSTR", "LPGLYPHMETRICSFLOAT" => "types::LPGLYPHMETRICSFLOAT", "LPVOID" => "types::LPVOID", "PGPU_DEVICE" => "types::PGPU_DEVICE", "PROC" => "types::PROC", "UINT" => "types::UINT", "VOID" => "types::VOID", // "int " => "__gl_imports::raw::c_int", // "unsigned int " => "__gl_imports::raw::c_uint", // "void " => "()", "BOOL *" => "*mut types::BOOL", "DWORD *" => "*mut types::DWORD", "FLOAT *" => "*mut types::FLOAT", // "GLuint *" => "*mut types::GLuint", "HANDLE *" => "*mut types::HANDLE", "HGPUNV *" => "*mut types::HGPUNV", "HPVIDEODEV *" => "*mut types::HPVIDEODEV", "HVIDEOINPUTDEVICENV *" => "*mut types::HVIDEOINPUTDEVICENV", "HVIDEOOUTPUTDEVICENV *" => "*mut types::HVIDEOOUTPUTDEVICENV", "INT32 *" => "*mut types::INT32", "INT64 *" => "*mut types::INT64", "UINT *" => "*mut types::UINT", "USHORT *" => "*mut types::USHORT", "const COLORREF *" => "*const types::COLORREF", "const DWORD *" => "*const types::DWORD", "const FLOAT *" => "*const types::FLOAT", // "const GLushort *" => "*const types::GLushort", "const HANDLE *" => "*const types::HANDLE", "const HGPUNV *" => "*const types::HGPUNV", "const LAYERPLANEDESCRIPTOR *" => "*const types::LAYERPLANEDESCRIPTOR", "const LPVOID *" => "*const types::LPVOID", "const PIXELFORMATDESCRIPTOR *" => "*const types::IXELFORMATDESCRIPTOR", "const USHORT *" => "*const types::USHORT", // "const char *" => "*const __gl_imports::raw::c_char", // "const int *" => "*const __gl_imports::raw::c_int", "float *" => "*mut __gl_imports::raw::c_float", // "int *" => "*mut __gl_imports::raw::c_int", // "unsigned long *" => "*mut __gl_imports::raw::c_ulong", // "void *" => "*mut __gl_imports::raw::c_void", // elx.xml types "khronos_utime_nanoseconds_t" => "types::khronos_utime_nanoseconds_t", "khronos_uint64_t" => "types::khronos_uint64_t", "khronos_ssize_t" => "types::khronos_ssize_t", "EGLNativeDisplayType" => "types::EGLNativeDisplayType", "EGLNativePixmapType" => "types::EGLNativePixmapType", "EGLNativeWindowType" => "types::EGLNativeWindowType", "EGLint" => "types::EGLint", "EGLint *" => "*mut types::EGLint", "const EGLint *" => "*const types::EGLint", "NativeDisplayType" => "types::NativeDisplayType", "NativePixmapType" => "types::NativePixmapType", "NativeWindowType" => "types::NativeWindowType", //"Bool" => "types::Bool", "EGLBoolean" => "types::EGLBoolean", "EGLenum" => "types::EGLenum", "EGLAttribKHR" => "types::EGLAttribKHR", "EGLAttrib" => "types::EGLAttrib", "EGLAttrib *" => "*mut types::EGLAttrib", "const EGLAttrib *" => "*const types::EGLAttrib", "const EGLattrib *" => "*const types::EGLAttrib", // Due to a typo in khronos_api/api_angle/scripts/egl_angle_ext.xml - see brendanzab/gl-rs#491 "EGLConfig" => "types::EGLConfig", "EGLConfig *" => "*mut types::EGLConfig", "EGLContext" => "types::EGLContext", "EGLDeviceEXT" => "types::EGLDeviceEXT", "EGLDisplay" => "types::EGLDisplay", "EGLSurface" => "types::EGLSurface", "EGLClientBuffer" => "types::EGLClientBuffer", "__eglMustCastToProperFunctionPointerType" => { "types::__eglMustCastToProperFunctionPointerType" }, "EGLImageKHR" => "types::EGLImageKHR", "EGLImage" => "types::EGLImage", "EGLOutputLayerEXT" => "types::EGLOutputLayerEXT", "EGLOutputPortEXT" => "types::EGLOutputPortEXT", "EGLSyncKHR" => "types::EGLSyncKHR", "EGLSync" => "types::EGLSync", "EGLTimeKHR" => "types::EGLTimeKHR", "EGLTime" => "types::EGLTime", "EGLSyncNV" => "types::EGLSyncNV", "EGLTimeNV" => "types::EGLTimeNV", "EGLuint64NV" => "types::EGLuint64NV", "EGLStreamKHR" => "types::EGLStreamKHR", "EGLuint64KHR" => "types::EGLuint64KHR", "EGLNativeFileDescriptorKHR" => "types::EGLNativeFileDescriptorKHR", "EGLsizeiANDROID" => "types::EGLsizeiANDROID", "EGLSetBlobFuncANDROID" => "types::EGLSetBlobFuncANDROID", "EGLGetBlobFuncANDROID" => "types::EGLGetBlobFuncANDROID", "EGLClientPixmapHI" => "types::EGLClientPixmapHI", "struct EGLClientPixmapHI *" => "*const types::EGLClientPixmapHI", "const EGLAttribKHR *" => "*const types::EGLAttribKHR", "const EGLuint64KHR *" => "*const types::EGLuint64KHR", "EGLAttribKHR *" => "*mut types::EGLAttribKHR", "EGLDeviceEXT *" => "*mut types::EGLDeviceEXT", "EGLNativeDisplayType *" => "*mut types::EGLNativeDisplayType", "EGLNativePixmapType *" => "*mut types::EGLNativePixmapType", "EGLNativeWindowType *" => "*mut types::EGLNativeWindowType", "EGLOutputLayerEXT *" => "*mut types::EGLOutputLayerEXT", "EGLTimeKHR *" => "*mut types::EGLTimeKHR", "EGLOutputPortEXT *" => "*mut types::EGLOutputPortEXT", "EGLuint64KHR *" => "*mut types::EGLuint64KHR", "const struct AHardwareBuffer *" => "*const __gl_imports::raw::c_void", // humm "GLeglClientBufferEXT" => "types::GLeglClientBufferEXT", "GLVULKANPROCNV" => "types::GLVULKANPROCNV", "EGLDEBUGPROCKHR" => "types::EGLDEBUGPROCKHR", "EGLObjectKHR" => "types::EGLObjectKHR", "EGLLabelKHR" => "types::EGLLabelKHR", "EGLnsecsANDROID" => "types::EGLnsecsANDROID", "EGLnsecsANDROID *" => "*mut types::EGLnsecsANDROID", "EGLBoolean *" => "*mut types::EGLBoolean", // failure _ => panic!("Type conversion not implemented for `{}`", ty.as_ref()), }; Cow::Borrowed(ty) } #[cfg(test)] mod tests { mod underscore_numeric_prefix { use registry::parse; #[test] fn test_numeric_prefix() { assert_eq!(parse::underscore_numeric_prefix("3"), "_3"); assert_eq!(parse::underscore_numeric_prefix("123_FOO"), "_123_FOO"); } #[test] fn test_non_numeric_prefix() { assert_eq!(parse::underscore_numeric_prefix(""), ""); assert_eq!(parse::underscore_numeric_prefix("A"), "A"); assert_eq!(parse::underscore_numeric_prefix("FOO"), "FOO"); } } mod underscore_keyword { use registry::parse; #[test] fn test_keyword() { assert_eq!(parse::underscore_keyword("in".to_string()), "in_"); assert_eq!(parse::underscore_keyword("ref".to_string()), "ref_"); assert_eq!(parse::underscore_keyword("type".to_string()), "type_"); } #[test] fn test_non_keyword() { assert_eq!(parse::underscore_keyword("foo".to_string()), "foo"); assert_eq!(parse::underscore_keyword("bar".to_string()), "bar"); } } mod make_enum { use registry::parse; #[test] fn test_cast_0() { let e = parse::make_enum( "FOO".to_string(), None, "((EGLint)-1)".to_string(), Some("BAR".to_string()), ); assert_eq!(e.ident, "FOO"); assert_eq!((&*e.ty, &*e.value), ("EGLint", "-1")); assert_eq!(e.alias, Some("BAR".to_string())); } #[test] fn test_cast_1() { let e = parse::make_enum( "FOO".to_string(), None, "((EGLint)(-1))".to_string(), Some("BAR".to_string()), ); assert_eq!(e.ident, "FOO"); assert_eq!((&*e.ty, &*e.value), ("EGLint", "(-1)")); assert_eq!(e.alias, Some("BAR".to_string())); } #[test] fn test_no_type() { let e = parse::make_enum( "FOO".to_string(), None, "value".to_string(), Some("BAR".to_string()), ); assert_eq!(e.ident, "FOO"); assert_eq!(e.value, "value"); assert_eq!(e.alias, Some("BAR".to_string())); assert_eq!(e.ty, "GLenum"); assert_eq!(e.cast, false); } #[test] fn test_u() { let e = parse::make_enum( "FOO".to_string(), Some("u".to_string()), String::new(), None, ); assert_eq!(e.ty, "GLuint"); } #[test] fn test_ull() { let e = parse::make_enum( "FOO".to_string(), Some("ull".to_string()), String::new(), None, ); assert_eq!(e.ty, "GLuint64"); } #[test] #[should_panic] fn test_unknown_type() { parse::make_enum( "FOO".to_string(), Some("blargh".to_string()), String::new(), None, ); } #[test] fn test_value_str() { let e = parse::make_enum("FOO".to_string(), None, "\"hi\"".to_string(), None); assert_eq!(e.ty, "&'static str"); } #[test] fn test_ident_true() { let e = parse::make_enum("TRUE".to_string(), None, String::new(), None); assert_eq!(e.ty, "GLboolean"); } #[test] fn test_ident_false() { let e = parse::make_enum("FALSE".to_string(), None, String::new(), None); assert_eq!(e.ty, "GLboolean"); } } mod make_egl_enum { use registry::parse; #[test] fn test_cast_egl() { let e = parse::make_egl_enum( "FOO".to_string(), None, "EGL_CAST(EGLint,-1)".to_string(), Some("BAR".to_string()), ); assert_eq!(e.ident, "FOO"); assert_eq!((&*e.ty, &*e.value), ("EGLint", "-1")); assert_eq!(e.alias, Some("BAR".to_string())); } #[test] fn test_ident_true() { let e = parse::make_egl_enum("TRUE".to_string(), None, "1234".to_string(), None); assert_eq!(e.ty, "EGLBoolean"); } #[test] fn test_ident_false() { let e = parse::make_egl_enum("FALSE".to_string(), None, "1234".to_string(), None); assert_eq!(e.ty, "EGLBoolean"); } #[test] fn test_ull() { let e = parse::make_egl_enum( "FOO".to_string(), Some("ull".to_string()), "1234".to_string(), None, ); assert_eq!(e.ty, "EGLuint64KHR"); } #[test] fn test_negative_value() { let e = parse::make_egl_enum("FOO".to_string(), None, "-1".to_string(), None); assert_eq!(e.ty, "EGLint"); } #[test] #[should_panic] fn test_unknown_type() { parse::make_egl_enum( "FOO".to_string(), Some("blargh".to_string()), String::new(), None, ); } #[test] #[should_panic] fn test_unknown_value() { parse::make_egl_enum("FOO".to_string(), None, "a".to_string(), None); } #[test] #[should_panic] fn test_empty_value() { parse::make_egl_enum("FOO".to_string(), None, String::new(), None); } } mod parse_event { mod from_xml { use xml::attribute::OwnedAttribute; use xml::common::XmlVersion; use xml::name::OwnedName; use xml::namespace::Namespace; use xml::reader::XmlEvent; use registry::parse::{Attribute, ParseEvent}; #[test] fn test_start_event() { let given = XmlEvent::StartElement { name: OwnedName::local("element"), attributes: vec![ OwnedAttribute::new(OwnedName::local("attr1"), "val1"), OwnedAttribute::new(OwnedName::local("attr2"), "val2"), ], namespace: Namespace::empty(), }; let expected = ParseEvent::Start( "element".to_string(), vec![ Attribute::new("attr1", "val1"), Attribute::new("attr2", "val2"), ], ); assert_eq!(ParseEvent::from_xml(given), Some(expected)); } #[test] fn test_end_element() { let given = XmlEvent::EndElement { name: OwnedName::local("element"), }; let expected = ParseEvent::End("element".to_string()); assert_eq!(ParseEvent::from_xml(given), Some(expected)); } #[test] fn test_characters() { let given = XmlEvent::Characters("text".to_string()); let expected = ParseEvent::Text("text".to_string()); assert_eq!(ParseEvent::from_xml(given), Some(expected)); } #[test] fn test_start_document() { let given = XmlEvent::StartDocument { version: XmlVersion::Version10, encoding: "".to_string(), standalone: None, }; assert_eq!(ParseEvent::from_xml(given), None); } #[test] fn test_end_document() { let given = XmlEvent::EndDocument; assert_eq!(ParseEvent::from_xml(given), None); } #[test] fn test_processing_instruction() { let given = XmlEvent::ProcessingInstruction { name: "".to_string(), data: None, }; assert_eq!(ParseEvent::from_xml(given), None); } #[test] fn test_cdata() { let given = XmlEvent::CData("CData".to_string()); assert_eq!(ParseEvent::from_xml(given), None); } #[test] fn test_comment() { let given = XmlEvent::Comment("Comment".to_string()); assert_eq!(ParseEvent::from_xml(given), None); } #[test] fn test_whitespace() { let given = XmlEvent::Whitespace("Whitespace".to_string()); assert_eq!(ParseEvent::from_xml(given), None); } } } } gl_generator-0.14.0/.cargo_vcs_info.json0000644000000001120000000000000136170ustar00{ "git": { "sha1": "ea503e8d5fb6d73c6030e6191ce738cd3bf3433e" } }