diff -Nru ukui-framework-4.10.0.0/.gitignore ukui-framework-5.0.0.0/.gitignore --- ukui-framework-4.10.0.0/.gitignore 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/.gitignore 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,18 @@ +moc_* +*.o +*.so +*.qm +*.mo +*.pro.user +qrc_* +ui_* +Makefile +.vscode +.idea +build/ +debian/.debhelper/ +debian/debhelper-build-stamp +debian/files +debian/tmp/ +debian/source/format +CMakeLists.txt.user diff -Nru ukui-framework-4.10.0.0/CMakeLists.txt ukui-framework-5.0.0.0/CMakeLists.txt --- ukui-framework-4.10.0.0/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.5) +find_package(PkgConfig) +project(ukui-framework VERSION 1.0) + + +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus Widgets) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_subdirectory(dbus) + +include_directories(${CMAKE_INCLUDE_CURRENT_DIR}) +include_directories(dbus/devices/screen/src) +include_directories(dbus/devices/audio/src) +include_directories(dbus/devices/network/src) +include_directories(dbus/devices/bluetooth/src) +include_directories(dbus/devices/power/src) +include_directories(dbus/devices/touchpad/src) + +add_executable(ukui-framework + main.cpp +) + +target_link_libraries(ukui-framework + Qt5::Core + Qt5::Widgets + Qt5::DBus + screen + audio + network + bluetooth + power + touchpad) diff -Nru ukui-framework-4.10.0.0/common.h ukui-framework-5.0.0.0/common.h --- ukui-framework-4.10.0.0/common.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/common.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,73 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef COMMON_H +#define COMMON_H + +#endif // COMMON_H + +// ukui framework统一接口Dbus名称 +const QString DBUS_NAME = "org.ukui.Framework"; + +// 设备类相关的路径名称 +const QString DEVICES_PATH = "/org/ukui/Framework/Devices"; +const QString DEVICES_POWER_PATH = "/org/ukui/Framework/Devices/Power"; +const QString DEVICES_SCREEN_PATH = "/org/ukui/Framework/Devices/Screen"; +const QString DEVICES_BLUETOOTH_PATH = "/org/ukui/Framework/Devices/Bluetooth"; +const QString DEVICES_WIFI_PATH = "/org/ukui/Framework/Devices/WIFI"; +const QString DEVICES_TOUCHPAD_PATH = "/org/ukui/Framework/Devices/Touchpad"; +const QString DEVICES_AUDIO_PATH = "/org/ukui/Framework/Devices/Audio"; +const QString DEVICES_GEOLOCATION_PATH = "/org/ukui/Framework/Devices/Geolocation"; + +// APP相关路径名称 +const QString APP_PATH = "/org/ukui/Framework/APP"; +const QString APP_INFO_PATH = "/org/ukui/Framework/APP/INFO"; +const QString APP_MANAGER_PATH = "/org/ukui/Framework/APP/Manager"; + +// 文件相关路径名称 +const QString FILE_PATH = "/org/ukui/Framework/File"; +const QString FILE_INDEX_PATH = "/org/ukui/Framework/File/Index"; + +// UI相关的路径名称 +const QString UI_PATH = "/org/ukui/Framework/UI"; +const QString UI_THEME_PATH = "/org/ukui/Framework/UI/Theme"; +const QString UI_WALLPAPER_PATH = "/org/ukui/Framework/UI/Wallpaper"; +const QString UI_EFFECTS_PATH = "/org/ukui/Framework/UI/Effects"; + +// Media +const QString MEDIA_PATH = "/org/ukui/Framework/Media"; + +// Notifications +const QString NOTIFICATIONS_PATH = "/org/ukui/Framework/Notifications"; + +// Configurations +const QString CONFIGURATIONS_PATH = "/org/ukui/Framework/Configurations"; + +// Network +const QString NETWORK_PATH = "/org/ukui/Framework/Network"; + +// Navigations +const QString NAVIGATIONS_PATH = "/org/ukui/Framework/Navigations"; + +// ModeControl +const QString MODE_PATH = "/org/ukui/Framework/Mode"; + +// AI +const QString AI_PATH = "/org/ukui/Framework/AI"; + diff -Nru ukui-framework-4.10.0.0/dbus/CMakeLists.txt ukui-framework-5.0.0.0/dbus/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,5 @@ +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + +add_subdirectory(devices) + +aux_source_directory(SOURCES devices/README.md) diff -Nru ukui-framework-4.10.0.0/dbus/README.md ukui-framework-5.0.0.0/dbus/README.md --- ukui-framework-4.10.0.0/dbus/README.md 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/README.md 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,58 @@ +# devices 设备模块 + __模块说明:__ + 提供设备相关的接口,用于实现对设备的查询、操作等功能。根据功能分为以下几个模块: +## 电池模块(一期实现) + 提供电源信息查询以及电源配置操作 +## 屏幕模块(一期实现) +## 蓝牙模块(一期实现) +## wifi模块(一期实现) +## 打印机模块 +## 摄像头模块 +## 鼠标模块 +## 触摸板模块 +## USB模块 + +# 应用模块 +__说明:__ 应用模块提供应用相关的接口,用于实现对应用的查询、操作等功能。根据功能分为以下几个模块: +## 应用数据管理 + +## 应用进程管理 + +## 应用自启动管理 + +## 应用快捷方式管理 + +# 文件模块(命名待明确) +## 文件索引(搜索)管理 + +## 文件操作 + +## 元数据 + +# UI模块 +__说明:__ UI模块提供UI相关的接口,用于实现对UI的查询、操作等功能。根据功能分为以下几个模块: +主题模块 +特效模块 +壁纸模块 +## 主题模块(一期实现) + +## 特效模块(一期实现) + +## 壁纸模块(一期实现) + +# 通知模块 +__说明:__ 通知模块提供通知相关的接口,用于实现对通知的查询、操作等功能。根据功能分为以下几个模块: +## 系统通知 +## 状态通知 +## 角标通知 + +# 多媒体模块 +## mpris 统一入口服务 + +# 网络控制 + +# 权限管理 + +# 其他 +## 语言模块 +__说明:__ 语言模块提供语言、地区相关的接口,用于实现对语言的查询、操作等功能。根据功能分为以下几个模块: diff -Nru ukui-framework-4.10.0.0/dbus/devices/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,6 @@ +add_subdirectory(screen) +add_subdirectory(audio) +add_subdirectory(bluetooth) +add_subdirectory(network) +add_subdirectory(power) +add_subdirectory(touchpad) diff -Nru ukui-framework-4.10.0.0/dbus/devices/README.md ukui-framework-5.0.0.0/dbus/devices/README.md --- ukui-framework-4.10.0.0/dbus/devices/README.md 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/README.md 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,13 @@ +# 设备模块 + __模块说明:__ + 提供设备相关的接口,用于实现对设备的查询、操作等功能。根据功能分为以下几个模块: +## 电池模块(一期实现) + 提供电源信息查询以及电源配置操作 +## 屏幕模块(一期实现) +## 蓝牙模块(一期实现) +## wifi模块(一期实现) +## 打印机模块 +## 摄像头模块 +## 鼠标模块 +## 触摸板模块 +## USB模块 \ No newline at end of file diff -Nru ukui-framework-4.10.0.0/dbus/devices/audio/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/audio/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/audio/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/audio/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.5) +project(audio VERSION 1.0) + +find_package(PkgConfig) + +cmake_minimum_required(VERSION 3.16) +# 查找Qt5及其模块 +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + +SET(CMAKE_AUTOMOC ON) + +file(GLOB LIBAUDIO_SOURCES src/*.cpp) + +# 编译动态库 +add_library(audio STATIC ${LIBAUDIO_SOURCES}) + +target_link_libraries(audio + PRIVATE + Qt5::Core + Qt5::DBus + ${DEVICE_AUDIO_LINK}) diff -Nru ukui-framework-4.10.0.0/dbus/devices/audio/src/audio.cpp ukui-framework-5.0.0.0/dbus/devices/audio/src/audio.cpp --- ukui-framework-4.10.0.0/dbus/devices/audio/src/audio.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/audio/src/audio.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,239 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "audio.h" +#include "audio_define.h" + +Audio::Audio(QObject *parent): + QObject(parent) +{ + qInfo() << "Initializing Audio"; + initSignals(); +} + +Audio::~Audio() +{ + +} + +void Audio::initSignals() +{ + QDBusConnection::sessionBus().connect(UKUI_MEDIA_SERVICE, + UKUI_MEDIA_CONTROL_PATH, + QString(), + "updateVolume", + this, + SIGNAL(SinkVolumeChanged(int))); + + QDBusConnection::sessionBus().connect(UKUI_MEDIA_SERVICE, + UKUI_MEDIA_CONTROL_PATH, + QString(), + "updateMute", + this, + SIGNAL(SinkMuteChanged(bool))); + + QDBusConnection::sessionBus().connect(UKUI_MEDIA_SERVICE, + UKUI_MEDIA_CONTROL_PATH, + QString(), + "updateDevice", + this, + SIGNAL(SinkDeviceChanged(QString))); + + QDBusConnection::sessionBus().connect(UKUI_MEDIA_SERVICE, + UKUI_MEDIA_CONTROL_PATH, + QString(), + "updateSourceVolume", + this, + SIGNAL(SourceVolumeChanged(int))); + + QDBusConnection::sessionBus().connect(UKUI_MEDIA_SERVICE, + UKUI_MEDIA_CONTROL_PATH, + QString(), + "updateSourceMute", + this, + SIGNAL(SourceMuteChanged(bool))); + + QDBusConnection::sessionBus().connect(UKUI_MEDIA_SERVICE, + UKUI_MEDIA_CONTROL_PATH, + QString(), + "updateSourceDevice", + this, + SIGNAL(SourceDeviceChanged(QString))); +} + +int Audio::GetSinkVolume() +{ + QDBusReply<int> reply = callMedia("getDefaultOutputVolume"); + + if (!reply.isValid()) { + qWarning() << "Failed to get default output volume."; + return -1; + } + this->sinkVolume = reply.value(); + + return this->sinkVolume; +} + +bool Audio::GetSinkMute() +{ + QDBusReply<bool> reply = callMedia("getDefaultOutputMuteState"); + + if (!reply.isValid()) { + qWarning() << "Failed to get output mute state."; + return false; + } + this->sinkMute = reply.value(); + + return this->sinkMute; +} + +QString Audio::GetSinkDevice() +{ + QDBusReply<QString> reply = callMedia("getDefaultOutputDevice"); + + if (!reply.isValid()) { + qWarning() << "Failed to get output device."; + return "NULL"; + } + this->sinkDevice = reply.value(); + + return this->sinkDevice; +} + +int Audio::GetSourceVolume() +{ + QDBusReply<int> reply = callMedia("getDefaultInputVolume"); + + if (!reply.isValid()) { + qWarning() << "Failed to get output mute state."; + return -1; + } + this->sourceVolume = reply.value(); + + return this->sourceVolume; +} + +bool Audio::GetSourceMute() +{ + QDBusReply<bool> reply = callMedia("getDefaultInputMuteState"); + + if (!reply.isValid()) { + qWarning() << "Failed to get input mute state."; + return false; + } + this->sourceMute = reply.value(); + + return this->sourceMute; +} + +QString Audio::GetSourceDevice() +{ + QDBusReply<QString> reply = callMedia("getDefaultInputDevice"); + + if (!reply.isValid()) { + qWarning() << "Failed to get input device."; + return "NULL"; + } + this->sourceDevice = reply.value(); + + return this->sourceDevice; +} + +bool Audio::SetSinkVolume(int volume) +{ + QDBusReply<bool> reply = callMedia("setDefaultOutputVolume", volume); + + if (!reply.isValid()) { + qWarning() << "Failed to set output volume to" << volume; + return false; + } + + return reply.value(); +} + +bool Audio::SetSinkMute(bool mute) +{ + QDBusReply<bool> reply = callMedia("setDefaultOutputMuteState", mute); + + if (!reply.isValid()) { + qWarning() << "Failed to set output mute state to" << mute; + return false; + } + + return reply.value(); +} + +bool Audio::SetSinkDevice(QString device) +{ + QDBusReply<bool> reply = callMedia("setDefaultOutputDevice", device); + + if (!reply.isValid()) { + qWarning() << "Failed to set outputdevice to" << device; + return false; + } + + return reply.value(); +} + +bool Audio::SetSourceVolume(int volume) +{ + QDBusReply<bool> reply = callMedia("setDefaultInputVolume", volume); + + if (!reply.isValid()) { + qWarning() << "Failed to set input volume to" << volume; + return false; + } + + return reply.value(); +} + +bool Audio::SetSourceMute(bool mute) +{ + QDBusReply<bool> reply = callMedia("setDefaultInputMuteState", mute); + + if (!reply.isValid()) { + qWarning() << "Failed to set input mute state to" << mute; + return false; + } + + return reply.value(); +} + +bool Audio::SetSourceDevice(QString device) +{ + QDBusReply<bool> reply = callMedia("setDefaultInputDevice", device); + + if (!reply.isValid()) { + qWarning() << "Failed to set inputdevice to" << device; + return false; + } + + return reply.value(); +} + + +QDBusMessage Audio::callMedia(const QString &method, const QVariant &arg1, const QVariant &arg2) +{ + QDBusInterface mediaInterface(UKUI_MEDIA_SERVICE, + UKUI_MEDIA_PATH, + UKUI_MEDIA_INTERFACE); + + return mediaInterface.call(method, arg1, arg2); +} + diff -Nru ukui-framework-4.10.0.0/dbus/devices/audio/src/audio.h ukui-framework-5.0.0.0/dbus/devices/audio/src/audio.h --- ukui-framework-4.10.0.0/dbus/devices/audio/src/audio.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/audio/src/audio.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,170 @@ +#ifndef __AUDIO_H__ +#define __AUDIO_H__ + +#include <QObject> +#include <QDBusContext> +#include <QDBusConnection> +#include <QDBusConnectionInterface> +#include <QDBusInterface> +#include <QDBusPendingCall> +#include <QDBusReply> +#include <QDebug> +#include <QString> +#include <QDebug> + +class Audio : public QObject, QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.Devices.Audio") + + Q_PROPERTY(int SinkVolume READ GetSinkVolume WRITE SetSinkVolume NOTIFY SinkVolumeChanged) + Q_PROPERTY(bool SinkMute READ GetSinkMute WRITE SetSinkMute NOTIFY SinkMuteChanged) + Q_PROPERTY(QString SinkDevice READ GetSinkDevice WRITE SetSinkDevice NOTIFY SinkDeviceChanged) + + Q_PROPERTY(int SourceVolume READ GetSourceVolume WRITE SetSourceVolume NOTIFY SourceVolumeChanged) + Q_PROPERTY(bool SourceMute READ GetSourceMute WRITE SetSourceMute NOTIFY SourceMuteChanged) + Q_PROPERTY(QString SourceDevice READ GetSourceDevice WRITE SetSourceDevice NOTIFY SourceDeviceChanged) + +public: + explicit Audio(QObject *parent = nullptr); + ~Audio(); + + /** + * @brief initSignals 初始化dbus信号连接 + */ + void initSignals(); + +public slots: + /** + * @brief GetSinkVolume 获取系统输出设备的音量属性值 + * @return 音量值,范围0~100 + */ + int GetSinkVolume(); + + /** + * @brief GetSinkMute 获取系统输出设备的静音状态属性值 + * @return true:静音,false:未静音 + */ + bool GetSinkMute(); + + /** + * @brief GetSinkDevice 获取系统输出设备的设备名属性值 + * @return 系统输出设备的设备名属性值 + */ + QString GetSinkDevice(); + + /** + * @brief GetSourceVolume 获取系统输入设备的音量属性值 + * @return 音量值,范围0~100 + */ + int GetSourceVolume(); + + /** + * @brief GetSourceMute 获取系统输入设备的静音状态属性值 + * @return true:静音,false:未静音 + */ + bool GetSourceMute(); + + /** + * @brief GetSourceDevice 获取系统输入设备的设备名属性值 + * @return 系统输入设备的设备名属性值 + */ + QString GetSourceDevice(); + + + + /** + * @brief SetSinkVolume 设置系统输出设备音量 + * @param volume 音量值,范围0~100 + * @return 是否操作成功 true为成功 false为失败 + */ + bool SetSinkVolume(int volume); + + /** + * @brief SetSinkMute 设置系统输出设备静音状态 + * @param mute 静音状态,true为静音,false为取消静音 + * @return 是否操作成功 true为成功 false为失败 + */ + bool SetSinkMute(bool mute); + + /** + * @brief SetSinkDevice 设置系统输出设备 + * @param device 输出设备的名称 + * @return 是否操作成功 true为成功 false为失败 + */ + bool SetSinkDevice(QString device); + + /** + * @brief SetSourceVolume 设置系统输入设备音量 + * @param volume 音量值,范围0~100 + * @return 是否操作成功 true为成功 false为失败 + */ + bool SetSourceVolume(int volume); + + /** + * @brief SetSourceMute 设置系统输入设备静音状态 + * @param mute 静音状态,true为静音,false为取消静音 + * @return 是否操作成功 true为成功 false为失败 + */ + bool SetSourceMute(bool mute); + + /** + * @brief SetSourceDevice 设置系统输入设备 + * @param device 输入设备的名称 + * @return 是否操作成功 true为成功 false为失败 + */ + bool SetSourceDevice(QString device); + +private: + QDBusMessage callMedia(const QString &method, + const QVariant &arg1 = QVariant(), + const QVariant &arg2 = QVariant()); + +signals: + /** + * @brief sinkVolumeChanged 系统输出设备音量改变信号 + * @param volume 音量值,范围0~65536,使用(volume / 65536.0 * 100.0) + 0.5转换为范围0~100 + */ + void SinkVolumeChanged(int volume); + + /** + * @brief sinkMuteChanged 系统输出设备静音状态改变信号 + * @param mute 静音状态,true为静音,false为取消静音 + */ + void SinkMuteChanged(bool mute); + + /** + * @brief sinkDeviceChanged 系统输出设备改变信号 + * @param device 输出设备的名称 + */ + void SinkDeviceChanged(QString device); + + /** + * @brief sourceVolumeChanged 系统输入设备音量改变信号 + * @param volume 音量值,范围0~65536,使用(volume / 65536.0 * 100.0) + 0.5转换为范围0~100 + */ + void SourceVolumeChanged(int volume); + + /** + * @brief sourceMuteChanged 系统输入设备静音状态改变信号 + * @param mute 静音状态,true为静音,false为取消静音 + */ + void SourceMuteChanged(bool mute); + + /** + * @brief sourceDeviceChanged 系统输入设备改变信号 + * @param device 输入设备的名称 + */ + void SourceDeviceChanged(QString device); + +private: + int sinkVolume; + bool sinkMute; + QString sinkDevice; + + int sourceVolume; + bool sourceMute; + QString sourceDevice; +}; + +#endif /* __AUDIO_H__ */ diff -Nru ukui-framework-4.10.0.0/dbus/devices/audio/src/audio_define.h ukui-framework-5.0.0.0/dbus/devices/audio/src/audio_define.h --- ukui-framework-4.10.0.0/dbus/devices/audio/src/audio_define.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/audio/src/audio_define.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,12 @@ +#ifndef __AUDIO_DEFINE_H__ +#define __AUDIO_DEFINE_H__ + +#define UKUI_MEDIA_SERVICE "org.ukui.media" +#define UKUI_MEDIA_PATH "/org/ukui/media" +#define UKUI_MEDIA_INTERFACE "org.ukui.media" +#define UKUI_MEDIA_CONTROL_PATH "/org/ukui/media/control" + +#define PA_VOLUME_NORMAL 65536.0 +#define UKMEDIA_VOLUME_NORMAL 100.0 + +#endif /* __AUDIO_DEFINE_H__ */ diff -Nru ukui-framework-4.10.0.0/dbus/devices/audio/test/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/audio/test/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/audio/test/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/audio/test/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,23 @@ +project(my_qt_app) + +include_directories(../src) +find_package(PkgConfig) +cmake_minimum_required(VERSION 3.16) + +# 查找Qt5及其模块 +find_package(Qt5 COMPONENTS Core DBus) +# 接下来,你可以使用Qt5::Core, Qt5::DBus来链接你的可执行文件或库 + +set(CMAKE_AUTOMOC ON) + +# 示例:添加可执行文件 +add_executable(my_qt_app + test.cpp + ../src/audio.cpp) + +target_include_directories(my_qt_app PRIVATE) + +# 链接Qt模块 +target_link_libraries(my_qt_app + Qt5::Core + Qt5::DBus) diff -Nru ukui-framework-4.10.0.0/dbus/devices/audio/test/test.cpp ukui-framework-5.0.0.0/dbus/devices/audio/test/test.cpp --- ukui-framework-4.10.0.0/dbus/devices/audio/test/test.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/audio/test/test.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,113 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QDebug> +#include <QDBusError> +#include <QDBusConnection> +#include <QCoreApplication> + +#include "test.h" + +AudioTest::AudioTest(QObject *obj, QObject *parent): + QObject(parent), + m_Obj(obj) +{ + qInfo() << "Initializing AudioTest"; + initSignals(); +} + +void AudioTest::initSignals() +{ + QObject::connect(m_Obj,SIGNAL(sinkVolumeChanged(int)),this,SLOT(updateSinkVolume(int))); + QObject::connect(m_Obj,SIGNAL(sinkMuteChanged(bool)),this,SLOT(updateSinkMute(bool))); + QObject::connect(m_Obj,SIGNAL(sinkDeviceChanged(QString)),this,SLOT(updateSinkDevice(QString))); + QObject::connect(m_Obj,SIGNAL(sourceVolumeChanged(int)),this,SLOT(updateSourceVolume(int))); + QObject::connect(m_Obj,SIGNAL(sourceMuteChanged(bool)),this,SLOT(updateSourceMute(bool))); + QObject::connect(m_Obj,SIGNAL(sourceDeviceChanged(QString)),this,SLOT(updateSourceDevice(QString))); +} + +int AudioTest::paVolumeToValue(int volume) +{ + return (volume / PA_VOLUME_NORMAL * UKMEDIA_VOLUME_NORMAL) + 0.5; +} + +void AudioTest::updateSinkVolume(int volume) +{ + qInfo() << __func__ << paVolumeToValue(volume); +} + +void AudioTest::updateSinkMute(bool mute) +{ + qInfo() << __func__ << mute; +} + +void AudioTest::updateSinkDevice(QString device) +{ + qInfo() << __func__ << device; +} + +void AudioTest::updateSourceVolume(int volume) +{ + qInfo() << __func__ << paVolumeToValue(volume); +} + +void AudioTest::updateSourceMute(bool mute) +{ + qInfo() << __func__ << mute; +} + +void AudioTest::updateSourceDevice(QString device) +{ + qInfo() << __func__ << device; +} + +AudioTest::~AudioTest() +{ + qInfo() << "~AudioTest"; +} + + +/* + * 测试情况: + * getDefaultOutputVolume():通过 + * setDefaultOutputVolume(int volume):通过 + * getDefaultOutputMute():通过 + * setDefaultOutputMute(bool mute):通过 + * getDefaultInputVolume():通过 + * setDefaultInputVolume(int volume):通过 + * getDefaultInputMute():通过 + * setDefaultInputMute(bool mute):通过 + * +*/ +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc,argv); + Audio audio; + QDBusConnection sessionBug = QDBusConnection::sessionBus(); + if (sessionBug.registerService("org.ukui.mediaTest")) { + sessionBug.registerObject("/Audio", &audio, + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + } + + AudioTest test(&audio); + app.exec(); + + return 0; +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/audio/test/test.h ukui-framework-5.0.0.0/dbus/devices/audio/test/test.h --- ukui-framework-4.10.0.0/dbus/devices/audio/test/test.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/audio/test/test.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,65 @@ +#ifndef __TEST_H__ +#define __TEST_H__ + +#include "audio_define.h" +#include "audio.h" + +class AudioTest : public QObject +{ + Q_OBJECT + +public: + explicit AudioTest(QObject *obj, QObject *parent = nullptr); + void initSignals(); + + /** + * @brief paVolumeToValue 音量值转换成滑动条值 + * @param volume 音量值,范围0~65536 + * @return 音量值,范围0~100 + */ + int paVolumeToValue(int volume); + + ~AudioTest(); + +private: + QObject *m_Obj; + +public slots: + /** + * @brief updateSinkVolume 系统输出设备音量改变信号 + * @param volume 音量值,范围0~100 + */ + void updateSinkVolume(int volume); + + /** + * @brief updateSinkMute 系统输出设备静音状态改变信号 + * @param mute 静音状态,true为静音,false为取消静音 + */ + void updateSinkMute(bool mute); + + /** + * @brief updateSinkDevice 系统输出设备改变信号 + * @param device 输入设备的名称 + */ + void updateSinkDevice(QString device); + + /** + * @brief updateSourceVolume 系统输入设备音量改变信号 + * @param volume 音量值,范围0~100 + */ + void updateSourceVolume(int volume); + + /** + * @brief updateSourceMute 系统输入设备静音状态改变信号 + * @param mute 静音状态,true为静音,false为取消静音 + */ + void updateSourceMute(bool mute); + + /** + * @brief updateSourceDevice 系统输入设备改变信号 + * @param device 输入设备的名称 + */ + void updateSourceDevice(QString device); +}; + +#endif // TEST_H diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/bluetooth/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.5) +project(bluetooth VERSION 1.0) + +find_package(PkgConfig) + +cmake_minimum_required(VERSION 3.16) +# 查找Qt5及其模块 +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + +set(CMAKE_AUTOMOC ON) + +file(GLOB LIBBLUETOOTH_SOURCES src/*.cpp) + +add_library(bluetooth STATIC ${LIBBLUETOOTH_SOURCES}) + +target_link_libraries(bluetooth + PRIVATE + Qt5::Core + Qt5::DBus) diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/CSingleton.h ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/CSingleton.h --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/CSingleton.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/CSingleton.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023, KylinSoft Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * +**/ + +#ifndef CSINGLETON_H +#define CSINGLETON_H + + +template <typename T> +class SingleTon +{ +public: + // 创建单例实例 + template<typename... Args> + static T* instance(Args&&... args) + { + if (m_pInstance == nullptr) + { + m_pInstance = new T(std::forward<Args>(args)...); + } + + return m_pInstance; + } + + // 获取单例 + static T* getInstance() + { + return m_pInstance; + } + + // 删除单例 + static void destroyInstance() + { + delete m_pInstance; + m_pInstance = nullptr; + } + +private: + SingleTon(); + virtual ~SingleTon(); + +private: + static T* m_pInstance; +}; + +template <class T> +T* SingleTon<T>::m_pInstance = nullptr; + + +#endif diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth.cpp ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth.cpp --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,126 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bluetooth.h" +#include "bluetooth_dbussignal_monitor.h" +#include "bluetooth_define.h" + +Bluetooth::Bluetooth(QObject *parent /*= nullptr*/): + QObject(parent) +{ + qDebug() << "init Bluetooth"; + DBUSSINALMONITOR::instance(); + + QDBusConnection::sessionBus().connect(UKUIBLUETHHTH_DBUS_SERVER, + UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE, + "defaultAdapterPowerChanged", + this, SIGNAL(EnableChanged(bool))); +} + + Bluetooth::~Bluetooth(){ + qDebug() << "fini Bluetooth"; + + DBUSSINALMONITOR::destroyInstance(); +} + + +bool Bluetooth::SetDeviceState(QString device, bool enable){ + qInfo() << device << enable; + + this->setDelayedReply(true); + + auto msg = this->message(); + auto con = this->connection(); + + QList<QVariant> args; + QMap<QString, QVariant> arg; + arg["Powered"] = enable; + args.append(arg); + + QDBusPendingCallWatcher * watch = this->__ukuibluetooth_dbus_call("setDefaultAdapterAttr", args); + connect(watch, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *self){ + QDBusMessage reply = self->reply(); + if(reply.type() == QDBusMessage::ReplyMessage) { + auto r = msg.createReply(reply.arguments()); + con.send(r); + } else { + auto r = msg.createErrorReply(reply.errorName(), reply.errorMessage()); + con.send(r); + } + }); + + return true; +} + +QStringList Bluetooth::GetAllDevices(void) +{ + this->setDelayedReply(true); + + auto msg = this->message(); + auto con = this->connection(); + QList<QVariant> args; + + QDBusPendingCallWatcher * watch = this->__ukuibluetooth_dbus_call("getAllAdapterAddress", args); + connect(watch, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *self){ + QDBusMessage reply = self->reply(); + if(reply.type() == QDBusMessage::ReplyMessage) { + auto r = msg.createReply(reply.arguments()); + con.send(r); + } else { + auto r = msg.createErrorReply(reply.errorName(), reply.errorMessage()); + con.send(r); + } + watch->deleteLater(); + }); + + return QStringList(); +} + +void Bluetooth::Enable(bool enable) +{ + callBlueToothDbus("setDefaultAdapterPower", enable); +} + +bool Bluetooth::IsEnable() +{ + QDBusReply<bool> reply = callBlueToothDbus("getDefaultAdapterPower"); + if (reply.isValid()) { + return reply.value(); + } + + return false; +} + +QDBusPendingCallWatcher * Bluetooth::__ukuibluetooth_dbus_call(const QString & method, const QList<QVariant> & args) +{ + QDBusInterface iface(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, UKUIBLUETHHTH_DBUS_INTERFACE, QDBusConnection::systemBus()); + QDBusPendingCallWatcher * watch = new QDBusPendingCallWatcher(iface.asyncCallWithArgumentList(method, args), this); + return watch; +} + +template<typename ...Args> +QDBusMessage Bluetooth::callBlueToothDbus(const QString &method, Args &&...args) +{ + QDBusInterface inputManagerInterface(UKUIBLUETHHTH_DBUS_SERVER, + UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE); + + return inputManagerInterface.call(method, std::forward<Args>(args)...); +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth.h ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth.h --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,70 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __BLUETOOTH_H__ +#define __BLUETOOTH_H__ + +#include <QObject> +#include <QDBusContext> +#include <QDBusConnection> +#include <QDBusConnectionInterface> +#include <QDBusInterface> +#include <QDBusPendingCall> +#include <QDBusReply> +#include <QDebug> +#include <QString> +#include <QStringList> + +#include "CSingleton.h" + +/* + 现主线系统仅能使用一个蓝牙适配器,因此仅能设置默认蓝牙适配器; + 暂未适配使用多个蓝牙适配器; + 使用无阻塞方式调用和获取其他dbus服务提供的接口,防止线程长时间阻塞; +*/ +class Bluetooth: public QObject, QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.Devices.Bluetooth") +protected: + explicit Bluetooth(QObject *parent = nullptr); + virtual ~Bluetooth(); + +public Q_SLOTS: + bool SetDeviceState(QString device, bool enable); + + QStringList GetAllDevices(void); + + void Enable(bool enable); + bool IsEnable(); + +Q_SIGNALS: + void EnableChanged(bool v); + +private: + QDBusPendingCallWatcher * __ukuibluetooth_dbus_call(const QString & method, const QList<QVariant> & args); + friend class SingleTon<Bluetooth>; + + template <typename...Args> + QDBusMessage callBlueToothDbus(const QString &method, Args &&...args); +}; + +typedef SingleTon<Bluetooth> BLUETOOTHDBUS; +#endif + diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.cpp ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.cpp --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,183 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "bluetooth_dbussignal_monitor.h" +#include <QDebug> + +#include "bluetooth.h" +#include "bluetooth_define.h" + +DbusSignalMonitor::DbusSignalMonitor(QObject *parent /*= nullptr*/) +{ + qDebug() << "init DbusSignalMonitor"; + + this->init(); +} + +DbusSignalMonitor::~DbusSignalMonitor() +{ + qDebug() << "fini DbusSignalMonitor"; + + this->fini(); +} + +int DbusSignalMonitor::init(void) +{ + QDBusConnection::systemBus().connect(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE, "adapterAddSignal", this, + SLOT(adapterAddSignal(QMap<QString, QVariant>))); + + QDBusConnection::systemBus().connect(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE, "adapterAttrChanged", this, + SLOT(adapterAttrChanged(QString, QMap<QString, QVariant>))); + + QDBusConnection::systemBus().connect(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE, "adapterRemoveSignal", this, + SLOT(adapterRemoveSignal(QString))); + + return 0; +} + +int DbusSignalMonitor::fini(void) +{ + QDBusConnection::systemBus().disconnect(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE, "adapterAddSignal", this, + SLOT(adapterAddSignal(QMap<QString, QVariant>))); + + QDBusConnection::systemBus().disconnect(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE, "adapterAttrChanged", this, + SLOT(adapterAttrChanged(QString, QMap<QString, QVariant>))); + + QDBusConnection::systemBus().disconnect(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, + UKUIBLUETHHTH_DBUS_INTERFACE, "adapterRemoveSignal", this, + SLOT(adapterRemoveSignal(QString))); + + return 0; +} + +void DbusSignalMonitor::adapterAddSignal(QMap<QString, QVariant> attrs) +{ + qDebug() << "adapterAddSignal" << attrs; + + QString device; + bool DefaultAdapter = false; + bool power = false; + + QString key = "DefaultAdapter"; + if(attrs.contains(key) && attrs[key].type() == QVariant::Bool) { + DefaultAdapter = attrs[key].toBool(); + } + + key = "Powered"; + if(attrs.contains(key) && attrs[key].type() == QVariant::Bool) { + power = attrs[key].toBool(); + } else { + return; + } + + key = "Addr"; + if(attrs.contains(key) && attrs[key].type() == QVariant::String) { + device = attrs[key].toString(); + } else { + return; + } + + if (DefaultAdapter) { + m_defaultAdapter = device; + qDebug() << "send enableChanged" << power; + emit BLUETOOTHDBUS::getInstance()->EnableChanged(power); + } + + return; +} + +void DbusSignalMonitor::adapterAttrChanged(QString device, QMap<QString, QVariant> attrs) +{ + qDebug() << "adapterAttrChanged" << device << attrs; + + QString key; + bool DefaultAdapter = false; + bool power = false; + + if (device == m_defaultAdapter) { + DefaultAdapter = true; + } + + key = "DefaultAdapter"; + if(attrs.contains(key) && attrs[key].type() == QVariant::Bool) { + DefaultAdapter = attrs[key].toBool(); + if (DefaultAdapter) + m_defaultAdapter = device; + else if ( DefaultAdapter == device) { + m_defaultAdapter = ""; + } + } + + key = "Powered"; + if(attrs.contains(key) && attrs[key].type() == QVariant::Bool) { + power = attrs[key].toBool(); + } else { + return; + } + + if (DefaultAdapter) { + qDebug() << "send enableChanged" << power; + emit BLUETOOTHDBUS::getInstance()->EnableChanged(power); + return; + } + + if (m_defaultAdapter.isEmpty()) { + QList<QVariant> args; + args.append(device); + args.append(""); + QDBusPendingCallWatcher * watch = this->__ukuibluetooth_dbus_call("getAdapterAttr", args); + connect(watch, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *self){ + QDBusMessage reply = self->reply(); + if(reply.type() == QDBusMessage::ReplyMessage) { + QMap<QString, QVariant> replyattrs = (QDBusReply<QMap<QString, QVariant>>)reply; + qDebug() << reply; + QString key = "DefaultAdapter"; + if(replyattrs.contains(key) && replyattrs[key].type() == QVariant::Bool + && replyattrs[key].toBool()) { + qDebug() << "send enableChanged" << power; + m_defaultAdapter = device; + emit BLUETOOTHDBUS::getInstance()->EnableChanged(power); + } + + } + }); + } + + return; +} + +void DbusSignalMonitor::adapterRemoveSignal(QString dev) +{ + qDebug() << "adapterRemoveSignal" << dev; + if ( m_defaultAdapter == dev) { + m_defaultAdapter = ""; + } +} + +QDBusPendingCallWatcher * DbusSignalMonitor::__ukuibluetooth_dbus_call(const QString & method, const QList<QVariant> & args) +{ + QDBusInterface iface(UKUIBLUETHHTH_DBUS_SERVER, UKUIBLUETHHTH_DBUS_OBJECT, UKUIBLUETHHTH_DBUS_INTERFACE, QDBusConnection::systemBus()); + QDBusPendingCallWatcher * watch = new QDBusPendingCallWatcher(iface.asyncCallWithArgumentList(method, args), this); + return watch; +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.h ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.h --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth_dbussignal_monitor.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,59 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __BLUETOOTH_DBUSSIGNAL_MONITOR_H__ +#define __BLUETOOTH_DBUSSIGNAL_MONITOR_H__ + + +#include <QObject> +#include <QString> +#include <QMap> + +#include "CSingleton.h" + +class QDBusPendingCallWatcher; + +class DbusSignalMonitor : public QObject +{ + Q_OBJECT +protected: + explicit DbusSignalMonitor(QObject *parent = nullptr); + virtual ~DbusSignalMonitor(); + +protected: + int init(void); + + int fini(void); + +protected slots: + void adapterAddSignal(QMap<QString, QVariant>); + void adapterAttrChanged(QString, QMap<QString, QVariant>); + void adapterRemoveSignal(QString); + +private: + QDBusPendingCallWatcher * __ukuibluetooth_dbus_call(const QString & method, const QList<QVariant> & args); + +private: + QString m_defaultAdapter; + + friend class SingleTon<DbusSignalMonitor>; +}; +typedef SingleTon<DbusSignalMonitor> DBUSSINALMONITOR; + +#endif \ No newline at end of file diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth_define.h ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth_define.h --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/src/bluetooth_define.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/src/bluetooth_define.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,32 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __BLUETOOTH_DEFINE_H__ +#define __BLUETOOTH_DEFINE_H__ + + +#define UKUIBLUETHHTH_DBUS_SERVER "com.ukui.bluetooth" +#define UKUIBLUETHHTH_DBUS_OBJECT "/com/ukui/bluetooth" +#define UKUIBLUETHHTH_DBUS_INTERFACE "com.ukui.bluetooth" + + + + + +#endif \ No newline at end of file diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/test/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/bluetooth/test/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/test/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/test/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,24 @@ +project(my_qt_app) + +find_package(PkgConfig) + +include_directories(../src) +cmake_minimum_required(VERSION 3.16) +# 查找Qt5及其模块 +find_package(Qt5 COMPONENTS Core DBus REQUIRED) + +# 接下来,你可以使用Qt5::Core, Qt5::Widgets, Qt5::DBus来链接你的可执行文件或库 +set(CMAKE_AUTOMOC ON) + +# 示例:添加可执行文件 +add_executable(my_qt_app + test.cpp + ../src/bluetooth.cpp ../src/bluetooth_dbussignal_monitor.cpp + ) + +target_include_directories(my_qt_app PRIVATE) + +# 链接Qt模块 +target_link_libraries(my_qt_app + Qt5::Core + Qt5::DBus) diff -Nru ukui-framework-4.10.0.0/dbus/devices/bluetooth/test/test.cpp ukui-framework-5.0.0.0/dbus/devices/bluetooth/test/test.cpp --- ukui-framework-4.10.0.0/dbus/devices/bluetooth/test/test.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/bluetooth/test/test.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,57 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QCoreApplication> +#include <QObject> +#include <QDBusContext> +#include <QDBusConnection> +#include <QDBusConnectionInterface> +#include <QDBusInterface> +#include <QDBusPendingCall> +#include <QDBusReply> +#include <QDebug> +#include <QString> +#include <QStringList> +#include <QTimer> + +#include "bluetooth.h" + + +/* + * 测试情况: + * setDeviceState(): 通过 + * getAllDevices():通过 + * enable():通过 + * +*/ + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc,argv); + + BLUETOOTHDBUS::instance(); + + QDBusConnection sessionBug = QDBusConnection::sessionBus(); + if (sessionBug.registerService("org.ukui.bluetooth.test")) { + sessionBug.registerObject("/bluetooth", BLUETOOTHDBUS::getInstance(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals); + } + app.exec(); + return 0; +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/network/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/network/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/network/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/network/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.5) +project(network VERSION 1.0) + +find_package(PkgConfig) + +cmake_minimum_required(VERSION 3.16) +# 查找Qt5及其模块 +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + +# 索引动态库的头文件地址 +include_directories(${GOBJECT_INCLUDE_DIRS}) + +set(CMAKE_AUTOMOC ON) + +file(GLOB LIBNETWORK_SOURCES src/*.cpp) + +add_library(network STATIC ${LIBNETWORK_SOURCES}) + +target_link_libraries(network + PRIVATE + Qt5::Core + Qt5::Widgets + Qt5::DBus) diff -Nru ukui-framework-4.10.0.0/dbus/devices/network/src/network.cpp ukui-framework-5.0.0.0/dbus/devices/network/src/network.cpp --- ukui-framework-4.10.0.0/dbus/devices/network/src/network.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/network/src/network.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,116 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "network.h" +#include "network_common.h" + +Network::Network(QObject *parent) : + QObject(parent) +{ + QDBusConnection::sessionBus().connect(KYLIN_NM_DBUS_SERVER, + KYLIN_NM_DBUS_PATH, + KYLIN_NM_DBUS_INTERFACE, + "wirelessSwitchBtnChanged", + this, SIGNAL(EnableChanged(bool))); +} + +Network::~Network(){ + +} + +QDBusPendingCallWatcher * Network::__network_dbus_call(const QString & method, const QList<QVariant> & args) +{ + QDBusInterface iface(KYLIN_NM_DBUS_SERVER, KYLIN_NM_DBUS_PATH, KYLIN_NM_DBUS_INTERFACE, QDBusConnection::sessionBus()); + QDBusPendingCallWatcher * watch = new QDBusPendingCallWatcher(iface.asyncCallWithArgumentList(method, args), this); + return watch; +} + +bool Network::SetDeviceState(QString device, bool enable){ + Q_UNUSED(device) + + this->setDelayedReply(true); + + auto msg = this->message(); + auto con = this->connection(); + + QList<QVariant> args; + args.append(enable); + + QDBusPendingCallWatcher * watch = this->__network_dbus_call("setWirelessSwitchEnable", args); + connect(watch, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *self){ + QDBusMessage reply = self->reply(); + if(reply.type() == QDBusMessage::ReplyMessage) { + auto r = msg.createReply(reply.arguments()); + con.send(r); + } else { + auto r = msg.createErrorReply(reply.errorName(), reply.errorMessage()); + con.send(r); + } + watch->deleteLater(); + }); + + return true; +} + +bool Network::IsEnable() +{ + QDBusReply<bool> reply = callNetworkMethod("getWirelessSwitchBtnState"); + if (false == reply.isValid()) { + sendErrorReply(QDBusError::ErrorType::Failed,QString("ukui-framework dbus method call failed.")); + } + return reply.value(); +} + +QStringList Network::GetAllDevices(void) +{ + this->setDelayedReply(true); + + auto msg = this->message(); + auto con = this->connection(); + QList<QVariant> args; + + QDBusPendingCallWatcher * watch = this->__network_dbus_call("getWirelessDeviceCap", args); + connect(watch, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *self){ + QDBusMessage reply = self->reply(); + if(reply.type() == QDBusMessage::ReplyMessage) { + QDBusReply<QVariantMap> retMap = reply; + auto r = msg.createReply(QVariant(retMap.value().keys())); + con.send(r); + } else { + auto r = msg.createErrorReply(reply.errorName(), reply.errorMessage()); + con.send(r); + } + }); + return QStringList(); +} + +void Network::Enable(bool enable) +{ + QList<QVariant> args; + args.append(enable); + + this->__network_dbus_call("setWirelessSwitchEnable", args); +} + +template<typename ...Args> +QDBusMessage Network::callNetworkMethod(const QString &method, Args &&...args) +{ + QDBusInterface iface(KYLIN_NM_DBUS_SERVER, KYLIN_NM_DBUS_PATH, KYLIN_NM_DBUS_INTERFACE, QDBusConnection::sessionBus()); + + return iface.call(method, std::forward<Args>(args)...); +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/network/src/network.h ukui-framework-5.0.0.0/dbus/devices/network/src/network.h --- ukui-framework-4.10.0.0/dbus/devices/network/src/network.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/network/src/network.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,70 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef NETWORK_H +#define NETWORK_H + +#include <QObject> +#include <QDBusContext> +#include <QDBusConnection> +#include <QDBusConnectionInterface> +#include <QDBusInterface> +#include <QDBusPendingCall> +#include <QDBusReply> +#include <QDebug> +#include <QString> +#include <QStringList> + +/* + 现主线系统不支持多网卡开关操作,因此仅能使用无线网络总开关; + 使用无阻塞方式调用和获取其他dbus服务提供的接口,防止线程长时间阻塞; +*/ +class Network : public QObject, QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.Devices.WIFI") +public: + explicit Network(QObject *parent = nullptr); + virtual ~Network(); + +public Q_SLOTS: + /** + * @brief IsEnable + * @return + */ + bool IsEnable(); + /** + * @brief Enable + * @param enable + */ + void Enable(bool enable); + + bool SetDeviceState(QString device, bool enable); + QStringList GetAllDevices(void); + +Q_SIGNALS: + void EnableChanged(bool); + +private: + QDBusPendingCallWatcher * __network_dbus_call(const QString & method, const QList<QVariant> & args); + + template <typename...Args> + QDBusMessage callNetworkMethod(const QString &method, Args &&...args); +}; + +#endif // NETWORK_H diff -Nru ukui-framework-4.10.0.0/dbus/devices/network/src/network_common.h ukui-framework-5.0.0.0/dbus/devices/network/src/network_common.h --- ukui-framework-4.10.0.0/dbus/devices/network/src/network_common.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/network/src/network_common.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,26 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef NETWORK_COMMON_H +#define NETWORK_COMMON_H + +#define KYLIN_NM_DBUS_SERVER "com.kylin.network" +#define KYLIN_NM_DBUS_PATH "/com/kylin/network" +#define KYLIN_NM_DBUS_INTERFACE "com.kylin.network" + +#endif // NETWORK_COMMON_H diff -Nru ukui-framework-4.10.0.0/dbus/devices/power/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/power/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/power/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/power/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.5) + +project(power VERSION 1.0) + +find_package(PkgConfig) +set(CMAKE_AUTOMOC ON) + +file(GLOB LIBPOWER_SOURCES src/*.cpp) + +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + +add_library(power STATIC ${LIBPOWER_SOURCES}) + +find_package(PkgConfig REQUIRED) + +pkg_check_modules(gsettings-qt REQUIRED IMPORTED_TARGET gsettings-qt) + +target_link_libraries(power PRIVATE PkgConfig::gsettings-qt) + +target_link_libraries(power + PRIVATE + Qt5::Core + Qt5::DBus + ${DEVICES_POWER_LINK}) diff -Nru ukui-framework-4.10.0.0/dbus/devices/power/src/power.cpp ukui-framework-5.0.0.0/dbus/devices/power/src/power.cpp --- ukui-framework-4.10.0.0/dbus/devices/power/src/power.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/power/src/power.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,279 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "power.h" + +#include <QDebug> +#include "../screen/src/QGSettings/qgsettings.h" +#include <QProcess> +#include <QtDBus/QtDBus> + +#define UPOWER_SERVICE "org.freedesktop.UPower" +#define UPOWER_PATH "/org/freedesktop/UPower" +#define UPOWER_INTERFACE "org.freedesktop.UPower" + +#define UPOWER_DBUS_PROPERTIES "org.freedesktop.DBus.Properties" +#define UPOWER_DEVICE "org.freedesktop.UPower.Device" + +#define POWERMANAGER_SERVICE "org.ukui.powerManager" +#define POWERMANAGER_PATH "/PowerManager" +#define POWERMANAGER_INTERFACE "org.ukui.powerManager" + +#define GSETTING_POWERMANAGER "org.ukui.power-manager" + +UkuiPowerInterface::UkuiPowerInterface(QObject *parent) : QObject(parent) +{ + getBatteryDbusPath(); + + // 连接设备插入信号 + QDBusConnection::systemBus().connect( + UPOWER_SERVICE, + UPOWER_PATH, + UPOWER_INTERFACE, + "DeviceAdded", + this, + SLOT(onDeviceAdded(QString)) + ); + + // 连接设备拔出信号 + QDBusConnection::systemBus().connect( + UPOWER_SERVICE, + UPOWER_PATH, + UPOWER_INTERFACE, + "DeviceRemoved", + this, + SLOT(onDeviceRemoved(QString)) + ); +} + +UkuiPowerInterface::~UkuiPowerInterface() = default; + +static QVariant GetDBusProperty(const QDBusInterface& iface, const QString &propertyName) +{ + if (!iface.isValid()) { + qDebug() << "QDBusInterface is not valid"<< iface.lastError().message(); + return QVariant(); + } + + QVariant reply = iface.property(propertyName.toUtf8().constData()); + if (!reply.isValid()) { + qDebug() << "QDBus call failed for service"; + } + + return reply; +} + +int UkuiPowerInterface::getDeviceType(const QString &dBusPath) +{ + qDebug() << "device dBus object path:" << dBusPath; + + QDBusInterface dBusInterface(UPOWER_SERVICE, + dBusPath, + UPOWER_DBUS_PROPERTIES, + QDBusConnection::systemBus()); + QDBusReply<QVariant> reply = dBusInterface.call("Get", UPOWER_DEVICE, "Type"); + if (reply.isValid()) { + return reply.value().toInt(); + } else { + qDebug() << "Get device type failed"; + return UP_DEVICE_TYPE_UNKNOWN; + } +} + +QVariant UkuiPowerInterface::getBatteryProperty(const QString &propertyName) +{ + QDBusInterface iface(UPOWER_SERVICE, + m_batteryPath, + UPOWER_DEVICE, + QDBusConnection::systemBus()); + + return GetDBusProperty(iface, propertyName); +} + +void UkuiPowerInterface::getBatteryDbusPath() +{ + QDBusInterface dBusInterface(UPOWER_SERVICE, + UPOWER_PATH, + UPOWER_INTERFACE, + QDBusConnection::systemBus()); + + QDBusReply<QList<QDBusObjectPath>> reply = dBusInterface.call("EnumerateDevices"); + if (dBusInterface.isValid()) { + for (QDBusObjectPath dBusObjectPath : reply.value()) { + int upDeviceType = getDeviceType(dBusObjectPath.path()); + qDebug() << "device type:" << upDeviceType; + if (UP_DEVICE_TYPE_BATTERY == upDeviceType) { + m_batteryPath = dBusObjectPath.path(); + qDebug() << "battery dBusObjectPath:" << m_batteryPath; + } + } + } +} + + +int UkuiPowerInterface::GetBatteryState() +{ + QVariant reply = getBatteryProperty("State"); + if (!reply.isValid()) { + sendErrorReply(QDBusError::Failed, "Failed to get Battery State"); + return -1; + } + + return reply.toInt(); +} + +int UkuiPowerInterface::BatteryPercentage() +{ + QVariant reply = getBatteryProperty("Percentage"); + if (!reply.isValid()) { + sendErrorReply(QDBusError::Failed, "Failed to get Battery Percentage"); + return -1; + } + + return reply.toInt(); +} + +int UkuiPowerInterface::TimeToFull() +{ + QVariant reply = getBatteryProperty("TimeToFull"); + if (!reply.isValid()) { + sendErrorReply(QDBusError::Failed, "Failed to get Time To Full"); + return -1; + } + + return reply.toInt(); +} + +int UkuiPowerInterface::TimeToEmpty() +{ + QVariant reply = getBatteryProperty("TimeToEmpty"); + if (!reply.isValid()) { + sendErrorReply(QDBusError::Failed, "Failed to get Time To Empty"); + return -1; + } + + return reply.toInt(); +} + +bool UkuiPowerInterface::IsBatteryPresent() +{ + QVariant reply = getBatteryProperty("IsPresent"); + + return reply.isValid() && reply.toBool(); +} + +int UkuiPowerInterface::GetPowerMode() +{ + QDBusInterface iface(UPOWER_SERVICE, + UPOWER_PATH, + UPOWER_INTERFACE, + QDBusConnection::systemBus()); + + QVariant reply = GetDBusProperty(iface, "OnBattery"); + + if (!reply.isValid()) { + return -1; + } + + if (!QGSettings::isSchemaInstalled(GSETTING_POWERMANAGER)) { + qWarning() << "org.ukui.power-manager is not install"; + return -1; + } + + QGSettings settings(GSETTING_POWERMANAGER); + QVariant value; + + if (reply.toBool()) { + value = settings.get("power-policy-battery"); + return value.isValid() ? value.toInt() : -1; + } else { + value = settings.get("power-policy-ac"); + return value.isValid() ? value.toInt() : -1; + } +} + +void UkuiPowerInterface::SetPowerMode(uint mode) +{ + if (mode > 2) + { + qWarning() << "error param " + QString::number(mode) + " just 0 or 1 or 2 can take effect!"; + return; + } + + QDBusInterface iface(UPOWER_SERVICE, + UPOWER_PATH, + UPOWER_INTERFACE, + QDBusConnection::systemBus()); + + QVariant reply = GetDBusProperty(iface, "OnBattery"); + + if (!reply.isValid()) { + return; + } + + if (!QGSettings::isSchemaInstalled(GSETTING_POWERMANAGER)) { + qWarning() << "org.ukui.power-manager is not install"; + return; + } + + QGSettings settings(GSETTING_POWERMANAGER); + settings.set((reply.toBool() ? "power-policy-battery" : "power-policy-ac"), mode); + return; +} + +int UkuiPowerInterface::GetPowerSaveLevel() +{ + QDBusInterface iface(POWERMANAGER_SERVICE, + POWERMANAGER_PATH, + POWERMANAGER_INTERFACE, + QDBusConnection::sessionBus()); + + QDBusReply<int> reply = iface.call("getPowersaveLevel"); + if (!reply.isValid()) { + qDebug() << "Failed to get powersaveLevel"; + sendErrorReply(QDBusError::Failed, "Failed to get power save Level"); + return -1; // 返回一个表示错误的值 + } + + return reply.value(); +} + +bool UkuiPowerInterface::IsLid() +{ + QDBusInterface iface(UPOWER_SERVICE, + UPOWER_PATH, + UPOWER_INTERFACE, + QDBusConnection::systemBus()); + + QVariant reply = GetDBusProperty(iface, "LidIsPresent"); + + return reply.isValid() && reply.toBool(); +} + +void UkuiPowerInterface::onDeviceAdded(const QString &devicePath) +{ + qDebug() << "Device added:" << devicePath; + getBatteryDbusPath(); +} + +void UkuiPowerInterface::onDeviceRemoved(const QString &devicePath) +{ + qDebug() << "Device removed:" << devicePath; + getBatteryDbusPath(); +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/power/src/power.h ukui-framework-5.0.0.0/dbus/devices/power/src/power.h --- ukui-framework-4.10.0.0/dbus/devices/power/src/power.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/power/src/power.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,122 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef POWER_H +#define POWER_H + +#include <QDBusContext> +#include <QObject> + +enum UpDeviceType +{ + UP_DEVICE_TYPE_UNKNOWN = 0, + UP_DEVICE_TYPE_LINE_POWER, + UP_DEVICE_TYPE_BATTERY, + UP_DEVICE_TYPE_UPS, + UP_DEVICE_TYPE_MONITOR, + UP_DEVICE_TYPE_MOUSE, + UP_DEVICE_TYPE_KEYBOARD, + UP_DEVICE_TYPE_PDA, + UP_DEVICE_TYPE_PHONE, + UP_DEVICE_TYPE_MEDIA_PLAYER, + UP_DEVICE_TYPE_TABLET, + UP_DEVICE_TYPE_COMPUTER, + UP_DEVICE_TYPE_MAX +}; + + +class UkuiPowerInterface : public QObject, protected QDBusContext +{ + Q_OBJECT + + Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.Devices.Power") + +public: + explicit UkuiPowerInterface(QObject *parent = nullptr); + ~UkuiPowerInterface() override; + +public slots: + /** + * @brief getPowerSaveLevel 获取节能等级 + * @return -1:错误信息; 0:正常工作; 1:节能; 2:极低电量 + */ + int GetPowerSaveLevel(); + + /** + * @brief getPowerMode 获取电源工作模式 + * @return -1:错误信息; 0:性能; 1:平衡; 2:节能 + */ + int GetPowerMode(); + + /** + * @brief SetPowerMode + * @param mode 0:性能模式 1:平衡模式 2:能效模式 + */ + void SetPowerMode(uint mode); + + /** + * @brief batteryPercentage 获取电量百分比 + * @return -1:错误信息;1-100:电量百分比 + */ + int BatteryPercentage(); + + /** + * @brief timeToFull 获取充满电时间 + * @return -1:错误信息;获取充满电时间 单位:秒; + */ + int TimeToFull(); + + /** + * @brief timeToUse 获取可用时长 + * @return -1:错误信息;可用时长 单位:秒 + */ + int TimeToEmpty(); + + /** + * @brief getBatteryState 获取电池状态 + * @return + * -1:错误信息; 0:未知状态 1:充电状态 2:放电状态 3:电量为空 4:电池已充满 5:准备充电 6:准备断开充电 + */ + int GetBatteryState(); + + /** + * @brief isBatteryPresent 是否有电池接入 + * @return true:有电池接入;false:无电池接入 + */ + bool IsBatteryPresent(); + + /** + * @brief isLid 是否有盖子 + * @return true:有盖子;false:无盖子 + */ + bool IsLid(); + + void onDeviceAdded(const QString &devicePath); + + void onDeviceRemoved(const QString &devicePath); + +private: + void getBatteryDbusPath(); + QVariant getBatteryProperty(const QString &propertyName); + int getDeviceType(const QString &dBusPath); + + QString m_batteryPath; +}; + + +#endif // POWER_H diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/screen/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/screen/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) +project(screen VERSION 1.0) + +find_package(PkgConfig) + + +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(GIO REQUIRED gio-2.0) +pkg_check_modules(GOBJECT REQUIRED gobject-2.0) + +include_directories(${GLIB_INCLUDE_DIRS}) +include_directories(${GIO_INCLUDE_DIRS}) +include_directories(${GOBJECT_INCLUDE_DIRS}) + +cmake_minimum_required(VERSION 3.16) +# 查找Qt5及其模块 +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus Widgets) + + +set(DEVICES_SCREEN_LINK + glib-2.0 + gio-2.0 + ${GLIB_LIBRARIES} + ${GIO_LIBRARIES} + ${GOBJECT_LIBRARIES} +) + + +# 索引动态库的头文件地址 +include_directories(${GLIB_INCLUDE_DIRS}) +include_directories(${GIO_INCLUDE_DIRS}) +include_directories(${GOBJECT_INCLUDE_DIRS}) + +set(CMAKE_AUTOMOC ON) + +file(GLOB LIBSCREEN_SOURCES src/*.cpp src/QGSettings/*.cpp) + +add_library(screen STATIC ${LIBSCREEN_SOURCES}) + +target_link_libraries(screen + PRIVATE + Qt5::Core + Qt5::Widgets + Qt5::DBus + ${DEVICES_SCREEN_LINK}) diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qconftype.cpp ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qconftype.cpp --- ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qconftype.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qconftype.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,366 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2020 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "qconftype.h" + +#include <QStringList> + +/** + * GVariant Type Name/Code C++ Type Name QVariant Type Name + * -------------------------------------------------------------------------- + * boolean b bool QVariant::Bool + * byte y char QVariant::Char + * int16 n int QVariant::Int + * uint16 q unsigned int QVariant::UInt + * int32 i int QVariant::Int + * uint32 u unsigned int QVariant::UInt + * int64 x long long QVariant::LongLong + * uint64 t unsigned long long QVariant::ULongLong + * double d double QVariant::Double + * string s QString QVariant::String + * string array* as QStringList QVariant::StringList + * byte array ay QByteArray QVariant::ByteArray + * dictionary a{ss} QVariantMap QVariant::Map + */ + +QVariant::Type qconf_types_convert(const GVariantType *gtype) +{ + switch (g_variant_type_peek_string(gtype)[0]) { + case G_VARIANT_CLASS_BOOLEAN: + return QVariant::Bool; + + case G_VARIANT_CLASS_BYTE: + return QVariant::Char; + + case G_VARIANT_CLASS_INT16: + return QVariant::Int; + + case G_VARIANT_CLASS_UINT16: + return QVariant::UInt; + + case G_VARIANT_CLASS_INT32: + return QVariant::Int; + + case G_VARIANT_CLASS_UINT32: + return QVariant::UInt; + + case G_VARIANT_CLASS_INT64: + return QVariant::LongLong; + + case G_VARIANT_CLASS_UINT64: + return QVariant::ULongLong; + + case G_VARIANT_CLASS_DOUBLE: + return QVariant::Double; + + case G_VARIANT_CLASS_STRING: + return QVariant::String; + + case G_VARIANT_CLASS_ARRAY: + if (g_variant_type_equal(gtype, G_VARIANT_TYPE_STRING_ARRAY)) + return QVariant::StringList; + + else if (g_variant_type_equal(gtype, G_VARIANT_TYPE_BYTESTRING)) + return QVariant::ByteArray; + + else if (g_variant_type_equal(gtype, G_VARIANT_TYPE ("a{ss}"))) + return QVariant::Map; + + // fall through + default: + return QVariant::Invalid; + } +} + +GVariant *qconf_types_collect_from_variant(const GVariantType *gtype, const QVariant &v) +{ + switch (g_variant_type_peek_string(gtype)[0]) { + case G_VARIANT_CLASS_BOOLEAN: + return g_variant_new_boolean(v.toBool()); + + case G_VARIANT_CLASS_BYTE: + return g_variant_new_byte(v.toChar().cell()); + + case G_VARIANT_CLASS_INT16: + return g_variant_new_int16(v.toInt()); + + case G_VARIANT_CLASS_UINT16: + return g_variant_new_uint16(v.toUInt()); + + case G_VARIANT_CLASS_INT32: + return g_variant_new_int32(v.toInt()); + + case G_VARIANT_CLASS_UINT32: + return g_variant_new_uint32(v.toUInt()); + + case G_VARIANT_CLASS_INT64: + return g_variant_new_int64(v.toLongLong()); + + case G_VARIANT_CLASS_UINT64: + return g_variant_new_int64(v.toULongLong()); + + case G_VARIANT_CLASS_DOUBLE: + return g_variant_new_double(v.toDouble()); + + case G_VARIANT_CLASS_STRING: + return g_variant_new_string(v.toString().toUtf8()); + + case G_VARIANT_CLASS_ARRAY: + if (g_variant_type_equal(gtype, G_VARIANT_TYPE_STRING_ARRAY)) { + const QStringList list = v.toStringList(); + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY); + + Q_FOREACH(const QString& string, list) + g_variant_builder_add(&builder, "s", string.toUtf8().constData()); + + return g_variant_builder_end(&builder); + } else if (g_variant_type_equal(gtype, G_VARIANT_TYPE_BYTESTRING)) { + const QByteArray array = v.toByteArray(); + gsize size = array.size(); + gpointer data; + + data = g_memdup(array.data(), size); + + return g_variant_new_from_data(G_VARIANT_TYPE_BYTESTRING, + data, size, TRUE, g_free, data); + } else if (g_variant_type_equal(gtype, G_VARIANT_TYPE("a{ss}"))) { + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE ("a{ss}")); + QMapIterator<QString, QVariant> it(v.toMap()); + while (it.hasNext()) { + it.next(); + QByteArray key = it.key().toUtf8(); + QByteArray val = it.value().toByteArray(); + g_variant_builder_add (&builder, "{ss}", key.constData(), val.constData()); + } + return g_variant_builder_end (&builder); + } else if (g_variant_type_equal(gtype, G_VARIANT_TYPE_VARDICT)) { + GVariantBuilder builder; + QMapIterator<QString, QVariant> it(v.toMap()); + + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + + while (it.hasNext()) { + it.next(); + GVariant *gvar; + QByteArray key = it.key().toUtf8(); + if (it.value().canConvert(QVariant::String)) { + gvar = g_variant_new_string(it.value().toString().toLatin1().data()); + } else if (it.value().canConvert(QVariant::UInt)) { + gvar = g_variant_new_uint32(it.value().toUInt()); + } + + g_variant_builder_add (&builder, "{sv}", key.constData(), gvar); + + } + return g_variant_builder_end (&builder); + } else if (g_variant_type_equal(gtype, G_VARIANT_TYPE("a{sd}"))) { + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE ("a{sd}")); + QMapIterator<QString, QVariant> it(v.toMap()); + while (it.hasNext()) { + it.next(); + QByteArray key = it.key().toUtf8(); + double val = it.value().toDouble(); + g_variant_builder_add (&builder, "{sd}", key.constData(), val); + } + return g_variant_builder_end (&builder); + } + + // fall through + case G_VARIANT_CLASS_TUPLE: + if (g_variant_type_equal(gtype, "(dd)")) { + QVariantList doubleList = v.value<QVariantList>(); + if (doubleList.count() == 2) + { + return g_variant_new ("(dd)", doubleList[0].toDouble(), doubleList[1].toDouble()); + } else { + return NULL; + } + } + break; + default: + return NULL; + } + return NULL; +} + +QVariant qconf_types_to_qvariant(GVariant *value) +{ + switch (g_variant_classify(value)) { + case G_VARIANT_CLASS_BOOLEAN: + return QVariant((bool) g_variant_get_boolean(value)); + + case G_VARIANT_CLASS_BYTE: + return QVariant((char) g_variant_get_byte(value)); + + case G_VARIANT_CLASS_INT16: + return QVariant((int) g_variant_get_int16(value)); + + case G_VARIANT_CLASS_UINT16: + return QVariant((unsigned int) g_variant_get_uint16(value)); + + case G_VARIANT_CLASS_INT32: + return QVariant((int) g_variant_get_int32(value)); + + case G_VARIANT_CLASS_UINT32: + return QVariant((unsigned int) g_variant_get_uint32(value)); + + case G_VARIANT_CLASS_INT64: + return QVariant((long long) g_variant_get_int64(value)); + + case G_VARIANT_CLASS_UINT64: + return QVariant((unsigned long long) g_variant_get_uint64(value)); + + case G_VARIANT_CLASS_DOUBLE: + return QVariant(g_variant_get_double(value)); + + case G_VARIANT_CLASS_STRING: + return QVariant(g_variant_get_string(value, NULL)); + + case G_VARIANT_CLASS_ARRAY: + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING_ARRAY)) { + GVariantIter iter; + QStringList list; + const gchar *str; + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "&s", &str)) + list.append (str); + + return QVariant(list); + } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_BYTESTRING)) { + return QVariant(QByteArray(g_variant_get_bytestring(value))); + } else if (g_variant_is_of_type(value, G_VARIANT_TYPE("a{ss}"))) { + GVariantIter iter; + QMap<QString, QVariant> map; + const gchar *key; + const gchar *val; + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &val)) + map.insert(key, QVariant(val)); + + return map; + } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARDICT)) { + GVariantIter iter; + QMap<QString, QVariant> map; + const gchar *key; + size_t str_len; + GVariant *val = NULL; + g_variant_iter_init (&iter, value); + + while (g_variant_iter_next (&iter, "{&sv}", &key, &val)) { + QVariant qvar; + + if(g_variant_is_of_type(val, G_VARIANT_TYPE_BOOLEAN)) { + qvar = g_variant_get_boolean(val); + } else if(g_variant_is_of_type(val, G_VARIANT_TYPE_STRING)) { + qvar = g_variant_get_string(val, &str_len); + } else if(g_variant_is_of_type(val, G_VARIANT_TYPE_STRING)) { + qvar = g_variant_get_string(val, &str_len); + } else if(g_variant_is_of_type(val, G_VARIANT_TYPE_UINT32)) { + qvar = g_variant_get_uint32(val); + } + map.insert(key, qvar); + } + + return map; + } else if (g_variant_is_of_type(value, G_VARIANT_TYPE("a{sd}"))) { + GVariantIter iter; + QMap<QString, QVariant> map; + const gchar *key; + gdouble val; + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "{&sd}", &key, &val)) { + map.insert(key, QVariant(val)); + } + return map; + } else { +// USD_LOG(LOG_ERR,"can't parse %s",g_variant_get_type(value)); + } + + return QVariant(); + // fall throughsudo apt install qtbase5-dev qt5-qmake qtchooser qtscript5-dev qttools5-dev-tools qtbase5-dev-tools libgsettings-qt-dev + case G_VARIANT_CLASS_TUPLE: + if (g_variant_is_of_type(value, G_VARIANT_TYPE("(dd)"))) { + QVariantList varList; + QVariant var; + double latitude,longitude; + + g_variant_get(value, "(dd)", &latitude, &longitude); + varList.append(latitude); + varList.append(longitude); + var = varList; + return var; + } + default: + g_assert_not_reached(); + break; + } + g_assert_not_reached(); + // return QVariant((bool) g_variant_get_boolean(value)); +} + +// trans 'aa-bb' to 'aaBb' +QString qtify_name(const char *name) +{ + bool next_cap = false; + QString result; + + while (*name) { + if (*name == '-') { + next_cap = true; + } else if (next_cap) { + result.append(QChar(*name).toUpper().toLatin1()); + next_cap = false; + } else { + result.append(*name); + } + + name++; + } + + return result; +} + +gchar * unqtify_name(const QString &name) +{ + const gchar *p; + QByteArray bytes; + GString *str; + + bytes = name.toUtf8(); + str = g_string_new (NULL); + + for (p = bytes.constData(); *p; p++) { + const QChar c(*p); + if (c.isUpper()) { + g_string_append_c (str, '-'); + g_string_append_c (str, c.toLower().toLatin1()); + } + else { + g_string_append_c (str, *p); + } + } + + return g_string_free(str, FALSE); +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qconftype.h ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qconftype.h --- ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qconftype.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qconftype.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,35 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2020 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef QCONFTYPE_H +#define QCONFTYPE_H + +#include <glib.h> +#include <QVariant> + +QVariant::Type qconf_types_convert (const GVariantType* gtype); +GVariant* qconf_types_collect (const GVariantType* gtype, const void* argument); +GVariant* qconf_types_collect_from_variant(const GVariantType* gtype, const QVariant& v); +QVariant qconf_types_to_qvariant (GVariant* value); +void qconf_types_unpack (GVariant* value, void* argument); + +QString qtify_name(const char *name); +gchar * unqtify_name(const QString &name); + +#endif // QCONFTYPE_H diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qgsettings.cpp ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qgsettings.cpp --- ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qgsettings.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qgsettings.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,299 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2020 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <glib.h> +#include <gio/gio.h> + +#include <QDebug> +#include <QString> + +#include "qgsettings.h" +#include "qconftype.h" + +struct QGSettingsPrivate +{ + QByteArray path; + GSettingsSchema *schema; + QByteArray schemaId; + GSettings *settings; + gulong signalHandlerId; + + static void settingChanged(GSettings *settings, const gchar *key, gpointer userData); +}; + +void QGSettingsPrivate::settingChanged(GSettings *, const gchar *key, gpointer userData) +{ + QGSettings *self = (QGSettings *)userData; + + /** + * 这里不属于 QObject的子类,只能通过此方法强制调用 QObject 子类的方法或信号 + * + * Qt::QueuedConnection 发送一个QEvent,并在应用程序进入主事件循环后立即调用该成员。 + * Qt::DirectConnection 立即调用 + * Qt::BlockingQueuedConnection 则将以与Qt::QueuedConnection相同的方式调用该方法,除了当前线程将阻塞直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁 + * Qt::AutoConnection 则如果obj与调用者位于同一个线程中,则会同步调用该成员; 否则它将异步调用该成员 + * + */ + QMetaObject::invokeMethod(self, "changed", Qt::AutoConnection, Q_ARG(QString, key)); +} + +static bool is_item_in_schema (const gchar* const* items, const QByteArray & item) +{ + while (*items) { + if (g_strcmp0 (*items++, item) == 0) { + return true; + } + } + return false; +} + +QGSettings::QGSettings(const QByteArray &schemaId, const QByteArray &path, QObject *parent) : QObject(parent) +{ + mPriv = new QGSettingsPrivate; + mPriv->schemaId = schemaId; + mPriv->path = path; + + if (false == is_item_in_schema (g_settings_list_schemas(), schemaId)){ + mPriv->settings = nullptr; + return; + } + + if (mPriv->path.isEmpty()) { + mPriv->settings = g_settings_new(mPriv->schemaId.constData()); + } else { + mPriv->settings = g_settings_new_with_path(mPriv->schemaId.constData(), mPriv->path.constData()); + } + g_object_get(mPriv->settings, "settings-schema", &mPriv->schema, NULL); + mPriv->signalHandlerId = g_signal_connect(mPriv->settings, "changed", G_CALLBACK(QGSettingsPrivate::settingChanged), this); +} + +QGSettings::~QGSettings() +{ + if (mPriv->schema) { + g_settings_sync (); + g_signal_handler_disconnect(mPriv->settings, mPriv->signalHandlerId); + g_object_unref (mPriv->settings); + g_settings_schema_unref (mPriv->schema); + } + delete mPriv; +} + +QVariant QGSettings::get(const QString &key) const +{ + gchar *gkey = unqtify_name(key); + if (mPriv->settings == nullptr) { + return -1; + } + + if (!keys().contains(gkey)) { +// USD_LOG(LOG_ERR, "can't find int key:%s in %s", gkey, mPriv->schemaId.data()); + return QVariant(0); + } + + GVariant *value = g_settings_get_value(mPriv->settings, gkey); + if( NULL == value) { +// USD_LOG(LOG_DEBUG,"g_settings_get_value is faild"); + return QVariant(0); + } + QVariant qvalue = qconf_types_to_qvariant(value); + g_variant_unref(value); + g_free(gkey); + + return qvalue; +} + +QString QGSettings::set(const QString &key, const QVariant &value) +{ + QString errorMsg = ""; + if (mPriv->settings == nullptr) { + return "settings are null"; + } + + gchar *gkey = unqtify_name(key); + if (keys().contains(QString(gkey))) { + if (!trySet(key, value)) { + errorMsg = QString("unable to set key '%1' to value '%2'\n").arg(key).arg(value.toString()); +// USD_LOG(LOG_ERR,"unable to set key '%s' to value '%s'", key.toUtf8().constData(), value.toString().toUtf8().constData()); + } + } else { +// USD_LOG(LOG_ERR, "can't find int key:%s in %s", gkey, mPriv->schemaId.data()); + errorMsg = QString("can't find int key:%1 in %2\n").arg(QString(gkey)).arg(QString(mPriv->schemaId.data())); + } + + return errorMsg; +} + +bool QGSettings::trySet(const QString &key, const QVariant &value) +{ + gchar *gkey = unqtify_name(key); + bool success = false; + + + /* fetch current value to find out the exact type */ + GVariant *cur = g_settings_get_value(mPriv->settings, gkey); + GVariant *new_value = qconf_types_collect_from_variant(g_variant_get_type (cur), value); + if (new_value) + success = g_settings_set_value(mPriv->settings, gkey, new_value); + + g_free(gkey); + g_variant_unref (cur); + + return success; +} + +void QGSettings::setEnum(const QString& key,int value) +{ + if (mPriv->settings == nullptr) { + return ; + } + g_settings_set_enum (mPriv->settings,key.toLatin1().data(),value); +} + +int QGSettings::getEnum(const QString& key) +{ + int enumNum; + if (mPriv->settings == nullptr) { + return -1; + } + enumNum = g_settings_get_enum (mPriv->settings,key.toLatin1().data()); + return enumNum; +} + +char **QGSettings::getStrv(const QString& key) +{ + return g_settings_get_strv(mPriv->settings,key.toLatin1().data()); +} + +void QGSettings::delay() +{ + g_settings_delay(mPriv->settings); +} + +void QGSettings::apply() +{ + g_settings_apply(mPriv->settings); +} + +QStringList QGSettings::keys() const +{ + QStringList list; + //gchar **keys = g_settings_list_keys(mPriv->settings); + gchar **keys = g_settings_schema_list_keys(mPriv->schema); + for (int i = 0; keys[i]; i++) + list.append(keys[i]); +// list.append(qtify_name(keys[i])); + + g_strfreev(keys); + + return list; +} + +QVariantList QGSettings::choices(const QString &qkey) const +{ + gchar *key = unqtify_name (qkey); + GSettingsSchemaKey *schema_key = g_settings_schema_get_key (mPriv->schema, key); + GVariant *range = g_settings_schema_key_get_range(schema_key); + g_settings_schema_key_unref (schema_key); + g_free(key); + + if (range == NULL) + return QVariantList(); + + const gchar *type; + GVariant *value; + g_variant_get(range, "(&sv)", &type, &value); + + QVariantList choices; + if (g_str_equal(type, "enum")) { + GVariantIter iter; + GVariant *child; + + g_variant_iter_init (&iter, value); + while ((child = g_variant_iter_next_value(&iter))) { + choices.append(qconf_types_to_qvariant(child)); + g_variant_unref(child); + } + } + + g_variant_unref (value); + g_variant_unref (range); + + return choices; +} + +void QGSettings::reset(const QString &qkey) +{ + gchar *key = unqtify_name(qkey); + g_settings_reset(mPriv->settings, key); + g_free(key); +} + +bool QGSettings::isSchemaInstalled(const QByteArray &schemaId) +{ + GSettingsSchemaSource *source = g_settings_schema_source_get_default (); + GSettingsSchema *schema = g_settings_schema_source_lookup (source, schemaId.constData(), TRUE); + if (schema) { + g_settings_schema_unref (schema); + return true; + } else { + return false; + } +} + +QString QGSettings::getSummary(const QString &key) const +{ + + gchar* gKey = unqtify_name(key); + if (!keys().contains(gKey)) { +// USD_LOG(LOG_ERR, "can't find key:%s in %s", gKey, mPriv->schemaId.data()); + g_free(gKey); + return QString(); + } + + GSettingsSchemaKey *schemaKey = nullptr; + schemaKey = g_settings_schema_get_key(mPriv->schema, gKey); + + if (!schemaKey) { +// USD_LOG(LOG_ERR, "can't get schema key:%s in %s", gKey, mPriv->schemaId.data()); + g_free(gKey); + return QString(); + } + g_free(gKey); + + const gchar* gSummary = g_settings_schema_key_get_summary(schemaKey); + g_settings_schema_key_unref(schemaKey); + + return QString(gSummary); +} + +QString QGSettings::getKeyType(const QString &key) const +{ + QString ret = ""; + gchar* gKey = unqtify_name(key); + if (!keys().contains(gKey)) { +// USD_LOG(LOG_ERR, "can't find key:%s in %s", gKey, mPriv->schemaId.data()); + g_free(gKey); + return QString(); + } + GVariant *cur = g_settings_get_value(mPriv->settings, gKey); + ret = g_variant_get_type_string(cur); + g_free(gKey); + return ret; +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qgsettings.h ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qgsettings.h --- ukui-framework-4.10.0.0/dbus/devices/screen/src/QGSettings/qgsettings.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/QGSettings/qgsettings.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,142 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2020 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef QGSETTINGS_H +#define QGSETTINGS_H + +#include <QObject> +#include <QStringList> + +/** + * gsettings 的 key 必须是小写字符和下划线组成 + * 此类将所有key转为驼峰方式 + */ + +class QGSettings : public QObject +{ + Q_OBJECT +public: + /* 根据 schemaId 和 path 创建QGSettings对象 */ + explicit QGSettings(const QByteArray& schemaId, const QByteArray& path=QByteArray(), QObject *parent = nullptr); + ~QGSettings(); + + /** + * 根据key获取值, key不存在则报错 + * + */ + QVariant get (const QString& key) const; + + /** + * 根据 key 设定值 + */ + QString set (const QString& key, const QVariant& value); + + /** + * 将QGSettings对象更改为'delay-apply'模式。 + * 在此模式下,对设置的更改不会立即传播到后端, + * 而是在本地保存,直到调用apply()。 + */ + void delay(); + + /** + * 应用对设置所做的任何更改。 + * 这个函数什么都不做,除非设置是在“延迟-应用”模式; + * 看到delay ()。在正常情况下,总是立即应用设置。 + */ + void apply(); + + /** + * @brief setEnum + * @param key + * @param value + * 在设置中查找枚举类型的nick以获取值并将其写入键。 + * 给出一个不包含在架构中的键来进行设置或未将其标记为枚举类型, + * 或者将值设为不是该命名类型的有效值是程序员的错误。 + * 执行写操作后,直接使用g_settings_get_string() + * 访问密钥将返回与值关联的'nick'。 + */ + void setEnum(const QString& key,int value); + + /** + * 获取存储在key设置中的值,并将其转换为它表示的枚举值。 + * 为了使用此函数,值的类型必须为字符串,并且必须在模式文件中将其标记为枚举类型。 + * 给出不包含在设置模式中或未标记为枚举类型的密钥是程序员的错误。 + * 如果配置数据库中存储的值不是该枚举类型的有效值,则此函数将返回默认值。 + */ + int getEnum(const QString& key); + + /** + * g_settings_get()字符串数组的便捷变体。 + * 给出一个key 未指定为的架构中的字符串类型数组是程序员的错误settings 。 + * return: 一个新分配的,NULL终止的字符串数组,该值存储在key 中settings + */ + char **getStrv(const QString& key); + + /** + * + */ + bool trySet (const QString& key, const QVariant& value); + + /** + * 获取 key 的列表 + */ + QStringList keys() const; + + /** + * + */ + QVariantList choices (const QString& key) const; + + /** + * 将 key 设为默认值 + */ + void reset (const QString& key); + + /** + * 根据给定 id 检查是否存在schema + */ + static bool isSchemaInstalled (const QByteArray& schemaId); + + /** + * @brief getSummary + * @param key + * @return 获取 key 对应的 summary + */ + + QString getSummary(const QString& key) const; + + /** + * @brief getKeyType + * @param key + * @return 获取key的类型,判断类型合适后再设置值。 + */ + QString getKeyType(const QString &key) const; +Q_SIGNALS: + /** + * key 的值改变时发射信号 + * + */ + void changed (const QString& key); + +private: + struct QGSettingsPrivate* mPriv; + friend struct QGSettingsPrivate; + +}; + +#endif // QGSETTINGS_H diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen.cpp ukui-framework-5.0.0.0/dbus/devices/screen/src/screen.cpp --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,292 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "screen.h" + + +Screen::Screen(QObject *parent): + QObject(parent) +{ + m_pColorGsettings = new QGSettings(UKUI_SETTINGS_DAEMON_COLOR_SCHEMA); + m_outputModeEnum = QMetaEnum::fromType<eScreenMode>(); + + qRegisterMetaType<OutputGammaInfo>("OutputGammaInfo"); + qRegisterMetaType<OutputGammaInfoList>("OutputGammaInfoList"); + qDBusRegisterMetaType<OutputGammaInfo>(); + qDBusRegisterMetaType<OutputGammaInfoList>(); + + m_brightControlByUPM = brightControlByUPM(); + if (Screen::eBrightnessControl::powerManager == m_brightControlByUPM) { + m_pscreen = new ScreenBrightNode(this); + } else if (Screen::eBrightnessControl::gamma == m_brightControlByUPM) { + m_pscreen = new ScreenGamma(this); + } +} + +Screen::~Screen() +{ + delete m_pColorGsettings; + m_pColorGsettings = nullptr; +} + +bool Screen::SetScreenBrightness(QString name, uint screenBrightness) +{ + if (Screen::eBrightnessControl::unknown == m_brightControlByUPM) { + return -1; + } + return m_pscreen->setScreenBrightness(name, screenBrightness); +} + +uint Screen::GetScreenBrightness(QString name) +{ + if (Screen::eBrightnessControl::unknown == m_brightControlByUPM) { + return -1; + } + return m_pscreen->getScreenBrightness(name); +} + +bool Screen::SetScreensBrightness(OutputGammaInfoList outputsInfo) +{ + if (Screen::eBrightnessControl::unknown == m_brightControlByUPM) { + return -1; + } + return m_pscreen->setScreensBrightness(outputsInfo); +} + +bool Screen::SetAllScreenSameBrightness(uint brighenss) +{ + if (Screen::eBrightnessControl::unknown == m_brightControlByUPM) { + return -1; + } + return m_pscreen->setAllScreenSameBrightness(brighenss); +} + +OutputGammaInfoList Screen::GetAllScreenBrightness() +{ + if (Screen::eBrightnessControl::unknown == m_brightControlByUPM) { + return OutputGammaInfoList(); + } + return m_pscreen->getAllScreenBrightness(); +} + +/** + * TODO 调用统一接口查询,设置屏幕亮度 + */ +bool Screen::SetPrimaryScreenBrightness(uint screenBrightness) +{ + QDBusReply<bool> reply = callBrighenss("setPrimaryBrightness", screenBrightness); + if (false == reply.isValid()) { + return false; + } + + return true; +} + +uint Screen::GetPrimaryScreenBrightness() +{ + QDBusReply<uint> reply = callBrighenss("getPrimaryBrightness"); + if (false == reply.isValid()) { + return -1; + } + + + return reply.value(); +} + +bool Screen::IncreaseBuiltinScreenBrightness() +{ + QDBusReply<void> reply = callMediaKeys("externalDoAction", 3,MY_NAME); + if (false == reply.isValid()) { + return false; + } + + return true; +} + +bool Screen::DecreaseBuiltinBrightness() +{ + QDBusReply<void> reply = callMediaKeys("externalDoAction", 2,MY_NAME); + if (false == reply.isValid()) { + return false; + } + + return true; +} + +QString Screen::GetScreenMode() +{ + QDBusReply<int> reply = callXrandr("getScreenMode",MY_NAME); + if (false == reply.isValid()) { + return ""; + } + + return m_outputModeEnum.valueToKey(reply.value()); +} + +bool Screen::SetScreenMode(const QString &mode) +{ + QDBusReply<int> reply = callXrandr("setScreenMode", mode, MY_NAME); + if (false == reply.isValid()) { + return false; + } + + return true; +} + +bool Screen::SetScreensParam(const QString &screenParam) +{ + QDBusReply<int> reply = callXrandr("setScreensParam", MY_NAME, screenParam); + if (false == reply.isValid()) { + return false; + } + + return true; +} + +QString Screen::GetScreensParam() +{ + QDBusReply<QString> reply = callXrandr("getScreensParam", MY_NAME); + if (false == reply.isValid()) { + return ""; + } + + return reply.value(); +} + +bool Screen::SetColorTemperature(QString appName, int colorTemp) +{ + return true; +} + +bool Screen::SetEyeCareEnabled(bool state) +{ + QString ret = m_pColorGsettings->set(UKUI_SETTINGS_DAEMON_COLOR_EYS_CARE, state); + return ret.isEmpty(); +} + +bool Screen::IsEyeCareEnabled() +{ + return m_pColorGsettings->get(UKUI_SETTINGS_DAEMON_COLOR_EYS_CARE).toBool(); +} + +bool Screen::SetNightModeEnable(bool state) +{ + QString ret = m_pColorGsettings->set(UKUI_SETTINGS_DAEMON_COLOR_NIGHT_MODE, state); + return ret.isEmpty(); +} + +bool Screen::IsNightModeEnable() +{ + return m_pColorGsettings->get(UKUI_SETTINGS_DAEMON_COLOR_NIGHT_MODE).toBool(); +} + +Screen::eBrightnessControl Screen::brightControlByUPM() +{ + QDBusInterface powerInterface(UKUI_POWER_MANAGER_DBUS_NAME, + UKUI_POWER_MANAGER_DBUS_PATH, + UKUI_POWER_MANAGER_DBUS_INTERFACE, + QDBusConnection::systemBus()); + + QDBusReply<bool> reply = powerInterface.call("CanSetBrightness"); + + if (reply.isValid()) { + if (reply.value()) { + return Screen::eBrightnessControl::powerManager; + } else { + return Screen::eBrightnessControl::gamma; + } + } + qDebug() << "powermanager's systembus call error!"<<reply.error(); + return Screen::eBrightnessControl::unknown; +} + +void Screen::watchUpmRegisterDbusServer() +{ + qDebug() << "ready connect dbus server!"; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + auto watcher = new QDBusServiceWatcher(QStringLiteral(UKUI_POWER_MANAGER_DBUS_NAME), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); + connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &Screen::serviceOwnerChanged); +#else + connect(QDBusConnection::sessionBus().interface(), &QDBusConnectionInterface::serviceOwnerChanged, this, &Screen::serviceOwnerChanged); +#endif +} + +QDBusMessage Screen::callGamma(const QString &method, const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4) +{ + QDBusInterface globalManagerInterface("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/GammaManager", + "org.ukui.SettingsDaemon.GammaManager"); + + return globalManagerInterface.call(method,arg1,arg2,arg3,arg4); +} + +QDBusMessage Screen::callXrandr(const QString &method, const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4) +{ + QDBusInterface globalManagerInterface("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/xrandr", + "org.ukui.SettingsDaemon.xrandr"); + + return globalManagerInterface.call(method,arg1,arg2,arg3,arg4);; +} + +QDBusMessage Screen::callBrighenss(const QString &method, const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4) +{ + QDBusInterface globalManagerInterface("org.ukui.SettingsDaemon", + "/GlobalBrightness", + "org.ukui.SettingsDaemon.Brightness"); + + + return globalManagerInterface.call(method,arg1,arg2,arg3,arg4); +} + +QDBusMessage Screen::callMediaKeys(const QString &method, const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4) +{ + QDBusInterface mediaKeysInterface("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/MediaKeys", + "org.ukui.SettingsDaemon.MediaKeys"); + + + return mediaKeysInterface.call(method,arg1,arg2,arg3,arg4); +} + +void Screen::serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) +{ + if (name.isEmpty()) { + return; + } + + if (!name.startsWith(UKUI_POWER_MANAGER_DBUS_NAME)) { + //过滤不符合mpris的seivice + return; + } + + if (nullptr != m_pscreen) { + delete m_pscreen; + m_pscreen = nullptr; + } + + m_brightControlByUPM = brightControlByUPM(); + if (Screen::eBrightnessControl::powerManager == m_brightControlByUPM) { + m_pscreen = new ScreenBrightNode(this); + } else if (Screen::eBrightnessControl::gamma == m_brightControlByUPM) { + m_pscreen = new ScreenGamma(this); + } + + disconnect(QDBusConnection::sessionBus().interface(), &QDBusConnectionInterface::serviceOwnerChanged, this, &Screen::serviceOwnerChanged); +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen.h ukui-framework-5.0.0.0/dbus/devices/screen/src/screen.h --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,276 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __SCREEN_H__ +#define __SCREEN_H__ + + +#include "screen_gamma.h" +#include "screen_power.h" + +class Screen: public QObject, QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.Devices.Screen") +public: + enum eScreenMode { + primaryScreenOnlyMode = 0, + mirrorScreenMode, + extensionMode, + secondaryScreenOnlyMode, + showKDS, + ERROR = 0x99}; + + Q_ENUM(eScreenMode) + + enum eBrightnessControl { + unknown = -1,//获取失败,理论上应该不会获取失败,是system的dbus服务 + gamma,//upm不控制背光则优先为gamma控制 + powerManager,//背光由upm控制。 + none};//第三种情况,upm不控制背光并且不支持gamma调节 + + Q_ENUM(eBrightnessControl) + + explicit Screen(QObject *parent = nullptr); + ~Screen(); + +public Q_SLOTS: + /** + * @brief SetScreenBrightness 设置显示器亮度,需要先获取所有显示器的亮度再使用。 + * @param name 显示器名称 + * @param screenBrightness 指定亮度 + * @return + */ + bool SetScreenBrightness(QString name, uint screenBrightness); + + /** + * @brief GetScreenBrightness 获取显示器的亮度 + * @param name + * @return 指定显示器的亮度 + */ + uint GetScreenBrightness(QString name); + + /** + * @brief SetScreensBrightness 分别设置显示器的亮度 + * @param screenMap 显示器亮度与其对应的显示器亮度 + * @return 成功标记 + */ + bool SetScreensBrightness(OutputGammaInfoList outputsInfo); + + /** + * @brief SetAllScreenSameBrightness 设置所有显示为同一个亮度 + * @param brighenss 全部亮度 + * @return 与参数一致 + */ + bool SetAllScreenSameBrightness(uint brightness); + + /** + * @brief GetAllScreenBrightness + * @return 与参数一致 + */ + OutputGammaInfoList GetAllScreenBrightness(); + + /** + * @brief SetPrimaryScreenBrightness 设置主屏亮度 + * @param screenBrightness 指定主屏亮度 + * @return 与参数一致 + */ + bool SetPrimaryScreenBrightness(uint screenBrightness); + + /** + * @brief GetPrimaryScreenBrightness 获取主屏亮度 + * @return 主屏亮度 + */ + uint GetPrimaryScreenBrightness(); + + /** + * @brief increaseBrightness 增加显示器亮度,效果等同于快捷键,目前仅笔记本可用 + * @return + */ + bool IncreaseBuiltinScreenBrightness(); + + /** + * @brief decreaseBuiltinBrightness 降低显示器亮度,效果等同于快捷键,目前仅笔记本可用 + * @return + */ + bool DecreaseBuiltinBrightness(); + /** + * @brief getScreenMode 获取显示器显示模式 + * primaryScreenOnlyMode = 0, 第一屏幕 + * mirrorScreenMode =,镜像屏幕 + * extensionMode,扩展 + * secondaryScreenOnlyMode,第二屏 + * @return 显示模式 + */ + QString GetScreenMode(); + + /** + * @brief setScreenMode 设置显示模式 + * @param mode 指定模式 + * primaryScreenOnlyMode = 0, 第一屏幕 + * mirrorScreenMode =,镜像屏幕 + * extensionMode,扩展 + * secondaryScreenOnlyMode,第二屏 + * @return 设置标记,0失败,1成功 + */ + bool SetScreenMode(const QString &mode); + + /** + * @brief setScreensParam 设置显示器参数 + * @param screenParam 显示器参数组合 + * @return 设置状态 + */ + bool SetScreensParam(const QString &screenParam); + + /** + * @brief getScreensParam 获取显示器状态 + * @return 显示器信息 + */ + QString GetScreensParam(); + + /** + * @brief setColorTemperature + * @param appName + * @param colorTemp + * @return 设置标记,0失败,1成功 + */ + bool SetColorTemperature(QString appName, int colorTemp); + + /** + * @brief setEyeCare 设置护眼模式, + * 0,进入护眼模式 + * 1,退出护眼模式 + * @param state + * @return 设置标记,false 失败,true 成功 + */ + bool SetEyeCareEnabled(bool state); + + /** + * @brief getEyeCare 获取护眼模式 + * @return 护眼模式 + */ + bool IsEyeCareEnabled(); + + /** + * @brief setNightMode 设置夜间模式 + * @param state 夜间模式状态 + * 0:关闭夜间模式 + * 1:开启夜间模式 + * @return 设置标记,0失败,1成功 + */ + bool SetNightModeEnable(bool state); + + /** + * @brief getNightMode 获取是否为夜间模式 + * @return 夜间模式 设置标记,0非夜间模式,1时进入模式 + */ + bool IsNightModeEnable(); + +private: + /** + * @brief brightControlByUPM 获取电源管理是否可以控制亮度 + * @return + */ + eBrightnessControl brightControlByUPM(); + + /** + * @brief watchDbusServer + */ + void watchUpmRegisterDbusServer(); + + QDBusMessage callGamma(const QString &method, + const QVariant &arg1 = QVariant(), + const QVariant &arg2 = QVariant(), + const QVariant &arg3 = QVariant(), + const QVariant &arg4 = QVariant()); + + QDBusMessage callXrandr(const QString &method, + const QVariant &arg1 = QVariant(), + const QVariant &arg2 = QVariant(), + const QVariant &arg3 = QVariant(), + const QVariant &arg4 = QVariant()); + + QDBusMessage callBrighenss(const QString &method, + const QVariant &arg1 = QVariant(), + const QVariant &arg2 = QVariant(), + const QVariant &arg3 = QVariant(), + const QVariant &arg4 = QVariant()); + + QDBusMessage callMediaKeys(const QString &method, + const QVariant &arg1 = QVariant(), + const QVariant &arg2 = QVariant(), + const QVariant &arg3 = QVariant(), + const QVariant &arg4 = QVariant()); + +private Q_SLOTS: + void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); + +private: + ScreenAbstract *m_pscreen = nullptr; + +Q_SIGNALS: + /** + * @brief nightModeChanged 夜间模式变化 + */ + void NightModeChanged(bool); + + /** + * @brief EyeCareChanged 护眼模式变化 + */ + void EyeCareChanged(bool); + + /** + * @brief primaryScreenBrightnessChanged 主屏信号变化 + */ + void PrimaryScreenBrightnessChanged(uint); + + /** + * @brief screenBrightnessChanged 亮度变化信号 + */ + void ScreenBrightnessChanged(QString name,uint brightness); + + /** + * @brief modeChanged 模式改变信号 + * @param mode + */ + void SceenModeChanged(QString mode); + + /** + * @brief paramChanged 显示器参数 + * @param param + */ + void ParamChanged(QString param); + +private: + QString m_screenMode = ""; + QString m_screenParam = ""; + QString m_primaryName = ""; + QMap<QString, int> m_allScreenBright; + + uint8_t m_primaryBright = 0; + uint8_t m_screenCount = 0; + + int m_brightControlByUPM = -1; + + QMetaEnum m_outputModeEnum; + QGSettings *m_pColorGsettings = nullptr; +}; +#endif + diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_abstract.cpp ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_abstract.cpp --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_abstract.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_abstract.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,32 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "screen_abstract.h" + +ScreenAbstract::ScreenAbstract(QObject *parent): + QObject(parent) +{ + qDebug() << "init screenBrightNode"; +} + +ScreenAbstract::~ScreenAbstract() +{ + +} + diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_abstract.h ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_abstract.h --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_abstract.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_abstract.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,67 @@ +#ifndef __SCREEN_ABSTRACT_H__ +#define __SCREEN_ABSTRACT_H__ + +#include <QObject> +#include <QProcess> +#include <QMetaEnum> +#include <QMetaObject> +#include <QtDBus/QtDBus> +#include <QDBusInterface> +#include <QtCore/QCoreApplication> + +#include "screen_define.h" +#include "QGSettings/qgsettings.h" + + +class ScreenAbstract: public QObject, QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "ukui.framework.devices.screen") +public: + + explicit ScreenAbstract(QObject *parent = nullptr); + ~ScreenAbstract(); + + +public: + /** + * @brief setScreenBrightness 设置显示器亮度,需要先获取所有显示器的亮度再使用。 + * @param name 显示器名称 + * @param screenBrightness 指定亮度 + * @return + */ + virtual bool setScreenBrightness(QString name, uint screenBrightness) = 0; + + /** + * @brief getScreenBrightness 获取显示器的亮度 + * @param name + * @return 指定显示器的亮度 + */ + virtual uint getScreenBrightness(QString name) = 0; + + /** + * @brief setAllScreenBrightness 分别设置显示器的亮度 + * @param screenMap 显示器亮度与其对应的显示器亮度 + * @return 成功标记 + */ + virtual bool setScreensBrightness(OutputGammaInfoList outputsInfo) = 0; + + /** + * @brief setAllScreenSameBrightness 设置所有显示为同一个亮度 + * @param brighenss 全部亮度 + * @return 与参数一致 + */ + virtual bool setAllScreenSameBrightness(uint brighenss) = 0; + + /** + * @brief getAllScreenBrightness + * @return 与参数一致 + */ + virtual OutputGammaInfoList getAllScreenBrightness() = 0; + +private: + int brightControlByUPM(); + bool isControlBright(); +}; + +#endif diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_define.h ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_define.h --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_define.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_define.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,46 @@ +#ifndef __SCREEN_DEFINE_H__ +#define __SCREEN_DEFINE_H__ + +#define UKUI_SETTINGS_DAEMON_COLOR_SCHEMA "org.ukui.SettingsDaemon.plugins.color" +#define UKUI_SETTINGS_DAEMON_COLOR_EYS_CARE "eye-care" +#define UKUI_SETTINGS_DAEMON_COLOR_NIGHT_MODE "night-light-enabled" +#define MY_NAME "ukui-framework-screen" +#define UKUI_POWER_MANAGER_DBUS_NAME "org.ukui.powermanagement" +#define UKUI_POWER_MANAGER_DBUS_PATH "/" +#define UKUI_POWER_MANAGER_DBUS_INTERFACE "org.ukui.powermanagement.interface" + +struct OutputGammaInfo{ + QString outputName; + uint gamma; + uint brignthess; + uint temperature; +}; + +typedef QList<OutputGammaInfo> OutputGammaInfoList; + +Q_DECLARE_METATYPE(OutputGammaInfo) +Q_DECLARE_METATYPE(OutputGammaInfoList) + +inline QDBusArgument &operator << (QDBusArgument &argument, const OutputGammaInfo &outputInfo) +{ + argument.beginStructure(); + argument << outputInfo.outputName; + argument << outputInfo.brignthess; + argument << outputInfo.gamma; + argument << outputInfo.temperature; + argument.endStructure(); + + return argument; +} + +inline const QDBusArgument &operator >> (const QDBusArgument &argument, OutputGammaInfo &outputInfo) { + argument.beginStructure(); + argument >> outputInfo.outputName; + argument >> outputInfo.brignthess; + argument >> outputInfo.gamma; + argument >> outputInfo.temperature; + argument.endStructure(); + return argument; +} + +#endif diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_gamma.cpp ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_gamma.cpp --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_gamma.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_gamma.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,98 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "screen_gamma.h" + + +ScreenGamma::ScreenGamma(QObject *parent) +{ + qDebug() << "init screenBrightNode"; +} + +ScreenGamma::~ScreenGamma() +{ + +} + +bool ScreenGamma::setScreenBrightness(QString name, uint screenBrightness) +{ + QDBusReply<int> reply = callGamma("setScreenBrightness", MY_NAME, name, screenBrightness); + if (false == reply.isValid()) { + return false; + } + + return reply.value() >= 0; +} + +uint ScreenGamma::getScreenBrightness(QString name) +{ + QDBusReply<OutputGammaInfoList> reply = callGamma("getScreensGammaList", MY_NAME); + + if (false == reply.isValid()) { + return false; + } + + Q_FOREACH(const OutputGammaInfo info, reply.value()) { + if (info.outputName == name) { + return info.brignthess; + } + } + return -1; +} + +bool ScreenGamma::setScreensBrightness(OutputGammaInfoList outputsInfo) +{ + Q_FOREACH(const OutputGammaInfo &info, outputsInfo) { + callGamma("setScreenBrightness", MY_NAME, info.outputName, info.brignthess); + } + + return true; +} + +bool ScreenGamma::setAllScreenSameBrightness(uint brighenss) +{ + QDBusReply<bool> reply = callGamma("setAllScreenBrightness", MY_NAME, (int)brighenss); + if (false == reply.isValid()) { + qDebug() << reply.error(); + return false; + } + + return reply.value(); +} + +OutputGammaInfoList ScreenGamma::getAllScreenBrightness() +{ + OutputGammaInfoList ret; + + QDBusReply<OutputGammaInfoList> reply = callGamma("getScreensGammaList", MY_NAME); + + if (false == reply.isValid()) { + return ret; + } + return reply.value(); +} + +QDBusMessage ScreenGamma::callGamma(const QString &method, const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4) +{ + QDBusInterface globalManagerInterface("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/GammaManager", + "org.ukui.SettingsDaemon.GammaManager"); + + return globalManagerInterface.call(method,arg1,arg2,arg3,arg4); +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_gamma.h ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_gamma.h --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_gamma.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_gamma.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,58 @@ +#ifndef __SCREEN_GAMMA_H__ +#define __SCREEN_GAMMA_H__ + +#include "screen_abstract.h" + +class ScreenGamma: public ScreenAbstract +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "ukui.framework.devices.screen") +public: + + explicit ScreenGamma(QObject *parent = nullptr); + ~ScreenGamma(); +public: + /** + * @brief setScreenBrightness 设置显示器亮度,需要先获取所有显示器的亮度再使用。 + * @param name 显示器名称 + * @param screenBrightness 指定亮度 + * @return + */ + bool setScreenBrightness(QString name, uint screenBrightness) override; + + /** + * @brief getScreenBrightness 获取显示器的亮度 + * @param name + * @return 指定显示器的亮度 + */ + uint getScreenBrightness(QString name) override; + + /** + * @brief setAllScreenBrightness 分别设置显示器的亮度 + * @param screenMap 显示器亮度与其对应的显示器亮度 + * @return 成功标记 + */ + bool setScreensBrightness(OutputGammaInfoList outputsInfo) override; + + /** + * @brief setAllScreenSameBrightness 设置所有显示为同一个亮度 + * @param brighenss 全部亮度 + * @return 与参数一致 + */ + bool setAllScreenSameBrightness(uint brighenss) override; + + /** + * @brief getAllScreenBrightness + * @return 与参数一致 + */ + OutputGammaInfoList getAllScreenBrightness() override; + +private: + QDBusMessage callGamma(const QString &method, + const QVariant &arg1 = QVariant(), + const QVariant &arg2 = QVariant(), + const QVariant &arg3 = QVariant(), + const QVariant &arg4 = QVariant()); +}; + +#endif diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_power.cpp ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_power.cpp --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_power.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_power.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,56 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "screen_power.h" + +ScreenBrightNode::ScreenBrightNode(QObject *parent) +{ + qDebug() << "init screenBrightNode"; +} + +ScreenBrightNode::~ScreenBrightNode() +{ + +} + +bool ScreenBrightNode::setScreenBrightness(QString name, uint screenBrightness) +{ + return false; +} + +uint ScreenBrightNode::getScreenBrightness(QString name) +{ + return -1; +} + +bool ScreenBrightNode::setScreensBrightness(OutputGammaInfoList outputsInfo) +{ + return false; +} + +bool ScreenBrightNode::setAllScreenSameBrightness(uint brighenss) +{ + return false; +} + +OutputGammaInfoList ScreenBrightNode::getAllScreenBrightness() +{ + OutputGammaInfoList ret; + return ret; +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_power.h ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_power.h --- ukui-framework-4.10.0.0/dbus/devices/screen/src/screen_power.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/src/screen_power.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,52 @@ +#ifndef __SCREEN_POWER_H__ +#define __SCREEN_POWER_H__ + +#include "screen_abstract.h" + +class ScreenBrightNode: public ScreenAbstract +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "ukui.framework.devices.screen") +public: + + explicit ScreenBrightNode(QObject *parent = nullptr); + ~ScreenBrightNode(); + +public: + /** + * @brief setScreenBrightness 设置显示器亮度,需要先获取所有显示器的亮度再使用。 + * @param name 显示器名称 + * @param screenBrightness 指定亮度 + * @return + */ + bool setScreenBrightness(QString name, uint screenBrightness); + + /** + * @brief getScreenBrightness 获取显示器的亮度 + * @param name + * @return 指定显示器的亮度 + */ + uint getScreenBrightness(QString name); + + /** + * @brief setAllScreenBrightness 分别设置显示器的亮度 + * @param screenMap 显示器亮度与其对应的显示器亮度 + * @return 成功标记 + */ + bool setScreensBrightness(OutputGammaInfoList outputsInfo); + + /** + * @brief setAllScreenSameBrightness 设置所有显示为同一个亮度 + * @param brighenss 全部亮度 + * @return 与参数一致 + */ + bool setAllScreenSameBrightness(uint brighenss); + + /** + * @brief getAllScreenBrightness + * @return 与参数一致 + */ + OutputGammaInfoList getAllScreenBrightness(); +}; + +#endif diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/test/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/screen/test/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/screen/test/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/test/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,41 @@ +project(my_qt_app) + + + +find_package(PkgConfig) +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(GIO REQUIRED gio-2.0) +pkg_check_modules(GOBJECT REQUIRED gobject-2.0) + +include_directories(${GLIB_INCLUDE_DIRS}) +include_directories(${GIO_INCLUDE_DIRS}) +include_directories(${GOBJECT_INCLUDE_DIRS}) +include_directories(../src) +cmake_minimum_required(VERSION 3.16) +# 查找Qt5及其模块 +find_package(Qt5 COMPONENTS Core Widgets DBus REQUIRED) + +# 接下来,你可以使用Qt5::Core, Qt5::Widgets, Qt5::DBus来链接你的可执行文件或库 +set(CMAKE_AUTOMOC ON) + +# 示例:添加可执行文件 +add_executable(my_qt_app + test.cpp + ../src/screen.cpp + ../src/QGSettings/qgsettings.cpp + ../src/QGSettings/qconftype.cpp) + + + +target_include_directories(my_qt_app PRIVATE) + +# 链接Qt模块 +target_link_libraries(my_qt_app + Qt5::Core + Qt5::Widgets + Qt5::DBus + glib-2.0 + gio-2.0 + ${GLIB_LIBRARIES} + ${GIO_LIBRARIES} + ${GOBJECT_LIBRARIES}) diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/test/test.cpp ukui-framework-5.0.0.0/dbus/devices/screen/test/test.cpp --- ukui-framework-4.10.0.0/dbus/devices/screen/test/test.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/test/test.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,59 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QDebug> +#include <QDBusError> +#include <QDBusConnection> +#include <QCoreApplication> + +#include "test.h" + +/* + * 测试情况: + * getEyeCare(): 通过 + * getNightMode():通过 + * getPrimaryBrightness():通过 + * getScreenMode():通过 + * getScreensParam()::通过 + * increaseBrightness():通过 + * openDisplaySetting()::通过 + * reduceBrightness()::通过 + * setAllScreenSameBrightness():通过 + * setColorTemperature():未通过 + * setEyeCare():通过 + * setNightMode():通过 + * setPrimaryBrightness():通过,建议异步调用 + * setScreenBrightness():通过, + * setScreenMode():通过, + * setScreensParam():通过, + * +*/ +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc,argv); + Screen *m_screen = new Screen(); + QDBusConnection sessionBug = QDBusConnection::sessionBus(); + if (sessionBug.registerService("org.ukui.SettingsDaemon1")) { + sessionBug.registerObject("/screen", m_screen, + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + } + app.exec(); + return 0; +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/screen/test/test.h ukui-framework-5.0.0.0/dbus/devices/screen/test/test.h --- ukui-framework-4.10.0.0/dbus/devices/screen/test/test.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/screen/test/test.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,11 @@ +#ifndef TEST_H +#define TEST_H + +#ifndef __TEST_H__ +#define __TEST_H__ + +#include "screen.h" + +#endif + +#endif // TEST_H diff -Nru ukui-framework-4.10.0.0/dbus/devices/touchpad/CMakeLists.txt ukui-framework-5.0.0.0/dbus/devices/touchpad/CMakeLists.txt --- ukui-framework-4.10.0.0/dbus/devices/touchpad/CMakeLists.txt 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/touchpad/CMakeLists.txt 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.5) +project(touchpad VERSION 1.0) + +find_package(PkgConfig) + + +include_directories(${GLIB_INCLUDE_DIRS}) +include_directories(${GIO_INCLUDE_DIRS}) +include_directories(${GOBJECT_INCLUDE_DIRS}) + +# 查找Qt5及其模块 +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + +set(CMAKE_AUTOMOC ON) + +file(GLOB LIBTOUCHPAD_SOURCES src/*.cpp) + +add_library(touchpad STATIC ${LIBTOUCHPAD_SOURCES}) + +target_link_libraries(touchpad + PRIVATE + Qt5::Core + Qt5::Widgets + Qt5::DBus) diff -Nru ukui-framework-4.10.0.0/dbus/devices/touchpad/src/touchpad.cpp ukui-framework-5.0.0.0/dbus/devices/touchpad/src/touchpad.cpp --- ukui-framework-4.10.0.0/dbus/devices/touchpad/src/touchpad.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/touchpad/src/touchpad.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,64 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "touchpad.h" + +TouchpadManager::TouchpadManager(QObject *parent): + QObject(parent) +{ + QDBusConnection::sessionBus().connect("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/InputManager", + "org.ukui.SettingsDaemon.InputManager", + "touchpadStateChanged", + this, SLOT(onTouchpadStateChanged(bool))); +} + +TouchpadManager::~TouchpadManager() +{ + +} + +bool TouchpadManager::IsEnable() +{ + QDBusReply<bool> reply = callInputDbus("getTouchpadState"); + if (reply.isValid()) { + return reply.value(); + } + + return false; +} + +void TouchpadManager::Enable(bool state) +{ + callInputDbus("setTouchpadState", state); +} + +void TouchpadManager::onTouchpadStateChanged(bool state) +{ + Q_EMIT EnableChanged(state); +} + +template <typename...Args> +QDBusMessage TouchpadManager::callInputDbus(const QString &method, Args &&...args) +{ + QDBusInterface inputManagerInterface("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/InputManager", + "org.ukui.SettingsDaemon.InputManager"); + return inputManagerInterface.call(method, std::forward<Args>(args)...); +} diff -Nru ukui-framework-4.10.0.0/dbus/devices/touchpad/src/touchpad.h ukui-framework-5.0.0.0/dbus/devices/touchpad/src/touchpad.h --- ukui-framework-4.10.0.0/dbus/devices/touchpad/src/touchpad.h 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/devices/touchpad/src/touchpad.h 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,66 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2024 KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __DEVICES_TOUCHPAD_H__ +#define __DEVICES_TOUCHPAD_H__ + +#include <memory> +#include <QObject> +#include <QProcess> +#include <QMetaEnum> +#include <QMetaObject> +#include <QtDBus/QtDBus> +#include <QDBusInterface> +#include <QtCore/QCoreApplication> + +class TouchpadManager : public QObject { + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.Devices.Touchpad") +public: + explicit TouchpadManager(QObject *parent = nullptr); + ~TouchpadManager(); +public Q_SLOTS: + /** + * @brief IsEnable 获取触摸板状态 + * @return false 关, true开 + */ + bool IsEnable(); + + /** + * @brief Enable 设置触摸板状态 + * @param state false 关闭,true开 + */ + void Enable(bool state); +private Q_SLOTS: + void onTouchpadStateChanged(bool state); + +private: + void connectTouchpadManager(); + + template <typename...Args> + QDBusMessage callInputDbus(const QString &method, Args &&...args); + +Q_SIGNALS: + /** + * @brief EnableChanged 触摸板使能状态改变信号 + */ + void EnableChanged(bool); +}; + +#endif diff -Nru ukui-framework-4.10.0.0/dbus/ui/README.md ukui-framework-5.0.0.0/dbus/ui/README.md --- ukui-framework-4.10.0.0/dbus/ui/README.md 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/dbus/ui/README.md 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,10 @@ +# UI模块 +__说明:__UI模块提供UI相关的接口,用于实现对UI的查询、操作等功能。根据功能分为以下几个模块: +主题模块 +特效模块 +壁纸模块 +## 主题模块(一期实现) + +## 特效模块(一期实现) + +## 壁纸模块(一期实现) diff -Nru ukui-framework-4.10.0.0/debian/changelog ukui-framework-5.0.0.0/debian/changelog --- ukui-framework-4.10.0.0/debian/changelog 2024-06-05 16:45:09.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/changelog 2025-03-25 09:41:05.000000000 +0800 @@ -1,3 +1,72 @@ +ukui-framework (5.0.0.0-ok2.5) huanghe; urgency=medium + + * 需求号:无 + * BUG:无 + * 其他改动说明:#426462(task) 提供实时获取物理键盘状态的接口 + * 其他改动影响域:无 + + -- cxc <chenxuechao@kylinos.cn> Tue, 25 Mar 2025 09:41:05 +0800 + +ukui-framework (5.0.0.0-ok2.4) huanghe; urgency=medium + + * 需求号:无 + * BUG:无 + * 其他改动说明:调整统一接口包名为ukui-framework-dbus + * 其他改动影响域:无 + + -- zhaikangning <zhaikangning@kylinos.cn> Tue, 17 Dec 2024 17:48:25 +0800 + +ukui-framework (5.0.0.0-ok2.3) huanghe; urgency=medium + + * 需求号:无 + * BUG:无 + * 其他改动说明:添加ukui-framework-api包信息和安装脚本 + * 其他改动影响域:无 + + -- zhaikangning <zhaikangning@kylinos.cn> Tue, 10 Dec 2024 10:27:10 +0800 + +ukui-framework (5.0.0.0-ok2.2) huanghe; urgency=medium + + * 需求号:无 + * BUG:无 + * 其他改动说明:修改control文件中build依赖,解决编译错误 + * 其他改动影响域:无 + + -- zhaikangning <zhaikangning@kylinos.cn> Wed, 04 Dec 2024 18:12:32 +0800 + +ukui-framework (5.0.0.0-ok2.1) huanghe; urgency=medium + + * 需求号:无 + * BUG: 无 + * 其他改动说明:在control文件中添加必要的依赖包 + * 其他改动影响域:无 + + -- zhaikangning <zhaikangning@kylinos.cn> Wed, 04 Dec 2024 16:54:22 +0800 + +ukui-framework (5.0.0.0-ok2.0) huanghe; urgency=medium + + * 需求号:33931 UKUI Framework统一接口一期开发 + * BUG: 无 + * 其他改动说明:新增主题、壁纸、字体、特效相关的查询配置接口和属性、信号 + * 其他改动影响域:无 + + -- zhaikangning <zhaikangning@kylinos.cn> Tue, 26 Nov 2024 10:48:42 +0800 + +ukui-framework (5.0.0.0-ok1.1) huanghe; urgency=medium + + * rebuild + + -- zhaikangning <zhaikangning@kylinos.cn> Wed, 20 Nov 2024 13:37:27 +0800 + +ukui-framework (5.0.0.0-ok1) huanghe; urgency=medium + + * 需求号:33931 UKUI Framework统一接口一期开发 + * BUG: 无 + * 其他改动说明:无 + * 其他改动影响域:无 + + -- zhaikangning <zhaikangning@kylinos.cn> Wed, 20 Nov 2024 11:39:56 +0800 + ukui-framework (4.10.0.0-ok2) nile; urgency=medium * Drop ukui-session-wayland and kwin-wayland. diff -Nru ukui-framework-4.10.0.0/debian/control ukui-framework-5.0.0.0/debian/control --- ukui-framework-4.10.0.0/debian/control 2024-06-05 16:45:09.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/control 2025-03-25 09:41:05.000000000 +0800 @@ -1,10 +1,17 @@ Source: ukui-framework -Section: x11 +Section: utils Priority: optional Maintainer: UKUI Sig <ukui@lists.openkylin.top> Uploaders: handsome_feng <jianfengli@ubuntukylin.com>, xibowen <xibowen@kylinos.cn> -Build-Depends: debhelper-compat (= 12), lsb-release + zhaikangning <zhaikangning@kylinos.cn> +Build-Depends: debhelper-compat (= 12), + lsb-release, + cmake, + pkgconf, + libgsettings-qt-dev, + qtbase5-dev, + libglib2.0-dev, Standards-Version: 4.6.1.0 Rules-Requires-Root: no Homepage: https://gitee.com/openkylin/ukui-framework @@ -13,7 +20,8 @@ Package: ukui-framework Architecture: all -Depends: kwin-x11, +Depends: debhelper-compat (=11), + kwin-x11, openkylin-theme, peony, qt5-ukui-platformtheme, @@ -26,3 +34,9 @@ ukui-sidebar, ${misc:Depends} Description: UKUI Framework + +Package: ukui-framework-dbus +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: The UKUI Framework API provides the ability for UKUI or third-party applications to have a desktop environment available + Making it easy for UKUI or third-party applications to operate within the UKUI desktop environment diff -Nru ukui-framework-4.10.0.0/debian/patches/0001-32-upstream.patch ukui-framework-5.0.0.0/debian/patches/0001-32-upstream.patch --- ukui-framework-4.10.0.0/debian/patches/0001-32-upstream.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/patches/0001-32-upstream.patch 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,1771 @@ +From: zhaikangning <857458455@qq.com> +Date: Tue, 26 Nov 2024 02:45:46 +0000 +Subject: =?utf-8?b?ITMyIOWQjOatpXVwc3RyZWFt77yM5paw5aKe5Li76aKY44CB5aOB57q4?= + =?utf-8?b?44CB5a2X5L2T44CB54m55pWI5o6l5Y+jIE1lcmdlIHB1bGwgcmVxdWVzdCAhMzIg?= + =?utf-8?b?ZnJvbSB6aGFpa2FuZ25pbmcvdXBzdHJlYW0=?= + +--- + CMakeLists.txt | 11 +- + common.h | 1 + + dbus/CMakeLists.txt | 4 + + dbus/ui/CMakeLists.txt | 4 + + dbus/ui/background/CMakeLists.txt | 29 ++ + dbus/ui/background/background.cpp | 181 +++++++++++++ + dbus/ui/background/background.h | 87 ++++++ + dbus/ui/effect/CMakeLists.txt | 29 ++ + dbus/ui/effect/effect.cpp | 131 +++++++++ + dbus/ui/effect/effect.h | 82 ++++++ + dbus/ui/font/CMakeLists.txt | 29 ++ + dbus/ui/font/font.cpp | 121 +++++++++ + dbus/ui/font/font.h | 81 ++++++ + dbus/ui/theme/CMakeLists.txt | 29 ++ + dbus/ui/theme/theme.cpp | 549 ++++++++++++++++++++++++++++++++++++++ + dbus/ui/theme/theme.h | 222 +++++++++++++++ + main.cpp | 12 + + 17 files changed, 1601 insertions(+), 1 deletion(-) + create mode 100644 dbus/ui/CMakeLists.txt + create mode 100644 dbus/ui/background/CMakeLists.txt + create mode 100644 dbus/ui/background/background.cpp + create mode 100644 dbus/ui/background/background.h + create mode 100644 dbus/ui/effect/CMakeLists.txt + create mode 100644 dbus/ui/effect/effect.cpp + create mode 100644 dbus/ui/effect/effect.h + create mode 100644 dbus/ui/font/CMakeLists.txt + create mode 100644 dbus/ui/font/font.cpp + create mode 100644 dbus/ui/font/font.h + create mode 100644 dbus/ui/theme/CMakeLists.txt + create mode 100644 dbus/ui/theme/theme.cpp + create mode 100644 dbus/ui/theme/theme.h + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 3b56318..214238d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -24,6 +24,11 @@ include_directories(dbus/devices/bluetooth/src) + include_directories(dbus/devices/power/src) + include_directories(dbus/devices/touchpad/src) + ++include_directories(dbus/ui/background) ++include_directories(dbus/ui/effect) ++include_directories(dbus/ui/font) ++include_directories(dbus/ui/theme) ++ + add_executable(ukui-framework + main.cpp + ) +@@ -37,4 +42,8 @@ target_link_libraries(ukui-framework + network + bluetooth + power +- touchpad) ++ touchpad ++ theme ++ background ++ font ++ effect) +diff --git a/common.h b/common.h +index a4c0de4..1b390c8 100644 +--- a/common.h ++++ b/common.h +@@ -49,6 +49,7 @@ const QString UI_PATH = "/org/ukui/Framework/UI"; + const QString UI_THEME_PATH = "/org/ukui/Framework/UI/Theme"; + const QString UI_WALLPAPER_PATH = "/org/ukui/Framework/UI/Wallpaper"; + const QString UI_EFFECTS_PATH = "/org/ukui/Framework/UI/Effects"; ++const QString UI_FONT_PATH = "/org/ukui/Framework/UI/Font"; + + // Media + const QString MEDIA_PATH = "/org/ukui/Framework/Media"; +diff --git a/dbus/CMakeLists.txt b/dbus/CMakeLists.txt +index cdc82a9..964e601 100644 +--- a/dbus/CMakeLists.txt ++++ b/dbus/CMakeLists.txt +@@ -3,3 +3,7 @@ find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + add_subdirectory(devices) + + aux_source_directory(SOURCES devices/README.md) ++ ++add_subdirectory(ui) ++ ++aux_source_directory(SOURCES ui/README.md) +diff --git a/dbus/ui/CMakeLists.txt b/dbus/ui/CMakeLists.txt +new file mode 100644 +index 0000000..c0d1904 +--- /dev/null ++++ b/dbus/ui/CMakeLists.txt +@@ -0,0 +1,4 @@ ++add_subdirectory(theme) ++add_subdirectory(background) ++add_subdirectory(font) ++add_subdirectory(effect) +diff --git a/dbus/ui/background/CMakeLists.txt b/dbus/ui/background/CMakeLists.txt +new file mode 100644 +index 0000000..fc15831 +--- /dev/null ++++ b/dbus/ui/background/CMakeLists.txt +@@ -0,0 +1,29 @@ ++cmake_minimum_required(VERSION 3.14) ++ ++project(background LANGUAGES CXX) ++ ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++set(CMAKE_AUTOUIC ON) ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTORCC ON) ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++find_package(PkgConfig REQUIRED) ++find_package(QT NAMES Qt6 Qt5 COMPONENTS Gui DBus REQUIRED) ++find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui DBus REQUIRED) ++ ++pkg_check_modules(GIO REQUIRED gio-2.0) ++pkg_check_modules(QGSettings REQUIRED gsettings-qt) ++ ++include_directories( ++ ${GIO_INCLUDE_DIRS} ++ ${QGSETTINGS_INCLUDE_DIRS} ++) ++ ++add_library(background STATIC ++ background.cpp ++ background.h ++) ++ ++target_link_libraries(background PRIVATE Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::DBus gio-2.0 ${QGSETTINGS_LIBRARIES}) +diff --git a/dbus/ui/background/background.cpp b/dbus/ui/background/background.cpp +new file mode 100644 +index 0000000..5c977af +--- /dev/null ++++ b/dbus/ui/background/background.cpp +@@ -0,0 +1,181 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#include "background.h" ++ ++#include <QImageReader> ++ ++#include <QGSettings/QGSettings> ++ ++#undef signals ++#include <gio/gio.h> ++ ++//决定如何显示墙纸文件名指定的图片。可用的值有:居中、拉伸、填充、平铺、适应、跨区 ++const QStringList supportOptions = {"centered", "stretched", "scaled", "wallpaper", "zoom", "spanned"}; ++ ++QByteArray g_bgSettingsSchema = "org.ukui.interface"; ++ ++bool g_backgroundServiceAvailable = true; ++ ++Background::Background(QObject *parent) ++ : QObject{parent} ++{ ++ if (QGSettings::isSchemaInstalled(g_bgSettingsSchema)) { ++ if (QGSettings::isSchemaInstalled("org.mate.background")) { ++ // 壁纸设置兼容 ++ // 如果是旧版本的ukui,需要监听org.mate.background ++ g_bgSettingsSchema = "org.mate.background"; ++ } ++ auto settings = new QGSettings(g_bgSettingsSchema); ++ settings->setParent(this); ++ BackgroundFile = settings->get("pictureFilename").toString(); ++ BackgroundOption = settings->get("pictureOptions").toString(); ++ ++ connect(settings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "pictureFilename") { ++ BackgroundFile = settings->get("pictureFilename").toString(); ++ emit BackgroundFileChanged(); ++ } else if (key == "pictureOptions") { ++ BackgroundOption = settings->get("pictureOptions").toString(); ++ emit BackgroundOptionChanged(); ++ } ++ }); ++ } else { ++ // 如果没有org.ukui.interface则使用org.mate.background ++ if (QGSettings::isSchemaInstalled("org.mate.background")) { ++ // 监听org.mate.background ++ g_bgSettingsSchema = "org.mate.background"; ++ ++ auto settings = new QGSettings(g_bgSettingsSchema); ++ settings->setParent(this); ++ BackgroundFile = settings->get("pictureFilename").toString(); ++ BackgroundOption = settings->get("pictureOptions").toString(); ++ ++ connect(settings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "pictureFilename") { ++ BackgroundFile = settings->get("pictureFilename").toString(); ++ emit BackgroundFileChanged(); ++ } else if (key == "pictureOptions") { ++ BackgroundOption = settings->get("pictureOptions").toString(); ++ emit BackgroundOptionChanged(); ++ } ++ }); ++ } else { ++ // 设置壁纸功能不可用 ++ g_backgroundServiceAvailable = false; ++ } ++ } ++} ++ ++Background::~Background() ++{ ++ ++} ++ ++const QString Background::GetBackgroundFile() const ++{ ++ if (!g_backgroundServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Background service is not available")); ++ } ++ } ++ return BackgroundFile; ++} ++ ++bool Background::SetBackgroundFile(const QString &filePath) ++{ ++ if (!g_backgroundServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Background service is not available")); ++ } ++ return false; ++ } ++ ++ if (BackgroundFile == filePath) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::Failed, tr("Can not set background repeatly")); ++ } ++ return false; ++ } ++ ++ QImageReader imgReader(filePath); ++ if (!imgReader.canRead()) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::NotSupported, tr("Can not read image from: %1").arg(filePath)); ++ } ++ return false; ++ } ++ ++ g_autoptr (GSettings) scopedSettings = g_settings_new(g_bgSettingsSchema.constData()); ++ if (g_settings_set_string(scopedSettings, "picture-filename", filePath.toLocal8Bit().constData())) { ++ return true; ++ } ++ ++ return false; ++} ++ ++const QStringList Background::GetSupportedBackgroundOptions() ++{ ++ if (!g_backgroundServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Background service is not available")); ++ } ++ } ++ return supportOptions; ++} ++ ++const QString Background::GetBackgroundOption() const ++{ ++ if (!g_backgroundServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Background service is not available")); ++ } ++ } ++ return BackgroundOption; ++} ++ ++bool Background::SetBackgroundOption(const QString &option) ++{ ++ if (!g_backgroundServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Background service is not available")); ++ } ++ return false; ++ } ++ ++ if (BackgroundOption == option) ++ return false; ++ ++ if (supportOptions.contains(option)) { ++ g_autoptr (GSettings) scopedSettings = g_settings_new(g_bgSettingsSchema.constData()); ++ if (g_settings_set_string(scopedSettings, "picture-options", option.toLocal8Bit().constData())) { ++ return true; ++ } ++ } else { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidArgs, tr("Invalid background option: %s, support options: [%1]").arg(supportOptions.join(", "))); ++ } ++ return false; ++ } ++ ++ return false; ++} +diff --git a/dbus/ui/background/background.h b/dbus/ui/background/background.h +new file mode 100644 +index 0000000..8f5e87b +--- /dev/null ++++ b/dbus/ui/background/background.h +@@ -0,0 +1,87 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#ifndef BACKGROUND_H ++#define BACKGROUND_H ++ ++#include <QObject> ++#include <QDBusContext> ++ ++class Background : public QObject, protected QDBusContext ++{ ++ Q_OBJECT ++ Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.UI.Backgroud") ++public: ++ explicit Background(QObject *parent = nullptr); ++ ~Background(); ++ ++public slots: ++ /** ++ * @brief GetBackgroundFile ++ * 获取当前壁纸所在路径 ++ * @return ++ */ ++ Q_INVOKABLE const QString GetBackgroundFile() const; ++ ++ /** ++ * @brief SetBackgroundFile ++ * 设置壁纸路径 ++ * @param filePath ++ * @return ++ */ ++ Q_INVOKABLE bool SetBackgroundFile(const QString &filePath); ++ ++ /** ++ * @brief GetSupportedBackgroundOptions ++ * 获取当前支持的壁纸选项 ++ * @return ++ */ ++ Q_INVOKABLE const QStringList GetSupportedBackgroundOptions(); ++ ++ /** ++ * @brief GetBackgroundOption ++ * 获取当前壁纸选项 ++ * @return ++ */ ++ Q_INVOKABLE const QString GetBackgroundOption() const; ++ ++ /** ++ * @brief SetBackgroundOption ++ * 设置壁纸选项 ++ * @param option ++ * @return ++ */ ++ Q_INVOKABLE bool SetBackgroundOption(const QString &option); ++ ++signals: ++ void BackgroundFileChanged(); ++ ++ void BackgroundOptionChanged(); ++ ++private: ++ QString BackgroundFile; ++ QString BackgroundOption; ++ Q_PROPERTY(QString BackgroundFile READ GetBackgroundFile WRITE SetBackgroundFile NOTIFY BackgroundFileChanged) ++ Q_PROPERTY(QString BackgroundOption READ GetBackgroundOption WRITE SetBackgroundOption NOTIFY BackgroundOptionChanged) ++}; ++ ++#endif // BACKGROUND_H +diff --git a/dbus/ui/effect/CMakeLists.txt b/dbus/ui/effect/CMakeLists.txt +new file mode 100644 +index 0000000..b35cc47 +--- /dev/null ++++ b/dbus/ui/effect/CMakeLists.txt +@@ -0,0 +1,29 @@ ++cmake_minimum_required(VERSION 3.14) ++ ++project(effect LANGUAGES CXX) ++ ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++set(CMAKE_AUTOUIC ON) ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTORCC ON) ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++find_package(PkgConfig REQUIRED) ++find_package(QT NAMES Qt6 Qt5 COMPONENTS Gui DBus REQUIRED) ++find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui DBus REQUIRED) ++ ++pkg_check_modules(GIO REQUIRED gio-2.0) ++pkg_check_modules(QGSettings REQUIRED gsettings-qt) ++ ++include_directories( ++ ${GIO_INCLUDE_DIRS} ++ ${QGSETTINGS_INCLUDE_DIRS} ++) ++ ++add_library(effect STATIC ++ effect.cpp ++ effect.h ++) ++ ++target_link_libraries(effect PRIVATE Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::DBus gio-2.0 ${QGSETTINGS_LIBRARIES}) +diff --git a/dbus/ui/effect/effect.cpp b/dbus/ui/effect/effect.cpp +new file mode 100644 +index 0000000..2ad8af3 +--- /dev/null ++++ b/dbus/ui/effect/effect.cpp +@@ -0,0 +1,131 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#include "effect.h" ++ ++#include <QGSettings/QGSettings> ++ ++#undef signals ++#include <gio/gio.h> ++ ++bool g_effectServiceAvailable = true; ++ ++Effect::Effect(QObject *parent) ++ : QObject{parent} ++{ ++ if (QGSettings::isSchemaInstalled("org.ukui.control-center.personalise")) { ++ auto settings = new QGSettings("org.ukui.control-center.personalise"); ++ ++ qreal transparency = settings->get("transparency").toReal(); ++ WindowOpacity = transparency * 100; ++ ++ WindowBlur = settings->get("effect").toBool(); ++ ++ connect(settings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "transparency") { ++ qreal transparency = settings->get("transparency").toReal(); ++ WindowOpacity = transparency * 100; ++ emit WindowOpacityChanged(); ++ } else if (key == "effect") { ++ WindowBlur = settings->get("effect").toBool(); ++ emit WindowBlurChanged(); ++ } ++ }); ++ } else { ++ // 特效服务不可用 ++ g_effectServiceAvailable = false; ++ } ++} ++ ++Effect::~Effect() ++{ ++ ++} ++ ++int Effect::GetWindowOpacity() const ++{ ++ if (!g_effectServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Effect service is not available")); ++ } ++ } ++ return WindowOpacity; ++} ++ ++bool Effect::SetWindowOpacity(int opacity) ++{ ++ if (!g_effectServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Effect service is not available")); ++ } ++ return false; ++ } ++ ++ if (WindowOpacity == opacity) ++ return false; ++ ++ if (WindowOpacity < 0 || WindowOpacity > 100) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidArgs, tr("Invalid opacity, must be in range [0, 100]")); ++ } ++ return false; ++ } ++ ++ qreal transparency; ++ transparency = opacity/100.0; ++ g_autoptr (GSettings) scopedSettings = g_settings_new("org.ukui.control-center.personalise"); ++ if (g_settings_set_double(scopedSettings, "transparency", transparency)) { ++ return true; ++ } ++ ++ return false; ++} ++ ++bool Effect::GetWindowBlur() const ++{ ++ if (!g_effectServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Effect service is not available")); ++ } ++ } ++ return WindowBlur; ++} ++ ++bool Effect::SetWindowBlur(bool blur) ++{ ++ if (!g_effectServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Effect service is not available")); ++ } ++ return false; ++ } ++ ++ if (WindowBlur == blur) ++ return false; ++ ++ g_autoptr (GSettings) scopedSettings = g_settings_new("org.ukui.control-center.personalise"); ++ if (g_settings_set_boolean(scopedSettings, "effect", true)) { ++ return true; ++ } ++ ++ return false; ++} +diff --git a/dbus/ui/effect/effect.h b/dbus/ui/effect/effect.h +new file mode 100644 +index 0000000..bd151ad +--- /dev/null ++++ b/dbus/ui/effect/effect.h +@@ -0,0 +1,82 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#ifndef EFFECT_H ++#define EFFECT_H ++ ++#include <QObject> ++#include <QDBusContext> ++ ++class Effect : public QObject, protected QDBusContext ++{ ++ Q_OBJECT ++ Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.UI.Effect") ++public: ++ explicit Effect(QObject *parent = nullptr); ++ ~Effect(); ++ ++public slots: ++ /** ++ * @brief GetWindowOpacity ++ * 获取系统应用窗口透明部分的透明度 ++ * @return ++ */ ++ Q_INVOKABLE int GetWindowOpacity() const; ++ ++ /** ++ * @brief SetWindowOpacity ++ * 设置系统应用窗口透明部分的透明度 ++ * @param opacity ++ * @return ++ */ ++ Q_INVOKABLE bool SetWindowOpacity(int opacity); ++ ++ /** ++ * @brief GetWindowBlur ++ * 获取当前窗口背景模糊特效开启状态 ++ * @return ++ * true为开启,false为关闭 ++ */ ++ Q_INVOKABLE bool GetWindowBlur() const; ++ ++ /** ++ * @brief SetWindowBlur ++ * 设置当前窗口背景模糊特效是否开启 ++ * @param blur ++ * @return ++ */ ++ Q_INVOKABLE bool SetWindowBlur(bool blur); ++ ++signals: ++ void WindowOpacityChanged(); ++ ++ void WindowBlurChanged(); ++ ++private: ++ int WindowOpacity = 100; ++ bool WindowBlur = false; ++ ++ Q_PROPERTY(int WindowOpacity READ GetWindowOpacity WRITE SetWindowOpacity NOTIFY WindowOpacityChanged) ++ Q_PROPERTY(bool WindowBlur READ GetWindowBlur WRITE SetWindowBlur NOTIFY WindowBlurChanged) ++}; ++ ++#endif // EFFECT_H +diff --git a/dbus/ui/font/CMakeLists.txt b/dbus/ui/font/CMakeLists.txt +new file mode 100644 +index 0000000..a3da291 +--- /dev/null ++++ b/dbus/ui/font/CMakeLists.txt +@@ -0,0 +1,29 @@ ++cmake_minimum_required(VERSION 3.14) ++ ++project(font LANGUAGES CXX) ++ ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++set(CMAKE_AUTOUIC ON) ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTORCC ON) ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++find_package(PkgConfig REQUIRED) ++find_package(QT NAMES Qt6 Qt5 COMPONENTS Gui DBus REQUIRED) ++find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui DBus REQUIRED) ++ ++pkg_check_modules(GIO REQUIRED gio-2.0) ++pkg_check_modules(QGSettings REQUIRED gsettings-qt) ++ ++include_directories( ++ ${GIO_INCLUDE_DIRS} ++ ${QGSETTINGS_INCLUDE_DIRS} ++) ++ ++add_library(font STATIC ++ font.cpp ++ font.h ++) ++ ++target_link_libraries(font PRIVATE Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::DBus gio-2.0 ${QGSETTINGS_LIBRARIES}) +diff --git a/dbus/ui/font/font.cpp b/dbus/ui/font/font.cpp +new file mode 100644 +index 0000000..86fc4bb +--- /dev/null ++++ b/dbus/ui/font/font.cpp +@@ -0,0 +1,121 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#include "font.h" ++ ++#include <QGSettings/QGSettings> ++ ++#undef signals ++#include <gio/gio.h> ++ ++bool g_fontServiceAvailable = true; ++ ++Font::Font(QObject *parent) ++ : QObject{parent} ++{ ++ if (QGSettings::isSchemaInstalled("org.ukui.style")) { ++ auto settings = new QGSettings("org.ukui.style"); ++ settings->setParent(this); ++ ++ FontFamily = settings->get("systemFont").toString(); ++ FontSize = settings->get("systemFontSize").toInt(); ++ ++ connect(settings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "systemFont") { ++ FontFamily = settings->get("systemFont").toString(); ++ emit FontFamilyChanged(); ++ } else if (key == "systemFontSize") { ++ FontSize = settings->get("systemFontSize").toInt(); ++ emit FontSizeChanged(); ++ } ++ }); ++ } else { ++ // 字体服务不可用 ++ g_fontServiceAvailable = false; ++ } ++} ++ ++Font::~Font() ++{ ++ ++} ++ ++const QString Font::GetFontFamily() const ++{ ++ if (!g_fontServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Font service is not available")); ++ } ++ } ++ return FontFamily; ++} ++ ++bool Font::SetFontFamily(const QString &family) ++{ ++ if (!g_fontServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Font service is not available")); ++ } ++ return false; ++ } ++ ++ if (FontFamily == family) ++ return false; ++ ++ g_autoptr (GSettings) scopedSettings = g_settings_new("org.ukui.style"); ++ if (g_settings_set_string(scopedSettings, "system-font", family.toLocal8Bit().constData())) { ++ return true; ++ } ++ ++ return false; ++} ++ ++int Font::GetFontSize() const ++{ ++ if (!g_fontServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Font service is not available")); ++ } ++ } ++ return FontSize; ++} ++ ++bool Font::SetFontSize(int size) ++{ ++ if (!g_fontServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Font service is not available")); ++ } ++ return false; ++ } ++ ++ if (FontSize == size) ++ return false; ++ ++ g_autoptr (GSettings) scopedSettings = g_settings_new("org.ukui.style"); ++ QString sizeString = QString::number(size); ++ if (g_settings_set_string(scopedSettings, "system-font-size", sizeString.toLocal8Bit().constData())) { ++ return true; ++ } ++ ++ return false; ++} +diff --git a/dbus/ui/font/font.h b/dbus/ui/font/font.h +new file mode 100644 +index 0000000..2528535 +--- /dev/null ++++ b/dbus/ui/font/font.h +@@ -0,0 +1,81 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#ifndef FONT_H ++#define FONT_H ++ ++#include <QObject> ++#include <QDBusContext> ++ ++class Font : public QObject, protected QDBusContext ++{ ++ Q_OBJECT ++ Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.UI.Font") ++public: ++ explicit Font(QObject *parent = nullptr); ++ ~Font(); ++ ++public slots: ++ /** ++ * @brief GetFontFamily ++ * 获取当前字体 ++ * @return ++ */ ++ Q_INVOKABLE const QString GetFontFamily() const; ++ ++ /** ++ * @brief SetFontFamily ++ * 设置当前字体 ++ * @param family ++ * @return ++ */ ++ Q_INVOKABLE bool SetFontFamily(const QString &family); ++ ++ /** ++ * @brief GetFontSize ++ * 获取当前字体大小 ++ * @return ++ */ ++ Q_INVOKABLE int GetFontSize() const; ++ ++ /** ++ * @brief SetFontSize ++ * 设置当前字体大小 ++ * @param size ++ * @return ++ */ ++ Q_INVOKABLE bool SetFontSize(int size); ++ ++signals: ++ void FontFamilyChanged(); ++ ++ void FontSizeChanged(); ++ ++private: ++ QString FontFamily = "Noto Sans CJK SC"; ++ int FontSize = 11; ++ ++ Q_PROPERTY(QString FontFamily READ GetFontFamily WRITE SetFontFamily NOTIFY FontFamilyChanged) ++ Q_PROPERTY(int FontSize READ GetFontSize WRITE SetFontSize NOTIFY FontSizeChanged) ++}; ++ ++#endif // FONT_H +diff --git a/dbus/ui/theme/CMakeLists.txt b/dbus/ui/theme/CMakeLists.txt +new file mode 100644 +index 0000000..792e4be +--- /dev/null ++++ b/dbus/ui/theme/CMakeLists.txt +@@ -0,0 +1,29 @@ ++cmake_minimum_required(VERSION 3.14) ++ ++project(theme LANGUAGES CXX) ++ ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++set(CMAKE_AUTOUIC ON) ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTORCC ON) ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++find_package(PkgConfig REQUIRED) ++find_package(QT NAMES Qt6 Qt5 COMPONENTS Gui DBus REQUIRED) ++find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui DBus REQUIRED) ++ ++pkg_check_modules(GIO REQUIRED gio-2.0) ++pkg_check_modules(QGSettings REQUIRED gsettings-qt) ++ ++include_directories( ++ ${GIO_INCLUDE_DIRS} ++ ${QGSETTINGS_INCLUDE_DIRS} ++) ++ ++add_library(theme STATIC ++ theme.cpp ++ theme.h ++) ++ ++target_link_libraries(theme PRIVATE Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::DBus gio-2.0 ${QGSETTINGS_LIBRARIES}) +diff --git a/dbus/ui/theme/theme.cpp b/dbus/ui/theme/theme.cpp +new file mode 100644 +index 0000000..6860444 +--- /dev/null ++++ b/dbus/ui/theme/theme.cpp +@@ -0,0 +1,549 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#include "theme.h" ++ ++#include <QProcess> ++#include <QStringList> ++ ++#include <QGSettings/QGSettings> ++ ++#undef signals ++#include <gio/gio.h> ++ ++#define QT_SETTINGS_SCHEMA_ID "org.ukui.style" ++#define GTK_SETTINGS_SCHEMA_ID "org.mate.interface" ++#define GLOBAL_SETTINGS_SCHEMA_ID "org.ukui.globaltheme.settings" ++ ++// 自动主题设置 ++#define AUTO_SCHEMA "org.ukui.SettingsDaemon.plugins.color" ++#define COLOR_KEY_AUTO_THEME "theme-schedule-automatic" ++ ++#define CURSOR_THEME_SCHEMA "org.ukui.peripherals-mouse" ++ ++#define KEY_SOUNDS_SCHEMA "org.ukui.sound" ++ ++const QStringList g_themes = {"Light-Seeking", "HeYin", "Classic"}; ++ ++const QStringList g_iconThemes = {"ukui-icon-theme-default", "ukui-icon-theme-fashion", "ukui-icon-theme-classical"}; ++ ++const QStringList g_cursorThemes = {"dark-sense", "DMZ-White", "blue-crystal"}; ++ ++const QStringList g_soundThemes = {"Light-Seeking", "HeYin", "Classic"}; ++ ++static bool g_selfAdaptedMode = false; ++ ++bool g_themeServiceAvailable = true; ++ ++// 临时切换实现,需要将GlobalTheme的机制从控制面板中迁移到后端服务,通过后端服务进行切换 ++void unstableSwitchGlobalTheme(int themeIndex) { ++ g_autoptr (GSettings) scopedQtSettings = g_settings_new(QT_SETTINGS_SCHEMA_ID); ++ g_autoptr (GSettings) scopedGtkSettings = g_settings_new(GTK_SETTINGS_SCHEMA_ID); ++ g_autoptr (GSettings) scopedBgSettings = g_settings_new("org.mate.background"); ++ g_autoptr (GSettings) scopedCursorSettings = g_settings_new(CURSOR_THEME_SCHEMA); ++ g_autoptr (GSettings) scopedUKUIIfaceSettings = g_settings_new("org.ukui.interface"); ++ ++ bool shouldChange = false; ++ QString wallpaperPath; ++ QString iconThemeName; ++ QString qtColor; ++ QString gtkColor; ++ QString qtWidgetTheme; ++ QString qtStyleName; ++ QString gtkStyleName; ++ QString cursorTheme; ++ int windowRadius = 0; ++ ++ switch (themeIndex) { ++ case 0: { ++ shouldChange = true; ++ wallpaperPath = "/usr/share/backgrounds/1-openkylin.jpg"; ++ iconThemeName = "ukui-icon-theme-default"; ++ qtColor = "daybreakBlue"; ++ gtkColor = "#3790FA"; ++ qtStyleName = "ukui-light"; ++ qtWidgetTheme = "default"; ++ gtkStyleName = "ukui-white"; ++ cursorTheme = "dark-sense"; ++ windowRadius = 12; ++ break; ++ } ++ case 1: { ++ shouldChange = true; ++ wallpaperPath = "/usr/share/backgrounds/heyin.png"; ++ iconThemeName = "ukui-icon-theme-fashion"; ++ qtColor = "jamPurple"; ++ gtkColor = "#6A287E"; ++ qtStyleName = "ukui-dark"; ++ qtWidgetTheme = "fashion"; ++ gtkStyleName = "ukui-black"; ++ cursorTheme = "DMZ-White"; ++ windowRadius = 12; ++ break; ++ } ++ case 2: { ++ shouldChange = true; ++ wallpaperPath = "/usr/share/backgrounds/water.jpg"; ++ iconThemeName = "ukui-icon-theme-classical"; ++ qtColor = "daybreakBlue"; ++ gtkColor = "#3790FA"; ++ qtStyleName = "ukui-light"; ++ qtWidgetTheme = "classical"; ++ gtkStyleName = "ukui-white"; ++ cursorTheme = "dark-sense"; ++ windowRadius = 0; ++ break; ++ } ++ default: ++ return; ++ } ++ ++ g_settings_set_string(scopedQtSettings, "widget-theme-name", qtWidgetTheme.toLocal8Bit().constData()); ++ g_settings_set_string(scopedQtSettings, "style-name", qtStyleName.toLocal8Bit().constData()); ++ g_settings_set_string(scopedQtSettings, "icon-theme-name", iconThemeName.toLocal8Bit().constData()); ++ g_settings_set_string(scopedQtSettings, "theme-color", qtColor.toLocal8Bit().constData()); ++ g_settings_set_int(scopedQtSettings, "window-radius", windowRadius); ++ ++ g_settings_set_string(scopedGtkSettings, "gtk-theme", gtkStyleName.toLocal8Bit().constData()); ++ g_settings_set_string(scopedGtkSettings, "icon-theme", iconThemeName.toLocal8Bit().constData()); ++ ++ g_settings_set_string(scopedUKUIIfaceSettings, "primary-color", gtkColor.toLocal8Bit().constData()); ++ ++ g_settings_set_string(scopedBgSettings, "picture-filename", wallpaperPath.toLocal8Bit().constData()); ++ ++ g_settings_set_string(scopedCursorSettings, "cursor-theme", cursorTheme.toLocal8Bit().constData()); ++} ++ ++Theme::Theme(QObject *parent): ++ QObject(parent) ++{ ++ if (!QGSettings::isSchemaInstalled(GLOBAL_SETTINGS_SCHEMA_ID) || !QGSettings::isSchemaInstalled(QT_SETTINGS_SCHEMA_ID) ++ || !QGSettings::isSchemaInstalled(AUTO_SCHEMA) || !QGSettings::isSchemaInstalled(GTK_SETTINGS_SCHEMA_ID) || ++ !QGSettings::isSchemaInstalled(CURSOR_THEME_SCHEMA) || !QGSettings::isSchemaInstalled(KEY_SOUNDS_SCHEMA)) { ++ g_themeServiceAvailable = false; ++ return; ++ } ++ ++ auto globalThemeSettings = new QGSettings(GLOBAL_SETTINGS_SCHEMA_ID); ++ globalThemeSettings->setParent(this); ++ GlobalThemeName = globalThemeSettings->get("globalThemeName").toString(); ++ UserCustomized = globalThemeSettings->get("isModified").toBool(); ++ connect(globalThemeSettings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "globalThemeName") { ++ GlobalThemeName = globalThemeSettings->get("globalThemeName").toString(); ++ emit GlobalThemeNameChanged(); ++ } else if (key == "isModified") { ++ UserCustomized = globalThemeSettings->get("isModified").toBool(); ++ emit UserCustomizedChanged(); ++ } ++ }); ++ ++ auto qtSettings = new QGSettings(QT_SETTINGS_SCHEMA_ID); ++ qtSettings->setParent(this); ++ QtStyleName = qtSettings->get("widgetThemeName").toString(); ++ QString qtColorSchemeName = qtSettings->get("styleName").toString(); ++ ++ auto selfAdaptedSettings = new QGSettings(AUTO_SCHEMA); ++ g_selfAdaptedMode = selfAdaptedSettings->get(COLOR_KEY_AUTO_THEME).toBool(); ++ // 判断自适应模式 ++ if (g_selfAdaptedMode) { ++ ThemeMode = SelfAdapted; ++ } else { ++ if (qtColorSchemeName == "ukui-dark") { ++ ThemeMode = Dark; ++ } else if (qtColorSchemeName == "ukui-default") { ++ ThemeMode = Mixed; ++ } else { ++ ThemeMode = Light; ++ } ++ } ++ ++ IconThemeName = qtSettings->get("iconThemeName").toString(); ++ WindowRadius = qtSettings->get("windowRadius").toInt(); ++ ++ connect(qtSettings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "widgetThemeName") { ++ QtStyleName = qtSettings->get("widgetThemeName").toString(); ++ emit QtStyleNameChanged(); ++ } else if (key == "styleName") { ++ // 判断自适应模式 ++ if (g_selfAdaptedMode) { ++ if (ThemeMode != SelfAdapted) { ++ ThemeMode = SelfAdapted; ++ emit ThemeModeChanged(); ++ } ++ return; ++ } ++ ++ if (qtColorSchemeName == "ukui-dark") { ++ ThemeMode = Dark; ++ } else if (qtColorSchemeName == "ukui-default") { ++ ThemeMode = Mixed; ++ } else { ++ ThemeMode = Light; ++ } ++ ++ emit ThemeModeChanged(); ++ } else if (key == "iconThemeName") { ++ IconThemeName = qtSettings->get("iconThemeName").toString(); ++ emit IconThemeNameChanged(); ++ } else if (key == "windowRadius") { ++ WindowRadius = qtSettings->get("windowRadius").toInt(); ++ emit WindowRadiusChanged(); ++ } ++ }); ++ ++ auto gtkSettings = new QGSettings(GTK_SETTINGS_SCHEMA_ID); ++ gtkSettings->setParent(this); ++ GtkStyleName = gtkSettings->get("gtkTheme").toString(); ++ connect(gtkSettings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "gtkTheme") { ++ GtkStyleName = gtkSettings->get("gtkTheme").toString(); ++ emit GtkStyleNameChanged(); ++ } ++ }); ++ ++ auto cursorSettings = new QGSettings(CURSOR_THEME_SCHEMA); ++ cursorSettings->setParent(this); ++ CursorThemeName = cursorSettings->get("cursorTheme").toString(); ++ connect(cursorSettings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "cursorTheme") { ++ CursorThemeName = cursorSettings->get("cursorTheme").toString(); ++ emit CursorThemeNameChanged(); ++ } ++ }); ++ ++ auto soundSettings = new QGSettings(KEY_SOUNDS_SCHEMA); ++ SoundThemeName = soundSettings->get("themeName").toString(); ++ connect(soundSettings, &QGSettings::changed, this, [=](const QString &key){ ++ if (key == "themeName") { ++ SoundThemeName = soundSettings->get("themeName").toString(); ++ emit SoundThemeNameChanged(); ++ } ++ }); ++} ++ ++Theme::~Theme() ++{ ++ ++} ++ ++bool Theme::IsUserCustomized() ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ } ++ return UserCustomized; ++} ++ ++QStringList Theme::GetStyleThemeList() ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ } ++ // fixme: 从后台获取全局主题 ++ return g_themes; ++} ++ ++bool Theme::SetStyleTheme(const QString &name) ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ return false; ++ } ++ ++ if (g_themes.contains(name)) { ++ // fixme: 后台响应全局主题切换 ++ unstableSwitchGlobalTheme(g_themes.indexOf(name)); ++ g_autoptr (GSettings) settings = g_settings_new(GLOBAL_SETTINGS_SCHEMA_ID); ++ bool successed = g_settings_set_string(settings, "global-theme-name", name.toLocal8Bit().constData()); ++ if (successed) { ++ setUserModified(false); ++ } ++ return successed; ++ } else { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidArgs, tr("Invalid theme name: %1, avaliable names are %2").arg(name).arg(g_themes.join(" "))); ++ } ++ return false; ++ } ++ return false; ++} ++ ++bool Theme::SetThemeMode(int themeMode) ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ return false; ++ } ++ ++ bool successed = false; ++ // 如果不是自适应模式,则需要重新设置当前主题自动切换功能 ++ if (themeMode != 3) { ++ g_autoptr (GSettings) scopedSettings = g_settings_new(AUTO_SCHEMA); ++ g_settings_set_boolean(scopedSettings, COLOR_KEY_AUTO_THEME, false); ++ g_selfAdaptedMode = false; ++ } else { ++ g_selfAdaptedMode = true; ++ } ++ ++ switch (ThemeModeEnum(themeMode)) { ++ case Light: { ++ g_autoptr (GSettings) qtSettings = g_settings_new(QT_SETTINGS_SCHEMA_ID); ++ g_autoptr (GSettings) gtkSettings = g_settings_new(GTK_SETTINGS_SCHEMA_ID); ++ if (g_settings_set_string(qtSettings, "style-name", "ukui-light")) { ++ // fixme: gtk主题需要适配widget theme name ++ successed = g_settings_set_string(gtkSettings, "gtk-theme", "ukui-white"); ++ } ++ break; ++ } ++ case Dark: { ++ g_autoptr (GSettings) qtSettings = g_settings_new(QT_SETTINGS_SCHEMA_ID); ++ g_autoptr (GSettings) gtkSettings = g_settings_new(GTK_SETTINGS_SCHEMA_ID); ++ if (g_settings_set_string(qtSettings, "style-name", "ukui-dark")) { ++ // fixme: gtk主题需要适配widget theme name ++ successed = g_settings_set_string(gtkSettings, "gtk-theme", "ukui-black"); ++ } ++ break; ++ } ++ case Mixed: { ++ g_autoptr (GSettings) qtSettings = g_settings_new(QT_SETTINGS_SCHEMA_ID); ++ g_autoptr (GSettings) gtkSettings = g_settings_new(GTK_SETTINGS_SCHEMA_ID); ++ if (g_settings_set_string(qtSettings, "style-name", "ukui-default")) { ++ // fixme: gtk主题需要适配widget theme name ++ successed = g_settings_set_string(gtkSettings, "gtk-theme", "ukui-white"); ++ } ++ break; ++ } ++ case SelfAdapted: { ++ g_autoptr (GSettings) scopedSettings = g_settings_new(AUTO_SCHEMA); ++ if (g_settings_set_boolean(scopedSettings, COLOR_KEY_AUTO_THEME, true)) { ++ return true; ++ } ++ break; ++ } ++ default: ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidArgs, tr("Invalid Mode: %1").arg(themeMode)); ++ } ++ return false; ++ } ++ ++ if (successed) { ++ setUserModified(true); ++ } ++ return successed; ++} ++ ++bool Theme::SetAccentColor(const QString &hexColor) ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ return false; ++ } ++ ++ // fixme: 当前强调色配置为字符类型,需要调整 ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::NotSupported, tr("Not supported yet.")); ++ } ++ ++ return false; ++} ++ ++QStringList Theme::GetIconThemeList() ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ } ++ // fixme: 从后台获取图标主题 ++ return g_iconThemes; ++} ++ ++bool Theme::SetIconTheme(const QString &iconThemeName) ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ return false; ++ } ++ ++ if (g_iconThemes.contains(iconThemeName)) { ++ bool successed = false; ++ g_autoptr (GSettings) qtSettings = g_settings_new(QT_SETTINGS_SCHEMA_ID); ++ successed = g_settings_set_string(qtSettings, "icon-theme-name", iconThemeName.toLocal8Bit().constData()); ++ if (successed) { ++ g_autoptr (GSettings) gtkSettings = g_settings_new(GTK_SETTINGS_SCHEMA_ID); ++ successed = g_settings_set_string(gtkSettings, "icon-theme", iconThemeName.toLocal8Bit().constData()); ++ setUserModified(true); ++ } ++ return successed; ++ } else { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidArgs, tr("Invalid theme name: %1, avaliable names are %2").arg(iconThemeName).arg(g_iconThemes.join(" "))); ++ } ++ return false; ++ } ++ return false; ++} ++ ++QStringList Theme::GetCursorThemeList() ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ } ++ // fixme: 从后台获取支持的光标主题 ++ return g_cursorThemes; ++} ++ ++bool Theme::SetCursorTheme(const QString &cursorThemeName) ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ return false; ++ } ++ ++ if (g_cursorThemes.contains(cursorThemeName)) { ++ bool successed = false; ++ g_autoptr (GSettings) scopedSettings = g_settings_new(CURSOR_THEME_SCHEMA); ++ successed = g_settings_set_string(scopedSettings, "cursor-theme", cursorThemeName.toLocal8Bit().constData()); ++ return successed; ++ } else { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidArgs, tr("Invalid theme name: %1, avaliable names are %2").arg(cursorThemeName).arg(g_cursorThemes.join(" "))); ++ } ++ return false; ++ } ++ return false; ++} ++ ++QStringList Theme::GetSoundThemeList() ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ } ++ // fixme: 从后台获取支持的声音主题 ++ return g_soundThemes; ++} ++ ++bool Theme::SetSoundTheme(const QString &soundThemeName) ++{ ++ if (!g_themeServiceAvailable) { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidService, tr("Theme service is not available")); ++ } ++ return false; ++ } ++ ++ if (g_soundThemes.contains(soundThemeName)) { ++ bool successed = false; ++ g_autoptr (GSettings) scopedSettings = g_settings_new(KEY_SOUNDS_SCHEMA); ++ successed = g_settings_set_string(scopedSettings, "theme-name", soundThemeName.toLocal8Bit().constData()); ++ return successed; ++ } else { ++ if (calledFromDBus()) { ++ sendErrorReply(QDBusError::InvalidArgs, tr("Invalid theme name: %1, avaliable names are %2").arg(soundThemeName).arg(g_soundThemes.join(" "))); ++ } ++ return false; ++ } ++ return false; ++} ++ ++/** ++ * @brief setUserModified ++ * 更新主题自定义状态,在用户设置全局主题后设置为false, ++ * 设置其它主题配置是设置为true ++ * @param modified ++ */ ++void Theme::setUserModified(bool modified) ++{ ++ g_autoptr (GSettings) settings = g_settings_new(GLOBAL_SETTINGS_SCHEMA_ID); ++ g_settings_set_boolean(settings, "is-modified", modified); ++} ++ ++int Theme::getThemeMode() const ++{ ++ return ThemeMode; ++} ++ ++bool Theme::SetWindowRadius(int newWindowRadius) ++{ ++ if (WindowRadius == newWindowRadius) ++ return false; ++ WindowRadius = newWindowRadius; ++ emit WindowRadiusChanged(); ++ ++ return true; ++} ++ ++int Theme::getWindowRadius() const ++{ ++ return WindowRadius; ++} ++ ++const QString &Theme::getGlobalThemeName() const ++{ ++ return GlobalThemeName; ++} ++ ++const QString &Theme::getSoundThemeName() const ++{ ++ return SoundThemeName; ++} ++ ++const QString &Theme::getCursorThemeName() const ++{ ++ return CursorThemeName; ++} ++ ++const QString &Theme::getIconThemeName() const ++{ ++ return IconThemeName; ++} ++ ++const QString &Theme::getGtkStyleName() const ++{ ++ return GtkStyleName; ++} ++ ++const QString &Theme::getQtStyleName() const ++{ ++ return QtStyleName; ++} +diff --git a/dbus/ui/theme/theme.h b/dbus/ui/theme/theme.h +new file mode 100644 +index 0000000..9e692ff +--- /dev/null ++++ b/dbus/ui/theme/theme.h +@@ -0,0 +1,222 @@ ++/* ++ * UKUI Framework ++ * ++ * Copyright (C) 2024, KylinSoft Co., Ltd. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 3 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library. If not, see <https://www.gnu.org/licenses/>. ++ * ++ * Authors: Yue Lan <lanyue@kylinos.cn> ++ * ++ */ ++ ++#ifndef THEME_H ++#define THEME_H ++ ++#include <QObject> ++#include <QDBusContext> ++ ++class Theme : public QObject, protected QDBusContext ++{ ++ Q_OBJECT ++ Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.UI.Theme") ++public: ++ /** ++ * @brief The ThemeMode enum ++ * 主题模式,分为 ++ * 深色、浅色、深浅混合、自适应 ++ * 四种模式 ++ */ ++ enum ThemeModeEnum { ++ Light, ++ Dark, ++ Mixed, ++ SelfAdapted ++ }; ++ Q_ENUM(ThemeModeEnum) ++ ++ explicit Theme(QObject *parent = nullptr); ++ ~Theme(); ++ ++public slots: ++ /** ++ * @brief isUserCustomed ++ * 用户是否进行了主题自定义 ++ * @return ++ * 是,用户修改过当前主题,如图标、壁纸等 ++ */ ++ Q_INVOKABLE bool IsUserCustomized(); ++ ++ /** ++ * @brief GetStyleThemeList ++ * 获取支持的主题列表 ++ * @return ++ * 主题列表,主题名称为非本地化主题名, ++ * 例如"Light-Seeking"(寻光), ++ * "HeYin"(和印), ++ * "Classic"(启典) ++ */ ++ Q_INVOKABLE QStringList GetStyleThemeList(); ++ ++ /** ++ * @brief SetStyleTheme ++ * 设置主题,可选在GetStyleThemeList()中的主题 ++ * @param name ++ * 主题名称,如"Light-Seeking" ++ * @return ++ * 设置成功/失败 ++ */ ++ Q_INVOKABLE bool SetStyleTheme(const QString &name); ++ ++ /** ++ * @brief SetThemeMode ++ * 设置主题模式 ++ * @param themeMode ++ * @sa ThemeMode ++ * @return ++ * 设置成功/失败 ++ */ ++ Q_INVOKABLE bool SetThemeMode(int themeMode); ++ ++ /** ++ * @brief SetAccentColor ++ * 设置控件强调色 ++ * @param hexColor ++ * 强调色,rgb hex格式 ++ * @return ++ * 设置成功/失败 ++ */ ++ Q_INVOKABLE bool SetAccentColor(const QString &hexColor); ++ ++ /** ++ * @brief GetIconThemeList ++ * 获取支持的图标主题列表 ++ * @return ++ * 如"ukui-icon-theme-default", ++ * "ukui-icon-theme-fashion", ++ * "ukui-icon-theme-classical" ++ */ ++ Q_INVOKABLE QStringList GetIconThemeList(); ++ ++ /** ++ * @brief SetIconTheme ++ * 设置主题图标 ++ * @param iconThemeName ++ * 在主题图标列表中的主题图标名 ++ * @return ++ * 设置成功/失败 ++ */ ++ Q_INVOKABLE bool SetIconTheme(const QString &iconThemeName); ++ ++ /** ++ * @brief GetCursorThemeList ++ * 获取光标主题列表 ++ * @return ++ */ ++ Q_INVOKABLE QStringList GetCursorThemeList(); ++ ++ /** ++ * @brief SetCursorTheme ++ * 设置声音主题 ++ * @param cursorThemeName ++ * @return ++ * 设置成功/失败 ++ */ ++ Q_INVOKABLE bool SetCursorTheme(const QString &cursorThemeName); ++ ++ /** ++ * @brief GetSoundThemeList ++ * 获取声音主题列表 ++ * @return ++ */ ++ Q_INVOKABLE QStringList GetSoundThemeList(); ++ ++ /** ++ * @brief SetSoundThemeList ++ * 设置声音主题 ++ * @param soundThemeName ++ * @return ++ * 设置成功/失败 ++ */ ++ Q_INVOKABLE bool SetSoundTheme(const QString &soundThemeName); ++ ++ /** ++ * @brief SetWindowRadius ++ * 设置窗口圆角 ++ * @param radius ++ * @return ++ * 设置成功/失败 ++ */ ++ Q_INVOKABLE bool SetWindowRadius(int newWindowRadius); ++ ++public: ++ const QString &getGlobalThemeName() const; ++ ++ const QString &getQtStyleName() const; ++ ++ const QString &getGtkStyleName() const; ++ ++ const QString &getIconThemeName() const; ++ ++ const QString &getCursorThemeName() const; ++ ++ const QString &getSoundThemeName() const; ++ ++ int getWindowRadius() const; ++ ++ int getThemeMode() const; ++ ++signals: ++ void ThemeModeChanged(); ++ ++ void QtStyleNameChanged(); ++ ++ void GtkStyleNameChanged(); ++ ++ void IconThemeNameChanged(); ++ ++ void CursorThemeNameChanged(); ++ ++ void SoundThemeNameChanged(); ++ ++ void GlobalThemeNameChanged(); ++ ++ void WindowRadiusChanged(); ++ ++ void UserCustomizedChanged(); ++ ++private: ++ void setUserModified(bool modified); ++ ++ QString GlobalThemeName; ++ int ThemeMode = 0; ++ QString QtStyleName; ++ QString GtkStyleName; ++ QString IconThemeName; ++ QString CursorThemeName; ++ QString SoundThemeName; ++ int WindowRadius = 12; ++ bool UserCustomized = false; ++ ++ Q_PROPERTY(QString GlobalThemeName READ getGlobalThemeName WRITE SetStyleTheme NOTIFY GlobalThemeNameChanged) ++ Q_PROPERTY(int ThemeMode READ getThemeMode NOTIFY ThemeModeChanged) ++ Q_PROPERTY(QString QtStyleName READ getQtStyleName NOTIFY QtStyleNameChanged) ++ Q_PROPERTY(QString GtkStyleName READ getGtkStyleName NOTIFY GtkStyleNameChanged) ++ Q_PROPERTY(QString IconThemeName READ getIconThemeName WRITE SetIconTheme NOTIFY IconThemeNameChanged) ++ Q_PROPERTY(QString CursorThemeName READ getCursorThemeName WRITE SetCursorTheme NOTIFY CursorThemeNameChanged) ++ Q_PROPERTY(QString SoundThemeName READ getSoundThemeName WRITE SetSoundTheme NOTIFY SoundThemeNameChanged) ++ Q_PROPERTY(int WindowRadius READ getWindowRadius WRITE SetWindowRadius NOTIFY WindowRadiusChanged) ++ Q_PROPERTY(bool UserCustomized READ IsUserCustomized NOTIFY UserCustomizedChanged) ++}; ++ ++#endif // THEME_H +diff --git a/main.cpp b/main.cpp +index f7a0d27..3f0320b 100644 +--- a/main.cpp ++++ b/main.cpp +@@ -10,6 +10,11 @@ + #include "power.h" + #include "touchpad.h" + ++#include "theme.h" ++#include "background.h" ++#include "font.h" ++#include "effect.h" ++ + int main(int argc, char *argv[]) + { + QCoreApplication a(argc, argv); +@@ -37,6 +42,13 @@ int main(int argc, char *argv[]) + sessionBus.registerObject(DEVICES_TOUCHPAD_PATH, new TouchpadManager(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); ++ ++ QDBusConnection::RegisterOptions uiOptions = QDBusConnection::ExportAllSlots | ++ QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllProperties; ++ sessionBus.registerObject(UI_THEME_PATH, new Theme(&a), uiOptions); ++ sessionBus.registerObject(UI_WALLPAPER_PATH, new Background(&a), uiOptions); ++ sessionBus.registerObject(UI_FONT_PATH, new Font(&a), uiOptions); ++ sessionBus.registerObject(UI_EFFECTS_PATH, new Effect(&a), uiOptions); + } + + return a.exec(); diff -Nru ukui-framework-4.10.0.0/debian/patches/0002-fix-control-debian-control.patch ukui-framework-5.0.0.0/debian/patches/0002-fix-control-debian-control.patch --- ukui-framework-4.10.0.0/debian/patches/0002-fix-control-debian-control.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/patches/0002-fix-control-debian-control.patch 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,20 @@ +From: zhaikangning <zhaikangning@kylinos.cn> +Date: Wed, 4 Dec 2024 16:57:15 +0800 +Subject: =?utf-8?b?Zml4KGNvbnRyb2wp77yaZGViaWFuIGNvbnRyb2zmlofku7bkuK3mlrA=?= + =?utf-8?b?5aKe5b+F6KaB55qE5L6d6LWW5YyFOyDniYjmnKzlj7fljYfnuqfliLA1LjAuMC4w?= + =?utf-8?b?LW9rMi4x?= + +--- + CMakeLists.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 214238d..da24f7d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -47,3 +47,5 @@ target_link_libraries(ukui-framework + background + font + effect) ++ ++install(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin) diff -Nru ukui-framework-4.10.0.0/debian/patches/0003-fix-contol-5.0.0.0-ok2.2.patch ukui-framework-5.0.0.0/debian/patches/0003-fix-contol-5.0.0.0-ok2.2.patch --- ukui-framework-4.10.0.0/debian/patches/0003-fix-contol-5.0.0.0-ok2.2.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/patches/0003-fix-contol-5.0.0.0-ok2.2.patch 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,20 @@ +From: zhaikangning <zhaikangning@kylinos.cn> +Date: Wed, 4 Dec 2024 18:18:29 +0800 +Subject: =?utf-8?b?Zml4KGNvbnRvbCk66LCD5pW057yW6K+R5L6d6LWW5L2N572u77yM6Kej?= + =?utf-8?b?5Yaz57yW6K+R6ZSZ6K+v6Zeu6aKY77yb54mI5pys5Y+35Y2H57qn5YiwNS4wLjAu?= + =?utf-8?b?MC1vazIuMg==?= + +--- + CMakeLists.txt | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index da24f7d..214238d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -47,5 +47,3 @@ target_link_libraries(ukui-framework + background + font + effect) +- +-install(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin) diff -Nru ukui-framework-4.10.0.0/debian/patches/0004-39-upstream.patch ukui-framework-5.0.0.0/debian/patches/0004-39-upstream.patch --- ukui-framework-4.10.0.0/debian/patches/0004-39-upstream.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/patches/0004-39-upstream.patch 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,436 @@ +From: zhaikangning <857458455@qq.com> +Date: Tue, 10 Dec 2024 01:39:29 +0000 +Subject: =?utf-8?b?ITM5IOWQjOatpXVwc3RyZWFt5YiG5pSv77yM6Ieq5ZCv5Yqo5ZKM5a6J?= + =?utf-8?b?6KOF5paH5Lu25Yqf6IO9IE1lcmdlIHB1bGwgcmVxdWVzdCAhMzkgZnJvbSB6aGFp?= + =?utf-8?b?a2FuZ25pbmcvdXBzdHJlYW0=?= + +--- + CMakeLists.txt | 44 ------------------------ + common.h | 74 ----------------------------------------- + data/ukui-framework-api.desktop | 7 ++++ + dbus/CMakeLists.txt | 55 ++++++++++++++++++++++++++++-- + dbus/common.h | 74 +++++++++++++++++++++++++++++++++++++++++ + dbus/main.cpp | 55 ++++++++++++++++++++++++++++++ + main.cpp | 55 ------------------------------ + 7 files changed, 189 insertions(+), 175 deletions(-) + delete mode 100644 common.h + create mode 100644 data/ukui-framework-api.desktop + create mode 100644 dbus/common.h + create mode 100644 dbus/main.cpp + delete mode 100644 main.cpp + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 214238d..bc485d9 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -2,48 +2,4 @@ cmake_minimum_required(VERSION 3.5) + find_package(PkgConfig) + project(ukui-framework VERSION 1.0) + +- +-find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus Widgets) +- +-set(CMAKE_INCLUDE_CURRENT_DIR ON) +- +-set(CMAKE_AUTOUIC ON) +-set(CMAKE_AUTOMOC ON) +-set(CMAKE_AUTORCC ON) +- +-set(CMAKE_CXX_STANDARD 11) +-set(CMAKE_CXX_STANDARD_REQUIRED ON) +- + add_subdirectory(dbus) +- +-include_directories(${CMAKE_INCLUDE_CURRENT_DIR}) +-include_directories(dbus/devices/screen/src) +-include_directories(dbus/devices/audio/src) +-include_directories(dbus/devices/network/src) +-include_directories(dbus/devices/bluetooth/src) +-include_directories(dbus/devices/power/src) +-include_directories(dbus/devices/touchpad/src) +- +-include_directories(dbus/ui/background) +-include_directories(dbus/ui/effect) +-include_directories(dbus/ui/font) +-include_directories(dbus/ui/theme) +- +-add_executable(ukui-framework +- main.cpp +-) +- +-target_link_libraries(ukui-framework +- Qt5::Core +- Qt5::Widgets +- Qt5::DBus +- screen +- audio +- network +- bluetooth +- power +- touchpad +- theme +- background +- font +- effect) +diff --git a/common.h b/common.h +deleted file mode 100644 +index 1b390c8..0000000 +--- a/common.h ++++ /dev/null +@@ -1,74 +0,0 @@ +-/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- +- * -*- coding: utf-8 -*- +- * +- * Copyright (C) 2024 KylinSoft Co., Ltd. +- * +- * This program is free software: you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#ifndef COMMON_H +-#define COMMON_H +- +-#endif // COMMON_H +- +-// ukui framework统一接口Dbus名称 +-const QString DBUS_NAME = "org.ukui.Framework"; +- +-// 设备类相关的路径名称 +-const QString DEVICES_PATH = "/org/ukui/Framework/Devices"; +-const QString DEVICES_POWER_PATH = "/org/ukui/Framework/Devices/Power"; +-const QString DEVICES_SCREEN_PATH = "/org/ukui/Framework/Devices/Screen"; +-const QString DEVICES_BLUETOOTH_PATH = "/org/ukui/Framework/Devices/Bluetooth"; +-const QString DEVICES_WIFI_PATH = "/org/ukui/Framework/Devices/WIFI"; +-const QString DEVICES_TOUCHPAD_PATH = "/org/ukui/Framework/Devices/Touchpad"; +-const QString DEVICES_AUDIO_PATH = "/org/ukui/Framework/Devices/Audio"; +-const QString DEVICES_GEOLOCATION_PATH = "/org/ukui/Framework/Devices/Geolocation"; +- +-// APP相关路径名称 +-const QString APP_PATH = "/org/ukui/Framework/APP"; +-const QString APP_INFO_PATH = "/org/ukui/Framework/APP/INFO"; +-const QString APP_MANAGER_PATH = "/org/ukui/Framework/APP/Manager"; +- +-// 文件相关路径名称 +-const QString FILE_PATH = "/org/ukui/Framework/File"; +-const QString FILE_INDEX_PATH = "/org/ukui/Framework/File/Index"; +- +-// UI相关的路径名称 +-const QString UI_PATH = "/org/ukui/Framework/UI"; +-const QString UI_THEME_PATH = "/org/ukui/Framework/UI/Theme"; +-const QString UI_WALLPAPER_PATH = "/org/ukui/Framework/UI/Wallpaper"; +-const QString UI_EFFECTS_PATH = "/org/ukui/Framework/UI/Effects"; +-const QString UI_FONT_PATH = "/org/ukui/Framework/UI/Font"; +- +-// Media +-const QString MEDIA_PATH = "/org/ukui/Framework/Media"; +- +-// Notifications +-const QString NOTIFICATIONS_PATH = "/org/ukui/Framework/Notifications"; +- +-// Configurations +-const QString CONFIGURATIONS_PATH = "/org/ukui/Framework/Configurations"; +- +-// Network +-const QString NETWORK_PATH = "/org/ukui/Framework/Network"; +- +-// Navigations +-const QString NAVIGATIONS_PATH = "/org/ukui/Framework/Navigations"; +- +-// ModeControl +-const QString MODE_PATH = "/org/ukui/Framework/Mode"; +- +-// AI +-const QString AI_PATH = "/org/ukui/Framework/AI"; +- +diff --git a/data/ukui-framework-api.desktop b/data/ukui-framework-api.desktop +new file mode 100644 +index 0000000..c93ea0b +--- /dev/null ++++ b/data/ukui-framework-api.desktop +@@ -0,0 +1,7 @@ ++[Desktop Entry] ++Type=Application ++Name=ukui-framework-api ++Exec=ukui-framework-api ++NoDisplay=true ++X-UKUI-Autostart-Notify=true ++ +diff --git a/dbus/CMakeLists.txt b/dbus/CMakeLists.txt +index 964e601..bff200a 100644 +--- a/dbus/CMakeLists.txt ++++ b/dbus/CMakeLists.txt +@@ -1,9 +1,60 @@ ++cmake_minimum_required(VERSION 3.5) ++find_package(PkgConfig) ++project(ukui-framework-api VERSION 1.0) ++ ++ ++find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus Widgets) ++ ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++ ++set(CMAKE_AUTOUIC ON) ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTORCC ON) ++ ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ + find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) + + add_subdirectory(devices) ++add_subdirectory(ui) + + aux_source_directory(SOURCES devices/README.md) ++aux_source_directory(SOURCES ui/README.md) ++aux_source_directory(SOURCES data/) + +-add_subdirectory(ui) ++include_directories(${CMAKE_INCLUDE_CURRENT_DIR}) ++include_directories(devices/screen/src) ++include_directories(devices/audio/src) ++include_directories(devices/network/src) ++include_directories(devices/bluetooth/src) ++include_directories(devices/power/src) ++include_directories(devices/touchpad/src) + +-aux_source_directory(SOURCES ui/README.md) ++include_directories(ui/background) ++include_directories(ui/effect) ++include_directories(ui/font) ++include_directories(ui/theme) ++ ++add_executable(ukui-framework-api ++ main.cpp ++) ++ ++target_link_libraries(ukui-framework-api ++ Qt5::Core ++ Qt5::Widgets ++ Qt5::DBus ++ screen ++ audio ++ network ++ bluetooth ++ power ++ touchpad ++ theme ++ background ++ font ++ effect) ++ ++install(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin) ++install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../data/ukui-framework-api.desktop ++ DESTINATION /etc/xdg/autostart) +diff --git a/dbus/common.h b/dbus/common.h +new file mode 100644 +index 0000000..1b390c8 +--- /dev/null ++++ b/dbus/common.h +@@ -0,0 +1,74 @@ ++/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- ++ * -*- coding: utf-8 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#ifndef COMMON_H ++#define COMMON_H ++ ++#endif // COMMON_H ++ ++// ukui framework统一接口Dbus名称 ++const QString DBUS_NAME = "org.ukui.Framework"; ++ ++// 设备类相关的路径名称 ++const QString DEVICES_PATH = "/org/ukui/Framework/Devices"; ++const QString DEVICES_POWER_PATH = "/org/ukui/Framework/Devices/Power"; ++const QString DEVICES_SCREEN_PATH = "/org/ukui/Framework/Devices/Screen"; ++const QString DEVICES_BLUETOOTH_PATH = "/org/ukui/Framework/Devices/Bluetooth"; ++const QString DEVICES_WIFI_PATH = "/org/ukui/Framework/Devices/WIFI"; ++const QString DEVICES_TOUCHPAD_PATH = "/org/ukui/Framework/Devices/Touchpad"; ++const QString DEVICES_AUDIO_PATH = "/org/ukui/Framework/Devices/Audio"; ++const QString DEVICES_GEOLOCATION_PATH = "/org/ukui/Framework/Devices/Geolocation"; ++ ++// APP相关路径名称 ++const QString APP_PATH = "/org/ukui/Framework/APP"; ++const QString APP_INFO_PATH = "/org/ukui/Framework/APP/INFO"; ++const QString APP_MANAGER_PATH = "/org/ukui/Framework/APP/Manager"; ++ ++// 文件相关路径名称 ++const QString FILE_PATH = "/org/ukui/Framework/File"; ++const QString FILE_INDEX_PATH = "/org/ukui/Framework/File/Index"; ++ ++// UI相关的路径名称 ++const QString UI_PATH = "/org/ukui/Framework/UI"; ++const QString UI_THEME_PATH = "/org/ukui/Framework/UI/Theme"; ++const QString UI_WALLPAPER_PATH = "/org/ukui/Framework/UI/Wallpaper"; ++const QString UI_EFFECTS_PATH = "/org/ukui/Framework/UI/Effects"; ++const QString UI_FONT_PATH = "/org/ukui/Framework/UI/Font"; ++ ++// Media ++const QString MEDIA_PATH = "/org/ukui/Framework/Media"; ++ ++// Notifications ++const QString NOTIFICATIONS_PATH = "/org/ukui/Framework/Notifications"; ++ ++// Configurations ++const QString CONFIGURATIONS_PATH = "/org/ukui/Framework/Configurations"; ++ ++// Network ++const QString NETWORK_PATH = "/org/ukui/Framework/Network"; ++ ++// Navigations ++const QString NAVIGATIONS_PATH = "/org/ukui/Framework/Navigations"; ++ ++// ModeControl ++const QString MODE_PATH = "/org/ukui/Framework/Mode"; ++ ++// AI ++const QString AI_PATH = "/org/ukui/Framework/AI"; ++ +diff --git a/dbus/main.cpp b/dbus/main.cpp +new file mode 100644 +index 0000000..3f0320b +--- /dev/null ++++ b/dbus/main.cpp +@@ -0,0 +1,55 @@ ++#include <QCoreApplication> ++#include <QtDBus/QDBusConnection> ++#include <QtDebug> ++ ++#include "common.h" ++#include "screen.h" ++#include "audio.h" ++#include "network.h" ++#include "bluetooth.h" ++#include "power.h" ++#include "touchpad.h" ++ ++#include "theme.h" ++#include "background.h" ++#include "font.h" ++#include "effect.h" ++ ++int main(int argc, char *argv[]) ++{ ++ QCoreApplication a(argc, argv); ++ // Todo ++ // 启动后台服务,加载Dbus接口,注册DBus对象 ++ QDBusConnection sessionBus = QDBusConnection::sessionBus(); ++ if (sessionBus.registerService(DBUS_NAME)) { ++ sessionBus.registerObject(DEVICES_SCREEN_PATH, new Screen(), ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ++ ); ++ sessionBus.registerObject(DEVICES_AUDIO_PATH, new Audio(), ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ++ ); ++ BLUETOOTHDBUS::instance(); ++ sessionBus.registerObject(DEVICES_BLUETOOTH_PATH, BLUETOOTHDBUS::getInstance(), ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ++ ); ++ sessionBus.registerObject(DEVICES_WIFI_PATH, new Network(), ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ++ ); ++ sessionBus.registerObject(DEVICES_POWER_PATH, new UkuiPowerInterface(), ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ++ ); ++ ++ sessionBus.registerObject(DEVICES_TOUCHPAD_PATH, new TouchpadManager(), ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ++ ); ++ ++ QDBusConnection::RegisterOptions uiOptions = QDBusConnection::ExportAllSlots | ++ QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllProperties; ++ sessionBus.registerObject(UI_THEME_PATH, new Theme(&a), uiOptions); ++ sessionBus.registerObject(UI_WALLPAPER_PATH, new Background(&a), uiOptions); ++ sessionBus.registerObject(UI_FONT_PATH, new Font(&a), uiOptions); ++ sessionBus.registerObject(UI_EFFECTS_PATH, new Effect(&a), uiOptions); ++ } ++ ++ return a.exec(); ++} +diff --git a/main.cpp b/main.cpp +deleted file mode 100644 +index 3f0320b..0000000 +--- a/main.cpp ++++ /dev/null +@@ -1,55 +0,0 @@ +-#include <QCoreApplication> +-#include <QtDBus/QDBusConnection> +-#include <QtDebug> +- +-#include "common.h" +-#include "screen.h" +-#include "audio.h" +-#include "network.h" +-#include "bluetooth.h" +-#include "power.h" +-#include "touchpad.h" +- +-#include "theme.h" +-#include "background.h" +-#include "font.h" +-#include "effect.h" +- +-int main(int argc, char *argv[]) +-{ +- QCoreApplication a(argc, argv); +- // Todo +- // 启动后台服务,加载Dbus接口,注册DBus对象 +- QDBusConnection sessionBus = QDBusConnection::sessionBus(); +- if (sessionBus.registerService(DBUS_NAME)) { +- sessionBus.registerObject(DEVICES_SCREEN_PATH, new Screen(), +- QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals +- ); +- sessionBus.registerObject(DEVICES_AUDIO_PATH, new Audio(), +- QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals +- ); +- BLUETOOTHDBUS::instance(); +- sessionBus.registerObject(DEVICES_BLUETOOTH_PATH, BLUETOOTHDBUS::getInstance(), +- QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals +- ); +- sessionBus.registerObject(DEVICES_WIFI_PATH, new Network(), +- QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals +- ); +- sessionBus.registerObject(DEVICES_POWER_PATH, new UkuiPowerInterface(), +- QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals +- ); +- +- sessionBus.registerObject(DEVICES_TOUCHPAD_PATH, new TouchpadManager(), +- QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals +- ); +- +- QDBusConnection::RegisterOptions uiOptions = QDBusConnection::ExportAllSlots | +- QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllProperties; +- sessionBus.registerObject(UI_THEME_PATH, new Theme(&a), uiOptions); +- sessionBus.registerObject(UI_WALLPAPER_PATH, new Background(&a), uiOptions); +- sessionBus.registerObject(UI_FONT_PATH, new Font(&a), uiOptions); +- sessionBus.registerObject(UI_EFFECTS_PATH, new Effect(&a), uiOptions); +- } +- +- return a.exec(); +-} diff -Nru ukui-framework-4.10.0.0/debian/patches/0005-feat-project-desktop-ukui-framework-api-ukui-framewo.patch ukui-framework-5.0.0.0/debian/patches/0005-feat-project-desktop-ukui-framework-api-ukui-framewo.patch --- ukui-framework-4.10.0.0/debian/patches/0005-feat-project-desktop-ukui-framework-api-ukui-framewo.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/patches/0005-feat-project-desktop-ukui-framework-api-ukui-framewo.patch 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,552 @@ +From: zhaikangning <zhaikangning@kylinos.cn> +Date: Mon, 16 Dec 2024 15:53:25 +0800 +Subject: =?utf-8?b?ZmVhdChwcm9qZWN0KTrosIPmlbTpobnnm67lkI3lj4rnm7jlhbPnmoQ=?= + =?utf-8?b?5LqM6L+b5Yi25ZKMZGVza3RvcOaWh+S7tuWQjXVrdWktZnJhbWV3b3JrLWFwaS0+?= + =?utf-8?b?dWt1aS1mcmFtZXdvcmstZGJ1cw==?= + +--- + data/ukui-framework-api.desktop | 7 - + data/ukui-framework-dbus.desktop | 7 + + dbus/CMakeLists.txt | 8 +- + dbus/devices/screen/CMakeLists.txt | 10 +- + dbus/devices/screen/src/screen.cpp | 8 +- + dbus/devices/screen/src/screen.h | 8 +- + dbus/devices/screen/test/CMakeLists.txt | 23 +-- + dbus/devices/screen/test/test.cpp | 251 +++++++++++++++++++++++++++----- + dbus/devices/screen/test/test.h | 43 +++++- + 9 files changed, 293 insertions(+), 72 deletions(-) + delete mode 100644 data/ukui-framework-api.desktop + create mode 100644 data/ukui-framework-dbus.desktop + +diff --git a/data/ukui-framework-api.desktop b/data/ukui-framework-api.desktop +deleted file mode 100644 +index c93ea0b..0000000 +--- a/data/ukui-framework-api.desktop ++++ /dev/null +@@ -1,7 +0,0 @@ +-[Desktop Entry] +-Type=Application +-Name=ukui-framework-api +-Exec=ukui-framework-api +-NoDisplay=true +-X-UKUI-Autostart-Notify=true +- +diff --git a/data/ukui-framework-dbus.desktop b/data/ukui-framework-dbus.desktop +new file mode 100644 +index 0000000..5ec5a60 +--- /dev/null ++++ b/data/ukui-framework-dbus.desktop +@@ -0,0 +1,7 @@ ++[Desktop Entry] ++Type=Application ++Name=ukui-framework-dbus ++Exec=ukui-framework-dbus ++NoDisplay=true ++X-UKUI-Autostart-Notify=true ++ +diff --git a/dbus/CMakeLists.txt b/dbus/CMakeLists.txt +index bff200a..f9d12b5 100644 +--- a/dbus/CMakeLists.txt ++++ b/dbus/CMakeLists.txt +@@ -1,6 +1,6 @@ + cmake_minimum_required(VERSION 3.5) + find_package(PkgConfig) +-project(ukui-framework-api VERSION 1.0) ++project(ukui-framework-dbus VERSION 1.0) + + + find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus Widgets) +@@ -36,11 +36,11 @@ include_directories(ui/effect) + include_directories(ui/font) + include_directories(ui/theme) + +-add_executable(ukui-framework-api ++add_executable(ukui-framework-dbus + main.cpp + ) + +-target_link_libraries(ukui-framework-api ++target_link_libraries(ukui-framework-dbus + Qt5::Core + Qt5::Widgets + Qt5::DBus +@@ -56,5 +56,5 @@ target_link_libraries(ukui-framework-api + effect) + + install(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin) +-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../data/ukui-framework-api.desktop ++install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../data/ukui-framework-dbus.desktop + DESTINATION /etc/xdg/autostart) +diff --git a/dbus/devices/screen/CMakeLists.txt b/dbus/devices/screen/CMakeLists.txt +index 6b4c9c1..4a70b23 100644 +--- a/dbus/devices/screen/CMakeLists.txt ++++ b/dbus/devices/screen/CMakeLists.txt +@@ -3,20 +3,20 @@ project(screen VERSION 1.0) + + find_package(PkgConfig) + +- + pkg_check_modules(GLIB REQUIRED glib-2.0) + pkg_check_modules(GIO REQUIRED gio-2.0) + pkg_check_modules(GOBJECT REQUIRED gobject-2.0) + ++# 索引动态库的头文件地址 + include_directories(${GLIB_INCLUDE_DIRS}) + include_directories(${GIO_INCLUDE_DIRS}) + include_directories(${GOBJECT_INCLUDE_DIRS}) ++add_subdirectory(test) + + cmake_minimum_required(VERSION 3.16) + # 查找Qt5及其模块 + find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus Widgets) + +- + set(DEVICES_SCREEN_LINK + glib-2.0 + gio-2.0 +@@ -25,12 +25,6 @@ set(DEVICES_SCREEN_LINK + ${GOBJECT_LIBRARIES} + ) + +- +-# 索引动态库的头文件地址 +-include_directories(${GLIB_INCLUDE_DIRS}) +-include_directories(${GIO_INCLUDE_DIRS}) +-include_directories(${GOBJECT_INCLUDE_DIRS}) +- + set(CMAKE_AUTOMOC ON) + + file(GLOB LIBSCREEN_SOURCES src/*.cpp src/QGSettings/*.cpp) +diff --git a/dbus/devices/screen/src/screen.cpp b/dbus/devices/screen/src/screen.cpp +index 372a20b..4a4e427 100644 +--- a/dbus/devices/screen/src/screen.cpp ++++ b/dbus/devices/screen/src/screen.cpp +@@ -37,6 +37,11 @@ Screen::Screen(QObject *parent): + } else if (Screen::eBrightnessControl::gamma == m_brightControlByUPM) { + m_pscreen = new ScreenGamma(this); + } ++ ++ m_modeMap.insert("primaryScreenOnlyMode","firstScreenMode"); ++ m_modeMap.insert("mirrorScreenMode","cloneScreenMode"); ++ m_modeMap.insert("extensionMode","extendScreenMode"); ++ m_modeMap.insert("secondaryScreenOnlyMode","secondScreenMode"); + } + + Screen::~Screen() +@@ -141,11 +146,10 @@ QString Screen::GetScreenMode() + + bool Screen::SetScreenMode(const QString &mode) + { +- QDBusReply<int> reply = callXrandr("setScreenMode", mode, MY_NAME); ++ QDBusReply<int> reply = callXrandr("setScreenMode", m_modeMap[mode], MY_NAME); + if (false == reply.isValid()) { + return false; + } +- + return true; + } + +diff --git a/dbus/devices/screen/src/screen.h b/dbus/devices/screen/src/screen.h +index 560fb72..add04c6 100644 +--- a/dbus/devices/screen/src/screen.h ++++ b/dbus/devices/screen/src/screen.h +@@ -183,6 +183,11 @@ public Q_SLOTS: + */ + bool IsNightModeEnable(); + ++ ++public: ++ Screen::eBrightnessControl getBrightControlMode() { ++ return m_brightControlByUPM; ++ } + private: + /** + * @brief brightControlByUPM 获取电源管理是否可以控制亮度 +@@ -267,10 +272,11 @@ private: + uint8_t m_primaryBright = 0; + uint8_t m_screenCount = 0; + +- int m_brightControlByUPM = -1; ++ eBrightnessControl m_brightControlByUPM = eBrightnessControl::unknown; + + QMetaEnum m_outputModeEnum; + QGSettings *m_pColorGsettings = nullptr; ++ QMap<QString,QString> m_modeMap; + }; + #endif + +diff --git a/dbus/devices/screen/test/CMakeLists.txt b/dbus/devices/screen/test/CMakeLists.txt +index 3f31f1b..0698007 100644 +--- a/dbus/devices/screen/test/CMakeLists.txt ++++ b/dbus/devices/screen/test/CMakeLists.txt +@@ -1,6 +1,5 @@ +-project(my_qt_app) +- +- ++cmake_minimum_required(VERSION 3.16) ++project(screen_test) + + find_package(PkgConfig) + pkg_check_modules(GLIB REQUIRED glib-2.0) +@@ -11,31 +10,35 @@ include_directories(${GLIB_INCLUDE_DIRS}) + include_directories(${GIO_INCLUDE_DIRS}) + include_directories(${GOBJECT_INCLUDE_DIRS}) + include_directories(../src) +-cmake_minimum_required(VERSION 3.16) ++ + # 查找Qt5及其模块 +-find_package(Qt5 COMPONENTS Core Widgets DBus REQUIRED) ++find_package(Qt5 COMPONENTS Core Widgets DBus REQUIRED Test) + + # 接下来,你可以使用Qt5::Core, Qt5::Widgets, Qt5::DBus来链接你的可执行文件或库 + set(CMAKE_AUTOMOC ON) + + # 示例:添加可执行文件 +-add_executable(my_qt_app ++add_executable(screen_test + test.cpp + ../src/screen.cpp ++ ../src/screen_gamma.cpp ++ ../src/screen_power.cpp ++ ../src/screen_abstract.cpp + ../src/QGSettings/qgsettings.cpp + ../src/QGSettings/qconftype.cpp) + + +- +-target_include_directories(my_qt_app PRIVATE) +- + # 链接Qt模块 +-target_link_libraries(my_qt_app ++target_link_libraries(screen_test + Qt5::Core + Qt5::Widgets + Qt5::DBus ++ Qt5::Test + glib-2.0 + gio-2.0 + ${GLIB_LIBRARIES} + ${GIO_LIBRARIES} + ${GOBJECT_LIBRARIES}) ++ ++enable_testing() ++add_test(NAME ScreenTest COMMAND screen_test) +\ No newline at end of file +diff --git a/dbus/devices/screen/test/test.cpp b/dbus/devices/screen/test/test.cpp +index 1f40286..d72027f 100644 +--- a/dbus/devices/screen/test/test.cpp ++++ b/dbus/devices/screen/test/test.cpp +@@ -17,43 +17,224 @@ + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +-#include <QDebug> +-#include <QDBusError> +-#include <QDBusConnection> +-#include <QCoreApplication> +- + #include "test.h" + +-/* +- * 测试情况: +- * getEyeCare(): 通过 +- * getNightMode():通过 +- * getPrimaryBrightness():通过 +- * getScreenMode():通过 +- * getScreensParam()::通过 +- * increaseBrightness():通过 +- * openDisplaySetting()::通过 +- * reduceBrightness()::通过 +- * setAllScreenSameBrightness():通过 +- * setColorTemperature():未通过 +- * setEyeCare():通过 +- * setNightMode():通过 +- * setPrimaryBrightness():通过,建议异步调用 +- * setScreenBrightness():通过, +- * setScreenMode():通过, +- * setScreensParam():通过, +- * +-*/ +-int main(int argc, char *argv[]) ++ScreenControlTest::ScreenControlTest() ++{ ++ m_screen = new Screen(); ++} ++ ++ScreenControlTest::~ScreenControlTest() ++{ ++ delete m_screen; ++ m_screen = nullptr; ++} ++ ++void ScreenControlTest::testSetPrimaryScreenBrightness() ++{ ++ uint bright = 99; ++// QThread::msleep(1500); ++ bool result = m_screen->SetPrimaryScreenBrightness(bright); ++ QCOMPARE(bright, m_screen->GetPrimaryScreenBrightness()); ++} ++ ++//void ScreenControlTest::testGetPrimaryScreenBrightness() ++//{ ++// uint bright = 99; ++// bool result = m_screen->SetPrimaryScreenBrightness(bright); ++// QVERIFY(result); ++//} ++ ++void ScreenControlTest::testIncreaseBuiltinScreenBrightness() ++{ ++ int errorTimes = 0; ++ if (Screen::eBrightnessControl::powerManager != m_screen->getBrightControlMode()) { ++ QVERIFY(true); ++ return; ++ } ++ ++ uint initValue = m_screen->GetPrimaryScreenBrightness(); ++ m_screen->SetPrimaryScreenBrightness(10); ++ ++ for (int var = 0; var < 10; ++var) { ++ m_screen->IncreaseBuiltinScreenBrightness(); ++ uint ret = m_screen->GetPrimaryScreenBrightness(); ++ if (ret != 10+5*(var+1)) { ++ errorTimes++; ++ } ++ } ++ m_screen->SetPrimaryScreenBrightness(initValue); ++ QCOMPARE(errorTimes, 0); ++} ++ ++void ScreenControlTest::testDecreaseBuiltinBrightness() ++{ ++ int errorTimes = 0; ++ if (Screen::eBrightnessControl::powerManager != m_screen->getBrightControlMode()) { ++ QVERIFY(true); ++ return; ++ } ++ ++ uint initValue = m_screen->GetPrimaryScreenBrightness(); ++ ++ for (int var = 0; var < 10; ++var) { ++ m_screen->IncreaseBuiltinScreenBrightness(); ++ uint ret = m_screen->GetPrimaryScreenBrightness(); ++ if (ret != 10-5*(var+1)) { ++ errorTimes++; ++ } ++ } ++ m_screen->SetPrimaryScreenBrightness(initValue); ++ QCOMPARE(errorTimes, 0); ++} ++ ++//void ScreenControlTest::testGetScreenMode() ++//{ ++ ++//} ++ ++void ScreenControlTest::testSetScreenMode() ++{ ++ int errorTimes = 0; ++ QString initMode = m_screen->GetScreenMode(); ++ const QStringList modes = {"primaryScreenOnlyMode","mirrorScreenMode","extensionMode","secondaryScreenOnlyMode"}; ++ for(QString mode: modes) { ++ m_screen->SetScreenMode(mode); ++ QThread::sleep(2); ++ QString currentMode = m_screen->GetScreenMode(); ++ qDebug()<<"-"<<mode<<"-"<<currentMode; ++ if (mode != currentMode) { ++ errorTimes++; ++ } ++ } ++ m_screen->SetScreenMode(initMode); ++ QCOMPARE(errorTimes, 0); ++} ++ ++void ScreenControlTest::testSetScreensParam() ++{ ++ int errorTimes = 0; ++ const QStringList modes = {"primaryScreenOnlyMode","mirrorScreenMode","extensionMode","secondaryScreenOnlyMode"}; ++ QJsonDocument parser; ++ QString screenParam = m_screen->GetScreensParam(); ++ QVariantList outputs = parser.fromJson(screenParam.toLatin1().data()).toVariant().toList(); ++ if (outputs.count()<2) { ++ QVERIFY(true); ++ return; ++ } ++ m_screen->SetScreenMode("mirrorScreenMode"); ++ QThread::sleep(2); ++ QString cloneParam = m_screen->GetScreensParam(); ++ ++ ++ m_screen->SetScreenMode("extensionMode"); ++ QThread::sleep(2); ++ m_screen->SetScreensParam(cloneParam); ++ qDebug()<<cloneParam; ++ QCOMPARE("mirrorScreenMode", m_screen->GetScreenMode()); ++ m_screen->SetScreensParam(screenParam); ++} ++ ++void ScreenControlTest::testGetScreensParam() ++{ ++ ++} ++ ++void ScreenControlTest::testSetEyeCareEnabled() ++{ ++ bool ret = false; ++ bool initialValue = false; ++ ++ initialValue = m_screen->IsEyeCareEnabled(); ++ m_screen->SetEyeCareEnabled(ret); ++ QCOMPARE(ret, m_screen->IsEyeCareEnabled()); ++ ++ ret =!ret; ++ ++ m_screen->SetEyeCareEnabled(ret); ++ QCOMPARE(ret, m_screen->IsEyeCareEnabled()); ++ m_screen->SetEyeCareEnabled(initialValue); ++} ++ ++//bool ScreenControlTest::testIsEyeCareEnabled() ++//{ ++ ++//} ++ ++void ScreenControlTest::testSetNightModeEnable() ++{ ++ bool ret = false; ++ bool initialValue = false; ++ ++ initialValue = m_screen->IsNightModeEnable(); ++ m_screen->SetNightModeEnable(ret); ++ QCOMPARE(ret, m_screen->IsNightModeEnable()); ++ ++ ret =!ret; ++ ++ m_screen->SetNightModeEnable(ret); ++ QCOMPARE(ret, m_screen->IsNightModeEnable()); ++ m_screen->SetNightModeEnable(initialValue); ++} ++ ++//void ScreenControlTest::testIsNightModeEnable() ++//{ ++ ++//} ++ ++void ScreenControlTest::testSetScreenBrightness() + { +- QCoreApplication app(argc,argv); +- Screen *m_screen = new Screen(); +- QDBusConnection sessionBug = QDBusConnection::sessionBus(); +- if (sessionBug.registerService("org.ukui.SettingsDaemon1")) { +- sessionBug.registerObject("/screen", m_screen, +- QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals +- ); ++ OutputGammaInfoList outputsList = m_screen->GetAllScreenBrightness(); ++ uint testBrightness[] = {100,90,80,70,60,50,40,30,20,10}; ++ uint errorTimes = 0; ++ ++ for (auto &outputInfo: outputsList) { ++ m_screen->SetScreenBrightness(outputInfo.outputName, 100); ++ } ++ ++ for (auto setBrightness: testBrightness) { ++ for (auto &outputInfo: outputsList) { ++ m_screen->SetScreenBrightness(outputInfo.outputName, setBrightness); ++ QThread::msleep(900); ++ } ++ ++ outputsList = m_screen->GetAllScreenBrightness(); ++ for (auto outputInfo: outputsList) { ++ if (outputInfo.brignthess != setBrightness) { ++ errorTimes++; ++ qWarning() << outputInfo.outputName << "fail set brightness to" << setBrightness; ++ } ++ } ++ } ++ ++ ++ for (auto &outputInfo: outputsList) { ++ m_screen->SetScreenBrightness(outputInfo.outputName, 100); ++ } ++ QThread::msleep(3500); ++ QCOMPARE(errorTimes, 0); ++} ++ ++void ScreenControlTest::testSetScreensBrightness() ++{ ++ if (Screen::eBrightnessControl::powerManager == m_screen->getBrightControlMode()) { ++ QVERIFY(true); + } +- app.exec(); +- return 0; + } ++ ++void ScreenControlTest::testSetAllScreenSameBrightness() ++{ ++ if (Screen::eBrightnessControl::powerManager == m_screen->getBrightControlMode()) { ++ QVERIFY(true); ++ } ++} ++ ++//void ScreenControlTest::testGetAllScreenBrightness() ++//{ ++ ++//} ++ ++ ++QTEST_MAIN(ScreenControlTest) ++ ++#include "moc_test.cpp" +diff --git a/dbus/devices/screen/test/test.h b/dbus/devices/screen/test/test.h +index db88a55..3961a86 100644 +--- a/dbus/devices/screen/test/test.h ++++ b/dbus/devices/screen/test/test.h +@@ -1,11 +1,44 @@ +-#ifndef TEST_H +-#define TEST_H +- + #ifndef __TEST_H__ + #define __TEST_H__ +- ++#include <QDebug> ++#include <QDBusError> ++#include <QDBusConnection> ++#include <QCoreApplication> ++#include <QtTest/QtTest> + #include "screen.h" + +-#endif ++#include "../src/screen.h" ++ ++class ScreenControlTest : public QObject ++{ ++ Q_OBJECT ++private: ++ Screen *m_screen; // 替换为你的实际类名 ++ ++public: ++ ScreenControlTest(); ++ ~ScreenControlTest(); ++ ++private slots: ++ void testSetScreenBrightness(); ++ void testSetScreensBrightness(); ++ void testSetAllScreenSameBrightness(); ++// void testGetAllScreenBrightness(); ++ void testSetPrimaryScreenBrightness(); ++// void testGetPrimaryScreenBrightness(); ++ ++ void testIncreaseBuiltinScreenBrightness(); ++ void testDecreaseBuiltinBrightness(); ++// void testGetScreenMode(); ++ void testSetScreenMode(); ++ void testSetScreensParam(); ++ void testGetScreensParam(); ++ void testSetEyeCareEnabled(); ++// bool testIsEyeCareEnabled(); ++ void testSetNightModeEnable(); ++// bool testIsNightModeEnable(); ++ ++}; ++ + + #endif // TEST_H diff -Nru ukui-framework-4.10.0.0/debian/patches/0006-update-changelog-5.0.0.0-ok2.5-task-426462.patch ukui-framework-5.0.0.0/debian/patches/0006-update-changelog-5.0.0.0-ok2.5-task-426462.patch --- ukui-framework-4.10.0.0/debian/patches/0006-update-changelog-5.0.0.0-ok2.5-task-426462.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/patches/0006-update-changelog-5.0.0.0-ok2.5-task-426462.patch 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,199 @@ +From: cxc <chenxuechao@kylinos.cn> +Date: Tue, 25 Mar 2025 09:42:56 +0800 +Subject: =?utf-8?b?dXBkYXRlIGNoYW5nZWxvZywg54mI5pys5Y+3OjUuMC4wLjAtb2syLjUs?= + =?utf-8?b?IHRhc2s6NDI2NDYy?= + +--- + dbus/CMakeLists.txt | 2 ++ + dbus/common.h | 1 + + dbus/devices/CMakeLists.txt | 1 + + dbus/devices/keyboard/CMakeLists.txt | 24 +++++++++++++++++++ + dbus/devices/keyboard/src/keyboard.cpp | 31 ++++++++++++++++++++++++ + dbus/devices/keyboard/src/keyboard.h | 44 ++++++++++++++++++++++++++++++++++ + dbus/main.cpp | 5 ++++ + 7 files changed, 108 insertions(+) + create mode 100644 dbus/devices/keyboard/CMakeLists.txt + create mode 100644 dbus/devices/keyboard/src/keyboard.cpp + create mode 100644 dbus/devices/keyboard/src/keyboard.h + +diff --git a/dbus/CMakeLists.txt b/dbus/CMakeLists.txt +index f9d12b5..4406181 100644 +--- a/dbus/CMakeLists.txt ++++ b/dbus/CMakeLists.txt +@@ -30,6 +30,7 @@ include_directories(devices/network/src) + include_directories(devices/bluetooth/src) + include_directories(devices/power/src) + include_directories(devices/touchpad/src) ++include_directories(devices/keyboard/src) + + include_directories(ui/background) + include_directories(ui/effect) +@@ -50,6 +51,7 @@ target_link_libraries(ukui-framework-dbus + bluetooth + power + touchpad ++ keyboard + theme + background + font +diff --git a/dbus/common.h b/dbus/common.h +index 1b390c8..51ad565 100644 +--- a/dbus/common.h ++++ b/dbus/common.h +@@ -34,6 +34,7 @@ const QString DEVICES_WIFI_PATH = "/org/ukui/Framework/Devices/WIFI"; + const QString DEVICES_TOUCHPAD_PATH = "/org/ukui/Framework/Devices/Touchpad"; + const QString DEVICES_AUDIO_PATH = "/org/ukui/Framework/Devices/Audio"; + const QString DEVICES_GEOLOCATION_PATH = "/org/ukui/Framework/Devices/Geolocation"; ++const QString DEVICES_KEYBOARD_PATH = "/org/ukui/Framework/Devices/Keyboard"; + + // APP相关路径名称 + const QString APP_PATH = "/org/ukui/Framework/APP"; +diff --git a/dbus/devices/CMakeLists.txt b/dbus/devices/CMakeLists.txt +index 19fb6db..5676e24 100644 +--- a/dbus/devices/CMakeLists.txt ++++ b/dbus/devices/CMakeLists.txt +@@ -4,3 +4,4 @@ add_subdirectory(bluetooth) + add_subdirectory(network) + add_subdirectory(power) + add_subdirectory(touchpad) ++add_subdirectory(keyboard) +diff --git a/dbus/devices/keyboard/CMakeLists.txt b/dbus/devices/keyboard/CMakeLists.txt +new file mode 100644 +index 0000000..684716e +--- /dev/null ++++ b/dbus/devices/keyboard/CMakeLists.txt +@@ -0,0 +1,24 @@ ++cmake_minimum_required(VERSION 3.5) ++project(keyboard VERSION 1.0) ++ ++find_package(PkgConfig) ++ ++ ++include_directories(${GLIB_INCLUDE_DIRS}) ++include_directories(${GIO_INCLUDE_DIRS}) ++include_directories(${GOBJECT_INCLUDE_DIRS}) ++ ++# 查找Qt5及其模块 ++find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core DBus) ++ ++set(CMAKE_AUTOMOC ON) ++ ++file(GLOB LIBTOUCHPAD_SOURCES src/*.cpp) ++ ++add_library(keyboard STATIC ${LIBTOUCHPAD_SOURCES}) ++ ++target_link_libraries(keyboard ++ PRIVATE ++ Qt5::Core ++ Qt5::Widgets ++ Qt5::DBus) +diff --git a/dbus/devices/keyboard/src/keyboard.cpp b/dbus/devices/keyboard/src/keyboard.cpp +new file mode 100644 +index 0000000..4d95df3 +--- /dev/null ++++ b/dbus/devices/keyboard/src/keyboard.cpp +@@ -0,0 +1,31 @@ ++#include "keyboard.h" ++ ++Keyboard::Keyboard(QObject *parent) : QObject(parent) ++{ ++ qInfo() << "Initializing Keyboard"; ++ initSignals(); ++} ++ ++int Keyboard::GetKbdCount() ++{ ++ QDBusInterface deviceManagerInterface(USD_SYSBUS_SERVER, ++ USD_SYSBUS_PATH, ++ USD_SYSBUS_INTERFACE, ++ QDBusConnection::systemBus()); ++ QDBusReply<int> reply = deviceManagerInterface.call("getDeviceNum", "kbd"); ++ if (!reply.isValid()) { ++ return 0; ++ } ++ return reply.value(); ++} ++ ++void Keyboard::initSignals() ++{ ++ QDBusConnection::systemBus().connect(USD_SYSBUS_SERVER, ++ USD_SYSBUS_PATH, ++ USD_SYSBUS_INTERFACE, ++ "DeviceNumChanged", ++ this, ++ SIGNAL(KbdCountChanged())); ++} ++ +diff --git a/dbus/devices/keyboard/src/keyboard.h b/dbus/devices/keyboard/src/keyboard.h +new file mode 100644 +index 0000000..1c4c302 +--- /dev/null ++++ b/dbus/devices/keyboard/src/keyboard.h +@@ -0,0 +1,44 @@ ++#ifndef KEYBOARD_H ++#define KEYBOARD_H ++ ++#include <QObject> ++#include <QDBusContext> ++#include <QDBusConnection> ++#include <QDBusConnectionInterface> ++#include <QDBusInterface> ++#include <QDBusPendingCall> ++#include <QDBusReply> ++#include <QDebug> ++#include <QString> ++ ++#define USD_SYSBUS_SERVER "com.kylin.ukui.SettingsDaemon" ++#define USD_SYSBUS_PATH "/devicemanager" ++#define USD_SYSBUS_INTERFACE "com.kylin.ukui.SettingsDaemon.interface" ++ ++class Keyboard : public QObject ++{ ++ Q_OBJECT ++ Q_CLASSINFO("D-Bus Interface", "org.ukui.Framework.Devices.Keyboard") ++public: ++ explicit Keyboard(QObject *parent = nullptr); ++ ++private: ++ /** ++ * @brief initSignals 初始化dbus信号连接 ++ */ ++ void initSignals(); ++ ++public Q_SLOTS: ++ /** ++ * @brief GetKbdNum 获取键盘数量 ++ */ ++ int GetKbdCount(); ++ ++Q_SIGNALS: ++ /** ++ * @brief KbdNumChanged 键盘数量改变信号 ++ */ ++ void KbdCountChanged(); ++}; ++ ++#endif // KEYBOARD_H +diff --git a/dbus/main.cpp b/dbus/main.cpp +index 3f0320b..15d2c8f 100644 +--- a/dbus/main.cpp ++++ b/dbus/main.cpp +@@ -9,6 +9,7 @@ + #include "bluetooth.h" + #include "power.h" + #include "touchpad.h" ++#include "keyboard.h" + + #include "theme.h" + #include "background.h" +@@ -43,6 +44,10 @@ int main(int argc, char *argv[]) + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + ++ sessionBus.registerObject(DEVICES_KEYBOARD_PATH, new Keyboard(), ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ++ ); ++ + QDBusConnection::RegisterOptions uiOptions = QDBusConnection::ExportAllSlots | + QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllProperties; + sessionBus.registerObject(UI_THEME_PATH, new Theme(&a), uiOptions); diff -Nru ukui-framework-4.10.0.0/debian/patches/series ukui-framework-5.0.0.0/debian/patches/series --- ukui-framework-4.10.0.0/debian/patches/series 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/patches/series 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,6 @@ +0001-32-upstream.patch +0002-fix-control-debian-control.patch +0003-fix-contol-5.0.0.0-ok2.2.patch +0004-39-upstream.patch +0005-feat-project-desktop-ukui-framework-api-ukui-framewo.patch +0006-update-changelog-5.0.0.0-ok2.5-task-426462.patch diff -Nru ukui-framework-4.10.0.0/debian/ukui-framework-dbus.install ukui-framework-5.0.0.0/debian/ukui-framework-dbus.install --- ukui-framework-4.10.0.0/debian/ukui-framework-dbus.install 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/debian/ukui-framework-dbus.install 2025-03-25 09:41:05.000000000 +0800 @@ -0,0 +1,2 @@ +data/ukui-framework-dbus.desktop /etc/xdg/autostart +usr/bin/ukui-framework-dbus diff -Nru ukui-framework-4.10.0.0/main.cpp ukui-framework-5.0.0.0/main.cpp --- ukui-framework-4.10.0.0/main.cpp 1970-01-01 08:00:00.000000000 +0800 +++ ukui-framework-5.0.0.0/main.cpp 2024-11-14 11:12:42.000000000 +0800 @@ -0,0 +1,43 @@ +#include <QCoreApplication> +#include <QtDBus/QDBusConnection> +#include <QtDebug> + +#include "common.h" +#include "screen.h" +#include "audio.h" +#include "network.h" +#include "bluetooth.h" +#include "power.h" +#include "touchpad.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + // Todo + // 启动后台服务,加载Dbus接口,注册DBus对象 + QDBusConnection sessionBus = QDBusConnection::sessionBus(); + if (sessionBus.registerService(DBUS_NAME)) { + sessionBus.registerObject(DEVICES_SCREEN_PATH, new Screen(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + sessionBus.registerObject(DEVICES_AUDIO_PATH, new Audio(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + BLUETOOTHDBUS::instance(); + sessionBus.registerObject(DEVICES_BLUETOOTH_PATH, BLUETOOTHDBUS::getInstance(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + sessionBus.registerObject(DEVICES_WIFI_PATH, new Network(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + sessionBus.registerObject(DEVICES_POWER_PATH, new UkuiPowerInterface(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + + sessionBus.registerObject(DEVICES_TOUCHPAD_PATH, new TouchpadManager(), + QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals + ); + } + + return a.exec(); +}