<commit_before>use super::{Config, ConfigKey, ConfigRelativePath, OptValue, PathAndArgs, StringList, CV};
use crate::core::compiler::BuildOutput;
use crate::util::CargoResult;
use serde::Deserialize;
use std::collections::{BTreeMap, HashMap};
use std::path::PathBuf;

/// Config definition of a [target.'cfg(…)'] table.
///
/// This is a subset of `TargetConfig`.
#[derive(Debug, Deserialize)]
pub struct TargetCfgConfig {
    pub runner: OptValue<PathAndArgs>,
    pub rustflags: OptValue<StringList>,
    // This is here just to ignore fields from normal `TargetConfig` because
    // all `[target]` tables are getting deserialized, whether they start with
    // `cfg(` or not.
    #[serde(flatten)]
    pub other: BTreeMap<String, toml::Value>,
}

/// Config definition of a [target] table.
#[derive(Debug)]
pub struct TargetConfig {
    /// Process to run as a wrapper for `cargo run`, `test`, and `bench` commands.
    pub runner: OptValue<PathAndArgs>,
    /// Additional rustc flags to pass.
    pub rustflags: OptValue<StringList>,
    /// The path of the linker for this target.
    pub linker: OptValue<ConfigRelativePath>,
    /// Build script override for the given library name.
    ///
    /// Any package with a `links` value for the given library name will skip
    /// running its build script and instead use the given output from the
    /// config file.
    pub links_overrides: BTreeMap<String, BuildOutput>,
}

/// Loads all of the `target.'cfg()'` tables.
pub(super) fn load_target_cfgs(config: &Config) -> CargoResult<Vec<(String, TargetCfgConfig)>> {
    // Load all [target] tables, filter out the cfg() entries.
    let mut result = Vec::new();
    // Use a BTreeMap so the keys are sorted. This is important for
    // deterministic ordering of rustflags, which affects fingerprinting and
    // rebuilds. We may perhaps one day wish to ensure a deterministic
    // ordering via the order keys were defined in files perhaps.
    let target: BTreeMap<String, TargetCfgConfig> = config.get("target")?;
    log::debug!("Got all targets {:#?}", target);
    for (key, cfg) in target {
        if key.starts_with("cfg(") {
            // Unfortunately this is not able to display the location of the
            // unused key. Using config::Value<toml::Value> doesn't work. One
            // solution might be to create a special "Any" type, but I think
            // that will be quite difficult with the current design.
            for other_key in cfg.other.keys() {
                config.shell().warn(format!(
                    "unused key `{}` in [target] config table `{}`",
                    other_key, key
                ))?;
            }
            result.push((key, cfg));
        }
    }
    Ok(result)
}

/// Loads a single `[target]` table for the given triple.
pub(super) fn load_target_triple(config: &Config, triple: &str) -> CargoResult<TargetConfig> {
    // This needs to get each field individually because it cannot fetch the
    // struct all at once due to `links_overrides`. Can't use `serde(flatten)`
    // because it causes serde to use `deserialize_map` which means the config
    // deserializer does not know which keys to deserialize, which means
    // environment variables would not work.
    let runner: OptValue<PathAndArgs> = config.get(&format!("target.{}.runner", triple))?;
    let rustflags: OptValue<StringList> = config.get(&format!("target.{}.rustflags", triple))?;
    let linker: OptValue<ConfigRelativePath> = config.get(&format!("target.{}.linker", triple))?;
    // Links do not support environment variables.
    let target_key = ConfigKey::from_str(&format!("target.{}", triple));
    let links_overrides = match config.get_table(&target_key)? {
        Some(links) => parse_links_overrides(&target_key, links.val)?,
        None => BTreeMap::new(),
    };
    Ok(TargetConfig {
        runner,
        rustflags,
        linker,
        links_overrides,
    })
}

fn parse_links_overrides(
    target_key: &ConfigKey,
    links: HashMap<String, CV>,
) -> CargoResult<BTreeMap<String, BuildOutput>> {
    let mut links_overrides = BTreeMap::new();
    for (lib_name, value) in links {
        // Skip these keys, it shares the namespace with `TargetConfig`.
        match lib_name.as_str() {
            // `ar` is a historical thing.
            "ar" | "linker" | "runner" | "rustflags" => continue,
            _ => {}
        }
        let mut output = BuildOutput::default();
        let table = value.table(&format!("{}.{}", target_key, lib_name))?.0;
        // We require deterministic order of evaluation, so we must sort the pairs by key first.
        let mut pairs = Vec::new();
        for (k, value) in table {
            pairs.push((k, value));
        }
        pairs.sort_by_key(|p| p.0);
        for (key, value) in pairs {
            match key.as_str() {
                "rustc-flags" => {
                    let flags = value.string(key)?;
                    let whence = format!("target config `{}.{}` (in {})", target_key, key, flags.1);
                    let (paths, links) = BuildOutput::parse_rustc_flags(flags.0, &whence)?;
                    output.library_paths.extend(paths);
                    output.library_links.extend(links);
                }
                "rustc-link-lib" => {
                    let list = value.list(key)?;
                    output
                        .library_links
                        .extend(list.iter().map(|v| v.0.clone()));
                }
                "rustc-link-search" => {
                    let list = value.list(key)?;
                    output
                        .library_paths
                        .extend(list.iter().map(|v| PathBuf::from(&v.0)));
                }
                "rustc-cdylib-link-arg" => {
                    let args = value.list(key)?;
                    output.linker_args.extend(args.iter().map(|v| v.0.clone()));
                }
                "rustc-cfg" => {
                    let list = value.list(key)?;
                    output.cfgs.extend(list.iter().map(|v| v.0.clone()));
                }
                "rustc-env" => {
                    for (name, val) in value.table(key)?.0 {
                        let val = val.string(name)?.0;
                        output.env.push((name.clone(), val.to_string()));
                    }
                }
                "warning" | "rerun-if-changed" | "rerun-if-env-changed" => {
                    anyhow::bail!("`{}` is not supported in build script overrides", key);
                }
                _ => {
                    let val = value.string(key)?.0;
                    output.metadata.push((key.clone(), val.to_string()));
                }
            }
        }
        links_overrides.insert(lib_name, output);
    }
    Ok(links_overrides)
}
<commit_msg>Auto merge of #8052 - ehuss:rustdoc-warnings, r=alexcrichton<commit_after>use super::{Config, ConfigKey, ConfigRelativePath, OptValue, PathAndArgs, StringList, CV};
use crate::core::compiler::BuildOutput;
use crate::util::CargoResult;
use serde::Deserialize;
use std::collections::{BTreeMap, HashMap};
use std::path::PathBuf;

/// Config definition of a `[target.'cfg(…)']` table.
///
/// This is a subset of `TargetConfig`.
#[derive(Debug, Deserialize)]
pub struct TargetCfgConfig {
    pub runner: OptValue<PathAndArgs>,
    pub rustflags: OptValue<StringList>,
    // This is here just to ignore fields from normal `TargetConfig` because
    // all `[target]` tables are getting deserialized, whether they start with
    // `cfg(` or not.
    #[serde(flatten)]
    pub other: BTreeMap<String, toml::Value>,
}

/// Config definition of a `[target]` table.
#[derive(Debug)]
pub struct TargetConfig {
    /// Process to run as a wrapper for `cargo run`, `test`, and `bench` commands.
    pub runner: OptValue<PathAndArgs>,
    /// Additional rustc flags to pass.
    pub rustflags: OptValue<StringList>,
    /// The path of the linker for this target.
    pub linker: OptValue<ConfigRelativePath>,
    /// Build script override for the given library name.
    ///
    /// Any package with a `links` value for the given library name will skip
    /// running its build script and instead use the given output from the
    /// config file.
    pub links_overrides: BTreeMap<String, BuildOutput>,
}

/// Loads all of the `target.'cfg()'` tables.
pub(super) fn load_target_cfgs(config: &Config) -> CargoResult<Vec<(String, TargetCfgConfig)>> {
    // Load all [target] tables, filter out the cfg() entries.
    let mut result = Vec::new();
    // Use a BTreeMap so the keys are sorted. This is important for
    // deterministic ordering of rustflags, which affects fingerprinting and
    // rebuilds. We may perhaps one day wish to ensure a deterministic
    // ordering via the order keys were defined in files perhaps.
    let target: BTreeMap<String, TargetCfgConfig> = config.get("target")?;
    log::debug!("Got all targets {:#?}", target);
    for (key, cfg) in target {
        if key.starts_with("cfg(") {
            // Unfortunately this is not able to display the location of the
            // unused key. Using config::Value<toml::Value> doesn't work. One
            // solution might be to create a special "Any" type, but I think
            // that will be quite difficult with the current design.
            for other_key in cfg.other.keys() {
                config.shell().warn(format!(
                    "unused key `{}` in [target] config table `{}`",
                    other_key, key
                ))?;
            }
            result.push((key, cfg));
        }
    }
    Ok(result)
}

/// Loads a single `[target]` table for the given triple.
pub(super) fn load_target_triple(config: &Config, triple: &str) -> CargoResult<TargetConfig> {
    // This needs to get each field individually because it cannot fetch the
    // struct all at once due to `links_overrides`. Can't use `serde(flatten)`
    // because it causes serde to use `deserialize_map` which means the config
    // deserializer does not know which keys to deserialize, which means
    // environment variables would not work.
    let runner: OptValue<PathAndArgs> = config.get(&format!("target.{}.runner", triple))?;
    let rustflags: OptValue<StringList> = config.get(&format!("target.{}.rustflags", triple))?;
    let linker: OptValue<ConfigRelativePath> = config.get(&format!("target.{}.linker", triple))?;
    // Links do not support environment variables.
    let target_key = ConfigKey::from_str(&format!("target.{}", triple));
    let links_overrides = match config.get_table(&target_key)? {
        Some(links) => parse_links_overrides(&target_key, links.val)?,
        None => BTreeMap::new(),
    };
    Ok(TargetConfig {
        runner,
        rustflags,
        linker,
        links_overrides,
    })
}

