<commit_before>use std::default::Default;
use graphics::{ self, DrawState, ImageSize, Graphics };
use glium::{
    Surface, Texture2d, Texture, Program, VertexBuffer,
    DrawParameters, BlendingFunction, LinearBlendingFactor
};
use glium::index::{ NoIndices, PrimitiveType };
use glium::backend::Facade;
use shader_version::{ Shaders, OpenGL };
use shader_version::glsl::GLSL;

/// Wrapper for 2D texture.
pub struct DrawTexture {
    /// The Glium texture.
    pub texture: Texture2d,
}

impl DrawTexture {
    /// Creates a new `DrawTexture`.
    pub fn new(texture: Texture2d) -> DrawTexture {
        DrawTexture { texture: texture }
    }
}

impl ImageSize for DrawTexture {
    fn get_size(&self) -> (u32, u32) {
        let ref tex = self.texture;
        (tex.get_width(), tex.get_height().unwrap())
    }
}

#[derive(Copy, Clone)]
struct PlainVertex {
    pos: [f32; 2],
}

implement_vertex!(PlainVertex, pos);

#[derive(Copy, Clone)]
struct TexturedVertex {
    pos: [f32; 2],
    uv: [f32; 2],
}

implement_vertex!(TexturedVertex, pos, uv);

/// The resources needed for rendering 2D.
pub struct Glium2d {
    plain_buffer: VertexBuffer<PlainVertex>,
    textured_buffer: VertexBuffer<TexturedVertex>,
    shader_texture: Program,
    shader_color: Program,
}

