Compare commits
20 commits
79154f71b1
...
59452c6cb1
Author | SHA1 | Date | |
---|---|---|---|
|
59452c6cb1 | ||
|
2b5fa35b29 | ||
|
39bb1f8750 | ||
|
a6a9b5be12 | ||
|
2bdbbafbb0 | ||
|
5a3dda7a10 | ||
|
c85b92b4cb | ||
|
543611983c | ||
|
658732ec4e | ||
|
d40bdb7415 | ||
|
0cc911f974 | ||
|
0c58b2b87a | ||
|
0a3c76e695 | ||
|
74a96391cf | ||
|
fb7d64c5ea | ||
|
c3db9da6d5 | ||
|
39f01efe7d | ||
|
0e2da1abc7 | ||
|
797ceec787 | ||
|
1a8c927f8b |
flake.lockflake.nixdefault.nixosu-wine.nixpackages.nix
home
pkgs
_sources
default.nixfirefox-addons
looking-glass.patchmatrix-appservice-discord
nix-plugins-overlay.nixosu-wine
audio-revert
mmdevapi
Makefile.inaudiovolume.cdevenum.cmain.cmmdevapi.hmmdevapi.specmmdevapi_classes.idlspatialaudio.c
tests
unixlib.hwinealsa.drv
winecoreaudio.drv
wineoss.drv
winepulse.drv
patches
0001-add-wine-unicode-again.patch0001-libs-libjpeg-Set-default-DCT-algorithm-to-fastest.patch0001-revert-staging-alt-tab.patch0001-server-Implement-thread-priorities-on-Linux.patch0002-midi-fixed-revert.patch0002-revert-mscvrt-ify-modules.patch0002-server-Fallback-to-RTKIT-for-thread-priorities.patch0003-server-Map-THREAD_PRIORITY_IDLE-to-SCHED_IDLE.patch0003-thread-characteristic-audio-priority-from-oglf-patchset.patch9989-misc-ps0126-devenum-Register-IEEE-float-for-Direct-Sound-defau.patch9989-misc-ps0171-server-Don-t-wait-for-low-level-hook-result-when-q.patch9999-diffs-8bpp-copy-support.patch9999-diffs-hide-wine-version.patch9999-diffs-use-clock_nanosleep-for-delay.patch9999-map-import-crash-fix.patchdisplay-cache-less-frequent-update.patchps0071-p0002-winex11.drv-Bypass-compositor-in-fullscreen-.patchps0128-HACK-Fix-osu-alt-tab-on-certain-window-managers.patchps0417-p0002-winex11.drv-Add-OpenGL-latency-reduction-cod.patchps0741-ntdll-Implement-NtFlushProcessWriteBuffers.patchrevert-x11-gnome-fix.patch
sources.nixsystem
devices
hardware
hosts
modules
566
flake.lock
566
flake.lock
|
@ -1,5 +1,38 @@
|
|||
{
|
||||
"nodes": {
|
||||
"agenix": {
|
||||
"inputs": {
|
||||
"darwin": [
|
||||
"nix-community-infra",
|
||||
"nix-darwin"
|
||||
],
|
||||
"home-manager": [
|
||||
"nix-community-infra",
|
||||
"empty"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"nix-community-infra",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718371084,
|
||||
"narHash": "sha256-abpBi61mg0g+lFFU0zY4C6oP6fBwPzbHPKBGw676xsA=",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"rev": "3a56735779db467538fb2e577eda28a9daacaca6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"blobs": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
@ -16,6 +49,57 @@
|
|||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"buildbot-nix": {
|
||||
"inputs": {
|
||||
"flake-parts": [
|
||||
"nix-community-infra",
|
||||
"flake-parts"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
],
|
||||
"treefmt-nix": [
|
||||
"nix-community-infra",
|
||||
"treefmt-nix"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719797756,
|
||||
"narHash": "sha256-TGZthxgxLdT8boadFm6+MK7HZlIxN1u1V+x3hu+Fd8I=",
|
||||
"owner": "nix-community",
|
||||
"repo": "buildbot-nix",
|
||||
"rev": "0b56574a5c823097771487d1bac952c3549fe9fb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "buildbot-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"comin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1714766748,
|
||||
"narHash": "sha256-//fP25eh1f9eA+0TEgWqusWjv9SuKh8rIF1ZJQNL1jo=",
|
||||
"owner": "nlewo",
|
||||
"repo": "comin",
|
||||
"rev": "d3658c452024824235de2355ac3e156b10c3eaaf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nlewo",
|
||||
"repo": "comin",
|
||||
"rev": "d3658c452024824235de2355ac3e156b10c3eaaf",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"coop-fd": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
|
@ -25,17 +109,16 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1715922722,
|
||||
"narHash": "sha256-OhV4fwcVNHpztKPML03mGmOFkYQnkctEr/ckOI8uKzc=",
|
||||
"lastModified": 1718936559,
|
||||
"narHash": "sha256-/wQ/mLp65bRgv42V8c86SKxr8jLLwinh3WVS0k93vq0=",
|
||||
"owner": "chayleaf",
|
||||
"repo": "coop-fd",
|
||||
"rev": "442f5d91bebffbf3e7c83723e9bcda87d0adee52",
|
||||
"rev": "d493b50550988a5a07421248102ebfdf68f4a046",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "chayleaf",
|
||||
"repo": "coop-fd",
|
||||
"rev": "442f5d91bebffbf3e7c83723e9bcda87d0adee52",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
|
@ -60,6 +143,42 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"disko": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719733833,
|
||||
"narHash": "sha256-6h2EqZU9bL9rHlXE+2LCBgnDImejzbS+4dYsNDDFlkY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "d185770ea261fb5cf81aa5ad1791b93a7834d12c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"empty": {
|
||||
"locked": {
|
||||
"lastModified": 1708697125,
|
||||
"narHash": "sha256-JeMK8G1oabQTSpqXhYaYtPRak4m6z1xxyRKf8CvHy14=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "empty",
|
||||
"rev": "23d743284b73ae69caf0cb7874edf05c0c631a1f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "empty",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
@ -93,6 +212,21 @@
|
|||
}
|
||||
},
|
||||
"flake-compat_3": {
|
||||
"locked": {
|
||||
"lastModified": 1717312683,
|
||||
"narHash": "sha256-FrlieJH50AuvagamEvWMIE6D2OAnERuDboFDYAED/dE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "flake-compat",
|
||||
"rev": "38fd3954cf65ce6faf3d0d45cd26059e059f07ea",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_4": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
|
@ -109,15 +243,36 @@
|
|||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719745305,
|
||||
"narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712014858,
|
||||
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||
"lastModified": 1717285511,
|
||||
"narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||
"rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -128,7 +283,25 @@
|
|||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
"systems": "systems_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
|
@ -183,33 +356,86 @@
|
|||
"mobile-nixos": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1702959560,
|
||||
"narHash": "sha256-3EmjKFKBypRGluGEY1oUMkQRBRDO5rZdzUXwTlRbUiY=",
|
||||
"owner": "chayleaf",
|
||||
"lastModified": 1720660935,
|
||||
"narHash": "sha256-GnDGoVaObUjnYdCHUSIYVE1anMElis+Pq+RY30LFlIk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "mobile-nixos",
|
||||
"rev": "55ec06035e85fcbda5caa6a73d045a9910fb16a2",
|
||||
"rev": "31704f8a55f5773c9b4e7adb7408a142d142e1f2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "chayleaf",
|
||||
"ref": "fix-op6-modem",
|
||||
"owner": "NixOS",
|
||||
"repo": "mobile-nixos",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-community-infra": {
|
||||
"inputs": {
|
||||
"agenix": "agenix",
|
||||
"buildbot-nix": "buildbot-nix",
|
||||
"comin": "comin",
|
||||
"disko": "disko",
|
||||
"empty": "empty",
|
||||
"flake-compat": "flake-compat_3",
|
||||
"flake-parts": "flake-parts",
|
||||
"nix-darwin": "nix-darwin",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-update": "nixpkgs-update",
|
||||
"nixpkgs-update-github-releases": "nixpkgs-update-github-releases",
|
||||
"nur-update": "nur-update",
|
||||
"sops-nix": "sops-nix",
|
||||
"srvos": "srvos",
|
||||
"systems": "systems",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719876004,
|
||||
"narHash": "sha256-YIGAUeEVgJ/Qpn+YUoyR9HjV6j01W+5vOKRYpqsx+gw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "infra",
|
||||
"rev": "766a23a468858d2413f12bec828860158abaadf1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "infra",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719128254,
|
||||
"narHash": "sha256-I7jMpq0CAOZA/i70+HDQO/ulLttyQu/K70cSESiMX7A=",
|
||||
"owner": "LnL7",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "50581970f37f06a4719001735828519925ef8310",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "LnL7",
|
||||
"repo": "nix-darwin",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-gaming": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"flake-parts": "flake-parts_2",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712452624,
|
||||
"narHash": "sha256-R35K+4krhK5B2fcV6W2HFe/uhXmP8YGTb35uZ+nDAxw=",
|
||||
"lastModified": 1717896375,
|
||||
"narHash": "sha256-qI8f1XSFo1X29+RSVmYo5hDAMKKULnpmIZbRl77u21A=",
|
||||
"owner": "fufexan",
|
||||
"repo": "nix-gaming",
|
||||
"rev": "06314bbf8fedd83c7253442994a2f0c81d47988e",
|
||||
"rev": "6ed58348c20bab127555a3645e832591d2611f0c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -225,11 +451,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712459390,
|
||||
"narHash": "sha256-e12bNDottaGoBgd0AdH/bQvk854xunlWAdZwr/oHO1c=",
|
||||
"lastModified": 1717919703,
|
||||
"narHash": "sha256-4i/c31+dnpv6KdUA3BhbMDS9Lvg/CDin78caYJlq0bY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-index-database",
|
||||
"rev": "4676d72d872459e1e3a248d049609f110c570e9a",
|
||||
"rev": "a157a81d0a4bc909b2b6666dd71909bcdc8cd0d6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -240,11 +466,11 @@
|
|||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1712760404,
|
||||
"narHash": "sha256-4zhaEW1nB+nGbCNMjOggWeY5nXs/H0Y71q0+h+jdxoU=",
|
||||
"lastModified": 1717828156,
|
||||
"narHash": "sha256-YvstO0lobf3JWQuAfZCLYRTROC2ZDEgtWeQtWbO49p4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "e1c4bac14beb8c409d0534382cf967171706b9d9",
|
||||
"rev": "057a7996d012f342a38a26261ee529cebb1755ef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -256,18 +482,18 @@
|
|||
"nixos-mailserver": {
|
||||
"inputs": {
|
||||
"blobs": "blobs",
|
||||
"flake-compat": "flake-compat_3",
|
||||
"flake-compat": "flake-compat_4",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710449465,
|
||||
"narHash": "sha256-2orO8nfplp6uQJBFqKkj1iyNMC6TysmwbWwbb4osTag=",
|
||||
"lastModified": 1717515088,
|
||||
"narHash": "sha256-nWOLpPA7+k7V1OjXTuxdsVd5jeeI0b13Di57wvnqkic=",
|
||||
"owner": "simple-nixos-mailserver",
|
||||
"repo": "nixos-mailserver",
|
||||
"rev": "79c8cfcd5873a85559da6201b116fb38b490d030",
|
||||
"rev": "0d51a32e4799d081f260eb4db37145f5f4ee7456",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@ -283,11 +509,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710972558,
|
||||
"narHash": "sha256-fA72ql4T4/KgSNxZwZJ1EoEHXjmwt7I/OukHC8NVVF0=",
|
||||
"lastModified": 1720913908,
|
||||
"narHash": "sha256-AZ0AcL1ze6gS8EmwRpuR04MXCLb/NDLjp9n+Gs4IhFQ=",
|
||||
"owner": "chayleaf",
|
||||
"repo": "nixos-router",
|
||||
"rev": "061cf097417ed363b1e23d11daa7192e4b5f1994",
|
||||
"rev": "38088dc1745350db709e9f2cf777979b5217f671",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -298,33 +524,119 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1717670519,
|
||||
"narHash": "sha256-4p8B6Iv55BUG+d4ZJRUBhx70yWnqYlJ2EGSxx3dk4nc=",
|
||||
"owner": "chayleaf",
|
||||
"lastModified": 1719824438,
|
||||
"narHash": "sha256-pY0wosAgcr9W4vmGML0T3BVhQiGuKoozCbs2t+Je1zc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "411826c44e54583b30f767d76489e37dabf1707c",
|
||||
"rev": "7f993cdf26ccef564eabf31fdb40d140821e12bc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "chayleaf",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-kernel": {
|
||||
"locked": {
|
||||
"lastModified": 1717974879,
|
||||
"narHash": "sha256-GTO3C88+5DX171F/gVS3Qga/hOs/eRMxPFpiHq2t+D8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c7b821ba2e1e635ba5a76d299af62821cbcb09f3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1711703276,
|
||||
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
|
||||
"lastModified": 1717284937,
|
||||
"narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
|
||||
}
|
||||
},
|
||||
"nixpkgs-update": {
|
||||
"inputs": {
|
||||
"mmdoc": [
|
||||
"nix-community-infra",
|
||||
"empty"
|
||||
],
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"runtimeDeps": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
],
|
||||
"treefmt-nix": [
|
||||
"nix-community-infra",
|
||||
"treefmt-nix"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719362107,
|
||||
"narHash": "sha256-Vrd+Y3odIIXjlUwSDOjyrhf6V4svB5njtGH9i0NJIxc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs-update",
|
||||
"rev": "d49fec1752e0bcb69f156a86ba5b93e14aaca2c3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"dir": "lib",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs-update",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-update-github-releases": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1713252683,
|
||||
"narHash": "sha256-/hWsx6qCMHIRgdGkEIHaI40eVUg5gQGxpfp6GG7moSU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs-update-github-releases",
|
||||
"rev": "e1a72b5848a3a08168917dee85a6b4b64eca6b24",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs-update-github-releases",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1672428209,
|
||||
"narHash": "sha256-eejhqkDz2cb2vc5VeaWphJz8UXNuoNoM8/Op8eWv2tQ=",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1720888318,
|
||||
"narHash": "sha256-s5Pf3Es1reWTvHiz0YNuVknH/0RGo2vu+8MyeKT7VWo=",
|
||||
"owner": "chayleaf",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "81b52fd15be6a3331668cc7bbaab4aec7c654472",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "chayleaf",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -336,11 +648,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1697413333,
|
||||
"narHash": "sha256-2nmu/+QhR/VhxFFr54l0Ok/yVhLCrrYVuTgeD4LHEhE=",
|
||||
"lastModified": 1718058511,
|
||||
"narHash": "sha256-OjkGD9v9hfgIkToZXoXFzvBlXQg5Dp4+dmpZUATGYdA=",
|
||||
"owner": "chayleaf",
|
||||
"repo": "notlua",
|
||||
"rev": "ef7cdb7a883fe87238c9fff13bc14ad1fd06f4ba",
|
||||
"rev": "a8e09538d284f35aad88e1adc9c044f4163eadf8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -371,11 +683,11 @@
|
|||
},
|
||||
"nur": {
|
||||
"locked": {
|
||||
"lastModified": 1712785619,
|
||||
"narHash": "sha256-1RCStMZUGqus3DAl7jivw7XM5jpbecfqWtA1r45Ts90=",
|
||||
"lastModified": 1717921035,
|
||||
"narHash": "sha256-TxZv3M3M2EromaaJCbRKWWjrnk9DSeJ139K4DkJlhAg=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "a0471f14e0499a66898fc1c7d5aff259a9fa58b9",
|
||||
"rev": "02f829e2432d4204370445272084ce22761ba4bc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -384,6 +696,48 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nur-update": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1716222588,
|
||||
"narHash": "sha256-gbyIIHsJpk3V8tnsGP8RZpgc0NM/R9QT4zk4SObRDas=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nur-update",
|
||||
"rev": "a54c4c1b0ec643ff36b3c9deecb5fefce57dcabc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nur-update",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"osu-wine": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720010227,
|
||||
"narHash": "sha256-ADhjhE6UMjcCgjycONnabDqJ7WR2O4SpoAYvmScLwgc=",
|
||||
"owner": "chayleaf",
|
||||
"repo": "osu-wine.nix",
|
||||
"rev": "1406bb2c6ee6eaa8c1433516ef5d324eb651c3fc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "chayleaf",
|
||||
"repo": "osu-wine.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"coop-fd": "coop-fd",
|
||||
|
@ -391,31 +745,34 @@
|
|||
"home-manager": "home-manager",
|
||||
"impermanence": "impermanence",
|
||||
"mobile-nixos": "mobile-nixos",
|
||||
"nix-community-infra": "nix-community-infra",
|
||||
"nix-gaming": "nix-gaming",
|
||||
"nix-index-database": "nix-index-database",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixos-mailserver": "nixos-mailserver",
|
||||
"nixos-router": "nixos-router",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"nixpkgs-kernel": "nixpkgs-kernel",
|
||||
"notlua": "notlua",
|
||||
"notnft": "notnft",
|
||||
"nur": "nur",
|
||||
"osu-wine": "osu-wine",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712715149,
|
||||
"narHash": "sha256-uOx7GaLV+5hekAYtm/CBr627Pi7+d1Yh70hwKmVjYYo=",
|
||||
"lastModified": 1717899611,
|
||||
"narHash": "sha256-9Z95F8lnY/5sOf7Z4IdABKz1ulB0ueNrZU864rQj280=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "9ef1eca23bee5fb8080863909af3802130b2ee57",
|
||||
"rev": "1f536afad5c18ea4ae6bb592c3fef038e1e33568",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -424,6 +781,52 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"sops-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": [
|
||||
"nix-community-infra",
|
||||
"empty"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719716556,
|
||||
"narHash": "sha256-KA9gy2Wkv76s4A8eLnOcdKVTygewbw3xsB8+awNMyqs=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "b5974d4331fb6c893e808977a2e1a6d34b3162d6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"srvos": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719835186,
|
||||
"narHash": "sha256-o0FB8SQVLOnbsYTk2Bt6gXwsfqEv4ZHsGP50/kM/gR0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "srvos",
|
||||
"rev": "14b3b0aa48fa291f1be26ab8948d5b9eadaed0b8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "srvos",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
|
@ -454,9 +857,60 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_3": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_4": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-community-infra",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719749022,
|
||||
"narHash": "sha256-ddPKHcqaKCIFSFc/cvxS14goUhCOAwsM1PbMr0ZtHMg=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "8df5ff62195d4e67e2264df0b7f5e8c9995fd0bd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709126324,
|
||||
|
|
65
flake.nix
65
flake.nix
|
@ -2,8 +2,8 @@
|
|||
description = "NixOS + Home Manager configuration of chayleaf";
|
||||
|
||||
inputs = {
|
||||
#nixpkgs.url = "github:NixOS/nixpkgs/3dc2b4f8166f744c3b3e9ff8224e7c5d74a5424f";
|
||||
# nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
nix-community-infra.url = "github:nix-community/infra";
|
||||
nixpkgs-kernel.url = "github:NixOS/nixpkgs/nixos-unstable/c7b821ba2e1e635ba5a76d299af62821cbcb09f3";
|
||||
nixpkgs.url = "github:chayleaf/nixpkgs";
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware";
|
||||
nix-index-database = {
|
||||
|
@ -11,10 +11,13 @@
|
|||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
mobile-nixos = {
|
||||
# url = "github:NixOS/mobile-nixos";
|
||||
url = "github:chayleaf/mobile-nixos/fix-op6-modem";
|
||||
url = "github:NixOS/mobile-nixos";
|
||||
flake = false;
|
||||
};
|
||||
osu-wine = {
|
||||
url = "github:chayleaf/osu-wine.nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
impermanence.url = "github:nix-community/impermanence";
|
||||
nur.url = "github:nix-community/NUR";
|
||||
rust-overlay = {
|
||||
|
@ -22,7 +25,7 @@
|
|||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
coop-fd = {
|
||||
url = "github:chayleaf/coop-fd/442f5d91bebffbf3e7c83723e9bcda87d0adee52";
|
||||
url = "github:chayleaf/coop-fd";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
home-manager = {
|
||||
|
@ -65,6 +68,7 @@
|
|||
# mobile-nixos = true;
|
||||
# nixos-router = true;
|
||||
# notnft = true;
|
||||
# nixpkgs = true;
|
||||
};
|
||||
# IRL-related stuff I'd rather not put into git
|
||||
priv =
|
||||
|
@ -80,7 +84,7 @@
|
|||
if dev.${name} or false then
|
||||
(if input._type or null == "flake"
|
||||
then let inputs = input.inputs // { self = (import /${devPath}/${name}/flake.nix).outputs inputs; };
|
||||
in inputs.self
|
||||
in { __toString = _: "/${toString devPath}/${name}"; } // inputs.self
|
||||
else /${devPath}/${name})
|
||||
else input)
|
||||
base-inputs;
|
||||
|
@ -94,30 +98,32 @@
|
|||
# extended lib
|
||||
lib = nixpkgs.lib // import ./lib.nix { inherit (nixpkgs) lib; };
|
||||
# can't use callPackage ./pkgs here, idk why; use import instead
|
||||
overlay' = args: self: super: import ./pkgs ({
|
||||
overlay' = args: self: super: import (if args.pluginsOverlay or false then ./pkgs/nix-plugins-overlay.nix else ./pkgs) ({
|
||||
pkgs = super;
|
||||
pkgs' = self;
|
||||
lib = super.lib;
|
||||
inherit inputs;
|
||||
} // args);
|
||||
overlay = overlay' { };
|
||||
nix-plugins-overlay = overlay' { pluginsOverlay = true; };
|
||||
all-overlays = [ nix-plugins-overlay overlay ];
|
||||
# I override some settings down the line, but overlays always stay the same
|
||||
mkPkgs = config: import nixpkgs (config // {
|
||||
overlays = config.overlays or [ ] ++ [ overlay ];
|
||||
overlays = config.overlays or [ ] ++ all-overlays;
|
||||
});
|
||||
# this is actual config, it gets processed below
|
||||
config = let
|
||||
mkBpiR3 = args: config: config // {
|
||||
system = "aarch64-linux";
|
||||
modules = config.modules or [ ] ++ [ (import ./system/devices/bpi-r3-router.nix args) ];
|
||||
modules = config.modules or [ ] ++ [
|
||||
(import ./system/devices/bpi-r3-router.nix args)
|
||||
];
|
||||
};
|
||||
routerConfig = rec {
|
||||
system = "aarch64-linux";
|
||||
modules = [
|
||||
{
|
||||
_module.args.server-config = self.nixosConfigurations.server.config;
|
||||
_module.args.notnft = inputs.notnft.lib.${system};
|
||||
}
|
||||
{ _module.args.server-config = self.nixosConfigurations.server.config;
|
||||
_module.args.notnft = inputs.notnft.lib.${system}; }
|
||||
inputs.nixos-router.nixosModules.default
|
||||
];
|
||||
};
|
||||
|
@ -150,7 +156,10 @@
|
|||
};
|
||||
|
||||
in {
|
||||
overlays.default = overlay;
|
||||
overlays = {
|
||||
default = overlay;
|
||||
nix-plugins = nix-plugins-overlay;
|
||||
};
|
||||
packages = lib.genAttrs [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
|
@ -187,13 +196,16 @@
|
|||
inherit inputs lib;
|
||||
hardware = inputs.nixos-hardware.nixosModules;
|
||||
} // args.specialArgs or { };
|
||||
modules = args.modules or [ ]
|
||||
++ [
|
||||
modules = [
|
||||
{ _module.args = {
|
||||
pkgs-kernel = import inputs.nixpkgs-kernel { inherit (args) system; overlays = all-overlays; };
|
||||
}; }
|
||||
(getPrivSys hostname)
|
||||
{ networking.hostName = lib.mkDefault hostname;
|
||||
nixpkgs.overlays = [ overlay ]; }
|
||||
nixpkgs.overlays = all-overlays; }
|
||||
inputs.impermanence.nixosModule
|
||||
]
|
||||
++ args.modules or [ ]
|
||||
++ map (x: ./system/modules/${x}) (builtins.attrNames (builtins.readDir ./system/modules))
|
||||
# the following is NixOS home-manager module configuration. Currently unused, but I might start using it for some hosts later.
|
||||
++ lib.optionals (home != { } && home.common.enableNixosModule or false) [
|
||||
|
@ -207,7 +219,7 @@
|
|||
{ nixpkgs = home.common.nixpkgs or { };
|
||||
nix = home.common.nix or { }; }
|
||||
({ config, pkgs, lib, ...}: {
|
||||
nixpkgs.overlays = [ overlay ];
|
||||
nixpkgs.overlays = all-overlays;
|
||||
nix.package = lib.mkDefault pkgs.nixForNixPlugins; })
|
||||
(getPrivUser hostname username)
|
||||
];
|
||||
|
@ -217,7 +229,20 @@
|
|||
|
||||
# for each hostname, for each user, generate an attribute "${user}@${hostname}"
|
||||
homeConfigurations =
|
||||
builtins.listToAttrs (builtins.concatLists
|
||||
{
|
||||
"chayleaf@hysteria" = inputs.home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = mkPkgs {
|
||||
system = "x86_64-linux";
|
||||
overlays = [ overlay ];
|
||||
};
|
||||
extraSpecialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
./home/hosts/remote.nix
|
||||
({ pkgs, ... }: { home.file.hysteria.source = pkgs.hysteria; })
|
||||
];
|
||||
};
|
||||
}
|
||||
// builtins.listToAttrs (builtins.concatLists
|
||||
(lib.flip lib.mapAttrsToList config
|
||||
(hostname: { system, home ? {}, ... }:
|
||||
let
|
||||
|
@ -236,7 +261,7 @@
|
|||
++ [
|
||||
(getPrivUser hostname user)
|
||||
({ pkgs, lib, ... }: {
|
||||
nixpkgs.overlays = [ overlay ];
|
||||
nixpkgs.overlays = all-overlays;
|
||||
nix.package = lib.mkDefault pkgs.nixForNixPlugins;
|
||||
})
|
||||
];
|
||||
|
|
|
@ -62,9 +62,9 @@
|
|||
openrgb piper
|
||||
steam-run steam
|
||||
# faf-client
|
||||
(osu-lazer-bin.override {
|
||||
command_prefix = "env SDL_VIDEODRIVER=wayland ${obs-studio-plugins.obs-vkcapture}/bin/obs-gamecapture";
|
||||
})
|
||||
#(osu-lazer-bin.override {
|
||||
#command_prefix = "env SDL_VIDEODRIVER=wayland ${obs-studio-plugins.obs-vkcapture}/bin/obs-gamecapture";
|
||||
#})
|
||||
taisei
|
||||
techmino
|
||||
(wrapOBS {
|
||||
|
|
15
home/hosts/remote.nix
Normal file
15
home/hosts/remote.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{ inputs
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../modules/general.nix
|
||||
inputs.nur.nixosModules.nur
|
||||
];
|
||||
|
||||
home.stateVersion = "24.05";
|
||||
home.username = "chayleaf";
|
||||
home.homeDirectory = "/home/chayleaf";
|
||||
minimal = true;
|
||||
}
|
|
@ -99,10 +99,10 @@
|
|||
|
||||
# the following 4 values are special in some way
|
||||
# (e.g. even if you use -gx to set them, it won't work)
|
||||
set -U _tide_left_items pwd git vi_mode
|
||||
set -U _tide_left_items context pwd git vi_mode
|
||||
set -U _tide_prompt_69105 \x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b34m\x1b\x5b44m\x20\x40PWD\x40\x20\x1b\x5b34m\x1b\x5b40m\ue0b0\x1b\x5b32m\x1b\x5b40m\x20\u276f\x20\x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b30m\ue0b0 \x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b30m\ue0b2\x1b\x5b32m\x1b\x5b40m\x20\uf00c\x20\x1b\x5b33m\x1b\x5b40m\ue0b2\x1b\x5b30m\x1b\x5b43m\x2021m\x2023s\x20\x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b33m
|
||||
set -U _tide_prompt_79899 \x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b34m\x1b\x5b44m\x20\x40PWD\x40\x20\x1b\x5b34m\x1b\x5b40m\ue0b0\x1b\x5b32m\x1b\x5b40m\x20\u276f\x20\x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b30m\ue0b0 \x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b30m\ue0b2\x1b\x5b32m\x1b\x5b40m\x20\uf00c\x20\x1b\x5b33m\x1b\x5b40m\ue0b2\x1b\x5b30m\x1b\x5b43m\x2015s\x20\x1b\x28B\x1b\x5bm\x1b\x28B\x1b\x5bm\x1b\x5b33m
|
||||
set -U _tide_right_items status cmd_duration context jobs rustc nix_shell
|
||||
set -U _tide_right_items status cmd_duration jobs rustc nix_shell
|
||||
|
||||
# for the following values, -gx works too (-g doesn't)
|
||||
# but it pollutes children's env, so do -U
|
||||
|
@ -160,7 +160,7 @@
|
|||
set -U tide_kubectl_color black
|
||||
set -U tide_kubectl_icon \u2388
|
||||
set -U tide_left_prompt_frame_enabled false
|
||||
set -U tide_left_prompt_items pwd git vi_mode
|
||||
set -U tide_left_prompt_items context pwd git vi_mode
|
||||
set -U tide_left_prompt_prefix
|
||||
set -U tide_left_prompt_separator_diff_color \ue0b0
|
||||
set -U tide_left_prompt_separator_same_color \ue0b1
|
||||
|
@ -195,7 +195,7 @@
|
|||
set -U tide_pwd_icon_unwritable \uf023
|
||||
set -U tide_pwd_markers \x2ebzr \x2ecitc \x2egit \x2ehg \x2enode\x2dversion \x2epython\x2dversion \x2eruby\x2dversion \x2eshorten_folder_marker \x2esvn \x2eterraform Cargo\x2etoml composer\x2ejson CVS go\x2emod package\x2ejson
|
||||
set -U tide_right_prompt_frame_enabled false
|
||||
set -U tide_right_prompt_items status cmd_duration context jobs node rustc java php go kubectl toolbox terraform aws nix_shell crystal
|
||||
set -U tide_right_prompt_items status cmd_duration jobs node rustc java php go kubectl toolbox terraform aws nix_shell crystal
|
||||
set -U tide_right_prompt_prefix \ue0b2
|
||||
set -U tide_right_prompt_separator_diff_color \ue0b2
|
||||
set -U tide_right_prompt_separator_same_color \ue0b3
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
./zsh.nix
|
||||
./fish.nix
|
||||
];
|
||||
manual.json.enable = true;
|
||||
manual.json.enable = !config.minimal;
|
||||
services.gpg-agent = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
enableSshSupport = true;
|
||||
maxCacheTtl = 72000;
|
||||
maxCacheTtlSsh = 72000;
|
||||
|
@ -65,14 +65,14 @@
|
|||
extraPackages = with pkgs; [
|
||||
# utils
|
||||
gnused mktemp fzf coreutils-full findutils xdg-utils gnupg whois curl
|
||||
file mediainfo unzip gnutar man rclone sshfs trash-cli
|
||||
file mediainfo unzip gnutar man rclone
|
||||
# for preview
|
||||
# exa - TODO: replace with eza wrapper?
|
||||
bat
|
||||
libarchive atool
|
||||
glow w3m
|
||||
bat libarchive atool glow
|
||||
# for opening
|
||||
p7zip unrar-wrapper odt2txt
|
||||
p7zip unrar-wrapper
|
||||
] ++ lib.optionals (!config.minimal) [
|
||||
odt2txt w3m sshfs trash-cli
|
||||
];
|
||||
plugins = {
|
||||
src = pluginSrc;
|
||||
|
@ -92,14 +92,14 @@
|
|||
home-manager.enable = true;
|
||||
# i only use this as a login shell
|
||||
bash = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
initExtra = ''
|
||||
bind -x '"\C-r": __atuin_history'
|
||||
export ATUIN_NOBIND=true
|
||||
'';
|
||||
};
|
||||
git = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
package = pkgs.gitAndTools.gitFull;
|
||||
delta.enable = true;
|
||||
extraConfig = {
|
||||
|
@ -135,7 +135,7 @@
|
|||
};
|
||||
};
|
||||
ssh = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
compression = true;
|
||||
};
|
||||
tmux = {
|
||||
|
@ -145,7 +145,7 @@
|
|||
keyMode = "vi";
|
||||
};
|
||||
gpg = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
homedir = "${config.xdg.dataHome}/gnupg";
|
||||
mutableKeys = true;
|
||||
mutableTrust = true;
|
||||
|
@ -156,7 +156,7 @@
|
|||
variables.show-mode-in-prompt = true;
|
||||
};
|
||||
nix-index = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
# don't add pkgs.nix to PATH
|
||||
# use the nix that's already in PATH
|
||||
# (because I use nix plugins and plugins are nix version-specific)
|
||||
|
@ -168,31 +168,38 @@
|
|||
# vimKeys = true;
|
||||
#};
|
||||
alot = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
settings = {
|
||||
handle_mouse = true;
|
||||
initial_command = "search tag:inbox AND NOT tag:killed";
|
||||
prefer_plaintext = true;
|
||||
};
|
||||
};
|
||||
msmtp.enable = true;
|
||||
msmtp.enable = !config.minimal;
|
||||
notmuch = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
hooks.preNew = ''
|
||||
${config.services.mbsync.package}/bin/mbsync --all || ${pkgs.coreutils}/bin/true
|
||||
'';
|
||||
};
|
||||
mbsync.enable = true;
|
||||
mbsync.enable = !config.minimal;
|
||||
};
|
||||
#services.mbsync.enable = true;
|
||||
# TODO: see https://github.com/pazz/alot/issues/1632
|
||||
home.file.".mailcap".text = ''
|
||||
text/html; ${pkgs.w3m}/bin/w3m -dump -o document_charset=%{charset} -o display_link_number=1 '%s'; nametemplate=%s.html; copiousoutput
|
||||
'';
|
||||
home.file.".mailcap" = lib.mkIf (!config.minimal) {
|
||||
text = ''
|
||||
text/html; ${pkgs.w3m}/bin/w3m -dump -o document_charset=%{charset} -o display_link_number=1 '%s'; nametemplate=%s.html; copiousoutput
|
||||
'';
|
||||
};
|
||||
|
||||
home.file.".cache/nix-index/files".source = assert config.xdg.cacheHome == "${config.home.homeDirectory}/.cache"; inputs.nix-index-database.legacyPackages.${pkgs.system}.database;
|
||||
home.file.".cache/nix-index/files" = lib.mkIf (!config.minimal) {
|
||||
source =
|
||||
assert config.xdg.cacheHome == "${config.home.homeDirectory}/.cache";
|
||||
inputs.nix-index-database.packages.${pkgs.system}.nix-index-database;
|
||||
};
|
||||
|
||||
systemd.user.tmpfiles.rules = builtins.map (file: "r! \"/home/${config.home.username}/${file}\"") [
|
||||
systemd.user.tmpfiles.rules = lib.mkIf (!config.minimal)
|
||||
(builtins.map (file: "r! \"/home/${config.home.username}/${file}\"") [
|
||||
".local/share/clipman.json"
|
||||
".local/state/lesshst" # I don't need less search history to persist across boots...
|
||||
".Xauthority"
|
||||
|
@ -301,12 +308,14 @@
|
|||
] ++ builtins.map (dir: "x \"/home/${config.home.username}/${dir}/\"") [
|
||||
# WHY DOES THIS KEEP PART OF THE CONFIG
|
||||
".cache/keepassxc"
|
||||
];
|
||||
]);
|
||||
|
||||
home.packages = with pkgs; [
|
||||
rclone sshfs fuse
|
||||
file jq python3Full killall
|
||||
appimage-run comma nix-output-monitor
|
||||
comma nix-output-monitor
|
||||
unzip p7zip unrar-wrapper
|
||||
] ++ lib.optionals (!config.minimal) [
|
||||
appimage-run
|
||||
];
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
ripgrep
|
||||
(python3.withPackages (p: with p; [
|
||||
python-lsp-server
|
||||
python-lsp-black
|
||||
pylsp-mypy
|
||||
python-lsp-server.optional-dependencies.pyflakes
|
||||
python-lsp-server.optional-dependencies.mccabe
|
||||
|
@ -433,6 +434,7 @@
|
|||
pylsp = {
|
||||
settings = {
|
||||
pylsp.plugins.pylsp_mypy.enabled = true;
|
||||
pylsp.plugins.black.enabled = true;
|
||||
};
|
||||
};
|
||||
svelte = { };
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
{ lib, config, ... }:
|
||||
with lib; {
|
||||
options.minimal = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
options.phone = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{ config, pkgs, ... }:
|
||||
{
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
enable = !config.minimal;
|
||||
# zsh-autosuggestions
|
||||
autosuggestion.enable = true;
|
||||
# zsh-syntax-highlighting
|
||||
|
|
|
@ -22,24 +22,24 @@
|
|||
"pinned": false,
|
||||
"src": {
|
||||
"name": null,
|
||||
"sha256": "sha256-wCIffeayOy3kEwmIKB7e+NrliuSpKXoVYC334fxVB3U=",
|
||||
"sha256": "sha256-4jh3mDm1GpR9tQBkzx9BRsJ5awNrBgRzylyRB04LqIE=",
|
||||
"type": "url",
|
||||
"url": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton9-1/GE-Proton9-1.tar.gz"
|
||||
"url": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton9-7/GE-Proton9-7.tar.gz"
|
||||
},
|
||||
"version": "GE-Proton9-1"
|
||||
"version": "GE-Proton9-7"
|
||||
},
|
||||
"searxng": {
|
||||
"cargoLocks": null,
|
||||
"date": "2024-03-15",
|
||||
"date": "2024-06-07",
|
||||
"extract": null,
|
||||
"name": "searxng",
|
||||
"passthru": null,
|
||||
"pinned": false,
|
||||
"src": {
|
||||
"sha256": "sha256-BqVnp/lByAMr/LOCGkuXCYsomu9hRBGXK3DbBQX10TA=",
|
||||
"sha256": "sha256-WWbpfZZei3kOdN607/J2M1oSzbPZKaLbsU5gO2kIc90=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/searxng/searxng/archive/e2af3e49702f6fb40e1614f826544dc3b03bca2f.tar.gz"
|
||||
"url": "https://github.com/searxng/searxng/archive/f5eb56b63f250c7804e5e1cf4426e550bc933906.tar.gz"
|
||||
},
|
||||
"version": "e2af3e49702f6fb40e1614f826544dc3b03bca2f"
|
||||
"version": "f5eb56b63f250c7804e5e1cf4426e550bc933906"
|
||||
}
|
||||
}
|
|
@ -12,19 +12,19 @@
|
|||
};
|
||||
proton-ge = {
|
||||
pname = "proton-ge";
|
||||
version = "GE-Proton9-1";
|
||||
version = "GE-Proton9-7";
|
||||
src = fetchurl {
|
||||
url = "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton9-1/GE-Proton9-1.tar.gz";
|
||||
sha256 = "sha256-wCIffeayOy3kEwmIKB7e+NrliuSpKXoVYC334fxVB3U=";
|
||||
url = "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton9-7/GE-Proton9-7.tar.gz";
|
||||
sha256 = "sha256-4jh3mDm1GpR9tQBkzx9BRsJ5awNrBgRzylyRB04LqIE=";
|
||||
};
|
||||
};
|
||||
searxng = {
|
||||
pname = "searxng";
|
||||
version = "e2af3e49702f6fb40e1614f826544dc3b03bca2f";
|
||||
version = "f5eb56b63f250c7804e5e1cf4426e550bc933906";
|
||||
src = fetchTarball {
|
||||
url = "https://github.com/searxng/searxng/archive/e2af3e49702f6fb40e1614f826544dc3b03bca2f.tar.gz";
|
||||
sha256 = "sha256-BqVnp/lByAMr/LOCGkuXCYsomu9hRBGXK3DbBQX10TA=";
|
||||
url = "https://github.com/searxng/searxng/archive/f5eb56b63f250c7804e5e1cf4426e550bc933906.tar.gz";
|
||||
sha256 = "sha256-WWbpfZZei3kOdN607/J2M1oSzbPZKaLbsU5gO2kIc90=";
|
||||
};
|
||||
date = "2024-03-15";
|
||||
date = "2024-06-07";
|
||||
};
|
||||
}
|
||||
|
|
103
pkgs/default.nix
103
pkgs/default.nix
|
@ -11,7 +11,6 @@ let
|
|||
sources = import ./_sources/generated.nix {
|
||||
inherit (pkgs) fetchgit fetchurl fetchFromGitHub dockerTools;
|
||||
};
|
||||
nixForNixPlugins = pkgs.nixVersions.nix_2_18;
|
||||
nur = import inputs.nur {
|
||||
inherit pkgs;
|
||||
nurpkgs = pkgs;
|
||||
|
@ -20,91 +19,16 @@ in
|
|||
|
||||
{
|
||||
inherit (inputs.nix-gaming.packages.${pkgs.system}) faf-client osu-lazer-bin;
|
||||
inherit nixForNixPlugins;
|
||||
nix = nixForNixPlugins;
|
||||
nixVersions = pkgs.nixVersions // {
|
||||
stable = nixForNixPlugins;
|
||||
unstable = nixForNixPlugins;
|
||||
};
|
||||
matrix-appservice-discord = pkgs.matrix-appservice-discord.overrideAttrs (old: {
|
||||
doCheck = false;
|
||||
patches = (old.patches or []) ++ [
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/917
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/eb989fa710e8db4ebc8f2ce36c6679ee6cbc1a44.patch";
|
||||
hash = "sha256-GPeFDw3XujqXHJveHSsBHwHuG51vad50p55FX1Esq58=";
|
||||
name = "set-missing-config-defaults.patch";
|
||||
})
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/918
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/a4cd5e3a6a2d544adac2a263e164671c8a9009d9.patch";
|
||||
hash = "sha256-qQJ4V6/Ns2Msu8+X8JoEycuQ2Jc90TXulsuLLmPecGU=";
|
||||
name = "dont-send-filenames.patch";
|
||||
})
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/878/
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/fc850ba2473973e28858449ec4020380470d78b2.patch";
|
||||
hash = "sha256-Lq0FWmR08wLsoq4APRTokZzb7U2po98pgyxH4UR/9/M=";
|
||||
name = "bridge-discord-replies-1.patch";
|
||||
})
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/86388901fa44d5d0f9d3dec8727c18cc00d613e7.patch";
|
||||
hash = "sha256-XcLbKJPmFZElzwU4YS8Md8dNLajddJPKmau0U65bp00=";
|
||||
name = "bridge-discord-replies-2.patch";
|
||||
})
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/8299c626188e676723a708e49635d2c4afa26ffa.patch";
|
||||
hash = "sha256-ZfUwpJ21/m3QbktbxxHyO8Lcl/IuDhaSKQRXBEPeJBo=";
|
||||
name = "bridge-discord-replies-3.patch";
|
||||
})
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/819
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/1c3223387aaf78ba5637f58ca57bd8206ad0446c.patch";
|
||||
hash = "sha256-3hxyqjI9F4j/XBq/59b7c2PorYRN2mR4XZJjpygs9dI=";
|
||||
name = "bridge-matrix-edits-1.patch";
|
||||
})
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/f8e9449908b332d97f11932fb835552adca0aa5b.patch";
|
||||
hash = "sha256-1qb4Zah1XKzxTpVJqOOqz+TiXMFmnsIMZeuqJQdqSIA=";
|
||||
name = "bridge-matrix-edits-2.patch";
|
||||
})
|
||||
./matrix-appservice-discord/disable-attachment-forwarding-to-matrix.patch
|
||||
];
|
||||
});
|
||||
# Various patches to change Nix version of existing packages so they don't error out because of nix-plugins in nix.conf
|
||||
/*nix-plugins = (pkgs.nix-plugins.override { nix = nixForNixPlugins; }).overrideAttrs (old: {
|
||||
version = "13.0.0";
|
||||
patches = [
|
||||
(pkgs.fetchpatch {
|
||||
# pull 16
|
||||
url = "https://github.com/chayleaf/nix-plugins/commit/8f945cadad7f2e60e8f308b2f498ec5e16961ede.patch";
|
||||
hash = "sha256-pOogMtjXYkSDtXW12TmBpGr/plnizJtud2nP3q2UldQ=";
|
||||
})
|
||||
];
|
||||
});*/
|
||||
harmonia = (pkgs.harmonia.override { nixVersions.nix_2_21 = nixForNixPlugins; }).overrideAttrs (old: rec {
|
||||
version = "0.7.3";
|
||||
src = old.src.override {
|
||||
rev = "refs/tags/${old.pname}-v${version}";
|
||||
hash = "sha256-XtnK54HvZMKZGSCrVD0FO5PQLMo3Vkj8ezUlsfqStq0=";
|
||||
};
|
||||
cargoDeps = pkgs.rustPlatform.importCargoLock { lockFile = "${src}/Cargo.lock"; };
|
||||
});
|
||||
nix-init = pkgs.nix-init.override { nix = nixForNixPlugins; };
|
||||
nix-serve = pkgs.nix-serve.override { nix = nixForNixPlugins; };
|
||||
nix-serve-ng = pkgs.nix-serve-ng.override { nix = nixForNixPlugins; };
|
||||
hydra_unstable = (pkgs.hydra_unstable.override {
|
||||
nix = nixForNixPlugins;
|
||||
}).overrideAttrs (old: {
|
||||
version = "2023-12-01";
|
||||
# who cares about tests amirite
|
||||
doCheck = false;
|
||||
src = old.src.override {
|
||||
rev = "4d1c8505120961f10897b8fe9a070d4e193c9a13";
|
||||
hash = "sha256-vXTuE83GL15mgZHegbllVAsVdDFcWWSayPfZxTJN5ys=";
|
||||
inherit (inputs.osu-wine.packages.${pkgs.system}) osu-wine;
|
||||
matrix-appservice-discord = pkgs.callPackage ./matrix-appservice-discord { inherit (pkgs) matrix-appservice-discord; };
|
||||
|
||||
openssh = pkgs.openssh.overrideAttrs (old: rec {
|
||||
version = "9.8p1";
|
||||
src = pkgs.fetchurl {
|
||||
url = "mirror://openbsd/OpenSSH/portable/openssh-${version}.tar.gz";
|
||||
hash = "sha256-3YvQAqN5tdSZ37BQ3R+pr4Ap6ARh9LtsUjxJlz9aOfM=";
|
||||
};
|
||||
});
|
||||
nurl = pkgs.nurl.override { nix = nixForNixPlugins; };
|
||||
|
||||
buffyboard = pkgs.callPackage ./buffyboard { };
|
||||
clang-tools_latest = pkgs.clang-tools_16;
|
||||
|
@ -124,12 +48,13 @@ in
|
|||
sha256 = "sha256-6vYbNmNJBCoU23nVculac24tHqH7F4AZVftIjL93WJU=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
patches = [ ];
|
||||
});
|
||||
kvmfrOverlay = kvmfr: kvmfr.overrideAttrs (old: {
|
||||
inherit (pkgs'.looking-glass-client) version src;
|
||||
patches = [ ./looking-glass.patch ];
|
||||
});
|
||||
mobile-config-firefox = callPackage ./mobile-config-firefox { };
|
||||
osu-wine = callPackage ./osu-wine { };
|
||||
ping-exporter = callPackage ./ping-exporter { };
|
||||
proton-ge = pkgs.stdenvNoCC.mkDerivation {
|
||||
inherit (sources.proton-ge) pname version src;
|
||||
|
@ -176,7 +101,9 @@ in
|
|||
qemu = pkgs'.qemu_7_ccache;
|
||||
stdenv = pkgs'.ccacheStdenv;
|
||||
};
|
||||
ccachePkgs = import ./ccache.nix { inherit pkgs pkgs' lib sources; };
|
||||
|
||||
# hardware stuff
|
||||
hw.bpi-r3 = import ../system/hardware/bpi-r3/pkgs.nix { inherit pkgs pkgs' lib sources; };
|
||||
hw.oneplus-enchilada = import ../system/hardware/oneplus-enchilada/pkgs.nix { inherit inputs pkgs pkgs' lib sources; };
|
||||
}
|
||||
// import ./ccache.nix { inherit pkgs pkgs' lib sources; }
|
||||
// import ../system/hardware/bpi-r3/pkgs.nix { inherit pkgs pkgs' lib sources; }
|
||||
// import ../system/hardware/oneplus-enchilada/pkgs.nix { inherit inputs pkgs pkgs' lib sources; }
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
{
|
||||
"fastforwardteam" = buildFirefoxXpiAddon {
|
||||
pname = "fastforwardteam";
|
||||
version = "0.2334";
|
||||
version = "0.2383";
|
||||
addonId = "addon@fastforward.team";
|
||||
url = "https://addons.mozilla.org/firefox/downloads/file/4177101/fastforwardteam-0.2334.xpi";
|
||||
sha256 = "d790219622469f08316b41c0d01abf2b584a37fa87b45666a74bd30cffb95ed0";
|
||||
url = "https://addons.mozilla.org/firefox/downloads/file/4258067/fastforwardteam-0.2383.xpi";
|
||||
sha256 = "eec6328df3df1afe2cb6a331f6907669d804235551ea766d48655f8f831caf28";
|
||||
meta = with lib;
|
||||
{
|
||||
homepage = "https://fastforward.team";
|
||||
|
@ -23,10 +23,10 @@
|
|||
};
|
||||
"rikaitan" = buildFirefoxXpiAddon {
|
||||
pname = "rikaitan";
|
||||
version = "24.3.7.1";
|
||||
version = "24.5.21.0";
|
||||
addonId = "tatsu@autistici.org";
|
||||
url = "https://addons.mozilla.org/firefox/downloads/file/4246908/rikaitan-24.3.7.1.xpi";
|
||||
sha256 = "db849343b029b2f1b510cc66032157502e3fe9e6168072d27e8aad9867b6ec17";
|
||||
url = "https://addons.mozilla.org/firefox/downloads/file/4291845/rikaitan-24.5.21.0.xpi";
|
||||
sha256 = "a2a94d88af04023f14daaafda1f6ca7a7197f2ab92ada08ee2e9e4292d57a391";
|
||||
meta = with lib;
|
||||
{
|
||||
homepage = "https://github.com/Ajatt-Tools/rikaitan";
|
||||
|
|
24
pkgs/looking-glass.patch
Normal file
24
pkgs/looking-glass.patch
Normal file
|
@ -0,0 +1,24 @@
|
|||
diff --git a/kvmfr.c b/kvmfr.c
|
||||
index 121aae5b..4c386f98 100644
|
||||
--- a/kvmfr.c
|
||||
+++ b/kvmfr.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/memremap.h>
|
||||
#include <linux/version.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
@@ -539,7 +540,11 @@ static int __init kvmfr_module_init(void)
|
||||
if (kvmfr->major < 0)
|
||||
goto out_free;
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
|
||||
kvmfr->pClass = class_create(THIS_MODULE, KVMFR_DEV_NAME);
|
||||
+#else
|
||||
+ kvmfr->pClass = class_create(KVMFR_DEV_NAME);
|
||||
+#endif
|
||||
if (IS_ERR(kvmfr->pClass))
|
||||
goto out_unreg;
|
||||
|
70
pkgs/matrix-appservice-discord/default.nix
Normal file
70
pkgs/matrix-appservice-discord/default.nix
Normal file
|
@ -0,0 +1,70 @@
|
|||
{ matrix-appservice-discord, fetchpatch }:
|
||||
|
||||
matrix-appservice-discord.overrideAttrs (old: {
|
||||
doCheck = false;
|
||||
patches = (old.patches or []) ++ [
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/917
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/eb989fa710e8db4ebc8f2ce36c6679ee6cbc1a44.patch";
|
||||
hash = "sha256-GPeFDw3XujqXHJveHSsBHwHuG51vad50p55FX1Esq58=";
|
||||
name = "set-missing-config-defaults.patch";
|
||||
})
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/918
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/a4cd5e3a6a2d544adac2a263e164671c8a9009d9.patch";
|
||||
hash = "sha256-qQJ4V6/Ns2Msu8+X8JoEycuQ2Jc90TXulsuLLmPecGU=";
|
||||
name = "dont-send-filenames.patch";
|
||||
})
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/878/
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/fc850ba2473973e28858449ec4020380470d78b2.patch";
|
||||
hash = "sha256-Lq0FWmR08wLsoq4APRTokZzb7U2po98pgyxH4UR/9/M=";
|
||||
name = "bridge-discord-replies-1.patch";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/86388901fa44d5d0f9d3dec8727c18cc00d613e7.patch";
|
||||
hash = "sha256-XcLbKJPmFZElzwU4YS8Md8dNLajddJPKmau0U65bp00=";
|
||||
name = "bridge-discord-replies-2.patch";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/8299c626188e676723a708e49635d2c4afa26ffa.patch";
|
||||
hash = "sha256-ZfUwpJ21/m3QbktbxxHyO8Lcl/IuDhaSKQRXBEPeJBo=";
|
||||
name = "bridge-discord-replies-3.patch";
|
||||
})
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/819
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/1c3223387aaf78ba5637f58ca57bd8206ad0446c.patch";
|
||||
hash = "sha256-3hxyqjI9F4j/XBq/59b7c2PorYRN2mR4XZJjpygs9dI=";
|
||||
name = "bridge-matrix-edits-1.patch";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/f8e9449908b332d97f11932fb835552adca0aa5b.patch";
|
||||
hash = "sha256-1qb4Zah1XKzxTpVJqOOqz+TiXMFmnsIMZeuqJQdqSIA=";
|
||||
name = "bridge-matrix-edits-2.patch";
|
||||
})
|
||||
# https://github.com/matrix-org/matrix-appservice-discord/pull/862
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/3106957ebd857bc88ba3f62182a61dd00275f2fc.patch";
|
||||
hash = "sha256-Xf+TuWXNVqi+0YRwBbCkLcMfsYNxq1ZlsgLWpwjqPww=";
|
||||
name = "discord-to-matrix-reactions-1.patch";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/a8186874b03c545a8728892b299a4367776fc538.patch";
|
||||
hash = "sha256-Hq2HY44hPeGPXI3MglyN7Am+NCNAHAbr2hYhXvDYtGk=";
|
||||
name = "discord-to-matrix-reactions-2.patch";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/da2c3b88c7dd4f3a679890c58f934e9b2ed775df.patch";
|
||||
hash = "sha256-4NMAr+Ni+7pI/I007YH5Y+4ZwAhwg91/BXGvLVcO0BQ=";
|
||||
name = "discord-to-matrix-reactions-3.patch";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://github.com/matrix-org/matrix-appservice-discord/commit/a33f269c88c432c532d7816f180e5262d73ebf02.patch";
|
||||
hash = "sha256-0WkfDkQsDoxfKH3MgPb893UPDPxeWueQwVSaxD2RKAw=";
|
||||
name = "discord-to-matrix-reactions-4.patch";
|
||||
})
|
||||
./reactions-as-mxc-urls.patch
|
||||
./disable-attachment-forwarding-to-matrix.patch
|
||||
./reduce-spamminess.patch
|
||||
];
|
||||
})
|
100
pkgs/matrix-appservice-discord/reactions-as-mxc-urls.patch
Normal file
100
pkgs/matrix-appservice-discord/reactions-as-mxc-urls.patch
Normal file
|
@ -0,0 +1,100 @@
|
|||
diff --git a/src/bot.ts b/src/bot.ts
|
||||
index 4445aa6..8613b5a 100644
|
||||
--- a/src/bot.ts
|
||||
+++ b/src/bot.ts
|
||||
@@ -1199,7 +1199,9 @@ export class DiscordBot {
|
||||
|
||||
public async OnMessageReactionAdd(reaction: Discord.MessageReaction, user: Discord.User | Discord.PartialUser) {
|
||||
const message = reaction.message;
|
||||
- const reactionName = reaction.emoji.name;
|
||||
+ const reactionName = (reaction.emoji.id
|
||||
+ ? await this.GetEmoji(reaction.emoji.name, reaction.emoji.animated, reaction.emoji.id) + "#" + reaction.emoji.name
|
||||
+ : reaction.emoji.name);
|
||||
log.verbose(`Got message reaction add event for ${message.id} with ${reactionName}`);
|
||||
|
||||
const storeEvent = await this.store.Get(DbEvent, {
|
||||
@@ -1229,7 +1231,7 @@ export class DiscordBot {
|
||||
const reactionEventId = await intent.underlyingClient.unstableApis.addReactionToEvent(
|
||||
roomId,
|
||||
eventId,
|
||||
- reaction.emoji.id ? `:${reactionName}:` : reactionName
|
||||
+ reactionName,
|
||||
);
|
||||
|
||||
const event = new DbEvent();
|
||||
@@ -1246,7 +1248,10 @@ export class DiscordBot {
|
||||
|
||||
public async OnMessageReactionRemove(reaction: Discord.MessageReaction, user: Discord.User | Discord.PartialUser) {
|
||||
const message = reaction.message;
|
||||
- log.verbose(`Got message reaction remove event for ${message.id} with ${reaction.emoji.name}`);
|
||||
+ const reactionName = (reaction.emoji.id
|
||||
+ ? await this.GetEmoji(reaction.emoji.name, reaction.emoji.animated, reaction.emoji.id) + "#" + reaction.emoji.name
|
||||
+ : reaction.emoji.name);
|
||||
+ log.verbose(`Got message reaction remove event for ${message.id} with ${reactionName}`);
|
||||
|
||||
const storeEvent = await this.store.Get(DbEvent, {
|
||||
discord_id: message.id,
|
||||
@@ -1274,7 +1279,7 @@ export class DiscordBot {
|
||||
|
||||
const underlyingClient = intent.underlyingClient;
|
||||
|
||||
- const { chunk } = await underlyingClient.unstableApis.getRelationsForEvent(
|
||||
+ const { chunk } = await underlyingClient.getRelationsForEvent(
|
||||
roomId,
|
||||
eventId,
|
||||
"m.annotation"
|
||||
@@ -1285,7 +1290,7 @@ export class DiscordBot {
|
||||
return false;
|
||||
}
|
||||
|
||||
- return event.content["m.relates_to"].key === reaction.emoji.name;
|
||||
+ return event.content["m.relates_to"].key === reactionName;
|
||||
});
|
||||
|
||||
if (!event) {
|
||||
@@ -1324,7 +1329,7 @@ export class DiscordBot {
|
||||
const [ eventId, roomId ] = storeEvent.MatrixId.split(";");
|
||||
const underlyingClient = this.bridge.botIntent.underlyingClient;
|
||||
|
||||
- const { chunk } = await underlyingClient.unstableApis.getRelationsForEvent(
|
||||
+ const { chunk } = await underlyingClient.getRelationsForEvent(
|
||||
roomId,
|
||||
eventId,
|
||||
"m.annotation"
|
||||
diff --git a/test/mocks/appservicemock.ts b/test/mocks/appservicemock.ts
|
||||
index 06cc3ce..f6ef585 100644
|
||||
--- a/test/mocks/appservicemock.ts
|
||||
+++ b/test/mocks/appservicemock.ts
|
||||
@@ -281,6 +281,10 @@ class MatrixClientMock extends AppserviceMockBase {
|
||||
public async redactEvent(roomId: string, eventId: string, reason?: string | null) {
|
||||
this.funcCalled("redactEvent", roomId, eventId, reason);
|
||||
}
|
||||
+
|
||||
+ public async getRelationsForEvent(roomId: string, eventId: string, relationType?: string, eventType?: string): Promise<any> {
|
||||
+ this.funcCalled("getRelationsForEvent", roomId, eventId, relationType, eventType);
|
||||
+ }
|
||||
}
|
||||
|
||||
class UnstableApis extends AppserviceMockBase {
|
||||
@@ -288,8 +292,4 @@ class UnstableApis extends AppserviceMockBase {
|
||||
public async addReactionToEvent(roomId: string, eventId: string, emoji: string) {
|
||||
this.funcCalled("addReactionToEvent", roomId, eventId, emoji);
|
||||
}
|
||||
-
|
||||
- public async getRelationsForEvent(roomId: string, eventId: string, relationType?: string, eventType?: string): Promise<any> {
|
||||
- this.funcCalled("getRelationsForEvent", roomId, eventId, relationType, eventType);
|
||||
- }
|
||||
}
|
||||
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
|
||||
index 9c9e469..2109bb7 100644
|
||||
--- a/test/test_discordbot.ts
|
||||
+++ b/test/test_discordbot.ts
|
||||
@@ -501,7 +501,7 @@ describe("DiscordBot", () => {
|
||||
discordBot = getDiscordBot();
|
||||
const intent = mockBridge.getIntent(author.id);
|
||||
|
||||
- intent.underlyingClient.unstableApis.getRelationsForEvent = async () => {
|
||||
+ intent.underlyingClient.getRelationsForEvent = async () => {
|
||||
return {
|
||||
chunk: [
|
||||
{
|
28
pkgs/matrix-appservice-discord/reduce-spamminess.patch
Normal file
28
pkgs/matrix-appservice-discord/reduce-spamminess.patch
Normal file
|
@ -0,0 +1,28 @@
|
|||
diff --git a/src/config.ts b/src/config.ts
|
||||
index 1e2f862..fd6e411 100644
|
||||
--- a/src/config.ts
|
||||
+++ b/src/config.ts
|
||||
@@ -163,7 +163,7 @@ export class LoggingFile {
|
||||
|
||||
class DiscordBridgeConfigGhosts {
|
||||
public nickPattern: string = ":nick";
|
||||
- public usernamePattern: string = ":username#:tag";
|
||||
+ public usernamePattern: string = ":username";
|
||||
}
|
||||
|
||||
export class DiscordBridgeConfigMetrics {
|
||||
diff --git a/src/usersyncroniser.ts b/src/usersyncroniser.ts
|
||||
index b82722d..fb534c6 100644
|
||||
--- a/src/usersyncroniser.ts
|
||||
+++ b/src/usersyncroniser.ts
|
||||
@@ -207,6 +207,10 @@ export class UserSyncroniser {
|
||||
log.warn("Remote user wasn't found, using blank avatar");
|
||||
}
|
||||
const intent = this.bridge.getIntentForUserId(memberState.mxUserId);
|
||||
+ const oldState = await intent.underlyingClient.getRoomStateEvent(roomId, "m.room.member", memberState.mxUserId);
|
||||
+ if (oldState && (oldState.avatar_url || "") == avatar && (oldState.displayname || "") == memberState.displayName) {
|
||||
+ return;
|
||||
+ }
|
||||
/* The intent class tries to be smart and deny a state update for <PL50 users.
|
||||
Obviously a user can change their own state so we use the client instead. */
|
||||
await intent.underlyingClient.sendStateEvent(roomId, "m.room.member", memberState.mxUserId, {
|
46
pkgs/nix-plugins-overlay.nix
Normal file
46
pkgs/nix-plugins-overlay.nix
Normal file
|
@ -0,0 +1,46 @@
|
|||
{ pkgs, pkgs', ... }:
|
||||
|
||||
let
|
||||
nixForNixPlugins = pkgs.nixVersions.nix_2_18;
|
||||
in {
|
||||
inherit nixForNixPlugins;
|
||||
nix = nixForNixPlugins;
|
||||
nixVersions = pkgs.nixVersions // {
|
||||
stable = nixForNixPlugins;
|
||||
unstable = nixForNixPlugins;
|
||||
};
|
||||
# Various patches to change Nix version of existing packages so they don't error out because of nix-plugins in nix.conf
|
||||
/*nix-plugins = (pkgs.nix-plugins.override { nix = nixForNixPlugins; }).overrideAttrs (old: {
|
||||
version = "13.0.0";
|
||||
patches = [
|
||||
(pkgs.fetchpatch {
|
||||
# pull 16
|
||||
url = "https://github.com/chayleaf/nix-plugins/commit/8f945cadad7f2e60e8f308b2f498ec5e16961ede.patch";
|
||||
hash = "sha256-pOogMtjXYkSDtXW12TmBpGr/plnizJtud2nP3q2UldQ=";
|
||||
})
|
||||
];
|
||||
});*/
|
||||
harmonia = (pkgs.harmonia.override { nixVersions.nix_2_21 = nixForNixPlugins; }).overrideAttrs (old: rec {
|
||||
version = "0.7.3";
|
||||
src = old.src.override {
|
||||
rev = "refs/tags/${old.pname}-v${version}";
|
||||
hash = "sha256-XtnK54HvZMKZGSCrVD0FO5PQLMo3Vkj8ezUlsfqStq0=";
|
||||
};
|
||||
cargoDeps = pkgs'.rustPlatform.importCargoLock { lockFile = "${src}/Cargo.lock"; };
|
||||
});
|
||||
nix-init = pkgs.nix-init.override { nix = nixForNixPlugins; };
|
||||
nix-serve = pkgs.nix-serve.override { nix = nixForNixPlugins; };
|
||||
nix-serve-ng = pkgs.nix-serve-ng.override { nix = nixForNixPlugins; };
|
||||
hydra_unstable = (pkgs.hydra_unstable.override {
|
||||
nix = nixForNixPlugins;
|
||||
}).overrideAttrs (old: {
|
||||
version = "2023-12-01";
|
||||
# who cares about tests amirite
|
||||
doCheck = false;
|
||||
src = old.src.override {
|
||||
rev = "4d1c8505120961f10897b8fe9a070d4e193c9a13";
|
||||
hash = "sha256-vXTuE83GL15mgZHegbllVAsVdDFcWWSayPfZxTJN5ys=";
|
||||
};
|
||||
});
|
||||
nurl = pkgs.nurl.override { nix = nixForNixPlugins; };
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
MODULE = mmdevapi.dll
|
||||
IMPORTS = uuid ole32 oleaut32 user32 advapi32
|
||||
|
||||
SOURCES = \
|
||||
audiovolume.c \
|
||||
devenum.c \
|
||||
main.c \
|
||||
mmdevapi_classes.idl \
|
||||
spatialaudio.c
|
|
@ -1,320 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 Maarten Lankhorst for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "ole2.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "mmsystem.h"
|
||||
#include "dsound.h"
|
||||
#include "audioclient.h"
|
||||
#include "endpointvolume.h"
|
||||
#include "audiopolicy.h"
|
||||
#include "spatialaudioclient.h"
|
||||
|
||||
#include "mmdevapi.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
|
||||
|
||||
typedef struct AEVImpl {
|
||||
IAudioEndpointVolumeEx IAudioEndpointVolumeEx_iface;
|
||||
LONG ref;
|
||||
float master_vol;
|
||||
BOOL mute;
|
||||
} AEVImpl;
|
||||
|
||||
static inline AEVImpl *impl_from_IAudioEndpointVolumeEx(IAudioEndpointVolumeEx *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, AEVImpl, IAudioEndpointVolumeEx_iface);
|
||||
}
|
||||
|
||||
static void AudioEndpointVolume_Destroy(AEVImpl *This)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_QueryInterface(IAudioEndpointVolumeEx *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface);
|
||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
|
||||
if (!ppv)
|
||||
return E_POINTER;
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IAudioEndpointVolume) ||
|
||||
IsEqualIID(riid, &IID_IAudioEndpointVolumeEx)) {
|
||||
*ppv = &This->IAudioEndpointVolumeEx_iface;
|
||||
}
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
IUnknown_AddRef((IUnknown *)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI AEV_AddRef(IAudioEndpointVolumeEx *iface)
|
||||
{
|
||||
AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI AEV_Release(IAudioEndpointVolumeEx *iface)
|
||||
{
|
||||
AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
if (!ref)
|
||||
AudioEndpointVolume_Destroy(This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_RegisterControlChangeNotify(IAudioEndpointVolumeEx *iface, IAudioEndpointVolumeCallback *notify)
|
||||
{
|
||||
TRACE("(%p)->(%p)\n", iface, notify);
|
||||
if (!notify)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_UnregisterControlChangeNotify(IAudioEndpointVolumeEx *iface, IAudioEndpointVolumeCallback *notify)
|
||||
{
|
||||
TRACE("(%p)->(%p)\n", iface, notify);
|
||||
if (!notify)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetChannelCount(IAudioEndpointVolumeEx *iface, UINT *count)
|
||||
{
|
||||
TRACE("(%p)->(%p)\n", iface, count);
|
||||
if (!count)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_SetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, float leveldb, const GUID *ctx)
|
||||
{
|
||||
AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface);
|
||||
|
||||
TRACE("(%p)->(%f,%s)\n", iface, leveldb, debugstr_guid(ctx));
|
||||
|
||||
if(leveldb < -100.f || leveldb > 0.f)
|
||||
return E_INVALIDARG;
|
||||
|
||||
This->master_vol = leveldb;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_SetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float level, const GUID *ctx)
|
||||
{
|
||||
TRACE("(%p)->(%f,%s)\n", iface, level, debugstr_guid(ctx));
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, float *leveldb)
|
||||
{
|
||||
AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", iface, leveldb);
|
||||
|
||||
if (!leveldb)
|
||||
return E_POINTER;
|
||||
|
||||
*leveldb = This->master_vol;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float *level)
|
||||
{
|
||||
TRACE("(%p)->(%p)\n", iface, level);
|
||||
if (!level)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
*level = 1.0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_SetChannelVolumeLevel(IAudioEndpointVolumeEx *iface, UINT chan, float leveldb, const GUID *ctx)
|
||||
{
|
||||
TRACE("(%p)->(%f,%s)\n", iface, leveldb, debugstr_guid(ctx));
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_SetChannelVolumeLevelScalar(IAudioEndpointVolumeEx *iface, UINT chan, float level, const GUID *ctx)
|
||||
{
|
||||
TRACE("(%p)->(%u,%f,%s)\n", iface, chan, level, debugstr_guid(ctx));
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetChannelVolumeLevel(IAudioEndpointVolumeEx *iface, UINT chan, float *leveldb)
|
||||
{
|
||||
TRACE("(%p)->(%u,%p)\n", iface, chan, leveldb);
|
||||
if (!leveldb)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetChannelVolumeLevelScalar(IAudioEndpointVolumeEx *iface, UINT chan, float *level)
|
||||
{
|
||||
TRACE("(%p)->(%u,%p)\n", iface, chan, level);
|
||||
if (!level)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_SetMute(IAudioEndpointVolumeEx *iface, BOOL mute, const GUID *ctx)
|
||||
{
|
||||
AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface);
|
||||
HRESULT ret;
|
||||
|
||||
TRACE("(%p)->(%u,%s)\n", iface, mute, debugstr_guid(ctx));
|
||||
|
||||
ret = This->mute == mute ? S_FALSE : S_OK;
|
||||
|
||||
This->mute = mute;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetMute(IAudioEndpointVolumeEx *iface, BOOL *mute)
|
||||
{
|
||||
AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", iface, mute);
|
||||
|
||||
if (!mute)
|
||||
return E_POINTER;
|
||||
|
||||
*mute = This->mute;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetVolumeStepInfo(IAudioEndpointVolumeEx *iface, UINT *stepsize, UINT *stepcount)
|
||||
{
|
||||
TRACE("(%p)->(%p,%p)\n", iface, stepsize, stepcount);
|
||||
if (!stepsize && !stepcount)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_VolumeStepUp(IAudioEndpointVolumeEx *iface, const GUID *ctx)
|
||||
{
|
||||
TRACE("(%p)->(%s)\n", iface, debugstr_guid(ctx));
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_VolumeStepDown(IAudioEndpointVolumeEx *iface, const GUID *ctx)
|
||||
{
|
||||
TRACE("(%p)->(%s)\n", iface, debugstr_guid(ctx));
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_QueryHardwareSupport(IAudioEndpointVolumeEx *iface, DWORD *mask)
|
||||
{
|
||||
TRACE("(%p)->(%p)\n", iface, mask);
|
||||
if (!mask)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetVolumeRange(IAudioEndpointVolumeEx *iface, float *mindb, float *maxdb, float *inc)
|
||||
{
|
||||
TRACE("(%p)->(%p,%p,%p)\n", iface, mindb, maxdb, inc);
|
||||
|
||||
if (!mindb || !maxdb || !inc)
|
||||
return E_POINTER;
|
||||
|
||||
*mindb = -100.f;
|
||||
*maxdb = 0.f;
|
||||
*inc = 1.f;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AEV_GetVolumeRangeChannel(IAudioEndpointVolumeEx *iface, UINT chan, float *mindb, float *maxdb, float *inc)
|
||||
{
|
||||
TRACE("(%p)->(%p,%p,%p)\n", iface, mindb, maxdb, inc);
|
||||
if (!mindb || !maxdb || !inc)
|
||||
return E_POINTER;
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IAudioEndpointVolumeExVtbl AEVImpl_Vtbl = {
|
||||
AEV_QueryInterface,
|
||||
AEV_AddRef,
|
||||
AEV_Release,
|
||||
AEV_RegisterControlChangeNotify,
|
||||
AEV_UnregisterControlChangeNotify,
|
||||
AEV_GetChannelCount,
|
||||
AEV_SetMasterVolumeLevel,
|
||||
AEV_SetMasterVolumeLevelScalar,
|
||||
AEV_GetMasterVolumeLevel,
|
||||
AEV_GetMasterVolumeLevelScalar,
|
||||
AEV_SetChannelVolumeLevel,
|
||||
AEV_SetChannelVolumeLevelScalar,
|
||||
AEV_GetChannelVolumeLevel,
|
||||
AEV_GetChannelVolumeLevelScalar,
|
||||
AEV_SetMute,
|
||||
AEV_GetMute,
|
||||
AEV_GetVolumeStepInfo,
|
||||
AEV_VolumeStepUp,
|
||||
AEV_VolumeStepDown,
|
||||
AEV_QueryHardwareSupport,
|
||||
AEV_GetVolumeRange,
|
||||
AEV_GetVolumeRangeChannel
|
||||
};
|
||||
|
||||
HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv)
|
||||
{
|
||||
AEVImpl *This;
|
||||
|
||||
*ppv = NULL;
|
||||
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
This->IAudioEndpointVolumeEx_iface.lpVtbl = &AEVImpl_Vtbl;
|
||||
This->ref = 1;
|
||||
|
||||
*ppv = &This->IAudioEndpointVolumeEx_iface;
|
||||
return S_OK;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,470 +0,0 @@
|
|||
/*
|
||||
* Copyright 2009 Maarten Lankhorst
|
||||
* Copyright 2011 Andrew Eikum for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
|
||||
#include "ole2.h"
|
||||
#include "olectl.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "propsys.h"
|
||||
#include "propkeydef.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "mmsystem.h"
|
||||
#include "dsound.h"
|
||||
#include "audioclient.h"
|
||||
#include "endpointvolume.h"
|
||||
#include "audiopolicy.h"
|
||||
#include "devpkey.h"
|
||||
#include "winreg.h"
|
||||
#include "spatialaudioclient.h"
|
||||
|
||||
#include "mmdevapi.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
|
||||
|
||||
DriverFuncs drvs;
|
||||
|
||||
const WCHAR drv_keyW[] = L"Software\\Wine\\Drivers";
|
||||
|
||||
static const char *get_priority_string(int prio)
|
||||
{
|
||||
switch(prio){
|
||||
case Priority_Unavailable:
|
||||
return "Unavailable";
|
||||
case Priority_Low:
|
||||
return "Low";
|
||||
case Priority_Neutral:
|
||||
return "Neutral";
|
||||
case Priority_Preferred:
|
||||
return "Preferred";
|
||||
}
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
static BOOL load_driver(const WCHAR *name, DriverFuncs *driver)
|
||||
{
|
||||
WCHAR driver_module[264];
|
||||
|
||||
lstrcpyW(driver_module, L"wine");
|
||||
lstrcatW(driver_module, name);
|
||||
lstrcatW(driver_module, L".drv");
|
||||
|
||||
TRACE("Attempting to load %s\n", wine_dbgstr_w(driver_module));
|
||||
|
||||
driver->module = LoadLibraryW(driver_module);
|
||||
if(!driver->module){
|
||||
TRACE("Unable to load %s: %lu\n", wine_dbgstr_w(driver_module),
|
||||
GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define LDFC(n) do { driver->p##n = (void*)GetProcAddress(driver->module, #n);\
|
||||
if(!driver->p##n) { FreeLibrary(driver->module); return FALSE; } } while(0)
|
||||
LDFC(GetPriority);
|
||||
LDFC(GetEndpointIDs);
|
||||
LDFC(GetAudioEndpoint);
|
||||
LDFC(GetAudioSessionManager);
|
||||
#undef LDFC
|
||||
|
||||
/* optional - do not fail if not found */
|
||||
driver->pGetPropValue = (void*)GetProcAddress(driver->module, "GetPropValue");
|
||||
|
||||
driver->priority = driver->pGetPriority();
|
||||
lstrcpyW(driver->module_name, driver_module);
|
||||
|
||||
TRACE("Successfully loaded %s with priority %s\n",
|
||||
wine_dbgstr_w(driver_module), get_priority_string(driver->priority));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI init_driver(INIT_ONCE *once, void *param, void **context)
|
||||
{
|
||||
static WCHAR default_list[] = L"pulse,alsa,oss,coreaudio";
|
||||
DriverFuncs driver;
|
||||
HKEY key;
|
||||
WCHAR reg_list[256], *p, *next, *driver_list = default_list;
|
||||
|
||||
if(RegOpenKeyW(HKEY_CURRENT_USER, drv_keyW, &key) == ERROR_SUCCESS){
|
||||
DWORD size = sizeof(reg_list);
|
||||
|
||||
if(RegQueryValueExW(key, L"Audio", 0, NULL, (BYTE*)reg_list, &size) == ERROR_SUCCESS){
|
||||
if(reg_list[0] == '\0'){
|
||||
TRACE("User explicitly chose no driver\n");
|
||||
RegCloseKey(key);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
driver_list = reg_list;
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
TRACE("Loading driver list %s\n", wine_dbgstr_w(driver_list));
|
||||
for(next = p = driver_list; next; p = next + 1){
|
||||
next = wcschr(p, ',');
|
||||
if(next)
|
||||
*next = '\0';
|
||||
|
||||
driver.priority = Priority_Unavailable;
|
||||
if(load_driver(p, &driver)){
|
||||
if(driver.priority == Priority_Unavailable)
|
||||
FreeLibrary(driver.module);
|
||||
else if(!drvs.module || driver.priority > drvs.priority){
|
||||
TRACE("Selecting driver %s with priority %s\n",
|
||||
wine_dbgstr_w(p), get_priority_string(driver.priority));
|
||||
if(drvs.module)
|
||||
FreeLibrary(drvs.module);
|
||||
drvs = driver;
|
||||
}else
|
||||
FreeLibrary(driver.module);
|
||||
}else
|
||||
TRACE("Failed to load driver %s\n", wine_dbgstr_w(p));
|
||||
|
||||
if(next)
|
||||
*next = ',';
|
||||
}
|
||||
|
||||
if (drvs.module != 0){
|
||||
load_devices_from_reg();
|
||||
load_driver_devices(eRender);
|
||||
load_driver_devices(eCapture);
|
||||
}
|
||||
|
||||
return drvs.module != 0;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
TRACE("(0x%p, %ld, %p)\n", hinstDLL, fdwReason, lpvReserved);
|
||||
|
||||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
if(lpvReserved)
|
||||
break;
|
||||
MMDevEnum_Free();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef HRESULT (*FnCreateInstance)(REFIID riid, LPVOID *ppobj);
|
||||
|
||||
typedef struct {
|
||||
IClassFactory IClassFactory_iface;
|
||||
REFCLSID rclsid;
|
||||
FnCreateInstance pfnCreateInstance;
|
||||
} IClassFactoryImpl;
|
||||
|
||||
static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
MMCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
|
||||
{
|
||||
IClassFactoryImpl *This = impl_from_IClassFactory(iface);
|
||||
TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
|
||||
if (ppobj == NULL)
|
||||
return E_POINTER;
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IClassFactory))
|
||||
{
|
||||
*ppobj = iface;
|
||||
IClassFactory_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI MMCF_AddRef(LPCLASSFACTORY iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI MMCF_Release(LPCLASSFACTORY iface)
|
||||
{
|
||||
/* static class, won't be freed */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MMCF_CreateInstance(
|
||||
LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pOuter,
|
||||
REFIID riid,
|
||||
LPVOID *ppobj)
|
||||
{
|
||||
IClassFactoryImpl *This = impl_from_IClassFactory(iface);
|
||||
TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
|
||||
|
||||
if (pOuter)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
if (ppobj == NULL) {
|
||||
WARN("invalid parameter\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return This->pfnCreateInstance(riid, ppobj);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MMCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
|
||||
{
|
||||
IClassFactoryImpl *This = impl_from_IClassFactory(iface);
|
||||
FIXME("(%p, %d) stub!\n", This, dolock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IClassFactoryVtbl MMCF_Vtbl = {
|
||||
MMCF_QueryInterface,
|
||||
MMCF_AddRef,
|
||||
MMCF_Release,
|
||||
MMCF_CreateInstance,
|
||||
MMCF_LockServer
|
||||
};
|
||||
|
||||
static IClassFactoryImpl MMDEVAPI_CF[] = {
|
||||
{ { &MMCF_Vtbl }, &CLSID_MMDeviceEnumerator, (FnCreateInstance)MMDevEnum_Create }
|
||||
};
|
||||
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
||||
unsigned int i = 0;
|
||||
TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||
|
||||
if(!InitOnceExecuteOnce(&init_once, init_driver, NULL, NULL)) {
|
||||
ERR("Driver initialization failed\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (ppv == NULL) {
|
||||
WARN("invalid parameter\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (!IsEqualIID(riid, &IID_IClassFactory) &&
|
||||
!IsEqualIID(riid, &IID_IUnknown)) {
|
||||
WARN("no interface for %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(MMDEVAPI_CF); ++i)
|
||||
{
|
||||
if (IsEqualGUID(rclsid, MMDEVAPI_CF[i].rclsid)) {
|
||||
IClassFactory_AddRef(&MMDEVAPI_CF[i].IClassFactory_iface);
|
||||
*ppv = &MMDEVAPI_CF[i];
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid),
|
||||
debugstr_guid(riid), ppv);
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
struct activate_async_op {
|
||||
IActivateAudioInterfaceAsyncOperation IActivateAudioInterfaceAsyncOperation_iface;
|
||||
LONG ref;
|
||||
|
||||
IActivateAudioInterfaceCompletionHandler *callback;
|
||||
HRESULT result_hr;
|
||||
IUnknown *result_iface;
|
||||
};
|
||||
|
||||
static struct activate_async_op *impl_from_IActivateAudioInterfaceAsyncOperation(IActivateAudioInterfaceAsyncOperation *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct activate_async_op, IActivateAudioInterfaceAsyncOperation_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI activate_async_op_QueryInterface(IActivateAudioInterfaceAsyncOperation *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
struct activate_async_op *This = impl_from_IActivateAudioInterfaceAsyncOperation(iface);
|
||||
|
||||
TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
|
||||
|
||||
if (!ppv)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IActivateAudioInterfaceAsyncOperation)) {
|
||||
*ppv = &This->IActivateAudioInterfaceAsyncOperation_iface;
|
||||
} else {
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI activate_async_op_AddRef(IActivateAudioInterfaceAsyncOperation *iface)
|
||||
{
|
||||
struct activate_async_op *This = impl_from_IActivateAudioInterfaceAsyncOperation(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) refcount now %li\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI activate_async_op_Release(IActivateAudioInterfaceAsyncOperation *iface)
|
||||
{
|
||||
struct activate_async_op *This = impl_from_IActivateAudioInterfaceAsyncOperation(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) refcount now %li\n", This, ref);
|
||||
if (!ref) {
|
||||
if(This->result_iface)
|
||||
IUnknown_Release(This->result_iface);
|
||||
IActivateAudioInterfaceCompletionHandler_Release(This->callback);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI activate_async_op_GetActivateResult(IActivateAudioInterfaceAsyncOperation *iface,
|
||||
HRESULT *result_hr, IUnknown **result_iface)
|
||||
{
|
||||
struct activate_async_op *This = impl_from_IActivateAudioInterfaceAsyncOperation(iface);
|
||||
|
||||
TRACE("(%p)->(%p, %p)\n", This, result_hr, result_iface);
|
||||
|
||||
*result_hr = This->result_hr;
|
||||
|
||||
if(This->result_hr == S_OK){
|
||||
*result_iface = This->result_iface;
|
||||
IUnknown_AddRef(*result_iface);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IActivateAudioInterfaceAsyncOperationVtbl IActivateAudioInterfaceAsyncOperation_vtbl = {
|
||||
activate_async_op_QueryInterface,
|
||||
activate_async_op_AddRef,
|
||||
activate_async_op_Release,
|
||||
activate_async_op_GetActivateResult,
|
||||
};
|
||||
|
||||
static DWORD WINAPI activate_async_threadproc(void *user)
|
||||
{
|
||||
struct activate_async_op *op = user;
|
||||
|
||||
SetThreadDescription(GetCurrentThread(), L"wine_mmdevapi_activate_async");
|
||||
|
||||
IActivateAudioInterfaceCompletionHandler_ActivateCompleted(op->callback, &op->IActivateAudioInterfaceAsyncOperation_iface);
|
||||
|
||||
IActivateAudioInterfaceAsyncOperation_Release(&op->IActivateAudioInterfaceAsyncOperation_iface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT get_mmdevice_by_activatepath(const WCHAR *path, IMMDevice **mmdev)
|
||||
{
|
||||
IMMDeviceEnumerator *devenum;
|
||||
HRESULT hr;
|
||||
|
||||
static const WCHAR DEVINTERFACE_AUDIO_RENDER_WSTR[] = L"{E6327CAD-DCEC-4949-AE8A-991E976A79D2}";
|
||||
static const WCHAR DEVINTERFACE_AUDIO_CAPTURE_WSTR[] = L"{2EEF81BE-33FA-4800-9670-1CD474972C3F}";
|
||||
static const WCHAR MMDEV_PATH_PREFIX[] = L"\\\\?\\SWD#MMDEVAPI#";
|
||||
|
||||
hr = MMDevEnum_Create(&IID_IMMDeviceEnumerator, (void**)&devenum);
|
||||
if (FAILED(hr)) {
|
||||
WARN("Failed to create MMDeviceEnumerator: %08lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!lstrcmpiW(path, DEVINTERFACE_AUDIO_RENDER_WSTR)){
|
||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, eRender, eMultimedia, mmdev);
|
||||
} else if (!lstrcmpiW(path, DEVINTERFACE_AUDIO_CAPTURE_WSTR)){
|
||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, eCapture, eMultimedia, mmdev);
|
||||
} else if (!memcmp(path, MMDEV_PATH_PREFIX, sizeof(MMDEV_PATH_PREFIX) - sizeof(WCHAR))) {
|
||||
WCHAR device_id[56]; /* == strlen("{0.0.1.00000000}.{fd47d9cc-4218-4135-9ce2-0c195c87405b}") + 1 */
|
||||
|
||||
lstrcpynW(device_id, path + (ARRAY_SIZE(MMDEV_PATH_PREFIX) - 1), ARRAY_SIZE(device_id));
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDevice(devenum, device_id, mmdev);
|
||||
} else {
|
||||
FIXME("Unrecognized device id format: %s\n", debugstr_w(path));
|
||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
WARN("Failed to get requested device (%s): %08lx\n", debugstr_w(path), hr);
|
||||
*mmdev = NULL;
|
||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
IMMDeviceEnumerator_Release(devenum);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ActivateAudioInterfaceAsync (MMDEVAPI.17)
|
||||
*/
|
||||
HRESULT WINAPI ActivateAudioInterfaceAsync(const WCHAR *path, REFIID riid,
|
||||
PROPVARIANT *params, IActivateAudioInterfaceCompletionHandler *done_handler,
|
||||
IActivateAudioInterfaceAsyncOperation **op_out)
|
||||
{
|
||||
struct activate_async_op *op;
|
||||
HANDLE ht;
|
||||
IMMDevice *mmdev;
|
||||
|
||||
TRACE("(%s, %s, %p, %p, %p)\n", debugstr_w(path), debugstr_guid(riid),
|
||||
params, done_handler, op_out);
|
||||
|
||||
op = HeapAlloc(GetProcessHeap(), 0, sizeof(*op));
|
||||
if (!op)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
op->ref = 2; /* returned ref and threadproc ref */
|
||||
op->IActivateAudioInterfaceAsyncOperation_iface.lpVtbl = &IActivateAudioInterfaceAsyncOperation_vtbl;
|
||||
op->callback = done_handler;
|
||||
IActivateAudioInterfaceCompletionHandler_AddRef(done_handler);
|
||||
|
||||
op->result_hr = get_mmdevice_by_activatepath(path, &mmdev);
|
||||
if (SUCCEEDED(op->result_hr)) {
|
||||
op->result_hr = IMMDevice_Activate(mmdev, riid, CLSCTX_INPROC_SERVER, params, (void**)&op->result_iface);
|
||||
IMMDevice_Release(mmdev);
|
||||
}else
|
||||
op->result_iface = NULL;
|
||||
|
||||
ht = CreateThread(NULL, 0, &activate_async_threadproc, op, 0, NULL);
|
||||
CloseHandle(ht);
|
||||
|
||||
*op_out = &op->IActivateAudioInterfaceAsyncOperation_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright 2009 Maarten Lankhorst
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "unixlib.h"
|
||||
#include <wine/unixlib.h>
|
||||
#include <wine/list.h>
|
||||
|
||||
extern HRESULT MMDevEnum_Create(REFIID riid, void **ppv);
|
||||
extern void MMDevEnum_Free(void);
|
||||
|
||||
typedef struct _DriverFuncs {
|
||||
HMODULE module;
|
||||
WCHAR module_name[64];
|
||||
int priority;
|
||||
|
||||
/* Returns a "priority" value for the driver. Highest priority wins.
|
||||
* If multiple drivers think they are valid, they will return a
|
||||
* priority value reflecting the likelihood that they are actually
|
||||
* valid. See enum _DriverPriority. */
|
||||
int (WINAPI *pGetPriority)(void);
|
||||
|
||||
/* ids gets an array of human-friendly endpoint names
|
||||
* keys gets an array of driver-specific stuff that is used
|
||||
* in GetAudioEndpoint to identify the endpoint
|
||||
* it is the caller's responsibility to free both arrays, and
|
||||
* all of the elements in both arrays with HeapFree() */
|
||||
HRESULT (WINAPI *pGetEndpointIDs)(EDataFlow flow, WCHAR ***ids,
|
||||
GUID **guids, UINT *num, UINT *default_index);
|
||||
HRESULT (WINAPI *pGetAudioEndpoint)(void *key, IMMDevice *dev,
|
||||
IAudioClient **out);
|
||||
HRESULT (WINAPI *pGetAudioSessionManager)(IMMDevice *device,
|
||||
IAudioSessionManager2 **out);
|
||||
HRESULT (WINAPI *pGetPropValue)(GUID *guid,
|
||||
const PROPERTYKEY *prop, PROPVARIANT *out);
|
||||
} DriverFuncs;
|
||||
|
||||
extern DriverFuncs drvs;
|
||||
|
||||
typedef struct MMDevice {
|
||||
IMMDevice IMMDevice_iface;
|
||||
IMMEndpoint IMMEndpoint_iface;
|
||||
LONG ref;
|
||||
|
||||
CRITICAL_SECTION crst;
|
||||
|
||||
EDataFlow flow;
|
||||
DWORD state;
|
||||
GUID devguid;
|
||||
WCHAR *drv_id;
|
||||
|
||||
struct list entry;
|
||||
} MMDevice;
|
||||
|
||||
extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv);
|
||||
extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv);
|
||||
extern HRESULT SpatialAudioClient_Create(IMMDevice *device, ISpatialAudioClient **out);
|
||||
|
||||
extern HRESULT load_devices_from_reg(void);
|
||||
extern HRESULT load_driver_devices(EDataFlow flow);
|
||||
|
||||
extern const WCHAR drv_keyW[];
|
|
@ -1,21 +0,0 @@
|
|||
2 stub @
|
||||
3 stub @
|
||||
4 stub @
|
||||
5 stub @
|
||||
6 stub @
|
||||
7 stub @
|
||||
8 stub @
|
||||
9 stub @
|
||||
10 stub @
|
||||
11 stub @
|
||||
12 stub @
|
||||
13 stub @
|
||||
14 stub @
|
||||
15 stub @
|
||||
16 stub @
|
||||
17 stdcall ActivateAudioInterfaceAsync( wstr ptr ptr ptr ptr )
|
||||
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject( ptr ptr ptr )
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* COM Classes for mmdevapi
|
||||
*
|
||||
* Copyright 2010 Alexandre Julliard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma makedep register
|
||||
|
||||
[
|
||||
helpstring("MMDeviceEnumerator class"),
|
||||
threading(both),
|
||||
uuid(bcde0395-e52f-467c-8e3d-c4579291692e)
|
||||
]
|
||||
coclass MMDeviceEnumerator { interface IMMDeviceEnumerator; }
|
|
@ -1,976 +0,0 @@
|
|||
/*
|
||||
* Copyright 2020 Andrew Eikum for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/heap.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
#include "ole2.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "mmsystem.h"
|
||||
#include "audioclient.h"
|
||||
#include "endpointvolume.h"
|
||||
#include "audiopolicy.h"
|
||||
#include "spatialaudioclient.h"
|
||||
|
||||
#include "mmdevapi.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
|
||||
|
||||
static UINT32 AudioObjectType_to_index(AudioObjectType type)
|
||||
{
|
||||
UINT32 o = 0;
|
||||
while(type){
|
||||
type >>= 1;
|
||||
++o;
|
||||
}
|
||||
return o - 2;
|
||||
}
|
||||
|
||||
typedef struct SpatialAudioImpl SpatialAudioImpl;
|
||||
typedef struct SpatialAudioStreamImpl SpatialAudioStreamImpl;
|
||||
typedef struct SpatialAudioObjectImpl SpatialAudioObjectImpl;
|
||||
|
||||
struct SpatialAudioObjectImpl {
|
||||
ISpatialAudioObject ISpatialAudioObject_iface;
|
||||
LONG ref;
|
||||
|
||||
SpatialAudioStreamImpl *sa_stream;
|
||||
AudioObjectType type;
|
||||
UINT32 static_idx;
|
||||
|
||||
float *buf;
|
||||
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
struct SpatialAudioStreamImpl {
|
||||
ISpatialAudioObjectRenderStream ISpatialAudioObjectRenderStream_iface;
|
||||
LONG ref;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
SpatialAudioImpl *sa_client;
|
||||
SpatialAudioObjectRenderStreamActivationParams params;
|
||||
|
||||
IAudioClient *client;
|
||||
IAudioRenderClient *render;
|
||||
|
||||
UINT32 period_frames, update_frames;
|
||||
WAVEFORMATEXTENSIBLE stream_fmtex;
|
||||
|
||||
float *buf;
|
||||
|
||||
UINT32 static_object_map[17];
|
||||
|
||||
struct list objects;
|
||||
};
|
||||
|
||||
struct SpatialAudioImpl {
|
||||
ISpatialAudioClient ISpatialAudioClient_iface;
|
||||
IAudioFormatEnumerator IAudioFormatEnumerator_iface;
|
||||
IMMDevice *mmdev;
|
||||
LONG ref;
|
||||
WAVEFORMATEXTENSIBLE object_fmtex;
|
||||
};
|
||||
|
||||
static inline SpatialAudioObjectImpl *impl_from_ISpatialAudioObject(ISpatialAudioObject *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, SpatialAudioObjectImpl, ISpatialAudioObject_iface);
|
||||
}
|
||||
|
||||
static inline SpatialAudioStreamImpl *impl_from_ISpatialAudioObjectRenderStream(ISpatialAudioObjectRenderStream *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, SpatialAudioStreamImpl, ISpatialAudioObjectRenderStream_iface);
|
||||
}
|
||||
|
||||
static inline SpatialAudioImpl *impl_from_ISpatialAudioClient(ISpatialAudioClient *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, SpatialAudioImpl, ISpatialAudioClient_iface);
|
||||
}
|
||||
|
||||
static inline SpatialAudioImpl *impl_from_IAudioFormatEnumerator(IAudioFormatEnumerator *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, SpatialAudioImpl, IAudioFormatEnumerator_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAO_QueryInterface(ISpatialAudioObject *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
|
||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
|
||||
|
||||
if (!ppv)
|
||||
return E_POINTER;
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_ISpatialAudioObjectBase) ||
|
||||
IsEqualIID(riid, &IID_ISpatialAudioObject)) {
|
||||
*ppv = &This->ISpatialAudioObject_iface;
|
||||
}
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*ppv);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAO_AddRef(ISpatialAudioObject *iface)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAO_Release(ISpatialAudioObject *iface)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
if(!ref){
|
||||
EnterCriticalSection(&This->sa_stream->lock);
|
||||
list_remove(&This->entry);
|
||||
LeaveCriticalSection(&This->sa_stream->lock);
|
||||
|
||||
ISpatialAudioObjectRenderStream_Release(&This->sa_stream->ISpatialAudioObjectRenderStream_iface);
|
||||
heap_free(This->buf);
|
||||
heap_free(This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAO_GetBuffer(ISpatialAudioObject *iface,
|
||||
BYTE **buffer, UINT32 *bytes)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
|
||||
TRACE("(%p)->(%p, %p)\n", This, buffer, bytes);
|
||||
|
||||
EnterCriticalSection(&This->sa_stream->lock);
|
||||
|
||||
if(This->sa_stream->update_frames == ~0){
|
||||
LeaveCriticalSection(&This->sa_stream->lock);
|
||||
return SPTLAUDCLNT_E_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
*buffer = (BYTE *)This->buf;
|
||||
*bytes = This->sa_stream->update_frames *
|
||||
This->sa_stream->sa_client->object_fmtex.Format.nBlockAlign;
|
||||
|
||||
LeaveCriticalSection(&This->sa_stream->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAO_SetEndOfStream(ISpatialAudioObject *iface, UINT32 frames)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
FIXME("(%p)->(%u)\n", This, frames);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAO_IsActive(ISpatialAudioObject *iface, BOOL *active)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
FIXME("(%p)->(%p)\n", This, active);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAO_GetAudioObjectType(ISpatialAudioObject *iface,
|
||||
AudioObjectType *type)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, type);
|
||||
|
||||
*type = This->type;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAO_SetPosition(ISpatialAudioObject *iface, float x,
|
||||
float y, float z)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
FIXME("(%p)->(%f, %f, %f)\n", This, x, y, z);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAO_SetVolume(ISpatialAudioObject *iface, float vol)
|
||||
{
|
||||
SpatialAudioObjectImpl *This = impl_from_ISpatialAudioObject(iface);
|
||||
FIXME("(%p)->(%f)\n", This, vol);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static ISpatialAudioObjectVtbl ISpatialAudioObject_vtbl = {
|
||||
SAO_QueryInterface,
|
||||
SAO_AddRef,
|
||||
SAO_Release,
|
||||
SAO_GetBuffer,
|
||||
SAO_SetEndOfStream,
|
||||
SAO_IsActive,
|
||||
SAO_GetAudioObjectType,
|
||||
SAO_SetPosition,
|
||||
SAO_SetVolume,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI SAORS_QueryInterface(ISpatialAudioObjectRenderStream *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
|
||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
|
||||
|
||||
if (!ppv)
|
||||
return E_POINTER;
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_ISpatialAudioObjectRenderStreamBase) ||
|
||||
IsEqualIID(riid, &IID_ISpatialAudioObjectRenderStream)) {
|
||||
*ppv = &This->ISpatialAudioObjectRenderStream_iface;
|
||||
}
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*ppv);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAORS_AddRef(ISpatialAudioObjectRenderStream *iface)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAORS_Release(ISpatialAudioObjectRenderStream *iface)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
if(!ref){
|
||||
IAudioClient_Stop(This->client);
|
||||
if(This->update_frames != ~0 && This->update_frames > 0)
|
||||
IAudioRenderClient_ReleaseBuffer(This->render, This->update_frames, 0);
|
||||
IAudioRenderClient_Release(This->render);
|
||||
IAudioClient_Release(This->client);
|
||||
if(This->params.NotifyObject)
|
||||
ISpatialAudioObjectRenderStreamNotify_Release(This->params.NotifyObject);
|
||||
heap_free((void*)This->params.ObjectFormat);
|
||||
CloseHandle(This->params.EventHandle);
|
||||
DeleteCriticalSection(&This->lock);
|
||||
ISpatialAudioClient_Release(&This->sa_client->ISpatialAudioClient_iface);
|
||||
heap_free(This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_GetAvailableDynamicObjectCount(
|
||||
ISpatialAudioObjectRenderStream *iface, UINT32 *count)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
FIXME("(%p)->(%p)\n", This, count);
|
||||
|
||||
*count = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_GetService(ISpatialAudioObjectRenderStream *iface,
|
||||
REFIID riid, void **service)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
FIXME("(%p)->(%s, %p)\n", This, debugstr_guid(riid), service);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_Start(ISpatialAudioObjectRenderStream *iface)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->()\n", This);
|
||||
|
||||
hr = IAudioClient_Start(This->client);
|
||||
if(FAILED(hr)){
|
||||
WARN("IAudioClient::Start failed: %08lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_Stop(ISpatialAudioObjectRenderStream *iface)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->()\n", This);
|
||||
|
||||
hr = IAudioClient_Stop(This->client);
|
||||
if(FAILED(hr)){
|
||||
WARN("IAudioClient::Stop failed: %08lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_Reset(ISpatialAudioObjectRenderStream *iface)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
FIXME("(%p)->()\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_BeginUpdatingAudioObjects(ISpatialAudioObjectRenderStream *iface,
|
||||
UINT32 *dyn_count, UINT32 *frames)
|
||||
{
|
||||
static BOOL fixme_once = FALSE;
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
SpatialAudioObjectImpl *object;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%p, %p)\n", This, dyn_count, frames);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if(This->update_frames != ~0){
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return SPTLAUDCLNT_E_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
This->update_frames = This->period_frames;
|
||||
|
||||
if(This->update_frames > 0){
|
||||
hr = IAudioRenderClient_GetBuffer(This->render, This->update_frames, (BYTE **)&This->buf);
|
||||
if(FAILED(hr)){
|
||||
WARN("GetBuffer failed: %08lx\n", hr);
|
||||
This->update_frames = ~0;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(object, &This->objects, SpatialAudioObjectImpl, entry){
|
||||
memset(object->buf, 0, This->update_frames * This->sa_client->object_fmtex.Format.nBlockAlign);
|
||||
}
|
||||
}else if (!fixme_once){
|
||||
fixme_once = TRUE;
|
||||
FIXME("Zero frame update.\n");
|
||||
}
|
||||
|
||||
*dyn_count = 0;
|
||||
*frames = This->update_frames;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void mix_static_object(SpatialAudioStreamImpl *stream, SpatialAudioObjectImpl *object)
|
||||
{
|
||||
float *in = object->buf, *out;
|
||||
UINT32 i;
|
||||
if(object->static_idx == ~0 ||
|
||||
stream->static_object_map[object->static_idx] == ~0){
|
||||
WARN("Got unmapped static object?! Not mixing. Type: 0x%x\n", object->type);
|
||||
return;
|
||||
}
|
||||
out = stream->buf + stream->static_object_map[object->static_idx];
|
||||
for(i = 0; i < stream->update_frames; ++i){
|
||||
*out += *in;
|
||||
++in;
|
||||
out += stream->stream_fmtex.Format.nChannels;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_EndUpdatingAudioObjects(ISpatialAudioObjectRenderStream *iface)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
SpatialAudioObjectImpl *object;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->()\n", This);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if(This->update_frames == ~0){
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return SPTLAUDCLNT_E_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
if(This->update_frames > 0){
|
||||
LIST_FOR_EACH_ENTRY(object, &This->objects, SpatialAudioObjectImpl, entry){
|
||||
if(object->type != AudioObjectType_Dynamic)
|
||||
mix_static_object(This, object);
|
||||
else
|
||||
WARN("Don't know how to mix dynamic object yet. %p\n", object);
|
||||
}
|
||||
|
||||
hr = IAudioRenderClient_ReleaseBuffer(This->render, This->update_frames, 0);
|
||||
if(FAILED(hr))
|
||||
WARN("ReleaseBuffer failed: %08lx\n", hr);
|
||||
}
|
||||
|
||||
This->update_frames = ~0;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAORS_ActivateSpatialAudioObject(ISpatialAudioObjectRenderStream *iface,
|
||||
AudioObjectType type, ISpatialAudioObject **object)
|
||||
{
|
||||
SpatialAudioStreamImpl *This = impl_from_ISpatialAudioObjectRenderStream(iface);
|
||||
SpatialAudioObjectImpl *obj;
|
||||
|
||||
TRACE("(%p)->(0x%x, %p)\n", This, type, object);
|
||||
|
||||
if(type == AudioObjectType_Dynamic)
|
||||
return SPTLAUDCLNT_E_NO_MORE_OBJECTS;
|
||||
|
||||
if(type & ~This->params.StaticObjectTypeMask)
|
||||
return SPTLAUDCLNT_E_STATIC_OBJECT_NOT_AVAILABLE;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(obj, &This->objects, SpatialAudioObjectImpl, entry){
|
||||
if(obj->static_idx == AudioObjectType_to_index(type))
|
||||
return SPTLAUDCLNT_E_OBJECT_ALREADY_ACTIVE;
|
||||
}
|
||||
|
||||
obj = heap_alloc_zero(sizeof(*obj));
|
||||
obj->ISpatialAudioObject_iface.lpVtbl = &ISpatialAudioObject_vtbl;
|
||||
obj->ref = 1;
|
||||
obj->type = type;
|
||||
if(type == AudioObjectType_None){
|
||||
FIXME("AudioObjectType_None not implemented yet!\n");
|
||||
obj->static_idx = ~0;
|
||||
}else{
|
||||
obj->static_idx = AudioObjectType_to_index(type);
|
||||
}
|
||||
|
||||
obj->sa_stream = This;
|
||||
SAORS_AddRef(&This->ISpatialAudioObjectRenderStream_iface);
|
||||
|
||||
obj->buf = heap_alloc_zero(This->period_frames * This->sa_client->object_fmtex.Format.nBlockAlign);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
list_add_tail(&This->objects, &obj->entry);
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
*object = &obj->ISpatialAudioObject_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ISpatialAudioObjectRenderStreamVtbl ISpatialAudioObjectRenderStream_vtbl = {
|
||||
SAORS_QueryInterface,
|
||||
SAORS_AddRef,
|
||||
SAORS_Release,
|
||||
SAORS_GetAvailableDynamicObjectCount,
|
||||
SAORS_GetService,
|
||||
SAORS_Start,
|
||||
SAORS_Stop,
|
||||
SAORS_Reset,
|
||||
SAORS_BeginUpdatingAudioObjects,
|
||||
SAORS_EndUpdatingAudioObjects,
|
||||
SAORS_ActivateSpatialAudioObject,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI SAC_QueryInterface(ISpatialAudioClient *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
|
||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
|
||||
|
||||
if (!ppv)
|
||||
return E_POINTER;
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_ISpatialAudioClient)) {
|
||||
*ppv = &This->ISpatialAudioClient_iface;
|
||||
}
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*ppv);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAC_AddRef(ISpatialAudioClient *iface)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAC_Release(ISpatialAudioClient *iface)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) new ref %lu\n", This, ref);
|
||||
if (!ref) {
|
||||
IMMDevice_Release(This->mmdev);
|
||||
heap_free(This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_GetStaticObjectPosition(ISpatialAudioClient *iface,
|
||||
AudioObjectType type, float *x, float *y, float *z)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
FIXME("(%p)->(0x%x, %p, %p, %p)\n", This, type, x, y, z);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_GetNativeStaticObjectTypeMask(ISpatialAudioClient *iface,
|
||||
AudioObjectType *mask)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
FIXME("(%p)->(%p)\n", This, mask);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_GetMaxDynamicObjectCount(ISpatialAudioClient *iface,
|
||||
UINT32 *value)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
FIXME("(%p)->(%p)\n", This, value);
|
||||
|
||||
*value = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_GetSupportedAudioObjectFormatEnumerator(
|
||||
ISpatialAudioClient *iface, IAudioFormatEnumerator **enumerator)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, enumerator);
|
||||
|
||||
*enumerator = &This->IAudioFormatEnumerator_iface;
|
||||
SAC_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_GetMaxFrameCount(ISpatialAudioClient *iface,
|
||||
const WAVEFORMATEX *format, UINT32 *count)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
|
||||
/* FIXME: should get device period from the device */
|
||||
static const REFERENCE_TIME period = 100000;
|
||||
|
||||
TRACE("(%p)->(%p, %p)\n", This, format, count);
|
||||
|
||||
*count = MulDiv(period, format->nSamplesPerSec, 10000000);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_IsAudioObjectFormatSupported(ISpatialAudioClient *iface,
|
||||
const WAVEFORMATEX *format)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
FIXME("(%p)->(%p)\n", This, format);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_IsSpatialAudioStreamAvailable(ISpatialAudioClient *iface,
|
||||
REFIID stream_uuid, const PROPVARIANT *info)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
FIXME("(%p)->(%s, %p)\n", This, debugstr_guid(stream_uuid), info);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static WAVEFORMATEX *clone_fmtex(const WAVEFORMATEX *src)
|
||||
{
|
||||
WAVEFORMATEX *r = heap_alloc(sizeof(WAVEFORMATEX) + src->cbSize);
|
||||
memcpy(r, src, sizeof(WAVEFORMATEX) + src->cbSize);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const char *debugstr_fmtex(const WAVEFORMATEX *fmt)
|
||||
{
|
||||
static char buf[2048];
|
||||
if(fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
|
||||
const WAVEFORMATEXTENSIBLE *fmtex = (const WAVEFORMATEXTENSIBLE *)fmt;
|
||||
snprintf(buf, sizeof(buf), "tag: 0x%x (%s), ch: %u (mask: 0x%lx), rate: %lu, depth: %u",
|
||||
fmt->wFormatTag, debugstr_guid(&fmtex->SubFormat),
|
||||
fmt->nChannels, fmtex->dwChannelMask, fmt->nSamplesPerSec,
|
||||
fmt->wBitsPerSample);
|
||||
}else{
|
||||
snprintf(buf, sizeof(buf), "tag: 0x%x, ch: %u, rate: %lu, depth: %u",
|
||||
fmt->wFormatTag, fmt->nChannels, fmt->nSamplesPerSec,
|
||||
fmt->wBitsPerSample);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void static_mask_to_channels(AudioObjectType static_mask, WORD *count, DWORD *mask, UINT32 *map)
|
||||
{
|
||||
UINT32 out_chan = 0, map_idx = 0;
|
||||
*count = 0;
|
||||
*mask = 0;
|
||||
#define CONVERT_MASK(f, t) \
|
||||
if(static_mask & f){ \
|
||||
*count += 1; \
|
||||
*mask |= t; \
|
||||
map[map_idx++] = out_chan++; \
|
||||
TRACE("mapping 0x%x to %u\n", f, out_chan - 1); \
|
||||
}else{ \
|
||||
map[map_idx++] = ~0; \
|
||||
}
|
||||
CONVERT_MASK(AudioObjectType_FrontLeft, SPEAKER_FRONT_LEFT);
|
||||
CONVERT_MASK(AudioObjectType_FrontRight, SPEAKER_FRONT_RIGHT);
|
||||
CONVERT_MASK(AudioObjectType_FrontCenter, SPEAKER_FRONT_CENTER);
|
||||
CONVERT_MASK(AudioObjectType_LowFrequency, SPEAKER_LOW_FREQUENCY);
|
||||
CONVERT_MASK(AudioObjectType_SideLeft, SPEAKER_SIDE_LEFT);
|
||||
CONVERT_MASK(AudioObjectType_SideRight, SPEAKER_SIDE_RIGHT);
|
||||
CONVERT_MASK(AudioObjectType_BackLeft, SPEAKER_BACK_LEFT);
|
||||
CONVERT_MASK(AudioObjectType_BackRight, SPEAKER_BACK_RIGHT);
|
||||
CONVERT_MASK(AudioObjectType_TopFrontLeft, SPEAKER_TOP_FRONT_LEFT);
|
||||
CONVERT_MASK(AudioObjectType_TopFrontRight, SPEAKER_TOP_FRONT_RIGHT);
|
||||
CONVERT_MASK(AudioObjectType_TopBackLeft, SPEAKER_TOP_BACK_LEFT);
|
||||
CONVERT_MASK(AudioObjectType_TopBackRight, SPEAKER_TOP_BACK_RIGHT);
|
||||
CONVERT_MASK(AudioObjectType_BackCenter, SPEAKER_BACK_CENTER);
|
||||
}
|
||||
|
||||
static HRESULT activate_stream(SpatialAudioStreamImpl *stream)
|
||||
{
|
||||
WAVEFORMATEXTENSIBLE *object_fmtex = (WAVEFORMATEXTENSIBLE *)stream->params.ObjectFormat;
|
||||
HRESULT hr;
|
||||
REFERENCE_TIME period;
|
||||
|
||||
if(!(object_fmtex->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
|
||||
(object_fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
|
||||
IsEqualGUID(&object_fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))){
|
||||
FIXME("Only float formats are supported for now\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
hr = IMMDevice_Activate(stream->sa_client->mmdev, &IID_IAudioClient,
|
||||
CLSCTX_INPROC_SERVER, NULL, (void**)&stream->client);
|
||||
if(FAILED(hr)){
|
||||
WARN("Activate failed: %08lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IAudioClient_GetDevicePeriod(stream->client, &period, NULL);
|
||||
if(FAILED(hr)){
|
||||
WARN("GetDevicePeriod failed: %08lx\n", hr);
|
||||
IAudioClient_Release(stream->client);
|
||||
return hr;
|
||||
}
|
||||
|
||||
stream->stream_fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
static_mask_to_channels(stream->params.StaticObjectTypeMask,
|
||||
&stream->stream_fmtex.Format.nChannels, &stream->stream_fmtex.dwChannelMask,
|
||||
stream->static_object_map);
|
||||
stream->stream_fmtex.Format.nSamplesPerSec = stream->params.ObjectFormat->nSamplesPerSec;
|
||||
stream->stream_fmtex.Format.wBitsPerSample = stream->params.ObjectFormat->wBitsPerSample;
|
||||
stream->stream_fmtex.Format.nBlockAlign = (stream->stream_fmtex.Format.nChannels * stream->stream_fmtex.Format.wBitsPerSample) / 8;
|
||||
stream->stream_fmtex.Format.nAvgBytesPerSec = stream->stream_fmtex.Format.nSamplesPerSec * stream->stream_fmtex.Format.nBlockAlign;
|
||||
stream->stream_fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
|
||||
stream->stream_fmtex.Samples.wValidBitsPerSample = stream->stream_fmtex.Format.wBitsPerSample;
|
||||
stream->stream_fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||
|
||||
hr = IAudioClient_Initialize(stream->client, AUDCLNT_SHAREMODE_SHARED,
|
||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
||||
period, 0, &stream->stream_fmtex.Format, NULL);
|
||||
if(FAILED(hr)){
|
||||
WARN("Initialize failed: %08lx\n", hr);
|
||||
IAudioClient_Release(stream->client);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IAudioClient_SetEventHandle(stream->client, stream->params.EventHandle);
|
||||
if(FAILED(hr)){
|
||||
WARN("SetEventHandle failed: %08lx\n", hr);
|
||||
IAudioClient_Release(stream->client);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IAudioClient_GetService(stream->client, &IID_IAudioRenderClient, (void**)&stream->render);
|
||||
if(FAILED(hr)){
|
||||
WARN("GetService(AudioRenderClient) failed: %08lx\n", hr);
|
||||
IAudioClient_Release(stream->client);
|
||||
return hr;
|
||||
}
|
||||
|
||||
stream->period_frames = MulDiv(period, stream->stream_fmtex.Format.nSamplesPerSec, 10000000);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAC_ActivateSpatialAudioStream(ISpatialAudioClient *iface,
|
||||
const PROPVARIANT *prop, REFIID riid, void **stream)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_ISpatialAudioClient(iface);
|
||||
SpatialAudioObjectRenderStreamActivationParams *params;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), stream);
|
||||
|
||||
if(IsEqualIID(riid, &IID_ISpatialAudioObjectRenderStream)){
|
||||
SpatialAudioStreamImpl *obj;
|
||||
|
||||
if(prop &&
|
||||
(prop->vt != VT_BLOB ||
|
||||
prop->blob.cbSize != sizeof(SpatialAudioObjectRenderStreamActivationParams))){
|
||||
WARN("Got invalid params\n");
|
||||
*stream = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
params = (SpatialAudioObjectRenderStreamActivationParams*) prop->blob.pBlobData;
|
||||
|
||||
if(params->StaticObjectTypeMask & AudioObjectType_Dynamic){
|
||||
*stream = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if(params->EventHandle == INVALID_HANDLE_VALUE ||
|
||||
params->EventHandle == 0){
|
||||
*stream = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if(!params->ObjectFormat ||
|
||||
memcmp(params->ObjectFormat, &This->object_fmtex.Format, sizeof(*params->ObjectFormat) + params->ObjectFormat->cbSize)){
|
||||
*stream = NULL;
|
||||
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
|
||||
obj = heap_alloc_zero(sizeof(SpatialAudioStreamImpl));
|
||||
|
||||
obj->ISpatialAudioObjectRenderStream_iface.lpVtbl = &ISpatialAudioObjectRenderStream_vtbl;
|
||||
obj->ref = 1;
|
||||
memcpy(&obj->params, params, sizeof(obj->params));
|
||||
|
||||
obj->update_frames = ~0;
|
||||
|
||||
InitializeCriticalSection(&obj->lock);
|
||||
list_init(&obj->objects);
|
||||
|
||||
obj->sa_client = This;
|
||||
SAC_AddRef(&This->ISpatialAudioClient_iface);
|
||||
|
||||
obj->params.ObjectFormat = clone_fmtex(obj->params.ObjectFormat);
|
||||
|
||||
DuplicateHandle(GetCurrentProcess(), obj->params.EventHandle,
|
||||
GetCurrentProcess(), &obj->params.EventHandle, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
|
||||
if(obj->params.NotifyObject)
|
||||
ISpatialAudioObjectRenderStreamNotify_AddRef(obj->params.NotifyObject);
|
||||
|
||||
if(TRACE_ON(mmdevapi)){
|
||||
TRACE("ObjectFormat: {%s}\n", debugstr_fmtex(obj->params.ObjectFormat));
|
||||
TRACE("StaticObjectTypeMask: 0x%x\n", obj->params.StaticObjectTypeMask);
|
||||
TRACE("MinDynamicObjectCount: 0x%x\n", obj->params.MinDynamicObjectCount);
|
||||
TRACE("MaxDynamicObjectCount: 0x%x\n", obj->params.MaxDynamicObjectCount);
|
||||
TRACE("Category: 0x%x\n", obj->params.Category);
|
||||
TRACE("EventHandle: %p\n", obj->params.EventHandle);
|
||||
TRACE("NotifyObject: %p\n", obj->params.NotifyObject);
|
||||
}
|
||||
|
||||
hr = activate_stream(obj);
|
||||
if(FAILED(hr)){
|
||||
if(obj->params.NotifyObject)
|
||||
ISpatialAudioObjectRenderStreamNotify_Release(obj->params.NotifyObject);
|
||||
DeleteCriticalSection(&obj->lock);
|
||||
heap_free((void*)obj->params.ObjectFormat);
|
||||
CloseHandle(obj->params.EventHandle);
|
||||
ISpatialAudioClient_Release(&obj->sa_client->ISpatialAudioClient_iface);
|
||||
heap_free(obj);
|
||||
*stream = NULL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
*stream = &obj->ISpatialAudioObjectRenderStream_iface;
|
||||
}else{
|
||||
FIXME("Unsupported audio stream IID: %s\n", debugstr_guid(riid));
|
||||
*stream = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ISpatialAudioClientVtbl ISpatialAudioClient_vtbl = {
|
||||
SAC_QueryInterface,
|
||||
SAC_AddRef,
|
||||
SAC_Release,
|
||||
SAC_GetStaticObjectPosition,
|
||||
SAC_GetNativeStaticObjectTypeMask,
|
||||
SAC_GetMaxDynamicObjectCount,
|
||||
SAC_GetSupportedAudioObjectFormatEnumerator,
|
||||
SAC_GetMaxFrameCount,
|
||||
SAC_IsAudioObjectFormatSupported,
|
||||
SAC_IsSpatialAudioStreamAvailable,
|
||||
SAC_ActivateSpatialAudioStream,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI SAOFE_QueryInterface(IAudioFormatEnumerator *iface,
|
||||
REFIID riid, void **ppvObject)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_IAudioFormatEnumerator(iface);
|
||||
return SAC_QueryInterface(&This->ISpatialAudioClient_iface, riid, ppvObject);
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAOFE_AddRef(IAudioFormatEnumerator *iface)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_IAudioFormatEnumerator(iface);
|
||||
return SAC_AddRef(&This->ISpatialAudioClient_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI SAOFE_Release(IAudioFormatEnumerator *iface)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_IAudioFormatEnumerator(iface);
|
||||
return SAC_Release(&This->ISpatialAudioClient_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAOFE_GetCount(IAudioFormatEnumerator *iface, UINT32 *count)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_IAudioFormatEnumerator(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, count);
|
||||
|
||||
*count = 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI SAOFE_GetFormat(IAudioFormatEnumerator *iface,
|
||||
UINT32 index, WAVEFORMATEX **format)
|
||||
{
|
||||
SpatialAudioImpl *This = impl_from_IAudioFormatEnumerator(iface);
|
||||
|
||||
TRACE("(%p)->(%u, %p)\n", This, index, format);
|
||||
|
||||
if(index > 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*format = &This->object_fmtex.Format;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IAudioFormatEnumeratorVtbl IAudioFormatEnumerator_vtbl = {
|
||||
SAOFE_QueryInterface,
|
||||
SAOFE_AddRef,
|
||||
SAOFE_Release,
|
||||
SAOFE_GetCount,
|
||||
SAOFE_GetFormat,
|
||||
};
|
||||
|
||||
HRESULT SpatialAudioClient_Create(IMMDevice *mmdev, ISpatialAudioClient **out)
|
||||
{
|
||||
SpatialAudioImpl *obj;
|
||||
IAudioClient *aclient;
|
||||
WAVEFORMATEX *closest;
|
||||
HRESULT hr;
|
||||
|
||||
obj = heap_alloc_zero(sizeof(*obj));
|
||||
|
||||
obj->ref = 1;
|
||||
obj->ISpatialAudioClient_iface.lpVtbl = &ISpatialAudioClient_vtbl;
|
||||
obj->IAudioFormatEnumerator_iface.lpVtbl = &IAudioFormatEnumerator_vtbl;
|
||||
|
||||
obj->object_fmtex.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
obj->object_fmtex.Format.nChannels = 1;
|
||||
obj->object_fmtex.Format.nSamplesPerSec = 48000;
|
||||
obj->object_fmtex.Format.wBitsPerSample = sizeof(float) * 8;
|
||||
obj->object_fmtex.Format.nBlockAlign = (obj->object_fmtex.Format.nChannels * obj->object_fmtex.Format.wBitsPerSample) / 8;
|
||||
obj->object_fmtex.Format.nAvgBytesPerSec = obj->object_fmtex.Format.nSamplesPerSec * obj->object_fmtex.Format.nBlockAlign;
|
||||
obj->object_fmtex.Format.cbSize = 0;
|
||||
|
||||
hr = IMMDevice_Activate(mmdev, &IID_IAudioClient,
|
||||
CLSCTX_INPROC_SERVER, NULL, (void**)&aclient);
|
||||
if(FAILED(hr)){
|
||||
WARN("Activate failed: %08lx\n", hr);
|
||||
heap_free(obj);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IAudioClient_IsFormatSupported(aclient, AUDCLNT_SHAREMODE_SHARED, &obj->object_fmtex.Format, &closest);
|
||||
|
||||
IAudioClient_Release(aclient);
|
||||
|
||||
if(hr == S_FALSE){
|
||||
if(sizeof(WAVEFORMATEX) + closest->cbSize > sizeof(obj->object_fmtex)){
|
||||
ERR("Returned format too large: %s\n", debugstr_fmtex(closest));
|
||||
CoTaskMemFree(closest);
|
||||
heap_free(obj);
|
||||
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||
}else if(!((closest->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
|
||||
(closest->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
|
||||
IsEqualGUID(&((WAVEFORMATEXTENSIBLE *)closest)->SubFormat,
|
||||
&KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))) &&
|
||||
closest->wBitsPerSample == 32)){
|
||||
ERR("Returned format not 32-bit float: %s\n", debugstr_fmtex(closest));
|
||||
CoTaskMemFree(closest);
|
||||
heap_free(obj);
|
||||
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
WARN("The audio stack doesn't support 48kHz 32bit float. Using the closest match. Audio may be glitchy. %s\n", debugstr_fmtex(closest));
|
||||
memcpy(&obj->object_fmtex,
|
||||
closest,
|
||||
sizeof(WAVEFORMATEX) + closest->cbSize);
|
||||
CoTaskMemFree(closest);
|
||||
} else if(hr != S_OK){
|
||||
WARN("Checking supported formats failed: %08lx\n", hr);
|
||||
heap_free(obj);
|
||||
return hr;
|
||||
}
|
||||
|
||||
obj->mmdev = mmdev;
|
||||
IMMDevice_AddRef(mmdev);
|
||||
|
||||
*out = &obj->ISpatialAudioClient_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
TESTDLL = mmdevapi.dll
|
||||
IMPORTS = ole32 version user32 advapi32 winmm
|
||||
|
||||
C_SRCS = \
|
||||
capture.c \
|
||||
dependency.c \
|
||||
mmdevenum.c \
|
||||
propstore.c \
|
||||
render.c \
|
||||
spatialaudio.c
|
File diff suppressed because it is too large
Load diff
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright 2009 Maarten Lankhorst
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#ifdef STANDALONE
|
||||
#include "initguid.h"
|
||||
#endif
|
||||
|
||||
#include "unknwn.h"
|
||||
#include "uuids.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "dshow.h"
|
||||
#include "dsound.h"
|
||||
|
||||
START_TEST(dependency)
|
||||
{
|
||||
HRESULT hr;
|
||||
IMMDeviceEnumerator *mme = NULL;
|
||||
IMMDevice *dev = NULL;
|
||||
IDirectSound8 *ds8 = NULL;
|
||||
IBaseFilter *bf = NULL;
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("mmdevapi not available: 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eRender, eMultimedia, &dev);
|
||||
ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08lx\n", hr);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
if (hr == E_NOTFOUND)
|
||||
skip("No sound card available\n");
|
||||
else
|
||||
skip("GetDefaultAudioEndpoint returns 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ok(!GetModuleHandleA("dsound.dll"), "dsound.dll was already loaded!\n");
|
||||
|
||||
hr = IMMDevice_Activate(dev, &IID_IDirectSound8, CLSCTX_INPROC_SERVER, NULL, (void**)&ds8);
|
||||
ok(hr == S_OK, "Activating ds8 interface failed: 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
ok(GetModuleHandleA("dsound.dll") != NULL, "dsound.dll not loaded!\n");
|
||||
ok(ds8 != NULL, "ds8 pointer is null\n");
|
||||
}
|
||||
if (ds8)
|
||||
IDirectSound8_Release(ds8);
|
||||
|
||||
ok(!GetModuleHandleA("quartz.dll"), "quartz.dll was already loaded!\n");
|
||||
hr = IMMDevice_Activate(dev, &IID_IBaseFilter, CLSCTX_INPROC_SERVER, NULL, (void**)&bf);
|
||||
ok(hr == S_OK, "Activating bf failed: 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
ok(GetModuleHandleA("quartz.dll") != NULL, "quartz.dll not loaded!\n");
|
||||
ok(bf != NULL, "bf pointer is null\n");
|
||||
if (bf)
|
||||
{
|
||||
CLSID clsid;
|
||||
hr = IBaseFilter_GetClassID(bf, &clsid);
|
||||
ok(hr == S_OK, "GetClassId failed with 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_DSoundRender), "Wrong class id %s\n", wine_dbgstr_guid(&clsid));
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (bf)
|
||||
IBaseFilter_Release(bf);
|
||||
if (dev)
|
||||
IMMDevice_Release(dev);
|
||||
if (mme)
|
||||
IMMDeviceEnumerator_Release(mme);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
|
@ -1,484 +0,0 @@
|
|||
/*
|
||||
* Copyright 2009 Maarten Lankhorst
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "initguid.h"
|
||||
#include "endpointvolume.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "audioclient.h"
|
||||
#include "spatialaudioclient.h"
|
||||
#include "audiopolicy.h"
|
||||
#include "dshow.h"
|
||||
#include "dsound.h"
|
||||
#include "devpkey.h"
|
||||
|
||||
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
||||
|
||||
static UINT g_num_mmdevs;
|
||||
static WCHAR g_device_path[MAX_PATH];
|
||||
|
||||
/* Some of the QueryInterface tests are really just to check if I got the IIDs right :) */
|
||||
|
||||
/* IMMDeviceCollection appears to have no QueryInterface method and instead forwards to mme */
|
||||
static void test_collection(IMMDeviceEnumerator *mme, IMMDeviceCollection *col)
|
||||
{
|
||||
IMMDeviceCollection *col2;
|
||||
IMMDeviceEnumerator *mme2;
|
||||
IUnknown *unk;
|
||||
HRESULT hr;
|
||||
ULONG ref;
|
||||
UINT numdev;
|
||||
IMMDevice *dev;
|
||||
|
||||
/* collection doesn't keep a ref on parent */
|
||||
IMMDeviceEnumerator_AddRef(mme);
|
||||
ref = IMMDeviceEnumerator_Release(mme);
|
||||
ok(ref == 2, "Reference count on parent is %lu\n", ref);
|
||||
|
||||
ref = IMMDeviceCollection_AddRef(col);
|
||||
IMMDeviceCollection_Release(col);
|
||||
ok(ref == 2, "Invalid reference count %lu on collection\n", ref);
|
||||
|
||||
hr = IMMDeviceCollection_QueryInterface(col, &IID_IUnknown, NULL);
|
||||
ok(hr == E_POINTER, "Null ppv returns %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceCollection_QueryInterface(col, &IID_IUnknown, (void**)&unk);
|
||||
ok(hr == S_OK, "Cannot query for IID_IUnknown: 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
ok((IUnknown*)col == unk, "Pointers are not identical %p/%p/%p\n", col, unk, mme);
|
||||
IUnknown_Release(unk);
|
||||
}
|
||||
|
||||
hr = IMMDeviceCollection_QueryInterface(col, &IID_IMMDeviceCollection, (void**)&col2);
|
||||
ok(hr == S_OK, "Cannot query for IID_IMMDeviceCollection: 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
IMMDeviceCollection_Release(col2);
|
||||
|
||||
hr = IMMDeviceCollection_QueryInterface(col, &IID_IMMDeviceEnumerator, (void**)&mme2);
|
||||
ok(hr == E_NOINTERFACE, "Query for IID_IMMDeviceEnumerator returned: 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
IMMDeviceEnumerator_Release(mme2);
|
||||
|
||||
hr = IMMDeviceCollection_GetCount(col, NULL);
|
||||
ok(hr == E_POINTER, "GetCount returned 0x%08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceCollection_GetCount(col, &numdev);
|
||||
ok(hr == S_OK, "GetCount returned 0x%08lx\n", hr);
|
||||
|
||||
dev = (void*)(LONG_PTR)0x12345678;
|
||||
hr = IMMDeviceCollection_Item(col, numdev, &dev);
|
||||
ok(hr == E_INVALIDARG, "Asking for too high device returned 0x%08lx\n", hr);
|
||||
ok(dev == NULL, "Returned non-null device\n");
|
||||
|
||||
g_num_mmdevs = numdev;
|
||||
|
||||
if (numdev)
|
||||
{
|
||||
hr = IMMDeviceCollection_Item(col, 0, NULL);
|
||||
ok(hr == E_POINTER, "Query with null pointer returned 0x%08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceCollection_Item(col, 0, &dev);
|
||||
ok(hr == S_OK, "Valid Item returned 0x%08lx\n", hr);
|
||||
ok(dev != NULL, "Device is null!\n");
|
||||
if (dev != NULL)
|
||||
{
|
||||
char temp[128];
|
||||
WCHAR *id = NULL;
|
||||
if (IMMDevice_GetId(dev, &id) == S_OK)
|
||||
{
|
||||
IMMDevice *dev2;
|
||||
|
||||
lstrcpyW(g_device_path, id);
|
||||
temp[sizeof(temp)-1] = 0;
|
||||
WideCharToMultiByte(CP_ACP, 0, id, -1, temp, sizeof(temp)-1, NULL, NULL);
|
||||
trace("Device found: %s\n", temp);
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDevice(mme, id, &dev2);
|
||||
ok(hr == S_OK, "GetDevice failed: %08lx\n", hr);
|
||||
|
||||
IMMDevice_Release(dev2);
|
||||
|
||||
CoTaskMemFree(id);
|
||||
}
|
||||
}
|
||||
if (dev)
|
||||
IMMDevice_Release(dev);
|
||||
}
|
||||
IMMDeviceCollection_Release(col);
|
||||
}
|
||||
|
||||
static struct {
|
||||
LONG ref;
|
||||
HANDLE evt;
|
||||
CRITICAL_SECTION lock;
|
||||
IActivateAudioInterfaceAsyncOperation *op;
|
||||
DWORD main_tid;
|
||||
char msg_pfx[128];
|
||||
IUnknown *result_iface;
|
||||
HRESULT result_hr;
|
||||
} async_activate_test;
|
||||
|
||||
static HRESULT WINAPI async_activate_QueryInterface(
|
||||
IActivateAudioInterfaceCompletionHandler *iface,
|
||||
REFIID riid,
|
||||
void **ppvObject)
|
||||
{
|
||||
if(IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IAgileObject) ||
|
||||
IsEqualIID(riid, &IID_IActivateAudioInterfaceCompletionHandler)){
|
||||
*ppvObject = iface;
|
||||
IUnknown_AddRef((IUnknown*)*ppvObject);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI async_activate_AddRef(
|
||||
IActivateAudioInterfaceCompletionHandler *iface)
|
||||
{
|
||||
return InterlockedIncrement(&async_activate_test.ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI async_activate_Release(
|
||||
IActivateAudioInterfaceCompletionHandler *iface)
|
||||
{
|
||||
ULONG ref = InterlockedDecrement(&async_activate_test.ref);
|
||||
if(ref == 1)
|
||||
SetEvent(async_activate_test.evt);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI async_activate_ActivateCompleted(
|
||||
IActivateAudioInterfaceCompletionHandler *iface,
|
||||
IActivateAudioInterfaceAsyncOperation *op)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
EnterCriticalSection(&async_activate_test.lock);
|
||||
ok(op == async_activate_test.op,
|
||||
"%s: Got different completion operation\n",
|
||||
async_activate_test.msg_pfx);
|
||||
LeaveCriticalSection(&async_activate_test.lock);
|
||||
|
||||
ok(GetCurrentThreadId() != async_activate_test.main_tid,
|
||||
"%s: Expected callback on worker thread\n",
|
||||
async_activate_test.msg_pfx);
|
||||
|
||||
hr = IActivateAudioInterfaceAsyncOperation_GetActivateResult(op,
|
||||
&async_activate_test.result_hr, &async_activate_test.result_iface);
|
||||
ok(hr == S_OK,
|
||||
"%s: GetActivateResult failed: %08lx\n",
|
||||
async_activate_test.msg_pfx, hr);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IActivateAudioInterfaceCompletionHandlerVtbl async_activate_vtbl = {
|
||||
async_activate_QueryInterface,
|
||||
async_activate_AddRef,
|
||||
async_activate_Release,
|
||||
async_activate_ActivateCompleted,
|
||||
};
|
||||
|
||||
static IActivateAudioInterfaceCompletionHandler async_activate_done = {
|
||||
&async_activate_vtbl
|
||||
};
|
||||
|
||||
static void test_ActivateAudioInterfaceAsync(void)
|
||||
{
|
||||
HRESULT (* WINAPI pActivateAudioInterfaceAsync)(const WCHAR *path,
|
||||
REFIID riid, PROPVARIANT *params,
|
||||
IActivateAudioInterfaceCompletionHandler *done_handler,
|
||||
IActivateAudioInterfaceAsyncOperation **op);
|
||||
HANDLE h_mmdev;
|
||||
HRESULT hr;
|
||||
LPOLESTR path;
|
||||
DWORD dr;
|
||||
IAudioClient3 *ac3;
|
||||
|
||||
h_mmdev = LoadLibraryA("mmdevapi.dll");
|
||||
|
||||
pActivateAudioInterfaceAsync = (void*)GetProcAddress(h_mmdev, "ActivateAudioInterfaceAsync");
|
||||
if (!pActivateAudioInterfaceAsync)
|
||||
{
|
||||
win_skip("ActivateAudioInterfaceAsync is not supported on Win <= 7\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* some applications look this up by ordinal */
|
||||
pActivateAudioInterfaceAsync = (void*)GetProcAddress(h_mmdev, (char *)17);
|
||||
ok(pActivateAudioInterfaceAsync != NULL, "mmdevapi.ActivateAudioInterfaceAsync missing!\n");
|
||||
|
||||
async_activate_test.ref = 1;
|
||||
async_activate_test.evt = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
InitializeCriticalSection(&async_activate_test.lock);
|
||||
async_activate_test.op = NULL;
|
||||
async_activate_test.main_tid = GetCurrentThreadId();
|
||||
async_activate_test.result_iface = NULL;
|
||||
async_activate_test.result_hr = 0;
|
||||
|
||||
|
||||
/* try invalid device path */
|
||||
strcpy(async_activate_test.msg_pfx, "invalid_path");
|
||||
|
||||
EnterCriticalSection(&async_activate_test.lock);
|
||||
hr = pActivateAudioInterfaceAsync(L"winetest_bogus", &IID_IAudioClient3, NULL, &async_activate_done, &async_activate_test.op);
|
||||
ok(hr == S_OK, "ActivateAudioInterfaceAsync failed: %08lx\n", hr);
|
||||
LeaveCriticalSection(&async_activate_test.lock);
|
||||
|
||||
IActivateAudioInterfaceAsyncOperation_Release(async_activate_test.op);
|
||||
|
||||
dr = WaitForSingleObject(async_activate_test.evt, 1000); /* wait for all refs other than our own to be released */
|
||||
ok(dr == WAIT_OBJECT_0, "Timed out waiting for async activate to complete\n");
|
||||
ok(async_activate_test.ref == 1, "ActivateAudioInterfaceAsync leaked a handler ref: %lu\n", async_activate_test.ref);
|
||||
ok(async_activate_test.result_hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
|
||||
"mmdevice activation gave wrong result: %08lx\n", async_activate_test.result_hr);
|
||||
ok(async_activate_test.result_iface == NULL, "Got non-NULL iface pointer: %p\n", async_activate_test.result_iface);
|
||||
|
||||
|
||||
/* device id from IMMDevice does not work */
|
||||
if(g_num_mmdevs > 0){
|
||||
strcpy(async_activate_test.msg_pfx, "mmdevice_id");
|
||||
|
||||
EnterCriticalSection(&async_activate_test.lock);
|
||||
hr = pActivateAudioInterfaceAsync(g_device_path, &IID_IAudioClient3, NULL, &async_activate_done, &async_activate_test.op);
|
||||
ok(hr == S_OK, "ActivateAudioInterfaceAsync failed: %08lx\n", hr);
|
||||
LeaveCriticalSection(&async_activate_test.lock);
|
||||
|
||||
IActivateAudioInterfaceAsyncOperation_Release(async_activate_test.op);
|
||||
|
||||
dr = WaitForSingleObject(async_activate_test.evt, 1000);
|
||||
ok(dr == WAIT_OBJECT_0, "Timed out waiting for async activate to complete\n");
|
||||
ok(async_activate_test.ref == 1, "ActivateAudioInterfaceAsync leaked a handler ref: %lu\n", async_activate_test.ref);
|
||||
ok(async_activate_test.result_hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
|
||||
"mmdevice activation gave wrong result: %08lx\n", async_activate_test.result_hr);
|
||||
ok(async_activate_test.result_iface == NULL, "Got non-NULL iface pointer: %p\n", async_activate_test.result_iface);
|
||||
}
|
||||
|
||||
|
||||
/* try DEVINTERFACE_AUDIO_RENDER */
|
||||
strcpy(async_activate_test.msg_pfx, "audio_render");
|
||||
StringFromIID(&DEVINTERFACE_AUDIO_RENDER, &path);
|
||||
|
||||
EnterCriticalSection(&async_activate_test.lock);
|
||||
hr = pActivateAudioInterfaceAsync(path, &IID_IAudioClient3, NULL, &async_activate_done, &async_activate_test.op);
|
||||
ok(hr == S_OK, "ActivateAudioInterfaceAsync failed: %08lx\n", hr);
|
||||
LeaveCriticalSection(&async_activate_test.lock);
|
||||
|
||||
IActivateAudioInterfaceAsyncOperation_Release(async_activate_test.op);
|
||||
|
||||
dr = WaitForSingleObject(async_activate_test.evt, 1000);
|
||||
ok(dr == WAIT_OBJECT_0, "Timed out waiting for async activate to complete\n");
|
||||
ok(async_activate_test.ref == 1, "ActivateAudioInterfaceAsync leaked a handler ref\n");
|
||||
ok(async_activate_test.result_hr == S_OK ||
|
||||
(g_num_mmdevs == 0 && async_activate_test.result_hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) || /* no devices */
|
||||
broken(async_activate_test.result_hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), /* win8 doesn't support DEVINTERFACE_AUDIO_RENDER */
|
||||
"mmdevice activation gave wrong result: %08lx\n", async_activate_test.result_hr);
|
||||
|
||||
if(async_activate_test.result_hr == S_OK){
|
||||
ok(async_activate_test.result_iface != NULL, "Got NULL iface pointer on success?\n");
|
||||
|
||||
/* returned iface should be the IID we requested */
|
||||
hr = IUnknown_QueryInterface(async_activate_test.result_iface, &IID_IAudioClient3, (void**)&ac3);
|
||||
ok(hr == S_OK, "Failed to query IAudioClient3: %08lx\n", hr);
|
||||
ok(async_activate_test.result_iface == (IUnknown*)ac3,
|
||||
"Activated interface other than IAudioClient3!\n");
|
||||
IAudioClient3_Release(ac3);
|
||||
|
||||
IUnknown_Release(async_activate_test.result_iface);
|
||||
}
|
||||
|
||||
CoTaskMemFree(path);
|
||||
|
||||
CloseHandle(async_activate_test.evt);
|
||||
DeleteCriticalSection(&async_activate_test.lock);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI notif_QueryInterface(IMMNotificationClient *iface,
|
||||
const GUID *riid, void **obj)
|
||||
{
|
||||
ok(0, "Unexpected QueryInterface call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static ULONG WINAPI notif_AddRef(IMMNotificationClient *iface)
|
||||
{
|
||||
ok(0, "Unexpected AddRef call\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI notif_Release(IMMNotificationClient *iface)
|
||||
{
|
||||
ok(0, "Unexpected Release call\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI notif_OnDeviceStateChanged(IMMNotificationClient *iface,
|
||||
const WCHAR *device_id, DWORD new_state)
|
||||
{
|
||||
ok(0, "Unexpected OnDeviceStateChanged call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI notif_OnDeviceAdded(IMMNotificationClient *iface,
|
||||
const WCHAR *device_id)
|
||||
{
|
||||
ok(0, "Unexpected OnDeviceAdded call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI notif_OnDeviceRemoved(IMMNotificationClient *iface,
|
||||
const WCHAR *device_id)
|
||||
{
|
||||
ok(0, "Unexpected OnDeviceRemoved call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI notif_OnDefaultDeviceChanged(IMMNotificationClient *iface,
|
||||
EDataFlow flow, ERole role, const WCHAR *device_id)
|
||||
{
|
||||
ok(0, "Unexpected OnDefaultDeviceChanged call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI notif_OnPropertyValueChanged(IMMNotificationClient *iface,
|
||||
const WCHAR *device_id, const PROPERTYKEY key)
|
||||
{
|
||||
ok(0, "Unexpected OnPropertyValueChanged call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static IMMNotificationClientVtbl notif_vtbl = {
|
||||
notif_QueryInterface,
|
||||
notif_AddRef,
|
||||
notif_Release,
|
||||
notif_OnDeviceStateChanged,
|
||||
notif_OnDeviceAdded,
|
||||
notif_OnDeviceRemoved,
|
||||
notif_OnDefaultDeviceChanged,
|
||||
notif_OnPropertyValueChanged
|
||||
};
|
||||
|
||||
static IMMNotificationClient notif = { ¬if_vtbl };
|
||||
|
||||
/* Only do parameter tests here, the actual MMDevice testing should be a separate test */
|
||||
START_TEST(mmdevenum)
|
||||
{
|
||||
HRESULT hr;
|
||||
IUnknown *unk = NULL;
|
||||
IMMDeviceEnumerator *mme, *mme2;
|
||||
ULONG ref;
|
||||
IMMDeviceCollection *col;
|
||||
IMMDevice *dev;
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("mmdevapi not available: 0x%08lx\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Odd behavior.. bug? */
|
||||
ref = IMMDeviceEnumerator_AddRef(mme);
|
||||
ok(ref == 3, "Invalid reference count after incrementing: %lu\n", ref);
|
||||
IMMDeviceEnumerator_Release(mme);
|
||||
|
||||
hr = IMMDeviceEnumerator_QueryInterface(mme, &IID_IUnknown, (void**)&unk);
|
||||
ok(hr == S_OK, "returned 0x%08lx\n", hr);
|
||||
if (hr != S_OK) return;
|
||||
|
||||
ok( (LONG_PTR)mme == (LONG_PTR)unk, "Pointers are unequal %p/%p\n", unk, mme);
|
||||
IUnknown_Release(unk);
|
||||
|
||||
/* Proving that it is static.. */
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme2);
|
||||
ok(hr == S_OK, "CoCreateInstance failed: 0x%08lx\n", hr);
|
||||
IMMDeviceEnumerator_Release(mme2);
|
||||
ok(mme == mme2, "Pointers are not equal!\n");
|
||||
|
||||
hr = IMMDeviceEnumerator_QueryInterface(mme, &IID_IUnknown, NULL);
|
||||
ok(hr == E_POINTER, "Null pointer on QueryInterface returned %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_QueryInterface(mme, &GUID_NULL, (void**)&unk);
|
||||
ok(!unk, "Unk not reset to null after invalid QI\n");
|
||||
ok(hr == E_NOINTERFACE, "Invalid hr %08lx returned on IID_NULL\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDevice(mme, L"notadevice", NULL);
|
||||
ok(hr == E_POINTER, "GetDevice gave wrong error: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDevice(mme, NULL, &dev);
|
||||
ok(hr == E_POINTER, "GetDevice gave wrong error: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDevice(mme, L"notadevice", &dev);
|
||||
ok(hr == E_INVALIDARG, "GetDevice gave wrong error: %08lx\n", hr);
|
||||
|
||||
col = (void*)(LONG_PTR)0x12345678;
|
||||
hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, 0xffff, DEVICE_STATEMASK_ALL, &col);
|
||||
ok(hr == E_INVALIDARG, "Setting invalid data flow returned 0x%08lx\n", hr);
|
||||
ok(col == NULL, "Collection pointer non-null on failure\n");
|
||||
|
||||
hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, eAll, DEVICE_STATEMASK_ALL+1, &col);
|
||||
ok(hr == E_INVALIDARG, "Setting invalid mask returned 0x%08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, eAll, DEVICE_STATEMASK_ALL, NULL);
|
||||
ok(hr == E_POINTER, "Invalid pointer returned: 0x%08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, eAll, DEVICE_STATEMASK_ALL, &col);
|
||||
ok(hr == S_OK, "Valid EnumAudioEndpoints returned 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
ok(!!col, "Returned null pointer\n");
|
||||
if (col)
|
||||
test_collection(mme, col);
|
||||
}
|
||||
|
||||
hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, NULL);
|
||||
ok(hr == E_POINTER, "RegisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, ¬if);
|
||||
ok(hr == S_OK, "RegisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, ¬if);
|
||||
ok(hr == S_OK, "RegisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, NULL);
|
||||
ok(hr == E_POINTER, "UnregisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, (IMMNotificationClient*)0xdeadbeef);
|
||||
ok(hr == E_NOTFOUND, "UnregisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, ¬if);
|
||||
ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, ¬if);
|
||||
ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, ¬if);
|
||||
ok(hr == E_NOTFOUND, "UnregisterEndpointNotificationCallback failed: %08lx\n", hr);
|
||||
|
||||
IMMDeviceEnumerator_Release(mme);
|
||||
|
||||
test_ActivateAudioInterfaceAsync();
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 Maarten Lankhorst for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#include "wine/test.h"
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#ifdef STANDALONE
|
||||
#include "initguid.h"
|
||||
#endif
|
||||
|
||||
#include "unknwn.h"
|
||||
#include "uuids.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "devpkey.h"
|
||||
|
||||
static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *);
|
||||
|
||||
static const WCHAR software_renderW[] =
|
||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio\\Render";
|
||||
|
||||
|
||||
static void test_propertystore(IPropertyStore *store)
|
||||
{
|
||||
HRESULT hr;
|
||||
PROPVARIANT pv;
|
||||
char temp[128];
|
||||
temp[sizeof(temp)-1] = 0;
|
||||
|
||||
pv.vt = VT_EMPTY;
|
||||
hr = IPropertyStore_GetValue(store, &PKEY_AudioEndpoint_GUID, &pv);
|
||||
ok(hr == S_OK, "Failed with %08lx\n", hr);
|
||||
ok(pv.vt == VT_LPWSTR, "Value should be %i, is %i\n", VT_LPWSTR, pv.vt);
|
||||
if (hr == S_OK && pv.vt == VT_LPWSTR)
|
||||
{
|
||||
WideCharToMultiByte(CP_ACP, 0, pv.pwszVal, -1, temp, sizeof(temp)-1, NULL, NULL);
|
||||
trace("guid: %s\n", temp);
|
||||
PropVariantClear(&pv);
|
||||
}
|
||||
|
||||
pv.vt = VT_EMPTY;
|
||||
hr = IPropertyStore_GetValue(store, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_FriendlyName, &pv);
|
||||
ok(hr == S_OK, "Failed with %08lx\n", hr);
|
||||
ok(pv.vt == VT_LPWSTR && pv.pwszVal, "FriendlyName value had wrong type: 0x%x or was NULL\n", pv.vt);
|
||||
PropVariantClear(&pv);
|
||||
|
||||
pv.vt = VT_EMPTY;
|
||||
hr = IPropertyStore_GetValue(store, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_Enabled, &pv);
|
||||
ok(hr == S_OK, "Failed with %08lx\n", hr);
|
||||
ok(pv.vt == VT_EMPTY, "Key should not be found\n");
|
||||
PropVariantClear(&pv);
|
||||
|
||||
pv.vt = VT_EMPTY;
|
||||
hr = IPropertyStore_GetValue(store, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_ClassGuid, &pv);
|
||||
ok(hr == S_OK, "Failed with %08lx\n", hr);
|
||||
ok(pv.vt == VT_EMPTY, "Key should not be found\n");
|
||||
PropVariantClear(&pv);
|
||||
}
|
||||
|
||||
static void test_deviceinterface(IPropertyStore *store)
|
||||
{
|
||||
HRESULT hr;
|
||||
PROPVARIANT pv;
|
||||
|
||||
static const PROPERTYKEY deviceinterface_key = {
|
||||
{0x233164c8, 0x1b2c, 0x4c7d, {0xbc, 0x68, 0xb6, 0x71, 0x68, 0x7a, 0x25, 0x67}}, 1
|
||||
};
|
||||
|
||||
pv.vt = VT_EMPTY;
|
||||
hr = IPropertyStore_GetValue(store, &deviceinterface_key, &pv);
|
||||
ok(hr == S_OK, "GetValue failed: %08lx\n", hr);
|
||||
ok(pv.vt == VT_LPWSTR, "Got wrong variant type: 0x%x\n", pv.vt);
|
||||
trace("device interface: %s\n", wine_dbgstr_w(pv.pwszVal));
|
||||
PropVariantClear(&pv);
|
||||
}
|
||||
|
||||
static void test_getat(IPropertyStore *store)
|
||||
{
|
||||
HRESULT hr;
|
||||
DWORD propcount;
|
||||
DWORD prop;
|
||||
PROPERTYKEY pkey;
|
||||
BOOL found_name = FALSE;
|
||||
BOOL found_desc = FALSE;
|
||||
char temp[128];
|
||||
temp[sizeof(temp)-1] = 0;
|
||||
|
||||
hr = IPropertyStore_GetCount(store, &propcount);
|
||||
|
||||
ok(hr == S_OK, "Failed with %08lx\n", hr);
|
||||
ok(propcount > 0, "Propcount %ld should be greater than zero\n", propcount);
|
||||
|
||||
for (prop = 0; prop < propcount; prop++) {
|
||||
hr = IPropertyStore_GetAt(store, prop, &pkey);
|
||||
ok(hr == S_OK, "Failed with %08lx\n", hr);
|
||||
if (IsEqualPropertyKey(pkey, DEVPKEY_Device_FriendlyName))
|
||||
found_name = TRUE;
|
||||
if (IsEqualPropertyKey(pkey, DEVPKEY_Device_DeviceDesc))
|
||||
found_desc = TRUE;
|
||||
}
|
||||
ok(found_name ||
|
||||
broken(!found_name) /* vista */, "DEVPKEY_Device_FriendlyName not found\n");
|
||||
ok(found_desc, "DEVPKEY_Device_DeviceDesc not found\n");
|
||||
}
|
||||
|
||||
static void test_setvalue_on_wow64(IPropertyStore *store)
|
||||
{
|
||||
PROPVARIANT pv;
|
||||
HRESULT hr;
|
||||
LONG ret;
|
||||
WCHAR *guidW;
|
||||
HKEY root, props, devkey;
|
||||
DWORD type, regval, size;
|
||||
|
||||
static const PROPERTYKEY PKEY_Bogus = {
|
||||
{0x1da5d803, 0xd492, 0x4edd, {0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x00}}, 0x7f
|
||||
};
|
||||
static const WCHAR bogusW[] = L"{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F00},127";
|
||||
|
||||
PropVariantInit(&pv);
|
||||
|
||||
pv.vt = VT_EMPTY;
|
||||
hr = IPropertyStore_GetValue(store, &PKEY_AudioEndpoint_GUID, &pv);
|
||||
ok(hr == S_OK, "Failed to get Endpoint GUID: %08lx\n", hr);
|
||||
|
||||
guidW = pv.pwszVal;
|
||||
|
||||
pv.vt = VT_UI4;
|
||||
pv.ulVal = 0xAB;
|
||||
|
||||
hr = IPropertyStore_SetValue(store, &PKEY_Bogus, &pv);
|
||||
ok(hr == S_OK || hr == E_ACCESSDENIED, "SetValue failed: %08lx\n", hr);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
win_skip("Missing permission to write to registry\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pv.ulVal = 0x00;
|
||||
|
||||
hr = IPropertyStore_GetValue(store, &PKEY_Bogus, &pv);
|
||||
ok(hr == S_OK, "GetValue failed: %08lx\n", hr);
|
||||
ok(pv.ulVal == 0xAB, "Got wrong value: 0x%lx\n", pv.ulVal);
|
||||
|
||||
/* should find the key in 64-bit view */
|
||||
ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, software_renderW, 0, KEY_READ|KEY_WOW64_64KEY, &root);
|
||||
ok(ret == ERROR_SUCCESS, "Couldn't open mmdevices Render key: %lu\n", ret);
|
||||
|
||||
ret = RegOpenKeyExW(root, guidW, 0, KEY_READ|KEY_WOW64_64KEY, &devkey);
|
||||
ok(ret == ERROR_SUCCESS, "Couldn't open mmdevice guid key: %lu\n", ret);
|
||||
|
||||
ret = RegOpenKeyExW(devkey, L"Properties", 0, KEY_READ|KEY_WOW64_64KEY, &props);
|
||||
ok(ret == ERROR_SUCCESS, "Couldn't open mmdevice property key: %lu\n", ret);
|
||||
|
||||
/* Note: the registry key exists even without calling IPropStore::Commit */
|
||||
size = sizeof(regval);
|
||||
ret = RegQueryValueExW(props, bogusW, NULL, &type, (LPBYTE)®val, &size);
|
||||
ok(ret == ERROR_SUCCESS, "Couldn't get bogus propertykey value: %lu\n", ret);
|
||||
ok(type == REG_DWORD, "Got wrong value type: %lu\n", type);
|
||||
ok(regval == 0xAB, "Got wrong value: 0x%lx\n", regval);
|
||||
|
||||
RegCloseKey(props);
|
||||
RegCloseKey(devkey);
|
||||
RegCloseKey(root);
|
||||
|
||||
CoTaskMemFree(guidW);
|
||||
|
||||
/* should NOT find the key in 32-bit view */
|
||||
ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, software_renderW, 0, KEY_READ, &root);
|
||||
ok(ret == ERROR_FILE_NOT_FOUND, "Wrong error when opening mmdevices Render key: %lu\n", ret);
|
||||
}
|
||||
|
||||
START_TEST(propstore)
|
||||
{
|
||||
HRESULT hr;
|
||||
IMMDeviceEnumerator *mme = NULL;
|
||||
IMMDevice *dev = NULL;
|
||||
IPropertyStore *store;
|
||||
BOOL is_wow64 = FALSE;
|
||||
HMODULE hk32 = GetModuleHandleA("kernel32.dll");
|
||||
|
||||
pIsWow64Process = (void *)GetProcAddress(hk32, "IsWow64Process");
|
||||
|
||||
if (pIsWow64Process)
|
||||
pIsWow64Process(GetCurrentProcess(), &is_wow64);
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("mmdevapi not available: 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eRender, eMultimedia, &dev);
|
||||
ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08lx\n", hr);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
if (hr == E_NOTFOUND)
|
||||
skip("No sound card available\n");
|
||||
else
|
||||
skip("GetDefaultAudioEndpoint returns 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
store = NULL;
|
||||
hr = IMMDevice_OpenPropertyStore(dev, 3, &store);
|
||||
ok(hr == E_INVALIDARG, "Wrong hr returned: %08lx\n", hr);
|
||||
if (hr != S_OK)
|
||||
/* It seems on windows returning with E_INVALIDARG doesn't
|
||||
* set store to NULL, so just don't set store to non-null
|
||||
* before calling this function
|
||||
*/
|
||||
ok(!store, "Store set to non-NULL on failure: %p/%08lx\n", store, hr);
|
||||
else if (store)
|
||||
IPropertyStore_Release(store);
|
||||
hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, NULL);
|
||||
ok(hr == E_POINTER, "Wrong hr returned: %08lx\n", hr);
|
||||
|
||||
store = NULL;
|
||||
hr = IMMDevice_OpenPropertyStore(dev, STGM_READWRITE, &store);
|
||||
if(hr == E_ACCESSDENIED)
|
||||
hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &store);
|
||||
ok(hr == S_OK, "Opening valid store returned %08lx\n", hr);
|
||||
if (store)
|
||||
{
|
||||
test_propertystore(store);
|
||||
test_deviceinterface(store);
|
||||
test_getat(store);
|
||||
if (is_wow64)
|
||||
test_setvalue_on_wow64(store);
|
||||
IPropertyStore_Release(store);
|
||||
}
|
||||
IMMDevice_Release(dev);
|
||||
cleanup:
|
||||
if (mme)
|
||||
IMMDeviceEnumerator_Release(mme);
|
||||
CoUninitialize();
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,506 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 Arkadiusz Hiler for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#ifdef STANDALONE
|
||||
#include "initguid.h"
|
||||
#endif
|
||||
|
||||
#include "mmdeviceapi.h"
|
||||
#include "spatialaudioclient.h"
|
||||
#include "mmsystem.h"
|
||||
|
||||
static IMMDeviceEnumerator *mme = NULL;
|
||||
static IMMDevice *dev = NULL;
|
||||
static ISpatialAudioClient *sac = NULL;
|
||||
static UINT32 max_dyn_count;
|
||||
static HANDLE event;
|
||||
static WAVEFORMATEX format;
|
||||
|
||||
static void test_formats(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
IAudioFormatEnumerator *afe;
|
||||
UINT32 format_count = 0;
|
||||
WAVEFORMATEX *fmt = NULL;
|
||||
|
||||
hr = ISpatialAudioClient_GetSupportedAudioObjectFormatEnumerator(sac, &afe);
|
||||
ok(hr == S_OK, "Getting format enumerator failed: 0x%08lx\n", hr);
|
||||
|
||||
hr = IAudioFormatEnumerator_GetCount(afe, &format_count);
|
||||
ok(hr == S_OK, "Getting format count failed: 0x%08lx\n", hr);
|
||||
ok(format_count == 1, "Got wrong format count, expected 1 got %u\n", format_count);
|
||||
|
||||
hr = IAudioFormatEnumerator_GetFormat(afe, 0, &fmt);
|
||||
ok(hr == S_OK, "Getting format failed: 0x%08lx\n", hr);
|
||||
ok(fmt != NULL, "Expected to get non-NULL format\n");
|
||||
|
||||
ok(fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT, "Wrong format, expected WAVE_FORMAT_IEEE_FLOAT got %hx\n", fmt->wFormatTag);
|
||||
ok(fmt->nChannels == 1, "Wrong number of channels, expected 1 got %hu\n", fmt->nChannels);
|
||||
ok(fmt->nSamplesPerSec == 48000, "Wrong sample ret, expected 48000 got %lu\n", fmt->nSamplesPerSec);
|
||||
ok(fmt->wBitsPerSample == 32, "Wrong bits per sample, expected 32 got %hu\n", fmt->wBitsPerSample);
|
||||
ok(fmt->nBlockAlign == 4, "Wrong block align, expected 4 got %hu\n", fmt->nBlockAlign);
|
||||
ok(fmt->nAvgBytesPerSec == 192000, "Wrong avg bytes per sec, expected 192000 got %lu\n", fmt->nAvgBytesPerSec);
|
||||
ok(fmt->cbSize == 0, "Wrong cbSize for simple format, expected 0, got %hu\n", fmt->cbSize);
|
||||
|
||||
memcpy(&format, fmt, sizeof(format));
|
||||
|
||||
IAudioFormatEnumerator_Release(afe);
|
||||
}
|
||||
|
||||
static void fill_activation_params(SpatialAudioObjectRenderStreamActivationParams *activation_params)
|
||||
{
|
||||
activation_params->StaticObjectTypeMask = \
|
||||
AudioObjectType_FrontLeft |
|
||||
AudioObjectType_FrontRight |
|
||||
AudioObjectType_FrontCenter |
|
||||
AudioObjectType_LowFrequency |
|
||||
AudioObjectType_SideLeft |
|
||||
AudioObjectType_SideRight |
|
||||
AudioObjectType_BackLeft |
|
||||
AudioObjectType_BackRight |
|
||||
AudioObjectType_TopFrontLeft |
|
||||
AudioObjectType_TopFrontRight |
|
||||
AudioObjectType_TopBackLeft |
|
||||
AudioObjectType_TopBackRight;
|
||||
|
||||
activation_params->MinDynamicObjectCount = 0;
|
||||
activation_params->MaxDynamicObjectCount = 0;
|
||||
activation_params->Category = AudioCategory_GameEffects;
|
||||
activation_params->EventHandle = event;
|
||||
activation_params->NotifyObject = NULL;
|
||||
|
||||
activation_params->ObjectFormat = &format;
|
||||
}
|
||||
|
||||
typedef struct NotifyObject
|
||||
{
|
||||
ISpatialAudioObjectRenderStreamNotify ISpatialAudioObjectRenderStreamNotify_iface;
|
||||
LONG ref;
|
||||
} NotifyObject;
|
||||
|
||||
static WINAPI HRESULT notifyobj_QueryInterface(
|
||||
ISpatialAudioObjectRenderStreamNotify *This,
|
||||
REFIID riid,
|
||||
void **ppvObject)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static WINAPI ULONG notifyobj_AddRef(
|
||||
ISpatialAudioObjectRenderStreamNotify *This)
|
||||
{
|
||||
NotifyObject *obj = CONTAINING_RECORD(This, NotifyObject, ISpatialAudioObjectRenderStreamNotify_iface);
|
||||
ULONG ref = InterlockedIncrement(&obj->ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static WINAPI ULONG notifyobj_Release(
|
||||
ISpatialAudioObjectRenderStreamNotify *This)
|
||||
{
|
||||
NotifyObject *obj = CONTAINING_RECORD(This, NotifyObject, ISpatialAudioObjectRenderStreamNotify_iface);
|
||||
ULONG ref = InterlockedDecrement(&obj->ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static WINAPI HRESULT notifyobj_OnAvailableDynamicObjectCountChange(
|
||||
ISpatialAudioObjectRenderStreamNotify *This,
|
||||
ISpatialAudioObjectRenderStreamBase *stream,
|
||||
LONGLONG deadline,
|
||||
UINT32 object_count)
|
||||
{
|
||||
ok(FALSE, "Expected to never be notified of dynamic object count change\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const ISpatialAudioObjectRenderStreamNotifyVtbl notifyobjvtbl =
|
||||
{
|
||||
notifyobj_QueryInterface,
|
||||
notifyobj_AddRef,
|
||||
notifyobj_Release,
|
||||
notifyobj_OnAvailableDynamicObjectCountChange
|
||||
};
|
||||
|
||||
static void test_stream_activation(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
WAVEFORMATEX wrong_format;
|
||||
ISpatialAudioObjectRenderStream *sas = NULL;
|
||||
|
||||
SpatialAudioObjectRenderStreamActivationParams activation_params;
|
||||
PROPVARIANT activation_params_prop;
|
||||
NotifyObject notify_object;
|
||||
|
||||
PropVariantInit(&activation_params_prop);
|
||||
activation_params_prop.vt = VT_BLOB;
|
||||
activation_params_prop.blob.cbSize = sizeof(activation_params);
|
||||
activation_params_prop.blob.pBlobData = (BYTE*) &activation_params;
|
||||
|
||||
/* correct params */
|
||||
fill_activation_params(&activation_params);
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio stream: 0x%08lx\n", hr);
|
||||
ok(ISpatialAudioObjectRenderStream_Release(sas) == 0, "Expected to release the last reference\n");
|
||||
|
||||
/* event handle */
|
||||
fill_activation_params(&activation_params);
|
||||
activation_params.EventHandle = NULL;
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == E_INVALIDARG, "Expected lack of no EventHandle to be invalid: 0x%08lx\n", hr);
|
||||
ok(sas == NULL, "Expected spatial audio stream to be set to NULL upon failed activation\n");
|
||||
|
||||
activation_params.EventHandle = INVALID_HANDLE_VALUE;
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == E_INVALIDARG, "Expected INVALID_HANDLE_VALUE to be invalid: 0x%08lx\n", hr);
|
||||
ok(sas == NULL, "Expected spatial audio stream to be set to NULL upon failed activation\n");
|
||||
|
||||
/* must use only queried sample rate */
|
||||
fill_activation_params(&activation_params);
|
||||
memcpy(&wrong_format, &format, sizeof(format));
|
||||
activation_params.ObjectFormat = &wrong_format;
|
||||
wrong_format.nSamplesPerSec = 44100;
|
||||
wrong_format.nAvgBytesPerSec = wrong_format.nSamplesPerSec * wrong_format.nBlockAlign;
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "Expected format to be unsupported: 0x%08lx\n", hr);
|
||||
ok(sas == NULL, "Expected spatial audio stream to be set to NULL upon failed activation\n");
|
||||
|
||||
/* dynamic objects are not supported */
|
||||
if (max_dyn_count == 0)
|
||||
{
|
||||
fill_activation_params(&activation_params);
|
||||
activation_params.StaticObjectTypeMask |= AudioObjectType_Dynamic;
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == E_INVALIDARG, "Expected dynamic objects type be invalid: 0x%08lx\n", hr);
|
||||
ok(sas == NULL, "Expected spatial audio stream to be set to NULL upon failed activation\n");
|
||||
}
|
||||
|
||||
activation_params.MinDynamicObjectCount = max_dyn_count + 1;
|
||||
activation_params.MaxDynamicObjectCount = max_dyn_count + 1;
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
if (max_dyn_count)
|
||||
ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "Expected dynamic object count exceeding max to be unsupported: 0x%08lx\n", hr);
|
||||
else
|
||||
ok(hr == E_INVALIDARG, "Expected setting dynamic object count to be invalid: 0x%08lx\n", hr);
|
||||
|
||||
/* ISpatialAudioObjectRenderStreamNotify */
|
||||
fill_activation_params(&activation_params);
|
||||
notify_object.ISpatialAudioObjectRenderStreamNotify_iface.lpVtbl = ¬ifyobjvtbl;
|
||||
notify_object.ref = 0;
|
||||
activation_params.NotifyObject = ¬ify_object.ISpatialAudioObjectRenderStreamNotify_iface;
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio stream: 0x%08lx\n", hr);
|
||||
ok(notify_object.ref == 1, "Expected to get increased NotifyObject's ref count\n");
|
||||
ok(ISpatialAudioObjectRenderStream_Release(sas) == 0, "Expected to release the last reference\n");
|
||||
ok(notify_object.ref == 0, "Expected to get lowered NotifyObject's ref count\n");
|
||||
}
|
||||
|
||||
static void test_audio_object_activation(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
BOOL is_active;
|
||||
ISpatialAudioObjectRenderStream *sas = NULL;
|
||||
ISpatialAudioObject *sao1, *sao2;
|
||||
|
||||
SpatialAudioObjectRenderStreamActivationParams activation_params;
|
||||
PROPVARIANT activation_params_prop;
|
||||
|
||||
PropVariantInit(&activation_params_prop);
|
||||
activation_params_prop.vt = VT_BLOB;
|
||||
activation_params_prop.blob.cbSize = sizeof(activation_params);
|
||||
activation_params_prop.blob.pBlobData = (BYTE*) &activation_params;
|
||||
|
||||
fill_activation_params(&activation_params);
|
||||
activation_params.StaticObjectTypeMask &= ~AudioObjectType_FrontRight;
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio stream: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_FrontLeft, &sao1);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio object: 0x%08lx\n", hr);
|
||||
hr = ISpatialAudioObject_IsActive(sao1, &is_active);
|
||||
todo_wine ok(hr == S_OK, "Failed to check if spatial audio object is active: 0x%08lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
ok(is_active, "Expected spatial audio object to be active\n");
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_FrontLeft, &sao2);
|
||||
ok(hr == SPTLAUDCLNT_E_OBJECT_ALREADY_ACTIVE, "Expected audio object to be already active: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_FrontRight, &sao2);
|
||||
ok(hr == SPTLAUDCLNT_E_STATIC_OBJECT_NOT_AVAILABLE, "Expected static object to be not available: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_Dynamic, &sao2);
|
||||
ok(hr == SPTLAUDCLNT_E_NO_MORE_OBJECTS, "Expected to not have no more dynamic objects: 0x%08lx\n", hr);
|
||||
|
||||
ISpatialAudioObject_Release(sao1);
|
||||
ISpatialAudioObjectRenderStream_Release(sas);
|
||||
}
|
||||
|
||||
static BOOL is_buffer_zeroed(const BYTE *buffer, UINT32 buffer_length)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i < buffer_length; i++)
|
||||
{
|
||||
if (buffer[i] != 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_audio_object_buffers(void)
|
||||
{
|
||||
UINT32 dyn_object_count, frame_count, max_frame_count, buffer_length;
|
||||
SpatialAudioObjectRenderStreamActivationParams activation_params;
|
||||
ISpatialAudioObjectRenderStream *sas = NULL;
|
||||
PROPVARIANT activation_params_prop;
|
||||
ISpatialAudioObject *sao[4];
|
||||
BYTE *buffer;
|
||||
INT i, j, k;
|
||||
HRESULT hr;
|
||||
|
||||
PropVariantInit(&activation_params_prop);
|
||||
activation_params_prop.vt = VT_BLOB;
|
||||
activation_params_prop.blob.cbSize = sizeof(activation_params);
|
||||
activation_params_prop.blob.pBlobData = (BYTE*) &activation_params;
|
||||
|
||||
fill_activation_params(&activation_params);
|
||||
hr = ISpatialAudioClient_ActivateSpatialAudioStream(sac, &activation_params_prop, &IID_ISpatialAudioObjectRenderStream, (void**)&sas);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio stream: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioClient_GetMaxFrameCount(sac, &format, &max_frame_count);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
frame_count = format.nSamplesPerSec / 100; /* 10ms */
|
||||
/* Most of the time the frame count matches the 10ms interval exactly.
|
||||
* However (seen on some Testbot machines) it might be a bit higher for some reason. */
|
||||
ok(max_frame_count <= frame_count + frame_count / 4, "Got unexpected frame count %u.\n", frame_count);
|
||||
|
||||
/* The tests below which check frame count from _BeginUpdatingAudioObjects fail on some Testbot machines
|
||||
* with max_frame_count from _GetMaxFrameCount(). */
|
||||
max_frame_count = frame_count + frame_count / 4;
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_FrontLeft, &sao[0]);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio object: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_Start(sas);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio render stream: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_FrontRight, &sao[1]);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio object: 0x%08lx\n", hr);
|
||||
|
||||
hr = WaitForSingleObject(event, 200);
|
||||
ok(hr == WAIT_OBJECT_0, "Expected event to be flagged: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_SideLeft, &sao[2]);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio object: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_BeginUpdatingAudioObjects(sas, &dyn_object_count, &frame_count);
|
||||
ok(hr == S_OK, "Failed to begin updating audio objects: 0x%08lx\n", hr);
|
||||
ok(dyn_object_count == 0, "Unexpected dynamic objects\n");
|
||||
ok(frame_count <= max_frame_count, "Got unexpected frame count %u.\n", frame_count);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_ActivateSpatialAudioObject(sas, AudioObjectType_SideRight, &sao[3]);
|
||||
ok(hr == S_OK, "Failed to activate spatial audio object: 0x%08lx\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(sao); i++)
|
||||
{
|
||||
hr = ISpatialAudioObject_GetBuffer(sao[i], &buffer, &buffer_length);
|
||||
ok(hr == S_OK, "Expected to be able to get buffers for audio object: 0x%08lx\n", hr);
|
||||
ok(buffer != NULL, "Expected to get a non-NULL buffer\n");
|
||||
ok(buffer_length == frame_count * format.wBitsPerSample / 8, "Expected buffer length to be sample_size * frame_count = %hu but got %u\n",
|
||||
frame_count * format.wBitsPerSample / 8, buffer_length);
|
||||
ok(is_buffer_zeroed(buffer, buffer_length), "Expected audio object's buffer to be zeroed\n");
|
||||
}
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_EndUpdatingAudioObjects(sas);
|
||||
ok(hr == S_OK, "Failed to end updating audio objects: 0x%08lx\n", hr);
|
||||
|
||||
/* Emulate underrun and test frame count approximate limit. */
|
||||
|
||||
/* Force 1ms Sleep() timer resolution. */
|
||||
timeBeginPeriod(1);
|
||||
for (j = 0; j < 20; ++j)
|
||||
{
|
||||
hr = WaitForSingleObject(event, 200);
|
||||
ok(hr == WAIT_OBJECT_0, "Expected event to be flagged: 0x%08lx, j %u.\n", hr, j);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_BeginUpdatingAudioObjects(sas, &dyn_object_count, &frame_count);
|
||||
ok(hr == S_OK, "Failed to begin updating audio objects: 0x%08lx\n", hr);
|
||||
ok(dyn_object_count == 0, "Unexpected dynamic objects\n");
|
||||
ok(frame_count <= max_frame_count, "Got unexpected frame_count %u.\n", frame_count);
|
||||
|
||||
/* Audio starts crackling with delays 10ms and above. However, setting such delay (that is, the delay
|
||||
* which skips the whole quantum) breaks SA on some Testbot machines: _BeginUpdatingAudioObjects fails
|
||||
* with SPTLAUDCLNT_E_INTERNAL starting from some iteration or WaitForSingleObject timeouts. That seems
|
||||
* to work on the real hardware though. */
|
||||
Sleep(5);
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(sao); i++)
|
||||
{
|
||||
hr = ISpatialAudioObject_GetBuffer(sao[i], &buffer, &buffer_length);
|
||||
ok(hr == S_OK, "Expected to be able to get buffers for audio object: 0x%08lx, i %d\n", hr, i);
|
||||
ok(buffer != NULL, "Expected to get a non-NULL buffer\n");
|
||||
ok(buffer_length == frame_count * format.wBitsPerSample / 8,
|
||||
"Expected buffer length to be sample_size * frame_count = %hu but got %u\n",
|
||||
frame_count * format.wBitsPerSample / 8, buffer_length);
|
||||
|
||||
/* Enable to hear the test sound. */
|
||||
if (0)
|
||||
{
|
||||
if (format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
|
||||
{
|
||||
for (k = 0; k < frame_count; ++k)
|
||||
{
|
||||
float time_sec = 10.0f / 1000.0f * (j + (float)k / frame_count);
|
||||
|
||||
/* 440Hz tone. */
|
||||
((float *)buffer)[k] = sinf(2.0f * M_PI * time_sec * 440.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hr = ISpatialAudioObjectRenderStream_EndUpdatingAudioObjects(sas);
|
||||
ok(hr == S_OK, "Failed to end updating audio objects: 0x%08lx\n", hr);
|
||||
}
|
||||
timeEndPeriod(1);
|
||||
|
||||
hr = WaitForSingleObject(event, 200);
|
||||
ok(hr == WAIT_OBJECT_0, "Expected event to be flagged: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_BeginUpdatingAudioObjects(sas, &dyn_object_count, &frame_count);
|
||||
ok(hr == S_OK, "Failed to begin updating audio objects: 0x%08lx\n", hr);
|
||||
ok(dyn_object_count == 0, "Unexpected dynamic objects\n");
|
||||
|
||||
/* one more iteration but not with every object */
|
||||
for (i = 0; i < ARRAYSIZE(sao) - 1; i++)
|
||||
{
|
||||
hr = ISpatialAudioObject_GetBuffer(sao[i], &buffer, &buffer_length);
|
||||
ok(hr == S_OK, "Expected to be able to get buffers for audio object: 0x%08lx\n", hr);
|
||||
ok(buffer != NULL, "Expected to get a non-NULL buffer\n");
|
||||
ok(buffer_length == frame_count * format.wBitsPerSample / 8, "Expected buffer length to be sample_size * frame_count = %hu but got %u\n",
|
||||
frame_count * format.wBitsPerSample / 8, buffer_length);
|
||||
ok(is_buffer_zeroed(buffer, buffer_length), "Expected audio object's buffer to be zeroed\n");
|
||||
}
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_EndUpdatingAudioObjects(sas);
|
||||
ok(hr == S_OK, "Failed to end updating audio objects: 0x%08lx\n", hr);
|
||||
|
||||
/* ending the stream */
|
||||
hr = ISpatialAudioObject_SetEndOfStream(sao[0], 0);
|
||||
todo_wine ok(hr == SPTLAUDCLNT_E_OUT_OF_ORDER, "Expected that ending the stream at this point won't be allowed: 0x%08lx\n", hr);
|
||||
|
||||
hr = WaitForSingleObject(event, 200);
|
||||
ok(hr == WAIT_OBJECT_0, "Expected event to be flagged: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObject_SetEndOfStream(sao[0], 0);
|
||||
todo_wine ok(hr == SPTLAUDCLNT_E_OUT_OF_ORDER, "Expected that ending the stream at this point won't be allowed: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_BeginUpdatingAudioObjects(sas, &dyn_object_count, &frame_count);
|
||||
ok(hr == S_OK, "Failed to begin updating audio objects: 0x%08lx\n", hr);
|
||||
ok(dyn_object_count == 0, "Unexpected dynamic objects\n");
|
||||
|
||||
/* expect the object that was not updated last cycle to be invalidated */
|
||||
hr = ISpatialAudioObject_GetBuffer(sao[ARRAYSIZE(sao) - 1], &buffer, &buffer_length);
|
||||
todo_wine ok(hr == SPTLAUDCLNT_E_RESOURCES_INVALIDATED, "Expected audio object to be invalidated: 0x%08lx\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(sao) - 1; i++)
|
||||
{
|
||||
hr = ISpatialAudioObject_GetBuffer(sao[i], &buffer, &buffer_length);
|
||||
ok(hr == S_OK, "Expected to be able to get buffers for audio object: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObject_SetEndOfStream(sao[i], 0);
|
||||
todo_wine ok(hr == S_OK, "Failed to end the stream: 0x%08lx\n", hr);
|
||||
|
||||
hr = ISpatialAudioObject_GetBuffer(sao[i], &buffer, &buffer_length);
|
||||
todo_wine ok(hr == SPTLAUDCLNT_E_RESOURCES_INVALIDATED, "Expected audio object to be invalidated: 0x%08lx\n", hr);
|
||||
}
|
||||
|
||||
hr = ISpatialAudioObjectRenderStream_EndUpdatingAudioObjects(sas);
|
||||
ok(hr == S_OK, "Failed to end updating audio objects: 0x%08lx\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(sao); i++)
|
||||
{
|
||||
ISpatialAudioObject_Release(sao[i]);
|
||||
}
|
||||
|
||||
ISpatialAudioObjectRenderStream_Release(sas);
|
||||
}
|
||||
|
||||
START_TEST(spatialaudio)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
event = CreateEventA(NULL, FALSE, FALSE, "spatial-audio-test-prog-event");
|
||||
ok(event != NULL, "Failed to create event, last error: 0x%08lx\n", GetLastError());
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("mmdevapi not available: 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eRender, eMultimedia, &dev);
|
||||
ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08lx\n", hr);
|
||||
if (hr != S_OK || !dev)
|
||||
{
|
||||
if (hr == E_NOTFOUND)
|
||||
skip("No sound card available\n");
|
||||
else
|
||||
skip("GetDefaultAudioEndpoint returns 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hr = IMMDevice_Activate(dev, &IID_ISpatialAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&sac);
|
||||
ok(hr == S_OK || hr == E_NOINTERFACE, "ISpatialAudioClient Activation failed: 0x%08lx\n", hr);
|
||||
if (hr != S_OK || !dev)
|
||||
{
|
||||
if (hr == E_NOINTERFACE)
|
||||
skip("ISpatialAudioClient interface not found\n");
|
||||
else
|
||||
skip("ISpatialAudioClient Activation returns 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hr = ISpatialAudioClient_GetMaxDynamicObjectCount(sac, &max_dyn_count);
|
||||
ok(hr == S_OK, "Failed to get max dynamic object count: 0x%08lx\n", hr);
|
||||
|
||||
/* that's the default, after manually enabling Windows Sonic it's possible to have max_dyn_count > 0 */
|
||||
/* ok(max_dyn_count == 0, "expected max dynamic object count to be 0 got %u\n", max_dyn_count); */
|
||||
|
||||
test_formats();
|
||||
test_stream_activation();
|
||||
test_audio_object_activation();
|
||||
test_audio_object_buffers();
|
||||
|
||||
ISpatialAudioClient_Release(sac);
|
||||
|
||||
cleanup:
|
||||
if (dev)
|
||||
IMMDevice_Release(dev);
|
||||
if (mme)
|
||||
IMMDeviceEnumerator_Release(mme);
|
||||
CoUninitialize();
|
||||
CloseHandle(event);
|
||||
}
|
|
@ -1,336 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 Jacek Caban for CodeWeavers
|
||||
* Copyright 2021-2022 Huw Davies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "audioclient.h"
|
||||
#include "mmdeviceapi.h"
|
||||
|
||||
typedef UINT64 stream_handle;
|
||||
|
||||
enum driver_priority
|
||||
{
|
||||
Priority_Unavailable = 0, /* driver won't work */
|
||||
Priority_Low, /* driver may work, but unlikely */
|
||||
Priority_Neutral, /* driver makes no judgment */
|
||||
Priority_Preferred /* driver thinks it's correct */
|
||||
};
|
||||
|
||||
struct endpoint
|
||||
{
|
||||
unsigned int name;
|
||||
unsigned int device;
|
||||
};
|
||||
|
||||
struct main_loop_params
|
||||
{
|
||||
HANDLE event;
|
||||
};
|
||||
|
||||
struct get_endpoint_ids_params
|
||||
{
|
||||
EDataFlow flow;
|
||||
struct endpoint *endpoints;
|
||||
unsigned int size;
|
||||
HRESULT result;
|
||||
unsigned int num;
|
||||
unsigned int default_idx;
|
||||
};
|
||||
|
||||
struct create_stream_params
|
||||
{
|
||||
const char *name;
|
||||
const char *device;
|
||||
EDataFlow flow;
|
||||
AUDCLNT_SHAREMODE share;
|
||||
DWORD flags;
|
||||
REFERENCE_TIME duration;
|
||||
REFERENCE_TIME period;
|
||||
const WAVEFORMATEX *fmt;
|
||||
HRESULT result;
|
||||
UINT32 *channel_count;
|
||||
stream_handle *stream;
|
||||
};
|
||||
|
||||
struct release_stream_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HANDLE timer_thread;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct start_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct stop_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct reset_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct timer_loop_params
|
||||
{
|
||||
stream_handle stream;
|
||||
};
|
||||
|
||||
struct get_render_buffer_params
|
||||
{
|
||||
stream_handle stream;
|
||||
UINT32 frames;
|
||||
HRESULT result;
|
||||
BYTE **data;
|
||||
};
|
||||
|
||||
struct release_render_buffer_params
|
||||
{
|
||||
stream_handle stream;
|
||||
UINT32 written_frames;
|
||||
UINT flags;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct get_capture_buffer_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
BYTE **data;
|
||||
UINT32 *frames;
|
||||
UINT *flags;
|
||||
UINT64 *devpos;
|
||||
UINT64 *qpcpos;
|
||||
};
|
||||
|
||||
struct release_capture_buffer_params
|
||||
{
|
||||
stream_handle stream;
|
||||
UINT32 done;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct is_format_supported_params
|
||||
{
|
||||
const char *device;
|
||||
EDataFlow flow;
|
||||
AUDCLNT_SHAREMODE share;
|
||||
const WAVEFORMATEX *fmt_in;
|
||||
WAVEFORMATEXTENSIBLE *fmt_out;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct get_mix_format_params
|
||||
{
|
||||
const char *device;
|
||||
EDataFlow flow;
|
||||
WAVEFORMATEXTENSIBLE *fmt;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct get_device_period_params
|
||||
{
|
||||
const char *device;
|
||||
EDataFlow flow;
|
||||
HRESULT result;
|
||||
REFERENCE_TIME *def_period;
|
||||
REFERENCE_TIME *min_period;
|
||||
};
|
||||
|
||||
struct get_buffer_size_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
UINT32 *frames;
|
||||
};
|
||||
|
||||
struct get_latency_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
REFERENCE_TIME *latency;
|
||||
};
|
||||
|
||||
struct get_current_padding_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
UINT32 *padding;
|
||||
};
|
||||
|
||||
struct get_next_packet_size_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
UINT32 *frames;
|
||||
};
|
||||
|
||||
struct get_frequency_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
UINT64 *freq;
|
||||
};
|
||||
|
||||
struct get_position_params
|
||||
{
|
||||
stream_handle stream;
|
||||
BOOL device;
|
||||
HRESULT result;
|
||||
UINT64 *pos;
|
||||
UINT64 *qpctime;
|
||||
};
|
||||
|
||||
struct set_volumes_params
|
||||
{
|
||||
stream_handle stream;
|
||||
float master_volume;
|
||||
const float *volumes;
|
||||
const float *session_volumes;
|
||||
int channel;
|
||||
};
|
||||
|
||||
struct set_event_handle_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HANDLE event;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct test_connect_params
|
||||
{
|
||||
const char *name;
|
||||
enum driver_priority priority;
|
||||
};
|
||||
|
||||
struct is_started_params
|
||||
{
|
||||
stream_handle stream;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct get_prop_value_params
|
||||
{
|
||||
const char *device;
|
||||
EDataFlow flow;
|
||||
const GUID *guid;
|
||||
const PROPERTYKEY *prop;
|
||||
HRESULT result;
|
||||
PROPVARIANT *value;
|
||||
void *buffer; /* caller allocated buffer to hold value's strings */
|
||||
unsigned int *buffer_size;
|
||||
};
|
||||
|
||||
struct midi_init_params
|
||||
{
|
||||
UINT *err;
|
||||
};
|
||||
|
||||
struct notify_context
|
||||
{
|
||||
BOOL send_notify;
|
||||
WORD dev_id;
|
||||
WORD msg;
|
||||
UINT_PTR param_1;
|
||||
UINT_PTR param_2;
|
||||
UINT_PTR callback;
|
||||
UINT flags;
|
||||
HANDLE device;
|
||||
UINT_PTR instance;
|
||||
};
|
||||
|
||||
struct midi_out_message_params
|
||||
{
|
||||
UINT dev_id;
|
||||
UINT msg;
|
||||
UINT_PTR user;
|
||||
UINT_PTR param_1;
|
||||
UINT_PTR param_2;
|
||||
UINT *err;
|
||||
struct notify_context *notify;
|
||||
};
|
||||
|
||||
struct midi_in_message_params
|
||||
{
|
||||
UINT dev_id;
|
||||
UINT msg;
|
||||
UINT_PTR user;
|
||||
UINT_PTR param_1;
|
||||
UINT_PTR param_2;
|
||||
UINT *err;
|
||||
struct notify_context *notify;
|
||||
};
|
||||
|
||||
struct midi_notify_wait_params
|
||||
{
|
||||
BOOL *quit;
|
||||
struct notify_context *notify;
|
||||
};
|
||||
|
||||
struct aux_message_params
|
||||
{
|
||||
UINT dev_id;
|
||||
UINT msg;
|
||||
UINT_PTR user;
|
||||
UINT_PTR param_1;
|
||||
UINT_PTR param_2;
|
||||
UINT *err;
|
||||
};
|
||||
|
||||
enum unix_funcs
|
||||
{
|
||||
process_attach,
|
||||
process_detach,
|
||||
main_loop,
|
||||
get_endpoint_ids,
|
||||
create_stream,
|
||||
release_stream,
|
||||
start,
|
||||
stop,
|
||||
reset,
|
||||
timer_loop,
|
||||
get_render_buffer,
|
||||
release_render_buffer,
|
||||
get_capture_buffer,
|
||||
release_capture_buffer,
|
||||
is_format_supported,
|
||||
get_mix_format,
|
||||
get_device_period,
|
||||
get_buffer_size,
|
||||
get_latency,
|
||||
get_current_padding,
|
||||
get_next_packet_size,
|
||||
get_frequency,
|
||||
get_position,
|
||||
set_volumes,
|
||||
set_event_handle,
|
||||
test_connect,
|
||||
is_started,
|
||||
get_prop_value,
|
||||
midi_init,
|
||||
midi_release,
|
||||
midi_out_message,
|
||||
midi_in_message,
|
||||
midi_notify_wait,
|
||||
aux_message,
|
||||
};
|
|
@ -1,11 +0,0 @@
|
|||
MODULE = winealsa.drv
|
||||
UNIXLIB = winealsa.so
|
||||
IMPORTS = uuid ole32 advapi32
|
||||
DELAYIMPORTS = winmm
|
||||
UNIX_LIBS = $(ALSA_LIBS) $(PTHREAD_LIBS)
|
||||
|
||||
SOURCES = \
|
||||
alsa.c \
|
||||
alsamidi.c \
|
||||
midi.c \
|
||||
mmdevdrv.c
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* MIDI driver for ALSA (PE-side)
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1998 Luiz Otavio L. Zorzella
|
||||
* Copyright 1998, 1999 Eric POUECH
|
||||
* Copyright 2003 Christian Costa
|
||||
* Copyright 2022 Huw Davies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winternl.h"
|
||||
#include "mmddk.h"
|
||||
#include "mmdeviceapi.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unixlib.h"
|
||||
|
||||
#include "unixlib.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(midi);
|
||||
|
||||
static void notify_client(struct notify_context *notify)
|
||||
{
|
||||
TRACE("dev_id = %d msg = %d param1 = %04IX param2 = %04IX\n", notify->dev_id, notify->msg, notify->param_1, notify->param_2);
|
||||
|
||||
DriverCallback(notify->callback, notify->flags, notify->device, notify->msg,
|
||||
notify->instance, notify->param_1, notify->param_2);
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* MIDI entry points *
|
||||
*======================================================================*/
|
||||
|
||||
/**************************************************************************
|
||||
* midMessage (WINEALSA.@)
|
||||
*/
|
||||
DWORD WINAPI ALSA_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
|
||||
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
struct midi_in_message_params params;
|
||||
struct notify_context notify;
|
||||
UINT err;
|
||||
|
||||
TRACE("(%04X, %04X, %08IX, %08IX, %08IX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
params.dev_id = wDevID;
|
||||
params.msg = wMsg;
|
||||
params.user = dwUser;
|
||||
params.param_1 = dwParam1;
|
||||
params.param_2 = dwParam2;
|
||||
params.err = &err;
|
||||
params.notify = ¬ify;
|
||||
|
||||
do
|
||||
{
|
||||
ALSA_CALL(midi_in_message, ¶ms);
|
||||
if ((!err || err == ERROR_RETRY) && notify.send_notify) notify_client(¬ify);
|
||||
} while (err == ERROR_RETRY);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* modMessage (WINEALSA.@)
|
||||
*/
|
||||
DWORD WINAPI ALSA_modMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
|
||||
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
struct midi_out_message_params params;
|
||||
struct notify_context notify;
|
||||
UINT err;
|
||||
|
||||
TRACE("(%04X, %04X, %08IX, %08IX, %08IX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
params.dev_id = wDevID;
|
||||
params.msg = wMsg;
|
||||
params.user = dwUser;
|
||||
params.param_1 = dwParam1;
|
||||
params.param_2 = dwParam2;
|
||||
params.err = &err;
|
||||
params.notify = ¬ify;
|
||||
|
||||
ALSA_CALL(midi_out_message, ¶ms);
|
||||
|
||||
if (!err && notify.send_notify) notify_client(¬ify);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static DWORD WINAPI notify_thread(void *p)
|
||||
{
|
||||
struct midi_notify_wait_params params;
|
||||
struct notify_context notify;
|
||||
BOOL quit;
|
||||
|
||||
SetThreadDescription(GetCurrentThread(), L"winealsa_midi_notify");
|
||||
|
||||
params.notify = ¬ify;
|
||||
params.quit = &quit;
|
||||
|
||||
while (1)
|
||||
{
|
||||
ALSA_CALL(midi_notify_wait, ¶ms);
|
||||
if (quit) break;
|
||||
if (notify.send_notify) notify_client(¬ify);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DriverProc (WINEALSA.@)
|
||||
*/
|
||||
LRESULT CALLBACK ALSA_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
|
||||
LPARAM dwParam1, LPARAM dwParam2)
|
||||
{
|
||||
switch(wMsg) {
|
||||
case DRV_LOAD:
|
||||
CloseHandle(CreateThread(NULL, 0, notify_thread, NULL, 0, NULL));
|
||||
return 1;
|
||||
case DRV_FREE:
|
||||
ALSA_CALL(midi_release, NULL);
|
||||
return 1;
|
||||
case DRV_OPEN:
|
||||
case DRV_CLOSE:
|
||||
case DRV_ENABLE:
|
||||
case DRV_DISABLE:
|
||||
case DRV_QUERYCONFIGURE:
|
||||
case DRV_CONFIGURE:
|
||||
return 1;
|
||||
case DRV_INSTALL:
|
||||
case DRV_REMOVE:
|
||||
return DRV_SUCCESS;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright 2022 Huw Davies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "../mmdevapi/unixlib.h"
|
||||
|
||||
NTSTATUS alsa_midi_release(void *args);
|
||||
NTSTATUS alsa_midi_out_message(void *args);
|
||||
NTSTATUS alsa_midi_in_message(void *args);
|
||||
NTSTATUS alsa_midi_notify_wait(void *args);
|
||||
|
||||
#ifdef _WIN64
|
||||
NTSTATUS alsa_wow64_midi_out_message(void *args);
|
||||
NTSTATUS alsa_wow64_midi_in_message(void *args);
|
||||
NTSTATUS alsa_wow64_midi_notify_wait(void *args);
|
||||
#endif
|
||||
|
||||
#define ALSA_CALL(func, params) WINE_UNIX_CALL(func, params)
|
|
@ -1,11 +0,0 @@
|
|||
# WinMM driver functions
|
||||
@ stdcall -private DriverProc(long long long long long) ALSA_DriverProc
|
||||
@ stdcall -private midMessage(long long long long long) ALSA_midMessage
|
||||
@ stdcall -private modMessage(long long long long long) ALSA_modMessage
|
||||
|
||||
# MMDevAPI driver functions
|
||||
@ stdcall -private GetPriority() AUDDRV_GetPriority
|
||||
@ stdcall -private GetEndpointIDs(long ptr ptr ptr ptr) AUDDRV_GetEndpointIDs
|
||||
@ stdcall -private GetAudioEndpoint(ptr ptr ptr) AUDDRV_GetAudioEndpoint
|
||||
@ stdcall -private GetAudioSessionManager(ptr ptr) AUDDRV_GetAudioSessionManager
|
||||
@ stdcall -private GetPropValue(ptr ptr ptr) AUDDRV_GetPropValue
|
|
@ -1,11 +0,0 @@
|
|||
MODULE = winecoreaudio.drv
|
||||
UNIXLIB = winecoreaudio.so
|
||||
IMPORTS = uuid ole32 user32 advapi32
|
||||
DELAYIMPORTS = winmm
|
||||
UNIX_LIBS = $(COREAUDIO_LIBS)
|
||||
|
||||
SOURCES = \
|
||||
coreaudio.c \
|
||||
coremidi.c \
|
||||
midi.c \
|
||||
mmdevdrv.c
|
File diff suppressed because it is too large
Load diff
|
@ -1,36 +0,0 @@
|
|||
/* Definition for CoreAudio drivers : wine multimedia system
|
||||
*
|
||||
* Copyright 2005-2007 Emmanuel Maillard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_COREAUDIO_H
|
||||
#define __WINE_COREAUDIO_H
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
/* fourcc is in native order, where MSB is the first character. */
|
||||
static inline const char* wine_dbgstr_fourcc(INT32 fourcc)
|
||||
{
|
||||
char buf[4] = { (char) (fourcc >> 24), (char) (fourcc >> 16),
|
||||
(char) (fourcc >> 8), (char) fourcc };
|
||||
/* OSStatus is a signed decimal except in parts of CoreAudio */
|
||||
if ((buf[0] < 32) || (buf[1] < 32) || (buf[2] < 32) || (buf[3] < 32))
|
||||
return wine_dbg_sprintf("%d", fourcc);
|
||||
return wine_dbgstr_an(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
#endif /* __WINE_COREAUDIO_H */
|
File diff suppressed because it is too large
Load diff
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
* MIDI driver for macOS (PE-side)
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1998 Luiz Otavio L. Zorzella
|
||||
* Copyright 1998, 1999 Eric POUECH
|
||||
* Copyright 2005, 2006 Emmanuel Maillard
|
||||
* Copyright 2021 Huw Davies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winternl.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "mmddk.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "audioclient.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unixlib.h"
|
||||
#include "coreaudio.h"
|
||||
#include "unixlib.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(midi);
|
||||
|
||||
static void notify_client(struct notify_context *notify)
|
||||
{
|
||||
TRACE("dev_id=%d msg=%d param1=%04IX param2=%04IX\n", notify->dev_id, notify->msg, notify->param_1, notify->param_2);
|
||||
|
||||
DriverCallback(notify->callback, notify->flags, notify->device, notify->msg,
|
||||
notify->instance, notify->param_1, notify->param_2);
|
||||
}
|
||||
|
||||
static DWORD WINAPI notify_thread(void *p)
|
||||
{
|
||||
struct midi_notify_wait_params params;
|
||||
struct notify_context notify;
|
||||
BOOL quit;
|
||||
|
||||
params.notify = ¬ify;
|
||||
params.quit = &quit;
|
||||
|
||||
while (1)
|
||||
{
|
||||
UNIX_CALL(midi_notify_wait, ¶ms);
|
||||
if (quit) break;
|
||||
if (notify.send_notify) notify_client(¬ify);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LONG CoreAudio_MIDIInit(void)
|
||||
{
|
||||
struct midi_init_params params;
|
||||
UINT err;
|
||||
|
||||
params.err = &err;
|
||||
|
||||
UNIX_CALL(midi_init, ¶ms);
|
||||
if (err != DRV_SUCCESS)
|
||||
{
|
||||
ERR("can't create midi client\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
CloseHandle(CreateThread(NULL, 0, notify_thread, NULL, 0, NULL));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static LONG CoreAudio_MIDIRelease(void)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
UNIX_CALL(midi_release, NULL);
|
||||
|
||||
return DRV_SUCCESS;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* modMessage
|
||||
*/
|
||||
DWORD WINAPI CoreAudio_modMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
struct midi_out_message_params params;
|
||||
struct notify_context notify;
|
||||
UINT err;
|
||||
|
||||
TRACE("%d %08x %08Ix %08Ix %08Ix\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
params.dev_id = wDevID;
|
||||
params.msg = wMsg;
|
||||
params.user = dwUser;
|
||||
params.param_1 = dwParam1;
|
||||
params.param_2 = dwParam2;
|
||||
params.err = &err;
|
||||
params.notify = ¬ify;
|
||||
|
||||
UNIX_CALL(midi_out_message, ¶ms);
|
||||
|
||||
if (!err && notify.send_notify) notify_client(¬ify);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* midMessage
|
||||
*/
|
||||
DWORD WINAPI CoreAudio_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
struct midi_in_message_params params;
|
||||
struct notify_context notify;
|
||||
UINT err;
|
||||
|
||||
TRACE("%d %08x %08Ix %08Ix %08Ix\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
params.dev_id = wDevID;
|
||||
params.msg = wMsg;
|
||||
params.user = dwUser;
|
||||
params.param_1 = dwParam1;
|
||||
params.param_2 = dwParam2;
|
||||
params.err = &err;
|
||||
params.notify = ¬ify;
|
||||
|
||||
do
|
||||
{
|
||||
UNIX_CALL(midi_in_message, ¶ms);
|
||||
if ((!err || err == ERROR_RETRY) && notify.send_notify) notify_client(¬ify);
|
||||
} while (err == ERROR_RETRY);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CoreAudio_drvLoad [internal]
|
||||
*/
|
||||
static LRESULT CoreAudio_drvLoad(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
|
||||
if (CoreAudio_MIDIInit() != DRV_SUCCESS)
|
||||
return DRV_FAILURE;
|
||||
|
||||
return DRV_SUCCESS;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CoreAudio_drvFree [internal]
|
||||
*/
|
||||
static LRESULT CoreAudio_drvFree(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
CoreAudio_MIDIRelease();
|
||||
return DRV_SUCCESS;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CoreAudio_drvOpen [internal]
|
||||
*/
|
||||
static LRESULT CoreAudio_drvOpen(LPSTR str)
|
||||
{
|
||||
TRACE("(%s)\n", str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CoreAudio_drvClose [internal]
|
||||
*/
|
||||
static DWORD CoreAudio_drvClose(DWORD dwDevID)
|
||||
{
|
||||
TRACE("(%08lx)\n", dwDevID);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DriverProc (WINECOREAUDIO.1)
|
||||
*/
|
||||
LRESULT CALLBACK CoreAudio_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
|
||||
LPARAM dwParam1, LPARAM dwParam2)
|
||||
{
|
||||
TRACE("(%08IX, %p, %s (%08X), %08IX, %08IX)\n",
|
||||
dwDevID, hDriv, wMsg == DRV_LOAD ? "DRV_LOAD" :
|
||||
wMsg == DRV_FREE ? "DRV_FREE" :
|
||||
wMsg == DRV_OPEN ? "DRV_OPEN" :
|
||||
wMsg == DRV_CLOSE ? "DRV_CLOSE" :
|
||||
wMsg == DRV_ENABLE ? "DRV_ENABLE" :
|
||||
wMsg == DRV_DISABLE ? "DRV_DISABLE" :
|
||||
wMsg == DRV_QUERYCONFIGURE ? "DRV_QUERYCONFIGURE" :
|
||||
wMsg == DRV_CONFIGURE ? "DRV_CONFIGURE" :
|
||||
wMsg == DRV_INSTALL ? "DRV_INSTALL" :
|
||||
wMsg == DRV_REMOVE ? "DRV_REMOVE" : "UNKNOWN",
|
||||
wMsg, dwParam1, dwParam2);
|
||||
|
||||
switch(wMsg) {
|
||||
case DRV_LOAD: return CoreAudio_drvLoad();
|
||||
case DRV_FREE: return CoreAudio_drvFree();
|
||||
case DRV_OPEN: return CoreAudio_drvOpen((LPSTR)dwParam1);
|
||||
case DRV_CLOSE: return CoreAudio_drvClose(dwDevID);
|
||||
case DRV_ENABLE: return 1;
|
||||
case DRV_DISABLE: return 1;
|
||||
case DRV_QUERYCONFIGURE: return 1;
|
||||
case DRV_CONFIGURE: MessageBoxA(0, "CoreAudio driver!", "CoreAudio driver", MB_OK); return 1;
|
||||
case DRV_INSTALL: return DRVCNF_RESTART;
|
||||
case DRV_REMOVE: return DRVCNF_RESTART;
|
||||
default:
|
||||
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Unixlib header file for winecoreaudio driver.
|
||||
*
|
||||
* Copyright 2021 Huw Davies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "../mmdevapi/unixlib.h"
|
||||
|
||||
NTSTATUS unix_midi_init( void * );
|
||||
NTSTATUS unix_midi_release( void * );
|
||||
NTSTATUS unix_midi_out_message( void * );
|
||||
NTSTATUS unix_midi_in_message( void * );
|
||||
NTSTATUS unix_midi_notify_wait( void * );
|
||||
|
||||
#ifdef _WIN64
|
||||
NTSTATUS unix_wow64_midi_init(void *args);
|
||||
NTSTATUS unix_wow64_midi_out_message(void *args);
|
||||
NTSTATUS unix_wow64_midi_in_message(void *args);
|
||||
NTSTATUS unix_wow64_midi_notify_wait(void *args);
|
||||
#endif
|
||||
|
||||
#define UNIX_CALL( func, params ) WINE_UNIX_CALL( func, params )
|
|
@ -1,10 +0,0 @@
|
|||
# WinMM driver functions
|
||||
@ stdcall -private DriverProc(long long long long long) CoreAudio_DriverProc
|
||||
@ stdcall -private midMessage(long long long long long) CoreAudio_midMessage
|
||||
@ stdcall -private modMessage(long long long long long) CoreAudio_modMessage
|
||||
|
||||
# MMDevAPI driver functions
|
||||
@ stdcall -private GetPriority() AUDDRV_GetPriority
|
||||
@ stdcall -private GetEndpointIDs(long ptr ptr ptr ptr) AUDDRV_GetEndpointIDs
|
||||
@ stdcall -private GetAudioEndpoint(ptr ptr ptr) AUDDRV_GetAudioEndpoint
|
||||
@ stdcall -private GetAudioSessionManager(ptr ptr) AUDDRV_GetAudioSessionManager
|
|
@ -1,14 +0,0 @@
|
|||
MODULE = wineoss.drv
|
||||
UNIXLIB = wineoss.so
|
||||
IMPORTS = uuid ole32 user32 advapi32
|
||||
DELAYIMPORTS = winmm
|
||||
UNIX_LIBS = $(OSS4_LIBS) $(PTHREAD_LIBS)
|
||||
UNIX_CFLAGS = $(OSS4_CFLAGS)
|
||||
|
||||
SOURCES = \
|
||||
midi.c \
|
||||
midipatch.c \
|
||||
mmaux.c \
|
||||
mmdevdrv.c \
|
||||
oss.c \
|
||||
ossmidi.c
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* MIDI driver for OSS (PE-side)
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1998 Luiz Otavio L. Zorzella (init procedures)
|
||||
* Copyright 1998, 1999 Eric POUECH
|
||||
* Copyright 2022 Huw Davies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
* + use better instrument definition for OPL/2 (midiPatch.c) or
|
||||
* use existing instrument definition (from playmidi or kmid)
|
||||
* with a .winerc option
|
||||
* + have a look at OPL/3 ?
|
||||
* + implement asynchronous playback of MidiHdr
|
||||
* + implement STREAM'ed MidiHdr (question: how shall we share the
|
||||
* code between the midiStream functions in MMSYSTEM/WINMM and
|
||||
* the code for the low level driver)
|
||||
* + use a more accurate read mechanism than the one of snooping on
|
||||
* timers (like select on fd)
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winternl.h"
|
||||
#include "mmddk.h"
|
||||
#include "audioclient.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unixlib.h"
|
||||
|
||||
#include "unixlib.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(midi);
|
||||
|
||||
/*======================================================================*
|
||||
* Low level MIDI implementation *
|
||||
*======================================================================*/
|
||||
|
||||
static void notify_client(struct notify_context *notify)
|
||||
{
|
||||
TRACE("dev_id = %d msg = %d param1 = %04IX param2 = %04IX\n",
|
||||
notify->dev_id, notify->msg, notify->param_1, notify->param_2);
|
||||
|
||||
DriverCallback(notify->callback, notify->flags, notify->device, notify->msg,
|
||||
notify->instance, notify->param_1, notify->param_2);
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* MIDI entry points *
|
||||
*======================================================================*/
|
||||
|
||||
/**************************************************************************
|
||||
* midMessage (WINEOSS.@)
|
||||
*/
|
||||
DWORD WINAPI OSS_midMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
|
||||
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
struct midi_in_message_params params;
|
||||
struct notify_context notify;
|
||||
UINT err;
|
||||
|
||||
TRACE("(%04X, %04X, %08IX, %08IX, %08IX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
params.dev_id = wDevID;
|
||||
params.msg = wMsg;
|
||||
params.user = dwUser;
|
||||
params.param_1 = dwParam1;
|
||||
params.param_2 = dwParam2;
|
||||
params.err = &err;
|
||||
params.notify = ¬ify;
|
||||
|
||||
do
|
||||
{
|
||||
OSS_CALL(midi_in_message, ¶ms);
|
||||
if ((!err || err == ERROR_RETRY) && notify.send_notify) notify_client(¬ify);
|
||||
} while (err == ERROR_RETRY);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* modMessage (WINEOSS.@)
|
||||
*/
|
||||
DWORD WINAPI OSS_modMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
|
||||
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
struct midi_out_message_params params;
|
||||
struct notify_context notify;
|
||||
UINT err;
|
||||
|
||||
TRACE("(%04X, %04X, %08IX, %08IX, %08IX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
params.dev_id = wDevID;
|
||||
params.msg = wMsg;
|
||||
params.user = dwUser;
|
||||
params.param_1 = dwParam1;
|
||||
params.param_2 = dwParam2;
|
||||
params.err = &err;
|
||||
params.notify = ¬ify;
|
||||
|
||||
OSS_CALL(midi_out_message, ¶ms);
|
||||
|
||||
if (!err && notify.send_notify) notify_client(¬ify);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static DWORD WINAPI notify_thread(void *p)
|
||||
{
|
||||
struct midi_notify_wait_params params;
|
||||
struct notify_context notify;
|
||||
BOOL quit;
|
||||
|
||||
params.notify = ¬ify;
|
||||
params.quit = &quit;
|
||||
|
||||
while (1)
|
||||
{
|
||||
OSS_CALL(midi_notify_wait, ¶ms);
|
||||
if (quit) break;
|
||||
if (notify.send_notify) notify_client(¬ify);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DriverProc (WINEOSS.1)
|
||||
*/
|
||||
LRESULT CALLBACK OSS_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
|
||||
LPARAM dwParam1, LPARAM dwParam2)
|
||||
{
|
||||
TRACE("(%08IX, %p, %08X, %08IX, %08IX)\n",
|
||||
dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
||||
|
||||
switch(wMsg) {
|
||||
case DRV_LOAD:
|
||||
CloseHandle(CreateThread(NULL, 0, notify_thread, NULL, 0, NULL));
|
||||
return 1;
|
||||
case DRV_FREE:
|
||||
OSS_CALL(midi_release, NULL);
|
||||
return 1;
|
||||
case DRV_OPEN:
|
||||
case DRV_CLOSE:
|
||||
case DRV_ENABLE:
|
||||
case DRV_DISABLE:
|
||||
case DRV_QUERYCONFIGURE:
|
||||
case DRV_CONFIGURE:
|
||||
return 1;
|
||||
case DRV_INSTALL:
|
||||
case DRV_REMOVE:
|
||||
return DRV_SUCCESS;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* FM patches for wine MIDI driver
|
||||
*
|
||||
* Copyright 1999 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Eric POUECH : MIDI FM patches for GM instruments
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#define NOT_DEFINED 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
const unsigned char midiFMInstrumentPatches[128 * 16] = {
|
||||
/* 0 Acoustic Grand Piano */ 0x21, 0x11, 0x4c, 0x00, 0xf1, 0xf2, 0x63, 0x72, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 1 Bright Acoustic Piano */ 0x01, 0x11, 0x4f, 0x00, 0xf1, 0xd2, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 2 Electric Grand Piano */ 0x01, 0x01, 0x4f, 0x04, 0xf1, 0xd2, 0x50, 0x7c, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 3 Honky-Tonk Piano */ 0x81, 0x13, 0x9d, 0x00, 0xf2, 0xf2, 0x51, 0xf1, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 4 Rhodes Piano */ 0x01, 0x01, 0x4f, 0x04, 0xf1, 0xd2, 0x50, 0x7c, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 5 Chorused Piano */ 0x01, 0x11, 0x4d, 0x00, 0xf1, 0xd2, 0x60, 0x7b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 6 Harpsichord */ 0x32, 0x16, 0x87, 0x80, 0xa1, 0x7d, 0x10, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 7 Clavinet */ 0x13, 0x08, 0x80, 0x00, 0xfb, 0xe8, 0xff, 0xff, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 8 Celesta */ 0x14, 0x04, 0x07, 0x00, 0x93, 0xb6, 0x73, 0x62, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 9 Glockenspiel */ 0x07, 0x12, 0x4f, 0x00, 0xf2, 0xf2, 0x60, 0x72, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 10 Music Box */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 11 Vibraphone */ 0x44, 0x60, 0x53, 0x80, 0xf5, 0xfd, 0x33, 0x25, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 12 Marimba */ 0x05, 0x01, 0x4e, 0x00, 0xda, 0xf9, 0x25, 0x15, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 13 Xylophone */ 0x11, 0x31, 0x2d, 0x00, 0xc8, 0xf5, 0x2f, 0xf5, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 14 Tubular Bells */ 0x03, 0x17, 0x4f, 0x03, 0xf1, 0xf2, 0x53, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 15 Dulcimer */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 16 Hammond Organ */ 0x72, 0x71, 0xcd, 0x80, 0x91, 0x91, 0x2a, 0x2a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 17 Percussive Organ */ 0x0c, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb5, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 18 Rock Organ */ 0x72, 0x70, 0xce, 0x80, 0x9f, 0x94, 0x12, 0x11, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 19 Church Organ */ 0xa5, 0xb1, 0xd2, 0x80, 0x81, 0xf1, 0x03, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 20 Reed Organ */ 0x3e, 0xb1, 0x29, 0x80, 0xfb, 0xa0, 0xf0, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 21 Accordion */ 0x24, 0x31, 0x4f, 0x00, 0xf2, 0x52, 0x0b, 0x0b, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 22 Harmonica */ 0x22, 0xf2, 0x8f, 0x40, 0x41, 0x61, 0x03, 0x05, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 23 Tango Accordion */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 24 Acoustic Nylon Guitar */ 0x01, 0x01, 0x11, 0x00, 0xf2, 0xf5, 0x1f, 0x88, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 25 Acoustic Steel Guitar */ 0x01, 0xa1, 0x46, 0x03, 0xf1, 0x31, 0x83, 0x86, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 26 Electric Jazz Guitar */ 0x03, 0x11, 0x5e, 0x00, 0x85, 0xd2, 0x51, 0x71, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 27 Electric Clean Guitar */ 0x32, 0x16, 0x87, 0x80, 0xa1, 0x7d, 0x10, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 28 Electric Muted Guitar */ 0x13, 0x11, 0x96, 0x80, 0xff, 0xff, 0x21, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 29 Overdriven Guitar */ 0x07, 0x14, 0x8f, 0x80, 0x82, 0x82, 0x7d, 0x7d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 30 Distortion Guitar */ 0x05, 0x01, 0x8f, 0x80, 0xda, 0xf9, 0x15, 0x14, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 31 Guitar Harmonics */ 0xc3, 0x01, 0x05, 0x0d, 0x91, 0xf1, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 32 Acoustic Bass */ 0x21, 0x01, 0x2a, 0x00, 0xf2, 0xf5, 0x1f, 0x88, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 33 Electric Bass Fingered */ 0x01, 0x21, 0x15, 0x80, 0x25, 0x65, 0x2f, 0x6c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 34 Electric Bass Picked */ 0x01, 0x01, 0x1d, 0x00, 0xf2, 0xf5, 0xef, 0x78, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 35 Fretless Bass */ 0x30, 0x21, 0x1e, 0x00, 0xf2, 0xf5, 0xef, 0x78, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 36 Slap Bass 1 */ 0x20, 0x21, 0x40, 0x00, 0x7b, 0x75, 0x04, 0x72, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 37 Slap Bass 2 */ 0x20, 0x21, 0x40, 0x00, 0x7b, 0xf5, 0x04, 0x72, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 38 Synth Bass 1 */ 0x41, 0x91, 0x83, 0x00, 0x65, 0x32, 0x05, 0x74, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 39 Synth Bass 2 */ 0x30, 0xb1, 0x88, 0x80, 0xd5, 0x61, 0x19, 0x1b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 40 Violin */ 0x72, 0x62, 0x1c, 0x05, 0x51, 0x52, 0x03, 0x13, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 41 Viola */ 0x70, 0x71, 0xd0, 0x80, 0x52, 0x31, 0x11, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 42 Cello */ 0x70, 0x71, 0xc5, 0x80, 0x52, 0x31, 0x11, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 43 Contrabass */ 0x01, 0x00, 0x00, 0x00, 0x94, 0x83, 0xb6, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 44 Tremolo Strings */ 0x71, 0xa1, 0x8b, 0x40, 0x71, 0x42, 0x11, 0x15, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 45 Pizzicato Strings */ 0xf2, 0xe1, 0x40, 0x80, 0xf5, 0xfd, 0xa8, 0xad, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 46 Orchestral Harp */ 0x21, 0x11, 0x11, 0x00, 0xa3, 0xc4, 0x43, 0x22, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 47 Timpani */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 48 String Ensemble 1 */ 0xe1, 0x21, 0x4f, 0x00, 0xc1, 0x32, 0xd3, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 49 String Ensemble 2 */ 0xe1, 0x21, 0x4f, 0x00, 0xb1, 0x12, 0xd3, 0x74, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 50 Synth Strings 1 */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 51 Synth Strings 2 */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 52 Choir Aahs */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 53 Voice oohs */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 54 Synth Voice */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 55 Orchestra Hit */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 56 Trumpet */ 0x31, 0xa1, 0x1c, 0x80, 0x41, 0x92, 0x0b, 0x3b, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 57 Trombone */ 0x21, 0xa1, 0x18, 0x80, 0x53, 0x52, 0x1d, 0x3b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 58 Tuba */ 0x21, 0x21, 0x19, 0x80, 0x43, 0x85, 0x8c, 0x2f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 59 Muted Trumpet */ 0x31, 0xa1, 0x1c, 0x80, 0x41, 0x92, 0x0b, 0x3b, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 60 French Horn */ 0x21, 0x21, 0x9f, 0x80, 0x53, 0xaa, 0x5a, 0x1a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 61 Brass Section */ 0x21, 0x21, 0x16, 0x00, 0x71, 0x81, 0xae, 0x9e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 62 Synth Brass 1 */ 0x61, 0x60, 0x1c, 0x00, 0x71, 0x81, 0xae, 0x2e, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 63 Synth Brass 2 */ 0x21, 0x21, 0x8e, 0x80, 0xbb, 0x90, 0x29, 0x0a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 64 Soprano Sax */ 0x01, 0x12, 0x4f, 0x00, 0x71, 0x52, 0x53, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 65 Alto Sax */ 0x01, 0x13, 0x4f, 0x00, 0x71, 0x62, 0x53, 0x84, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 66 Tenor Sax */ 0x01, 0x13, 0x8d, 0x00, 0x51, 0x52, 0x53, 0x7c, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 67 Baritone Sax */ 0x01, 0x12, 0x4f, 0x00, 0x71, 0x22, 0x53, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 68 Oboe */ 0x71, 0x62, 0xc5, 0x05, 0x6e, 0x8b, 0x17, 0x0e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 69 English Horn */ 0xe1, 0xe4, 0x23, 0x00, 0x71, 0x82, 0xae, 0x9e, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 70 Bassoon */ 0x30, 0xb1, 0xcd, 0x80, 0xd5, 0x61, 0x19, 0x1b, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 71 Clarinet */ 0x32, 0xa1, 0x1c, 0x80, 0x51, 0x82, 0x15, 0x45, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 72 Piccolo */ 0xe4, 0xe4, 0x0f, 0x00, 0x70, 0x60, 0x0f, 0x9f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 73 Flute */ 0xe1, 0x61, 0x27, 0x80, 0x53, 0x53, 0x8a, 0x57, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 74 Recorder */ 0x61, 0x61, 0x27, 0x80, 0x74, 0x65, 0x8f, 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 75 Pan Flute */ 0xe0, 0xa1, 0xec, 0x00, 0x6e, 0x65, 0x8f, 0x2a, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 76 Bottle Blow */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 77 Shakuhashi */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 78 Whistle */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 79 Ocarina */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 80 Synth lead 1 - Sq wave lead */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 81 Synth lead 2 - Sawtooth Wave */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 82 Synth lead 3 - Caliope lead */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 83 Synth lead 4 - Chiff lead */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 84 Synth lead 5 - Charang */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 85 Synth lead 6 - Solo Synth Voice */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 86 Synth lead 7 - Bright Saw Wave */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 87 Synth lead 8 - Brass and Lead */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 88 Synth pad 1 - Fantasia Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 89 Synth pad 2 - Warm Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 90 Synth pad 3 - Poly Synth Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 91 Synth pad 4 - Space Voice Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 92 Synth pad 5 - Bowed Glass Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 93 Synth pad 6 - Metal Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 94 Synth pad 7 - Halo Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 95 Synth pad 8 - Sweep Pad */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 96 Synth SFX 1 - Ice Rain */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 97 Synth SFX 2 - Soundtrack */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 98 Synth SFX 3 - Crystal */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 99 Synth SFX 4 - Atmosphere */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 100 Synth SFX 5 - Brightness */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 101 Synth SFX 6 - Goblin */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 102 Synth SFX 7 - Echo drops */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 103 Synth SFX 8 - Star Theme */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 104 Sitar */ 0x01, 0x08, 0x40, 0x00, 0xf2, 0xf2, 0x54, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 105 Banjo */ 0x31, 0x16, 0x87, 0x80, 0xa1, 0x7d, 0x11, 0x43, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 106 Shamisen */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 107 Koto */ 0x0e, 0x02, 0x40, 0x00, 0x09, 0xf7, 0x53, 0x94, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 108 Kalimba */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 109 Bagpipe */ 0x31, 0x22, 0x43, 0x05, 0x6e, 0x8b, 0x17, 0x0c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 110 Fiddle */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 111 Shanai */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 112 Tinkle Bell */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 113 Agogo */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 114 Steel Drums */ 0x00, 0x00, 0x0b, 0x00, 0xa8, 0xd6, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 115 Woodblock */ 0x02, 0x11, 0x4f, 0x00, 0x71, 0x52, 0x53, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 116 Taiko Drum */ 0x12, 0x02, 0x0b, 0x00, 0x95, 0xd4, 0x4c, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 117 Melodic Tom */ 0x01, 0x02, 0x00, 0x00, 0xfa, 0xda, 0xbf, 0xbf, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 118 Synth Drum */ 0x06, 0x00, 0x00, 0x00, 0xf0, 0xf6, 0xf0, 0xb4, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 119 Reverse Cymbal */ 0x64, 0x03, 0x00, 0x40, 0xb2, 0x97, 0x82, 0xd4, 0x02, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 120 Guitar Fret Noise */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 121 Breath Noise */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 122 Seashore */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 123 Bird Tweet */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 124 Telephone Ring */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 125 Helicopter */ 0xf0, 0xe2, 0x00, 0xc0, 0x1e, 0x11, 0x11, 0x11, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 126 Applause */ 0x07, 0x01, 0x87, 0x80, 0xf0, 0xf0, 0x05, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 127 Gunshot */ 0x0c, 0x50, 0x00, 0x21, 0xf8, 0x09, 0xb6, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
const unsigned char midiFMDrumsPatches[16 * 128] = {
|
||||
/* 1 Not defined */ NOT_DEFINED
|
||||
/* 2 Not defined */ NOT_DEFINED
|
||||
/* 3 Not defined */ NOT_DEFINED
|
||||
/* 4 Not defined */ NOT_DEFINED
|
||||
/* 5 Not defined */ NOT_DEFINED
|
||||
/* 6 Not defined */ NOT_DEFINED
|
||||
/* 7 Not defined */ NOT_DEFINED
|
||||
/* 8 Not defined */ NOT_DEFINED
|
||||
/* 9 Not defined */ NOT_DEFINED
|
||||
/* 10 Not defined */ NOT_DEFINED
|
||||
/* 11 Not defined */ NOT_DEFINED
|
||||
/* 12 Not defined */ NOT_DEFINED
|
||||
/* 13 Not defined */ NOT_DEFINED
|
||||
/* 14 Not defined */ NOT_DEFINED
|
||||
/* 15 Not defined */ NOT_DEFINED
|
||||
/* 16 Not defined */ NOT_DEFINED
|
||||
/* 17 Not defined */ NOT_DEFINED
|
||||
/* 18 Not defined */ NOT_DEFINED
|
||||
/* 19 Not defined */ NOT_DEFINED
|
||||
/* 20 Not defined */ NOT_DEFINED
|
||||
/* 21 Not defined */ NOT_DEFINED
|
||||
/* 22 Not defined */ NOT_DEFINED
|
||||
/* 23 Not defined */ NOT_DEFINED
|
||||
/* 24 Not defined */ NOT_DEFINED
|
||||
/* 25 Not defined */ NOT_DEFINED
|
||||
/* 26 Not defined */ NOT_DEFINED
|
||||
/* 27 Not defined */ NOT_DEFINED
|
||||
/* 28 Not defined */ NOT_DEFINED
|
||||
/* 29 Not defined */ NOT_DEFINED
|
||||
/* 30 Not defined */ NOT_DEFINED
|
||||
/* 31 Not defined */ NOT_DEFINED
|
||||
/* 32 Not defined */ NOT_DEFINED
|
||||
/* 33 Not defined */ NOT_DEFINED
|
||||
/* 34 Not defined */ NOT_DEFINED
|
||||
/* 35 Acoustic Bass Drum */ 0x00, 0x00, 0x0d, 0x00, 0xe8, 0xa5, 0xef, 0xff, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 36 Bass Drum 1 */ 0x00, 0x00, 0x0b, 0x00, 0xa8, 0xd6, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 37 Side Stick */ NOT_DEFINED
|
||||
/* 38 Acoustic Snare */ 0x2e, 0x02, 0x0a, 0x1b, 0xff, 0xf6, 0x0f, 0x4a, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, /* snare */
|
||||
/* 39 Hand Clap */ NOT_DEFINED
|
||||
/* 40 Electric Snare */ 0x0c, 0xd0, 0x00, 0x00, 0xc7, 0x70, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* rksnare */
|
||||
/* 41 Low Floor Tom */ NOT_DEFINED
|
||||
/* 42 Closed Hi-Hat */ 0x64, 0x03, 0x02, 0x40, 0xb2, 0x97, 0xa2, 0xd4, 0x02, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, /* cymbal */
|
||||
/* 43 High Floor Tom */ NOT_DEFINED
|
||||
/* 44 Pedal Hi-Hat */ NOT_DEFINED
|
||||
/* 45 Low Tom */ 0x01, 0x02, 0x00, 0x00, 0xfa, 0xda, 0xbf, 0xbf, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* tom */
|
||||
/* 46 Open Hi-Hat */ NOT_DEFINED
|
||||
/* 47 Low-Mid Tom */ 0x02, 0x30, 0x00, 0x00, 0xc8, 0xe0, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* tom2 */
|
||||
/* 48 Hi-Mid Tom */ NOT_DEFINED
|
||||
/* 49 Crash Cymbal 1 */ NOT_DEFINED
|
||||
/* 50 High Tom */ NOT_DEFINED
|
||||
/* 51 Ride Cymbal 1 */ 0x64, 0x03, 0x00, 0x40, 0xb2, 0x97, 0x82, 0xd4, 0x02, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, /* bcymbal */
|
||||
/* 52 Chinese Cymbal */ NOT_DEFINED
|
||||
/* 53 Ride Bell */ NOT_DEFINED
|
||||
/* 54 Tambourine */ NOT_DEFINED
|
||||
/* 55 Splash Cymbal */ NOT_DEFINED
|
||||
/* 56 Cowbell */ NOT_DEFINED
|
||||
/* 57 Crash Cymbal 2 */ NOT_DEFINED
|
||||
/* 58 Vibrasl */ NOT_DEFINED
|
||||
/* 59 Ride Cymbal */ NOT_DEFINED
|
||||
/* 60 Hi Bon */ NOT_DEFINED
|
||||
/* 61 Low Bon */ NOT_DEFINED
|
||||
/* 62 Mute Hi Con */ NOT_DEFINED
|
||||
/* 63 Open Hi Con */ NOT_DEFINED
|
||||
/* 64 Low Con */ NOT_DEFINED
|
||||
/* 65 High Timba */ NOT_DEFINED
|
||||
/* 66 Low Timba */ NOT_DEFINED
|
||||
/* 67 High Ago */ NOT_DEFINED
|
||||
/* 68 Low Ago */ NOT_DEFINED
|
||||
/* 69 Caba */ NOT_DEFINED
|
||||
/* 70 Marac */ NOT_DEFINED
|
||||
/* 71 Short Whist */ NOT_DEFINED
|
||||
/* 72 Long Whist */ NOT_DEFINED
|
||||
/* 73 Short Gui */ NOT_DEFINED
|
||||
/* 74 Long Gui */ NOT_DEFINED
|
||||
/* 75 Clav */ 0x13, 0x08, 0x80, 0x00, 0xfb, 0xe8, 0xff, 0xff, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, /* claves */
|
||||
/* 76 Hi Wood Blo */ NOT_DEFINED
|
||||
/* 77 Low Wood Blo */ NOT_DEFINED
|
||||
/* 78 Mute Cui */ NOT_DEFINED
|
||||
/* 79 Open Cui */ NOT_DEFINED
|
||||
/* 80 Mute Triang */ NOT_DEFINED
|
||||
/* 81 Open Triang */ 0x26, 0x1e, 0x03, 0x00, 0xe0, 0xff, 0xf0, 0x31, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* triangle */
|
||||
/* 82 Not defined */ NOT_DEFINED
|
||||
/* 83 Not defined */ NOT_DEFINED
|
||||
/* 84 Not defined */ NOT_DEFINED
|
||||
/* 85 Not defined */ NOT_DEFINED
|
||||
/* 86 Not defined */ NOT_DEFINED
|
||||
/* 87 Not defined */ NOT_DEFINED
|
||||
/* 88 Not defined */ NOT_DEFINED
|
||||
/* 89 Not defined */ NOT_DEFINED
|
||||
/* 90 Not defined */ NOT_DEFINED
|
||||
/* 91 Not defined */ NOT_DEFINED
|
||||
/* 92 Not defined */ NOT_DEFINED
|
||||
/* 93 Not defined */ NOT_DEFINED
|
||||
/* 94 Not defined */ NOT_DEFINED
|
||||
/* 95 Not defined */ NOT_DEFINED
|
||||
/* 96 Not defined */ NOT_DEFINED
|
||||
/* 97 Not defined */ NOT_DEFINED
|
||||
/* 98 Not defined */ NOT_DEFINED
|
||||
/* 99 Not defined */ NOT_DEFINED
|
||||
/* 100 Not defined */ NOT_DEFINED
|
||||
/* 101 Not defined */ NOT_DEFINED
|
||||
/* 102 Not defined */ NOT_DEFINED
|
||||
/* 103 Not defined */ NOT_DEFINED
|
||||
/* 104 Not defined */ NOT_DEFINED
|
||||
/* 105 Not defined */ NOT_DEFINED
|
||||
/* 106 Not defined */ NOT_DEFINED
|
||||
/* 107 Not defined */ NOT_DEFINED
|
||||
/* 108 Not defined */ NOT_DEFINED
|
||||
/* 109 Not defined */ NOT_DEFINED
|
||||
/* 110 Not defined */ NOT_DEFINED
|
||||
/* 111 Not defined */ NOT_DEFINED
|
||||
/* 112 Not defined */ NOT_DEFINED
|
||||
/* 113 Not defined */ NOT_DEFINED
|
||||
/* 114 Not defined */ NOT_DEFINED
|
||||
/* 115 Not defined */ NOT_DEFINED
|
||||
/* 116 Not defined */ NOT_DEFINED
|
||||
/* 117 Not defined */ NOT_DEFINED
|
||||
/* 118 Not defined */ NOT_DEFINED
|
||||
/* 119 Not defined */ NOT_DEFINED
|
||||
/* 120 Not defined */ NOT_DEFINED
|
||||
/* 121 Not defined */ NOT_DEFINED
|
||||
/* 122 Not defined */ NOT_DEFINED
|
||||
/* 123 Not defined */ NOT_DEFINED
|
||||
/* 124 Not defined */ NOT_DEFINED
|
||||
/* 125 Not defined */ NOT_DEFINED
|
||||
/* 126 Not defined */ NOT_DEFINED
|
||||
/* 127 Not defined */ NOT_DEFINED
|
||||
/* 128 Not defined */ NOT_DEFINED
|
||||
};
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Sample AUXILIARY Wine Driver
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "mmddk.h"
|
||||
#include "audioclient.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unixlib.h"
|
||||
|
||||
#include "unixlib.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mmaux);
|
||||
|
||||
/**************************************************************************
|
||||
* auxMessage (WINEOSS.2)
|
||||
*/
|
||||
DWORD WINAPI OSS_auxMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
|
||||
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
struct aux_message_params params;
|
||||
UINT err;
|
||||
|
||||
TRACE("(%04X, %04X, %08IX, %08IX, %08IX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
params.dev_id = wDevID;
|
||||
params.msg = wMsg;
|
||||
params.user = dwUser;
|
||||
params.param_1 = dwParam1;
|
||||
params.param_2 = dwParam2;
|
||||
params.err = &err;
|
||||
OSS_CALL(aux_message, ¶ms);
|
||||
|
||||
return err;
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright 2022 Huw Davies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "../mmdevapi/unixlib.h"
|
||||
|
||||
NTSTATUS oss_midi_release(void *args);
|
||||
NTSTATUS oss_midi_out_message(void *args);
|
||||
NTSTATUS oss_midi_in_message(void *args);
|
||||
NTSTATUS oss_midi_notify_wait(void *args);
|
||||
|
||||
#ifdef _WIN64
|
||||
NTSTATUS oss_wow64_midi_out_message(void *args);
|
||||
NTSTATUS oss_wow64_midi_in_message(void *args);
|
||||
NTSTATUS oss_wow64_midi_notify_wait(void *args);
|
||||
#endif
|
||||
|
||||
#define OSS_CALL(func, params) WINE_UNIX_CALL(func, params)
|
|
@ -1,11 +0,0 @@
|
|||
# WinMM driver functions
|
||||
@ stdcall -private DriverProc(long long long long long) OSS_DriverProc
|
||||
@ stdcall -private auxMessage(long long long long long) OSS_auxMessage
|
||||
@ stdcall -private midMessage(long long long long long) OSS_midMessage
|
||||
@ stdcall -private modMessage(long long long long long) OSS_modMessage
|
||||
|
||||
# MMDevAPI driver functions
|
||||
@ stdcall -private GetPriority() AUDDRV_GetPriority
|
||||
@ stdcall -private GetEndpointIDs(long ptr ptr ptr ptr) AUDDRV_GetEndpointIDs
|
||||
@ stdcall -private GetAudioEndpoint(ptr ptr ptr) AUDDRV_GetAudioEndpoint
|
||||
@ stdcall -private GetAudioSessionManager(ptr ptr) AUDDRV_GetAudioSessionManager
|
|
@ -1,9 +0,0 @@
|
|||
MODULE = winepulse.drv
|
||||
IMPORTS = dxguid uuid winmm user32 advapi32 ole32
|
||||
UNIX_LIBS = $(PULSE_LIBS) $(PTHREAD_LIBS)
|
||||
UNIX_CFLAGS = $(PULSE_CFLAGS)
|
||||
|
||||
EXTRADLLFLAGS = -mcygwin
|
||||
|
||||
SOURCES = \
|
||||
mmdevdrv.c
|
File diff suppressed because it is too large
Load diff
|
@ -1,11 +0,0 @@
|
|||
# MMDevAPI driver functions
|
||||
@ stdcall -private GetPriority() AUDDRV_GetPriority
|
||||
@ stdcall -private GetEndpointIDs(long ptr ptr ptr ptr) AUDDRV_GetEndpointIDs
|
||||
@ stdcall -private GetAudioEndpoint(ptr ptr ptr) AUDDRV_GetAudioEndpoint
|
||||
@ stdcall -private GetAudioSessionManager(ptr ptr) AUDDRV_GetAudioSessionManager
|
||||
@ stdcall -private GetPropValue(ptr ptr ptr) AUDDRV_GetPropValue
|
||||
|
||||
# WinMM driver functions
|
||||
@ stdcall -private DriverProc(long long long long long) winealsa.drv.DriverProc
|
||||
@ stdcall -private midMessage(long long long long long) winealsa.drv.midMessage
|
||||
@ stdcall -private modMessage(long long long long long) winealsa.drv.modMessage
|
|
@ -1,64 +0,0 @@
|
|||
## Configuration:
|
||||
# Control you default wine config in nixpkgs-config:
|
||||
# wine = {
|
||||
# release = "stable"; # "stable", "unstable", "staging", "wayland"
|
||||
# build = "wineWow"; # "wine32", "wine64", "wineWow"
|
||||
# };
|
||||
# Make additional configurations on demand:
|
||||
# wine.override { wineBuild = "wine32"; wineRelease = "staging"; };
|
||||
{ lib, stdenv, callPackage, darwin,
|
||||
wineBuild ? if stdenv.hostPlatform.system == "x86_64-linux" then "wineWow" else "wine32",
|
||||
gettextSupport ? true,
|
||||
fontconfigSupport ? stdenv.isLinux,
|
||||
alsaSupport ? stdenv.isLinux,
|
||||
gtkSupport ? false,
|
||||
openglSupport ? true,
|
||||
tlsSupport ? true,
|
||||
gstreamerSupport ? false,
|
||||
cupsSupport ? true,
|
||||
dbusSupport ? stdenv.isLinux,
|
||||
openclSupport ? false,
|
||||
cairoSupport ? stdenv.isLinux,
|
||||
odbcSupport ? false,
|
||||
netapiSupport ? false,
|
||||
cursesSupport ? true,
|
||||
vaSupport ? false,
|
||||
pcapSupport ? false,
|
||||
v4lSupport ? false,
|
||||
saneSupport ? stdenv.isLinux,
|
||||
gphoto2Support ? false,
|
||||
krb5Support ? false,
|
||||
pulseaudioSupport ? stdenv.isLinux,
|
||||
udevSupport ? stdenv.isLinux,
|
||||
xineramaSupport ? stdenv.isLinux,
|
||||
vulkanSupport ? true,
|
||||
sdlSupport ? true,
|
||||
usbSupport ? true,
|
||||
mingwSupport ? true,
|
||||
waylandSupport ? stdenv.isLinux,
|
||||
x11Support ? stdenv.isLinux,
|
||||
embedInstallers ? false, # The Mono and Gecko MSI installers
|
||||
moltenvk ? darwin.moltenvk # Allow users to override MoltenVK easily
|
||||
}:
|
||||
|
||||
let wine-build = build: release:
|
||||
lib.getAttr build (callPackage ./packages.nix {
|
||||
wineRelease = release;
|
||||
supportFlags = {
|
||||
inherit
|
||||
alsaSupport cairoSupport cupsSupport cursesSupport dbusSupport
|
||||
embedInstallers fontconfigSupport gettextSupport gphoto2Support
|
||||
gstreamerSupport gtkSupport krb5Support mingwSupport netapiSupport
|
||||
odbcSupport openclSupport openglSupport pcapSupport
|
||||
pulseaudioSupport saneSupport sdlSupport tlsSupport udevSupport
|
||||
usbSupport v4lSupport vaSupport vulkanSupport waylandSupport
|
||||
x11Support xineramaSupport
|
||||
;
|
||||
};
|
||||
inherit moltenvk;
|
||||
});
|
||||
|
||||
in
|
||||
callPackage ./osu-wine.nix {
|
||||
wineUnstable = wine-build wineBuild "unstable";
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
{ lib, callPackage, autoconf, hexdump, perl, python3, wineUnstable, path }:
|
||||
|
||||
with callPackage "${path}/pkgs/applications/emulators/wine/util.nix" {};
|
||||
|
||||
let patch = (callPackage ./sources.nix {}).staging;
|
||||
build-inputs = pkgNames: extra:
|
||||
(mkBuildInputs wineUnstable.pkgArches pkgNames) ++ extra;
|
||||
patchList = lib.mapAttrsToList (k: v: ./patches/${k}) (builtins.readDir ./patches);
|
||||
in assert lib.versions.majorMinor wineUnstable.version == lib.versions.majorMinor patch.version;
|
||||
|
||||
(lib.overrideDerivation (wineUnstable.override { wineRelease = "staging"; }) (self: {
|
||||
buildInputs = build-inputs [ "perl" "util-linux" "autoconf" "gitMinimal" ] self.buildInputs;
|
||||
nativeBuildInputs = [ autoconf hexdump perl python3 ] ++ self.nativeBuildInputs;
|
||||
|
||||
prePatch = self.prePatch or "" + ''
|
||||
patchShebangs tools
|
||||
cp -r ${patch}/patches ${patch}/staging .
|
||||
chmod +w patches
|
||||
patchShebangs ./patches/gitapply.sh
|
||||
python3 ./staging/patchinstall.py DESTDIR="$PWD" --all ${lib.concatMapStringsSep " " (ps: "-W ${ps}") patch.disabledPatchsets}
|
||||
for dir in $(ls ${./audio-revert}); do
|
||||
rm -rf dlls/$dir
|
||||
cp -r ${./audio-revert}/$dir dlls
|
||||
chmod -R +w dlls/$dir
|
||||
done
|
||||
for patch in ${builtins.concatStringsSep " " patchList}; do
|
||||
echo "Applying $patch"
|
||||
patch -p1 < "$patch"
|
||||
done
|
||||
'';
|
||||
})) // {
|
||||
meta = wineUnstable.meta // {
|
||||
description = wineUnstable.meta.description + " (with osu-wine patches)";
|
||||
};
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
{ stdenv_32bit, lib, pkgs, pkgsi686Linux, pkgsCross, callPackage, substituteAll, moltenvk, path,
|
||||
wineRelease ? "stable",
|
||||
supportFlags
|
||||
}:
|
||||
|
||||
let
|
||||
src = lib.getAttr wineRelease (callPackage ./sources.nix {});
|
||||
in with src; {
|
||||
wine32 = pkgsi686Linux.callPackage "${path}/pkgs/applications/emulators/wine/base.nix" {
|
||||
pname = "wine";
|
||||
inherit src version supportFlags patches moltenvk wineRelease;
|
||||
pkgArches = [ pkgsi686Linux ];
|
||||
geckos = [ gecko32 ];
|
||||
mingwGccs = with pkgsCross; [ mingw32.buildPackages.gcc ];
|
||||
monos = [ mono ];
|
||||
platforms = [ "i686-linux" "x86_64-linux" ];
|
||||
};
|
||||
wine64 = callPackage "${path}/pkgs/applications/emulators/wine/base.nix" {
|
||||
pname = "wine64";
|
||||
inherit src version supportFlags patches moltenvk wineRelease;
|
||||
pkgArches = [ pkgs ];
|
||||
mingwGccs = with pkgsCross; [ mingwW64.buildPackages.gcc ];
|
||||
geckos = [ gecko64 ];
|
||||
monos = [ mono ];
|
||||
configureFlags = [ "--enable-win64" ];
|
||||
platforms = [ "x86_64-linux" "x86_64-darwin" ];
|
||||
mainProgram = "wine64";
|
||||
};
|
||||
wineWow = callPackage "${path}/pkgs/applications/emulators/wine/base.nix" {
|
||||
pname = "wine-wow";
|
||||
inherit src version supportFlags patches moltenvk wineRelease;
|
||||
stdenv = stdenv_32bit;
|
||||
pkgArches = [ pkgs pkgsi686Linux ];
|
||||
geckos = [ gecko32 gecko64 ];
|
||||
mingwGccs = with pkgsCross; [ mingw32.buildPackages.gcc mingwW64.buildPackages.gcc ];
|
||||
monos = [ mono ];
|
||||
buildScript = substituteAll {
|
||||
src = "${path}/pkgs/applications/emulators/wine/builder-wow.sh";
|
||||
# pkgconfig has trouble picking the right architecture
|
||||
pkgconfig64remove = lib.makeSearchPathOutput "dev" "lib/pkgconfig" [ pkgs.glib pkgs.gst_all_1.gstreamer ];
|
||||
};
|
||||
platforms = [ "x86_64-linux" ];
|
||||
mainProgram = "wine64";
|
||||
};
|
||||
wineWow64 = callPackage "${path}/pkgs/applications/emulators/wine/base.nix" {
|
||||
pname = "wine-wow64";
|
||||
inherit src version patches moltenvk wineRelease;
|
||||
supportFlags = supportFlags // { mingwSupport = true; }; # Required because we request "--enable-archs=x86_64"
|
||||
pkgArches = [ pkgs ];
|
||||
mingwGccs = with pkgsCross; [ mingw32.buildPackages.gcc mingwW64.buildPackages.gcc ];
|
||||
geckos = [ gecko64 ];
|
||||
monos = [ mono ];
|
||||
configureFlags = [ "--enable-archs=x86_64,i386" ];
|
||||
platforms = [ "x86_64-linux" "x86_64-darwin" ];
|
||||
mainProgram = "wine";
|
||||
};
|
||||
}
|
|
@ -1,207 +0,0 @@
|
|||
--- a/include/wine/test.h
|
||||
+++ b/include/wine/test.h
|
||||
@@ -28,6 +28,13 @@
|
||||
#include <winbase.h>
|
||||
#include <wine/debug.h>
|
||||
|
||||
+#ifdef __WINE_CONFIG_H
|
||||
+#error config.h should not be used in Wine tests
|
||||
+#endif
|
||||
+#ifdef __WINE_WINE_UNICODE_H
|
||||
+#error wine/unicode.h should not be used in Wine tests
|
||||
+#endif
|
||||
+
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
#define INVALID_FILE_ATTRIBUTES (~0u)
|
||||
#endif
|
||||
--- /dev/null
|
||||
+++ b/include/wine/unicode.h
|
||||
@@ -0,0 +1,178 @@
|
||||
+/*
|
||||
+ * Wine internal Unicode definitions
|
||||
+ *
|
||||
+ * Copyright 2000 Alexandre Julliard
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#if 0
|
||||
+#pragma makedep install
|
||||
+#endif
|
||||
+
|
||||
+#ifndef __WINE_WINE_UNICODE_H
|
||||
+#define __WINE_WINE_UNICODE_H
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+
|
||||
+#include <windef.h>
|
||||
+#include <winbase.h>
|
||||
+#include <winnls.h>
|
||||
+#include <winternl.h>
|
||||
+
|
||||
+#ifdef __WINE_USE_MSVCRT
|
||||
+#error This file should not be used with msvcrt headers
|
||||
+#endif
|
||||
+
|
||||
+#ifndef WINE_UNICODE_INLINE
|
||||
+#define WINE_UNICODE_INLINE static FORCEINLINE
|
||||
+#endif
|
||||
+
|
||||
+WINE_UNICODE_INLINE WCHAR tolowerW( WCHAR ch )
|
||||
+{
|
||||
+ return RtlDowncaseUnicodeChar( ch );
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE WCHAR toupperW( WCHAR ch )
|
||||
+{
|
||||
+ return RtlUpcaseUnicodeChar( ch );
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE int isspaceW( WCHAR wc )
|
||||
+{
|
||||
+ unsigned short type;
|
||||
+ GetStringTypeW( CT_CTYPE1, &wc, 1, &type );
|
||||
+ return type & C1_SPACE;
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE unsigned int strlenW( const WCHAR *str )
|
||||
+{
|
||||
+ const WCHAR *s = str;
|
||||
+ while (*s) s++;
|
||||
+ return s - str;
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE WCHAR *strcpyW( WCHAR *dst, const WCHAR *src )
|
||||
+{
|
||||
+ WCHAR *p = dst;
|
||||
+ while ((*p++ = *src++));
|
||||
+ return dst;
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE WCHAR *strcatW( WCHAR *dst, const WCHAR *src )
|
||||
+{
|
||||
+ strcpyW( dst + strlenW(dst), src );
|
||||
+ return dst;
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE WCHAR *strrchrW( const WCHAR *str, WCHAR ch )
|
||||
+{
|
||||
+ WCHAR *ret = NULL;
|
||||
+ do { if (*str == ch) ret = (WCHAR *)(ULONG_PTR)str; } while (*str++);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE int strcmpiW( const WCHAR *str1, const WCHAR *str2 )
|
||||
+{
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ int ret = tolowerW(*str1) - tolowerW(*str2);
|
||||
+ if (ret || !*str1) return ret;
|
||||
+ str1++;
|
||||
+ str2++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n )
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ for ( ; n > 0; n--, str1++, str2++)
|
||||
+ if ((ret = tolowerW(*str1) - tolowerW(*str2)) || !*str1) break;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+WINE_UNICODE_INLINE LONG strtolW( LPCWSTR s, LPWSTR *end, INT base )
|
||||
+{
|
||||
+ BOOL negative = FALSE, empty = TRUE;
|
||||
+ LONG ret = 0;
|
||||
+
|
||||
+ if (base < 0 || base == 1 || base > 36) return 0;
|
||||
+ if (end) *end = (WCHAR *)s;
|
||||
+ while (isspaceW(*s)) s++;
|
||||
+
|
||||
+ if (*s == '-')
|
||||
+ {
|
||||
+ negative = TRUE;
|
||||
+ s++;
|
||||
+ }
|
||||
+ else if (*s == '+') s++;
|
||||
+
|
||||
+ if ((base == 0 || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
|
||||
+ {
|
||||
+ base = 16;
|
||||
+ s += 2;
|
||||
+ }
|
||||
+ if (base == 0) base = s[0] != '0' ? 10 : 8;
|
||||
+
|
||||
+ while (*s)
|
||||
+ {
|
||||
+ int v;
|
||||
+
|
||||
+ if ('0' <= *s && *s <= '9') v = *s - '0';
|
||||
+ else if ('A' <= *s && *s <= 'Z') v = *s - 'A' + 10;
|
||||
+ else if ('a' <= *s && *s <= 'z') v = *s - 'a' + 10;
|
||||
+ else break;
|
||||
+ if (v >= base) break;
|
||||
+ if (negative) v = -v;
|
||||
+ s++;
|
||||
+ empty = FALSE;
|
||||
+
|
||||
+ if (!negative && (ret > MAXLONG / base || ret * base > MAXLONG - v))
|
||||
+ ret = MAXLONG;
|
||||
+ else if (negative && (ret < (LONG)MINLONG / base || ret * base < (LONG)(MINLONG - v)))
|
||||
+ ret = MINLONG;
|
||||
+ else
|
||||
+ ret = ret * base + v;
|
||||
+ }
|
||||
+
|
||||
+ if (end && !empty) *end = (WCHAR *)s;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+NTSYSAPI int __cdecl _vsnwprintf(WCHAR*,size_t,const WCHAR*,__ms_va_list);
|
||||
+
|
||||
+static inline int WINAPIV snprintfW( WCHAR *str, size_t len, const WCHAR *format, ...)
|
||||
+{
|
||||
+ int retval;
|
||||
+ __ms_va_list valist;
|
||||
+ __ms_va_start(valist, format);
|
||||
+ retval = _vsnwprintf(str, len, format, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static inline int WINAPIV sprintfW( WCHAR *str, const WCHAR *format, ...)
|
||||
+{
|
||||
+ int retval;
|
||||
+ __ms_va_list valist;
|
||||
+ __ms_va_start(valist, format);
|
||||
+ retval = _vsnwprintf(str, MAXLONG, format, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+#undef WINE_UNICODE_INLINE
|
||||
+
|
||||
+#endif /* __WINE_WINE_UNICODE_H */
|
||||
--- a/include/Makefile.in
|
||||
+++ b/include/Makefile.in
|
||||
@@ -873,6 +873,7 @@
|
||||
wine/strmbase.h \
|
||||
wine/svcctl.idl \
|
||||
wine/test.h \
|
||||
+ wine/unicode.h \
|
||||
wine/unixlib.h \
|
||||
wine/vulkan.h \
|
||||
wine/vulkan_driver.h \
|
|
@ -1,24 +0,0 @@
|
|||
From 1b5de04e1ae401f2f3d7179da0379191886cdfad Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Tue, 2 May 2023 01:36:12 +0200
|
||||
Subject: [PATCH] libs/libjpeg: Set default DCT algorithm to fastest.
|
||||
|
||||
---
|
||||
libs/jpeg/jconfig.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/libs/jpeg/jconfig.h b/libs/jpeg/jconfig.h
|
||||
index 2d05a3b09026..9f18c71751bd 100644
|
||||
--- a/libs/jpeg/jconfig.h
|
||||
+++ b/libs/jpeg/jconfig.h
|
||||
@@ -17,6 +17,7 @@
|
||||
/* #undef NEED_SHORT_EXTERNAL_NAMES */
|
||||
/* Define this if you get warnings about undefined structures. */
|
||||
/* #undef INCOMPLETE_TYPES_BROKEN */
|
||||
+#define JDCT_DEFAULT JDCT_FASTEST
|
||||
|
||||
/* Define "boolean" as unsigned char, not enum, on Windows systems. */
|
||||
#ifdef _WIN32
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
--- b/dlls/winex11.drv/event.c
|
||||
+++ a/dlls/winex11.drv/event.c
|
||||
@@ -604,27 +604,16 @@
|
||||
*/
|
||||
static void set_focus( Display *display, HWND hwnd, Time time )
|
||||
{
|
||||
+ HWND focus;
|
||||
- HWND focus, old_active;
|
||||
Window win;
|
||||
GUITHREADINFO threadinfo;
|
||||
|
||||
- old_active = NtUserGetForegroundWindow();
|
||||
-
|
||||
/* prevent recursion */
|
||||
x11drv_thread_data()->active_window = hwnd;
|
||||
|
||||
TRACE( "setting foreground window to %p\n", hwnd );
|
||||
NtUserSetForegroundWindow( hwnd );
|
||||
|
||||
- /* Some applications expect that a being deactivated topmost window
|
||||
- * receives the WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED messages,
|
||||
- * and perform some specific actions. Chessmaster is one of such apps.
|
||||
- * Window Manager keeps a topmost window on top in z-oder, so there is
|
||||
- * no need to actually do anything, just send the messages.
|
||||
- */
|
||||
- if (old_active && (NtUserGetWindowLongW( old_active, GWL_EXSTYLE ) & WS_EX_TOPMOST))
|
||||
- NtUserSetWindowPos( old_active, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER );
|
||||
-
|
||||
threadinfo.cbSize = sizeof(threadinfo);
|
||||
NtUserGetGUIThreadInfo( 0, &threadinfo );
|
||||
focus = threadinfo.hwndFocus;
|
||||
--- b/dlls/win32u/input.c
|
||||
+++ a/dlls/win32u/input.c
|
||||
@@ -1375,9 +1375,6 @@
|
||||
send_message( hwnd, WM_ACTIVATE,
|
||||
MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, is_iconic(hwnd) ),
|
||||
(LPARAM)previous );
|
||||
-
|
||||
- send_message( hwnd, WM_NCPOINTERUP, 0, 0);
|
||||
-
|
||||
if (NtUserGetAncestor( hwnd, GA_PARENT ) == get_desktop_window())
|
||||
NtUserPostMessage( get_desktop_window(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
|
||||
|
||||
--- b/dlls/win32u/input.c
|
||||
+++ a/dlls/win32u/input.c
|
||||
@@ -1633,10 +1633,6 @@
|
||||
(LPARAM)previous );
|
||||
if (NtUserGetAncestor( hwnd, GA_PARENT ) == get_desktop_window())
|
||||
NtUserPostMessage( get_desktop_window(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
|
||||
-
|
||||
- if (hwnd == NtUserGetForegroundWindow() && !is_iconic( hwnd ))
|
||||
- NtUserSetActiveWindow( hwnd );
|
||||
-
|
||||
}
|
||||
|
||||
user_driver->pSetActiveWindow( hwnd );
|
||||
--- b/dlls/win32u/driver.c
|
||||
+++ a/dlls/win32u/driver.c
|
||||
@@ -838,10 +838,6 @@
|
||||
hdc, rect.left - dx, rect.top - dy, SRCCOPY, 0, 0 );
|
||||
}
|
||||
|
||||
-static void nulldrv_SetActiveWindow( HWND hwnd )
|
||||
-{
|
||||
-}
|
||||
-
|
||||
static void nulldrv_SetCapture( HWND hwnd, UINT flags )
|
||||
{
|
||||
}
|
||||
@@ -1245,7 +1241,6 @@
|
||||
nulldrv_ProcessEvents,
|
||||
nulldrv_ReleaseDC,
|
||||
nulldrv_ScrollDC,
|
||||
- nulldrv_SetActiveWindow,
|
||||
nulldrv_SetCapture,
|
||||
loaderdrv_SetDesktopWindow,
|
||||
nulldrv_SetFocus,
|
||||
@@ -1325,7 +1320,6 @@
|
||||
SET_USER_FUNC(ProcessEvents);
|
||||
SET_USER_FUNC(ReleaseDC);
|
||||
SET_USER_FUNC(ScrollDC);
|
||||
- SET_USER_FUNC(SetActiveWindow);
|
||||
SET_USER_FUNC(SetCapture);
|
||||
SET_USER_FUNC(SetDesktopWindow);
|
||||
SET_USER_FUNC(SetFocus);
|
||||
--- b/dlls/win32u/input.c
|
||||
+++ a/dlls/win32u/input.c
|
||||
@@ -1887,8 +1887,6 @@
|
||||
NtUserPostMessage( get_desktop_window(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
|
||||
}
|
||||
|
||||
- user_driver->pSetActiveWindow( hwnd );
|
||||
-
|
||||
/* now change focus if necessary */
|
||||
if (focus)
|
||||
{
|
||||
--- b/dlls/winex11.drv/event.c
|
||||
+++ a/dlls/winex11.drv/event.c
|
||||
@@ -576,9 +576,6 @@
|
||||
Window win;
|
||||
GUITHREADINFO threadinfo;
|
||||
|
||||
- /* prevent recursion */
|
||||
- x11drv_thread_data()->active_window = hwnd;
|
||||
-
|
||||
TRACE( "setting foreground window to %p\n", hwnd );
|
||||
NtUserSetForegroundWindow( hwnd );
|
||||
|
||||
@@ -836,8 +833,6 @@
|
||||
|
||||
if (!focus_win)
|
||||
{
|
||||
- x11drv_thread_data()->active_window = 0;
|
||||
-
|
||||
/* Abey : 6-Oct-99. Check again if the focus out window is the
|
||||
Foreground window, because in most cases the messages sent
|
||||
above must have already changed the foreground window, in which
|
||||
--- b/dlls/winex11.drv/init.c
|
||||
+++ a/dlls/winex11.drv/init.c
|
||||
@@ -421,7 +421,6 @@
|
||||
.pProcessEvents = X11DRV_ProcessEvents,
|
||||
.pReleaseDC = X11DRV_ReleaseDC,
|
||||
.pScrollDC = X11DRV_ScrollDC,
|
||||
- .pSetActiveWindow = X11DRV_SetActiveWindow,
|
||||
.pSetCapture = X11DRV_SetCapture,
|
||||
.pSetDesktopWindow = X11DRV_SetDesktopWindow,
|
||||
.pSetFocus = X11DRV_SetFocus,
|
||||
--- b/dlls/winex11.drv/window.c
|
||||
+++ a/dlls/winex11.drv/window.c
|
||||
@@ -2431,54 +2431,6 @@
|
||||
}
|
||||
|
||||
|
||||
-/***********************************************************************
|
||||
- * SetActiveWindow (X11DRV.@)
|
||||
- */
|
||||
-void X11DRV_SetActiveWindow( HWND hwnd )
|
||||
-{
|
||||
- struct x11drv_thread_data *thread_data = x11drv_init_thread_data();
|
||||
- struct x11drv_win_data *data;
|
||||
-
|
||||
- TRACE("%p\n", hwnd);
|
||||
-
|
||||
- if (thread_data->active_window == hwnd)
|
||||
- {
|
||||
- TRACE("ignoring activation for already active window %p\n", hwnd);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (!(data = get_win_data( hwnd ))) return;
|
||||
-
|
||||
- if (data->mapped && data->managed && !data->iconic)
|
||||
- {
|
||||
- XEvent xev;
|
||||
- struct x11drv_win_data *active = get_win_data( thread_data->active_window );
|
||||
- DWORD timestamp = NtUserGetThreadInfo()->message_time - EVENT_x11_time_to_win32_time( 0 );
|
||||
-
|
||||
- TRACE("setting _NET_ACTIVE_WINDOW to %p/%lx, current active %p/%lx\n",
|
||||
- data->hwnd, data->whole_window, active ? active->hwnd : NULL, active ? active->whole_window : 0 );
|
||||
-
|
||||
- xev.xclient.type = ClientMessage;
|
||||
- xev.xclient.window = data->whole_window;
|
||||
- xev.xclient.message_type = x11drv_atom(_NET_ACTIVE_WINDOW);
|
||||
- xev.xclient.serial = 0;
|
||||
- xev.xclient.display = data->display;
|
||||
- xev.xclient.send_event = True;
|
||||
- xev.xclient.format = 32;
|
||||
-
|
||||
- xev.xclient.data.l[0] = 1; /* source: application */
|
||||
- xev.xclient.data.l[1] = timestamp;
|
||||
- xev.xclient.data.l[2] = active ? active->whole_window : 0;
|
||||
- xev.xclient.data.l[3] = 0;
|
||||
- xev.xclient.data.l[4] = 0;
|
||||
- XSendEvent( data->display, root_window, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev );
|
||||
-
|
||||
- if (active) release_win_data( active );
|
||||
- }
|
||||
-
|
||||
- release_win_data( data );
|
||||
-}
|
||||
-
|
||||
/***********************************************************************
|
||||
* SetCapture (X11DRV.@)
|
||||
*/
|
||||
--- b/dlls/winex11.drv/x11drv.h
|
||||
+++ a/dlls/winex11.drv/x11drv.h
|
||||
@@ -231,7 +231,6 @@
|
||||
const RECT *top_rect, DWORD flags );
|
||||
extern void X11DRV_ReleaseDC( HWND hwnd, HDC hdc );
|
||||
extern BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update );
|
||||
-extern void X11DRV_SetActiveWindow( HWND hwnd );
|
||||
extern void X11DRV_SetCapture( HWND hwnd, UINT flags );
|
||||
extern void X11DRV_SetDesktopWindow( HWND hwnd );
|
||||
extern void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha,
|
||||
@@ -383,7 +382,6 @@
|
||||
Display *display;
|
||||
XEvent *current_event; /* event currently being processed */
|
||||
HWND grab_hwnd; /* window that currently grabs the mouse */
|
||||
- HWND active_window; /* active window */
|
||||
HWND last_focus; /* last window that had focus */
|
||||
XIM xim; /* input method */
|
||||
HWND last_xic_hwnd; /* last xic window */
|
||||
@@ -490,7 +488,6 @@
|
||||
XATOM__ICC_PROFILE,
|
||||
XATOM__KDE_NET_WM_STATE_SKIP_SWITCHER,
|
||||
XATOM__MOTIF_WM_HINTS,
|
||||
- XATOM__NET_ACTIVE_WINDOW,
|
||||
XATOM__NET_STARTUP_INFO_BEGIN,
|
||||
XATOM__NET_STARTUP_INFO,
|
||||
XATOM__NET_SUPPORTED,
|
||||
--- b/dlls/winex11.drv/x11drv_main.c
|
||||
+++ a/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -154,7 +154,6 @@
|
||||
"_ICC_PROFILE",
|
||||
"_KDE_NET_WM_STATE_SKIP_SWITCHER",
|
||||
"_MOTIF_WM_HINTS",
|
||||
- "_NET_ACTIVE_WINDOW",
|
||||
"_NET_STARTUP_INFO_BEGIN",
|
||||
"_NET_STARTUP_INFO",
|
||||
"_NET_SUPPORTED",
|
||||
--- b/include/wine/gdi_driver.h
|
||||
+++ a/include/wine/gdi_driver.h
|
||||
@@ -316,7 +316,6 @@
|
||||
BOOL (*pProcessEvents)(DWORD);
|
||||
void (*pReleaseDC)(HWND,HDC);
|
||||
BOOL (*pScrollDC)(HDC,INT,INT,HRGN);
|
||||
- void (*pSetActiveWindow)(HWND);
|
||||
void (*pSetCapture)(HWND,UINT);
|
||||
void (*pSetDesktopWindow)(HWND);
|
||||
void (*pSetFocus)(HWND);
|
||||
--- b/dlls/winex11.drv/window.c
|
||||
+++ a/dlls/winex11.drv/window.c
|
||||
@@ -278,6 +278,9 @@
|
||||
if (style & WS_MINIMIZEBOX) ret |= MWM_DECOR_MINIMIZE;
|
||||
if (style & WS_MAXIMIZEBOX) ret |= MWM_DECOR_MAXIMIZE;
|
||||
}
|
||||
+ if (ex_style & WS_EX_DLGMODALFRAME) ret |= MWM_DECOR_BORDER;
|
||||
+ else if (style & WS_THICKFRAME) ret |= MWM_DECOR_BORDER;
|
||||
+ else if ((style & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME) ret |= MWM_DECOR_BORDER;
|
||||
return ret;
|
||||
}
|
||||
|
||||
--- b/dlls/winex11.drv/window.c
|
||||
+++ a/dlls/winex11.drv/window.c
|
||||
@@ -279,7 +279,7 @@
|
||||
if (style & WS_MAXIMIZEBOX) ret |= MWM_DECOR_MAXIMIZE;
|
||||
}
|
||||
if (ex_style & WS_EX_DLGMODALFRAME) ret |= MWM_DECOR_BORDER;
|
||||
+ else if (style & WS_THICKFRAME) ret |= MWM_DECOR_BORDER | MWM_DECOR_RESIZEH;
|
||||
- else if (style & WS_THICKFRAME) ret |= MWM_DECOR_BORDER;
|
||||
else if ((style & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME) ret |= MWM_DECOR_BORDER;
|
||||
return ret;
|
||||
}
|
|
@ -1,292 +0,0 @@
|
|||
commit 6a033150c36bea6d704b7537c219e9b13b4387ec
|
||||
Author: Rémi Bernon <rbernon@codeweavers.com>
|
||||
Date: Tue Dec 1 22:49:26 2020 +0100
|
||||
Subject: [PATCH 1/3] server: Implement thread priorities on Linux.
|
||||
|
||||
This does not report permission errors in order to avoid any breaking
|
||||
change, only the parameter checks that were already there are returning
|
||||
errors.
|
||||
|
||||
Only call setpriority on Linux, as unix_tid is a Mach port on Mac OS.
|
||||
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2086,6 +2086,25 @@
|
||||
AC_DEFINE(HAVE_SCHED_SETAFFINITY, 1, [Define to 1 if you have the `sched_setaffinity' function.])
|
||||
fi
|
||||
|
||||
+AC_CACHE_CHECK([for sched_setscheduler],wine_cv_have_sched_setscheduler,
|
||||
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
||||
+[[#define _GNU_SOURCE
|
||||
+#include <sched.h>]], [[sched_setscheduler(0, 0, 0);]])],[wine_cv_have_sched_setscheduler=yes],[wine_cv_have_sched_setscheduler=no]))
|
||||
+if test "$wine_cv_have_sched_setscheduler" = "yes"
|
||||
+then
|
||||
+ AC_DEFINE(HAVE_SCHED_SETSCHEDULER, 1, [Define to 1 if you have the `sched_setscheduler' function.])
|
||||
+fi
|
||||
+
|
||||
+AC_CACHE_CHECK([for setpriority],wine_cv_have_setpriority,
|
||||
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
||||
+[[#define _GNU_SOURCE
|
||||
+#include <sys/resource.h>
|
||||
+#include <sys/time.h>]], [[setpriority(0, 0, 0);]])],[wine_cv_have_setpriority=yes],[wine_cv_have_setpriority=no]))
|
||||
+if test "$wine_cv_have_setpriority" = "yes"
|
||||
+then
|
||||
+ AC_DEFINE(HAVE_SETPRIORITY, 1, [Define to 1 if you have the `setpriority' function.])
|
||||
+fi
|
||||
+
|
||||
dnl **** Check for types ****
|
||||
|
||||
AC_C_INLINE
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -1638,6 +1638,24 @@
|
||||
release_object( process );
|
||||
}
|
||||
|
||||
+static void set_process_priority( struct process *process, int priority )
|
||||
+{
|
||||
+ struct thread *thread;
|
||||
+
|
||||
+ if (!process->running_threads)
|
||||
+ {
|
||||
+ set_error( STATUS_PROCESS_IS_TERMINATING );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
|
||||
+ {
|
||||
+ set_thread_priority( thread, priority, thread->priority );
|
||||
+ }
|
||||
+
|
||||
+ process->priority = priority;
|
||||
+}
|
||||
+
|
||||
static void set_process_affinity( struct process *process, affinity_t affinity )
|
||||
{
|
||||
struct thread *thread;
|
||||
@@ -1663,7 +1681,7 @@
|
||||
|
||||
if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
|
||||
{
|
||||
- if (req->mask & SET_PROCESS_INFO_PRIORITY) process->priority = req->priority;
|
||||
+ if (req->mask & SET_PROCESS_INFO_PRIORITY) set_process_priority( process, req->priority );
|
||||
if (req->mask & SET_PROCESS_INFO_AFFINITY) set_process_affinity( process, req->affinity );
|
||||
release_object( process );
|
||||
}
|
||||
--- a/server/thread.c
|
||||
+++ b/server/thread.c
|
||||
@@ -37,6 +37,12 @@
|
||||
#define _WITH_CPU_SET_T
|
||||
#include <sched.h>
|
||||
#endif
|
||||
+#ifdef HAVE_SYS_TIME_H
|
||||
+#include <sys/time.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_SYS_RESOURCE_H
|
||||
+#include <sys/resource.h>
|
||||
+#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
@@ -253,6 +259,7 @@
|
||||
thread->state = RUNNING;
|
||||
thread->exit_code = 0;
|
||||
thread->priority = 0;
|
||||
+ thread->priority_applied = 0;
|
||||
thread->suspend = 0;
|
||||
thread->dbg_hidden = 0;
|
||||
thread->desktop_users = 0;
|
||||
@@ -648,31 +655,151 @@
|
||||
return mask;
|
||||
}
|
||||
|
||||
+#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SETPRIORITY)
|
||||
+static int get_unix_priority( int priority_class, int priority )
|
||||
+{
|
||||
+ switch (priority_class) {
|
||||
+ case PROCESS_PRIOCLASS_IDLE:
|
||||
+ switch (priority) {
|
||||
+ case THREAD_PRIORITY_IDLE: return 15;
|
||||
+ case THREAD_PRIORITY_LOWEST: return 10;
|
||||
+ case THREAD_PRIORITY_BELOW_NORMAL: return 8;
|
||||
+ case THREAD_PRIORITY_NORMAL: return 6;
|
||||
+ case THREAD_PRIORITY_ABOVE_NORMAL: return 4;
|
||||
+ case THREAD_PRIORITY_HIGHEST: return 2;
|
||||
+ case THREAD_PRIORITY_TIME_CRITICAL: return -15;
|
||||
+ }
|
||||
+ case PROCESS_PRIOCLASS_BELOW_NORMAL:
|
||||
+ switch (priority) {
|
||||
+ case THREAD_PRIORITY_IDLE: return 15;
|
||||
+ case THREAD_PRIORITY_LOWEST: return 8;
|
||||
+ case THREAD_PRIORITY_BELOW_NORMAL: return 6;
|
||||
+ case THREAD_PRIORITY_NORMAL: return 4;
|
||||
+ case THREAD_PRIORITY_ABOVE_NORMAL: return 2;
|
||||
+ case THREAD_PRIORITY_HIGHEST: return 0;
|
||||
+ case THREAD_PRIORITY_TIME_CRITICAL: return -15;
|
||||
+ }
|
||||
+ case PROCESS_PRIOCLASS_NORMAL:
|
||||
+ switch (priority) {
|
||||
+ case THREAD_PRIORITY_IDLE: return 15;
|
||||
+ case THREAD_PRIORITY_LOWEST: return 4;
|
||||
+ case THREAD_PRIORITY_BELOW_NORMAL: return 2;
|
||||
+ case THREAD_PRIORITY_NORMAL: return 0;
|
||||
+ case THREAD_PRIORITY_ABOVE_NORMAL: return -2;
|
||||
+ case THREAD_PRIORITY_HIGHEST: return -4;
|
||||
+ case THREAD_PRIORITY_TIME_CRITICAL: return -15;
|
||||
+ }
|
||||
+ case PROCESS_PRIOCLASS_ABOVE_NORMAL:
|
||||
+ switch (priority) {
|
||||
+ case THREAD_PRIORITY_IDLE: return 15;
|
||||
+ case THREAD_PRIORITY_LOWEST: return 0;
|
||||
+ case THREAD_PRIORITY_BELOW_NORMAL: return -2;
|
||||
+ case THREAD_PRIORITY_NORMAL: return -4;
|
||||
+ case THREAD_PRIORITY_ABOVE_NORMAL: return -6;
|
||||
+ case THREAD_PRIORITY_HIGHEST: return -8;
|
||||
+ case THREAD_PRIORITY_TIME_CRITICAL: return -15;
|
||||
+ }
|
||||
+ case PROCESS_PRIOCLASS_HIGH:
|
||||
+ switch (priority) {
|
||||
+ case THREAD_PRIORITY_IDLE: return 15;
|
||||
+ case THREAD_PRIORITY_LOWEST: return -2;
|
||||
+ case THREAD_PRIORITY_BELOW_NORMAL: return -4;
|
||||
+ case THREAD_PRIORITY_NORMAL: return -6;
|
||||
+ case THREAD_PRIORITY_ABOVE_NORMAL: return -8;
|
||||
+ case THREAD_PRIORITY_HIGHEST: return -10;
|
||||
+ case THREAD_PRIORITY_TIME_CRITICAL: return -15;
|
||||
+ }
|
||||
+ case PROCESS_PRIOCLASS_REALTIME:
|
||||
+ switch (priority) {
|
||||
+ case THREAD_PRIORITY_IDLE: return 1;
|
||||
+ case -7:
|
||||
+ case -6:
|
||||
+ case -5:
|
||||
+ case -4:
|
||||
+ case -3:
|
||||
+ case THREAD_PRIORITY_LOWEST:
|
||||
+ case THREAD_PRIORITY_BELOW_NORMAL:
|
||||
+ case THREAD_PRIORITY_NORMAL:
|
||||
+ case THREAD_PRIORITY_ABOVE_NORMAL:
|
||||
+ case THREAD_PRIORITY_HIGHEST:
|
||||
+ case 3:
|
||||
+ case 4:
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ return priority + 9;
|
||||
+ case THREAD_PRIORITY_TIME_CRITICAL:
|
||||
+ return 16;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#define THREAD_PRIORITY_REALTIME_HIGHEST 6
|
||||
#define THREAD_PRIORITY_REALTIME_LOWEST -7
|
||||
|
||||
+int set_thread_priority( struct thread* thread, int priority_class, int priority )
|
||||
+{
|
||||
+ int max = THREAD_PRIORITY_HIGHEST;
|
||||
+ int min = THREAD_PRIORITY_LOWEST;
|
||||
+ if (priority_class == PROCESS_PRIOCLASS_REALTIME)
|
||||
+ {
|
||||
+ max = THREAD_PRIORITY_REALTIME_HIGHEST;
|
||||
+ min = THREAD_PRIORITY_REALTIME_LOWEST;
|
||||
+ }
|
||||
+
|
||||
+ if ((priority < min || priority > max) &&
|
||||
+ priority != THREAD_PRIORITY_IDLE &&
|
||||
+ priority != THREAD_PRIORITY_TIME_CRITICAL)
|
||||
+ {
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (thread->process->priority == priority_class &&
|
||||
+ thread->priority == priority &&
|
||||
+ thread->priority_applied)
|
||||
+ return 0;
|
||||
+
|
||||
+ thread->priority = priority;
|
||||
+ thread->priority_applied = 0;
|
||||
+ if (thread->unix_tid == -1)
|
||||
+ return 0;
|
||||
+
|
||||
+#ifdef __linux__
|
||||
+ if (priority_class == PROCESS_PRIOCLASS_REALTIME)
|
||||
+ {
|
||||
+#ifdef HAVE_SCHED_SETSCHEDULER
|
||||
+ struct sched_param param;
|
||||
+ if (sched_getparam( thread->unix_tid, ¶m ) != 0)
|
||||
+ return 0; /* ignore errors for now */
|
||||
+
|
||||
+ param.sched_priority = get_unix_priority( priority_class, priority );
|
||||
+ if (sched_setscheduler( thread->unix_tid, SCHED_RR|SCHED_RESET_ON_FORK, ¶m ) == 0)
|
||||
+ return 0;
|
||||
+#endif
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+#ifdef HAVE_SETPRIORITY
|
||||
+ if (setpriority( PRIO_PROCESS, thread->unix_tid,
|
||||
+ get_unix_priority( priority_class, priority ) ) == 0)
|
||||
+ return 0;
|
||||
+#endif
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return 0; /* ignore errors for now */
|
||||
+}
|
||||
+
|
||||
/* set all information about a thread */
|
||||
static void set_thread_info( struct thread *thread,
|
||||
const struct set_thread_info_request *req )
|
||||
{
|
||||
if (req->mask & SET_THREAD_INFO_PRIORITY)
|
||||
{
|
||||
- int max = THREAD_PRIORITY_HIGHEST;
|
||||
- int min = THREAD_PRIORITY_LOWEST;
|
||||
- if (thread->process->priority == PROCESS_PRIOCLASS_REALTIME)
|
||||
- {
|
||||
- max = THREAD_PRIORITY_REALTIME_HIGHEST;
|
||||
- min = THREAD_PRIORITY_REALTIME_LOWEST;
|
||||
- }
|
||||
- if ((req->priority >= min && req->priority <= max) ||
|
||||
- req->priority == THREAD_PRIORITY_IDLE ||
|
||||
- req->priority == THREAD_PRIORITY_TIME_CRITICAL)
|
||||
- {
|
||||
- thread->priority = req->priority;
|
||||
- set_scheduler_priority( thread );
|
||||
- }
|
||||
- else
|
||||
- set_error( STATUS_INVALID_PARAMETER );
|
||||
+ if (set_thread_priority( thread, thread->process->priority, req->priority ))
|
||||
+ file_set_error();
|
||||
}
|
||||
if (req->mask & SET_THREAD_INFO_AFFINITY)
|
||||
{
|
||||
@@ -1541,6 +1668,7 @@
|
||||
|
||||
init_thread_context( current );
|
||||
generate_debug_event( current, DbgCreateThreadStateChange, &req->entry );
|
||||
+ set_thread_priority( current, current->process->priority, current->priority );
|
||||
set_thread_affinity( current, current->affinity );
|
||||
|
||||
reply->suspend = (current->suspend || current->process->suspend || current->context != NULL);
|
||||
--- a/server/thread.h
|
||||
+++ b/server/thread.h
|
||||
@@ -84,6 +84,7 @@
|
||||
client_ptr_t entry_point; /* entry point (in client address space) */
|
||||
affinity_t affinity; /* affinity mask */
|
||||
int priority; /* priority level */
|
||||
+ int priority_applied; /* priority level successfully applied status */
|
||||
int suspend; /* suspend count */
|
||||
int dbg_hidden; /* hidden from debugger */
|
||||
obj_handle_t desktop; /* desktop handle */
|
||||
@@ -124,6 +125,7 @@
|
||||
extern int thread_add_inflight_fd( struct thread *thread, int client, int server );
|
||||
extern int thread_get_inflight_fd( struct thread *thread, int client );
|
||||
extern struct token *thread_get_impersonation_token( struct thread *thread );
|
||||
+extern int set_thread_priority( struct thread *thread, int priority_class, int priority );
|
||||
extern int set_thread_affinity( struct thread *thread, affinity_t affinity );
|
||||
extern int suspend_thread( struct thread *thread );
|
||||
extern int resume_thread( struct thread *thread );
|
|
@ -1,17 +0,0 @@
|
|||
--- b/include/mmddk.h
|
||||
+++ a/include/mmddk.h
|
||||
@@ -30,6 +30,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+#define MAX_MIDIINDRV (16)
|
||||
+/* For now I'm making 16 the maximum number of midi devices one can
|
||||
+ * have. This should be more than enough for everybody. But as a purist,
|
||||
+ * I intend to make it unbounded in the future, as soon as I figure
|
||||
+ * a good way to do so.
|
||||
+ */
|
||||
+#define MAX_MIDIOUTDRV (16)
|
||||
+
|
||||
/* ==================================
|
||||
* Multimedia DDK compatible part
|
||||
* ================================== */
|
|
@ -1,198 +0,0 @@
|
|||
--- a/tools/makedep.c
|
||||
+++ b/tools/makedep.c
|
||||
@@ -199,6 +199,7 @@
|
||||
const char *staticlib;
|
||||
const char *importlib;
|
||||
const char *unixlib;
|
||||
+ int use_msvcrt;
|
||||
int data_only;
|
||||
int is_win16;
|
||||
int is_exe;
|
||||
@@ -602,17 +603,6 @@
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
- * is_using_msvcrt
|
||||
- *
|
||||
- * Check if the files of a makefile use msvcrt by default.
|
||||
- */
|
||||
-static int is_using_msvcrt( struct makefile *make )
|
||||
-{
|
||||
- return make->module || make->testdll;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/*******************************************************************
|
||||
* arch_module_name
|
||||
*/
|
||||
static char *arch_module_name( const char *module, unsigned int arch )
|
||||
@@ -870,7 +860,7 @@
|
||||
file->basename = xstrdup( filename ? filename : name );
|
||||
file->filename = obj_dir_path( make, file->basename );
|
||||
file->file->flags = FLAG_GENERATED;
|
||||
- file->use_msvcrt = is_using_msvcrt( make );
|
||||
+ file->use_msvcrt = make->use_msvcrt;
|
||||
list_add_tail( &make->sources, &file->entry );
|
||||
if (make == include_makefile)
|
||||
{
|
||||
@@ -1620,7 +1610,7 @@
|
||||
|
||||
memset( file, 0, sizeof(*file) );
|
||||
file->name = xstrdup(name);
|
||||
- file->use_msvcrt = is_using_msvcrt( make );
|
||||
+ file->use_msvcrt = make->use_msvcrt;
|
||||
file->is_external = !!make->extlib;
|
||||
list_add_tail( &make->sources, &file->entry );
|
||||
if (make == include_makefile)
|
||||
@@ -1818,12 +1808,13 @@
|
||||
unsigned int i, arch;
|
||||
struct incl_file *source, *next, *file, *dlldata = NULL;
|
||||
struct strarray objs = get_expanded_make_var_array( make, "EXTRA_OBJS" );
|
||||
+ int multiarch = archs.count > 1 && make->use_msvcrt;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE( source, next, &make->sources, struct incl_file, entry )
|
||||
{
|
||||
for (arch = 0; arch < archs.count; arch++)
|
||||
{
|
||||
- if (!is_multiarch( arch )) continue;
|
||||
+ if (!arch != !multiarch) continue;
|
||||
if (source->file->flags & FLAG_IDL_CLIENT)
|
||||
{
|
||||
file = add_generated_source( make, replace_extension( source->name, ".idl", "_c.c" ), NULL, arch );
|
||||
@@ -1942,7 +1933,7 @@
|
||||
{
|
||||
for (arch = 0; arch < archs.count; arch++)
|
||||
{
|
||||
- if (!is_multiarch( arch )) continue;
|
||||
+ if (!arch != !multiarch) continue;
|
||||
file = add_generated_source( make, "testlist.o", "testlist.c", arch );
|
||||
add_dependency( file->file, "wine/test.h", INCL_NORMAL );
|
||||
add_all_includes( make, file, file->file );
|
||||
@@ -2196,6 +2187,7 @@
|
||||
*/
|
||||
static const char *get_default_crt( const struct makefile *make )
|
||||
{
|
||||
+ if (!make->use_msvcrt) return NULL;
|
||||
if (make->module && is_crt_module( make->module )) return NULL; /* don't add crt import to crt dlls */
|
||||
return !make->testdll && (!make->staticlib || make->extlib) ? "ucrtbase" : "msvcrt";
|
||||
}
|
||||
@@ -2352,7 +2344,6 @@
|
||||
strarray_add( &ret, strmake( "-I%s", root_src_dir_path( "include/msvcrt" )));
|
||||
for (i = 0; i < make->include_paths.count; i++)
|
||||
strarray_add( &ret, strmake( "-I%s", make->include_paths.str[i] ));
|
||||
- strarray_add( &ret, get_crt_define( make ));
|
||||
}
|
||||
strarray_addall( &ret, make->define_args );
|
||||
strarray_addall( &ret, get_expanded_file_local_var( make, obj, "EXTRADEFS" ));
|
||||
@@ -2412,9 +2403,7 @@
|
||||
output_filename( tools_path( make, "winebuild" ));
|
||||
}
|
||||
output_filenames( target_flags[arch] );
|
||||
- if (arch) return;
|
||||
- output_filename( "-mno-cygwin" );
|
||||
- output_filenames( lddll_flags );
|
||||
+ if (!arch) output_filenames( lddll_flags );
|
||||
}
|
||||
|
||||
|
||||
@@ -2816,6 +2805,7 @@
|
||||
struct strarray multiarch_targets[MAX_ARCHS] = { empty_strarray };
|
||||
const char *dest;
|
||||
unsigned int i, arch;
|
||||
+ int multiarch;
|
||||
|
||||
if (find_include_file( make, strmake( "%s.h", obj ))) source->file->flags |= FLAG_IDL_HEADER;
|
||||
if (!source->file->flags) return;
|
||||
@@ -2839,9 +2829,10 @@
|
||||
for (i = 0; i < ARRAY_SIZE(idl_outputs); i++)
|
||||
{
|
||||
if (!(source->file->flags & idl_outputs[i].flag)) continue;
|
||||
+ multiarch = (make->use_msvcrt && archs.count > 1);
|
||||
for (arch = 0; arch < archs.count; arch++)
|
||||
{
|
||||
- if (!is_multiarch( arch )) continue;
|
||||
+ if (!arch != !multiarch) continue;
|
||||
if (make->disabled[arch]) continue;
|
||||
dest = strmake( "%s%s%s", arch_dirs[arch], obj, idl_outputs[i].ext );
|
||||
if (!find_src_file( make, dest )) strarray_add( &make->clean_files, dest );
|
||||
@@ -3152,13 +3143,13 @@
|
||||
if (arch)
|
||||
{
|
||||
if (source->file->flags & FLAG_C_UNIX) return;
|
||||
- if (!is_using_msvcrt( make ) && !make->staticlib && !(source->file->flags & FLAG_C_IMPLIB)) return;
|
||||
+ if (!make->use_msvcrt && !make->staticlib && !(source->file->flags & FLAG_C_IMPLIB)) return;
|
||||
}
|
||||
else if (source->file->flags & FLAG_C_UNIX)
|
||||
{
|
||||
if (!unix_lib_supported) return;
|
||||
}
|
||||
- else if (archs.count > 1 && is_using_msvcrt( make ))
|
||||
+ else if (archs.count > 1 && make->use_msvcrt)
|
||||
{
|
||||
if (!so_dll_supported) return;
|
||||
if (!(source->file->flags & FLAG_C_IMPLIB) && (!make->staticlib || make->extlib)) return;
|
||||
@@ -3349,6 +3340,12 @@
|
||||
strarray_addall( &all_libs, add_import_libs( make, &dep_libs, default_imports, IMPORT_TYPE_DEFAULT, arch ) );
|
||||
if (!arch) strarray_addall( &all_libs, libs );
|
||||
|
||||
+ if (!make->use_msvcrt)
|
||||
+ {
|
||||
+ strarray_addall( &all_libs, get_expanded_make_var_array( make, "UNIX_LIBS" ));
|
||||
+ strarray_addall( &all_libs, libs );
|
||||
+ }
|
||||
+
|
||||
if (delay_load_flags[arch])
|
||||
{
|
||||
for (i = 0; i < make->delayimports.count; i++)
|
||||
@@ -3541,7 +3538,7 @@
|
||||
output( ": %s", obj_dir_path( make, testmodule ));
|
||||
if (parent)
|
||||
{
|
||||
- char *parent_module = arch_module_name( make->testdll, arch );
|
||||
+ char *parent_module = arch_module_name( make->testdll, parent->use_msvcrt ? arch : 0 );
|
||||
output_filename( obj_dir_path( parent, parent_module ));
|
||||
if (parent->unixlib) output_filename( obj_dir_path( parent, parent->unixlib ));
|
||||
}
|
||||
@@ -3792,11 +3789,15 @@
|
||||
}
|
||||
else if (make->module)
|
||||
{
|
||||
- for (arch = 0; arch < archs.count; arch++)
|
||||
+ if (!make->use_msvcrt) output_module( make, 0 );
|
||||
+ else
|
||||
{
|
||||
- if (is_multiarch( arch )) output_module( make, arch );
|
||||
- if (make->importlib && (is_multiarch( arch ) || !is_native_arch_disabled( make )))
|
||||
- output_import_lib( make, arch );
|
||||
+ for (arch = 0; arch < archs.count; arch++)
|
||||
+ {
|
||||
+ if (is_multiarch( arch )) output_module( make, arch );
|
||||
+ if (make->importlib && (is_multiarch( arch ) || !is_native_arch_disabled( make )))
|
||||
+ output_import_lib( make, arch );
|
||||
+ }
|
||||
}
|
||||
if (make->unixlib) output_unix_lib( make );
|
||||
if (make->is_exe && !make->is_win16 && unix_lib_supported && strendswith( make->module, ".exe" ))
|
||||
@@ -4236,9 +4237,13 @@
|
||||
}
|
||||
make->is_win16 = strarray_exists( &make->extradllflags, "-m16" );
|
||||
make->data_only = strarray_exists( &make->extradllflags, "-Wb,--data-only" );
|
||||
+ make->use_msvcrt = (make->module || make->testdll || make->is_win16) &&
|
||||
+ !strarray_exists( &make->extradllflags, "-mcygwin" );
|
||||
make->is_exe = strarray_exists( &make->extradllflags, "-mconsole" ) ||
|
||||
strarray_exists( &make->extradllflags, "-mwindows" );
|
||||
|
||||
+ if (make->use_msvcrt) strarray_add_uniq( &make->extradllflags, "-mno-cygwin" );
|
||||
+
|
||||
if (make->module)
|
||||
{
|
||||
/* add default install rules if nothing was specified */
|
||||
@@ -4296,6 +4301,8 @@
|
||||
|
||||
add_generated_sources( make );
|
||||
|
||||
+ if (make->use_msvcrt) strarray_add( &make->define_args, get_crt_define( make ));
|
||||
+
|
||||
LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry ) parse_file( make, file, 0 );
|
||||
LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry ) get_dependencies( file, file );
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
commit ebf411c1e5f20c6db7962cea587d6169246078e0
|
||||
Author: Rémi Bernon <rbernon@codeweavers.com>
|
||||
Date: Wed Jul 3 10:54:06 2019 +0200
|
||||
Subject: [PATCH 2/3] server: Fallback to RTKIT for thread priorities.
|
||||
|
||||
sched_setscheduler and setpriority usually require elevated privileges
|
||||
to succeed and most Linux distributions ship rtkit daemon with a dbus
|
||||
interface to enable unprivileged control of some scheduling parameters.
|
||||
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1416,7 +1416,7 @@
|
||||
if test "x$with_dbus" != "xno"
|
||||
then
|
||||
WINE_PACKAGE_FLAGS(DBUS,[dbus-1],,,,
|
||||
- [AC_CHECK_HEADER([dbus/dbus.h],
|
||||
+ [AC_CHECK_HEADERS([dbus/dbus.h],
|
||||
[WINE_CHECK_SONAME(dbus-1, dbus_connection_close,,[DBUS_CFLAGS=""],[$DBUS_LIBS])],
|
||||
[DBUS_CFLAGS=""])])
|
||||
fi
|
||||
--- a/server/Makefile.in
|
||||
+++ b/server/Makefile.in
|
||||
@@ -50,6 +50,7 @@
|
||||
wineserver.man.in \
|
||||
winstation.c
|
||||
|
||||
-UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS)
|
||||
+UNIX_CFLAGS = $(DBUS_CFLAGS)
|
||||
+UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) $(DBUS_LIBS)
|
||||
|
||||
unicode_EXTRADEFS = -DNLSDIR="\"${nlsdir}\"" -DBIN_TO_NLSDIR=\"`${MAKEDEP} -R ${bindir} ${nlsdir}`\"
|
||||
--- a/server/thread.c
|
||||
+++ b/server/thread.c
|
||||
@@ -59,6 +59,77 @@
|
||||
#include "esync.h"
|
||||
#include "fsync.h"
|
||||
|
||||
+#ifdef HAVE_DBUS_DBUS_H
|
||||
+#include <dbus/dbus.h>
|
||||
+
|
||||
+static int rtkit_set_realtime( dbus_uint64_t process, dbus_uint64_t thread, dbus_uint32_t priority )
|
||||
+{
|
||||
+ DBusConnection* dbus;
|
||||
+ DBusMessage *msg;
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ if ((dbus = dbus_bus_get(DBUS_BUS_SYSTEM, NULL)))
|
||||
+ {
|
||||
+ dbus_connection_set_exit_on_disconnect(dbus, 0);
|
||||
+
|
||||
+ if ((msg = dbus_message_new_method_call("org.freedesktop.RealtimeKit1",
|
||||
+ "/org/freedesktop/RealtimeKit1",
|
||||
+ "org.freedesktop.RealtimeKit1",
|
||||
+ "MakeThreadRealtimeWithPID")))
|
||||
+ {
|
||||
+ dbus_message_set_no_reply(msg, 1);
|
||||
+
|
||||
+ if (dbus_message_append_args(msg,
|
||||
+ DBUS_TYPE_UINT64, &process,
|
||||
+ DBUS_TYPE_UINT64, &thread,
|
||||
+ DBUS_TYPE_UINT32, &priority,
|
||||
+ DBUS_TYPE_INVALID) &&
|
||||
+ dbus_connection_send(dbus, msg, NULL))
|
||||
+ ret = 0;
|
||||
+
|
||||
+ dbus_message_unref(msg);
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_unref(dbus);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rtkit_set_niceness( dbus_uint64_t process, dbus_uint64_t thread, dbus_int32_t niceness )
|
||||
+{
|
||||
+ DBusConnection* dbus;
|
||||
+ DBusMessage *msg;
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ if ((dbus = dbus_bus_get(DBUS_BUS_SYSTEM, NULL)))
|
||||
+ {
|
||||
+ dbus_connection_set_exit_on_disconnect(dbus, 0);
|
||||
+
|
||||
+ if ((msg = dbus_message_new_method_call("org.freedesktop.RealtimeKit1",
|
||||
+ "/org/freedesktop/RealtimeKit1",
|
||||
+ "org.freedesktop.RealtimeKit1",
|
||||
+ "MakeThreadHighPriorityWithPID")))
|
||||
+ {
|
||||
+ dbus_message_set_no_reply(msg, 1);
|
||||
+
|
||||
+ if (dbus_message_append_args(msg,
|
||||
+ DBUS_TYPE_UINT64, &process,
|
||||
+ DBUS_TYPE_UINT64, &thread,
|
||||
+ DBUS_TYPE_INT32, &niceness,
|
||||
+ DBUS_TYPE_INVALID) &&
|
||||
+ dbus_connection_send(dbus, msg, NULL))
|
||||
+ ret = 0;
|
||||
+
|
||||
+ dbus_message_unref(msg);
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_unref(dbus);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif
|
||||
|
||||
/* thread queues */
|
||||
|
||||
@@ -655,7 +726,8 @@
|
||||
return mask;
|
||||
}
|
||||
|
||||
-#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SETPRIORITY)
|
||||
+#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SETPRIORITY) || \
|
||||
+ defined(HAVE_DBUS_DBUS_H)
|
||||
static int get_unix_priority( int priority_class, int priority )
|
||||
{
|
||||
switch (priority_class) {
|
||||
@@ -778,6 +850,11 @@
|
||||
if (sched_setscheduler( thread->unix_tid, SCHED_RR|SCHED_RESET_ON_FORK, ¶m ) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
+#ifdef HAVE_DBUS_DBUS_H
|
||||
+ if (rtkit_set_realtime( thread->unix_pid, thread->unix_tid,
|
||||
+ get_unix_priority( priority_class, priority ) ) == 0)
|
||||
+ return 0;
|
||||
+#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -786,6 +863,11 @@
|
||||
get_unix_priority( priority_class, priority ) ) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
+#ifdef HAVE_DBUS_DBUS_H
|
||||
+ if (rtkit_set_niceness( thread->unix_pid, thread->unix_tid,
|
||||
+ get_unix_priority( priority_class, priority ) ) == 0)
|
||||
+ return 0;
|
||||
+#endif
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
From df72c4d301123c0ea0c33af4bc9d00c47255a664 Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <openglfreak@googlemail.com>
|
||||
Date: Thu, 26 Jan 2023 22:13:55 +0100
|
||||
Subject: [PATCH 3/3] server: Map THREAD_PRIORITY_IDLE to SCHED_IDLE.
|
||||
|
||||
---
|
||||
server/thread.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
--- a/server/thread.c
|
||||
+++ b/server/thread.c
|
||||
@@ -858,6 +858,18 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
+#ifdef HAVE_SCHED_SETSCHEDULER
|
||||
+ if (priority == THREAD_PRIORITY_IDLE)
|
||||
+ {
|
||||
+ struct sched_param param;
|
||||
+ if (sched_getparam( thread->unix_tid, ¶m ) == 0)
|
||||
+ {
|
||||
+ param.sched_priority = 0;
|
||||
+ if (sched_setscheduler( thread->unix_tid, SCHED_IDLE|SCHED_RESET_ON_FORK, ¶m ) == 0)
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
#ifdef HAVE_SETPRIORITY
|
||||
if (setpriority( PRIO_PROCESS, thread->unix_tid,
|
||||
get_unix_priority( priority_class, priority ) ) == 0)
|
|
@ -1,12 +0,0 @@
|
|||
--- a/dlls/avrt/main.c
|
||||
+++ b/dlls/avrt/main.c
|
||||
@@ -70,6 +70,9 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (!wcscmp(name, L"Audio") || !wcscmp(name, L"Pro Audio"))
|
||||
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
+
|
||||
return (HANDLE)0x12345678;
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
commit d444330ed7685686f46db7fb8ed1ad0cbec72c7b
|
||||
Author: Rémi Bernon <rbernon@codeweavers.com>
|
||||
Date: Wed Jun 16 17:36:15 2021 +0200
|
||||
Subject: [PATCH] devenum: Register IEEE float for Direct Sound default device.
|
||||
|
||||
--
|
||||
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
|
||||
index 8e9cf56eb09..97855b12b81 100644
|
||||
--- a/dlls/devenum/createdevenum.c
|
||||
+++ b/dlls/devenum/createdevenum.c
|
||||
@@ -481,7 +481,7 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
|
||||
static const WCHAR defaultW[] = L"Default DirectSound Device";
|
||||
IPropertyBag *prop_bag = NULL;
|
||||
REGFILTERPINS2 rgpins = {0};
|
||||
- REGPINTYPES rgtypes = {0};
|
||||
+ REGPINTYPES rgtypes[2] = {};
|
||||
REGFILTER2 rgf = {0};
|
||||
WCHAR clsid[CHARS_IN_GUID];
|
||||
VARIANT var;
|
||||
@@ -512,10 +512,12 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
|
||||
rgf.rgPins2 = &rgpins;
|
||||
rgpins.dwFlags = REG_PINFLAG_B_RENDERER;
|
||||
/* FIXME: native registers many more formats */
|
||||
- rgpins.nMediaTypes = 1;
|
||||
- rgpins.lpMediaType = &rgtypes;
|
||||
- rgtypes.clsMajorType = &MEDIATYPE_Audio;
|
||||
- rgtypes.clsMinorType = &MEDIASUBTYPE_PCM;
|
||||
+ rgpins.nMediaTypes = 2;
|
||||
+ rgpins.lpMediaType = rgtypes;
|
||||
+ rgtypes[0].clsMajorType = &MEDIATYPE_Audio;
|
||||
+ rgtypes[0].clsMinorType = &MEDIASUBTYPE_PCM;
|
||||
+ rgtypes[1].clsMajorType = &MEDIATYPE_Audio;
|
||||
+ rgtypes[1].clsMinorType = &MEDIASUBTYPE_IEEE_FLOAT;
|
||||
|
||||
write_filter_data(prop_bag, &rgf);
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
From: Piotr Caban <piotr@codeweavers.com>
|
||||
Subject: [PATCH v2] server: Don't wait for low level hook result when queuing hardware message.
|
||||
Message-Id: <daf382d3-924e-7c33-c876-5b8d6298c137@codeweavers.com>
|
||||
Date: Tue, 21 Sep 2021 15:51:35 +0200
|
||||
|
||||
|
||||
Without the change graphic drivers are blocking until low level hooks
|
||||
are processed when injecting keyboard and mouse events. Causes 2-seconds
|
||||
(timeout) freeze in GtaV.
|
||||
|
||||
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
|
||||
---
|
||||
v2:
|
||||
- don't specify sender in send_hook_ll_message to avoid queuing result
|
||||
|
||||
server/queue.c | 16 +++++++++++++---
|
||||
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index e4903bcb79f..5c19348eeba 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1839,7 +1839,12 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
/* specify a sender only when sending the last message */
|
||||
if (!(flags & ((1 << ARRAY_SIZE( messages )) - 1)))
|
||||
{
|
||||
- if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
|
||||
+ if (origin == IMO_HARDWARE)
|
||||
+ {
|
||||
+ if (!send_hook_ll_message( desktop, msg, input, NULL ))
|
||||
+ queue_hardware_message( desktop, msg, 0 );
|
||||
+ }
|
||||
+ else if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
else if (!send_hook_ll_message( desktop, msg, input, NULL ))
|
||||
@@ -1860,7 +1865,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
struct thread *foreground;
|
||||
unsigned char vkey = input->kbd.vkey;
|
||||
unsigned int message_code, time;
|
||||
- int wait;
|
||||
+ int wait = 0;
|
||||
|
||||
if (!(time = input->kbd.time)) time = get_tick_count();
|
||||
|
||||
@@ -1981,7 +1986,12 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
msg_data->flags |= (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
|
||||
}
|
||||
|
||||
- if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
|
||||
+ if (origin == IMO_HARDWARE)
|
||||
+ {
|
||||
+ if (!send_hook_ll_message( desktop, msg, input, NULL ))
|
||||
+ queue_hardware_message( desktop, msg, 1 );
|
||||
+ }
|
||||
+ else if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
|
||||
queue_hardware_message( desktop, msg, 1 );
|
||||
|
||||
return wait;
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
|
||||
index 11111111111..11111111111 100644
|
||||
--- a/dlls/windowscodecs/converter.c
|
||||
+++ b/dlls/windowscodecs/converter.c
|
||||
@@ -1034,6 +1034,50 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec
|
||||
|
||||
switch (source_format)
|
||||
{
|
||||
+ case format_8bppGray:
|
||||
+ if (prc)
|
||||
+ {
|
||||
+ HRESULT res;
|
||||
+ INT x, y;
|
||||
+ BYTE *srcdata;
|
||||
+ UINT srcstride, srcdatasize;
|
||||
+ const BYTE *srcrow;
|
||||
+ const BYTE *srcbyte;
|
||||
+ BYTE *dstrow;
|
||||
+ BYTE *dstpixel;
|
||||
+
|
||||
+ srcstride = prc->Width;
|
||||
+ srcdatasize = srcstride * prc->Height;
|
||||
+
|
||||
+ srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
|
||||
+ if (!srcdata) return E_OUTOFMEMORY;
|
||||
+
|
||||
+ res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
|
||||
+
|
||||
+ if (SUCCEEDED(res))
|
||||
+ {
|
||||
+ srcrow = srcdata;
|
||||
+ dstrow = pbBuffer;
|
||||
+ for (y=0; y<prc->Height; y++) {
|
||||
+ srcbyte = srcrow;
|
||||
+ dstpixel = dstrow;
|
||||
+ for (x=0; x<prc->Width; x++)
|
||||
+ {
|
||||
+ *dstpixel++ = *srcbyte;
|
||||
+ *dstpixel++ = *srcbyte;
|
||||
+ *dstpixel++ = *srcbyte;
|
||||
+ srcbyte++;
|
||||
+ }
|
||||
+ srcrow += srcstride;
|
||||
+ dstrow += cbStride;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, srcdata);
|
||||
+
|
||||
+ return res;
|
||||
+ }
|
||||
+ return S_OK;
|
||||
case format_24bppBGR:
|
||||
case format_24bppRGB:
|
||||
if (prc)
|
|
@ -1,54 +0,0 @@
|
|||
diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c
|
||||
index 11111111111..11111111111 100644
|
||||
--- a/dlls/kernel32/module.c
|
||||
+++ b/dlls/kernel32/module.c
|
||||
@@ -262,6 +262,34 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
|
||||
return GetBinaryTypeW(NtCurrentTeb()->StaticUnicodeString.Buffer, lpBinaryType);
|
||||
}
|
||||
|
||||
+static BOOL block_wine_get_version = FALSE;
|
||||
+
|
||||
+BOOL CALLBACK init_block_wine_get_version( INIT_ONCE* init_once, PVOID param, PVOID *ctx )
|
||||
+{
|
||||
+ WCHAR *buffer;
|
||||
+ DWORD size;
|
||||
+
|
||||
+ if ((size = GetEnvironmentVariableW( L"WINE_BLOCK_GET_VERSION", NULL, 0 )))
|
||||
+ {
|
||||
+ if (!(buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(*buffer) * size )))
|
||||
+ {
|
||||
+ ERR("No memory.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (GetEnvironmentVariableW( L"WINE_BLOCK_GET_VERSION", buffer, size ) != size - 1)
|
||||
+ {
|
||||
+ ERR("Error getting WINE_BLOCK_GET_VERSION env variable.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ block_wine_get_version = *buffer && !!wcsncmp( buffer, L"0", 1 );
|
||||
+
|
||||
+ HeapFree( GetProcessHeap(), 0, buffer );
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* GetProcAddress (KERNEL32.@)
|
||||
*
|
||||
@@ -279,6 +307,14 @@ FARPROC get_proc_address( HMODULE hModule, LPCSTR function )
|
||||
{
|
||||
FARPROC fp;
|
||||
|
||||
+ if ((ULONG_PTR)function >> 16)
|
||||
+ {
|
||||
+ static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
||||
+ InitOnceExecuteOnce( &init_once, init_block_wine_get_version, NULL, NULL );
|
||||
+ if (block_wine_get_version && !strncmp( function, "wine_get_version", 16 ))
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
if (!hModule) hModule = NtCurrentTeb()->Peb->ImageBaseAddress;
|
||||
|
||||
if ((ULONG_PTR)function >> 16)
|
|
@ -1,46 +0,0 @@
|
|||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index e303367c29f..3723d21f885 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -2788,10 +2788,39 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
|
||||
}
|
||||
else
|
||||
{
|
||||
+ LONGLONG ticks = timeout->QuadPart;
|
||||
LARGE_INTEGER now;
|
||||
- timeout_t when, diff;
|
||||
+ timeout_t when = ticks, diff;
|
||||
|
||||
- if ((when = timeout->QuadPart) < 0)
|
||||
+#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CLOCK_NANOSLEEP)
|
||||
+ static BOOL disable_clock_nanosleep = FALSE;
|
||||
+ if (!disable_clock_nanosleep && ticks != 0)
|
||||
+ {
|
||||
+ struct timespec when;
|
||||
+ int err;
|
||||
+
|
||||
+ if (ticks < 0)
|
||||
+ {
|
||||
+ clock_gettime( CLOCK_REALTIME, &when );
|
||||
+ when.tv_sec += (time_t)(-ticks / TICKSPERSEC);
|
||||
+ when.tv_nsec += (long)((-ticks % TICKSPERSEC) * 100);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ when.tv_sec = (time_t)((ticks / TICKSPERSEC) - SECS_1601_TO_1970);
|
||||
+ when.tv_nsec = (long)((ticks % TICKSPERSEC) * 100);
|
||||
+ }
|
||||
+
|
||||
+ usleep(0);
|
||||
+ while ((err = clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME, &when, NULL )) == EINTR);
|
||||
+ if (!err)
|
||||
+ return STATUS_SUCCESS;
|
||||
+ else
|
||||
+ disable_clock_nanosleep = TRUE;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ if (when < 0)
|
||||
{
|
||||
NtQuerySystemTime( &now );
|
||||
when = now.QuadPart - when;
|
|
@ -1,13 +0,0 @@
|
|||
## osu! fix: disables assertion causing game to crash when importing maps
|
||||
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
|
||||
index 9e84ec3cc96..dfa2a2781bc 100644
|
||||
--- a/dlls/ntdll/unix/thread.c
|
||||
+++ b/dlls/ntdll/unix/thread.c
|
||||
@@ -1783,7 +1783,6 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma
|
||||
*/
|
||||
void ntdll_set_exception_jmp_buf( __wine_jmp_buf *jmp )
|
||||
{
|
||||
- assert( !jmp || !ntdll_get_thread_data()->jmp_buf );
|
||||
ntdll_get_thread_data()->jmp_buf = jmp;
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
|
||||
index 11111111111..11111111111 100644
|
||||
--- a/dlls/win32u/sysparams.c
|
||||
+++ b/dlls/win32u/sysparams.c
|
||||
@@ -26,9 +26,14 @@
|
||||
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
+#include <stdarg.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
+#include "windef.h"
|
||||
+#include "winbase.h"
|
||||
+#include "winternl.h"
|
||||
+#include "ddk/wdm.h"
|
||||
#include "ntgdi_private.h"
|
||||
#include "ntuser_private.h"
|
||||
#include "devpropdef.h"
|
||||
@@ -1679,12 +1684,31 @@ static void clear_display_devices(void)
|
||||
}
|
||||
}
|
||||
|
||||
+static ULONGLONG last_update = 0;
|
||||
+
|
||||
+#define user_shared_data ((volatile const struct _KUSER_SHARED_DATA *)0x7ffe0000)
|
||||
+
|
||||
+static ULONGLONG get_tick_count(void)
|
||||
+{
|
||||
+ ULONG high, low;
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ high = user_shared_data->TickCount.High1Time;
|
||||
+ low = user_shared_data->TickCount.LowPart;
|
||||
+ }
|
||||
+ while (high != user_shared_data->TickCount.High2Time);
|
||||
+ /* note: we ignore TickCountMultiplier */
|
||||
+ return (ULONGLONG)high << 32 | low;
|
||||
+}
|
||||
+
|
||||
static BOOL update_display_cache_from_registry(void)
|
||||
{
|
||||
DWORD adapter_id, monitor_id, monitor_count = 0, size;
|
||||
KEY_BASIC_INFORMATION key;
|
||||
struct adapter *adapter;
|
||||
struct monitor *monitor, *monitor2;
|
||||
+ ULONGLONG tick_count;
|
||||
HANDLE mutex = NULL;
|
||||
NTSTATUS status;
|
||||
BOOL ret;
|
||||
@@ -1694,12 +1718,18 @@ static BOOL update_display_cache_from_registry(void)
|
||||
sizeof(devicemap_video_keyW) )))
|
||||
return FALSE;
|
||||
|
||||
+ if ((tick_count = get_tick_count()) - last_update < 1000) return TRUE;
|
||||
+
|
||||
status = NtQueryKey( video_key, KeyBasicInformation, &key,
|
||||
offsetof(KEY_BASIC_INFORMATION, Name), &size );
|
||||
if (status && status != STATUS_BUFFER_OVERFLOW)
|
||||
return FALSE;
|
||||
|
||||
- if (key.LastWriteTime.QuadPart <= last_query_display_time) return TRUE;
|
||||
+ if (key.LastWriteTime.QuadPart <= last_query_display_time)
|
||||
+ {
|
||||
+ last_update = tick_count;
|
||||
+ return TRUE;
|
||||
+ }
|
||||
|
||||
mutex = get_display_device_init_mutex();
|
||||
pthread_mutex_lock( &display_lock );
|
||||
@@ -1746,7 +1776,10 @@ static BOOL update_display_cache_from_registry(void)
|
||||
}
|
||||
|
||||
if ((ret = !list_empty( &adapters ) && !list_empty( &monitors )))
|
||||
+ {
|
||||
last_query_display_time = key.LastWriteTime.QuadPart;
|
||||
+ last_update = tick_count;
|
||||
+ }
|
||||
pthread_mutex_unlock( &display_lock );
|
||||
release_display_device_init_mutex( mutex );
|
||||
return ret;
|
|
@ -1,70 +0,0 @@
|
|||
From 138916577787bbdf19cf9523b15603f73b4f4472 Mon Sep 17 00:00:00 2001
|
||||
From: Kai Krakow <kai@kaishome.de>
|
||||
Date: Thu, 4 Oct 2018 05:51:20 +0200
|
||||
Subject: [PATCH 2/2] winex11.drv: Bypass compositor in fullscreen mode.
|
||||
|
||||
Bypass the compositor in fullscreen mode. This reduces stutter
|
||||
introduced by window updates in the background and also allows for maybe
|
||||
a few more FPS. To not change the visual appearance of the desktop for
|
||||
windowed games, this hack only enables itself when the game was switched
|
||||
to fullscreen mode, and returns to default WM setting when the game
|
||||
leaves fullscreen mode.
|
||||
|
||||
Compositors tend to cause severe stutter if the game is GPU-bound.
|
||||
---
|
||||
dlls/winex11.drv/window.c | 7 +++++++
|
||||
dlls/winex11.drv/x11drv.h | 1 +
|
||||
dlls/winex11.drv/x11drv_main.c | 1 +
|
||||
3 files changed, 9 insertions(+)
|
||||
|
||||
--- a/dlls/winex11.drv/window.c
|
||||
+++ b/dlls/winex11.drv/window.c
|
||||
@@ -1036,6 +1036,7 @@
|
||||
void update_net_wm_states( struct x11drv_win_data *data )
|
||||
{
|
||||
UINT i, style, ex_style, new_state = 0;
|
||||
+ unsigned long net_wm_bypass_compositor = 0;
|
||||
|
||||
if (!data->managed) return;
|
||||
if (data->whole_window == root_window) return;
|
||||
@@ -1048,7 +1049,10 @@
|
||||
if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
|
||||
new_state |= (1 << NET_WM_STATE_MAXIMIZED);
|
||||
else if (!(style & WS_MINIMIZE))
|
||||
+ {
|
||||
+ net_wm_bypass_compositor = 1;
|
||||
new_state |= (1 << NET_WM_STATE_FULLSCREEN);
|
||||
+ }
|
||||
}
|
||||
else if (style & WS_MAXIMIZE)
|
||||
new_state |= (1 << NET_WM_STATE_MAXIMIZED);
|
||||
@@ -1112,6 +1116,9 @@
|
||||
}
|
||||
data->net_wm_state = new_state;
|
||||
update_net_wm_fullscreen_monitors( data );
|
||||
+
|
||||
+ XChangeProperty( data->display, data->whole_window, x11drv_atom(_NET_WM_BYPASS_COMPOSITOR), XA_CARDINAL,
|
||||
+ 32, PropModeReplace, (unsigned char *)&net_wm_bypass_compositor, 1 );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -501,6 +501,7 @@
|
||||
XATOM__NET_SYSTEM_TRAY_OPCODE,
|
||||
XATOM__NET_SYSTEM_TRAY_S0,
|
||||
XATOM__NET_SYSTEM_TRAY_VISUAL,
|
||||
+ XATOM__NET_WM_BYPASS_COMPOSITOR,
|
||||
XATOM__NET_WM_FULLSCREEN_MONITORS,
|
||||
XATOM__NET_WM_ICON,
|
||||
XATOM__NET_WM_MOVERESIZE,
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -159,6 +159,7 @@
|
||||
"_NET_SYSTEM_TRAY_OPCODE",
|
||||
"_NET_SYSTEM_TRAY_S0",
|
||||
"_NET_SYSTEM_TRAY_VISUAL",
|
||||
+ "_NET_WM_BYPASS_COMPOSITOR",
|
||||
"_NET_WM_FULLSCREEN_MONITORS",
|
||||
"_NET_WM_ICON",
|
||||
"_NET_WM_MOVERESIZE",
|
|
@ -1,28 +0,0 @@
|
|||
From 5c8c060fc9d1d20eebe12da2e6dacddd88c07d82 Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Sun, 26 Nov 2023 18:29:53 +0100
|
||||
Subject: [PATCH] HACK: Fix osu! alt-tab.
|
||||
|
||||
---
|
||||
dlls/win32u/window.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c
|
||||
index 11111111111..11111111111 100644
|
||||
--- a/dlls/win32u/window.c
|
||||
+++ b/dlls/win32u/window.c
|
||||
@@ -3514,6 +3514,11 @@ BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y )
|
||||
|
||||
orig_flags = winpos->flags;
|
||||
|
||||
+ /* HACK: fix osu! taking back focus immediately when it is unfocused. */
|
||||
+ if (winpos->hwndInsertAfter == HWND_NOTOPMOST &&
|
||||
+ (get_window_long( winpos->hwnd, GWL_EXSTYLE ) & WS_EX_TOPMOST))
|
||||
+ winpos->flags |= SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
+
|
||||
/* First, check z-order arguments. */
|
||||
if (!(winpos->flags & SWP_NOZORDER))
|
||||
{
|
||||
--
|
||||
0.0.0
|
||||
|
|
@ -1,324 +0,0 @@
|
|||
From ec87cc3742130c138e4caa37084c92c46b9cb9ad Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <openglfreak@googlemail.com>
|
||||
Date: Sun, 3 Jul 2022 15:54:01 +0200
|
||||
Subject: [PATCH 2/2] winex11.drv: Add OpenGL latency reduction code.
|
||||
|
||||
---
|
||||
dlls/winex11.drv/opengl.c | 255 +++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 252 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
|
||||
index 11111111111..11111111111 100644
|
||||
--- a/dlls/winex11.drv/opengl.c
|
||||
+++ b/dlls/winex11.drv/opengl.c
|
||||
@@ -42,6 +42,8 @@
|
||||
#include "xcomposite.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
+#include "wine/server.h"
|
||||
+#include "../win32u/ntuser_private.h"
|
||||
|
||||
#ifdef SONAME_LIBGL
|
||||
|
||||
|
||||
@@ -225,6 +229,8 @@ enum dc_gl_layered_type
|
||||
DC_GL_LAYERED_ATTRIBUTES,
|
||||
};
|
||||
|
||||
+typedef LONGLONG rtime_t;
|
||||
+
|
||||
struct gl_drawable
|
||||
{
|
||||
LONG ref; /* reference count */
|
||||
|
||||
@@ -3443,6 +3454,130 @@ static void X11DRV_WineGL_LoadExtensions(void)
|
||||
}
|
||||
}
|
||||
|
||||
+static inline BOOL allow_latency_reduction( void )
|
||||
+{
|
||||
+ static int status = -1;
|
||||
+ if (status == -1)
|
||||
+ {
|
||||
+ const char *env = getenv( "WINE_OPENGL_LATENCY_REDUCTION" );
|
||||
+ status = !!(env && atoi(env));
|
||||
+ }
|
||||
+ return status == 1;
|
||||
+}
|
||||
+
|
||||
+#define TICKSPERSEC 10000000
|
||||
+
|
||||
+typedef struct ftime_t {
|
||||
+ LONGLONG time;
|
||||
+ ULONGLONG freq;
|
||||
+} ftime_t;
|
||||
+
|
||||
+static inline ftime_t current_ftime( void )
|
||||
+{
|
||||
+ LARGE_INTEGER counter, freq;
|
||||
+ ftime_t ret;
|
||||
+ NtQueryPerformanceCounter( &counter, &freq );
|
||||
+ ret.time = counter.QuadPart;
|
||||
+ ret.freq = (ULONGLONG)freq.QuadPart;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static inline rtime_t ftime_to_rtime( ftime_t ftime, BOOL round_up )
|
||||
+{
|
||||
+ ftime.time *= TICKSPERSEC;
|
||||
+ if (round_up)
|
||||
+ ftime.time += ftime.freq - 1;
|
||||
+ return ftime.time / ftime.freq;
|
||||
+}
|
||||
+
|
||||
+static inline rtime_t current_rtime( BOOL round_up )
|
||||
+{
|
||||
+ return ftime_to_rtime( current_ftime(), round_up );
|
||||
+}
|
||||
+
|
||||
+static rtime_t get_vblank_interval( HWND hwnd )
|
||||
+{
|
||||
+ HMONITOR monitor;
|
||||
+ UNICODE_STRING device_name;
|
||||
+ MONITORINFOEXW moninfo = { sizeof(MONITORINFOEXW) };
|
||||
+ DEVMODEW devmode = { {0}, 0, 0, sizeof(DEVMODEW) };
|
||||
+
|
||||
+ monitor = NtUserMonitorFromWindow( hwnd, MONITOR_DEFAULTTONEAREST );
|
||||
+ if (!monitor || !NtUserGetMonitorInfo( monitor, (MONITORINFO*)&moninfo ))
|
||||
+ return 0;
|
||||
+
|
||||
+ RtlInitUnicodeString( &device_name, moninfo.szDevice );
|
||||
+ if (!NtUserEnumDisplaySettings( &device_name, ENUM_CURRENT_SETTINGS, &devmode, 0 )
|
||||
+ || devmode.dmDisplayFrequency <= 1)
|
||||
+ return 0;
|
||||
+ MESSAGE("detected display frequency: %u\n", devmode.dmDisplayFrequency);
|
||||
+ return TICKSPERSEC / devmode.dmDisplayFrequency;
|
||||
+}
|
||||
+
|
||||
+#define FRAMETIME_MARGIN_SHIFT 2
|
||||
+
|
||||
+static inline rtime_t frame_time_with_margin( rtime_t frame_time )
|
||||
+{
|
||||
+ return frame_time + (frame_time >> FRAMETIME_MARGIN_SHIFT) + 3500;
|
||||
+}
|
||||
+
|
||||
+static void get_swap_interval(GLXDrawable drawable, int *interval)
|
||||
+{
|
||||
+ /* HACK: does not work correctly with __GL_SYNC_TO_VBLANK */
|
||||
+ /*pglXQueryDrawable(gdi_display, gl->drawable, GLX_SWAP_INTERVAL_EXT, (unsigned int*)interval);*/
|
||||
+ *interval = 0;
|
||||
+}
|
||||
+
|
||||
+#define WAIT_MASK (QS_MOUSEBUTTON | QS_KEY | QS_SENDMESSAGE | QS_TIMER | QS_HOTKEY)
|
||||
+
|
||||
+static void msg_wait( const LARGE_INTEGER *timeout )
|
||||
+{
|
||||
+ LARGE_INTEGER to = *timeout, to2 = to;
|
||||
+ rtime_t start, end;
|
||||
+ DWORD ret;
|
||||
+
|
||||
+ /* HACK: __wine_msg_wait_objects likes to wait for about 1 ms too long */
|
||||
+
|
||||
+ if (to2.QuadPart < 0)
|
||||
+ {
|
||||
+ to2.QuadPart += 10000;
|
||||
+ if (to2.QuadPart >= 0)
|
||||
+ {
|
||||
+ end = current_rtime( TRUE );
|
||||
+ goto busy_loop;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (to2.QuadPart >= 10000)
|
||||
+ to2.QuadPart -= 10000;
|
||||
+
|
||||
+ if (to2.QuadPart >= 0)
|
||||
+ {
|
||||
+ __wine_msg_wait_objects( 0, NULL, &to2, WAIT_MASK, MWMO_INPUTAVAILABLE );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+again:
|
||||
+ start = current_rtime( FALSE );
|
||||
+ ret = __wine_msg_wait_objects( 0, NULL, &to2, WAIT_MASK, MWMO_INPUTAVAILABLE );
|
||||
+ if (ret == WAIT_OBJECT_0)
|
||||
+ return;
|
||||
+ end = current_rtime( TRUE );
|
||||
+
|
||||
+ to.QuadPart += end - start;
|
||||
+ if (to.QuadPart < -11000)
|
||||
+ {
|
||||
+ to2.QuadPart = to.QuadPart + 10000;
|
||||
+ goto again;
|
||||
+ }
|
||||
+
|
||||
+busy_loop:
|
||||
+ if (to.QuadPart < -1000)
|
||||
+ {
|
||||
+ end = end - to.QuadPart - 1000;
|
||||
+ while (current_rtime( TRUE ) < end)
|
||||
+ YieldProcessor();
|
||||
+ }
|
||||
+}
|
||||
|
||||
/**
|
||||
* glxdrv_SwapBuffers
|
||||
@@ -3457,6 +3592,11 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
|
||||
INT64 ust, msc, sbc, target_sbc = 0;
|
||||
HWND hwnd;
|
||||
|
||||
+ BOOL enable_latency_reduction = FALSE;
|
||||
+ BOOL synchronize_to_vblank = FALSE;
|
||||
+ rtime_t frame_end_time;
|
||||
+ rtime_t next_vblank_time = 0;
|
||||
+
|
||||
TRACE("(%p)\n", hdc);
|
||||
|
||||
escape.code = X11DRV_PRESENT_DRAWABLE;
|
||||
@@ -3469,18 +3609,78 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ if (allow_latency_reduction())
|
||||
+ enable_latency_reduction = gl->type == DC_GL_WINDOW
|
||||
+ || gl->type == DC_GL_CHILD_WIN || gl->type == DC_GL_PIXMAP_WIN;
|
||||
+
|
||||
+ if (enable_latency_reduction)
|
||||
+ {
|
||||
+ if (ctx && (gl->type == DC_GL_WINDOW || gl->type == DC_GL_CHILD_WIN
|
||||
+ || gl->type == DC_GL_PIXMAP_WIN))
|
||||
+ sync_context( ctx );
|
||||
+ pglFinish();
|
||||
+ frame_end_time = current_rtime( TRUE );
|
||||
+ }
|
||||
+
|
||||
pthread_mutex_lock( &context_mutex );
|
||||
- if (gl->refresh_swap_interval)
|
||||
+
|
||||
+ if (enable_latency_reduction)
|
||||
+ {
|
||||
+ if (!gl->vblank_interval)
|
||||
+ {
|
||||
+ HWND hwnd = 0;
|
||||
+ assert(!XFindContext( gdi_display, gl->window, winContext, (char **)&hwnd ));
|
||||
+ assert(hwnd);
|
||||
+ gl->vblank_interval = get_vblank_interval( hwnd );
|
||||
+ assert(gl->vblank_interval);
|
||||
+ }
|
||||
+
|
||||
+ if (gl->last_vblank_time)
|
||||
+ {
|
||||
+ next_vblank_time = gl->last_vblank_time + gl->vblank_interval;
|
||||
+ while (next_vblank_time < frame_end_time)
|
||||
+ next_vblank_time += gl->vblank_interval;
|
||||
+ }
|
||||
+
|
||||
+ if (gl->last_swap_time)
|
||||
+ {
|
||||
+ rtime_t new_frame_time = frame_end_time - gl->last_swap_time;
|
||||
+ if (new_frame_time >= gl->frame_time)
|
||||
+ gl->frame_time = new_frame_time;
|
||||
+ else if (gl->frame_time > new_frame_time * 3)
|
||||
+ gl->frame_time = frame_time_with_margin( new_frame_time );
|
||||
+ else
|
||||
+ gl->frame_time = (gl->frame_time * 20 + new_frame_time) / 21;
|
||||
+ }
|
||||
+
|
||||
+ if (frame_end_time - gl->last_vblank_time >= TICKSPERSEC
|
||||
+ || (!gl->refresh_swap_interval && next_vblank_time - frame_end_time <= frame_time_with_margin( gl->frame_time )))
|
||||
+ synchronize_to_vblank = TRUE;
|
||||
+ }
|
||||
+
|
||||
+ if (synchronize_to_vblank)
|
||||
+ {
|
||||
+ if (!gl->previous_frame_synchronized)
|
||||
+ {
|
||||
+ get_swap_interval(gl->drawable, &gl->swap_interval);
|
||||
+ if (!set_swap_interval(gl->drawable, 1))
|
||||
+ synchronize_to_vblank = FALSE;
|
||||
+ gl->previous_frame_synchronized = TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (gl->refresh_swap_interval || gl->previous_frame_synchronized)
|
||||
{
|
||||
set_swap_interval(gl->drawable, gl->swap_interval);
|
||||
gl->refresh_swap_interval = FALSE;
|
||||
+ gl->previous_frame_synchronized = FALSE;
|
||||
}
|
||||
+
|
||||
pthread_mutex_unlock( &context_mutex );
|
||||
|
||||
switch (gl->type)
|
||||
{
|
||||
case DC_GL_PIXMAP_WIN:
|
||||
- if (ctx) sync_context( ctx );
|
||||
+ if (!enable_latency_reduction && ctx) sync_context( ctx );
|
||||
escape.drawable = gl->pixmap;
|
||||
if (pglXCopySubBufferMESA) {
|
||||
/* (glX)SwapBuffers has an implicit glFlush effect, however
|
||||
@@ -3501,7 +3701,7 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
|
||||
break;
|
||||
case DC_GL_WINDOW:
|
||||
case DC_GL_CHILD_WIN:
|
||||
- if (ctx) sync_context( ctx );
|
||||
+ if (!enable_latency_reduction && ctx) sync_context( ctx );
|
||||
if (gl->type == DC_GL_CHILD_WIN) escape.drawable = gl->window;
|
||||
/* fall through */
|
||||
default:
|
||||
@@ -3519,5 +3719,54 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
|
||||
pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc );
|
||||
|
||||
+
|
||||
+ if (enable_latency_reduction)
|
||||
+ {
|
||||
+ rtime_t current_time = current_rtime( FALSE );
|
||||
+
|
||||
+ if (!synchronize_to_vblank && gl->last_vblank_time && gl->frame_time)
|
||||
+ {
|
||||
+ LARGE_INTEGER timeout;
|
||||
+
|
||||
+ next_vblank_time = gl->last_vblank_time + gl->vblank_interval;
|
||||
+ while (next_vblank_time < current_time + frame_time_with_margin( gl->frame_time ))
|
||||
+ next_vblank_time += gl->vblank_interval;
|
||||
+
|
||||
+ timeout.QuadPart = -(next_vblank_time - frame_time_with_margin( gl->frame_time ) - current_time);
|
||||
+ if (timeout.QuadPart < 0 && -timeout.QuadPart < TICKSPERSEC)
|
||||
+ msg_wait( &timeout );
|
||||
+
|
||||
+ current_time = current_rtime( FALSE );
|
||||
+ }
|
||||
+
|
||||
+ pthread_mutex_lock( &context_mutex );
|
||||
+
|
||||
+ gl->last_swap_time = current_time;
|
||||
+ if (synchronize_to_vblank)
|
||||
+ gl->last_vblank_time = current_time;
|
||||
+
|
||||
+ pthread_mutex_unlock( &context_mutex );
|
||||
+
|
||||
+ if (synchronize_to_vblank && gl->frame_time)
|
||||
+ {
|
||||
+ LARGE_INTEGER timeout;
|
||||
+
|
||||
+ next_vblank_time = gl->last_vblank_time + gl->vblank_interval;
|
||||
+ while (next_vblank_time < current_time + frame_time_with_margin( gl->frame_time ))
|
||||
+ next_vblank_time += gl->vblank_interval;
|
||||
+
|
||||
+ timeout.QuadPart = -(next_vblank_time - frame_time_with_margin( gl->frame_time ) - current_time);
|
||||
+ if (timeout.QuadPart < 0 && -timeout.QuadPart < TICKSPERSEC)
|
||||
+ {
|
||||
+ msg_wait( &timeout );
|
||||
+
|
||||
+ current_time = current_rtime( FALSE );
|
||||
+ pthread_mutex_lock( &context_mutex );
|
||||
+ gl->last_swap_time = current_time;
|
||||
+ pthread_mutex_unlock( &context_mutex );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
release_gl_drawable( gl );
|
||||
|
||||
if (ctx && escape.drawable)
|
||||
--
|
||||
2.40.0
|
||||
|
|
@ -1,319 +0,0 @@
|
|||
From a21d85ace24116af87b83738909001c1e7cf87c2 Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Wed, 23 Nov 2022 15:47:49 +0100
|
||||
Subject: [PATCH 1/3] ntdll: Add MADV_DONTNEED-based implementation of
|
||||
NtFlushProcessWriteBuffers.
|
||||
|
||||
Credits to Avi Kivity (scylladb) and Aliaksei Kandratsenka (gperftools) for this trick, see [1].
|
||||
|
||||
[1] https://github.com/scylladb/seastar/commit/77a58e4dc020233f66fccb8d9e8f7a8b7f9210c4
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 52 +++++++++++++++++++++++++++++++++++++-
|
||||
tools/winapi/nativeapi.dat | 1 +
|
||||
2 files changed, 52 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 8087a12785c..de8f8b6ebc1 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -215,6 +215,11 @@ struct range_entry
|
||||
static struct range_entry *free_ranges;
|
||||
static struct range_entry *free_ranges_end;
|
||||
|
||||
+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
|
||||
+static void *dontneed_page;
|
||||
+static pthread_mutex_t dontneed_page_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
+#endif
|
||||
+
|
||||
|
||||
static inline BOOL is_beyond_limit( const void *addr, size_t size, const void *limit )
|
||||
{
|
||||
@@ -5174,14 +5179,58 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T
|
||||
}
|
||||
|
||||
|
||||
+static BOOL try_madvise( void )
|
||||
+{
|
||||
+ BOOL success = FALSE;
|
||||
+ char *mem;
|
||||
+
|
||||
+ pthread_mutex_lock(&dontneed_page_mutex);
|
||||
+ /* Credits to Avi Kivity (scylladb) and Aliaksei Kandratsenka (gperftools) for this trick,
|
||||
+ see https://github.com/scylladb/seastar/commit/77a58e4dc020233f66fccb8d9e8f7a8b7f9210c4 */
|
||||
+ mem = dontneed_page;
|
||||
+ if (!mem)
|
||||
+ {
|
||||
+ int ret;
|
||||
+ /* Allocate one page of memory that we can call madvise() on */
|
||||
+ mem = anon_mmap_alloc( page_size, PROT_READ | PROT_WRITE );
|
||||
+ if (mem == MAP_FAILED)
|
||||
+ goto failed;
|
||||
+ /* If the memory is locked, e.g. by a call to mlockall(MCL_FUTURE), the madvise() call below
|
||||
+ will fail with error EINVAL, so unlock it here */
|
||||
+ ret = munlock( mem, page_size );
|
||||
+ /* munlock() may fail on old kernels if we don't have sufficient permissions, but that is not
|
||||
+ a problem since in that case we didn't have permission to lock the memory either */
|
||||
+ if (ret && errno != EPERM)
|
||||
+ goto failed;
|
||||
+ dontneed_page = mem;
|
||||
+ }
|
||||
+ /* Force the page into memory to make madvise() have real work to do */
|
||||
+ *mem = 3;
|
||||
+ /* Evict the page from memory to force the kernel to send an IPI to all threads of this process,
|
||||
+ which has the side effect of executing a memory barrier in those threads */
|
||||
+ success = !madvise( mem, page_size, MADV_DONTNEED );
|
||||
+failed:
|
||||
+ pthread_mutex_unlock(&dontneed_page_mutex);
|
||||
+ return success;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**********************************************************************
|
||||
* NtFlushProcessWriteBuffers (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtFlushProcessWriteBuffers(void)
|
||||
{
|
||||
static int once = 0;
|
||||
- if (!once++) FIXME( "stub\n" );
|
||||
- return STATUS_SUCCESS;
|
||||
+ if (try_madvise())
|
||||
+ {
|
||||
+#ifdef __aarch64__
|
||||
+ /* Some ARMv8 processors can broadcast TLB invalidations using the TLBI instruction,
|
||||
+ the madvise trick does not work on those */
|
||||
+ if (!once++) FIXME( "memory barrier may not work on this platform\n" );
|
||||
+#endif
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!once++) FIXME( "no implementation available on this platform\n" );
|
||||
}
|
||||
|
||||
|
||||
diff --git a/tools/winapi/nativeapi.dat b/tools/winapi/nativeapi.dat
|
||||
index ade20b5ee68..5512c4f1833 100644
|
||||
--- a/tools/winapi/nativeapi.dat
|
||||
+++ b/tools/winapi/nativeapi.dat
|
||||
@@ -134,6 +134,7 @@ log10
|
||||
logb
|
||||
longjmp
|
||||
lseek
|
||||
+madvise
|
||||
malloc
|
||||
mblen
|
||||
memccpy
|
||||
--
|
||||
GitLab
|
||||
|
||||
|
||||
From d3afd6ff2ffe7942d6e0846dea52a3884111a06a Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Wed, 23 Nov 2022 15:47:50 +0100
|
||||
Subject: [PATCH 2/3] ntdll: Add sys_membarrier-based implementation of
|
||||
NtFlushProcessWriteBuffers.
|
||||
|
||||
Uses the MEMBARRIER_CMD_PRIVATE_EXPEDITED membarrier command introduced in Linux 4.14.
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 49 ++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 48 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index de8f8b6ebc1..e90bdb3abfb 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -39,6 +39,9 @@
|
||||
#ifdef HAVE_SYS_SYSINFO_H
|
||||
# include <sys/sysinfo.h>
|
||||
#endif
|
||||
+#ifdef HAVE_SYS_SYSCALL_H
|
||||
+# include <sys/syscall.h>
|
||||
+#endif
|
||||
#ifdef HAVE_SYS_SYSCTL_H
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
@@ -215,10 +218,16 @@ struct range_entry
|
||||
static struct range_entry *free_ranges;
|
||||
static struct range_entry *free_ranges_end;
|
||||
|
||||
-#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
|
||||
+#ifdef __linux__
|
||||
+#ifdef __NR_membarrier
|
||||
+static BOOL membarrier_exp_available;
|
||||
+static pthread_once_t membarrier_init_once = PTHREAD_ONCE_INIT;
|
||||
+#endif
|
||||
+#if defined(__i386__) || defined(__x86_64__)
|
||||
static void *dontneed_page;
|
||||
static pthread_mutex_t dontneed_page_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
|
||||
static inline BOOL is_beyond_limit( const void *addr, size_t size, const void *limit )
|
||||
@@ -5179,6 +5188,42 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T
|
||||
}
|
||||
|
||||
|
||||
+#if defined(__linux__) && defined(__NR_membarrier)
|
||||
+#define MEMBARRIER_CMD_QUERY 0x00
|
||||
+#define MEMBARRIER_CMD_PRIVATE_EXPEDITED 0x08
|
||||
+#define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED 0x10
|
||||
+
|
||||
+
|
||||
+static int membarrier( int cmd, unsigned int flags, int cpu_id )
|
||||
+{
|
||||
+ return syscall( __NR_membarrier, cmd, flags, cpu_id );
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void membarrier_init( void )
|
||||
+{
|
||||
+ static const int exp_required_cmds =
|
||||
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED;
|
||||
+ int available_cmds = membarrier( MEMBARRIER_CMD_QUERY, 0, 0 );
|
||||
+ if (available_cmds == -1)
|
||||
+ return;
|
||||
+ if ((available_cmds & exp_required_cmds) == exp_required_cmds)
|
||||
+ membarrier_exp_available = !membarrier( MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0 );
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static BOOL try_exp_membarrier( void )
|
||||
+{
|
||||
+ pthread_once(&membarrier_init_once, membarrier_init);
|
||||
+ if (!membarrier_exp_available)
|
||||
+ return FALSE;
|
||||
+ return !membarrier( MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0 );
|
||||
+}
|
||||
+#else
|
||||
+static BOOL try_exp_membarrier( void ) { return 0; }
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
static BOOL try_madvise( void )
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
@@ -5221,6 +5266,8 @@ failed:
|
||||
void WINAPI NtFlushProcessWriteBuffers(void)
|
||||
{
|
||||
static int once = 0;
|
||||
+ if (try_exp_membarrier())
|
||||
+ return;
|
||||
if (try_madvise())
|
||||
{
|
||||
#ifdef __aarch64__
|
||||
--
|
||||
GitLab
|
||||
|
||||
|
||||
From 48f1d7cad78235c5c9e64c419235289608294440 Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Wed, 23 Nov 2022 15:47:50 +0100
|
||||
Subject: [PATCH 3/3] ntdll: Add thread_get_register_pointer_values-based
|
||||
implementation of NtFlushProcessWriteBuffers.
|
||||
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 68 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 68 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index e90bdb3abfb..c5a2f878e3b 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -65,6 +65,9 @@
|
||||
#if defined(__APPLE__)
|
||||
# include <mach/mach_init.h>
|
||||
# include <mach/mach_vm.h>
|
||||
+# include <mach/task.h>
|
||||
+# include <mach/thread_state.h>
|
||||
+# include <mach/vm_map.h>
|
||||
#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
@@ -218,6 +221,11 @@ struct range_entry
|
||||
static struct range_entry *free_ranges;
|
||||
static struct range_entry *free_ranges_end;
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+static kern_return_t (*p_thread_get_register_pointer_values)( thread_t, uintptr_t*, size_t*, uintptr_t* );
|
||||
+static pthread_once_t tgrpvs_init_once = PTHREAD_ONCE_INIT;
|
||||
+#endif
|
||||
+
|
||||
#ifdef __linux__
|
||||
#ifdef __NR_membarrier
|
||||
static BOOL membarrier_exp_available;
|
||||
@@ -5188,6 +5196,64 @@ NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T
|
||||
}
|
||||
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+
|
||||
+static void tgrpvs_init( void )
|
||||
+{
|
||||
+ p_thread_get_register_pointer_values = dlsym( RTLD_DEFAULT, "thread_get_register_pointer_values" );
|
||||
+}
|
||||
+
|
||||
+static BOOL try_mach_tgrpvs( void )
|
||||
+{
|
||||
+ /* Taken from https://github.com/dotnet/runtime/blob/7be37908e5a1cbb83b1062768c1649827eeaceaa/src/coreclr/pal/src/thread/process.cpp#L2799 */
|
||||
+ mach_msg_type_number_t count, i = 0;
|
||||
+ thread_act_array_t threads;
|
||||
+ kern_return_t kret;
|
||||
+ BOOL success = FALSE;
|
||||
+
|
||||
+ pthread_once(&tgrpvs_init_once, tgrpvs_init);
|
||||
+ if (!p_thread_get_register_pointer_values)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Get references to all threads of this process */
|
||||
+ kret = task_threads( mach_task_self(), &threads, &count );
|
||||
+ if (kret)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Iterate through the threads in the list */
|
||||
+ while (i < count)
|
||||
+ {
|
||||
+ uintptr_t reg_values[128];
|
||||
+ size_t reg_count = ARRAY_SIZE( reg_values );
|
||||
+ uintptr_t sp;
|
||||
+
|
||||
+ /* Request the thread's register pointer values to force the thread to go through a memory barrier */
|
||||
+ kret = p_thread_get_register_pointer_values( threads[i], &sp, ®_count, reg_values );
|
||||
+ /* This function always fails when querying Rosetta's exception handling thread, so we only treat
|
||||
+ KERN_INSUFFICIENT_BUFFER_SIZE as an error, like .NET core does. */
|
||||
+ if (kret == KERN_INSUFFICIENT_BUFFER_SIZE)
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* Deallocate thread reference once we're done with it */
|
||||
+ kret = mach_port_deallocate( mach_task_self(), threads[i++] );
|
||||
+ if (kret)
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ success = TRUE;
|
||||
+fail:
|
||||
+ /* Deallocate remaining thread references */
|
||||
+ while (i < count)
|
||||
+ mach_port_deallocate( mach_task_self(), threads[i++] );
|
||||
+ /* Deallocate thread list */
|
||||
+ vm_deallocate( mach_task_self(), (vm_address_t)threads, count * sizeof(threads[0]) );
|
||||
+ return success;
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+static BOOL try_mach_tgrpvs( void ) { return 0; }
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
#if defined(__linux__) && defined(__NR_membarrier)
|
||||
#define MEMBARRIER_CMD_QUERY 0x00
|
||||
#define MEMBARRIER_CMD_PRIVATE_EXPEDITED 0x08
|
||||
@@ -5266,6 +5332,8 @@ failed:
|
||||
void WINAPI NtFlushProcessWriteBuffers(void)
|
||||
{
|
||||
static int once = 0;
|
||||
+ if (try_mach_tgrpvs())
|
||||
+ return;
|
||||
if (try_exp_membarrier())
|
||||
return;
|
||||
if (try_madvise())
|
||||
--
|
||||
GitLab
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
## Patch to revert commit 35193586 which supposedly broke osu!
|
||||
## on GNOME on X11 due to compositor not turning off even with fullscreen enabled
|
||||
|
||||
--- b/dlls/winex11.drv/window.c
|
||||
+++ a/dlls/winex11.drv/window.c
|
||||
@@ -1542,21 +1542,9 @@
|
||||
attrib.border_pixel = 0;
|
||||
attrib.colormap = default_colormap;
|
||||
|
||||
-#ifdef HAVE_LIBXSHAPE
|
||||
- {
|
||||
- static XRectangle empty_rect;
|
||||
- dummy_parent = XCreateWindow( gdi_display, root_window, 0, 0, 1, 1, 0,
|
||||
- default_visual.depth, InputOutput, default_visual.visual,
|
||||
- CWColormap | CWBorderPixel | CWOverrideRedirect, &attrib );
|
||||
- XShapeCombineRectangles( gdi_display, dummy_parent, ShapeBounding, 0, 0, &empty_rect, 1,
|
||||
- ShapeSet, YXBanded );
|
||||
- }
|
||||
-#else
|
||||
dummy_parent = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, default_visual.depth,
|
||||
InputOutput, default_visual.visual,
|
||||
CWColormap | CWBorderPixel | CWOverrideRedirect, &attrib );
|
||||
- WARN("Xshape support is not compiled in. Applications under XWayland may have poor performance.\n");
|
||||
-#endif
|
||||
XMapWindow( gdi_display, dummy_parent );
|
||||
}
|
||||
return dummy_parent;
|
|
@ -1,177 +0,0 @@
|
|||
{ pkgs ? import <nixpkgs> {}, path ? pkgs.path }:
|
||||
## we default to importing <nixpkgs> here, so that you can use
|
||||
## a simple shell command to insert new hashes into this file
|
||||
## e.g. with emacs C-u M-x shell-command
|
||||
##
|
||||
## nix-prefetch-url sources.nix -A {stable{,.mono,.gecko64,.gecko32}, unstable, staging, winetricks}
|
||||
|
||||
# here we wrap fetchurl and fetchFromGitHub, in order to be able to pass additional args around it
|
||||
let fetchurl = args@{url, hash, ...}:
|
||||
pkgs.fetchurl { inherit url hash; } // args;
|
||||
fetchFromGitHub = args@{owner, repo, rev, hash, ...}:
|
||||
pkgs.fetchFromGitHub { inherit owner repo rev hash; } // args;
|
||||
fetchFromGitLab = args@{domain, owner, repo, rev, hash, ...}:
|
||||
pkgs.fetchFromGitLab { inherit domain owner repo rev hash; } // args;
|
||||
|
||||
updateScriptPreamble = ''
|
||||
set -eou pipefail
|
||||
PATH=${with pkgs; lib.makeBinPath [ common-updater-scripts coreutils curl gnugrep gnused jq nix ]}
|
||||
sources_file=${__curPos.file}
|
||||
source ${./update-lib.sh}
|
||||
'';
|
||||
|
||||
inherit (pkgs) writeShellScript;
|
||||
in rec {
|
||||
|
||||
stable = fetchurl rec {
|
||||
version = "9.0";
|
||||
url = "https://dl.winehq.org/wine/source/9.0/wine-${version}.tar.xz";
|
||||
hash = "sha256-fP0JClOV9bdtlbtd76yKMSyN5MBwwRY7i1jaODMMpu4=";
|
||||
|
||||
## see http://wiki.winehq.org/Gecko
|
||||
gecko32 = fetchurl rec {
|
||||
version = "2.47.4";
|
||||
url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86.msi";
|
||||
hash = "sha256-Js7MR3BrCRkI9/gUvdsHTGG+uAYzGOnvxaf3iYV3k9Y=";
|
||||
};
|
||||
gecko64 = fetchurl rec {
|
||||
version = "2.47.4";
|
||||
url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86_64.msi";
|
||||
hash = "sha256-5ZC32YijLWqkzx2Ko6o9M3Zv3Uz0yJwtzCCV7LKNBm8=";
|
||||
};
|
||||
|
||||
## see http://wiki.winehq.org/Mono
|
||||
mono = fetchurl rec {
|
||||
version = "8.1.0";
|
||||
url = "https://dl.winehq.org/wine/wine-mono/${version}/wine-mono-${version}-x86.msi";
|
||||
hash = "sha256-DtPsUzrvebLzEhVZMc97EIAAmsDFtMK8/rZ4rJSOCBA=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Also look for root certificates at $NIX_SSL_CERT_FILE
|
||||
"${path}/pkgs/applications/emulators/wine/cert-path.patch"
|
||||
];
|
||||
|
||||
updateScript = writeShellScript "update-wine-stable" (''
|
||||
${updateScriptPreamble}
|
||||
major=''${UPDATE_NIX_OLD_VERSION%%.*}
|
||||
latest_stable=$(get_latest_wine_version "$major.0")
|
||||
|
||||
# Can't use autobump on stable because we don't want the path
|
||||
# <source/7.0/wine-7.0.tar.xz> to become <source/7.0.1/wine-7.0.1.tar.xz>.
|
||||
if [[ "$UPDATE_NIX_OLD_VERSION" != "$latest_stable" ]]; then
|
||||
set_version_and_hash stable "$latest_stable" "$(nix-prefetch-url "$wine_url_base/source/$major.0/wine-$latest_stable.tar.xz")"
|
||||
fi
|
||||
|
||||
do_update
|
||||
'');
|
||||
};
|
||||
|
||||
unstable = fetchurl rec {
|
||||
# NOTE: Don't forget to change the hash for staging as well.
|
||||
version = "9.0";
|
||||
url = "https://dl.winehq.org/wine/source/9.0/wine-${version}.tar.xz";
|
||||
hash = "sha256-fP0JClOV9bdtlbtd76yKMSyN5MBwwRY7i1jaODMMpu4=";
|
||||
inherit (stable) patches;
|
||||
|
||||
## see http://wiki.winehq.org/Gecko
|
||||
gecko32 = fetchurl rec {
|
||||
version = "2.47.4";
|
||||
url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86.msi";
|
||||
hash = "sha256-Js7MR3BrCRkI9/gUvdsHTGG+uAYzGOnvxaf3iYV3k9Y=";
|
||||
};
|
||||
gecko64 = fetchurl rec {
|
||||
version = "2.47.4";
|
||||
url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86_64.msi";
|
||||
hash = "sha256-5ZC32YijLWqkzx2Ko6o9M3Zv3Uz0yJwtzCCV7LKNBm8=";
|
||||
};
|
||||
|
||||
## see http://wiki.winehq.org/Mono
|
||||
mono = fetchurl rec {
|
||||
version = "8.1.0";
|
||||
url = "https://dl.winehq.org/wine/wine-mono/${version}/wine-mono-${version}-x86.msi";
|
||||
hash = "sha256-DtPsUzrvebLzEhVZMc97EIAAmsDFtMK8/rZ4rJSOCBA=";
|
||||
};
|
||||
|
||||
updateScript = writeShellScript "update-wine-unstable" ''
|
||||
${updateScriptPreamble}
|
||||
major=''${UPDATE_NIX_OLD_VERSION%%.*}
|
||||
latest_unstable=$(get_latest_wine_version "$major.x")
|
||||
latest_gecko=$(get_latest_lib_version wine-gecko)
|
||||
latest_mono=$(get_latest_lib_version wine-mono)
|
||||
|
||||
update_staging() {
|
||||
staging_url=$(get_source_attr staging.url)
|
||||
set_source_attr staging hash "\"$(to_sri "$(nix-prefetch-url --unpack "''${staging_url//$1/$2}")")\""
|
||||
}
|
||||
|
||||
autobump unstable "$latest_unstable" "" update_staging
|
||||
autobump unstable.gecko32 "$latest_gecko"
|
||||
autobump unstable.gecko64 "$latest_gecko"
|
||||
autobump unstable.mono "$latest_mono"
|
||||
|
||||
do_update
|
||||
'';
|
||||
};
|
||||
|
||||
staging = fetchFromGitHub rec {
|
||||
# https://github.com/wine-staging/wine-staging/releases
|
||||
inherit (unstable) version;
|
||||
hash = "sha256-lE/95OZigifreaRRCPkvA+Z0FqsBmm018jD6leSysXU=";
|
||||
owner = "wine-staging";
|
||||
repo = "wine-staging";
|
||||
rev = "v${version}";
|
||||
|
||||
disabledPatchsets = [ ];
|
||||
};
|
||||
|
||||
wayland = fetchFromGitLab {
|
||||
# https://gitlab.collabora.com/alf/wine/-/tree/wayland
|
||||
version = "8.2";
|
||||
hash = "sha256-Eb2SFBIeQQ3cVZkUQcwNT5mcYe0ShFxBdMc3BlqkwTo=";
|
||||
domain = "gitlab.collabora.com";
|
||||
owner = "alf";
|
||||
repo = "wine";
|
||||
rev = "b2547ddf9e08cafce98cf7734d5c4ec926ef3536";
|
||||
|
||||
inherit (unstable) gecko32 gecko64;
|
||||
|
||||
inherit (unstable) mono;
|
||||
|
||||
updateScript = writeShellScript "update-wine-wayland" ''
|
||||
${updateScriptPreamble}
|
||||
wayland_rev=$(get_source_attr wayland.rev)
|
||||
|
||||
latest_wayland_rev=$(curl -s 'https://gitlab.collabora.com/api/v4/projects/2847/repository/branches/wayland' | jq -r .commit.id)
|
||||
|
||||
if [[ "$wayland_rev" != "$latest_wayland_rev" ]]; then
|
||||
latest_wayland=$(curl -s 'https://gitlab.collabora.com/alf/wine/-/raw/wayland/VERSION' | cut -f3 -d' ')
|
||||
wayland_url=$(get_source_attr wayland.url)
|
||||
set_version_and_hash wayland "$latest_wayland" "$(nix-prefetch-url --unpack "''${wayland_url/$wayland_rev/$latest_wayland_rev}")"
|
||||
set_source_attr wayland rev "\"$latest_wayland_rev\""
|
||||
fi
|
||||
|
||||
do_update
|
||||
'';
|
||||
};
|
||||
|
||||
winetricks = fetchFromGitHub rec {
|
||||
# https://github.com/Winetricks/winetricks/releases
|
||||
version = "20240105";
|
||||
hash = "sha256-YTEgb19aoM54KK8/IjrspoChzVnWAEItDlTxpfpS52w=";
|
||||
owner = "Winetricks";
|
||||
repo = "winetricks";
|
||||
rev = version;
|
||||
|
||||
updateScript = writeShellScript "update-winetricks" ''
|
||||
${updateScriptPreamble}
|
||||
winetricks_repourl=$(get_source_attr winetricks.gitRepoUrl)
|
||||
|
||||
latest_winetricks=$(list-git-tags --url="$winetricks_repourl" | grep -E '^[0-9]{8}$' | sort --reverse --numeric-sort | head -n 1)
|
||||
|
||||
autobump winetricks "$latest_winetricks" 'nix-prefetch-url --unpack'
|
||||
|
||||
do_update
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, router-config
|
||||
, hardware
|
||||
, ... }:
|
||||
, ...
|
||||
}:
|
||||
|
||||
let
|
||||
uuids.enc = "15945050-df48-418b-b736-827749b9262a";
|
||||
|
@ -35,9 +36,7 @@ in
|
|||
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||
};
|
||||
|
||||
networking.useDHCP = true;
|
||||
/*
|
||||
# as expected, systemd initrd and networking didn't work well, and i really cba to debug it
|
||||
# as expected, systemd initrd didn't work well, and i really cba to debug it
|
||||
networking.useDHCP = false;
|
||||
networking.useNetworkd = true;
|
||||
systemd.network = {
|
||||
|
@ -52,11 +51,18 @@ in
|
|||
networks."10-dhcp" = {
|
||||
DHCP = "yes";
|
||||
name = "e*";
|
||||
networkConfig.IPv6AcceptRA = "yes";
|
||||
dhcpV4Config = {
|
||||
ClientIdentifier = "mac";
|
||||
DUIDType = "link-layer";
|
||||
};
|
||||
dhcpV6Config.DUIDType = "link-layer";
|
||||
};
|
||||
};*/
|
||||
};
|
||||
|
||||
boot.initrd = {
|
||||
/*systemd = {
|
||||
systemd = {
|
||||
services.unlock-bcachefs-persist.enable = false;
|
||||
enable = true;
|
||||
network = {
|
||||
enable = true;
|
||||
|
@ -70,20 +76,24 @@ in
|
|||
networks."10-dhcp" = {
|
||||
DHCP = "yes";
|
||||
name = "e*";
|
||||
networkConfig = {
|
||||
IPv6AcceptRA = "yes";
|
||||
};
|
||||
dhcpV4Config = {
|
||||
ClientIdentifier = "mac";
|
||||
DUIDType = "link-layer";
|
||||
};
|
||||
dhcpV6Config = {
|
||||
DUIDType = "link-layer";
|
||||
};
|
||||
};
|
||||
};
|
||||
};*/
|
||||
# eth0 on some kernels
|
||||
# end0 on other kernels
|
||||
# sometimes even version dependent
|
||||
preLVMCommands = lib.mkOrder 499 ''
|
||||
ip link set end0 address ${router-config.router-settings.serverInitrdMac} || ip link set eth0 address ${router-config.router-settings.serverInitrdMac} || true
|
||||
'';
|
||||
postMountCommands = ''
|
||||
ip link set end0 address ${router-config.router-settings.serverMac} || ip link set eth0 address ${router-config.router-settings.serverInitrdMac} || true
|
||||
'';
|
||||
network.enable = true;
|
||||
network.udhcpc.extraArgs = [ "-t6" ];
|
||||
};
|
||||
network.enable = false;
|
||||
network.flushBeforeStage2 = true;
|
||||
systemd.initrdBin = [ pkgs.iproute2 pkgs.vim pkgs.bashInteractive pkgs.util-linux ];
|
||||
systemd.storePaths = [ pkgs.vim pkgs.busybox ];
|
||||
systemd.users.root.shell = "/bin/bash";
|
||||
network.ssh = {
|
||||
enable = true;
|
||||
port = 22;
|
||||
|
@ -92,7 +102,6 @@ in
|
|||
"/secrets/initrd/ssh_host_rsa_key"
|
||||
"/secrets/initrd/ssh_host_ed25519_key"
|
||||
];
|
||||
# shell = "/bin/cryptsetup-askpass";
|
||||
};
|
||||
luks.devices.cryptroot = {
|
||||
device = parts.enc;
|
||||
|
@ -117,7 +126,15 @@ in
|
|||
options = [ "defaults" "size=2G" "mode=755" ]; };
|
||||
"/persist" =
|
||||
{ device = "UUID=${uuids.bch}"; fsType = "bcachefs"; inherit neededForBoot;
|
||||
options = [ "errors=ro" ]; };
|
||||
# TODO: https://github.com/systemd/systemd/pull/33720/files
|
||||
options = [
|
||||
"degraded"
|
||||
"errors=ro"
|
||||
"x-systemd.device-timeout=0"
|
||||
"x-systemd.requires=dev-mapper-bch0.device"
|
||||
"x-systemd.requires=dev-mapper-bch1.device"
|
||||
"x-systemd.requires=dev-mapper-bch2.device"
|
||||
]; };
|
||||
"/boot" = { device = parts.boot; fsType = "vfat"; inherit neededForBoot; };
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ pkgs
|
||||
, pkgs-kernel
|
||||
, config
|
||||
, ... }:
|
||||
|
||||
|
@ -8,7 +9,7 @@
|
|||
generic-extlinux-compatible.enable = true;
|
||||
};
|
||||
|
||||
boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.buildLinuxWithCcache pkgs.linux_bpiR3);
|
||||
boot.kernelPackages = pkgs-kernel.linuxPackagesFor (pkgs-kernel.ccachePkgs.buildLinuxWithCcache pkgs-kernel.hw.bpi-r3.linux);
|
||||
|
||||
hardware.deviceTree.enable = true;
|
||||
hardware.deviceTree.filter = "mt7986a-bananapi-bpi-r3.dtb";
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
, ... }:
|
||||
|
||||
let
|
||||
armTrustedFirmwareBpiR3 = { bootDevice, uboot ? null }: pkgs.buildArmTrustedFirmware rec {
|
||||
mkArmTrustedFirmwareBpiR3 = { bootDevice, uboot ? null }: pkgs.buildArmTrustedFirmware rec {
|
||||
inherit (sources.atf-bpir3) src;
|
||||
patches = [ ./bpi-r3-atf-backport-mkimage-support.patch ];
|
||||
extraMakeFlags = assert builtins.elem bootDevice [
|
||||
|
@ -36,7 +36,7 @@ let
|
|||
# CONFIG_DISTRO_DEFAULTS - surely this won't hurt, it adds autocomplete and stuff and doesn't weight much in the large scale of things
|
||||
# CONFIG_SYS_BOOTM_LEN - increase max initrd? size
|
||||
# CONFIG_ZSTD - allow zstd initrd
|
||||
ubootConfig = storage: ''
|
||||
mkUbootConfig = storage: ''
|
||||
CONFIG_AUTOBOOT=y
|
||||
CONFIG_BOOTCOMMAND="${builtins.replaceStrings [ "\n" ] [ "; " ] ''
|
||||
setenv boot_prefixes /@boot/ /@/ /boot/ /
|
||||
|
@ -61,9 +61,9 @@ let
|
|||
};
|
||||
|
||||
in rec {
|
||||
ubootBpiR3Sd = pkgs.buildUBoot {
|
||||
sd.uboot = pkgs.buildUBoot {
|
||||
defconfig = "mt7986a_bpir3_sd_defconfig";
|
||||
extraConfig = ubootConfig "sd";
|
||||
extraConfig = mkUbootConfig "sd";
|
||||
src = ubootSrc;
|
||||
version = ubootVersion;
|
||||
extraMeta.platforms = [ "aarch64-linux" ];
|
||||
|
@ -71,52 +71,52 @@ in rec {
|
|||
patches = [ ./mt7986-default-bootcmd.patch ];
|
||||
filesToInstall = [ "u-boot.bin" ];
|
||||
};
|
||||
ubootBpiR3Emmc = pkgs.buildUBoot {
|
||||
emmc.uboot = pkgs.buildUBoot {
|
||||
defconfig = "mt7986a_bpir3_emmc_defconfig";
|
||||
extraConfig = ubootConfig "emmc";
|
||||
extraConfig = mkUbootConfig "emmc";
|
||||
src = ubootSrc;
|
||||
version = ubootVersion;
|
||||
extraMeta.platforms = [ "aarch64-linux" ];
|
||||
patches = [ ./mt7986-default-bootcmd.patch ];
|
||||
filesToInstall = [ "u-boot.bin" ];
|
||||
};
|
||||
armTrustedFirmwareBpiR3Sd = armTrustedFirmwareBpiR3 { uboot = ubootBpiR3Sd; bootDevice = "sdmmc"; };
|
||||
armTrustedFirmwareBpiR3Emmc = armTrustedFirmwareBpiR3 { uboot = ubootBpiR3Emmc; bootDevice = "emmc"; };
|
||||
bpiR3StuffCombined = pkgs.stdenvNoCC.mkDerivation {
|
||||
sd.armTrustedFirmware = mkArmTrustedFirmwareBpiR3 { inherit (sd) uboot; bootDevice = "sdmmc"; };
|
||||
emmc.armTrustedFirmware = mkArmTrustedFirmwareBpiR3 { inherit (emmc) uboot; bootDevice = "emmc"; };
|
||||
combinedStuff = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "bpi-r3-stuff";
|
||||
unpackPhase = "true";
|
||||
buildPhase = "true";
|
||||
installPhase = ''
|
||||
mkdir -p $out/sd
|
||||
mkdir -p $out/emmc
|
||||
cp ${bpiR3StuffEmmc}/* $out/emmc
|
||||
cp ${bpiR3StuffSd}/* $out/sd
|
||||
cp ${emmc.stuff}/* $out/emmc
|
||||
cp ${sd.stuff}/* $out/sd
|
||||
'';
|
||||
fixupPhase = "true";
|
||||
};
|
||||
bpiR3StuffEmmc = pkgs.stdenvNoCC.mkDerivation {
|
||||
emmc.stuff = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "bpi-r3-stuff-emmc";
|
||||
unpackPhase = "true";
|
||||
buildPhase = "true";
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp ${ubootBpiR3Emmc}/*.* $out
|
||||
cp ${armTrustedFirmwareBpiR3Emmc}/*.* $out
|
||||
cp ${emmc.uboot}/*.* $out
|
||||
cp ${emmc.armTrustedFirmware}/*.* $out
|
||||
'';
|
||||
fixupPhase = "true";
|
||||
};
|
||||
bpiR3StuffSd = pkgs.stdenvNoCC.mkDerivation {
|
||||
sd.stuff = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "bpi-r3-stuff-sd";
|
||||
unpackPhase = "true";
|
||||
buildPhase = "true";
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp ${ubootBpiR3Sd}/*.* $out
|
||||
cp ${armTrustedFirmwareBpiR3Sd}/*.* $out
|
||||
cp ${sd.uboot}/*.* $out
|
||||
cp ${sd.armTrustedFirmware}/*.* $out
|
||||
'';
|
||||
fixupPhase = "true";
|
||||
};
|
||||
linux_bpiR3 = pkgs.linux_latest.override {
|
||||
linux = pkgs.linux_latest.override {
|
||||
ignoreConfigErrors = false;
|
||||
# there's probably more enabled-by-default configs that are better left disabled, but whatever
|
||||
structuredExtraConfig = with lib.kernel; {
|
||||
|
@ -351,5 +351,5 @@ in rec {
|
|||
XEN_PVHVM.tristate = lib.mkForce null; XEN_SAVE_RESTORE.tristate = lib.mkForce null; XEN_SYS_HYPERVISOR.tristate = lib.mkForce null;
|
||||
};
|
||||
};
|
||||
linuxPackages_bpiR3 = pkgs.linuxPackagesFor linux_bpiR3;
|
||||
linuxPackages = pkgs.linuxPackagesFor linux;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ pkgs
|
||||
, pkgs-kernel
|
||||
, lib
|
||||
, config
|
||||
, inputs
|
||||
|
@ -7,6 +8,8 @@
|
|||
|
||||
let
|
||||
cfg = config.phone;
|
||||
hw = pkgs.hw.oneplus-enchilada;
|
||||
hw-kernel = pkgs-kernel.hw.oneplus-enchilada;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
@ -27,16 +30,21 @@ in
|
|||
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
inherit (self.hw.oneplus-enchilada) pd-mapper qrtr rmtfs tqftpserv;
|
||||
})
|
||||
];
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
mobile.quirks.qualcomm.sdm845-modem.enable = true;
|
||||
mobile.quirks.audio.alsa-ucm-meld = true;
|
||||
environment.systemPackages = [ pkgs.alsa-ucm-conf-enchilada ];
|
||||
environment.systemPackages = [ hw.alsa-ucm-conf ];
|
||||
systemd.services.q6voiced = {
|
||||
description = "QDSP6 driver daemon";
|
||||
after = [ "ModemManager.service" "dbus.socket" ];
|
||||
wantedBy = [ "ModemManager.service" ];
|
||||
requires = [ "dbus.socket" ];
|
||||
serviceConfig.ExecStart = "${pkgs.q6voiced}/bin/q6voiced hw:0,6";
|
||||
serviceConfig.ExecStart = "${hw.q6voiced}/bin/q6voiced hw:0,6";
|
||||
};
|
||||
# TODO when testing PipeWire instead of PulseAudio, the following is needed:
|
||||
# https://gitlab.freedesktop.org/pipewire/wireplumber/-/blob/master/docs/rst/daemon/configuration/migration.rst
|
||||
|
@ -62,8 +70,8 @@ in
|
|||
percentageAction = 3;
|
||||
criticalPowerAction = "PowerOff";
|
||||
};
|
||||
hardware.firmware = lib.mkAfter [ pkgs.firmware-oneplus-sdm845 ];
|
||||
boot.kernelPackages = lib.mkForce (pkgs.linuxPackagesFor pkgs.linux_enchilada_ccache);
|
||||
hardware.firmware = lib.mkAfter [ hw.firmware ];
|
||||
boot.kernelPackages = lib.mkForce (pkgs-kernel.linuxPackagesFor hw-kernel.linux_ccache);
|
||||
hardware.deviceTree.enable = true;
|
||||
hardware.deviceTree.name = "qcom/sdm845-oneplus-enchilada.dtb";
|
||||
# loglevel=7 console=ttyMSM0,115200 is a way to delay boot
|
||||
|
@ -79,7 +87,7 @@ in
|
|||
"firmware-oneplus-sdm845"
|
||||
"firmware-oneplus-sdm845-xz"
|
||||
];
|
||||
system.build.uboot = pkgs.ubootImageEnchilada;
|
||||
system.build.uboot = pkgs.ubootImage;
|
||||
boot.initrd.includeDefaultModules = false;
|
||||
boot.initrd.availableKernelModules = [
|
||||
"sd_mod"
|
||||
|
@ -187,7 +195,7 @@ in
|
|||
};
|
||||
|
||||
boot.initrd.extraUtilsCommands = ''
|
||||
copy_bin_and_libs ${pkgs.adbd}/bin/adbd
|
||||
copy_bin_and_libs ${hw.adbd}/bin/adbd
|
||||
cp -pv ${pkgs.glibc.out}/lib/libnss_files.so.* $out/lib
|
||||
'';
|
||||
|
||||
|
@ -222,7 +230,7 @@ in
|
|||
description = "adb daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.adbd}/bin/adbd";
|
||||
ExecStart = "${hw.adbd}/bin/adbd";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,7 @@ in {
|
|||
meta.license = lib.licenses.mit;
|
||||
};
|
||||
|
||||
alsa-ucm-conf-enchilada = pkgs.stdenvNoCC.mkDerivation {
|
||||
alsa-ucm-conf = pkgs.stdenvNoCC.mkDerivation {
|
||||
pname = "alsa-ucm-conf-enchilada";
|
||||
version = "unstable-2022-12-08";
|
||||
src = pkgs.fetchFromGitLab {
|
||||
|
@ -55,7 +55,7 @@ in {
|
|||
meta.priority = -10;
|
||||
};
|
||||
|
||||
ubootEnchilada = pkgs.buildUBoot {
|
||||
uboot = pkgs.buildUBoot {
|
||||
defconfig = "qcom_defconfig";
|
||||
version = "unstable-2023-12-11";
|
||||
src = pkgs.fetchFromGitLab {
|
||||
|
@ -73,7 +73,7 @@ in {
|
|||
filesToInstall = [ "u-boot-nodtb.bin" "u-boot-dtb.bin" "u-boot.dtb" ];
|
||||
};
|
||||
|
||||
ubootImageEnchilada = pkgs.stdenvNoCC.mkDerivation {
|
||||
ubootImage = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "u-boot-enchilada.img";
|
||||
nativeBuildInputs = [
|
||||
# available from mobile-nixos's overlay
|
||||
|
@ -97,13 +97,13 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
firmware-oneplus-sdm845 = pkgs.stdenvNoCC.mkDerivation {
|
||||
firmware = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "firmware-oneplus-sdm845";
|
||||
src = pkgs.fetchFromGitLab {
|
||||
owner = "sdm845-mainline";
|
||||
repo = "firmware-oneplus-sdm845";
|
||||
rev = "dc9c77f220d104d7224c03fcbfc419a03a58765e";
|
||||
hash = "sha256-jrbWIS4T9HgBPYOV2MqPiRQCxGMDEfQidKw9Jn5pgBI=";
|
||||
rev = "176ca713448c5237a983fb1f158cf3a5c251d775";
|
||||
hash = "sha256-ZrBvYO+MY0tlamJngdwhCsI1qpA/2FXoyEys5FAYLj4=";
|
||||
};
|
||||
installPhase = ''
|
||||
cp -a . "$out"
|
||||
|
@ -119,13 +119,13 @@ in {
|
|||
meta.license = lib.licenses.unfreeRedistributableFirmware;
|
||||
};
|
||||
|
||||
linux_enchilada = pkgs.linux_latest.override {
|
||||
linux = pkgs.linux_latest.override {
|
||||
# TODO: uncomment
|
||||
# ignoreConfigErrors = false;
|
||||
kernelPatches = [
|
||||
{
|
||||
name = "linux_6_8";
|
||||
patch = ./linux_6_8.patch;
|
||||
name = "linux_6_9";
|
||||
patch = ./linux_6_9.patch;
|
||||
}
|
||||
{
|
||||
name = "config_fixes";
|
||||
|
@ -627,5 +627,5 @@ in {
|
|||
XEN_PVHVM.tristate = lib.mkForce null; XEN_SAVE_RESTORE.tristate = lib.mkForce null; XEN_SYS_HYPERVISOR.tristate = lib.mkForce null;
|
||||
};
|
||||
};
|
||||
linux_enchilada_ccache = pkgs'.buildLinuxWithCcache pkgs'.linux_enchilada;
|
||||
linux_ccache = pkgs'.ccachePkgs.buildLinuxWithCcache pkgs'.hw.oneplus-enchilada.linux;
|
||||
}
|
||||
|
|
|
@ -167,6 +167,17 @@
|
|||
"nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
|
||||
];
|
||||
};
|
||||
nix.buildMachines = [
|
||||
{
|
||||
hostName = "darwin-build-box.nix-community.org";
|
||||
protocol = "ssh-ng";
|
||||
systems = [ "aarch64-darwin" "x86_64-darwin" ];
|
||||
supportedFeatures = inputs.nix-community-infra.darwinConfigurations.darwin01.config.nix.settings.system-features;
|
||||
sshKey = "/secrets/community-builder-key";
|
||||
sshUser = "chayleaf";
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUZ6OEZYU1ZFZGY4RnZETWZib3hoQjVWalNlN3kyV2dTYTA5cTFMNHQwOTkgCg==";
|
||||
}
|
||||
];
|
||||
services.udev.packages = [
|
||||
pkgs.android-udev-rules
|
||||
];
|
||||
|
|
|
@ -595,6 +595,10 @@ def add_split_domain(domains: Domains, split_domain: list[str]):
|
|||
if not split_domain:
|
||||
return
|
||||
split_domain = split_domain[:]
|
||||
if split_domain and split_domain[-1] == '*':
|
||||
split_domain.pop()
|
||||
if not split_domain:
|
||||
return
|
||||
while len(split_domain) > 1:
|
||||
key = split_domain[-1]
|
||||
if key in domains.keys():
|
||||
|
|
|
@ -296,6 +296,7 @@ in {
|
|||
{ ipAddress = lightBulbAddress6;
|
||||
macAddress = cfg.lightBulbMac; }
|
||||
{ ipAddress = serverInitrdAddress6;
|
||||
duid = cfg.serverInitrdDuid;
|
||||
macAddress = cfg.serverInitrdMac; }
|
||||
];
|
||||
|
||||
|
@ -414,6 +415,21 @@ in {
|
|||
};
|
||||
*/
|
||||
# ethernet wan
|
||||
router.tunnels.sittun0 = lib.mkIf (cfg.vpn.tunnel.mode == "sit") {
|
||||
mode = "sit";
|
||||
remote = cfg.vpn.tunnel.ip;
|
||||
local = cfg.vpn.tunnel.localIp;
|
||||
ttl = 255;
|
||||
};
|
||||
router.interfaces.sittun0 = lib.mkIf (cfg.vpn.tunnel.mode == "sit") {
|
||||
dependentServices = [
|
||||
(lib.mkIf cfg.vpn.wireguard.enable { service = "wireguard-${vpn_iface}"; inNetns = false; })
|
||||
(lib.mkIf cfg.vpn.openvpn.enable { service = "openvpn-client"; inNetns = false; })
|
||||
];
|
||||
ipv6.addresses = [ (router-lib.parseCidr cfg.vpn.tunnel.ifaceAddr) ];
|
||||
ipv6.routes = [ { extraArgs = [ "::/0" "dev" "sittun0" ]; } ];
|
||||
networkNamespace = "wan";
|
||||
};
|
||||
router.interfaces.wan = {
|
||||
dependentServices = [
|
||||
(lib.mkIf cfg.vpn.wireguard.enable { service = "wireguard-${vpn_iface}"; inNetns = false; })
|
||||
|
@ -580,20 +596,21 @@ in {
|
|||
[(is.eq ip6.daddr "@block6") (log "block6 ") drop]
|
||||
[(is.eq ip.saddr "@block4") (log "block4/s ") drop]
|
||||
[(is.eq ip6.saddr "@block6") (log "block6/s ") drop]
|
||||
# default to no vpn...
|
||||
[(mangle meta.mark wan_table)]
|
||||
# default to vpn...
|
||||
# # default to vpn...
|
||||
# [(mangle meta.mark vpn_table)]
|
||||
# ...but unvpn traffic to/from force_unvpn4/force_unvpn6
|
||||
# [(is.eq ip.daddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
||||
# [(is.eq ip6.daddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
||||
# [(is.eq ip.saddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
||||
# [(is.eq ip6.saddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
||||
# ...force vpn to/from force_vpn4/force_vpn6
|
||||
# (disable this if it breaks some sites)
|
||||
[(is.eq ip.daddr "@force_vpn4") (mangle meta.mark vpn_table)]
|
||||
[(is.eq ip6.daddr "@force_vpn6") (mangle meta.mark vpn_table)]
|
||||
[(is.eq ip.saddr "@force_vpn4") (mangle meta.mark vpn_table)]
|
||||
[(is.eq ip6.saddr "@force_vpn6") (mangle meta.mark vpn_table)]
|
||||
# ...but unvpn traffic to/from force_unvpn4/force_unvpn6
|
||||
[(is.eq ip.daddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
||||
[(is.eq ip6.daddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
||||
[(is.eq ip.saddr "@force_unvpn4") (mangle meta.mark wan_table)]
|
||||
[(is.eq ip6.saddr "@force_unvpn6") (mangle meta.mark wan_table)]
|
||||
# block requests to port 25 from hosts other than the server so they can't send mail pretending to originate from my domain
|
||||
# only do this for lans since traffic from other interfaces isn't forwarded to wan
|
||||
[(is.eq meta.iifname lanSet) (is.ne ether.saddr cfg.serverMac) (is.eq meta.l4proto (f: f.tcp)) (is.eq tcp.dport 25) (log "smtp ") drop]
|
||||
|
@ -701,12 +718,18 @@ in {
|
|||
];
|
||||
};
|
||||
router.networkNamespaces.wan = {
|
||||
sysctl = {
|
||||
"net.ipv4.conf.all.forwarding" = true;
|
||||
"net.ipv6.conf.all.forwarding" = true;
|
||||
};
|
||||
# this is the even more boring nftables config
|
||||
nftables.jsonRules = mkRules {
|
||||
nftables.jsonRules = let
|
||||
wans = [ "wan" ] ++ lib.optional (cfg.vpn.tunnel.mode == "sit") "sittun0";
|
||||
in mkRules {
|
||||
selfIp4 = netAddresses.netnsWan4;
|
||||
selfIp6 = netAddresses.netnsWan6;
|
||||
inherit wans;
|
||||
lans = [ "veth-wan-b" ];
|
||||
wans = [ "wan" ];
|
||||
netdevIngressWanRules = with notnft.dsl; with payload; [
|
||||
[(is.eq (fib (f: with f; [ saddr mark iif ]) (f: f.oif)) missing) (log "wan oif missing ") drop]
|
||||
];
|
||||
|
@ -717,10 +740,10 @@ in {
|
|||
rule4 = rule.target4; rule6 = rule.target6;
|
||||
in with notnft.dsl; with payload;
|
||||
lib.optionals (rule4 != null) [
|
||||
[ (is.eq meta.iifname "wan") (is.eq ip.protocol protocols) (is.eq th.dport rule.port)
|
||||
[ (is.eq meta.iifname (setIfNeeded wans)) (is.eq ip.protocol protocols) (is.eq th.dport rule.port)
|
||||
(if rule4.port == null then dnat.ip rule4.address else dnat.ip rule4.address rule4.port) ]
|
||||
] ++ lib.optionals (rule6 != null) [
|
||||
[ (is.eq meta.iifname "wan") (is.eq ip6.nexthdr protocols) (is.eq th.dport rule.port)
|
||||
[ (is.eq meta.iifname (setIfNeeded wans)) (is.eq ip6.nexthdr protocols) (is.eq th.dport rule.port)
|
||||
(if rule6.port == null then dnat.ip6 rule6.address else dnat.ip6 rule6.address rule6.port) ]
|
||||
])
|
||||
(builtins.filter (x: !x.inVpn && (x.tcp || x.udp)) cfg.dnatRules));
|
||||
|
@ -733,10 +756,10 @@ in {
|
|||
rule4 = rule.target4; rule6 = rule.target6;
|
||||
in with notnft.dsl; with payload;
|
||||
lib.optionals (rule4 != null) [
|
||||
[ (is.eq meta.iifname "wan") (is.eq meta.oifname "veth-wan-b") (is.eq ip.protocol protocols)
|
||||
[ (is.eq meta.iifname (setIfNeeded wans)) (is.eq meta.oifname "veth-wan-b") (is.eq ip.protocol protocols)
|
||||
(is.eq th.dport (if rule4.port != null then rule4.port else rule.port)) (is.eq ip.daddr rule4.address) masquerade ]
|
||||
] ++ lib.optionals (rule6 != null) [
|
||||
[ (is.eq meta.iifname "wan") (is.eq meta.oifname "veth-wan-b") (is.eq ip6.nexthdr protocols)
|
||||
[ (is.eq meta.iifname (setIfNeeded wans)) (is.eq meta.oifname "veth-wan-b") (is.eq ip6.nexthdr protocols)
|
||||
(is.eq th.dport (if rule6.port != null then rule6.port else rule.port)) (is.eq ip6.daddr rule6.address) masquerade ]
|
||||
])
|
||||
(builtins.filter (x: !x.inVpn && (x.tcp || x.udp) && dnatRuleMode x == "snat") cfg.dnatRules));
|
||||
|
@ -763,12 +786,26 @@ in {
|
|||
|
||||
# vpn socket is in wan namespace, meaning traffic gets sent through the wan namespace
|
||||
# vpn interface is in default namespace, meaning it can be used in the default namespace
|
||||
# networking.wireguard.interfaces.${vpn_iface} = cfg.vpn.wireguard.config // {
|
||||
# socketNamespace = "wan";
|
||||
# interfaceNamespace = "init";
|
||||
# };
|
||||
networking.wireguard.interfaces.${vpn_iface} = lib.mkIf cfg.vpn.wireguard.enable
|
||||
(cfg.vpn.wireguard.config // {
|
||||
socketNamespace = "wan";
|
||||
interfaceNamespace = "init";
|
||||
});
|
||||
|
||||
systemd.services.vpn-tunnel = {
|
||||
# see https://pavluk.org/blog/2022/01/26/nixos_router.html
|
||||
# (ipv6 doesn't work without this, for whatever reason)
|
||||
systemd.services.ping-ipv6 = {
|
||||
after = [ "network.target" "netns-wan.service" ];
|
||||
wants = [ "netns-wan.service" ];
|
||||
wantedBy = [ "default.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.iputils}/bin/ping -q ${netAddresses.netnsWan6}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "30s";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.vpn-tunnel = lib.mkIf (cfg.vpn.tunnel.mode == "ssh") {
|
||||
description = "VPN Tunnel";
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
|
@ -780,24 +817,23 @@ in {
|
|||
stopIfChanged = false;
|
||||
path = [ config.programs.ssh.package ];
|
||||
script = ''
|
||||
while true; do
|
||||
${config.programs.ssh.package}/bin/ssh \
|
||||
-i /secrets/vpn/sshtunnel.key \
|
||||
-L ${netAddresses.netnsWan4}:${toString cfg.vpn.tunnel.localPort}:127.0.0.1:${toString cfg.vpn.tunnel.remotePort} \
|
||||
-p ${toString cfg.vpn.tunnel.port} \
|
||||
-N -T -v \
|
||||
sshtunnel@${cfg.vpn.tunnel.ip}
|
||||
echo "Restarting..."
|
||||
sleep 10
|
||||
done
|
||||
${config.programs.ssh.package}/bin/ssh \
|
||||
-i /secrets/vpn/sshtunnel.key \
|
||||
-L ${netAddresses.netnsWan4}:${toString cfg.vpn.tunnel.localPort}:127.0.0.1:${toString cfg.vpn.tunnel.remotePort} \
|
||||
-p ${toString cfg.vpn.tunnel.port} \
|
||||
-N -T -v \
|
||||
${cfg.vpn.tunnel.user}@${cfg.vpn.tunnel.ip}
|
||||
'';
|
||||
serviceConfig = {
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
Type = "simple";
|
||||
NetworkNamespacePath = "/var/run/netns/wan";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.openvpn-client = lib.mkIf cfg.vpn.openvpn.enable {
|
||||
wantedBy = [ "nftables-netns-default.service" ];
|
||||
};
|
||||
services.openvpn.servers = lib.mkIf cfg.vpn.openvpn.enable {
|
||||
client.config = cfg.vpn.openvpn.config;
|
||||
};
|
||||
|
@ -874,6 +910,8 @@ in {
|
|||
unbound-python = pkgs.python3.withPackages (ps: with ps; [ pydbus dnspython requests pytricia nftables ]);
|
||||
in
|
||||
"${unbound-python}/${unbound-python.sitePackages}";
|
||||
# see https://github.com/NixOS/nixpkgs/pull/310514
|
||||
environment.GI_TYPELIB_PATH = "${lib.getLib pkgs.glib}/lib/girepository-1.0";
|
||||
environment.MDNS_ACCEPT_NAMES = "^(.*\\.)?local\\.$";
|
||||
# resolve retracker.local to whatever router.local resolves to
|
||||
# we can't add a local zone alongside using avahi resolver, so we have to use hacks like this
|
||||
|
@ -884,8 +922,8 @@ in {
|
|||
environment.NFT_QUERIES = "vpn:force_vpn4,force_vpn6;unvpn!:force_unvpn4,force_unvpn6;iot:allow_iot4,allow_iot6";
|
||||
serviceConfig.EnvironmentFile = "/secrets/unbound_env";
|
||||
# it needs to run after nftables has been set up because it sets up the sets
|
||||
after = [ "nftables-default.service" "avahi-daemon.service" ];
|
||||
wants = [ "nftables-default.service" "avahi-daemon.service" ];
|
||||
after = [ "nftables-netns-default.service" "avahi-daemon.service" ];
|
||||
wants = [ "nftables-netns-default.service" "avahi-daemon.service" ];
|
||||
# allow it to call nft
|
||||
serviceConfig.AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
serviceConfig.CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||
|
|
|
@ -7,7 +7,18 @@
|
|||
options.router-settings = {
|
||||
vpn = {
|
||||
tunnel = {
|
||||
enable = lib.mkEnableOption "VPN tunnel";
|
||||
mode = lib.mkOption {
|
||||
description = "tunnel mode";
|
||||
type = with lib.types; nullOr (enum [ "ssh" "sit" ]);
|
||||
};
|
||||
ifaceAddr = lib.mkOption {
|
||||
description = "interface cidr";
|
||||
type = router-lib.types.cidr;
|
||||
};
|
||||
localIp = lib.mkOption {
|
||||
description = "local ip";
|
||||
type = router-lib.types.ip;
|
||||
};
|
||||
localPort = lib.mkOption {
|
||||
description = "local port";
|
||||
type = lib.types.port;
|
||||
|
@ -18,13 +29,18 @@
|
|||
};
|
||||
ip = lib.mkOption {
|
||||
description = "remote ip";
|
||||
type = router-lib.types.ipv4;
|
||||
type = router-lib.types.ip;
|
||||
};
|
||||
port = lib.mkOption {
|
||||
description = "SSH port";
|
||||
type = lib.types.port;
|
||||
default = 22;
|
||||
};
|
||||
user = lib.mkOption {
|
||||
description = "SSH user";
|
||||
type = lib.types.str;
|
||||
default = "sshtunnel";
|
||||
};
|
||||
};
|
||||
openvpn.enable = lib.mkEnableOption "OpenVPN";
|
||||
openvpn.config = lib.mkOption {
|
||||
|
@ -54,6 +70,11 @@
|
|||
description = "server's mac address in initrd";
|
||||
type = lib.types.str;
|
||||
};
|
||||
serverInitrdDuid = lib.mkOption {
|
||||
description = "server's duid in initrd";
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
};
|
||||
vacuumMac = lib.mkOption {
|
||||
description = "robot vacuum's mac address";
|
||||
type = lib.types.str;
|
||||
|
|
|
@ -72,7 +72,7 @@ in {
|
|||
};
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
package = pkgs.nextcloud28;
|
||||
package = pkgs.nextcloud29;
|
||||
autoUpdateApps.enable = true;
|
||||
# TODO: use socket auth and remove the next line
|
||||
database.createLocally = false;
|
||||
|
|
|
@ -46,8 +46,6 @@ in {
|
|||
hashedPassword = cfg.hashedNoreplyPassword;
|
||||
sendOnly = true;
|
||||
};
|
||||
# TODO: remove when https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/issues/275 is fixed
|
||||
services.dovecot2.sieve.extensions = [ "fileinto" ];
|
||||
services.dovecot2.extraConfig =
|
||||
let
|
||||
passwd = builtins.toFile "dovecot2-local-passwd" ''
|
||||
|
|
|
@ -133,7 +133,7 @@ in {
|
|||
extraGroups = [ "wheel" ];
|
||||
};
|
||||
# nixos-hardware uses mkDefault here, so we use slightly higher priority
|
||||
services.xserver.libinput.enable = mkForceDefault (!cfg.minimal);
|
||||
services.libinput.enable = mkForceDefault (!cfg.minimal);
|
||||
programs.fuse.userAllowOther = true;
|
||||
# autologin once after boot
|
||||
# --skip-login means directly call login instead of first asking for username
|
||||
|
@ -190,6 +190,9 @@ in {
|
|||
})
|
||||
|
||||
(lib.mkIf (!cfg.minimal) {
|
||||
environment.systemPackages = with pkgs; [
|
||||
unixtools.xxd
|
||||
];
|
||||
hardware.pulseaudio.enable = false;
|
||||
services.pipewire = {
|
||||
enable = lib.mkDefault true;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue