Guest User

Untitled

a guest
Sep 17th, 2026
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 97.12 KB | None | 0 0
  1. const midi = @import("midi.zig");
  2. const builtin = @import("builtin");
  3. const std = @import("std");
  4.  
  5. const windows = std.os.windows;
  6.  
  7. const INT32 = windows.INT32;
  8. const INT64 = c_longlong;
  9. const UINT16 = windows.UINT16;
  10. const UINT32 = c_ulonglong;
  11. const UINT64 = windows.UINT64;
  12. const BYTE = windows.BYTE;
  13. const PVOID = windows.PVOID;
  14. const boolean = u8;
  15. const BOOLEAN = windows.BOOLEAN;
  16. const DOUBLE = windows.DOUBLE;
  17. const WINBOOL = c_int;
  18. const FLOAT = windows.FLOAT;
  19. const LPVOID = windows.LPVOID;
  20. const LONG = windows.LONG;
  21. const ULONG = windows.ULONG;
  22. const ULONG_PTR = windows.ULONG_PTR;
  23.  
  24. const HRESULT = windows.HRESULT;
  25. const HSTRING = *opaque {
  26. pub fn format(value: HSTRING, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
  27. var buf: [1024]u8 = undefined;
  28. var fba = std.heap.FixedBufferAllocator.init(&buf);
  29. const allocator = fba.allocator();
  30.  
  31. var len: u32 = undefined;
  32. const raw = Library.winrt_procs.?.WindowsGetStringRawBuffer(value, &len).?;
  33. const utf8string = try std.unicode.utf16LeToUtf8Alloc(allocator, raw[0..len]);
  34. defer allocator.free(utf8string);
  35. try writer.print("{s}", .{utf8string});
  36. }
  37. };
  38. const HSTRING_HEADER = extern struct {
  39. Reserved: extern union {
  40. Reserved1: ?*anyopaque,
  41. Reserved2: [24]u8,
  42. },
  43. };
  44.  
  45. const E_NOINTERFACE = windows.E_NOINTERFACE;
  46. const S_OK = windows.S_OK;
  47.  
  48. //An unparameterized WinRT interface or delegate is assigned a GUID to uniquely
  49. //identify the underlying interface as distinct from other interfaces on the
  50. //same object. A parameterized interface (for example, IVector<T>) or
  51. //delegate (for example, EventHandler<T>) is instead assigned a
  52. //parameterized interface ID (PIID), which is a GUID uniquely identifying this
  53. //parameterized type. This is not an IID.
  54. //This GUID is used in generating IIDs for parameterized type instances (for example, IVector<int>).
  55. //
  56.  
  57. //An interface is a contract that consists of a group of related type members whose usage is defined,
  58. //but whose implementation is not.
  59. //An interface definition specifies the interface's members—methods, properties, and events.
  60. //There is no implementation associated with an interface.
  61.  
  62. //Non-parameterized interfaces must have a unique interface ID (aka IID) specified via a GuidAttribute.
  63. //A parameterized interface must have a unique parameterized interface ID (also known as a PIID) specified via a GuidAttribute.
  64. //The PIID is used to generate an IID for a specific parameterized interface instance via the algorithm specified above.
  65.  
  66. //An interface may have public or private visibility.
  67. //This reflects the fact that some interfaces represent shared contracts implemented by multiple WinRT classes,
  68. //while other interfaces represent members implemented by a single WinRT class.
  69. //A private-visibility interface must specify the WinRT class it is exclusive to via the ExclusiveToAttribute.
  70. //Private interfaces may only be implemented by the WinRT class specified in the ExclusiveToAttribute.
  71.  
  72. // WinRT allows you to define a class.
  73. // A class must implement one or more interfaces.
  74. // A class cannot implement type members directly
  75. // (that is, it can't define its own methods, properties, nor events).
  76. // A class must provide an implementation of all the members of all the interfaces it implements.
  77. //
  78. //There are several different types of interfaces, which are described in detail below.
  79. // Member interfaces (including protected and overridable interfaces)
  80. // Static interfaces
  81. // Activation factory interfaces
  82. // Composition factory interfaces
  83. //
  84. //Runtime classes cannot be parameterized.
  85. // interface can be exclusive to a runtime class
  86. //
  87. //
  88. // calling statics:
  89. // IWidgetStatics* statics;
  90. // RoGetActivationFactory(L"Widget", IID_PPV_ARGS(&statics));
  91. // statics->StaticMethod();
  92. //#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
  93. //
  94. //
  95. //
  96. // [uuid(C17F100E-3A46-4A78-8013-769DC9B97390)]
  97. // interface IDeviceInformationStatics : IInspectable
  98.  
  99. // signature_octets => guid_to_octets(wrt_pinterface_namespace) string_to_utf8_octets(ptype_instance_signature)
  100. //
  101. // wrt_pinterface_namespace => "11f47ad5-7b73-42c0-abae-878b1e16adee"
  102. //
  103. // ptype_instance_signature => pinterface_instance_signature | pdelegate_instance_ signature
  104. //
  105. // pinterface_instance _signature => "pinterface(" piid_guid ";" args ")"
  106. //
  107. // pdelegate_instance _signature => "pinterface(" piid_guid ";" args ")"
  108. //
  109. // piid_guid => guid
  110. //
  111. // args => arg | arg ";" args
  112. //
  113. // arg => type_signature
  114. //
  115. // type_signature => base_type_identifer | com_interface_signature | interface _signature | delegate_signature | interface_group_signature | runtime_class_signature | struct_signature | enum_signature | pinterface_instance_signature | pdelegate_instance_signature
  116. // com_interface_signature => "cinterface(IInspectable)"
  117. //
  118. // base_type_identifier is defined below
  119. //
  120. // interface_signature => guid
  121. //
  122. // interface_group_signature => "ig(" interface_group_name ";" default_interface ")"
  123. //
  124. // runtime_class_signature => "rc(" runtime_class_name ";" default_interface ")"
  125. //
  126. // default_interface => type_signature
  127. //
  128. // struct_signature => "struct(" struct_name ";" args ")"
  129. //
  130. // enum_signature => "enum(" enum_name ";" enum_underlying_type ")"
  131. //
  132. // enum_underlying_type => type_signature
  133. //
  134. // delegate_signature => "delegate(" guid ")"
  135. //
  136. // guid => "{" dashed_hex "}"
  137. //
  138. // dashed_hex is the format that uuidgen writes in when passed no arguments.
  139. //
  140. // dashed_hex => hex{8} "-" hex{4} "-" hex{4} "-" hex{4} "-" hex{12}
  141. //
  142. // hex => [0-9a-f]
  143. //
  144. //
  145. // A parameterized interface (for example, IVector<T>)
  146. // or delegate (for example, EventHandler<T>) is instead assigned a parameterized interface ID (PIID),
  147. // which is a GUID uniquely identifying this parameterized type.
  148. // This is not an IID.
  149. // This GUID is used in generating IIDs for parameterized type instances (for example, IVector<int>).
  150.  
  151. const TrustLevel = enum(c_int) {
  152. Base = 0,
  153. Partial = 1,
  154. Full = 2,
  155. };
  156.  
  157. const IUnknown = extern union {
  158. const IID_Value = Guid_parse("00000000-0000-0000-c000-000000000046");
  159. pub const IID = &IID_Value;
  160. const This = @This();
  161. vtable: *const VTable,
  162. pub const VTable = extern struct {
  163. QueryInterface: *const fn (*const This, *const Guid, *?*anyopaque) callconv(.C) HRESULT,
  164. AddRef: *const fn (*const This) callconv(.C) ULONG,
  165. Release: *const fn (*const This) callconv(.C) ULONG,
  166. };
  167. pub inline fn QueryInterface(self: *const IUnknown, riid: ?*const Guid, ppvObject: ?*?*anyopaque) HRESULT {
  168. return self.vtable.QueryInterface(self, riid, ppvObject);
  169. }
  170. pub inline fn AddRef(self: *const IUnknown) u32 {
  171. return self.vtable.AddRef(self);
  172. }
  173. pub inline fn Release(self: *const IUnknown) u32 {
  174. return self.vtable.Release(self);
  175. }
  176. fn TryQuery(self: *const IUnknown, comptime dest_type: type) ?*dest_type {
  177. var dest_object: ?*dest_type = undefined;
  178. const hr = self.vtable.QueryInterface(self, dest_type.IID, @ptrCast(&dest_object));
  179. if (hr != 0) {
  180. return null;
  181. }
  182. return dest_object orelse null_panic();
  183. }
  184. };
  185.  
  186. const IInspectable = extern union {
  187. const IID_Value = Guid_parse("af86e2e0-b12d-4c6a-9c5a-d7aa65101e90");
  188. pub const IID = &IID_Value;
  189. const This = @This();
  190. vtable: *const VTable,
  191. IUnknown: IUnknown,
  192. pub const VTable = extern struct {
  193. base: IUnknown.VTable,
  194. GetIids: *const fn (*const IInspectable, *ULONG, *[*]Guid) callconv(.C) HRESULT,
  195. GetRuntimeClassName: *const fn (*const IInspectable, *HSTRING) callconv(.C) HRESULT,
  196. GetTrustLevel: *const fn (*const IInspectable, *TrustLevel) callconv(.C) HRESULT,
  197. };
  198.  
  199. pub fn GetIids(self: *const IInspectable, count: *ULONG, guids: *[*]Guid) HRESULT {
  200. return self.vtable.GetIids(self, count, guids);
  201. }
  202. pub fn GetRuntimeClassName(self: *const IInspectable, classname: *HSTRING) HRESULT {
  203. return self.vtable.GetRuntimeClassName(self, classname);
  204. }
  205. pub fn GetTrustLevel(self: *const IInspectable, trust_level: *TrustLevel) HRESULT {
  206. return self.vtable.GetTrustLevel(self, trust_level);
  207. }
  208. };
  209.  
  210. const AsyncStatus = enum(c_uint) {
  211. Started = 0,
  212. Completed = 1,
  213. Canceled = 2,
  214. Error = 3,
  215. };
  216.  
  217. const IAsyncInfo = extern union {
  218. const IID_Value = Guid_parse("00000036-0000-0000-c000-000000000046");
  219. pub const IID = &IID_Value;
  220. const This = @This();
  221. vtable: *const VTable,
  222. IUnknown: IUnknown,
  223. IInspectable: IInspectable,
  224. pub const VTable = extern struct {
  225. base: IInspectable.VTable,
  226. get_Id: *const fn (*This, *UINT32) callconv(.C) HRESULT,
  227. get_Status: *const fn (*This, *AsyncStatus) callconv(.C) HRESULT,
  228. get_ErrorCode: *const fn (*This, *HRESULT) callconv(.C) HRESULT,
  229. Cancel: *const fn (*This) callconv(.C) HRESULT,
  230. Close: *const fn (*This) callconv(.C) HRESULT,
  231. };
  232.  
  233. pub fn getStatus(async_info: *IAsyncInfo) !AsyncStatus {
  234. var async_status: AsyncStatus = undefined;
  235. const hr = async_info.vtable.get_Status(async_info, &async_status);
  236. std.debug.assert(hr == 0);
  237. return async_status;
  238. }
  239. };
  240.  
  241. const EventRegistrationToken = extern struct {
  242. value: INT64,
  243. };
  244.  
  245. fn AsyncCompletedHandler(comptime AsyncOpType: type) type {
  246. return extern union {
  247. const This = @This();
  248. vtable: *const VTable,
  249. IUnknown: IUnknown,
  250. pub const VTable = extern struct {
  251. base: IUnknown.VTable,
  252. Invoke: *const fn (*This, [*c]AsyncOpType, AsyncStatus) callconv(.C) HRESULT,
  253. };
  254. };
  255. }
  256.  
  257. fn IAsyncOperation(comptime TResult: type) type {
  258. return extern union {
  259. const This = @This();
  260. pub const CompletedHandler = AsyncCompletedHandler(This);
  261. vtable: *const VTable,
  262. IInspectable: IInspectable,
  263. IUnknown: IUnknown,
  264. pub const VTable = extern struct {
  265. base: IInspectable.VTable,
  266. put_Completed: *const fn (*This, *CompletedHandler) callconv(.C) HRESULT,
  267. get_Completed: *const fn (*This, *?*CompletedHandler) callconv(.C) HRESULT,
  268. GetResults: *const fn (*This, *?*TResult) callconv(.C) HRESULT,
  269. };
  270.  
  271. pub fn getInfo(async_op: *This) !*IAsyncInfo {
  272. var async_info: ?*IAsyncInfo = undefined;
  273. const hr = async_op.vtable.base.base.QueryInterface(@ptrCast(async_op), IAsyncInfo.IID, @ptrCast(&async_info));
  274. std.debug.assert(hr == 0);
  275. return async_info.?;
  276. }
  277.  
  278. pub fn getResults(async_op: *This) !*TResult {
  279. var result: ?*TResult = undefined;
  280. const hr = async_op.vtable.GetResults(async_op, &result);
  281. std.debug.assert(hr == 0);
  282. return result.?;
  283. }
  284. };
  285. }
  286.  
  287. fn TypedEventHandler(comptime T: type, comptime U: type) type {
  288. return extern union {
  289. const This = @This();
  290. vtable: *const VTable,
  291. IUnknown: IUnknown,
  292. pub const VTable = extern struct {
  293. base: IUnknown.VTable,
  294. Invoke: *const fn (*This, *T, *U) callconv(.C) HRESULT,
  295. };
  296. };
  297. }
  298.  
  299. const Windows = struct {
  300. const Foundation = struct {
  301. const Collections = struct {
  302. pub const IPropertySet = extern union {
  303. const This = @This();
  304. vtable: *const VTable,
  305. IInspectable: IInspectable,
  306. IUnknown: IUnknown,
  307. pub const VTable = extern struct {
  308. base: IInspectable.VTable,
  309. };
  310. };
  311. pub const IVectorChangedEventArgs = extern union {
  312. const This = @This();
  313. vtable: *const VTable,
  314. IInspectable: IInspectable,
  315. IUnknown: IUnknown,
  316. pub const VTable = extern struct {
  317. base: IInspectable.VTable,
  318. get_CollectionChange: *const fn (*This, [*c]CollectionChange) callconv(.C) HRESULT,
  319. get_Index: *const fn (*This, [*c]c_uint) callconv(.C) HRESULT,
  320. };
  321. };
  322. pub const CollectionChange = enum(c_uint) {
  323. Reset = 0,
  324. ItemInserted = 1,
  325. ItemRemoved = 2,
  326. ItemChanged = 3,
  327. };
  328. };
  329. pub const IAsyncAction = extern union {
  330. const This = @This();
  331. vtable: *const VTable,
  332. IInspectable: IInspectable,
  333. IUnknown: IUnknown,
  334. pub const VTable = extern struct {
  335. base: IInspectable.VTable,
  336. put_Completed: *const fn (*This, [*c]IAsyncActionCompletedHandler) callconv(.C) HRESULT,
  337. get_Completed: *const fn (*This, [*c][*c]IAsyncActionCompletedHandler) callconv(.C) HRESULT,
  338. GetResults: *const fn (*This) callconv(.C) HRESULT,
  339. };
  340. };
  341. pub const IAsyncActionCompletedHandler = extern union {
  342. const This = @This();
  343. vtable: *const VTable,
  344. IUnknown: IUnknown,
  345. pub const VTable = extern struct {
  346. base: IUnknown.VTable,
  347. Invoke: *const fn (*This, [*c]IAsyncAction, AsyncStatus) callconv(.C) HRESULT,
  348. };
  349. };
  350. pub const IDeferralCompletedHandler = extern union {
  351. const This = @This();
  352. vtable: *const VTable,
  353. IUnknown: IUnknown,
  354. pub const VTable = extern struct {
  355. base: IUnknown.VTable,
  356. Invoke: *const fn (*This) callconv(.C) HRESULT,
  357. };
  358. };
  359. pub const IStringable = extern union {
  360. const This = @This();
  361. vtable: *const VTable,
  362. IInspectable: IInspectable,
  363. IUnknown: IUnknown,
  364. pub const VTable = extern struct {
  365. base: IInspectable.VTable,
  366. ToString: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  367. };
  368. };
  369. pub const IClosable = extern union {
  370. const This = @This();
  371. vtable: *const VTable,
  372. IInspectable: IInspectable,
  373. IUnknown: IUnknown,
  374. pub const VTable = extern struct {
  375. base: IInspectable.VTable,
  376. Close: *const fn (*This) callconv(.C) HRESULT,
  377. };
  378. };
  379. pub const IDeferral = extern union {
  380. const This = @This();
  381. vtable: *const VTable,
  382. IInspectable: IInspectable,
  383. IUnknown: IUnknown,
  384. pub const VTable = extern struct {
  385. base: IInspectable.VTable,
  386. Complete: *const fn (*This) callconv(.C) HRESULT,
  387. };
  388. };
  389. pub const IDeferralFactory = extern union {
  390. const This = @This();
  391. vtable: *const VTable,
  392. IInspectable: IInspectable,
  393. IUnknown: IUnknown,
  394. pub const VTable = extern struct {
  395. base: IInspectable.VTable,
  396. Create: *const fn (*This, [*c]IDeferralCompletedHandler, [*c][*c]IDeferral) callconv(.C) HRESULT,
  397. };
  398. };
  399. pub const IMemoryBufferReference = extern union {
  400. const This = @This();
  401. vtable: *const VTable,
  402. IInspectable: IInspectable,
  403. IUnknown: IUnknown,
  404. pub const VTable = extern struct {
  405. base: IInspectable.VTable,
  406. get_Capacity: *const fn (*This, [*c]UINT32) callconv(.C) HRESULT,
  407. add_Closed: *const fn (*This, [*c]TypedEventHandler(IMemoryBufferReference, IInspectable), [*c]EventRegistrationToken) callconv(.C) HRESULT,
  408. remove_Closed: *const fn (*This, EventRegistrationToken) callconv(.C) HRESULT,
  409. };
  410. };
  411. pub const IMemoryBuffer = extern union {
  412. const This = @This();
  413. vtable: *const VTable,
  414. IInspectable: IInspectable,
  415. IUnknown: IUnknown,
  416. pub const VTable = extern struct {
  417. base: IInspectable.VTable,
  418. CreateReference: *const fn (*This, [*c][*c]IMemoryBufferReference) callconv(.C) HRESULT,
  419. };
  420. };
  421. pub const IMemoryBufferFactory = extern union {
  422. const This = @This();
  423. vtable: *const VTable,
  424. IInspectable: IInspectable,
  425. IUnknown: IUnknown,
  426. pub const VTable = extern struct {
  427. base: IInspectable.VTable,
  428. Create: *const fn (*This, UINT32, [*c][*c]IMemoryBuffer) callconv(.C) HRESULT,
  429. };
  430. };
  431. pub const IUriEscapeStatics = extern union {
  432. const This = @This();
  433. vtable: *const VTable,
  434. IInspectable: IInspectable,
  435. IUnknown: IUnknown,
  436. pub const VTable = extern struct {
  437. base: IInspectable.VTable,
  438. UnescapeComponent: *const fn (*This, HSTRING, [*c]HSTRING) callconv(.C) HRESULT,
  439. EscapeComponent: *const fn (*This, HSTRING, [*c]HSTRING) callconv(.C) HRESULT,
  440. };
  441. };
  442. pub const IWwwFormUrlDecoderRuntimeClass = extern union {
  443. const This = @This();
  444. vtable: *const VTable,
  445. IInspectable: IInspectable,
  446. IUnknown: IUnknown,
  447. pub const VTable = extern struct {
  448. base: IInspectable.VTable,
  449. GetFirstValueByName: *const fn (*This, HSTRING, [*c]HSTRING) callconv(.C) HRESULT,
  450. };
  451. };
  452. pub const IUriRuntimeClass = extern union {
  453. const This = @This();
  454. vtable: *const VTable,
  455. IInspectable: IInspectable,
  456. IUnknown: IUnknown,
  457. pub const VTable = extern struct {
  458. base: IInspectable.VTable,
  459. get_AbsoluteUri: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  460. get_DisplayUri: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  461. get_Domain: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  462. get_Extension: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  463. get_Fragment: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  464. get_Host: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  465. get_Password: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  466. get_Path: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  467. get_Query: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  468. get_QueryparseNoBracesd: *const fn (*This, [*c][*c]IWwwFormUrlDecoderRuntimeClass) callconv(.C) HRESULT,
  469. get_RawUri: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  470. get_SchemeName: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  471. get_UserName: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  472. get_Port: *const fn (*This, [*c]INT32) callconv(.C) HRESULT,
  473. get_Suspicious: *const fn (*This, [*c]boolean) callconv(.C) HRESULT,
  474. Equals: *const fn (*This, [*c]IUriRuntimeClass, [*c]boolean) callconv(.C) HRESULT,
  475. CombineUri: *const fn (*This, HSTRING, [*c][*c]IUriRuntimeClass) callconv(.C) HRESULT,
  476. };
  477. };
  478. pub const IUriRuntimeClassFactory = extern union {
  479. const This = @This();
  480. vtable: *const VTable,
  481. IInspectable: IInspectable,
  482. IUnknown: IUnknown,
  483. pub const VTable = extern struct {
  484. base: IInspectable.VTable,
  485. CreateUri: *const fn (*This, HSTRING, [*c][*c]IUriRuntimeClass) callconv(.C) HRESULT,
  486. CreateWithRelativeUri: *const fn (*This, HSTRING, HSTRING, [*c][*c]IUriRuntimeClass) callconv(.C) HRESULT,
  487. };
  488. };
  489. pub const IUriRuntimeClassWithAbsoluteCanonicalUri = extern union {
  490. const This = @This();
  491. vtable: *const VTable,
  492. IInspectable: IInspectable,
  493. IUnknown: IUnknown,
  494. pub const VTable = extern struct {
  495. base: IInspectable.VTable,
  496. get_AbsoluteCanonicalUri: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  497. get_DisplayIri: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  498. };
  499. };
  500. pub const IWwwFormUrlDecoderEntry = extern union {
  501. const This = @This();
  502. vtable: *const VTable,
  503. IInspectable: IInspectable,
  504. IUnknown: IUnknown,
  505. pub const VTable = extern struct {
  506. base: IInspectable.VTable,
  507. get_Name: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  508. get_Value: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  509. };
  510. };
  511. pub const IWwwFormUrlDecoderRuntimeClassFactory = extern union {
  512. const This = @This();
  513. vtable: *const VTable,
  514. IInspectable: IInspectable,
  515. IUnknown: IUnknown,
  516. pub const VTable = extern struct {
  517. base: IInspectable.VTable,
  518. CreateWwwFormUrlDecoder: *const fn (*This, HSTRING, [*c][*c]IWwwFormUrlDecoderRuntimeClass) callconv(.C) HRESULT,
  519. };
  520. };
  521. pub const Deferral = opaque {};
  522. pub const MemoryBuffer = opaque {};
  523. pub const Uri = opaque {};
  524. pub const WwwFormUrlDecoder = opaque {};
  525. pub const WwwFormUrlDecoderEntry = opaque {};
  526.  
  527. pub const Point = extern struct {
  528. X: FLOAT,
  529. Y: FLOAT,
  530. };
  531. pub const Size = extern struct {
  532. Width: FLOAT,
  533. Height: FLOAT,
  534. };
  535. pub const Rect = extern struct {
  536. X: FLOAT,
  537. Y: FLOAT,
  538. Width: FLOAT,
  539. Height: FLOAT,
  540. };
  541. pub const DateTime = extern struct {
  542. UniversalTime: INT64,
  543. };
  544. pub const TimeSpan = extern struct {
  545. Duration: INT64,
  546. };
  547. };
  548.  
  549. pub fn IKeyValuePair(comptime K: type, comptime V: type) type {
  550. return extern union {
  551. const This = @This();
  552. vtable: *const VTable,
  553. IInspectable: IInspectable,
  554. IUnknown: IUnknown,
  555. pub const VTable = extern struct {
  556. base: IInspectable.VTable,
  557. get_Key: *const fn (*This, [*c]K) callconv(.C) HRESULT,
  558. get_Value: *const fn (*This, [*c][*c]V) callconv(.C) HRESULT,
  559. };
  560. };
  561. }
  562.  
  563. pub fn IIterator(comptime T: type) type {
  564. return extern union {
  565. const This = @This();
  566. vtable: *const VTable,
  567. IInspectable: IInspectable,
  568. IUnknown: IUnknown,
  569. pub const VTable = extern struct {
  570. base: IInspectable.VTable,
  571. get_Current: *const fn (*This, *?*T) callconv(.C) HRESULT, //check that's it's not *?*T
  572. get_HasCurrent: *const fn (*This, [*c]WINBOOL) callconv(.C) HRESULT,
  573. MoveNext: *const fn (*This, [*c]WINBOOL) callconv(.C) HRESULT,
  574. GetMany: *const fn (*This, UINT32, [*]*T, *UINT32) callconv(.C) HRESULT,
  575. };
  576. };
  577. }
  578.  
  579. pub fn IIterable(comptime T: type) type {
  580. return extern union {
  581. const This = @This();
  582. vtable: *const VTable,
  583. IInspectable: IInspectable,
  584. IUnknown: IUnknown,
  585. pub const VTable = extern struct {
  586. base: IInspectable.VTable,
  587. First: *const fn (*This, *?*IIterator(T)) callconv(.C) HRESULT,
  588. };
  589. };
  590. }
  591.  
  592. pub fn IVectorView(comptime T: type) type {
  593. return extern union {
  594. const This = @This();
  595. vtable: *const VTable,
  596. IInspectable: IInspectable,
  597. IUnknown: IUnknown,
  598. pub const VTable = extern struct {
  599. base: IInspectable.VTable,
  600. GetAt: *const fn (*This, UINT32, *?*T) callconv(.C) HRESULT,
  601. get_Size: *const fn (*This, [*c]UINT32) callconv(.C) HRESULT,
  602. IndexOf: *const fn (*This, *T, [*c]UINT32, [*c]BOOLEAN) callconv(.C) HRESULT,
  603. GetMany: *const fn (*This, UINT32, UINT32, [*]*T, *UINT32) callconv(.C) HRESULT,
  604. };
  605. pub const Iterator = struct {
  606. vector: *This,
  607. count: u32,
  608. idx: u32 = 0,
  609.  
  610. pub fn next(iter: *Iterator) !?*T {
  611. if (iter.idx < iter.count) {
  612. var element: ?*T = undefined;
  613. const hr = iter.vector.vtable.GetAt(iter.vector, iter.idx, &element);
  614. std.debug.assert(hr == 0);
  615. iter.idx += 1;
  616. return element.?;
  617. } else {
  618. return null;
  619. }
  620. }
  621. };
  622. pub fn iterator(vector: *This) !Iterator {
  623. var count: u32 = undefined;
  624. const hr = vector.vtable.get_Size(vector, &count);
  625. std.debug.assert(hr == 0);
  626. return .{ .vector = vector, .count = count };
  627. }
  628. };
  629. }
  630.  
  631. pub fn IVector(comptime T: type) type {
  632. return extern union {
  633. const This = @This();
  634. vtable: *const VTable,
  635. IInspectable: IInspectable,
  636. IUnknown: IUnknown,
  637. pub const VTable = extern struct {
  638. base: IInspectable.VTable,
  639. GetAt: *const fn (*This, UINT32, [*c]T) callconv(.C) HRESULT,
  640. get_Size: *const fn (*This, [*c]UINT32) callconv(.C) HRESULT,
  641. GetView: *const fn (*This, [*c][*c]IVectorView(T)) callconv(.C) HRESULT,
  642. IndexOf: *const fn (*This, T, [*c]UINT32, [*c]BOOLEAN) callconv(.C) HRESULT,
  643. SetAt: *const fn (*This, UINT32, T) callconv(.C) HRESULT,
  644. InsertAt: *const fn (*This, UINT32, T) callconv(.C) HRESULT,
  645. RemoveAt: *const fn (*This, UINT32) callconv(.C) HRESULT,
  646. Append: *const fn (*This, T) callconv(.C) HRESULT,
  647. RemoveAtEnd: *const fn (*This) callconv(.C) HRESULT,
  648. Clear: *const fn (*This) callconv(.C) HRESULT,
  649. GetMany: *const fn (*This, UINT32, UINT32, [*c]T, [*c]UINT32) callconv(.C) HRESULT,
  650. ReplaceAll: *const fn (*This, UINT32, [*c]T) callconv(.C) HRESULT,
  651. };
  652. };
  653. }
  654.  
  655. pub fn IMapView(comptime K: type, comptime V: type) type {
  656. return extern union {
  657. const This = @This();
  658. vtable: *const VTable,
  659. IInspectable: IInspectable,
  660. IUnknown: IUnknown,
  661. pub const VTable = extern struct {
  662. base: IInspectable.VTable,
  663. Lookup: *const fn (*This, K, [*c][*c]V) callconv(.C) HRESULT,
  664. get_Size: *const fn (*This, [*c]c_uint) callconv(.C) HRESULT,
  665. HasKey: *const fn (*This, K, [*c]boolean) callconv(.C) HRESULT,
  666. Split: *const fn (*This, [*c][*c]This, [*c][*c]This) callconv(.C) HRESULT,
  667. };
  668. };
  669. }
  670.  
  671. pub fn IReference(comptime T: type) type {
  672. return extern union {
  673. const This = @This();
  674. vtable: *const VTable,
  675. IInspectable: IInspectable,
  676. IUnknown: IUnknown,
  677. pub const VTable = extern struct {
  678. base: IInspectable.VTable,
  679. get_Value: *const fn (*This, [*c]T) callconv(.C) HRESULT,
  680. };
  681. };
  682. }
  683.  
  684. pub const PropertyType = enum(c_uint) {
  685. Empty = 0,
  686. UInt8 = 1,
  687. Int16 = 2,
  688. UInt16 = 3,
  689. Int32 = 4,
  690. UInt32 = 5,
  691. Int64 = 6,
  692. UInt64 = 7,
  693. Single = 8,
  694. Double = 9,
  695. Char16 = 10,
  696. Boolean = 11,
  697. String = 12,
  698. Inspectable = 13,
  699. DateTime = 14,
  700. TimeSpan = 15,
  701. Guid = 16,
  702. Point = 17,
  703. Size = 18,
  704. Rect = 19,
  705. OtherType = 20,
  706. UInt8Array = 1025,
  707. Int16Array = 1026,
  708. UInt16Array = 1027,
  709. Int32Array = 1028,
  710. UInt32Array = 1029,
  711. Int64Array = 1030,
  712. UInt64Array = 1031,
  713. SingleArray = 1032,
  714. DoubleArray = 1033,
  715. Char16Array = 1034,
  716. BooleanArray = 1035,
  717. StringArray = 1036,
  718. InspectableArray = 1037,
  719. DateTimeArray = 1038,
  720. TimeSpanArray = 1039,
  721. GuidArray = 1040,
  722. PointArray = 1041,
  723. SizeArray = 1042,
  724. RectArray = 1043,
  725. OtherTypeArray = 1044,
  726. };
  727.  
  728. const Devices = struct {
  729. const Enumeration = struct {
  730. pub const Panel = enum(c_uint) {
  731. Unknown = 0,
  732. Front = 1,
  733. Back = 2,
  734. Top = 3,
  735. Bottom = 4,
  736. Left = 5,
  737. Right = 6,
  738. };
  739. pub const IEnclosureLocation = extern union {
  740. const This = @This();
  741. vtable: *const VTable,
  742. IInspectable: IInspectable,
  743. IUnknown: IUnknown,
  744. pub const VTable = extern struct {
  745. base: IInspectable.VTable,
  746. get_InDock: *const fn (*This, [*c]boolean) callconv(.C) HRESULT,
  747. get_InLid: *const fn (*This, [*c]boolean) callconv(.C) HRESULT,
  748. get_Panel: *const fn (*This, [*c]Panel) callconv(.C) HRESULT,
  749. };
  750. };
  751. pub const IDeviceInformationUpdate = extern union {
  752. const This = @This();
  753. vtable: *const VTable,
  754. IInspectable: IInspectable,
  755. IUnknown: IUnknown,
  756. pub const VTable = extern struct {
  757. base: IInspectable.VTable,
  758. get_Id: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  759. get_Properties: *const fn (*This, [*c][*c]IMapView(HSTRING, IInspectable)) callconv(.C) HRESULT,
  760. };
  761. };
  762.  
  763. pub const IDeviceInformation = extern union {
  764. const This = @This();
  765. vtable: *const VTable,
  766. IInspectable: IInspectable,
  767. IUnknown: IUnknown,
  768. pub const VTable = extern struct {
  769. base: IInspectable.VTable,
  770. get_Id: *const fn (*This, *HSTRING) callconv(.C) HRESULT,
  771. get_Name: *const fn (*This, *HSTRING) callconv(.C) HRESULT,
  772. get_IsEnabled: *const fn (*This, *boolean) callconv(.C) HRESULT,
  773. get_IsDefault: *const fn (*This, *boolean) callconv(.C) HRESULT,
  774. get_EnclosureLocation: *const fn (*This, *?*IEnclosureLocation) callconv(.C) HRESULT,
  775. get_Properties: *const fn (*This, *?*IMapView(HSTRING, IInspectable)) callconv(.C) HRESULT,
  776. Update: *const fn (*This, *IDeviceInformationUpdate) callconv(.C) HRESULT,
  777. GetThumbnailAsync: *const fn (*This, *?*IAsyncOperation(Storage.Streams.IRandomAccessStreamWithContentType)) callconv(.C) HRESULT,
  778. GetGlyphThumbnailAsync: *const fn (*This, *?*IAsyncOperation(Storage.Streams.IRandomAccessStreamWithContentType)) callconv(.C) HRESULT,
  779. };
  780. };
  781.  
  782. pub const DeviceWatcherStatus = enum(c_uint) {
  783. Created = 0,
  784. Started = 1,
  785. EnumerationCompleted = 2,
  786. Stopping = 3,
  787. Stopped = 4,
  788. Aborted = 5,
  789. };
  790.  
  791. pub const IDeviceWatcher = extern union {
  792. pub const Added_EventHandler = struct {
  793. const IID_Value = Guid_parse("03C5A07B-990C-5D09-B0B8-5734EAA38222");
  794. pub const IID = &IID_Value;
  795. pub const Arg = IDeviceInformation;
  796. pub const Caller = IDeviceWatcher;
  797. };
  798. pub const Updated_EventHandler = struct {
  799. const IID_Value = Guid_parse("906F1254-79AD-54FC-93C4-CDB99B437899");
  800. pub const IID = &IID_Value;
  801. pub const Arg = IDeviceInformationUpdate;
  802. pub const Caller = IDeviceWatcher;
  803. };
  804. pub const Removed_EventHandler = Updated_EventHandler;
  805.  
  806. pub const EnumerationCompleted_Handler = struct {
  807. const IID_Value = Guid_parse("9234630F-1FF4-54F6-9E3F-AC20369B7725");
  808. pub const IID = &IID_Value;
  809. pub const Arg = IInspectable;
  810. pub const Caller = IDeviceWatcher;
  811. };
  812.  
  813. pub const Stopped_Handler = struct {
  814. const IID_Value = Guid_parse("9234630F-1FF4-54F6-9E3F-AC20369B7725");
  815. pub const IID = &IID_Value;
  816. pub const Arg = IInspectable;
  817. pub const Caller = IDeviceWatcher;
  818. };
  819.  
  820. const This = @This();
  821. vtable: *const VTable,
  822. IInspectable: IInspectable,
  823. IUnknown: IUnknown,
  824. pub const VTable = extern struct {
  825. base: IInspectable.VTable,
  826. add_Added: *const fn (*const This, *TypedEventHandler(This, IDeviceInformation), *EventRegistrationToken) callconv(.C) HRESULT,
  827. remove_Added: *const fn (*const This, EventRegistrationToken) callconv(.C) HRESULT,
  828. add_Updated: *const fn (*const This, *TypedEventHandler(This, IDeviceInformationUpdate), *EventRegistrationToken) callconv(.C) HRESULT,
  829. remove_Updated: *const fn (*const This, EventRegistrationToken) callconv(.C) HRESULT,
  830. add_Removed: *const fn (*const This, *TypedEventHandler(This, IDeviceInformationUpdate), *EventRegistrationToken) callconv(.C) HRESULT,
  831. remove_Removed: *const fn (*const This, EventRegistrationToken) callconv(.C) HRESULT,
  832. add_EnumerationCompleted: *const fn (*const This, *TypedEventHandler(This, IInspectable), *EventRegistrationToken) callconv(.C) HRESULT,
  833. remove_EnumerationCompleted: *const fn (*const This, EventRegistrationToken) callconv(.C) HRESULT,
  834. add_Stopped: *const fn (*const This, *TypedEventHandler(This, IInspectable), *EventRegistrationToken) callconv(.C) HRESULT,
  835. remove_Stopped: *const fn (*const This, EventRegistrationToken) callconv(.C) HRESULT,
  836. get_Status: *const fn (*const This, *DeviceWatcherStatus) callconv(.C) HRESULT,
  837. Start: *const fn (*const This) callconv(.C) HRESULT,
  838. Stop: *const fn (*const This) callconv(.C) HRESULT,
  839. };
  840. };
  841.  
  842. pub const DeviceClass = enum(c_uint) {
  843. All = 0,
  844. AudioCapture = 1,
  845. AudioRender = 2,
  846. PortableStorageDevice = 3,
  847. VideoCapture = 4,
  848. ImageScanner = 5,
  849. Location = 6,
  850. };
  851.  
  852. pub const IDeviceInformationStatics = extern union {
  853. pub const Name = "Windows.Devices.Enumeration.DeviceInformation";
  854. const IID_Value = Guid_parse("c17f100e-3a46-4a78-8013-769dc9b97390");
  855. pub const IID = &IID_Value;
  856. const This = @This();
  857. vtable: *const VTable,
  858. IInspectable: IInspectable,
  859. IUnknown: IUnknown,
  860. pub const VTable = extern struct {
  861. base: IInspectable.VTable,
  862. CreateFromIdAsync: *const fn (*This, HSTRING, [*c][*c]IAsyncOperation(IDeviceInformation)) callconv(.C) HRESULT,
  863. CreateFromIdAsyncAdditionalProperties: *const fn (*This, HSTRING, [*c]IIterable(HSTRING), [*c][*c]IAsyncOperation(IDeviceInformation)) callconv(.C) HRESULT,
  864. FindAllAsync: *const fn (*This, [*c][*c]IAsyncOperation(DeviceInformationCollection)) callconv(.C) HRESULT,
  865. FindAllAsyncDeviceClass: *const fn (*This, DeviceClass, [*c][*c]IAsyncOperation(DeviceInformationCollection)) callconv(.C) HRESULT,
  866. FindAllAsyncAqsFilter: *const fn (*This, HSTRING, [*c][*c]IAsyncOperation(DeviceInformationCollection)) callconv(.C) HRESULT,
  867. FindAllAsyncAqsFilterAndAdditionalProperties: *const fn (*This, HSTRING, [*c]IIterable(HSTRING), [*c][*c]IAsyncOperation(DeviceInformationCollection)) callconv(.C) HRESULT,
  868. CreateWatcher: *const fn (*This, *?*IDeviceWatcher) callconv(.C) HRESULT,
  869. CreateWatcherDeviceClass: *const fn (*This, DeviceClass, [*c]IDeviceWatcher) callconv(.C) HRESULT,
  870. CreateWatcherAqsFilter: *const fn (*This, HSTRING, [*c][*c]IDeviceWatcher) callconv(.C) HRESULT,
  871. CreateWatcherAqsFilterAndAdditionalProperties: *const fn (*This, HSTRING, [*c]IIterable(HSTRING), [*c][*c]IDeviceWatcher) callconv(.C) HRESULT,
  872. };
  873. };
  874.  
  875. pub const DeviceInformationKind = enum(c_uint) {
  876. Unknown = 0,
  877. DeviceInterface = 1,
  878. DeviceContainer = 2,
  879. Device = 3,
  880. DeviceInterfaceClass = 4,
  881. AssociationEndpoint = 5,
  882. AssociationEndpointContainer = 6,
  883. AssociationEndpointService = 7,
  884. DevicePanel = 8,
  885. };
  886.  
  887. pub const IDeviceInformationStatics2 = extern union {
  888. const This = @This();
  889. vtable: *const VTable,
  890. IInspectable: IInspectable,
  891. IUnknown: IUnknown,
  892. pub const VTable = extern struct {
  893. base: IInspectable.VTable,
  894. GetAqsFilterFromDeviceClass: *const fn (*This, DeviceClass, [*c]HSTRING) callconv(.C) HRESULT,
  895. CreateFromIdAsyncWithKindAndAdditionalProperties: *const fn (*This, HSTRING, [*c]IIterable(HSTRING), DeviceInformationKind, [*c][*c]IAsyncOperation(IDeviceInformation)) callconv(.C) HRESULT,
  896. FindAllAsyncWithKindAqsFilterAndAdditionalProperties: *const fn (*This, HSTRING, [*c]IIterable(HSTRING), DeviceInformationKind, [*c][*c]IAsyncOperation(DeviceInformationCollection)) callconv(.C) HRESULT,
  897. CreateWatcherWithKindAqsFilterAndAdditionalProperties: *const fn (*This, HSTRING, [*c]IIterable(HSTRING), DeviceInformationKind, [*c][*c]IDeviceWatcher) callconv(.C) HRESULT,
  898. };
  899. };
  900.  
  901. pub const DeviceAccessStatus = enum(c_uint) {
  902. Unspecified = 0,
  903. Allowed = 1,
  904. DeniedByUser = 2,
  905. DeniedBySystem = 3,
  906. };
  907.  
  908. pub const IDeviceAccessChangedEventArgs = extern union {
  909. const This = @This();
  910. vtable: *const VTable,
  911. IInspectable: IInspectable,
  912. IUnknown: IUnknown,
  913. pub const VTable = extern struct {
  914. base: IInspectable.VTable,
  915. get_Status: *const fn (*This, *DeviceAccessStatus) callconv(.C) HRESULT,
  916. };
  917. };
  918.  
  919. pub const IDeviceAccessChangedEventArgs2 = extern union {
  920. const This = @This();
  921. vtable: *const VTable,
  922. IInspectable: IInspectable,
  923. IUnknown: IUnknown,
  924. pub const VTable = extern struct {
  925. base: IInspectable.VTable,
  926. get_Id: *const fn (*This, *HSTRING) callconv(.C) HRESULT,
  927. };
  928. };
  929.  
  930. pub const IDeviceAccessInformation = extern union {
  931. const This = @This();
  932. vtable: *const VTable,
  933. IInspectable: IInspectable,
  934. IUnknown: IUnknown,
  935. pub const VTable = extern struct {
  936. base: IInspectable.VTable,
  937. add_AccessChanged: *const fn (*This, *TypedEventHandler(This, IDeviceAccessChangedEventArgs), *EventRegistrationToken) callconv(.C) HRESULT,
  938. remove_AccessChanged: *const fn (*This, EventRegistrationToken) callconv(.C) HRESULT,
  939. get_CurrentStatus: *const fn (*This, *DeviceAccessStatus) callconv(.C) HRESULT,
  940. };
  941. };
  942.  
  943. pub const IDeviceAccessInformationStatics = extern union {
  944. const This = @This();
  945. vtable: *const VTable,
  946. IInspectable: IInspectable,
  947. IUnknown: IUnknown,
  948. pub const VTable = extern struct {
  949. base: IInspectable.VTable,
  950. CreateFromId: *const fn (*This, HSTRING, [*c][*c]IDeviceAccessInformation) callconv(.C) HRESULT,
  951. CreateFromDeviceClassId: *const fn (*This, Guid, [*c][*c]IDeviceAccessInformation) callconv(.C) HRESULT,
  952. CreateFromDeviceClass: *const fn (*This, DeviceClass, [*c]IDeviceAccessInformation) callconv(.C) HRESULT,
  953. };
  954. };
  955.  
  956. pub const DeviceInformation = opaque {};
  957. pub const DeviceInformationCollection = opaque {};
  958. pub const DeviceInformationUpdate = opaque {};
  959. pub const DeviceThumbnail = opaque {};
  960. pub const DeviceWatcher = opaque {};
  961. pub const EnclosureLocation = opaque {};
  962. pub const DeviceAccessChangedEventArgs = opaque {};
  963. pub const DeviceAccessInformation = opaque {};
  964. };
  965.  
  966. const Midi = struct {
  967. pub const IMidiChannelPressureMessage = extern union {
  968. const This = @This();
  969. vtable: *const VTable,
  970. IInspectable: IInspectable,
  971. IUnknown: IUnknown,
  972. pub const VTable = extern struct {
  973. base: IInspectable.VTable,
  974. get_Channel: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  975. get_Pressure: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  976. };
  977. };
  978. pub const IMidiChannelPressureMessageFactory = extern union {
  979. const This = @This();
  980. vtable: *const VTable,
  981. IInspectable: IInspectable,
  982. IUnknown: IUnknown,
  983. pub const VTable = extern struct {
  984. base: IInspectable.VTable,
  985. CreateMidiChannelPressureMessage: *const fn (*This, BYTE, BYTE, *?*IMidiChannelPressureMessage) callconv(.C) HRESULT,
  986. };
  987. };
  988. pub const IMidiControlChangeMessage = extern union {
  989. const IID_Value = Guid_parse("B7E15F83-780D-405F-B781-3E1598C97F40");
  990. pub const IID = &IID_Value;
  991. const This = @This();
  992. vtable: *const VTable,
  993. IInspectable: IInspectable,
  994. IUnknown: IUnknown,
  995. pub const VTable = extern struct {
  996. base: IInspectable.VTable,
  997. get_Channel: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  998. get_Controller: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  999. get_ControlValue: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  1000. };
  1001. };
  1002. pub const IMidiControlChangeMessageFactory = extern union {
  1003. const This = @This();
  1004. vtable: *const VTable,
  1005. IInspectable: IInspectable,
  1006. IUnknown: IUnknown,
  1007. pub const VTable = extern struct {
  1008. base: IInspectable.VTable,
  1009. CreateMidiControlChangeMessage: *const fn (*This, BYTE, BYTE, BYTE, *?*IMidiControlChangeMessage) callconv(.C) HRESULT,
  1010. };
  1011. };
  1012.  
  1013. pub const IMidiInPort = extern union {
  1014. const EventHandler_IID_Value = Guid_parse("50017240-cc39-5775-8a6b-f6f22386bfca");
  1015. pub const EventHandler_IID = &EventHandler_IID_Value;
  1016. pub const EventHandler = TypedEventHandler(This, IMidiMessageReceivedEventArgs);
  1017.  
  1018. const This = @This();
  1019. vtable: *const VTable,
  1020. IInspectable: IInspectable,
  1021. IUnknown: IUnknown,
  1022. pub const VTable = extern struct {
  1023. base: IInspectable.VTable,
  1024. add_MessageReceived: *const fn (*This, *EventHandler, *EventRegistrationToken) callconv(.C) HRESULT,
  1025. remove_MessageReceived: *const fn (*This, EventRegistrationToken) callconv(.C) HRESULT,
  1026. get_DeviceId: *const fn (*This, *HSTRING) callconv(.C) HRESULT,
  1027. };
  1028. };
  1029.  
  1030. pub const IMidiInPortStatics = extern union {
  1031. pub const Name = "Windows.Devices.Midi.MidiInPort";
  1032. const IID_Value = Guid_parse("44c439dc-67ff-4a6e-8bac-fdb6610cf296");
  1033. pub const IID = &IID_Value;
  1034. const This = @This();
  1035. vtable: *const VTable,
  1036. IInspectable: IInspectable,
  1037. IUnknown: IUnknown,
  1038. pub const VTable = extern struct {
  1039. base: IInspectable.VTable,
  1040. FromIdAsync: *const fn (*This, HSTRING, *?*IAsyncOperation(IMidiInPort)) callconv(.C) HRESULT,
  1041. GetDeviceSelector: *const fn (*This, *HSTRING) callconv(.C) HRESULT,
  1042. };
  1043. pub fn fromIdAsync(this: *This, hstring: HSTRING) !*IAsyncOperation(IMidiInPort) {
  1044. var c: ?*IAsyncOperation(IMidiInPort) = undefined;
  1045. const hr = this.vtable.FromIdAsync(this, hstring, &c);
  1046. try Success(hr);
  1047. return c orelse null_panic();
  1048. }
  1049. };
  1050. pub const MidiMessageType = enum(c_uint) {
  1051. None = 0,
  1052. NoteOff = 128,
  1053. NoteOn = 144,
  1054. PolyphonicKeyPressure = 160,
  1055. ControlChange = 176,
  1056. ProgramChange = 192,
  1057. ChannelPressure = 208,
  1058. PitchBendChange = 224,
  1059. SystemExclusive = 240,
  1060. MidiTimeCode = 241,
  1061. SongPositionPointer = 242,
  1062. SongSelect = 243,
  1063. TuneRequest = 246,
  1064. EndSystemExclusive = 247,
  1065. TimingClock = 248,
  1066. Start = 250,
  1067. Continue = 251,
  1068. Stop = 252,
  1069. ActiveSensing = 254,
  1070. SystemReset = 255,
  1071. };
  1072.  
  1073. pub const IMidiMessage = extern union {
  1074. const This = @This();
  1075. vtable: *const VTable,
  1076. IInspectable: IInspectable,
  1077. IUnknown: IUnknown,
  1078. pub const VTable = extern struct {
  1079. base: IInspectable.VTable,
  1080. get_Timestamp: *const fn (*This, *Foundation.TimeSpan) callconv(.C) HRESULT,
  1081. get_RawData: *const fn (*This, *?*Storage.Streams.IBuffer) callconv(.C) HRESULT,
  1082. get_Type: *const fn (*This, *MidiMessageType) callconv(.C) HRESULT,
  1083. };
  1084. };
  1085. pub const IMidiMessageReceivedEventArgs = extern union {
  1086. const This = @This();
  1087. vtable: *const VTable,
  1088. IInspectable: IInspectable,
  1089. IUnknown: IUnknown,
  1090. pub const VTable = extern struct {
  1091. base: IInspectable.VTable,
  1092. get_Message: *const fn (*This, *?*IMidiMessage) callconv(.C) HRESULT,
  1093. };
  1094. };
  1095. pub const IMidiNoteOffMessage = extern union {
  1096. const IID_Value = Guid_parse("16FD8AF4-198E-4D8F-A654-D305A293548F");
  1097. pub const IID = &IID_Value;
  1098. const This = @This();
  1099. vtable: *const VTable,
  1100. IInspectable: IInspectable,
  1101. IUnknown: IUnknown,
  1102. pub const VTable = extern struct {
  1103. base: IInspectable.VTable,
  1104. get_Channel: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  1105. get_Note: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  1106. get_Velocity: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  1107. };
  1108. };
  1109. pub const IMidiNoteOffMessageFactory = extern union {
  1110. const IID_Value = Guid_parse("A6B240E0-A749-425F-8AF4-A4D979CC15B5");
  1111. pub const IID = &IID_Value;
  1112. const This = @This();
  1113. vtable: *const VTable,
  1114. IInspectable: IInspectable,
  1115. IUnknown: IUnknown,
  1116. pub const VTable = extern struct {
  1117. base: IInspectable.VTable,
  1118. CreateMidiNoteOffMessage: *const fn (*This, BYTE, BYTE, BYTE, [*c][*c]IMidiNoteOffMessage) callconv(.C) HRESULT,
  1119. };
  1120. };
  1121. pub const IMidiNoteOnMessage = extern union {
  1122. const IID_Value = Guid_parse("E0224AF5-6181-46DD-AFA2-410004C057AA");
  1123. pub const IID = &IID_Value;
  1124. const This = @This();
  1125. vtable: *const VTable,
  1126. IInspectable: IInspectable,
  1127. IUnknown: IUnknown,
  1128. pub const VTable = extern struct {
  1129. base: IInspectable.VTable,
  1130. get_Channel: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  1131. get_Note: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  1132. get_Velocity: *const fn (*This, *BYTE) callconv(.C) HRESULT,
  1133. };
  1134. };
  1135. pub const IMidiNoteOnMessageFactory = extern union {
  1136. const IID_Value = Guid_parse("9B4280A0-59C1-420E-B517-15A10AA9606B");
  1137. pub const IID = &IID_Value;
  1138. const This = @This();
  1139. vtable: *const VTable,
  1140. IInspectable: IInspectable,
  1141. IUnknown: IUnknown,
  1142. pub const VTable = extern struct {
  1143. base: IInspectable.VTable,
  1144. CreateMidiNoteOnMessage: *const fn (*This, BYTE, BYTE, BYTE, [*c][*c]IMidiNoteOnMessage) callconv(.C) HRESULT,
  1145. };
  1146. };
  1147. pub const IMidiOutPort = extern union {
  1148. const IID_Value = Guid_parse("931D6D9F-57A2-4A3A-ADB8-4640886F6693");
  1149. pub const IID = &IID_Value;
  1150. const This = @This();
  1151. vtable: *const VTable,
  1152. IInspectable: IInspectable,
  1153. IUnknown: IUnknown,
  1154. pub const VTable = extern struct {
  1155. base: IInspectable.VTable,
  1156. SendMessageA: *const fn (*This, [*c]IMidiMessage) callconv(.C) HRESULT,
  1157. SendBuffer: *const fn (*This, [*c]Storage.Streams.IBuffer) callconv(.C) HRESULT,
  1158. get_DeviceId: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  1159. };
  1160. };
  1161. pub const IMidiOutPortStatics = extern union {
  1162. const IID_Value = Guid_parse("065CC3E9-0F88-448B-9B64-A95826C65B8F");
  1163. pub const IID = &IID_Value;
  1164. const This = @This();
  1165. vtable: *const VTable,
  1166. IInspectable: IInspectable,
  1167. IUnknown: IUnknown,
  1168. pub const VTable = extern struct {
  1169. base: IInspectable.VTable,
  1170. FromIdAsync: *const fn (*This, HSTRING, [*c][*c]IAsyncOperation(IMidiOutPort)) callconv(.C) HRESULT,
  1171. GetDeviceSelector: *const fn (*This, [*c]HSTRING) callconv(.C) HRESULT,
  1172. };
  1173. };
  1174. pub const IMidiPitchBendChangeMessage = extern union {
  1175. const IID_Value = Guid_parse("29DF4CB1-2E9F-4FAF-8C2B-9CB82A9079CA");
  1176. pub const IID = &IID_Value;
  1177. const This = @This();
  1178. vtable: *const VTable,
  1179. IInspectable: IInspectable,
  1180. IUnknown: IUnknown,
  1181. pub const VTable = extern struct {
  1182. base: IInspectable.VTable,
  1183. get_Channel: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1184. get_Bend: *const fn (*This, [*c]UINT16) callconv(.C) HRESULT,
  1185. };
  1186. };
  1187. pub const IMidiPitchBendChangeMessageFactory = extern union {
  1188. const IID_Value = Guid_parse("F5EEDF55-CFC8-4926-B30E-A3622393306C");
  1189. pub const IID = &IID_Value;
  1190. const This = @This();
  1191. vtable: *const VTable,
  1192. IInspectable: IInspectable,
  1193. IUnknown: IUnknown,
  1194. pub const VTable = extern struct {
  1195. base: IInspectable.VTable,
  1196. CreateMidiPitchBendChangeMessage: *const fn (*This, BYTE, UINT16, [*c][*c]IMidiPitchBendChangeMessage) callconv(.C) HRESULT,
  1197. };
  1198. };
  1199. pub const IMidiPolyphonicKeyPressureMessage = extern union {
  1200. const IID_Value = Guid_parse("1F7337FE-ACE8-48A0-868E-7CDBF20F04D6");
  1201. pub const IID = &IID_Value;
  1202. const This = @This();
  1203. vtable: *const VTable,
  1204. IInspectable: IInspectable,
  1205. IUnknown: IUnknown,
  1206. pub const VTable = extern struct {
  1207. base: IInspectable.VTable,
  1208. get_Channel: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1209. get_Note: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1210. get_Pressure: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1211. };
  1212. };
  1213. pub const IMidiPolyphonicKeyPressureMessageFactory = extern union {
  1214. const IID_Value = Guid_parse("E98F483E-C4B3-4DD2-917C-E349815A1B3B");
  1215. pub const IID = &IID_Value;
  1216. const This = @This();
  1217. vtable: *const VTable,
  1218. IInspectable: IInspectable,
  1219. IUnknown: IUnknown,
  1220. pub const VTable = extern struct {
  1221. base: IInspectable.VTable,
  1222. CreateMidiPolyphonicKeyPressureMessage: *const fn (*This, BYTE, BYTE, BYTE, [*c][*c]IMidiPolyphonicKeyPressureMessage) callconv(.C) HRESULT,
  1223. };
  1224. };
  1225. pub const IMidiProgramChangeMessage = extern union {
  1226. const IID_Value = Guid_parse("9CBB3C78-7A3E-4327-AA98-20B8E4485AF8");
  1227. pub const IID = &IID_Value;
  1228. const This = @This();
  1229. vtable: *const VTable,
  1230. IInspectable: IInspectable,
  1231. IUnknown: IUnknown,
  1232. pub const VTable = extern struct {
  1233. base: IInspectable.VTable,
  1234. get_Channel: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1235. get_Program: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1236. };
  1237. };
  1238. pub const IMidiProgramChangeMessageFactory = extern union {
  1239. const IID_Value = Guid_parse("D6B04387-524B-4104-9C99-6572BFD2E261");
  1240. pub const IID = &IID_Value;
  1241. const This = @This();
  1242. vtable: *const VTable,
  1243. IInspectable: IInspectable,
  1244. IUnknown: IUnknown,
  1245. pub const VTable = extern struct {
  1246. base: IInspectable.VTable,
  1247. CreateMidiProgramChangeMessage: *const fn (*This, BYTE, BYTE, [*c][*c]IMidiProgramChangeMessage) callconv(.C) HRESULT,
  1248. };
  1249. };
  1250. pub const IMidiSongPositionPointerMessage = extern union {
  1251. const IID_Value = Guid_parse("4CA50C56-EC5E-4AE4-A115-88DC57CC2B79");
  1252. pub const IID = &IID_Value;
  1253. const This = @This();
  1254. vtable: *const VTable,
  1255. IInspectable: IInspectable,
  1256. IUnknown: IUnknown,
  1257. pub const VTable = extern struct {
  1258. base: IInspectable.VTable,
  1259. get_Beats: *const fn (*This, [*c]UINT16) callconv(.C) HRESULT,
  1260. };
  1261. };
  1262. pub const IMidiSongPositionPointerMessageFactory = extern union {
  1263. const IID_Value = Guid_parse("9C00E996-F10B-4FEA-B395-F5D6CF80F64E");
  1264. pub const IID = &IID_Value;
  1265. const This = @This();
  1266. vtable: *const VTable,
  1267. IInspectable: IInspectable,
  1268. IUnknown: IUnknown,
  1269. pub const VTable = extern struct {
  1270. base: IInspectable.VTable,
  1271. CreateMidiSongPositionPointerMessage: *const fn (*This, UINT16, [*c][*c]IMidiSongPositionPointerMessage) callconv(.C) HRESULT,
  1272. };
  1273. };
  1274. pub const IMidiSongSelectMessage = extern union {
  1275. const IID_Value = Guid_parse("49F0F27F-6D83-4741-A5BF-4629F6BE974F");
  1276. pub const IID = &IID_Value;
  1277. const This = @This();
  1278. vtable: *const VTable,
  1279. IInspectable: IInspectable,
  1280. IUnknown: IUnknown,
  1281. pub const VTable = extern struct {
  1282. base: IInspectable.VTable,
  1283. get_Song: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1284. };
  1285. };
  1286. pub const IMidiSongSelectMessageFactory = extern union {
  1287. const IID_Value = Guid_parse("848878E4-8748-4129-A66C-A05493F75DAA");
  1288. pub const IID = &IID_Value;
  1289. const This = @This();
  1290. vtable: *const VTable,
  1291. IInspectable: IInspectable,
  1292. IUnknown: IUnknown,
  1293. pub const VTable = extern struct {
  1294. base: IInspectable.VTable,
  1295. CreateMidiSongSelectMessage: *const fn (*This, BYTE, [*c][*c]IMidiSongSelectMessage) callconv(.C) HRESULT,
  1296. };
  1297. };
  1298. pub const IMidiSynthesizer = extern union {
  1299. const IID_Value = Guid_parse("F0DA155E-DB90-405F-B8AE-21D2E17F2E45");
  1300. pub const IID = &IID_Value;
  1301. const This = @This();
  1302. vtable: *const VTable,
  1303. IInspectable: IInspectable,
  1304. IUnknown: IUnknown,
  1305. pub const VTable = extern struct {
  1306. base: IInspectable.VTable,
  1307. get_AudioDevice: *const fn (*This, [*c][*c]Devices.Enumeration.IDeviceInformation) callconv(.C) HRESULT,
  1308. get_Volume: *const fn (*This, [*c]DOUBLE) callconv(.C) HRESULT,
  1309. put_Volume: *const fn (*This, DOUBLE) callconv(.C) HRESULT,
  1310. };
  1311. };
  1312. pub const IMidiSynthesizerStatics = extern union {
  1313. const This = @This();
  1314. vtable: *const VTable,
  1315. IInspectable: IInspectable,
  1316. IUnknown: IUnknown,
  1317. pub const VTable = extern struct {
  1318. base: IInspectable.VTable,
  1319. CreateAsync: *const fn (*This, [*c][*c]IAsyncOperation(IMidiSynthesizer)) callconv(.C) HRESULT,
  1320. CreateFromAudioDeviceAsync: *const fn (*This, [*c]Devices.Enumeration.IDeviceInformation, [*c][*c]IAsyncOperation(IMidiSynthesizer)) callconv(.C) HRESULT,
  1321. IsSynthesizer: *const fn (*This, [*c]Devices.Enumeration.IDeviceInformation, [*c]boolean) callconv(.C) HRESULT,
  1322. };
  1323. };
  1324. pub const IMidiSystemExclusiveMessageFactory = extern union {
  1325. const IID_Value = Guid_parse("083DE222-3B74-4320-9B42-0CA8545F8A24");
  1326. pub const IID = &IID_Value;
  1327. const This = @This();
  1328. vtable: *const VTable,
  1329. IInspectable: IInspectable,
  1330. IUnknown: IUnknown,
  1331. pub const VTable = extern struct {
  1332. base: IInspectable.VTable,
  1333. CreateMidiSystemExclusiveMessage: *const fn (*This, [*c]Storage.Streams.IBuffer, [*c][*c]IMidiMessage) callconv(.C) HRESULT,
  1334. };
  1335. };
  1336. pub const IMidiTimeCodeMessage = extern union {
  1337. const IID_Value = Guid_parse("0BF7087D-FA63-4A1C-8DEB-C0E87796A6D7");
  1338. pub const IID = &IID_Value;
  1339. const This = @This();
  1340. vtable: *const VTable,
  1341. IInspectable: IInspectable,
  1342. IUnknown: IUnknown,
  1343. pub const VTable = extern struct {
  1344. base: IInspectable.VTable,
  1345. get_FrameType: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1346. get_Values: *const fn (*This, [*c]BYTE) callconv(.C) HRESULT,
  1347. };
  1348. };
  1349. pub const IMidiTimeCodeMessageFactory = extern union {
  1350. const IID_Value = Guid_parse("EB3099C5-771C-40DE-B961-175A7489A85E");
  1351. pub const IID = &IID_Value;
  1352. const This = @This();
  1353. vtable: *const VTable,
  1354. IInspectable: IInspectable,
  1355. IUnknown: IUnknown,
  1356. pub const VTable = extern struct {
  1357. base: IInspectable.VTable,
  1358. CreateMidiTimeCodeMessage: *const fn (*This, BYTE, BYTE, [*c][*c]IMidiTimeCodeMessage) callconv(.C) HRESULT,
  1359. };
  1360. };
  1361. };
  1362. };
  1363.  
  1364. const Storage = struct {
  1365. const Streams = struct {
  1366. pub const IRandomAccessStreamWithContentType = extern union {
  1367. const This = @This();
  1368. vtable: *const VTable,
  1369. IInspectable: IInspectable,
  1370. IUnknown: IUnknown,
  1371. pub const VTable = extern struct {
  1372. base: IInspectable.VTable,
  1373. };
  1374. };
  1375.  
  1376. pub const IBuffer = extern union {
  1377. const This = @This();
  1378. vtable: *const VTable,
  1379. IInspectable: IInspectable,
  1380. IUnknown: IUnknown,
  1381. pub const VTable = extern struct {
  1382. base: IInspectable.VTable,
  1383. get_Capacity: *const fn (*This, [*c]UINT32) callconv(.C) HRESULT,
  1384. get_Length: *const fn (*This, [*c]UINT32) callconv(.C) HRESULT,
  1385. put_Length: *const fn (*This, UINT32) callconv(.C) HRESULT,
  1386. };
  1387. };
  1388.  
  1389. pub const IBufferFactory = extern union {
  1390. const This = @This();
  1391. vtable: *const VTable,
  1392. IInspectable: IInspectable,
  1393. IUnknown: IUnknown,
  1394. pub const VTable = extern struct {
  1395. base: IInspectable.VTable,
  1396. Create: *const fn (*This, UINT32, [*c][*c]IBuffer) callconv(.C) HRESULT,
  1397. };
  1398. };
  1399.  
  1400. pub const IBufferStatics = extern union {
  1401. const This = @This();
  1402. vtable: *const VTable,
  1403. IInspectable: IInspectable,
  1404. IUnknown: IUnknown,
  1405. pub const VTable = extern struct {
  1406. base: IInspectable.VTable,
  1407. CreateCopyFromMemoryBuffer: *const fn (*This, [*c]Foundation.IMemoryBuffer, [*c][*c]IBuffer) callconv(.C) HRESULT,
  1408. CreateMemoryBufferOverIBuffer: *const fn (*This, [*c]IBuffer, [*c][*c]Foundation.IMemoryBuffer) callconv(.C) HRESULT,
  1409. };
  1410. };
  1411. pub const IInputStream = opaque {};
  1412. pub const IOutputStream = opaque {};
  1413. pub const IRandomAccessStream = extern union {
  1414. const This = @This();
  1415. vtable: *const VTable,
  1416. IInspectable: IInspectable,
  1417. IUnknown: IUnknown,
  1418. pub const VTable = extern struct {
  1419. base: IInspectable.VTable,
  1420. get_Size: *const fn (*This, [*c]UINT64) callconv(.C) HRESULT,
  1421. put_Size: *const fn (*This, UINT64) callconv(.C) HRESULT,
  1422. GetInputStreamAt: *const fn (*This, UINT64, [*c]?*IInputStream) callconv(.C) HRESULT,
  1423. GetOutputStreamAt: *const fn (*This, UINT64, [*c]?*IOutputStream) callconv(.C) HRESULT,
  1424. get_Position: *const fn (*This, [*c]UINT64) callconv(.C) HRESULT,
  1425. Seek: *const fn (*This, UINT64) callconv(.C) HRESULT,
  1426. CloneStream: *const fn (*This, [*c][*c]IRandomAccessStream) callconv(.C) HRESULT,
  1427. get_CanRead: *const fn (*This, [*c]boolean) callconv(.C) HRESULT,
  1428. get_CanWrite: *const fn (*This, [*c]boolean) callconv(.C) HRESULT,
  1429. };
  1430. };
  1431. pub const RandomAccessStream = opaque {};
  1432. pub const Buffer = opaque {};
  1433. pub const RandomAccessStreamReference = opaque {};
  1434. pub const IContentTypeProvider = opaque {};
  1435. pub const IInputStreamReference = opaque {};
  1436. pub const IRandomAccessStreamReference = opaque {};
  1437. pub const IRandomAccessStreamReferenceStatics = opaque {};
  1438. pub const IRandomAccessStreamStatics = opaque {};
  1439. };
  1440. };
  1441. };
  1442.  
  1443. const Guid = windows.GUID;
  1444.  
  1445. fn Guid_parse(comptime s: []const u8) Guid {
  1446. return Guid.parseNoBraces(s) catch @compileError("Failed to parse as a GUID\n");
  1447. }
  1448.  
  1449. // pub fn format(value: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
  1450. // return writer.print("{X:0>8}-{X:0>4}-{X:0>4}-{X:0>2}{X:0>2}-{X:0>2}{X:0>2}{X:0>2}{X:0>2}{X:0>2}{X:0>2}", .{
  1451. // value.Ints.a,
  1452. // value.Ints.b,
  1453. // value.Ints.c,
  1454. // value.Ints.d[0],
  1455. // value.Ints.d[1],
  1456. // value.Ints.d[2],
  1457. // value.Ints.d[3],
  1458. // value.Ints.d[4],
  1459. // value.Ints.d[5],
  1460. // value.Ints.d[6],
  1461. // value.Ints.d[7],
  1462. // });
  1463. // }
  1464. //};
  1465.  
  1466. pub const Library = struct {
  1467. pub extern fn CoInitialize(pvReserved: LPVOID) HRESULT;
  1468. pub extern fn CoUninitialize() void;
  1469. pub extern fn CoTaskMemFree(pv: LPVOID) void;
  1470.  
  1471. pub fn load() !void {
  1472. winrt_lib = try std.DynLib.open("api-ms-win-core-winrt-l1-1-0");
  1473.  
  1474. if (winrt_lib) |*lib| {
  1475. // zig fmt: off
  1476. winrt_procs = .{
  1477. .RoInitialize = lib.lookup(@TypeOf(Library.winrt_procs.?.RoInitialize), "RoInitialize") orelse return error.Unknown,
  1478. .RoUninitialize = lib.lookup(@TypeOf(Library.winrt_procs.?.RoUninitialize), "RoUninitialize") orelse return error.Unknown,
  1479. .RoActivateInstance = lib.lookup(@TypeOf(Library.winrt_procs.?.RoActivateInstance), "RoActivateInstance") orelse return error.Unknown,
  1480. .RoGetActivationFactory = lib.lookup(@TypeOf(Library.winrt_procs.?.RoGetActivationFactory), "RoGetActivationFactory") orelse return error.Unknown,
  1481. .WindowsCreateStringReference = lib.lookup(@TypeOf(Library.winrt_procs.?.WindowsCreateStringReference), "WindowsCreateStringReference") orelse return error.Unknown,
  1482. .WindowsGetStringRawBuffer = lib.lookup(@TypeOf(Library.winrt_procs.?.WindowsGetStringRawBuffer), "WindowsGetStringRawBuffer") orelse return error.Unknown,
  1483. .WindowsDuplicateString = lib.lookup(@TypeOf(Library.winrt_procs.?.WindowsDuplicateString), "WindowsDuplicateString") orelse return error.Unknown,
  1484. .WindowsDeleteString = lib.lookup(@TypeOf(Library.winrt_procs.?.WindowsDeleteString), "WindowsDeleteString") orelse return error.Unknown,
  1485. };
  1486. // zig fmt: on
  1487. }
  1488. }
  1489.  
  1490. pub fn close() void {
  1491. if (winrt_lib != null) {
  1492. winrt_lib.?.close();
  1493. winrt_lib = null;
  1494. }
  1495. }
  1496. pub fn initializeCom() !void {
  1497. const hr = Library.winrt_procs.?.RoInitialize(.MULTITHREADED);
  1498. if (hr < 0) {
  1499. return error.Unknown;
  1500. }
  1501. }
  1502. const RO_INIT_TYPE = enum(i32) {
  1503. SINGLETHREADED = 0,
  1504. MULTITHREADED = 1,
  1505. };
  1506.  
  1507. const WinRT_Procs = struct {
  1508. RoInitialize: *fn (
  1509. initType: RO_INIT_TYPE,
  1510. ) callconv(@import("std").os.windows.WINAPI) HRESULT,
  1511.  
  1512. RoUninitialize: *fn () callconv(@import("std").os.windows.WINAPI) void,
  1513.  
  1514. RoActivateInstance: *fn (
  1515. activatableClassId: ?HSTRING,
  1516. instance: ?*?*IInspectable,
  1517. ) callconv(@import("std").os.windows.WINAPI) HRESULT,
  1518.  
  1519. RoGetActivationFactory: *fn (
  1520. activatableClassId: ?HSTRING,
  1521. iid: ?*const Guid,
  1522. factory: ?*?*anyopaque,
  1523. ) callconv(@import("std").os.windows.WINAPI) HRESULT,
  1524.  
  1525. WindowsCreateStringReference: *fn (
  1526. sourceString: ?[*:0]const u16,
  1527. length: u32,
  1528. hstringHeader: ?*HSTRING_HEADER,
  1529. string: ?*?HSTRING,
  1530. ) callconv(@import("std").os.windows.WINAPI) HRESULT,
  1531.  
  1532. WindowsGetStringRawBuffer: *fn (
  1533. string: ?HSTRING,
  1534. length: ?*u32,
  1535. ) callconv(@import("std").os.windows.WINAPI) ?[*:0]u16,
  1536.  
  1537. WindowsDuplicateString: *fn (
  1538. string: HSTRING,
  1539. newString: ?*HSTRING,
  1540. ) callconv(@import("std").os.windows.WINAPI) HRESULT,
  1541.  
  1542. WindowsDeleteString: *fn (
  1543. string: HSTRING,
  1544. ) callconv(@import("std").os.windows.WINAPI) HRESULT,
  1545. };
  1546.  
  1547. var winrt_procs: ?WinRT_Procs = null;
  1548. var winrt_lib: ?std.DynLib = null;
  1549. };
  1550.  
  1551. //DD9F8A5D-EC98-5F4B-A3EA-9C8B5AD53C4B = IIterable<DeviceInformation*>
  1552. //00000037-0000-0000-C000-000000000046 = IWeakReference
  1553. //E170688F-3495-5BF6-AAB5-9CAC17E0F10F = IVectorView<DeviceInformation*>
  1554. const weak_ref_source_guid = Guid_parse("00000038-0000-0000-C000-000000000046"); // = IWeakReferenceSource
  1555.  
  1556. const Helpers = struct {
  1557. pub fn string_ref(comptime str: [:0]const u8) !struct { HSTRING_HEADER, HSTRING } {
  1558. const L = std.unicode.utf8ToUtf16LeStringLiteral;
  1559. const wstr = L(str);
  1560. var hstr: ?HSTRING = undefined;
  1561. var header: HSTRING_HEADER = undefined;
  1562. const hr = Library.winrt_procs.?.WindowsCreateStringReference(wstr, wstr.len, &header, &hstr);
  1563. if (hr != 0) {
  1564. return error.OutOfMemory;
  1565. }
  1566. return .{
  1567. header,
  1568. hstr orelse null_panic(),
  1569. };
  1570. }
  1571.  
  1572. fn hstring_to_utf8_alloc(allocator: std.mem.Allocator, string: HSTRING) ![:0]u8 {
  1573. var len: u32 = undefined;
  1574. const raw = Library.winrt_procs.?.WindowsGetStringRawBuffer(string, &len).?;
  1575. const utf8string = try std.unicode.utf16LeToUtf8AllocZ(allocator, raw[0..len]);
  1576. return utf8string;
  1577. }
  1578.  
  1579. pub fn get_statics(comptime static_type: type) !*static_type {
  1580. const class_name = static_type.Name;
  1581. _, const hstr = try string_ref(class_name);
  1582.  
  1583. var statics: *static_type = undefined;
  1584. const hr = Library.winrt_procs.?.RoGetActivationFactory(hstr, static_type.IID, @ptrCast(&statics));
  1585. if (hr != 0) return error.Unkown;
  1586. return statics;
  1587. }
  1588.  
  1589. pub fn print_iids(object: anytype) void {
  1590. const count, const iids = blk: {
  1591. var count: ULONG = undefined;
  1592. var iids: [*]Guid = undefined;
  1593. const hr = object.IInspectable.GetIids(&count, &iids);
  1594. std.debug.assert(hr == 0);
  1595. break :blk .{ count, iids };
  1596. };
  1597. for (iids[0..count]) |iid| {
  1598. if (std.meta.eql(iid.Ints, weak_ref_source_guid.Ints)) continue;
  1599. const interface = blk: {
  1600. var interface: ?*IInspectable = undefined;
  1601. const hr = object.IUnknown.QueryInterface(&iid, @ptrCast(&interface));
  1602. std.debug.assert(hr == 0); //call must succeed according to msdn
  1603. break :blk interface orelse null_panic();
  1604. };
  1605. defer interface.Release();
  1606. std.debug.print("{any}:\n ", .{iid});
  1607. print_class(interface) catch @panic("hmm");
  1608. }
  1609. Library.CallTaskMemFree(iids);
  1610. }
  1611.  
  1612. pub fn print_class(object: anytype) !void {
  1613. var class_name: HSTRING = undefined;
  1614. const hr = object.IInspectable.GetRuntimeClassName(&class_name);
  1615. std.debug.assert(hr == 0);
  1616. defer _ = Library.winrt_procs.?.WindowsDeleteString(class_name);
  1617. std.debug.print("{any}\n", .{class_name});
  1618. }
  1619.  
  1620. pub fn createEventHandler(comptime Handler: type, comptime Callback: type, comptime CallbackArg: type) type {
  1621. return struct {
  1622. const Self = @This();
  1623. pub fn init(user_arg: *CallbackArg) Self {
  1624. return .{
  1625. .com = .{
  1626. .TypedEventHandler = .{
  1627. .vtable = &.{
  1628. .base = .{
  1629. .QueryInterface = Self.QueryInterface,
  1630. .AddRef = Self.AddRef,
  1631. .Release = Self.Release,
  1632. },
  1633. .Invoke = Self.Invoke,
  1634. },
  1635. },
  1636. },
  1637. .ref = 1,
  1638. .user_arg = user_arg,
  1639. };
  1640. }
  1641.  
  1642. fn getThisFromEventHandler(this_event_handler: *const TypedEventHandler(Handler.Caller, Handler.Arg)) *@This() {
  1643. const com_ptr: *Com = @fieldParentPtr("TypedEventHandler", @constCast(this_event_handler));
  1644. return @fieldParentPtr("com", com_ptr);
  1645. }
  1646.  
  1647. fn getThisFromUnknown(this_unknown: *const IUnknown) *@This() {
  1648. const com_ptr: *Com = @fieldParentPtr("IUnknown", @constCast(this_unknown));
  1649. return @fieldParentPtr("com", com_ptr);
  1650. }
  1651.  
  1652. pub fn QueryInterface(this_unknown: *const IUnknown, guid: *const Guid, out_interface: *?*anyopaque) callconv(.C) HRESULT {
  1653. const this = getThisFromUnknown(this_unknown);
  1654. if (std.meta.eql(guid.*, IUnknown.IID.*) or
  1655. std.meta.eql(guid.*, agile_guid) or
  1656. std.meta.eql(guid.*, Handler.IID.*))
  1657. {
  1658. out_interface.* = this;
  1659. _ = AddRef(this_unknown);
  1660. return S_OK;
  1661. } else {
  1662. out_interface.* = null;
  1663. return E_NOINTERFACE;
  1664. }
  1665. }
  1666.  
  1667. pub fn AddRef(this_unknown: *const IUnknown) callconv(.C) ULONG {
  1668. const this = getThisFromUnknown(this_unknown);
  1669. this.ref += 1;
  1670. return this.ref;
  1671. }
  1672.  
  1673. pub fn Release(this_unknown: *const IUnknown) callconv(.C) ULONG {
  1674. const this = getThisFromUnknown(this_unknown);
  1675. this.ref -= 1;
  1676. if (this.ref == 0) {
  1677. //dont delete, i'm heap allocated
  1678. }
  1679. return this.ref;
  1680. }
  1681.  
  1682. pub fn Invoke(this_event_handler: *const TypedEventHandler(Handler.Caller, Handler.Arg), caller: *Handler.Caller, arg: *Handler.Arg) callconv(.C) HRESULT {
  1683. const this = getThisFromEventHandler(this_event_handler);
  1684. _ = caller;
  1685. Callback.invoke(arg, this.user_arg);
  1686. return S_OK;
  1687. }
  1688.  
  1689. const Com = extern union {
  1690. IUnknown: IUnknown,
  1691. TypedEventHandler: TypedEventHandler(Handler.Caller, Handler.Arg),
  1692. };
  1693.  
  1694. com: Com,
  1695. ref: u32,
  1696. user_arg: *CallbackArg,
  1697. };
  1698. }
  1699. test "Helpers" {
  1700. std.testing.refAllDeclsRecursive(@This());
  1701. }
  1702. };
  1703.  
  1704. //fn unknown_get_interface(comptime dest: type, object: *anyopaque) !*dest {
  1705. // var async_info: ?*dest = undefined;
  1706. //
  1707. // const hr = object.vtable.base.base.QueryInterface(@ptrCast(async_op), IAsyncInfo.IID, @ptrCast(&async_info));
  1708. // std.debug.assert(hr == 0);
  1709. // return async_info.?;
  1710. //}
  1711.  
  1712. const agile_guid = Guid_parse("94EA2B94-E9CC-49E0-C0FF-EE64CA8F5B90");
  1713. const no_marshall_guid = Guid_parse("ECC8691B-C1DB-4DC0-855E-65F6C551AF49");
  1714. const marshall_guid = Guid_parse("00000003-0000-0000-C000-000000000046");
  1715.  
  1716. const MidiInEventHandler = struct {
  1717. pub fn init(callback_arg: *anyopaque, user_callback: *const fn (midi.Message, *anyopaque) void, allocator: *const std.mem.Allocator) @This() {
  1718. return .{
  1719. .com = .{
  1720. .EventHandler = .{
  1721. .vtable = &.{
  1722. .base = .{
  1723. .QueryInterface = MidiInEventHandler.QueryInterface,
  1724. .AddRef = MidiInEventHandler.AddRef,
  1725. .Release = MidiInEventHandler.Release,
  1726. },
  1727. .Invoke = MidiInEventHandler.Invoke,
  1728. },
  1729. },
  1730. },
  1731. .ref = 1,
  1732. .allocator = allocator,
  1733. .callback_arg = callback_arg,
  1734. .user_callback = user_callback,
  1735. };
  1736. }
  1737.  
  1738. fn getThisFromEventHandler(this_event_handler: *Windows.Devices.Midi.IMidiInPort.EventHandler) *@This() {
  1739. const com_ptr: *Com = @fieldParentPtr("EventHandler", @constCast(this_event_handler));
  1740. return @fieldParentPtr("com", com_ptr);
  1741. }
  1742.  
  1743. fn getThisFromUnknown(this_unknown: *const IUnknown) *@This() {
  1744. const com_ptr: *Com = @fieldParentPtr("IUnknown", @constCast(this_unknown));
  1745. return @fieldParentPtr("com", com_ptr);
  1746. }
  1747.  
  1748. pub fn QueryInterface(this_unknown: *const IUnknown, guid: *const Guid, out_interface: *?*anyopaque) callconv(.C) HRESULT {
  1749. const this = getThisFromUnknown(this_unknown);
  1750. std.debug.print("query: {}\n", .{std.Thread.getCurrentId()});
  1751. //std.debug.print("query: {any}\n", .{guid.*});
  1752. if (std.meta.eql(guid.*, IUnknown.IID.*) or
  1753. std.meta.eql(guid.*, Windows.Devices.Midi.IMidiInPort.EventHandler_IID.*) or
  1754. std.meta.eql(guid.*, agile_guid))
  1755. {
  1756. out_interface.* = this;
  1757. _ = AddRef(this_unknown);
  1758. return S_OK;
  1759. } else {
  1760. out_interface.* = null;
  1761. return E_NOINTERFACE;
  1762. }
  1763. }
  1764.  
  1765. pub fn AddRef(this_unknown: *const IUnknown) callconv(.C) ULONG {
  1766. const this = getThisFromUnknown(this_unknown);
  1767. this.ref += 1;
  1768. return this.ref;
  1769. }
  1770.  
  1771. pub fn Release(this_unknown: *const IUnknown) callconv(.C) ULONG {
  1772. const this = getThisFromUnknown(this_unknown);
  1773. this.ref -= 1;
  1774. if (this.ref == 0) {
  1775. this.allocator.destroy(this);
  1776. return 0;
  1777. }
  1778. return this.ref;
  1779. }
  1780.  
  1781. pub fn Invoke(this_event_handler: *Windows.Devices.Midi.IMidiInPort.EventHandler, port: *Windows.Devices.Midi.IMidiInPort, args: *Windows.Devices.Midi.IMidiMessageReceivedEventArgs) callconv(.C) HRESULT {
  1782. _ = port;
  1783. const this = getThisFromEventHandler(this_event_handler);
  1784. const message = tryGet(?*Windows.Devices.Midi.IMidiMessage, args, "get_Message") catch @panic("") orelse null_panic();
  1785. defer _ = message.IUnknown.Release();
  1786.  
  1787. const message_type = tryGet(Windows.Devices.Midi.MidiMessageType, message, "get_Type") catch @panic("");
  1788.  
  1789. switch (message_type) {
  1790. .NoteOn => {
  1791. const note_on = message.IUnknown.TryQuery(Windows.Devices.Midi.IMidiNoteOnMessage) orelse @panic("sould have worked");
  1792. defer _ = note_on.IUnknown.Release();
  1793.  
  1794. const channel = tryGet(BYTE, note_on, "get_Channel") catch @panic("");
  1795. const note = tryGet(BYTE, note_on, "get_Note") catch @panic("");
  1796. const velocity = tryGet(BYTE, note_on, "get_Velocity") catch @panic("");
  1797.  
  1798. this.user_callback(.{ .Note_On = .{ .channel = @intCast(channel), .note = note, .velocity = velocity } }, this.callback_arg);
  1799. },
  1800. .NoteOff => {
  1801. const note_off = message.IUnknown.TryQuery(Windows.Devices.Midi.IMidiNoteOffMessage) orelse @panic("sould have worked");
  1802. defer _ = note_off.IUnknown.Release();
  1803.  
  1804. const channel = tryGet(BYTE, note_off, "get_Channel") catch @panic("");
  1805. const note = tryGet(BYTE, note_off, "get_Note") catch @panic("");
  1806. const velocity = tryGet(BYTE, note_off, "get_Velocity") catch @panic("");
  1807.  
  1808. this.user_callback(.{ .Note_Off = .{ .channel = @intCast(channel), .note = note, .velocity = velocity } }, this.callback_arg);
  1809. },
  1810. .ControlChange => {
  1811. const cc = message.IUnknown.TryQuery(Windows.Devices.Midi.IMidiControlChangeMessage) orelse @panic("sould have worked");
  1812. defer _ = cc.IUnknown.Release();
  1813.  
  1814. const channel = tryGet(BYTE, cc, "get_Channel") catch @panic("");
  1815. const controller = tryGet(BYTE, cc, "get_Controller") catch @panic("");
  1816. const value = tryGet(BYTE, cc, "get_ControlValue") catch @panic("");
  1817.  
  1818. this.user_callback(.{ .CC = .{ .channel = @intCast(channel), .id = controller, .value = value } }, this.callback_arg);
  1819. },
  1820. else => {},
  1821. }
  1822.  
  1823. return S_OK;
  1824. }
  1825.  
  1826. const Com = extern union {
  1827. IUnknown: IUnknown,
  1828. EventHandler: Windows.Devices.Midi.IMidiInPort.EventHandler,
  1829. };
  1830.  
  1831. com: Com,
  1832. ref: u32,
  1833. allocator: *const std.mem.Allocator,
  1834. callback_arg: *anyopaque,
  1835. user_callback: *const fn (midi.Message, *anyopaque) void,
  1836. };
  1837.  
  1838. pub const Context = struct {
  1839. const WinMidi = Windows.Devices.Midi;
  1840. const Enumeration = Windows.Devices.Enumeration;
  1841. const This = @This();
  1842.  
  1843. const Watcher_Procs = struct {
  1844. const Added_ = struct {
  1845. pub fn invoke(arg: *Enumeration.IDeviceInformation, ctx: *This) void {
  1846. var device_name: HSTRING = undefined;
  1847. _ = arg.vtable.get_Name(arg, &device_name);
  1848. defer _ = Library.winrt_procs.?.WindowsDeleteString(device_name);
  1849.  
  1850. var id: HSTRING = undefined;
  1851. _ = arg.vtable.get_Id(arg, &id);
  1852. defer _ = Library.winrt_procs.?.WindowsDeleteString(id);
  1853.  
  1854. var copied_id: HSTRING = undefined;
  1855. _ = Library.winrt_procs.?.WindowsDuplicateString(id, &copied_id);
  1856. //errdefer _ = Library.winrt_procs.?.WindowsDeleteString(id);
  1857.  
  1858. std.debug.print("added: {any} {any}\n", .{ device_name, id });
  1859.  
  1860. const id_utf8 = Helpers.hstring_to_utf8_alloc(ctx.allocator, id) catch @panic("OOM");
  1861. defer ctx.allocator.free(id_utf8);
  1862. const id_hash: u64 = std.hash.Wyhash.hash(0, id_utf8);
  1863.  
  1864. if (ctx.devices.getPtr(id_hash)) |existing_device| {
  1865. switch (existing_device.state) {
  1866. .Closed, .Open => {
  1867. std.debug.print("Error: should be disconnected", .{});
  1868. },
  1869. .Disconnected => {
  1870. existing_device.state = .{ .Closed = void{} };
  1871. },
  1872. }
  1873. } else {
  1874. const device_name_utf8 = Helpers.hstring_to_utf8_alloc(ctx.allocator, device_name) catch @panic("OOM");
  1875. const new_device = InputDevice{
  1876. .descriptor = .{ .name = device_name_utf8, .hstring_id = copied_id, .id = id_hash },
  1877. .state = .{ .Closed = void{} },
  1878. };
  1879.  
  1880. ctx.devices.put(id_hash, new_device) catch @panic("OOM");
  1881. }
  1882. }
  1883. };
  1884.  
  1885. pub const Added = Helpers.createEventHandler(Enumeration.IDeviceWatcher.Added_EventHandler, Added_, This);
  1886.  
  1887. const Updated_ = struct {
  1888. pub fn invoke(arg: *Enumeration.IDeviceInformationUpdate, ctx: *This) void {
  1889. _ = ctx;
  1890. var id: HSTRING = undefined;
  1891. _ = arg.vtable.get_Id(arg, &id);
  1892. defer _ = Library.winrt_procs.?.WindowsDeleteString(id);
  1893. std.debug.print("updated: {any}\n", .{id});
  1894. }
  1895. };
  1896.  
  1897. pub const Updated = Helpers.createEventHandler(Enumeration.IDeviceWatcher.Updated_EventHandler, Updated_, This);
  1898.  
  1899. const Removed_ = struct {
  1900. pub fn invoke(arg: *Enumeration.IDeviceInformationUpdate, ctx: *This) void {
  1901. var id: HSTRING = undefined;
  1902. _ = arg.vtable.get_Id(arg, &id);
  1903. defer _ = Library.winrt_procs.?.WindowsDeleteString(id);
  1904. const id_utf8 = Helpers.hstring_to_utf8_alloc(ctx.allocator, id) catch @panic("OOM");
  1905. defer ctx.allocator.free(id_utf8);
  1906. const id_hash: u64 = std.hash.Wyhash.hash(0, id_utf8);
  1907.  
  1908. if (ctx.devices.getPtr(id_hash)) |existing_device| {
  1909. switch (existing_device.state) {
  1910. .Closed => {
  1911. existing_device.state = .{ .Disconnected = void{} };
  1912. },
  1913. .Open => |*port| {
  1914. _ = port.midi_in_port.vtable.remove_MessageReceived(port.midi_in_port, port.message_received_event_token);
  1915. _ = port.message_received_event_handler.com.IUnknown.Release();
  1916. existing_device.state = .{ .Disconnected = void{} };
  1917. std.debug.print("TODO: notify of the closing", .{});
  1918. },
  1919. .Disconnected => {
  1920. std.debug.print("weird, it was supposed to already be disconnected\n", .{});
  1921. },
  1922. }
  1923. } else {
  1924. std.debug.print("Error: a device was removed but was not in the list", .{});
  1925. }
  1926. }
  1927. };
  1928. pub const Removed = Helpers.createEventHandler(Enumeration.IDeviceWatcher.Removed_EventHandler, Removed_, This);
  1929.  
  1930. const EnumerationCompleted_ = struct {
  1931. pub fn invoke(arg: *IInspectable, ctx: *This) void {
  1932. _ = ctx;
  1933. _ = arg;
  1934. std.debug.print("enumeration_completed\n", .{});
  1935. }
  1936. };
  1937. const EnumerationCompleted = Helpers.createEventHandler(Enumeration.IDeviceWatcher.EnumerationCompleted_Handler, EnumerationCompleted_, This);
  1938.  
  1939. const Stopped_ = struct {
  1940. pub fn invoke(arg: *IInspectable, ctx: *This) void {
  1941. _ = ctx;
  1942. _ = arg;
  1943. std.debug.print("Stopped\n", .{});
  1944. }
  1945. };
  1946. const Stopped = Helpers.createEventHandler(Enumeration.IDeviceWatcher.Stopped_Handler, Stopped_, This);
  1947. };
  1948. const Device_Map = std.AutoArrayHashMap(u64, InputDevice);
  1949.  
  1950. allocator: std.mem.Allocator,
  1951. options: midi.Context.Options,
  1952.  
  1953. midi_in_port_statics: *WinMidi.IMidiInPortStatics,
  1954. device_info_statics: *Enumeration.IDeviceInformationStatics,
  1955. watcher: *Enumeration.IDeviceWatcher,
  1956.  
  1957. devices: Device_Map,
  1958.  
  1959. added_handler: Watcher_Procs.Added,
  1960. added_token: EventRegistrationToken,
  1961. updated_handler: Watcher_Procs.Updated,
  1962. updated_token: EventRegistrationToken,
  1963. removed_handler: Watcher_Procs.Removed,
  1964. removed_token: EventRegistrationToken,
  1965. enumeration_completed_handler: Watcher_Procs.EnumerationCompleted,
  1966. enumeration_completed_token: EventRegistrationToken,
  1967. stopped_handler: Watcher_Procs.Stopped,
  1968. stopped_token: EventRegistrationToken,
  1969.  
  1970. pub fn init(allocator: std.mem.Allocator, options: midi.Context.Options) !*Context {
  1971. var ctx: *Context = try allocator.create(Context);
  1972. errdefer allocator.destroy(ctx);
  1973.  
  1974. ctx.devices = Device_Map.init(allocator);
  1975.  
  1976. ctx.allocator = allocator;
  1977. ctx.options = options;
  1978. ctx.midi_in_port_statics = try Helpers.get_statics(WinMidi.IMidiInPortStatics);
  1979. errdefer _ = ctx.midi_in_port_statics.IUnknown.Release();
  1980.  
  1981. const midi_in_selector = tryGet(HSTRING, ctx.midi_in_port_statics, "GetDeviceSelector") catch @panic("");
  1982. defer _ = Library.winrt_procs.?.WindowsDeleteString(midi_in_selector);
  1983.  
  1984. ctx.device_info_statics = try Helpers.get_statics(Enumeration.IDeviceInformationStatics);
  1985. errdefer _ = ctx.device_info_statics.IUnknown.Release();
  1986.  
  1987. ctx.watcher = blk: {
  1988. var w: ?*Enumeration.IDeviceWatcher = undefined;
  1989. const h = ctx.device_info_statics.vtable.CreateWatcherAqsFilter(ctx.device_info_statics, midi_in_selector, &w);
  1990. try Success(h);
  1991. break :blk w orelse null_panic();
  1992. };
  1993. errdefer _ = ctx.watcher.IUnknown.Release();
  1994.  
  1995. ctx.added_handler = Watcher_Procs.Added.init(ctx);
  1996. var hr = ctx.watcher.vtable.add_Added(ctx.watcher, @ptrCast(&ctx.added_handler), &ctx.added_token);
  1997. try Success(hr);
  1998. errdefer _ = ctx.added_handler.com.IUnknown.Release();
  1999.  
  2000. ctx.updated_handler = Watcher_Procs.Updated.init(ctx);
  2001. hr = ctx.watcher.vtable.add_Updated(ctx.watcher, @ptrCast(&ctx.updated_handler), &ctx.updated_token);
  2002. try Success(hr);
  2003. errdefer _ = ctx.updated_handler.com.IUnknown.Release();
  2004.  
  2005. ctx.removed_handler = Watcher_Procs.Removed.init(ctx);
  2006. hr = ctx.watcher.vtable.add_Removed(ctx.watcher, @ptrCast(&ctx.removed_handler), &ctx.removed_token);
  2007. try Success(hr);
  2008. errdefer _ = ctx.removed_handler.com.IUnknown.Release();
  2009.  
  2010. ctx.enumeration_completed_handler = Watcher_Procs.EnumerationCompleted.init(ctx);
  2011. hr = ctx.watcher.vtable.add_EnumerationCompleted(ctx.watcher, @ptrCast(&ctx.enumeration_completed_handler), &ctx.enumeration_completed_token);
  2012. try Success(hr);
  2013. errdefer _ = ctx.enumeration_completed_handler.com.IUnknown.Release();
  2014.  
  2015. ctx.stopped_handler = Watcher_Procs.Stopped.init(ctx);
  2016. hr = ctx.watcher.vtable.add_Stopped(ctx.watcher, @ptrCast(&ctx.stopped_handler), &ctx.stopped_token);
  2017. try Success(hr);
  2018. errdefer _ = ctx.stopped_handler.com.IUnknown.Release();
  2019.  
  2020. hr = ctx.watcher.vtable.Start(ctx.watcher);
  2021. try Success(hr);
  2022. return ctx;
  2023. }
  2024.  
  2025. pub fn deinit(ctx: *Context) void {
  2026. _ = ctx.watcher.vtable.remove_Added(ctx.watcher, ctx.added_token);
  2027. _ = ctx.watcher.vtable.remove_Updated(ctx.watcher, ctx.updated_token);
  2028. _ = ctx.watcher.vtable.remove_Removed(ctx.watcher, ctx.removed_token);
  2029. _ = ctx.watcher.vtable.remove_EnumerationCompleted(ctx.watcher, ctx.enumeration_completed_token);
  2030. _ = ctx.watcher.vtable.remove_Stopped(ctx.watcher, ctx.stopped_token);
  2031. _ = ctx.watcher.vtable.Stop(ctx.watcher);
  2032.  
  2033. std.debug.assert(ctx.added_handler.ref == 1);
  2034. std.debug.assert(ctx.removed_handler.ref == 1);
  2035. std.debug.assert(ctx.updated_handler.ref == 1);
  2036. std.debug.assert(ctx.enumeration_completed_handler.ref == 1);
  2037. std.debug.assert(ctx.stopped_handler.ref == 1);
  2038. std.debug.assert(ctx.stopped_handler.ref == 1);
  2039.  
  2040. const watcher_ref = ctx.watcher.IUnknown.Release();
  2041. std.debug.assert(watcher_ref == 0);
  2042.  
  2043. for (ctx.devices.values()) |*device| {
  2044. if (@as(InputDeviceState, device.state) == .Open) {
  2045. ctx.closeDevice(device.descriptor.id);
  2046. }
  2047. ctx.allocator.free(device.descriptor.name);
  2048. _ = Library.winrt_procs.?.WindowsDeleteString(device.descriptor.hstring_id);
  2049. }
  2050. //release statics
  2051. ctx.devices.deinit();
  2052. ctx.allocator.destroy(ctx);
  2053. }
  2054.  
  2055. pub fn refresh(ctx: *Context) !void {
  2056. _ = ctx;
  2057. }
  2058.  
  2059. pub fn getDeviceDescriptors(ctx: *Context, allocator: std.mem.Allocator) ![]const DeviceDescriptor {
  2060. const descriptors = try allocator.alloc(DeviceDescriptor, ctx.devices.count());
  2061. for (descriptors, ctx.devices.values()) |*descriptor, *input_device| {
  2062. descriptor.* = input_device.*.descriptor;
  2063. }
  2064. return descriptors;
  2065. }
  2066.  
  2067. const OpenDeviceOptions = struct {
  2068. user_callback: *const fn (midi.Message, *anyopaque) void,
  2069. callback_arg: *anyopaque,
  2070. };
  2071.  
  2072. //this shit should be async
  2073. pub fn openDevice(ctx: Context, device_id: DeviceId, options: OpenDeviceOptions) !void {
  2074. const device = ctx.devices.getPtr(device_id) orelse {
  2075. return error.Unknown;
  2076. };
  2077. switch (device.state) {
  2078. .Closed => {},
  2079. .Open => {
  2080. std.debug.print("Error: device is already open", .{});
  2081. return error.AlreadyOpen;
  2082. },
  2083. .Disconnected => {
  2084. std.debug.print("Error: device is disconncted", .{});
  2085. return error.Disconnected;
  2086. },
  2087. }
  2088.  
  2089. const create_port_op = ctx.midi_in_port_statics.fromIdAsync(device.descriptor.hstring_id) catch @panic("");
  2090. defer _ = create_port_op.IUnknown.Release();
  2091.  
  2092. const create_port_op_info = try create_port_op.getInfo();
  2093. defer _ = create_port_op_info.IUnknown.Release();
  2094.  
  2095. while (true) {
  2096. const async_status = try create_port_op_info.getStatus();
  2097. if (async_status != .Started) {
  2098. break;
  2099. }
  2100. std.time.sleep(100_000_000);
  2101. }
  2102.  
  2103. const midi_in_port = try create_port_op.getResults();
  2104. errdefer _ = midi_in_port.IUnknown.Release();
  2105.  
  2106. const midi_event_handler = try ctx.allocator.create(MidiInEventHandler);
  2107. midi_event_handler.* = MidiInEventHandler.init(options.callback_arg, options.user_callback, &ctx.allocator);
  2108.  
  2109. const token = blk: {
  2110. var t: EventRegistrationToken = undefined;
  2111. const h = midi_in_port.vtable.add_MessageReceived(midi_in_port, @ptrCast(midi_event_handler), &t);
  2112. try Success(h);
  2113. break :blk t;
  2114. };
  2115.  
  2116. device.state = .{ .Open = .{
  2117. .midi_in_port = midi_in_port,
  2118. .message_received_event_handler = midi_event_handler,
  2119. .message_received_event_token = token,
  2120. } };
  2121. }
  2122.  
  2123. pub fn closeDevice(ctx: Context, device_id: DeviceId) void {
  2124. if (ctx.devices.getPtr(device_id)) |device| {
  2125. switch (device.state) {
  2126. .Closed => {
  2127. std.debug.print("Error: device is already closed", .{});
  2128. },
  2129. .Open => |*port| {
  2130. _ = port.midi_in_port.vtable.remove_MessageReceived(port.midi_in_port, port.message_received_event_token);
  2131. _ = port.message_received_event_handler.com.IUnknown.Release();
  2132. device.state = .{ .Closed = void{} };
  2133. },
  2134. .Disconnected => {
  2135. std.debug.print("Error: device is disconncted", .{});
  2136. },
  2137. }
  2138. } else {
  2139. std.debug.print("Error: device does not exitst", .{});
  2140. }
  2141. }
  2142. };
  2143.  
  2144. pub const DeviceId = u64;
  2145.  
  2146. pub const DeviceDescriptor = struct {
  2147. name: [:0]const u8,
  2148. hstring_id: HSTRING,
  2149. id: DeviceId,
  2150. };
  2151.  
  2152. pub const InputDeviceState = enum {
  2153. Closed,
  2154. Open,
  2155. Disconnected,
  2156. };
  2157.  
  2158. pub const InputDevice = struct {
  2159. descriptor: DeviceDescriptor,
  2160. state: union(InputDeviceState) {
  2161. Closed: void,
  2162. Open: InputPort,
  2163. Disconnected: void,
  2164. },
  2165. };
  2166.  
  2167. pub const InputPort = struct {
  2168. midi_in_port: *Windows.Devices.Midi.IMidiInPort,
  2169. message_received_event_handler: *MidiInEventHandler,
  2170. message_received_event_token: EventRegistrationToken,
  2171. };
  2172.  
  2173. fn null_panic() noreturn {
  2174. @panic("winrt returned hr = 0 and this pointer is still null\n");
  2175. }
  2176.  
  2177. fn Success(hr: HRESULT) !void {
  2178. if (hr < 0) {
  2179. return error.Unknown;
  2180. }
  2181. }
  2182.  
  2183. fn tryGet(comptime out_type: type, source: anytype, comptime func_name: []const u8) !out_type {
  2184. var out: out_type = undefined;
  2185. const hr = @field(source.vtable, func_name)(source, &out);
  2186. try Success(hr);
  2187. return out;
  2188. }
  2189.  
  2190. test {
  2191. std.testing.refAllDeclsRecursive(@This());
  2192. }
  2193.  
Advertisement
Add Comment
Please, Sign In to add comment