fn parse_links_overrides(
    target_key: &ConfigKey,
    links: HashMap<String, CV>,
) -> CargoResult<BTreeMap<String, BuildOutput>> {
    let mut links_overrides = BTreeMap::new();
    for (lib_name, value) in links {
        // Skip these keys, it shares the namespace with `TargetConfig`.
        match lib_name.as_str() {
            // `ar` is a historical thing.
            "ar" | "linker" | "runner" | "rustflags" => continue,
            _ => {}
        }
        let mut output = BuildOutput::default();
        let table = value.table(&format!("{}.{}", target_key, lib_name))?.0;
        // We require deterministic order of evaluation, so we must sort the pairs by key first.
        let mut pairs = Vec::new();
        for (k, value) in table {
            pairs.push((k, value));
        }
        pairs.sort_by_key(|p| p.0);
        for (key, value) in pairs {
            match key.as_str() {
                "rustc-flags" => {
                    let flags = value.string(key)?;
                    let whence = format!("target config `{}.{}` (in {})", target_key, key, flags.1);
                    let (paths, links) = BuildOutput::parse_rustc_flags(flags.0, &whence)?;
                    output.library_paths.extend(paths);
                    output.library_links.extend(links);
                }
                "rustc-link-lib" => {
                    let list = value.list(key)?;
                    output
                        .library_links
                        .extend(list.iter().map(|v| v.0.clone()));
                }
                "rustc-link-search" => {
                    let list = value.list(key)?;
                    output
                        .library_paths
                        .extend(list.iter().map(|v| PathBuf::from(&v.0)));
                }
                "rustc-cdylib-link-arg" => {
                    let args = value.list(key)?;
                    output.linker_args.extend(args.iter().map(|v| v.0.clone()));
                }
                "rustc-cfg" => {
                    let list = value.list(key)?;
                    output.cfgs.extend(list.iter().map(|v| v.0.clone()));
                }
                "rustc-env" => {
                    for (name, val) in value.table(key)?.0 {
                        let val = val.string(name)?.0;
                        output.env.push((name.clone(), val.to_string()));
                    }
                }
                "warning" | "rerun-if-changed" | "rerun-if-env-changed" => {
                    anyhow::bail!("`{}` is not supported in build script overrides", key);
                }
                _ => {
                    let val = value.string(key)?.0;
                    output.metadata.push((key.clone(), val.to_string()));
                }
            }
        }
        links_overrides.insert(lib_name, output);
    }
    Ok(links_overrides)
}
<|endoftext|>


<commit_before>// Copyright 2014 The Gfx-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 device;

use gfx;

#[packed]
#[vertex_format]
struct MyVertex {
     a0: [f32, ..2],
     #[normalized]
     a1: i16,
     #[as_float]
     a2: [i8, ..4],
     #[as_double]
     a3: f64,
     #[name = "a_a4"]
     a4: [f32, ..3],
}

#[test]
fn test_vertex_format() {
    use a = gfx::attrib;

    let buf = device::make_fake_buffer();
    let mesh = gfx::Mesh::from::<MyVertex>(buf, 0);
    let stride = 34 as a::Stride;

    assert_eq!(mesh.attributes, vec![
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 2,
            elem_type: a::Float(a::FloatDefault, a::F32),
            offset: 0,
            stride: stride,
            name: "a0".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 1,
            elem_type: a::Int(a::IntNormalized, a::U16, a::Signed),
            offset: 8,
            stride: stride,
            name: "a1".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 4,
            elem_type: a::Int(a::IntAsFloat, a::U8, a::Signed),
            offset: 10,
            stride: stride,
            name: "a2".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 1,
            elem_type: a::Float(a::FloatPrecision, a::F64),
            offset: 14,
            stride: stride,
            name: "a3".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 3,
            elem_type: a::Float(a::FloatDefault, a::F32),
            offset: 22,
            stride: stride,
            name: "a_a4".to_string(),
        },
    ]);
}
<commit_msg>Fix tests<commit_after>// Copyright 2014 The Gfx-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 device;

use gfx;

#[packed]
#[vertex_format]
struct MyVertex {
     a0: [f32, ..2],
     #[normalized]
     a1: i16,
     #[as_float]
     a2: [i8, ..4],
     #[as_double]
     a3: f64,
     #[name = "a_a4"]
     a4: [f32, ..3],
}

#[test]
fn test_vertex_format() {
    use gfx::attrib as a;

    let buf = device::make_fake_buffer();
    let mesh = gfx::Mesh::from::<MyVertex>(buf, 0);
    let stride = 34 as a::Stride;

    assert_eq!(mesh.attributes, vec![
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 2,
            elem_type: a::Float(a::FloatDefault, a::F32),
            offset: 0,
            stride: stride,
            name: "a0".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 1,
            elem_type: a::Int(a::IntNormalized, a::U16, a::Signed),
            offset: 8,
            stride: stride,
            name: "a1".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 4,
            elem_type: a::Int(a::IntAsFloat, a::U8, a::Signed),
            offset: 10,
            stride: stride,
            name: "a2".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 1,
            elem_type: a::Float(a::FloatPrecision, a::F64),
            offset: 14,
            stride: stride,
            name: "a3".to_string(),
        },
        gfx::Attribute {
            buffer: buf.raw(),
            elem_count: 3,
            elem_type: a::Float(a::FloatDefault, a::F32),
            offset: 22,
            stride: stride,
            name: "a_a4".to_string(),
        },
    ]);
}
<|endoftext|>


<commit_before>pub struct GraphemeIndex(usize);
pub struct ByteIndex(usize);
pub struct CharIndex(usize);

#[cfg(feature = "unstable")]
trait UnicodeIndexing {
    fn graphemes<'a>(&'a self) -> impl Iterator<Item = &'a str> + 'a;
    fn grapheme_indices<'a>(&'a self)
                            -> impl Iterator<Item = (usize, &'a str)> + 'a;

    #[inline]
    fn grapheme_count(&self) -> usize {
        self.graphemes().count()
    }

    /// Returns the byte index corresponding to a given grapheme index
    /// or none, if it is off the end of the string.
    // TODO: newtypes for usize
    fn grapheme_to_byte_index(&self, idx: GraphemeIndex) -> Option<ByteIndex> {
        self.grapheme_indices()
            .find(|(i, _)| i == idx.0)
            .map(ByteIndex)
        // TODO: what about the case where g_idx is the last grapheme
    }

    fn grapheme_to_char_index(&self, idx: GraphemeIndex) -> Option<CharIndex> {
        unimplemented!()
    }

    fn char_to_grapheme_index(&self, idx: CharIndex) -> Option<GraphemeIndex> {
        unimplemented!()
    }

    fn char_to_byte_index(&self, idx: CharIndex) -> Option<ByteIndex> {
        unimplemented!()
    }

    fn byte_to_char_index(&self, idx: ByteIndex) -> Option<CharIndex> {
        unimplemented!()
    }

    fn byte_to_grapheme_index(&self, idx: ByteIndex) -> Option<GraphemeIndex> {
        unimplemented!()
    }

}
<commit_msg>rope: attempting to do grapheme index conversions w/ newtypes<commit_after>use std::convert::Into;
use unicode_segmentation::UnicodeSegmentation;

pub struct GraphemeIndex<'a> { index: usize
                             , into_str: &'a str
                             }
pub struct ByteIndex<'a> { index: usize
                         , into_str: &'a str
                         }
pub struct CharIndex<'a> { index: usize
                         , into_str: &'a str
                         }

impl<'a> Into<ByteIndex<'a>> for GraphemeIndex<'a> {
    // TODO is this reasonable?
    fn into(self) -> ByteIndex<'a> {
        self.into_str.grapheme_indices(true)
            .find(|&(i, _)| i == self.index)
            .map(|(i, _)| ByteIndex { index: i, into_str: self.into_str})
            .expect(&format!( "Grapheme index {} off the end of string {}!"
                             , self.index
                             , self.into_str))
    }
}

impl<'a> Into<CharIndex<'a>> for GraphemeIndex<'a> {
    fn into(self) -> CharIndex<'a> {
        unimplemented!()
    }
}
<|endoftext|>


<commit_before>use super::start_server;
use graph;
use graph::*;
use graph::edge::*;
use graph::vertex::*;
use server::schema::{MorpheusSchema, SchemaError, EMPTY_FIELDS};
use neb::ram::schema::Field;
use neb::ram::types::{TypeId, Value, Map};
use neb::ram::cell::Cell;

#[test]
pub fn schemas() {
    let server = start_server(4001, "schemas");
    let graph = &server.graph;
    let mut edge_schema = MorpheusSchema::new(
        "test_edge_schema",
        None,
        &vec![Field::new(&"test_field", TypeId::U32 as u32, false, false, None)], false
    );
    assert_eq!(edge_schema.id, 0);
    assert!(
    graph.new_edge_group(
        &mut edge_schema,
        graph::edge::EdgeAttributes::new
            (
                graph::edge::EdgeType::Directed,
                false
            )).is_err());
    assert_eq!(edge_schema.id, 0);
    graph.new_edge_group(
        &mut edge_schema,
        graph::edge::EdgeAttributes::new(graph::edge::EdgeType::Directed, true)).unwrap();
    let mut vertex_schema = edge_schema.clone();
    vertex_schema.name = "test_vertex_schema".to_string();
    graph.new_vertex_group(&mut vertex_schema).unwrap();
    assert_eq!(edge_schema.id, 1);
    assert_eq!(vertex_schema.id, 2);
    let mut test_data = Map::new();
    test_data.insert("test_field", Value::U32(1));
    graph.new_vertex(&vertex_schema, test_data.clone()).unwrap();
    graph.new_vertex("test_edge_schema", test_data.clone()).is_err();
}

