Skip to content

[WIP] Implement DPMS get/setValue (Screen Off/On for KMS) #478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

DisDis
Copy link
Contributor

@DisDis DisDis commented May 1, 2025

I added kms drm property set function.
The code is dirty, but it works.
Any suggestions for improvement?

It allows turn off/on screen.

For my case I use HDMI-0.
kmsprint -p
show:

Connector 0 (33) HDMI-A-1 (connected)
    EDID (1) = blob-id 678 len 256 (immutable)
    DPMS (2) = 0 (On) [On=0|Standby=1|Suspend=2|Off=3]
    TILE (4) = blob-id 0 (immutable)
    link-status (5) = 0 (Good) [Good=0|Bad=1]

Screen ON:

if (kmsDrmService.isAvailable()) {
  // DPMS (2) = 3 (Off) [On=0|Standby=1|Suspend=2|Off=3]
  kmsDrmService.setProperty(2, 0);
}

Screen OFF:

if (kmsDrmService.isAvailable()) {
  // DPMS (2) = 0 (On) [On=0|Standby=1|Suspend=2|Off=3]
  kmsDrmService.setProperty(2, 3);
}

Service:
static final KmsDrmService kmsDrmService = KmsDrmService();

/*
uint32_t KMS_DRM_isAvailable();

void KMS_DRM_setProperty(uint32_t propId, uint64_t value) ;

uint64_t KMS_DRM_getProperty(uint32_t propId);
*/

typedef KMS_DRM_setPropertyFuncType = ffi.Void Function(ffi.Uint32 propId, ffi.Uint64 value);
typedef KMS_DRM_setPropertyType = void Function(int propId, int value);

typedef KMS_DRM_isAvailableFuncType = ffi.Uint32 Function();
typedef KMS_DRM_isAvailableType = int Function();

class KmsDrmService {
  final _KmsDrmService _service = _KmsDrmService.instance;
  bool isAvailable() {
    if (_service.KMS_DRM_isAvailable == null || _service.KMS_DRM_isAvailable!() == 0) {
      return false;
    }
    return true;
  }

  void setProperty(int propId, int value) {
    if (_service.KMS_DRM_setProperty == null) {
      return;
    }
    _service.KMS_DRM_setProperty!(propId, value);
  }
}

class _KmsDrmService {
  final KMS_DRM_setPropertyType? KMS_DRM_setProperty;
  final KMS_DRM_isAvailableType? KMS_DRM_isAvailable;
  _KmsDrmService._constructor({required this.KMS_DRM_setProperty, required this.KMS_DRM_isAvailable});

  factory _KmsDrmService._() {
    final lib = ffi.DynamicLibrary.process();

    try {
      final KMS_DRM_setPropertyLFunc = lib.lookupFunction<KMS_DRM_setPropertyFuncType, KMS_DRM_setPropertyType>("KMS_DRM_setProperty");
      final KMS_DRM_isAvailableLFunc = lib.lookupFunction<KMS_DRM_isAvailableFuncType, KMS_DRM_isAvailableType>("KMS_DRM_isAvailable");

      return _KmsDrmService._constructor(
        KMS_DRM_setProperty: KMS_DRM_setPropertyLFunc,
        KMS_DRM_isAvailable: KMS_DRM_isAvailableLFunc,
      );
    } on ArgumentError {
      return _KmsDrmService._constructor(
        KMS_DRM_setProperty: null,
        KMS_DRM_isAvailable: null,
      );
    }
  }

  static _KmsDrmService? _instance;

  static _KmsDrmService get instance {
    if (_instance == null) {
      _instance = _KmsDrmService._();
    }

    return _instance!;
  }
}

@DisDis
Copy link
Contributor Author

DisDis commented May 1, 2025

@ardera
Copy link
Owner

ardera commented May 2, 2025

Thanks for the contribution @DisDis !

I think providing support for DPMS & backlight is definitely useful, but a generic way to set KMS properties might be a bit too powerful. It's very easy to shoot yourself in the foot with that and it can easily conflict with flutter-pi's modesetting.

Might be better to provide an abstraction specifically for DPMS (and/or backlight). Just a package where you can do something like:

void main() async {
  final dpms = await DPMS.getInstance(); // optionally allow passing the view id here, for multi-view

  await dpms.setMode(PowerMode.on);
  await Future.delayed(Duration(seconds: 5));
  await dpms.setMode(PowerMode.standby);

  // ...
}

For backlight, one could implement a platform interface for: https://github.com/aaassseee/screen_brightness/

Weston has its own little sub-library to help with backlight: https://gitlab.freedesktop.org/wayland/weston/-/blob/main/libweston/backend-drm/libbacklight.c, that could just be added to the flutter-pi source tree under third_party/libbacklight.

@DisDis
Copy link
Contributor Author

DisDis commented May 3, 2025

Hi @ardera.
I implemented get/setDPMSValue.
When this MR merge, I will start implement DPMS package in "flutter_packages"

@DisDis DisDis changed the title [MVP/WIP] add support kms drm property set [WIP] Implement DPMS get/setValue (Screen Off/On for KMS) May 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants