Skip to content

Commit

Permalink
x11: Allow setting the window icon on x11
Browse files Browse the repository at this point in the history
  • Loading branch information
emilio committed May 12, 2016
1 parent dd6c8b8 commit aad118a
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,59 +88,68 @@ wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.i586-unknown-linux-gnu.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.x86_64-unknown-linux-gnu.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.arm-unknown-linux-gnueabihf.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.armv7-unknown-linux-gnueabihf.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.aarch64-unknown-linux-gnu.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.x86_64-unknown-dragonfly.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.x86_64-unknown-freebsd.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"

[target.x86_64-unknown-openbsd.dependencies]
osmesa-sys = "0.0.5"
wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] }
wayland-kbd = "0.3.3"
wayland-window = "0.2.2"
x11-dl = "~2.4"
image = "0.10"
51 changes: 51 additions & 0 deletions src/api/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ use std::{mem, ptr, cmp};
use std::cell::Cell;
use std::sync::atomic::AtomicBool;
use std::collections::VecDeque;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::os::raw::c_long;
use std::thread;
use std::time::Duration;
use image;

use Api;
use ContextError;
Expand Down Expand Up @@ -706,10 +708,59 @@ impl Window {
}
}

if let Some(ref icon_path) = window_attrs.icon {
window.set_icon(icon_path);
}

// returning
Ok(window)
}

pub fn set_icon(&self, icon: &PathBuf) {
use image::GenericImage;

let img = match image::open(icon) {
Ok(img) => img,
Err(_) => return,
};

let (width, height) = img.dimensions();

// This is an array of 32bit packed CARDINAL ARGB with high byte being
// A, low byte being B. The first two cardinals are width, height. Data
// is in rows, left to right and top to bottom.
let mut buff = Vec::<libc::c_ulong>::with_capacity((width * height + 2) as usize);

buff.push(width as libc::c_ulong);
buff.push(height as libc::c_ulong);

for (_x, _y, rgba) in img.pixels() {
let mut value: u32 = (rgba[3] as u32) << 24 |
(rgba[0] as u32) << 16 |
(rgba[1] as u32) << 8 |
(rgba[2] as u32);
buff.push(value as libc::c_ulong);
}

assert!(buff.len() == (width * height + 2) as usize);

unsafe {
let net_wm_icon = (self.x.display.xlib.XInternAtom)(self.x.display.display,
b"_NET_WM_ICON\0".as_ptr() as *const _, 0);

let cardinal = (self.x.display.xlib.XInternAtom)(self.x.display.display,
b"CARDINAL\0".as_ptr() as *const _, 0);

(self.x.display.xlib.XChangeProperty)(self.x.display.display,
self.x.window,
net_wm_icon,
cardinal, 32, ffi::PropModeReplace,
buff.as_ptr() as *const _,
buff.len() as libc::c_int);
self.x.display.check_errors().expect("Failed to set the icon");
}
}

pub fn set_title(&self, title: &str) {
let wm_name = unsafe {
(self.x.display.xlib.XInternAtom)(self.x.display.display, b"_NET_WM_NAME\0".as_ptr() as *const _, 0)
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ extern crate x11_dl;
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
#[macro_use(wayland_env)]
extern crate wayland_client;
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
extern crate image;

pub use events::*;
pub use headless::{HeadlessRendererBuilder, HeadlessContext};
Expand Down

0 comments on commit aad118a

Please sign in to comment.