impl Glium2d {
    /// Creates a new `Glium2d`.
    pub fn new<W>(opengl: OpenGL, window: &W) -> Glium2d where W: Facade {
        use shaders::{ colored, textured };

        let src = |bytes| { unsafe { ::std::str::from_utf8_unchecked(bytes) } };

        // FIXME: create empty buffers when glium supports them
        let plain_data = ::std::iter::repeat(PlainVertex { pos: [0.0, 0.0] })
                                .take(graphics::BACK_END_MAX_VERTEX_COUNT).collect::<Vec<_>>();
        let textured_data = ::std::iter::repeat(TexturedVertex { pos: [0.0, 0.0], uv: [0.0, 0.0] })
                                .take(graphics::BACK_END_MAX_VERTEX_COUNT).collect::<Vec<_>>();
        let glsl = opengl.to_GLSL();
        Glium2d {
            plain_buffer: VertexBuffer::dynamic(window, plain_data),
            textured_buffer: VertexBuffer::dynamic(window, textured_data),
            shader_texture:
                Program::from_source(window,
                                     Shaders::new().set(GLSL::_1_20, src(textured::VERTEX_GLSL_120))
                                                   .set(GLSL::_1_50, src(textured::VERTEX_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     Shaders::new().set(GLSL::_1_20, src(textured::FRAGMENT_GLSL_120))
                                                   .set(GLSL::_1_50, src(textured::FRAGMENT_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     None).ok().expect("failed to initialize textured shader"),
            shader_color:
                Program::from_source(window,
                                     Shaders::new().set(GLSL::_1_20, src(colored::VERTEX_GLSL_120))
                                                   .set(GLSL::_1_50, src(colored::VERTEX_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     Shaders::new().set(GLSL::_1_20, src(colored::FRAGMENT_GLSL_120))
                                                   .set(GLSL::_1_50, src(colored::FRAGMENT_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     None).ok().expect("failed to initialize colored shader"),
        }
    }
}

/// Graphics back-end.
pub struct GliumGraphics<'d, 's, S: 's> {
    system: &'d mut Glium2d,
    surface: &'s mut S,
}

impl<'d, 's, S> GliumGraphics<'d, 's, S> {
    /// Creates a new graphics object.
    pub fn new(system: &'d mut Glium2d, surface: &'s mut S)
               -> GliumGraphics<'d, 's, S> {
        GliumGraphics {
            system: system,
            surface: surface,
        }
    }
}

/// Implemented by all graphics back-ends.
impl<'d, 's, S: Surface> Graphics for GliumGraphics<'d, 's, S> {
    type Texture = DrawTexture;

    /// Clears background with a color.
    fn clear_color(&mut self, color: [f32; 4]) {
        let (r, g, b, a) = (color[0], color[1], color[2], color[3]);
        self.surface.clear_color(r, g, b, a);
    }

    fn clear_stencil(&mut self, value: u8) {
        self.surface.clear_stencil(value as i32);
    }

    /// Renders list of 2d triangles.
    fn tri_list<F>(
        &mut self,
        _draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        f(&mut |vertices: &[f32]| {
            let slice = self.system.plain_buffer.slice(0..vertices.len() / 2).unwrap();

            slice.write({
                (0 .. vertices.len() / 2)
                    .map(|i| PlainVertex {
                        pos: [vertices[2 * i], vertices[2 * i + 1]]
                    })
                    .collect::<Vec<_>>()
            });

            self.surface.draw(
                slice,
                &NoIndices(PrimitiveType::TrianglesList),
                &self.system.shader_color,
                &uniform! { color: *color },
                &DrawParameters {
                    blending_function: Some(BlendingFunction::Addition {
                        source: LinearBlendingFactor::SourceAlpha,
                        destination: LinearBlendingFactor::OneMinusSourceAlpha,
                    }),
                    .. Default::default()
                },
            )
            .ok()
            .expect("failed to draw triangle list");
        })
    }

    /// Renders list of 2d triangles.
    ///
    /// A texture coordinate is assigned per vertex.
    /// The texture coordinates refers to the current texture.
    fn tri_list_uv<F>(
        &mut self,
        _draw_state: &DrawState,
        color: &[f32; 4],
        texture: &DrawTexture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        use std::cmp::min;

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            let len = min(vertices.len(), texture_coords.len()) / 2;

            let slice = self.system.textured_buffer.slice(0..len).unwrap();

            slice.write({
                (0 .. len)
                    .map(|i| TexturedVertex {
                        pos: [vertices[2 * i], vertices[2 * i + 1]],
                        // FIXME: The `1.0 - ...` is because of a wrong convention
                        uv: [texture_coords[2 * i], 1.0 - texture_coords[2 * i + 1]]
                    })
                    .collect::<Vec<_>>()
            });

            let texture = &texture.texture;
            self.surface.draw(
                slice,
                &NoIndices(PrimitiveType::TrianglesList),
                &self.system.shader_texture,
                &uniform! {
                    color: *color,
                    s_texture: texture
                },
                &DrawParameters {
                    blending_function: Some(BlendingFunction::Addition {
                        source: LinearBlendingFactor::SourceAlpha,
                        destination: LinearBlendingFactor::OneMinusSourceAlpha,
                    }),
                    .. Default::default()
                },
            )
            .ok()
            .expect("failed to draw triangle list");
        })
    }
}
<commit_msg>Create empty buffers instead of generating dummy data<commit_after>use std::default::Default;
use graphics::{ self, DrawState, ImageSize, Graphics };
use glium::{
    Surface, Texture2d, Texture, Program, VertexBuffer,
    DrawParameters, BlendingFunction, LinearBlendingFactor
};
use glium::index::{ NoIndices, PrimitiveType };
use glium::backend::Facade;
use shader_version::{ Shaders, OpenGL };
use shader_version::glsl::GLSL;

/// Wrapper for 2D texture.
pub struct DrawTexture {
    /// The Glium texture.
    pub texture: Texture2d,
}

impl DrawTexture {
    /// Creates a new `DrawTexture`.
    pub fn new(texture: Texture2d) -> DrawTexture {
        DrawTexture { texture: texture }
    }
}

impl ImageSize for DrawTexture {
    fn get_size(&self) -> (u32, u32) {
        let ref tex = self.texture;
        (tex.get_width(), tex.get_height().unwrap())
    }
}

#[derive(Copy, Clone)]
struct PlainVertex {
    pos: [f32; 2],
}

implement_vertex!(PlainVertex, pos);

#[derive(Copy, Clone)]
struct TexturedVertex {
    pos: [f32; 2],
    uv: [f32; 2],
}

implement_vertex!(TexturedVertex, pos, uv);

/// The resources needed for rendering 2D.
pub struct Glium2d {
    plain_buffer: VertexBuffer<PlainVertex>,
    textured_buffer: VertexBuffer<TexturedVertex>,
    shader_texture: Program,
    shader_color: Program,
}

impl Glium2d {
    /// Creates a new `Glium2d`.
    pub fn new<W>(opengl: OpenGL, window: &W) -> Glium2d where W: Facade {
        use shaders::{ colored, textured };

        let src = |bytes| { unsafe { ::std::str::from_utf8_unchecked(bytes) } };
        let glsl = opengl.to_GLSL();

        Glium2d {
            plain_buffer: VertexBuffer::empty_dynamic(window, graphics::BACK_END_MAX_VERTEX_COUNT),
            textured_buffer: VertexBuffer::empty_dynamic(window, graphics::BACK_END_MAX_VERTEX_COUNT),
            shader_texture:
                Program::from_source(window,
                                     Shaders::new().set(GLSL::_1_20, src(textured::VERTEX_GLSL_120))
                                                   .set(GLSL::_1_50, src(textured::VERTEX_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     Shaders::new().set(GLSL::_1_20, src(textured::FRAGMENT_GLSL_120))
                                                   .set(GLSL::_1_50, src(textured::FRAGMENT_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     None).ok().expect("failed to initialize textured shader"),
            shader_color:
                Program::from_source(window,
                                     Shaders::new().set(GLSL::_1_20, src(colored::VERTEX_GLSL_120))
                                                   .set(GLSL::_1_50, src(colored::VERTEX_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     Shaders::new().set(GLSL::_1_20, src(colored::FRAGMENT_GLSL_120))
                                                   .set(GLSL::_1_50, src(colored::FRAGMENT_GLSL_150_CORE))
                                                   .get(glsl).unwrap(),
                                     None).ok().expect("failed to initialize colored shader"),
        }
    }
}

/// Graphics back-end.
pub struct GliumGraphics<'d, 's, S: 's> {
    system: &'d mut Glium2d,
    surface: &'s mut S,
}

impl<'d, 's, S> GliumGraphics<'d, 's, S> {
    /// Creates a new graphics object.
    pub fn new(system: &'d mut Glium2d, surface: &'s mut S)
               -> GliumGraphics<'d, 's, S> {
        GliumGraphics {
            system: system,
            surface: surface,
        }
    }
}

/// Implemented by all graphics back-ends.
impl<'d, 's, S: Surface> Graphics for GliumGraphics<'d, 's, S> {
    type Texture = DrawTexture;

    /// Clears background with a color.
    fn clear_color(&mut self, color: [f32; 4]) {
        let (r, g, b, a) = (color[0], color[1], color[2], color[3]);
        self.surface.clear_color(r, g, b, a);
    }

    fn clear_stencil(&mut self, value: u8) {
        self.surface.clear_stencil(value as i32);
    }

    /// Renders list of 2d triangles.
    fn tri_list<F>(
        &mut self,
        _draw_state: &DrawState,
        color: &[f32; 4],
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32]))
    {
        f(&mut |vertices: &[f32]| {
            let slice = self.system.plain_buffer.slice(0..vertices.len() / 2).unwrap();

            slice.write({
                (0 .. vertices.len() / 2)
                    .map(|i| PlainVertex {
                        pos: [vertices[2 * i], vertices[2 * i + 1]]
                    })
                    .collect::<Vec<_>>()
            });

            self.surface.draw(
                slice,
                &NoIndices(PrimitiveType::TrianglesList),
                &self.system.shader_color,
                &uniform! { color: *color },
                &DrawParameters {
                    blending_function: Some(BlendingFunction::Addition {
                        source: LinearBlendingFactor::SourceAlpha,
                        destination: LinearBlendingFactor::OneMinusSourceAlpha,
                    }),
                    .. Default::default()
                },
            )
            .ok()
            .expect("failed to draw triangle list");
        })
    }

    /// Renders list of 2d triangles.
    ///
    /// A texture coordinate is assigned per vertex.
    /// The texture coordinates refers to the current texture.
    fn tri_list_uv<F>(
        &mut self,
        _draw_state: &DrawState,
        color: &[f32; 4],
        texture: &DrawTexture,
        mut f: F
    )
        where F: FnMut(&mut FnMut(&[f32], &[f32]))
    {
        use std::cmp::min;

        f(&mut |vertices: &[f32], texture_coords: &[f32]| {
            let len = min(vertices.len(), texture_coords.len()) / 2;

            let slice = self.system.textured_buffer.slice(0..len).unwrap();

            slice.write({
                (0 .. len)
                    .map(|i| TexturedVertex {
                        pos: [vertices[2 * i], vertices[2 * i + 1]],
                        // FIXME: The `1.0 - ...` is because of a wrong convention
                        uv: [texture_coords[2 * i], 1.0 - texture_coords[2 * i + 1]]
                    })
                    .collect::<Vec<_>>()
            });

            let texture = &texture.texture;
            self.surface.draw(
                slice,
                &NoIndices(PrimitiveType::TrianglesList),
                &self.system.shader_texture,
                &uniform! {
                    color: *color,
                    s_texture: texture
                },
                &DrawParameters {
                    blending_function: Some(BlendingFunction::Addition {
                        source: LinearBlendingFactor::SourceAlpha,
                        destination: LinearBlendingFactor::OneMinusSourceAlpha,
                    }),
                    .. Default::default()
                },
            )
            .ok()
            .expect("failed to draw triangle list");
        })
    }
}
<|endoftext|>


<commit_before>use yaml_rust::yaml::Hash;
use yaml_rust::{Yaml, YamlLoader};

static EN: &str = include_str!("../../lang/document/en.yaml");
static ES: &str = include_str!("../../lang/document/es.yaml");
static FR: &str = include_str!("../../lang/document/fr.yaml");

/// Get the hashmap for a given language
pub fn get_hash(lang: &str) -> Hash {
    let lang = lang.to_lowercase();
    let docs = if lang.starts_with("fr") {
        YamlLoader::load_from_str(FR).unwrap()
    } else if lang.starts_with("es") {
        YamlLoader::load_from_str(ES).unwrap()
    } else {
        YamlLoader::load_from_str(EN).unwrap()
    };
    let elem = docs.into_iter().next().unwrap();
    if let Yaml::Hash(hash) = elem {
        hash
    } else {
        panic!(
            "{}",
            lformat!(
                "Yaml file for language {lang} didn't contain a hash",
                lang = lang
            )
        );
    }
}

/// Get a string for a given language
pub fn get_str(lang: &str, s: &str) -> String {
    let hash = get_hash(lang);
    let yaml = hash.get(&Yaml::String(s.to_owned())).expect(&lformat!(
        "Could not find translation for {key} in language {lang}",
        key = s,
        lang = lang
    ));
    if let &Yaml::String(ref result) = yaml {
        result.clone()
    } else {
        panic!(
            "{}",
            lformat!(
                "Yaml for {key} in lang {lang} is not a String!",
                key = s,
                lang = lang
            )
        );
    }
}
<commit_msg>Add Deutsche and Russian languages<commit_after>use yaml_rust::yaml::Hash;
use yaml_rust::{Yaml, YamlLoader};

static EN: &str = include_str!("../../lang/document/en.yaml");
static ES: &str = include_str!("../../lang/document/es.yaml");
static FR: &str = include_str!("../../lang/document/fr.yaml");
static RU: &str = include_str!("../../lang/document/ru.yaml");
static DE: &str = include_str!("../../lang/document/de.yaml");

/// Get the hashmap for a given language
pub fn get_hash(lang: &str) -> Hash {
    let lang = lang.to_lowercase();
    let docs = if lang.starts_with("fr") {
        YamlLoader::load_from_str(FR).unwrap()
    } else if lang.starts_with("es") {
        YamlLoader::load_from_str(ES).unwrap()
    } else if lang.starts_with("de") {
        YamlLoader::load_from_str(DE).unwrap()
    } else if lang.starts_with("ru") {
        YamlLoader::load_from_str(RU).unwrap()
    } else {
        YamlLoader::load_from_str(EN).unwrap()
    };
    let elem = docs.into_iter().next().unwrap();
    if let Yaml::Hash(hash) = elem {
        hash
    } else {
        panic!(
            "{}",
            lformat!(
                "Yaml file for language {lang} didn't contain a hash",
                lang = lang
            )
        );
    }
}

/// Get a string for a given language
pub fn get_str(lang: &str, s: &str) -> String {
    let hash = get_hash(lang);
    let yaml = hash.get(&Yaml::String(s.to_owned())).expect(&lformat!(
        "Could not find translation for {key} in language {lang}",
        key = s,
        lang = lang
    ));
    if let &Yaml::String(ref result) = yaml {
        result.clone()
    } else {
        panic!(
            "{}",
            lformat!(
                "Yaml for {key} in lang {lang} is not a String!",
                key = s,
                lang = lang
            )
        );
    }
}
<|endoftext|>


<commit_before>#![allow(unstable)]

extern crate x11;
extern crate libc;

use std::ptr;
use std::ffi;
use std::mem;
use std::str;
use std::boxed::Box;

use x11::xlib;
use x11::xlib::{ Display, Window };
use libc::{ c_int, c_long, c_ulong, c_void };

pub fn open_display(name: Option<&str>) -> Option<*mut Display> {
    unsafe{
        let display = match name {
            Some(n) => {
                let s = ffi::CString::new(n).unwrap();
                xlib::XOpenDisplay(s.as_ptr())
            }
            None => { xlib::XOpenDisplay(ptr::null()) }
        };

        if display == ptr::null_mut() {
            None
        }
        else{
            // let b = Some(Box::<Display>::new(*display));
            // xlib::XFree(display as *mut libc::c_void);
            // b
            Some(display)
        }
    }
}

pub fn close_display(display: *mut Display) {
    unsafe{
        xlib::XCloseDisplay(display);
    }
}

pub fn default_screen(display: *mut Display) -> c_int {
    unsafe{
        xlib::XDefaultScreen(display)
    }
}

pub fn root_window(display: *mut Display, screen_num: c_int) -> c_ulong {
    unsafe {
        xlib::XRootWindow(display, screen_num)
    }
}

pub fn next_event(display: *mut Display) -> xlib::XEvent {
    unsafe{
        let mut e: xlib::XEvent = mem::zeroed();
        xlib::XNextEvent(display, &mut e);
        e
    }
}

pub fn get_atom_name(display: *mut Display, atom: xlib::Atom) -> Option<String> {
    unsafe{
        let name = xlib::XGetAtomName(display, atom);
        if name == ptr::null_mut() {
            return None
        }
        let s = ffi::CStr::from_ptr(name);
        let s = s.to_bytes();
        match str::from_utf8(s) {
            Ok(v) => {
                let tmp = Some(v.to_string());
                xlib::XFree(name as *mut libc::c_void);
                tmp
            }
            _ => None
        }
    }
}

pub fn get_atom(display: *mut Display, name: &str) -> xlib::Atom{
    unsafe{
        let cstr = ffi::CString::new(name).unwrap();
        let atom = xlib::XInternAtom(display, cstr.as_ptr(), xlib::False);
        atom
    }
}

pub fn get_text_property(display: *mut Display, window: xlib::Window, atom: xlib::Atom) -> Option<String>{
    unsafe{
        let mut prop: xlib::XTextProperty = mem::zeroed();
        let r = xlib::XGetTextProperty(display, window, &mut prop, atom);
        if r == 0 || prop.nitems == 0{
            None
        }else{
            let s = String::from_raw_parts(prop.value, prop.nitems as usize, prop.nitems as usize).clone();
            let text = Some(s);
            xlib::XFree(prop.value as *mut libc::c_void);
            text
        }
    }
}

pub fn get_wm_protocols(display: *mut Display, window: Window) -> Vec<xlib::Atom>{
    unsafe{
        let mut atoms: *mut xlib::Atom = ptr::null_mut();
        let mut count = 0;
        let s = xlib::XGetWMProtocols(display, window, &mut atoms, &mut count);
        let mut vec: Vec<xlib::Atom> = Vec::new();
        if s > 0 {
            println!("protocols {}", count);
            for i in 0..count {
                vec = Vec::from_raw_parts(atoms, count as usize, count as usize).clone();
            }
            // xlib::XFree(atoms as *mut c_void);
        }
        vec
    }
}

pub fn get_window_attributes(display: *mut Display, window: Window) -> xlib::XWindowAttributes {
    unsafe{
        let mut attrs: xlib::XWindowAttributes = mem::zeroed();
        xlib::XGetWindowAttributes(display, window, &mut attrs);
        attrs
    }
}

pub fn get_transient_for_hint(display: *mut Display, window: Window) -> i32 {
    unsafe{
        let mut window_return: xlib::Window = 0;
        xlib::XGetTransientForHint(display, window, &mut window_return)
    }
}

pub fn change_window_attributes(display: *mut Display, window: Window, valuemask: c_ulong, attrs: *mut xlib::XSetWindowAttributes) {
    unsafe{
        xlib::XChangeWindowAttributes(display, window, valuemask, attrs);
    }

}
fn get_window_property(display: *mut xlib::Display, window: Window, atom: xlib::Atom) {
    unsafe {
        let mut actual_type_return: u64 = 0;
        let mut actual_format_return: i32 = 0;
        let mut nitem_return: libc::c_ulong = 0;
        let mut bytes_after_return: libc::c_ulong = 0;
        let mut prop_return: *mut libc::c_uchar = mem::zeroed();

        let r = xlib::XGetWindowProperty(display, window, xlib::XA_WM_NAME,
                                         0, 0xFFFFFFFF, 0, 0,
                                         &mut actual_type_return,
                                         &mut actual_format_return,
                                         &mut nitem_return,
                                         &mut bytes_after_return,
                                         &mut prop_return);

        debug!("result get wp {}", r);
        if r == 0 {

        }else{
            debug!("actual format return {}", actual_format_return);
            if actual_format_return == 0 {

            }
            else {
                // let s = from_raw_parts(prop_return as *const libc::c_ulong, nitems_return as usize).iter()
                //     .map(|&c| c as u64)
                //     .collect();
                let s = String::from_raw_parts(prop_return, nitem_return as usize, nitem_return as usize);
                println!("{}", s);

            }
        }
    }
}

pub fn set_input_focus(display: *mut Display, window: Window, revert_to: c_int, time: xlib::Time) {
    unsafe{
        xlib::XSetInputFocus(display, window, revert_to, time);
    }
}

pub fn get_input_focus(display: *mut Display) -> (Window, c_int){
    let mut window: xlib::Window = 0;
    let mut revert_to: libc::c_int = 0;
    unsafe{
        let s = xlib::XGetInputFocus(display, &mut window, &mut revert_to);
    }
    (window, revert_to)
}

pub fn unmap_window(display: *mut Display, window: Window) -> c_int{
    unsafe{
        xlib::XUnmapWindow(display, window)
    }

}

pub fn map_window(display: *mut Display, window: Window) -> c_int{
    unsafe{
        xlib::XMapWindow(display, window)
    }
}

pub fn send_event(display: *mut Display, window: Window,
                  propagate: c_int, event_mask: c_long,
                  mut event: xlib::XEvent) {
    unsafe{
        xlib::XSendEvent(display, window, propagate, event_mask, &mut event);
    }
}

pub fn string_to_keysym(s: &str) -> xlib::KeySym {
    let tmp = ffi::CString::new(s).unwrap();
    unsafe{
        xlib::XStringToKeysym(tmp.as_ptr())
    }

}

#[cfg(test)]
mod test{
use super::*;

#[test]
fn test_open(){
    let display = open_display(None);
    assert!(display.is_some());
}

}
<commit_msg>add wrappers<commit_after>#![allow(unstable)]

extern crate x11;
extern crate libc;

use std::ptr;
use std::ffi;
use std::mem;
use std::str;
use std::slice;
use std::boxed::Box;

use x11::xlib;
use x11::xlib::{ Display, Window };
use libc::{ c_int, c_long, c_uint, c_ulong, c_void };

pub fn open_display(name: Option<&str>) -> Option<*mut Display> {
    unsafe{
        let display = match name {
            Some(n) => {
                let s = ffi::CString::new(n).unwrap();
                xlib::XOpenDisplay(s.as_ptr())
            }
            None => { xlib::XOpenDisplay(ptr::null()) }
        };

        if display == ptr::null_mut() {
            None
        }
        else{
            // let b = Some(Box::<Display>::new(*display));
            // xlib::XFree(display as *mut libc::c_void);
            // b
            Some(display)
        }
    }
}

pub fn close_display(display: *mut Display) {
    unsafe{
        xlib::XCloseDisplay(display);
    }
}

pub fn default_screen(display: *mut Display) -> c_int {
    unsafe{
        xlib::XDefaultScreen(display)
    }
}

pub fn root_window(display: *mut Display, screen_num: c_int) -> c_ulong {
    unsafe {
        xlib::XRootWindow(display, screen_num)
    }
}

pub fn next_event(display: *mut Display) -> xlib::XEvent {
    unsafe{
        let mut e: xlib::XEvent = mem::zeroed();
        xlib::XNextEvent(display, &mut e);
        e
    }
}

pub fn get_atom_name(display: *mut Display, atom: xlib::Atom) -> Option<String> {
    unsafe{
        let name = xlib::XGetAtomName(display, atom);
        if name == ptr::null_mut() {
            return None
        }
        let s = ffi::CStr::from_ptr(name);
        let s = s.to_bytes();
        match str::from_utf8(s) {
            Ok(v) => {
                let tmp = Some(v.to_string());
                xlib::XFree(name as *mut libc::c_void);
                tmp
            }
            _ => None
        }
    }
}

pub fn get_atom(display: *mut Display, name: &str) -> xlib::Atom{
    unsafe{
        let cstr = ffi::CString::new(name).unwrap();
        let atom = xlib::XInternAtom(display, cstr.as_ptr(), xlib::False);
        atom
    }
}

pub fn get_text_property(display: *mut Display, window: xlib::Window, atom: xlib::Atom) -> Option<String>{
    unsafe{
        let mut prop: xlib::XTextProperty = mem::zeroed();
        let r = xlib::XGetTextProperty(display, window, &mut prop, atom);
        if r == 0 || prop.nitems == 0{
            None
        }else{

            // let s = String::from_raw_parts(prop.value, prop.nitems as usize, prop.nitems as usize).clone()
            let s = slice::from_raw_parts(prop.value, prop.nitems as usize).iter().map(|&c| c as u8).collect();
            match String::from_utf8(s) {
                Ok(v) => {
                    xlib::XFree(prop.value as *mut libc::c_void);
                    Some(v)
                }
                _ => None
            }
        }
    }
}

pub fn get_wm_protocols(display: *mut Display, window: Window) -> Vec<xlib::Atom>{
    unsafe{
        let mut atoms: *mut xlib::Atom = ptr::null_mut();
        let mut count = 0;
        let s = xlib::XGetWMProtocols(display, window, &mut atoms, &mut count);
        let mut vec: Vec<xlib::Atom> = Vec::new();
        if s > 0 {
            vec = slice::from_raw_parts(atoms, count as usize).iter()
                .map(|&a| a as xlib::Atom).collect();
            xlib::XFree(atoms as *mut c_void);
        }
        vec
    }
}

pub fn get_window_attributes(display: *mut Display, window: Window) -> xlib::XWindowAttributes {
    unsafe{
        let mut attrs: xlib::XWindowAttributes = mem::zeroed();
        xlib::XGetWindowAttributes(display, window, &mut attrs);
        attrs
    }
}

pub fn get_transient_for_hint(display: *mut Display, window: Window) -> i32 {
    unsafe{
        let mut window_return: xlib::Window = 0;
        xlib::XGetTransientForHint(display, window, &mut window_return)
    }
}

pub fn change_window_attributes(display: *mut Display, window: Window, valuemask: c_ulong, attrs: *mut xlib::XSetWindowAttributes) {
    unsafe{
        xlib::XChangeWindowAttributes(display, window, valuemask, attrs);
    }

}

fn get_window_property(display: *mut xlib::Display, window: Window, atom: xlib::Atom) {
    unsafe {
        let mut actual_type_return: u64 = 0;
        let mut actual_format_return: i32 = 0;
        let mut nitem_return: libc::c_ulong = 0;
        let mut bytes_after_return: libc::c_ulong = 0;
        let mut prop_return: *mut libc::c_uchar = mem::zeroed();

        let r = xlib::XGetWindowProperty(display, window, xlib::XA_WM_NAME,
                                         0, 0xFFFFFFFF, 0, 0,
                                         &mut actual_type_return,
                                         &mut actual_format_return,
                                         &mut nitem_return,
                                         &mut bytes_after_return,
                                         &mut prop_return);

        debug!("result get wp {}", r);
        if r == 0 {

        }else{
            debug!("actual format return {}", actual_format_return);
            if actual_format_return == 0 {

            }
            else {
                // let s = from_raw_parts(prop_return as *const libc::c_ulong, nitems_return as usize).iter()
                //     .map(|&c| c as u64)
                //     .collect();
                let s = String::from_raw_parts(prop_return, nitem_return as usize, nitem_return as usize);
                println!("{}", s);

            }
        }
    }
}

pub fn set_input_focus(display: *mut Display, window: Window) {
    let none = 0;
    let pointer_root = 1;
    let parent = 2;
    unsafe{
        xlib::XSetInputFocus(display, window, pointer_root, 0);
    }
}

pub fn get_input_focus(display: *mut Display) -> (Window, c_int){
    let mut window: xlib::Window = 0;
    let mut revert_to: libc::c_int = 0;
    unsafe{
        let s = xlib::XGetInputFocus(display, &mut window, &mut revert_to);
    }
    (window, revert_to)
}

pub fn unmap_window(display: *mut Display, window: Window) -> c_int{
    unsafe{
        xlib::XUnmapWindow(display, window)
    }

}

pub fn configure_window(display: *mut Display, window: Window, mask:c_uint, mut change: xlib::XWindowChanges) {
    unsafe{
        xlib::XConfigureWindow(display, window, mask, &mut change);
    }
}
pub fn map_window(display: *mut Display, window: Window) -> c_int{
    unsafe{
        xlib::XMapWindow(display, window)
    }
}

pub fn kill_window(display: *mut Display, window: Window) {
    let mut event: xlib::XClientMessageEvent = unsafe {
        mem::zeroed()
    };

    let wm_delete_window = get_atom(display, "WM_DELETE_WINDOW");
    let wm_protocols = get_atom(display, "WM_PROTOCOLS");
    let protocols = get_wm_protocols(display, window);

    if protocols.iter().any(|&p| p == wm_delete_window){
        event.type_ = xlib::ClientMessage;
        event.message_type = wm_protocols;
        event.format = 32;
        event.window = window;
        event.send_event = xlib::True;
        event.display = display;
        event.data.set_long(0, wm_delete_window as libc::c_long);

        let mut e: xlib::XEvent = From::from(event);
        send_event(display, window, xlib::True, xlib::NoEventMask, e);
    }
    else{
        unsafe{
            xlib::XKillClient(display, window);
        }
    }

}

pub fn send_event(display: *mut Display, window: Window,
                  propagate: c_int, event_mask: c_long,
                  mut event: xlib::XEvent) {
    unsafe{
        xlib::XSendEvent(display, window, propagate, event_mask, &mut event);
    }
}

pub fn string_to_keysym(s: &str) -> xlib::KeySym {
    let tmp = ffi::CString::new(s).unwrap();
    unsafe{
        xlib::XStringToKeysym(tmp.as_ptr())
    }

}

#[cfg(test)]
mod test{
use super::*;

#[test]
fn test_open(){
    let display = open_display(None);
    assert!(display.is_some());
}

}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Some crumminess to make sure we link correctly

#[cfg(target_os = "linux")]
#[link(name = "azure", kind = "static")]
#[link(name = "stdc++")]
#[link(name = "skia", kind = "static")]
// skia must come before freetype for linking to succeed
#[link(name = "freetype")]
// fontconfig must come before expat for linking to succeed
#[link(name = "fontconfig")]
#[link(name = "expat")]
#[link(name = "X11")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "azure", kind = "static")]
#[link(name = "stdc++")]
#[link(name = "skia", kind = "static")]
#[link(name = "expat")]
#[link(name = "fontconfig")]
#[link(name = "EGL")]
extern { }

#[cfg(target_os = "macos")]
#[link(name = "azure", kind = "static")]
#[link(name = "stdc++")]
#[link(name = "skia", kind = "static")]
#[link(name = "objc")]
#[link(name = "IOSurface", kind = "framework")]
#[link(name = "OpenGL", kind = "framework")]
#[link(name = "Foundation", kind = "framework")]
#[link(name = "QuartzCore", kind = "framework")]
#[link(name = "ApplicationServices", kind = "framework")]
extern { }
<commit_msg>Use freetype-sys on Linux.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Some crumminess to make sure we link correctly

#[cfg(target_os = "linux")]
#[link(name = "azure", kind = "static")]
#[link(name = "stdc++")]
#[link(name = "skia", kind = "static")]
// skia must come before freetype for linking to succeed
#[link(name = "freetype")]
#[link(name = "bz2")]
// fontconfig must come before expat for linking to succeed
#[link(name = "fontconfig")]
#[link(name = "expat")]
#[link(name = "X11")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "azure", kind = "static")]
#[link(name = "stdc++")]
#[link(name = "skia", kind = "static")]
#[link(name = "expat")]
#[link(name = "fontconfig")]
#[link(name = "EGL")]
extern { }

#[cfg(target_os = "macos")]
#[link(name = "azure", kind = "static")]
#[link(name = "stdc++")]
#[link(name = "skia", kind = "static")]
#[link(name = "objc")]
#[link(name = "IOSurface", kind = "framework")]
#[link(name = "OpenGL", kind = "framework")]
#[link(name = "Foundation", kind = "framework")]
#[link(name = "QuartzCore", kind = "framework")]
#[link(name = "ApplicationServices", kind = "framework")]
extern { }
<|endoftext|>


<commit_before>//! A `SpriteBatch` is a way to efficiently draw a large
//! number of copies of the same image, or part of the same image.  It's
//! useful for implementing tiled maps, spritesheets, particles, and
//! other such things.
//!
//! Essentially this uses a technique called "instancing" to queue up
//! a large amount of location/position data in a buffer, then feed it
//! to the graphics card all in one go.

use context::Context;
use graphics;
use error;
use gfx;
use gfx::Factory;
use GameResult;
use super::shader::BlendMode;

/// A `SpriteBatch` draws a number of copies of the same image, using a single draw call.
///
/// This is generally faster than drawing the same sprite with many invocations of `draw()`,
/// though it has a bit of overhead to set up the batch.  This makes it run very slowly
/// in Debug mode because it spends a lot of time on array bounds checking and
/// un-optimized math; you need to build with optimizations enabled to really get the
/// speed boost.
#[derive(Debug, Clone)]
pub struct SpriteBatch {
    image: graphics::Image,
    sprites: Vec<graphics::DrawParam>,
    blend_mode: Option<BlendMode>,
}

/// A drawable combination of a `SpriteBatch` and a specific `Image`.
/// It is not always convenient for a `SpriteBatch` to own the image
/// it is drawing, so this structure lets you override the image with
/// a borrowed one.
///
/// This is now deprecated; an `Image` is cheap to clone and
/// this was never terribly useful to begin with.
#[deprecated]
#[derive(Debug)]
pub struct BoundSpriteBatch<'a> {
    image: &'a graphics::Image,
    batch: &'a mut SpriteBatch,
}

/// An index of a particular sprite in a `SpriteBatch`.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SpriteIdx(usize);

impl SpriteBatch {
    /// Creates a new `SpriteBatch`, drawing with the given image.
    pub fn new(image: graphics::Image) -> Self {
        Self {
            image,
            sprites: vec![],
            blend_mode: None,
        }
    }

    /// Adds a new sprite to the sprite batch.
    ///
    /// Returns a handle with whictypeh to modify the sprite using `set()`
    pub fn add(&mut self, param: graphics::DrawParam) -> SpriteIdx {
        self.sprites.push(param);
        SpriteIdx(self.sprites.len() - 1)
    }

    /// Alters a sprite in the batch to use the given draw params
    pub fn set(&mut self, handle: SpriteIdx, param: graphics::DrawParam) -> GameResult<()> {
        if handle.0 < self.sprites.len() {
            self.sprites[handle.0] = param;
            Ok(())
        } else {
            Err(error::GameError::RenderError(String::from(
                "Provided index is out of bounds.",
            )))
        }
    }

    /// Immediately sends all data in the batch to the graphics card.
    ///
    /// Generally just calling `graphics::draw()` on the `SpriteBatch`
    /// will do this automaticassertally.
    fn flush(
        &self,
        ctx: &mut Context,
        image: &graphics::Image,
        draw_color: Option<graphics::Color>,
    ) -> GameResult<()> {
        // This is a little awkward but this is the right place
        // to do whatever transformations need to happen to DrawParam's.
        // We have a Context, and *everything* must pass through this
        // function to be drawn, so.
        // Though we do awkwardly have to allocate a new vector.
        assert!(draw_color.is_some());
        let new_sprites = self.sprites
            .iter()
            .map(|param| {
                // Copy old params
                let mut new_param = *param;
                let src_width = param.src.w;
                let src_height = param.src.h;
                let real_scale = graphics::Point2::new(
                    src_width * param.scale.x * image.width as f32,
                    src_height * param.scale.y * image.height as f32,
                );
                new_param.scale = real_scale;
                // If we have no color, our color is white.
                // This is fine because coloring the whole spritebatch is possible
                // with graphics::set_color(); this just inherits from that.
                new_param.color = new_param.color.or(draw_color);
                graphics::InstanceProperties::from(new_param)
            })
            .collect::<Vec<_>>();

        let gfx = &mut ctx.gfx_context;
        if gfx.data.rect_instance_properties.len() < self.sprites.len() {
            gfx.data.rect_instance_properties = gfx.factory.create_buffer(
                self.sprites.len(),
                gfx::buffer::Role::Vertex,
                gfx::memory::Usage::Dynamic,
                gfx::memory::Bind::TRANSFER_DST,
            )?;
        }
        gfx.encoder
            .update_buffer(&gfx.data.rect_instance_properties, &new_sprites[..], 0)?;
        Ok(())
    }

    /// Removes all data from the sprite batch.
    pub fn clear(&mut self) {
        self.sprites.clear();
    }

    /// Unwraps the contained `Image`
    pub fn into_inner(self) -> graphics::Image {
        self.image
    }

    /// Replaces the contained `Image`, returning the old one.
    pub fn set_image(&mut self, image: graphics::Image) -> graphics::Image {
        use std::mem;
        mem::replace(&mut self.image, image)
    }

    /// Create an object which draws the current sprite batch with a different image.
    #[deprecated]
    #[allow(deprecated)]
    pub fn with_image<'a>(&'a mut self, image: &'a graphics::Image) -> BoundSpriteBatch<'a> {
        BoundSpriteBatch {
            image,
            batch: self,
        }
    }
}

#[deprecated]
#[allow(deprecated)]
impl<'a> graphics::Drawable for BoundSpriteBatch<'a> {
    fn draw_ex(&self, ctx: &mut Context, param: graphics::DrawParam) -> GameResult<()> {
        // Awkwardly we must update values on all sprites and such.
        // Also awkwardly we have this chain of colors with differing priorities.
        let fg = Some(ctx.gfx_context.foreground_color);
        let draw_color = param.color.or(fg);
        self.batch.flush(ctx, self.image, draw_color)?;
        let gfx = &mut ctx.gfx_context;
        let sampler = gfx.samplers
            .get_or_insert(self.image.sampler_info, gfx.factory.as_mut());
        gfx.data.vbuf = gfx.quad_vertex_buffer.clone();
        gfx.data.tex = (self.image.texture.clone(), sampler);
        let mut slice = gfx.quad_slice.clone();
        slice.instances = Some((self.batch.sprites.len() as u32, 0));
        let curr_transform = gfx.get_transform();
        gfx.push_transform(param.into_matrix() * curr_transform);
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        let previous_mode: Option<BlendMode> = if let Some(mode) = self.batch.blend_mode {
            let current_mode = gfx.get_blend_mode();
            if current_mode != mode {
                gfx.set_blend_mode(mode)?;
                Some(current_mode)
            } else {
                None
            }
        } else {
            None
        };
        gfx.draw(Some(&slice))?;
        if let Some(mode) = previous_mode {
            gfx.set_blend_mode(mode)?;
        }
        gfx.pop_transform();
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        Ok(())
    }

    fn set_blend_mode(&mut self, mode: Option<BlendMode>) {
        self.batch.blend_mode = mode;
    }

    fn get_blend_mode(&self) -> Option<BlendMode> {
        self.batch.blend_mode
    }
}

impl graphics::Drawable for SpriteBatch {
    fn draw_ex(&self, ctx: &mut Context, param: graphics::DrawParam) -> GameResult<()> {
        // Awkwardly we must update values on all sprites and such.
        // Also awkwardly we have this chain of colors with differing priorities.
        let fg = Some(ctx.gfx_context.foreground_color);
        let draw_color = param.color.or(fg);
        self.flush(ctx, &self.image, draw_color)?;
        let gfx = &mut ctx.gfx_context;
        let sampler = gfx.samplers
            .get_or_insert(self.image.sampler_info, gfx.factory.as_mut());
        gfx.data.vbuf = gfx.quad_vertex_buffer.clone();
        gfx.data.tex = (self.image.texture.clone(), sampler);
        let mut slice = gfx.quad_slice.clone();
        slice.instances = Some((self.sprites.len() as u32, 0));
        let curr_transform = gfx.get_transform();
        gfx.push_transform(param.into_matrix() * curr_transform);
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        let previous_mode: Option<BlendMode> = if let Some(mode) = self.blend_mode {
            let current_mode = gfx.get_blend_mode();
            if current_mode != mode {
                gfx.set_blend_mode(mode)?;
                Some(current_mode)
            } else {
                None
            }
        } else {
            None
        };
        gfx.draw(Some(&slice))?;
        if let Some(mode) = previous_mode {
            gfx.set_blend_mode(mode)?;
        }
        gfx.pop_transform();
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        Ok(())
    }
    fn set_blend_mode(&mut self, mode: Option<BlendMode>) {
        self.blend_mode = mode;
    }
    fn get_blend_mode(&self) -> Option<BlendMode> {
        self.blend_mode
    }
}
<commit_msg>Add set_filter() and get_filter() function for SpriteBatch<commit_after>//! A `SpriteBatch` is a way to efficiently draw a large
//! number of copies of the same image, or part of the same image.  It's
//! useful for implementing tiled maps, spritesheets, particles, and
//! other such things.
//!
//! Essentially this uses a technique called "instancing" to queue up
//! a large amount of location/position data in a buffer, then feed it
//! to the graphics card all in one go.

use context::Context;
use graphics;
use error;
use gfx;
use gfx::Factory;
use GameResult;
use super::shader::BlendMode;
use super::types::FilterMode;

/// A `SpriteBatch` draws a number of copies of the same image, using a single draw call.
///
/// This is generally faster than drawing the same sprite with many invocations of `draw()`,
/// though it has a bit of overhead to set up the batch.  This makes it run very slowly
/// in Debug mode because it spends a lot of time on array bounds checking and
/// un-optimized math; you need to build with optimizations enabled to really get the
/// speed boost.
#[derive(Debug, Clone)]
pub struct SpriteBatch {
    image: graphics::Image,
    sprites: Vec<graphics::DrawParam>,
    blend_mode: Option<BlendMode>,
}

/// A drawable combination of a `SpriteBatch` and a specific `Image`.
/// It is not always convenient for a `SpriteBatch` to own the image
/// it is drawing, so this structure lets you override the image with
/// a borrowed one.
///
/// This is now deprecated; an `Image` is cheap to clone and
/// this was never terribly useful to begin with.
#[deprecated]
#[derive(Debug)]
pub struct BoundSpriteBatch<'a> {
    image: &'a graphics::Image,
    batch: &'a mut SpriteBatch,
}

/// An index of a particular sprite in a `SpriteBatch`.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SpriteIdx(usize);

impl SpriteBatch {
    /// Creates a new `SpriteBatch`, drawing with the given image.
    pub fn new(image: graphics::Image) -> Self {
        Self {
            image,
            sprites: vec![],
            blend_mode: None,
        }
    }

    /// Adds a new sprite to the sprite batch.
    ///
    /// Returns a handle with whictypeh to modify the sprite using `set()`
    pub fn add(&mut self, param: graphics::DrawParam) -> SpriteIdx {
        self.sprites.push(param);
        SpriteIdx(self.sprites.len() - 1)
    }

    /// Alters a sprite in the batch to use the given draw params
    pub fn set(&mut self, handle: SpriteIdx, param: graphics::DrawParam) -> GameResult<()> {
        if handle.0 < self.sprites.len() {
            self.sprites[handle.0] = param;
            Ok(())
        } else {
            Err(error::GameError::RenderError(String::from(
                "Provided index is out of bounds.",
            )))
        }
    }

    /// Immediately sends all data in the batch to the graphics card.
    ///
    /// Generally just calling `graphics::draw()` on the `SpriteBatch`
    /// will do this automaticassertally.
    fn flush(
        &self,
        ctx: &mut Context,
        image: &graphics::Image,
        draw_color: Option<graphics::Color>,
    ) -> GameResult<()> {
        // This is a little awkward but this is the right place
        // to do whatever transformations need to happen to DrawParam's.
        // We have a Context, and *everything* must pass through this
        // function to be drawn, so.
        // Though we do awkwardly have to allocate a new vector.
        assert!(draw_color.is_some());
        let new_sprites = self.sprites
            .iter()
            .map(|param| {
                // Copy old params
                let mut new_param = *param;
                let src_width = param.src.w;
                let src_height = param.src.h;
                let real_scale = graphics::Point2::new(
                    src_width * param.scale.x * image.width as f32,
                    src_height * param.scale.y * image.height as f32,
                );
                new_param.scale = real_scale;
                // If we have no color, our color is white.
                // This is fine because coloring the whole spritebatch is possible
                // with graphics::set_color(); this just inherits from that.
                new_param.color = new_param.color.or(draw_color);
                graphics::InstanceProperties::from(new_param)
            })
            .collect::<Vec<_>>();

        let gfx = &mut ctx.gfx_context;
        if gfx.data.rect_instance_properties.len() < self.sprites.len() {
            gfx.data.rect_instance_properties = gfx.factory.create_buffer(
                self.sprites.len(),
                gfx::buffer::Role::Vertex,
                gfx::memory::Usage::Dynamic,
                gfx::memory::Bind::TRANSFER_DST,
            )?;
        }
        gfx.encoder
            .update_buffer(&gfx.data.rect_instance_properties, &new_sprites[..], 0)?;
        Ok(())
    }

    /// Removes all data from the sprite batch.
    pub fn clear(&mut self) {
        self.sprites.clear();
    }

    /// Unwraps the contained `Image`
    pub fn into_inner(self) -> graphics::Image {
        self.image
    }

    /// Replaces the contained `Image`, returning the old one.
    pub fn set_image(&mut self, image: graphics::Image) -> graphics::Image {
        use std::mem;
        mem::replace(&mut self.image, image)
    }

    /// Get the filter mode for the SpriteBatch.
    pub fn get_filter(&self) -> FilterMode {
        self.image.get_filter()
    }

    /// Set the filter mode for the SpriteBatch.
    pub fn set_filter(&mut self, mode: FilterMode) {
        self.image.set_filter(mode);
    }

    /// Create an object which draws the current sprite batch with a different image.
    #[deprecated]
    #[allow(deprecated)]
    pub fn with_image<'a>(&'a mut self, image: &'a graphics::Image) -> BoundSpriteBatch<'a> {
        BoundSpriteBatch {
            image,
            batch: self,
        }
    }
}

#[deprecated]
#[allow(deprecated)]
impl<'a> graphics::Drawable for BoundSpriteBatch<'a> {
    fn draw_ex(&self, ctx: &mut Context, param: graphics::DrawParam) -> GameResult<()> {
        // Awkwardly we must update values on all sprites and such.
        // Also awkwardly we have this chain of colors with differing priorities.
        let fg = Some(ctx.gfx_context.foreground_color);
        let draw_color = param.color.or(fg);
        self.batch.flush(ctx, self.image, draw_color)?;
        let gfx = &mut ctx.gfx_context;
        let sampler = gfx.samplers
            .get_or_insert(self.image.sampler_info, gfx.factory.as_mut());
        gfx.data.vbuf = gfx.quad_vertex_buffer.clone();
        gfx.data.tex = (self.image.texture.clone(), sampler);
        let mut slice = gfx.quad_slice.clone();
        slice.instances = Some((self.batch.sprites.len() as u32, 0));
        let curr_transform = gfx.get_transform();
        gfx.push_transform(param.into_matrix() * curr_transform);
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        let previous_mode: Option<BlendMode> = if let Some(mode) = self.batch.blend_mode {
            let current_mode = gfx.get_blend_mode();
            if current_mode != mode {
                gfx.set_blend_mode(mode)?;
                Some(current_mode)
            } else {
                None
            }
        } else {
            None
        };
        gfx.draw(Some(&slice))?;
        if let Some(mode) = previous_mode {
            gfx.set_blend_mode(mode)?;
        }
        gfx.pop_transform();
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        Ok(())
    }

    fn set_blend_mode(&mut self, mode: Option<BlendMode>) {
        self.batch.blend_mode = mode;
    }

    fn get_blend_mode(&self) -> Option<BlendMode> {
        self.batch.blend_mode
    }
}

impl graphics::Drawable for SpriteBatch {
    fn draw_ex(&self, ctx: &mut Context, param: graphics::DrawParam) -> GameResult<()> {
        // Awkwardly we must update values on all sprites and such.
        // Also awkwardly we have this chain of colors with differing priorities.
        let fg = Some(ctx.gfx_context.foreground_color);
        let draw_color = param.color.or(fg);
        self.flush(ctx, &self.image, draw_color)?;
        let gfx = &mut ctx.gfx_context;
        let sampler = gfx.samplers
            .get_or_insert(self.image.sampler_info, gfx.factory.as_mut());
        gfx.data.vbuf = gfx.quad_vertex_buffer.clone();
        gfx.data.tex = (self.image.texture.clone(), sampler);
        let mut slice = gfx.quad_slice.clone();
        slice.instances = Some((self.sprites.len() as u32, 0));
        let curr_transform = gfx.get_transform();
        gfx.push_transform(param.into_matrix() * curr_transform);
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        let previous_mode: Option<BlendMode> = if let Some(mode) = self.blend_mode {
            let current_mode = gfx.get_blend_mode();
            if current_mode != mode {
                gfx.set_blend_mode(mode)?;
                Some(current_mode)
            } else {
                None
            }
        } else {
            None
        };
        gfx.draw(Some(&slice))?;
        if let Some(mode) = previous_mode {
            gfx.set_blend_mode(mode)?;
        }
        gfx.pop_transform();
        gfx.calculate_transform_matrix();
        gfx.update_globals()?;
        Ok(())
    }
    fn set_blend_mode(&mut self, mode: Option<BlendMode>) {
        self.blend_mode = mode;
    }
    fn get_blend_mode(&self) -> Option<BlendMode> {
        self.blend_mode
    }
}
<|endoftext|>


<commit_before>extern crate mpv ;
extern crate sdl2;

use sdl2::Sdl;
use sdl2::event::Event as SdlEvent;
use sdl2_sys::video::SDL_WindowFlags;
use sdl2::video::FullscreenType;
use sdl2::keyboard::{Keycode, Scancode};
use displayer::Displayer;
use std::cmp::{min, max};

fn speed_btn(mpv: &mut mpv::MpvHandler, is_shift_pressed: bool, keynumber: u64) {
    let mut speed = (keynumber as f64) / 10.0;
    if (is_shift_pressed) {
        speed += 1.0;
    }
    mpv.set_property_async("speed", speed, 1).expect("Failed to modify player speed");
}

fn add_volume(mpv: &mut mpv::MpvHandler, delta: i64) {
    let max_volume: i64 = mpv.get_property("volume-max").expect("Failed to get volume-max");
    let current_volume: i64 = mpv.get_property("volume").expect("Failed to get volume");
    let new_volume = min(max(current_volume + delta, 0), max_volume);
    mpv.set_property("volume", new_volume).unwrap();
}

pub fn main_loop(sdl_context: Sdl, mut displayer: Displayer, mut mpv: Box<mpv::MpvHandlerWithGl>) {
    let mut event_pump = sdl_context.event_pump().expect("Failed to create event_pump");
    'main: loop {
        let (_is_alt_pressed, is_ctrl_pressed, is_shift_pressed) = {
            let keyboard_state = event_pump.keyboard_state();
            (keyboard_state.is_scancode_pressed(Scancode::RAlt) ||
             keyboard_state.is_scancode_pressed(Scancode::LAlt),
             keyboard_state.is_scancode_pressed(Scancode::RCtrl) ||
             keyboard_state.is_scancode_pressed(Scancode::LCtrl),
             keyboard_state.is_scancode_pressed(Scancode::RShift) ||
             keyboard_state.is_scancode_pressed(Scancode::LShift))
        };
        for event in event_pump.poll_iter() {
            match event {
                SdlEvent::Quit {..} | SdlEvent::KeyDown { keycode: Some(Keycode::Escape), .. } => break 'main,
                SdlEvent::KeyDown { keycode: Some(Keycode::Space),repeat: false, .. } => {
                    match mpv.get_property("pause").unwrap() {
                        true => {
                            mpv.set_property_async("pause", false, 1)
                               .expect("Failed to pause player");
                        }
                        false => {
                            mpv.set_property_async("pause", true, 1)
                               .expect("Failed to unpause player");
                        }
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp9), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 9)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp8), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 8)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp7), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 7)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp6), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 6)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp5), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 5)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp4), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 4)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp3), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 3)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp2), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 2)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp1), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 1)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp0), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 10)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::KpPlus),  .. } => {
                    add_volume(&mut mpv, 5);
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::KpMinus), .. } => {
                    add_volume(&mut mpv, -5);
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Right), repeat: false,.. } => {
                    if (is_ctrl_pressed) {
                        match mpv.command(&["frame-step"]) {
                            Ok(_) => {}
                            Err(err) => {
                                error!("Failed to frame step with error {:?}", err);
                            }
                        };
                    } else if (is_shift_pressed) {
                        mpv.command(&["seek", 15.to_string().as_str()]).unwrap();
                    } else {
                        mpv.command(&["seek", 3.to_string().as_str()]).unwrap();
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Left), repeat: false,.. } => {
                    if (is_ctrl_pressed) {
                        match mpv.command(&["frame-back-step"]) {
                            Ok(_) => {}
                            Err(err) => {
                                error!("Failed to frame back step with error {:?}", err);
                            }
                        };
                    } else if (is_shift_pressed) {
                        mpv.command(&["seek", (-15).to_string().as_str()]).unwrap();
                    } else {
                        mpv.command(&["seek", (-3).to_string().as_str()]).unwrap();
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Up), .. } => {
                    if is_ctrl_pressed {
                        add_volume(&mut mpv, 5);
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Down), .. } => {
                    if is_ctrl_pressed {
                        add_volume(&mut mpv, -5);
                    }
                }
                SdlEvent::MouseWheel { y:delta_y, .. } => {
                    let delta_y: i64 = (delta_y as i64) *
                                       if is_ctrl_pressed {
                        1
                    } else {
                        10
                    };
                    add_volume(&mut mpv, delta_y);
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::F), repeat: false, .. } => {
                    if (displayer.sdl_renderer().window().unwrap().window_flags() &
                        (SDL_WindowFlags::SDL_WINDOW_FULLSCREEN as u32)) !=
                       0 {
                        displayer.sdl_renderer_mut()
                                 .window_mut()
                                 .unwrap()
                                 .set_fullscreen(FullscreenType::Off)
                    } else {
                        displayer.sdl_renderer_mut()
                                 .window_mut()
                                 .unwrap()
                                 .set_fullscreen(FullscreenType::Desktop)
                    }
                    .expect("Failed to change fullscreen parameter of toyunda-player");
                }
                _ => {}
            }
        }
        while let Some(event) = mpv.wait_event(0.0) {
            match event {
                mpv::Event::Shutdown | mpv::Event::EndFile(_) => {
                    break 'main;
                }
                _ => {}
            };
        }
        let (width, height) = displayer.sdl_renderer().window().unwrap().size();
        mpv.draw(0, width as i32, -(height as i32)).expect("Failed to draw");
        // displayer.display("0123456789ABCDEF0123456789abcdef0123456789");
        let _time_pos: Option<f64> = mpv.get_property("time-pos").ok();
        let frame_pos: Option<u32> = mpv.get_property::<i64>("estimated-frame-number")
                                        .ok()
                                        .map(|v| v as u32);
        // example(time_pos,&mut displayer);
        // displayer.example();
        match frame_pos {
            Some(frame_pos) => displayer.render_subtitles(frame_pos),
            _ => {}
        };
        displayer.render();
    }
}
<commit_msg>Added keybind to display current_frame and current_time<commit_after>extern crate mpv ;
extern crate sdl2;