#[test]
pub fn relationship() {
    let server = start_server(4002, "relationship");
    let graph = &server.graph;
    let mut people_schema = MorpheusSchema::new("people", Some(&vec!["name".to_string()]), &vec! [
        Field::new("name", TypeId::String as u32, false, false, None)
    ], true);
    let mut movie_schema = MorpheusSchema::new("movie", Some(&vec!["name".to_string()]), &vec! [
        Field::new("name", TypeId::String as u32, false, false, None),
        Field::new("year", TypeId::U32 as u32, false, false, None)
    ], true);
    let mut acted_in_schema = MorpheusSchema::new("acted-in", None, &vec! [
        Field::new("role", TypeId::String as u32, false, false, None)
    ], true);
    let mut spouse_schema = MorpheusSchema::new("spouse", None, &EMPTY_FIELDS, false);
    graph.new_vertex_group(&mut people_schema).unwrap();
    graph.new_vertex_group(&mut movie_schema).unwrap();
    graph.new_edge_group(
        &mut acted_in_schema,
        EdgeAttributes::new(
            EdgeType::Directed,
            true
        )
    ).unwrap();
    graph.new_edge_group(
        &mut spouse_schema,
        EdgeAttributes::new(
            EdgeType::Undirected,
            false
        )
    ).unwrap();
    assert_eq!(people_schema.id, 1);
    assert_eq!(movie_schema.id, 2);
    assert_eq!(acted_in_schema.id, 3);
    assert_eq!(spouse_schema.id, 4);
    let morgan_freeman_name = "Morgan Freeman";
    let batman_begins_name = "Batman Begins";
    let the_dark_knight_name = "The Dark Knight";
    let the_dark_knight_rises_name = "The Dark Knight Rises";
    let oblivion_name = "Oblivion";
    let jeanette_name = "Jeanette Adair Bradshaw";
    graph.new_vertex("people", data_map!{
        name: morgan_freeman_name, age: 80 as u8
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: batman_begins_name, year: 2005 as u32
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: the_dark_knight_name, year: 2008 as u32
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: the_dark_knight_rises_name, year: 2012 as u32
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: oblivion_name, year: 2010 as u32
    }).unwrap();
    graph.new_vertex("people", data_map!{
        name: jeanette_name
    }).unwrap();

    assert_eq!(
        graph.vertex_by_key("people", morgan_freeman_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        morgan_freeman_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", batman_begins_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        batman_begins_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", the_dark_knight_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        the_dark_knight_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", the_dark_knight_rises_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        the_dark_knight_rises_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", oblivion_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        oblivion_name
    );
    assert_eq!(
        graph.vertex_by_key("people", jeanette_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        jeanette_name
    );
    assert_eq!(
        graph.vertex_by_key("people", morgan_freeman_name)
            .unwrap().unwrap()["age"].U8().unwrap(),
        80u8
    );

    let morgan_freeman =
        graph.vertex_by_key("people", morgan_freeman_name)
        .unwrap().unwrap();

    let batman_begins =
        graph.vertex_by_key("movie", batman_begins_name)
        .unwrap().unwrap();

    graph.link(&morgan_freeman, "acted-in", &batman_begins, Some(&data_map!{
        as: "Lucius Fox", works_for: "Bruce Wayne"
    }));
}<commit_msg>test link, but failed<commit_after>use super::start_server;
use graph;
use graph::*;
use graph::edge::*;
use graph::vertex::*;
use server::schema::{MorpheusSchema, SchemaError, EMPTY_FIELDS};
use neb::ram::schema::Field;
use neb::ram::types::{TypeId, Value, Map};
use neb::ram::cell::Cell;

#[test]
pub fn schemas() {
    let server = start_server(4001, "schemas");
    let graph = &server.graph;
    let mut edge_schema = MorpheusSchema::new(
        "test_edge_schema",
        None,
        &vec![Field::new(&"test_field", TypeId::U32 as u32, false, false, None)], false
    );
    assert_eq!(edge_schema.id, 0);
    assert!(
    graph.new_edge_group(
        &mut edge_schema,
        graph::edge::EdgeAttributes::new
            (
                graph::edge::EdgeType::Directed,
                false
            )).is_err());
    assert_eq!(edge_schema.id, 0);
    graph.new_edge_group(
        &mut edge_schema,
        graph::edge::EdgeAttributes::new(graph::edge::EdgeType::Directed, true)).unwrap();
    let mut vertex_schema = edge_schema.clone();
    vertex_schema.name = "test_vertex_schema".to_string();
    graph.new_vertex_group(&mut vertex_schema).unwrap();
    assert_eq!(edge_schema.id, 1);
    assert_eq!(vertex_schema.id, 2);
    let mut test_data = Map::new();
    test_data.insert("test_field", Value::U32(1));
    graph.new_vertex(&vertex_schema, test_data.clone()).unwrap();
    graph.new_vertex("test_edge_schema", test_data.clone()).is_err();
}

#[test]
pub fn relationship() {
    let server = start_server(4002, "relationship");
    let graph = &server.graph;
    let mut people_schema = MorpheusSchema::new("people", Some(&vec!["name".to_string()]), &vec! [
        Field::new("name", TypeId::String as u32, false, false, None)
    ], true);
    let mut movie_schema = MorpheusSchema::new("movie", Some(&vec!["name".to_string()]), &vec! [
        Field::new("name", TypeId::String as u32, false, false, None),
        Field::new("year", TypeId::U32 as u32, false, false, None)
    ], true);
    let mut acted_in_schema = MorpheusSchema::new("acted-in", None, &vec! [
        Field::new("role", TypeId::String as u32, false, false, None)
    ], true);
    let mut spouse_schema = MorpheusSchema::new("spouse", None, &EMPTY_FIELDS, false);
    graph.new_vertex_group(&mut people_schema).unwrap();
    graph.new_vertex_group(&mut movie_schema).unwrap();
    graph.new_edge_group(
        &mut acted_in_schema,
        EdgeAttributes::new(
            EdgeType::Directed,
            true
        )
    ).unwrap();
    graph.new_edge_group(
        &mut spouse_schema,
        EdgeAttributes::new(
            EdgeType::Undirected,
            false
        )
    ).unwrap();
    assert_eq!(people_schema.id, 1);
    assert_eq!(movie_schema.id, 2);
    assert_eq!(acted_in_schema.id, 3);
    assert_eq!(spouse_schema.id, 4);
    let morgan_freeman_name = "Morgan Freeman";
    let batman_begins_name = "Batman Begins";
    let the_dark_knight_name = "The Dark Knight";
    let the_dark_knight_rises_name = "The Dark Knight Rises";
    let oblivion_name = "Oblivion";
    let jeanette_name = "Jeanette Adair Bradshaw";
    graph.new_vertex("people", data_map!{
        name: morgan_freeman_name, age: 80 as u8
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: batman_begins_name, year: 2005 as u32
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: the_dark_knight_name, year: 2008 as u32
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: the_dark_knight_rises_name, year: 2012 as u32
    }).unwrap();
    graph.new_vertex("movie", data_map!{
        name: oblivion_name, year: 2010 as u32
    }).unwrap();
    graph.new_vertex("people", data_map!{
        name: jeanette_name
    }).unwrap();

    assert_eq!(
        graph.vertex_by_key("people", morgan_freeman_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        morgan_freeman_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", batman_begins_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        batman_begins_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", the_dark_knight_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        the_dark_knight_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", the_dark_knight_rises_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        the_dark_knight_rises_name
    );
    assert_eq!(
        graph.vertex_by_key("movie", oblivion_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        oblivion_name
    );
    assert_eq!(
        graph.vertex_by_key("people", jeanette_name)
            .unwrap().unwrap()["name"].String().unwrap(),
        jeanette_name
    );
    assert_eq!(
        graph.vertex_by_key("people", morgan_freeman_name)
            .unwrap().unwrap()["age"].U8().unwrap(),
        80u8
    );

    let morgan_freeman =
        graph.vertex_by_key("people", morgan_freeman_name)
        .unwrap().unwrap();

    let batman_begins =
        graph.vertex_by_key("movie", batman_begins_name)
        .unwrap().unwrap();

    graph.link(&morgan_freeman, "acted-in", &batman_begins, Some(&data_map!{
        as: "Lucius Fox", works_for: "Bruce Wayne"
    })).unwrap().unwrap();
}<|endoftext|>


<commit_before>//! Wrapper for wlr_cursor

use std::ptr;

use wlroots_sys::{wlr_cursor, wlr_cursor_create, wlr_cursor_destroy, wlr_cursor_move,
                  wlr_cursor_set_image, wlr_cursor_warp};

use {InputDevice, XCursorImage};

#[derive(Debug)]
pub struct CursorBuilder {
    cursor: *mut wlr_cursor
}

#[derive(Debug)]
pub struct Cursor {
    cursor: *mut wlr_cursor
}

impl CursorBuilder {
    pub fn new() -> Option<Self> {
        unsafe {
            let cursor = wlr_cursor_create();
            if cursor.is_null() {
                None
            } else {
                Some(CursorBuilder { cursor: cursor })
            }
        }
    }

    /// Sets the image of the cursor to the image from the XCursor.
    pub fn set_cursor_image(self, image: &XCursorImage) -> Self {
        unsafe {
            let scale = 0.0;
            // NOTE Rationale for why lifetime isn't attached:
            //
            // wlr_cursor_set_image uses gl calls internally, which copies
            // the buffer and so it doesn't matter what happens to the
            // xcursor image after this call.
            wlr_cursor_set_image(self.cursor,
                                 image.buffer.as_ptr(),
                                 image.width as i32,
                                 image.width,
                                 image.height,
                                 image.hotspot_x as i32,
                                 image.hotspot_y as i32,
                                 scale)
        }
        self
    }

    pub(crate) fn build(self) -> Cursor {
        Cursor { cursor: self.cursor }
    }
}

impl Cursor {
    pub fn coords(&self) -> (f64, f64) {
        unsafe { ((*self.cursor).x, (*self.cursor).y) }
    }

    pub fn warp(&mut self, dev: Option<&InputDevice>, x: f64, y: f64) -> bool {
        unsafe {
            let dev_ptr = dev.map(|dev| dev.as_ptr()).unwrap_or(ptr::null_mut());
            wlr_cursor_warp(self.cursor, dev_ptr, x, y)
        }
    }

    pub fn move_to(&mut self, dev: &InputDevice, delta_x: f64, delta_y: f64) {
        unsafe { wlr_cursor_move(self.cursor, dev.as_ptr(), delta_x, delta_y) }
    }

    /// Sets the image of the cursor to the image from the XCursor.
    pub fn set_cursor_image(&mut self, image: &XCursorImage) {
        unsafe {
            let scale = 0.0;
            // NOTE Rationale for why lifetime isn't attached:
            //
            // wlr_cursor_set_image uses gl calls internally, which copies
            // the buffer and so it doesn't matter what happens to the
            // xcursor image after this call.
            wlr_cursor_set_image(self.cursor,
                                 image.buffer.as_ptr(),
                                 image.width as i32,
                                 image.width,
                                 image.height,
                                 image.hotspot_x as i32,
                                 image.hotspot_y as i32,
                                 scale)
        }
    }

    pub(crate) unsafe fn as_ptr(&self) -> *mut wlr_cursor {
        self.cursor
    }
}

impl Drop for Cursor {
    fn drop(&mut self) {
        unsafe { wlr_cursor_destroy(self.cursor) }
    }
}
<commit_msg>Wrapped rest of cursor functions<commit_after>//! Wrapper for wlr_cursor

use std::ptr;

use wlroots_sys::{wlr_cursor, wlr_cursor_absolute_to_layout_coords,
                  wlr_cursor_attach_input_device, wlr_cursor_create, wlr_cursor_destroy,
                  wlr_cursor_detach_input_device, wlr_cursor_map_input_to_output,
                  wlr_cursor_map_input_to_region, wlr_cursor_map_to_output,
                  wlr_cursor_map_to_region, wlr_cursor_move, wlr_cursor_set_image,
                  wlr_cursor_set_surface, wlr_cursor_warp, wlr_cursor_warp_absolute};

use {Area, InputDevice, Output, Surface, XCursorImage};

#[derive(Debug)]
pub struct CursorBuilder {
    cursor: *mut wlr_cursor
}

#[derive(Debug)]
pub struct Cursor {
    cursor: *mut wlr_cursor
}

impl CursorBuilder {
    pub fn new() -> Option<Self> {
        unsafe {
            let cursor = wlr_cursor_create();
            if cursor.is_null() {
                None
            } else {
                Some(CursorBuilder { cursor: cursor })
            }
        }
    }

    /// Sets the image of the cursor to the image from the XCursor.
    pub fn set_cursor_image(self, image: &XCursorImage) -> Self {
        unsafe {
            let scale = 0.0;
            // NOTE Rationale for why lifetime isn't attached:
            //
            // wlr_cursor_set_image uses gl calls internally, which copies
            // the buffer and so it doesn't matter what happens to the
            // xcursor image after this call.
            wlr_cursor_set_image(self.cursor,
                                 image.buffer.as_ptr(),
                                 image.width as i32,
                                 image.width,
                                 image.height,
                                 image.hotspot_x as i32,
                                 image.hotspot_y as i32,
                                 scale)
        }
        self
    }

    pub(crate) fn build(self) -> Cursor {
        Cursor { cursor: self.cursor }
    }
}

impl Cursor {
    /// Get the coordinates the cursor is located at.
    pub fn coords(&self) -> (f64, f64) {
        unsafe { ((*self.cursor).x, (*self.cursor).y) }
    }

    /// Warp the cursor to the given x and y in layout coordinates. If x and y are
    /// out of the layout boundaries or constraints, no warp will happen.
    ///
    /// `dev` may be passed to respect device mapping constraints. If `dev` is None,
    /// device mapping constraints will be ignored.
    ///
    /// Returns true when the mouse warp was successful.
    pub fn warp(&mut self, dev: Option<&InputDevice>, x: f64, y: f64) -> bool {
        unsafe {
            let dev_ptr = dev.map(|input_device| input_device.as_ptr()).unwrap_or(ptr::null_mut());
            wlr_cursor_warp(self.cursor, dev_ptr, x, y)
        }
    }

    pub fn warp_absolute(&mut self, dev: Option<&InputDevice>, x_mm: f64, y_mm: f64) {
        unsafe {
            let dev_ptr = dev.map(|input_device| input_device.as_ptr()).unwrap_or(ptr::null_mut());
            wlr_cursor_warp_absolute(self.cursor, dev_ptr, x_mm, y_mm)
        }
    }

    /// Move the cursor in the direction of the given x and y coordinates.
    ///
    /// `dev` may be passed to respect device mapping constraints. If `dev` is None,
    /// device mapping constraints will be ignored.
    pub fn move_to(&mut self, dev: &InputDevice, delta_x: f64, delta_y: f64) {
        unsafe { wlr_cursor_move(self.cursor, dev.as_ptr(), delta_x, delta_y) }
    }

    // TODO Allow setting cursor images to arbitrary bytes,
    // just like in wlroots. Want to make sure that's safe though

    /// Sets the image of the cursor to the image from the XCursor.
    pub fn set_cursor_image(&mut self, image: &XCursorImage) {
        unsafe {
            let scale = 0.0;
            // NOTE Rationale for why lifetime isn't attached:
            //
            // wlr_cursor_set_image uses gl calls internally, which copies
            // the buffer and so it doesn't matter what happens to the
            // xcursor image after this call.
            wlr_cursor_set_image(self.cursor,
                                 image.buffer.as_ptr(),
                                 image.width as i32,
                                 image.width,
                                 image.height,
                                 image.hotspot_x as i32,
                                 image.hotspot_y as i32,
                                 scale)
        }
    }

    /// Set the cursor surface. The surface can be committed to update the cursor
    /// image. The surface position is substracted from the hotspot.
    ///
    /// A `None` surface commit hides the cursor.
    pub fn set_surface(&mut self, surface: Option<&Surface>, hotspot_x: i32, hotspot_y: i32) {
        unsafe {
            let surface_ptr = surface.map(|surface| surface.as_ptr())
                                     .unwrap_or(ptr::null_mut());
            wlr_cursor_set_surface(self.cursor, surface_ptr, hotspot_x, hotspot_y)
        }
    }

    // TODO Ensure the safety of these functions.
    // It's possible we need more handles floating about with checks...
    // or a different memory model -_-

    /// Attaches this input device to this cursor. The input device must be one of:
    ///
    /// - WLR_INPUT_DEVICE_POINTER
    /// - WLR_INPUT_DEVICE_TOUCH
    /// - WLR_INPUT_DEVICE_TABLET_TOOL
    ///
    /// TODO Make this impossible to mess up with using an enum
    /// Note that it's safe to use the wrong type.
    pub fn attach_input_device(&mut self, dev: &InputDevice) {
        unsafe { wlr_cursor_attach_input_device(self.cursor, dev.as_ptr()) }
    }

    /// Deattaches the input device from this cursor.
    pub fn deattach_input_device(&mut self, dev: &InputDevice) {
        unsafe { wlr_cursor_detach_input_device(self.cursor, dev.as_ptr()) }
    }

    // TODO Test what it means for the call to be "invalid". Segfault?

    /// Attaches this cursor to the given output, which must be among the outputs in
    /// the current output_layout for this cursor.
    ///
    /// This call is invalid for a cursor without an associated output layout.
    pub fn map_to_output(&mut self, output: &Output) {
        unsafe { wlr_cursor_map_to_output(self.cursor, output.as_ptr()) }
    }

    /// Maps all input from a specific input device to a given output.
    ///
    /// The input device must be attached to this cursor
    /// and the output must be among the outputs in the attached output layout.
    pub fn map_input_to_output(&mut self, dev: &InputDevice, output: &Output) {
        unsafe { wlr_cursor_map_input_to_output(self.cursor, dev.as_ptr(), output.as_ptr()) }
    }

    /// Maps this cursor to an arbitrary region on the associated
    /// wlr_output_layout.
    pub fn map_to_region(&mut self, mut area: Area) {
        unsafe { wlr_cursor_map_to_region(self.cursor, &mut area.0) }
    }

    /// Maps inputs from this input device to an arbitrary region on the associated
    /// wlr_output_layout.
    pub fn map_input_to_region(&mut self, dev: &InputDevice, mut area: Area) {
        unsafe { wlr_cursor_map_input_to_region(self.cursor, dev.as_ptr(), &mut area.0) }
    }

    /// Convert absolute coordinates to layout coordinates for the device.
    ///
    /// Coordinates are in (x, y).
    pub fn absolute_to_layout_coords(&mut self,
                                     dev: &InputDevice,
                                     x_mm: f64,
                                     y_mm: f64,
                                     width_mm: f64,
                                     height_mm: f64)
                                     -> (f64, f64) {
        unsafe {
            let (mut lx, mut ly) = (0.0, 0.0);
            wlr_cursor_absolute_to_layout_coords(self.cursor,
                                                 dev.as_ptr(),
                                                 x_mm,
                                                 y_mm,
                                                 width_mm,
                                                 height_mm,
                                                 &mut lx,
                                                 &mut ly);
            (lx, ly)
        }
    }

    pub(crate) unsafe fn as_ptr(&self) -> *mut wlr_cursor {
        self.cursor
    }
}

impl Drop for Cursor {
    fn drop(&mut self) {
        unsafe { wlr_cursor_destroy(self.cursor) }
    }
}
<|endoftext|>


<commit_before>/*================================================================================================*/
// Copyright 2016 Kyle Finlay
//
// 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 Mathf;

use std::ops::*;
use std::cmp::PartialEq;

/*================================================================================================*/
/*------STRUCTS-----------------------------------------------------------------------------------*/
/*================================================================================================*/

/// The Vec3f struct
///
/// This is the most used out of the three vector structs.
/// It is used to representing positions in 3D space (vertices, normals, positions, etc).
/// 32-bit floats are used for the values.
#[derive (Copy, Clone)]
pub struct Vec3f {

    // Public
    /// X-axis coordinate
    pub x : f32,
    /// Y-axis coordinate
    pub y : f32,
    /// Z-axis coordinate
    pub z : f32
}

/*================================================================================================*/
/*------PUBLIC FUNCTIONS--------------------------------------------------------------------------*/
/*================================================================================================*/

impl Vec3f {

    /// Formats the vector as a string.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec3f {x : 10.0, y : 5.0};
    /// println! ("Vector = {}", vec.to_string ());
    /// ```
    /// ```c
    /// Output : Vector = 10.0, 5.0
    pub fn to_string (&self) -> String {

        format! ("{}, {}, {}", self.x, self.y, self.z)
    }

/*================================================================================================*/
/*------PUBLIC STATIC FUNCTIONS-------------------------------------------------------------------*/
/*================================================================================================*/

    /// Creates a vector with a default value of zero.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec3f::new ();
    pub fn new () -> Vec3f {

        Vec3f {x : 0.0,
               y : 0.0,
               z : 0.0}
    }

/*================================================================================================*/

    /// Retuns the cross product of two vectors.
    pub fn cross (lhs : &Vec3f, rhs : &Vec3f) -> Vec3f {

        Vec3f {x : lhs.y * rhs.z - rhs.y * lhs.z,
               y : lhs.z * rhs.x - rhs.x * lhs.x,
               z : lhs.x * rhs.y - rhs.x * lhs.y}
    }

/*================================================================================================*/

    /// Returns the dot product of two vectors.
    pub fn dot (lhs : &Vec3f, rhs : &Vec3f) -> f32 {

        (lhs.x * rhs.x) +
        (lhs.y * rhs.y) +
        (lhs.z * rhs.z)
    }

/*================================================================================================*/

    /// Returns the distance between two vectors
    pub fn distance (start : &Vec3f, end : &Vec3f) -> f32 {

        Vec3f::length (& (*start - *end))
    }

/*================================================================================================*/

    /// Returns the length of a vector
    pub fn length (vector : &Vec3f) -> f32 {

        (vector.x * vector.x +
         vector.y * vector.y +
         vector.z * vector.z).sqrt ()
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors.
    pub fn lerp (start : &Vec3f, end : &Vec3f, percentage : f32) -> Vec3f {

        Vec3f {x : Mathf::lerp (start.x, end.x, percentage),
               y : Mathf::lerp (start.y, end.y, percentage),
               z : Mathf::lerp (start.z, end.z, percentage)}
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors without clamping
    pub fn lerp_unclamped (start : &Vec3f, end : &Vec3f, percentage : f32) -> Vec3f {

        Vec3f {x : Mathf::lerp_unclamped (start.x, end.x, percentage),
               y : Mathf::lerp_unclamped (start.y, end.y, percentage),
               z : Mathf::lerp_unclamped (start.z, end.z, percentage)}
    }

/*================================================================================================*/

    /// Get a normalized vector.
    pub fn normalize (vector : &Vec3f) -> Vec3f {

        let length = Vec3f::length (vector);

        if length != 0.0 {

            return Vec3f {x : vector.x / length,
                          y : vector.y / length,
                          z : vector.z / length}
        }

        Vec3f::new ()
    }
}

/*================================================================================================*/
/*------OPERATOR OVERLOADS------------------------------------------------------------------------*/
/*================================================================================================*/

impl Add for Vec3f {

    type Output = Vec3f;

    // Addition operator (vector)
    fn add (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x + rhs.x,
               y : self.y + rhs.y,
               z : self.z + rhs.z}
    }
}

/*================================================================================================*/

impl Add <f32> for Vec3f {

    type Output = Vec3f;

    // Addition operator (f32)
    fn add (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x + rhs,
               y : self.y + rhs,
               z : self.z + rhs}
    }
}

/*================================================================================================*/

impl AddAssign for Vec3f {

    // Addition assignment operator (vector)
    fn add_assign (&mut self, rhs : Vec3f) {

        self.x += rhs.x;
        self.y += rhs.y;
        self.z += rhs.z;
    }
}

/*================================================================================================*/

impl AddAssign <f32> for Vec3f {

    // Addition assignment operator (f32)
    fn add_assign (&mut self, rhs : f32) {

        self.x += rhs;
        self.y += rhs;
        self.z += rhs;
    }
}

/*================================================================================================*/

impl Sub for Vec3f {

    type Output = Vec3f;

    // Subtraction operator (vector)
    fn sub (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x - rhs.x,
               y : self.y - rhs.y,
               z : self.z - rhs.z}
    }
}

/*================================================================================================*/

impl Sub <f32> for Vec3f {

    type Output = Vec3f;

    // Subtraction operator (f32)
    fn sub (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x - rhs,
               y : self.y - rhs,
               z : self.z - rhs}
    }
}

/*================================================================================================*/

impl SubAssign for Vec3f {

    // Subtraction assignment operator (vector)
    fn sub_assign (&mut self, rhs : Vec3f) {

        self.x -= rhs.x;
        self.y -= rhs.y;
        self.z -= rhs.z;
    }
}

/*================================================================================================*/

impl SubAssign <f32> for Vec3f {

    // Subtraction assignment operator (f32)
    fn sub_assign (&mut self, rhs : f32) {

        self.x -= rhs;
        self.y -= rhs;
        self.z -= rhs;
    }
}

/*================================================================================================*/

impl Neg for Vec3f {

    type Output = Vec3f;

    // Unary minus operator
    fn neg (self) -> Vec3f {

        Vec3f {x : -self.x,
               y : -self.y,
               z : -self.z}
    }
}

/*================================================================================================*/

impl Mul for Vec3f {

    type Output = Vec3f;

    // Multiplication operator (vector)
    fn mul (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x * rhs.x,
               y : self.y * rhs.y,
               z : self.z * rhs.z}
    }
}

/*================================================================================================*/

impl Mul <f32> for Vec3f {

    type Output = Vec3f;

    // Multiplication operator (f32)
    fn mul (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x * rhs,
               y : self.y * rhs,
               z : self.z * rhs}
    }
}

