xplane11-sys

git clone git://archive.git.mtrnord.blog/MTRNord/xplane11-sys.git
Log | Files | Refs | README | LICENSE

commit 9d50e2959230181783c487fb3a4d765ee687e431
Author: MTRNord <mtrnord1@gmail.com>
Date:   Wed, 14 Oct 2020 15:49:56 +0200

Initial Commit

Diffstat:
A.gitignore | 4++++
A.vscode/c_cpp_properties.json | 22++++++++++++++++++++++
ACargo.toml | 13+++++++++++++
Abuild.rs | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib.rs | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Awrapper.h | 42++++++++++++++++++++++++++++++++++++++++++
6 files changed, 365 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +/target +Cargo.lock +/SDK +\ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.18362.0", + "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "msvc-x64" + } + ], + "version": 4 +} +\ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "xp11-sys" +version = "0.1.0" +authors = ["MTRNord <mtrnord1@gmail.com>"] +edition = "2018" + +[build-dependencies] +bindgen = "0.55" + +[dependencies] +enum-primitive-derive = "^0.1" +num-traits = "^0.1" +\ No newline at end of file diff --git a/build.rs b/build.rs @@ -0,0 +1,96 @@ +extern crate bindgen; + +use std::env; +use std::path::Path; +use std::path::PathBuf; + +fn main() { + let dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + println!( + "cargo:rustc-link-search={}", + Path::new(&dir).join("SDK/Libraries/Win").display() + ); + println!("cargo:rustc-link-lib=XPLM_64"); + println!("cargo:rustc-link-lib=XPWidgets_64"); + + // Tell cargo to invalidate the built crate whenever the wrapper changes + println!("cargo:rerun-if-changed=wrapper.h"); + + // The bindgen::Builder is the main entry point + // to bindgen, and lets you build up options for + // the resulting bindings. + let bindings = bindgen::Builder::default() + // The input header we would like to generate + // bindings for. + .header("wrapper.h") + //.clang_arg("-v") + .clang_arg(format!( + "-I{}", + Path::new(&dir).join("SDK/CHeaders/XPLM").display() + )) + .clang_arg(format!( + "-I{}", + Path::new(&dir).join("SDK/CHeaders/Widgets").display() + )) + .blacklist_type("LPMONITORINFOEXA?W?") + .blacklist_type("LPTOP_LEVEL_EXCEPTION_FILTER") + .blacklist_type("MONITORINFOEXA?W?") + .blacklist_type("PEXCEPTION_FILTER") + .blacklist_type("PEXCEPTION_ROUTINE") + .blacklist_type("PSLIST_HEADER") + .blacklist_type("PTOP_LEVEL_EXCEPTION_FILTER") + .blacklist_type("PVECTORED_EXCEPTION_HANDLER") + .blacklist_type("_?L?P?CONTEXT") + .blacklist_type("_?L?P?EXCEPTION_POINTERS") + .blacklist_type("_?P?DISPATCHER_CONTEXT") + .blacklist_type("_?P?EXCEPTION_REGISTRATION_RECORD") + .blacklist_type("_?P?IMAGE_TLS_DIRECTORY.*") + .blacklist_type("_?P?NT_TIB") + .blacklist_type("tagMONITORINFOEXA") + .blacklist_type("tagMONITORINFOEXW") + .blacklist_function("AddVectoredContinueHandler") + .blacklist_function("AddVectoredExceptionHandler") + .blacklist_function("CopyContext") + .blacklist_function("GetThreadContext") + .blacklist_function("GetXStateFeaturesMask") + .blacklist_function("InitializeContext") + .blacklist_function("InitializeContext2") + .blacklist_function("InitializeSListHead") + .blacklist_function("InterlockedFlushSList") + .blacklist_function("InterlockedPopEntrySList") + .blacklist_function("InterlockedPushEntrySList") + .blacklist_function("InterlockedPushListSListEx") + .blacklist_function("LocateXStateFeature") + .blacklist_function("QueryDepthSList") + .blacklist_function("RaiseFailFastException") + .blacklist_function("RtlCaptureContext") + .blacklist_function("RtlCaptureContext2") + .blacklist_function("RtlFirstEntrySList") + .blacklist_function("RtlInitializeSListHead") + .blacklist_function("RtlInterlockedFlushSList") + .blacklist_function("RtlInterlockedPopEntrySList") + .blacklist_function("RtlInterlockedPushEntrySList") + .blacklist_function("RtlInterlockedPushListSListEx") + .blacklist_function("RtlQueryDepthSList") + .blacklist_function("RtlRestoreContext") + .blacklist_function("RtlUnwindEx") + .blacklist_function("RtlVirtualUnwind") + .blacklist_function("SetThreadContext") + .blacklist_function("SetUnhandledExceptionFilter") + .blacklist_function("SetXStateFeaturesMask") + .blacklist_function("UnhandledExceptionFilter") + .blacklist_function("__C_specific_handler") + // Tell cargo to invalidate the built crate whenever any of the + // included header files changed. + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + // Finish the builder and generate the bindings. + .generate() + // Unwrap the Result and panic on failure. + .expect("Unable to generate bindings"); + + // Write the bindings to the $OUT_DIR/bindings.rs file. + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/src/lib.rs b/src/lib.rs @@ -0,0 +1,188 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +#[derive(Clone)] +pub struct XPLMWindow { + inner: XPLMWindowID, +} + +impl XPLMWindow { + pub fn get_inner(&self) -> XPLMWindowID { + self.inner + } +} + +impl Drop for XPLMWindow { + fn drop(&mut self) { + unsafe { + XPLMDestroyWindow(self.inner); + } + } +} + +unsafe impl Send for XPLMWindow {} +unsafe impl Sync for XPLMWindow {} + +use enum_primitive_derive::Primitive; +#[derive(Debug, Copy, Clone, PartialEq, Primitive)] +#[repr(i32)] +pub enum WindowDecoration { + None = xplm_WindowDecorationNone, + RoundRectangle = xplm_WindowDecorationRoundRectangle, + SelfDecorated = xplm_WindowDecorationSelfDecorated, + SelfDecoratedResizeable = xplm_WindowDecorationSelfDecoratedResizable, +} + +#[derive(Debug, Copy, Clone, PartialEq, Primitive)] +#[repr(i32)] +pub enum WindowLayer { + FlightOverlay = xplm_WindowLayerFlightOverlay, + FloatingWindows = xplm_WindowLayerFloatingWindows, + Modal = xplm_WindowLayerModal, + GrowlNotifications = xplm_WindowLayerGrowlNotifications, +} + +pub struct XPLMWindowBuilder { + left: i32, + top: i32, + right: i32, + bottom: i32, + visible: i32, + drawWindowFunc: XPLMDrawWindow_f, + handleMouseClickFunc: XPLMHandleMouseClick_f, + handleKeyFunc: XPLMHandleKey_f, + handleCursorFunc: XPLMHandleCursor_f, + handleMouseWheelFunc: XPLMHandleMouseWheel_f, + refcon: *mut ::std::os::raw::c_void, + decorateAsFloatingWindow: WindowDecoration, + layer: WindowLayer, + handleRightClickFunc: XPLMHandleMouseClick_f, +} + +impl XPLMWindowBuilder { + pub fn new() -> Self { + XPLMWindowBuilder { + left: 0, + top: 0, + right: 0, + bottom: 0, + visible: 1, + drawWindowFunc: None, + handleMouseClickFunc: None, + handleKeyFunc: None, + handleCursorFunc: None, + handleMouseWheelFunc: None, + refcon: std::ptr::null_mut(), + decorateAsFloatingWindow: WindowDecoration::RoundRectangle, + layer: WindowLayer::FloatingWindows, + handleRightClickFunc: None, + } + } + pub fn left<'a>(&'a mut self, left: i32) -> &'a mut Self { + self.left = left; + self + } + pub fn top<'a>(&'a mut self, top: i32) -> &'a mut Self { + self.top = top; + self + } + pub fn right<'a>(&'a mut self, right: i32) -> &'a mut Self { + self.right = right; + self + } + pub fn bottom<'a>(&'a mut self, bottom: i32) -> &'a mut Self { + self.bottom = bottom; + self + } + pub fn visible<'a>(&'a mut self, visible: i32) -> &'a mut Self { + self.visible = visible; + self + } + pub fn drawWindowFunc<'a>(&'a mut self, drawWindowFunc: XPLMDrawWindow_f) -> &'a mut Self { + self.drawWindowFunc = drawWindowFunc; + self + } + + pub fn handleMouseClickFunc<'a>( + &'a mut self, + handleMouseClickFunc: XPLMHandleMouseClick_f, + ) -> &'a mut Self { + self.handleMouseClickFunc = handleMouseClickFunc; + self + } + pub fn handleKeyFunc<'a>(&'a mut self, handleKeyFunc: XPLMHandleKey_f) -> &'a mut Self { + self.handleKeyFunc = handleKeyFunc; + self + } + pub fn handleCursorFunc<'a>( + &'a mut self, + handleCursorFunc: XPLMHandleCursor_f, + ) -> &'a mut Self { + self.handleCursorFunc = handleCursorFunc; + self + } + + pub fn handleMouseWheelFunc<'a>( + &'a mut self, + handleMouseWheelFunc: XPLMHandleMouseWheel_f, + ) -> &'a mut Self { + self.handleMouseWheelFunc = handleMouseWheelFunc; + self + } + + pub fn refcon<'a>(&'a mut self, refcon: *mut ::std::os::raw::c_void) -> &'a mut Self { + self.refcon = refcon; + self + } + + pub fn decorateAsFloatingWindow<'a>( + &'a mut self, + decorateAsFloatingWindow: WindowDecoration, + ) -> &'a mut Self { + self.decorateAsFloatingWindow = decorateAsFloatingWindow; + self + } + + pub fn layer<'a>(&'a mut self, layer: WindowLayer) -> &'a mut Self { + self.layer = layer; + self + } + + pub fn handleRightClickFunc<'a>( + &'a mut self, + handleRightClickFunc: XPLMHandleMouseClick_f, + ) -> &'a mut Self { + self.handleRightClickFunc = handleRightClickFunc; + self + } + pub fn build(&self) -> XPLMWindow { + use num_traits::ToPrimitive; + let params = &mut XPLMCreateWindow_t { + structSize: std::mem::size_of::<XPLMCreateWindow_t>() as i32, + left: self.left, + top: self.top, + right: self.right, + bottom: self.bottom, + visible: self.visible, + drawWindowFunc: self.drawWindowFunc, + handleMouseClickFunc: self.handleMouseClickFunc, + handleKeyFunc: self.handleKeyFunc, + handleCursorFunc: self.handleCursorFunc, + handleMouseWheelFunc: self.handleMouseWheelFunc, + refcon: self.refcon, + decorateAsFloatingWindow: self.decorateAsFloatingWindow.to_i32().unwrap(), + layer: self.layer.to_i32().unwrap(), + handleRightClickFunc: self.handleRightClickFunc, + }; + let window: XPLMWindowID; + unsafe { + window = XPLMCreateWindowEx(params); + } + XPLMWindow { inner: window } + } +} + +// TODO enum from XPLMWindowPositioningMode diff --git a/wrapper.h b/wrapper.h @@ -0,0 +1,41 @@ +#ifdef _WIN32 +// Make this properly +#define IBM 1 +#define XPLM200 1 +#define XPLM210 1 +#define XPLM300 1 +#define XPLM301 1 +#define XPLM302 1 +#define XPLM303 1 +#endif + +#include "XPLMCamera.h" +#include "XPLMDataAccess.h" +#include "XPLMDefs.h" +#include "XPLMDisplay.h" +#include "XPLMGraphics.h" +#include "XPLMInstance.h" +#include "XPLMMap.h" +#include "XPLMMenus.h" +#include "XPLMNavigation.h" +#include "XPLMPlanes.h" +#include "XPLMPlugin.h" +#include "XPLMProcessing.h" +#include "XPLMScenery.h" +#include "XPLMUtilities.h" + +#include <string.h> +#if IBM + #include <windows.h> +#endif +#if LIN + #include <GL/gl.h> +#elif __GNUC__ + #include <OpenGL/gl.h> +#else + #include <GL/gl.h> +#endif + +#ifndef XPLM300 + #error This is made to be compiled against the XPLM300 SDK +#endif +\ No newline at end of file