use sdl2::Sdl;
use sdl2::event::Event as SdlEvent;
use sdl2_sys::video::SDL_WindowFlags;
use sdl2::video::FullscreenType;
use sdl2::keyboard::{Keycode, Scancode};
use displayer::Displayer;
use std::cmp::{min, max};

fn speed_btn(mpv: &mut mpv::MpvHandler, is_shift_pressed: bool, keynumber: u64) {
    let mut speed = (keynumber as f64) / 10.0;
    if (is_shift_pressed) {
        speed += 1.0;
    }
    mpv.set_property_async("speed", speed, 1).expect("Failed to modify player speed");
}

fn add_volume(mpv: &mut mpv::MpvHandler, delta: i64) {
    let max_volume: i64 = mpv.get_property("volume-max").expect("Failed to get volume-max");
    let current_volume: i64 = mpv.get_property("volume").expect("Failed to get volume");
    let new_volume = min(max(current_volume + delta, 0), max_volume);
    mpv.set_property("volume", new_volume).unwrap();
}

pub fn main_loop(sdl_context: Sdl, mut displayer: Displayer, mut mpv: Box<mpv::MpvHandlerWithGl>) {
    let mut event_pump = sdl_context.event_pump().expect("Failed to create event_pump");
    'main: loop {
        let (_is_alt_pressed, is_ctrl_pressed, is_shift_pressed) = {
            let keyboard_state = event_pump.keyboard_state();
            (keyboard_state.is_scancode_pressed(Scancode::RAlt) ||
             keyboard_state.is_scancode_pressed(Scancode::LAlt),
             keyboard_state.is_scancode_pressed(Scancode::RCtrl) ||
             keyboard_state.is_scancode_pressed(Scancode::LCtrl),
             keyboard_state.is_scancode_pressed(Scancode::RShift) ||
             keyboard_state.is_scancode_pressed(Scancode::LShift))
        };
        for event in event_pump.poll_iter() {
            match event {
                SdlEvent::Quit {..} | SdlEvent::KeyDown { keycode: Some(Keycode::Escape), .. } => break 'main,
                SdlEvent::KeyDown { keycode: Some(Keycode::Space),repeat: false, .. } => {
                    match mpv.get_property("pause").unwrap() {
                        true => {
                            mpv.set_property_async("pause", false, 1)
                               .expect("Failed to pause player");
                        }
                        false => {
                            mpv.set_property_async("pause", true, 1)
                               .expect("Failed to unpause player");
                        }
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::A), repeat: false, .. } => {
                    println!("estimated_frame:\t{}\
                            \tcurrent_time:\t{}",
                            mpv.get_property::<i64>("estimated-frame-number").unwrap_or(0),
                            mpv.get_property::<f64>("time-pos").unwrap_or(0.0));
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp9), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 9)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp8), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 8)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp7), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 7)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp6), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 6)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp5), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 5)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp4), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 4)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp3), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 3)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp2), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 2)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp1), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 1)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Kp0), repeat: false, .. } => {
                    speed_btn(&mut mpv, is_shift_pressed, 10)
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::KpPlus),  .. } => {
                    add_volume(&mut mpv, 5);
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::KpMinus), .. } => {
                    add_volume(&mut mpv, -5);
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Right), repeat: false,.. } => {
                    if (is_ctrl_pressed) {
                        match mpv.command(&["frame-step"]) {
                            Ok(_) => {}
                            Err(err) => {
                                error!("Failed to frame step with error {:?}", err);
                            }
                        };
                    } else if (is_shift_pressed) {
                        mpv.command(&["seek", 15.to_string().as_str()]).unwrap();
                    } else {
                        mpv.command(&["seek", 3.to_string().as_str()]).unwrap();
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Left), repeat: false,.. } => {
                    if (is_ctrl_pressed) {
                        match mpv.command(&["frame-back-step"]) {
                            Ok(_) => {}
                            Err(err) => {
                                error!("Failed to frame back step with error {:?}", err);
                            }
                        };
                    } else if (is_shift_pressed) {
                        mpv.command(&["seek", (-15).to_string().as_str()]).unwrap();
                    } else {
                        mpv.command(&["seek", (-3).to_string().as_str()]).unwrap();
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Up), .. } => {
                    if is_ctrl_pressed {
                        add_volume(&mut mpv, 5);
                    }
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::Down), .. } => {
                    if is_ctrl_pressed {
                        add_volume(&mut mpv, -5);
                    }
                }
                SdlEvent::MouseWheel { y:delta_y, .. } => {
                    let delta_y: i64 = (delta_y as i64) *
                                       if is_ctrl_pressed {
                        1
                    } else {
                        10
                    };
                    add_volume(&mut mpv, delta_y);
                }
                SdlEvent::KeyDown { keycode: Some(Keycode::F), repeat: false, .. } => {
                    if (displayer.sdl_renderer().window().unwrap().window_flags() &
                        (SDL_WindowFlags::SDL_WINDOW_FULLSCREEN as u32)) !=
                       0 {
                        displayer.sdl_renderer_mut()
                                 .window_mut()
                                 .unwrap()
                                 .set_fullscreen(FullscreenType::Off)
                    } else {
                        displayer.sdl_renderer_mut()
                                 .window_mut()
                                 .unwrap()
                                 .set_fullscreen(FullscreenType::Desktop)
                    }
                    .expect("Failed to change fullscreen parameter of toyunda-player");
                }
                _ => {}
            }
        }
        while let Some(event) = mpv.wait_event(0.0) {
            match event {
                mpv::Event::Shutdown | mpv::Event::EndFile(_) => {
                    break 'main;
                }
                _ => {}
            };
        }
        let (width, height) = displayer.sdl_renderer().window().unwrap().size();
        mpv.draw(0, width as i32, -(height as i32)).expect("Failed to draw");
        // displayer.display("0123456789ABCDEF0123456789abcdef0123456789");
        let _time_pos: Option<f64> = mpv.get_property("time-pos").ok();
        let frame_pos: Option<u32> = mpv.get_property::<i64>("estimated-frame-number")
                                        .ok()
                                        .map(|v| v as u32);
        // example(time_pos,&mut displayer);
        // displayer.example();
        match frame_pos {
            Some(frame_pos) => displayer.render_subtitles(frame_pos),
            _ => {}
        };
        displayer.render();
    }
}
<|endoftext|>


