falahati/NvAPIWrapper

Setting rotation for any display doesn't work

ogulzarinlighten opened this issue · 6 comments

Hi,

I have been using this API to write a small application to set the position, resolution and rotation of displays. It works perfectly fine when setting the position and resolution, BUT setting the rotation has no effect, all displays revert back to zero degrees as soon as the configuration is applied.

Can you share your code so I can take a look at it?

This is a console app, it read the display config, changes the rotation of each display to 90 degrees and then sets the config in the end, It works on one of the NVidia cards with two displays, but not on any other of my setups, although they have same version of driver and windows

`
using System;
using NvAPIWrapper;
using NvAPIWrapper.Display;

namespace NVidiaApp
{
class Program
{
static void Main(string[] args)
{
NVIDIA.Initialize();

        PathInfo[] pathInfoArr = PathInfo.GetDisplaysConfig();

        foreach (PathInfo info in pathInfoArr)
        {
            Console.WriteLine($"{info.Position}");
            Console.WriteLine($"{info.Resolution}");
            Console.WriteLine($"{info.IsGDIPrimary}");

            foreach(PathTargetInfo target in info.TargetsInfo)
            {
                Console.WriteLine($"{target.Rotation}");
                target.Rotation = NvAPIWrapper.Native.Display.Rotate.Degree90;
            }

            Console.WriteLine("");
        }

        Console.WriteLine("-----------------------------------");

        foreach (PathInfo info in pathInfoArr)
        {
            Console.WriteLine($"{info.Position}");
            Console.WriteLine($"{info.Resolution}");
            Console.WriteLine($"{info.IsGDIPrimary}");

            foreach (PathTargetInfo target in info.TargetsInfo)
            {
                Console.WriteLine($"{target.Rotation}");
            }

            Console.WriteLine("");
        }

        PathInfo.SetDisplaysConfig(pathInfoArr, NvAPIWrapper.Native.Display.DisplayConfigFlags.None);

        Console.ReadLine();
    }
}

}`

One more thing, when i tried the same thing using c++ API, it works on all my setups

I will take a look at this. but in the meanwhile, why not using a more general-purpose library?

My WindowsDisplayAPI library should be able to do this easily and with all GPU vendors since its only dependency is Windows's APIs themselves.

The code would be similar, but for better results; use the display config API instead of legacy at the root of the library.

If you decided to go with WindowsDisplayAPI, the following is an example that I just wrote for someone who wants to do the same thing:
falahati/WindowsDisplayAPI#15

The same thing using this library is possible with the following code:

NVIDIA.Initialize();

var paths = NvAPIWrapper.Display.PathInfo.GetDisplaysConfig();
var originalPaths = paths.ToArray();

for (int i = 0; i < paths.Length; i++)
{
    var path = paths[i];

    if (path.IsGDIPrimary)
    {
        continue;
    }

    paths[i] = new PathInfo(
        path.Resolution,
        path.ColorFormat,
        path.TargetsInfo.Select(
            (t) => new PathTargetInfo(t.DisplayDevice) {Rotation = Rotate.Degree180}
        ).ToArray()
    );
}

NvAPIWrapper.Display.PathInfo.SetDisplaysConfig(paths, DisplayConfigFlags.DriverReloadAllowed);
Console.WriteLine("Press 'Enter' to revert back.");
Console.ReadLine();
NvAPIWrapper.Display.PathInfo.SetDisplaysConfig(originalPaths, DisplayConfigFlags.DriverReloadAllowed);
NVIDIA.Unload();

As you can see, the code is almost identical.