/*================================================================================================*/

impl MulAssign for Vec3f {

    // Multiplication assignment operator (vector)
    fn mul_assign (&mut self, rhs : Vec3f) {

        self.x *= rhs.x;
        self.y *= rhs.y;
        self.z *= rhs.z;
    }
}

/*================================================================================================*/

impl MulAssign <f32> for Vec3f {

    // Multiplication assignment operator (f32)
    fn mul_assign (&mut self, rhs : f32) {

        self.x *= rhs;
        self.y *= rhs;
        self.z *= rhs;
    }
}

/*================================================================================================*/

impl Div for Vec3f {

    type Output = Vec3f;

    // Division operator (vector)
    fn div (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x / rhs.x,
               y : self.y / rhs.y,
               z : self.z / rhs.z}
    }
}

/*================================================================================================*/

impl Div <f32> for Vec3f {

    type Output = Vec3f;

    // Division operator (f32)
    fn div (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x / rhs,
               y : self.y / rhs,
               z : self.z / rhs}
    }
}

/*================================================================================================*/

impl DivAssign for Vec3f {

    // Division assignment operator (vector)
    fn div_assign (&mut self, rhs : Vec3f) {

        self.x /= rhs.x;
        self.y /= rhs.y;
        self.z /= rhs.z;
    }
}

