Skip to content

Commit

Permalink
app: add CLI support
Browse files Browse the repository at this point in the history
  • Loading branch information
nomi-san committed Jun 19, 2024
1 parent 5137073 commit 6df9e86
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 7 deletions.
235 changes: 235 additions & 0 deletions app/CLI.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace ParsecVDisplay
{
internal static class CLI
{
static StreamWriter _stdOutWriter;

public static int Execute(string[] args)
{
AttachConsole(-1);

if (args.Length > 0)
{
try
{
switch (args[0])
{
case "add":
return AddDisplay();
case "remove":
return RemoveDisplay(args);
case "list":
return ListDisplay();
case "set":
return SetDisplayMode(args);
case "status":
return QueryDriverStatus();
case "version":
return QueryDriverVersion();
case "help":
ShowHelp();
return 0;
default:
Console.WriteLine("Invalid command '{0}'", args[0]);
ShowHelp();
return 0;
}
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
return -1;
}
finally
{
ParsecVDD.Uninit();
}
}
else
{
ShowHelp();
return 0;
}
}

static Device.Status PrepareVdd()
{
var status = ParsecVDD.QueryStatus();

if (status == Device.Status.NOT_INSTALLED)
{
throw new Exception("The driver is not found, please install it first");
}
else if (status != Device.Status.OK)
{
throw new Exception($"The driver is not OK, got status {status}");
}

if (!ParsecVDD.Init())
{
throw new Exception("Failed to obtain the driver device handle");
}

return status;
}

static void CheckAppRunning()
{
if (!EventWaitHandle.TryOpenExisting(Program.AppId, out var _))
{
throw new Exception($"{Program.AppName} app is not running");
}
}

static int AddDisplay()
{
var displays = ParsecVDD.GetDisplays();
if (displays.Count >= ParsecVDD.MAX_DISPLAYS)
{
throw new Exception(string.Format("Exceeded limit ({0}), could not add more displays", ParsecVDD.MAX_DISPLAYS));
}

PrepareVdd();
CheckAppRunning();

if (ParsecVDD.AddDisplay(out int index))
{
Console.WriteLine($"Added a virtual display with index {0}.", index);
return index;
}
else
{
throw new Exception("Failed to add a virtual display.");
}
}

static int RemoveDisplay(string[] args)
{
if (args.Length < 2)
throw new Exception("Missing display index.");

var arg1 = args[1];
bool removeAll = arg1 == "all" || arg1 == "*";
int index = -1;

if (removeAll || int.TryParse(arg1, out index))
{
var displays = ParsecVDD.GetDisplays();

if (displays.Count == 0)
{
Console.WriteLine("No Parsec Display available.");
return 0;
}
else if (removeAll)
{
PrepareVdd();
foreach (var di in displays)
{
if (!ParsecVDD.RemoveDisplay(di.DisplayIndex))
throw new Exception(string.Format("Failed to remove the display at index {0}.", index));
}
return 0;
}
else
{
var display = index == -1 ? displays.LastOrDefault()
: displays.FirstOrDefault(di => di.DisplayIndex == index);
if (display != null)
{
PrepareVdd();
if (!ParsecVDD.RemoveDisplay(index))
throw new Exception(string.Format("Failed to remove the display at index {0}.", index));
return 0;
}
else
{
throw new Exception(string.Format("Display index {0} is not found.", index));
}
}
}
else
{
throw new Exception(string.Format("Invalid display index '{0}'.", arg1));
}
}

static int ListDisplay()
{
var displays = ParsecVDD.GetDisplays();

if (displays.Count > 0)
{
foreach (var di in displays)
{
Console.WriteLine("Index: {0}", di.DisplayIndex);
Console.WriteLine(" - Device: {0}", di.DeviceName);
Console.WriteLine(" - Number: {0}", di.Identifier);
Console.WriteLine(" - Name: {0}", di.DisplayName);
Console.WriteLine(" - Mode: {0}", di.CurrentMode);
Console.WriteLine(" - Orientation: {0} ({1}°)", di.CurrentOrientation, (int)di.CurrentOrientation * 90);
}
}
else
{
Console.WriteLine("No Parsec Display available.");
}

return 0;
}

static int SetDisplayMode(string[] args)
{
// todo
throw new NotImplementedException();
}

static int QueryDriverStatus()
{
var status = ParsecVDD.QueryStatus();
Console.WriteLine("The driver status is {0}", status);

return (int)status;
}

static int QueryDriverVersion()
{
if (ParsecVDD.QueryVersion(out var version))
{
Console.WriteLine("{0} - v{1}", ParsecVDD.ADAPTER, version);
return 0;
}
else
{
throw new Exception("Failed to query the driver version.");
}
}

static void ShowHelp()
{
Console.WriteLine("vdd-cli [command] [args...]");
Console.WriteLine(" add - Add a virtual display");
Console.WriteLine(" remove X - Remove the virtual display at index X (number)");
Console.WriteLine(" -1 - Remove the last added virtual display");
Console.WriteLine(" all - Remove all the added virtual displays");
Console.WriteLine(" list - Show all the added virtual displays and specs");
Console.WriteLine(" set X WxH - Set resolution for a virtual display");
Console.WriteLine(" where X is index number, WxH is size, e.g 1920x1080");
Console.WriteLine(" X @R - Set only the refresh rate R, e.g @60, @120 (hz)");
Console.WriteLine(" X WxH@R - Set full display mode as above, e.g 1920x1080@144");
Console.WriteLine(" status - Query the driver status");
Console.WriteLine(" version - Query the driver version");
Console.WriteLine(" help - Show this help");
}

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AttachConsole(int dwProcessId);
}
}
10 changes: 5 additions & 5 deletions app/Display.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ internal class Display
{
public enum Orientation
{
Angle0 = 0, // landscape
Angle90, // portrait
Angle180, // landscape (flipped)
Angle270 // portrait (flipped)
Landscape = 0, // Angle0
Portrait, // Angle90
Landscape_Flipped, // Angle180
Portrait_Flipped // Angle270
}

public class Mode
Expand Down Expand Up @@ -81,7 +81,7 @@ public class ModeSet
Display()
{
ModeList = new List<Mode>();
CurrentOrientation = Orientation.Angle0;
CurrentOrientation = Orientation.Landscape;
SupportedResolutions = new List<ModeSet>();
}

Expand Down
4 changes: 4 additions & 0 deletions app/ParsecVDisplay.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
<PropertyGroup>
<StartupObject>ParsecVDisplay.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
Expand All @@ -72,6 +75,7 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="CLI.cs" />
<Compile Include="Components\Button.xaml.cs">
<DependentUpon>Button.xaml</DependentUpon>
</Compile>
Expand Down
13 changes: 11 additions & 2 deletions app/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
Expand All @@ -13,7 +14,7 @@ public static class Program
public const string GitHubRepo = "nomi-san/parsec-vdd";

[STAThread]
static void Main(string[] args)
static int Main(string[] args)
{
if (args.Length >= 2 && args[0] == "-custom")
{
Expand All @@ -28,7 +29,13 @@ static void Main(string[] args)
}
}

return;
return 0;
}

if (args.Length > 0 && args[0] == "-cli")
{
args = args.Skip(1).ToArray();
return CLI.Execute(args);
}

if (SingleInstance())
Expand All @@ -42,6 +49,8 @@ static void Main(string[] args)
ParsecVDD.Uninit();
}
}

return 0;
}

static bool SingleInstance()
Expand Down

0 comments on commit 6df9e86

Please sign in to comment.