diff --git a/packages/dpms/.gitignore b/packages/dpms/.gitignore new file mode 100644 index 0000000..3cceda5 --- /dev/null +++ b/packages/dpms/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ + +# Avoid committing pubspec.lock for library packages; see +# https://dart.dev/guides/libraries/private-files#pubspeclock. +pubspec.lock diff --git a/packages/dpms/LICENSE b/packages/dpms/LICENSE new file mode 100644 index 0000000..c4b6a63 --- /dev/null +++ b/packages/dpms/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Igor Demyanov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/dpms/analysis_options.yaml b/packages/dpms/analysis_options.yaml new file mode 100644 index 0000000..dee8927 --- /dev/null +++ b/packages/dpms/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/packages/dpms/lib/dpms.dart b/packages/dpms/lib/dpms.dart new file mode 100644 index 0000000..af63ee8 --- /dev/null +++ b/packages/dpms/lib/dpms.dart @@ -0,0 +1,2 @@ +export 'src/dpms_stub.dart' if (dart.library.io) 'src/dpms.dart' if (dart.library.js) 'src/dpms_web.dart'; +export 'src/power_mode.dart'; diff --git a/packages/dpms/lib/src/dpms.dart b/packages/dpms/lib/src/dpms.dart new file mode 100644 index 0000000..1ae3169 --- /dev/null +++ b/packages/dpms/lib/src/dpms.dart @@ -0,0 +1,42 @@ +import 'package:dpms/src/platform/flutterpi.dart'; +import 'package:dpms/src/power_mode.dart'; + +class Dpms { + final FlutterpiDPMS _service = FlutterpiDPMS.instance; + /* +https://github.com/torvalds/linux/blob/master/include/uapi/drm/drm_mode.h#L143 +/* bit compatible with the xorg definitions. */ +#define DRM_MODE_DPMS_ON 0 +#define DRM_MODE_DPMS_STANDBY 1 +#define DRM_MODE_DPMS_SUSPEND 2 +#define DRM_MODE_DPMS_OFF 3 +*/ + // ignore: constant_identifier_names + static const DRM_MODE_DPMS_ON = 0; + // ignore: constant_identifier_names + static const DRM_MODE_DPMS_OFF = 3; + bool isAvailable() { + if (_service.dpmsIsAvailable == null || _service.dpmsSetProperty == null) { + return false; + } + return true; + } + + void setMode(PowerMode state) { + if (_service.dpmsSetProperty != null) { + _service.dpmsSetProperty!(state == PowerMode.on ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); + } + return; + } + + PowerMode getMode() { + if (_service.dpmsGetProperty != null) { + final value = _service.dpmsGetProperty!(); + if (value == DRM_MODE_DPMS_ON) { + return PowerMode.on; + } + PowerMode.off; + } + return PowerMode.on; + } +} diff --git a/packages/dpms/lib/src/dpms_stub.dart b/packages/dpms/lib/src/dpms_stub.dart new file mode 100644 index 0000000..281b4a7 --- /dev/null +++ b/packages/dpms/lib/src/dpms_stub.dart @@ -0,0 +1,15 @@ +import 'package:dpms/src/power_mode.dart'; + +class Dpms { + bool isAvailable() { + throw UnimplementedError(); + } + + void setMode(PowerMode mode) { + throw UnimplementedError(); + } + + PowerMode getMode() { + throw UnimplementedError(); + } +} diff --git a/packages/dpms/lib/src/dpms_web.dart b/packages/dpms/lib/src/dpms_web.dart new file mode 100644 index 0000000..b1c811a --- /dev/null +++ b/packages/dpms/lib/src/dpms_web.dart @@ -0,0 +1,13 @@ +import 'package:dpms/src/power_mode.dart'; + +class Dpms { + bool isAvailable() { + return false; + } + + void setMode(PowerMode mode) {} + + PowerMode getMode() { + return PowerMode.on; + } +} diff --git a/packages/dpms/lib/src/platform/flutterpi.dart b/packages/dpms/lib/src/platform/flutterpi.dart new file mode 100644 index 0000000..2b113f8 --- /dev/null +++ b/packages/dpms/lib/src/platform/flutterpi.dart @@ -0,0 +1,57 @@ +import 'dart:ffi' as ffi; + +/* +uint32_t dpms_isAvailable(); +void dpms_setProperty(uint64_t value); +uint64_t dpms_getProperty(); +*/ + +typedef DpmsGetPropertyFuncType = ffi.Uint64 Function(); +typedef DpmsGetPropertyType = int Function(); + +typedef DpmsSetPropertyFuncType = ffi.Void Function(ffi.Uint64 value); +typedef DpmsSetPropertyType = void Function(int value); + +typedef DpmsIsAvailableFuncType = ffi.Uint32 Function(); +typedef DpmsIsAvailableType = int Function(); + +class FlutterpiDPMS { + final DpmsIsAvailableType? dpmsIsAvailable; + final DpmsGetPropertyType? dpmsGetProperty; + final DpmsSetPropertyType? dpmsSetProperty; + + FlutterpiDPMS._constructor({ + required this.dpmsIsAvailable, + required this.dpmsGetProperty, + required this.dpmsSetProperty, + }); + + factory FlutterpiDPMS._() { + final lib = ffi.DynamicLibrary.process(); + + try { + final dpmsIsAvailable = lib.lookupFunction("dpms_isAvailable"); + final dpmsGetProperty = lib.lookupFunction("dpms_getProperty"); + final dpmsSetProperty = lib.lookupFunction("dpms_setProperty"); + + return FlutterpiDPMS._constructor( + dpmsIsAvailable: dpmsIsAvailable, + dpmsGetProperty: dpmsGetProperty, + dpmsSetProperty: dpmsSetProperty, + ); + } on ArgumentError { + return FlutterpiDPMS._constructor( + dpmsIsAvailable: null, + dpmsGetProperty: null, + dpmsSetProperty: null, + ); + } + } + + static FlutterpiDPMS? _instance; + + static FlutterpiDPMS get instance { + _instance ??= FlutterpiDPMS._(); + return _instance!; + } +} diff --git a/packages/dpms/lib/src/power_mode.dart b/packages/dpms/lib/src/power_mode.dart new file mode 100644 index 0000000..56eb9ca --- /dev/null +++ b/packages/dpms/lib/src/power_mode.dart @@ -0,0 +1,4 @@ +enum PowerMode { + on, + off, +} diff --git a/packages/dpms/pubspec.yaml b/packages/dpms/pubspec.yaml new file mode 100644 index 0000000..b1c0bd8 --- /dev/null +++ b/packages/dpms/pubspec.yaml @@ -0,0 +1,13 @@ +name: dpms +description: Package for using DPMS (Display Power Management Signaling) on linux. +version: 1.0.0+1 +repository: https://github.com/ardera/flutter_packages + +environment: + sdk: '>=3.0.0 <4.0.0' + +dev_dependencies: + lints: ^3.0.0 + test: ^1.21.0 + + \ No newline at end of file