/*================================================================================================*/

impl DivAssign <f32> for Vec3f {

    // Division assignment operator (f32)
    fn div_assign (&mut self, rhs : f32) {

        self.x /= rhs;
        self.y /= rhs;
        self.z /= rhs;
    }
}

/*================================================================================================*/

impl PartialEq for Vec3f {

    // Equal to operator
    fn eq (&self, rhs : &Vec3f) -> bool {

        self.x == rhs.x &&
        self.y == rhs.y &&
        self.z == rhs.z
    }

/*================================================================================================*/

    // Not equal to operator
    fn ne (&self, rhs : &Vec3f) -> bool {

        self.x != rhs.x ||
        self.y != rhs.y ||
        self.z != rhs.z
    }
}

/*================================================================================================*/

impl Index <u8> for Vec3f {

    type Output = f32;

    // Index operator (immutable)
    fn index (&self, index : u8) -> &f32 {

        match index {

            0 => &self.x,
            1 => &self.y,
            2 => &self.z,
            _ => unreachable! ("Index out of range for Vec3f")
        }
    }
}

/*================================================================================================*/

impl IndexMut <u8> for Vec3f {

    // Index operator (mutable)
    fn index_mut (&mut self, index : u8) -> &mut f32 {

        match index {

            0 => &mut self.x,
            1 => &mut self.y,
            2 => &mut self.z,
            _ => unreachable! ("Index out of range for Vec3f")
        }
    }
}
<commit_msg>Fixed documentation error<commit_after>/*================================================================================================*/
// Copyright 2016 Kyle Finlay
//
// 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 Mathf;

use std::ops::*;
use std::cmp::PartialEq;

/*================================================================================================*/
/*------STRUCTS-----------------------------------------------------------------------------------*/
/*================================================================================================*/

/// The Vec3f struct
///
/// This is the most used out of the three vector structs.
/// It is used for representing positions in 3D space (vertices, normals, positions, etc).
/// 32-bit floats are used for the values.
#[derive (Copy, Clone)]
pub struct Vec3f {

    // Public
    /// X-axis coordinate
    pub x : f32,
    /// Y-axis coordinate
    pub y : f32,
    /// Z-axis coordinate
    pub z : f32
}

/*================================================================================================*/
/*------PUBLIC FUNCTIONS--------------------------------------------------------------------------*/
/*================================================================================================*/

impl Vec3f {

    /// Formats the vector as a string.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec3f {x : 10.0, y : 5.0};
    /// println! ("Vector = {}", vec.to_string ());
    /// ```
    /// ```c
    /// Output : Vector = 10.0, 5.0
    pub fn to_string (&self) -> String {

        format! ("{}, {}, {}", self.x, self.y, self.z)
    }

/*================================================================================================*/
/*------PUBLIC STATIC FUNCTIONS-------------------------------------------------------------------*/
/*================================================================================================*/

    /// Creates a vector with a default value of zero.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec3f::new ();
    pub fn new () -> Vec3f {

        Vec3f {x : 0.0,
               y : 0.0,
               z : 0.0}
    }

/*================================================================================================*/

    /// Retuns the cross product of two vectors.
    pub fn cross (lhs : &Vec3f, rhs : &Vec3f) -> Vec3f {

        Vec3f {x : lhs.y * rhs.z - rhs.y * lhs.z,
               y : lhs.z * rhs.x - rhs.x * lhs.x,
               z : lhs.x * rhs.y - rhs.x * lhs.y}
    }

/*================================================================================================*/

    /// Returns the dot product of two vectors.
    pub fn dot (lhs : &Vec3f, rhs : &Vec3f) -> f32 {

        (lhs.x * rhs.x) +
        (lhs.y * rhs.y) +
        (lhs.z * rhs.z)
    }

/*================================================================================================*/

    /// Returns the distance between two vectors
    pub fn distance (start : &Vec3f, end : &Vec3f) -> f32 {

        Vec3f::length (& (*start - *end))
    }

/*================================================================================================*/

