1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-28 07:55:03 +03:00

Now basically functional on windows!

This commit is contained in:
Wez Furlong 2019-02-17 12:11:12 -08:00
parent df99a4f3fb
commit dfdefb2ed4
4 changed files with 58 additions and 34 deletions

View File

@ -75,10 +75,6 @@ impl<'a> NamedFont for NamedFontImpl<'a> {
let hmetrics = glyph.h_metrics(); let hmetrics = glyph.h_metrics();
let glyph = glyph.positioned(point(0.0, 0.0)); let glyph = glyph.positioned(point(0.0, 0.0));
if c != ' ' {
eprintln!("{} -> glyph {} {:?}", c, glyph.id().0, hmetrics);
}
shaped.push(GlyphInfo { shaped.push(GlyphInfo {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
text: s[cluster..cluster].to_string(), text: s[cluster..cluster].to_string(),
@ -140,10 +136,12 @@ impl<'a> Font for NamedFontImpl<'a> {
data.push(v); // green data.push(v); // green
data.push(v); // blue data.push(v); // blue
}); });
/*
eprintln!( eprintln!(
"rasterize_glyph {} {}x{} {} bounds {:?}", "rasterize_glyph {} {}x{} {} bounds {:?}",
glyph_pos, width, height, self.cell_height, bounds glyph_pos, width, height, self.cell_height, bounds
); );
*/
// FIXME: there's something funky about either the bearing // FIXME: there's something funky about either the bearing
// calculation here or the y_offset calculation in the // calculation here or the y_offset calculation in the
// shape function that causes the baseline to vary and // shape function that causes the baseline to vary and

View File

@ -131,7 +131,7 @@ impl TerminalWindow {
let display = { let display = {
let pref_context = glutin::ContextBuilder::new() let pref_context = glutin::ContextBuilder::new()
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (2, 0))) //.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (2, 0)))
.with_vsync(true) .with_vsync(true)
.with_pixel_format(24, 8) .with_pixel_format(24, 8)
.with_srgb(true); .with_srgb(true);
@ -143,7 +143,11 @@ impl TerminalWindow {
match glium::Display::new(window, pref_context, &*mut_loop) { match glium::Display::new(window, pref_context, &*mut_loop) {
Ok(display) => display, Ok(display) => display,
Err(_) => { Err(err) => {
eprintln!(
"preferred GL context not available: {}, try a fallback",
err
);
// Take anything that might show something. // Take anything that might show something.
// This fallback is typically hit when running with a remote // This fallback is typically hit when running with a remote
// X server. // X server.

View File

@ -110,7 +110,7 @@ implement_vertex!(
); );
const VERTEX_SHADER: &str = r#" const VERTEX_SHADER: &str = r#"
#version 300 es #version 330
in vec2 position; in vec2 position;
in vec2 adjust; in vec2 adjust;
in vec2 tex; in vec2 tex;
@ -187,7 +187,7 @@ const U_STRIKE_ONE: f32 = 4.0 / U_COLS;
const U_STRIKE_TWO: f32 = 5.0 / U_COLS; const U_STRIKE_TWO: f32 = 5.0 / U_COLS;
const FRAGMENT_SHADER: &str = r#" const FRAGMENT_SHADER: &str = r#"
#version 300 es #version 330
precision mediump float; precision mediump float;
in vec2 tex_coords; in vec2 tex_coords;
in vec2 underline_coords; in vec2 underline_coords;
@ -227,7 +227,7 @@ void main() {
// take that pixel, otherwise we'll use the background color. // take that pixel, otherwise we'll use the background color.
if (o_underline != 0.0) { if (o_underline != 0.0) {
// Compute the pixel color for this location // Compute the pixel color for this location
vec4 under_color = multiply(o_fg_color, texture2D(underline_tex, underline_coords)); vec4 under_color = multiply(o_fg_color, texture(underline_tex, underline_coords));
if (under_color.a != 0.0) { if (under_color.a != 0.0) {
// if the line glyph isn't transparent in this position then // if the line glyph isn't transparent in this position then
// we take this pixel color, otherwise we'll leave the color // we take this pixel color, otherwise we'll leave the color
@ -236,7 +236,7 @@ void main() {
} }
} }
} else { } else {
color = texture2D(glyph_tex, tex_coords); color = texture(glyph_tex, tex_coords);
if (o_has_color == 0.0) { if (o_has_color == 0.0) {
// if it's not a color emoji, tint with the fg_color // if it's not a color emoji, tint with the fg_color
color = multiply(o_fg_color, color); color = multiply(o_fg_color, color);

View File

@ -3,7 +3,6 @@ use std::io::{self, Error as IoError, Result as IoResult};
extern crate winapi; extern crate winapi;
use std::env; use std::env;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use std::fs;
use std::mem; use std::mem;
use std::os::windows::ffi::OsStrExt; use std::os::windows::ffi::OsStrExt;
use std::os::windows::ffi::OsStringExt; use std::os::windows::ffi::OsStringExt;
@ -33,20 +32,20 @@ pub struct Command {
impl Command { impl Command {
pub fn new<S: AsRef<OsStr>>(program: S) -> Self { pub fn new<S: AsRef<OsStr>>(program: S) -> Self {
Self { Self {
args: vec![Self::search_path(program.as_ref().to_owned())], args: vec![program.as_ref().to_owned()],
input: None, input: None,
output: None, output: None,
hpc: None, hpc: None,
} }
} }
fn search_path(exe: OsString) -> OsString { fn search_path(exe: &OsStr) -> OsString {
if let Some(path) = env::var_os("PATH") { if let Some(path) = env::var_os("PATH") {
let extensions = env::var_os("PATHEXT").unwrap_or(".EXE".into()); let extensions = env::var_os("PATHEXT").unwrap_or(".EXE".into());
for path in env::split_paths(&path) { for path in env::split_paths(&path) {
// Check for exactly the user's string in this path dir // Check for exactly the user's string in this path dir
let candidate = path.join(&exe); let candidate = path.join(&exe);
if fs::metadata(&candidate).is_ok() { if candidate.exists() {
return candidate.into_os_string(); return candidate.into_os_string();
} }
@ -58,14 +57,14 @@ impl Command {
// doesn't want that // doesn't want that
let ext = ext.to_str().expect("PATHEXT entries must be utf8"); let ext = ext.to_str().expect("PATHEXT entries must be utf8");
let path = path.join(&exe).with_extension(&ext[1..]); let path = path.join(&exe).with_extension(&ext[1..]);
if fs::metadata(&path).is_ok() { if path.exists() {
return path.into_os_string(); return path.into_os_string();
} }
} }
} }
} }
exe exe.to_owned()
} }
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command { pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
@ -105,21 +104,23 @@ impl Command {
self self
} }
fn cmdline(&self) -> Result<Vec<u16>, Error> { fn cmdline(&self) -> Result<(Vec<u16>, Vec<u16>), Error> {
let mut cmdline = Vec::<u16>::new(); let mut cmdline = Vec::<u16>::new();
for (idx, arg) in self.args.iter().enumerate() {
if idx != 0 { let exe = Self::search_path(&self.args[0]);
cmdline.push(' ' as u16); Self::append_quoted(&exe, &mut cmdline);
} let exe = exe.encode_wide().collect();
for arg in self.args.iter().skip(1) {
cmdline.push(' ' as u16);
ensure!( ensure!(
!arg.encode_wide().any(|c| c == 0), !arg.encode_wide().any(|c| c == 0),
"invalid encoding for command line argument at index {}: {:?}", "invalid encoding for command line argument {:?}",
idx,
arg arg
); );
Self::append_quoted(arg, &mut cmdline); Self::append_quoted(arg, &mut cmdline);
} }
Ok(cmdline) Ok((exe, cmdline))
} }
// Borrowed from https://github.com/hniksic/rust-subprocess/blob/873dfed165173e52907beb87118b2c0c05d8b8a1/src/popen.rs#L1117 // Borrowed from https://github.com/hniksic/rust-subprocess/blob/873dfed165173e52907beb87118b2c0c05d8b8a1/src/popen.rs#L1117
@ -179,10 +180,16 @@ impl Command {
let mut pi: PROCESS_INFORMATION = unsafe { mem::zeroed() }; let mut pi: PROCESS_INFORMATION = unsafe { mem::zeroed() };
let mut cmdline = self.cmdline()?; let (mut exe, mut cmdline) = self.cmdline()?;
let cmd_os = OsString::from_wide(&cmdline);
eprintln!(
"Running: module: {:?} {:?}",
OsString::from_wide(&exe),
cmd_os
);
let res = unsafe { let res = unsafe {
CreateProcessW( CreateProcessW(
ptr::null(), exe.as_mut_slice().as_mut_ptr(),
cmdline.as_mut_slice().as_mut_ptr(), cmdline.as_mut_slice().as_mut_ptr(),
ptr::null_mut(), ptr::null_mut(),
ptr::null_mut(), ptr::null_mut(),
@ -195,11 +202,8 @@ impl Command {
) )
}; };
if res == 0 { if res == 0 {
bail!( let err = IoError::last_os_error();
"CreateProcessW `{:?}` failed: {}", bail!("CreateProcessW `{:?}` failed: {}", cmd_os, err);
OsString::from_wide(&cmdline),
IoError::last_os_error()
);
} }
// Make sure we close out the thread handle so we don't leak it; // Make sure we close out the thread handle so we don't leak it;
@ -354,12 +358,20 @@ struct OwnedHandle {
unsafe impl Send for OwnedHandle {} unsafe impl Send for OwnedHandle {}
impl Drop for OwnedHandle { impl Drop for OwnedHandle {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { CloseHandle(self.handle) }; if self.handle != INVALID_HANDLE_VALUE && !self.handle.is_null() {
unsafe { CloseHandle(self.handle) };
}
} }
} }
impl OwnedHandle { impl OwnedHandle {
fn try_clone(&self) -> Result<Self, IoError> { fn try_clone(&self) -> Result<Self, IoError> {
if self.handle == INVALID_HANDLE_VALUE || self.handle.is_null() {
return Ok(OwnedHandle {
handle: self.handle,
});
}
let proc = unsafe { GetCurrentProcess() }; let proc = unsafe { GetCurrentProcess() };
let mut duped = INVALID_HANDLE_VALUE; let mut duped = INVALID_HANDLE_VALUE;
let ok = unsafe { let ok = unsafe {
@ -448,13 +460,23 @@ impl MasterPty {
} }
pub fn try_clone(&self) -> Result<Self, Error> { pub fn try_clone(&self) -> Result<Self, Error> {
// FIXME: this isn't great. Replace this with a way to
// clone the output handle and read it.
let mut inner = self.inner.lock().unwrap();
Ok(Self { Ok(Self {
inner: self.inner.clone(), inner: Arc::new(Mutex::new(Inner {
con: PsuedoCon {
con: INVALID_HANDLE_VALUE,
},
readable: inner.readable.try_clone()?,
writable: inner.writable.try_clone()?,
size: inner.size,
})),
}) })
} }
pub fn clear_nonblocking(&self) -> Result<(), Error> { pub fn clear_nonblocking(&self) -> Result<(), Error> {
unimplemented!(); Ok(())
} }
} }