<commit_before>use seed::prelude::*;
use crate::Msg;

mod perfects_utils {
	pub struct Perfect<'a> {
		pub n: u64,
		pub p: u64,
		pub digits: u64,
		pub discovery: &'a str,
	}

	pub fn perfects<'a>() -> Vec<Perfect<'a>> {
        vec![
			Perfect {n: 51, p: 82589934, digits: 49724095, discovery: "2018 Laroche, Woltman, Kurowski, Blosser, et al."},
			Perfect {n: 50, p: 77232917, digits: 46498850, discovery: "2017 Jonathan Pace, George Woltman, Scott Kurowski, Aaron Blosser, et al.." },
			Perfect {n: 49, p: 74207281, digits: 44677235, discovery: "2016 Cooper, Woltman, Kurowski, Blosser et al." },
			Perfect {n: 48, p: 57885161, digits: 34850340, discovery: "2013 Cooper, Woltman, Kurowski, et al." },
			Perfect {n: 47, p: 43112609, digits: 25956377, discovery: "2008 Smith, Woltman, Kurowski, et al." },
			Perfect {n: 46, p: 42643801, digits: 42643801, discovery: "2009 Strindmo, Woltman, Kurowski, et al." },
			Perfect {n: 45, p: 37156667, digits: 22370543, discovery: "2008 Elvenich, Woltman, Kurowski, et al." },
			Perfect {n: 44, p: 32582657, digits: 19616714, discovery: "2006 Cooper, Boone, Woltman, Kurowski, et al." },
			Perfect {n: 43, p: 30402457, digits: 18304103, discovery: "2005 Cooper, Boone, Woltman, Kurowski, et al." },
			Perfect {n: 42, p: 25964951, digits: 15632458, discovery: "2005 Nowak, Woltman, Kurowski, et. al." },
			Perfect {n: 41, p: 24036583, digits: 14471465, discovery: "2004 Findley, Woltman, Kurowski, et. al." },
			Perfect {n: 40, p: 20996011, digits: 12640858, discovery: "2003 Shafer, Woltman, Kurowski, et. al." },
			Perfect {n: 39, p: 13466917, digits: 8107892, discovery: "2001 Cameron, Woltman, Kurowski, et. al." },
			Perfect {n: 38, p: 6972593, digits: 4197919, discovery: "1999 Hajratwala, Woltman, Kurowski, et. al." },
			Perfect {n: 37, p: 3021377, digits: 1819050, discovery: "1998 Clarkson, Woltman, Kurowski, et. al." },
			Perfect {n: 36, p: 2976221, digits: 1791864, discovery: "1997 Spence, Woltman, et. al." },
			Perfect {n: 35, p: 1398269, digits: 841842, discovery: "1996 Armengaud, Woltman, et. al." },
			Perfect {n: 34, p: 1257787, digits: 757263, discovery: "1996 Slowinski&Gage" },
			Perfect {n: 33, p: 859433, digits: 517430, discovery: "1994 Slowinski&Gage" },
			Perfect {n: 32, p: 756839, digits: 455663, discovery: "1992 Slowinski&Gage" },
			Perfect {n: 31, p: 216091, digits: 130100, discovery: "1985 Slowinski" },
			Perfect {n: 30, p: 132049, digits: 79502, discovery: "1983 Slowinski" },
			Perfect {n: 29, p: 110503, digits: 66530, discovery: "1988 Colquitt&Welsh" },
			Perfect {n: 28, p: 86243, digits: 51924, discovery: "1982 Slowinski" },
			Perfect {n: 27, p: 44497, digits: 26790, discovery: "1979 Nelson&Slowinski" },
			Perfect {n: 26, p: 23209, digits: 13973, discovery: "1979 Noll" },
			Perfect {n: 25, p: 21701, digits: 13066, discovery: "1978 Noll&Nickel" },
			Perfect {n: 24, p: 19937, digits: 12003, discovery: "1971 Tuckerman" },
			Perfect {n: 23, p: 11213, digits: 6751, discovery: "1963 Gillies" },
			Perfect {n: 22, p: 9941, digits: 5985, discovery: "1963 Gillies" },
			Perfect {n: 21, p: 9689, digits: 5834, discovery: "1963 Gillies" },
			Perfect {n: 20, p: 4423, digits: 2663, discovery: "1961 Hurwitz" },
			Perfect {n: 19, p: 4253, digits: 2561, discovery: "1961 Hurwitz" },
			Perfect {n: 18, p: 3217, digits: 1937, discovery: "1957 Riesel" },
			Perfect {n: 17, p: 2281, digits: 1373, discovery: "1952 Robinson" },
			Perfect {n: 16, p: 2203, digits: 1327, discovery: "1952 Robinson" },
			Perfect {n: 15, p: 1279, digits: 770, discovery: "1952 Robinson" },
			Perfect {n: 14, p: 607, digits: 366, discovery: "1952 Robinson" },
			Perfect {n: 13, p: 521, digits: 314, discovery: "1952 Robinson" },
			Perfect {n: 12, p: 127, digits: 77, discovery: "1876 Lucas" },
			Perfect {n: 11, p: 107, digits: 65, discovery: "1914 Powers" },
			Perfect {n: 10, p: 89, digits: 54, discovery: "1911 Powers" },
			Perfect {n: 9, p: 61, digits: 37, discovery: "1883 Pervushin" },
			Perfect {n: 8, p: 31, digits: 19, discovery: "1772 Euler" },
			Perfect {n: 7, p: 19, digits: 12, discovery: "1588 Cataldi" },
			Perfect {n: 6, p: 17, digits: 10, discovery: "1588 Cataldi" },
			Perfect {n: 5, p: 13, digits: 8, discovery: "1456 ?" },
			Perfect {n: 4, p: 7, digits: 4, discovery: "?" },
			Perfect {n: 3, p: 5, digits: 3, discovery: "?" },
			Perfect {n: 2, p: 3, digits: 2, discovery: "?" },
			Perfect {n: 1, p: 3, digits: 1, discovery: "?" },
		]
	}
}

