Skip to content

Commit 839fc8f

Browse files
committed
PipeWire.NET: .NET bindings for PipeWire
0 parents  commit 839fc8f

189 files changed

Lines changed: 9392 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# editorconfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
[*]
7+
insert_final_newline = true
8+
indent_style = space
9+
indent_size = 4
10+
trim_trailing_whitespace = true
11+
12+
[*{_AssemblyInfo.cs,.notsupported.cs,AsmOffsets.cs}]
13+
generated_code = true
14+
15+
[*.cs]
16+
csharp_new_line_before_open_brace = all
17+
csharp_new_line_before_else = true
18+
csharp_new_line_before_catch = true
19+
csharp_new_line_before_finally = true
20+
csharp_new_line_before_members_in_object_initializers = true
21+
csharp_new_line_before_members_in_anonymous_types = true
22+
csharp_new_line_between_query_expression_clauses = true
23+
csharp_indent_block_contents = true
24+
csharp_indent_braces = false
25+
csharp_indent_case_contents = true
26+
csharp_indent_case_contents_when_block = false
27+
csharp_indent_switch_labels = true
28+
csharp_indent_labels = one_less_than_current
29+
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion
30+
dotnet_style_qualification_for_field = false:suggestion
31+
dotnet_style_qualification_for_property = false:suggestion
32+
dotnet_style_qualification_for_method = false:suggestion
33+
dotnet_style_qualification_for_event = false:suggestion
34+
csharp_style_var_for_built_in_types = false:suggestion
35+
csharp_style_var_when_type_is_apparent = false:none
36+
csharp_style_var_elsewhere = false:suggestion
37+
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
38+
dotnet_style_predefined_type_for_member_access = true:suggestion
39+
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
40+
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
41+
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
42+
dotnet_naming_symbols.constant_fields.applicable_kinds = field
43+
dotnet_naming_symbols.constant_fields.required_modifiers = const
44+
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
45+
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
46+
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
47+
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
48+
dotnet_naming_symbols.static_fields.applicable_kinds = field
49+
dotnet_naming_symbols.static_fields.required_modifiers = static
50+
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
51+
dotnet_naming_style.static_prefix_style.required_prefix = s_
52+
dotnet_naming_style.static_prefix_style.capitalization = camel_case
53+
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
54+
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
55+
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
56+
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
57+
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
58+
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
59+
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
60+
csharp_using_directive_placement = outside_namespace:suggestion
61+
dotnet_sort_system_directives_first = true
62+
csharp_prefer_braces = true:silent
63+
csharp_prefer_static_local_function = true:suggestion
64+
csharp_style_prefer_switch_expression = true:suggestion
65+
dotnet_style_readonly_field = true:suggestion
66+
dotnet_style_object_initializer = true:suggestion
67+
dotnet_style_collection_initializer = true:suggestion
68+
dotnet_style_prefer_collection_expression = when_types_exactly_match
69+
dotnet_style_explicit_tuple_names = true:suggestion
70+
dotnet_style_coalesce_expression = true:suggestion
71+
dotnet_style_null_propagation = true:suggestion
72+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
73+
dotnet_style_prefer_auto_properties = true:suggestion
74+
csharp_prefer_simple_default_expression = true:suggestion
75+
csharp_style_expression_bodied_methods = true:silent
76+
csharp_style_expression_bodied_constructors = true:silent
77+
csharp_style_expression_bodied_operators = true:silent
78+
csharp_style_expression_bodied_properties = true:silent
79+
csharp_style_expression_bodied_indexers = true:silent
80+
csharp_style_expression_bodied_accessors = true:silent
81+
csharp_style_expression_bodied_lambdas = true:silent
82+
csharp_style_expression_bodied_local_functions = true:silent
83+
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
84+
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
85+
csharp_style_inlined_variable_declaration = true:suggestion
86+
csharp_style_throw_expression = true:suggestion
87+
csharp_style_conditional_delegate_call = true:suggestion
88+
csharp_space_after_cast = false
89+
csharp_space_after_colon_in_inheritance_clause = true
90+
csharp_space_after_comma = true
91+
csharp_space_after_dot = false
92+
csharp_space_after_keywords_in_control_flow_statements = true
93+
csharp_space_after_semicolon_in_for_statement = true
94+
csharp_space_around_binary_operators = before_and_after
95+
csharp_space_before_colon_in_inheritance_clause = true
96+
csharp_space_before_comma = false
97+
csharp_space_before_dot = false
98+
csharp_space_before_open_square_brackets = false
99+
csharp_space_before_semicolon_in_for_statement = false
100+
csharp_space_between_empty_square_brackets = false
101+
csharp_space_between_method_call_empty_parameter_list_parentheses = false
102+
csharp_space_between_method_call_name_and_opening_parenthesis = false
103+
csharp_space_between_method_call_parameter_list_parentheses = false
104+
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
105+
csharp_space_between_method_declaration_name_and_open_parenthesis = false
106+
csharp_space_between_method_declaration_parameter_list_parentheses = false
107+
csharp_space_between_parentheses = false
108+
csharp_space_between_square_brackets = false
109+
110+
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
111+
indent_size = 2
112+
113+
[*.{csproj,vbproj,proj,nativeproj,locproj}]
114+
charset = utf-8
115+
116+
[*.builds]
117+
indent_size = 2
118+
119+
[*.{xml,stylecop,resx,ruleset}]
120+
indent_size = 2
121+
122+
[*.{props,targets,config,nuspec}]
123+
indent_size = 2
124+
125+
[*.{yml,yaml}]
126+
indent_size = 2
127+
128+
[*.sh]
129+
end_of_line = lf
130+
[*.{cmd,bat}]
131+
end_of_line = crlf

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto eol=lf
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Bug report
2+
description: Report a problem with PipeWire.NET
3+
labels: [bug]
4+
body:
5+
- type: textarea
6+
id: what-happened
7+
attributes:
8+
label: What happened
9+
description: A clear description of the bug and what you expected instead.
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: repro
14+
attributes:
15+
label: Steps to reproduce
16+
description: Minimal code or steps that trigger the problem.
17+
validations:
18+
required: true
19+
- type: input
20+
id: package-version
21+
attributes:
22+
label: PipeWire.NET version
23+
placeholder: e.g. 0.1.0
24+
validations:
25+
required: true
26+
- type: input
27+
id: pipewire-version
28+
attributes:
29+
label: PipeWire version
30+
description: Output of `pipewire --version`.
31+
placeholder: e.g. 1.0.5
32+
validations:
33+
required: true
34+
- type: input
35+
id: dotnet-version
36+
attributes:
37+
label: .NET version
38+
placeholder: e.g. 10.0.100
39+
validations:
40+
required: true
41+
- type: input
42+
id: distro
43+
attributes:
44+
label: Distribution / kernel
45+
placeholder: e.g. Ubuntu 24.04, x86_64
46+
validations:
47+
required: false
48+
- type: textarea
49+
id: logs
50+
attributes:
51+
label: Logs
52+
description: Relevant exception or `PIPEWIRE_DEBUG=3` output, if any.
53+
render: shell
54+
validations:
55+
required: false

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
blank_issues_enabled: false
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Feature request
2+
description: Suggest an addition or change
3+
labels: [enhancement]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: Problem
9+
description: What are you trying to do that the library does not support today?
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: proposal
14+
attributes:
15+
label: Proposed solution
16+
description: What would the API or behaviour look like?
17+
validations:
18+
required: false

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Summary
2+
3+
<!-- What does this change and why? -->
4+
5+
## Checklist
6+
7+
- [ ] `dotnet build` is clean (warnings are errors)
8+
- [ ] `dotnet test --filter "TestCategory!=Integration"` passes
9+
- [ ] If the native surface changed, `generate/generate.sh` was re-run and the result committed
10+
- [ ] Public API changes are documented

.github/workflows/build.yml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: build
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches: [main]
7+
tags: ["v*"]
8+
pull_request:
9+
branches: [main]
10+
release:
11+
types: [published]
12+
13+
env:
14+
NuGetDirectory: ${{ github.workspace }}/nuget
15+
16+
jobs:
17+
build_and_test:
18+
name: Build, Test, and Pack
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- uses: actions/checkout@v6
23+
with:
24+
fetch-depth: 0 # MinVer needs full history
25+
26+
- name: Install PipeWire runtime + dev headers + libclang
27+
run: |
28+
sudo apt-get update -qq
29+
sudo apt-get install -y --no-install-recommends \
30+
libpipewire-0.3-0 \
31+
libpipewire-0.3-dev \
32+
libclang-dev \
33+
pkg-config
34+
35+
- uses: actions/setup-dotnet@v5
36+
with:
37+
# net11.0 target requires the .NET 11 preview SDK alongside the .NET 10 SDK.
38+
# global.json (rollForward latestMajor, allowPrerelease) then selects the 11 SDK,
39+
# which builds both the net10.0 and net11.0 target frameworks.
40+
dotnet-version: |
41+
10.0.x
42+
11.0.x
43+
44+
- name: Restore
45+
run: dotnet restore PipeWire.NET.slnx
46+
47+
- name: Build
48+
run: dotnet build PipeWire.NET.slnx --no-restore -c Release
49+
50+
- name: Test (non-integration on host runner)
51+
run: dotnet test PipeWire.NET.slnx --no-build -c Release
52+
--filter "TestCategory!=Integration"
53+
54+
- name: Install ClangSharpPInvokeGenerator + native runtime packages
55+
run: |
56+
dotnet tool install --global ClangSharpPInvokeGenerator --version 21.1.8.3
57+
# The dotnet tool packaging does not bundle libclang/libClangSharp;
58+
# pull matching native packages and let generate.sh point LD at them.
59+
mkdir -p /tmp/clangsharp-bootstrap
60+
cd /tmp/clangsharp-bootstrap
61+
dotnet new console -o dummy -n dummy --force
62+
cd dummy
63+
dotnet add package libclang.runtime.linux-x64 --version 21.1.8
64+
dotnet add package libClangSharp.runtime.linux-x64 --version 21.1.8
65+
66+
- name: Verify generated bindings are up to date
67+
run: |
68+
bash generate/generate.sh
69+
if ! git diff --quiet -- src/PipeWire.NET/generated/; then
70+
echo "::error::Generated bindings are out of date."
71+
echo "Run 'bash generate/generate.sh' locally and commit the result."
72+
git diff -- src/PipeWire.NET/generated/
73+
exit 1
74+
fi
75+
76+
- name: Run Linux integration tests (against installed runtime, no daemon required)
77+
run: dotnet test PipeWire.NET.slnx --no-build -c Release
78+
--filter "TestCategory=Integration&TestCategory!=RequiresDaemon"
79+
80+
- name: Daemon end-to-end tests (headless PipeWire + GStreamer real sources)
81+
# Non-gating: these exercise a real GStreamer -> PipeWire graph and pass in a proper
82+
# PipeWire session (e.g. a desktop or WSL), but GitHub's headless runners cannot
83+
# reliably host pipewiresink producers, so frames never arrive and the tests time out.
84+
# Kept for signal; run locally for authoritative end-to-end validation.
85+
continue-on-error: true
86+
run: |
87+
sudo apt-get install -y --no-install-recommends \
88+
pipewire wireplumber pipewire-bin \
89+
gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-pipewire
90+
export XDG_RUNTIME_DIR="$(mktemp -d)"
91+
pipewire & PW_PID=$!
92+
wireplumber & WP_PID=$!
93+
for i in $(seq 1 40); do pw-cli info 0 >/dev/null 2>&1 && break; sleep 0.25; done
94+
set +e
95+
dotnet test PipeWire.NET.slnx --no-build -c Release \
96+
--filter "TestCategory=RequiresDaemon&TestCategory!=RequiresGpu"
97+
RC=$?
98+
set -e
99+
kill $WP_PID $PW_PID 2>/dev/null || true
100+
exit $RC
101+
102+
- name: Pack
103+
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
104+
run: dotnet pack src/PipeWire.NET/PipeWire.NET.csproj --no-build -c Release -o ${{ env.NuGetDirectory }}
105+
106+
- name: Upload package artifact
107+
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
108+
uses: actions/upload-artifact@v7
109+
with:
110+
name: nuget-package
111+
if-no-files-found: error
112+
retention-days: 1
113+
path: ${{ env.NuGetDirectory }}/*.nupkg
114+
115+
publish_nuget:
116+
name: Publish NuGet Packages
117+
needs: [build_and_test]
118+
# Publishing runs only when a GitHub release is published (or manually dispatched), matching
119+
# the other Agash packages. Requires a NuGet.org trusted-publishing policy for this package.
120+
if: (github.event_name == 'release' && github.event.action == 'published') || github.event_name == 'workflow_dispatch'
121+
runs-on: ubuntu-latest
122+
permissions:
123+
contents: read
124+
id-token: write # OIDC for NuGet.org trusted publishing
125+
126+
steps:
127+
- name: Download package artifact
128+
uses: actions/download-artifact@v8
129+
with:
130+
name: nuget-package
131+
path: ${{ env.NuGetDirectory }}
132+
133+
- uses: actions/setup-dotnet@v5
134+
135+
- name: NuGet login (OIDC)
136+
id: login
137+
uses: NuGet/login@v1
138+
with:
139+
user: Agash
140+
141+
- name: Publish packages
142+
run: |
143+
for f in "${{ env.NuGetDirectory }}"/*.nupkg; do
144+
echo "Pushing $f"
145+
dotnet nuget push "$f" \
146+
--api-key "${{ steps.login.outputs.NUGET_API_KEY }}" \
147+
--source https://api.nuget.org/v3/index.json \
148+
--skip-duplicate
149+
done

.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## .NET
2+
bin/
3+
obj/
4+
*.user
5+
.vs/
6+
*.suo
7+
project.lock.json
8+
project.fragment.lock.json
9+
artifacts/
10+
11+
## NuGet
12+
*.nupkg
13+
*.snupkg
14+
nuget/
15+
16+
# VS/Rider per-user launch profiles
17+
**/Properties/launchSettings.json

0 commit comments

Comments
 (0)