Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/.vscode
/build
/extensions/nanoled/build
/extensions/grayscale/extension.so
/extensions/grayscale/extension.so
/examples/csharp/obj
/examples/csharp/bin
.claude/
CLAUDE.md
122 changes: 122 additions & 0 deletions examples/csharp/PanelPlayer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;
using System.IO;

namespace PanelPlayerExample
{
/// <summary>
/// Managed wrapper for PanelPlayer native library
/// </summary>
public class PanelPlayer : IDisposable
{
private bool disposed = false;

public PanelPlayer(string interfaceName, int width, int height, int brightness = 255)
{
int result = PanelPlayerNative.panelplayer_init(interfaceName, width, height, brightness);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to initialize PanelPlayer: {result}");
}
}

public void SetMix(int mixPercentage)
{
int result = PanelPlayerNative.panelplayer_set_mix(mixPercentage);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to set mix: {result}");
}
}

public void SetFrameRate(int frameRate)
{
int result = PanelPlayerNative.panelplayer_set_rate(frameRate);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to set frame rate: {result}");
}
}

public void SetDuplicate(bool enable)
{
int result = PanelPlayerNative.panelplayer_set_duplicate(enable);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to set duplicate mode: {result}");
}
}

public void LoadExtension(string extensionPath)
{
int result = PanelPlayerNative.panelplayer_load_extension(extensionPath);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to load extension: {result}");
}
}

public void PlayFile(string filePath)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"Image file not found: {filePath}");
}

int result = PanelPlayerNative.panelplayer_play_file(filePath);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to play image file: {result}");
}
}

public void PlayFrameBGR(byte[] bgrData, int width, int height)
{
if (bgrData == null)
{
throw new ArgumentNullException(nameof(bgrData));
}

if (bgrData.Length != width * height * 3)
{
throw new ArgumentException("BGR data length doesn't match width * height * 3");
}

int result = PanelPlayerNative.panelplayer_play_frame_bgr(bgrData, width, height);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to play frame: {result}");
}
}

public void SetBrightness(byte red, byte green, byte blue)
{
int result = PanelPlayerNative.panelplayer_send_brightness(red, green, blue);
if (result != PanelPlayerNative.PANELPLAYER_SUCCESS)
{
throw new Exception($"Failed to set brightness: {result}");
}
}

public bool IsInitialized => PanelPlayerNative.panelplayer_is_initialized();

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
PanelPlayerNative.panelplayer_cleanup();
disposed = true;
}
}

~PanelPlayer()
{
Dispose(false);
}
}
}
16 changes: 16 additions & 0 deletions examples/csharp/PanelPlayerExample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<None Update="../../build/libpanelplayer.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
69 changes: 69 additions & 0 deletions examples/csharp/PanelPlayerNative.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;
using System.Runtime.InteropServices;

namespace PanelPlayerExample
{
/// <summary>
/// Native P/Invoke declarations for libpanelplayer.so
/// </summary>
public static class PanelPlayerNative
{
private const string LibraryName = "libpanelplayer.so";

public const int PANELPLAYER_SUCCESS = 0;
public const int PANELPLAYER_ERROR = -1;
public const int PANELPLAYER_INVALID_PARAM = -2;
public const int PANELPLAYER_NOT_INITIALIZED = -3;
public const int PANELPLAYER_ALREADY_INITIALIZED = -4;

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_init(
[MarshalAs(UnmanagedType.LPStr)] string interface_name,
int width,
int height,
int brightness
);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_set_mix(int mix_percentage);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_set_rate(int frame_rate);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_set_duplicate(
[MarshalAs(UnmanagedType.I1)] bool enable
);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_load_extension(
[MarshalAs(UnmanagedType.LPStr)] string extension_path
);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_play_file(
[MarshalAs(UnmanagedType.LPStr)] string file_path
);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_play_frame_bgr(
[MarshalAs(UnmanagedType.LPArray)] byte[] bgr_data,
int width,
int height
);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern int panelplayer_send_brightness(
byte red,
byte green,
byte blue
);

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool panelplayer_is_initialized();

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
public static extern void panelplayer_cleanup();
}
}
Loading