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:
parent
df99a4f3fb
commit
dfdefb2ed4
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user