    /// Returns the length of a vector
    pub fn length (vector : &Vec3f) -> f32 {

        (vector.x * vector.x +
         vector.y * vector.y +
         vector.z * vector.z).sqrt ()
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors.
    pub fn lerp (start : &Vec3f, end : &Vec3f, percentage : f32) -> Vec3f {

        Vec3f {x : Mathf::lerp (start.x, end.x, percentage),
               y : Mathf::lerp (start.y, end.y, percentage),
               z : Mathf::lerp (start.z, end.z, percentage)}
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors without clamping
    pub fn lerp_unclamped (start : &Vec3f, end : &Vec3f, percentage : f32) -> Vec3f {

        Vec3f {x : Mathf::lerp_unclamped (start.x, end.x, percentage),
               y : Mathf::lerp_unclamped (start.y, end.y, percentage),
               z : Mathf::lerp_unclamped (start.z, end.z, percentage)}
    }

/*================================================================================================*/

    /// Get a normalized vector.
    pub fn normalize (vector : &Vec3f) -> Vec3f {

        let length = Vec3f::length (vector);

        if length != 0.0 {

            return Vec3f {x : vector.x / length,
                          y : vector.y / length,
                          z : vector.z / length}
        }

        Vec3f::new ()
    }
}

/*================================================================================================*/
/*------OPERATOR OVERLOADS------------------------------------------------------------------------*/
/*================================================================================================*/

impl Add for Vec3f {

    type Output = Vec3f;

    // Addition operator (vector)
    fn add (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x + rhs.x,
               y : self.y + rhs.y,
               z : self.z + rhs.z}
    }
}

/*================================================================================================*/

impl Add <f32> for Vec3f {

    type Output = Vec3f;

    // Addition operator (f32)
    fn add (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x + rhs,
               y : self.y + rhs,
               z : self.z + rhs}
    }
}

/*================================================================================================*/

impl AddAssign for Vec3f {

    // Addition assignment operator (vector)
    fn add_assign (&mut self, rhs : Vec3f) {

        self.x += rhs.x;
        self.y += rhs.y;
        self.z += rhs.z;
    }
}

/*================================================================================================*/

impl AddAssign <f32> for Vec3f {

    // Addition assignment operator (f32)
    fn add_assign (&mut self, rhs : f32) {

        self.x += rhs;
        self.y += rhs;
        self.z += rhs;
    }
}

/*================================================================================================*/

impl Sub for Vec3f {

    type Output = Vec3f;

    // Subtraction operator (vector)
    fn sub (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x - rhs.x,
               y : self.y - rhs.y,
               z : self.z - rhs.z}
    }
}

/*================================================================================================*/

impl Sub <f32> for Vec3f {

    type Output = Vec3f;

    // Subtraction operator (f32)
    fn sub (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x - rhs,
               y : self.y - rhs,
               z : self.z - rhs}
    }
}

/*================================================================================================*/

impl SubAssign for Vec3f {

    // Subtraction assignment operator (vector)
    fn sub_assign (&mut self, rhs : Vec3f) {

        self.x -= rhs.x;
        self.y -= rhs.y;
        self.z -= rhs.z;
    }
}

/*================================================================================================*/

impl SubAssign <f32> for Vec3f {

    // Subtraction assignment operator (f32)
    fn sub_assign (&mut self, rhs : f32) {

        self.x -= rhs;
        self.y -= rhs;
        self.z -= rhs;
    }
}

/*================================================================================================*/

impl Neg for Vec3f {

    type Output = Vec3f;

    // Unary minus operator
    fn neg (self) -> Vec3f {

        Vec3f {x : -self.x,
               y : -self.y,
               z : -self.z}
    }
}

/*================================================================================================*/

impl Mul for Vec3f {

    type Output = Vec3f;

    // Multiplication operator (vector)
    fn mul (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x * rhs.x,
               y : self.y * rhs.y,
               z : self.z * rhs.z}
    }
}

/*================================================================================================*/

impl Mul <f32> for Vec3f {

    type Output = Vec3f;

    // Multiplication operator (f32)
    fn mul (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x * rhs,
               y : self.y * rhs,
               z : self.z * rhs}
    }
}

/*================================================================================================*/

impl MulAssign for Vec3f {

    // Multiplication assignment operator (vector)
    fn mul_assign (&mut self, rhs : Vec3f) {

        self.x *= rhs.x;
        self.y *= rhs.y;
        self.z *= rhs.z;
    }
}

/*================================================================================================*/

impl MulAssign <f32> for Vec3f {

    // Multiplication assignment operator (f32)
    fn mul_assign (&mut self, rhs : f32) {

        self.x *= rhs;
        self.y *= rhs;
        self.z *= rhs;
    }
}

/*================================================================================================*/

impl Div for Vec3f {

    type Output = Vec3f;

    // Division operator (vector)
    fn div (self, rhs : Vec3f) -> Vec3f {

        Vec3f {x : self.x / rhs.x,
               y : self.y / rhs.y,
               z : self.z / rhs.z}
    }
}

/*================================================================================================*/

impl Div <f32> for Vec3f {

    type Output = Vec3f;

    // Division operator (f32)
    fn div (self, rhs : f32) -> Vec3f {

        Vec3f {x : self.x / rhs,
               y : self.y / rhs,
               z : self.z / rhs}
    }
}

/*================================================================================================*/

impl DivAssign for Vec3f {

    // Division assignment operator (vector)
    fn div_assign (&mut self, rhs : Vec3f) {

        self.x /= rhs.x;
        self.y /= rhs.y;
        self.z /= rhs.z;
    }
}

/*================================================================================================*/

impl DivAssign <f32> for Vec3f {

    // Division assignment operator (f32)
    fn div_assign (&mut self, rhs : f32) {

        self.x /= rhs;
        self.y /= rhs;
        self.z /= rhs;
    }
}

/*================================================================================================*/

impl PartialEq for Vec3f {

    // Equal to operator
    fn eq (&self, rhs : &Vec3f) -> bool {

        self.x == rhs.x &&
        self.y == rhs.y &&
        self.z == rhs.z
    }

/*================================================================================================*/

    // Not equal to operator
    fn ne (&self, rhs : &Vec3f) -> bool {

        self.x != rhs.x ||
        self.y != rhs.y ||
        self.z != rhs.z
    }
}

/*================================================================================================*/

impl Index <u8> for Vec3f {

    type Output = f32;

    // Index operator (immutable)
    fn index (&self, index : u8) -> &f32 {

        match index {

            0 => &self.x,
            1 => &self.y,
            2 => &self.z,
            _ => unreachable! ("Index out of range for Vec3f")
        }
    }
}

/*================================================================================================*/

impl IndexMut <u8> for Vec3f {

