Remove UWP / Hololens support
16
.gitignore
vendored
|
@ -55,22 +55,6 @@ Sessionx.vim
|
|||
|
||||
/unminified-js
|
||||
|
||||
# Hololens artifacts
|
||||
support/hololens/x64/
|
||||
support/hololens/ARM/
|
||||
support/hololens/ARM64/
|
||||
support/hololens/ServoApp/x64/
|
||||
support/hololens/ServoApp/ARM/
|
||||
support/hololens/ServoApp/ARM64/
|
||||
support/hololens/ServoApp/Generated Files/
|
||||
support/hololens/ServoApp/BundleArtifacts/
|
||||
support/hololens/ServoApp/support/
|
||||
support/hololens/ServoApp/Debug/
|
||||
support/hololens/ServoApp/Release/
|
||||
support/hololens/packages/
|
||||
support/hololens/AppPackages/
|
||||
support/hololens/.vs/
|
||||
|
||||
# Layout debugger trace files
|
||||
layout_trace*
|
||||
|
||||
|
|
23
Cargo.lock
generated
|
@ -4251,26 +4251,6 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openxr"
|
||||
version = "0.12.2"
|
||||
source = "git+https://github.com/servo/openxrs.git?branch=secondary-views-2#87c0186c88f6e2bc22dbbe0bf5c02afc60fc37ef"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libloading 0.6.1",
|
||||
"openxr-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openxr-sys"
|
||||
version = "0.8.2"
|
||||
source = "git+https://github.com/servo/openxrs.git?branch=secondary-views-2#87c0186c88f6e2bc22dbbe0bf5c02afc60fc37ef"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "orbclient"
|
||||
version = "0.3.42"
|
||||
|
@ -7085,15 +7065,12 @@ dependencies = [
|
|||
"gl_generator 0.13.1",
|
||||
"gvr-sys",
|
||||
"log",
|
||||
"openxr",
|
||||
"serde",
|
||||
"sparkle",
|
||||
"surfman",
|
||||
"surfman-chains",
|
||||
"time 0.1.45",
|
||||
"webxr-api",
|
||||
"winapi",
|
||||
"wio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -44,7 +44,7 @@ manually, try the [manual build setup][manual-build].
|
|||
- Download and run [`rustup-init.exe`](https://win.rustup.rs/) then follow the onscreen instructions.
|
||||
- Install [chocolatey](https://chocolatey.org/)
|
||||
- Run `mach bootstrap`
|
||||
- *This will install CMake, Git, Ninja, NuGet, Python and the Visual Studio 2019 Build Tools
|
||||
- *This will install CMake, Git, Ninja, Python and the Visual Studio 2019 Build Tools
|
||||
via choco in an Administrator console. It can take quite a while.*
|
||||
- *If you already have Visual Studio 2019 installed, this may not install all necessary components.
|
||||
Please follow the Visual Studio 2019 installation instructions in the [manual setup][manual-build].*
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[target.x86_64-uwp-windows-msvc.dependencies]
|
||||
std = { features = ["panic-unwind"] }
|
||||
|
||||
# https://github.com/rust-lang/rust/issues/65313
|
||||
[target.aarch64-uwp-windows-msvc.dependencies]
|
||||
std = { features = ["panic-unwind"] }
|
||||
|
|
@ -6,9 +6,6 @@ license = "MPL-2.0"
|
|||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
uwp = []
|
||||
|
||||
[lib]
|
||||
name = "servo_config"
|
||||
path = "lib.rs"
|
||||
|
|
|
@ -35,14 +35,9 @@ pub fn default_config_dir() -> Option<PathBuf> {
|
|||
Some(config_dir)
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "windows", not(feature = "uwp")))]
|
||||
#[cfg(all(target_os = "windows"))]
|
||||
pub fn default_config_dir() -> Option<PathBuf> {
|
||||
let mut config_dir = ::dirs_next::config_dir().unwrap();
|
||||
config_dir.push("Servo");
|
||||
Some(config_dir)
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "windows", feature = "uwp"))]
|
||||
pub fn default_config_dir() -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ fn test_set_all_error_on_unknown_field() -> Result<(), Box<dyn Error>> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android", feature = "uwp")))]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
#[test]
|
||||
fn test_default_config_dir_create_read_write() {
|
||||
let json_str = "{\
|
||||
|
|
|
@ -21,7 +21,6 @@ default = ["unrooted_must_root_lint"]
|
|||
webgl_backtrace = ["canvas_traits/webgl_backtrace"]
|
||||
js_backtrace = []
|
||||
refcell_backtrace = ["accountable-refcell"]
|
||||
uwp = ["js/uwp"]
|
||||
xr-profile = ["webxr-api/profile"]
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -26,7 +26,6 @@ no-wgl = ["canvas/no-wgl"]
|
|||
no_static_freetype = ["webrender/no_static_freetype"]
|
||||
profilemozjs = ["script/profilemozjs"]
|
||||
refcell_backtrace = ["script/refcell_backtrace"]
|
||||
uwp = ["servo_config/uwp", "script/uwp"]
|
||||
webdriver = ["webdriver_server"]
|
||||
webgl_backtrace = [
|
||||
"script/webgl_backtrace",
|
||||
|
|
|
@ -141,40 +141,8 @@ mod media_platform {
|
|||
use super::ServoMedia;
|
||||
use servo_media_gstreamer::GStreamerBackend;
|
||||
|
||||
#[cfg(feature = "uwp")]
|
||||
fn set_gstreamer_log_handler() {
|
||||
use gstreamer::{debug_add_log_function, DebugLevel};
|
||||
|
||||
debug_add_log_function(|cat, level, file, function, line, _, message| {
|
||||
let message = format!(
|
||||
"{:?} {:?} {:?}:{:?}:{:?} {:?}",
|
||||
cat.get_name(),
|
||||
level,
|
||||
file,
|
||||
line,
|
||||
function,
|
||||
message
|
||||
);
|
||||
match level {
|
||||
DebugLevel::Debug => debug!("{}", message),
|
||||
DebugLevel::Error => error!("{}", message),
|
||||
DebugLevel::Warning => warn!("{}", message),
|
||||
DebugLevel::Fixme | DebugLevel::Info => info!("{}", message),
|
||||
DebugLevel::Memdump | DebugLevel::Count | DebugLevel::Trace => {
|
||||
trace!("{}", message)
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(any(windows, target_os = "macos"))]
|
||||
pub fn init() {
|
||||
// UWP apps have the working directory set appropriately. Win32 apps
|
||||
// do not and need some assistance finding the DLLs.
|
||||
let plugin_dir = if cfg!(feature = "uwp") {
|
||||
std::path::PathBuf::new()
|
||||
} else {
|
||||
let mut plugin_dir = std::env::current_exe().unwrap();
|
||||
plugin_dir.pop();
|
||||
|
||||
|
@ -182,9 +150,6 @@ mod media_platform {
|
|||
plugin_dir.push("lib");
|
||||
}
|
||||
|
||||
plugin_dir
|
||||
};
|
||||
|
||||
let backend = match GStreamerBackend::init_with_plugins(
|
||||
plugin_dir,
|
||||
&gstreamer_plugins::GSTREAMER_PLUGINS,
|
||||
|
@ -196,10 +161,6 @@ mod media_platform {
|
|||
},
|
||||
};
|
||||
ServoMedia::init_with_backend(backend);
|
||||
#[cfg(feature = "uwp")]
|
||||
{
|
||||
set_gstreamer_log_handler();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(windows, target_os = "macos")))]
|
||||
|
|
|
@ -48,7 +48,6 @@ no_static_freetype = ["libservo/no_static_freetype"]
|
|||
no-wgl = ["libservo/no-wgl"]
|
||||
profilemozjs = ["libservo/profilemozjs"]
|
||||
refcell_backtrace = ["libservo/refcell_backtrace"]
|
||||
uwp = ["libservo/uwp", "webxr/openxr-api"]
|
||||
webdriver = ["libservo/webdriver"]
|
||||
webgl_backtrace = ["libservo/webgl_backtrace"]
|
||||
xr-profile = ["libservo/xr-profile"]
|
||||
|
|
|
@ -49,22 +49,6 @@ fn main() {
|
|||
let mut pkg_prefs = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
pkg_prefs.push("../../../resources/package-prefs.json");
|
||||
let pkg_prefs: Value = serde_json::from_reader(File::open(&pkg_prefs).unwrap()).unwrap();
|
||||
if target.contains("uwp") {
|
||||
// Assuming Hololens build
|
||||
let to_merge = pkg_prefs
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.get("hololens")
|
||||
.unwrap()
|
||||
.as_object()
|
||||
.unwrap();
|
||||
for (key, value) in to_merge.iter() {
|
||||
prefs
|
||||
.as_object_mut()
|
||||
.unwrap()
|
||||
.insert(key.clone(), value.clone());
|
||||
}
|
||||
}
|
||||
let file = File::create(&dest.join("prefs.json")).unwrap();
|
||||
serde_json::to_writer(file, &prefs).unwrap();
|
||||
}
|
||||
|
|
|
@ -267,12 +267,9 @@ pub fn init(
|
|||
|
||||
// Initialize surfman
|
||||
let connection = Connection::new().or(Err("Failed to create connection"))?;
|
||||
let adapter = match create_adapter() {
|
||||
Some(adapter) => adapter,
|
||||
None => connection
|
||||
let adapter = connection
|
||||
.create_adapter()
|
||||
.or(Err("Failed to create adapter"))?,
|
||||
};
|
||||
.or(Err("Failed to create adapter"))?;
|
||||
let surface_type = match init_opts.surfman_integration {
|
||||
SurfmanIntegration::Widget(native_widget) => {
|
||||
let native_widget = unsafe {
|
||||
|
@ -824,79 +821,6 @@ struct ServoWindowCallbacks {
|
|||
}
|
||||
|
||||
impl EmbedderMethods for ServoEmbedderCallbacks {
|
||||
#[cfg(feature = "uwp")]
|
||||
fn register_webxr(
|
||||
&mut self,
|
||||
registry: &mut webxr::MainThreadRegistry,
|
||||
embedder_proxy: EmbedderProxy,
|
||||
) {
|
||||
use ipc_channel::ipc::{self, IpcReceiver};
|
||||
use webxr::openxr;
|
||||
debug!("EmbedderMethods::register_xr");
|
||||
assert!(
|
||||
self.xr_discovery.is_none(),
|
||||
"UWP builds should not be initialized with a WebXR Discovery object"
|
||||
);
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ContextMenuCallback(EmbedderProxy);
|
||||
|
||||
struct ContextMenuFuture(IpcReceiver<ContextMenuResult>);
|
||||
|
||||
impl openxr::ContextMenuProvider for ContextMenuCallback {
|
||||
fn open_context_menu(&self) -> Box<dyn openxr::ContextMenuFuture> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.0.send((
|
||||
None,
|
||||
EmbedderMsg::ShowContextMenu(
|
||||
sender,
|
||||
Some("Would you like to exit the XR session?".into()),
|
||||
vec!["Exit".into()],
|
||||
),
|
||||
));
|
||||
|
||||
Box::new(ContextMenuFuture(receiver))
|
||||
}
|
||||
fn clone_object(&self) -> Box<dyn openxr::ContextMenuProvider> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl openxr::ContextMenuFuture for ContextMenuFuture {
|
||||
fn poll(&self) -> openxr::ContextMenuResult {
|
||||
if let Ok(result) = self.0.try_recv() {
|
||||
if let ContextMenuResult::Selected(0) = result {
|
||||
openxr::ContextMenuResult::ExitSession
|
||||
} else {
|
||||
openxr::ContextMenuResult::Dismissed
|
||||
}
|
||||
} else {
|
||||
openxr::ContextMenuResult::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if openxr::create_instance(false, false).is_ok() {
|
||||
let discovery =
|
||||
openxr::OpenXrDiscovery::new(Box::new(ContextMenuCallback(embedder_proxy)));
|
||||
registry.register(discovery);
|
||||
} else {
|
||||
let msg =
|
||||
"Cannot initialize OpenXR - please ensure runtime is installed and enabled in \
|
||||
the OpenXR developer portal app.\n\nImmersive mode will not function until \
|
||||
this error is fixed.";
|
||||
let (sender, _receiver) = ipc::channel().unwrap();
|
||||
embedder_proxy.send((
|
||||
None,
|
||||
EmbedderMsg::Prompt(
|
||||
PromptDefinition::Alert(msg.to_owned(), sender),
|
||||
PromptOrigin::Trusted,
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "uwp"))]
|
||||
fn register_webxr(
|
||||
&mut self,
|
||||
registry: &mut webxr::MainThreadRegistry,
|
||||
|
@ -1002,13 +926,3 @@ impl ResourceReaderMethods for ResourceReaderInstance {
|
|||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "uwp")]
|
||||
fn create_adapter() -> Option<Adapter> {
|
||||
webxr::openxr::create_surfman_adapter()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "uwp"))]
|
||||
fn create_adapter() -> Option<Adapter> {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ native-bluetooth = ["simpleservo/native-bluetooth"]
|
|||
no-wgl = ["simpleservo/no-wgl"]
|
||||
profilemozjs = ["simpleservo/profilemozjs"]
|
||||
refcell_backtrace = ["simpleservo/refcell_backtrace"]
|
||||
uwp = ["simpleservo/uwp"]
|
||||
webdriver = ["simpleservo/webdriver"]
|
||||
webgl_backtrace = ["simpleservo/webgl_backtrace"]
|
||||
xr-profile = ["simpleservo/xr-profile"]
|
||||
|
|
|
@ -36,9 +36,6 @@ six == 1.15
|
|||
# For sending build notifications.
|
||||
notify-py == 0.3.42
|
||||
|
||||
# For formatting C++ files.
|
||||
clang-format ~= 16.0.0
|
||||
|
||||
# A few more requirements for tidy.
|
||||
voluptuous == 0.12.1
|
||||
PyYAML == 5.4
|
||||
|
|
|
@ -143,48 +143,6 @@ class MachCommands(CommandBase):
|
|||
|
||||
env['PKG_CONFIG_ALLOW_CROSS'] = "1"
|
||||
|
||||
if self.is_uwp_build:
|
||||
# Ensure libstd is ready for the new UWP target.
|
||||
check_call(["rustup", "component", "add", "rust-src"])
|
||||
|
||||
# Don't try and build a desktop port.
|
||||
libsimpleservo = True
|
||||
|
||||
arches = {
|
||||
"aarch64": {
|
||||
"angle": "arm64",
|
||||
"gst": "ARM64",
|
||||
"gst_root": "arm64",
|
||||
},
|
||||
"x86_64": {
|
||||
"angle": "x64",
|
||||
"gst": "X86_64",
|
||||
"gst_root": "x64",
|
||||
},
|
||||
}
|
||||
arch = arches.get(target_triple.split('-')[0])
|
||||
if not arch:
|
||||
print("Unsupported UWP target.")
|
||||
sys.exit(1)
|
||||
|
||||
# Ensure that the NuGet ANGLE package containing libEGL is accessible
|
||||
# to the Rust linker.
|
||||
servo.util.append_paths_to_env(env, "LIB", angle_root(target_triple, env))
|
||||
|
||||
# Don't want to mix non-UWP libraries with vendored UWP libraries.
|
||||
if "gstreamer" in env['LIB']:
|
||||
print("Found existing GStreamer library path in LIB. Please remove it.")
|
||||
sys.exit(1)
|
||||
|
||||
# Override any existing GStreamer installation with the vendored libraries.
|
||||
env["GSTREAMER_1_0_ROOT_" + arch['gst']] = path.join(
|
||||
servo.platform.windows.get_dependency_dir("gstreamer-uwp"), arch['gst_root']
|
||||
)
|
||||
env["PKG_CONFIG_PATH"] = path.join(
|
||||
servo.platform.windows.get_dependency_dir("gstreamer-uwp"),
|
||||
arch['gst_root'], "lib", "pkgconfig"
|
||||
)
|
||||
|
||||
if 'windows' in host:
|
||||
process = subprocess.Popen('("%s" %s > nul) && "python" -c "import os; print(repr(os.environ))"' %
|
||||
(os.path.join(vs_dirs['vcdir'], "Auxiliary", "Build", "vcvarsall.bat"), "x64"),
|
||||
|
@ -448,8 +406,6 @@ class MachCommands(CommandBase):
|
|||
for lib in libs:
|
||||
print("WARNING: could not find " + lib)
|
||||
|
||||
# UWP build has its own ANGLE library that it packages.
|
||||
if not self.is_uwp_build:
|
||||
print("Packaging EGL DLLs")
|
||||
egl_libs = ["libEGL.dll", "libGLESv2.dll"]
|
||||
if not package_generated_shared_libraries(egl_libs, build_path, servo_exe_dir):
|
||||
|
@ -458,7 +414,7 @@ class MachCommands(CommandBase):
|
|||
# copy needed gstreamer DLLs in to servo.exe dir
|
||||
if has_media_stack:
|
||||
print("Packaging gstreamer DLLs")
|
||||
if not package_gstreamer_dlls(env, servo_exe_dir, target_triple, self.is_uwp_build):
|
||||
if not package_gstreamer_dlls(env, servo_exe_dir, target_triple):
|
||||
status = 1
|
||||
|
||||
# UWP app packaging already bundles all required DLLs for us.
|
||||
|
@ -507,7 +463,7 @@ class MachCommands(CommandBase):
|
|||
return status
|
||||
|
||||
@Command('clean',
|
||||
description='Clean the target/ and python/_virtualenv[version]/ and support/hololens/ directories',
|
||||
description='Clean the target/ and python/_virtualenv[version]/ directories',
|
||||
category='build')
|
||||
@CommandArgument('--manifest-path',
|
||||
default=None,
|
||||
|
@ -526,43 +482,12 @@ class MachCommands(CommandBase):
|
|||
print('Removing virtualenv directory: %s' % virtualenv_path)
|
||||
shutil.rmtree(virtualenv_path)
|
||||
|
||||
self.clean_uwp()
|
||||
|
||||
opts = ["--manifest-path", manifest_path or path.join(self.context.topdir, "Cargo.toml")]
|
||||
if verbose:
|
||||
opts += ["-v"]
|
||||
opts += params
|
||||
return check_call(["cargo", "clean"] + opts, env=self.build_env(), verbose=verbose)
|
||||
|
||||
@Command('clean-uwp',
|
||||
description='Clean the support/hololens/ directory',
|
||||
category='build')
|
||||
def clean_uwp(self):
|
||||
uwp_artifacts = [
|
||||
"support/hololens/x64/",
|
||||
"support/hololens/ARM/",
|
||||
"support/hololens/ARM64/",
|
||||
"support/hololens/ServoApp/x64/",
|
||||
"support/hololens/ServoApp/ARM/",
|
||||
"support/hololens/ServoApp/ARM64/",
|
||||
"support/hololens/ServoApp/Generated Files/",
|
||||
"support/hololens/ServoApp/BundleArtifacts/",
|
||||
"support/hololens/ServoApp/support/",
|
||||
"support/hololens/ServoApp/Debug/",
|
||||
"support/hololens/ServoApp/Release/",
|
||||
"support/hololens/packages/",
|
||||
"support/hololens/AppPackages/",
|
||||
"support/hololens/ServoApp/ServoApp.vcxproj.user",
|
||||
]
|
||||
|
||||
for uwp_artifact in uwp_artifacts:
|
||||
artifact = path.join(self.get_top_dir(), uwp_artifact)
|
||||
if path.exists(artifact):
|
||||
if path.isdir(artifact):
|
||||
shutil.rmtree(artifact)
|
||||
else:
|
||||
os.remove(artifact)
|
||||
|
||||
def notify(self, title: str, message: str):
|
||||
"""Generate desktop notification when build is complete and the
|
||||
elapsed build time was longer than 30 seconds.
|
||||
|
@ -612,36 +537,6 @@ class MachCommands(CommandBase):
|
|||
notification.send(block=False)
|
||||
|
||||
|
||||
def angle_root(target, nuget_env):
|
||||
arch = {
|
||||
"aarch64": "arm64",
|
||||
"x86_64": "x64",
|
||||
}
|
||||
angle_arch = arch[target.split('-')[0]]
|
||||
|
||||
package_name = "ANGLE.WindowsStore.Servo"
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
tree = ET.parse(os.path.join('support', 'hololens', 'ServoApp', 'packages.config'))
|
||||
root = tree.getroot()
|
||||
for package in root.iter('package'):
|
||||
if package.get('id') == package_name:
|
||||
package_version = package.get('version')
|
||||
break
|
||||
else:
|
||||
raise Exception("Couldn't locate ANGLE package")
|
||||
|
||||
angle_default_path = path.join(os.getcwd(), "support", "hololens", "packages",
|
||||
package_name + "." + package_version, "bin", "UAP", angle_arch)
|
||||
|
||||
# Nuget executable command
|
||||
nuget_app = path.join(os.getcwd(), "support", "hololens", "ServoApp.sln")
|
||||
if not os.path.exists(angle_default_path):
|
||||
check_call(['nuget.exe', 'restore', nuget_app], env=nuget_env)
|
||||
|
||||
return angle_default_path
|
||||
|
||||
|
||||
def otool(s):
|
||||
o = subprocess.Popen(['/usr/bin/otool', '-L', s], stdout=subprocess.PIPE)
|
||||
for line in map(lambda s: s.decode('ascii'), o.stdout):
|
||||
|
@ -757,7 +652,7 @@ def package_gstreamer_dylibs(cross_compilation_target, servo_bin):
|
|||
return True
|
||||
|
||||
|
||||
def package_gstreamer_dlls(env, servo_exe_dir, target, uwp):
|
||||
def package_gstreamer_dlls(env, servo_exe_dir, target):
|
||||
gst_root = servo.platform.get().gstreamer_root(cross_compilation_target=target)
|
||||
if not gst_root:
|
||||
print("Could not find GStreamer installation directory.")
|
||||
|
@ -775,28 +670,8 @@ def package_gstreamer_dlls(env, servo_exe_dir, target, uwp):
|
|||
"glib-2.0-0.dll",
|
||||
"gmodule-2.0-0.dll",
|
||||
"gobject-2.0-0.dll",
|
||||
"intl-8.dll",
|
||||
"orc-0.4-0.dll",
|
||||
"swresample-3.dll",
|
||||
"z-1.dll",
|
||||
]
|
||||
|
||||
gst_dlls += windows_dlls(uwp)
|
||||
|
||||
if uwp:
|
||||
# These come from a more recent version of ffmpeg and
|
||||
# aren't present in the official GStreamer 1.16 release.
|
||||
gst_dlls += [
|
||||
"avresample-4.dll",
|
||||
"postproc-55.dll",
|
||||
"swscale-5.dll",
|
||||
"x264-157.dll",
|
||||
]
|
||||
else:
|
||||
# These are built with MinGW and are not yet compatible
|
||||
# with UWP's restrictions.
|
||||
gst_dlls += [
|
||||
"graphene-1.0-0.dll",
|
||||
"intl-8.dll",
|
||||
"libcrypto-1_1-x64.dll",
|
||||
"libgmp-10.dll",
|
||||
"libgnutls-30.dll",
|
||||
|
@ -816,7 +691,10 @@ def package_gstreamer_dlls(env, servo_exe_dir, target, uwp):
|
|||
"libvorbisenc-2.dll",
|
||||
"libwinpthread-1.dll",
|
||||
"nice-10.dll",
|
||||
]
|
||||
"orc-0.4-0.dll",
|
||||
"swresample-3.dll",
|
||||
"z-1.dll",
|
||||
] + windows_dlls()
|
||||
|
||||
missing = []
|
||||
for gst_lib in gst_dlls:
|
||||
|
@ -831,7 +709,7 @@ def package_gstreamer_dlls(env, servo_exe_dir, target, uwp):
|
|||
return False
|
||||
|
||||
# Only copy a subset of the available plugins.
|
||||
gst_dlls = windows_plugins(uwp)
|
||||
gst_dlls = windows_plugins()
|
||||
|
||||
gst_plugin_path_root = os.environ.get("GSTREAMER_PACKAGE_PLUGIN_PATH") or gst_root
|
||||
gst_plugin_path = path.join(gst_plugin_path_root, "lib", "gstreamer-1.0")
|
||||
|
@ -868,7 +746,7 @@ def package_msvc_dlls(servo_exe_dir, target, vcinstalldir, vs_version):
|
|||
"msvcp140.dll",
|
||||
"vcruntime140.dll",
|
||||
]
|
||||
if target_arch != "aarch64" and "uwp" not in target and vs_version in ("14.0", "15.0", "16.0"):
|
||||
if target_arch != "aarch64" and vs_version in ("14.0", "15.0", "16.0"):
|
||||
msvc_deps += ["api-ms-win-crt-runtime-l1-1-0.dll"]
|
||||
|
||||
# Check if it's Visual C++ Build Tools or Visual Studio 2015
|
||||
|
|
|
@ -205,7 +205,6 @@ class CommandBase(object):
|
|||
self.context = context
|
||||
self.features = []
|
||||
self.cross_compile_target = None
|
||||
self.is_uwp_build = False
|
||||
self.is_android_build = False
|
||||
|
||||
def get_env_bool(var, default):
|
||||
|
@ -510,11 +509,6 @@ class CommandBase(object):
|
|||
extra_path += [path.join(self.msvc_package_dir("llvm"), "bin")]
|
||||
env.setdefault("CC", "clang-cl.exe")
|
||||
env.setdefault("CXX", "clang-cl.exe")
|
||||
if self.is_uwp_build:
|
||||
env.setdefault("TARGET_CFLAGS", "")
|
||||
env.setdefault("TARGET_CXXFLAGS", "")
|
||||
env["TARGET_CFLAGS"] += " -DWINAPI_FAMILY=WINAPI_FAMILY_APP"
|
||||
env["TARGET_CXXFLAGS"] += " -DWINAPI_FAMILY=WINAPI_FAMILY_APP"
|
||||
|
||||
arch = effective_target.split('-')[0]
|
||||
vcpkg_arch = {
|
||||
|
@ -523,8 +517,6 @@ class CommandBase(object):
|
|||
"aarch64": "arm64-windows",
|
||||
}
|
||||
target_arch = vcpkg_arch[arch]
|
||||
if self.is_uwp_build:
|
||||
target_arch += "-uwp"
|
||||
openssl_base_dir = path.join(self.msvc_package_dir("openssl"), target_arch)
|
||||
|
||||
# Link openssl
|
||||
|
@ -674,11 +666,6 @@ class CommandBase(object):
|
|||
help='Build for Android. If --target is not specified, this '
|
||||
'will choose a default target architecture.',
|
||||
),
|
||||
CommandArgument(
|
||||
'--uwp',
|
||||
group="Cross Compilation",
|
||||
action='store_true',
|
||||
help='Build for HoloLens (x64)'),
|
||||
CommandArgument('--win-arm64', action='store_true', help="Use arm64 Windows target"),
|
||||
CommandArgumentGroup('Feature Selection'),
|
||||
CommandArgument(
|
||||
|
@ -725,9 +712,7 @@ class CommandBase(object):
|
|||
]
|
||||
|
||||
def configuration_decorator(self, *args, **kwargs):
|
||||
self.configure_cross_compilation(
|
||||
kwargs['target'], kwargs['android'],
|
||||
kwargs['uwp'], kwargs['win_arm64'])
|
||||
self.configure_cross_compilation(kwargs['target'], kwargs['android'], kwargs['win_arm64'])
|
||||
|
||||
self.features = kwargs.get("features", None) or []
|
||||
self.configure_media_stack(kwargs['media_stack'])
|
||||
|
@ -743,15 +728,8 @@ class CommandBase(object):
|
|||
self,
|
||||
cross_compile_target: Optional[str],
|
||||
android: Optional[str],
|
||||
uwp: Optional[str],
|
||||
win_arm64: Optional[str]):
|
||||
# Force the UWP-enabled target if the convenience UWP flags are passed.
|
||||
if uwp and not cross_compile_target:
|
||||
if win_arm64:
|
||||
cross_compile_target = 'aarch64-uwp-windows-msvc'
|
||||
else:
|
||||
cross_compile_target = 'x86_64-uwp-windows-msvc'
|
||||
|
||||
if android is None:
|
||||
android = self.config["build"]["android"]
|
||||
if android:
|
||||
|
@ -765,7 +743,6 @@ class CommandBase(object):
|
|||
self.setup_configuration_for_android_target(cross_compile_target)
|
||||
|
||||
self.cross_compile_target = cross_compile_target
|
||||
self.is_uwp_build = uwp or (cross_compile_target and "uwp" in cross_compile_target)
|
||||
self.is_android_build = (cross_compile_target and "android" in cross_compile_target)
|
||||
|
||||
if self.cross_compile_target:
|
||||
|
@ -783,7 +760,6 @@ class CommandBase(object):
|
|||
not self.cross_compile_target
|
||||
or ("armv7" in self.cross_compile_target and self.is_android_build)
|
||||
or "x86_64" in self.cross_compile_target
|
||||
or "uwp" in self.cross_compile_target
|
||||
):
|
||||
media_stack = "gstreamer"
|
||||
else:
|
||||
|
@ -825,10 +801,6 @@ class CommandBase(object):
|
|||
|
||||
features.append("native-bluetooth")
|
||||
|
||||
if self.is_uwp_build:
|
||||
features.append("no-wgl")
|
||||
features.append("uwp")
|
||||
|
||||
if with_layout_2020 or (self.config["build"]["layout-2020"] and not with_layout_2013):
|
||||
features.append("layout-2020")
|
||||
elif "layout-2020" not in features:
|
||||
|
@ -847,8 +819,6 @@ class CommandBase(object):
|
|||
if with_debug_assertions or self.config["build"]["debug-assertions"]:
|
||||
env['RUSTFLAGS'] = env.get('RUSTFLAGS', "") + " -C debug_assertions"
|
||||
|
||||
if self.is_uwp_build:
|
||||
cargo_args += ["-Z", "build-std"]
|
||||
return self.call_rustup_run(["cargo", command] + args + cargo_args, env=env, verbose=verbose)
|
||||
|
||||
def android_support_dir(self):
|
||||
|
@ -934,7 +904,6 @@ class CommandBase(object):
|
|||
check_call(["rustup", "component", "add", "--toolchain", toolchain, component])
|
||||
|
||||
needs_toolchain_install = self.cross_compile_target \
|
||||
and not self.is_uwp_build \
|
||||
and self.cross_compile_target.encode("utf-8") not in check_output(
|
||||
["rustup", "target", "list", "--installed", "--toolchain", toolchain]
|
||||
)
|
||||
|
|
|
@ -78,18 +78,12 @@ GSTREAMER_PLUGINS = [
|
|||
]
|
||||
|
||||
|
||||
def windows_dlls(uwp):
|
||||
def windows_dlls():
|
||||
libs = list(GSTREAMER_DYLIBS)
|
||||
NON_UWP_DYLIBS = [
|
||||
"gstnet",
|
||||
"gstsctp",
|
||||
]
|
||||
if uwp:
|
||||
libs = filter(lambda x: x not in NON_UWP_DYLIBS, libs)
|
||||
return [f"{lib}-1.0-0.dll" for lib in libs]
|
||||
|
||||
|
||||
def windows_plugins(uwp):
|
||||
def windows_plugins():
|
||||
# FIXME: We should support newer gstreamer versions here that replace
|
||||
# gstvideoconvert and gstvideoscale with gstvideoconvertscale.
|
||||
libs = [
|
||||
|
@ -98,25 +92,6 @@ def windows_plugins(uwp):
|
|||
"gstvideoscale",
|
||||
"gstwasapi"
|
||||
]
|
||||
NON_UWP_PLUGINS = [
|
||||
"gstnice",
|
||||
# gst-plugins-base
|
||||
"gstogg",
|
||||
"gstopengl",
|
||||
"gstopus",
|
||||
"gstrtp",
|
||||
"gsttheora",
|
||||
"gstvorbis",
|
||||
# gst-plugins-good
|
||||
"gstmatroska",
|
||||
"gstrtpmanager",
|
||||
"gstvpx",
|
||||
# gst-plugins-bad
|
||||
"gstdtls",
|
||||
"gstwebrtc",
|
||||
]
|
||||
if uwp:
|
||||
libs = filter(lambda x: x not in NON_UWP_PLUGINS, libs)
|
||||
return [f"{lib}.dll" for lib in libs]
|
||||
|
||||
|
||||
|
@ -156,7 +131,7 @@ def write_plugin_list(target):
|
|||
if "apple-" in target:
|
||||
plugins = [os.path.basename(x) for x in macos_plugins()]
|
||||
elif '-windows-' in target:
|
||||
plugins = windows_plugins('-uwp-' in target)
|
||||
plugins = windows_plugins()
|
||||
print('''/* This is a generated file. Do not modify. */
|
||||
|
||||
pub(crate) static GSTREAMER_PLUGINS: &[&'static str] = &[
|
||||
|
|
|
@ -12,7 +12,6 @@ from __future__ import absolute_import, print_function, unicode_literals
|
|||
from datetime import datetime
|
||||
from github import Github
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
|
@ -22,7 +21,6 @@ import shutil
|
|||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import xml
|
||||
|
||||
from mach.decorators import (
|
||||
CommandArgument,
|
||||
|
@ -85,10 +83,6 @@ PACKAGES = {
|
|||
def packages_for_platform(platform):
|
||||
target_dir = get_target_dir()
|
||||
|
||||
if platform == "uwp":
|
||||
yield r'support\hololens\AppPackages\ServoApp\FirefoxReality.zip'
|
||||
return
|
||||
|
||||
for package in PACKAGES[platform]:
|
||||
yield path.join(target_dir, package)
|
||||
|
||||
|
@ -150,13 +144,8 @@ class PackageCommands(CommandBase):
|
|||
default=None,
|
||||
action='store_true',
|
||||
help='Create a local Maven repository')
|
||||
@CommandArgument('--uwp',
|
||||
default=None,
|
||||
action='append',
|
||||
help='Create an APPX package')
|
||||
@CommandArgument('--ms-app-store', default=None, action='store_true')
|
||||
def package(self, release=False, dev=False, android=None, target=None,
|
||||
flavor=None, maven=False, uwp=None, ms_app_store=False):
|
||||
flavor=None, maven=False):
|
||||
if android is None:
|
||||
android = self.config["build"]["android"]
|
||||
if target and android:
|
||||
|
@ -171,14 +160,10 @@ class PackageCommands(CommandBase):
|
|||
env = self.build_env()
|
||||
binary_path = self.get_binary_path(
|
||||
release, dev, target=target, android=android,
|
||||
simpleservo=uwp is not None
|
||||
)
|
||||
dir_to_root = self.get_top_dir()
|
||||
target_dir = path.dirname(binary_path)
|
||||
if uwp:
|
||||
vs_info = self.vs_dirs()
|
||||
build_uwp(uwp, dev, vs_info['msbuild'], ms_app_store)
|
||||
elif android:
|
||||
if android:
|
||||
android_target = self.config["android"]["target"]
|
||||
if "aarch64" in android_target:
|
||||
build_type = "Arm64"
|
||||
|
@ -698,100 +683,3 @@ class PackageCommands(CommandBase):
|
|||
update_brew(packages[0], timestamp)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def setup_uwp_signing(ms_app_store, publisher):
|
||||
# App package needs to be signed. If we find a certificate that has been installed
|
||||
# already, we use it. Otherwise we create and install a temporary certificate.
|
||||
|
||||
if ms_app_store:
|
||||
return ["/p:AppxPackageSigningEnabled=false"]
|
||||
|
||||
def run_powershell_cmd(cmd):
|
||||
try:
|
||||
return (
|
||||
subprocess
|
||||
.check_output(['powershell.exe', '-NoProfile', '-Command', cmd])
|
||||
.decode('utf-8')
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
print("ERROR: PowerShell command failed: ", cmd)
|
||||
exit(1)
|
||||
|
||||
pfx = None
|
||||
if 'CODESIGN_CERT' in os.environ:
|
||||
pfx = os.environ['CODESIGN_CERT']
|
||||
|
||||
if pfx:
|
||||
open("servo.pfx", "wb").write(base64.b64decode(pfx))
|
||||
run_powershell_cmd('Import-PfxCertificate -FilePath .\\servo.pfx -CertStoreLocation Cert:\\CurrentUser\\My')
|
||||
os.remove("servo.pfx")
|
||||
|
||||
# Powershell command that lists all certificates for publisher
|
||||
cmd = '(dir cert: -Recurse | Where-Object {$_.Issuer -eq "' + publisher + '"}).Thumbprint'
|
||||
certs = list(set(run_powershell_cmd(cmd).splitlines()))
|
||||
if not certs:
|
||||
print("No certificate installed for publisher " + publisher)
|
||||
print("Creating and installing a temporary certificate")
|
||||
# PowerShell command that creates and install signing certificate for publisher
|
||||
cmd = '(New-SelfSignedCertificate -Type Custom -Subject ' + publisher + \
|
||||
' -FriendlyName "Allizom Signing Certificate (temporary)"' + \
|
||||
' -KeyUsage DigitalSignature -CertStoreLocation "Cert:\\CurrentUser\\My"' + \
|
||||
' -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")).Thumbprint'
|
||||
thumbprint = run_powershell_cmd(cmd)
|
||||
elif len(certs) > 1:
|
||||
print("Warning: multiple signing certificate are installed for " + publisher)
|
||||
print("Warning: Using first one")
|
||||
thumbprint = certs[0]
|
||||
else:
|
||||
thumbprint = certs[0]
|
||||
return ["/p:AppxPackageSigningEnabled=true", "/p:PackageCertificateThumbprint=" + thumbprint]
|
||||
|
||||
|
||||
def build_uwp(platforms, dev, msbuild_dir, ms_app_store):
|
||||
if any(map(lambda p: p not in ['x64', 'x86', 'arm64'], platforms)):
|
||||
raise Exception("Unsupported appx platforms: " + str(platforms))
|
||||
if dev and len(platforms) > 1:
|
||||
raise Exception("Debug package with multiple architectures is unsupported")
|
||||
|
||||
if dev:
|
||||
Configuration = "Debug"
|
||||
else:
|
||||
Configuration = "Release"
|
||||
|
||||
# Parse appxmanifest to find the publisher name and version
|
||||
manifest_file = path.join(os.getcwd(), 'support', 'hololens', 'ServoApp', 'Package.appxmanifest')
|
||||
manifest = xml.etree.ElementTree.parse(manifest_file)
|
||||
namespace = "{http://schemas.microsoft.com/appx/manifest/foundation/windows10}"
|
||||
identity = manifest.getroot().find(namespace + "Identity")
|
||||
publisher = identity.attrib["Publisher"]
|
||||
version = identity.attrib["Version"]
|
||||
|
||||
msbuild = path.join(msbuild_dir, "msbuild.exe")
|
||||
build_file_template = path.join('support', 'hololens', 'package.msbuild')
|
||||
with open(build_file_template) as f:
|
||||
template_contents = f.read()
|
||||
build_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
build_file.write(
|
||||
template_contents
|
||||
.replace("%%BUILD_PLATFORMS%%", ';'.join(platforms))
|
||||
.replace("%%PACKAGE_PLATFORMS%%", '|'.join(platforms))
|
||||
.replace("%%CONFIGURATION%%", Configuration)
|
||||
.replace("%%SOLUTION%%", path.join(os.getcwd(), 'support', 'hololens', 'ServoApp.sln'))
|
||||
.encode('utf-8')
|
||||
)
|
||||
build_file.close()
|
||||
# Generate an appxbundle.
|
||||
msbuild_args = setup_uwp_signing(ms_app_store, publisher)
|
||||
subprocess.check_call([msbuild, "/m", build_file.name] + msbuild_args)
|
||||
os.unlink(build_file.name)
|
||||
|
||||
# Don't bother creating an archive that contains unsigned app packages.
|
||||
if not ms_app_store:
|
||||
print("Creating ZIP")
|
||||
out_dir = path.join(os.getcwd(), 'support', 'hololens', 'AppPackages', 'ServoApp')
|
||||
name = 'ServoApp_%s_%sTest' % (version, 'Debug_' if dev else '')
|
||||
artifacts_dir = path.join(out_dir, name)
|
||||
zip_path = path.join(out_dir, "FirefoxReality.zip")
|
||||
archive_deterministically(artifacts_dir, zip_path, prepend_path='servo/')
|
||||
print("Packaged Servo into " + zip_path)
|
||||
|
|
|
@ -25,14 +25,9 @@ class Base:
|
|||
def set_gstreamer_environment_variables_if_necessary(
|
||||
self, env: Dict[str, str], cross_compilation_target: Optional[str], check_installation=True
|
||||
):
|
||||
# Environment variables are not needed when cross-compiling on any
|
||||
# platform other than Windows. UWP doesn't support GStreamer. GStreamer
|
||||
# for Android is handled elsewhere.
|
||||
if cross_compilation_target and (
|
||||
not self.is_windows
|
||||
or "uwp" in cross_compilation_target
|
||||
or "android" in cross_compilation_target
|
||||
):
|
||||
# Environment variables are not needed when cross-compiling on any platform other
|
||||
# than Windows. GStreamer for Android is handled elsewhere.
|
||||
if cross_compilation_target and (not self.is_windows or "android" in cross_compilation_target):
|
||||
return
|
||||
|
||||
# We may not need to update environment variables if GStreamer is installed
|
||||
|
|
|
@ -22,8 +22,6 @@ DEPENDENCIES = {
|
|||
"llvm": "15.0.5",
|
||||
"moztools": "3.2",
|
||||
"openssl": "111.3.0+1.1.1c-vs2017-2019-09-18",
|
||||
"gstreamer-uwp": "1.16.0.5",
|
||||
"openxr-loader-uwp": "1.0",
|
||||
}
|
||||
|
||||
URL_BASE = "https://gstreamer.freedesktop.org/data/pkg/windows/1.16.0/"
|
||||
|
|
|
@ -36,10 +36,7 @@ from mach.decorators import (
|
|||
import servo.util
|
||||
import tidy
|
||||
|
||||
from servo.command_base import (
|
||||
CommandBase,
|
||||
call, check_call, check_output,
|
||||
)
|
||||
from servo.command_base import CommandBase, call, check_call
|
||||
from servo.util import delete
|
||||
from distutils.dir_util import copy_tree
|
||||
|
||||
|
@ -48,9 +45,6 @@ PROJECT_TOPLEVEL_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, "..", ".."))
|
|||
WEB_PLATFORM_TESTS_PATH = os.path.join("tests", "wpt", "tests")
|
||||
SERVO_TESTS_PATH = os.path.join("tests", "wpt", "mozilla", "tests")
|
||||
|
||||
CLANGFMT_CPP_DIRS = ["support/hololens/"]
|
||||
CLANGFMT_VERSION = "15"
|
||||
|
||||
TEST_SUITES = OrderedDict([
|
||||
("wpt", {"kwargs": {"release": False},
|
||||
"paths": [path.abspath(WEB_PLATFORM_TESTS_PATH),
|
||||
|
@ -301,14 +295,10 @@ class MachCommands(CommandBase):
|
|||
self.install_rustfmt()
|
||||
rustfmt_failed = self.call_rustup_run(["cargo", "fmt", "--", "--check"])
|
||||
|
||||
print("Checking C++ files for tidiness...")
|
||||
env = self.build_env()
|
||||
clangfmt_failed = not run_clang_format(env, ["--dry-run", "--Werror"])
|
||||
|
||||
if rustfmt_failed or clangfmt_failed:
|
||||
if rustfmt_failed:
|
||||
print("Run `./mach fmt` to fix the formatting")
|
||||
|
||||
return tidy_failed or manifest_dirty or rustfmt_failed or clangfmt_failed
|
||||
return tidy_failed or manifest_dirty or rustfmt_failed
|
||||
|
||||
@Command('test-scripts',
|
||||
description='Run tests for all build and support scripts.',
|
||||
|
@ -414,12 +404,9 @@ class MachCommands(CommandBase):
|
|||
return wpt.manifestupdate.update(check_clean=False)
|
||||
|
||||
@Command('fmt',
|
||||
description='Format the Rust and CPP source files with rustfmt and clang-format',
|
||||
description='Format the Rust and CPP source files with rustfmt',
|
||||
category='testing')
|
||||
def format_code(self):
|
||||
env = self.build_env()
|
||||
run_clang_format(env, ['-i'])
|
||||
|
||||
self.install_rustfmt()
|
||||
return self.call_rustup_run(["cargo", "fmt"])
|
||||
|
||||
|
@ -613,20 +600,6 @@ class MachCommands(CommandBase):
|
|||
[run_file, "|".join(tests), bin_path, base_dir])
|
||||
|
||||
|
||||
def run_clang_format(env, args):
|
||||
gitfiles = check_output(
|
||||
['git', 'ls-files'] + CLANGFMT_CPP_DIRS,
|
||||
universal_newlines=True).splitlines()
|
||||
files = [line for line in gitfiles if line.endswith(".h") or line.endswith(".cpp")]
|
||||
clang_cmd = "clang-format.exe" if sys.platform == "win32" else "clang-format"
|
||||
|
||||
if not files:
|
||||
return True
|
||||
|
||||
returncode = call([clang_cmd] + args + files, env=env)
|
||||
return returncode == 0
|
||||
|
||||
|
||||
def create_parser_create():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser()
|
||||
|
|
|
@ -5,13 +5,6 @@
|
|||
"linux": {},
|
||||
"android": {},
|
||||
"windows": {},
|
||||
"hololens": {
|
||||
"_comment": "settings specific to Hololens/UWP builds",
|
||||
"devtools.server.enabled": true,
|
||||
"dom.webxr.enabled": true,
|
||||
"shell.homepage": "https://servo.org/hl-home/",
|
||||
"gfx.subpixel-text-antialiasing.enabled": false
|
||||
},
|
||||
"vr": {
|
||||
"_comment": "settings specific to VR builds",
|
||||
"dom.webvr.enabled": true,
|
||||
|
|
|
@ -134,7 +134,6 @@ files = [
|
|||
directories = [
|
||||
# Upstream
|
||||
"./support/android/apk",
|
||||
"./support/hololens",
|
||||
"./tests/wpt/harness",
|
||||
"./tests/wpt/tests",
|
||||
"./tests/wpt/mozilla/tests/mozilla/referrer-policy",
|
||||
|
|
4
support/hololens/.gitignore
vendored
|
@ -1,4 +0,0 @@
|
|||
/Generated Files
|
||||
ServoApp.vcxproj.user
|
||||
bin
|
||||
obj
|
|
@ -1,35 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.705
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ServoApp", "ServoApp\ServoApp.vcxproj", "{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Debug|x64.Build.0 = Debug|x64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Release|x64.ActiveCfg = Release|x64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Release|x64.Build.0 = Release|x64
|
||||
{0EAB7D8B-97FD-4C92-8BB2-D5691B3D5ABD}.Release|x64.Deploy.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E7A46429-FCAF-424D-B65F-A6395E915F23}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,117 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pch.h"
|
||||
#include "App.h"
|
||||
#include "BrowserPage.h"
|
||||
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::ApplicationModel::Activation;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
using namespace winrt::ServoApp;
|
||||
using namespace winrt::ServoApp::implementation;
|
||||
|
||||
App::App() {
|
||||
InitializeComponent();
|
||||
Suspending({this, &App::OnSuspending});
|
||||
|
||||
#if defined _DEBUG && \
|
||||
!defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
|
||||
UnhandledException(
|
||||
[this](IInspectable const &, UnhandledExceptionEventArgs const &e) {
|
||||
if (IsDebuggerPresent()) {
|
||||
auto errorMessage = e.Message();
|
||||
__debugbreak();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void App::createRootFrame(
|
||||
Frame &rootFrame, bool prelaunchActivated,
|
||||
winrt::Windows::Foundation::IInspectable const &args) {
|
||||
auto content = Window::Current().Content();
|
||||
if (content) {
|
||||
rootFrame = content.try_as<Frame>();
|
||||
}
|
||||
|
||||
if (rootFrame == nullptr) {
|
||||
rootFrame = Frame();
|
||||
|
||||
rootFrame.NavigationFailed({this, &App::OnNavigationFailed});
|
||||
|
||||
if (prelaunchActivated == false) {
|
||||
if (rootFrame.Content() == nullptr) {
|
||||
rootFrame.Navigate(xaml_typename<ServoApp::BrowserPage>(), args);
|
||||
}
|
||||
Window::Current().Content(rootFrame);
|
||||
Window::Current().Activate();
|
||||
}
|
||||
} else {
|
||||
if (prelaunchActivated == false) {
|
||||
if (rootFrame.Content() == nullptr) {
|
||||
rootFrame.Navigate(xaml_typename<ServoApp::BrowserPage>(), args);
|
||||
}
|
||||
Window::Current().Activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void App::OnLaunched(LaunchActivatedEventArgs const &e) {
|
||||
Frame rootFrame{nullptr};
|
||||
this->createRootFrame(rootFrame, e.PrelaunchActivated(),
|
||||
box_value(e.Arguments()));
|
||||
}
|
||||
|
||||
void App::OnActivated(IActivatedEventArgs const &args) {
|
||||
if (args.Kind() == Windows::ApplicationModel::Activation::ActivationKind::
|
||||
CommandLineLaunch) {
|
||||
auto cmdLineArgs{args.as<Windows::ApplicationModel::Activation::
|
||||
CommandLineActivatedEventArgs>()};
|
||||
auto cmdLineStr = cmdLineArgs.Operation().Arguments();
|
||||
Frame rootFrame{nullptr};
|
||||
this->createRootFrame(rootFrame, false, nullptr);
|
||||
auto page = rootFrame.Content().try_as<BrowserPage>();
|
||||
page->SetArgs(cmdLineStr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Kind() ==
|
||||
Windows::ApplicationModel::Activation::ActivationKind::Protocol) {
|
||||
auto protocolActivatedEventArgs{args.as<
|
||||
Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs>()};
|
||||
|
||||
Frame rootFrame{nullptr};
|
||||
|
||||
auto content = Window::Current().Content();
|
||||
bool isRunning = content != nullptr;
|
||||
if (!isRunning) {
|
||||
this->createRootFrame(rootFrame, false, nullptr);
|
||||
} else {
|
||||
rootFrame = content.try_as<Frame>();
|
||||
}
|
||||
auto page = rootFrame.Content().try_as<BrowserPage>();
|
||||
page->LoadFXRURI(protocolActivatedEventArgs.Uri());
|
||||
}
|
||||
}
|
||||
|
||||
void App::OnSuspending(IInspectable const &, SuspendingEventArgs const &) {
|
||||
// FIXME: Apps can be suspended for various reasons, not just closing them.
|
||||
// * Figure out how to save state like the current URL so it can be
|
||||
// restored if necessary.
|
||||
// * Determine if the user has actually closed the app and shutdown.
|
||||
/*auto content = Window::Current().Content();
|
||||
Frame rootFrame = content.try_as<Frame>();
|
||||
auto page = rootFrame.Content().try_as<BrowserPage>();
|
||||
page->Shutdown();*/
|
||||
}
|
||||
|
||||
void App::OnNavigationFailed(IInspectable const &,
|
||||
NavigationFailedEventArgs const &e) {
|
||||
throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") +
|
||||
e.SourcePageType().Name);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
#include "App.xaml.g.h"
|
||||
|
||||
namespace winrt::ServoApp::implementation {
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::ApplicationModel::Activation;
|
||||
|
||||
struct App : AppT<App> {
|
||||
App();
|
||||
|
||||
void createRootFrame(Controls::Frame &, bool, IInspectable const &);
|
||||
void OnLaunched(LaunchActivatedEventArgs const &);
|
||||
void OnActivated(IActivatedEventArgs const &);
|
||||
void OnSuspending(IInspectable const &, SuspendingEventArgs const &);
|
||||
void OnNavigationFailed(IInspectable const &,
|
||||
Navigation::NavigationFailedEventArgs const &);
|
||||
};
|
||||
} // namespace winrt::ServoApp::implementation
|
|
@ -1,3 +0,0 @@
|
|||
namespace ServoApp
|
||||
{
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<Application
|
||||
x:Class="ServoApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ServoApp">
|
||||
|
||||
<Application.Resources>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
</Application.Resources>
|
||||
|
||||
</Application>
|
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 156 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 160 KiB |
Before Width: | Height: | Size: 446 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 146 KiB |
Before Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 9 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 154 KiB |
|
@ -1,100 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pch.h"
|
||||
#include "Bookmarks.h"
|
||||
|
||||
namespace winrt::servo {
|
||||
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Data::Json;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
|
||||
Bookmarks::Bookmarks() {
|
||||
db = winrt::single_threaded_observable_vector<IInspectable>();
|
||||
auto x = Concurrency::create_task([=] {
|
||||
auto storageFolder = ApplicationData::Current().LocalFolder();
|
||||
auto bm_file = storageFolder.GetFileAsync(L"bookmarks.json").get();
|
||||
bool file_exist =
|
||||
storageFolder.TryGetItemAsync(L"bookmarks.json").get() != nullptr;
|
||||
if (file_exist) {
|
||||
auto content = FileIO::ReadTextAsync(bm_file).get();
|
||||
JsonValue out = JsonValue::Parse(L"[]");
|
||||
if (!JsonValue::TryParse(content, out)) {
|
||||
return;
|
||||
}
|
||||
auto list = out.GetArray();
|
||||
std::vector<IInspectable> bookmarks;
|
||||
for (auto value : list) {
|
||||
auto obj = value.GetObject();
|
||||
auto name = obj.GetNamedString(L"name");
|
||||
auto url = obj.GetNamedString(L"url");
|
||||
bookmarks.push_back(box_value(ServoApp::Bookmark(url, name)));
|
||||
}
|
||||
auto dispatcher = CoreApplication::MainView().CoreWindow().Dispatcher();
|
||||
dispatcher.RunAsync(CoreDispatcherPriority::High, [=] {
|
||||
db.ReplaceAll(bookmarks);
|
||||
BuildIndex();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool Bookmarks::Contains(const hstring &url) { return mIndex.count(url) > 0; }
|
||||
|
||||
void Bookmarks::Set(hstring url, hstring title) {
|
||||
auto bm = box_value(ServoApp::Bookmark(url, title));
|
||||
if (Contains(url)) {
|
||||
auto index = mIndex.at(url);
|
||||
db.SetAt(index, bm);
|
||||
} else {
|
||||
db.Append(bm);
|
||||
}
|
||||
InvalidateDB();
|
||||
}
|
||||
|
||||
hstring Bookmarks::GetName(const hstring &url) {
|
||||
auto index = mIndex.at(url);
|
||||
ServoApp::Bookmark bm = unbox_value<ServoApp::Bookmark>(db.GetAt(index));
|
||||
return bm.Name();
|
||||
}
|
||||
|
||||
void Bookmarks::Delete(const hstring &url) {
|
||||
auto index = mIndex.at(url);
|
||||
db.RemoveAt(index);
|
||||
InvalidateDB();
|
||||
}
|
||||
|
||||
void Bookmarks::BuildIndex() {
|
||||
mIndex.clear();
|
||||
int i = 0;
|
||||
for (auto bm : db) {
|
||||
auto url = unbox_value<ServoApp::Bookmark>(bm).Url();
|
||||
mIndex.insert_or_assign(url, i++);
|
||||
}
|
||||
}
|
||||
|
||||
void Bookmarks::InvalidateDB() {
|
||||
BuildIndex();
|
||||
WriteSettings();
|
||||
}
|
||||
|
||||
IAsyncAction Bookmarks::WriteSettings() {
|
||||
auto storageFolder = ApplicationData::Current().LocalFolder();
|
||||
auto file = co_await storageFolder.CreateFileAsync(
|
||||
L"bookmarks.json", CreationCollisionOption::ReplaceExisting);
|
||||
JsonArray list;
|
||||
for (auto boxed_bm : db) {
|
||||
auto bm = unbox_value<ServoApp::Bookmark>(boxed_bm);
|
||||
JsonObject bookmark;
|
||||
bookmark.Insert(L"name", JsonValue::CreateStringValue(bm.Name()));
|
||||
bookmark.Insert(L"url", JsonValue::CreateStringValue(bm.Url()));
|
||||
list.Append(bookmark);
|
||||
}
|
||||
FileIO::WriteTextAsync(file, list.Stringify());
|
||||
}
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,38 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
#include "Bookmark.g.h"
|
||||
|
||||
namespace winrt::servo {
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
|
||||
class Bookmarks {
|
||||
|
||||
public:
|
||||
Bookmarks();
|
||||
bool Contains(const hstring &url);
|
||||
hstring GetName(const hstring &url);
|
||||
void Set(hstring url, hstring title);
|
||||
void Delete(const hstring &url);
|
||||
const Collections::IObservableVector<IInspectable> &TemplateSource() {
|
||||
return db;
|
||||
};
|
||||
|
||||
private:
|
||||
IAsyncAction WriteSettings();
|
||||
void BuildIndex();
|
||||
void InvalidateDB();
|
||||
// Array of Bookmarks as defined in the IDL
|
||||
// An IObservableMap would be better, but this is not supported in XAML+winrt:
|
||||
// See https://github.com/microsoft/microsoft-ui-xaml/issues/1612
|
||||
Collections::IObservableVector<IInspectable> db;
|
||||
// ... so we have an additional map that link a url to the index in the array:
|
||||
std::map<hstring, int> mIndex;
|
||||
};
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,544 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pch.h"
|
||||
#include "strutils.h"
|
||||
#include "BrowserPage.h"
|
||||
#include "BrowserPage.g.cpp"
|
||||
#include "Bookmark.g.cpp"
|
||||
#include "ConsoleLog.g.cpp"
|
||||
#include "Devtools/Client.h"
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::ViewManagement;
|
||||
using namespace winrt::Windows::ApplicationModel::Core;
|
||||
using namespace winrt::Windows::ApplicationModel::Resources;
|
||||
using namespace winrt::Windows::ApplicationModel::Resources::Core;
|
||||
using namespace winrt::Windows::UI::Notifications;
|
||||
using namespace winrt::Windows::Data::Json;
|
||||
using namespace winrt::Windows::Data::Xml::Dom;
|
||||
using namespace winrt::Windows::Storage;
|
||||
using namespace winrt::servo;
|
||||
|
||||
namespace winrt::ServoApp::implementation {
|
||||
|
||||
BrowserPage::BrowserPage() {
|
||||
InitializeComponent();
|
||||
BindServoEvents();
|
||||
mLogs = winrt::single_threaded_observable_vector<IInspectable>();
|
||||
|
||||
auto ctx = ResourceContext::GetForCurrentView();
|
||||
auto current = ResourceManager::Current();
|
||||
auto tree = current.MainResourceMap().GetSubtree(L"PromotedPrefs");
|
||||
for (auto s : tree) {
|
||||
hstring k = s.Key();
|
||||
std::wstring wk = k.c_str();
|
||||
std::replace(wk.begin(), wk.end(), '/', '.');
|
||||
hstring v = s.Value().Resolve(ctx).ValueAsString();
|
||||
mPromotedPrefs.insert(std::pair(wk, v));
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::BindServoEvents() {
|
||||
servoView().OnURLChanged([=](const auto &, hstring url) {
|
||||
mCurrentUrl = url;
|
||||
urlTextbox().Text(url);
|
||||
UpdateBookmarkPanel();
|
||||
});
|
||||
servoView().OnTitleChanged([=](const auto &, hstring title) {
|
||||
if (title.size() > 0) {
|
||||
mCurrentTitle = {title};
|
||||
} else {
|
||||
mCurrentTitle = {};
|
||||
}
|
||||
UpdateBookmarkPanel();
|
||||
});
|
||||
servoView().OnHistoryChanged([=](bool back, bool forward) {
|
||||
backButton().IsEnabled(back);
|
||||
forwardButton().IsEnabled(forward);
|
||||
});
|
||||
servoView().OnServoPanic([=](const auto &, hstring /*message*/) {
|
||||
mPanicking = true;
|
||||
CheckCrashReport();
|
||||
});
|
||||
servoView().OnLoadStarted([=] {
|
||||
mCurrentUrl = {};
|
||||
mCurrentTitle = {};
|
||||
urlbarLoadingIndicator().IsActive(true);
|
||||
transientLoadingIndicator().IsIndeterminate(true);
|
||||
reloadButton().IsEnabled(false);
|
||||
reloadButton().Visibility(Visibility::Collapsed);
|
||||
stopButton().IsEnabled(true);
|
||||
stopButton().Visibility(Visibility::Visible);
|
||||
devtoolsButton().IsEnabled(true);
|
||||
CheckCrashReport();
|
||||
UpdateBookmarkPanel();
|
||||
});
|
||||
servoView().OnLoadEnded([=] {
|
||||
urlbarLoadingIndicator().IsActive(false);
|
||||
transientLoadingIndicator().IsIndeterminate(false);
|
||||
reloadButton().IsEnabled(true);
|
||||
reloadButton().Visibility(Visibility::Visible);
|
||||
stopButton().IsEnabled(false);
|
||||
stopButton().Visibility(Visibility::Collapsed);
|
||||
});
|
||||
bookmarkPanel().Opening([=](const auto &, const auto &) {
|
||||
if (!mCurrentUrl.has_value()) {
|
||||
return;
|
||||
}
|
||||
hstring url = *mCurrentUrl;
|
||||
auto resourceLoader = ResourceLoader::GetForCurrentView();
|
||||
if (!mBookmarks.Contains(url)) {
|
||||
auto label = resourceLoader.GetString(L"bookmarkPanel/addedTitle");
|
||||
bookmarkPanelLabel().Text(label);
|
||||
mBookmarks.Set(url, bookmarkPanelTitle().Text());
|
||||
} else {
|
||||
auto label = resourceLoader.GetString(L"bookmarkPanel/editTitle");
|
||||
bookmarkPanelLabel().Text(label);
|
||||
}
|
||||
bookmarkPanelTitle().SelectAll();
|
||||
});
|
||||
servoView().OnCaptureGesturesStarted([=] {
|
||||
servoView().Focus(FocusState::Programmatic);
|
||||
navigationBar().IsHitTestVisible(false);
|
||||
});
|
||||
servoView().OnCaptureGesturesEnded(
|
||||
[=] { navigationBar().IsHitTestVisible(true); });
|
||||
urlTextbox().GotFocus(std::bind(&BrowserPage::OnURLFocused, this, _1));
|
||||
servoView().OnMediaSessionMetadata(
|
||||
[=](hstring /*title*/, hstring /*artist*/, hstring /*album*/) {});
|
||||
servoView().OnMediaSessionPosition(
|
||||
[=](double /*duration*/, double /*position*/, double /*rate*/) {});
|
||||
servoView().OnMediaSessionPlaybackStateChange([=](const auto &, int state) {
|
||||
if (state == Servo::MediaSessionPlaybackState::None) {
|
||||
mediaControls().Visibility(Visibility::Collapsed);
|
||||
return;
|
||||
}
|
||||
mediaControls().Visibility(Visibility::Visible);
|
||||
playButton().Visibility(state == Servo::MediaSessionPlaybackState::Paused
|
||||
? Visibility::Visible
|
||||
: Visibility::Collapsed);
|
||||
pauseButton().Visibility(state == Servo::MediaSessionPlaybackState::Paused
|
||||
? Visibility::Collapsed
|
||||
: Visibility::Visible);
|
||||
});
|
||||
servoView().OnDevtoolsStatusChanged(
|
||||
[=](DevtoolsStatus status, unsigned int port, hstring token) {
|
||||
mDevtoolsStatus = status;
|
||||
mDevtoolsPort = port;
|
||||
mDevtoolsToken = token;
|
||||
});
|
||||
Window::Current().VisibilityChanged(
|
||||
[=](const auto &, const VisibilityChangedEventArgs &args) {
|
||||
servoView().ChangeVisibility(args.Visible());
|
||||
});
|
||||
|
||||
auto obsBM =
|
||||
mBookmarks.TemplateSource().as<IObservableVector<IInspectable>>();
|
||||
obsBM.VectorChanged(std::bind(&BrowserPage::OnBookmarkDBChanged, this));
|
||||
}
|
||||
|
||||
void BrowserPage::OnURLFocused(IInspectable const &) {
|
||||
urlTextbox().SelectAll();
|
||||
}
|
||||
|
||||
void BrowserPage::OnURLKeyboardAccelerator(
|
||||
IInspectable const &, Input::KeyboardAcceleratorInvokedEventArgs const &) {
|
||||
urlTextbox().Focus(FocusState::Programmatic);
|
||||
}
|
||||
|
||||
void BrowserPage::LoadFXRURI(Uri uri) {
|
||||
auto scheme = uri.SchemeName();
|
||||
std::wstring raw{uri.RawUri()};
|
||||
if (scheme == FXR_SCHEME) {
|
||||
auto raw2 = raw.substr(FXR_SCHEME_SLASH_SLASH.size());
|
||||
servoView().LoadURIOrSearch(raw2);
|
||||
SetTransientMode(false);
|
||||
} else if (scheme == FXRMIN_SCHEME) {
|
||||
auto raw2 = raw.substr(FXRMIN_SCHEME_SLASH_SLASH.size());
|
||||
servoView().LoadURIOrSearch(raw2);
|
||||
SetTransientMode(true);
|
||||
} else {
|
||||
log(L"Unexpected URL: ", uri.RawUri().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::SetTransientMode(bool transient) {
|
||||
servoView().SetTransientMode(transient);
|
||||
navigationBar().Visibility(transient ? Visibility::Collapsed
|
||||
: Visibility::Visible);
|
||||
transientLoadingIndicator().Visibility(transient ? Visibility::Visible
|
||||
: Visibility::Collapsed);
|
||||
}
|
||||
|
||||
void BrowserPage::SetArgs(hstring args) { servoView().SetArgs(args); }
|
||||
|
||||
void BrowserPage::Shutdown() { servoView().Shutdown(); }
|
||||
|
||||
/**** USER INTERACTIONS WITH UI ****/
|
||||
|
||||
void BrowserPage::OnBackButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
servoView().GoBack();
|
||||
}
|
||||
|
||||
void BrowserPage::OnForwardButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
servoView().GoForward();
|
||||
}
|
||||
|
||||
void BrowserPage::OnReloadButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
servoView().Reload();
|
||||
}
|
||||
|
||||
void BrowserPage::OnStopButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
servoView().Stop();
|
||||
}
|
||||
|
||||
void BrowserPage::OnHomeButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
servoView().GoHome();
|
||||
}
|
||||
|
||||
// Given a pref, update its associated UI control.
|
||||
void BrowserPage::UpdatePref(ServoApp::Pref pref, Controls::Control ctrl) {
|
||||
auto value = pref.Value();
|
||||
auto type = value.as<IPropertyValue>().Type();
|
||||
if (type == PropertyType::Boolean) {
|
||||
ctrl.as<Controls::CheckBox>().IsChecked(unbox_value<bool>(value));
|
||||
} else if (type == PropertyType::Double) {
|
||||
ctrl.as<Microsoft::UI::Xaml::Controls::NumberBox>().Value(
|
||||
unbox_value<double>(value));
|
||||
} else if (type == PropertyType::Int64) {
|
||||
ctrl.as<Microsoft::UI::Xaml::Controls::NumberBox>().Value(
|
||||
(double)unbox_value<int64_t>(value));
|
||||
} else if (type == PropertyType::String) {
|
||||
ctrl.as<Controls::TextBox>().Text(unbox_value<hstring>(value));
|
||||
}
|
||||
auto stack = ctrl.Parent().as<Controls::StackPanel>();
|
||||
auto font = winrt::Windows::UI::Text::FontWeights::Normal();
|
||||
if (!pref.IsDefault()) {
|
||||
font = winrt::Windows::UI::Text::FontWeights::Bold();
|
||||
}
|
||||
stack.Children().GetAt(0).as<Controls::TextBlock>().FontWeight(font);
|
||||
stack.Children().GetAt(2).as<Controls::Button>().IsEnabled(!pref.IsDefault());
|
||||
}
|
||||
|
||||
void BrowserPage::OnSeeAllPrefClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
BuildPrefList();
|
||||
}
|
||||
|
||||
// Retrieve the preference list from Servo and build the preference table.
|
||||
void BrowserPage::BuildPrefList() {
|
||||
prefList().Children().Clear();
|
||||
bool promoted = !seeAllPrefCheckBox().IsChecked().GetBoolean();
|
||||
preferenceSearchbox().Visibility(promoted ? Visibility::Collapsed
|
||||
: Visibility::Visible);
|
||||
preferenceSearchbox().Text(L"");
|
||||
// It would be better to use a template and bindings, but the
|
||||
// <ListView> takes too long to generate all the items, and
|
||||
// it's pretty difficiult to have different controls depending
|
||||
// on the pref type.
|
||||
auto resourceLoader = ResourceLoader::GetForCurrentView();
|
||||
auto resetStr =
|
||||
resourceLoader.GetString(L"devtoolsPreferenceResetButton/Content");
|
||||
for (auto pref : servoView().Preferences()) {
|
||||
std::optional<hstring> description = {};
|
||||
if (promoted) {
|
||||
auto search = mPromotedPrefs.find(pref.Key());
|
||||
if (search == mPromotedPrefs.end()) {
|
||||
continue;
|
||||
}
|
||||
description = {search->second};
|
||||
}
|
||||
auto value = pref.Value();
|
||||
auto type = value.as<IPropertyValue>().Type();
|
||||
std::optional<Controls::Control> ctrl;
|
||||
if (type == PropertyType::Boolean) {
|
||||
auto checkbox = Controls::CheckBox();
|
||||
checkbox.IsChecked(unbox_value<bool>(value));
|
||||
checkbox.Click([=](const auto &, auto const &) {
|
||||
auto upref = servoView().SetBoolPref(pref.Key(),
|
||||
checkbox.IsChecked().GetBoolean());
|
||||
UpdatePref(upref, checkbox);
|
||||
});
|
||||
ctrl = checkbox;
|
||||
} else if (type == PropertyType::String) {
|
||||
auto textbox = Controls::TextBox();
|
||||
textbox.Text(unbox_value<hstring>(value));
|
||||
textbox.KeyUp([=](const auto &, Input::KeyRoutedEventArgs const &e) {
|
||||
if (e.Key() == Windows::System::VirtualKey::Enter) {
|
||||
auto upref = servoView().SetStringPref(pref.Key(), textbox.Text());
|
||||
UpdatePref(upref, textbox);
|
||||
}
|
||||
});
|
||||
ctrl = textbox;
|
||||
} else if (type == PropertyType::Int64) {
|
||||
// Note: These are *not* under Windows::UI:Xaml namespace.
|
||||
auto nbox = Microsoft::UI::Xaml::Controls::NumberBox();
|
||||
nbox.Value((double)unbox_value<int64_t>(value));
|
||||
nbox.SpinButtonPlacementMode(
|
||||
Microsoft::UI::Xaml::Controls::NumberBoxSpinButtonPlacementMode::
|
||||
Inline);
|
||||
nbox.ValueChanged([=](const auto &, const auto &) {
|
||||
int val = (int)nbox.Value();
|
||||
auto upref = servoView().SetIntPref(pref.Key(), val);
|
||||
UpdatePref(upref, nbox);
|
||||
});
|
||||
ctrl = nbox;
|
||||
} else if (type == PropertyType::Double) {
|
||||
auto nbox = Microsoft::UI::Xaml::Controls::NumberBox();
|
||||
nbox.Value(unbox_value<double>(value));
|
||||
nbox.ValueChanged([=](const auto &, const auto &) {
|
||||
auto upref = servoView().SetIntPref(pref.Key(), (int64_t)nbox.Value());
|
||||
UpdatePref(upref, (Controls::Control &)nbox);
|
||||
});
|
||||
ctrl = nbox;
|
||||
}
|
||||
if (ctrl.has_value()) {
|
||||
auto stack = Controls::StackPanel();
|
||||
stack.Tag(winrt::box_value(pref.Key()));
|
||||
stack.Padding({4, 4, 4, 4});
|
||||
stack.Orientation(Controls::Orientation::Horizontal);
|
||||
auto key = Controls::TextBlock();
|
||||
key.Text(promoted ? *description : pref.Key());
|
||||
key.Width(350);
|
||||
if (!pref.IsDefault()) {
|
||||
auto font = winrt::Windows::UI::Text::FontWeights::Bold();
|
||||
key.FontWeight(font);
|
||||
}
|
||||
stack.Children().Append(key);
|
||||
ctrl->Width(300);
|
||||
ctrl->Margin({4, 0, 40, 0});
|
||||
stack.Children().Append(*ctrl);
|
||||
auto reset = Controls::Button();
|
||||
reset.Content(winrt::box_value(resetStr));
|
||||
reset.IsEnabled(!pref.IsDefault());
|
||||
reset.Click([=](const auto &, auto const &) {
|
||||
auto upref = servoView().ResetPref(pref.Key());
|
||||
UpdatePref(upref, *ctrl);
|
||||
});
|
||||
stack.Children().Append(reset);
|
||||
prefList().Children().Append(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::OnPrefererenceSearchboxEdited(
|
||||
IInspectable const &, Input::KeyRoutedEventArgs const &) {
|
||||
auto input = preferenceSearchbox().Text();
|
||||
for (auto element : prefList().Children()) {
|
||||
auto ctrl = (Controls::Control &)element;
|
||||
if (input.size() == 0) {
|
||||
ctrl.Visibility(Visibility::Visible);
|
||||
} else {
|
||||
auto tag = ctrl.Tag();
|
||||
std::wstring key = static_cast<std::wstring>(unbox_value<hstring>(tag));
|
||||
bool not_found = key.find(input) == std::wstring::npos;
|
||||
ctrl.Visibility(not_found ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::ClearConsole() {
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::High, [=] { mLogs.Clear(); });
|
||||
}
|
||||
|
||||
void BrowserPage::OnDevtoolsMessage(DevtoolsMessageLevel level, hstring source,
|
||||
hstring body) {
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::High, [=] {
|
||||
auto glyphColor = UI::Colors::Transparent();
|
||||
auto glyph = L"";
|
||||
if (level == servo::DevtoolsMessageLevel::Error) {
|
||||
glyphColor = UI::Colors::Red();
|
||||
glyph = L"\xEA39"; // ErrorBadge
|
||||
} else if (level == servo::DevtoolsMessageLevel::Warn) {
|
||||
glyphColor = UI::Colors::Orange();
|
||||
glyph = L"\xE7BA"; // Warning
|
||||
}
|
||||
mLogs.Append(make<ConsoleLog>(glyphColor, glyph, body, source));
|
||||
});
|
||||
}
|
||||
|
||||
void BrowserPage::CheckCrashReport() {
|
||||
Concurrency::create_task([=] {
|
||||
auto pref = servo::Servo::GetPref(L"shell.crash_reporter.enabled");
|
||||
bool reporter_enabled = unbox_value<bool>(std::get<1>(pref));
|
||||
auto storageFolder = ApplicationData::Current().LocalFolder();
|
||||
bool file_exist =
|
||||
storageFolder.TryGetItemAsync(L"crash-report.txt").get() != nullptr;
|
||||
if (reporter_enabled && file_exist) {
|
||||
auto crash_file = storageFolder.GetFileAsync(L"crash-report.txt").get();
|
||||
auto content = FileIO::ReadTextAsync(crash_file).get();
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::High, [=] {
|
||||
auto resourceLoader = ResourceLoader::GetForCurrentView();
|
||||
auto message = resourceLoader.GetString(mPanicking ? L"crash/Happening"
|
||||
: L"crash/Happened");
|
||||
crashTabMessage().Text(message);
|
||||
crashReport().Text(content);
|
||||
crashTab().Visibility(Visibility::Visible);
|
||||
crashTab().IsSelected(true);
|
||||
ShowToolbox();
|
||||
});
|
||||
} else {
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::High, [=] {
|
||||
crashTab().Visibility(Visibility::Collapsed);
|
||||
devtoolsTabConsole().IsSelected(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void BrowserPage::OnDismissCrashReport(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
Concurrency::create_task([=] {
|
||||
auto storageFolder = ApplicationData::Current().LocalFolder();
|
||||
auto crash_file = storageFolder.GetFileAsync(L"crash-report.txt").get();
|
||||
crash_file.DeleteAsync().get();
|
||||
});
|
||||
HideToolbox();
|
||||
}
|
||||
|
||||
void BrowserPage::OnSubmitCrashReport(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
void BrowserPage::OnDevtoolsDetached() {}
|
||||
|
||||
void BrowserPage::ShowToolbox() {
|
||||
if (toolbox().Visibility() == Visibility::Visible) {
|
||||
return;
|
||||
}
|
||||
toolbox().Visibility(Visibility::Visible);
|
||||
CheckCrashReport();
|
||||
BuildPrefList();
|
||||
auto resourceLoader = ResourceLoader::GetForCurrentView();
|
||||
if (mDevtoolsStatus == DevtoolsStatus::Running) {
|
||||
hstring port = to_hstring(mDevtoolsPort);
|
||||
if (mDevtoolsClient == nullptr) {
|
||||
DevtoolsDelegate *dd = static_cast<DevtoolsDelegate *>(this);
|
||||
mDevtoolsClient = std::make_unique<DevtoolsClient>(L"localhost", port,
|
||||
mDevtoolsToken, *dd);
|
||||
}
|
||||
mDevtoolsClient->Run();
|
||||
std::wstring message =
|
||||
resourceLoader.GetString(L"devtoolsStatus/Running").c_str();
|
||||
hstring formatted{format(message, port.c_str())};
|
||||
OnDevtoolsMessage(servo::DevtoolsMessageLevel::None, L"", formatted);
|
||||
} else if (mDevtoolsStatus == DevtoolsStatus::Failed) {
|
||||
auto body = resourceLoader.GetString(L"devtoolsStatus/Failed");
|
||||
OnDevtoolsMessage(servo::DevtoolsMessageLevel::Error, L"", body);
|
||||
} else if (mDevtoolsStatus == DevtoolsStatus::Stopped) {
|
||||
auto body = resourceLoader.GetString(L"devtoolsStatus/Stopped");
|
||||
OnDevtoolsMessage(servo::DevtoolsMessageLevel::None, L"", body);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::HideToolbox() {
|
||||
prefList().Children().Clear();
|
||||
toolbox().Visibility(Visibility::Collapsed);
|
||||
ClearConsole();
|
||||
if (mDevtoolsClient != nullptr) {
|
||||
mDevtoolsClient->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::OnDevtoolsButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
if (toolbox().Visibility() == Visibility::Visible) {
|
||||
HideToolbox();
|
||||
} else {
|
||||
ShowToolbox();
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::OnBookmarkDBChanged() {
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::High,
|
||||
[=] { UpdateBookmarkPanel(); });
|
||||
}
|
||||
|
||||
void BrowserPage::UpdateBookmarkPanel() {
|
||||
if (mCurrentUrl.has_value()) {
|
||||
bookmarkButton().IsEnabled(true);
|
||||
if (mBookmarks.Contains(*mCurrentUrl)) {
|
||||
bookmarkPanelIcon().Symbol(Controls::Symbol::SolidStar);
|
||||
auto name = mBookmarks.GetName(*mCurrentUrl);
|
||||
bookmarkPanelTitle().Text(name);
|
||||
} else {
|
||||
bookmarkPanelIcon().Symbol(Controls::Symbol::OutlineStar);
|
||||
auto label = mCurrentTitle.value_or(*mCurrentUrl);
|
||||
bookmarkPanelTitle().Text(label);
|
||||
}
|
||||
} else {
|
||||
bookmarkButton().IsEnabled(false);
|
||||
}
|
||||
if (mBookmarks.TemplateSource().Size() == 0) {
|
||||
bookmarkToolbar().Visibility(Visibility::Collapsed);
|
||||
} else {
|
||||
bookmarkToolbar().Visibility(Visibility::Visible);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::OnBookmarkEdited(IInspectable const &,
|
||||
Input::KeyRoutedEventArgs const &e) {
|
||||
if (e.Key() == Windows::System::VirtualKey::Enter) {
|
||||
UpdateBookmark();
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::OnBookmarkClicked(IInspectable const &sender,
|
||||
RoutedEventArgs const &) {
|
||||
auto button = sender.as<Controls::Button>();
|
||||
auto url = winrt::unbox_value<hstring>(button.Tag());
|
||||
servoView().LoadURIOrSearch(url);
|
||||
}
|
||||
|
||||
void BrowserPage::RemoveBookmark() {
|
||||
mBookmarks.Delete(*mCurrentUrl);
|
||||
bookmarkPanel().Hide();
|
||||
}
|
||||
|
||||
void BrowserPage::UpdateBookmark() {
|
||||
mBookmarks.Set(*mCurrentUrl, bookmarkPanelTitle().Text());
|
||||
bookmarkPanel().Hide();
|
||||
}
|
||||
|
||||
void BrowserPage::OnJSInputEdited(IInspectable const &,
|
||||
Input::KeyRoutedEventArgs const &e) {
|
||||
if (e.Key() == Windows::System::VirtualKey::Enter) {
|
||||
auto input = JSInput().Text();
|
||||
JSInput().Text(L"");
|
||||
mDevtoolsClient->Evaluate(input);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::OnURLEdited(IInspectable const &,
|
||||
Input::KeyRoutedEventArgs const &e) {
|
||||
if (e.Key() == Windows::System::VirtualKey::Enter) {
|
||||
servoView().Focus(FocusState::Programmatic);
|
||||
auto input = urlTextbox().Text();
|
||||
auto uri = servoView().LoadURIOrSearch(input);
|
||||
urlTextbox().Text(uri);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserPage::OnMediaControlsPlayClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
servoView().SendMediaSessionAction(
|
||||
static_cast<int32_t>(Servo::MediaSessionActionType::Play));
|
||||
}
|
||||
void BrowserPage::OnMediaControlsPauseClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
servoView().SendMediaSessionAction(
|
||||
static_cast<int32_t>(Servo::MediaSessionActionType::Pause));
|
||||
}
|
||||
|
||||
} // namespace winrt::ServoApp::implementation
|
|
@ -1,134 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BrowserPage.g.h"
|
||||
#include "Bookmark.g.h"
|
||||
#include "ConsoleLog.g.h"
|
||||
#include "ServoControl/ServoControl.h"
|
||||
#include "Devtools/Client.h"
|
||||
#include "Bookmarks.h"
|
||||
|
||||
namespace winrt::ServoApp::implementation {
|
||||
|
||||
using namespace winrt::servo;
|
||||
using namespace winrt::Windows;
|
||||
using namespace winrt::Windows::Data::Json;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Media;
|
||||
|
||||
static const hstring FXR_SCHEME = L"fxr";
|
||||
static const hstring FXR_SCHEME_SLASH_SLASH = L"fxr://";
|
||||
static const hstring FXRMIN_SCHEME = L"fxrmin";
|
||||
static const hstring FXRMIN_SCHEME_SLASH_SLASH = L"fxrmin://";
|
||||
|
||||
struct BrowserPage : BrowserPageT<BrowserPage>, public DevtoolsDelegate {
|
||||
public:
|
||||
BrowserPage();
|
||||
|
||||
void OnForwardButtonClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnBackButtonClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnReloadButtonClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnStopButtonClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnHomeButtonClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnDevtoolsButtonClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnBookmarkClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnUpdateBookmarkButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
UpdateBookmark();
|
||||
};
|
||||
void OnRemoveBookmarkButtonClicked(IInspectable const &,
|
||||
RoutedEventArgs const &) {
|
||||
RemoveBookmark();
|
||||
};
|
||||
void OnBookmarkEdited(IInspectable const &,
|
||||
Input::KeyRoutedEventArgs const &);
|
||||
void OnJSInputEdited(IInspectable const &, Input::KeyRoutedEventArgs const &);
|
||||
void OnURLEdited(IInspectable const &, Input::KeyRoutedEventArgs const &);
|
||||
void OnSeeAllPrefClicked(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnURLFocused(IInspectable const &);
|
||||
void
|
||||
OnURLKeyboardAccelerator(IInspectable const &,
|
||||
Input::KeyboardAcceleratorInvokedEventArgs const &);
|
||||
void Shutdown();
|
||||
void LoadFXRURI(Uri uri);
|
||||
void SetArgs(hstring);
|
||||
void OnDismissCrashReport(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnSubmitCrashReport(IInspectable const &, RoutedEventArgs const &);
|
||||
void OnMediaControlsPlayClicked(IInspectable const &,
|
||||
RoutedEventArgs const &);
|
||||
void OnMediaControlsPauseClicked(IInspectable const &,
|
||||
RoutedEventArgs const &);
|
||||
void OnPrefererenceSearchboxEdited(IInspectable const &,
|
||||
Input::KeyRoutedEventArgs const &);
|
||||
void OnDevtoolsMessage(DevtoolsMessageLevel, hstring, hstring);
|
||||
void ClearConsole();
|
||||
void OnDevtoolsDetached();
|
||||
Collections::IObservableVector<IInspectable> ConsoleLogs() { return mLogs; };
|
||||
Collections::IObservableVector<IInspectable> Bookmarks() {
|
||||
return mBookmarks.TemplateSource();
|
||||
};
|
||||
void RemoveBookmark();
|
||||
void UpdateBookmark();
|
||||
|
||||
private:
|
||||
void SetTransientMode(bool);
|
||||
void UpdatePref(ServoApp::Pref, Controls::Control);
|
||||
void CheckCrashReport();
|
||||
void BindServoEvents();
|
||||
void ShowToolbox();
|
||||
void HideToolbox();
|
||||
void BuildPrefList();
|
||||
void UpdateBookmarkPanel();
|
||||
void OnBookmarkDBChanged();
|
||||
DevtoolsStatus mDevtoolsStatus = DevtoolsStatus::Stopped;
|
||||
unsigned int mDevtoolsPort = 0;
|
||||
hstring mDevtoolsToken;
|
||||
bool mPanicking = false;
|
||||
std::unique_ptr<DevtoolsClient> mDevtoolsClient;
|
||||
Collections::IObservableVector<IInspectable> mLogs;
|
||||
std::map<hstring, hstring> mPromotedPrefs;
|
||||
std::optional<hstring> mCurrentUrl;
|
||||
std::optional<hstring> mCurrentTitle;
|
||||
servo::Bookmarks mBookmarks;
|
||||
};
|
||||
|
||||
struct ConsoleLog : ConsoleLogT<ConsoleLog> {
|
||||
public:
|
||||
ConsoleLog(Windows::UI::Color glyph, hstring g, hstring b, hstring s)
|
||||
: mGlyph(g), mSource(s), mBody(b) {
|
||||
mGlyphColor = UI::Xaml::Media::SolidColorBrush(glyph);
|
||||
};
|
||||
SolidColorBrush GlyphColor() { return mGlyphColor; };
|
||||
hstring Glyph() { return mGlyph; };
|
||||
hstring Source() { return mSource; };
|
||||
hstring Body() { return mBody; };
|
||||
|
||||
private:
|
||||
SolidColorBrush mGlyphColor;
|
||||
hstring mGlyph;
|
||||
hstring mSource;
|
||||
hstring mBody;
|
||||
};
|
||||
|
||||
struct Bookmark : BookmarkT<Bookmark> {
|
||||
public:
|
||||
Bookmark(hstring url, hstring name) : mName(name), mUrl(url){};
|
||||
hstring Name() { return mName; };
|
||||
hstring Url() { return mUrl; };
|
||||
|
||||
private:
|
||||
hstring mName;
|
||||
hstring mUrl;
|
||||
};
|
||||
|
||||
} // namespace winrt::ServoApp::implementation
|
||||
|
||||
namespace winrt::ServoApp::factory_implementation {
|
||||
struct BrowserPage : BrowserPageT<BrowserPage, implementation::BrowserPage> {};
|
||||
struct ConsoleLog : ConsoleLogT<ConsoleLog, implementation::ConsoleLog> {};
|
||||
struct Bookmark : BookmarkT<Bookmark, implementation::Bookmark> {};
|
||||
} // namespace winrt::ServoApp::factory_implementation
|
|
@ -1,26 +0,0 @@
|
|||
namespace ServoApp
|
||||
{
|
||||
[default_interface]
|
||||
runtimeclass BrowserPage : Windows.UI.Xaml.Controls.Page
|
||||
{
|
||||
BrowserPage();
|
||||
Windows.Foundation.Collections.IObservableVector<IInspectable> ConsoleLogs{ get; };
|
||||
Windows.Foundation.Collections.IObservableVector<IInspectable> Bookmarks{ get; };
|
||||
}
|
||||
|
||||
runtimeclass ConsoleLog
|
||||
{
|
||||
ConsoleLog(Windows.UI.Color glyphColor, String glyph, String body, String source);
|
||||
Windows.UI.Xaml.Media.SolidColorBrush GlyphColor{ get; };
|
||||
String Glyph{ get; };
|
||||
String Body{ get; };
|
||||
String Source{ get; };
|
||||
}
|
||||
|
||||
runtimeclass Bookmark
|
||||
{
|
||||
Bookmark(String name, String url);
|
||||
String Name{ get; };
|
||||
String Url{ get; };
|
||||
}
|
||||
}
|
|
@ -1,261 +0,0 @@
|
|||
<Page
|
||||
x:Class="ServoApp.BrowserPage"
|
||||
x:Name="browserPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ServoApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<Style x:Key="NavigationBarButton" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}"/>
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Margin" Value="5,0"/>
|
||||
<Setter Property="MinWidth" Value="40"/>
|
||||
<Setter Property="MinHeight" Value="40"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
|
||||
<Setter Property="FocusVisualMargin" Value="-3"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" CornerRadius="{TemplateBinding CornerRadius}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal">
|
||||
<Storyboard>
|
||||
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Opacity">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="0.2"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</ContentPresenter>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/> <!-- navigation bar -->
|
||||
<RowDefinition Height="auto"/> <!-- bookmarks bar -->
|
||||
<RowDefinition Height="*" MinHeight="200"/> <!-- Servo -->
|
||||
<RowDefinition Height="auto"/> <!-- devtools tabs -->
|
||||
<RowDefinition Height="auto"/> <!-- loading indicator for transient mode -->
|
||||
<RowDefinition Height="auto"/> <!-- media controls -->
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" x:Name="navigationBar" Background="{ThemeResource InkToolbarButtonBackgroundThemeBrush}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Orientation="Horizontal" Grid.Column="0">
|
||||
<Button Style="{StaticResource NavigationBarButton}" x:Uid="backButton" x:Name="backButton" IsTabStop="true" IsEnabled="false" Click="OnBackButtonClicked">
|
||||
<SymbolIcon Symbol="Back"/>
|
||||
<Button.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="Left" Modifiers="Menu" />
|
||||
</Button.KeyboardAccelerators>
|
||||
</Button>
|
||||
<Button Style="{StaticResource NavigationBarButton}" x:Uid="forwardButton" x:Name="forwardButton" IsTabStop="true" IsEnabled="false" Click="OnForwardButtonClicked">
|
||||
<SymbolIcon Symbol="Forward"/>
|
||||
<Button.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="Right" Modifiers="Menu" />
|
||||
</Button.KeyboardAccelerators>
|
||||
</Button>
|
||||
<Button Style="{StaticResource NavigationBarButton}" x:Name="reloadButton" x:Uid="reloadButton" IsTabStop="true" IsEnabled="false" Visibility="Visible" Click="OnReloadButtonClicked">
|
||||
<SymbolIcon Symbol="Refresh"/>
|
||||
<Button.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="R" Modifiers="Control" />
|
||||
</Button.KeyboardAccelerators>
|
||||
</Button>
|
||||
<Button Style="{StaticResource NavigationBarButton}" x:Name="stopButton" x:Uid="stopButton" IsTabStop="true" IsEnabled="false" Visibility="Collapsed" Click="OnStopButtonClicked">
|
||||
<SymbolIcon Symbol="Cancel"/>
|
||||
<Button.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="Escape" Modifiers="None" />
|
||||
</Button.KeyboardAccelerators>
|
||||
</Button>
|
||||
<Button Style="{StaticResource NavigationBarButton}" x:Name="homeButton" x:Uid="homeButton" IsTabStop="true" Click="OnHomeButtonClicked">
|
||||
<SymbolIcon Symbol="Home"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBox x:Uid="urlTextbox" Text="" IsTabStop="true" InputScope="Url" x:Name="urlTextbox" VerticalAlignment="Center" Grid.Column="1" KeyUp="OnURLEdited" IsSpellCheckEnabled="False" Margin="3,0" KeyboardAcceleratorPlacementMode="Hidden">
|
||||
<TextBox.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="L" Modifiers="Control" Invoked="OnURLKeyboardAccelerator"/>
|
||||
</TextBox.KeyboardAccelerators>
|
||||
</TextBox>
|
||||
<StackPanel Orientation="Horizontal" Grid.Column="2">
|
||||
<Button Style="{StaticResource NavigationBarButton}" x:Uid="bookmarkButton" x:Name="bookmarkButton" IsTabStop="true" IsEnabled="false">
|
||||
<SymbolIcon x:Name="bookmarkPanelIcon" Symbol="OutlineStar"/>
|
||||
<Button.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="B" Modifiers="Control" />
|
||||
</Button.KeyboardAccelerators>
|
||||
<Button.Flyout>
|
||||
<Flyout x:Name="bookmarkPanel">
|
||||
<StackPanel Orientation="Vertical" MinWidth="200">
|
||||
<TextBlock x:Name="bookmarkPanelLabel"/>
|
||||
<TextBox x:Name="bookmarkPanelTitle" VerticalAlignment="Center" IsSpellCheckEnabled="False" KeyUp="OnBookmarkEdited" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Margin="4" x:Uid="rmBookmarkButton" Click="OnRemoveBookmarkButtonClicked"/>
|
||||
<Button Margin="4" x:Uid="upBookmarkButton" Click="OnUpdateBookmarkButtonClicked"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button Style="{StaticResource NavigationBarButton}" x:Name="devtoolsButton" IsEnabled="false" x:Uid="devtoolsButton" IsTabStop="true" Click="OnDevtoolsButtonClicked">
|
||||
<!-- EC7A is the "DeveloperTools" symbol, not exported in the symbol list for some reason -->
|
||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph=""/>
|
||||
</Button>
|
||||
<ProgressRing x:Name="urlbarLoadingIndicator" Margin="10,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<ItemsControl ItemsSource="{x:Bind Bookmarks}" Grid.Row="1" x:Name="bookmarkToolbar">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:Bookmark">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Tag="{x:Bind Url}" ToolTipService.ToolTip="{x:Bind Url}" Background="Transparent" Content="{x:Bind Name}" Click="OnBookmarkClicked"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Padding="4" Background="{ThemeResource InkToolbarButtonBackgroundThemeBrush}"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
|
||||
<local:ServoControl Grid.Row="2" TabIndex="0" x:Name="servoView"/>
|
||||
<muxc:TabView x:Name="toolbox" IsAddTabButtonVisible="False" Grid.Row="3" Visibility="Collapsed" Height="300">
|
||||
<muxc:TabView.TabStripFooter>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="1" Style="{StaticResource NavigationBarButton}" x:Name="toolboxCloseButton" IsTabStop="true" Click="OnDevtoolsButtonClicked">
|
||||
<SymbolIcon Symbol="Cancel"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</muxc:TabView.TabStripFooter>
|
||||
<muxc:TabViewItem x:Uid="devtoolsTabConsole" x:Name="devtoolsTabConsole" IsClosable="False">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<ListView ItemsSource="{x:Bind ConsoleLogs}">
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<ItemsStackPanel Orientation="Vertical" ItemsUpdatingScrollMode="KeepLastItemInView"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:ConsoleLog">
|
||||
<Grid Padding="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon FontSize="12" FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="{x:Bind Glyph}" Foreground="{x:Bind GlyphColor}" Grid.Column="0" MinWidth="22"/>
|
||||
<TextBlock FontFamily="Consolas" FontSize="12" Text="{x:Bind Body}" Grid.Column="1"/>
|
||||
<TextBlock FontFamily="Consolas" FontSize="12" Text="{x:Bind Source}" Grid.Column="2" Margin="10,0" Style="{ThemeResource BodyTextBlockStyle}" Foreground="{ThemeResource SystemBaseMediumColor}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
</ListView>
|
||||
<TextBox MinHeight="12" FontFamily="Consolas" FontSize="12" Grid.Row="1" IsTabStop="true" x:Name="JSInput" VerticalAlignment="Center" KeyUp="OnJSInputEdited" IsSpellCheckEnabled="False"/>
|
||||
</Grid>
|
||||
</muxc:TabViewItem>
|
||||
<muxc:TabViewItem x:Uid="devtoolsTabPrefs" IsClosable="False">
|
||||
<Grid VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<CheckBox Margin="3" x:Name="seeAllPrefCheckBox" x:Uid="seeAllPrefCheckBox" Click="OnSeeAllPrefClicked" IsChecked="False" Grid.Row="0"/>
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel x:Name="prefList"/>
|
||||
</ScrollViewer>
|
||||
<TextBox Grid.Row="2" IsTabStop="true" x:Uid="preferenceSearchbox" x:Name="preferenceSearchbox" VerticalAlignment="Center" KeyUp="OnPrefererenceSearchboxEdited" IsSpellCheckEnabled="False" Margin="3"/>
|
||||
</Grid>
|
||||
</muxc:TabViewItem>
|
||||
<muxc:TabViewItem x:Uid="crashTab" x:Name="crashTab" IsClosable="False" Visibility="Collapsed">
|
||||
<Grid VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Padding="4" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" x:Name="crashTabMessage"></TextBlock>
|
||||
<Button IsTabStop="true" x:Uid="SubmitCrashReportButton" Margin="4" Click="OnSubmitCrashReport"/>
|
||||
<Button IsTabStop="true" x:Uid="DismissCrashReportButton" Margin="4" Click="OnDismissCrashReport"/>
|
||||
</StackPanel>
|
||||
<TextBox Grid.Row="1" TextWrapping="Wrap" IsTabStop="true" x:Name="crashReport" AcceptsReturn="True" IsSpellCheckEnabled="False" Margin="3"/>
|
||||
</Grid>
|
||||
</muxc:TabViewItem>
|
||||
</muxc:TabView>
|
||||
<ProgressBar x:Name="transientLoadingIndicator" Visibility="Collapsed" Grid.Row="4"/>
|
||||
<CommandBar Grid.Row="5" x:Name="mediaControls" Visibility="Collapsed">
|
||||
<AppBarButton Icon="Play" x:Uid="playButton" x:Name="playButton" Visibility="Collapsed" Click="OnMediaControlsPlayClicked"/>
|
||||
<AppBarButton Icon="Pause" x:Uid="pauseButton" x:Name="pauseButton" Click="OnMediaControlsPauseClicked"/>
|
||||
</CommandBar>
|
||||
</Grid>
|
||||
|
||||
</Page>
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#define FALLBACK_DEFAULT_URL L"https://servo.org/hl-home/"
|
||||
|
||||
// For development purpose.
|
||||
// Will override shell.homepage preference:
|
||||
// #define OVERRIDE_DEFAULT_URL L"data:text/html,<input>"
|
||||
// #define OVERRIDE_DEFAULT_URL L"http://localhost:8000/test.html"
|
|
@ -1,288 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pch.h"
|
||||
#include "strutils.h"
|
||||
#include "Client.h"
|
||||
|
||||
using namespace winrt::Windows::Data::Json;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Networking;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
|
||||
namespace winrt::servo {
|
||||
|
||||
void DevtoolsClient::Stop() {
|
||||
if (mReceiving && mReceiveOp.has_value() &&
|
||||
mReceiveOp->Status() != AsyncStatus::Completed) {
|
||||
mReceiveOp->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void DevtoolsClient::Run() {
|
||||
if (mReceiving) {
|
||||
throw hresult_error(E_FAIL, L"Already running");
|
||||
}
|
||||
mReceiving = true;
|
||||
auto socket = Sockets::StreamSocket();
|
||||
auto hostname = HostName(mHostname);
|
||||
auto connecting = socket.ConnectAsync(hostname, mPort);
|
||||
connecting.Completed([=](const auto &, const auto &) {
|
||||
mDataReader = DataReader(socket.InputStream());
|
||||
mDataWriter = DataWriter(socket.OutputStream());
|
||||
|
||||
JsonObject out;
|
||||
out.Insert(L"auth_token", JsonValue::CreateStringValue(mToken));
|
||||
Send(out);
|
||||
|
||||
mReceiveOp = {Loop()};
|
||||
mReceiveOp->Completed([=](const auto &, const auto &) {
|
||||
mReceiveOp = {};
|
||||
mDataReader->DetachStream();
|
||||
mDataWriter->DetachStream();
|
||||
mReceiving = false;
|
||||
mDelegate.OnDevtoolsDetached();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void DevtoolsClient::Evaluate(hstring code) {
|
||||
if (!code.empty() && mConsoleActor.has_value()) {
|
||||
JsonObject out;
|
||||
out.Insert(L"to", *mConsoleActor);
|
||||
out.Insert(L"type", JsonValue::CreateStringValue(L"evaluateJSAsync"));
|
||||
out.Insert(L"text", JsonValue::CreateStringValue(code));
|
||||
Send(out);
|
||||
}
|
||||
}
|
||||
|
||||
IAsyncAction DevtoolsClient::Loop() {
|
||||
auto cancellation = co_await winrt::get_cancellation_token();
|
||||
cancellation.callback([=] {
|
||||
if (mReaderOp.Status() != AsyncStatus::Completed) {
|
||||
mReaderOp.Cancel();
|
||||
}
|
||||
});
|
||||
|
||||
while (!cancellation()) {
|
||||
unsigned int len = 0;
|
||||
while (!cancellation()) {
|
||||
mReaderOp = mDataReader->LoadAsync(1);
|
||||
co_await mReaderOp;
|
||||
hstring c = mDataReader->ReadString(1);
|
||||
if (c == L":")
|
||||
break;
|
||||
try {
|
||||
unsigned int digit = std::stoi(c.c_str());
|
||||
len = 10 * len + digit;
|
||||
} catch (...) {
|
||||
throw hresult_error(E_FAIL, L"Can't parse message header:" + c);
|
||||
}
|
||||
if (len >= 100000) {
|
||||
throw hresult_error(E_FAIL, L"Message length too long");
|
||||
}
|
||||
}
|
||||
if (cancellation()) {
|
||||
break;
|
||||
}
|
||||
hstring request = L"";
|
||||
mReaderOp = mDataReader->LoadAsync(len);
|
||||
auto bytesLoaded = co_await mReaderOp;
|
||||
request = request + mDataReader->ReadString(bytesLoaded);
|
||||
JsonObject json;
|
||||
if (!JsonObject::TryParse(request, json)) {
|
||||
throw hresult_error(E_FAIL, L"Can't parse message: " + request);
|
||||
}
|
||||
HandleMessage(json);
|
||||
}
|
||||
}
|
||||
|
||||
void DevtoolsClient::HandleMessage(JsonObject obj) {
|
||||
// Basic devtools protocol implementation:
|
||||
// https://docs.firefox-dev.tools/backend/protocol.html
|
||||
|
||||
if (obj.HasKey(L"from") && obj.GetNamedString(L"from") == L"root") {
|
||||
if (obj.HasKey(L"applicationType")) {
|
||||
// First message. Ask for the current tab
|
||||
JsonObject out;
|
||||
out.Insert(L"to", JsonValue::CreateStringValue(L"root"));
|
||||
out.Insert(L"type", JsonValue::CreateStringValue(L"getTab"));
|
||||
Send(out);
|
||||
return;
|
||||
} else if (obj.HasKey(L"tab")) {
|
||||
// Got the current tab.
|
||||
auto tab = obj.GetNamedObject(L"tab");
|
||||
JsonObject out;
|
||||
out.Insert(L"to", tab.GetNamedValue(L"actor"));
|
||||
out.Insert(L"type", JsonValue::CreateStringValue(L"getTarget"));
|
||||
Send(out);
|
||||
return;
|
||||
}
|
||||
} else if (obj.HasKey(L"resultID")) {
|
||||
// evaluateJSAsync response.
|
||||
if (obj.GetNamedString(L"type", L"") == L"evaluationResult") {
|
||||
HandleEvaluationResult(obj);
|
||||
}
|
||||
return;
|
||||
} else if (obj.HasKey(L"type")) { // Not from root
|
||||
if (obj.GetNamedString(L"type") == L"pageError") {
|
||||
// Got a page error
|
||||
HandlePageError(obj.GetNamedObject(L"pageError"));
|
||||
return;
|
||||
} else if (obj.GetNamedString(L"type") == L"consoleAPICall") {
|
||||
// console.* calls
|
||||
auto message = obj.GetNamedObject(L"message");
|
||||
HandleConsoleMessage(message);
|
||||
return;
|
||||
} else if (obj.GetNamedString(L"type") == L"tabAttached") {
|
||||
// Ignore
|
||||
return;
|
||||
} else if (obj.GetNamedString(L"type") == L"networkEvent") {
|
||||
// Ignore
|
||||
return;
|
||||
} else if (obj.GetNamedString(L"type") == L"tabNavigated") {
|
||||
if (obj.HasKey(L"state") && obj.GetNamedString(L"state") == L"stop") {
|
||||
mDelegate.ClearConsole();
|
||||
}
|
||||
return;
|
||||
} else if (obj.GetNamedString(L"type") == L"networkEventUpdate") {
|
||||
// FIXME: log if there is a non-200 HTTP response
|
||||
return;
|
||||
}
|
||||
} else if (obj.HasKey(L"frame")) {
|
||||
auto frame = obj.GetNamedObject(L"frame");
|
||||
// Attach to tab, and ask for cached messaged
|
||||
JsonObject msg1;
|
||||
mConsoleActor = frame.GetNamedValue(L"consoleActor");
|
||||
msg1.Insert(L"to", frame.GetNamedValue(L"actor"));
|
||||
msg1.Insert(L"type", JsonValue::CreateStringValue(L"attach"));
|
||||
Send(msg1);
|
||||
JsonObject msg2;
|
||||
msg2.Insert(L"to", *mConsoleActor);
|
||||
msg2.Insert(L"type", JsonValue::CreateStringValue(L"getCachedMessages"));
|
||||
JsonArray types;
|
||||
types.Append(JsonValue::CreateStringValue(L"PageError"));
|
||||
types.Append(JsonValue::CreateStringValue(L"ConsoleAPI"));
|
||||
msg2.Insert(L"messageTypes", types);
|
||||
Send(msg2);
|
||||
return;
|
||||
} else if (obj.HasKey(L"messages")) {
|
||||
// Response to getCachedMessages
|
||||
for (auto messageValue : obj.GetNamedArray(L"messages")) {
|
||||
auto message = messageValue.GetObject();
|
||||
if (message.GetNamedString(L"_type") == L"ConsoleAPI") {
|
||||
HandleConsoleMessage(message);
|
||||
} else if (message.GetNamedString(L"_type") == L"PageError") {
|
||||
HandlePageError(message);
|
||||
} else {
|
||||
HandleNonHandledMessage(message);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
HandleNonHandledMessage(obj);
|
||||
}
|
||||
|
||||
DevtoolsMessageLevel DevtoolsClient::ParseLevel(JsonObject message) {
|
||||
if (message.GetNamedBoolean(L"error", false)) {
|
||||
return DevtoolsMessageLevel::Error;
|
||||
}
|
||||
if (message.GetNamedBoolean(L"warning", false)) {
|
||||
return DevtoolsMessageLevel::Warn;
|
||||
}
|
||||
if (message.GetNamedBoolean(L"exception", false)) {
|
||||
return DevtoolsMessageLevel::Error;
|
||||
}
|
||||
auto level = message.GetNamedString(L"level", L"");
|
||||
if (level == L"warn") {
|
||||
return DevtoolsMessageLevel::Warn;
|
||||
} else if (level == L"error") {
|
||||
return DevtoolsMessageLevel::Error;
|
||||
}
|
||||
return DevtoolsMessageLevel::None;
|
||||
}
|
||||
|
||||
hstring DevtoolsClient::ParseSource(JsonObject message) {
|
||||
auto source = message.GetNamedString(L"filename", L"<>");
|
||||
if (message.HasKey(L"lineNumber")) {
|
||||
source = source + L":" + to_hstring(message.GetNamedNumber(L"lineNumber"));
|
||||
}
|
||||
if (message.HasKey(L"columnNumber")) {
|
||||
source =
|
||||
source + L":" + to_hstring(message.GetNamedNumber(L"columnNumber"));
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
void DevtoolsClient::HandlePageError(JsonObject message) {
|
||||
auto source = ParseSource(message);
|
||||
auto body = message.GetNamedString(L"errorMessage", L"");
|
||||
auto level = ParseLevel(message);
|
||||
mDelegate.OnDevtoolsMessage(level, source, body);
|
||||
}
|
||||
|
||||
void DevtoolsClient::HandleEvaluationResult(JsonObject message) {
|
||||
auto level = DevtoolsMessageLevel::None;
|
||||
hstring body = L"";
|
||||
if (message.HasKey(L"result")) {
|
||||
auto value = message.GetNamedValue(L"result");
|
||||
if (value.ValueType() == JsonValueType::Object) {
|
||||
auto type = value.GetObject().GetNamedString(L"type");
|
||||
if (type == L"undefined") {
|
||||
body = L"undefined";
|
||||
} else {
|
||||
body = L"<object>";
|
||||
}
|
||||
} else {
|
||||
body = value.Stringify();
|
||||
}
|
||||
} else if (message.GetNamedValue(L"exception").ValueType() !=
|
||||
JsonValueType::Null) {
|
||||
level = DevtoolsMessageLevel::Error;
|
||||
body = message.GetNamedString(L"exceptionMessage", L"");
|
||||
}
|
||||
mDelegate.OnDevtoolsMessage(level, L"", body);
|
||||
}
|
||||
|
||||
void DevtoolsClient::HandleConsoleMessage(JsonObject message) {
|
||||
auto source = ParseSource(message);
|
||||
auto level = ParseLevel(message);
|
||||
hstring body = L"";
|
||||
for (auto arg : message.GetNamedArray(L"arguments")) {
|
||||
body = body + arg.Stringify();
|
||||
}
|
||||
mDelegate.OnDevtoolsMessage(level, source, body);
|
||||
}
|
||||
|
||||
void DevtoolsClient::HandleNonHandledMessage(JsonObject message) {
|
||||
auto level = DevtoolsMessageLevel::Warn;
|
||||
auto body = L"Unhandled devtools message: " + message.Stringify();
|
||||
mDelegate.OnDevtoolsMessage(level, L"", body);
|
||||
}
|
||||
|
||||
void DevtoolsClient::SendPendingObjects() {
|
||||
if (mPendingObjects.empty() || mSending) {
|
||||
return;
|
||||
}
|
||||
mSending = true;
|
||||
auto obj = mPendingObjects.front();
|
||||
mPendingObjects.erase(mPendingObjects.begin());
|
||||
hstring msg = obj.Stringify();
|
||||
hstring size = to_hstring(msg.size());
|
||||
hstring request = size + L":" + msg;
|
||||
mDataWriter->WriteString(request);
|
||||
mDataWriter->StoreAsync().Completed([=](const auto &, const auto &) {
|
||||
mDataWriter->FlushAsync().Completed([=](const auto &, const auto &) {
|
||||
mSending = false;
|
||||
SendPendingObjects();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void DevtoolsClient::Send(JsonObject obj) {
|
||||
mPendingObjects.push_back(obj);
|
||||
SendPendingObjects();
|
||||
}
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,63 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
namespace winrt::servo {
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
using namespace winrt::Windows::Data::Json;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Networking::Sockets;
|
||||
|
||||
class DevtoolsDelegate;
|
||||
|
||||
enum DevtoolsMessageLevel { Error, Warn, None };
|
||||
|
||||
class DevtoolsClient {
|
||||
|
||||
public:
|
||||
DevtoolsClient(hstring hostname, hstring port, hstring token,
|
||||
DevtoolsDelegate &d)
|
||||
: mDelegate(d), mHostname(hostname), mToken(token), mPort(port){};
|
||||
|
||||
~DevtoolsClient() { Stop(); }
|
||||
void Run();
|
||||
void Stop();
|
||||
void Send(JsonObject);
|
||||
void Evaluate(hstring);
|
||||
|
||||
private:
|
||||
hstring mPort;
|
||||
hstring mToken;
|
||||
hstring mHostname;
|
||||
DevtoolsDelegate &mDelegate;
|
||||
std::optional<DataReader> mDataReader;
|
||||
std::optional<DataWriter> mDataWriter;
|
||||
std::optional<IAsyncAction> mReceiveOp;
|
||||
std::vector<JsonObject> mPendingObjects;
|
||||
IAsyncOperation<unsigned int> mReaderOp;
|
||||
bool mSending = false;
|
||||
bool mReceiving = false;
|
||||
void SendPendingObjects();
|
||||
IAsyncAction Loop();
|
||||
DevtoolsMessageLevel ParseLevel(JsonObject);
|
||||
hstring ParseSource(JsonObject);
|
||||
void HandleMessage(JsonObject);
|
||||
void HandlePageError(JsonObject);
|
||||
void HandleConsoleMessage(JsonObject);
|
||||
void HandleNonHandledMessage(JsonObject);
|
||||
void HandleEvaluationResult(JsonObject);
|
||||
std::optional<JsonValue> mConsoleActor;
|
||||
};
|
||||
|
||||
class DevtoolsDelegate {
|
||||
public:
|
||||
virtual void OnDevtoolsMessage(DevtoolsMessageLevel, hstring, hstring) = 0;
|
||||
virtual void ClearConsole() = 0;
|
||||
virtual void OnDevtoolsDetached() = 0;
|
||||
};
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,56 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" IgnorableNamespaces="uap mp uap5">
|
||||
<Identity Name="MozillaFoundation.FirefoxReality" Publisher="CN=Allizom" Version="1.2.0.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="1d265729-8836-4bd3-9992-4cb111d1068b" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>Firefox Reality</DisplayName>
|
||||
<PublisherDisplayName>Mozilla Corporation</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
<PackageDependency Name="Microsoft.WindowsMixedReality.Runtime" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" MinVersion="102.2006.3006.0"/>
|
||||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ServoApp.App">
|
||||
<uap:VisualElements DisplayName="Firefox Reality" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent" Description="ms-resource:appDescription">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="Firefox Reality" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
|
||||
<uap:ShowNameOnTiles>
|
||||
<uap:ShowOn Tile="square150x150Logo" />
|
||||
<uap:ShowOn Tile="wide310x150Logo" />
|
||||
<uap:ShowOn Tile="square310x310Logo" />
|
||||
</uap:ShowNameOnTiles>
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<uap5:Extension Category="windows.appExecutionAlias" Executable="ServoApp.exe" EntryPoint="ServoApp.App">
|
||||
<uap5:AppExecutionAlias>
|
||||
<uap5:ExecutionAlias Alias="Servo.exe" />
|
||||
</uap5:AppExecutionAlias>
|
||||
</uap5:Extension>
|
||||
<uap:Extension Category="windows.protocol">
|
||||
<uap:Protocol Name="fxr">
|
||||
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
|
||||
<uap:DisplayName>Firefox Reality URL</uap:DisplayName>
|
||||
</uap:Protocol>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.protocol">
|
||||
<uap:Protocol Name="fxrmin">
|
||||
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
|
||||
<uap:DisplayName>Firefox Reality URL (Kiosk mode)</uap:DisplayName>
|
||||
</uap:Protocol>
|
||||
</uap:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
<Capability Name="codeGeneration" />
|
||||
<Capability Name="privateNetworkClientServer" />
|
||||
<Capability Name="internetClientServer" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<!--
|
||||
To customize common C++/WinRT project properties:
|
||||
* right-click the project node
|
||||
* expand the Common Properties item
|
||||
* select the C++/WinRT property page
|
||||
|
||||
For more advanced scenarios, and complete documentation, please see:
|
||||
https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget
|
||||
-->
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup />
|
||||
</Project>
|
|
@ -1,125 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="dom.webxr.hands.enabled"><value>WebXR: Enable articulated hand input</value></data>
|
||||
<data name="dom.webxr.layers.enabled"><value>WebXR: Enable composition layers</value></data>
|
||||
<data name="dom.webxr.sessionavailable"><value>WebXR: Enable "sessionavailable" event</value></data>
|
||||
<data name="dom.webxr.first_person_observer_view"><value>WebXR: Enable first person observer view</value></data>
|
||||
<data name="dom.webgl2.enabled"><value>Enable WebGL2</value></data>
|
||||
</root>
|
|
@ -1,189 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!-- A xx-XX/Resources.resw file doesn't need to 100% cover the en-US/Resources.resw counterpart.
|
||||
The application falls back to the english resources if the string is not found -->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="appDescription">
|
||||
<value>Firefox Reality brings the best and freshest content from the web that you know and love to Virtual Reality headsets. Our browser provides an open, accessible and secure way for everyone to explore the web. Experience sharp text, high quality videos, and a seamless transition from 2D to 3D immersive modes. Enjoy the best possible web browsing experience with Firefox Reality.</value>
|
||||
</data>
|
||||
<data name="backButton.AutomationProperties.Name">
|
||||
<value>Back</value>
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
</data>
|
||||
<data name="backButton.ToolTipService.ToolTip">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="devtoolsButton.AutomationProperties.Name">
|
||||
<value>Developer Tools</value>
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
</data>
|
||||
<data name="devtoolsButton.ToolTipService.ToolTip">
|
||||
<value>Developer Tools</value>
|
||||
</data>
|
||||
<data name="forwardButton.AutomationProperties.Name">
|
||||
<value>Forward</value>
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
</data>
|
||||
<data name="forwardButton.ToolTipService.ToolTip">
|
||||
<value>Forward</value>
|
||||
</data>
|
||||
<data name="homeButton.AutomationProperties.Name">
|
||||
<value>Home</value>
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
</data>
|
||||
<data name="homeButton.ToolTipService.ToolTip">
|
||||
<value>Home</value>
|
||||
</data>
|
||||
<data name="reloadButton.AutomationProperties.Name">
|
||||
<value>Reload</value>
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
</data>
|
||||
<data name="reloadButton.ToolTipService.ToolTip">
|
||||
<value>Reload</value>
|
||||
</data>
|
||||
<data name="stopButton.AutomationProperties.Name">
|
||||
<value>Stop</value>
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
</data>
|
||||
<data name="stopButton.ToolTipService.ToolTip">
|
||||
<value>Stop</value>
|
||||
</data>
|
||||
<data name="urlTextbox.PlaceholderText">
|
||||
<value>Type a URL</value>
|
||||
</data>
|
||||
<data name="devtoolsTabConsole.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header">
|
||||
<value>Console</value>
|
||||
</data>
|
||||
<data name="devtoolsTabPrefs.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header">
|
||||
<value>Preferences</value>
|
||||
</data>
|
||||
<data name="crashTab.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header">
|
||||
<value>Crash Report</value>
|
||||
</data>
|
||||
<data name="crash.Happening">
|
||||
<value>Internal crash detected. Application might be unstable:</value>
|
||||
</data>
|
||||
<data name="crash.Happened">
|
||||
<value>Internal crash was detected during last run:</value>
|
||||
</data>
|
||||
<data name="SubmitCrashReportButton.Content">
|
||||
<value>Send crash report</value>
|
||||
</data>
|
||||
<data name="DismissCrashReportButton.Content">
|
||||
<value>Dismiss</value>
|
||||
</data>
|
||||
<data name="preferenceSearchbox.PlaceholderText">
|
||||
<value>Search Preferences</value>
|
||||
</data>
|
||||
<data name="playButton.Label">
|
||||
<value>Play</value>
|
||||
</data>
|
||||
<data name="pauseButton.Label">
|
||||
<value>Pause</value>
|
||||
</data>
|
||||
<data name="devtoolsStatus.Running">
|
||||
<value>Devtools server is listening on port %s.</value>
|
||||
</data>
|
||||
<data name="devtoolsStatus.Failed">
|
||||
<value>Devtools server failed to start.</value>
|
||||
</data>
|
||||
<data name="devtoolsStatus.Stopped">
|
||||
<value>Devtools server is starting.</value>
|
||||
</data>
|
||||
<data name="devtoolsPreferenceResetButton.Content">
|
||||
<value>reset</value>
|
||||
</data>
|
||||
<data name="URINotValid.Alert">
|
||||
<value>URI not valid</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.ok">
|
||||
<value>ok</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.cancel">
|
||||
<value>cancel</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.yes">
|
||||
<value>yes</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.no">
|
||||
<value>no</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.title">
|
||||
<value>"%s" says:</value>
|
||||
</data>
|
||||
<data name="ContextMenu.title">
|
||||
<value>Menu</value>
|
||||
</data>
|
||||
<data name="seeAllPrefCheckBox.Content">
|
||||
<value>See all preferences</value>
|
||||
</data>
|
||||
<data name="upBookmarkButton.Content">
|
||||
<value>Done</value>
|
||||
</data>
|
||||
<data name="rmBookmarkButton.Content">
|
||||
<value>Remove</value>
|
||||
</data>
|
||||
<data name="bookmarkPanel.addedTitle">
|
||||
<value>Bookmark added</value>
|
||||
</data>
|
||||
<data name="bookmarkPanel.editTitle">
|
||||
<value>Edit bookmark:</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,152 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
|
||||
<data name="backButton.AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Retour</value>
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
</data>
|
||||
<data name="backButton.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Retour</value>
|
||||
</data>
|
||||
<data name="devtoolsButton.AutomationProperties.Name" xml:space="preserve">
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
<value>Outils de développement</value>
|
||||
</data>
|
||||
<data name="devtoolsButton.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Outils de développement</value>
|
||||
</data>
|
||||
<data name="forwardButton.AutomationProperties.Name" xml:space="preserve">
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
<value>Avancer</value>
|
||||
</data>
|
||||
<data name="forwardButton.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Avancer</value>
|
||||
</data>
|
||||
<data name="homeButton.AutomationProperties.Name" xml:space="preserve">
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
<value>Accueil</value>
|
||||
</data>
|
||||
<data name="homeButton.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Accueil</value>
|
||||
</data>
|
||||
<data name="reloadButton.AutomationProperties.Name" xml:space="preserve">
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
<value>Actualiser</value>
|
||||
</data>
|
||||
<data name="reloadButton.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Actualiser</value>
|
||||
</data>
|
||||
<data name="stopButton.AutomationProperties.Name" xml:space="preserve">
|
||||
<comment>Will be recognized by the speech recognition system</comment>
|
||||
<value>Arrêter</value>
|
||||
</data>
|
||||
<data name="stopButton.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Arrêter</value>
|
||||
</data>
|
||||
<data name="urlTextbox.PlaceholderText" xml:space="preserve">
|
||||
<value>Saisir une adresse</value>
|
||||
</data>
|
||||
<data name="devtoolsTabPrefs.[using:Microsoft.UI.Xaml.Controls]TabViewItem.Header" xml:space="preserve">
|
||||
<value>Préférences</value>
|
||||
</data>
|
||||
<data name="preferenceSearchbox.PlaceholderText" xml:space="preserve">
|
||||
<value>Rechercher préférence</value>
|
||||
</data>
|
||||
<data name="playButton.Label" xml:space="preserve">
|
||||
<value>Jouer</value>
|
||||
</data>
|
||||
<data name="pauseButton.Label" xml:space="preserve">
|
||||
<value>Pause</value>
|
||||
</data>
|
||||
<data name="devtoolsStatus.Running" xml:space="preserve">
|
||||
<value>Le serveur DevTools écoute sur le port %s.</value>
|
||||
</data>
|
||||
<data name="devtoolsStatus.Failed" xml:space="preserve">
|
||||
<value>Le serveur DevTools n'a pas pu démarrer.</value>
|
||||
</data>
|
||||
<data name="devtoolsStatus.Stopped" xml:space="preserve">
|
||||
<value>Le serveur DevTools démarre.</value>
|
||||
</data>
|
||||
<data name="devtoolsPreferenceResetButton.Content" xml:space="preserve">
|
||||
<value>réinitialiser</value>
|
||||
</data>
|
||||
<data name="URINotValid.Alert" xml:space="preserve">
|
||||
<value>URI invalide</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.ok" xml:space="preserve">
|
||||
<value>ok</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.cancel" xml:space="preserve">
|
||||
<value>annuler</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.yes" xml:space="preserve">
|
||||
<value>oui</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.no" xml:space="preserve">
|
||||
<value>non</value>
|
||||
</data>
|
||||
<data name="JavascriptPrompt.title" xml:space="preserve">
|
||||
<value>"%s" dit:</value>
|
||||
</data>
|
||||
<data name="ContextMenu.title" xml:space="preserve">
|
||||
<value>Menu</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,974 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Midl Include="BrowserPage.idl" />
|
||||
<Midl Include="App.idl" />
|
||||
<Midl Include="ServoControl\ServoControl.idl">
|
||||
<Filter>ServoControl</Filter>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="BrowserPage.cpp" />
|
||||
<ClCompile Include="App.cpp" />
|
||||
<ClCompile Include="ServoControl\OpenGLES.cpp">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ServoControl\Servo.cpp">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ServoControl\ServoControl.cpp">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Devtools\Client.cpp">
|
||||
<Filter>Devtools</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Bookmarks.cpp" />
|
||||
<ClCompile Include="ServoControl\Crash.cpp">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="BrowserPage.h" />
|
||||
<ClInclude Include="App.h" />
|
||||
<ClInclude Include="ServoControl\OpenGLES.h">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ServoControl\Servo.h">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ServoControl\ServoControl.h">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DefaultUrl.h" />
|
||||
<ClInclude Include="strutils.h" />
|
||||
<ClInclude Include="Devtools\Client.h">
|
||||
<Filter>Devtools</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ServoControl\Keys.h">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Bookmarks.h" />
|
||||
<ClInclude Include="ServoControl\Crash.h">
|
||||
<Filter>ServoControl</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Assets\Wide310x150Logo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square150x150Logo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SplashScreen.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SmallTile.scale-100.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SmallTile.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SmallTile.scale-400.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square150x150Logo.scale-100.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square150x150Logo.scale-400.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Wide310x150Logo.scale-100.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Wide310x150Logo.scale-400.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\LargeTile.scale-100.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\LargeTile.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\LargeTile.scale-400.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.scale-100.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.scale-400.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.targetsize-16.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.targetsize-48.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.targetsize-256.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SplashScreen.scale-100.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SplashScreen.scale-400.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\StoreLogo.scale-100.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\StoreLogo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\StoreLogo.scale-400.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.scale-125.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.scale-150.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.targetsize-24.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.targetsize-32.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.altform-unplated_targetsize-16.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.altform-unplated_targetsize-24.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.altform-unplated_targetsize-32.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.altform-unplated_targetsize-48.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.altform-unplated_targetsize-256.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\simpleservo.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\libcrypto.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\libssl.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\libcrypto.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\libssl.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\simpleservo.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\libcrypto.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\libssl.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\simpleservo.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\vcruntime140.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\msvcp140.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\avcodec-58.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\avfilter-7.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\avformat-58.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\avresample-4.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\avutil-56.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\bz2.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\ffi-7.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gio-2.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\glib-2.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gmodule-2.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gobject-2.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstapp.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstapp-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstaudio-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstaudioconvert.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstaudiofx.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstaudioparsers.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstaudioresample.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstautodetect.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstbase-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstcodecparsers-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstcontroller-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstcoreelements.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstdeinterlace.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstfft-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstgl-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstinterleave.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstisomp4.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstlibav.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstpbutils-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstplayback.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstplayer-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstproxy.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstreamer-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstriff-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstrtp-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstrtsp-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstsdp-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gsttag-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gsttypefindfunctions.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstvideo-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstvideoconvert.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstvideofilter.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstvideoparsersbad.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstvideoscale.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstvolume.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstwasapi.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstwebrtc-1.0-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\intl-8.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\orc-0.4-0.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\postproc-55.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\swresample-3.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\swscale-5.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\x264-157.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\z-1.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\avcodec-58.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\avfilter-7.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\avformat-58.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\avresample-4.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\avutil-56.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\bz2.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\ffi-7.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gio-2.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\glib-2.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gmodule-2.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gobject-2.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstapp.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstapp-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstaudio-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstaudioconvert.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstaudiofx.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstaudioparsers.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstaudioresample.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstautodetect.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstbase-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstcodecparsers-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstcontroller-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstcoreelements.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstdeinterlace.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstfft-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstgl-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstinterleave.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstisomp4.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstlibav.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstpbutils-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstplayback.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstplayer-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstproxy.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstreamer-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstriff-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstrtp-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstrtsp-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstsdp-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gsttag-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gsttypefindfunctions.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstvideo-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstvideoconvert.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstvideofilter.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstvideoparsersbad.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstvideoscale.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstvolume.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstwasapi.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstwebrtc-1.0-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\intl-8.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\orc-0.4-0.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\postproc-55.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\swresample-3.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\swscale-5.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\x264-157.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\z-1.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\avcodec-58.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\avformat-58.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\avutil-56.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\bz2.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\ffi-7.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gio-2.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gmodule-2.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gobject-2.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstapp.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstaudioconvert.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstaudiofx.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstautodetect.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstcontroller-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstfft-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstinterleave.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstlibav.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstpbutils-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstproxy.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstreamer-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstriff-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstrtsp-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstsdp-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gsttag-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstvideofilter.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstvideoparsersbad.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstvolume.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\swresample-3.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\swscale-5.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\x264-157.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\libcrypto.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\libssl.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\bz2.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\ffi-7.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gio-2.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gmodule-2.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gobject-2.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstapp.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstaudioconvert.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstaudiofx.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstautodetect.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstcontroller-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstfft-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstinterleave.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstlibav.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstpbutils-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstproxy.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstreamer-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstriff-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstrtsp-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstsdp-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gsttag-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstvideofilter.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstvideoparsersbad.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstvolume.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\avutil-56.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\avformat-58.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\avcodec-58.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\swscale-5.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\x264-157.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\simpleservo.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\orc-0.4-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\z-1.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\orc-0.4-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\z-1.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\avfilter-7.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\avresample-4.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\intl-8.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\intl-8.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\avfilter-7.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\avresample-4.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\postproc-55.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstwasapi.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstvideoscale.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstvideoconvert.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstvideo-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gsttypefindfunctions.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstrtp-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstplayer-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstplayback.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstisomp4.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstgl-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstdeinterlace.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstcoreelements.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstcodecparsers-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstbase-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstaudioresample.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstaudioparsers.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstaudio-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstapp-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\glib-2.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\glib-2.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstapp-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstaudio-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstaudioparsers.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstaudioresample.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstbase-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstcodecparsers-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstcoreelements.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstdeinterlace.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstgl-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstisomp4.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstplayback.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstplayer-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstrtp-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gsttypefindfunctions.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstvideo-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstvideoconvert.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstvideoscale.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstwasapi.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\postproc-55.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstwebrtc-1.0-0.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstwebrtc-1.0-0.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\swresample-3.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="$(OpenXRLoaderBinaryRoot)\bin\openxr_loader.dll" />
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstaudiobuffersplit.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstgio.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstid3tag.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\debug\gstid3demux.dll">
|
||||
<Filter>DebugARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstaudiobuffersplit.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstgio.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstid3tag.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\aarch64-uwp-windows-msvc\release\gstid3demux.dll">
|
||||
<Filter>ReleaseARM64ServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstaudiobuffersplit.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstgio.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstid3tag.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\debug\gstid3demux.dll">
|
||||
<Filter>DebugServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstaudiobuffersplit.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstgio.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstid3tag.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\gstid3demux.dll">
|
||||
<Filter>ReleaseServoDLLs</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Assets">
|
||||
<UniqueIdentifier>{e48dc53e-40b1-40cb-970a-f89935452892}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="DebugServoDLLs">
|
||||
<UniqueIdentifier>{6c943d94-ac99-4fb1-825f-233a21441ae7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ReleaseServoDLLs">
|
||||
<UniqueIdentifier>{663f48bc-21ec-4f00-9db5-cd0a5fa87983}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="DebugARM64ServoDLLs">
|
||||
<UniqueIdentifier>{e372e8ac-7cab-47de-80a5-020370a51fd4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ReleaseARM64ServoDLLs">
|
||||
<UniqueIdentifier>{384b4019-d076-4301-994d-a891969a3036}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ServoControl">
|
||||
<UniqueIdentifier>{d21a959c-19d1-4a54-b942-692c27e5b3a6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>{c05cce0c-d62c-11ea-87d0-0242ac130003}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resources\Strings">
|
||||
<UniqueIdentifier>{49e23631-d899-4caf-bf7b-30776fee4d09}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resources\Strings\en-US">
|
||||
<UniqueIdentifier>{c12ff5d4-3730-4a0e-8b16-56ded3138875}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resources\Strings\fr-FR">
|
||||
<UniqueIdentifier>{b7d3273d-a27c-4176-87a1-3d5222b796b3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Devtools">
|
||||
<UniqueIdentifier>{12da8b9d-c14a-4be1-8328-c4e729fdfd3b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="BrowserPage.xaml" />
|
||||
<Page Include="Themes\Generic.xaml">
|
||||
<Filter>ServoControl</Filter>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PRIResource Include="Resources\PromotedPrefs.resw">
|
||||
<Filter>Resources</Filter>
|
||||
</PRIResource>
|
||||
<PRIResource Include="Resources\Strings\en-US\Resources.resw">
|
||||
<Filter>Resources\Strings\en-US</Filter>
|
||||
</PRIResource>
|
||||
<PRIResource Include="Resources\Strings\fr-FR\Resources.resw">
|
||||
<Filter>Resources\Strings\fr-FR</Filter>
|
||||
</PRIResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,60 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pch.h"
|
||||
#include "Crash.h"
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include "Servo.h"
|
||||
|
||||
namespace winrt::servo {
|
||||
|
||||
using namespace Windows::Storage;
|
||||
|
||||
void WriteSection(StorageFile const &file, hstring section, hstring content) {
|
||||
hstring title{format(L"\r\n--- %s ---\r\n", section.c_str())};
|
||||
FileIO::AppendTextAsync(file, title).get();
|
||||
FileIO::AppendTextAsync(file, content).get();
|
||||
}
|
||||
|
||||
void WriteCrashReport(hstring contentBacktrack, hstring contentUrl) {
|
||||
// Making all sync operations sync, as we are crashing.
|
||||
auto storageFolder = ApplicationData::Current().LocalFolder();
|
||||
auto fd = storageFolder
|
||||
.CreateFileAsync(L"crash-report.txt",
|
||||
CreationCollisionOption::ReplaceExisting)
|
||||
.get();
|
||||
FileIO::WriteTextAsync(fd, L"").get();
|
||||
|
||||
// Stdout
|
||||
auto stdout_txt = storageFolder.GetFileAsync(L"stdout.txt").get();
|
||||
auto contentStdout = FileIO::ReadTextAsync(stdout_txt).get();
|
||||
|
||||
// Crash time
|
||||
char cTime[70];
|
||||
auto crash_time = std::chrono::system_clock::now();
|
||||
auto now_c = std::chrono::system_clock::to_time_t(crash_time);
|
||||
std::tm now_tm;
|
||||
localtime_s(&now_tm, &now_c);
|
||||
strftime(cTime, sizeof cTime, "%FT%T%z", &now_tm);
|
||||
auto contentTime = char2hstring(cTime);
|
||||
|
||||
// App + servo version
|
||||
auto pkg = winrt::Windows::ApplicationModel::Package::Current();
|
||||
auto v = pkg.Id().Version();
|
||||
auto servo_version = char2hstring(capi::servo_version());
|
||||
hstring contentVersion{format(L"%i.%i.%i.%i (%s)", v.Major, v.Minor, v.Build,
|
||||
v.Revision, servo_version.c_str())};
|
||||
|
||||
WriteSection(fd, L"CUSTOM MESSAGE",
|
||||
L"Feel free to add details here before reporting");
|
||||
WriteSection(fd, L"CURRENT URL (remove if sensitive)", contentUrl);
|
||||
WriteSection(fd, L"CRASH TIME", contentTime);
|
||||
WriteSection(fd, L"VERSION", contentVersion);
|
||||
WriteSection(fd, L"BACKTRACE", contentBacktrack);
|
||||
WriteSection(fd, L"STDOUT", contentStdout);
|
||||
FileIO::AppendTextAsync(fd, L"\r\n").get();
|
||||
}
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
#include "strutils.h"
|
||||
|
||||
namespace winrt::servo {
|
||||
|
||||
void WriteCrashReport(hstring backtrace, hstring url);
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,130 +0,0 @@
|
|||
using namespace winrt::Windows::System;
|
||||
|
||||
namespace winrt {
|
||||
std::optional<const char *> KeyToString(Windows::System::VirtualKey key) {
|
||||
switch (key) {
|
||||
case VirtualKey::F1:
|
||||
return "F1";
|
||||
case VirtualKey::F2:
|
||||
return "F2";
|
||||
case VirtualKey::F3:
|
||||
return "F3";
|
||||
case VirtualKey::F4:
|
||||
return "F4";
|
||||
case VirtualKey::F5:
|
||||
return "F5";
|
||||
case VirtualKey::F6:
|
||||
return "F6";
|
||||
case VirtualKey::F7:
|
||||
return "F7";
|
||||
case VirtualKey::F8:
|
||||
return "F8";
|
||||
case VirtualKey::F9:
|
||||
return "F9";
|
||||
case VirtualKey::F10:
|
||||
return "F10";
|
||||
case VirtualKey::F11:
|
||||
return "F11";
|
||||
case VirtualKey::F12:
|
||||
return "F12";
|
||||
case VirtualKey::Shift:
|
||||
return "Shift";
|
||||
case VirtualKey::LeftShift:
|
||||
return "Shift";
|
||||
case VirtualKey::RightShift:
|
||||
return "Shift";
|
||||
case VirtualKey::Control:
|
||||
return "Control";
|
||||
case VirtualKey::LeftControl:
|
||||
return "Control";
|
||||
case VirtualKey::RightControl:
|
||||
return "Control";
|
||||
case VirtualKey::Escape:
|
||||
return "Escape";
|
||||
case VirtualKey::Enter:
|
||||
return "Enter";
|
||||
case VirtualKey::Tab:
|
||||
return "Tab";
|
||||
case VirtualKey::Delete:
|
||||
return "Delete";
|
||||
case VirtualKey::Back:
|
||||
return "Backspace";
|
||||
case VirtualKey::GoForward:
|
||||
return "BrowserForward";
|
||||
case VirtualKey::GoBack:
|
||||
return "BrowserBack";
|
||||
case VirtualKey::GoHome:
|
||||
return "BrowserHome";
|
||||
case VirtualKey::Favorites:
|
||||
return "BrowserFavorites";
|
||||
case VirtualKey::Search:
|
||||
return "BrowserSearch";
|
||||
case VirtualKey::Stop:
|
||||
return "BrowserStop";
|
||||
case VirtualKey::Menu:
|
||||
return "Alt";
|
||||
case VirtualKey::RightMenu:
|
||||
return "Alt";
|
||||
case VirtualKey::LeftMenu:
|
||||
return "Alt";
|
||||
case VirtualKey::CapitalLock:
|
||||
return "CapsLock";
|
||||
case VirtualKey::LeftWindows:
|
||||
return "Meta";
|
||||
case VirtualKey::RightWindows:
|
||||
return "Meta";
|
||||
case VirtualKey::NumberKeyLock:
|
||||
return "NumLock";
|
||||
case VirtualKey::Scroll:
|
||||
return "ScrollLock";
|
||||
case VirtualKey::Down:
|
||||
return "ArrowDown";
|
||||
case VirtualKey::Up:
|
||||
return "ArrowUp";
|
||||
case VirtualKey::Left:
|
||||
return "ArrowLeft";
|
||||
case VirtualKey::Right:
|
||||
return "ArrowRight";
|
||||
case VirtualKey::End:
|
||||
return "End";
|
||||
case VirtualKey::Home:
|
||||
return "Home";
|
||||
case VirtualKey::PageDown:
|
||||
return "PageHome";
|
||||
case VirtualKey::PageUp:
|
||||
return "PageUp";
|
||||
case VirtualKey::Clear:
|
||||
return "Clear";
|
||||
case VirtualKey::Insert:
|
||||
return "Insert";
|
||||
case VirtualKey::Accept:
|
||||
return "Accept";
|
||||
case VirtualKey::Cancel:
|
||||
return "Cancel";
|
||||
case VirtualKey::Execute:
|
||||
return "Execute";
|
||||
case VirtualKey::Help:
|
||||
return "Help";
|
||||
case VirtualKey::Pause:
|
||||
return "Pause";
|
||||
case VirtualKey::Select:
|
||||
return "Select";
|
||||
case VirtualKey::Print:
|
||||
return "Print";
|
||||
case VirtualKey::Convert:
|
||||
return "Convert";
|
||||
case VirtualKey::NonConvert:
|
||||
return "NonConvert";
|
||||
case VirtualKey::ModeChange:
|
||||
return "ModeChange";
|
||||
case VirtualKey::Hangul:
|
||||
return "HangulMode";
|
||||
case VirtualKey::Hanja:
|
||||
return "HanjaMode";
|
||||
case VirtualKey::Junja:
|
||||
return "JunjaMode";
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
} // namespace winrt
|
|
@ -1,189 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pch.h"
|
||||
#include "strutils.h"
|
||||
#include "OpenGLES.h"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
|
||||
OpenGLES::OpenGLES()
|
||||
: mEglConfig(nullptr), mEglDisplay(EGL_NO_DISPLAY),
|
||||
mEglContext(EGL_NO_CONTEXT) {
|
||||
log(L"OpenGLES::OpenGLES()");
|
||||
Initialize();
|
||||
}
|
||||
|
||||
OpenGLES::~OpenGLES() { Cleanup(); }
|
||||
|
||||
void OpenGLES::Initialize() {
|
||||
const EGLint configAttributes[] = {EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_ALPHA_SIZE,
|
||||
8,
|
||||
EGL_DEPTH_SIZE,
|
||||
24,
|
||||
EGL_STENCIL_SIZE,
|
||||
8,
|
||||
EGL_NONE};
|
||||
|
||||
const EGLint contextAttributes[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
|
||||
|
||||
// Based on Angle MS template.
|
||||
|
||||
const EGLint defaultDisplayAttributes[] = {
|
||||
// These are the default display attributes, used to request ANGLE's D3D11
|
||||
// renderer.
|
||||
// eglInitialize will only succeed with these attributes if the hardware
|
||||
// supports D3D11 Feature Level 10_0+.
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
|
||||
// EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE is an optimization that
|
||||
// can have large performance benefits on mobile devices.
|
||||
EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
|
||||
EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
|
||||
|
||||
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that
|
||||
// enables ANGLE to automatically call
|
||||
// the IDXGIDevice3::Trim method on behalf of the application when it gets
|
||||
// suspended.
|
||||
// Calling IDXGIDevice3::Trim when an application is suspended is a
|
||||
// Windows Store application certification
|
||||
// requirement.
|
||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
|
||||
EGL_TRUE,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
const EGLint fl9_3DisplayAttributes[] = {
|
||||
// These can be used to request ANGLE's D3D11 renderer, with D3D11 Feature
|
||||
// Level 9_3.
|
||||
// These attributes are used if the call to eglInitialize fails with the
|
||||
// default display attributes.
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
|
||||
9,
|
||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,
|
||||
3,
|
||||
EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
|
||||
EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
|
||||
EGL_TRUE,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
const EGLint warpDisplayAttributes[] = {
|
||||
// These attributes can be used to request D3D11 WARP.
|
||||
// They are used if eglInitialize fails with both the default display
|
||||
// attributes and the 9_3 display attributes.
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE,
|
||||
EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
|
||||
EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
|
||||
EGL_TRUE,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
// eglGetPlatformDisplayEXT is an alternative to eglGetDisplay.
|
||||
// It allows us to pass in display attributes, used to configure D3D11.
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
|
||||
reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
|
||||
eglGetProcAddress("eglGetPlatformDisplayEXT"));
|
||||
if (!eglGetPlatformDisplayEXT) {
|
||||
throw winrt::hresult_error(
|
||||
E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT");
|
||||
}
|
||||
|
||||
//
|
||||
// To initialize the display, we make three sets of calls to
|
||||
// eglGetPlatformDisplayEXT and eglInitialize, with varying parameters passed
|
||||
// to eglGetPlatformDisplayEXT: 1) The first calls uses
|
||||
// "defaultDisplayAttributes" as a parameter. This corresponds to D3D11
|
||||
// Feature Level 10_0+. 2) If eglInitialize fails for step 1 (e.g. because
|
||||
// 10_0+ isn't supported by the default GPU), then we try again
|
||||
// using "fl9_3DisplayAttributes". This corresponds to D3D11 Feature Level
|
||||
// 9_3.
|
||||
// 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by
|
||||
// the default GPU), then we try again
|
||||
// using "warpDisplayAttributes". This corresponds to D3D11 Feature Level
|
||||
// 11_0 on WARP, a D3D11 software rasterizer.
|
||||
//
|
||||
|
||||
// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above
|
||||
// comment for details.
|
||||
mEglDisplay = eglGetPlatformDisplayEXT(
|
||||
EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
|
||||
if (mEglDisplay == EGL_NO_DISPLAY) {
|
||||
throw winrt::hresult_error(E_FAIL, L"Failed to get EGL display");
|
||||
}
|
||||
|
||||
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) {
|
||||
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is
|
||||
// unavailable (e.g. on some mobile devices).
|
||||
mEglDisplay = eglGetPlatformDisplayEXT(
|
||||
EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
|
||||
if (mEglDisplay == EGL_NO_DISPLAY) {
|
||||
throw winrt::hresult_error(E_FAIL, L"Failed to get EGL display");
|
||||
}
|
||||
|
||||
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) {
|
||||
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is
|
||||
// unavailable on the default GPU.
|
||||
mEglDisplay = eglGetPlatformDisplayEXT(
|
||||
EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
|
||||
if (mEglDisplay == EGL_NO_DISPLAY) {
|
||||
throw winrt::hresult_error(E_FAIL, L"Failed to get EGL display");
|
||||
}
|
||||
|
||||
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) {
|
||||
// If all of the calls to eglInitialize returned EGL_FALSE then an error
|
||||
// has occurred.
|
||||
throw winrt::hresult_error(E_FAIL, L"Failed to initialize EGL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EGLint numConfigs = 0;
|
||||
if ((eglChooseConfig(mEglDisplay, configAttributes, &mEglConfig, 1,
|
||||
&numConfigs) == EGL_FALSE) ||
|
||||
(numConfigs == 0)) {
|
||||
throw winrt::hresult_error(E_FAIL, L"Failed to choose first EGLConfig");
|
||||
}
|
||||
|
||||
mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT,
|
||||
contextAttributes);
|
||||
if (mEglContext == EGL_NO_CONTEXT) {
|
||||
throw winrt::hresult_error(E_FAIL, L"Failed to create EGL context");
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLES::Cleanup() {
|
||||
if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT) {
|
||||
eglDestroyContext(mEglDisplay, mEglContext);
|
||||
mEglContext = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (mEglDisplay != EGL_NO_DISPLAY) {
|
||||
eglTerminate(mEglDisplay);
|
||||
mEglDisplay = EGL_NO_DISPLAY;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLES::Reset() {
|
||||
Cleanup();
|
||||
Initialize();
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
class OpenGLES {
|
||||
public:
|
||||
OpenGLES();
|
||||
~OpenGLES();
|
||||
|
||||
EGLNativeWindowType
|
||||
GetNativeWindow(winrt::Windows::UI::Xaml::Controls::SwapChainPanel const &,
|
||||
float dpi);
|
||||
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
void Initialize();
|
||||
void Cleanup();
|
||||
|
||||
private:
|
||||
EGLDisplay mEglDisplay = EGL_NO_DISPLAY;
|
||||
EGLContext mEglContext = nullptr;
|
||||
EGLConfig mEglConfig = nullptr;
|
||||
};
|
|
@ -1,470 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pch.h"
|
||||
#include "Servo.h"
|
||||
#include "Crash.h"
|
||||
#include <EGL/egl.h>
|
||||
#include "../DefaultUrl.h"
|
||||
|
||||
namespace winrt::servo {
|
||||
|
||||
using namespace Windows::Storage;
|
||||
|
||||
void on_load_started() { sServo->Delegate().OnServoLoadStarted(); }
|
||||
|
||||
void on_load_ended() { sServo->Delegate().OnServoLoadEnded(); }
|
||||
|
||||
void on_history_changed(bool back, bool forward) {
|
||||
sServo->Delegate().OnServoHistoryChanged(back, forward);
|
||||
}
|
||||
|
||||
void on_shutdown_complete() { sServo->Delegate().OnServoShutdownComplete(); }
|
||||
|
||||
void on_title_changed(const char *title) {
|
||||
sServo->Delegate().OnServoTitleChanged(char2hstring(title));
|
||||
}
|
||||
|
||||
void on_url_changed(const char *curl) {
|
||||
auto url = char2hstring(curl);
|
||||
sServo->CurrentUrl(url);
|
||||
sServo->Delegate().OnServoURLChanged(url);
|
||||
}
|
||||
|
||||
void wakeup() {
|
||||
if (sServo != nullptr)
|
||||
sServo->Delegate().WakeUp();
|
||||
}
|
||||
|
||||
bool on_allow_navigation(const char *url) {
|
||||
return sServo->Delegate().OnServoAllowNavigation(char2hstring(url));
|
||||
};
|
||||
|
||||
void on_animating_changed(bool aAnimating) {
|
||||
sServo->Delegate().OnServoAnimatingChanged(aAnimating);
|
||||
}
|
||||
|
||||
void on_panic(const char *cbacktrace) {
|
||||
|
||||
if (sLogHandle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(sLogHandle);
|
||||
sLogHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
auto backtrace = char2hstring(cbacktrace);
|
||||
|
||||
try {
|
||||
WriteCrashReport(backtrace, sServo->CurrentUrl());
|
||||
} catch (...) {
|
||||
log(L"Failed to log panic to crash report");
|
||||
}
|
||||
|
||||
// If this is happening in the GL thread, the app can continue running.
|
||||
// So let's show the crash report:
|
||||
sServo->Delegate().OnServoPanic(backtrace);
|
||||
throw hresult_error(E_FAIL, backtrace);
|
||||
}
|
||||
|
||||
void on_ime_show(const char *text, int32_t text_index, bool multiline,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height) {
|
||||
hstring htext = L"";
|
||||
if (text != nullptr) {
|
||||
htext = char2hstring(text);
|
||||
}
|
||||
sServo->Delegate().OnServoIMEShow(htext, x, y, width, height);
|
||||
}
|
||||
|
||||
void on_ime_hide() { sServo->Delegate().OnServoIMEHide(); }
|
||||
|
||||
void set_clipboard_contents(const char *) {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
const char *get_clipboard_contents() {
|
||||
// FIXME
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void on_media_session_set_position_state(double duration, double position,
|
||||
double playback_rate) {
|
||||
return sServo->Delegate().OnServoMediaSessionPosition(duration, position,
|
||||
playback_rate);
|
||||
}
|
||||
|
||||
void on_media_session_metadata(const char *title, const char *album,
|
||||
const char *artist) {
|
||||
return sServo->Delegate().OnServoMediaSessionMetadata(
|
||||
char2hstring(title), char2hstring(album), char2hstring(artist));
|
||||
}
|
||||
|
||||
void on_media_session_playback_state_change(
|
||||
const capi::CMediaSessionPlaybackState state) {
|
||||
return sServo->Delegate().OnServoMediaSessionPlaybackStateChange(state);
|
||||
}
|
||||
|
||||
void prompt_alert(const char *message, bool trusted) {
|
||||
sServo->Delegate().OnServoPromptAlert(char2hstring(message), trusted);
|
||||
}
|
||||
|
||||
void show_context_menu(const char *title, const char *const *items_list,
|
||||
uint32_t items_size) {
|
||||
std::optional<hstring> opt_title = {};
|
||||
if (title != nullptr) {
|
||||
opt_title = char2hstring(title);
|
||||
}
|
||||
std::vector<winrt::hstring> items;
|
||||
for (uint32_t i = 0; i < items_size; i++) {
|
||||
items.push_back(char2hstring(items_list[i]));
|
||||
}
|
||||
sServo->Delegate().OnServoShowContextMenu(opt_title, items);
|
||||
}
|
||||
|
||||
void on_devtools_started(Servo::DevtoolsServerState result,
|
||||
const unsigned int port, const char *token) {
|
||||
auto state = result == Servo::DevtoolsServerState::Started;
|
||||
sServo->Delegate().OnServoDevtoolsStarted(state, port, char2hstring(token));
|
||||
}
|
||||
|
||||
void on_log_output(const char *buffer, uint32_t buffer_length) {
|
||||
OutputDebugStringA(buffer);
|
||||
|
||||
if (sLogHandle == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD bytesWritten;
|
||||
auto writeResult =
|
||||
WriteFile(sLogHandle, buffer, buffer_length, &bytesWritten, nullptr);
|
||||
|
||||
if (writeResult == FALSE || bytesWritten != buffer_length)
|
||||
throw std::runtime_error(
|
||||
"Failed to write log message to the log file: error code " +
|
||||
std::to_string(GetLastError()));
|
||||
}
|
||||
|
||||
Servo::PromptResult prompt_ok_cancel(const char *message, bool trusted) {
|
||||
return sServo->Delegate().OnServoPromptOkCancel(char2hstring(message),
|
||||
trusted);
|
||||
}
|
||||
|
||||
Servo::PromptResult prompt_yes_no(const char *message, bool trusted) {
|
||||
return sServo->Delegate().OnServoPromptYesNo(char2hstring(message), trusted);
|
||||
}
|
||||
|
||||
const char *prompt_input(const char *message, const char *def, bool trusted) {
|
||||
auto input = sServo->Delegate().OnServoPromptInput(
|
||||
char2hstring(message), char2hstring(def), trusted);
|
||||
if (input.has_value()) {
|
||||
return *hstring2char(*input);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Servo::Servo(std::optional<hstring> initUrl, hstring args, GLsizei width,
|
||||
GLsizei height, EGLNativeWindowType eglNativeWindow, float dpi,
|
||||
ServoDelegate &aDelegate, bool transient)
|
||||
: mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) {
|
||||
ApplicationDataContainer localSettings =
|
||||
ApplicationData::Current().LocalSettings();
|
||||
if (!localSettings.Containers().HasKey(L"servoUserPrefs")) {
|
||||
ApplicationDataContainer container = localSettings.CreateContainer(
|
||||
L"servoUserPrefs", ApplicationDataCreateDisposition::Always);
|
||||
}
|
||||
|
||||
auto prefs = localSettings.Containers().Lookup(L"servoUserPrefs");
|
||||
|
||||
std::vector<capi::CPref> cprefs;
|
||||
|
||||
// Ensure few things stay in memories long enough as we send raw
|
||||
// pointers to Rust.
|
||||
std::vector<std::unique_ptr<char *>> memChar;
|
||||
std::vector<std::unique_ptr<bool>> memBool;
|
||||
std::vector<std::unique_ptr<int64_t>> memInt;
|
||||
std::vector<std::unique_ptr<double>> memDouble;
|
||||
|
||||
for (auto pref : prefs.Values()) {
|
||||
|
||||
auto charkey = hstring2char(pref.Key());
|
||||
auto key = *charkey.get();
|
||||
memChar.push_back(std::move(charkey));
|
||||
auto value = pref.Value();
|
||||
|
||||
auto type = value.as<Windows::Foundation::IPropertyValue>().Type();
|
||||
capi::CPref cpref;
|
||||
cpref.key = key;
|
||||
cpref.pref_type = capi::CPrefType::Missing;
|
||||
cpref.value = NULL;
|
||||
if (type == Windows::Foundation::PropertyType::Boolean) {
|
||||
cpref.pref_type = capi::CPrefType::Bool;
|
||||
auto val = std::make_unique<bool>(unbox_value<bool>(value));
|
||||
cpref.value = val.get();
|
||||
memBool.push_back(std::move(val));
|
||||
} else if (type == Windows::Foundation::PropertyType::String) {
|
||||
cpref.pref_type = capi::CPrefType::Str;
|
||||
auto val = hstring2char(unbox_value<hstring>(value));
|
||||
cpref.value = *val.get();
|
||||
memChar.push_back(std::move(val));
|
||||
} else if (type == Windows::Foundation::PropertyType::Int64) {
|
||||
cpref.pref_type = capi::CPrefType::Int;
|
||||
auto val = std::make_unique<int64_t>(unbox_value<int64_t>(value));
|
||||
cpref.value = val.get();
|
||||
memInt.push_back(std::move(val));
|
||||
} else if (type == Windows::Foundation::PropertyType::Double) {
|
||||
cpref.pref_type = capi::CPrefType::Float;
|
||||
auto val = std::make_unique<double>(unbox_value<double>(value));
|
||||
cpref.value = val.get();
|
||||
memDouble.push_back(std::move(val));
|
||||
} else if (type == Windows::Foundation::PropertyType::Empty) {
|
||||
cpref.pref_type = capi::CPrefType::Missing;
|
||||
} else {
|
||||
log(L"skipping pref %s. Unknown type", key);
|
||||
continue;
|
||||
}
|
||||
cprefs.push_back(cpref);
|
||||
}
|
||||
|
||||
if (initUrl.has_value()) {
|
||||
setNonPersistentHomepage(*initUrl, cprefs);
|
||||
} else {
|
||||
#ifdef OVERRIDE_DEFAULT_URL
|
||||
setNonPersistentHomepage(OVERRIDE_DEFAULT_URL, cprefs);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (transient) {
|
||||
capi::CPref cpref;
|
||||
cpref.key = "dom.webxr.sessionavailable";
|
||||
cpref.pref_type = capi::CPrefType::Bool;
|
||||
cpref.value = &transient;
|
||||
cprefs.push_back(cpref);
|
||||
}
|
||||
|
||||
capi::CPrefList prefsList = {cprefs.size(), cprefs.data()};
|
||||
|
||||
capi::CInitOptions o;
|
||||
o.prefs = &prefsList;
|
||||
o.args = *hstring2char(args);
|
||||
o.width = mWindowWidth;
|
||||
o.height = mWindowHeight;
|
||||
o.density = dpi;
|
||||
o.native_widget = eglNativeWindow;
|
||||
|
||||
// Note about logs:
|
||||
// By default: all modules are enabled. Only warn level-logs are displayed.
|
||||
// To change the log level, add "--vslogger-level debug" to o.args.
|
||||
// To only print logs from specific modules, add their names to pfilters.
|
||||
// For example:
|
||||
// static char *pfilters[] = {
|
||||
// "servo",
|
||||
// "simpleservo",
|
||||
// "script::dom::bindings::error", // Show JS errors by default.
|
||||
// "canvas::webgl_thread", // Show GL errors by default.
|
||||
// "compositing",
|
||||
// "constellation",
|
||||
// };
|
||||
// o.vslogger_mod_list = pfilters;
|
||||
// o.vslogger_mod_size = sizeof(pfilters) / sizeof(pfilters[0]);
|
||||
|
||||
o.vslogger_mod_list = NULL;
|
||||
o.vslogger_mod_size = 0;
|
||||
|
||||
sServo = this; // FIXME;
|
||||
|
||||
auto current = ApplicationData::Current();
|
||||
auto gstLog = std::wstring(current.LocalFolder().Path()) + L"\\gst.log";
|
||||
SetEnvironmentVariable(L"GST_DEBUG_FILE", gstLog.c_str());
|
||||
// SetEnvironmentVariableA("GST_DEBUG", "4");
|
||||
|
||||
auto filePath = std::wstring(current.LocalFolder().Path()) + L"\\stdout.txt";
|
||||
sLogHandle =
|
||||
CreateFile2(filePath.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr);
|
||||
if (sLogHandle == INVALID_HANDLE_VALUE) {
|
||||
throw std::runtime_error("Failed to open the log file: error code " +
|
||||
std::to_string(GetLastError()));
|
||||
}
|
||||
|
||||
if (SetFilePointer(sLogHandle, 0, nullptr, FILE_END) ==
|
||||
INVALID_SET_FILE_POINTER) {
|
||||
throw std::runtime_error(
|
||||
"Failed to set file pointer to the end of file: error code " +
|
||||
std::to_string(GetLastError()));
|
||||
}
|
||||
|
||||
capi::CHostCallbacks c = capi::CHostCallbacks{
|
||||
.on_load_started = &on_load_started,
|
||||
.on_load_ended = &on_load_ended,
|
||||
.on_title_changed = &on_title_changed,
|
||||
.on_allow_navigation = &on_allow_navigation,
|
||||
.on_url_changed = &on_url_changed,
|
||||
.on_history_changed = &on_history_changed,
|
||||
.on_animating_changed = &on_animating_changed,
|
||||
.on_shutdown_complete = &on_shutdown_complete,
|
||||
.on_ime_show = &on_ime_show,
|
||||
.on_ime_hide = &on_ime_hide,
|
||||
.get_clipboard_contents = &get_clipboard_contents,
|
||||
.set_clipboard_contents = &set_clipboard_contents,
|
||||
.on_media_session_metadata = &on_media_session_metadata,
|
||||
.on_media_session_playback_state_change =
|
||||
&on_media_session_playback_state_change,
|
||||
.on_media_session_set_position_state =
|
||||
&on_media_session_set_position_state,
|
||||
.prompt_alert = &prompt_alert,
|
||||
.prompt_ok_cancel = &prompt_ok_cancel,
|
||||
.prompt_yes_no = &prompt_yes_no,
|
||||
.prompt_input = &prompt_input,
|
||||
.on_devtools_started = &on_devtools_started,
|
||||
.show_context_menu = &show_context_menu,
|
||||
.on_log_output = &on_log_output,
|
||||
};
|
||||
|
||||
capi::register_panic_handler(&on_panic);
|
||||
|
||||
capi::init_with_egl(o, &wakeup, c);
|
||||
}
|
||||
|
||||
Servo::~Servo() {
|
||||
sServo = nullptr;
|
||||
if (sLogHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(sLogHandle);
|
||||
}
|
||||
|
||||
Servo::PrefTuple Servo::SetFloatPref(hstring key, double val) {
|
||||
auto ckey = *hstring2char(key);
|
||||
capi::set_float_pref(ckey, val);
|
||||
auto updatedPref = WrapPref(capi::get_pref(ckey));
|
||||
SaveUserPref(updatedPref);
|
||||
return updatedPref;
|
||||
}
|
||||
|
||||
Servo::PrefTuple Servo::SetIntPref(hstring key, int64_t val) {
|
||||
auto ckey = *hstring2char(key);
|
||||
capi::set_int_pref(ckey, val);
|
||||
auto updatedPref = WrapPref(capi::get_pref(ckey));
|
||||
SaveUserPref(updatedPref);
|
||||
return updatedPref;
|
||||
}
|
||||
|
||||
Servo::PrefTuple Servo::SetBoolPref(hstring key, bool val) {
|
||||
auto ckey = *hstring2char(key);
|
||||
capi::set_bool_pref(ckey, val);
|
||||
auto updatedPref = WrapPref(capi::get_pref(ckey));
|
||||
SaveUserPref(updatedPref);
|
||||
return updatedPref;
|
||||
}
|
||||
|
||||
Servo::PrefTuple Servo::SetStringPref(hstring key, hstring val) {
|
||||
auto ckey = *hstring2char(key);
|
||||
auto cval = *hstring2char(val);
|
||||
capi::set_str_pref(ckey, cval);
|
||||
auto updatedPref = WrapPref(capi::get_pref(ckey));
|
||||
SaveUserPref(updatedPref);
|
||||
return updatedPref;
|
||||
}
|
||||
|
||||
Servo::PrefTuple Servo::ResetPref(hstring key) {
|
||||
auto ckey = *hstring2char(key);
|
||||
capi::reset_pref(ckey);
|
||||
auto updatedPref = WrapPref(capi::get_pref(ckey));
|
||||
SaveUserPref(updatedPref);
|
||||
return updatedPref;
|
||||
}
|
||||
|
||||
void Servo::GoHome() {
|
||||
ApplicationDataContainer localSettings =
|
||||
ApplicationData::Current().LocalSettings();
|
||||
auto prefs = localSettings.Containers().Lookup(L"servoUserPrefs");
|
||||
auto home_pref = prefs.Values().Lookup(L"shell.homepage");
|
||||
auto home = home_pref ? unbox_value<hstring>(home_pref) :
|
||||
#ifdef OVERRIDE_DEFAULT_URL
|
||||
OVERRIDE_DEFAULT_URL
|
||||
#else
|
||||
FALLBACK_DEFAULT_URL
|
||||
#endif
|
||||
;
|
||||
LoadUri(home);
|
||||
}
|
||||
|
||||
void Servo::SaveUserPref(PrefTuple pref) {
|
||||
auto localSettings = ApplicationData::Current().LocalSettings();
|
||||
auto values = localSettings.Containers().Lookup(L"servoUserPrefs").Values();
|
||||
auto [key, val, isDefault] = pref;
|
||||
if (isDefault) {
|
||||
values.Remove(key);
|
||||
} else {
|
||||
values.Insert(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
Servo::PrefTuple Servo::WrapPref(capi::CPref pref) {
|
||||
winrt::Windows::Foundation::IInspectable val;
|
||||
if (pref.pref_type == capi::CPrefType::Bool) {
|
||||
val = box_value(*(capi::get_pref_as_bool(pref.value)));
|
||||
} else if (pref.pref_type == capi::CPrefType::Int) {
|
||||
val = box_value(*(capi::get_pref_as_int(pref.value)));
|
||||
} else if (pref.pref_type == capi::CPrefType::Float) {
|
||||
val = box_value(*(capi::get_pref_as_float(pref.value)));
|
||||
} else if (pref.pref_type == capi::CPrefType::Str) {
|
||||
val = box_value(char2hstring(capi::get_pref_as_str(pref.value)));
|
||||
}
|
||||
auto key = char2hstring(pref.key);
|
||||
auto isDefault = pref.is_default;
|
||||
Servo::PrefTuple t{key, val, isDefault};
|
||||
return t;
|
||||
}
|
||||
|
||||
Servo::PrefTuple Servo::GetPref(hstring key) {
|
||||
auto ckey = *hstring2char(key);
|
||||
return WrapPref(capi::get_pref(ckey));
|
||||
}
|
||||
|
||||
std::vector<Servo::PrefTuple> Servo::GetPrefs() {
|
||||
if (sServo == nullptr) {
|
||||
return {};
|
||||
}
|
||||
auto prefs = capi::get_prefs();
|
||||
std::vector<PrefTuple> vec;
|
||||
for (auto i = 0; i < prefs.len; i++) {
|
||||
auto pref = WrapPref(prefs.list[i]);
|
||||
vec.push_back(pref);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
void setNonPersistentHomepage(hstring url, std::vector<capi::CPref> &cprefs) {
|
||||
for (auto cpref : cprefs) {
|
||||
if (strcmp(cpref.key, "shell.homepage") == 0) {
|
||||
cpref.value = *hstring2char(url);
|
||||
return;
|
||||
}
|
||||
}
|
||||
capi::CPref cpref;
|
||||
cpref.key = "shell.homepage";
|
||||
cpref.pref_type = capi::CPrefType::Str;
|
||||
cpref.value = *hstring2char(url);
|
||||
cprefs.push_back(cpref);
|
||||
}
|
||||
|
||||
winrt::hstring char2hstring(const char *c_str) {
|
||||
// FIXME: any better way of doing this?
|
||||
auto str = std::string(c_str);
|
||||
int size_needed =
|
||||
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
|
||||
std::wstring str2(size_needed, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &str2[0],
|
||||
size_needed);
|
||||
winrt::hstring str3{str2};
|
||||
return str3;
|
||||
}
|
||||
|
||||
std::unique_ptr<char *> hstring2char(hstring hstr) {
|
||||
const wchar_t *wc = hstr.c_str();
|
||||
size_t size = hstr.size() + 1;
|
||||
char *str = new char[size];
|
||||
size_t converted = 0;
|
||||
wcstombs_s(&converted, str, size, wc, hstr.size());
|
||||
return std::make_unique<char *>(str);
|
||||
}
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,146 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
#include <EGL/egl.h>
|
||||
#include "strutils.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace winrt::servo {
|
||||
|
||||
namespace capi {
|
||||
extern "C" {
|
||||
#include <simpleservo.h>
|
||||
}
|
||||
} // namespace capi
|
||||
|
||||
using namespace capi;
|
||||
|
||||
hstring char2hstring(const char *);
|
||||
std::unique_ptr<char *> hstring2char(hstring);
|
||||
void setNonPersistentHomepage(hstring, std::vector<capi::CPref> &);
|
||||
|
||||
class ServoDelegate;
|
||||
|
||||
class Servo {
|
||||
public:
|
||||
Servo(std::optional<hstring>, hstring, GLsizei, GLsizei, EGLNativeWindowType,
|
||||
float, ServoDelegate &, bool);
|
||||
~Servo();
|
||||
ServoDelegate &Delegate() { return mDelegate; }
|
||||
hstring CurrentUrl() { return mUrl; }
|
||||
void CurrentUrl(hstring url) { mUrl = url; }
|
||||
|
||||
typedef std::tuple<hstring, winrt::Windows::Foundation::IInspectable, bool>
|
||||
PrefTuple;
|
||||
static std::vector<PrefTuple> GetPrefs();
|
||||
static PrefTuple GetPref(hstring key);
|
||||
static PrefTuple SetBoolPref(hstring key, bool val);
|
||||
static PrefTuple SetStringPref(hstring key, hstring val);
|
||||
static PrefTuple SetIntPref(hstring key, int64_t val);
|
||||
static PrefTuple SetFloatPref(hstring key, double val);
|
||||
static PrefTuple ResetPref(hstring key);
|
||||
|
||||
typedef CMouseButton MouseButton;
|
||||
typedef CPromptResult PromptResult;
|
||||
typedef CContextMenuResult ContextMenuResult;
|
||||
typedef CMediaSessionActionType MediaSessionActionType;
|
||||
typedef CMediaSessionPlaybackState MediaSessionPlaybackState;
|
||||
typedef CDevtoolsServerState DevtoolsServerState;
|
||||
typedef CPrefType CPrefType;
|
||||
|
||||
void PerformUpdates() { perform_updates(); }
|
||||
void DeInit() { deinit(); }
|
||||
void RequestShutdown() { request_shutdown(); }
|
||||
void SetBatchMode(bool mode) { set_batch_mode(mode); }
|
||||
void GoForward() { go_forward(); }
|
||||
void GoBack() { go_back(); }
|
||||
void Click(float x, float y) { click(x, y); }
|
||||
void MouseDown(float x, float y, CMouseButton b) { mouse_down(x, y, b); }
|
||||
void MouseUp(float x, float y, CMouseButton b) { mouse_up(x, y, b); }
|
||||
void TouchDown(float x, float y, int32_t id) { touch_down(x, y, id); }
|
||||
void TouchUp(float x, float y, int32_t id) { touch_up(x, y, id); }
|
||||
void TouchMove(float x, float y, int32_t id) { touch_move(x, y, id); }
|
||||
void TouchCancel(float x, float y, int32_t id) { touch_cancel(x, y, id); }
|
||||
void MouseMove(float x, float y) { mouse_move(x, y); }
|
||||
void KeyDown(const char *k) { key_down(k); }
|
||||
void KeyUp(const char *k) { key_up(k); }
|
||||
|
||||
void Reload() {
|
||||
clear_cache();
|
||||
reload();
|
||||
}
|
||||
void Stop() { stop(); }
|
||||
bool LoadUri(hstring uri) { return load_uri(*hstring2char(uri)); }
|
||||
void ChangeVisibility(bool visible) { change_visibility(visible); }
|
||||
bool IsUriValid(hstring uri) { return is_uri_valid(*hstring2char(uri)); }
|
||||
void GoHome();
|
||||
void Scroll(float dx, float dy, float x, float y) {
|
||||
scroll((int32_t)dx, (int32_t)dy, (int32_t)x, (int32_t)y);
|
||||
}
|
||||
void SetSize(GLsizei width, GLsizei height) {
|
||||
if (width != mWindowWidth || height != mWindowHeight) {
|
||||
mWindowWidth = width;
|
||||
mWindowHeight = height;
|
||||
resize(mWindowWidth, mWindowHeight);
|
||||
}
|
||||
}
|
||||
void SendMediaSessionAction(CMediaSessionActionType action) {
|
||||
media_session_action(action);
|
||||
}
|
||||
void ContextMenuClosed(CContextMenuResult res, unsigned int idx) {
|
||||
on_context_menu_closed(res, idx);
|
||||
}
|
||||
void IMEDismissed() { ime_dismissed(); }
|
||||
|
||||
private:
|
||||
ServoDelegate &mDelegate;
|
||||
hstring mUrl;
|
||||
GLsizei mWindowWidth;
|
||||
GLsizei mWindowHeight;
|
||||
static void SaveUserPref(PrefTuple);
|
||||
static PrefTuple WrapPref(CPref cpref);
|
||||
};
|
||||
|
||||
class ServoDelegate {
|
||||
public:
|
||||
// Called from any thread
|
||||
virtual void WakeUp() = 0;
|
||||
// Called from GL thread
|
||||
virtual void OnServoLoadStarted() = 0;
|
||||
virtual void OnServoLoadEnded() = 0;
|
||||
virtual void OnServoHistoryChanged(bool, bool) = 0;
|
||||
virtual void OnServoShutdownComplete() = 0;
|
||||
virtual void OnServoTitleChanged(hstring) = 0;
|
||||
virtual void OnServoURLChanged(hstring) = 0;
|
||||
virtual bool OnServoAllowNavigation(hstring) = 0;
|
||||
virtual void OnServoAnimatingChanged(bool) = 0;
|
||||
virtual void OnServoPanic(hstring) = 0;
|
||||
virtual void OnServoIMEShow(hstring text, int32_t x, int32_t y, int32_t width,
|
||||
int32_t height) = 0;
|
||||
virtual void OnServoIMEHide() = 0;
|
||||
virtual void OnServoDevtoolsStarted(bool, const unsigned int, hstring) = 0;
|
||||
virtual void OnServoMediaSessionMetadata(hstring, hstring, hstring) = 0;
|
||||
virtual void OnServoMediaSessionPosition(double, double, double) = 0;
|
||||
virtual void OnServoMediaSessionPlaybackStateChange(int) = 0;
|
||||
virtual void OnServoPromptAlert(hstring, bool) = 0;
|
||||
virtual void OnServoShowContextMenu(std::optional<hstring>,
|
||||
std::vector<hstring>) = 0;
|
||||
virtual Servo::PromptResult OnServoPromptOkCancel(hstring, bool) = 0;
|
||||
virtual Servo::PromptResult OnServoPromptYesNo(hstring, bool) = 0;
|
||||
virtual std::optional<hstring> OnServoPromptInput(hstring, hstring, bool) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~ServoDelegate(){};
|
||||
};
|
||||
|
||||
// This is sad. We need a static pointer to Servo because we use function
|
||||
// pointer as callback in Servo, and these functions need a way to get
|
||||
// the Servo instance. See https://github.com/servo/servo/issues/22967
|
||||
static Servo *sServo = nullptr;
|
||||
static HANDLE sLogHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
} // namespace winrt::servo
|
|
@ -1,733 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "strutils.h"
|
||||
#include "ServoControl.h"
|
||||
#include "ServoControl.g.cpp"
|
||||
#include "Pref.g.cpp"
|
||||
#include <stdlib.h>
|
||||
#include "Keys.h"
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace winrt::Windows::ApplicationModel::Resources;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Popups;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Text::Core;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::Devices::Input;
|
||||
using namespace concurrency;
|
||||
using namespace winrt::servo;
|
||||
|
||||
namespace winrt::ServoApp::implementation {
|
||||
|
||||
ServoControl::ServoControl() {
|
||||
mDPI = (float)DisplayInformation::GetForCurrentView().ResolutionScale() / 100;
|
||||
DefaultStyleKey(winrt::box_value(L"ServoApp.ServoControl"));
|
||||
Loaded(std::bind(&ServoControl::OnLoaded, this, _1, _2));
|
||||
|
||||
auto r = ResourceLoader::GetForCurrentView();
|
||||
L10NStrings l10NStrings = {r.GetString(L"ContextMenu/title"),
|
||||
r.GetString(L"JavascriptPrompt/title"),
|
||||
r.GetString(L"JavascriptPrompt/ok"),
|
||||
r.GetString(L"JavascriptPrompt/cancel"),
|
||||
r.GetString(L"JavascriptPrompt/yes"),
|
||||
r.GetString(L"JavascriptPrompt/no"),
|
||||
r.GetString(L"URINotValid/Alert")};
|
||||
mL10NStrings = std::make_unique<L10NStrings>(l10NStrings);
|
||||
}
|
||||
|
||||
void ServoControl::Shutdown() {
|
||||
if (mServo != nullptr) {
|
||||
if (!mLooping) {
|
||||
// FIXME: this should not happen. In that case, we can't send the
|
||||
// shutdown event to Servo.
|
||||
} else {
|
||||
RunOnGLThread([=] { mServo->RequestShutdown(); });
|
||||
mLoopTask->wait();
|
||||
mLoopTask.reset();
|
||||
mServo.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) {
|
||||
auto panel = Panel();
|
||||
panel.Tapped(std::bind(&ServoControl::OnSurfaceTapped, this, _1, _2));
|
||||
panel.PointerPressed(
|
||||
std::bind(&ServoControl::OnSurfacePointerPressed, this, _1, _2, true));
|
||||
panel.PointerReleased(
|
||||
std::bind(&ServoControl::OnSurfacePointerPressed, this, _1, _2, false));
|
||||
panel.PointerCanceled(
|
||||
std::bind(&ServoControl::OnSurfacePointerCanceled, this, _1, _2));
|
||||
panel.PointerExited(
|
||||
std::bind(&ServoControl::OnSurfacePointerExited, this, _1, _2));
|
||||
panel.PointerCaptureLost(
|
||||
std::bind(&ServoControl::OnSurfacePointerLost, this, _1, _2));
|
||||
panel.PointerMoved(
|
||||
std::bind(&ServoControl::OnSurfacePointerMoved, this, _1, _2));
|
||||
panel.PointerWheelChanged(
|
||||
std::bind(&ServoControl::OnSurfaceWheelChanged, this, _1, _2));
|
||||
panel.ManipulationStarted([=](const auto &, const auto &e) {
|
||||
mOnCaptureGesturesStartedEvent();
|
||||
e.Handled(true);
|
||||
});
|
||||
panel.ManipulationCompleted([=](const auto &, const auto &e) {
|
||||
mOnCaptureGesturesEndedEvent();
|
||||
e.Handled(true);
|
||||
});
|
||||
panel.ManipulationDelta(
|
||||
std::bind(&ServoControl::OnSurfaceManipulationDelta, this, _1, _2));
|
||||
panel.SizeChanged(std::bind(&ServoControl::OnSurfaceResized, this, _1, _2));
|
||||
|
||||
InitializeTextController();
|
||||
InitializeConditionVariable(&mGLCondVar);
|
||||
InitializeCriticalSection(&mGLLock);
|
||||
InitializeConditionVariable(&mDialogCondVar);
|
||||
InitializeCriticalSection(&mDialogLock);
|
||||
CreateNativeWindow();
|
||||
StartRenderLoop();
|
||||
}
|
||||
|
||||
void ServoControl::InitializeTextController() {
|
||||
mInputPane = Windows::UI::ViewManagement::InputPane::GetForCurrentView();
|
||||
mInputPane->Hiding([=](const auto &, const auto &) {
|
||||
if (mLooping) {
|
||||
RunOnGLThread([=] { mServo->IMEDismissed(); });
|
||||
}
|
||||
});
|
||||
|
||||
auto manager = CoreTextServicesManager::GetForCurrentView();
|
||||
mEditContext = manager.CreateEditContext();
|
||||
mEditContext->InputPaneDisplayPolicy(CoreTextInputPaneDisplayPolicy::Manual);
|
||||
|
||||
mEditContext->TextRequested([=](const auto &, const auto &e) {
|
||||
e.Request().Text(*mFocusedInputText);
|
||||
});
|
||||
|
||||
mEditContext->SelectionRequested([=](const auto &, const auto &) {});
|
||||
|
||||
mEditContext->LayoutRequested([=](const auto &, const auto &e) {
|
||||
// Necessary to show the preview
|
||||
e.Request().LayoutBounds().TextBounds(*mFocusedInputRect);
|
||||
e.Request().LayoutBounds().ControlBounds(*mFocusedInputRect);
|
||||
});
|
||||
|
||||
mEditContext->TextUpdating([=](const auto &, const auto &e) {
|
||||
RunOnGLThread([=] {
|
||||
auto text = *hstring2char(e.Text());
|
||||
size_t size = strlen(text);
|
||||
for (int i = 0; i < size; i++) {
|
||||
char letter[2];
|
||||
memcpy(letter, &text[i], 1);
|
||||
letter[1] = '\0';
|
||||
mServo->KeyDown(letter);
|
||||
mServo->KeyUp(letter);
|
||||
}
|
||||
});
|
||||
e.Result(CoreTextTextUpdatingResult::Succeeded);
|
||||
});
|
||||
|
||||
GotFocus(
|
||||
[=](const auto &, const auto &) { mEditContext->NotifyFocusEnter(); });
|
||||
|
||||
LostFocus(
|
||||
[=](const auto &, const auto &) { mEditContext->NotifyFocusLeave(); });
|
||||
|
||||
PreviewKeyDown([=](const auto &, const auto &e) {
|
||||
auto keystr = KeyToString(e.Key());
|
||||
if (keystr.has_value()) {
|
||||
RunOnGLThread([=] {
|
||||
auto keyname = *keystr;
|
||||
mServo->KeyDown(keyname);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
PreviewKeyUp([=](const auto &, const auto &e) {
|
||||
auto keystr = KeyToString(e.Key());
|
||||
if (keystr.has_value()) {
|
||||
RunOnGLThread([=] {
|
||||
auto keyname = *keystr;
|
||||
mServo->KeyUp(keyname);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Controls::SwapChainPanel ServoControl::Panel() {
|
||||
return GetTemplateChild(L"swapChainPanel").as<Controls::SwapChainPanel>();
|
||||
}
|
||||
|
||||
void ServoControl::CreateNativeWindow() {
|
||||
mPanelWidth = (int)(Panel().ActualWidth() * mDPI);
|
||||
mPanelHeight = (int)(Panel().ActualHeight() * mDPI);
|
||||
mNativeWindowProperties.Insert(EGLNativeWindowTypeProperty, Panel());
|
||||
// How to set size and or scale:
|
||||
// Insert(EGLRenderSurfaceSizeProperty),
|
||||
// PropertyValue::CreateSize(*renderSurfaceSize));
|
||||
mNativeWindowProperties.Insert(EGLRenderResolutionScaleProperty,
|
||||
PropertyValue::CreateSingle(mDPI));
|
||||
}
|
||||
|
||||
EGLNativeWindowType ServoControl::GetNativeWindow() {
|
||||
EGLNativeWindowType win =
|
||||
static_cast<EGLNativeWindowType>(winrt::get_abi(mNativeWindowProperties));
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
void ServoControl::RecoverFromLostDevice() {
|
||||
StopRenderLoop();
|
||||
StartRenderLoop();
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfaceManipulationDelta(
|
||||
IInspectable const &, Input::ManipulationDeltaRoutedEventArgs const &e) {
|
||||
auto x = e.Position().X * mDPI;
|
||||
auto y = e.Position().Y * mDPI;
|
||||
auto dx = e.Delta().Translation.X * mDPI;
|
||||
auto dy = e.Delta().Translation.Y * mDPI;
|
||||
RunOnGLThread([=] { mServo->Scroll(dx, dy, x, y); });
|
||||
e.Handled(true);
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfaceTapped(IInspectable const &,
|
||||
Input::TappedRoutedEventArgs const &e) {
|
||||
Focus(FocusState::Programmatic);
|
||||
if (e.PointerDeviceType() == PointerDeviceType::Mouse) {
|
||||
auto coords = e.GetPosition(Panel());
|
||||
auto x = coords.X * mDPI;
|
||||
auto y = coords.Y * mDPI;
|
||||
RunOnGLThread([=] { mServo->Click(x, y); });
|
||||
}
|
||||
e.Handled(true);
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfacePointerPressed(
|
||||
IInspectable const &, Input::PointerRoutedEventArgs const &e, bool down) {
|
||||
auto ty = e.Pointer().PointerDeviceType();
|
||||
if (ty == PointerDeviceType::Mouse) {
|
||||
auto point = e.GetCurrentPoint(Panel());
|
||||
|
||||
auto x = point.Position().X * mDPI;
|
||||
auto y = point.Position().Y * mDPI;
|
||||
auto props = point.Properties();
|
||||
std::optional<Servo::MouseButton> button = {};
|
||||
|
||||
if (props.IsLeftButtonPressed()) {
|
||||
button = Servo::MouseButton::Left;
|
||||
} else if (props.IsRightButtonPressed()) {
|
||||
button = Servo::MouseButton::Right;
|
||||
} else if (props.IsMiddleButtonPressed()) {
|
||||
button = Servo::MouseButton::Middle;
|
||||
}
|
||||
|
||||
if (!button.has_value() && mPressedMouseButton.has_value()) {
|
||||
auto releasedButton = *mPressedMouseButton;
|
||||
mPressedMouseButton = {};
|
||||
RunOnGLThread([=] { mServo->MouseUp(x, y, releasedButton); });
|
||||
e.Handled(true);
|
||||
}
|
||||
|
||||
if (button.has_value()) {
|
||||
RunOnGLThread([=] { mServo->MouseDown(x, y, *button); });
|
||||
e.Handled(true);
|
||||
}
|
||||
|
||||
mPressedMouseButton = button;
|
||||
} else if (ty == PointerDeviceType::Touch) {
|
||||
auto point = e.GetCurrentPoint(Panel());
|
||||
|
||||
auto x = point.Position().X * mDPI;
|
||||
auto y = point.Position().Y * mDPI;
|
||||
|
||||
if (down) {
|
||||
RunOnGLThread([=] { mServo->TouchDown(x, y, point.PointerId()); });
|
||||
} else {
|
||||
RunOnGLThread([=] { mServo->TouchUp(x, y, point.PointerId()); });
|
||||
}
|
||||
e.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfacePointerCanceled(
|
||||
IInspectable const &, Input::PointerRoutedEventArgs const &e) {
|
||||
e.Handled(true);
|
||||
auto ty = e.Pointer().PointerDeviceType();
|
||||
if (ty == PointerDeviceType::Mouse) {
|
||||
mPressedMouseButton = {};
|
||||
} else if (ty == PointerDeviceType::Touch) {
|
||||
auto point = e.GetCurrentPoint(Panel());
|
||||
auto x = point.Position().X * mDPI;
|
||||
auto y = point.Position().Y * mDPI;
|
||||
RunOnGLThread([=] { mServo->TouchCancel(x, y, point.PointerId()); });
|
||||
}
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfacePointerExited(
|
||||
IInspectable const &, Input::PointerRoutedEventArgs const &e) {
|
||||
e.Handled(true);
|
||||
auto ty = e.Pointer().PointerDeviceType();
|
||||
if (ty == PointerDeviceType::Touch) {
|
||||
auto point = e.GetCurrentPoint(Panel());
|
||||
auto x = point.Position().X * mDPI;
|
||||
auto y = point.Position().Y * mDPI;
|
||||
RunOnGLThread([=] { mServo->TouchCancel(x, y, point.PointerId()); });
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfacePointerLost(
|
||||
IInspectable const &, Input::PointerRoutedEventArgs const &e) {
|
||||
// According to the documentation:
|
||||
// https://docs.microsoft.com/en-us/windows/uwp/design/input/handle-pointer-input#handle-pointer-events
|
||||
// we should cancel the event on PointLost. But we keep getting
|
||||
// PointerMoved events after PointerLost. Servo doesn't like getting events
|
||||
// from a pointer id that has been canceled. So we do nothing.
|
||||
e.Handled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfacePointerMoved(
|
||||
IInspectable const &, Input::PointerRoutedEventArgs const &e) {
|
||||
auto ty = e.Pointer().PointerDeviceType();
|
||||
auto point = e.GetCurrentPoint(Panel());
|
||||
auto x = point.Position().X * mDPI;
|
||||
auto y = point.Position().Y * mDPI;
|
||||
if (ty == PointerDeviceType::Touch && point.IsInContact()) {
|
||||
RunOnGLThread([=] { mServo->TouchMove(x, y, point.PointerId()); });
|
||||
} else {
|
||||
RunOnGLThread([=] { mServo->MouseMove(x, y); });
|
||||
}
|
||||
e.Handled(true);
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfaceWheelChanged(
|
||||
IInspectable const &, Input::PointerRoutedEventArgs const &e) {
|
||||
if (e.Pointer().PointerDeviceType() == PointerDeviceType::Mouse) {
|
||||
auto point = e.GetCurrentPoint(Panel());
|
||||
auto x = point.Position().X * mDPI;
|
||||
auto y = point.Position().Y * mDPI;
|
||||
auto delta = point.Properties().MouseWheelDelta() * mDPI;
|
||||
RunOnGLThread([=] { mServo->Scroll(0, (float)delta, x, y); });
|
||||
}
|
||||
}
|
||||
|
||||
void ServoControl::OnSurfaceResized(IInspectable const &,
|
||||
SizeChangedEventArgs const &e) {
|
||||
auto size = e.NewSize();
|
||||
auto w = (size.Width * mDPI);
|
||||
auto h = (size.Height * mDPI);
|
||||
RunOnGLThread([=] { mServo->SetSize((GLsizei)w, (GLsizei)h); });
|
||||
}
|
||||
|
||||
void ServoControl::GoBack() {
|
||||
RunOnGLThread([=] { mServo->GoBack(); });
|
||||
}
|
||||
void ServoControl::GoForward() {
|
||||
RunOnGLThread([=] { mServo->GoForward(); });
|
||||
}
|
||||
void ServoControl::Reload() {
|
||||
RunOnGLThread([=] { mServo->Reload(); });
|
||||
}
|
||||
void ServoControl::ChangeVisibility(bool visible) {
|
||||
RunOnGLThread([=] { mServo->ChangeVisibility(visible); });
|
||||
}
|
||||
void ServoControl::Stop() {
|
||||
RunOnGLThread([=] { mServo->Stop(); });
|
||||
}
|
||||
void ServoControl::GoHome() {
|
||||
RunOnGLThread([=] { mServo->GoHome(); });
|
||||
}
|
||||
hstring ServoControl::LoadURIOrSearch(hstring input) {
|
||||
// Initial input is valid
|
||||
if (mServo->IsUriValid(input)) {
|
||||
TryLoadUri(input);
|
||||
return input;
|
||||
}
|
||||
|
||||
// Not valid. Maybe it's just missing the scheme.
|
||||
hstring with_scheme = L"https://" + input;
|
||||
// If the user only types "mozilla" we don't want to go to
|
||||
// https://mozilla even though it's a valid url.
|
||||
bool has_dot = wcsstr(input.c_str(), L".") != nullptr;
|
||||
if (mServo->IsUriValid(with_scheme) && has_dot) {
|
||||
TryLoadUri(with_scheme);
|
||||
return with_scheme;
|
||||
}
|
||||
|
||||
// Doesn't look like a URI. Let's search for the string.
|
||||
auto escapedInput = Uri::EscapeComponent(input);
|
||||
std::wstring searchUri =
|
||||
unbox_value<hstring>(std::get<1>(Servo::GetPref(L"shell.searchpage")))
|
||||
.c_str();
|
||||
std::wstring formatted = format(searchUri, escapedInput.c_str());
|
||||
hstring finalUri{formatted};
|
||||
TryLoadUri(finalUri);
|
||||
return finalUri;
|
||||
}
|
||||
|
||||
void ServoControl::SendMediaSessionAction(int32_t action) {
|
||||
RunOnGLThread([=] {
|
||||
mServo->SendMediaSessionAction(
|
||||
static_cast<Servo::MediaSessionActionType>(action));
|
||||
});
|
||||
}
|
||||
|
||||
void ServoControl::TryLoadUri(hstring input) {
|
||||
if (mLooping) {
|
||||
RunOnGLThread([=] {
|
||||
if (!mServo->LoadUri(input)) {
|
||||
RunOnUIThread([=] {
|
||||
MessageDialog msg{mL10NStrings->URINotValid};
|
||||
msg.ShowAsync();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mInitUrl = input;
|
||||
}
|
||||
}
|
||||
|
||||
void ServoControl::RunOnGLThread(std::function<void()> task) {
|
||||
EnterCriticalSection(&mGLLock);
|
||||
mTasks.push_back(task);
|
||||
LeaveCriticalSection(&mGLLock);
|
||||
WakeConditionVariable(&mGLCondVar);
|
||||
}
|
||||
|
||||
/**** GL THREAD LOOP ****/
|
||||
|
||||
void ServoControl::Loop() {
|
||||
log(L"BrowserPage::Loop(). GL thread: %i", GetCurrentThreadId());
|
||||
|
||||
if (mServo == nullptr) {
|
||||
log(L"Entering loop");
|
||||
ServoDelegate *sd = static_cast<ServoDelegate *>(this);
|
||||
EGLNativeWindowType win = GetNativeWindow();
|
||||
mServo = std::make_unique<Servo>(mInitUrl, mArgs, mPanelWidth, mPanelHeight,
|
||||
win, mDPI, *sd, mTransient);
|
||||
} else {
|
||||
// FIXME: this will fail since create_task didn't pick the thread
|
||||
// where Servo was running initially.
|
||||
throw winrt::hresult_error(E_FAIL, L"Recovering loop unimplemented");
|
||||
}
|
||||
|
||||
mServo->SetBatchMode(true);
|
||||
|
||||
while (true) {
|
||||
EnterCriticalSection(&mGLLock);
|
||||
try {
|
||||
while (mTasks.size() == 0 && !mAnimating && mLooping) {
|
||||
SleepConditionVariableCS(&mGLCondVar, &mGLLock, INFINITE);
|
||||
}
|
||||
if (!mLooping) {
|
||||
LeaveCriticalSection(&mGLLock);
|
||||
break;
|
||||
}
|
||||
for (auto &&task : mTasks) {
|
||||
task();
|
||||
}
|
||||
mTasks.clear();
|
||||
LeaveCriticalSection(&mGLLock);
|
||||
mServo->PerformUpdates();
|
||||
} catch (hresult_error const &e) {
|
||||
log(L"GL Thread exception: %s", e.message().c_str());
|
||||
throw e;
|
||||
} catch (...) {
|
||||
log(L"GL Thread exception");
|
||||
throw winrt::hresult_error(E_FAIL, L"GL Thread exception");
|
||||
}
|
||||
}
|
||||
mServo->DeInit();
|
||||
}
|
||||
|
||||
void ServoControl::StartRenderLoop() {
|
||||
if (mLooping) {
|
||||
throw winrt::hresult_error(E_FAIL, L"GL thread is already looping");
|
||||
}
|
||||
mLooping = true;
|
||||
log(L"BrowserPage::StartRenderLoop(). UI thread: %i", GetCurrentThreadId());
|
||||
auto task = Concurrency::create_task([=] {
|
||||
try {
|
||||
Loop();
|
||||
} catch (...) {
|
||||
// Do our best to recover. Exception has been logged at that point.
|
||||
mLooping = false;
|
||||
mLoopTask.reset();
|
||||
mServo.reset();
|
||||
LeaveCriticalSection(&mGLLock);
|
||||
}
|
||||
});
|
||||
mLoopTask = std::make_unique<Concurrency::task<void>>(task);
|
||||
}
|
||||
|
||||
void ServoControl::StopRenderLoop() {
|
||||
if (mLooping) {
|
||||
EnterCriticalSection(&mGLLock);
|
||||
mLooping = false;
|
||||
LeaveCriticalSection(&mGLLock);
|
||||
WakeConditionVariable(&mGLCondVar);
|
||||
mLoopTask->wait();
|
||||
mLoopTask.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**** SERVO CALLBACKS ****/
|
||||
|
||||
void ServoControl::OnServoLoadStarted() {
|
||||
RunOnUIThread([=] { mOnLoadStartedEvent(); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoLoadEnded() {
|
||||
RunOnUIThread([=] { mOnLoadEndedEvent(); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoHistoryChanged(bool back, bool forward) {
|
||||
RunOnUIThread([=] { mOnHistoryChangedEvent(back, forward); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoShutdownComplete() {
|
||||
EnterCriticalSection(&mGLLock);
|
||||
mLooping = false;
|
||||
LeaveCriticalSection(&mGLLock);
|
||||
}
|
||||
|
||||
void ServoControl::OnServoTitleChanged(hstring title) {
|
||||
RunOnUIThread([=] { mOnTitleChangedEvent(*this, title); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoURLChanged(hstring url) {
|
||||
RunOnUIThread([=] {
|
||||
mCurrentUrl = url;
|
||||
mOnURLChangedEvent(*this, url);
|
||||
});
|
||||
}
|
||||
|
||||
void ServoControl::WakeUp() {
|
||||
RunOnGLThread([=] {});
|
||||
}
|
||||
|
||||
bool ServoControl::OnServoAllowNavigation(hstring uri) {
|
||||
if (mTransient) {
|
||||
RunOnUIThread([=] { Launcher::LaunchUriAsync(Uri{uri}); });
|
||||
}
|
||||
return !mTransient;
|
||||
}
|
||||
|
||||
void ServoControl::OnServoPanic(hstring backtrace) {
|
||||
RunOnUIThread([=] { mOnServoPanic(*this, backtrace); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoAnimatingChanged(bool animating) {
|
||||
EnterCriticalSection(&mGLLock);
|
||||
mAnimating = animating;
|
||||
LeaveCriticalSection(&mGLLock);
|
||||
WakeConditionVariable(&mGLCondVar);
|
||||
}
|
||||
|
||||
void ServoControl::OnServoIMEHide() {
|
||||
RunOnUIThread([=] { mInputPane->TryHide(); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoIMEShow(hstring text, int32_t x, int32_t y,
|
||||
int32_t width, int32_t height) {
|
||||
RunOnUIThread([=] {
|
||||
mEditContext->NotifyFocusEnter();
|
||||
// FIXME: The simpleservo on_ime_show callback comes with a input method
|
||||
// type parameter that could be used to set the input scope here.
|
||||
mEditContext->InputScope(CoreTextInputScope::Text);
|
||||
// offset of the Servo SwapChainPanel.
|
||||
auto transform = Panel().TransformToVisual(Window::Current().Content());
|
||||
auto offset = transform.TransformPoint(Point(0, 0));
|
||||
mFocusedInputRect =
|
||||
Rect(x + offset.X, y + offset.Y, (float)width, (float)height);
|
||||
mFocusedInputText = text;
|
||||
mInputPane->TryShow();
|
||||
});
|
||||
}
|
||||
|
||||
void ServoControl::OnServoMediaSessionPosition(double duration, double position,
|
||||
double playback_rate) {
|
||||
RunOnUIThread(
|
||||
[=] { mOnMediaSessionPositionEvent(duration, position, playback_rate); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoMediaSessionMetadata(hstring title, hstring artist,
|
||||
hstring album) {
|
||||
RunOnUIThread([=] { mOnMediaSessionMetadataEvent(title, artist, album); });
|
||||
}
|
||||
|
||||
void ServoControl::OnServoMediaSessionPlaybackStateChange(int state) {
|
||||
RunOnUIThread([=] { mOnMediaSessionPlaybackStateChangeEvent(*this, state); });
|
||||
}
|
||||
|
||||
std::tuple<Controls::ContentDialogResult, std::optional<hstring>>
|
||||
ServoControl::PromptSync(hstring title, hstring message, hstring primaryButton,
|
||||
std::optional<hstring> secondaryButton,
|
||||
std::optional<hstring> input) {
|
||||
|
||||
bool showing = true;
|
||||
Controls::ContentDialogResult retButton = Controls::ContentDialogResult::None;
|
||||
std::optional<hstring> retString = {};
|
||||
|
||||
EnterCriticalSection(&mDialogLock);
|
||||
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::High, [&] {
|
||||
auto dialog = Controls::ContentDialog();
|
||||
dialog.IsPrimaryButtonEnabled(true);
|
||||
dialog.PrimaryButtonText(primaryButton);
|
||||
|
||||
if (secondaryButton.has_value()) {
|
||||
dialog.IsSecondaryButtonEnabled(true);
|
||||
dialog.SecondaryButtonText(*secondaryButton);
|
||||
} else {
|
||||
dialog.IsSecondaryButtonEnabled(false);
|
||||
}
|
||||
|
||||
auto titleBlock = Controls::TextBlock();
|
||||
titleBlock.Text(title);
|
||||
|
||||
auto messageBlock = Controls::TextBlock();
|
||||
messageBlock.TextWrapping(TextWrapping::Wrap);
|
||||
messageBlock.Text(message);
|
||||
Controls::StackPanel stack = Controls::StackPanel();
|
||||
stack.Children().Append(titleBlock);
|
||||
stack.Children().Append(messageBlock);
|
||||
|
||||
dialog.Content(stack);
|
||||
|
||||
auto textbox = Controls::TextBox();
|
||||
textbox.KeyDown([=](auto sender, auto args) {
|
||||
if (args.Key() == Windows::System::VirtualKey::Enter) {
|
||||
dialog.Hide();
|
||||
}
|
||||
});
|
||||
if (input.has_value()) {
|
||||
textbox.Text(*input);
|
||||
stack.Children().Append(textbox);
|
||||
}
|
||||
|
||||
dialog.Closed([&, textbox](Controls::ContentDialog d, auto closed) {
|
||||
EnterCriticalSection(&mDialogLock);
|
||||
retButton = closed.Result();
|
||||
showing = false;
|
||||
if (retButton == Controls::ContentDialogResult::Primary &&
|
||||
input.has_value()) {
|
||||
retString = hstring(textbox.Text());
|
||||
}
|
||||
LeaveCriticalSection(&mDialogLock);
|
||||
WakeConditionVariable(&mDialogCondVar);
|
||||
});
|
||||
dialog.ShowAsync();
|
||||
});
|
||||
|
||||
while (showing) {
|
||||
SleepConditionVariableCS(&mDialogCondVar, &mDialogLock, INFINITE);
|
||||
}
|
||||
LeaveCriticalSection(&mDialogLock);
|
||||
|
||||
return {retButton, retString};
|
||||
}
|
||||
|
||||
void ServoControl::OnServoPromptAlert(winrt::hstring message, bool trusted) {
|
||||
auto titlefmt =
|
||||
format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
|
||||
hstring title{trusted ? L"" : titlefmt};
|
||||
PromptSync(title, message, mL10NStrings->PromptOk, {}, {});
|
||||
}
|
||||
|
||||
Servo::PromptResult ServoControl::OnServoPromptOkCancel(winrt::hstring message,
|
||||
bool trusted) {
|
||||
auto titlefmt =
|
||||
format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
|
||||
hstring title{trusted ? L"" : titlefmt};
|
||||
auto [button, string] = PromptSync(title, message, mL10NStrings->PromptOk,
|
||||
mL10NStrings->PromptCancel, {});
|
||||
if (button == Controls::ContentDialogResult::Primary) {
|
||||
return Servo::PromptResult::Primary;
|
||||
} else if (button == Controls::ContentDialogResult::Secondary) {
|
||||
return Servo::PromptResult::Secondary;
|
||||
} else {
|
||||
return Servo::PromptResult::Dismissed;
|
||||
}
|
||||
}
|
||||
|
||||
Servo::PromptResult ServoControl::OnServoPromptYesNo(winrt::hstring message,
|
||||
bool trusted) {
|
||||
auto titlefmt =
|
||||
format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
|
||||
hstring title{trusted ? L"" : titlefmt};
|
||||
auto [button, string] = PromptSync(title, message, mL10NStrings->PromptYes,
|
||||
mL10NStrings->PromptNo, {});
|
||||
if (button == Controls::ContentDialogResult::Primary) {
|
||||
return Servo::PromptResult::Primary;
|
||||
} else if (button == Controls::ContentDialogResult::Secondary) {
|
||||
return Servo::PromptResult::Secondary;
|
||||
} else {
|
||||
return Servo::PromptResult::Dismissed;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<hstring> ServoControl::OnServoPromptInput(winrt::hstring message,
|
||||
winrt::hstring def,
|
||||
bool trusted) {
|
||||
auto titlefmt =
|
||||
format(mL10NStrings->PromptTitle.c_str(), mCurrentUrl.c_str());
|
||||
hstring title{trusted ? L"" : titlefmt};
|
||||
auto [button, string] = PromptSync(title, message, mL10NStrings->PromptOk,
|
||||
mL10NStrings->PromptCancel, def);
|
||||
return string;
|
||||
}
|
||||
|
||||
void ServoControl::OnServoDevtoolsStarted(bool success, const unsigned int port,
|
||||
hstring token) {
|
||||
RunOnUIThread([=] {
|
||||
auto status = success ? DevtoolsStatus::Running : DevtoolsStatus::Failed;
|
||||
// This port works, let's save it for future use.
|
||||
Servo::SetIntPref(L"devtools.server.port", port);
|
||||
mOnDevtoolsStatusChangedEvent(status, port, token);
|
||||
});
|
||||
}
|
||||
|
||||
void ServoControl::OnServoShowContextMenu(std::optional<hstring> title,
|
||||
std::vector<winrt::hstring> items) {
|
||||
RunOnUIThread([=] {
|
||||
auto titlestr = mL10NStrings->ContextMenuTitle;
|
||||
MessageDialog msg{title.value_or(titlestr)};
|
||||
for (auto i = 0; i < items.size(); i++) {
|
||||
UICommand cmd{items[i], [=](auto) {
|
||||
RunOnGLThread([=] {
|
||||
mServo->ContextMenuClosed(
|
||||
Servo::ContextMenuResult::Selected, i);
|
||||
});
|
||||
}};
|
||||
msg.Commands().Append(cmd);
|
||||
}
|
||||
UICommand cancel{mL10NStrings->PromptCancel, [=](auto) {
|
||||
RunOnGLThread([=] {
|
||||
mServo->ContextMenuClosed(
|
||||
Servo::ContextMenuResult::Dismissed_, 0);
|
||||
});
|
||||
}};
|
||||
msg.Commands().Append(cancel);
|
||||
msg.CancelCommandIndex((uint32_t)items.size());
|
||||
msg.ShowAsync();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Callable> void ServoControl::RunOnUIThread(Callable cb) {
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::High, cb);
|
||||
}
|
||||
|
||||
Collections::IVector<ServoApp::Pref> ServoControl::Preferences() {
|
||||
std::vector<ServoApp::Pref> prefs;
|
||||
for (auto [key, val, isDefault] : Servo::GetPrefs()) {
|
||||
prefs.push_back(ServoApp::Pref(key, val, isDefault));
|
||||
}
|
||||
return winrt::single_threaded_observable_vector<ServoApp::Pref>(
|
||||
std::move(prefs));
|
||||
}
|
||||
|
||||
} // namespace winrt::ServoApp::implementation
|
|
@ -1,316 +0,0 @@
|
|||
#pragma once
|
||||
#include "ServoControl.g.h"
|
||||
#include "Pref.g.h"
|
||||
#include "OpenGLES.h"
|
||||
#include "Servo.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
|
||||
namespace winrt::ServoApp::implementation {
|
||||
|
||||
struct Pref : PrefT<Pref> {
|
||||
public:
|
||||
Pref(hstring key, IInspectable value, bool isDefault) {
|
||||
mKey = key;
|
||||
mValue = value;
|
||||
mIsDefault = isDefault;
|
||||
};
|
||||
IInspectable Value() { return mValue; }
|
||||
hstring Key() { return mKey; }
|
||||
bool IsDefault() { return mIsDefault; }
|
||||
|
||||
private:
|
||||
hstring mKey;
|
||||
IInspectable mValue;
|
||||
bool mIsDefault;
|
||||
};
|
||||
|
||||
struct L10NStrings {
|
||||
hstring ContextMenuTitle;
|
||||
hstring PromptTitle;
|
||||
hstring PromptOk;
|
||||
hstring PromptCancel;
|
||||
hstring PromptYes;
|
||||
hstring PromptNo;
|
||||
hstring URINotValid;
|
||||
};
|
||||
|
||||
struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
|
||||
|
||||
ServoControl();
|
||||
|
||||
IVector<ServoApp::Pref> Preferences();
|
||||
|
||||
void GoBack();
|
||||
void GoForward();
|
||||
void Reload();
|
||||
void Stop();
|
||||
void ChangeVisibility(bool);
|
||||
void Shutdown();
|
||||
hstring LoadURIOrSearch(hstring);
|
||||
void GoHome();
|
||||
void SendMediaSessionAction(int32_t);
|
||||
|
||||
ServoApp::Pref SetBoolPref(hstring aKey, bool aVal) {
|
||||
auto [key, val, isDefault] = servo::Servo::SetBoolPref(aKey, aVal);
|
||||
return ServoApp::Pref(key, val, isDefault);
|
||||
}
|
||||
|
||||
ServoApp::Pref SetStringPref(hstring aKey, hstring aVal) {
|
||||
auto [key, val, isDefault] = servo::Servo::SetStringPref(aKey, aVal);
|
||||
return ServoApp::Pref(key, val, isDefault);
|
||||
}
|
||||
|
||||
ServoApp::Pref SetIntPref(hstring aKey, int64_t aVal) {
|
||||
auto [key, val, isDefault] = servo::Servo::SetIntPref(aKey, aVal);
|
||||
return ServoApp::Pref(key, val, isDefault);
|
||||
}
|
||||
|
||||
ServoApp::Pref SetFloatPref(hstring aKey, double aVal) {
|
||||
auto [key, val, isDefault] = servo::Servo::SetFloatPref(aKey, aVal);
|
||||
return ServoApp::Pref(key, val, isDefault);
|
||||
}
|
||||
|
||||
ServoApp::Pref ResetPref(hstring aKey) {
|
||||
auto [key, val, isDefault] = servo::Servo::ResetPref(aKey);
|
||||
return ServoApp::Pref(key, val, isDefault);
|
||||
}
|
||||
|
||||
ServoApp::Pref GetPref(hstring aKey) {
|
||||
auto [key, val, isDefault] = servo::Servo::GetPref(aKey);
|
||||
return ServoApp::Pref(key, val, isDefault);
|
||||
}
|
||||
|
||||
void OnLoaded(IInspectable const &,
|
||||
Windows::UI::Xaml::RoutedEventArgs const &);
|
||||
|
||||
winrt::event_token
|
||||
OnURLChanged(Windows::Foundation::EventHandler<hstring> const &handler) {
|
||||
return mOnURLChangedEvent.add(handler);
|
||||
};
|
||||
void OnURLChanged(winrt::event_token const &token) noexcept {
|
||||
mOnURLChangedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token
|
||||
OnTitleChanged(Windows::Foundation::EventHandler<hstring> const &handler) {
|
||||
return mOnTitleChangedEvent.add(handler);
|
||||
};
|
||||
void OnTitleChanged(winrt::event_token const &token) noexcept {
|
||||
mOnTitleChangedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token
|
||||
OnServoPanic(Windows::Foundation::EventHandler<hstring> const &handler) {
|
||||
return mOnServoPanic.add(handler);
|
||||
};
|
||||
void OnServoPanic(winrt::event_token const &token) noexcept {
|
||||
mOnServoPanic.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token OnHistoryChanged(HistoryChangedDelegate const &handler) {
|
||||
return mOnHistoryChangedEvent.add(handler);
|
||||
};
|
||||
void OnHistoryChanged(winrt::event_token const &token) noexcept {
|
||||
mOnHistoryChangedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token
|
||||
OnDevtoolsStatusChanged(DevtoolsStatusChangedDelegate const &handler) {
|
||||
return mOnDevtoolsStatusChangedEvent.add(handler);
|
||||
};
|
||||
void OnDevtoolsStatusChanged(winrt::event_token const &token) noexcept {
|
||||
mOnDevtoolsStatusChangedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token OnLoadStarted(EventDelegate const &handler) {
|
||||
return mOnLoadStartedEvent.add(handler);
|
||||
};
|
||||
void OnLoadStarted(winrt::event_token const &token) noexcept {
|
||||
mOnLoadStartedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token OnLoadEnded(EventDelegate const &handler) {
|
||||
return mOnLoadEndedEvent.add(handler);
|
||||
};
|
||||
void OnLoadEnded(winrt::event_token const &token) noexcept {
|
||||
mOnLoadEndedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token OnCaptureGesturesStarted(EventDelegate const &handler) {
|
||||
return mOnCaptureGesturesStartedEvent.add(handler);
|
||||
};
|
||||
void OnCaptureGesturesStarted(winrt::event_token const &token) noexcept {
|
||||
mOnCaptureGesturesStartedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token OnCaptureGesturesEnded(EventDelegate const &handler) {
|
||||
return mOnCaptureGesturesEndedEvent.add(handler);
|
||||
};
|
||||
void OnCaptureGesturesEnded(winrt::event_token const &token) noexcept {
|
||||
mOnCaptureGesturesEndedEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token
|
||||
OnMediaSessionPosition(MediaSessionPositionDelegate const &handler) {
|
||||
return mOnMediaSessionPositionEvent.add(handler);
|
||||
};
|
||||
void OnMediaSessionPosition(winrt::event_token const &token) noexcept {
|
||||
mOnMediaSessionPositionEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token
|
||||
OnMediaSessionMetadata(MediaSessionMetadataDelegate const &handler) {
|
||||
return mOnMediaSessionMetadataEvent.add(handler);
|
||||
};
|
||||
void OnMediaSessionMetadata(winrt::event_token const &token) noexcept {
|
||||
mOnMediaSessionMetadataEvent.remove(token);
|
||||
}
|
||||
|
||||
winrt::event_token OnMediaSessionPlaybackStateChange(
|
||||
Windows::Foundation::EventHandler<int> const &handler) {
|
||||
return mOnMediaSessionPlaybackStateChangeEvent.add(handler);
|
||||
};
|
||||
void
|
||||
OnMediaSessionPlaybackStateChange(winrt::event_token const &token) noexcept {
|
||||
mOnMediaSessionPlaybackStateChangeEvent.remove(token);
|
||||
}
|
||||
|
||||
void SetTransientMode(bool transient) { mTransient = transient; }
|
||||
|
||||
void SetArgs(hstring args) { mArgs = args; }
|
||||
|
||||
virtual void WakeUp();
|
||||
virtual void OnServoLoadStarted();
|
||||
virtual void OnServoLoadEnded();
|
||||
virtual void OnServoHistoryChanged(bool, bool);
|
||||
virtual void OnServoShutdownComplete();
|
||||
virtual void OnServoTitleChanged(winrt::hstring);
|
||||
virtual void OnServoURLChanged(winrt::hstring);
|
||||
virtual bool OnServoAllowNavigation(winrt::hstring);
|
||||
virtual void OnServoAnimatingChanged(bool);
|
||||
virtual void OnServoPanic(hstring);
|
||||
virtual void OnServoIMEHide();
|
||||
virtual void OnServoIMEShow(hstring text, int32_t, int32_t, int32_t, int32_t);
|
||||
virtual void OnServoMediaSessionMetadata(winrt::hstring, winrt::hstring,
|
||||
winrt::hstring);
|
||||
virtual void OnServoMediaSessionPlaybackStateChange(int);
|
||||
virtual void OnServoMediaSessionPosition(double, double, double);
|
||||
virtual void OnServoPromptAlert(winrt::hstring, bool);
|
||||
virtual void OnServoShowContextMenu(std::optional<winrt::hstring>,
|
||||
std::vector<winrt::hstring>);
|
||||
virtual servo::Servo::PromptResult OnServoPromptOkCancel(winrt::hstring,
|
||||
bool);
|
||||
virtual servo::Servo::PromptResult OnServoPromptYesNo(winrt::hstring, bool);
|
||||
virtual std::optional<hstring> OnServoPromptInput(winrt::hstring,
|
||||
winrt::hstring, bool);
|
||||
virtual void OnServoDevtoolsStarted(bool, const unsigned int, winrt::hstring);
|
||||
|
||||
DevtoolsStatus GetDevtoolsStatus();
|
||||
|
||||
private:
|
||||
winrt::event<Windows::Foundation::EventHandler<hstring>> mOnURLChangedEvent;
|
||||
winrt::event<Windows::Foundation::EventHandler<hstring>> mOnTitleChangedEvent;
|
||||
winrt::event<Windows::Foundation::EventHandler<hstring>> mOnServoPanic;
|
||||
winrt::event<HistoryChangedDelegate> mOnHistoryChangedEvent;
|
||||
winrt::event<DevtoolsStatusChangedDelegate> mOnDevtoolsStatusChangedEvent;
|
||||
winrt::event<EventDelegate> mOnLoadStartedEvent;
|
||||
winrt::event<EventDelegate> mOnLoadEndedEvent;
|
||||
winrt::event<EventDelegate> mOnCaptureGesturesStartedEvent;
|
||||
winrt::event<EventDelegate> mOnCaptureGesturesEndedEvent;
|
||||
winrt::event<MediaSessionMetadataDelegate> mOnMediaSessionMetadataEvent;
|
||||
winrt::event<MediaSessionPositionDelegate> mOnMediaSessionPositionEvent;
|
||||
winrt::event<Windows::Foundation::EventHandler<int>>
|
||||
mOnMediaSessionPlaybackStateChangeEvent;
|
||||
|
||||
CRITICAL_SECTION mDialogLock;
|
||||
CONDITION_VARIABLE mDialogCondVar;
|
||||
|
||||
std::tuple<Windows::UI::Xaml::Controls::ContentDialogResult,
|
||||
std::optional<hstring>>
|
||||
PromptSync(hstring title, hstring message, hstring primaryButton,
|
||||
std::optional<hstring> secondaryButton,
|
||||
std::optional<hstring> input);
|
||||
|
||||
int mPanelHeight = 0;
|
||||
int mPanelWidth = 0;
|
||||
float mDPI = 1;
|
||||
hstring mCurrentUrl = L"";
|
||||
bool mTransient = false;
|
||||
std::optional<hstring> mInitUrl = {};
|
||||
|
||||
Windows::UI::Xaml::Controls::SwapChainPanel Panel();
|
||||
void CreateNativeWindow();
|
||||
EGLNativeWindowType GetNativeWindow();
|
||||
void RecoverFromLostDevice();
|
||||
|
||||
void StartRenderLoop();
|
||||
void StopRenderLoop();
|
||||
void Loop();
|
||||
|
||||
void OnSurfaceTapped(IInspectable const &,
|
||||
Windows::UI::Xaml::Input::TappedRoutedEventArgs const &);
|
||||
|
||||
void OnSurfacePointerPressed(
|
||||
IInspectable const &,
|
||||
Windows::UI::Xaml::Input::PointerRoutedEventArgs const &, bool);
|
||||
|
||||
void OnSurfacePointerCanceled(
|
||||
IInspectable const &,
|
||||
Windows::UI::Xaml::Input::PointerRoutedEventArgs const &);
|
||||
|
||||
void OnSurfacePointerExited(
|
||||
IInspectable const &,
|
||||
Windows::UI::Xaml::Input::PointerRoutedEventArgs const &);
|
||||
|
||||
void OnSurfacePointerLost(
|
||||
IInspectable const &,
|
||||
Windows::UI::Xaml::Input::PointerRoutedEventArgs const &);
|
||||
|
||||
void OnSurfacePointerMoved(
|
||||
IInspectable const &,
|
||||
Windows::UI::Xaml::Input::PointerRoutedEventArgs const &);
|
||||
|
||||
void OnSurfaceWheelChanged(
|
||||
IInspectable const &,
|
||||
Windows::UI::Xaml::Input::PointerRoutedEventArgs const &);
|
||||
|
||||
void OnSurfaceManipulationDelta(
|
||||
IInspectable const &,
|
||||
Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs const &);
|
||||
|
||||
void OnSurfaceResized(IInspectable const &,
|
||||
Windows::UI::Xaml::SizeChangedEventArgs const &);
|
||||
|
||||
template <typename Callable> void RunOnUIThread(Callable);
|
||||
void RunOnGLThread(std::function<void()>);
|
||||
|
||||
void TryLoadUri(hstring);
|
||||
void InitializeTextController();
|
||||
|
||||
std::unique_ptr<servo::Servo> mServo;
|
||||
PropertySet mNativeWindowProperties;
|
||||
OpenGLES mOpenGLES;
|
||||
bool mAnimating = false;
|
||||
bool mLooping = false;
|
||||
std::vector<std::function<void()>> mTasks;
|
||||
CRITICAL_SECTION mGLLock;
|
||||
CONDITION_VARIABLE mGLCondVar;
|
||||
std::unique_ptr<Concurrency::task<void>> mLoopTask;
|
||||
hstring mArgs;
|
||||
std::optional<servo::Servo::MouseButton> mPressedMouseButton = {};
|
||||
std::unique_ptr<L10NStrings> mL10NStrings = nullptr;
|
||||
|
||||
std::optional<Windows::UI::Text::Core::CoreTextEditContext> mEditContext;
|
||||
std::optional<Windows::UI::ViewManagement::InputPane> mInputPane;
|
||||
|
||||
std::optional<Windows::Foundation::Rect> mFocusedInputRect;
|
||||
std::optional<hstring> mFocusedInputText;
|
||||
};
|
||||
} // namespace winrt::ServoApp::implementation
|
||||
|
||||
namespace winrt::ServoApp::factory_implementation {
|
||||
struct ServoControl
|
||||
: ServoControlT<ServoControl, implementation::ServoControl> {};
|
||||
struct Pref : PrefT<Pref, implementation::Pref> {};
|
||||
} // namespace winrt::ServoApp::factory_implementation
|
|
@ -1,56 +0,0 @@
|
|||
namespace ServoApp {
|
||||
|
||||
delegate void EventDelegate();
|
||||
delegate void HistoryChangedDelegate(Boolean back, Boolean forward);
|
||||
delegate void MediaSessionMetadataDelegate(String title, String artist, String album);
|
||||
delegate void MediaSessionPositionDelegate(Double duration, Double position, Double rate);
|
||||
delegate void DevtoolsStatusChangedDelegate(DevtoolsStatus status, UInt32 port, String token);
|
||||
|
||||
enum DevtoolsStatus {
|
||||
Running = 0,
|
||||
Stopped,
|
||||
Failed,
|
||||
};
|
||||
|
||||
runtimeclass Pref
|
||||
{
|
||||
Pref(String key, IInspectable val, Boolean isDefault);
|
||||
IInspectable Value { get; };
|
||||
String Key { get; };
|
||||
Boolean IsDefault { get; };
|
||||
}
|
||||
|
||||
runtimeclass ServoControl : Windows.UI.Xaml.Controls.Control {
|
||||
ServoControl();
|
||||
void GoBack();
|
||||
void GoForward();
|
||||
void Reload();
|
||||
void Stop();
|
||||
String LoadURIOrSearch(String url);
|
||||
void GoHome();
|
||||
void SetTransientMode(Boolean transient);
|
||||
void SetArgs(String args);
|
||||
void Shutdown();
|
||||
void ChangeVisibility(Boolean visible);
|
||||
void SendMediaSessionAction(UInt32 action);
|
||||
event EventDelegate OnLoadStarted;
|
||||
event EventDelegate OnLoadEnded;
|
||||
event EventDelegate OnCaptureGesturesStarted;
|
||||
event EventDelegate OnCaptureGesturesEnded;
|
||||
event DevtoolsStatusChangedDelegate OnDevtoolsStatusChanged;
|
||||
event HistoryChangedDelegate OnHistoryChanged;
|
||||
event Windows.Foundation.EventHandler<String> OnTitleChanged;
|
||||
event Windows.Foundation.EventHandler<String> OnServoPanic;
|
||||
event Windows.Foundation.EventHandler<String> OnURLChanged;
|
||||
event MediaSessionMetadataDelegate OnMediaSessionMetadata;
|
||||
event MediaSessionPositionDelegate OnMediaSessionPosition;
|
||||
event Windows.Foundation.EventHandler<int> OnMediaSessionPlaybackStateChange;
|
||||
Windows.Foundation.Collections.IVector<Pref> Preferences { get; };
|
||||
Pref GetPref(String key);
|
||||
Pref SetBoolPref(String key, Boolean val);
|
||||
Pref SetIntPref(String key, Int64 val);
|
||||
Pref SetFloatPref(String key, Double val);
|
||||
Pref SetStringPref(String key, String val);
|
||||
Pref ResetPref(String key);
|
||||
}
|
||||
} // namespace ServoApp
|
|
@ -1,19 +0,0 @@
|
|||
<!-- \Themes\Generic.xaml -->
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ServoApp">
|
||||
|
||||
<Style TargetType="local:ServoControl" >
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:ServoControl">
|
||||
<Grid>
|
||||
<SwapChainPanel x:Name="swapChainPanel" MinHeight="200" MinWidth="200" ManipulationMode="All" IsTapEnabled="True">
|
||||
</SwapChainPanel>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ANGLE.WindowsStore.Servo" version="2.1.19" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.4.2" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
|
||||
<package id="OpenXR.Loader" version="1.0.6.2" targetFramework="native" />
|
||||
</packages>
|
|
@ -1 +0,0 @@
|
|||
#include "pch.h"
|
|
@ -1,73 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <hstring.h>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <restrictederrorinfo.h>
|
||||
#include <unknwn.h>
|
||||
#include <vector>
|
||||
#include <wincodec.h>
|
||||
#include <array>
|
||||
#include <d2d1_2.h>
|
||||
#include <d3d11_4.h>
|
||||
#include <DirectXColors.h>
|
||||
#include <dwrite_2.h>
|
||||
#include <sstream>
|
||||
#include <Windows.Graphics.Directx.Direct3D11.Interop.h>
|
||||
#include <windows.h>
|
||||
#include <WindowsNumerics.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <angle_windowsstore.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <EGL/eglplatform.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Windows.ApplicationModel.Core.h>
|
||||
#include <winrt/Windows.ApplicationModel.Resources.h>
|
||||
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Metadata.h>
|
||||
#include <winrt/Windows.Gaming.Input.h>
|
||||
#include <winrt/Windows.Graphics.Display.h>
|
||||
#include <winrt/Windows.Graphics.Holographic.h>
|
||||
#include <winrt/Windows.Networking.Sockets.h>
|
||||
#include <winrt/Windows.Perception.People.h>
|
||||
#include <winrt/Windows.Perception.Spatial.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/windows.system.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
#include <winrt/Windows.UI.Popups.h>
|
||||
#include <winrt/Windows.UI.ViewManagement.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.UI.Xaml.Data.h>
|
||||
#include <winrt/Windows.UI.Xaml.h>
|
||||
#include <winrt/Windows.UI.Xaml.Documents.h>
|
||||
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Interop.h>
|
||||
#include <winrt/Windows.UI.Xaml.Media.h>
|
||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||
#include <winrt/Windows.UI.Xaml.Navigation.h>
|
||||
#include <winrt/Windows.UI.Xaml.Shapes.h>
|
||||
#include <winrt/Windows.UI.Notifications.h>
|
||||
#include <winrt/Windows.UI.Text.h>
|
||||
#include <winrt/Windows.UI.Text.Core.h>
|
||||
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.Data.Json.h>
|
||||
|
||||
#include <winrt/Microsoft.UI.Xaml.Automation.Peers.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Media.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
|
|
@ -1,22 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
template <typename... Args>
|
||||
std::wstring format(const std::wstring &txt, Args... args) {
|
||||
size_t size = swprintf(nullptr, 0, txt.c_str(), args...) + 1;
|
||||
if (size <= 0) {
|
||||
throw std::runtime_error("Error during formatting.");
|
||||
}
|
||||
auto ptr = new wchar_t[size];
|
||||
swprintf(ptr, size, txt.c_str(), args...);
|
||||
auto wstr = std::wstring(ptr);
|
||||
delete[] ptr;
|
||||
return wstr;
|
||||
}
|
||||
|
||||
template <typename... Args> void log(const std::wstring &txt, Args... args) {
|
||||
OutputDebugString((format(txt, args...) + L"\r\n").c_str());
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
REM USAGE
|
||||
REM Clone https://github.com/microsoft/OpenXR-SDK-VisualStudio, open the openxr_loader_uwp project
|
||||
REM Change the project output type to a dynamic library
|
||||
REM Build it for Debug/Release x64/ARM64
|
||||
REM create-openxr-package path\to\outputdir path\to\OpenXR-SDK-VisualStudio
|
||||
REM name the outputdir openxr-loader-uwp-versionnumber and zip it
|
||||
|
||||
cd %1
|
||||
mkdir arm64
|
||||
mkdir arm64\Debug
|
||||
cd arm64\Debug
|
||||
copy %2\bin\Debug\ARM64\openxr_loader_uwp\* .
|
||||
ren *.* openxr_loader.*
|
||||
cd ..
|
||||
mkdir Release
|
||||
cd Release
|
||||
copy %2\bin\Release\ARM64\openxr_loader_uwp\* .
|
||||
ren *.* openxr_loader.*
|
||||
cd ..\..
|
||||
mkdir x64
|
||||
mkdir x64\Debug
|
||||
cd x64\Debug
|
||||
copy %2\bin\Debug\x64\openxr_loader_uwp\* .
|
||||
ren *.* openxr_loader.*
|
||||
cd ..
|
||||
mkdir Release
|
||||
cd Release
|
||||
copy %2\bin\Release\x64\openxr_loader_uwp\* .
|
||||
ren *.* openxr_loader.*
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="FullRebuild">
|
||||
<Target Name="FullRebuild">
|
||||
<ItemGroup>
|
||||
<Configurations Include="%%CONFIGURATION%%"/>
|
||||
<Platforms Include="%%BUILD_PLATFORMS%%"/>
|
||||
<ConfigAndPlatform Include="@(Configurations)">
|
||||
<Platform>%(Platforms.Identity)</Platform>
|
||||
</ConfigAndPlatform>
|
||||
</ItemGroup>
|
||||
<MSBuild Projects="%%SOLUTION%%" Targets="Build"
|
||||
Properties="Configuration=%(ConfigAndPlatform.Identity);Platform=%(ConfigAndPlatform.Platform);AppxBundle=Always;AppxBundlePlatforms=%%PACKAGE_PLATFORMS%%;UseSubFolderForOutputDirDuringMultiPlatformBuild=false"/>
|
||||
</Target>
|
||||
</Project>
|
|
@ -3,7 +3,6 @@
|
|||
<package id="cmake" version="3.26.4" installArguments="ADD_CMAKE_TO_PATH=System"/>
|
||||
<package id="git"/>
|
||||
<package id="ninja"/>
|
||||
<package id="nuget.commandline" version="6.6.0" />
|
||||
<package id="python"/>
|
||||
<package id="python3-virtualenv"/>
|
||||
<package id="visualstudio2019buildtools" packageParameters="--add Microsoft.VisualStudio.Component.Roslyn.Compiler --add Microsoft.Component.MSBuild --add Microsoft.VisualStudio.Component.CoreBuildTools --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.Windows10SDK --add Microsoft.VisualStudio.Component.Windows10SDK.20348 --add Microsoft.VisualStudio.Component.VC.CoreBuildTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.VC.Redist.14.Latest --add Microsoft.VisualStudio.Component.VC.ATL --add Microsoft.VisualStudio.Component.VC.ATLMFC --add Microsoft.VisualStudio.Component.TextTemplating --add Microsoft.VisualStudio.Component.VC.CoreIde --add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core --add Microsoft.VisualStudio.Workload.VCTools" />
|
||||
|
|