pub fn render() -> seed::dom_types::Node<Msg> {
    let mut html = vec![];

    let perfects = perfects_utils::perfects();

    for n in 0..perfects.len() {
        let download_txt:String = vec!["https://static.bigprimes.net/archive/perfect/",&perfects[n].n.to_string(),".txt"].into_iter().collect();
        let download_zip:String = vec!["https://static.bigprimes.net/archive/perfect/",&perfects[n].n.to_string(),".zip"].into_iter().collect();

		let equation:String = vec!["2",&(perfects[n].p-1).to_string()," × (2",&(perfects[n].p).to_string(),"-1)"].into_iter().collect();

        html.push(
            tr![
                td![perfects[n].n.to_string()],//rank
				td![El::from_html(&equation)],//perfect number as a formula

                td![perfects[n].digits.to_string()],//digits in length
                td![perfects[n].discovery],//disocvery
                if perfects[n].n >= 25 {a![attrs!{At::Href => download_zip},"ZIP"]} else {a![attrs!{At::Href => download_txt},"TXT"]}//downloads
            ]
        );
    }

    div![
        h1!["The Perfect Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Class => "perfecttable text"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Prime"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Discovered"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn perfect_test<'a>() {
        let mut perfects:Vec<perfects_utils::Perfect<'a>> = perfects_utils::perfects();
		perfects.reverse();
        assert_eq!(perfects[49].digits, 46498850);
        assert_eq!(perfects[39].digits, 12640858);
    }
}<commit_msg>Removed zip download links<commit_after>use seed::prelude::*;
use crate::Msg;

mod perfects_utils {
	pub struct Perfect<'a> {
		pub n: u64,
		pub p: u64,
		pub digits: u64,
		pub discovery: &'a str,
	}

	pub fn perfects<'a>() -> Vec<Perfect<'a>> {
        vec![
			Perfect {n: 51, p: 82589934, digits: 49724095, discovery: "2018 Laroche, Woltman, Kurowski, Blosser, et al."},
			Perfect {n: 50, p: 77232917, digits: 46498850, discovery: "2017 Jonathan Pace, George Woltman, Scott Kurowski, Aaron Blosser, et al.." },
			Perfect {n: 49, p: 74207281, digits: 44677235, discovery: "2016 Cooper, Woltman, Kurowski, Blosser et al." },
			Perfect {n: 48, p: 57885161, digits: 34850340, discovery: "2013 Cooper, Woltman, Kurowski, et al." },
			Perfect {n: 47, p: 43112609, digits: 25956377, discovery: "2008 Smith, Woltman, Kurowski, et al." },
			Perfect {n: 46, p: 42643801, digits: 42643801, discovery: "2009 Strindmo, Woltman, Kurowski, et al." },
			Perfect {n: 45, p: 37156667, digits: 22370543, discovery: "2008 Elvenich, Woltman, Kurowski, et al." },
			Perfect {n: 44, p: 32582657, digits: 19616714, discovery: "2006 Cooper, Boone, Woltman, Kurowski, et al." },
			Perfect {n: 43, p: 30402457, digits: 18304103, discovery: "2005 Cooper, Boone, Woltman, Kurowski, et al." },
			Perfect {n: 42, p: 25964951, digits: 15632458, discovery: "2005 Nowak, Woltman, Kurowski, et. al." },
			Perfect {n: 41, p: 24036583, digits: 14471465, discovery: "2004 Findley, Woltman, Kurowski, et. al." },
			Perfect {n: 40, p: 20996011, digits: 12640858, discovery: "2003 Shafer, Woltman, Kurowski, et. al." },
			Perfect {n: 39, p: 13466917, digits: 8107892, discovery: "2001 Cameron, Woltman, Kurowski, et. al." },
			Perfect {n: 38, p: 6972593, digits: 4197919, discovery: "1999 Hajratwala, Woltman, Kurowski, et. al." },
			Perfect {n: 37, p: 3021377, digits: 1819050, discovery: "1998 Clarkson, Woltman, Kurowski, et. al." },
			Perfect {n: 36, p: 2976221, digits: 1791864, discovery: "1997 Spence, Woltman, et. al." },
			Perfect {n: 35, p: 1398269, digits: 841842, discovery: "1996 Armengaud, Woltman, et. al." },
			Perfect {n: 34, p: 1257787, digits: 757263, discovery: "1996 Slowinski&Gage" },
			Perfect {n: 33, p: 859433, digits: 517430, discovery: "1994 Slowinski&Gage" },
			Perfect {n: 32, p: 756839, digits: 455663, discovery: "1992 Slowinski&Gage" },
			Perfect {n: 31, p: 216091, digits: 130100, discovery: "1985 Slowinski" },
			Perfect {n: 30, p: 132049, digits: 79502, discovery: "1983 Slowinski" },
			Perfect {n: 29, p: 110503, digits: 66530, discovery: "1988 Colquitt&Welsh" },
			Perfect {n: 28, p: 86243, digits: 51924, discovery: "1982 Slowinski" },
			Perfect {n: 27, p: 44497, digits: 26790, discovery: "1979 Nelson&Slowinski" },
			Perfect {n: 26, p: 23209, digits: 13973, discovery: "1979 Noll" },
			Perfect {n: 25, p: 21701, digits: 13066, discovery: "1978 Noll&Nickel" },
			Perfect {n: 24, p: 19937, digits: 12003, discovery: "1971 Tuckerman" },
			Perfect {n: 23, p: 11213, digits: 6751, discovery: "1963 Gillies" },
			Perfect {n: 22, p: 9941, digits: 5985, discovery: "1963 Gillies" },
			Perfect {n: 21, p: 9689, digits: 5834, discovery: "1963 Gillies" },
			Perfect {n: 20, p: 4423, digits: 2663, discovery: "1961 Hurwitz" },
			Perfect {n: 19, p: 4253, digits: 2561, discovery: "1961 Hurwitz" },
			Perfect {n: 18, p: 3217, digits: 1937, discovery: "1957 Riesel" },
			Perfect {n: 17, p: 2281, digits: 1373, discovery: "1952 Robinson" },
			Perfect {n: 16, p: 2203, digits: 1327, discovery: "1952 Robinson" },
			Perfect {n: 15, p: 1279, digits: 770, discovery: "1952 Robinson" },
			Perfect {n: 14, p: 607, digits: 366, discovery: "1952 Robinson" },
			Perfect {n: 13, p: 521, digits: 314, discovery: "1952 Robinson" },
			Perfect {n: 12, p: 127, digits: 77, discovery: "1876 Lucas" },
			Perfect {n: 11, p: 107, digits: 65, discovery: "1914 Powers" },
			Perfect {n: 10, p: 89, digits: 54, discovery: "1911 Powers" },
			Perfect {n: 9, p: 61, digits: 37, discovery: "1883 Pervushin" },
			Perfect {n: 8, p: 31, digits: 19, discovery: "1772 Euler" },
			Perfect {n: 7, p: 19, digits: 12, discovery: "1588 Cataldi" },
			Perfect {n: 6, p: 17, digits: 10, discovery: "1588 Cataldi" },
			Perfect {n: 5, p: 13, digits: 8, discovery: "1456 ?" },
			Perfect {n: 4, p: 7, digits: 4, discovery: "?" },
			Perfect {n: 3, p: 5, digits: 3, discovery: "?" },
			Perfect {n: 2, p: 3, digits: 2, discovery: "?" },
			Perfect {n: 1, p: 3, digits: 1, discovery: "?" },
		]
	}
}

pub fn render() -> seed::dom_types::Node<Msg> {
    let mut html = vec![];

    let perfects = perfects_utils::perfects();

    for n in 0..perfects.len() {
        let download_txt:String = vec!["https://static.bigprimes.net/archive/perfect/",&perfects[n].n.to_string(),".txt"].into_iter().collect();

		let equation:String = vec!["2",&(perfects[n].p-1).to_string()," × (2",&(perfects[n].p).to_string(),"-1)"].into_iter().collect();

        html.push(
            tr![
                td![perfects[n].n.to_string()],//rank
				td![El::from_html(&equation)],//perfect number as a formula

                td![perfects[n].digits.to_string()],//digits in length
                td![perfects[n].discovery],//disocvery
                a![attrs!{At::Href => download_txt},"TXT"]//downloads
            ]
        );
    }

    div![
        h1!["The Perfect Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Class => "perfecttable text"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Prime"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Discovered"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn perfect_test<'a>() {
        let mut perfects:Vec<perfects_utils::Perfect<'a>> = perfects_utils::perfects();
		perfects.reverse();
        assert_eq!(perfects[49].digits, 46498850);
        assert_eq!(perfects[39].digits, 12640858);
    }
}<|endoftext|>


<commit_before>use webcore::value::Reference;
use webcore::try_from::TryInto;
use webapi::event_target::{IEventTarget, EventTarget};
use webapi::node::{INode, Node};
use webapi::element::{IElement, Element};
use webapi::html_element::{IHtmlElement, HtmlElement};

/// The HTML input element is used to create interactive controls
/// for web-based forms in order to accept data from the user.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en/docs/Web/HTML/Element/input)
// https://html.spec.whatwg.org/#htmlinputelement
#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
#[reference(instance_of = "HTMLInputElement")]
#[reference(subclass_of(EventTarget, Node, Element, HtmlElement))]
pub struct InputElement( Reference );

impl IEventTarget for InputElement {}
impl INode for InputElement {}
impl IElement for InputElement {}
impl IHtmlElement for InputElement {}

impl InputElement {
    /// The value of the control. This attribute is optional except when the input is a radio button or a checkbox.
    // https://html.spec.whatwg.org/#the-input-element:dom-input-value
    #[inline]
    pub fn raw_value( &self ) -> String {
        js! (
            return @{self}.value;
        ).try_into().unwrap()
    }

    /// Sets the value of the control.
    // https://html.spec.whatwg.org/#dom-input-value
    #[inline]
    pub fn set_raw_value( &self, value: &str ) {
        js! { @(no_return)
            @{self}.value = @{value};
        }
    }
}
<commit_msg>Add `InputElement::{selection_start, selection_end, set_selection_start, set_selection_end}` (#365)<commit_after>use webcore::value::Reference;
use webcore::try_from::TryInto;
use webapi::dom_exception::InvalidStateError;
use webapi::event_target::{IEventTarget, EventTarget};
use webapi::node::{INode, Node};
use webapi::element::{IElement, Element};
use webapi::html_element::{IHtmlElement, HtmlElement};

/// The HTML input element is used to create interactive controls
/// for web-based forms in order to accept data from the user.
///
/// [(JavaScript docs)](https://developer.mozilla.org/en/docs/Web/HTML/Element/input)
// https://html.spec.whatwg.org/#htmlinputelement
#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
#[reference(instance_of = "HTMLInputElement")]
#[reference(subclass_of(EventTarget, Node, Element, HtmlElement))]
pub struct InputElement( Reference );

impl IEventTarget for InputElement {}
impl INode for InputElement {}
impl IElement for InputElement {}
impl IHtmlElement for InputElement {}

impl InputElement {
    /// The value of the control. This attribute is optional except when the input is a radio button or a checkbox.
    ///
    // https://html.spec.whatwg.org/#the-input-element:dom-input-value
    #[inline]
    pub fn raw_value( &self ) -> String {
        js! (
            return @{self}.value;
        ).try_into().unwrap()
    }

    /// Sets the value of the control.
    ///
    // https://html.spec.whatwg.org/#dom-input-value
    #[inline]
    pub fn set_raw_value( &self, value: &str ) {
        js! { @(no_return)
            @{self}.value = @{value};
        }
    }

    /// The offset to the start of the selection.
    /// This attribute only applies when the input is a text, search, url, telephone or password.
    ///
    // https://html.spec.whatwg.org/#the-input-element:dom-textarea/input-selectionstart
    #[inline]
    pub fn selection_start( &self ) -> Option<u32> {
        js! (
            return @{self}.selectionStart;
        ).try_into().ok()
    }

    /// Sets the offset to the start of the selection.
    /// This attribute only applies when the input is a text, search, url, telephone or password.
    ///
    // https://html.spec.whatwg.org/#the-input-element:dom-textarea/input-selectionstart
    #[inline]
    pub fn set_selection_start( &self, value: u32 ) -> Result<(), InvalidStateError> {
        js_try! ( @(no_return)
            @{self}.selectionStart = @{value};
        ).unwrap()
    }

    /// The offset to the end of the selection.
    /// This attribute only applies when the input is a text, search, url, telephone or password.
    ///
    // https://html.spec.whatwg.org/#the-input-element:dom-textarea/input-selectionstart
    #[inline]
    pub fn selection_end( &self ) -> Option<u32> {
        js! (
            return @{self}.selectionEnd;
        ).try_into().ok()
    }

    /// Sets the offset to the end of the selection.
    /// This attribute only applies when the input is a text, search, url, telephone or password.
    ///
    // https://html.spec.whatwg.org/#the-input-element:dom-textarea/input-selectionstart
    #[inline]
    pub fn set_selection_end( &self, value: u32 ) -> Result<(), InvalidStateError> {
        js_try! ( @(no_return)
            @{self}.selectionEnd = @{value};
        ).unwrap()
    }
}
<|endoftext|>