    // Index operator (mutable)
    fn index_mut (&mut self, index : u8) -> &mut f32 {

        match index {

            0 => &mut self.x,
            1 => &mut self.y,
            2 => &mut self.z,
            _ => unreachable! ("Index out of range for Vec3f")
        }
    }
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use std::f32::consts::{PI, FRAC_PI_2};
use std::num::{Float};
use cgmath::{Vector3, Vector, Deg, Angle, deg};
use common::types::{ZInt, ZFloat, MapPos};
use zgl::types::{VertexCoord, WorldPos};
use core::geom;

pub use core::geom::{HEX_IN_RADIUS, HEX_EX_RADIUS};

pub const MINIMAL_LIFT_HEIGHT: ZFloat = 0.01;

pub fn map_pos_to_world_pos(i: &MapPos) -> WorldPos {
    WorldPos{v: geom::map_pos_to_world_pos(i).extend(0.0)}
}

pub fn lift(v: Vector3<ZFloat>) -> Vector3<ZFloat> {
    let mut v = v;
    v.z += MINIMAL_LIFT_HEIGHT;
    v
}

pub fn index_to_circle_vertex(count: ZInt, i: ZInt) -> VertexCoord {
    let n = FRAC_PI_2 + 2.0 * PI * (i as ZFloat) / (count as ZFloat);
    VertexCoord {
        v: Vector3 {
            x: n.cos(),
            y: n.sin(),
            z: 0.0
        }.mul_s(HEX_EX_RADIUS)
    }
}

pub fn index_to_hex_vertex(i: ZInt) -> VertexCoord {
    index_to_circle_vertex(6, i)
}

pub fn index_to_hex_vertex_s(scale: ZFloat, i: ZInt) -> VertexCoord {
    let v = index_to_hex_vertex(i).v.mul_s(scale);
    VertexCoord{v: v}
}

// TODO: ZFloat -> WorldDistance
pub fn dist(a: &WorldPos, b: &WorldPos) -> ZFloat {
    let dx = (b.v.x - a.v.x).abs();
    let dy = (b.v.y - a.v.y).abs();
    let dz = (b.v.z - a.v.z).abs();
    ((dx.powi(2) + dy.powi(2) + dz.powi(2)) as ZFloat).sqrt()
}

// TODO: fix this: a.v.angle(&b.v).to_deg();
pub fn get_rot_angle(a: &WorldPos, b: &WorldPos) -> Deg<ZFloat> {
    let mut angle = (((b.v.x - a.v.x) / dist(a, b)).asin()).to_degrees();
    if b.v.y - a.v.y > 0.0 {
        angle = -(180.0 + angle);
    }
    deg(angle)
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>(#70) visualizer/src/geom.rs: get_rot_angle: Employed 'atan2'<commit_after>// See LICENSE file for copyright and license details.

use std::f32::consts::{PI, FRAC_PI_2};
use std::num::{Float};
use cgmath::{Vector3, Vector, Deg, Angle, deg};
use common::types::{ZInt, ZFloat, MapPos};
use zgl::types::{VertexCoord, WorldPos};
use core::geom;

pub use core::geom::{HEX_IN_RADIUS, HEX_EX_RADIUS};

pub const MINIMAL_LIFT_HEIGHT: ZFloat = 0.01;

pub fn map_pos_to_world_pos(i: &MapPos) -> WorldPos {
    WorldPos{v: geom::map_pos_to_world_pos(i).extend(0.0)}
}

pub fn lift(v: Vector3<ZFloat>) -> Vector3<ZFloat> {
    let mut v = v;
    v.z += MINIMAL_LIFT_HEIGHT;
    v
}

pub fn index_to_circle_vertex(count: ZInt, i: ZInt) -> VertexCoord {
    let n = FRAC_PI_2 + 2.0 * PI * (i as ZFloat) / (count as ZFloat);
    VertexCoord {
        v: Vector3 {
            x: n.cos(),
            y: n.sin(),
            z: 0.0
        }.mul_s(HEX_EX_RADIUS)
    }
}

pub fn index_to_hex_vertex(i: ZInt) -> VertexCoord {
    index_to_circle_vertex(6, i)
}

pub fn index_to_hex_vertex_s(scale: ZFloat, i: ZInt) -> VertexCoord {
    let v = index_to_hex_vertex(i).v.mul_s(scale);
    VertexCoord{v: v}
}

// TODO: ZFloat -> WorldDistance
pub fn dist(a: &WorldPos, b: &WorldPos) -> ZFloat {
    let dx = (b.v.x - a.v.x).abs();
    let dy = (b.v.y - a.v.y).abs();
    let dz = (b.v.z - a.v.z).abs();
    ((dx.powi(2) + dy.powi(2) + dz.powi(2)) as ZFloat).sqrt()
}

pub fn get_rot_angle(a: &WorldPos, b: &WorldPos) -> Deg<ZFloat> {
    let diff = b.v - a.v;
    let angle = Float::atan2(diff.x, diff.y).to_degrees();
    let angle = -(180.0 + angle); // TODO: remove this
    deg(angle)
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>//! Wrapper for wlr_seat. For more information about what a seat is, please
//! consult the Wayland documentation ([libinput docs](https://wayland.freedesktop.org/libinput/doc/latest/seats.html), [wayland docs](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_seat))

use std::time::Duration;

use wlroots_sys::{wlr_axis_orientation, wlr_seat, wlr_seat_client, wlr_seat_create,
                  wlr_seat_destroy, wlr_seat_keyboard_clear_focus, wlr_seat_keyboard_end_grab,
                  wlr_seat_keyboard_enter, wlr_seat_keyboard_has_grab,
                  wlr_seat_keyboard_notify_enter, wlr_seat_keyboard_notify_key,
                  wlr_seat_keyboard_notify_modifiers, wlr_seat_keyboard_send_key,
                  wlr_seat_keyboard_send_modifiers, wlr_seat_keyboard_start_grab,
                  wlr_seat_pointer_clear_focus, wlr_seat_pointer_end_grab, wlr_seat_pointer_enter,
                  wlr_seat_pointer_has_grab, wlr_seat_pointer_notify_axis,
                  wlr_seat_pointer_notify_button, wlr_seat_pointer_notify_enter,
                  wlr_seat_pointer_notify_motion, wlr_seat_pointer_send_axis,
                  wlr_seat_pointer_send_button, wlr_seat_pointer_send_motion,
                  wlr_seat_pointer_start_grab, wlr_seat_pointer_surface_has_focus,
                  wlr_seat_set_capabilities, wlr_seat_set_keyboard, wlr_seat_set_name,
                  wlr_seat_touch_end_grab, wlr_seat_touch_has_grab, wlr_seat_touch_notify_down,
                  wlr_seat_touch_notify_motion, wlr_seat_touch_notify_up,
                  wlr_seat_touch_num_points, wlr_seat_touch_point_clear_focus,
                  wlr_seat_touch_point_focus, wlr_seat_touch_send_down,
                  wlr_seat_touch_send_motion, wlr_seat_touch_send_up, wlr_seat_touch_start_grab,
                  wlr_touch_point};
use wlroots_sys::wayland_server::protocol::wl_seat::Capability;

use compositor::Compositor;
use utils::{c_to_rust_string, safe_as_cstring};

use super::grab::{KeyboardGrab, PointerGrab, TouchGrab};
use types::surface::Surface;

/// A wrapper around `wlr_seat`.
pub struct Seat {
    seat: *mut wlr_seat
}

impl Seat {
    /// Allocates a new `wlr_seat` and adds a wl_seat global to the display.
    pub fn create(compositor: &mut Compositor, name: String) -> Option<Self> {
        unsafe {
            let name = safe_as_cstring(name);
            let seat = wlr_seat_create(compositor.display() as _, name.as_ptr());
            if seat.is_null() {
                None
            } else {
                Some(Seat { seat })
            }
        }
    }

    /// Get the name of the seat.
    pub fn name(&self) -> Option<String> {
        unsafe {
            let name_ptr = (*self.seat).name;
            if name_ptr.is_null() {
                return None
            }
            c_to_rust_string(name_ptr)
        }
    }

    /// Updates the name of this seat.
    /// Will automatically send it to all clients.
    pub fn set_name(&mut self, name: String) {
        let name = safe_as_cstring(name);
        unsafe {
            wlr_seat_set_name(self.seat, name.as_ptr());
        }
    }

    /// Gets the capabilities of this seat.
    pub fn capabilities(&self) -> Capability {
        unsafe {
            Capability::from_raw((*self.seat).capabilities).expect("Invalid capabilities")
        }
    }

    /// Updates the capabilities available on this seat.
    /// Will automatically send it to all clients.
    pub fn set_capabilities(&mut self, capabilities: Capability) {
        unsafe { wlr_seat_set_capabilities(self.seat, capabilities.bits()) }
    }

    /// Determines if the surface has pointer focus.
    pub fn pointer_surface_has_focus(&mut self, surface: Surface) -> bool {
        unsafe { wlr_seat_pointer_surface_has_focus(self.seat, surface.as_ptr()) }
    }

    // Sends a pointer enter event to the given surface and considers it to be
    // the focused surface for the pointer.
    //
    // This will send a leave event to the last surface that was entered.
    //
    // Coordinates for the enter event are surface-local.
    //
    // Compositor should use `Seat::notify_enter` to
    // change pointer focus to respect pointer grabs.
    pub fn pointer_enter(&mut self, surface: Surface, sx: f64, sy: f64) {
        unsafe {
            wlr_seat_pointer_enter(self.seat, surface.as_ptr(), sx, sy);
        }
    }

    /// Clears the focused surface for the pointer and leaves all entered
    /// surfaces.
    pub fn clear_focus(&mut self) {
        unsafe { wlr_seat_pointer_clear_focus(self.seat) }
    }

    /// Sends a motion event to the surface with pointer focus.
    ///
    /// Coordinates for the motion event are surface-local.
    ///
    /// Compositors should use `Seat::notify_motion` to
    /// send motion events to the respect pointer grabs.
    pub fn send_motion(&mut self, time: Duration, sx: f64, sy: f64) {
        let seconds_delta = time.as_secs() as u32;
        let nano_delta = time.subsec_nanos();
        let ms = (seconds_delta * 1000) + nano_delta / 1000000;
        unsafe {
            // TODO FIXME what kind of time? ms? s?
            // I'm just guessing it's ms, there's no documentation on this.
            wlr_seat_pointer_send_motion(self.seat, ms, sx, sy)
        }
    }

    // TODO Button and State should probably be wrapped in some sort of type...

    /// Send a button event to the surface with pointer focus.
    ///
    /// Coordinates for the button event are surface-local.
    ///
    /// Returns the serial.
    ///
    /// Compositors should use `Seat::notify_button` to
    /// send button events to respect pointer grabs.
    pub fn send_button(&mut self, time: Duration, button: u32, state: u32) -> u32 {
        let seconds_delta = time.as_secs() as u32;
        let nano_delta = time.subsec_nanos();
        let ms = (seconds_delta * 1000) + nano_delta / 1000000;
        unsafe { wlr_seat_pointer_send_button(self.seat, ms, button, state) }
    }

    /// Send an axis event to the surface with pointer focus.
    ///
    /// Compositors should use `Seat::notify_axis` to
    /// send axis events to respect pointer grabs.
    pub fn send_axis(&mut self, time: Duration, orientation: wlr_axis_orientation, value: f64) {
        let seconds_delta = time.as_secs() as u32;
        let nano_delta = time.subsec_nanos();
        let ms = (seconds_delta * 1000) + nano_delta / 1000000;
        unsafe {
            wlr_seat_pointer_send_axis(self.seat, ms, orientation, value);
        }
    }

    /// Start a grab of the pointer of this seat. The grabber is responsible for
    /// handling all pointer events until the grab ends.
    pub fn pointer_start_grab(&mut self, grab: PointerGrab) {
        unsafe { wlr_seat_pointer_start_grab(self.seat, grab.as_ptr()) }
    }

    /// End the grab of the pointer of this seat. This reverts the grab back to the
    /// default grab for the pointer.
    pub fn pointer_end_grab(&mut self) {
        unsafe { wlr_seat_pointer_end_grab(self.seat) }
    }

    /// Whether or not the pointer has a grab other than the default grab.
    pub fn pointer_has_grab(&self) -> bool {
        unsafe { wlr_seat_pointer_has_grab(self.seat) }
    }

    /// Clear the focused surface for the pointer and leave all entered
    /// surfaces.
    pub fn pointer_clear_focus(&mut self) {
        unsafe { wlr_seat_pointer_clear_focus(self.seat) }
    }

    /// Start a grab of the keyboard of this seat. The grabber is responsible for
    /// handling all keyboard events until the grab ends.
    pub fn keyboard_start_grab(&mut self, grab: KeyboardGrab) {
        unsafe { wlr_seat_keyboard_start_grab(self.seat, grab.as_ptr()) }
    }

    /// End the grab of the keyboard of this seat. This reverts the grab back to the
    /// default grab for the keyboard.
    pub fn keyboard_end_grab(&mut self) {
        unsafe { wlr_seat_keyboard_end_grab(self.seat) }
    }

    /// Whether or not the keyboard has a grab other than the default grab
    pub fn keyboard_has_grab(&self) -> bool {
        unsafe { wlr_seat_keyboard_has_grab(self.seat) }
    }

    /// Clear the focused surface for the keyboard and leave all entered
    /// surfaces.
    pub fn keyboard_clear_focus(&mut self) {
        unsafe { wlr_seat_keyboard_clear_focus(self.seat) }
    }

    /// Start a grab of the touch device of this seat. The grabber is responsible for
    /// handling all touch events until the grab ends.
    pub fn touch_start_grab(&mut self, grab: TouchGrab) {
        unsafe { wlr_seat_touch_start_grab(self.seat, grab.as_ptr()) }
    }

    /// End the grab of the touch device of this seat. This reverts the grab back to
    /// the default grab for the touch device.
    pub fn touch_end_grab(&mut self) {
        unsafe { wlr_seat_touch_end_grab(self.seat) }
    }

    /// Whether or not the seat has a touch grab other than the default grab.
    pub fn touch_has_grab(&self) -> bool {
        unsafe { wlr_seat_touch_has_grab(self.seat) }
    }

    // TODO notify and some other specific input misc functions

    pub unsafe fn to_ptr(&self) -> *mut wlr_seat {
        self.seat
    }
}

impl Drop for Seat {
    fn drop(&mut self) {
        unsafe { wlr_seat_destroy(self.seat) }
    }
}
<commit_msg>Added Seat::keyboard_enter<commit_after>//! Wrapper for wlr_seat. For more information about what a seat is, please
//! consult the Wayland documentation ([libinput docs](https://wayland.freedesktop.org/libinput/doc/latest/seats.html), [wayland docs](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_seat))

use std::time::Duration;

use wlroots_sys::{wlr_axis_orientation, wlr_seat, wlr_seat_client, wlr_seat_create,
                  wlr_seat_destroy, wlr_seat_keyboard_clear_focus, wlr_seat_keyboard_end_grab,
                  wlr_seat_keyboard_enter, wlr_seat_keyboard_has_grab,
                  wlr_seat_keyboard_notify_enter, wlr_seat_keyboard_notify_key,
                  wlr_seat_keyboard_notify_modifiers, wlr_seat_keyboard_send_key,
                  wlr_seat_keyboard_send_modifiers, wlr_seat_keyboard_start_grab,
                  wlr_seat_pointer_clear_focus, wlr_seat_pointer_end_grab, wlr_seat_pointer_enter,
                  wlr_seat_pointer_has_grab, wlr_seat_pointer_notify_axis,
                  wlr_seat_pointer_notify_button, wlr_seat_pointer_notify_enter,
                  wlr_seat_pointer_notify_motion, wlr_seat_pointer_send_axis,
                  wlr_seat_pointer_send_button, wlr_seat_pointer_send_motion,
                  wlr_seat_pointer_start_grab, wlr_seat_pointer_surface_has_focus,
                  wlr_seat_set_capabilities, wlr_seat_set_keyboard, wlr_seat_set_name,
                  wlr_seat_touch_end_grab, wlr_seat_touch_has_grab, wlr_seat_touch_notify_down,
                  wlr_seat_touch_notify_motion, wlr_seat_touch_notify_up,
                  wlr_seat_touch_num_points, wlr_seat_touch_point_clear_focus,
                  wlr_seat_touch_point_focus, wlr_seat_touch_send_down,
                  wlr_seat_touch_send_motion, wlr_seat_touch_send_up, wlr_seat_touch_start_grab,
                  wlr_touch_point};
use wlroots_sys::wayland_server::protocol::wl_seat::Capability;

use compositor::Compositor;
use utils::{c_to_rust_string, safe_as_cstring};

use super::grab::{KeyboardGrab, PointerGrab, TouchGrab};
use types::surface::Surface;

/// A wrapper around `wlr_seat`.
pub struct Seat {
    seat: *mut wlr_seat
}

impl Seat {
    /// Allocates a new `wlr_seat` and adds a wl_seat global to the display.
    pub fn create(compositor: &mut Compositor, name: String) -> Option<Self> {
        unsafe {
            let name = safe_as_cstring(name);
            let seat = wlr_seat_create(compositor.display() as _, name.as_ptr());
            if seat.is_null() {
                None
            } else {
                Some(Seat { seat })
            }
        }
    }

    /// Get the name of the seat.
    pub fn name(&self) -> Option<String> {
        unsafe {
            let name_ptr = (*self.seat).name;
            if name_ptr.is_null() {
                return None
            }
            c_to_rust_string(name_ptr)
        }
    }

    /// Updates the name of this seat.
    /// Will automatically send it to all clients.
    pub fn set_name(&mut self, name: String) {
        let name = safe_as_cstring(name);
        unsafe {
            wlr_seat_set_name(self.seat, name.as_ptr());
        }
    }

    /// Gets the capabilities of this seat.
    pub fn capabilities(&self) -> Capability {
        unsafe {
            Capability::from_raw((*self.seat).capabilities).expect("Invalid capabilities")
        }
    }

    /// Updates the capabilities available on this seat.
    /// Will automatically send it to all clients.
    pub fn set_capabilities(&mut self, capabilities: Capability) {
        unsafe { wlr_seat_set_capabilities(self.seat, capabilities.bits()) }
    }

    /// Determines if the surface has pointer focus.
    pub fn pointer_surface_has_focus(&mut self, surface: Surface) -> bool {
        unsafe { wlr_seat_pointer_surface_has_focus(self.seat, surface.as_ptr()) }
    }

    // Sends a pointer enter event to the given surface and considers it to be
    // the focused surface for the pointer.
    //
    // This will send a leave event to the last surface that was entered.
    //
    // Coordinates for the enter event are surface-local.
    //
    // Compositor should use `Seat::pointer_notify_enter` to
    // change pointer focus to respect pointer grabs.
    pub fn pointer_enter(&mut self, surface: Surface, sx: f64, sy: f64) {
        unsafe {
            wlr_seat_pointer_enter(self.seat, surface.as_ptr(), sx, sy);
        }
    }

    /// Clears the focused surface for the pointer and leaves all entered
    /// surfaces.
    pub fn clear_focus(&mut self) {
        unsafe { wlr_seat_pointer_clear_focus(self.seat) }
    }

    /// Sends a motion event to the surface with pointer focus.
    ///
    /// Coordinates for the motion event are surface-local.
    ///
    /// Compositors should use `Seat::notify_motion` to
    /// send motion events to the respect pointer grabs.
    pub fn send_motion(&mut self, time: Duration, sx: f64, sy: f64) {
        let seconds_delta = time.as_secs() as u32;
        let nano_delta = time.subsec_nanos();
        let ms = (seconds_delta * 1000) + nano_delta / 1000000;
        unsafe {
            // TODO FIXME what kind of time? ms? s?
            // I'm just guessing it's ms, there's no documentation on this.
            wlr_seat_pointer_send_motion(self.seat, ms, sx, sy)
        }
    }

    // TODO Button and State should probably be wrapped in some sort of type...

    /// Send a button event to the surface with pointer focus.
    ///
    /// Coordinates for the button event are surface-local.
    ///
    /// Returns the serial.
    ///
    /// Compositors should use `Seat::notify_button` to
    /// send button events to respect pointer grabs.
    pub fn send_button(&mut self, time: Duration, button: u32, state: u32) -> u32 {
        let seconds_delta = time.as_secs() as u32;
        let nano_delta = time.subsec_nanos();
        let ms = (seconds_delta * 1000) + nano_delta / 1000000;
        unsafe { wlr_seat_pointer_send_button(self.seat, ms, button, state) }
    }

    /// Send an axis event to the surface with pointer focus.
    ///
    /// Compositors should use `Seat::notify_axis` to
    /// send axis events to respect pointer grabs.
    pub fn send_axis(&mut self, time: Duration, orientation: wlr_axis_orientation, value: f64) {
        let seconds_delta = time.as_secs() as u32;
        let nano_delta = time.subsec_nanos();
        let ms = (seconds_delta * 1000) + nano_delta / 1000000;
        unsafe {
            wlr_seat_pointer_send_axis(self.seat, ms, orientation, value);
        }
    }

    /// Start a grab of the pointer of this seat. The grabber is responsible for
    /// handling all pointer events until the grab ends.
    pub fn pointer_start_grab(&mut self, grab: PointerGrab) {
        unsafe { wlr_seat_pointer_start_grab(self.seat, grab.as_ptr()) }
    }

    /// End the grab of the pointer of this seat. This reverts the grab back to the
    /// default grab for the pointer.
    pub fn pointer_end_grab(&mut self) {
        unsafe { wlr_seat_pointer_end_grab(self.seat) }
    }

    /// Whether or not the pointer has a grab other than the default grab.
    pub fn pointer_has_grab(&self) -> bool {
        unsafe { wlr_seat_pointer_has_grab(self.seat) }
    }

    /// Clear the focused surface for the pointer and leave all entered
    /// surfaces.
    pub fn pointer_clear_focus(&mut self) {
        unsafe { wlr_seat_pointer_clear_focus(self.seat) }
    }

    /// Send a keyboard enter event to the given surface and consider it to be the
    /// focused surface for the keyboard.
    ///
    /// This will send a leave event to the last surface that was entered.
    ///
    /// Compositors should use `Seat::keyboard_notify_enter()` to
    /// change keyboard focus to respect keyboard grabs.
    pub fn keyboard_enter(&mut self, surface: Surface) {
        unsafe { wlr_seat_keyboard_enter(self.seat, surface.as_ptr()) }
    }

    /// Start a grab of the keyboard of this seat. The grabber is responsible for
    /// handling all keyboard events until the grab ends.
    pub fn keyboard_start_grab(&mut self, grab: KeyboardGrab) {
        unsafe { wlr_seat_keyboard_start_grab(self.seat, grab.as_ptr()) }
    }

    /// End the grab of the keyboard of this seat. This reverts the grab back to the
    /// default grab for the keyboard.
    pub fn keyboard_end_grab(&mut self) {
        unsafe { wlr_seat_keyboard_end_grab(self.seat) }
    }

    /// Whether or not the keyboard has a grab other than the default grab
    pub fn keyboard_has_grab(&self) -> bool {
        unsafe { wlr_seat_keyboard_has_grab(self.seat) }
    }

    /// Clear the focused surface for the keyboard and leave all entered
    /// surfaces.
    pub fn keyboard_clear_focus(&mut self) {
        unsafe { wlr_seat_keyboard_clear_focus(self.seat) }
    }

    /// Start a grab of the touch device of this seat. The grabber is responsible for
    /// handling all touch events until the grab ends.
    pub fn touch_start_grab(&mut self, grab: TouchGrab) {
        unsafe { wlr_seat_touch_start_grab(self.seat, grab.as_ptr()) }
    }

    /// End the grab of the touch device of this seat. This reverts the grab back to
    /// the default grab for the touch device.
    pub fn touch_end_grab(&mut self) {
        unsafe { wlr_seat_touch_end_grab(self.seat) }
    }

    /// Whether or not the seat has a touch grab other than the default grab.
    pub fn touch_has_grab(&self) -> bool {
        unsafe { wlr_seat_touch_has_grab(self.seat) }
    }

    // TODO notify and some other specific input misc functions

    pub unsafe fn to_ptr(&self) -> *mut wlr_seat {
        self.seat
    }
}

impl Drop for Seat {
    fn drop(&mut self) {
        unsafe { wlr_seat_destroy(self.seat) }
    }
}
<|endoftext|>