ukui-control-center/0000755000175000017500000000000014201663716013415 5ustar fengfengukui-control-center/checkUserPwdWithPAM/0000755000175000017500000000000014201663671017176 5ustar fengfengukui-control-center/checkUserPwdWithPAM/conf/0000755000175000017500000000000014201663671020123 5ustar fengfengukui-control-center/checkUserPwdWithPAM/conf/control-center0000644000175000017500000000036314201663671023006 0ustar fengfeng@include common-auth auth optional pam_gnome_keyring.so #If you are using Arch,comment out the #above and use the following. #auth include system-auth #account include system-auth #password include system-auth #session include system-auth ukui-control-center/checkUserPwdWithPAM/childCheckPwdWithPAM/0000755000175000017500000000000014201663716023064 5ustar fengfengukui-control-center/checkUserPwdWithPAM/childCheckPwdWithPAM/childCheckPwdWithPAM.pro0000644000175000017500000000165414201663716027502 0ustar fengfengQT -= core QT -= gui TARGET = childCheckpwdwithPAM TEMPLATE = app CONFIG += c++11 # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 LIBS += -lpam SOURCES += \ main.cpp HEADERS += cf.files += ../conf/control-center cf.path = /etc/pam.d/ target.source += $$TARGET target.path = /usr/bin INSTALLS += \ cf \ target \ ukui-control-center/checkUserPwdWithPAM/childCheckPwdWithPAM/main.cpp0000644000175000017500000001054214201663716024516 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include #include #include #include #include #include #include #include static int toParent = 0; static int fromChild = 0; typedef struct pam_message PAM_MESSAGE; typedef struct pam_response PAM_RESPONSE; static void writeData(int fd, const void *buf, ssize_t count) { if(write(fd, buf, count) != count) printf("write to parent failed: %s\n",strerror(errno)); } static void writeString(int fd, const char *data) { int length = data ? strlen(data) : -1; writeData(fd, &length, sizeof(length)); if(data) writeData(fd, data, sizeof(char) * length); } static int readData(int fd, void *buf, size_t count) { ssize_t nRead = read(fd, buf, count); if(nRead < 0) printf("read data failed: %s\n",strerror(errno)); return nRead; } static char * readString(int fd) { int length; if(readData(fd, &length, sizeof(length)) <= 0) return NULL; if(length <= 0) return NULL; char *value = (char *)malloc(sizeof(char) * (length + 1)); readData(fd, value, length); value[length] = '\0'; return value; } static int pam_conversation(int msgLength, const struct pam_message **msg, PAM_RESPONSE **resp, void */*appData*/) { PAM_RESPONSE *response = (PAM_RESPONSE*)calloc(msgLength,sizeof(PAM_RESPONSE)); int authComplete = 0; writeData(toParent, (const void*)&authComplete, sizeof(authComplete)); writeData(toParent, (const void*)&msgLength, sizeof(msgLength)); //发送pam消息 for(int i = 0; i < msgLength; i++) { const struct pam_message *m = msg[i]; writeData(toParent, (const void *)&m->msg_style, sizeof(m->msg_style)); writeString(toParent, m->msg); } //读取响应 for(int i = 0; i < msgLength; i++) { PAM_RESPONSE *r = &response[i]; readData(fromChild, &r->resp_retcode, sizeof(r->resp_retcode)); r->resp = readString(fromChild); } *resp = response; return PAM_SUCCESS; } static void _authenticate(const char *userName) { // printf("authenticate %s\n",userName); pam_handle_t *pamh = NULL; char *newUser; int ret; int authRet; struct pam_conv conv; conv.conv = pam_conversation; conv.appdata_ptr = NULL; ret = pam_start("control-center", userName, &conv, &pamh); if(ret != PAM_SUCCESS) { printf("failed to start PAM: = %s\n", pam_strerror(NULL, ret)); } authRet = pam_authenticate(pamh, 0); ret = pam_get_item(pamh, PAM_USER, (const void **)&newUser); if(ret != PAM_SUCCESS) { pam_end(pamh, 0); printf("failed to get username\n"); } free(newUser); newUser = NULL; // fprintf(stderr, "authentication result: %d\n", authRet); // 发送认证结果 int authComplete = 1; writeData(toParent, (const void*)&authComplete, sizeof(authComplete)); writeData(toParent, (const void *)&authRet, sizeof(authRet)); /* ---认证完成\n*/ _exit(EXIT_SUCCESS); } int main(int argc, char **argv) { if (argc != 4) { return EXIT_FAILURE; } toParent = atoi (argv[1]); fromChild = atoi (argv[2]); if (toParent == 0 || fromChild == 0) { printf ("Invalid file descriptors %s %s\n", argv[2], argv[3]); return EXIT_FAILURE; } mlockall (MCL_CURRENT | MCL_FUTURE); fcntl (toParent, F_SETFD, FD_CLOEXEC); fcntl (fromChild, F_SETFD, FD_CLOEXEC); _authenticate(argv[3]); } ukui-control-center/checkUserPwdWithPAM/checkUserPwdWithPAM.pro0000644000175000017500000000014114201663671023475 0ustar fengfengTEMPLATE = subdirs CONFIG += ordered SUBDIRS = \ childCheckPwdWithPAM \ checkUserPwd \ ukui-control-center/checkUserPwdWithPAM/checkUserPwd/0000755000175000017500000000000014201663716021565 5ustar fengfengukui-control-center/checkUserPwdWithPAM/checkUserPwd/auth.h0000644000175000017500000000312214201663671022675 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology 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 . * **/ #ifndef AUTH_H #define AUTH_H #ifndef QT_NO_KEYWORDS #define QT_NO_KEYWORDS #endif #include class Auth : public QObject { Q_OBJECT Q_ENUMS(PromptType MessageType) public: explicit Auth(QObject *parent = nullptr) : QObject(parent) { } enum PromptType { PromptTypeQuestion, PromptTypeSecret }; enum MessageType { MessageTypeInfo, MessageTypeError }; Q_SIGNALS: void showPrompt(const QString &prompt, Auth::PromptType type); void showMessage(const QString &message, Auth::MessageType type); void authenticateComplete(); public: virtual void authenticate(const QString &userName, const QString &userPwd) = 0; virtual void stopAuth() = 0; virtual void respond(const QString &response) = 0; virtual bool isAuthenticating() = 0; virtual bool isAuthenticated() = 0; }; #endif // AUTH_H ukui-control-center/checkUserPwdWithPAM/checkUserPwd/auth-pam.cpp0000644000175000017500000002245414201663716024014 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology 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 . * **/ #include "auth-pam.h" #include #include #include #include #include #include #define PAM_SERVICE_NAME "control-center" //通信管道的文件描述符 int toParent[2], toChild[2]; static void writeData(int fd, const void *buf, ssize_t count); static void writeString(int fd, const char *data); static int readData(int fd, void *buf, size_t count); static char * readString(int fd); static int pam_conversation(int msgLength, const struct pam_message **msg, PAM_RESPONSE **resp, void *appData); static void sigchld_handler(int signo); AuthPAM::AuthPAM(QObject *parent) : Auth(parent), pid(0), nPrompts(0), _isAuthenticated(false), _isAuthenticating(false) { signal(SIGCHLD, sigchld_handler); } void AuthPAM::authenticate(const QString &userName, const QString &userPwd) { stopAuth(); if(pipe(toParent) || pipe(toChild)) qDebug()<< "create pipe failed: " << strerror(errno); if((pid = fork()) < 0) { qDebug() << "fork error: " << strerror(errno); } else if(pid == 0) { int arg1_int = toParent[1]; int arg2_int = toChild[0]; char arg1[128]; char arg2[128]; snprintf(arg1,128,"%d",arg1_int); snprintf(arg2,128,"%d",arg2_int); //_authenticate(userName.toLocal8Bit().data()); prctl(PR_SET_PDEATHSIG,SIGHUP); execlp ("childCheckpwdwithPAM", "childCheckpwdwithPAM", arg1, arg2,userName.toLocal8Bit().data(), NULL); _exit (EXIT_FAILURE); } else { _isAuthenticating = true; notifier = new QSocketNotifier(toParent[0], QSocketNotifier::Read); connect(notifier, &QSocketNotifier::activated, this, &AuthPAM::onSockRead); } QTimer::singleShot(300, this, [=]{respond(userPwd);}); } void AuthPAM::stopAuth() { // qDebug()<<"pppppppppppppppppid = "<resp = (char *)malloc(sizeof(char) * respLength); memcpy(r->resp, responseList[j].toLocal8Bit().data(), respLength); j++; } } _respond(resp); free(resp); resp = NULL; messageList.clear(); responseList.clear(); } } bool AuthPAM::isAuthenticated() { return _isAuthenticated; } bool AuthPAM::isAuthenticating() { return _isAuthenticating; } void AuthPAM::onSockRead() { // qDebug() << "has message"; int msgLength; int authComplete; readData(toParent[0], &authComplete, sizeof(authComplete)); if(authComplete) { int authRet; if(readData(toParent[0], (void*)&authRet, sizeof(authRet)) <= 0) qDebug() << "get authentication result failed: " << strerror(errno); // qDebug() << "result: " << authRet; _isAuthenticated = (authRet == PAM_SUCCESS); _isAuthenticating = false; Q_EMIT authenticateComplete(); } else { readData(toParent[0], &msgLength, sizeof(msgLength)); // qDebug() << "message length: " << msgLength; for(int i = 0; i < msgLength; i++) { //读取message struct pam_message message; readData(toParent[0], &message.msg_style, sizeof(message.msg_style)); message.msg = readString(toParent[0]); // qDebug() << message.msg; messageList.push_back(message); switch (message.msg_style) { case PAM_PROMPT_ECHO_OFF: nPrompts++; Q_EMIT showPrompt(message.msg, Auth::PromptTypeSecret); break; case PAM_PROMPT_ECHO_ON: nPrompts++; Q_EMIT showPrompt(message.msg, Auth::PromptTypeQuestion); break; case PAM_ERROR_MSG: Q_EMIT showMessage(message.msg, Auth::MessageTypeInfo); break; case PAM_TEXT_INFO: Q_EMIT showMessage(message.msg, Auth::MessageTypeError); break; } } if(nPrompts == 0) { //不需要响应,发送一个空的 PAM_RESPONSE *response = (PAM_RESPONSE*)calloc(messageList.size(), sizeof(PAM_RESPONSE)); _respond(response); free(response); response = NULL; messageList.clear(); } } } static void writeData(int fd, const void *buf, ssize_t count) { if(write(fd, buf, count) != count) qDebug() << "write to parent failed: " << strerror(errno); } static void writeString(int fd, const char *data) { int length = data ? strlen(data) : -1; writeData(fd, &length, sizeof(length)); if(data) writeData(fd, data, sizeof(char) * length); } static int readData(int fd, void *buf, size_t count) { ssize_t nRead = read(fd, buf, count); if(nRead < 0) qDebug() << "read data failed: " << strerror(errno); return nRead; } static char * readString(int fd) { int length; if(readData(fd, &length, sizeof(length)) <= 0) return NULL; if(length <= 0) return NULL; char *value = (char *)malloc(sizeof(char) * (length + 1)); readData(fd, value, length); value[length] = '\0'; return value; } void AuthPAM::_authenticate(const char *userName) { // qDebug() << "authenticate " << userName; pam_handle_t *pamh = NULL; char *newUser; int ret; int authRet; struct pam_conv conv; conv.conv = pam_conversation; conv.appdata_ptr = NULL; ret = pam_start(PAM_SERVICE_NAME, userName, &conv, &pamh); if(ret != PAM_SUCCESS) { qDebug() << "failed to start PAM: " << pam_strerror(NULL, ret); } authRet = pam_authenticate(pamh, 0); ret = pam_get_item(pamh, PAM_USER, (const void **)&newUser); if(ret != PAM_SUCCESS) { pam_end(pamh, 0); qDebug() << "failed to get username"; } free(newUser); newUser = NULL; // fprintf(stderr, "authentication result: %d\n", authRet); // 发送认证结果 int authComplete = 1; writeData(toParent[1], (const void*)&authComplete, sizeof(authComplete)); writeData(toParent[1], (const void *)&authRet, sizeof(authRet)); // qDebug() << "--- 认证完成"; _exit(EXIT_SUCCESS); } void AuthPAM::_respond(const PAM_RESPONSE *response) { for(int i = 0; i < messageList.size(); i++) { const PAM_RESPONSE *resp = &response[i]; writeData(toChild[1], (const void *)&resp->resp_retcode, sizeof(resp->resp_retcode)); writeString(toChild[1], resp->resp); } } static int pam_conversation(int msgLength, const struct pam_message **msg, PAM_RESPONSE **resp, void */*appData*/) { PAM_RESPONSE *response = (PAM_RESPONSE*)calloc(msgLength,sizeof(PAM_RESPONSE)); int authComplete = 0; writeData(toParent[1], (const void*)&authComplete, sizeof(authComplete)); writeData(toParent[1], (const void*)&msgLength, sizeof(msgLength)); //发送pam消息 for(int i = 0; i < msgLength; i++) { const struct pam_message *m = msg[i]; writeData(toParent[1], (const void *)&m->msg_style, sizeof(m->msg_style)); writeString(toParent[1], m->msg); } //读取响应 for(int i = 0; i < msgLength; i++) { PAM_RESPONSE *r = &response[i]; readData(toChild[0], &r->resp_retcode, sizeof(r->resp_retcode)); r->resp = readString(toChild[0]); } *resp = response; return PAM_SUCCESS; } void sigchld_handler(int signo) { if(signo == SIGCHLD) { ::waitpid(-1, NULL, WNOHANG); } } ukui-control-center/checkUserPwdWithPAM/checkUserPwd/auth-pam.h0000644000175000017500000000312514201663671023453 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology 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 . * **/ #ifndef AUTHPAM_H #define AUTHPAM_H #include "auth.h" #include #include #include typedef struct pam_message PAM_MESSAGE; typedef struct pam_response PAM_RESPONSE; class AuthPAM : public Auth { Q_OBJECT public: AuthPAM(QObject *parent = nullptr); void authenticate(const QString &userName, const QString &userPwd); void stopAuth(); void respond(const QString &response); bool isAuthenticated(); bool isAuthenticating(); private: void _authenticate(const char *userName); void _respond(const struct pam_response *response); private Q_SLOTS: void onSockRead(); private: QString userName; pid_t pid; QSocketNotifier *notifier; int nPrompts; QStringList responseList; QList messageList; bool _isAuthenticated; //认证结果 bool _isAuthenticating; }; #endif // AUTHPAM_H ukui-control-center/checkUserPwdWithPAM/checkUserPwd/widget.h0000644000175000017500000000231614201663716023223 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef WIDGET_H #define WIDGET_H #include "auth-pam.h" class Widget : public QObject { Q_OBJECT public: Widget(); ~Widget(); public: void pwdCheck(QString userName, QString userPwd); private: Auth * auth; bool accountlock; private Q_SLOTS: void onShowMessage(const QString &message, Auth::MessageType type); void onShowPrompt(const QString &prompt, Auth::PromptType type); void onAuthComplete(); }; #endif // WIDGET_H ukui-control-center/checkUserPwdWithPAM/checkUserPwd/widget.cpp0000644000175000017500000000354114201663716023557 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "widget.h" #include "auth-pam.h" #include Widget::Widget() { auth = new AuthPAM(this); accountlock = false; connect(auth, &Auth::showMessage, this, &Widget::onShowMessage); connect(auth, &Auth::showPrompt, this, &Widget::onShowPrompt); connect(auth, &Auth::authenticateComplete, this, &Widget::onAuthComplete); } Widget::~Widget() { auth->stopAuth(); delete auth; } void Widget::pwdCheck(QString userName, QString userPwd){ auth->authenticate(userName, userPwd); } void Widget::onShowMessage(const QString &message, Auth::MessageType type) { // qDebug() << "message:" << message; accountlock = true; printf("%s\n", message.toUtf8().data()); } void Widget::onShowPrompt(const QString &prompt, Auth::PromptType type) { // qDebug() << "prompt: " << prompt; } void Widget::onAuthComplete() { if (!accountlock){ if(auth->isAuthenticated()){ // qDebug() << "Succes!\n"; // printf("Succes!\n"); } else { printf("Failed!\n"); // qDebug() << "Failed!"; } } exit(0); } ukui-control-center/checkUserPwdWithPAM/checkUserPwd/checkUserPwd.pro0000644000175000017500000000171214201663671024677 0ustar fengfengQT += core greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = checkUserPwd TEMPLATE = app CONFIG += c++11 # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 LIBS += -lpam SOURCES += \ auth-pam.cpp \ main.cpp \ widget.cpp HEADERS += \ auth-pam.h \ auth.h \ widget.h target.source += $$TARGET target.path = /usr/bin INSTALLS += \ target \ ukui-control-center/checkUserPwdWithPAM/checkUserPwd/main.cpp0000644000175000017500000000201714201663716023215 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "widget.h" #include #include int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Widget w; if (argc == 3){ w.pwdCheck(argv[1], argv[2]); } else { return 1; } return a.exec(); } ukui-control-center/plugins/0000755000175000017500000000000014201663716015076 5ustar fengfengukui-control-center/plugins/messages-task/0000755000175000017500000000000014201663716017645 5ustar fengfengukui-control-center/plugins/messages-task/experienceplan/0000755000175000017500000000000014201663716022647 5ustar fengfengukui-control-center/plugins/messages-task/experienceplan/experienceplan.h0000644000175000017500000000352114201663716026023 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef EXPERIENCEPLAN_H #define EXPERIENCEPLAN_H #include #include #include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" QT_BEGIN_NAMESPACE namespace Ui { class ExperiencePlan; } QT_END_NAMESPACE class ExperiencePlan : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: ExperiencePlan(); ~ExperiencePlan(); public: QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void setupComponent(); void initEpStatus(); private: Ui::ExperiencePlan *ui; private: QString pluginName; int pluginType; QWidget * pluginWidget; private: SwitchButton * joinSwitchBtn; QGSettings * eSettings; }; #endif // EXPERIENCEPLAN_H ukui-control-center/plugins/messages-task/experienceplan/experienceplan.pro0000644000175000017500000000150614201663716026375 0ustar fengfenginclude(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(experienceplan) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt CONFIG += \ link_pkgconfig \ c++11 \ PKGCONFIG += gsettings-qt \ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ experienceplan.cpp HEADERS += \ experienceplan.h FORMS += \ experienceplan.ui INSTALLS += target ukui-control-center/plugins/messages-task/experienceplan/experienceplan.ui0000644000175000017500000001470614201663716026220 0ustar fengfeng ExperiencePlan 0 0 800 600 ExperiencePlan 0 0 0 32 30 550 0 960 16777215 0 0 0 0 0 8 0 0 0 User Experience 0 50 16777215 50 0 0 0 0 0 16 16 0 0 Join in user Experience plan Qt::Horizontal 40 20 0 16 16 0 0 User experience plan terms, see 《User Experience plan》 Qt::Horizontal 40 20 Qt::Vertical 20 40 TitleLabel QLabel
Label/titlelabel.h
ukui-control-center/plugins/messages-task/experienceplan/experienceplan.cpp0000644000175000017500000000442114201663716026356 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "experienceplan.h" #include "ui_experienceplan.h" #define E_PLAN_SCHEMA "org.ukui.control-center.experienceplan" #define JOIN_KEY "join" ExperiencePlan::ExperiencePlan() { ui = new Ui::ExperiencePlan; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); pluginName = tr("Experienceplan"); pluginType = NOTICEANDTASKS; QByteArray id(E_PLAN_SCHEMA); eSettings = new QGSettings(id); setupComponent(); initEpStatus(); } ExperiencePlan::~ExperiencePlan() { delete ui; ui = nullptr; delete eSettings; eSettings = nullptr; } QString ExperiencePlan::get_plugin_name(){ return pluginName; } int ExperiencePlan::get_plugin_type(){ return pluginType; } QWidget * ExperiencePlan::get_plugin_ui(){ return pluginWidget; } void ExperiencePlan::plugin_delay_control(){ } const QString ExperiencePlan::name() const{ return QStringLiteral("experienceplan"); } void ExperiencePlan::setupComponent(){ joinSwitchBtn = new SwitchButton(pluginWidget); ui->joinHorLayout->addWidget(joinSwitchBtn); connect(joinSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ eSettings->set(JOIN_KEY, checked); }); } void ExperiencePlan::initEpStatus(){ joinSwitchBtn->blockSignals(true); joinSwitchBtn->setChecked(eSettings->get(JOIN_KEY).toBool()); joinSwitchBtn->blockSignals(false); } ukui-control-center/plugins/messages-task/messages-task.pro0000644000175000017500000000012114201663716023130 0ustar fengfengTEMPLATE = subdirs SUBDIRS = \ about \ multitask \ notice-operation ukui-control-center/plugins/messages-task/multitask/0000755000175000017500000000000014201663716021662 5ustar fengfengukui-control-center/plugins/messages-task/multitask/multitask.cpp0000644000175000017500000000267214201663716024412 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "multitask.h" #include "ui_multitask.h" Multitask::Multitask() { ui = new Ui::Multitask; pluginWidget = new CustomWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); pluginName = tr("multitask"); pluginType = MESSAGES_TASK; } Multitask::~Multitask() { delete ui; ui = nullptr; } QString Multitask::get_plugin_name(){ return pluginName; } int Multitask::get_plugin_type(){ return pluginType; } CustomWidget * Multitask::get_plugin_ui(){ return pluginWidget; } void Multitask::plugin_delay_control(){ } ukui-control-center/plugins/messages-task/multitask/multitask.pro0000644000175000017500000000106514201663716024423 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-06-29T15:22:24 # #------------------------------------------------- include(../../../env.pri) include(../../pluginsComponent/pluginsComponent.pri) QT += widgets TARGET = $$qtLibraryTarget(multitask) DESTDIR = ../.. TEMPLATE = lib CONFIG += plugin INCLUDEPATH += ../../.. #DEFINES += QT_DEPRECATED_WARNINGS target.path = $${PLUGIN_INSTALL_DIRS} INSTALLS += target SOURCES += \ multitask.cpp HEADERS += \ multitask.h FORMS += \ multitask.uiukui-control-center/plugins/messages-task/multitask/multitask.ui0000644000175000017500000000233614201663716024242 0ustar fengfeng Multitask 0 0 756 574 756 574 756 574 Multitask 0 Multitask ukui-control-center/plugins/messages-task/multitask/multitask.h0000644000175000017500000000311314201663716024046 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef MULTITASK_H #define MULTITASK_H #include #include #include #include "mainui/interface.h" #include "../../pluginsComponent/customwidget.h" namespace Ui { class Multitask; } class Multitask : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Multitask(); ~Multitask(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; CustomWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; private: Ui::Multitask *ui; QString pluginName; int pluginType; CustomWidget * pluginWidget; }; #endif // MULTITASK_H ukui-control-center/plugins/messages-task/search/0000755000175000017500000000000014201663716021112 5ustar fengfengukui-control-center/plugins/messages-task/search/search.pro0000644000175000017500000000204314201663716023100 0ustar fengfengQT += widgets #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/comboxframe.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(search) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gio-2.0 \ gio-unix-2.0 \ INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ /usr/include/dconf LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -ldconf CONFIG += c++11 \ link_pkgconfig \ PKGCONFIG += gsettings-qt \ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ search.cpp HEADERS += \ search.h FORMS += \ search.ui INSTALLS += target DISTFILES += \ ../../../commonComponent/imageutil.pri ukui-control-center/plugins/messages-task/search/search.h0000644000175000017500000000660414201663716022536 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SEARCH_H #define SEARCH_H #include #include #include #include #include #include #include #include #include #include #include #include #include "HoverWidget/hoverwidget.h" #include "shell/interface.h" #include "ComboxFrame/comboxframe.h" #define UKUI_SEARCH_SCHEMAS "org.ukui.search.settings" #define SEARCH_METHOD_KEY "indexSearch" #define WEB_ENGINE_KEY "webEngine" //TODO #define CONFIG_FILE "/.config/org.ukui/ukui-search/ukui-search-block-dirs.conf" #include "Label/titlelabel.h" namespace Ui { class Search; } enum ReturnCode { Succeed, PathEmpty, NotInHomeDir, ParentExist, HasBeenBlocked }; class Search : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: explicit Search(); ~Search(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; private: Ui::Search *ui; QWidget * m_plugin_widget = nullptr; QString m_plugin_name = ""; int m_plugin_type = 0; QGSettings * m_gsettings = nullptr; void initUi(); QVBoxLayout * m_mainLyt = nullptr; //设置搜索模式 TitleLabel * m_methodTitleLabel = nullptr; QLabel * m_descLabel = nullptr; QFrame * m_searchMethodFrame = nullptr; QHBoxLayout * m_searchMethodLyt = nullptr; QLabel * m_searchMethodLabel = nullptr; SwitchButton * m_searchMethodBtn = nullptr; //设置黑名单 TitleLabel * m_blockDirTitleLabel = nullptr; QLabel * m_blockDirDescLabel = nullptr; QFrame * m_blockDirsFrame = nullptr; QVBoxLayout * m_blockDirsLyt = nullptr; HoverWidget * m_addBlockDirWidget = nullptr; QLabel * m_addBlockDirIcon = nullptr; QLabel * m_addBlockDirLabel = nullptr; QHBoxLayout * m_addBlockDirLyt = nullptr; QStringList m_blockDirs; QSettings * m_dirSettings = nullptr; void getBlockDirs(); int setBlockDir(const QString &dirPath, const bool &is_add = true); void appendBlockDirToList(const QString &path); void removeBlockDirFromList(const QString &path); void initBlockDirsList(); // void refreshBlockDirsList(); //设置搜索引擎 TitleLabel * m_webEngineLabel = nullptr; ComboxFrame * m_webEngineFrame = nullptr; void setupConnection(); private slots: void onBtnAddFolderClicked(); }; #endif // SEARCH_H ukui-control-center/plugins/messages-task/search/search.cpp0000644000175000017500000004000514201663716023062 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "search.h" #include "ui_search.h" #include "ImageUtil/imageutil.h" Search::Search() { m_plugin_name = tr("Search"); m_plugin_type = NOTICEANDTASKS; initUi(); setupConnection(); m_dirSettings = new QSettings(QDir::homePath() + CONFIG_FILE, QSettings::NativeFormat, this); m_dirSettings->setIniCodec(QTextCodec::codecForName("UTF-8")); initBlockDirsList(); } Search::~Search() { if (m_gsettings) { delete m_gsettings; m_gsettings = nullptr; } } QString Search::get_plugin_name() { return m_plugin_name; } int Search::get_plugin_type() { return m_plugin_type; } QWidget *Search::get_plugin_ui() { ui = new Ui::Search; m_plugin_widget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(m_plugin_widget); const QByteArray id(UKUI_SEARCH_SCHEMAS); if (QGSettings::isSchemaInstalled(id)) { m_gsettings = new QGSettings(id, QByteArray(), this); //按钮状态初始化 if (m_gsettings->keys().contains(SEARCH_METHOD_KEY)) { //当前是否使用索引搜索/暴力搜索 bool is_index_search_on = m_gsettings->get(SEARCH_METHOD_KEY).toBool(); m_searchMethodBtn->setChecked(is_index_search_on); } else { m_searchMethodBtn->setEnabled(false); } if (m_gsettings->keys().contains(WEB_ENGINE_KEY)) { //当前网页搜索的搜索引擎 QString engine = m_gsettings->get(WEB_ENGINE_KEY).toString(); m_webEngineFrame->mCombox->setCurrentIndex(m_webEngineFrame->mCombox->findData(engine)); } else { m_webEngineFrame->mCombox->setEnabled(false); } //监听gsettings值改变,更新控制面板UI connect(m_gsettings, &QGSettings::changed, this, [ = ](const QString &key) { if (key == SEARCH_METHOD_KEY) { bool is_index_search_on = m_gsettings->get(SEARCH_METHOD_KEY).toBool(); m_searchMethodBtn->blockSignals(true); m_searchMethodBtn->setChecked(is_index_search_on); m_searchMethodBtn->blockSignals(false); } else if (key == WEB_ENGINE_KEY) { QString engine = m_gsettings->get(WEB_ENGINE_KEY).toString(); m_webEngineFrame->mCombox->blockSignals(true); m_webEngineFrame->mCombox->setCurrentIndex(m_webEngineFrame->mCombox->findData(engine)); m_webEngineFrame->mCombox->blockSignals(false); } }); connect(m_searchMethodBtn, &SwitchButton::checkedChanged, this, [ = ](bool checked) { if (m_gsettings && m_gsettings->keys().contains(SEARCH_METHOD_KEY)) { m_gsettings->set(SEARCH_METHOD_KEY, checked); } }); connect(m_webEngineFrame->mCombox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { if (m_gsettings && m_gsettings->keys().contains(WEB_ENGINE_KEY)) { m_gsettings->set(WEB_ENGINE_KEY, m_webEngineFrame->mCombox->currentData().toString()); } }); } else { qCritical() << UKUI_SEARCH_SCHEMAS << " not installed!\n"; m_searchMethodBtn->setEnabled(false); m_webEngineFrame->mCombox->setEnabled(false); } return m_plugin_widget; } void Search::plugin_delay_control() { } const QString Search::name() const { return QStringLiteral("search"); } /** * @brief Search::initUi 初始化此插件UI */ void Search::initUi() { m_plugin_widget = new QWidget; m_mainLyt = new QVBoxLayout(m_plugin_widget); m_plugin_widget->setLayout(m_mainLyt); //设置搜索模式部分的ui m_methodTitleLabel = new TitleLabel(m_plugin_widget); //~ contents_path /search/Create Index m_methodTitleLabel->setText(tr("Create Index")); m_descLabel = new QLabel(m_plugin_widget); m_descLabel->setText(tr("Creating index can help you getting results quickly.")); m_searchMethodFrame = new QFrame(m_plugin_widget); m_searchMethodFrame->setFrameShape(QFrame::Shape::Box); m_searchMethodFrame->setFixedHeight(56); m_searchMethodFrame->setMinimumWidth(550); m_searchMethodFrame->setMaximumWidth(960); m_searchMethodLyt = new QHBoxLayout(m_searchMethodFrame); m_searchMethodFrame->setLayout(m_searchMethodLyt); m_searchMethodLabel = new QLabel(m_searchMethodFrame); m_searchMethodLabel->setText(tr("Create Index")); m_searchMethodBtn = new SwitchButton(m_searchMethodFrame); m_searchMethodLyt->addWidget(m_searchMethodLabel); m_searchMethodLyt->addStretch(); m_searchMethodLyt->addWidget(m_searchMethodBtn); m_mainLyt->addWidget(m_methodTitleLabel); m_mainLyt->addWidget(m_descLabel); m_mainLyt->addWidget(m_searchMethodFrame); //设置黑名单文件夹部分的ui m_blockDirTitleLabel = new TitleLabel(m_plugin_widget); //~ contents_path /search/Block Folders m_blockDirTitleLabel->setText(tr("Block Folders")); m_blockDirDescLabel = new QLabel(m_plugin_widget); m_blockDirDescLabel->setWordWrap(true); m_blockDirDescLabel->setText(tr("Following folders will not be searched. You can set it by adding and removing folders.")); m_blockDirsFrame = new QFrame(m_plugin_widget); m_blockDirsFrame->setFrameShape(QFrame::Shape::NoFrame); m_blockDirsLyt = new QVBoxLayout(m_blockDirsFrame); m_blockDirsFrame->setLayout(m_blockDirsLyt); m_blockDirsLyt->setContentsMargins(0, 0, 0, 0); m_blockDirsLyt->setSpacing(2); m_addBlockDirWidget = new HoverWidget("", m_plugin_widget); m_addBlockDirWidget->setObjectName("addBlockDirWidget"); QPalette pal; QBrush brush = pal.highlight(); //获取window的色值 QColor highLightColor = brush.color(); QString stringColor = QString("rgba(%1,%2,%3)") //叠加20%白色 .arg(highLightColor.red()*0.8 + 255*0.2) .arg(highLightColor.green()*0.8 + 255*0.2) .arg(highLightColor.blue()*0.8 + 255*0.2); m_addBlockDirWidget->setStyleSheet(QString("HoverWidget#addBlockDirWidget{background: palette(button);\ border-radius: 4px;}\ HoverWidget:hover:!pressed#addBlockDirWidget{background: %1; \ border-radius: 4px;}").arg(stringColor)); m_addBlockDirWidget->setFixedHeight(50); m_addBlockDirWidget->setMaximumWidth(960); m_addBlockDirIcon = new QLabel(m_addBlockDirWidget); m_addBlockDirIcon->setPixmap(QIcon(":/img/titlebar/add.svg").pixmap(12, 12)); m_addBlockDirIcon->setProperty("useIconHighlightEffect", true); m_addBlockDirIcon->setProperty("iconHighlightEffectMode", 1); m_addBlockDirLabel = new QLabel(m_addBlockDirWidget); m_addBlockDirLabel->setText(tr("Choose folder")); m_addBlockDirLyt = new QHBoxLayout(m_addBlockDirWidget); m_addBlockDirWidget->setLayout(m_addBlockDirLyt); m_addBlockDirLyt->addWidget(m_addBlockDirIcon); m_addBlockDirLyt->addWidget(m_addBlockDirLabel); m_addBlockDirLyt->addStretch(); m_mainLyt->addSpacing(32); m_mainLyt->addWidget(m_blockDirTitleLabel); m_mainLyt->addWidget(m_blockDirDescLabel); m_mainLyt->addWidget(m_blockDirsFrame); m_mainLyt->addWidget(m_addBlockDirWidget); //设置网页搜索引擎部分的ui m_webEngineLabel = new TitleLabel(m_plugin_widget); //~ contents_path /search/Web Engine m_webEngineLabel->setText(tr("Web Engine")); m_webEngineFrame = new ComboxFrame(tr("Default web searching engine"), m_plugin_widget); m_webEngineFrame->setFixedHeight(56); m_webEngineFrame->setMinimumWidth(550); m_webEngineFrame->setMaximumWidth(960); m_webEngineFrame->mCombox->insertItem(0, QIcon(":/img/plugins/search/baidu.svg"), tr("baidu"), "baidu"); m_webEngineFrame->mCombox->insertItem(1, QIcon(":/img/plugins/search/sougou.svg"), tr("sougou"), "sougou"); m_webEngineFrame->mCombox->insertItem(2, QIcon(":/img/plugins/search/360.svg"), tr("360"), "360"); m_mainLyt->addSpacing(32); m_mainLyt->setSpacing(8); m_mainLyt->addWidget(m_webEngineLabel); m_mainLyt->addWidget(m_webEngineFrame); m_mainLyt->addStretch(); m_mainLyt->setContentsMargins(0, 0, 40, 0); // 悬浮改变Widget状态 connect(m_addBlockDirWidget, &HoverWidget::enterWidget, this, [=](){ m_addBlockDirIcon->setProperty("useIconHighlightEffect", false); m_addBlockDirIcon->setProperty("iconHighlightEffectMode", 0); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); m_addBlockDirIcon->setPixmap(pixgray); m_addBlockDirLabel->setStyleSheet("color: white;"); }); // 还原状态 connect(m_addBlockDirWidget, &HoverWidget::leaveWidget, this, [=](){ m_addBlockDirIcon->setProperty("useIconHighlightEffect", true); m_addBlockDirIcon->setProperty("iconHighlightEffectMode", 1); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); m_addBlockDirIcon->setPixmap(pixgray); m_addBlockDirLabel->setStyleSheet("color: palette(windowText);"); }); } /** * @brief Search::getBlockDirs 从配置文件获取黑名单并将黑名单列表传入 */ void Search::getBlockDirs() { m_blockDirs.clear(); if (m_dirSettings) m_blockDirs = m_dirSettings->allKeys(); } /** * @brief Search::setBlockDir 尝试写入新的黑名单文件夹 * @param dirPath 待添加到黑名单的文件夹路径 * @param is_add 是否是在添加黑名单 * @return 0成功 !0添加失败的错误代码 */ int Search::setBlockDir(const QString &dirPath, const bool &is_add) { if (!is_add) { if (dirPath.isEmpty()) { return ReturnCode::PathEmpty; } //删除黑名单目录 m_dirSettings->remove(dirPath); removeBlockDirFromList(dirPath); return ReturnCode::Succeed; } if (!dirPath.startsWith(QDir::homePath())) { return ReturnCode::NotInHomeDir; } QString pathKey = dirPath.right(dirPath.length() - 1); for (QString dir : m_blockDirs) { if (pathKey == dir) { return ReturnCode::HasBeenBlocked; } if (pathKey.startsWith(dir)) { return ReturnCode::ParentExist; } //有它的子文件夹已被添加,删除这些子文件夹 if (dir.startsWith(pathKey)) { m_dirSettings->remove(dir); removeBlockDirFromList("/" + dir); } } m_dirSettings->setValue(pathKey, "0"); appendBlockDirToList(dirPath); return ReturnCode::Succeed; } /** * @brief Search::initBlockDirsList 初始化黑名单列表 */ void Search::initBlockDirsList() { getBlockDirs(); foreach (QString path, m_blockDirs) { QString wholePath = QString("/%1").arg(path); if (QFileInfo(wholePath).isDir() && path.startsWith("home")) { appendBlockDirToList(wholePath); } } } ///** // * @brief Search::refreshBlockDirsList // */ //void Search::refreshBlockDirsList() //{ //} void Search::appendBlockDirToList(const QString &path) { HoverWidget * dirWidget = new HoverWidget(path, m_blockDirsFrame); dirWidget->setObjectName(path); dirWidget->setMinimumSize(550,50); dirWidget->setMaximumSize(960,50); dirWidget->setAttribute(Qt::WA_DeleteOnClose); QHBoxLayout * dirWidgetLyt = new QHBoxLayout(dirWidget); dirWidgetLyt->setSpacing(8); dirWidgetLyt->setContentsMargins(0, 0, 0, 0); dirWidget->setLayout(dirWidgetLyt); QFrame * dirFrame = new QFrame(dirWidget); dirFrame->setFrameShape(QFrame::Shape::Box); dirFrame->setFixedHeight(50); QHBoxLayout * dirFrameLayout = new QHBoxLayout(dirFrame); dirFrameLayout->setSpacing(16); dirFrameLayout->setContentsMargins(16, 0, 16, 0); QLabel * iconLabel = new QLabel(dirFrame); QLabel * pathLabel = new QLabel(dirFrame); dirFrameLayout->addWidget(iconLabel); iconLabel->setPixmap(QIcon::fromTheme("inode-directory").pixmap(QSize(24, 24))); pathLabel->setText(path); dirFrameLayout->addWidget(pathLabel); dirFrameLayout->addStretch(); QPushButton * delBtn = new QPushButton(dirWidget); delBtn->setText(tr("delete")); delBtn->hide(); connect(delBtn, &QPushButton::clicked, this, [ = ]() { setBlockDir(path, false); getBlockDirs(); }); connect(dirWidget, &HoverWidget::enterWidget, this, [ = ]() { delBtn->show(); }); connect(dirWidget, &HoverWidget::leaveWidget, this, [ = ]() { delBtn->hide(); }); dirWidgetLyt->addWidget(dirFrame); dirWidgetLyt->addWidget(delBtn); m_blockDirsLyt->addWidget(dirWidget); } void Search::removeBlockDirFromList(const QString &path) { HoverWidget * delDirWidget = m_blockDirsFrame->findChild(path); if (delDirWidget) { qDebug() << "Delete folder succeed! path = " << path; delDirWidget->close(); } } void Search::setupConnection() { connect(m_addBlockDirWidget, &HoverWidget::widgetClicked, this, &Search::onBtnAddFolderClicked); } void Search::onBtnAddFolderClicked() { QFileDialog * fileDialog = new QFileDialog(m_plugin_widget); // fileDialog->setFileMode(QFileDialog::Directory); //允许查看文件和文件夹,但只允许选择文件夹 fileDialog->setFileMode(QFileDialog::DirectoryOnly); //只允许查看文件夹 // fileDialog->setViewMode(QFileDialog::Detail); fileDialog->setDirectory(QDir::homePath()); fileDialog->setNameFilter(tr("Directories")); fileDialog->setWindowTitle(tr("select blocked folder")); fileDialog->setLabelText(QFileDialog::Accept, tr("Select")); fileDialog->setLabelText(QFileDialog::LookIn, tr("Position: ")); fileDialog->setLabelText(QFileDialog::FileName, tr("FileName: ")); fileDialog->setLabelText(QFileDialog::FileType, tr("FileType: ")); fileDialog->setLabelText(QFileDialog::Reject, tr("Cancel")); if(fileDialog->exec() != QDialog::Accepted) { fileDialog->deleteLater(); return; } QString selectedDir = 0; selectedDir = fileDialog->selectedFiles().first(); qDebug() << "Selected a folder in onBtnAddClicked(): " << selectedDir; int returnCode = setBlockDir(selectedDir, true); switch (returnCode) { case ReturnCode::Succeed : qDebug() << "Add blocked folder succeed! path = " << selectedDir; getBlockDirs(); break; case ReturnCode::PathEmpty : qWarning() << "Add blocked folder failed, choosen path is empty! path = " << selectedDir; QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, choosen path is empty!")); break; case ReturnCode::NotInHomeDir : qWarning() << "Add blocked folder failed, it is not in home path! path = " << selectedDir; QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, it is not in home path!")); break; case ReturnCode::ParentExist : qWarning() << "Add blocked folder failed, its parent dir is exist! path = " << selectedDir; QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, its parent dir is exist!")); break; case ReturnCode::HasBeenBlocked : qWarning() << "Add blocked folder failed, it has been already blocked! path = " << selectedDir; QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, it has been already blocked!")); break; default: break; } } ukui-control-center/plugins/messages-task/search/search.ui0000644000175000017500000000057114201663716022721 0ustar fengfeng Search 0 0 784 630 Form ukui-control-center/plugins/messages-task/notice/0000755000175000017500000000000014201663716021126 5ustar fengfengukui-control-center/plugins/messages-task/notice/realizenotice.h0000644000175000017500000000417214201663716024140 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef REALIZENOTICE_H #define REALIZENOTICE_H #include #include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif extern "C" { #include #include #include #include } #define THEME_QT_SCHEMA "org.ukui.style" #define ICON_QT_KEY "icon-theme-name" #define NOTICE_SCHEMA "org.ukui.control-center.notice" #define NEW_FEATURE_KEY "show-new-feature" #define ENABLE_NOTICE_KEY "enable-notice" #define SHOWON_LOCKSCREEN_KEY "show-on-lockscreen" #define IS_CN "iscn-env" #define BLACKLIST "blacklist" #define NOTICE_ORIGIN_SCHEMA "org.ukui.control-center.noticeorigin" #define NOTICE_ORIGIN_PATH "/org/ukui/control-center/noticeorigin/" #define MAX_SHORTCUTS 1000 #define MESSAGES_KEY "messages" #define VOICE_KEY "voice" #define MAXIMINE_KEY "maximize" #define NAME_KEY_US "name-us" #define NAME_KEY_CN "name-cn" #define MAX_CUSTOM_SHORTCUTS 1000 QList listExistsCustomNoticePath(); QString findFreePath(); #endif // REALIZENOTICE_H ukui-control-center/plugins/messages-task/notice/appdialog.cpp0000644000175000017500000000174014201663716023574 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "appdialog.h" #include "ui_appdialog.h" AppDialog::AppDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AppDialog) { ui->setupUi(this); } AppDialog::~AppDialog() { delete ui; ui = nullptr; } ukui-control-center/plugins/messages-task/notice/notice.h0000644000175000017500000000562114201663716022564 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef NOTICE_H #define NOTICE_H #include #include #include #include #include #include #include #include #include #include "SwitchButton/switchbutton.h" /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif #include #include #include QT_BEGIN_NAMESPACE namespace Ui { class Notice; } QT_END_NAMESPACE class Notice : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Notice(); ~Notice(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; void initSearchText(); void setupComponent(); void setupGSettings(); void initNoticeStatus(); void initOriNoticeStatus(); void initGSettings(); void initListUI(QDir dir,QString mpath,QStringList *stringlist); private: void changeAppstatus(bool checked, QString name,SwitchButton *appBtn); void setHiddenNoticeApp(bool status); private: Ui::Notice *ui; QString pluginName; int pluginType; QWidget * pluginWidget; SwitchButton * newfeatureSwitchBtn; SwitchButton * enableSwitchBtn; SwitchButton * lockscreenSwitchBtn; QMap appMap; QGSettings * nSetting; QGSettings * mThemeSetting; QGSettings * oriSettings; QStringList whitelist; QVector vecGsettins; QVBoxLayout *applistverticalLayout; QStringList *mstringlist; QList listChar; QStringList mblacklist; bool mFirstLoad; bool isCN_env; bool mEnv; QString mlocale; int count = 0; int mcount = 0; public slots: void loadlist(); }; #endif // NOTICE_H ukui-control-center/plugins/messages-task/notice/appdetail.ui0000644000175000017500000002122114201663716023426 0ustar fengfeng AppDetail 0 0 460 284 0 0 460 284 460 284 Dialog 0 0 0 0 0 460 284 16777215 284 QFrame::NoFrame QFrame::Raised 8 32 24 32 24 8 8 App Qt::Horizontal 40 20 396 50 396 50 QFrame::Box 0 0 0 0 0 9 9 9 Allow notification 396 50 396 50 QFrame::Box 0 0 0 0 0 9 Number of notification centers 135 32 135 32 Qt::Vertical QSizePolicy::Fixed 20 24 6 0 Qt::Horizontal 40 20 120 36 120 36 cancel 120 36 120 36 confirm TitleLabel QLabel
Label/titlelabel.h
ukui-control-center/plugins/messages-task/notice/notice.pro0000644000175000017500000000232714201663716023135 0ustar fengfengQT += widgets #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/closebutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(notice) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} ##加载gio库和gio-unix库,用于处理desktop文件 CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gio-2.0 \ gio-unix-2.0 \ # Qt5X INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ /usr/include/dconf LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -ldconf CONFIG += c++11 \ link_pkgconfig \ PKGCONFIG += gsettings-qt \ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ appdetail.cpp \ notice.cpp \ realizenotice.cpp HEADERS += \ appdetail.h \ notice.h \ realizenotice.h FORMS += \ appdetail.ui \ notice.ui INSTALLS += target ukui-control-center/plugins/messages-task/notice/appdetail.h0000644000175000017500000000320314201663716023240 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef APPDETAIL_H #define APPDETAIL_H #include #include #include #include "SwitchButton/switchbutton.h" #define MESSAGES_KEY "messages" #define VOICE_KEY "voice" #define MAXIMINE_KEY "maximize" #define NAME_KEY_US "name-us" #define NAME_KEY_CN "name-cn" namespace Ui { class AppDetail; } class AppDetail : public QDialog { Q_OBJECT public: explicit AppDetail(QString Name, QString key, QGSettings *gsettings, QWidget *parent = nullptr); ~AppDetail(); private: Ui::AppDetail *ui; QString appName; QString appKey; SwitchButton * enablebtn; QGSettings * m_gsettings; private: void initUiStatus(); void initComponent(); void initConnect(); protected: void paintEvent(QPaintEvent *); private slots: void confirmbtnSlot(); }; #endif // APPDETAIL_H ukui-control-center/plugins/messages-task/notice/appdetail.cpp0000644000175000017500000000767114201663716023610 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "appdetail.h" #include "CloseButton/closebutton.h" #include #include "ui_appdetail.h" #define NOTICE_ORIGIN_SCHEMA "org.ukui.control-center.noticeorigin" extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); AppDetail::AppDetail(QString Name,QString key, QGSettings *gsettings, QWidget *parent) : QDialog(parent), ui(new Ui::AppDetail), appName(Name), appKey(key), m_gsettings(gsettings) { ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setWindowTitle(appName); ui->titleLabel->setStyleSheet("QLabel{color: palette(windowText);}"); initUiStatus(); initComponent(); initConnect(); } AppDetail::~AppDetail() { delete ui; ui = nullptr; } void AppDetail::initUiStatus() { enablebtn = new SwitchButton; ui->enableLayout->addWidget(enablebtn); } void AppDetail::initComponent() { ui->titleLabel->setText(appName); for(int i = 1; i < 5; i++) { ui->numberComboBox->addItem(QString::number(i)); } if (m_gsettings) { bool judge = m_gsettings->get(MESSAGES_KEY).toBool(); QString numvalue = m_gsettings->get(MAXIMINE_KEY).toString(); enablebtn->setChecked(judge); ui->numberComboBox->setCurrentText(numvalue); } } void AppDetail::initConnect() { connect(ui->cancelBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) close(); }); connect(ui->confirmBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) confirmbtnSlot(); }); } void AppDetail::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QPainterPath rectPath; rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); // 画一个黑底 QPixmap pixmap(this->rect().size()); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); // 模糊这个黑底 QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); pixmapPainter2.setRenderHint(QPainter::Antialiasing); pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); pixmapPainter2.setPen(Qt::transparent); pixmapPainter2.setBrush(Qt::transparent); pixmapPainter2.drawPath(rectPath); // 绘制阴影 p.drawPixmap(this->rect(), pixmap, pixmap.rect()); // 绘制一个背景 p.save(); p.fillPath(rectPath,palette().color(QPalette::Base)); p.restore(); } void AppDetail::confirmbtnSlot() { //TODO: get gsetting may invalid, so program will throw crash error if (m_gsettings) { bool judge = enablebtn->isChecked(); int num = ui->numberComboBox->currentIndex() + 1; m_gsettings->set(MESSAGES_KEY, judge); m_gsettings->set(MAXIMINE_KEY, num); } close(); } ukui-control-center/plugins/messages-task/notice/notice.ui0000644000175000017500000002572614201663716022762 0ustar fengfeng Notice 0 0 800 600 Notice 0 0 0 32 48 550 0 960 16777215 0 0 0 0 Notice Settings 0 0 Set notice type of operation center 2 0 0 56 16777215 56 0 0 0 0 0 0 16 16 0 0 Show new feature ater system upgrade Qt::Horizontal 40 20 0 56 16777215 56 QFrame::Box 0 0 0 0 0 0 16 16 0 0 Get notifications from the app Qt::Horizontal 40 20 0 56 16777215 56 0 0 0 0 0 0 16 16 0 0 Show notifications on the lock screen Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Fixed 20 32 0 0 Notice Origin QFrame::NoFrame QFrame::Plain Qt::Vertical 20 40 TitleLabel QLabel
Label/titlelabel.h
ukui-control-center/plugins/messages-task/notice/realizenotice.cpp0000644000175000017500000000376414201663716024501 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "realizenotice.h" #include QList listExistsCustomNoticePath(){ char ** childs; int len; DConfClient * client = dconf_client_new(); childs = dconf_client_list (client, NOTICE_ORIGIN_PATH, &len); g_object_unref (client); QList vals; for (int i = 0; childs[i] != NULL; i++){ if (dconf_is_rel_dir (childs[i], NULL)){ char * val = g_strdup (childs[i]); vals.append(val); } } g_strfreev (childs); return vals; } QString findFreePath(){ int i = 0; char * dir; bool found; QList existsdirs; existsdirs = listExistsCustomNoticePath(); for (; i < MAX_CUSTOM_SHORTCUTS; i++){ found = true; dir = QString("custom%1/").arg(i).toLatin1().data(); for (int j = 0; j < existsdirs.count(); j++) { if (!g_strcmp0(dir, existsdirs.at(j))){ found = false; break; } } if (found) break; } if (i == MAX_CUSTOM_SHORTCUTS){ return ""; } return QString("%1%2").arg(NOTICE_ORIGIN_PATH).arg(QString(dir)); } ukui-control-center/plugins/messages-task/notice/notice.cpp0000644000175000017500000003357614201663716023131 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "notice.h" #include "ui_notice.h" #include "appdetail.h" #include "realizenotice.h" #include "commonComponent/HoverWidget/hoverwidget.h" #include #include #include #include #define NOTICE_SCHEMA "org.ukui.control-center.notice" #define NEW_FEATURE_KEY "show-new-feature" #define ENABLE_NOTICE_KEY "enable-notice" #define SHOWON_LOCKSCREEN_KEY "show-on-lockscreen" #define DESKTOPPATH "/usr/share/applications/" #define DESKTOPOTHERPAYH "/etc/xdg/autostart/" Notice::Notice() : mFirstLoad(true) { pluginName = tr("Notice"); pluginType = NOTICEANDTASKS; } Notice::~Notice() { if (!mFirstLoad) { delete ui; ui = nullptr; delete mstringlist; mstringlist = nullptr; qDeleteAll(vecGsettins); vecGsettins.clear(); } } QString Notice::get_plugin_name() { return pluginName; } int Notice::get_plugin_type() { return pluginType; } QWidget *Notice::get_plugin_ui() { if (mFirstLoad) { ui = new Ui::Notice; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); mFirstLoad = false; //获取已经存在的动态路径 listChar = listExistsCustomNoticePath(); ui->newfeatureWidget->setVisible(false); ui->lockscreenWidget->setVisible(false); ui->title2Label->hide(); ui->verticalSpacer->changeSize(0,0); ui->noticeLabel->hide(); mstringlist = new QStringList(); initSearchText(); setupGSettings(); setupComponent(); initNoticeStatus(); //设置白名单 whitelist.append("kylin-screenshot.desktop"); whitelist.append("peony.desktop"); whitelist.append("kylin-nm.desktop"); whitelist.append("ukui-flash-disk.desktop"); whitelist.append("ukui-power-manager.desktop"); whitelist.append("kylin-system-update.desktop"); whitelist.append("ukui-bluetooth.desktop"); initOriNoticeStatus(); nSetting->set(IS_CN,mEnv); //加载列表 // QTimer *mtimer = new QTimer(this); // connect(mtimer, &QTimer::timeout, this,[=](){ // int i = count; // initOriNoticeStatus(); // if (i == count) { // mstringlist->clear(); // nSetting->set(IS_CN,mEnv); // mtimer->stop(); // } // } ); // mtimer->start(500); //监视desktop文件列表 QFileSystemWatcher *m_fileWatcher=new QFileSystemWatcher; m_fileWatcher->addPaths(QStringList()<label_3->setText(tr("Get notifications from the app")); ui->noticeLabel->setText(tr("Set notice type of operation center")); ui->title2Label->setText(tr("Notice Origin")); } void Notice::setupComponent() { newfeatureSwitchBtn = new SwitchButton(pluginWidget); enableSwitchBtn = new SwitchButton(pluginWidget); lockscreenSwitchBtn = new SwitchButton(pluginWidget); applistverticalLayout = new QVBoxLayout(); applistverticalLayout->setSpacing(1); applistverticalLayout->setContentsMargins(0, 0, 0, 1); ui->newfeatureHorLayout->addWidget(newfeatureSwitchBtn); ui->enableHorLayout->addWidget(enableSwitchBtn); ui->lockscreenHorLayout->addWidget(lockscreenSwitchBtn); ui->frame->setLayout(applistverticalLayout); connect(newfeatureSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ nSetting->set(NEW_FEATURE_KEY, checked); }); connect(enableSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ nSetting->set(ENABLE_NOTICE_KEY, checked); setHiddenNoticeApp(checked); }); connect(lockscreenSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ nSetting->set(SHOWON_LOCKSCREEN_KEY, checked); }); } void Notice::setupGSettings() { if (QGSettings::isSchemaInstalled(NOTICE_SCHEMA)) { QByteArray id(NOTICE_SCHEMA); nSetting = new QGSettings(id, QByteArray(), this); } if (QGSettings::isSchemaInstalled(THEME_QT_SCHEMA)) { QByteArray id(THEME_QT_SCHEMA); mThemeSetting = new QGSettings(id, QByteArray(), this); connect(mThemeSetting, &QGSettings::changed, [=](){ loadlist(); }); } } void Notice::initNoticeStatus() { newfeatureSwitchBtn->blockSignals(true); enableSwitchBtn->blockSignals(true); lockscreenSwitchBtn->blockSignals(true); newfeatureSwitchBtn->setChecked(nSetting->get(NEW_FEATURE_KEY).toBool()); enableSwitchBtn->setChecked(nSetting->get(ENABLE_NOTICE_KEY).toBool()); lockscreenSwitchBtn->setChecked(nSetting->get(SHOWON_LOCKSCREEN_KEY).toBool()); newfeatureSwitchBtn->blockSignals(false); enableSwitchBtn->blockSignals(false); lockscreenSwitchBtn->blockSignals(false); isCN_env = nSetting->get(IS_CN).toBool(); mlocale = QLocale::system().name(); if (mlocale == "zh_CN") { mEnv = true; } else { mEnv = false; } setHiddenNoticeApp(enableSwitchBtn->isChecked()); } void Notice::initOriNoticeStatus() { QDir dir(QString(DESKTOPPATH).toUtf8()); QDir otherdir(QDir::homePath() + "/.local/share/applications"); QDir autodir(QString(DESKTOPOTHERPAYH).toUtf8()); QStringList filters; filters<clear(); } void Notice::initListUI(QDir dir,QString mpath,QStringList *stringlist) { for (int i = 0; i < dir.count(); i++) { QString file_name = dir[i]; // 文件名称 if (!whitelist.contains(file_name)) { continue; } QSettings* desktopFile = new QSettings(mpath+file_name, QSettings::IniFormat); QString no_display,not_showin,only_showin,appname,appname_CN,appname_US,icon; if (desktopFile) { desktopFile->setIniCodec("utf-8"); no_display = desktopFile->value(QString("Desktop Entry/NoDisplay")).toString(); not_showin = desktopFile->value(QString("Desktop Entry/NotShowIn")).toString(); only_showin = desktopFile->value(QString("Desktop Entry/OnlyShowIn")).toString(); icon = desktopFile->value(QString("Desktop Entry/Icon")).toString(); appname = desktopFile->value(QString("Desktop Entry/Name")).toString(); appname_CN = desktopFile->value(QString("Desktop Entry/Name[zh_CN]")).toString(); appname_US = desktopFile->value(QString("Desktop Entry/Name")).toString(); delete desktopFile; desktopFile = nullptr; } // if (no_display != nullptr) { // if (no_display.contains("true")) { // continue; // } // } if (not_showin != nullptr) { if (not_showin.contains("UKUI")) { continue; } } if (only_showin != nullptr) { if (only_showin.contains("LXQt") || only_showin.contains("KDE")) { continue; } } if (stringlist->contains(appname)) { qDebug()<append(appname); // 构建Widget QFrame *baseWidget = new QFrame(); baseWidget->setMinimumWidth(550); baseWidget->setMaximumWidth(960); baseWidget->setFixedHeight(50); baseWidget->setFrameShape(QFrame::Shape::Box); baseWidget->setAttribute(Qt::WA_DeleteOnClose); QPushButton *iconBtn = new QPushButton(baseWidget); iconBtn->setStyleSheet("QPushButton{background-color:transparent;border-radius:4px}" "QPushButton:hover{background-color: transparent ;color:transparent;}"); iconBtn->setIconSize(QSize(32, 32)); iconBtn->setIcon(QIcon::fromTheme(icon, QIcon(QString("/usr/share/pixmaps/"+icon) +".png"))); QHBoxLayout *devHorLayout = new QHBoxLayout(baseWidget); devHorLayout->setSpacing(8); devHorLayout->setContentsMargins(16, 0, 16, 0); QLabel *nameLabel = new QLabel(baseWidget); SwitchButton *appSwitch = new SwitchButton(baseWidget); devHorLayout->addWidget(iconBtn); devHorLayout->addWidget(nameLabel); devHorLayout->addStretch(); devHorLayout->addWidget(appSwitch); baseWidget->setLayout(devHorLayout); applistverticalLayout->addWidget(baseWidget); //创建gsettings对象 if(appname_CN == nullptr) { appname_CN = appname_US; } const QByteArray id(NOTICE_ORIGIN_SCHEMA); QGSettings *settings = nullptr; vecGsettins.append(settings); QString name = (!mEnv ? appname : appname_CN); QString path = QString("%1%2%3").arg(NOTICE_ORIGIN_PATH).arg(name).arg("/"); settings = new QGSettings(id, path.toUtf8().data(), this); // qDebug()<setText(appname); } else { ba2 = (QString("%1%2").arg(appname).arg("/")).toUtf8(); mfile_path1 = ba2.data(); ba1 = (QString("%1%2").arg(appname_CN).arg("/")).toUtf8(); mfile_path = ba1.data(); nameLabel->setText(appname_CN); } //在已存在的动态路径列表中一一比较 bool found = false; for (int j = 0; j < listChar.count(); j++) { if (!g_strcmp0(mfile_path, listChar.at(j))){ found = true; break; } } if (!found || mEnv != isCN_env) { for (int j = 0; j < listChar.count(); j++) { if (!g_strcmp0(mfile_path1, listChar.at(j))){ QString path1 = QString("%1%2").arg(NOTICE_ORIGIN_PATH).arg(QString::fromUtf8(mfile_path1)); QGSettings *msettings = new QGSettings(id, path1.toUtf8().data(), this); settings->set(NAME_KEY_CN, appname_CN); settings->set(NAME_KEY_US, appname_US); settings->set(MAXIMINE_KEY,msettings->get(MAXIMINE_KEY).toInt()); settings->set(MESSAGES_KEY,msettings->get(MESSAGES_KEY).toBool()); found = true; delete msettings; msettings = nullptr; break; } } } if (!found){ settings->set(NAME_KEY_CN, appname_CN); settings->set(NAME_KEY_US, appname_US); settings->set(MAXIMINE_KEY,3); settings->set(MESSAGES_KEY,true); } bool isCheck = settings->get(MESSAGES_KEY).toBool(); appSwitch->setChecked(isCheck); connect(settings, &QGSettings::changed, [=](QString key) { if (static_cast(MESSAGES_KEY) == key) { bool judge = settings->get(MESSAGES_KEY).toBool(); appSwitch->setChecked(judge); } }); connect(appSwitch, &SwitchButton::checkedChanged, [=](bool checked) { settings->set(MESSAGES_KEY, checked); }); } } void Notice::setHiddenNoticeApp(bool status) { ui->frame->setVisible(status); } void Notice::loadlist() { QLayoutItem *child; while ((child = applistverticalLayout->takeAt(0)) != nullptr) { child->widget()->setParent(nullptr); delete child; } initOriNoticeStatus(); nSetting->set(IS_CN,mEnv); //重新加载列表 // QTimer *timer = new QTimer(this); // count = 0; // connect(timer, &QTimer::timeout, this,[=](){ // int i = count; // initOriNoticeStatus(); // if (i == count) { // mstringlist->clear(); // nSetting->set(IS_CN,mEnv); // timer->stop(); // } // } ); // timer->start(300); } ukui-control-center/plugins/messages-task/about/0000755000175000017500000000000014201663716020757 5ustar fengfengukui-control-center/plugins/messages-task/about/about.h0000644000175000017500000000521214201663716022242 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef ABOUT_H #define ABOUT_H #include #include #include #include #include #include #include #include #include #include #include #include "shell/interface.h" namespace Ui { class About; } class About : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: About(); ~About(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; private: void initUI(); QStringList readFile(QString filePath); void initSearchText(); void initActiveDbus(); void setupDesktopComponent(); void setupKernelCompenent(); void setupVersionCompenent(); void setupSerialComponent(); bool QLabelSetText(QLabel *label, QString string); void showExtend(QString dateres); char *ntpdate(); int getMonth(QString month); qlonglong calculateTotalRam(); QStringList totalMemory(); QString getTotalMemory(); QStringList getUserDefaultLanguage(); private: Ui::About *ui; QString pluginName; int pluginType; QWidget *pluginWidget; QLabel *envlogoLabel; QLabel *logoLabel; QDBusInterface *interface; QString computerinfo; QMap infoMap; QSharedPointer activeInterface; bool mFirstLoad; QGSettings *themeStyleQgsettings; private slots: void runActiveWindow(); void showPdf(); void activeSlot(int activeSignal); void ChangedSlot(); }; #endif // ABOUT_H ukui-control-center/plugins/messages-task/about/about.cpp0000644000175000017500000004516614201663716022611 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include "about.h" #include "ui_about.h" #include "trialdialog.h" #include "shell/utils/utils.h" #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_LINUX #include #elif defined(Q_OS_FREEBSD) #include #include #endif #include #include #include #include #include #define THEME_STYLE_SCHEMA "org.ukui.style" #define STYLE_NAME_KEY "style-name" #define CONTAIN_STYLE_NAME_KEY "styleName" #define UKUI_DEFAULT "ukui-default" #define UKUI_DARK "ukui-dark" const QString vTen = "v10"; const QString vTenEnhance = "v10.1"; const QString vFour = "v4"; About::About() : mFirstLoad(true) { pluginName = tr("About"); pluginType = NOTICEANDTASKS; } About::~About() { if (!mFirstLoad) { delete ui; ui = nullptr; } } QString About::get_plugin_name() { return pluginName; } int About::get_plugin_type() { return pluginType; } QWidget *About::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; ui = new Ui::About; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); ui->activeContent->setText(tr("Active Status")); ui->diskContent->setVisible(false); initSearchText(); initActiveDbus(); setupDesktopComponent(); setupVersionCompenent(); setupSerialComponent(); setupKernelCompenent(); } return pluginWidget; } void About::plugin_delay_control() { } const QString About::name() const { return QStringLiteral("about"); } void About::setupDesktopComponent() { // 获取当前桌面环境 QString dEnv; bool ExitDesktopEnv =false; foreach (dEnv, QProcess::systemEnvironment()) { if (dEnv.startsWith("XDG_CURRENT_DESKTOP")){ ExitDesktopEnv = true; break; } } // 设置当前桌面环境信息 if (!dEnv.isEmpty() && ExitDesktopEnv) { QString desktop = dEnv.section("=", -1, -1); if (desktop.contains("UKUI", Qt::CaseInsensitive)) { ui->desktopContent->setText("UKUI"); } else { ui->desktopContent->setText(desktop); } } ui->desktopContent->setText("UKUI"); ChangedSlot(); QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/Accounts/User1000"), QString("org.freedesktop.Accounts.User"), "Changed",this, SLOT(ChangedSlot())); } void About::setupKernelCompenent() { QString memorySize; QString cpuType; QString kernal = QSysInfo::kernelType() + " " + QSysInfo::kernelVersion(); memorySize = getTotalMemory(); ui->kernalContent->setText(kernal); ui->memoryContent->setText(memorySize); cpuType = Utils::getCpuInfo(); ui->cpuContent->setText(cpuType); } void About::setupVersionCompenent() { QString versionPath = "/etc/os-release"; QStringList osRes = readFile(versionPath); QString versionID; QString version; if (QGSettings::isSchemaInstalled(THEME_STYLE_SCHEMA)) { themeStyleQgsettings = new QGSettings(THEME_STYLE_SCHEMA, QByteArray(), this); } else { themeStyleQgsettings = nullptr; qDebug()< -1) { versionID = rx.cap(1); } } if (!QLocale::system().name().compare("zh_CN", Qt::CaseInsensitive)) { if (str.contains("VERSION=")) { QRegExp rx("VERSION=\"(.*)\"$"); int pos = rx.indexIn(str); if (pos > -1) { version = rx.cap(1); } } } else { if (str.contains("VERSION_US=")) { QRegExp rx("VERSION_US=\"(.*)\"$"); int pos = rx.indexIn(str); if (pos > -1) { version = rx.cap(1); } } } } if (!version.isEmpty()) { ui->versionContent->setText(version); } if (!versionID.compare(vTen, Qt::CaseInsensitive) || !versionID.compare(vTenEnhance, Qt::CaseInsensitive) || !versionID.compare(vFour, Qt::CaseInsensitive)) { ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-light.svg")); //默认设置为light if (themeStyleQgsettings != nullptr && themeStyleQgsettings->keys().contains(CONTAIN_STYLE_NAME_KEY)) { if (themeStyleQgsettings->get(STYLE_NAME_KEY).toString() == UKUI_DARK) { //深色模式改为dark ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-dark.svg")); } connect(themeStyleQgsettings,&QGSettings::changed,this,[=](QString changedKey) { //监听主题变化 if (changedKey == CONTAIN_STYLE_NAME_KEY) { if (themeStyleQgsettings->get(STYLE_NAME_KEY).toString() == UKUI_DARK) { ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-dark.svg")); } else { ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-light.svg")); } } }); } } else { ui->activeFrame->setVisible(false); ui->trialButton->setVisible(false); ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logoukui.svg")); } } void About::setupSerialComponent() { if (!activeInterface.get()->isValid()) { qDebug() << "Create active Interface Failed When Get active info: " << QDBusConnection::systemBus().lastError(); return; } int status = 0; QDBusMessage activeReply = activeInterface.get()->call("status"); if (activeReply.type() == QDBusMessage::ReplyMessage) { status = activeReply.arguments().at(0).toInt(); } QString serial; QDBusReply serialReply; serialReply = activeInterface.get()->call("serial_number"); if (!serialReply.isValid()) { qDebug()<<"serialReply is invalid"<call("date"); QString dateRes; if (dateReply.type() == QDBusMessage::ReplyMessage) { dateRes = dateReply.arguments().at(0).toString(); } ui->serviceContent->setText(serial); if (dateRes.isEmpty()) { //未激活 ui->label->hide(); ui->timeContent->hide(); ui->activeContent->setText(tr("Inactivated")); ui->activeContent->setStyleSheet("color : red"); ui->activeButton->setText(tr("Active")); } else { //已激活 ui->activeButton->hide(); ui->trialButton->hide(); ui->activeContent->setText(tr("Activated")); ui->timeContent->setText(dateRes); QTimer::singleShot( 1, this, [=](){ QString s1(ntpdate()); if (s1.isNull()) { //未连接上网络 ui->timeContent->setText(dateRes); } else { //获取到网络时间 QStringList list_1 = s1.split(" "); QStringList list_2 = dateRes.split("-"); if (QString(list_2.at(0)).toInt() > QString(list_1.at(4)).toInt() ) { //未到服务到期时间 ui->timeContent->setText(dateRes); } else if (QString(list_2.at(0)).toInt() == QString(list_1.at(4)).toInt()) { if (QString(list_2.at(1)).toInt() > getMonth(list_1.at(1))) { ui->timeContent->setText(dateRes); } else if (QString(list_2.at(1)).toInt() == getMonth(list_1.at(1))) { if (QString(list_2.at(2)).toInt() > QString(list_1.at(2)).toInt()) { ui->timeContent->setText(dateRes); } else { // 已过服务到期时间 showExtend(dateRes); } } else { showExtend(dateRes); } } else { showExtend(dateRes); } } }); } connect(ui->activeButton, &QPushButton::clicked, this, &About::runActiveWindow); connect(ui->trialButton, &QPushButton::clicked, this, [=](){ TrialDialog *mDialog = new TrialDialog(pluginWidget); mDialog->show(); }); } void About::showExtend(QString dateres) { ui->timeContent->setStyleSheet("color:red;"); ui->timeContent->setText(dateres+QString("(%1)").arg(tr("expired"))); ui->activeButton->setVisible(true); ui->trialButton->setVisible(true); ui->activeButton->setText(tr("Extend")); } char *About::ntpdate() { char *hostname=(char *)"200.20.186.76"; int portno = 123; //NTP is port 123 int maxlen = 1024; //check our buffers int i; // misc var i unsigned char msg[48]={010,0,0,0,0,0,0,0,0}; // the packet we send unsigned long buf[maxlen]; // the buffer we get back struct protoent *proto; struct sockaddr_in server_addr; int s; // socket long tmit; // the time -- This is a time_t sort of proto = getprotobyname("udp"); s = socket(PF_INET, SOCK_DGRAM, proto->p_proto); if (-1 == s) { perror("socket"); return NULL; } memset( &server_addr, 0, sizeof( server_addr )); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr = inet_addr(hostname); server_addr.sin_port=htons(portno); i=sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr)); if (-1 == i) { perror("sendto"); return NULL; } // 设置超时 struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0;//微秒 if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) { perror("setsockopt failed:"); return NULL; } struct sockaddr saddr; socklen_t saddr_l = sizeof (saddr); i=recvfrom(s,buf,48,0,&saddr,&saddr_l); if (-1 == i) { perror("recvfr"); return NULL; } tmit=ntohl((time_t)buf[4]); // get transmit time tmit -= 2208988800U; return ctime(&tmit); } int About::getMonth(QString month) { if (month == "Jan") { return 1; } else if (month == "Feb") { return 2; } else if (month == "Mar") { return 3; } else if (month == "Apr") { return 4; } else if (month == "May") { return 5; } else if (month == "Jun") { return 6; } else if (month == "Jul") { return 7; } else if (month == "Aug") { return 8; } else if (month == "Sep" || month == "Sept") { return 9; } else if (month == "Oct") { return 10; } else if (month == "Nov") { return 11; } else if (month == "Dec") { return 12; } } qlonglong About::calculateTotalRam() { qlonglong ret = -1; #ifdef Q_OS_LINUX struct sysinfo info; if (sysinfo(&info) == 0) // manpage "sizes are given as multiples of mem_unit bytes" ret = qlonglong(info.totalram) * info.mem_unit; #elif defined(Q_OS_FREEBSD) /* Stuff for sysctl */ size_t len; unsigned long memory; len = sizeof(memory); sysctlbyname("hw.physmem", &memory, &len, NULL, 0); ret = memory; #endif return ret; } QString About::getTotalMemory() { const QString fileName = "/proc/meminfo"; QFile meninfoFile(fileName); if (!meninfoFile.exists()) { printf("/proc/meminfo file not exist \n"); } if (!meninfoFile.open(QIODevice::ReadOnly | QIODevice::Text)) { printf("open /proc/meminfo fail \n"); } QTextStream in(&meninfoFile); QString line = in.readLine(); float memtotal = 0; while (!line.isNull()) { if (line.contains("MemTotal")) { line.replace(QRegExp("[\\s]+"), " "); QStringList lineList = line.split(" "); QString mem = lineList.at(1); memtotal = mem.toFloat(); break; } else { line = in.readLine(); } } memtotal = ceil(memtotal / 1024 / 1024); // // 向2的n次方取整 // int nPow = ceil(log(memtotal)/log(2.0)); // memtotal = pow(2.0, nPow); return QString::number(memtotal) + " GB"; } QStringList About::totalMemory() { QStringList res; const qlonglong totalRam = calculateTotalRam(); if (totalRam > 0) { QString total = KFormat().formatByteSize(totalRam, 0, KFormat::JEDECBinaryDialect); QString available = KFormat().formatByteSize(totalRam, 1, KFormat::JEDECBinaryDialect); if (atof(total.toLatin1()) < atof(available.toLatin1())) { qSwap(total, available); } res << total << available; return res; } return res; } QStringList About::readFile(QString filepath) { QStringList fileCont; QFile file(filepath); if (file.exists()) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "ReadFile() failed to open" << filepath; return QStringList(); } QTextStream textStream(&file); while (!textStream.atEnd()) { QString line = textStream.readLine(); line.remove('\n'); fileCont<versionLabel->setText(tr("version")); //~ contents_path /about/Kernel ui->kernalLabel->setText(tr("Kernel")); //~ contents_path /about/CPU ui->cpuLabel->setText(tr("CPU")); //~ contents_path /about/Memory ui->memoryLabel->setText(tr("Memory")); //~ contents_path /about/Desktop ui->label_3->setText(tr("Desktop")); //~ contents_path /about/User ui->label_6->setText(tr("User")); //~ contents_path /about/Status ui->label_5->setText(tr("Status")); //~ contents_path /about/Active ui->activeButton->setText(tr("Active")); //~ contents_path /about/Protocol ui->trialButton->setText(tr("Protocol")); ui->diskLabel->setVisible(false); } void About::initActiveDbus() { activeInterface = QSharedPointer( new QDBusInterface("org.freedesktop.activation", "/org/freedesktop/activation", "org.freedesktop.activation.interface", QDBusConnection::systemBus())); if (activeInterface.get()->isValid()) { connect(activeInterface.get(), SIGNAL(activation_result(int)), this, SLOT(activeSlot(int))); } } void About::runActiveWindow() { QString cmd = "kylin-activation"; QProcess process(this); process.startDetached(cmd); } void About::showPdf() { QStringList res = getUserDefaultLanguage(); QString lang = res.at(1); QString cmd; QFile pdfFile_zh("/usr/share/kylin-verify-gui/免责协议.pdf"); QFile pdfFile_en("/usr/share/kylin-verify-gui/disclaimers.pdf"); if (lang.split(':').at(0) == "zh_CN") { if (pdfFile_zh.exists()) { cmd = "atril /usr/share/kylin-verify-gui/免责协议.pdf"; } else { cmd = "atril /usr/share/man/statement.pdf.gz"; } } else { if (pdfFile_en.exists()) { cmd = "atril /usr/share/kylin-verify-gui/disclaimers.pdf"; } else { cmd = "atril /usr/share/man/statement_en.pdf.gz"; } } QProcess process(this); process.startDetached(cmd); } void About::activeSlot(int activeSignal) { if (!activeSignal) { setupSerialComponent(); } } void About::ChangedSlot() { qlonglong uid = getuid(); QDBusInterface user("org.freedesktop.Accounts", "/org/freedesktop/Accounts", "org.freedesktop.Accounts", QDBusConnection::systemBus()); QDBusMessage result = user.call("FindUserById", uid); QString userpath = result.arguments().value(0).value().path(); QDBusInterface *userInterface = new QDBusInterface ("org.freedesktop.Accounts", userpath, "org.freedesktop.Accounts.User", QDBusConnection::systemBus()); QString userName = userInterface->property("RealName").value(); ui->userContent->setText(userName); } QStringList About::getUserDefaultLanguage() { QString formats; QString language; QStringList result; unsigned int uid = getuid(); QString objpath = "/org/freedesktop/Accounts/User"+QString::number(uid); QDBusInterface iproperty("org.freedesktop.Accounts", objpath, "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); QDBusReply > reply = iproperty.call("GetAll", "org.freedesktop.Accounts.User"); if (reply.isValid()) { QMap propertyMap; propertyMap = reply.value(); if (propertyMap.keys().contains("FormatsLocale")) { formats = propertyMap.find("FormatsLocale").value().toString(); } if(language.isEmpty() && propertyMap.keys().contains("Language")) { language = propertyMap.find("Language").value().toString(); } } else { //qDebug() << "reply failed"; } result.append(formats); result.append(language); return result; } ukui-control-center/plugins/messages-task/about/about.pro0000644000175000017500000000113514201663716022613 0ustar fengfenginclude(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets dbus KI18n KCoreAddons TEMPLATE = lib CONFIG += plugin \ link_pkgconfig PKGCONFIG += gsettings-qt TARGET = $$qtLibraryTarget(about) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_ROOTDIR \ $$PROJECT_COMPONENTSOURCE #DEFINES += QT_DEPRECATED_WARNINGS HEADERS += \ about.h \ trialdialog.h SOURCES += \ about.cpp \ trialdialog.cpp FORMS += \ about.ui RESOURCES += \ res/img.qrc INSTALLS += target ukui-control-center/plugins/messages-task/about/about.ui0000644000175000017500000005246314201663716022442 0ustar fengfeng About 0 0 800 710 0 0 16777215 16777215 Form 0 0 32 0 0 System Summary true 550 0 960 16777215 0 0 0 0 550 0 960 16777215 0 0 QFrame::Box QFrame::Raised 2 0 0 100 0 100 16777215 Version Kylin Linux Desktop V10 (SP1) 0 0 100 0 100 16777215 Copyright © 2009-2021 KylinSoft. All rights reserved. true 0 0 true 0 0 550 0 960 16777215 0 0 QFrame::Box QFrame::Raised 0 0 100 0 100 16777215 Kernel true 0 0 100 0 100 16777215 CPU 0 0 16777215 16777215 0 0 100 0 100 16777215 Memory 0 0 16777215 16777215 0 0 100 0 100 16777215 Disk 0 0 16777215 16777215 QFrame::Box QFrame::Raised 100 0 100 16777215 Desktop 100 0 100 16777215 User QFrame::Box QFrame::Raised 100 0 100 16777215 Status 400 0 0 100 0 100 16777215 DataRes 100 0 100 16777215 Serial 0 0 130 37 130 37 Active 90 0 150 16777215 0 0 Protocol Qt::Vertical 20 40 widget titleLabel TitleLabel QLabel
Label/titlelabel.h
FixLabel QLabel
Label/fixlabel.h
ukui-control-center/plugins/messages-task/about/res/0000755000175000017500000000000014201663716021550 5ustar fengfengukui-control-center/plugins/messages-task/about/res/logo.svg0000644000175000017500000003042314201663716023233 0ustar fengfeng ukui-control-center/plugins/messages-task/about/res/manufacturers/0000755000175000017500000000000014201663716024427 5ustar fengfengukui-control-center/plugins/messages-task/about/res/manufacturers/MMC.jpg0000644000175000017500000001047114201663716025550 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1 q!AQ"2B #%!1AQa"q2BR$4%56 ?&.qW&-H&Ei{pVM|5JT%^ %Jߘh$1H U;DxjbŤ[@H$~Zn=8+H&*AwAP%r4E*DQAErY [@g8$H: BDLw~NLzễ+&FIb}\sG\dVq]"1 TA:js=sSkGۻ,~ $(zN,y:=0=W{N2CJJ Ȼ-M+J1 f绝p"X!J11ND8$[<ښ69cqn,h67B }bd`yԯ*Cyv!/_kRLGg T^P[[HޤW7U+NaaT>u{-y{fz#K2ؐ.@$H Z7YFȆ.qˬԚ:N^w herdZE=ˆ58pL,=Zvغ}8٘]ǩL b*#D>Dux0~d+g8k4эyYLzenəT w~E>K;t[s-큑`F\ m4t?517Wh\<0 )3WU :F7. Dܜo#:o!Νwnv9Gq$B$9ei<5oǹi/^[-Dg3w1%S+fTk+19RC*ku}l6qߵX}SI;#VX\,6̤̏L*AsR#oo1Z֊}.Kcr9ë*.ꛖqBU`U'UP8[4CB#c^W⣍)0\Jk}#_-nعX ռI & &/>xU$#I #m[`i:GdXR+iJI]$VH)]K~L? ۻ{"%y$)I2_g}Q9_He B_jϥgqprrꪳQ?q SAE+9`B\k nHp048puGƽ'܇ "^K{ nCL+,[&4NHZ4Jb'ՅPbyy-ᮾϸ&`yxho lagkpO=XwJԂ[R%x̝+RW *2E9&5E(K]*PC:ziS%1'0pխզe]& \5WuN]U)x9ڕBq?Q0E Z~>*qNmfe2y{7 doz"v4B& Ӌ>D҉9D8LaausnC&aeļ0W '8=SoFt@hfNӃkq9Ju"O0:\ܛ|Dǧ^ZK[&Ogf;fnj Rؼ70ݼDK~Hi4Z-o7?QU J!N *[6Jc9q ~=k=RWȓvYk_1;ShP5֖^TuD*c8ց~RmVRh}.pAl P-,;H-gc@3ec a&]QRGVx|tR`JIcyiS! O~7-n]  bb!31XFK-(:cӭv5@mv)*~i6*R5 ߖ v o_ʐ]÷D$s4I\ D) 6PQ\pxh?^MLRXkyhro)oQVMǻGi߷TH.ݢU_9j$]C[hj((]<4GJ?)y,ZM 7hBA7+H&ݣoWp*I/5 W.DQ!@h⭴H W.#%OןSukui-control-center/plugins/messages-task/about/res/manufacturers/TERRATEC.jpg0000644000175000017500000000750114201663716026345 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !q$ AQ2B"Ga4&W'w 1AR!BQaq$D%"24T ?&Q5^L RI`ID1g|%8y"Ts + /.{B%RN "g@)A9TL8RgR"L@"Lǒ&a>hC.aLmXQys(’q8`F hQOwo ʠղe?DBAg1f<3 DB(sHeo4 ‹˞ЉFP0 sD{}PNU4oje4ɝ ̮R(:]GDlե;<̅M"p%L#$uKOlb8}iAVE}_UwWƁAQ?C}V@1Hx5A@Y)U?<$H2ņP:8ћ/iʪIRG. >ۦZ%T̴{07hp[ nKrfzI2g!>EiF] 9!6 SB"SjLs]TtݿRW$ZE\ds*X "\~1ϭ[Xx286{ Ia|J̌ RK9&7 TK+#!קdQeW4ǣG)J欦%D (0Ale3ʁ9hM-:O*hЅ iO؏w%hp.M"))ķrBBH w'ր2RqՅa=.ECOLSƉ2.KLxyT'B#ȧeHJ|mH1P"~O$ӼlI!HKo2ϚTlޞ;*fna}RB- #NU-kO&Y!e?&-/?5n=[!<\څuMgV鹍S9MZX$>O&靚=4Jnc?PL)= 㐀FQJk8zuֆwPO5ʚ|{StVyTӬ Bm\ͷt&IN $.)8L11\]ZjPwZ Q/IvW}Uzަ$)e֢ѣKes)fǵ0 `#\{RN4}DMU.dO҆uv7(3KJ4tBFN3d{Pp]`7(o )=/P#GVGPlRDi>h?Ϋ8CQJWwYoooE;G7V͢(m% ;XRwO.lAI3 IG҃juUٸn8Kj+w'eByXJͨxQ^WUZ?D(eoaD 9۷S2IIV&!@:й,!!o*$hDI&ͿLab-{.1IwREKSK5(Vq2a!EkEtœ[%{%g;@qMXXz/׶)?>4ScY+zmK.:N= 1n'M¯S'kV[Ov) or>ebhK2АЎҷ*=gUl0kwaނ(?hrU(dyu ;-g'geet/&~)Z$d0b$y"f3>Q<*9h=)'3 ayr@Mv [&Q`)y3D)J&{ y&c0I4!0Q&_h6@(aI8n@e# ːr4Jo(Pj2Kɟ!JV33H"LyD$Ja2AaEhD ILu(^\9SyE=ݾ'*ukui-control-center/plugins/messages-task/about/res/manufacturers/IBM.jpg0000644000175000017500000001521514201663716025544 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !AQq2Ba"b#C$4d'  !1AQaq"2B$Rbr4U#T%3CtE& ?M1qɯ0G1^%eQ`t `^l /#N]{0  0 r`G|-`hI3# v!4s' `^l / 1J`P0$(0Z -c9Dr30VRq)j%-ZcG Տ@ ȏ1O(V0Gk4`}nE-vmHKVnMs<C]T-gH BD(MىLMb)Ls9ODՔwV L {η AFb|pህM#kX|_{7<\Mb"r3}ܴԙnDf=-<,.LPA-<^R'Ԫ8L^q{Mi=˵7Ȟq#G.d9ׅQJ}zxǣ^=II2.A__{toPzp,+5/#?ǿun}6ܷX7 M>?T*`x-TEDԦ)(1IuJGq  }WzEXl_z2"y1|bl.:մjRɣoSWq^in ^Xc: {0{kq΅iJѦu"[C{Ѵij0T(;Hk̞2+XV9(J  r=L9c{ܽ HGz]+]m^ɶqSV0&K]>R"1}tU zڽS3S2%9%1qID£yr%JerɖDuß|F#RwFvFnӷ56Ne*W+UPHcÑC)fOp:q'(7%BSyQU,[HǦ9w*\Sn;$ :-+x=׋0On7{)!*7BRZj~*0k"aZ6R.FfcIC:e OK+h1_nNG]4fk-aPHŽpNAb!i䖝ZI4S zDp)qЗ)[m.d`pvHFѩd%kW2qW;:1]x#DƕR8}L<6YcTۻ]FVK4:MI"ۍN}'!A6(ScVE;19OƛۤJwFlN JPӪ-B9b5ݺW\I3âY9c9".eDd(f%IH#!'\qH,)hLn# jz.S+t`3"Z^bZD YsT|iRVoKĶJJ@'fX h/,٧zmo6 nv̆[8y۝aN̤XVTw h80T`@棿BܵQމ3YLfz5u7%>k˘(vDw% vmj?}obnq$323])lgTa/M:tqAG(cԶmWEaBxLT2H1 6昺eE]t%=s28Sg\*?QF6d?gݎD}6W}Uʻ-hV5lvKsXTͮeM+D̪L[6d&J  :UBiflK4 33Rqs>ޮВUGt$]$ x,KAm*ӧV-tE;iD^Jv/E9Uu)Z:m3YMkO.cD>Fl]A7?gJ -ҧY(wKR>!rtjTƨ5Y pIgtmi-Re-N%Á4w&_4Uрako9U45whRTw6JFs5G GkLy٪:*nBt2u&GmS&qzG VUYk^Rg cK;ZK!=QP{l/Bc0)%H>e6AG*: Q||iN|jBpKPGQ a6\6ths >]J8t&c8e{ŊƛrD}Ƒ҉C"@԰ik[ L&*@Qfݧ 7\'&IF1i^#rs&H$8jt#3pmHخW{,ALR+CyVtHd {3nmO+E!XmuwFX^J evlBmмsT:I 'js99J'7 =)j#tG)v%fjZ[`Ԧ0 7Ԇ0LȘP;|x֯ږ޹&@IBx 3I9;3OQI?nn&.^751xh-yIRТ0/ x31uKIHŚLza15rfRJL gl_m;TVlJʆ~{6T)+rvUhxRB*GAC/zO*j8gdXu+ , x,{b?1{N_~Oţ/*MmnzIE C&N1IKE֛zE+)9T̠lr6%vP (˾&y#r[tۥjE29#8/GDgqZe xUi@䕒W쩿ݱǶH)\QKu&5.N5hҧ8%Ì\E3m7?YM0H1+ʫVy.&X<7foWu_ݱ_w>ƍTFw[#{kxj?ѽ_;H䝕)k[ t%ʌ/4ixdKzE2 ˓`(S1)qa+ے]oSN} Cgzbkoki~sOҹvEu^r\]ӚҺƕL̗zj*i#gDDH!(dP?Od}m iՎ-[JfOI:cI^ܸ}uIOL;>Z,l2m^\:4?HcqmȔs:uT+~ygxWb񒪟Ww`l|IOg5&%^|;rԨ-Qw!)UEʡHhJjX@Gb4wV[xL>1OkG(Ʒæw rnŧs_"JБ3}&6LfHҏ&aLf]VT592坳qU}R?sHv8 ]"X(akEZM1'&M{<MGՁ&^4?т yy&H$w0PQ9u CX 0:ç( 4„2ˠzف,Iukui-control-center/plugins/messages-task/about/res/manufacturers/ELSA.jpg0000644000175000017500000001071014201663716025654 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!AQ$Wq4UaB#DT8Xd%5uf(bCStev'7  ATҔ5U!1qB$4%Q2DtEad6& ?!g48"1sCg1cP3,f 1c?,hfk+{_r,x᳃ 9r |9`N=7dw&BthCc$TI5qm.5)%%eMx=OYri2mk<{0b䤻LI X%."A j!i 4Zf\ޅMx5Qa,VnAZnsMهE96vCgxeb{@m 556^3IB&<)p)cݯ7 lsm0' {85}(Mm$څMx4O9Pm.6^sRmB&<S{P 6^sR[лIT$wm 5UEy ܷIwS'E}˟CZKWcTt`Jw2ۊr!6ݠNr +I : NR/jrs=5Q&ܘ|kdop ⛈ͭ `YTzj"Š*_1mfpMcܓQA Mc ]}[bz2Kr/cLGm,NF9TXyw$<~BmTõ5crocLG і7ZX#;{Wzj?h!br6jkN՞XjkN՞XjklCNE1.da9Sҥ*o?1YXD@b:n8A?v+hXx7 (ٻ j)B+`,OrAedI>L5qT9nFlc XZ\aw&JbG> ndX nnMnݛF(e\ gI {c}3eg Hpp`]ÎTBQdou]V~w>1l =F,p !ѹ:8UĨ'j W @.?f8vK߄( U2ϊ aѸxM&I21Sz|`g7ώ#;s 7-b,oSmOrÆYnT-qF  PTl]W|<2TӉw9n/4`Hs.1||hD=f`9IMW~{  E!Xt`KW^牔y +?u"V'qI*DKgT:Ƶ@z` j6)Mܩuk/3㗇lGcT+njz%0>pèBjT,ZAr2(B!6FX>9:v((SyэJ/0 [ZI4nqK w$bŃ1Be;L4qTU֙saw\kehNL>꓂ EYR9Q/׭e+^(-tO>4XubMVA;_#9_G h2Z$ᔆ!!蓈/Oy#`^rV0%b!"yZU.'`e?(0bLw`ف5"U9{hXx6rGvK؀º n1r`nmFwX*ꀡ9P&_'Y#: H^bFcxԇ4K["$ېGdFH71bZT!7.+@BetXj JK̆-@[`'Gi_:bUut >{$>E}7C oC%G0GWzG0}g:%jJAo=)µ$_Ї)4˞9{8蛈/"=RzIqᆂձO/S'ܚ6"q @2vPprNܤbw$Ϗ`I 2#kDL6GwTف8K!6((W+#f5ة[Xg. ܊6PKPC 3y6kV:¸-@n"\UL9H1##HWt`f06qh/5Ʊ'7ݰފ/pYd^fKJV8"tmȬM2UoZa@oԉȩZF5~r'E1v>]ʍv  rz'E VOemw7am|`CmrQDӃEVO'%N$w:O\Z)  ="TDGB ]_qds{U5~?€V& 3r;^(b`Q3q^m ,?E)n܎A EX~jh"QV6bB߼w~wV&+`1EqT(MZ*C8sp`4hTrb2]_\z8E+A]?v:%݋=Y/8Dz.pɭ5OpN _).A8+$x_1weK5[+{[i9y%?[zNOX▋^8l4:A쿪Ejm c\~{6? FC.)Jr KZUz,\ &f;#fZe+]sgsSV۱:+/[c7Ui]3xuY.%n7[-/5RZݭֳoZ?1e"Uz82Ü,<'v=Qժ}_.pɭ5OpN _).A8+$x_1weK5[+{[i9y%?[zNOX▋^8l4:A쿪Ejm c\~{6? FC.)Jr KZUz,\ &f;#fZe+]sgsSV۱:+/[c7Ui]3xuY.%n7[-/5RZݭֳoZ?1e"Uz82Ü,<'v=Qժ}_ 1 93 70 1 72/1 72/1 2 2012-03-14T14:01:45+08:00 2012-03-14T14:01:45+08:00 2012-03-14T14:01:45+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:208f50b3-6d9b-11e1-b399-988578345a81 image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~KIPmǽTW^8\~ީOn΢#w|>g '~e+ou1>_o:v'-O6C4 e!aR]W^-rxK?YIi7%3UqZ[%O$i3D:ԍ$WN ؛q+?̞lm?ôIiꪶ%,cQrc?.$Ml3ZJi8}:?xySye)qI,RIV =!|l- ܸ|f6[_tmqY,tm,D!F_ٽݶD[tiM)Rj]@KՓ[ kGLLTn GB5ݜvvW]ċV!}:fek߷l2%Tq7O4}w[%~9f ]P#K|Xu|Pᨖ2 $6|ܙu~w_"xJpP >wt乚 q$/#H%"@p {q^Tgmt',?|0uo_cr4%No𘍏Y)2KG"W=R8 9vNT"nb2̵UK~cO]At otn}-Yo6=xu+QR¨\@q:;63{Uu^km|^`){GM #CE20P/qe=D3'Ėwclj5:gmwwXWMoVŒ~B:MMzQKdk)1չ,dOGCE;JyX O+eEROͳoq+I6r#$⟙7FXެ̍j}( zmk1S *5[y]smͯO\}Fcppd%#AG&N*&s܆OnA$}>}'n\(' 8෶5JM6Tr*0պ>-:LuV\xB-p}Xn-fHJ@?exV[Kd:I4ϥ$M:G 1K+qEj^IdXc`UZ@TMHlͱ5wtyW-81iӊ]EU))ndA<+b3Ld?hc{W m֔Ofmay䲙љ]Sd1"g1  6}\&wm/)xjTL*jZˬvݤ>Kix"SFty½l/!Y71X^\wƽ-{K-04ݍ}I* '$SWRѝexR>^mIT"eJ5;2BPq'3ɶrFEo-~ڕ0|T Ѫx`W7ϊkf펾ob]ok7S9xܦ?63umy3jԧ#yxC2 '9˔ydwdVP +UaV|*z9 Ý9{j[Չnw&J KB2p444k2φ|{] .J9{O'&58UiQGOGvh"eW~Y}nm2N z@A(['ieDEV8ݼ> {IfNCߖ_>͝Yu_dzҷw6SE7U6+p2u?eZ:JXT5;%w\^&<"A2VE =˘,_6ܭhrPxRi0 j|F;?]vvc+۝g֝y4Uϓd2:} QHx]y(w?#n[͛[rĖPZPP{_߰lܥ˖\5(!I  <]?;'+1}7Oݱu}}]x .^-8zoϣcmz2$tY 1oG"V(V@~6 1\T:0گa[@yaHLj>ޠ~)]~Ȯ\r=mǜyNcʋ%)s|f/OMw3:ga0أ fSf.Bi1S*6`Wmi94k{>4+^_r5\"bEf=9r=Mz?=ֽ ^Y}Sظl >ٴ`r?k/ =*"tc!O'm{}$ԂiUzǝeZj+heR(4#:hJ*zW|;휞S_6:6_16cnw3Fշ:buĐ(C"grm -VP-\O\sou ڙ$R*`%18G?+zq{쏒uw^a#"dirLut8\nUpX^Rl!o$~ g~S?:佰tHZ sٚ Ef豭Ut)5r  E\Λ^Ѳ],єBMԓ<ʻ{8Yv⇪S6Gn7pu[0~ﬧjlm'.3mn|XR>& zH 3 ,Q!;m{庶^PXjV.i\Ҿx){gc&Xa;[9+1>`u?k٧Gb#FVCB/xc_ߞIu5U+Y _Gct^?i1=~o^9~׺SsJ@ }׺袛}~Pghk^V}oҽq1FH%"'+ǯqDE {BOEz\|Q''$:Y5=wO#ou"I֨=:_ʟ.AJyuߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ukui-control-center/plugins/messages-task/about/res/manufacturers/TP-LINK.jpg0000644000175000017500000001105214201663716026206 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!qAQ"2B 5!1AQa"B2q#3$Rr4 ?ǓJU\) cH&;$R RA5Ґ]CI~P\ Qa@RrH *(2W.ԣSoŤҳW& B *j="Mz{#P(_9T9&W.”djܒJ ˠvu(Tyji4XG7#m,c9DS~&ĢDf<_1a).;[`0m>7U~!OcNNH\) W&vHWX"b`w])&-"kQ졢)ק?JAuR%uCer)FIK- 4\`wReOǟʦKUJSxb+'bDCfzhnpn;B m!F(LHkACK8E-y52A5Ґ]CI~P\ Qa@RrH *(2W.ԣSoOIM [/_˜]lRZ=aվóqݸ[8GJkp`6t\_ev)9HހeW.jFv޾U%mRRal3?pX_侎B m6q.d X1&NGUƛ{^RRl kp3^NzBP;k'&'A2NY&D:U˳{,8KO'qXoѨn92dO5=qFS?;'vyEc]hJ+c uq-|bQ!Y!|ʚYu =Û*E@$@gXY^Y<~5ǞX B謶$Ne*찑dPE)}"JHUhZZDM`sHS? p 5IeNmwsw1[89:2_E!nwkeɭ+aRs9DesЭX[T@!,{މ\9N0B xUG)nXt0MoK[.V-XT5%p,1 ՝JΕ50K\I1 yŠgk5*5s}ibH#Č|#piGΙ'R[hgZ…CM^ة\s^N'_ kun*gi$鏤F#we\V9QllL`I&1aܿ`ܶal7#w@ѐZX0ZEb΋At{jB_jηPg7t.ۆxaUew{S%\y3C9俥;kW}fį8цHx#[RXH7g`:ԗ5&\̜f``p>Cz=c:qYi:OGhl$ cawiR=ϲNP1`-,ck0y,iY|ڷDx .MqU&Lyk^\tg$zZvQ݁+jWNlzYpL4Cq3p̒28B%l}G4cu";q26i=nШWStX-oL<@@J&hĨ"do,$ᓁl$|;Xd{_1 45`Uɯ9w` y%QH1V"n vLQH[U @'%6=Vr4?p>k6nhRf$79~%ym۾Ʋ6ːQ\"'FHc/ ryٚkP!]Gn{Hr tqb"KXW%r]wLv< c sInbo Yxۛ.JHQA{*^G$f8ӛe wؼSr [jvՁZ 4*|R;AhDp>t!hAG:㨜s  8p!gc?Xoi&T7ِ+),{B mW$. 5 o[!M"n!.n֬ܕ49Z%1af:fߵ-J&*KaQsф0o{>71s;egYdX(ed)/dșqRY|D7=we9gRe2.āaqgGX]IgU)I2RćBniN| ;n7W HQ;0i&Y/ _t62dv7+ވ²R@ Ïï[&jrԁCnFF\~ %oܻ$)t=B`&"@\fל\{zSabfT@MNw<ɐ'0IVC7$TC{"1$R|NUxpE>f؆w!͉>J@\0}(icIinOꖎ T6?9w ginF.JpÊ hZ, >&IxovbttȚ ㍳*'"LsE0qQZw}nN :⛚Xm 6Zp 6zȸ1oq01l ٖ3&KF Z1Wzj39 / k (Ti9^ititYU; Cic-bNhʊJVXTF:$vb v+:ѽCҜ|~Oyc}ϣ|ꯙ:|oW׻~KJXe\) cH&;$R RA5Ґ]CI~P\ Qa@RrH *(2W.ԣSoŤҳW& B *j="Mz{#P(_9T9&W.”djܒJ ˠvu(Tyji4Uɯ9kʣE e.^):{)J:$}I˯0&.$Ң%rJ>)?*/ukui-control-center/plugins/messages-task/about/res/manufacturers/YESTON.jpg0000644000175000017500000000746014201663716026161 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF] 1q !AQ2B"$a4D% !1AQaqB"2#34d ?&ZM~T1H&U$R RA5𠏕 Ou)GDϲer)D RTi@iQA%rAJ;S*~<5MܲiWM~T1H&U$R RA5𠏕 Ou)GDϲer)D RTi@iQA%rAJ;S*~<5MܲiWM~T1H&U$R RA5𠏕 Ou)GDϲer)D RTi@iQA%rAJ;S*~<5MܲiWM~T1H&U$R Rd,v3ǚ9ior.,_y:b F4`#S&Xj-޳rW vrˆq)!2D1M/*")LsLa:xR&.$ҢJ:vTy*jeү*|ztt<6I9fOIyceb뢌` w$m!RO&)Hb=[nՌqkH.Ċ%έ&t 9[ 5p4ȱ20uUa9o;SV|v35f<ЕA`UqLK18?T w|N" ,eA`7G_ d9K0_<_Y|kgٹ,!-K*Lvn;e Ӑg6^)Ubq:0"5ԎܟN Wv 8ɵw9}6V~Z2ՙ0@gZ^>Iu;jcgX p^2ҳ»o7RɥnV3wnwńwisW=܆NǍ|- eIxǿӍě KjFF^T|ai31Ʊ黬Ɛs~Nݟ.w&o"A9N0@z9e]-K*t:U"!DxJkQv1Z#iqWya+ÍH`KPD[B ApmjُI^/9C;l"` -e8F[(I  r$[ !\w ܃ˁ@{?vw̝Umo6~h#}ٻQaA˹ki̶oY4W&*B$^U*)ztE PGʐ]CI~P2uIK4 4t?JYi4ʁW&*B$^U*)ztE PGʐ]CI~P2uIK4 4t?JYi4ʁW&*B$^U*)ztE PGʐ]CI~P2uIK4 4t?J_ukui-control-center/plugins/messages-task/about/res/manufacturers/PHILIPS.jpg0000644000175000017500000000752014201663716026245 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1 !q AQ2B"34#ar$Tu&w891A!a"BQq2R3 ?&ɏ&;J&#&<= .!e4gaXK"K #X sA])Fȼ [&p2cIұDIADItBDKpAe~ExAVȀV/.Wx}Q/Ʉw 1;c4Qb T%6,jOx崤UHNZ;-R2:,T]َf"lO}P:7_vҽ>vd/I csԆRZbj5Sw7g#&߷\).`]iy^bs3UC)O`|)ESfȄU10-7NY(mIEQ7NHוLZ*ީY+6Qd"^ebbXh\wgNY]3lJtk\rs@ᬖQx6HUiyz#$͔pgm*8Zn1e.9%$@ iW*}[zu n\L >ABIkr ZWuVg Tu9U;YB";8U z~c6z]^{ϋgއ{(~u:GVJ~1Rn] xL/Ul2Q)T\ 3v.//{?ǡWJ]ȈvөNztNrDTNnD{:W_JY2 #7 1ữQܛ$#pUpRʪ<י&ۮ(ly6}d/Iqf^wci_U.=U]촒L8UBL-ͮ̊&a$tkdTՙTȋr9.voAJ8FrOm\eU0Hnvő\ cRoŔr4<*5\* )dQ4$> mtS4< -Tҷ_52?V{|& U7^U+հ')AO=C5MNd`*g'*xERl&( MOGӴ6دbl^2n~JG;]IF_xgډE1:imbgL"'>&\LhDm-jȮwZJ2#ZUr)rvs5a;b%J?`Orvd/Gye쿠K'J(e*ijpVrݘNt7|:R%Hm{,R0 2[.1(AA$L[&yXjZGZơdu.8XԈ+d$eP6NTsϙblZށ0F\֧*tJPkדteNH44%愈.y~"HZ4~y %Chk:Ա(*oH[ZJRz]2;$LЖ=QIŒڴrwz uaf8҂6JjnvʾH iis{SK'3m6v#k4}r(Zy};y4%d- cIgI@ 3zqEQ}m>vߦ~7-n+ե6WZ3< B(FY̅޾I 6 JV!AYIAjŻ3$5dd.0]ggI8'$~ds) gdBQc5RE锄WyCLjjm6,X.S<3&JTgQv{t8M.JPq(dv*Z;䯁<ϺK?焻{t1<{{Gyɏ&;J&#&<= .!e4gaXK"K #X sA])Fȼ [&p2cIұDIADItBDKpAe~ExAVȀV/.Wx}Q/Ʉw 1;c4Qb AdobedF]   1!AQB q$"2#34C  !1AQ2Baq"R3$t%rC4DT ?/\y\TTv$NA:$:A8 ‰drxVjuO^EH*ON5UXmg,W'>U: I:tN΄N=;¤)$Y%\?*4UA{?SW$dR2JӾUx,/YϕNH'mN4A9s:$N*I8<(IW'ʍh^ƧTUI$TU^%@DDDt 9,>ts|_wSs`k'ƍwEk#:$֒L Uuz{":ل=a#[-l|e7a#֮9+u!WbA?HlH _ܻ}z/,y5,:L3G\2B7IXJw'ER`CܳzcX@#*Q?:"6H  d\侤Ik#Ek'%b Jr S"* 5{m=A9NQ$FiY%V!NS؀0 "u(pև ʛTV;hp $2JӾUxoj2&0D1Ӧ/0ɗ[yb=aKY$9 pMZp(6Mp`>WWzTU[eG13@`I&L_fk⩽k8m3)}%s\l0RBSy-spĞWHdF=X;hN"XM*1f6&Պw$tU(-syOk)lH"#/0km pHɗd:OwmԴ{%5oNF }^S|Q"vVfO=xMGR57R~3Ȯ# t/;{*c.mJ7-WYY#qQYq1#Q&bZ8 ʻ%Zz:̗Dvm=d\[;C' m1e-enWۚnkչQ/8EX\`?~hX8W)6iKg 0ݕ ;Zɓ8F1Dw, r_$YU]R(K bZXzAtUnƌ!x0Ki:4q6~edcL6ls1;*l"}emw}ꕦ8{d]4먩)?&t߇]".:ݿ6N-Ejj/-xfÏΞAEś`]D+9mjپsW^i:DuD>?(16&F>lAy[{P_baRIwX/{/o=Gn>%q%+9IFK>"ZT,tW F ZHS,vB{g\)3.d;9Hg^grl1߫錉f$c8W~=\*q;p vnFD+IɠA= bB%XrRj1xM1]aw˧1N 'y- F$[[K,5]i3{03*;lݰ*R`Z E&E*̮T51pؿk dhz?x%M5w*ۇ 1mͱ{ YCSĢЍqa0:.ɑͅ%"Ui[Uhs]]h+Mʋ~p.Lēہw1aBYM;^hlq9iVGfWl-f764̉=R퐜$MwEK"7˄BFU*4L kprKwT*f76C5.lE \%nM6,/+I,R }DWBhHdo W&6»HG^3Sbê@&9, 04mTߙ-َRiپِ9H_z BBy"37Ycʌʛ⏨63Ҥ |F^osxl=ܶ8'r˾Fez| ƻ:Q^AY'sSuH'mN4A9s:$N*I8<(IW'ʍh^ƧTUI$T>ǵO=?O|o>uZf^Ӷ+*UjN$R h:'DrBtH'RUqxQ,O* N֒2H%WFKt{ʧUZ'Tp Н ǧxTE$~K$FH/gS|**FIUzwѪukui-control-center/plugins/messages-task/about/res/manufacturers/ONKYO.jpg0000644000175000017500000001142714201663716026035 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   !1 $TAQqb2B4Dԇa#SdFHcst%5Eu6G !1AQaq"23$%B4t56rD& ?4lɟ#xLI &88&?w1.pDJx&eAܤ.~)[  DGIPbU5ዲK5xqeYm\X>\TLUIsv9Cs"ʧtnrB{+\rk͸z. yeX,N.2s`[(s٧EB9 ^$%=rx?az}Ҹra0`˙i\a0)M n % ԶeE,2'+D6n _[״jڶI2m  ₩9Q7|vԏ+«r/Ky=M\SKy=!M/@4ODSKy=!M/@4O')fM# N߇4]l}-l~I\<^\M5wqsm,UMZ7c<9^$*EHɜSN44Rc҉$|zI71`GmG(e'6rlX 54u7Xq>5BL!RuAF3kmMqo%A>loe, ?vD 2GgMQ؛zs_&7wUj/%x29 , 4.NP'Tޖ01^ɴ_V<5Q;TyLx"/+,TLjc`Z#daRoerY!&)TSI3N ?Setrb8#R0>Q[#MNWԇLT℗4[oԭdV FjQ-QXN2gPJLpˀ@sI[f=w cͣU+1bӥԃJJvPiI*'4(floi =uXy9C( FAiViH= G{7{41mzlXwklZcF0n.T bᴲn"lvFBdWr©pS-"S+Iș?;q!|/Dt1XS9|.v K3va0kĄ)gZjI򭹛T˵zaQ4\˱Y m:ZiMi*xњ'6FVjj:ɨioV@͑QHM0TjAA/[WhN2i1.n5ArvQƊ"9[I.Z;J=gNQޙ49aX"muf OovkoUo7SUqM AƩDPuiHzWS8<90Z֊M.B,)?c={GS_).` !b A00Φ:rSd Dt"|^Q[Z1/_3AA2&UtAjƲdC#}NNS Bo Y,ٌLdt#ī/f kJOoߪ>88Uv/, Cires eyA,?.SVK^ă`>u?G7@Oϻcv/f?E漼$޳<)խO0Lۚ>*h,6/ێEC͠YB2 qB`(e-@VRSh_33.I#8c6fStZ`_e4b,kM7\JS牳EV X{e>x`-IvSUDaXQ 曬![zYrI'gM+w[+]Uu[𧅧j C>+EtʖKTº@}A$e}n: WK87Z3oT%rIBa=EE-ɉnQt:<Ȯy%qQYq*: 0#*tY2. .7إ_ZSg.^twŽ+ãn|Uq"+~* e}-al>|S%JkQk:$}S#1b7FHHU,iǏ4`ʭhߴBqI>d-cG}T$GG}IZ4Tk#WoSq5a&9]r+S}h~45gVDXSK=w<jrd݁O[Ft_Xמ :k2O0-M-ٵM1ZXOq,}:nVx\_*,*( 0&4[i^֬mW̋Q+{cd# 5w晈؟ )nm?~&Aw&M,!(SI}M#ci 9 Z։ΧNfR(+&Od~̈́ߟakqVIoېy«,  AiW9Ԛmpڈ fg l^fKYl=e-8bn}5yTv)%*G< $) $phڳӖF]1D9 {?m*UWba֎?˺wYʋ,O[8pm?'qSSIXkǣ*?ixYTamX $*2UQ9m:%fl0U۰dsC|v{'7[:^-:+?÷9VQXTZϵinQIMbk )B;>^Jt9PP׹Lfq[oXwzeŽZٲ]D6J\7:X,]Id#/+K)ɜX8' MaRXlLN 8l>) *i\[Qi%zW:G豪3Gs/?.n,>9i;cuFs5셄qrQ]2@y(c3Xx,"Z@CG>}M{%2ڏ%>Խ$rMl'<\TߟeYz徖UNY:mhu\jœBK×Oy0Qevj#ڂ\b_7GE[[v=0ݛ0=0ݛEvoovOΏ5;\`Ƿ'G~|kl>xb\vvOޏ | {ۛ۫QrL2xkFc''Y'VSuݤ#[%5nٻQZкð7nm{&xx%(g"Hg5ɦ$>( $LK; ~Pp7)#˟""!`"8fys<RD?z[&hy3o 3AgGgBO%O̿(8|r0Sr`3@r<h"| T ukui-control-center/plugins/messages-task/about/res/manufacturers/CREATIVE.jpg0000644000175000017500000000740214201663716026336 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1Qq !A$X 2B4Dtv(8HSd%5&6FV"cG1A!QRa2qB$4 ?&QsL j(>(3X23Q&{(0ډc_|; \%XR"o[ (X<rD~b2<"NQ&|Pfef<7 LoBQ.aqL8 v]JӸxl\I=6-;ґ^H6r~n&ѫ-;ґ+^{p6ZRkO"uk^0p-)tZ WU͇ۚef_=AkۖEQ!׋  +)Z Nyf+`@rǝ{}} wa4nڳWi& Tp;L_Z Jȷ*I@8yl*Cpw[EWO.ž:_FyaV"~2ē}880Lk0@qb䫻42;n72RO%*(M@zul 䥋mÞ? /EmZW[qu_Q&tMMSUGMvGj#N4_.Ph1Cw׋+(&ch*{* K6ܕA=?bhTb"xY%Ͱ* &,]|ߨTYI|1q=Dl +|?An 'ThJ2թPͣv0_nDs'HNg/q h#q7M ~dgX8| [/ˈzHy%]٧y+ݣd&?ZWtުEMuk4I<ͳɳa|ȉ2~3_~4Ͽv@a\hAk=n|AAr',#{4{s{_q]TkwckN*MVZoJQ5wɐ'!6:N5Nr:\t&8J3HTTk+o4-֝M5iyLW}I`jm~6Eg$D2TjTMUGxJ@`vCjOsUM]ת*&K9.vvR!m]ޮJjvC[pɤ[*z~8OxL9cv|;ΓyU Զ]%8^V8qUj Ȥu8 E2J<6P0zȩO6 a*+Cu2M=FW5VCA;jᯭ9Fp]fR&}JPS1e$l-kmEQt{lgQ{c& VFNTѶ^cg89JB"=\av:Cڥ欠PZ⾪8kWۙԥ]c\n&lӮ]ͦEuR&]NU`uLEuJÈj#34ݫV-* 무ռ}|=G3LQB.3wބ<஑X_OA=5Vyi뉄(]O6 T'g.J:P)&aP[_H}}=Ci@J ;ڎV'f)qZ5Vmb=bϷdΩfehS:p- d:T: v4cmPoJz}f҉򞍆``7/ɀ =>;lD[9'QSSt%M(n:"Y9If 4vle7#tiŞPv(`Lup/}ZQZzN#iL|ЧhBU+Í Ж$rF 1Li|54{:#:hOA>SXKbK=_)/1I}3ɓbilZ=m_{(97by2lX-?sVx2ذ2lX%f#Bl=Yc2lX%Y=^iwbJylFDZR-.lزrX"l>qz9a͋^\uc2H|OS՛5.^\a5cjԃ4رR˂,.} -?֐xN͋*!¬cvAt'D3b•/c^3uSs5fŕ͈eLy3D2L`$x"nDބ?\wj%~q@(ysaJ򀉼yl( `Wd7g܈e;QDAID23ݽDK2 P*•xP@ 8%x' #ukui-control-center/plugins/messages-task/about/res/manufacturers/BROADCOM.jpg0000644000175000017500000005522514201663716026330 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2011:12:02 10:23:03]F&(. HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJ\_֯}CS֛]%?hݾ.yuc?}bdSE͎&t~Yb'GcкfszOh/`~`B ~ Lq] 6$I%$I)T^0nVa1z_dx߮6Շkz9Y"n;Vo6qbJ}%♿Ynǹ =Anmmk=޶xj8ܸ=}.&<ߚ/&oϮ#Lq:=[1ELcYٯof^O+qjׇC"}Kw}4K96i<\7V`욺K~;]/hm|PVf3>7K2>>L`;v};ڋ I/"w7;tfupvE=V{]k 9IO^_UY]1*[KA/3c:Ljq}85m5'nqw=[V'T[mnn26msV(M -u>a7܄y(DJsiPTc.YerJUzGs.ķ3!+"Lѵvm]OC7ulhe&"ֶ<lvnwt5eP=\maݽ?خT`?bcN&}_鹀f=_UzwTgTkl4 k]m5آ ;ًǃ19g/ю7α}Yj32zYSrGkCvA?Hlz_[x5߻OW*븍`p*M5UXjnmc@h.a0?Gd2C 3CAc,s˄Vx.o= z?Xwbc49d[Z[=XS>Xx-1ޭkS19V92_d?kGMT/ǮȍԽG7?eԡ~=__/; =a{ݹlb?G/ٿo[zgzJ뤾/6~w.'& d8q8K;zdqb89Og?Z9ü- . w-4Sg\;ϧK/ݷ}G5ޯ~?Yԭu{Z^ևu/߶=__]GVgWFDu:~}=o]['h(gz, 1ak_}>wYj,-꿶X`D;Sgt1(l2&n_I+T,?(?m$z^FnOڽg^hyavYUbѱ+h]axY%ij\&Qc\_,ZNGWH;C!iSDzSPYC_]ԕbԎ(}wFgPʫӊǐǺ+ i {>#e~_VI: DTʩ$ꤗʩ$ꤗʩ$=~Dϻ)/RI'wꤗʩ$czݳփctwȋTI_Photoshop 3.08BIM%8BIMHH8BIM&?8BIM x8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]g*h-7]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FL JFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJ\_֯}CS֛]%?hݾ.yuc?}bdSE͎&t~Yb'GcкfszOh/`~`B ~ Lq] 6$I%$I)T^0nVa1z_dx߮6Շkz9Y"n;Vo6qbJ}%♿Ynǹ =Anmmk=޶xj8ܸ=}.&<ߚ/&oϮ#Lq:=[1ELcYٯof^O+qjׇC"}Kw}4K96i<\7V`욺K~;]/hm|PVf3>7K2>>L`;v};ڋ I/"w7;tfupvE=V{]k 9IO^_UY]1*[KA/3c:Ljq}85m5'nqw=[V'T[mnn26msV(M -u>a7܄y(DJsiPTc.YerJUzGs.ķ3!+"Lѵvm]OC7ulhe&"ֶ<lvnwt5eP=\maݽ?خT`?bcN&}_鹀f=_UzwTgTkl4 k]m5آ ;ًǃ19g/ю7α}Yj32zYSrGkCvA?Hlz_[x5߻OW*븍`p*M5UXjnmc@h.a0?Gd2C 3CAc,s˄Vx.o= z?Xwbc49d[Z[=XS>Xx-1ޭkS19V92_d?kGMT/ǮȍԽG7?eԡ~=__/; =a{ݹlb?G/ٿo[zgzJ뤾/6~w.'& d8q8K;zdqb89Og?Z9ü- . w-4Sg\;ϧK/ݷ}G5ޯ~?Yԭu{Z^ևu/߶=__]GVgWFDu:~}=o]['h(gz, 1ak_}>wYj,-꿶X`D;Sgt1(l2&n_I+T,?(?m$z^FnOڽg^hyavYUbѱ+h]axY%ij\&Qc\_,ZNGWH;C!iSDzSPYC_]ԕbԎ(}wFgPʫӊǐǺ+ i {>#e~_VI: DTʩ$ꤗʩ$ꤗʩ$=~Dϻ)/RI'wꤗʩ$czݳփctwȋTI_8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2011-12-02T10:23:03+08:00 2011-12-02T10:23:03+08:00 2011-12-02T10:23:03+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:0e0a365b-1c8c-11e1-ae7e-db667b27342f image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺZ4/~SVtǭڃ0[g'عm邭s1aǂZEz䕪p@X8'};ifDQaZ+(#t/Ϸ{C{e+y#̛̲jʵZn3 HwC #[/ T$m< )?o<`*2,)TIP.yE5m9|;P + xl~`ZjPEOF=׺Bd_c&>Gs1;{ M_7E>b~&VzYbk&Pt#EM#~?c7(]ilSm=s6srEQ-JŤHמy 'v ¬M>ʜt]ɾџdC{]/ٝsؿu[[Q6>y; MYO$ Uye,z(fb Q˕+0}pr)k}mK#\cUR:x##{t$P0~c?Ʈ9_{'k`viS~Acp&tcu;& %=%d5RߺUK;il7oI>dvG^Kl nͅ׸VM5y;yTF H{)ݟϐ4{{!]Wlٙ]K?5{nJ3{K;E1YT,T1K[Y]=)6Ԣ=je$.vI\UT8颫VXrs.d Yg}}Z=} ڄOH4̔"ʊOHQX{Kn,/'x|{#ߝ]\+}h#7av6jITtZYNu ]Pxk?o!;= ~`ؚÙEe4@YG 8z Žv/&fN>"0__蝕_Ը\p3kcwک Z6NdX 'F*) B8 tH~W"sw|Z/GtP^xuٲ6,߻nd(s4{qMX詄8*:UX)=; :T/Og~a V_Q%YDW`C0P SRc)=>sޝ{ҿ*;7;vn{das{bQbTU_ܾ\Łkl5>b \$Y[y2أ%R;Z4 e-K){Cg Vtw<a{ VaZO^}}g9܎Fض8!pҵBgA2 ͡ 9{~鬗e&;c's#JŒ ,ncBɊ,tzJs1UI׬wǠc)_Mu"S{{;}yt،^ic0۫id/CѪ*+᭣#DtyZ7-7k5]MF<eݿ~w^[ڒV֝%kr3{jus|>ωaҽj]n~^Ow'0LligIOT($6,J@#z]=٦×M4,֑M,oRđV2h+\?O )ߝ&bԵ`vuÿM7,j=2{^h0|v>HFHh [X'V>ru˼7,C$VD]g}ǿq^osQubexβ9Q.-փQ|~U-~@?,aˋlޣVⲔra2remH6g-zJWf$I/inwɸo)J j4ܟ>{M5J˛;}H;$lXr̷2biDbɲ'\겿zl&.d|UQP&kjnhmgw44k歐>x;'3Ҟ{/&{Y M0LIJCA 8,%-7km];;iRIDlx)ғ HjqsZ9i)#*cɬ'54~9kq?zkK=0.%  W ^{v&ev[?:embYu;k%^R<,HԸ@{X䜟icS ß^`oyl{>f-wPO$- v"  ?W;S?/V;S%tWdMzZ}Flgggw7W^'ܟt|O;ga:Sk77%3d9W^VǒǴB=퐢iU_)#^#˾#;/-ۘ\mV7fl)*o&즆9MW`}׺m8fvN;Wz߹Nr=)Uw.ms+MRvya2\n7#8G6W^{'r-7K^ym>5nsbS 6l#CZHRZ rb7ӱ7P6$NEUڪX+eW8+aO_2kߺGߺ^׽u~{ߺ^?4Zuckֺ|_Uz-ߪ=zU+JyR)g_ߺ^+QࣗQmfY0k|SQ ZqM&8MW: ^Ww%[Tҿ\C{q{3y;n|43/ʢњ]k.ꓮƫ %"/#jm47-ݺwRbuf\kjںҮܘ )3QSaްd#ϭ4TcMj| l־?{GvT+u!>ӤPzd׉:w9hg{|Y$-1FbM@o2:.rwLsvkvSb;5kn>ԡ)iaqdx) CifV)"<"xv+tܬ/ W)o`1#žJ@y--jH;=}4.ݹ*pn[7Ȋ967 Kǵux3v٫ڽ3.zpm)jWZʲ]Jעxuj:J~ک}wtsn ī$OllMK>%mA ݣcQ%eqh6cSqص?su}K`:ZsNљXFbx-BAVOqy}?<{s%<7%_x\;Hd}e@BL/)A'ytҏ`~7_tkӣwϠ| 7kuWW׏QݴH<_ѯtqvuߺ^׽u~{ߺ^>+_?ɾ?ׯ׫WM;)|z[~kfVztyhӧ<{Hu{_ߋegO ~_ [V϶υ-t Na~>ŧgO)蛯ukui-control-center/plugins/messages-task/about/res/manufacturers/ASINT.jpg0000644000175000017500000004200514201663716026010 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2011:12:21 09:59:00]F&(.RHHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOTY_Y=ƍϵͳ4@$7*&cg9=I*=sAkϨ{nեmQS {CZl/q.sx>g2LgQ'tNIhgVO*8#/I#Q] #Q^_~1ŧVHk>Ncl?VS0s}'NO{Z,.d{6Viĉt5Qt= E>}X 0kƀ\ NJQgO~]YuuKCkQqrkū*cldaseExxu~+޵t$r(~NUľǐց%W#W^FC*} Cn.;X~i%?U_>c5>Mn.tUF7hΑ_pv0;Gݺߠߡ z-yw<.=WDΧΫw2[knl?}iϫ=S'5S q`Zݯ_c|}.8YG7icBR Zd:>$Kx+ %jkyd$6m1HMf8yt"s6QY[%jYkD4<I?Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ @Photoshop 3.08BIM%8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIMGF] AtherosQSa]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM n]FLRJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOTY_Y=ƍϵͳ4@$7*&cg9=I*=sAkϨ{nեmQS {CZl/q.sx>g2LgQ'tNIhgVO*8#/I#Q] #Q^_~1ŧVHk>Ncl?VS0s}'NO{Z,.d{6Viĉt5Qt= E>}X 0kƀ\ NJQgO~]YuuKCkQqrkū*cldaseExxu~+޵t$r(~NUľǐց%W#W^FC*} Cn.;X~i%?U_>c5>Mn.tUF7hΑ_pv0;Gݺߠߡ z-yw<.=WDΧΫw2[knl?}iϫ=S'5S q`Zݯ_c|}.8YG7icBR Zd:>$Kx+ %jkyd$6m1HMf8yt"s6QY[%jYkD4<I?Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2011-12-21T09:59:00+08:00 2011-12-21T09:59:00+08:00 2011-12-21T09:59:00+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWN*UߙD|Yգ}v7')*8x+-]y/Y|#d5{;K;i.K{hTwfj2 4fVnY Dd#C^<;ѺƿCh$ª՘I"Ƞ4 2vb]v*N*ſ3lt!~DW=={\)QJ~.#6y> q$z:.=ռ̶$S,U80a9e?Flx$EjVi[rn(eއ!O8X'!H46]چsf  ҬaF&F4\кOk6ޕ[E*W3"N*Ng -̋M-? .j2~7E8_'z>jv/.=֖ & KCn@FFC œIwG$xC$t:i嗛#tI/YPx]G j9-d֜ HpI'-jֿ3/DW̗m#ͦj;#8ErxG&:hLDk!7r7YU<ͩb$(dIyIUV9ggR1H= $h^eb/ !+Py(zGrI3ᅳ^kɗyV֮Hd!gc,x%m58yvk;iV, y'}35zT 8_~B5Դmn!Rus z#a89~fTyMӗ^DER&Y^de=6ɊBWWr[?_) wiK/5Ea 4N _$!8O:QyKvY]l}Y##4W͘MPLMqz /?-<}YMmdgcL8aP):O 'ɘGy?imn70ߤ#I@ E)GVc .D sg~ae?tKx㼵dmo.a 'eLEtzC˩/4tB) +oo2#F_c`D'77dK744M„aP֖r#$d&=m"S֯ƞJ6t!*Bipq rV Q2*6F!T[ƛ`z)O%KAuzTM) wzzAGT)JTqk*AdRN*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/AVEO.jpg0000644000175000017500000004117414201663716025672 0ustar fengfengJFIFHH'ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:04:13 11:27:44]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOUK|.SHhkD?Eo+7YoUoNF}?iԸ1{鼼#AO]{8o;-{ϢnRm̵W]25V]fTz`:.5ݏKjlᛄ,Z<#p D8}%?Q]]h,ǥm eu_X2ǧ]6۷W-'cc,o}iÉa5/}鷵Zvebǿ8 @,Em/O#\~>O]~ٶ[_skdmvoS?$7Y^+krG2@\a䗑t߭YԱfs\ ZCΕ멙9yBQ OYdg:7ii/ xkSܫ& };g-f; wnq\ߠ?RUc!V N;U9q"%ҿY Iyuu_Uڱ)/ *Rg_ȳ!O~;zbCC@nŽoUz>h!M'Q.< q2Yh̃Iyzg^mNхIﱍ2_mGeQBJ6.7TiKkZ]['M=+{n`pȸ\w ݿGc~S1ˆW)tMqR>uHv9ՕuN~ggdPƐ)3{i-ǹc[Xs^X"]nǙ`.w'Kd=u:GW YL[zl.,unbs>}g9|Afuoe/&_FQhx-mͮw_7݊,lŵ{{إ̏WwO _ھc%׻#m#ڽusV>b^}2dx 憆ZN].hO]~ٶ[_skdmvoS?$7Y^+krG2@\a䗑t߭YԱfs\ ZCΕ멙9yBQ OYdg:7ii/ xkSܫ& };g-f; wnq\ߠ?RUc!V N;U9q"%ҿY Iyuu_Uڱ)/ *Rg_ȳ!O~;zbCC@nŽoUz>h!M'Q.< q2Yh̃Iyzg^mNхIﱍ2_mGeQBJ6.7TiKkZ]['M=+{n`pȸ\w ݿGc~S1ˆW)tMqR>uHv9ՕuN~ggdPƐ)3{i-ǹc[Xs^X"]nǙ`.w'Kd=u:GW YL[zl.,unbs>}g9|Afuoe/&_FQhx-mͮw_7݊,lŵ{{إ̏WwO _ھc%׻#m#ڽusV>b^}2dx 憆ZN].h 1 93 70 1 72/1 72/1 2 2012-04-13T11:27:44+08:00 2012-04-13T11:27:44+08:00 2012-04-13T11:27:44+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:8b2c796b-8518-11e1-a998-f15f6a1faa8a image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWN*y74Iu^FKhDDF(Xp$byAЫvYIWɿ/<8럡Ri-RzbO~-NX|Arlv*UثWb]N*r3cWTzPD;5܃ID[tGܸefȴU$k_y-Ymm٤%9p #1Q^GѬu2ZH^XZkap\_J#“Q#R?z'䇝|:2Ɠai5rpQз?1,WC-쮮LzeA)I7͙Xש%//^E Ɩ Hlj*. >cozǕjOn.5#5[Zi"c2#p cE|E _TLүίYd+42F-_Vla^.%ok:_1EMx&e* J0 _˲[ L朗?`򧔵 i3B-#o۸oyel>$X|} Qwlm%ΧpZ /<伛:l( /MlL2WycHk.$Lll/~7H_vZ[ăP4G ~ AdobedF]   1! AQa"2qRr#$4d%5H 1A!Qaq"2Br4$%񂒢#&6 ?H٫- ) \)큂o :qGeE E1H&p"U)ep 5xb5r!B"e 4R @3E 0M$T.(LBh(2 J~2LT&,V Vf\(DL fArh dtR WMwEA W/I8*ڥ$ lP<ΕB23B*#r9̝9G`ΜY<%Z{dSV;31G1޴}/#.|ǝWkIS7:6Cߨ5yv c}WUSUV}wL2YZyZ٣%/z)R(JJsJ*N`!RMꈍ9ڗ'Qp1W 58bxv(9Q azi H. &,V Vf) %dtv.C=gl߳þ1s~;aVD [9po޴ Es-uEny}\Z򜒽[o:7xE7J&'*‚=Tt劫TZwbo֫k۴Oh[umb>}kR5vuR:-)@ȌzGoWK<9v@@+r{#Β#T& .30W; tѩ]#Zz]d#:/ڊjt<;w^1zUuh]lwwsR2/)@Aj#,==b  ʷa٨ݴĞ^icF8 k]eSkgYWݫTc 1R$x Ljh`&C8`&ԵueGmۏ;W@t7fv»|tvF =33t}5b>]FZ,HJTna1ZttVZ>k"F<$A8n ̖^tgsZ6 P@6`ĬūJg[5K ˨qKX-1/=-Fԯonr3a#1@vUm[bt{tH8:mYl#\H'#0kj&P|_~LvxárPw=_ڽuHQd-n>oF+HpH>F5}sG)qWlf.ĺ#15#rDdx{&i}ݟ0S}N?/ykʫUsuS\a㴁MZ[=q_fV%:G6ذA!f AdobedF]   1 !AQq"Ba2Rr3$4%S&  !1AQaq"2B#$3DRrC5 ?<5$ŧ'@X!')gb ~Z؂qiV Cݡ,1% r 0f6ypb!N^B;ؚOifj5'@X!')gb ~Z؂qiVX`'xX0wZ#;N^=1 ؀. @pd0i>AhG{I{M,ؽ͗.ewK#.f抧ـ-o>5[XƦ4 RL!!N uAPOŴKd'T"#yjr&}K7zڲu6T飊JFVOtaDw^%<:hB,ɔ4\r e1G hbR))<%"C ]3kԩ8lɸ eG8@0Hhwe.IC ņ :[ĒH46,!72Gf't7-#Y=`TQ2E#8dzvYQ3'+eɛ+f2bPb3UԹ Z^ABg1=jhR̢ٺ$sTGϘסɯŒ0׽6ԵIMX/q?GM-!~Ξߦj^ c/ytL w*2+Ø:N!epbe8x[3•y|~H@* |iPJgwU/*,)A,rIUJ&m'9M6] $o1KRQC: u.ݝ :>M!1IgI?,^}`xB}8|P]Wsjn}9I=47؊F ŨtM +q|vn#Cpj~EvSӅP9×/9yxMSwOcerZ e*5a%%. Ȗc@IHC\UO )|蟠Lh6˟5Bi:QѱSIc1=#3$M5Jʪ.HrɌܩ8]s+'tq%=m,Y/pu'MO?J!&y ?6Nm3]E(\W I$mWqu\%P۩ 9x }ĺU6JRۂO3)|fp.%7=T-44S43DDCnrcยsZb+Pڠʛ(PűAQC`ܦ%S]i^/ʗ<!ĞFI.rH{e>U{/tbJq" QƇDy$hqvSA9\J"qTz}IOU1c?TQ5U@1YGtܙ3C{Zߌ.$KQ¯lx&jL5 :_tN^eW Е38{am3YmvJfq7b?[дpd%ڙՍ^Z'X%LFVLT7.ڨʎnꕣpB;2+#%N<߀哠Ֆw`R @ڡ5ڃ[KB"*תWAB?ٮK>ӝ1w܇\$8@=Z-55]% gW08caZ9v#Pk1#CӶ@{voᯐ}P/;ͭn:-%Vsñ$NF]d6HZRK)a(G_^tE=Wntxv7.,>:SpGAu0kg͎0SNkM$zRh;DRr,wDwק=6KZ9CqTM1ݵ}ދo|:C폻xO(.P9Á<۱}:r,ϷcPylO $_*1"|ք*MA)GT<BEr? d%[]Sh\8\z 34=~)! Du 6#-*l9Gsh"p7Vث[ԄE)`R89ºUjRޙpotI.s^S(5 ԛw,aTuUTL4tx٩JI̥_S&9lu-]gY Ku0 #NNP72\-?}&`52:oO.<65-UVJSesZQ孮1ۧIKzr>}EQr9בAW7#%H©Xsm˭]AW^Ba ӧZG˓پmpE6ʖx@eVxFLSo3+,BLv/u&)IyMoT^<M{>p*LۑKl\5gH+ztkT[2zi\½zVTinkH]p l/߇(Dјif-i-ä.:Z jfKp'qFDb`kcI"A/)D9F8;v,+ۦܶI6Ifr&diD$)-I*TsvRclH}NLJ2%Z,y6%MLېh%JTS]BBS) Op=g {x{A"xELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]" 5!W1QARa"2q,!1AQ"aRq2 ?`~fbx^wk+ O?Q o ƔḢ^'guv!JGRRkFz1?pӱŤ{Lezt}eVc zc;53\1_f|Og;u8%OTfi x`oGIzB8T6duZImi.ZB\6rHvZΎi7%gݨvO>f|O;'ڟ 3>E'8o\#_P@iI*[ۥ&HnV6EE'O"+Zqcn4>EܛϤi7R/qNTFi夐 O9s!yrdIpҍ\"&O򗆄Ef;'ڟ 3>E'O"mLO@3쭸S:`͉Me}eukui-control-center/plugins/messages-task/about/res/manufacturers/KINGSTON.jpg0000644000175000017500000001114714201663716026371 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !AQq "2BR#S$4t5ar3TU1!AQa"Bq2#$R4 ?M\Qɿը*B`5D }&6&$~t5#HjE 1`7k,(]f{"}ޟ[5\ZM.G&V5 o֕&jrJ`< <<%A4T]!T3L4Ɖݬ9w=Tz~lpQi7kZ& ZTJ`ѩ)ohOʘ.jJrLOXR9wQP0&vˆjGR'5Uyo˜kEM+{[9 rD|tX9+~Ʀ7GUʁGr ̾o*rĘZH1 1rį_nICbtsh7m1ksb#s [YJ1HK8w&|GSy"kқVOmG;4bEoٙ\mFc#UB v|v ^\8 | kSFzwNMGuggma2"Efc#٦W"9@V4F+QvoS5|(D-rsZSJRRg;m@J"EPM{-zU~#CF?tPpUfZ%CR9CԈG^QmZX*׶*j\@xBEi hyRUTMܹt3;Ȩks%Ÿ^wgwjl-U0x(Js}}J1ŽQm~vq2:K S qqԒG1~J"d#.@4Cmd xkDNsZ2|1V)M +i4$YVP=ɌOn[q TS6>LNwnنw~ڒ/٤9(h@"M$]+VYEa+q\TS9=8\{ia/+Ai?b%Bs*򤼿k'AmL䄟Ӧ sVR(oVi}|5R3"+ S ljX.uΏߏtx};/wܜ?=.+?g|zQ2]dw5bQcY 5jKMJ$N华 P:Sb@?^G}ImwVDjȸ%~}3vmy'To!s̴{6r/ A"dՐRs{wFbbtl{\қHUz:TU٢όI[HP!TOAٶ]GEF0 (=Nx ]uv[.uӷ}1}sR17WW7W#ᖖy  贺aRXhH˖|t2$A*lK8 _Q lN9aLD(p3A/m@r #f] sg uPZ oQ^GwmPc"߶%3:(`fUIͷ9t6cQ%9׎_ijia44NҰkJ2)T 8ʆ. |.]Ɇp̶=p$3oӴ#mƭ_LqjܗJݙ?ފ Je fjQ8t|ƚJ1 HfZ;W7`n3UOU(}+{Nf[]7 w!3U! @>^ d٧N'?YasJɦc=kݏ1ajM,\Y}" $E*B3[doP:l=`OT?}׽7 cU fH+ʇ0"$֬%,&Mv 4hA05Ï $V!TqUdYG9r{<=jU|0:Geu=ƸYKr-[jHwpfҪ}"&2}_bjɧ.l/vb#yϸYFL5+ d5(*8Mt%z Ag-W[?Ǝ/u=p>- u[U⼜9}$arw܍˸3s˟3Ȍw?UpA_pO0!t}×v!4/qJ'iV˔htQ/k]b PKMDFL@tPć9"YX2gn`#1)t:EӽUOO⺦0aZ⥖~|Q0J]l#2ylYtzDkk-%!'p%SI(#Tt!SeD3dGZ+rcJ, 74D)a΅;K * J;DF18"1Zh$qBҮEy tN̝ϒڍׇU >;p&uv `;[6MBh,Lڮ m";:3BcNl6h/d'R{c}e-7k6, 4&sPU7kJLx59%0Mm SMINIk*G.Ԋ*ScDnXQHD?Fj(\MATjѭ*%0M7y'Lxxy5%9&K٬hCR(f NiYaDr@{5#ީ٪࣢/!^'ˊh}I>ˊTvpIKX>\RyL=G ~z|BS~SC,ς9hŧU~ou$ Q0Z4T?UO}bKP%G-"mf?R j4TGU CBړpy*~/WoTFj/ukui-control-center/plugins/messages-task/about/res/manufacturers/COLORFUL.jpg0000644000175000017500000001763514201663716026372 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1$ AQ#Faq"3CT 2S4t%V7BRrcDd5Ue&68 !1AQ"aq$2T BR4Dt%r#3s5U6FCE&f78 ?H0a=;ajj/;!{ìy`'´ܷQb{G )k }\u]FŐ=۔Dtai5d=v` r x|Р=~VOTpE`H~ptE`9{c7D+ߏ0;B'V{Nt@:=2YgU"ne8 &~NHvi黚Ъ"m3̏DhT{{%Qk>`oJed]'s,Rވ?So:zcS'z _8A*:Kg^}1]KHʏRt:`ڇS)H9g??Kr%0 MpjX:eLk;z-LLZ,nfUpPPqREI:TɵwBX6(8VMI8WlάDzZ4C\)bx$UTvbcI6WƘ5FʌdkA2>b1͙S3J-dr| .]127^yƴ}dĖ;z:1d?:g2'U*UzbC. r]'($t-蚾F_T5tҚl &Sq"ɍ R.A0zPf߁(}.7}q]&\};+pRg[BJٻ ;jI. HZkhjc{mhSUڌsA?$UPFyD^򧩨i,'RJ^ΣMvͬӽa2:%aNPSmZΚVuVcYYrL/ջ +bg=m$m11Ueo44u꣸ M(@07÷ӫYN8K#(jTxޥwiT4ŻwmMی p}v :FWj1`hԀ^4hQƞ`4S1Df$nt=(Jv )e`im_5{};ݞɃ)l#eM\;OUQyfTnUN2pWsl[Ҹĭu&\❵-- .e&''٭V99zkoJd4 jO B(DfpafatM:+?M, -֟NfԤ5hKJX%-@̎ziIr"b;?0SKYuJY(U%O*C)nv1#=r)#̎a,z^lZT7wM^U34'> 86Rr!R-F^u>H}0s6dj/E*Jx2)Pyʜpjpi'DiSZb{3j#dץrbD UR>Vr(]VW,$iRz56ۮ2xP ,Z{G`C-9'J[A)WXLK zDӞm*7OwwS MDžjU/iA-) )Y 6iRaSH !8jBp-ҬHѥӫy|,fH[MK9<8TTA Ȯ?ph#]{r&5n'u eO+q\odfSn~Yg:#|8St3v6nf c%RrAU-]ͻ4 &@4˧jZء9Wms!Xn'޳UK;]/*B,[\HsVwNSPfݒ z&8JDح%h$dg~/W8u"bU_5dd ܷ댝޵pt$o`$1'"` p&=JWݠP*WEM95YKuM+$-å$7DA= ȩ$$KJo,9vЬ"NҒl*$ʉݩ@umÏUE.m$d3-Ϡ/UiO%X&\J#ueE 9s(ϭFe ^uع;% O"qPӺ\3 "B,LpѣZBU)(@|qn9|# ,E5UqӫmR*3RTV3Iki D#Q3∝eÆr)#L 'tq!_^uy6aW[.h,ޒԎt])C*HkƲj5B֖Ko5O>.A2d)Hh@g]Lu\LPdN xyAY-5m}LMPm6΢8~KJb@$LD LIה+I6Z.:=&ͤ|ez{*lM3+!ÿ8t͐,Yo-I-]/>9隥^NF]FpLsۭOPdGTVʁ* o7jFmӽ.'u-?itDN$#>S,[ӘLjnNkJjZ[֙Il i= ٷ RD=iS/**ziY n Z* 'EL=bTra">Ͻ &Qm BL^e ̿i^ u,U  6YYXWXݧ} 6faǬu< shڢ[a<CS *ȦS+Pq=AZT43L99<<QDYrq;Cf⽋7mmjl٫ξHjd9 CS3G@]Zh-5f nRx!CtӍց`yDjf{vWm5Ev""+þ34Zh0#vbOL":%EzCrWVNVvZ!UEJ v5F0$pZ=sYnp%pfV0̚"G!b2?ZF8qͣg3?SkюE"sjlቪW!1n;?z%J)OdmuͧVR I1t|[TRr)l E%K7VtbiubΡuzՕ&>;Ni#P$U/Ĉ B7&OKv7JZ0Sz]zw7#i;.r%-kcP!ZG}SQ_*$N[(ҙ-+Z{ː5k)lvcΔ]j&o| ڻMFLڻkmds~K!Ӫ(uڬ#lG&Xt'a$=N3jџ hLWϡۅe$L5*J ~k4kg呎;s9S1s|߃ UM"ꏓuէ5=THl ҋPjbZŋf(ƓBȏ^:mT^˧`2xaUhQu2;mL^yݜ紘Dx:rNqϑ^|?7ݼW}ϳe_DZ_Ґ|/ÍGD.cݎG 5iIPHR×2ŝ7=i}z l}\>Zwj˧g7c[mz lև+ew{;HGT.gv>zG7cx{;HS>Z.~8t~'`O4`gHvw){5GpEe+<rrZy}7Љv5})k>5;ka˼ m\/Y>4}Lѯ=ѩyŌw{FFaz9,vhсtg?IZWґ4=CW{-ޔ;aʪ:P"PHq{&KwHk-xua?h]aq}Ui\' ^QC}Yʼn"Q0<Da)!zx48PnP0CNج06d}A8{c#!\dd8FB~ukui-control-center/plugins/messages-task/about/res/manufacturers/LEADTEK.jpg0000644000175000017500000000721114201663716026203 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !Q$՗Aq4%F 2BDVE&63TdtU'Gw1Aa!QB ?FhtFbZ3C+)3LQ"LS]̮iBlf,jbQWha/hOCVKSx1F~Hee1Fy#:)3qD_s˻?:\HMŚLJ3c,=93 y~Hj׳Էͮ, Xx>}ü-{uWKcӖv ꮘOet徍,&*b'6TCҖk~a˖ō)9op%Y}5-2[g2! (q :&3D ̀d`.Oʾ$7i:A#aaQA*r>d0R fpO`o@Q׍]״'j[2X8 \ ^LeV^7AF5mƯ-*D ٱX5̟f0qM=HM| R]\f0+F5P\Y 5JX=RVYe\e)ŭ?)1_¢ںn&I\"]-6mɽVܰP~j܍ Ø#מVi]p#$UMM017V4LsUdT9sYJCM[|Q[6eAO讦`=a] }qwMU@tE24IX2e'R"HE] KwգO)YicVKGթ@ߡԧƮȅ"̦jA<_0x׮nZ^ĻX{Bӣwr,~gQOyT9ۻsyn6XL,`\(N3`2eKSAEn7M\u#.N&W]NpNo`;mpwܾS5Rtt-q^:՛c%ygXiK㡤rxe!S┸)Spֺo?U1 Q8#h@aTyV{Pa"{g<{r*Tֲ8 5KM䆇?u%V cGr\'A>>MC ~B!3M z/ <ހm۹ ZsO* Fku&&0`Ί=6/T?b;ؖO^j}K^O概3oT|b ڌ`aOۂldRgi8'8NTH{C4>T1`QhAlCaAy,`~a)wEҌA^PlZ],Bפ%b=NLF00{snbaSmBȤ*fRM`^PoL kq֯jH-.|ibtP 853j*~ w^[ G!)tFjQI80dØ'~mB/zl֨彶gPMz$dSkAJ\(9dg0ؾQn&ɢQB&>'m- Sp`4ͽ6ZqR3 3+tGSai~vjndyrOߟhNvn3Î?v[ OٻrsɵS֚+Oӌw^lJv.8ҽW-bݳ9OYduʕ蔾cuj%׎&TAeԜmuNSݥ?kMV3ev]k!;#Xd_MݡAE#)_ VS 9r$c )*Fܙv:o1Z-ǡ 3GKSx1F~Hee1Fy#:)3qD_s˻?:\HMŚLJ3c,=93 y~Hj׳њ;=Qjo( (?gE1F~(1Nyww2K CӟQQFu\lbYE4Fcա>/ Zukui-control-center/plugins/messages-task/about/res/manufacturers/CHICONY.jpg0000644000175000017500000004274314201663716026237 0ustar fengfengJFIFHHaExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:01:05 11:12:21]F&(.+HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO7]bl{Xʡ_?rVukxcriĥ0Zʫv?5gK,kh`iS{PqN݋ܙ'Fz!uF!3S\U?\V.F lChgcKn[tۍu6>m4^i6zVczBXH_*Q>OE6sFn$ YnG+]xO{r-{kFq'WAc?n1_e `c`o~71ϣcy☏1?c"eQɓC1eun- 9i˚E4fSCUMXD]_Wq/e@&YC=kZֹ{dt |/}EhK?qӆh+N)./uy00#LևDa;%Ճs?߹iOcZÎNj{G]T;:I]]8ЌW0oG^-r0k) qzg"Vv{=/Ju[!?gm2o5:lٲz.{F]ddYMQB2WHe15;Q;߸W11rfM,cC?j~RmhGZΝб}캗ŕ:.wKyT:&{o̤gS[AyvQdw6cCd{2 [ѭu_ >(Sv S^+%+k7S߹Y_;g;_l== ":;@D$I$$I)IKɬ[Ss!${cOW{GvFjIr5r&hE@Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ .Photoshop 3.08BIM8BIM%F &Vڰw8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIMCF]sunplus]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM G]FL+JFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO7]bl{Xʡ_?rVukxcriĥ0Zʫv?5gK,kh`iS{PqN݋ܙ'Fz!uF!3S\U?\V.F lChgcKn[tۍu6>m4^i6zVczBXH_*Q>OE6sFn$ YnG+]xO{r-{kFq'WAc?n1_e `c`o~71ϣcy☏1?c"eQɓC1eun- 9i˚E4fSCUMXD]_Wq/e@&YC=kZֹ{dt |/}EhK?qӆh+N)./uy00#LևDa;%Ճs?߹iOcZÎNj{G]T;:I]]8ЌW0oG^-r0k) qzg"Vv{=/Ju[!?gm2o5:lٲz.{F]ddYMQB2WHe15;Q;߸W11rfM,cC?j~RmhGZΝб}캗ŕ:.wKyT:&{o̤gS[AyvQdw6cCd{2 [ѭu_ >(Sv S^+%+k7S߹Y_;g;_l== ":;@D$I$$I)IKɬ[Ss!${cOW{GvFjIr5r&hE@Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-01-05T11:12:21+08:00 2012-01-05T11:12:21+08:00 2012-01-05T11:12:21+08:00 Adobe Photoshop CS Windows uuid:f29b9da8-2b78-11e1-9c1d-e060394baa3b adobe:docid:photoshop:f29b9da7-2b78-11e1-9c1d-e060394baa3b adobe:docid:photoshop:14e7de70-374b-11e1-96b9-84cebc0057bb image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثW,6(iH' WK?b\.ǎ=yhVY\n/颳 !7xG9'T6WZ~bi^Z\麎{{ftw5ZIH14u@o%1n,ЉvuW بujrS-: (-C]{7)2L{)khnt T^H*9!nU揕Q_m+es|mL!Mq9!pq|6áCsŦtE ~?V'Az]y[2"u(ms=Na;⬿Wx\go5ߗ:Nkv06DM,sƲ(oҮ* d3],#) 4JmBe`*k%QAKTyT~M^D,<*%^ mqo?Q/vk7_%77)bc ,l~<+PBCW.L?ʟtt'˿w,M?a]i hKX$8'W"*J?h*l/ nV[#P mg}|1C҂I_xػ$sgτ6I:^K> *KdGi]wrK3dI`|k##J5,Zbmo {lb$ш xGO1qI6+IO(~oC~ӯCx|?l_N>/|GM*UثWb]LUT&ڭj0-ͤ5=J07E$(H叐j -e,6s#󹿜Z?'%8~=8jf5GN*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/VIA.jpg0000644000175000017500000001511114201663716025547 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !QqB$A"2%՗Xa34& !1AQa"q2B$R4Vb%rt ?y8jJ#.N?vDN=N'hxCC CИ~I0wPxi8 i zա\)4{' gF# ǻIC>x |hy} /V /Ѝ XNZe1b)@8&aۤFft' |q}.ʌSy~/?vd,ުq9v6]#"[; /fVFe SmGUr(0"DsI@ۘ7EYBYnQ/hb߭nbWD&S"~r1}֓uOVUL_"uqKnab{"mbɍP3$@Ѝm$ht5C˰--?yPm=4W֊:HSp_sIiMx)gis\6tUTcC^/2FcB^7"g%FC3gr7Vjm֯+ۜ)*VeȶDޣ65 PAH S|Aqia$ 9ƪ2f`4o*cT5E ;SvNC+M:~@VHSRy>T)l Il}u0 vΣX™=$2[3sHR!O|D/6K2נ_igG?۷y9b2?!1c'ٍE˸7&|\雬%1eqyq4Q%P .5Zr3 rmpE%Ե7ZVO>X?DO I:-٪.՗ֺZ`j(]Vb,o6EVWl۹y=c; [Yuw\@XF-gi Vf %wcp= `Bevn&(R]*iB)L ""J"bi7W޺!-jh 'Š !?EtHTQdq퀓k>4nWkkH*@VޔU B, p}:=6\]RdIj,^Zn~%}Vԫ/1Pe *fDRWP|]Ԋq mq#ڷ$f(d3I"2DH[&;20[(z; 7sK_V%S۪ՓĒ7-ϝ5VWCD<4N 2p5:XF0"{r7Nᾪ!\jU[f|EPbTX`55z],Ca:qI:rHɹeӽk/ڬtqOqUZ/t50WoiH|Rx>DjTՓ$9BdԊ?f~3{[]MiDD;D rٖتq9]2##~D&;e;!\T>ASVܳmA}+"׫vOQ* ҬH9C(tMn)|:J f:ԧ+ZZQdLQeMAc;iJ`(^iإސGG}[c 9]ITTRCJ(@(zܺL0V44J@inD%J{!Vs̋[ZV!/OIDQı(o) Go&Nn}Gu]_qJM?)܉[Vp݇d(;S*@!0bc@0G!36 "'Q^P:Ze),-MJJp@bdm):v@)5B`h-W'C}PXp§buTu=Zֵ-0D9HR;bg5:}7Zr6⛘-bYRNvRx3Gjis7yo1bbMq|u[l|I%3c-LE8-+j"$FJ_R^|RNTu3SEv@YUZT (Ƈ\ sޜTHau6)ol^Vλ+AE4ܥGN ?8/N]W{h = SS촉qΜsҸ%h];)De+>"yJJ܋,ZLrKJ&AtD7h6?ڻ3jQR?b6I.B-wJ=. ೬Q) [T;Ѭ{V *?+,iRg4S[M/>,{?2m--Spn}D:R \ KApwlVWtۋX7>_k[4DKiByc^Tdl⑹|BaflNO4aEp~@,~5p50[EŨ+͒DKV^7IA2:96®y# ( X0<.ګK)DB{ c~vzt`Q#4сD#bWwiXB+@uYfT 3LΝ^q݂GYtjskL>[|֎t]x\XӸ-ڱ##AE 0!ye ax:`HPAiآ4< ?Ʋީ-T G!N \Q:4nQIR5(e*Hڸ jf!Tz݋Ht=:~Lqg- UJ?LY FAXm 5ȧ4jVZW0k\Wku:>TnZ-->x ~rJ#5 sGdUݶNH5rP7vԒFG- ӡPG(&Y>m" 2 ąJ.(EC[яI(W*FvcbFSR(N1w$wKcK7lW|Ki9&f#7XK\`lY+dss *uRjf# Vk$HTE՘d;A⠖h$z'Kʤo.N %#aקRsԑ#%x8% ax:ҳs"cېG@CU \eL@yPGC.'&<el3pܓW4-mvLir4&*P=@@!ɦG*B9ΣU9y=a\ucshl2ZM.tma.K7X*@ yÎ^6ZƻFi5 S>@gR5hGSZw[s%oRIYӧ7ZjLcE"R{^kIYрarq qvA8C'/6_fKդtǼ4#H! v (CH\Ow٥ i8k:0 .N?vDN=N'hxCC CИ~I0wPxi8 i zա\)4{ukui-control-center/plugins/messages-task/about/res/manufacturers/KINGSPEC.jpg0000644000175000017500000001275014201663716026341 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!AQq a"2B$%U&V#DT5  !1AQaq"2BR#3$4brT%&' ?M1%M~l9`aM<0MGс&^l4?݆ yv`L>~wPPr  PPr`GF^I3ɯ̀0G1 ^) 0:C͆u. /V ]{2\ ]`w J 3JPFF˫+5@y7)xq]YEq]1ڃzb.M5iTS}bQsT嗴Hjyz ģv#6X,kּx^6Po^Kkj+Zܽ`;!XU9NdQ#TI'1J2mEPqN)0"E ?zxz")'cc-p\{ B=l#\qaP=(z#M.ߗ .$ξ{de8W ۋ$F? gt֍5̩UĊ)P>!G;h(8tڴ**x092Z~O< 7|M&bi3 ;s1.Q\da}4^U U#7A"|Uz ' |9n-w$8d$J1S:ocq9LZFj%*hSPdTP v=cMg7D ek9^.eʋwƂ@])Ǭr{rVƷG(sU*RPk"KlMaٍMe\}kfN'Sb#9QwyoN4e(uQ U"B Z;x )bj&Rnd>^^kkP:=ɪ@sP޼g*- LN}](mb sҧ~'X-mm>ZDpV̙ysH$xuϷ""fr>a#Qõ>/ 4ϡ&bcF 'VWG)iEUGf!ϊ[t}&'3S ^AL:;c>Ux\|SkɄ4L*t~߬"ŵB'EBe7/$ȹW.=/b=!Jt֊A'궭YynGe\5uؼbe(u;nLUR%! 1{suB/+VY[ 0'yVcPBԏ7*@LI=#" HvnUbQׇzXjꕶ= } H`}Az'gGrO7M. de+dPbQJ⥧( KQ4PW\e e LLQvդbJۼLd|?fUNEN6Yn-s4lalc+ 13H ~~ЏAZܦ 4BeN ^z{cZUlvC21]N"C$ZS{׎ x +opV s'Eyl_2~+)n-RS.Yt ۳;zrqxzNg>nvl! Wpt eb V]T <~^*S\W]G76GrH2:9v۾̓v֤$ڕ͕x "<ck˻}*+>qjrNaѪthAyƺn{6oՕ mojE@ 9aQZ@z%W@C[V)[i-Q<2f⟼''bKi֯ItGNPebxù.חGa X-j-^(o9Obi`eDW]כ Y7JZ;;d1X]K+}M#YI3¹ "Be@&R=Wcd?eZdyS/HWTɯr5Ԛ*JqHC0 JVEuQxE4"RÈkxrtY捾LB{u@,s11!8ֽ $am[S> ?PKR^0817Mm?)%;%J`p*J/N9͜вZG;=Z Lŏp`fkql2T:Q,K,/+\%?ǏЬ{zϊZtA$T.:!xYj =AE[T"W},g~* )өx?fĢ=;+jdzjĩpO(^%-UXx:)ծ~OE`.T~uw#,i>w6% Jk=FH "#N}J^+qZiiS-O)N\h\eN|w[|SWf<%4e1 ҭa3) Cčv7/}mw# 8br۷hw0kXǢFlmMid[/zt=9>~~s1^c~qÉ?WO uW) JbŅ;TFyI:ϥ݀`VUi[ZΤPN#*Qw +3I,JW E塰o#%Ii Idq k$s|Y(|RHl04UBl詰߆r JĬ9m]$>;1:X"89ͽ9n=_M&za$Vg"%j\qiV5L; $bq@䀠Jn`jMݖn^-+pP$*V2! [Ls^1v.zA\ 6yt:0"x`(v+ܥ#¹eZԘCpG%m㊉7-7=a*K$ߴZ Ϳf1Oi Yi|>%{od}gSh3=E-Hs5Q/mLF@Zh\08->CǕfSmK‚jgYPTH q*Wݼqq;R!Gd)!Ta2-=ܽZ9b7#8MܭY+ֺ+ d*Lu[ A7N!VnvmRݸ"\0e0vJB\enS =IxN  qXKi$4eɓUTmJC"޳y ]z'4Q:xSDžH:TZl&3FvBG/Uٽr}N.ʚhY.ОtM$VC<뉹9Z9bghydk٣OqpE[sTnpGiTry"`vkT~1Zj+fT"RU.xQ֫KLUN3 s Cӊ?׃"G+Fؠ0i%$/~ْ~[T8τ4ںQwxnJѕbB TvVĹBS}8>r.G'̨aDL첔R},0`\dW:y1u:$7+TB)Ö}PgR_gٌb<>}+i)0D v [ѺA%  cD:S{Rtk?J*"`p&c]W-3D]"&0rk` C׻ lj> akC`f >w&PPu - `u(`4„2V<̼C |t 芴c>0 s5›(x`<0M|h P}!a׼0#(!0a 0 = {-`VLgF_`b&Se Q`t a]2_#e5х?ukui-control-center/plugins/messages-task/about/res/manufacturers/DELL.jpg0000644000175000017500000001104014201663716025645 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1! AqB Qa2"$4d%R#tDTu&'1!AQaq2B"r3 ?}sG?HyF-M9KO;ۖ "תEn+PG5n2).75(eW3ٮjN>F 0&g[[pA/7E2(?.s~GOHg}@[`@QZOK"hKe$nbpN%o;-wK5I|; CUD-L&u4p)ed3n[u?{Ѡ-a0n\J'#l/cbYLeХh^2ۋ;L]Z;CDyuśgeAXf̚/7^f dm:,`,yե]F }7W0s4gWwC9mʸ&8v<걈(3ݥ:qR-5_pJ۫MVWYBr /UL(K /YE~ag'3@!:9C/qV+jG`npF}UT2fQ , ^_JbtN&2=ťt3rmڮ4[ݛa[ɐ] #I5RC UV(?5XN%nr)JiOV#QH}<̞j`OwѸ݄Zo gy4sáuA[iç`kTrk)%̡nYw{9g)1]domr\"aB *[nKu..B=FF;{V n [ljyrRIKh嫈nG\}_{"_:/ο%X//}'Wc̍/=^mO~1x$ 2[Vn0zQxGbR,wl ҴQ5]U|dgW\t$pdu\]f07Vw,EMC%h % P;6zUv֭e/+[Y/,f l*-jq[ ܩZj!I)fy%mC]bkgJSskGa;Ynj1\N}Y˦8n-'Y'`heLZv ݌Z  DNƥiW-[HߑPrG2WPF*VmJ/ڦfY{*`4VCR'i8'TEt뾔F|7s6.{9g)JHșERJҼ&</idiQ{f%r pO c[1",kػU5pT]sL4'WgRvݏ sˎG5 0ڼðݒAo1IuP9R~Ot_T~;1-^2-a83eIB[͊gՃJj8韲DlU2! @sf,ӝʒ:˜rŹ[5|諵^}K%Y _.f gAM[aՖGaҜµZJkw. `] Ԩ*]!/.'¯i^Hߟ{qnM:b".ݤٙM0Y)(Y[Z%%9P*z<<@m!oNp8bwlZG^M#%4 _},*_%`5r]jvA.X3R1YS.|_"ȉ㭮L <Ӯ}>Kh嫈z9F3*e^x0MSgȃ33P`Y)ԭ]4 uiH<Ŋ%*U&R)^Wt_RȴсW氻Xmm]|nj<-}dNO6 h4WZ#ĭ?;)NF"Ƽ jU~F~0v/ZDZ@:fndlfKh嫈z9F3<f;4>DemRhE}gFgWQe^W)QS,PMP_o%;*X% 4f6YS[#hd(vsvNI3 ^)vw@E[uZ{z2;خvv'_TQCXOVqjS\:SR/f*D^ӆ{L v0V =`P ,d_&%wk~r؃fEJdQq#MTiuqf+O%btG ѓHQ=0BMKqLiLh^e͓@oo[0k*Pu%UDvOEO2z=OFv9j94[s_6cHݸ>nO2ŸY(-M^k)^M**{kn-ork躃RH%*~Ӯ6Nukui-control-center/plugins/messages-task/about/res/manufacturers/SONIX.jpg0000644000175000017500000001227514201663716026040 0ustar fengfengJFIFHH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]"1!1"AQqRa#23-!1AQaq2R ?t(JR(JR(JRnuSH) DI}ٮLhp'W yyy5wWޖnuxnQ",cm(gn *"wAVIHjbR2HQi won-fpۇ_{2 KW==Nh.o<=·#VZu~gPȄXO )98Vg-.:SQ恲4OsajCgJYRe /ɳv8quzK30h'69U0ӃwttfE~#uR{cQ +GZ-m7#a27%Dei;ꖘB+ȴ猎A֖#ߓ!Q=uCnq~䚺A\0ja~UuIڬy0nlMm/+Zx tk=2/eŸS iRq$z]<}վnR{c<15#Cj[',1vy*BUwA$V5>;nugoF?>XhX$;m4p{W~ҖK=j\7˩Zqk;޵i (r' Q+q9)#FMr9@FvpSGEDXܮ7m/ua[a-{j;I{v:mʙu $WU]{lv3m + s 9S8з b-iCZQ|#KFض({u9'fʃLϋ9@ fκ]v[%]4:T1=c:ˡ-mG)6{Qb i^# %;qssfjXVEn"HS Uҵ{׹mC"_=tE iG!}qViG%u651[Dt>6"ͶCs.$:džII9\wR `-F"2MSa' !]WtmEvI IKVϽ\Qd&Zq\c?Edn!8T0`pTkqSHr-EA/nse=kvnOjma`Y.,[6DgR )WVq+aJ4MGFsѬRLG SR[FIKHpVy*,T"psAӺ~2W+Hc!26+'ʷ*+iN}וзPPrJVNHiy[VM H1[s&/kENrqv8ߊe y% xDm° sV]& HqB<%̡R %D탌dLS_ek[ekR샕2 n>]))JT)JQ)JQ)JQukui-control-center/plugins/messages-task/about/res/manufacturers/TRUST.jpg0000644000175000017500000004531414201663716026061 0ustar fengfengJFIFHH?ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:14 14:02:19]F&(. HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO1 G/]#auGj[-pp%cߟn=sObO,qV>32Xȥ[pm;\}qzCeݑZn׵cا!Bˆx⌢,d*dn$sqz%Yv nڇ/GuY=_V-eZᵢv׿vWmѾIJ3pwѹ9R\SkUYc 7VhW:^p T$~JuRXmt_jmx=[iӷcXSiL[RSԤ`}|9X*pm,wnC3*=^[%WW}̦$:*^CKtoCTu[i!Ķ$m$^/Wu̇ -KwWK{Y:UX6/}ew 3:8|_~]f;ZL<˭-ZW^Բsٳ/ٲb{ragV?ո\vƹD'/MK/1dJ?u~\uG\RXwR/uX_wb0>߉77s@a lٻw$oRvSrNVݻ7~ÌԦ>魍h[;+Z \\ Th/PYV]ydͥ{'s[ceF~G2RF߿{y%40>Y?/}t߉sm cˏK6ն}dUޛ|c?n2ZeEVq&^kLkl,ͫ*AmnXuֵ.l{*IN/ɧxxQHcke`36-RgC3wec6Y]֏8]oaabpӛ!l>ogF=b[fEw4m˫}ѵ2JTI%)$IJI$RI$I%)$IOTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM%8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM=F]QH QIq]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM %]FL JFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO1 G/]#auGj[-pp%cߟn=sObO,qV>32Xȥ[pm;\}qzCeݑZn׵cا!Bˆx⌢,d*dn$sqz%Yv nڇ/GuY=_V-eZᵢv׿vWmѾIJ3pwѹ9R\SkUYc 7VhW:^p T$~JuRXmt_jmx=[iӷcXSiL[RSԤ`}|9X*pm,wnC3*=^[%WW}̦$:*^CKtoCTu[i!Ķ$m$^/Wu̇ -KwWK{Y:UX6/}ew 3:8|_~]f;ZL<˭-ZW^Բsٳ/ٲb{ragV?ո\vƹD'/MK/1dJ?u~\uG\RXwR/uX_wb0>߉77s@a lٻw$oRvSrNVݻ7~ÌԦ>魍h[;+Z \\ Th/PYV]ydͥ{'s[ceF~G2RF߿{y%40>Y?/}t߉sm cˏK6ն}dUޛ|c?n2ZeEVq&^kLkl,ͫ*AmnXuֵ.l{*IN/ɧxxQHcke`36-RgC3wec6Y]֏8]oaabpӛ!l>ogF=b[fEw4m˫}ѵ2JTI%)$IJI$RI$I%)$IOTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-03-14T14:02:19+08:00 2012-03-14T14:02:19+08:00 2012-03-14T14:02:19+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:208f50bb-6d9b-11e1-b399-988578345a81 image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ޛ1qryb'Z`R SMM2HR\&v m.!5 +JZ㡍 ^emY큭&]HL+R+ViP+c՟kt?q?_gΟjOo[zqս][w힣K)f!-jieeji(r(C;\Cy76EH.ze&iP~H#H# M(/j O~b..T:ӤӮ#OyTjzޝ{Czul}%}]76/x߽Ux(w.lw Q,%\TY,nZH*xfDetRR(hz t)^׺u{{^׺뿺S_7cc6m~ǐfǘ[P@,mUFHH*TЎzٞ;lW77IhPZi9"]7ee`A n{VPhhH #=e66 yUXCQZ0 A0Ak7O۟tvwivOnTxH5mN^L)i MH${ȎTg]٭w G} Lr,8sX}Gs=ߞsعYf&- D (/"P@j'⿑s\x]{6Sv l+68٪d-S϶TI$>歷qݬw DsFV* Ǒ>K|7nZ>^l;g+E4dQЊ*~D4&[7_OON}^돬6xmTWmr9g|8mUP و`tPXm $?:6v7<^3{ӭdޒ.CrM8'A嫟WҸXeӏT*1}˲6vfv?wm|WXowش3dV|^xr4L:mAkKztf>`2;fm~ܞ/x}wEff/e4e\}Ue -:Ǥǽ&q@äl{ >2lѿ7/7wf !.2mc6K5ڒzVUb=Jgi530d{K|yE%>N-WJi%_qViymoմ7U |}z{~VUovo/ ]| ۻ+t,t˃Z]ŷVh&d*4t@A,:-A$cғlJ䧞=IS'ǵil=6FO^3{uQN$`;7] K3c *(Jci:LuO= ߝѲl9zQ`[sTT9ǝhb xBeYMow P3׺ sxo}G}3mnڌVu{ֻ5MEV0-n9!s\1s&ź‘+*悟{Cۿh#y~bZe6m#,n* kzNޓ`;7n_f8 -un.M-]%%SRF$ob.=— Do#F 5:'r(-[.a)2"ʉ* VeԼ Ҡձ=Fk?1WovJuh \r/[–qأoU[wS޻?.~ztKM?A|oبjctU:__':ޟ%r(7Kh#;+enIv|YܾrY9_2x-#HP;ګnF*8bL?ݗ-:gо;j_0QXlAxJjEGyؒI:SgiuX_"io흺+39mq{rbs5\oFE>Fd*ҞYHtw7TOT:vnO𜾊;^v/C=[uh캽ל`my%EI5Nvhҡ]!::_Dco}Cӽ=Yv7O ؝K'S:qqa:IIJ/k|U*o[1o/%ƒv7 ꬇enw|I =ef?=6׭bY+bZyfT~ j:ЩQU>]Y~?J7owo}`~>6n Smjl7pf)X)]GħUuԶϚ~P|[K؛w&#pcNOJ1Cn)2*嚧Pp8 uj{|T_ ,nݻwOw`hk[/ J*Zwe&X{^W'O#;ِ]7_y&}uO5g4F}aWP#=wv-7T e!xug {Sg!{l=ܻd6o☆z|3PM sы`q|Yjw#b3rn~;67IgrIx>67YCB/lVRmNݷ XaT, HxTw}>{Ϟ㝴Ykg-]zt/=P,:c7DoM[]Y͵2Q_QUU[G5. QήRGɇy)1*]k*;~6>ȃrVL^JHAƱrIn4滛کcqlN?D[^MwN]߳w\N_XXrx\KzL,*XQqLum?gTOxoQ3g?m\=YE`6Y-×t)ҝd2V>X3{z-ܿ'Ι i8}6{+T,fFUM[I,5, d_W_ui۟^lcB1˾sifnK2CM> Ƕ( Dy)jR*D2h[[^z; ޕGFN'7ٗdUazͥ9 JRIT3VI'ϭ s?5.CQ孠"z1Fg6/]]_C<wObbUTFާ-h;xUtb_ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ukui-control-center/plugins/messages-task/about/res/manufacturers/BENQ.jpg0000644000175000017500000001375214201663716025666 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     !1AQq"2B$5 aRbr4%#SsEe6v7!1AQa"q2B3$4҄7 ?<-qKi cD٢X)D~m.JQ|?^|ZR$I~{~rCJ0L3D510K>`4ڙ)}V{ZN^T 3R<[z\0P6 Q< HB~ K&zgSӻ6Pp +&S2l v'xLȑ+JΫ@Eb\ʕLR;?GCj,{i 2DpL@ăr5`)SV2>o&b1Y. R R .*cnNu˚S(ͬ|.mre$@Fts9WFQ? y>`5{T?њorIݫʁ_=ηُY 2$$lJ0/xl+n\#Z*Tg/8XwU7.TFҫ&{:A@njQRuV-hM:FYľ|K*n~MJH!'{5Yz/{03vzS\6"*Bm%Z>L`R!jT N*aF"!am}oזƕgh'uZ|DQ.d`fh0Z4~I+ܡWۚYHz^WK@K0A֢ؗ\9. ?G:hc\; +~wӿ܎ZYuJ$Ɲ1ǘآ* S7 Qc*q9Mٲt{n :\k@c\U{S _vmܤڨ0i&2I:n*^[jhPUqkqmgl_) PmXT pnT;i~E&YX5Dmz\Ȥ 텝ۇ85W#hc* 1 *gf7}mC"ecwm\*{=#i}. ~B*#fD+8sb:zs6y*~L a1֧ܣt0MIv Śi5K,dlot:y ʤThKmNτr+G Tg>(cQ|4zۻymOk2ލq%! '50HƳٚغMЦB$`= \'ZLQi;yP+֏ WZ[W?)W|ڲ[-b|E^W嚪 *ogng?{IJ. йoW&əH7 2f|+nGFUk0Y+yX/2U$[Ήo[bw}#KQZ3TslXط9e04iYls/ ^Sڎˁy1݃!ZX0x=NzX]7~Pլ{÷{$YO6};tir%YXAzY,kjSXک2}6X|W{xPfj^hX Օ َlgdV~^aTlBȗyKH5 (}rE;r֭@'D~h)PowR???)yzֽ:]gM,b]oHX }tv۴b.P /ȑ{Z~w)\ƨDI0T|Aߝ"{G,ͥ;zNx]al~]GlM1C4Gh TI. +_Ց*TbW8x{|=+{_k7&L^ 2lSs[ =wOKu| y $ $JSK=_-HD &@VzY^k6~±Ap+h(ڼ7KkȮҊ$Ε&`H%5g0,̘31E!1cvDxv݈t\T2IegDJJ p $8ssaQi(Ç X(5V/;_'~ltO_m.*FфUlu3}N<4e1ە^L 9aGoon:sFSXđGGɛ߮d,V.'>w7ik .OH>&Zӥj:ˤk 4h O.7iR4sAezֿ(FcʼnTÊv-l<>تu`$1 0DW݀MǼLlpašE0E0q\:6-2p\I8via2`w/ݴo$:+j1̱X!|-πJֵIA"^.8hMǮ}]N۝~oxDKͮ?2>+l`317v Z{xݕ'X )ֶȜ[هiW%^鵺^9q k*nr.=m&g-6_/Dp@MnfUcrU%K6 PG跃gYn Fd:ewZ4I ݫ ʷ܁'Kg>Uq EB|(Ӵyrm H -Pʫ*B,TX䅑Ka !PW8!ۭDDJǵ*3e{LӜNSGmLL ZVR/ρiȻ&70!m4(Щ0,Zҗ)r@*ɝb|$ Txd)}ɼ#txn F]{+(FAwk hБYz@"V̸{01˘1J"PO ɓj<5S1\'2/ ?v&:R c,L.łXF\,d+4>2w?&?~uŸ&2!O$lé/rܱ-]2Zځ<ƏcFDUI]KFoa*:p9(1]Eׯ5{=:\r4L-E{M-b̙JXP<6.2ܪD)RcːHNuO<ɸI Ҁ[֚1KYL<҆72JZX7'4͡2uGʲ:](>9xY[G.FCCnIkж eX VΈupnUA-q& Tkw!YD|^{<S̹Ox<^/y~fx͗ڊ}Vۭr|վk^\*NʌrG`X/YY$ۢ'TCS8~1-Z]弮sl.O>0gi ڛ~pd׹**vvgkFKx$jZ:˕[tdE^CcJ7tnV|e+;9F0⻸Rjl$Rr+ ]ke˦$0檷cܚ?à6¢sm,A^g$q3$O99Ȣtɒޥl#㽁r.Ԙ]K!.#d=>*~ʝznsM75.$ѩqUN]Pu $Nl䛶<-r]ɸ7vzlabIA<#4(1[ҺdQ0d ;y"փ^M:x̘ uZ㤵4DƔ&X#fDy}E\Kr H3҈ =LbbH/C$ rtYPɔ)k(]Ze:5"]ܷw,7$ iXF4'cLτQ`:D4y;v&G%rI1Za$8⮞+ 2 (w!c^[B9j9& \%UqT-MMDr$Na(ymgSom'%ko""2 ';9" Tg҂Y3GgLsleB,l7n *܌Ȩ);Zi*pK+b>Bse̞Yvv7}N疓8_~}+( %EJ0V#oiR 5xhv# _2컷$aSFX&]2k]v#ZMN y޼}Znk2Y$y!ҲNȪHr[nG23*:Ѽ ^'sAj_bI ؐ٩VÓM79 ~p3wcg1gR(-12>Mc fO$ZR@MBʈ/x|>-)S$x=Fd{&K%0}QL>߫Fiukui-control-center/plugins/messages-task/about/res/manufacturers/LITEON.jpg0000644000175000017500000001173714201663716026134 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !Aq2BQ"a$tw9 #Dd%7x: !1AQq"Ba2t7r5u8R$4D6 ?M+d\ԅ1$^U)|Ժ"M{}R vRtI/I˯0&.$Ң%r`R:eOw JX\ԅ1$^U)|Ժ"M{}R vRtI/I˯0&.$Ң%r`R:eOw JX\ԅ1$^U)|Ժ"M{}R vRtI/I˯0&.$Ң%r`R:eOw ˶tWXW#{x=/ml92A,HdzڂVU1|mpW&|3x[/6Czv2a4%y랛{VFO/ߓ􈁺֗ë{)cU/6>eKN&";r&mI!tt-t|&ĺxs>xS-A#ZDv2+W,5ohDv#@{m7 9c(fAZY$xqMD+U^ YJ5,%aD_-&- 5.۸bCfCb#k}Jo=]۱dE!zBD IjHJ=(UǴ)۬Ժf /=&tU;yt "CpG'\ɢ|89x0 #H^Q-vXՈ_@;+<5:)׃`=,*ro4f Zӎ([͏e y ]!~C>5* Z.+v!T[HJ'C{YeES~q諝3savɉW/!z݈yݸ>o}*EbXI/5)E;(^X&p9DDH,Yw/ 8hi8 & >qFº `ܥ01D'x:OCNM|-bckҽ,Vr'+G-j":J=+4?ݿ4"7ci1dW!&'i|A0"81 tp9s[FM7 q0șZ !L/n2 `ͦHG/luuCIw q11ˆsZ;u:\L V7o-/_yu@E%H&yUZZb5m"£XTK/骸k1&8Tk5{Z ꦁր H"=\N΢Y;JoDIpjKM-Rv+,v4/R1lE|pC5{n[\KmT~Uq|I &d̲g6@db[:c% #d[?YG/ h>XH4ŜfA *z3y)P1c=VJ ʻV m!c*hKMUmxJG g%rzTmWoP L}gcaN*~eU?)Oͧi8kngo+Csk{պD>~ϦL&OXv(jgGOciKRC;1/sX at$INۂh.Wn 's^oq !- nm3!4Wz"'W6RT71YpZy_X` ā9eRcwCJb٣VD5%Jii."%d4 V5JNocM~v Nj\b0e:㙕i 9 F~a_My#Yj]oˑqeW5^//oZyL?0P_afZYytU /ZұduA70xRX\j[őpRfg2b7&:rl"2F_8bʃ?)&m5c֑ؒ9zNuX.bV7MdY%86IV;_F&.Lɯ$`|F/C>Ox^-KnK6_)_9#亵#~_7ſ6+նE/aJdj28嗏 =d Gq*.D/݋NYRlh힘p$@1lKvб7m9?!#@y-u5+vDp I1mG '%JV)X @1/)|aǏ '1R9*%NYi꓎=Ў8q=[gg{^:ص_=tKtxYWuorKCNyd'%Gpzݥ8kyˑ%l59&6bav_ q={V^ZOsvghDHl:0~N..@Kl̪1a@b:""G4"$q q<;SW.m:ȷT8I͗TQ3 Ϝ队xa{ڦ?~^lmpRّ&St,"V4x\/°T5-\?RBx93δ/rVK:]Ȉca09t$@Z1k A㩻FraMc f[5=Q=9d ?2n<Ȱy"Y<6ܘ"7=$ :pEkEj^D Ӝ38Ecq5qq7-5Ns 8!JQw!&| $".by 'g~ox;xrM2j-%()K@xq%8~ݿkl'Sɹ 2]{Uȵ]wбi4UɯHSA5Q"MGK)׷AU o%)GDAP\ Qa@RrH *(2W.E(Tyjбi4UɯHSA5Q"MGK)׷AU o%)GDAP\ Qa@RrH *(2W.E(Tyjбi4UɯHSA5Q"MGK)׷AU o%)GDAP\ Qa@RrH *(2W.E(Tyjпukui-control-center/plugins/messages-task/about/res/manufacturers/ONDA.jpg0000644000175000017500000000626214201663716025660 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF] 1AqB !Q2"a3C% !1AQqB"2$ ?&\˓_'T eA5^Ȃ:I~YE˯0%qFƂJT.];Vi4し& NA5[*A56(kP:uQeAϺ^aEPJˍ\`wQ]b)ql2i].M~PkʶT(j=lQק{" ta%ugA.Š +PtSZd [*su\/Se"$ivJn͋6D0vz:oWUtSnkw{S:.(C-䀘<+p1ϏG 1I&7gqMz׊KdATrL{2Pfx+b 7M(Ԋ*M(\b9O_b%ҘY+xࣔc*;O~㾌_OdF/[JԔ]]<+6-wK<^Xtmj>wD? ;M>GG>?㛰3rv4kMn(dH@ e[vgM G^+s$ľ({aԗ3 Oq~Nj/֟"P:1bfw7Kb%ؾؘIX>bHJsc|fmH̭tMv >%3Uf|ml}{-z}chE_TVZD"d8;wx-TkBgyQS(>5)魸  O]i ñ>az1^Eݶ$9'dFfq cp)Zi˔derg=n!z==sqzC.bx&"ujU"y\g(P}]o[*qNuL+?CYKoJ M 2LY3Rx@,fir cwO6n-FCE3H4C(I J"ط8=Mt-;ȰGtboVL)iM2knpXƢ9Co\lW4k]qeZow7oFnoNǎ쵕1n.|'&Ưvls -aD,=*S6i4し& NA5[*A56(kP:uQeAϺ^aEPJˍ\`QB)ql2i].M~PkʶT(j=lQק{" ta%ugA.Š +PtSZeһ\(1:וlQ{(آ OuBDPEK>΂.]yA+ 7.4V2rEuʵŰIw 5PbuB *P QD^.Ӫ-}՝\ *Wn\h 4eB;O/?kaukui-control-center/plugins/messages-task/about/res/manufacturers/B-LINK.jpg0000644000175000017500000001102214201663716026041 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!AqQ2B a"$#3C4%v9 !1AQaq"2B#3$RcT ?&X&B *j=Ը"Mz{(#PJQ$0snL.”\bےJ ;”zS)> *U@ɯ7kʣE u.^):vRpI/*)˯0&.(Ң9tO¦)J&yP*rk) H&K)ק? AuK? r)EɆ)K- 4N]<)G2oR[Ϊ6ϷL -<[\^V9s`X2ӔgT7-X@v"WJd3_C\b- Bv<фpEYTǜ}1b(6_l73[% V1.x AݭQES+C6Fp]Kq"Vv[4u$i .'K `ΰĆ4iwqm7nTg>@^ӾPŞ̵ۡJ/f^[qWjInM6Fav7G%wO*WjRY2̙k<5>Ӛ$AXq|?pZ9)d|'*0d6]H VصssUnuku67.~}XZ"qU{iδۭhIY2rDZ蹰o!kk[ ? ɛwh1kKcxMPS#R(JP3(uQ/ZwtPdwt]c8qEngnmBUN9G  #"*lN *Xs()mP F؞Ս͌:>nur5oL[Vsd NN.aG+п¶W /*?*_"/\v.Kn}S?e$4CAql=vG7JM:gʱ~q|p/WҘs%4!2 neVwش6Һ3%[IM}.rf_Rk#Ka㏼e Ļ93{: /XX&?]FW`oF x\Bҫtvp%*$6j"dÐݜEdL9]U2Svp%E٪ j4V17'!w&HB)$V="?wDvF?x@J!{$MN_p&,rd"C}js集oTN"Fƹkre-r.eR֫ > }ipU^ :]${6=Fj[.TH7F8Kl4 2F>E0<0B)1vM @}+kj28\ik1+%EhJfY=G\N>K.W*Uү*NM}ԅ1$^Ur){pE PGH.ӲI~`PܙN]y(0 )qE$)ˠw(R}<1MUi4ʁS_u!Lo וG\A5\H&=R t(_9T7&S^aJ.L1H \QmErJ=)O?LSzZM*THSA5Q"MGR Oe~;)J8$~ ɔטR R[r@iQArpxRJe'Sޥukui-control-center/plugins/messages-task/about/res/manufacturers/ASZ.jpg0000644000175000017500000001407014201663716025570 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1!A q"Qa2Bbs$ #4T3CSt5U !1AQaq"2Br#3$ Rb4dDTt% ?Yx(. `FPAxCAAҘn0A8~PA8{~z^0xSAKc.NoK Bam՗j,. `FQRO 鯢X ǡԯP(H Pi(4^Z&ͶQ4LYUPtmaջƝG2>ww ; nYP:ǗG(3:3Wx"GdG`o0M=H5@)(X,} tGe%]q3>8)/F~Y䫱V܇~?##&Za"ѕ1T3#o2ϘFNv]sY[~GAqd?GR;OLr]YÑ87;ײ,\sҜ؏ p{3ĵoE~lNPrRm3j/G4[xem+,9 1˻0Hi~zȌD8\ߎ )B0!/Y\4 C=f}g3Nm}$tihq g5ǜVqp9Pt`2DiI *;Z30D]mA*kK{>ge> z]֊R5Җ@!ðdG)ɱO4W3wүP]f?rVgH Eb1kg[c"R݇ʵG۝-ewd%ۆbqV=E{pQ5u?Vpby@&6=7tڰu$=P͒r9Ğhe)IOA]ZLS]r;A[ CsJIgzc-w:S+ [^E;2ϛ^S3I8HOOꦮ06 w/%uh b8 Y6Ґ8/YW4KuqF`MEk%G#0?F~Oiy{g^*D<}y^WM6l|'5lS6HD>^r9g)3- dT[UEBٯKOP@/ x6iI=mhAҺDFٙQ*ٳF--۔/ NZ7Sݠ>qdW[:5ԭ E zp'L\{IXi2o+RQΐzsrcɎJa deIqk6-Ҥk'4Hp!rq|J}жj5{b(oVC~zg*¬{u5҉ǘЙUY@U31E75~6'IEs!XpL#K-ϻho.R6XOdKfjj)'B3eɅg*ff\|??5R& J"cpip0u/yڬj|F J)d'rm`R 5$ጾ1 YND`LgX #)T$Q` BAP/0yɩ3 ۃULo}KY}3Om}'`wwQSRLII LI޻=_?/u2RU—!%fI}jG 3rj^O]T** 'W7/iꭝY*JA:L%(V 2!(fh/ԟ$=W)d Cro PBӨu0ecn-qYk;7Ƈ|V&\ H||tO|ihCs>UTuy5&Sņt5цqUCwntdޛ>nHd>ֳ@_t6h ԙd6MyC(9M TybHx8ӎz/MڤSoPh١: BRs 2 3Li$d5͕LSU(MMr5xmSFːJR9q\:GMĞmO"zݽ8(o9԰nEMVj|zg\_hhEЋٕ,Cw÷l~ߟ.^I`,9br":%ӳ?+&ٍt;Jv蟋 ە4ARY$ L&w`pk@ڜA6с pr2ʥwfM?W! b{~R6ƪEn5̥ %"}iQ}LSWP&}2(R%<7n_l^m녇kЁ ômp;_9־_S-\rIT&  XB?MT|H2Vͪy}x{~?48ģ` !HBgo P>_FHME>eLjQfIxƿrwӬu2x%#Bxd%_\2+Ǝ^4|o2~ȭz |hu~(mknX[Ǜ-jIO6dHt^$˘ŵhўUa9h3|?nheEKafֱtIz$_j< ~%$1-ͩ@[r^V&`+WSˌ_m6NŔ:>Px1vZUS;e &10+oo-BH c<@L8J|Ot5{܎+ WڳR|JۄKؽ!pM#2gs=׷R s#O"%Iv}koH?ܖI5 ʬqʜр>^ %q8Y jђHO;O N9cm(Fd ?4g!0;og{\4k)- vp'7}m1& PHP! 0n(}=;fq´TG] >yu& 2"㝦eZ!y<ɔoͱpLd!f {;C^kk8Rc$kU\Y#u9# *_,{~s1>Wg-<;~Z3R0RUZ1pv7QVvU.ZmU+VGO. ; cԦrzs9Cc(T_::t@Ķ)O"|~-&˩ʳo2k]&t@jZJE\t Ȍ+mZt0GՂRMp ?A(_/wnT7JmT\2E ~C9?9D2UEr?jəc)Lci&ɣVplA+bQwٛR#0 }A۴vt`ըm4B@ Jr9vbDXsSPFd]8YgUn֗ lku-<UR!?z #У5PZ'#6{q?`'>0Hpb;}]kjk7/J6XX,)+"ݣWbg%<`y*s4^$ǐQi>*yPplu4Q3`S9s2A0lA s-a|j$ԇA9࣢1'i*{>)`N$U,".4GvpE(6$ihx o#I `rL<GоGɌjv:_oR,Q;wcv;׺R>vڲZAS(| @-M?q dEJ*ڢ?yTP n}bR閳>F$wvDzbDճ%f'Em1a9g~DanY)gh0;clWWS\A+=52WJ'P05H$@PࢼZP(;53a'ɌJ*Wt4N6a2&͂Uأp=C5e'.&( <@s3sJPJp t.90R Frg1v陆Lr%c1#nP) wÅMXX,1mPcI:؉gqFwOrU⫆2sEe *yrȀ7hhHV:\#|JznQe5l]jŚH6@>۸Cs" 1p8"vwaY ~swM h kBK֢[NR3ufG V/*W1޳PŐSc)| n*v_9+ )Lc"<˗,{;??[S}b%p?Q Y2Ǟ"~0tYA @^,kHtgtUH(H)K %6ҭ|rv˔֏|EA7gˤ PG^ߠ}$=Q9t 8>a>h[F5e1 8iD^PFP@w|4Nߪ0~Nߞ0Ax~`F s8>a>h[Fukui-control-center/plugins/messages-task/about/res/manufacturers/KINGBOX.jpg0000644000175000017500000000731514201663716026240 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1  !AQqTG"2B$ђWw(X#S1AQa!BR2 ?>L#>t&>ĵ5c Sb>bL|b\C̿h8К4BI^Z5m /:m5m$NE(k(}(K>~j>C66~_Q6'r??/xVƧɯڽZEz:ii+yP)Jj8؋EXPm &ČN'q>AK9Icx` ݾ^ @Wo0ײ|?񆽐~v񦽡 5Tv >I=-cN_mڊ$5s&q $͘ MRil@ɽgx6ܥm{vWJ3)SVW)y&B5SyUy-bʚD*C0,cB0ȏ iDQ4VӰ\4q;M6X 6xytJGy6c%R֍ng5q׶ʈ٪dRh R˘\)d٧f}F96%Bnq[&afeh-/Rjj@a&TifZ3l`2 eNS]MPb4cn[J-U֤PЩhtҟ.r,mf&]rS%DUj`jE!aXEuM2jz*tƓ vͶ:LZi18N&5p(RZ/Z-< Ν],{EO3⬓Ux2ן*4pbV*PoF] %UKBf Vml+,?L\JcMLT*ա:OhCdAtJԭ)XEͤ p,]˞8Ih\r1:ў |di›Bx^6z'i ƨJ&V9y,iRc s`>Y۾>70͙O?/6i}y8x*qGgO?:.wG<7ŨiYĻ=ٚ'{ 'KNyawG̑;߸_mduXGAGQ;߸_mgZt7yt r3:y8/ֲGADl 7!:y,n8GE8j&!<]ٖ,k ?N+蝱jF{*8nh"wq^/Dk\ n b&;z$e{W*D丿G~'lZ=Z#ɏ1-M`ĘC5Ę3r/DEFen3/?t&.ĵ5c Sb>bL|b\C̿h8К4 AdobedF]  1!AQq2B a$"#4%1!AaQ"B$D24q ?Ǔ(.qW&$>]D DA3 ? NȒ%˟T7HӶW.AQ#TArIo-LQH&| 14gӺ*As%=K( +>!(n;m((\]D DA3 ? NȒ%˟T7H'm(D?MuO u:lFӛm6r*DQQNUj3 !I2a"c?^_^ȱ7ȼ7+#ыѺDh₤¬[j*}XیٹUmn_L]@崳dD8Mqsrq#pl#cg19vdk^ -E]tf>;&LwBOH.aӲ$I~r"E ש0zL=`Y0x!'mSD V%S̕ϗI@@N',+_VĸB (!BR5\ijf%A3Q˗3L4HyK<~E.:W#''G39|:N=x7or-޽sOӥ/jujUɢTgK\$ @C7sRDpuw{;.Al`ܝ7zۘc8Ӵx87ٴxT{ZtcE{lBiޫw^whUn^K[꫖0?5QM@OkqG,>SwQ]]Waygu1/>Մ;Ab% @}{mS{ܺ}emcTԷ;-wZ :2*YiQ1x伪6/!-بb`.@ :XBusܷ)+',%t6G' Y\;0Wٿ+5==oV۲{iCUAhʙEI}`JaM lNfk10#̔"I(n3oay.Lۤu.4 S$vnfuMogh]>*Hܭ6„U@`e:jzqؾ=s*\#F P-%s:>r,,Aw ,҂8Qݜrg"9G" y]MY&z6oȇ u?Mѱ ;M5EŢӝoJ* JM1+-ʔ6kֺ'=L,s~X֖6tf#R*RZM՟[iyu sԃ YbٕJM*KEyTRDcZ?ᝎk#1n5B%B.$ӡ Br7.18~Z^[H'Pb۾۰qsprV^ͭ tKgilK|vs9ี݅^ZAIp~Hv8~k|U[ #9T5X.5J]f/K(ѽ*ڮ>ܚ+G+"{[嬺}.°-^_t-p*mŵh1Ҕ]2j(YO 4Xo}۵a\|v719r_kE·vͷwN}٦R,gU:ymR܊f]5mƋ}܈MCs܄SD^^ ~O!0&8F-ML=bZ]h%Gߎ)nk?=PaG{w3 4G.IIyk;}y<. 9 <2cD܂*tʘJ-JY$#N$P(0%@ Ke츃Y+v^\'Sʖr!LB HwQdI$|fs4i.8:Շ dܳlyUJ, S:\Z2IJՀ !fr̗vi2i Bp8 cU$T'/G+Ayz0F4ó !M˾tM.,iT3*:)g>ZDôCw]wP=QeP%W3A9kՆ8F=D 넘HO"AG"LxD{5_l W-&Q 3DF &L'd NI:vDI/|4T\H@DH @rO {ZLyhrg*BA3M Nɤ>ГR t)_8@h\ECt;h@Er?UJo,F*Ug A3H&};'0S$PqRs"v 2<$~>?(7U_ukui-control-center/plugins/messages-task/about/res/manufacturers/REALTEK.jpg0000644000175000017500000001351514201663716026225 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !Aq"BQ2#$4%a!1AQaq"B3$2R5r4DE&6 ?<5mqc@X0N=ZUI4:6Yq5f ==Zљ/#&&9xIjV2f!&9x;4#͉4b4ZN| }fs _a^b}ӌTXwdqM @/s{6pӝ)QJnetu$kDk"{Kݠw|iQ[kЮXsr9Vw2iBu(w W2zsQ~.,K=9 rCǮKkhzeey#6 AU٧-ݔ+rqCխImpui16Osŋc ߢw)1Q)Bq@WN&Wknw7W wCsclnz{σU9`g0 ؤytlFP Z8&D&oB4#f/:DCip߽zW{dDZ+S#+CoVg75:xUtjStk@=VO!%S3?6Eְyщ4b4ZN| }fbP\j#UHQ=!6Y{w[y$_Z9~ĶOlmVfy<ֹ@r"wfu'VX  }H\,- \A!2&q% ![L-a`ԯ3oD [|2 DcQLZNqHZ+D b8ejOoke(2@L :wGK՗K#)hnCwu=Ym5aeM[q2О3]2E:uH}ۘtQxw*c+?*7Us>~KpOOMQ'q6uJ9E c6r>wPmdi%de~G,%_MJۂ J=}bi.}8J<pc(AoXtߵO/]1 E`dk&sPͫ$DPwU ?*f(o Ydb a52+d?ے݀pkj$/fy1>^IOc@X0N=ZUIBfp'ˡ$J$ w9iYY:ֱ,9qǤ5rCv2۟#HZ5U8L{çi݄)֚GR*N [ ߻s#/mЄZ 8NdHX:lv*!^zE6X#GhJ'\o=Gf/vkJԮYK:mi#-rk-z{0ڧSV3>GɣW1 c oRzkeDvԶTph@^֑$PԁB#Cc3{4$9@[C41cbk+sÝue sW/Rz1h})pi1ӎ6qSTxi3ķ9v7莚:>p!PfMNt[\rF.p#7h([d~TGA[1 Tm Z Eglt 7xՒw_?uQ~?\YulmQ %pS+5(,u:*}CWk›j~>[|-o,Hm 4i<s6I^bb}= -X3'h nY$*94 ᒗkdekpƵ% e5I."(7xǻJZnMj*Un-Y4 *p[Rv%,0[J_mIYҾJ \;ԁ7a3eu<6 WtJ Z^<-H?E-WUtM6r{Ȃk+XYմi2R7xGck6Xm21(ʩZt˄7* &YqJkb53J<\DCǹO/wUW_A斗ңE\VxFo~{\yFb}= -X3(nG}y"qc/&(%l7/yeͷt fݩVEqH7"e ~RV2k͗2 yh( =ɢ#qh~jϱ񞊪H7UzG4;{vv zĉc m [yrN#F"XEփ5^T آ#ۦIZ  o@&Dz@-BsжzRtqDzeQ>.qt7.Ny|Ι.}-`f_.[ y  *l3 8|D{sbjA[͔V"di~,V \ q1I^O؍n P.rGQDIk[.|Z4>!O41"RzGPN-]IaԌKG KP_Dww`wP>duu,ǭ޺t/Jk>T-t6)'max;5u'Ջi8i0,rqh oN x`erI]FifBhkB /K_H|*?$ݭK$J1q{q6l\J; ԤL?}g 5'OZ6`Cա-2bcXhDF p幻+p2ѭ~1ҥJWƶ*R;kQIoZ=NiҒkCNq_4&k} %c{B<ؘO_KV/sEݠ,Fa'*f },8~g l̗_fzB$5fCf3IzZ{ukui-control-center/plugins/messages-task/about/res/manufacturers/MOTOROLA.jpg0000644000175000017500000000412114201663716026363 0ustar fengfengJFIF``@ExifII*i ] FC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222F]" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( (:ƯgiW] s'M&ݐ7mYtPI Ԛùm%1OタhRG5]^cVq7vzW5XϦj77K{y7שK-3[G~j[O-nJz@PYyaNaIb\5 >'I:-zy^׮U(;],R咱QEyXQEQEW|rפQУr!>0?*X;~Z\v]*9qrjý#gZ].裗ϓj|H񭯌OWBp[ԟ uK i5glO# [> լ>*isBwNRp{Bҽ ԒZ]^Rׄ!-1GPkl=ocQLέ?iMR 4m#Nro7~TV:ޚ=M &?`cXĒfrJG*s"jQ0fu{9lyw1́NL?\fX^jWKmcm-8?{o'򦱬mK $oׅ芣JUw!t X hB uckV+rwgQEdVO,|1\ZC,+n 1r0W/ 3K4a Gp39:ݏsz(PUSnV1U+GUIWWPЃtK-5cj3xn;1,[F>ۘHAzм&/sxbTk:#;FH?]ҭᢕJ۵bn<;ۂ:F4Iדh^}.iiws;wcSM-GN9dGgI#6>rN:a֖)Yu]}ǹYZ|~]c? * IZ N_M ;0s .20W~׺E텿h5[ -8ы smW*xU Y)X0=:m7S5JE-m7/#3.r@h(M@X.,ґIrIWqwfD^ |G|Em[MS[H.nĨd$ɐ^Y֦ܪsWjF(4 Q(\Rb(qF( (?ukui-control-center/plugins/messages-task/about/res/manufacturers/PIXART.jpg0000644000175000017500000005647314201663716026157 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:13 13:25:46]F&(. }HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?}ѿ~7_My"Jů}ѿ~7_My"I}?U}ѿ~7_My"I}?U}ѿ~7_My"I}?U}ѿ~7_My"I}?U}ѿ~7_My"I}?UFǡ^vV@6dv@/ǀh7o?Мt*1}>[?ދoumkYEGX[?)v^߳vQΦWТtۏiUkmf(nõV]8url542}>7aM+ToΛ1E@,kCֻwl#@Ia xeb,ͮ.I*-?u4o@ԍS%u]u|OsyrX=Ċ,gfob1.ƾk'赩OܼӍHvS֏-`S-*Tj#CKòddexSr>׌:afVuaerCӣ#;ҺvUYp ΁w_Xz[?Ls TfHQ&4.?sY1dc! ч3. 79k\{9\.(c?֞i~gˇ$ rF#uOKQ1ϳ\G?zDȹZ% ^"5zL>ҝ]0]sdocK {Ҷںkec7m.cK]>[/[_͟blZuMږ{WNpĿ7VyM f_:l'$k to]Ӻ'7ن)}h?YnmX\wnC (lȩ;bw??+/?p敜ӌv241{|ڌ8L=.GlYsmq;\oVο}$x(8'gE/؝kd6Wh:/9I˗&Crx÷ 4QkmbǪMncK].;~^p2?)~_'ٳ"n^dzH f_:l'GV_Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$`Photoshop 3.08BIM%8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM9F]N-Qt]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FL }JFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?}ѿ~7_My"Jů}ѿ~7_My"I}?U}ѿ~7_My"I}?U}ѿ~7_My"I}?U}ѿ~7_My"I}?U}ѿ~7_My"I}?UFǡ^vV@6dv@/ǀh7o?Мt*1}>[?ދoumkYEGX[?)v^߳vQΦWТtۏiUkmf(nõV]8url542}>7aM+ToΛ1E@,kCֻwl#@Ia xeb,ͮ.I*-?u4o@ԍS%u]u|OsyrX=Ċ,gfob1.ƾk'赩OܼӍHvS֏-`S-*Tj#CKòddexSr>׌:afVuaerCӣ#;ҺvUYp ΁w_Xz[?Ls TfHQ&4.?sY1dc! ч3. 79k\{9\.(c?֞i~gˇ$ rF#uOKQ1ϳ\G?zDȹZ% ^"5zL>ҝ]0]sdocK {Ҷںkec7m.cK]>[/[_͟blZuMږ{WNpĿ7VyM f_:l'$k to]Ӻ'7ن)}h?YnmX\wnC (lȩ;bw??+/?p敜ӌv241{|ڌ8L=.GlYsmq;\oVο}$x(8'gE/؝kd6Wh:/9I˗&Crx÷ 4QkmbǪMncK].;~^p2?)~_'ٳ"n^dzH f_:l'GV_Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-03-13T13:25:46+08:00 2012-03-13T13:25:46+08:00 2012-03-13T13:25:46+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:b3a0bc81-6ccc-11e1-818a-a659f6cdec7a image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?s}u_e~ԾqOsY_z]{}u_e~Kd?%߿/=Zh.?>~2{@u?4^gc?]W_R=g:V? ߿|Ld{GO׿gyoGUWԾqOsYbէ|3+_8',^sGAuv>[c/~ؿi9; -1?K?׿_z]{}u_e~Kd?%߿/=Zh.?>~2{@u?4^gc?]W_R=g:V? #]&~{}uݽu׿uG=uǿq׺RC+xg^oΞ}{Ekӯq{޺_#Kބ޼tZꜽtx6"+0cqMeK;Bt1V|hzbzYinhOq=\_W|*=6~|ij:,Y*|cH<{ ϸ󒳼|?ӏ=kFDlZJ.ֿr FjM(\'jsuBO| s#Ro|_SwmeMuE Jݕw,o1E2.]UDXe$0 ob]wܭRHU֒s>Tou\j*m)]rWK+b"{!ݹAedq7CXs\+\L+e,'?L> uɎs SunގjTTPo޺X}Z Њw#\ͬNkvƼI<gY63FW`w?IGR#qn({"L6ގ-ZSp{oɾr3\nh!5)ZLk.״K*}2 ~,dvtw7 >cfo R,Yj.g 5~x۹ꡔWφQW5fʛͻ[_^70GV{5q0׊GUbNR)1S}EeV6)d*Aos PtIZ,b 4)Ǥ.7p|X]O8lWgisoU!cOJZ1Y?qXklT8+u5)㪘64Բ% T$T۫7j1ފ˹lIoUBk¤+)e2n\, .'vXF0?ըݷ^޿dg{_nbOmzJRW$_$U0tom{ok-psh_L1#, j+eh0/q*@&JyҔvO *wG 3.micl;V\vA QV! ;o[wÔ%[k:K|L_ c'u̜7&r.۳-Tg @Z#($@?g..߽;ۖ6M.Cxm?Oez3+B*̌551Ԓz=\o\'?6$k/n`֏XNQ)gϞ{W7ɋa̐[p־*ʅ,Hу  p|L4?7+Kj=nzw\Jד{jmʼgr9ZHE<f{ $^{y-ٵquy<*^B*WֽMݷ }c3191pF3Dn_'_r6+?.Rl~q`ZFZ(ފ |sѤkji&J Y^eΗFbWR" d* i%$itfo tm;O 6L=^wn枦H1RCΝc[~9;mX eH,%3#Du]5 |~B]^=ɺfߔMǿ^ž+"jڋKID%gl~{;^%R4报jjkP8O\"w՞WrQ42xE+F*~X|o=5 lnjrXܘe>#E,㪫JQYԧ\ g7/+{]]81-jޣ*pX wؔhAP( =QiPGӤQpcyR[)ZeĿ{OnOtQoZk^%l]Fc#G-UDP($>S4 m#(KOGT]kktnpS7Eb,I2?+.?Qhryu6xb(P3)a{o*Yr_z>9y{qʎ}eٝGK^ثlnFlU*,!X5TUr${}}oi%$,bh0-:9nx6{yf[u ė4Z/-ovO%[K ]Gɦogu^fT(+MBrF+5 ȉB7|ļWvn/d^vcTiZI{fw7ncAwwyb4$ +/%ٴK6%F?iu.xq +7_W(A$8V$Fo|}vBm eQSR|_+{eϴۨ$I(eIAUgBT+_勴{Ǎp{-3no-2CE*b9ћx1LBQ9R$b.H9fٹzۑjmv/(TW̓\r}zͽq{|[ZutVƀE(ƴA:O|Q[ىWp;urM-'UoTSeRdN2I2YFѯ'wc^eߣzw qw+[h H49?.ϻOw>qGj9w<[f [˵["LU.CcӳĔ[yTW=\C&'U]c3JUTY7&y] ݯ6;[Uy$U_ԨBxeutn`VﻀivU6KGFwF.^dJ PPuv>M3=]YpĂuW\OtURji*gWe1D5sۚn;;2$-lÀ"UQ@=s}/ܝJV[_"p$KokgUI(&I^=>g~>sw6l dcyӚSA-LkV"dIur=/fܛk-,xʲ R$UW%}~kj'ݬfkigx DQx'M;Xv=˨ZTBs6;]C"4{|T] F DqiR$&=J;rܹqF.#AE@j|"٭O´cNr_S7~䟟A?˯|Wyc&6u_Va2;z+4MG;֕m0RB I"(yλن6nw.#FIg4Oʧsv$yt4 3|W>&o ɻM{>?1YJ|WNm^%)r,<.:9֒+#5Erߓ}=4689M|ztgg<ǙZ<?@1>}<ɞΚ"isuT[Q4x f>5>Z\ wQIuy?2kq/Mf+Uz*&i)sP@?q߸O6|UʀөCMs_3W3n_Fx|P^]xČdd [klQ$fq1"IEJ^WMV[Nvt{mIu7/6 1ny"g)|CAzT}RT ~?c3xNu_U,;۶4C#vֆ2p}iܲ @'$`pM2}y֯d[O GO7ַ<2u hi-HkJf`k~JuϐU ڍM՘L-M XK[ }߃]ڟn[ }37k%C&;uU L[z?j9uϼqmšHN>=6l[ {;SRڕv㯍/N\D2 3嶁$b{{u۹?d,Uuemѵx0m?ZQ¨ԑ}Rmvӳn^&(+5D Q5Ҝ=8tY+#Qjk~XL|5[[nOYeGE2͕T韜=NUYvKIXBDXc4wOwm9p'B.e?JS]SݽfuzިX1w 81#~܅lr,r[iuZ~Qt0/d{;a^߇mu_km:}~FwDrTɎTU\Mk)Ovo9Oewъtуm sA҄)VI~=Wߤy{T==Ne/MKl T|#'d)d#̔{2>[v9GĴIy˛c6$WSAhbϣ/;,8v輼}]nmѴq5jvl: v4ΊU w~ܡm.fIЉ&)pJur}ʮ9Vk6(U5L1m,P5DQF ANK[qo]y ,Xw iǞj<ImcMm$ԗ\ x%+\t'=mpmv3G"b8 OˣÿW[ݫ{#v.I smi4YbTM+V:y/-O27g3r(tt&,rW(XW$H&?0=QWtߝ/SP:S+!@8Ɛ{,F5ѱXqƁ5P@0:M|/^᝙$k 'bvNo~?#Y&3rTÖѳfHWpfȥ-5-i *~bu${/1u}C܀Ȣ$iyj8V{+(78i.T5|t||Ãjudufɟ=-2[wFf/vUVMA7NȂa āDv?36qodWut *蠪m#Xmq9mRTՎZgtK̲n  @6}H{]U_?(A]?޶\/?*eſ ~漧ѓ.?.?GklT>L9l?>v-ٯ? X'xsD/j)NMl?gUіp@Q5MGABo&mUl߸72?o?>6|cUGoa@vngIemh8ifOlCwEFխk~v>ُ==LVmHJ_5kU? ĒtGk1v/9rb/5|L6ſ+)?3At:G*tk6*_w2?_5@m\.mu?>~5/'ω(_={T߇9r`潳ʠwfR=adgGا]9;ͳʠ OO3#^S߿MfeP}{F['ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ukui-control-center/plugins/messages-task/about/res/manufacturers/UNIKA.jpg0000644000175000017500000001027114201663716026001 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1$AQB 24%5v7aq#3DdtEu&f'X"brSce6VƇ8 !1AQaq23R"4t% ?G4 f,ZϊQ[$+k*V`cUXzO&:]n+Yp-[rպB&UZx[$%cZAfk[Gm=UBM 2KJbSFTdfťsN9 m-DH-Kqt<Wc@'=쿽?v^nY*~;Ry{jb/U@]a9 |zQX8ZPm|9QCg6 dݝJEavFqu`qx&NZiÏȍ244mbHGik}} Gu|ъPPL5hyew߶ڮa3rE&J N}fmj=5v{n `[G/(Du<} =KR5JQ4#?-YE7ҿaU ,_EM+>p𼛼1ݖ{|ީB`rڢW5!,w]p h.SjzWUaE>H)@?T k"@ i_*X`XkK{o\ÇnWV %z@cR٢{,^P=󹿒DO6G^˄[| mM۷~ua/Bzn j5:vp˚n2xl A 3g( MH[W王bJor̭KXU쎯7T$5"%M6yJÄ%'3exhM(hWp| 4%qAo.$mI@Tzx]k_{>؜vRR_1cH=H&z9Yepr:KAMCËs*;/x§qO:l {瘨ݻLiYi$j[ixc+ TҐ #xg7 |H5TzڶuI[hȓYsP9i|Ѿg?VfEQYEO_h<=΋[jǛ[xe|ީIrڢW5!,w]p hkOɄ@-e-YE<.0[J^hbt=xm{ xV-[qʺneAZ[fFT&o`+U[h9d{֎j fZoQKY~f^:TcE8D׷bHY\,ŞnƠ M2zDO("W{1;0ng;{o<of㞌y?\m&hWڣu3&5#ulKFѨr{Nڒǀ6ϋi))9)9 8LO(97p^+Κ]7i8]3 S#fO%&[2iv\ ]]Z^c(,r50ޯf QbJOw%v_PCau^ї)v 5cwӄfx.|~ %z@aX0iu-"a{jiV\ɜN]|XE?n@G_|6GWی9Za/l5Aڍc Dikewpñi)r#PWUpSn="eIR`bS&[T$'*Z[},?QxC&^>bc˪R7 %{r1w Ŗ]&ٻM&PWG% fmf ;,K-J6HFb7&ZBxlTGf aY%RPX&M!<EJs+kx>nËgZt/}#j^T7,w]p hfd:Qgwpod%{Ob 1ҫfbԊMgtR5EP3|BMH~" y_8J[ޒNwq%9 ari}C5`c>Ʃ'5׋$fz 3KĀzﱐ&DOb >mwz-~i#9<>^ %z@apXy{4ŋcy:]kfQ > pod=P{Ob 1ҫ5ТDZӒF~&5_%0㍢QHCKd % #À o/(>3bNJcJ3Q)*9cGsi[tV_7„EQ"Qp@|4USI9w\vx܏S 7]+'=]E% }< Sۉ:g 0,?%X䄷BUr.sqXx(.m*{)]K:E:1ƴLAP5R@C!aPX0iu-"E:>VH -tmUr:-=PZxSx9k*6:.~_e^nhrG!ŞlٷzGN}©t&c#\ZBhvŽ( u4f8h*ƭM>4b/6pC;G^jr5ݥP@>U4$k~&PS[Sg6TM{{1^F|o^8M֚kjqyj?\#AkoD5qk\ߛMz{`1I%vջizAEsV/:(qP@9zc4RCpEfvT_/4CZ)mjR(n"PrjS ҙvUM!f)**!p]pukui-control-center/plugins/messages-task/about/res/manufacturers/HASEE.jpg0000644000175000017500000000665414201663716025771 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF] 1 !qAQ"2Bar$4%5!1AqQaB2 ?&˓'t A7_hYp$pq"߈AVȀac+.PW~<~Q.ZMeɿMFM D/Aw,_8Fvr d@Au1`(+E??(c-&p2&#mb&M{ od\ /|;wU @m˰x"lܪ̽G]GU],Hjii>D`):Fqk6]4j3髟m5UZ)yZAYM>V%WZnGF[6*Dic4M5 9||ajtL ,V,͊Onve )ȧּovWMS\ˇeS|M(TxP#CQ ʬiܜPU\[.]6a Q_fK\uԉb~ܡ@j]*NZS0F&$S`sOoVqNRmoSw'I|F\oiڕz˪z~RA5U-J2d%',fpOgUG =y[C$8Ւ&7S ;M!%}U`P*Oy%L*f!sHbf=`DTzL;8-u῭LY&&NiUCiOGTP֗STLF&A㻩 MkWWuTm+fdQrI7eK˷ζ+uzܻBRK.r:a=Er}N7zrT2b,2VaY& ( UyC`RZƖI),7~V6Bq-ԕpssm\Tnq6_tM;W e4t۟*UUIk -Qrf}~<~PN\6N#V%*R BOVIpug7Gfѯ&q*lCƬPjИT-*u@،]z^-i =w,R}?HjGk?F#7vZuK,@e+%gjTWjb=PYfmvҖu]7,p1'^͒[?*JIpۂwO$L U3 O%?8Yy6u7&MZHau#+o^jW|u~UMiĿ*M9Xjzʚ@F*Jb1ZbUJeL|!|PB DEjNR%ǩ.`B*ժdө$9 9'E3f P8{/lK4oލO#;@96Mg5Wu:^RJ閏¹Z v}%]Qեk,ZA`(,ز+e =P\֗be5\n5kJ\meQQz:IMDÕ̓?,h8bmiݧtyqРm!K(hp{c=u2P5Ӹ6⒕rjK*Y@7k*PL$(a4e`!(*`M!}9yO#ETD)%^1}1iy,42fPG]>#.[H1&Գ~UeŽTP4sC^FZy1\h8ro~Dq& ]÷ .>Q\*Yr]l 6eb< OǏ6EIw 7@bwB X AD~.K(.]a,9.F2rz"e;\ 1;߄mQ| otBDpˁ%ga.B D[ XvDSv?ukui-control-center/plugins/messages-task/about/res/manufacturers/PLDS.jpg0000644000175000017500000004320714201663716025701 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:04:16 09:27:57]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO "㶺\տCٿ/:^K:*;UWǒ4g&)<}))hּIVpԯ#Wz%ճ$]_UtG!^-wJ\+e.(\79d8dž`^}u[Soq{rNOI^1)S4ȇ7 >]3&d x !4>r6? f[ZǨ WK2C >64%%ju_}goC~9Y#˂"fc)|bՏ=d %$\Zuj {k\/?3Ҳ]~λ٭Cտxv&$R^;檿s1k8`5?uϫCC÷];DOnW\ZeU=I#Q ٰa\xI[>iaɖqeLJn"Ŀ/0c[lsOk{?ȹ/>uJ%.k \%o7taj.z6UX 7N7tވݗdkykb+k0tL+EuGw 8 x//J92KgG1?*VSuzsgsSY_[Z_Q,hgܧ ybAكb"d|e/\/ǯ!$ Eo'}:?kTξ|SlpmSBv[.sdgn`aǒdhj׿ᶯofO ė\,?V/l;G¹?ZzLbT .it-*,Nf XvYp8Y5C֝:jy[,:WgW/WH.s;4{G<.j1>iJ<_zUJGˇ_S+jUkx THƹU]կk`z<ҏ4DPcA 6I(A(r3*\x> 8? UK)\GQn g]U5ps\ ܉OGtZnXL\4gyK@c)P=#[fb` fmJ<Ќq$ (B\{Kp@w-<ҏ4|VxW @ۣTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM8BIM%F &Vڰw8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]asint]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO "㶺\տCٿ/:^K:*;UWǒ4g&)<}))hּIVpԯ#Wz%ճ$]_UtG!^-wJ\+e.(\79d8dž`^}u[Soq{rNOI^1)S4ȇ7 >]3&d x !4>r6? f[ZǨ WK2C >64%%ju_}goC~9Y#˂"fc)|bՏ=d %$\Zuj {k\/?3Ҳ]~λ٭Cտxv&$R^;檿s1k8`5?uϫCC÷];DOnW\ZeU=I#Q ٰa\xI[>iaɖqeLJn"Ŀ/0c[lsOk{?ȹ/>uJ%.k \%o7taj.z6UX 7N7tވݗdkykb+k0tL+EuGw 8 x//J92KgG1?*VSuzsgsSY_[Z_Q,hgܧ ybAكb"d|e/\/ǯ!$ Eo'}:?kTξ|SlpmSBv[.sdgn`aǒdhj׿ᶯofO ė\,?V/l;G¹?ZzLbT .it-*,Nf XvYp8Y5C֝:jy[,:WgW/WH.s;4{G<.j1>iJ<_zUJGˇ_S+jUkx THƹU]կk`z<ҏ4DPcA 6I(A(r3*\x> 8? UK)\GQn g]U5ps\ ܉OGtZnXL\4gyK@c)P=#[fb` fmJ<Ќq$ (B\{Kp@w-<ҏ4|VxW @ۣTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-04-16T09:27:57+08:00 2012-04-16T09:27:57+08:00 2012-04-16T09:27:57+08:00 Adobe Photoshop CS Windows uuid:d94422aa-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:acba8ddb-875f-11e1-93bc-952fd8ae208c image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWZ3]1Kkd2EQRh2PG2$"dy+"dI}?ؘBUE#4\.ʲvh 1ٷi`-[U,*I[ks4}>7+O؞Ӯ#;l 'oỰ%7ʱS=TG'Qld]w~o~^ʱE+W>|,x$kF*A eai-om,x DYc9& Ŷk0E!< & WCOl`z!ßҿFjݭ_? ֿ_̝_/|O rGUk(=J);坞03/r@igv]k{IN@B+5 Ffzr/& @G\֘×/5U!X2;P|x=zopǧ¿.,uO66YLD;5(>ȧ|kAv|܁}G<;S9 gg? ֿ_̝'_/-wKwN2@즟1v O5ܔ'/4Aq_NB׊/v9<lxAQɚW#o'y%Lu2DvdN[|YeKv^|Ig1FOCbYM7co՜$y"˿iчOu//\}ﭼ=.ʶKo/ϡRq8oq@}4+1/tNJ3ԑJ^L p}|忮Y'-KK4H:A%c^J?Lާ.;TC=Y|戭c7TdC.M#F'7qVG<_? ֿ_̝_/*"?iJ♤D=Z& >_h0Hyg?ϒt{uaAʚeW4W.4JF "#( 6;1\>r4ZLc5t-O;}.h<&#9>jơs{W0ƼyNaha$D7W<ɗ{h't>wfQԦEִO_@iJ MV\DoH?4kPJFH(Se?d3Uݡ#>$5_cK͞]EΏI ڽLtgSr=ݳ.ˋ!yS<_kfFydW_EnN{3wx̏sLؼ»R%խռ`JKn8c" le!GOa_(iq^XP2 吩H (@)c.P:갈u+8nef@WY,n$ů&LT+.o%eR iJLә"x!Q!.P%Z-O# pyN1dihpb1MerVUWQMI jrQP≱iP$݋WL(O]m8uq8ٴxlO+B,!kFo2dws]qWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/DTK.jpg0000644000175000017500000001222414201663716025554 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!AQq 2B$3%aRbr#S4DTU&H !1AQaqB$"2R4%tFbr#3DTE ?>LWy3@G0>Sd1&c:bL:!)sNhbf_;}Hϴ FH@O.IC$yr@Z$O j.ɔNP < #LId)N1؝1&~Ĺ4 O3/G$H#$Cj` v$e !<P{ G'rݵUT⏊SOR)":M 5J5a ?;/,;rsZmM+~ӛtIl+@/Je.@&To{]kQ%Vkk1hJbJI=RӖИe0:U rwp ]#6AZ;vJLOaSV-tvBfW.RP@vrD% f0ϖ5%JKO)?#;U̚%1fS Ee+qEi4AV1 \f멑6UI,42T$` #|yJՓzĢ%R=N@0F,厛Lέ,3:A9fJ&d1- e&8T;K&tÚ9ulAN[@gT:vݓ7Fm1*nN{SWG#ݩ0MKx2A}e_ #M(w"wS!QԔE2FDHAH/o]˕_=ćŽ3ʼnҭoH&0<46߫u67^QwjTY/xMsW{nʬ ߟl(Ǒ8~Cwf))d\}Aջ0{SVB84:W?6ͱdˢ1NF{;-myDf˨M1 Gr]fWo@CGJ (u,xՔ 6Té0"]+:֏@<5;Wpwwڻ{q72ZKnp7_F.sfQe)p$ktAV+{vCpՎDa8uA,f^zsԵo3;KptS-{rXy++hq3(w7P vUG䛃AXuv5qN<ޮȌE{sa[Ni.-܊i>psMUšʱ*U8rqd⊽ZZVgi(YFCaчԻf$L} "2G dD{}жZms7`Ԗȭ_em)iη ݩBg&"L=1^X\t߭< sr;1.OgX=DR`$i5rݮ]mɬb叶&L"D`Lq%,%&Eh !U;Ӫp's H5A]7Ѳr[tZի74Qԋ@텩I0K 0^9۶`Ůlpy :r U]!֟ޖf u*m $Y?67qDo=PjSn̺ &O)x;G1q兹ۖMG;e f154{=v2Ֆ9}o"½bE(ErZ—E)sln;96T2 9 I#ߚܼjI,%ќ4O`o@p#U'TdkGymR\rà|]aCy5i)2#݊[RV_E|ܤQe2uoHx\ᦆ,D D:b=^n&:\Q)>gLmJtXFb"L#8VdV'=I)t] Uuf^;O&"$1.sVzhǁp0&:8e ém fKt뎚f$#jJ )U1)jE3(yf4i&m11O^Ϫ}ygy`C6wQi,i2Se2LP5Li&L4& uFۭ2ԚH|ItmZ:ZHYg,` kIRjW GϿ {!>={/.@|A_Ng=.?7}29)[P>Xy=6̸LGk=,k-3g-(M^u|MJuIjcQ}Rg^Vj6 Jn܋SnD'RfJM֬^?ޕ tP#g^S/.fTC5ZgDS Accu~^3h2 Ff!)k]v Ƽi^_o8-j Sg̛Ǖ%9'(x_@۶`F0Po|ʳT+?snm|+;J۶)!ҿ6r)ʹ)%L .>zThK(^\S\ ^W?L[h~J,P\8 vW?{–V`Tܟ>6Xmmo:XƅxJ6Qu%%C%M3'Ө268D9kO&2KGKFR4)ИXiH50Bi$L T錰%y*OVBeeW' |26'3MNJL!QK0fc }J1UI-*l;\G($0YT0;1<pJY`ߩW@SVY1XǺ% )rBQ%_ j.ɔOP < #LId)N1؝1&~Ĺ4 O3/G$H#$Cj` v$e !<P{ G'rd'(LP&$ϲ'LI@N?Ndb\Ӛؙd#$ys!0;S˒`2\=#։Bڋukui-control-center/plugins/messages-task/about/res/manufacturers/TSSTCORP.jpg0000644000175000017500000004217014201663716026416 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:01:05 13:20:46]F&(.pHHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOU_;?㜬T^A:09羹tq(c\a mܟ"SG'r YM<eM/deMy~N=[.,|vܶq>{*67¿vQ\+ 2/mc3uN̬M69 nX}?yY?ns602bj )u=vG卽N+\\Ƶ#Wk V׼r?S^|No{[~y/uDгU[NWzѾu.+ u#tHř^g,i??4g\7ƏEsxɷ qcLZaJ1KH̟"?Pr՟?̳IoSS|G+:wԾ1 ln-ŏ./ Ӷ3gdm8LX8F2'Ե$T ܖaߒMnyG\׼߳t ?)W?jv8N1Q#@ϜUoPϮlʴ{ߕ{Ǩzd&6ԯ'9s8wH]8GҊ7 DbH݇WD5X Ov֮oOQvɏ6+z>ԺUlǶ,րf 镽-{-ecN\De _#?A^˺,nv;coEIu.<X.N#EaKۙQJ5zq䇢)c|Q:G\ԻLp<)ƪ̫@?T}Q-SO;z&z-"YZG_^DbY*30[VګelѬhkGIg6UuMǮia|lվt'(HJ:^[ҩkX3?Uwi)~xV[dn *3VS0zVF9L˰nvkYѤ쑎` Vwæf~CLMos޻{*67¿vQ\+ 2/mc3uN̬M69 nX}?yY?ns602bj )u=vG卽N+\\Ƶ#Wk V׼r?S^|No{[~y/uDгU[NWzѾu.+ u#tHř^g,i??4g\7ƏEsxɷ qcLZaJ1KH̟"?Pr՟?̳IoSS|G+:wԾ1 ln-ŏ./ Ӷ3gdm8LX8F2'Ե$T ܖaߒMnyG\׼߳t ?)W?jv8N1Q#@ϜUoPϮlʴ{ߕ{Ǩzd&6ԯ'9s8wH]8GҊ7 DbH݇WD5X Ov֮oOQvɏ6+z>ԺUlǶ,րf 镽-{-ecN\De _#?A^˺,nv;coEIu.<X.N#EaKۙQJ5zq䇢)c|Q:G\ԻLp<)ƪ̫@?T}Q-SO;z&z-"YZG_^DbY*30[VګelѬhkGIg6UuMǮia|lվt'(HJ:^[ҩkX3?Uwi)~xV[dn *3VS0zVF9L˰nvkYѤ쑎` Vwæf~CLMos޻ 1 93 70 1 72/1 72/1 2 2012-01-05T13:20:46+08:00 2012-01-05T13:20:46+08:00 2012-01-05T13:20:46+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:fbac8e27-375c-11e1-96b9-84cebc0057bb image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWN*5#BӟQծlҰfQD ۟l)LE2ƿs~Z?MS̏fow9,$iA7Ofoܿ{!|7NQ/⵳C$pÐ&ǖQ 3,,\ߖ{OqTfow^ו<4KuNrU&"ʲ駏#.E~j~^-ms."LDrqe'<T7oOy/fo܏C-?& hs~YSSqTo_CGC~uǟ*Sߦb𛮭N*_+yE,{$/ckg3C(>mԴ7P.m$hgܔ:,a! ȣLH}ťsQΉw4UxR~bO]}?6c~`׵/3k{pyGi4Hb&ĵUE?Y rd* 5$nbi&b)nc׼幦Hﵶ[15\O)G!=ƔݜnʟN*ֵ(QI1'Ê@wF>m.uv5;Fܙβr?#}}iOe?<)j| OZLtߣGّEoG_Y1WWz_3[c^zzm S~g N;?.|iSCìWj?k)Pxeɞ|k:Ⱦ&yf *8[#f> Ca叝GɲbioѿJsQy۲=:\mMZRTn|_,!}moV E ,h<E3&ͻp)S_N*}gVj~IqN?aٸ\}L>~]6M_VId萨v2*1_˖nXlϟKt.Z[c?Fc5O&Kؘo*M"H#D?i_,yGȨhw|-'>kմVS8EiTq,p吔2k94O V0߈P dp?2 'qlbPѿHZŦB,{s#ӏrpNUis>q;N*3--M,m섇hLJ|UvV0\Mf+?=j/Eoo/ؿ=j=O0' \mH4q߷/<مΑWQtD _ROO,P*>)SF9B}S_W2~Ư=Oj$mQkz?w#˕eYQ,Aas-55\%\UQN/UUZqc583a,?,B[,F.)~zԵpk55mKov*N*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/APACER.jpg0000644000175000017500000001103214201663716026061 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1q!AQ2B "3% !1AQ"Baq2$Rr3c ?ɵl!Ls ߥIE e.Ou|)==K^$ߨR RTe 6\`wReOʦ-&yP*HSA7RlH&K)A AwOe)GDA׺2w$TrH (2W.ԣSoI^T 7R0;qsg?cyYtRq,ǯWܷpb[-kl)))7J~{ݼMQ霓3Kq Fe`zto I~P\ Qa@Rꌹ$+`QLT7eگ*t DW(+G%ΤYюY,]:8;9>) x չsɳêagl^&P5ʌMW0D{n ̎ pso59'jO {yj Kѭ2dnG1 m e˨kd던Jeg.eϐ447({H/y/a^HrcWĚ-(&I)SL cfrl(|bf2+[t0>+\}ⶮ)\.BXmm,}(`DL]̼pna\RK]`ZyZ=?<3=*"jRM}xaQõx_B:n*Ԟv$kA甝cBq׷&82 z?pO~4 ;Su[WHg)QZ?(2MQnnhDcR|+3VfF1"pqH2g Ο|ؿ(>Cq-LGvbw &v—ɂO&DH/i[y2ďq"z-w=Y__^ f:DG9DNb`@ɾrX0V?5/ӆW'`U"9Xw95nyIb(RgZv ]Of)Rkyq JILG38Zfi dF.Jƶ7;5nj :B7YT]$ZPPDڈAFs(ÏH}5/*j#f$ˑk[.Ո|SoI^T 7R0MT$WY8iǶ<пl6\i3SlZ'4e~z`Ƶ}_Uϔ򠏴}>8:Uc7MQtI扏{?1vb9wukna1d@.(!L?Ŀܤk^J|Ep7?.FhGAߜeyzŢ3\G8!lJD:WS827 cS@>޽o洂jl%R%uCer)FIK2TPd];G2STEjro)a 6Hqo I~P\ Qa@Rꌹ$+`QLT7ukui-control-center/plugins/messages-task/about/res/manufacturers/ADATA.jpg0000644000175000017500000001162114201663716025744 0ustar fengfengJFIFHH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]"4 !1A"QaB2q#$br-!1AQ"aq2 ?Uɐ1||cj+K\Um+:GkGcu{RCmHZlJ׽$~Ҥ~* ލ{Z2HϳBqZ$Fș{%_F88HVcOV4> JR)J"R%)J"=dXf!):|%K&.mQJhΤ{NF~܃b-3%_PQVo3lW=y pضD?w '+h"4%@ޔ7Ҹt54ݮt8%JHi($#ۡs!qk.c-Pq >j#Mm,EH B${4?:N&*_, $k<}+_vwo F"x-'Y- ΰB>mSg[)"Nhlo;tjZ¡ŞLKWd(-m%'y$${j2- J`F&[L>i~)UJR(Q/2 DZ']@b*}"3'$ kInRbws ]3kQ/?!VJxܑmrVǞ) O]Ugq*Y 2PPUO_) G_f8:%->J: }ݳ{ 2IA,;m[Hf"٢k+.p͊ol8MےE)ށI5s)exbD6W@Cjh ucq͵\vf*wҪN!nwɟ_n\Syiu2$c6;bR^a|,r/ dcL]GIGϦ AdobedF]      1 !AQq"2B a#3$%RrS4Dt5' !1AQaq"B23$Rb#4D ?<5.8'HEN# ~~Ax٥(/PܙN^=&K0܈ 42ژZ5yP*rq1" ǻR+D4"'A^!iJ8"K7&SxiEɆ(7"H%{Rd2Ɛ) s:oG Ύʒ" `ݣ;/ͱ@י~YU|=kO}{w{]3{.\fTM :Yl@"m (Ю^CM[PCmȌs NJ+/ v.W wL.÷.!҈pjdovJM.ns',Y) dJydmH ( MqvmWK@og_} '}ko!ԑ7OK܉JZ-fRP63L~i:Stf!|oŪz/9OR23[Ê֝:逷m%(藨]&JJn!nT_Z>j:"}:#Zz C$da?LXxK ^+"fɛ3q;ۈɕ$}!ƗhD=E 5٭}wR0< }%hz] e)#5?%+榅,44e+Vాry+lXMlF]=s͠xp<5i5zJqb ,7q+c?B:/X<WƷc.-\ цӑwܥlELy2yj`eJ |5"fb:8AYc2,z<̭g;c}޺.x@mMd׸ p1Gnr~NR&I/4n u3u02$$ d-|ɄCvq!1NtsF2Hej U(X(!,&Q^x\xj!{e]ߥVaO7."VY$jR5XVRtN^P\!(ˤvJTUGZVUbTGCa7on {W/rr'/ڍj/I:Ag_.8HglUL`58ӎ)^\V|$4jʀ ݉Ugg]ZԴmM7 |f6d}a馭2oNnZ2Oin=[$roXl^5ؔw'$sT P06vtGuPɁA{8Imc)uS)lZnrv[FR6qn-ثo mu<%5 R:U;Lh0nuPְ<ڂh1Xm ]9鴇4d愐Yy$[v^zƉU͈+na˷wmg'~S =O}f A 7W' ?z?twu,z3>V/O3 mڠj$վ aQrDgBbwb$6B:_~煕kؾj&6mE \h'$$+oknEMt/$\&[E`\7c$~ވ e͇p(஥#IoLhR~G|5lrfz3.2a Yq'퍞m#pW&t%DJJ'~̀D,nLpbzBt7[LD7y[`|mQj)V*+W偕iS/gojTԡF6gc;x.zF?HI3җ=cRng^R^YFǗy$c'Ց5|EL̫ %X{֫PR-+#;&"Z{- ]}+-=Wtp&J oUխR`0P!p$5B^ەSp>]G-f,m|MbrJao-cvWF*#@/+XW1~`YxN)?OݩoIW'HS {"A8K(q{QOf$;Cre9x\b .(r9v۳ݠA7/٠;R~S V*NN?V7A8jEr(qQh# >)GI0wr (0\Q@pP\/٥锟7ukui-control-center/plugins/messages-task/about/res/manufacturers/CANON.jpg0000644000175000017500000004665414201663716026006 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2011:12:02 10:27:22]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOT$RJ㳿uvX qvDN1̓˜7.R'֔%׺~>3qm;{G=;S`>1lnG} TO/ID(8Ŵr&.evـcgzFeU0LnG5v)^.n|U..tY`UۙSr-!Ż^9yؘmkm;XKv۹V;qd7 z̈́WR/nKm}MvYE@`5lN0+uk.!Sn\Q(ˊ1'E%O_~ϧ.2Low7-bX(kEq_g?lȳ}cK<{?Ř9OH/ErOMf t[nY!#(:tyk0f岓zrqp]Υqzɲ0Ǹ}V>YN0)ʴ @ß[/GꢱVU"u͗9TbZ C@uBA~LHwۊG>OsDچC?W㾲?`Uik&dUsu k[}Zݸs%u?uJknue\%jng/u06pjZ֒2:! ӔXDx WZ袎kmac9L#u0jN5ƞv45ڱt][N?Sͣ1OXkZ>}Qms6k jcOډ?Q$3qm;{G=;S`>1lnG} TO/ID(8Ŵr&.evـcgzFeU0LnG5v)^.n|U..tY`UۙSr-!Ż^9yؘmkm;XKv۹V;qd7 z̈́WR/nKm}MvYE@`5lN0+uk.!Sn\Q(ˊ1'E%O_~ϧ.2Low7-bX(kEq_g?lȳ}cK<{?Ř9OH/ErOMf t[nY!#(:tyk0f岓zrqp]Υqzɲ0Ǹ}V>YN0)ʴ @ß[/GꢱVU"u͗9TbZ C@uBA~LHwۊG>OsDچC?W㾲?`Uik&dUsu k[}Zݸs%u?uJknue\%jng/u06pjZ֒2:! ӔXDx WZ袎kmac9L#u0jN5ƞv45ڱt][N?Sͣ1OXkZ>}Qms6k jcOډ?Q$ 1 93 70 1 72/1 72/1 2 2011-12-02T10:27:22+08:00 2011-12-02T10:27:22+08:00 2011-12-02T10:27:22+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:08e90667-1c8d-11e1-ae7e-db667b27342f image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ƪx)i) TigFX@` Ycg*K14I$v?~|v+{h7Vs)W;9M#NU3:>>z+>w|m/5[F tkط<9z ciTmS13]Bgyfۦn[(Se}j>ZƗoE 8/{qg;\{!Mo6{ZȷӼh^Eh|v~잒"dxzwx`aXTT/JrfL^CUUA1Wx]OE5bSε8 "c1{[ܱ{+ݷ:\d6B*cԫP{cInQpC%EZm\~6oo iiy$LU]c$jYQe7zvy[%S +I= y׷ܦ~vtECj ) H n#@>{7{D޻C+d3V!=GɵJ~'tj~nr7rv[bm7MbHFEXBҔ|(̯; ckەMf2Y",ƙzr >O})S]XI#2t..%h !^Ng%NGtm]O2n{oz)*%ߌn h*hY($,hc769e\Q°*GBq}kh۟pyo?m5@`#y݊VBM@zOU0/ي'UP<-'᫷5Ng^8ώHFǏm75I h5sXv 2܉wZcICDɧ,D ̱ѯ`:ϴ>||7G~}αVț7&*e%VGA)$y4.A_%lHZ ~i= b֙ 0IjӦǽC]ϑ(73F#GxYD@Y!sQѼP_ܗa;r|_Z#;D8(S.Is4+W_㪆8I^@ 0Üܱc_6Jq>ej>}Nv[\>_il֦BЧ'z*Lcb @:7GϜ&𖆛u^-TJK6G [-c+ڰŨSٯ5i6ʒ>mA%JBc!wRp>]nS7VMFn/{nHX MDnLVK5>9ZGueB6 Zú+IeDv /q/x9E m`cYVњ QUB>3-ן˿ޔK;N ^Y0[[em*T/U CNuDy-a I՞U `YcnyeOk)dagIg/",2/|H?#;#zcP&u=avrn 28:hֶɬI(q9GlӶo0[]R9)V2c`UHks/|_Yݢ_GM$1VYUW$"?U 2n.3:;1r Pr8x-W%ZVX5ym[pn-bEI U`A4hx̟x>cڷUfxPyיvHѭ 4~|z>{q70O#JF+$:@F.P>݁Sn_cW3'՝1xɚ!nꊪy$I!anشkibA"@bbI Neln`9r6y$7<11tGl,I>lm-7U|}W~1[ok𝏶j_CͦbzGWFarfa>){P?BȇY~@:'xؽ^mț>e3?yilV9Ic:H!:b{?eUwƺz1f oTd!CMO:ؽ@1g$M[[eF-[pP( j\L>7\w\Wrol+RY+pPwwFml&'mG}O`q>.fR3caϺZ$0FEQ@?M׹rw57&ۙ%I$"]ܖc@XSsG'ٔ2 E"#ߺ =Pɏ˶{Eà~OE=nՇv,X|}~I^^iN>:rtBhzg;y-uCԣ rt|G#o' NZÕ>{U6a@.P%|hw;P]dӎhݟ&xRC MQ+S.<HV$ /ݹk)B4z4 gN?)^F׶w]f %I/ ,QfZb@#t_~[(>;<2-  p-lު(NImwv,o FE RqRwەyחl7).vIݖkXI ŌNF$P[#m7g||=ݛ{  i}~WI_%17h?%jxNM]f*)B<0STx}7_f齾d۹>ͪ9n4%Ƶcy-܆K/b**F$?n1/lc(j~1,^;nxba-uK1Uw(U"gV0nlm]z5JK}osf$\ռRCHʥ]YIVR*>V$޼W}MY[K# v pnZLeMeluiҢf߽߷+ ]X@AA$Ϣh~"#X{}aymn7o,#ɡUTXM yӡg(`Mg::-IG_.[ E;VcZ鱕G:U/vB/AWtR2)P#@O+/ܿgaorԍ#\3 W^[yT:HY$%CwtE_}[w=CY4[i(䫒}[\~?ީUVLiȐ*$}{Em""rbRh AdobedF]   1!qAQ"2B a#r3$T5V9!1AQaq"B2Rbr$53S4U678 ?Ǔ*F8ɟ 𨫠 RLyAa:y)L!%uCt4\ Qt0MЀʤAt\`wR)TUbHaLTUa{)p&}< 0<Ǻ.\(c \`@eR .\;G xc ZLP1rg0&|**0f=A>j~AsJSI}P .|B] 1.0St 2].Aԣ놊|<}U1G}lt!N5rDS1t3<-9ح:I[T[!N޷s=U-ȷ*RѶRe?x/-JeH`o3+g&RFOp1ޝh{Ii&Hx2?P3?ɄW;z&ʉgh*=VnR`@::㶼y/[h鵪<-*jM~) )(lcV.߶FmC!f {=U;?(Ei7eƌ4y[R~`['[}+jp g!-IRIIGi\%(2(܈BLB \@1ʱNj,>UARIEKE'q?ۛkKdTRKG rJHPL u'oUo=J=N%/R[h.==N )N& #ml/-}'}mt0SFӫ]3NSA[luHo ݗ^wqGGOѦ1FL-|#aXF"\@Dk[8;R_0Q/jn.GnGr+ O1 [2Ip'Q@["*0%8znR;{StO6x%נ3IxfK>F\D>2!1CVrvݽ;sHV>e9FcRvbsS^# D%w`H@̀a>c~`KZSY۰9SckFVsՍU*29LC t9:hŗ@M3#U25ݩfJЄEgLf  Me8 :HԽ0]Far]. iݬ~3Dd!W[)hFGզyE"m?vg+tl6.+܎M%ҋ(Bd${RB{bqM|ۗV[w>5?.Gv<$OV\!G^50`ZDY" c P|T&`}z]vѤ>{r4M]͋gkHW& ~TJ6bn4@RL[GzD9mrN1"kPUu(1E2Vf1@>2v >lyArV_Msh켙lqY'Ѣz7 GNѝ6BQa#i\x#)ZD:2N¶)5li D[da<%Vxu#xpR̪S)ӐIr'1ylI 𖜦6ŻQ[h{?&6W;* ߴ 5\ub!R$Qvr4!dDAH%q{틳Րf D7=VFwg6ȮaհfC̼t5#(lRLHX@ȉ>m%$kyO"ziˆ}Iߙ>-J @Tt6<27kee]=[j'"IP[9nA]jfIv\^ةq pFr4mf֮-XqLݻ|@5˥shI=D3z yFiTZ1@ 1XikJt l0}#zt9:Ɠ[[UD9iTZ=gDhݛ@~Ǝ4@(XjqL[*/P؅*f:t(4&͖ɳ&l%M::iBvdXL󉥚b9/x/{c%toeHwⴶPCqSE7*C _Tdp b~\z𪙕,ca ꘏5H>/q4vfu*]q"Q]*F1̶&Ȧ:)jKw} ^}1>mդʯE&~C og¢&cKA300p= r)E@R7B*rJ>hSodjeW?E!7A3QWA1 P tR8BKhsa )qHr\4Sꩌ75i2@ɟ 𨫠 RLyAa:y)L!%uCt4\ Qt0MЀʤAt\`wR)Tukui-control-center/plugins/messages-task/about/res/manufacturers/BIOSTAR.jpg0000644000175000017500000001014714201663716026237 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1! AQq2B"$aRr341!AQaq"B2$#& ?NI_OfJAuOV$I~`h\ H@bsN4H 0 Q\>ީS`WŤ@_UkA5v'$ ? S$0q`4T]x$QP 19$(] HTfbiUɯ*BA5TM iلҐ]CՉ)_80*W.C(fӍLW.$wTx3U㫻\}zFfd \"dMRŪUӢ2zF9a)@Gstg2Z:vv3ՔcR,+m^gF<\IU4"qFjDȬ ;s&]MR*!D@8.;FpDn`d ݖ'/mz<ӥHZ 9ьDDtK"WDl(IhGjVJsR6G {#T!r涭ץJ7:z`F^ g؈0(ww͟E.˜Z ' T?0` R`^XNC!G>LUYJԒ.UU"cfHĒ)lz_%GY~>) U2!wsD r%zL0H1T4\EiS) S{C1.0 +VW7L:AjuGnˎL)kQL*PN3gRP({ WⓛmS'5j?:jiKPL8@ب}w4w> 񮛫^?鿟q'/nXOu7LCV׃3Ac/eӺ[:kb %՛>(XN(FFR$.}kGRoim(*aNыn[_GocpwZ;V׶qi]71sZuW ~,>M[Mdnd)[niZWHKu,gݑ29%d1BX@L[ǤqA|ݧ?,Z 6 Uf^ {-wdwE-cYHP0(;$J>LW `.j 37o=k.O19c<4z`d^6F^8-΀Ʀ'G}5M_Qb\EJH!.VX}nެ͎H0=/1!8uciJ:r:Ehf†ω|F]6e)KY:KDcPJ|^}ێ| a|{OU5ί1ߺN큫tlVVhmL2ܺN*#,[lKDJw59wAKAAh.6X[R+{{r^uμ̛k+.qnteqq.$h,]_2/*?-E;lSjIP+ycËӲVbmE*ـ{{3ϔ0D ^n=o;BZē% zZySD lhw<յm҇I# 2_V'>`pYLGRݱJM73k-{ jK:ZfnVJ۳>dM]GtP \rep`V,n\Ԛ. * 4E:5i׍a TN0Mn >Lkq⋂]:mdշIJ](1! ]})c+*;sV3 Q A<a1 Lw]CIp/ KnwZӲk@gkX$iIfǴ++RbLlLI0] hyjݷڦ{"#Y MX]^)Q{R%p(PřV/)#62~OxOne_8lLr *F *&MG݉4kOH.ĔI/~ +^!T3H NiƉ +@;*}<lXcyhrkb PMx`H&A5a'PbJy$? ˯Ċ*'4Dˠ{>? x,ZM1 51QH&0JQbrM {0R zz% AdobedF]  1 !AQq2Ba"$ђ#4Td 1!AQBa"$q2Tt%5E ?M5̹75 4 hCMb H~==<oCE˿hjTY NcBm\>ZQOљ^F&0rojNhA7T SOv" z{5,y /ߖ"~ԩLHv|+Ģ2ZM`22Ђo٢ A7!&!DpjX_-E.R)f 59 rjWE?OoFey;=_Msj@s,P7_[$h(+zcAOJ6SDC79,@@ BXv c!v)r3= ўZ^U_} xmZƗ[8,,bJ#1=F)aiRR Gsŀ~]h68J–[6$i!~aW"""NgLeTa5iE@n=+\SV$eT͇)X9 qËZW9e"2SKS,XUfUSHf>auL}=w5䲛y$R"}A =&*U _͔[!=tjad}*\-{3OrF"uLW:W i@E1ERszpb(]Yק_V8M5?3QlIlĞwwZX^܊$dRUF&r•BnNs&'0|\Vxc!{':Mnګ=h_8URֈAEA`ѕz#*4;ƟX<ɲ4+"@nN{m]qJw-enKd~gܟy&E7kZbU|w䜏hk`3+95a VlhY nyC.)W Njr:VRt D1|hߘ\J,E) oZpcucZtBݴ5o75DĮeSQ3:"f6JRϹEmRx܊Ψ &4ly{Uvk4u;gǺI2TbAQWPB!Xv=†(Lo[*(B D3^VN@dlm RTGMm_uoHt;:icjd3X4IbY"LGB+}LN CxHPk볕}7rnkG) *rb6Q\aglIqtz(d- UP2gC'[$Zaj׫K_fI+>$G6cƴw8ҽ*6@Tic1~YWKgEU9aU=j?̬ʨUZw.U,QJ 3 ݚںx=I3{N| _aqT֫I1I᎖,>@ 6L.Ki{;tߌ̱s_`I`-JԌ>R[=%ݴF2G(swQX$"J:z4F9 dEXW5D1%S8b&_agj7Z>A Ց0"V QQk5Y^F&0rojNhA7T SOv" z{5,y0)/ÉF#z͋>2eaX J+jCKhi)LHv|+Ģ2ZM`22Ђo٢ A7!&!DpjX_-E.R)f 59 rjWE?OoFeyk8eɿe9߳ERn? NCM=C.Ա$;~Z.]CRR@js2h">ԯ~ߦ?ukui-control-center/plugins/messages-task/about/res/manufacturers/SEAGATE.jpg0000644000175000017500000001040114201663716026176 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1!AQqTa2BS$D%5 "#4&R3Cu61!AQaB$"24qbDdtT%Ee ?eY*⟳o5!L^m')DY|)DYPhxqR6"m根2~ݼJZ [T@lv<ԣ2sZElSm)"ͼD(6(6xQ*RM9|&O۷)C QKj\ 9?nuN|_rSv(͕ ~ͼԅ1xDYfRإfB"ݡJT؉/'C$ feY3f)L巳g lEhJbxpr*rrϣiTpܣ ɧ/Jy^3]*s3 [.!+E`wVy;lGFX ^s7x=] ӄ5eGznK2,f5c 9Lp0 $EG 6\ݮT8NK49#S\ÖQv $9P )WD$H̚\ljz1ΖAKSYubV|5IoAѸ˓s/ؘ͚.LK]k&J(ɵ&׺9 )k-+|qKI8zL&^{6U)6RfJ"rEGKbE|N5K>v? ?0N,ueQΦRܚǷ1Srs\9D[ एTJUK8A]%a#|ϓ ܪwOs!za&3jq^lfӵI%K:[^: s;xm3yNDjFύ>6 >ҍݨ.Fv~mtٙ VYCa%R‘jhY P=9Dvxһo/ ֽ( gC͸6yDZлV ǫdcqL4ߞy\r1fPgzDP$p-c @ƴV[_HzɚMcP>d-U„PE9j;JUdi N04\J#*bi`n`"Ѷ oiu/ nDeW;WLAHdzQԅpgbZ L& ;TTϴ X2zπJT,,[[sAM#`I 3?N+(iMTNxx. e\ʯA9sg DFeOH5#GBI,QB!@~)&W҄;r/͑J9|Gi9ؾҦNh""#%Ɨ./>AFMC,F򼐫5좻sԒvJ9MQ[H:9o2841~hV^ S_P)b7%qǔ,ET2%E4@;a4T' nAS=`֭vyxtԬY @j]X(ngCpq̮w I80JmmF`tw,q?cru>N)!{,yM%sڕ+Ҋy5VOGi_Thpr1rEcl: ╻ 4k5ڿG:2! =18,9 q^k`m5(K¡k觾xom={]w꾟KCCM[/Wz郛iSb]30! z_J&CE PaCmߌJ2\c$pDIxߊ&a/;:CWpN7$!]SM\>%[Ilx<5I[Opp/eogiw// y /%yY೼0q6 Ѣ}SɑUg_)kx. sx.;9ٿ> wwc/3y߻%&fV0qF(o }a7ߠ3f>uF( .{}Q~1\Q^oM{0Pz]G}I~4%TLaCB]OԏNn4.uzC M*Wy bo%9J"ͣ䥱J";*=ECÊo_5ɓ P@Rڦ"eO۰<i'ܢ݋ukui-control-center/plugins/messages-task/about/res/manufacturers/ATHEROS.jpg0000644000175000017500000001152114201663716026236 0ustar fengfengJFIFHH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]"1!1AS"2QaBR,!1AQa2q"BR ?.!A!A!A*mnOx22I㯍b;Ud\u&^G$Ƈd;!p۔[,N6%[=;vAKg\=Q1s>/ׂ3׷lG6ٌxm&ȃ:egp簺hFvX!)$Yr5>-tG0FQ*.fN#FÀ+.nTTvH#XZ"xO74!",(ha.qtruG_Su5֓#*ZZVÊ8HZ u'$#MX~lj~2VE \_Xw.%J4Rp 1jRCDu'^Z)u9..3IP.ݵnSPXLM_mƂ |q|#vZMԺ«uT*+KL[ͩaH8 eEtYm6 aIBV|0.it'"af;?ͅ{28;7BnQ]gPRx@F;f3gWr\6Kl9'gV:!a^ս[>J6:|=:|=Jk/OOP(>O>O%B?@{t?@{"abT /Of%c<$!"B$!"B$!"B/ukui-control-center/plugins/messages-task/about/res/manufacturers/APPLE.jpg0000644000175000017500000004125014201663716025774 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2011:12:02 10:24:49]F&(.]HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI%_6*sq?kI)z>s4}@lYlb7J~vr^0@0 r ,&[\ˉ:]  emIIe:hNI$TI%)d/d J_HjclɹߣǯDMU7~FV:WLms\mrǟoJtG>[]{}?"qK_ӕKKE;2z 3%8uuKΗq~kCCZXΝ{4֬ǃnZ [u1INLMϨ{b,i{%3lbk97ټ5cEI$TI%8Y?u`<]g4f]"uñ$vEqԆ%;.kyp Bޟ#T%7mϟ>XR͆A70%U#C{Aӳ[tۙݯeIJRI$TI%"ɨ]K<<gPH#V|BJT mLS ci)JD-*cC!:7Pm>kd)ڊM|#;Qs,w'ߤcyc|ԔJ9.$-G>uw>8%WRI$Tʩ$ ^#gy_,*ntg6^ѷkEk\AWI$輺@H._Dm[0A֛I$%I)%I) HPhotoshop 3.08BIM%8BIMHH8BIM&?8BIM x8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]g*h-7]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM y]FL]JFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI%_6*sq?kI)z>s4}@lYlb7J~vr^0@0 r ,&[\ˉ:]  emIIe:hNI$TI%)d/d J_HjclɹߣǯDMU7~FV:WLms\mrǟoJtG>[]{}?"qK_ӕKKE;2z 3%8uuKΗq~kCCZXΝ{4֬ǃnZ [u1INLMϨ{b,i{%3lbk97ټ5cEI$TI%8Y?u`<]g4f]"uñ$vEqԆ%;.kyp Bޟ#T%7mϟ>XR͆A70%U#C{Aӳ[tۙݯeIJRI$TI%"ɨ]K<<gPH#V|BJT mLS ci)JD-*cC!:7Pm>kd)ڊM|#;Qs,w'ߤcyc|ԔJ9.$-G>uw>8%WRI$Tʩ$ ^#gy_,*ntg6^ѷkEk\AWI$輺@H._Dm[0A֛I$%I)%I)8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2011-12-02T10:24:49+08:00 2011-12-02T10:24:49+08:00 2011-12-02T10:24:49+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:cf644b22-1c8c-11e1-ae7e-db667b27342f image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^So~ϑ6zB]ىH9Vvlk JwSe&f$M2$Љ_ zoY2ŏa1y ^v%f:<<5$i*?;st;+6s_%PrY (h[~](^}LQNz{uQb򽟇ٔu:}IuF߻~a_>FYmڿ6cGl3Uw?ט<glTJSQr{ |L 3[I27MoUéUl|.+uo)Um%4VT=׺Jt;&pg`&M"3QHj/dg l9 5_~Zoxϑ;NdnΧ-S/u^Qg:͎+2;kyleӼ3:z?uu{{^ߺ^,`&2(vwl E>\^Ӫ$A{8jLx9zCO3gߺ@O͂ywrvN^Iws>Ow! jڏ DXAC4([{(_(GQk{^)8$Hp?#StXK=tRV%-WS-DtZɡ8b puA {t5||ԠXϼɊr[sr >ڔ- m4FSǿul".m*\YjcW'~MGqTR;IҪ",[.+GP۟zRj+wţiXRvb)5Bd%G~lUKt)MIOczBF5U׺}׽u~ߺ^.")w~œe]B?]uovH목qBIRIihZYUA:{䕘v.זkߺ]y7ڏ[~J7` qϿumsc"և#dOĿS.;! s/<^>=5sjaAM읬iW⿑yr>Uo^>h6Ou~{ߺ^ߺ^v6ٛjUCWP kh&=t[T Ik誠h9>J5YA.kJJH-{u3'o+{*Uu m?O8׺GpA6}y˴6ܒ< I'{1;V(HloM=W 2ĬHԿͬo㫎%HJFY@'{3׽u~ߺ^JF-<׺{b;;menB ]6qS@ 8)bIBiU--1 ^^砥m|?pk"yl5D9 HUᕂC"׺L}{"Ƕz >>S7KaO%Dފ?~b{{'bYU6 Z\!^n`}tY}ӔԒg#2Dm=߻rKACUJ:8CK,OuWιLWyoO%JKQ`Xҟ1$8)ca3k {tj}u~{ߺ_ߺ^|W_!mt݋ 7$˃hW$K"(-{{^6/j)vSɵmU%-Qv֛|."<#ի_Qɫ<{^wM&dvח'v ,GߺL}~ '604߬}v,˨Z10S}Oԟ~=|i yuGĵtc.b󩧓4Ɋ0#R _.>{^ϣ x]tmaM׺w׽u~ukui-control-center/plugins/messages-task/about/res/manufacturers/ACER.jpg0000644000175000017500000001146514201663716025652 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1 !qAQ2B"#$4 DTE!1AqQa"B2$r3S4DT& ?Ld3a cxH&{"f=\H&}=):{0KCrer07$X ːvvwTw1Mi2r*) ĊR apE `#0”pI/ ɕ˞‹ R 0ܐb(.W.AQޙS7Ť?7g+H&cمg݀\ç Q$Po7&W.{ .L1H .(r@e\`waGzeO H6_\XE;v2^]](H.*J?=Arϊ8r,>`-b>G9NaErm3~cB'3EC1!¬:XPY^AQu]FZp?K @+PineoMcMz/mlpkt[[^{Q7J펍(2!qm)ES>vk};M!ɓss!BŌ]F$%F疵G:[gWɢЫ|-5ޕFxOڒ7-!(SOi5m˵:[ jz;+#@Os ]00r imw4!Y9,Ći5ڹ=k-ʋQb$2 5 pr[O Jk @7Bz0Â:|wn)Y cx1cv \,ɻHѭU ~a]P?o9wigH _2q_Do isꡭ@ck#nC'R:P_啤bQ i52w'Dq4-Ե}E37j^j/Zz˥J E{q'pM2msqf|3UBD-n .[WV#}5w(Qۉ RP)TQC 5%J(fTfVg!DxF]`j\7,XB3^bֲfduKnE۰jgSS9đNO&-x4Vֻ/xڽ>/N gs!t/lRS:fo!SdPd;U>1@Ge樞˂h- ,__'qM PiiVnf"\d4\KH06]YS:+{ə+l ZnSVڸm ˬ\IGR{EP56n]d273iK@J+nZginS FTJŽ Mv RJvWUvnPi58&Nvb/h/\6Gg7bZR+Y1+$K2$^O!IPG?&J"!v>ھz D =ڎNj\ʞY~1;/:+رrƀ;׽U>,LSx/<\yhܭfݫUρ0=C$eE0q JfF(,ؑM%BSŷPSE`n& KpĝgOXDQAkⱝ uV9sLrem>*Ee{xM)HdZ~x@,'stٙx8b-HʡHIH pDJ?rl t?Pju&ddН}ѴLl 0jB"z&90"=x̒iQy(ck-S.ڷ5T%fQy@ ?b\ϔ$NMZ|no]hល٧ґ܈'Ӑ$Rc@9BqkJsA}? ^Oc$6RtR(e4nXc!KDH/yhyM cQ*P^Z;|Tv$F.BraCߋ#x 46f% =^Y%lM,ekwGSEtwfO\fەŦbPi`?7 1[n^ߝň28et<Ţ"@*\qmЦrї-ejO3Y U o-C$i# }26ڧg9Hn=J~T =ozۭ%E79G ޝ/ Uk!u:Ux;5;$0Rp? 5RRnl\?Η1PR1/˦ &aﳔOSv.5]ܺ4aa199*D-ї*fϼmceG&f7nmEssʃf>L%7%/( RfMxd YHFֽ[: ܽ_=#%%ӥdera$?47ޏ#4'{?nktB#ˀ5+iq&Vq%1W'~k 2+gˡ},LSx/ukui-control-center/plugins/messages-task/about/res/manufacturers/FUJITSU.jpg0000644000175000017500000001466714201663716026300 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1! AqQ"2Bw8R4v9 a#$%&:J  !1AQaq" 2Bt$u6v789Rrs53S4DTGI ?M1q_V0Mz0<0MGс _/ a^l O.!A0`xç(`4„2@>('|QLgF_V0Mz0<0MGс _/ b:! vܕE+LXyYі 4;N6 Լ MK#;,k=+ cwB/uX0׊"ӪE?>:V@1Qyi꘢)S@Jbf10&bb9.!A0`xç(`4„2@>('|QLgF_V0Mz0<Ze9 R9: #&I!1[ߥ;ՇRW5P7e@6C<DZDLp8(.Fφ"ڏ[1O(| 'c 3:+b;k֛E\4VP:kjPTG! WT1I wme3(\,t|ET_?϶!y%ikR6&Y~Q5ܛkm՜h@aL/5M\58ru(tTڤbjtEE&8ɿOs5V-23&C;;g(Fj]/\m %H)I6[ԯ[7t2ZJ-.Էy-|vVgdP PJuhWL 0y5Jsۘ]\ri/|+u޹u.[[˰K!( LscNw˙=ҫ 2cnJ>kǕSxl/.hƓ!26e/cz e/[;Hö~W n7 ai륉F=[ktTC)hd\pLɕoVbgz3n4LL!JА]*NM(weHyg JkU<8?mvzilݮCvtM^I PJĤ)!3mJxÞ1<;u*ϴvAX;|L)~^q~ݿˏ_hS>Mz鼿)a9[EB!}xKT$rpEftb“κ daH5 L a+ww32 3VW} 2 tVdVW#FXm۝\6nng(,Z8g!^43 sŇe ]Q-' Ϸnu-_Azwkm*PZnz=A!M4fR3;Wg; eTvGlks{urAmXӛ/&<_ߺ~OW括y_#c7lo}_?sDTvFjz Rz^,3 5 Q8 D y(ǡ9{'?~=kMQݶQJf "%6[5%U%,cu݃^}W7d*6MԫUZ=xl֦t*̐Ysomo+3[URRfteԒdmo{rF kgIĤ+x-ND9#n켥7 tƉZn2F2Oͺ7̿\o..RRS!!$T Xv7̣ۤw [5Wyaoj4UaC/BbHq\i|Fw9zZ.7ZjmBےYZ9r{c覜V׫ 4jmĸU\LзNe '!2 g(J[Sۅ;K1-:2*xdCv]Nbe}%S>|g?n^|;B}b}r;cO)cy+*k!w=$yBlfL^WD((P2ԫH2M2ݬG!N(NSۑ՜9۫3I 5,&e3# 9 GH cZ˸c:T@W jW:uG<>8ke%ÖSqc]C^65WYrfjN|1"R 姰w .ZѠQ)R)kK T%A23\Օ4{SwAlʖÇ()M}BI˙#2vf }-D.oRT Ιkz:&1!8Ij!h<n`<0-/t8D5T$02$AQS!-ҟ6gv䎔h_Mmkc+m^:@~E\̓1XyMߵΠu@.V_GĻsi4t`95` Cף YC}q8|R ,Y+^--љr]jʔҥNu֫T'91۵nd%;cmx޵r:pHOT_(3Q2g('|QLgF_V0Mz0<0MGс _/ a^l O.!A0`xç(`4„2@>('|Qukui-control-center/plugins/messages-task/about/res/manufacturers/LITTLE TIGER.jpg0000644000175000017500000000744414201663716026772 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1!Qq$ A4%a2BrDE3cdt5&6V"RSTU71a!AQq$B4T5"bt6 ?LyN1&4&9{9ʂ gNDbBLWE>Qք>F%Ew':CE ya0}vyjW _{lИ% wZxf Xd-FYw{~T^o\Vo>x6jeSӾkZ覣zs:c?UFvGYGJIŎQ*hm'?"LeMLGu58.,MTa:&T֪W2wl]攺9:XK5}A sO`rVTiʤ9%Z58 pG+SU4NȘ4L~]<0@nÚfLQ+Ia V&= 80]Ke_0]l`aûw>=\ WcjyE2vQ@5;5q7i>p+e 櫤#ozgW35TSOʺkm֞kN^'W<P '#wqpu8p^5[XD˹=qmgRyd@ % K]DT+Q7xam&_fuyfWWRVUekUM-NiuygydnVe*Μs+eUF% W`FTKT5D{%l }-:((W!/s*#v`BѨs~K׊]%%--#r[jb:UGGCWd֪ʳ|n9o,/}jdWClU*eT #&iTY5/dt$~C\E}%;ś!^*<ۊ($7ƺ$T 'ti*`/ +Y.mkfEܭR^ faa oPS;O(\GֵFp"jŷR'-vkmYz ]&; =qA&P&G֍: q˹.# ou~ACnO R^oC+fm+l&^<Ea@QaOUPcKzun^Z[绒BBD䗕Z=pB~zc 3-{md˶Wv ӳ*΋q@z5`Gk'GꢋrVX2:e֙7Wvcy[2,.ZS'/7T ,3(mcEuCuh|e.ey\)է;ig~zfk fJ5XOFZrSҖvr62$ft0H> (Va'71M~L&ծj;W]O45m(v?OjXu&aKZuc,}Nj'0Ax!K&J] VP=*Tj?γQ[QV3ZͅYʆc]2yd5r(aYb  |$+4!7.icߧSò0@~z[2+nW*tUef]lCN1y'MqǿM6 -ud+(=V޴cXyRj 64I@<`?KPP %K]ݗ{~n`dbK)7ț+P׎'FGn;a44tV,1>3mЫ/8R- ml 2 "Q#!D4€ eszF\n4Ԡin-Qhv# ѣ偍XDt쬱V>% MIo3WiG`C91Q76N0}`ZHodXd hO:v[/s&5:B1ďd6&hS I$X11(KnD/aAǔ"U-r0@ A^}^_ |L#8aǚ!Cc bLG'`$w!#,{eAPyqaKhD <x"WWi_ukui-control-center/plugins/messages-task/about/res/manufacturers/TONGFANG.jpg0000644000175000017500000001140014201663716026330 0ustar fengfengJFIFHH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]" 0!"1AQ2aq#BRb$1!QAa#2 ?t()JJRR()JJŗYEe RTt>욬#[_c:%f_CWo#KAHhz׉%(m_]i.~i)_>xsLk5nvJ.jn6Q:=}]sdMV8]BZ~@ujڒV =DZ);L.9IbP-~9#MCl6M |||T<'BBGG4aU}܎.(%J.k֟-ױZ6dJPV<#D#4e ;x&JTKiu=Wܭ;bCG*u%. hh8|]썎*L@8ԥuzH>A$4h/$ńuCBն~ y+ UEY\t-KRul"{kgm"M-Kk=vڵGG. 'qokzuw ?j5U'g[S>i7V+wIYsZAvo$$v{'C]_ԛxܗ YPq؝ԄQqj@*H>}'Vm!iJRVO 4[WM.夂Tz #c͞fxK\xƗ?';l}?6[qؔ%F뺵c08LIhY_yr4CwR~QfM3ȅ!VV}ĥ H$(> 5֥!) H@VNVQ_T90mQ2 JA*SoSI]_dOC5 !7Lp$]x#^KB{|}׏D əa&dc$e#XxbÄh?Ϊhn*^;qMcihuzZelֳhkv^%GzN3b?MXG)mf;d儕?jGE1,9ۂ$$t2put2}m  pvTC;v[f2NZN.T!?. ֽVW߽NE.މq_pŒ|I$Mzg|qg&7I1R))G$Hu1klյ-( $ u$ҔIR()JJRR()JJRR()Jukui-control-center/plugins/messages-task/about/res/manufacturers/SPARK.jpg0000644000175000017500000001233114201663716026011 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1 AQq"$2B%aSR#s4TdtEeH   !1AQaqB$"4DT%&2dRb35EU6 ?FY*F57:b1F?xxtXJ|4 Y#ӿ,"CXqO-ɀdEyQ"}^]J-u(kDo 7YMrta:b+2U1N谔&iA7"GXXEȆ)[!r=;D%(YHCiy%1GLܽ)lFly+誫5?s3!y`*riɘ6`p* < CmCH`ݛ/i6tyAU+)*śi>#. AHoX|R5H!A[=ݭ4jԊ~a A4WhKfót-^8F1C nzR{\_ZbX 0s6 e\fL p~ϵ.̡s3,}2xy^}vBMw ݛ2P WA;\u[ѻMxY-I"MAJHQ M;3ᦉZ{`"E !`!wWJ,fMi<ό.2 nǭmh(t5wLn?ź]cYO T}ɤM*,h\p j ie-Ϥ-5:PLYI_=fJ\<&D6=*kKSjadlWtᢪwIj>G>_.O1&zEfлӧ 񧉬ԢىCu^p'far剤]A%Q?FBƘ@!iFXiQã$P~9FC-ܞ-?Y . h7Km6rR1fJHazV6VMk30&??x<\yjO&bU du27N,@|HKpM]z%m'0u7WvmnZ]j-Fu³s^$*W/Gr& gGh/ ]=0$H8LܠBϡ4&-m'2L|W|і*|vV\[Ú~ZJO4xI^EړdfM5ȉ׉54:mWt+:.jQug7_?'>aG:-1kVZīV|p>!(:6) z-BkK*ͦ3'Z)޾>IgP|l_[9 m#2u",ѹ\Ym{~X&0(JEf;3Ԛl+4@n: 3u-Te@ !ͰǟU:/`G,D{^y!Ϗ[UZKX8rQSC:=`[fǠuvQ"wzpMr'cQvqE fq˼5It#DuP..CteB;v0Xn[TroV OK>8+H(~j>xn??t_.}x}4#}1jW>bVB]uBQT"(U<'eND` #vծu |Qݖ_}>^pO>PuX17mDz$\9h&7B|h_&=4"Uۭ!wi0FrT -^~W I<ԯJ&0$Gl,JjXKSNqqMI">R/UɕP8CǍ*e 4;.ݵ wWTqYGԟzL~\L"7+]F=ts֜ jQP Lu6)\(t"U*k\=Z=Exjr7W.Վ] =2O:u6̻t&M-ǽ5*"&B69v%JdζDEZ9.HOJl 7=R1Խ?8Tv9 TG@[\w+v)ŨE=ud3*l{n fέt}ٶ=Gκ8íve5y[" Z ~/ V.V S 1Tw4zr7.UUYό\y3܎4zP[dCUiVTz+ʅ;}_1go[릸隩ZobM#"4&W&-,<ݛYycao<013"x˔8u)%44GW䅘4'8M O5֊spB_S{ u֥iɢ(/#mo\﷾Zon<"m=E< UJgM+4bQFpnZO9p|Hc>%?wgp\մ >8]7ZF(lfDD _簜/5m+G-/".e RPL|r=8ua~ wy6l-orõzA8 AdobedF]    !1  AQ"BqVGa2WiRr#$46h)I!1AђQaqT"2Ee&Vg)4DGBRbr3F#f ?N=%ruGSN'"'  #*Az|)G_qɑLaR‹fRApu2'l)%i:@Ufm?13pgi\@5Fr&ghQ*!G&Rsq ̜4'F{`qhjM5ǫM)UΞ--q̋ ωYTY0b#amXiQªvitH2O+fpb+Űcm@wUr:_cq>Ea?.,)q|t.>k [ް.42k{ bVn46X8BU!S=9Lx DKs:1Fc"yBWM8ߓ0K3d`r#5@`k$Qh Xixj,AG N% 3Hډ6uj 9%&S'j[fWb)lh:]4δ+e;@S=pajp#s2nA>T/aQ2C6 h3#FZ8yx@0S+kZc,(]ڿY rVy[bucX %0l~a>>D>_IZN.Px|XE㊭݃AnmªSct.iϊ:m]hh>T\aS{*94k#qǑƾ>L/`5A8J eh:R. \c{SxO,n~fG yƊX*%8' `9$b)DD~qJ<i]eJ=ԃu[RAVbp`D_]C}.3I-!zy0({=1iO ńEUǏ_pĕ\ѹ9V}̈3U5}TӓD̝ L"ϑXfKv$y7 J\˒6R#ϑ2.ZǒK:1aI DCh0f^>3 FuddɚS6gS."n0O (sǹX6/ZХ… by3#2%T+.ϒ1ybCkNR)LP"H}>ހ #:I(m7^dJƃM!R!izȑa)dU"=Kp :ΐ톽ǣ3ӬۼeUĆi3-rmzLܝPB$k,쒑k7՗64aS]=tٴouٕEQ82LUWCkS#d,0ivĎ:d+wݯ9Ƥ҄Wa !M]1m"9JHf(x\4 q+efN" IcFML* N;\iW[3J[g;cVk49γVl]dM)y(sENlvkfݲx:oMf) d$p LWa+ĕ\>9Y7$C]t%K%mSXo4HF0Ʌy!I=(\*^sLDD|͚i l}[߲ZA880gG Quޒxjضu4g]4Z׷ml *RXm/zV9Ajl牔G$!R>`6i#KekctQ]a͞^eȁLЇs0dKdzv(REDVxq[S0-Hӻ#K]~ %m^!ad-*$UmjqrNNS n!vF?nig*^(o}3kY6n3M R5aXfȦzܹ"(s?g샘s`me&Q73skLֺXug\Uӽm]+z>5HL+}a{k0WvψQ| M60sG$'W( 9!pYgS(Πؚeϐ>lN "acg&%:AzXZA@Z)LEAɱ^gx̑u ˭mY*ٖL%DEEFv&|v,mj sAɻ=CuUXdC[`olma;䶓mN@;OMTD%,dD[0B$RSV}jY AdobedF]    1 !AqB Q"2aRwb#4%&89 !1AQaBq"2r4RbD3%5eu67 ?L$\ cxH&|":R BA3쀏u .R %dCrer!EɆ) - 2\PvBʞ?XE@?t!Lo τG\A3\H&|0 Q$PqnL\(0 !qE$Q+ Q֙S݋(rg) H&c )ϗ=Ԃ!J8$=X\ܮ^'2 XPD*?|Sv-;è-&o}ѤzZްa+kZ~\ɗ99%þ+Q`RTBa=kۭh %܍#CFifu- VRB$A[,rPt)z>pAn$gn_Wvc{Sۿpk'ňnX;:vmܕȝSZҌyor!e>|j~״4`0EaKLiL.sot5 ;٨5Xc''@F)BZ)É,;CBk.j6Y׫S;؅Ę_D. jtJnxouYZE>:.'KOZ6! ~w*U {\ӆ ي78ʀ,lD=*5*J`04޿=F:쳩ワ_m UIt?5J͖00,s 1+8o!kj@':yLɪ6Fm9?Upj<!ެ#L4~m^#=inZlqu4+Z:[+Jk]1n dJ 1if﵋2N3.9ɒa@ aE"i\%tZ9317!v+~İ•"W"?:`*\N>=ItEdY96b@&IcdV&^9ULWW.A+{!ąJ;0Q;Zȩ9?QڮviS,دxU]]v]pJUw5f ֝!0 G gGuc|)p3vD6 {|<~v-/17] 󅊙Ҽ=hhkp.EFO%,(UB\G k@p.&/mK*T KT̋m#hnm lv^@NW-4[mG}cT{=Qojhd:U4 %VJ4{je}|%D)ScE,y:^lH#Iy]+V/;UЁ+3փa_(}G#38੒/7vkČ=b3<ݗAwI. !jF{lIֳ LZ1h8kyl9GO2@y!c~E˟^xu:Vu PvCU<<~1MشUT-GsmS[\ZKSg)RaLP]8d8+Ggs+9GHZL#.al AhEOR4Z:[wjʦC::($j|G08wDCx%[0i@8!wbI2R:F倷> MDM3Jj"d+/z|wr Lu@^R r(_8@tabeb͏Tpxc9a !ے(_r0udqxQtbU|<~ˊnŋI^T 3BLDuȤ1gAs]KȆψB R[r@eArri<<~1Mرi2ʁW&~B f=P"L{ #H.aˢI~ܙ\Qra@BnH (.W.A2&)ukui-control-center/plugins/messages-task/about/res/manufacturers/SMP.jpg0000644000175000017500000004103114201663716025567 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:05 13:41:08]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TB9X%.$ ԕ$bg/bg!&d 5K혟8z\CUɒAf'jޗ1?Wpp=$O?/bqT{&I 8pk,cxT"Uu!=K(Mݮ.__{ qq?*8,@]\4d|Qk:s)% 7bVm,j]/;:]hua+Z'}%Jh}Wmߜ B:J2]%``w;`  K꩜t<"r_L1vQ88joWqӇOYY{dƥC+LnQFw8btQ/wڟ5Rf;'8*CK{wz?kCf}b>b8]rFAVd?UP܎},uI.YDhEσS FٟoM̺:HSl-^\ѥg,]B;mh7 9]d0 ja⢎\q ~zO'鼹5cag`9ǀ;?Q~UDzNkgEuvi8L.]$mU>UU :MyH#MqlMllDpFQ0#LqEAz^z{i4Px #RY{kBX oS WvUMJR<2"'"^5^Cdwڟ5Rf;'8*CK{wz?kCf}b>b8]rFAVd?UP܎},uI.YDhEσS FٟoM̺:HSl-^\ѥg,]B;mh7 9]d0 ja⢎\q ~zO'鼹5cag`9ǀ;?Q~UDzNkgEuvi8L.]$mU>UU :MyH#MqlMllDpFQ0#LqEAz^z{i4Px #RY{kBX oS WvUMJR<2"'"^5^Cd 1 93 70 1 72/1 72/1 2 2012-03-05T13:41:08+08:00 2012-03-05T13:41:08+08:00 2012-03-05T13:41:08+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:909f7134-6685-11e1-91d2-fc4f58cca079 image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*}SMGd{UԐdPAAYp忥lF/ǽxsK__돋=/d1?>,{׀;-^WA#ǽxsK_O돋=/d1?>,{׀;-^ܾGOA71I#tDubi@p&S6/N*2|ǪR`nI.vWSrʿ]*=Շ宷qn\K jZƛfN= lh!u!zd r8&גC6Qxa5Ivnia%ޡ mp);nɖ0 [ c1~s3͎,џEuMm&{`!_y6fJz oDq ݰC̗< *@( jxTt4Љ/.M&%:/d΍ԿN*2G HaWW3ʶ;Q=ɶHD2Ȩt5?= Yy_۫Gk 8xTÓ\yXnR^4IdĢ!AbaJ ٓ fOcM[T5? rj:jʲ|?*(6r'S#.#*0Fjz.tTܧEp5sj q+k^guo`$5ÛPrhńCWRe?./d΍ԿN*]_Ujש>L%9cV%3e99(ԸbOg^Pq?{w(Ըx! AdobedF]   1 !qAQ"B 2#r$4֗8  !1AQaqB"2Rb#$%34& ?y6פMZB& -J`vSѠ0]ͥ(/~C$ߘiD Sd G.(LjbEWMZB& -J`vSѠ0]ͥ(/~C$ߘiD Sd G.(LjbEWMZB(cym Z7x S JSI^-P0JGD&0gծ_^QmoǬՠܫaeC2"\'2<iT@QX9#mtP`ܫaSQ7jTr~nT7~G&r5 Sd G.c1Dyئ\wgq2M/O LޕSKKXWYf_Nf$0c)~Ŋg֧3` ,l@d7:r#n\bSd @uHH§׏䌗&Z'gWn(X86mF \sp3o4˳eu] 40yme)~Wy mUL˘̋OӐ@-.OҪ5:Ou>2;5džknW}THx]I^T4v#L;r4Qh5ͩ8dr# m@g`M;vAuifNZvb{<U%TC;6zg;&XUPZgM9*8$ݮ o,o(fJp˟aV:d04ML{ Q}Ak+[7{&+$6)Ш%sYsOM<1TRsnJ"_z;OBM.?揱a'룲 ? +Z'8KCoj̥Ur&H\Q^eVȗ3Wc% R8p~_mMo|8K`\uܘRGFwr ADқD9aPM{Qp%驱'Rc *%/q":ϥ@ªGsM(?&u=@K#Oqh~Hy#gY<* nmrٔh)@mdh ZP}w" x6 =G^__ٛ*?/s\WMz^Iݥ_ /#B@(K4l0dA"8ҙިͬ|Pl!.ЌpYTuw40 m g-JifwTڹ}IօݡxWA=?4mPmש q.Ib}*z]IT,TnC#HH^ ",hjH^(Wh5f9稙1˩c=!&K.|yr;VglMal.Pk]Uj#D6-H87+oa0U$:^]Oye4=J0re/?v~+?Φ-qEon-" H誗MR…ØVX%Q(!Dwm)m! ̺韚O@T@?/)w0Y(t o5#VKQ}TR2 6߮]O?h=j(v5}C(ϼ bA}o na)A+=j-ýfO7~'; G`4~z 嶂%#?(j_QBT?gr8+1a,xFصO0+;ѳ$̑@$iLX*S*g@J*GӘ)kQ6Naj~ .K'(g[ kx:C;_ҬT [*}vejXԊԌܗ7ID  v֩5kNkU&`hv^~LSx(jQɿHS7TLq`z4 yy%A٨d (a`4LH;٥>^~LSx(jQɿHS7TLq`z4 yy%A٨d (a`4LH;٥>^~LSx/ukui-control-center/plugins/messages-task/about/res/manufacturers/PIONEER.jpg0000644000175000017500000001063014201663716026232 0ustar fengfengJFIFHH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]".!"1QAqa3br(!A1Qaq ?h""" ""}Du^n[l[06@\X$ѢCGzS]T-5GR>hCb׻DeosG:tvt.\19?d҈OӯYr+.kQn#-\]$k[vۢW_S7U1>ZtS&ˬ麍w$y_ߞ TPYd,e5S$pvoƾz[CT._DmZ̯E=]W$(Acw l:{j(ixp}glT -|mp?E\]/ jJ6SUA53ɳG s?}>w~B.[/u6VrNb} /ACDkkki@4d`oQ:Qؤrk,]SųOey 2冺L 4Ǧ=_<~ WӟN-TX28 'W']շJ[b_٘zSDͨcK|0ϲ:scYYpEGKJ q o}ֳEf=˩M>]ȯ,DY$LO%^DzCZ4~纴tl6qf+|I!{m+I",JܙTxڝ$-?pg4Yl*x9ak|GߕZ ٱELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]" :!12AQa"q3BV8Ebu(!12A"qQa ?p !BB !H@&45Z7aƳ)϶DSMb -:6'ra KxqG$pA=,|vLY=g&Qm|7UM&K2XBmJI9NHUG9ˡX9G? 70_VmH?rz31:jkY^feႊ!G;7{nXҹYo> )y+a%_~KnzFZrFSd +ߝDv2Smj@OH|Fڨ'<`kt˧;rqLxyM{ncux"0$6o܅#8g |vx>;=k,֫笓6KyhIR֣:OVV%3HTJ)WB I#8#*+O6ӷrL. o~OccH,V|MAS=ۖЍ>L>HZWfje&%K%VP%;qg"&_UM 5[Yju:R\R[hAINˉH1ŸkMtO76w K$#Ǥq[qSiI8#A+/VKʥ54eUŭuKh_WZS) }"@\fnMMY̼dii:}}ZTDMMJKґR>"ٷ vvsہ9yYr}GCsepSyjo?^+ߗlU*AnFY-_uO+FK\EuNSSUToË!\ג68tۧuA9 vھ?&5S~۹`ƮUgIv/M9}Bzzmx~mvó!$6#Q\J:Aii?Y'N7:fٜryJJ^\TmB6W?_ZkɯRO|yX_:Kum9nIn y`*Ooq}--Y or~Mb9PR$u!S~Or? *i7-˵YDXjm6U> #@,V~园5/T\%0hm@(+>ɝ55lZʹ]թ¬deBuҒ(dzf9*OXveFBeX-+n(()eJOVtM:e^e5S,8SN0?.u8 I]/EYrDhHh/ ǪsӬ??ڗ-hִ3M2 h8+QgbpQz]n׍"eE,ݵ /J:&AЃk%J*UoNI4r "Qx#(F]- D5Mc%gd1^ݷʫЩlԔ)Shm/1+vNNz#>{#Шجѩ y~.Y|nӭR8>آ4Im$mh‚r:#u+&[\&ff]yyPPn$)+I Ђ=#෨vMrvH[ų#*QJ".ʻ2Ӳ̸. {4!anVUۖeRNv gLf !BB !Bukui-control-center/plugins/messages-task/about/res/manufacturers/MICROSOFT.jpg0000644000175000017500000000644514201663716026507 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1 qAQ2B!"#4% 1A!BQaq ?Ǔm}#2&MǻGEM| o.~\ [;-`@me˰w"?Ť].M NPoZQ{tQ߷P vhI E˿0P%P\pxh)kl]ZMp2&MǻGEM| o.~\ [;-`@me˰w"?Ť]<1֓ z\-& vF-)$&wZLd}끪8=^<<EG{WkvUoÝw ttcG.tC }q"FF* Jm2UpX~]c%ҋ26NKkVDճҩӡr[۪Z$iL8rZ3GU &ZA]÷EBK? g.]- yDקSE%W2X7Adh;qԳddEڷ`d2*hy!X*Ujz&=_)PHpL<C^mmI~g-D}T.U(E:sm:tSZuތ[OG\ ' <?\?G՚w7(t,T$5eJcXœEIY>T yVqX">c6;2#)|*Ɯʛ`T߼W}ݾs]) rGӣ oI=;1Rjiv'CgnoI#?U43%䫑Y~=!C ncE둩SR{Se;CNNtMG $XY6yHK-ӧ;gq;êFWUJXӻ-Z1ݺ8z#e:d3=D-/f0d Ƃ̯%F֊q4=QJ#bD5"L6p5-%GnEQ- U}17Xղ]G|coU>gE%*Ʒ@H(JnB~nT}WyZr2ǩW#|J?I"TX;T=,W> /yU2|A܆)B[Կ6[%"6)vG,[&.pD$O_OJX.>ۨ]dc4.ھ]+| U<-QU{TR2& 6fןWebmずzwGZ.n9=A] nR4Ƒ&xIR*. SS-^`s=`~ ߙd|S,lt99Abg<3zd4!H@FÁxpI%dۦf\!o1q>Ace) o]T=ȫC";(W *#|RUxb+ي)% oXۭ$7$rP#IE#dsAeW!B2j '±7y!=80K0fqۇXg4.#cDc(VJG+pP̥q0Zʭe^韀y; :q́ oSqn:0Ec:z9x/gJaݍ5VZ /o(QFe!fF ꦵG.)ią+7ZcMŲ6lV&"U G5N\̹R@N"J+!|* ܝ_ӻ. &[y#c`RAd ]ughl\ڤ$qVʔJ MLS"u wb?Ť].M NPoZQ{tQ߷P vhI E˿0P%P\pxh)kl]ZMp2&MǻGEM| o.~\ [;-`@me˰w"?Ť].M NPoZQ{tQ߷P vhI E˿0P%P\pxh)kl]ukui-control-center/plugins/messages-task/about/res/manufacturers/MSI.jpg0000644000175000017500000001054514201663716025566 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1AqB Q2!"#$!1AQa"B$q2r4 ?ǓJ-qW&j *%i{*tM ROH.ӪI ARu#%CT8Pt5J~jiY_ATs ו4j=:&Mz})'PRS$s\ @TrH (@\`wTOO? 5UYi4Uɯڠ9kʉdA5ʝH&>R t)_9PrT]yHP *uN9$ d];GR,Vr*PUA5DM eN^JI):uTI/9*W.¤dj:J2W.#SU}0bx?kp{ysTa*f榤W8P` l$I` >Rlx9crԒ7)n8D}W/|o4cs@ۏ>KFD>X Ts΅J=8<6 qrQ9X]3>ܬBYخQуjZ!Ӑp.[|RJKU-F@nh4d7 K>3l#hv1}V&vBבٍJiatr$,(T/% lKclt5O<UyHNF- d\[ʑ?z4n=}oP?k\;2aorX#x4?n,㬅w5sHf KW "ew,EVӏK>>xAW+TƖF\fQs wb@v.k<ckš3r8;B"@1 Ka7Lg܎+uR֖ɰLř0'l}V384-`_jc8{Wq ]mi#SY#!"F߸[F[d$;7^eR]nWI~ u3྇,pF1[)w)Cm(˦qK5Hsϙ7CtT,2r~mWPGP"D"L\b8cһb|5{#$ofh$a,yM2 P;Wqno!үXڨ剽)K A<]+oꚋ&-"c ϶@0%^g<.sࡩ22,B8ӌ%:pp flY~̞7+y[X\vH< V >pp]/SYj;o[-ع +_~Uj9q¯`|Nц?؟ܵ\c(nuDzqh$xCl"No$aZwr;1 A@)V6{[ Nlw.N,"=^,qNT¤۾ G سAdV៤шS@bc D;[:լY^ͮG&J։s%qe`Lc0RҞC*@lb6p2>w3[ιۮwn;]dcIK2qIvVeɸw3b<cܧ<;g]l\1d,A ,XN3.F%N<=}bMxWToTr>=-7r¬7!/-®gGKmlvȽ_j&_r<+5_7K|ٓNʢ^}B}=4qu !9Sy-1@}gQ*eKɼBeH>r]Xjl:qSǰ 긲Ye/ cPC1b@F-hE,-N(KjQtnq-1LܜD ƻoT~Lu-=Uߕa#w'\U-5}\v2[A2.Ka_&"v?z{kg{6bIu &u)ɉk\Tݮ݂tݺrh#,#,#8vf]ĶNgk9#i ۴'\Bμwdr1V..8:`exѳݩRf/v^ZSt o͋PtxV7[UW]~Rj+N-qu|yYiͲy➉} ^/sr` \U$a j䧘*w)B٤^o1n.Sh< ?4:y~ꪭq `| sxC׸{9ƒg }ľ9{'˰8"\olPܾ.b6_Me”G7X-|0DDy+=ˎό `^&$k:/H[urPr;>D|gq.Oe(<$9@"3t`]ن!UC;iJmN6Mqr2'!]u{[KFaW)ZBMX*Ymų'xiR^hj%&ݠX;w|Cf'#S/se-2!QbrW&vťj;dfJӂ5n ܨ9<+ydZ鹑q82]CAx%\#ЀzK};`@W~\Jv PIQp{yKS'nIڦʣA`Fy+ksAȂHſ2뫺%ECC_8[08(-b<|?֕0S%[Y[Gh00 »C^PUk~S~QѵTl d Vf+;xn N? mƦx$T'D.dOҳcP2I⥃pZ\{Ampjdͬ]U]4TpUsRP\ 7m8uU-KP SL?LA⾒zyW7iY_ATs ו4j=:&Mz})'PRS$s\ @TrH (@\`wTOO? 5UYi4Uɯڠ9kʉdA5ʝH&>R t)_9PrT]yHP *uN9$ d];GR,Vr*PUA5DM eN^JI):uTI/9*W.¤dj:J2W.#SU}ukui-control-center/plugins/messages-task/about/res/manufacturers/GAMEN.jpg0000644000175000017500000000776714201663716026001 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1 AQB!q"$ a4#ST&A!1QBa2q"Rb ?Bۿ^?1=xjfTQߢ7!8q2FԲ7d${-*B)3R}`jVBK\YN߮S2" Qt9 QÎ7ѿh!'hROwߩd#R_D*wnwOG1wf"ád"t Q5,&EY =D{LǔX+!=&W1VS;w~cUL10!aەM/>^ st 3QKW 13Oꂅᦻ߂&MD)b_0b(˿6V,|ȥbBpGoI$D9cM`$ 3B&i{{X:z%*4oۜwWkMmn;<ꈓjSMu&H@Sʭ`@](!]#j~9Ԭ.zUӳJZVUTUCYcG: Ñqk'2"(o5qM h8e=2UH_o@4WE8T-Q]^U@/0ۙQ&+z~Lubp\߃ڕ4|>fP53Ƹ ;[ӳ!21[Rգ7UBM{X&A=XɆeMP/m-XHjz^9:K*Vd]z/6:k(a4OQ+KwztJҍ'R0R.vtDv_jh}ɳ?ω,@}P:ӿJzjWދPμ\'/G?~߹<:?jcQ8< )Uڰ$g*DذڮUg'%e57dyCfFzx_z5}{ӨpQrBsȋ$c|̃:'vIHKS jMǻ&x%6`(櫤 &sFƾ}flOmFնZ=i6n s YU"rR.*(^Otc(uEw"" l(D4!P*e$B{eҭU .V_iᧈU>9LB{vK(yƠ JW[h U<Ӣ 6հ4c)'BC˷=iMӧQb=4*vtL3|a1>vjj+ Chn")-tm ›wZ{Fn(kNx#UtB29놱C7ssj1#X-OcʎFrEjI8hӊl5W?zv"ϴ동2;*R%ƃ#|)Whq$zMb6dIbt&zqNZJ66GhY(.½ Ss3t)Q2΀nIMTa׌5/gRZV ئXwml^Vf%A =MڥlIWJC9Ԕ&\l 5BnIm\h"T&O OrM6=I1/k)# (*J !Ni<;zixc cV8%=:-E,3\ļqi\rJ7"(Vl1T%j3Xrʫ @<}_Pŭ ':k{>?#0:uM PPL磸|e5 N +IKW|dDKH}{pOAPf[Vw)B#m*2hSM2LBqZ ͽFӞg &NGUuz:{b3b#CcixjԢMYD fmwINvC@zeӲZn_=r*JxٟȦތ2nu/q0ͨ?Uh0qF( AdobedF]   1 !AQq2B" $4a3S%5!1AQ"Ba2qR ?MÓV&F 4tQo/`EC%٬ ߴ4V0;,p0k`9v@{4W|mmw 97h1 *FuZBRNDG9N8C+=JffQv-msන]Zb*pxskUQ+r[(/ٍYݩ%U%Y{TU+t`w 18Ԫ$  :j<>&jzxbw*`;]Dm}Hu!+:TTmBFOTP9ǷUWds/7Q #ok]UUfBg K0rthTVE%R5ELq >}rWhJvLr4̲ZdWEпv8ՙ71$3)A}&DJ%'+r( <<)w:L–n&m5#|PcGƇyQw I4uIYLSԕЇ+ {8U*@7}٪ 뵍 ~J7_vaV^G U~o[tK^ EecF>99xPKrqD:swVӞّ-ܢ,2:WEg̅!D‘MB-=C[ij :D3S)N#w͂&xxQTCxg<-^GWHTC(Zq%La)6G^ lE"Z)Q͝tjer Yno8xR-,jW9߈_}>?ğ]k}n{{|խoxF,t[vV?r-%6z.ggRv6ιNsqӂٯ;/!k۪DI,G@"S$W`7bs^+.ULٷR$[s3FI!/tvE;1ofpѶYO] UK>AГG?3N)ªEdW6?G^[M{.7pfLNۧVi*#[B1Q1AC:?q5vJ]kgg-̢]ydz%n kޤR4hL-!V?a׳R8N5<8tFJٜ*:]J{#O|:׫$ﭥtyHCRve(q|;*7* <8p!r9VnExwMK' j4W&zDzPUDL;(I6XQV*^37ci=L5Obߓ1 'LZ4unqFk:tlm Y"=7WkteD&ZMBIqqTnOTJ^}*AS"2:P_Mmj^@PZ(hE+ _tCWk.ݿZ2yQL7Q#jQ9xq<5M\m``phE - FƪcE54mͨbJH^"# x&=M``=ԡ>^vЋIP7֖ 0Mѣ6~#<<,/g.%cX˰z٢Dkl]kaɿA ~i`}:(7j0]ɢˡAxr+[ 8 =+A>^vukui-control-center/plugins/messages-task/about/res/manufacturers/IOMEGA.jpg0000644000175000017500000001302714201663716026075 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!q BAQ"w826vx9#  !1AQaq"2B345uRs$t7#8% ?y8J1N}s9VP9x`>4?ъte,=Zi\d n ͅP"W+JrMht7kot93N6567vU`\@NhBXYf'nEc& 24+iI1 EHwo3~cz zMM)̽mu\Т V^{CL2004 :ա('ꈴjt@0rs# f hxC./.X[!S?HtS=+H+d[ v(lѸ\urj*e|Onf6)5;9p4̸:LSR]zo\ܒKY i+BTĞA|hOxzuk=*röDϘY.ۻn㵓MQce:j1#Q>/ՎLQkDqmlkXTr #!xY 6@02T|oƓG0{J\ڠ1'2N|cIYBI]2TЭL@ѪP=:0rS@C[P:X) (X d PPrAЏLiqDZN5: 99h CIYCz(oŏT:ӷm1◊td~N(՗!wxj{DZ>lZŏG{ ~ Wf'>(ή6oTf PPrAЏLiqDZN5: 99h CIYCz:dȇbU?MS,N hNJ^*=8V^~r᪙ǸW%k=m$'J52-]_T :浾QbӔ0iBAuB=0POw٥ i8cP/^^&3悜0eQXA@~Nj¦ڡY * c/']uU_g]fz.)e2^mZt 9Ri`RdBbr~FR$mŴfOfiƔUHܣ+D\Mj/kH#^s)#;|mxz--ґ.kԀ۠K]GjSI uOx w"IЬek>F4$;_Dٖixx}+UmVӚ뼡jyӘ u@L9d0, jUqP 0@]c U(/TRbqZ5릝QWZJg1S숕ڽu-J_uSb:Q @KbsD$۝溰gtќ0PЮK$UPTi˄Dype϶, `V{`(jZǦ|yľ91/Xm'm1/|QF8KUM8Q,2a2GS]W3D&CC"٫n6 Ct+W^\ڔT|ߜu;Ic!yxdNd=!a9ԑYiOl鹻6M-z`NdyD#G~/i9(HL3QI&aFvKaKgSt*`5TҮ2: ´{Le.MF;%X71T7ҝK> Q wI/g!e\nywҎ-TL̗scܛVs^(]'7תwLꘒ $icΘ̨0jn[ny"zN:Iu.^6e`,('X0F\Jo\c_DZN5: fjb齙{-|y\珲͎ RRP"r9 6RLvKH;kd;'Y& ut1XZ,emGgج<ΜsB4UHշ)$HS7~@R"q2=2Q[D^(7%= j(v) 2t-SG .m~# Udw!/Qadz UgMy 5L kl;N89gO^X1lGwߚY ei *X$)@RJED74ޜ纐`ӹjr=镁^7]e91.6g~X{kf.Jf1d1b fy[ Fm 5n);cc]M騵W-]Z5=IU'9f-V +(YlOt./ԜVd2xYq&5@%S>`)C$c<< 9r-Yvv*x֫vYZ:W-Y$FEE'\LkMscg|RټI'7攔2ClCL _Upy@7kՆjZ?ϔYTm_`׍īɺXjޫ򋦎D$3$)9FXsk2*!VԷk]hβޥF@D2! Ro*WYj@t`eoͭӬwS-=9})r#:խzcOw٥ i8`Ѡ0G1 %e  C`И~;}ZG((|R?)d"7 x)mv@HSScš4)eu#70qBt5SKbQ:|(8L:=n7FI49OMzD%zhJj2"FlVd\N=] 4>(&Xԯ؎0D)XQƋA[ AdobedF]    1 !qAQ2BY $a4%5I1A!QBqa"2 ?&ɏ&<" &#Fh~%:y t&_h8D" l@Aٵ"X/.Wxؾ [&p2cIDIAѢ$ǧ0ߨqH, =<+[vmp 0 ˀudE=>/VɄw 1<c+`b=Pth17"\C 7BedO/.]5^ʭ٦YfR)R.reNIw';t;ܔ%ecƭW=lJR=Uj]| c )kI4IRJSʨ(il׍SJu, `$;;8ĚULQE*UXjuj25+5ʬ0i4biDgS( TckPQ&fi@yQR^؉+S6S[X-%h6eK4bVqP'}IL$|IaM0G_5ruҙ6$eVjBnAeG.td9M'(-?82h f]OыjMNyJ^{0J.Tvy(;mZ#SQ`e[Iœ*Ŝ &TKHT e-ֆj^ӨnMhuaYJ3%IGzc=ճDƩP9zRJs{#NzVˮ6&N.eH;-Fz픙w$Z]R!Dl&1oOvb.R a=TB4 z[eQ-fW$I TI#FydbˌW{\WetگR$w,! 4Sg7Zܫ}ɢvܶɨ]Y(v^pɾRim(B9RMڊh:ZDW n綆o_%a-Ts^-~*k@URBtM[ww0\6Vy[޾)UL?:wY5?"9;Q>Sj-?tӟ*^F{"o,S &g9-Pg qАHߊ*OyߐEn{Wg (᧽<"L3*zۦo{F~Pz}=oާAn{WgO>m/e3/y?CPe+?'S>WTo ?j𼿇J~(e(T}|9/C)C%UK?'yG<ڧ%x@<xJ0FC4d>y1@byB$DŽV$zcoDO$nȞ^\x-;6DK: "T[d;^L}P1h1:4DF.!2ADz'!`Kbͮyp삼j0しD'"LxEl"LG&=<цDKtAfLqELjAX؀kD^\; ")E|ukui-control-center/plugins/messages-task/about/res/manufacturers/JJM.jpg0000644000175000017500000003554014201663716025560 0ustar fengfengJFIF,, {ExifMM*bj(1r2i-ƶ'-ƶ'Adobe Photoshop CS4 Windows2018:10:26 10:00:15]F&(. EHHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TUzT XL6dc.r h 'A &[I.ZbclfN^+ خU0g$dxGb3$!.) o?W֝H{^ \T啐z? q}3ٗH*?hǘY>%3OO%= ta?]M4EvJJtI$U__k¬2;ol?m^O^#~cVk9q%-W )dXڥ9;H#4(4^v;w])˰\wl޵1uZ_]W qAc†xqKx/+r,qO76`yv9yݝCUk:cV yxu0<8QN nvfw@{5}b8݈Acխ0>TF׌n^?>YnG%+}#uF&Aq[ux!\CܶbVwqPr;*?'Q9m>e8Cau^pewnjLwwVfX>-m>9 HDV9Y E_M JqMrO5æS9e6~ҺpZ?֍;&Nhkc\oz/U{gRN%|Rls/vójy KIU;[T>W6qoAM;7cw[G\xӫyg}sJ!ge=+ǡEQ IQN딒I$́~S\(H`/Es#aƲo}Lu+cU=[vV_f=;uF障zikj3ޱ0~culw߁K%_J;CSlܜYvM6я[ f2XڙMuX32/7;k^>/k~%fRWbhհ/ƽYwKUWb? %I+kn֨bH魺}R_]eߛ_SG֊n_Eީ"&hs-[|^MOj{ȋn?ڨb7ZKj?"ۍ[Rqq3ֆ;FJVWYȪ>]n^MTS>F[S`ݴz~c*9_]qAn5Wr{nnSzӺ^^?֎Ԭhb2 &w7jVNO\~5 K#A65@_w򙱉)ցeUuؽ1.NEo{_wٿ;SܷK.fΡsֲ;*4a}eu[h[Af?@f'\>Փ22kSYsKuO~%7_ ~*/vYX/sSgh__}pW[}?C}/Me.d}}vV-XXڛSM4[b?bLKퟳؽo{=IOTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$\Photoshop 3.08BIM%8BIM++8BIM&?8BIM 8BIM8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM08BIM-8BIM@@8BIM8BIMOF] logo-07_93x70]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM8BIM a]FL EJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TUzT XL6dc.r h 'A &[I.ZbclfN^+ خU0g$dxGb3$!.) o?W֝H{^ \T啐z? q}3ٗH*?hǘY>%3OO%= ta?]M4EvJJtI$U__k¬2;ol?m^O^#~cVk9q%-W )dXڥ9;H#4(4^v;w])˰\wl޵1uZ_]W qAc†xqKx/+r,qO76`yv9yݝCUk:cV yxu0<8QN nvfw@{5}b8݈Acխ0>TF׌n^?>YnG%+}#uF&Aq[ux!\CܶbVwqPr;*?'Q9m>e8Cau^pewnjLwwVfX>-m>9 HDV9Y E_M JqMrO5æS9e6~ҺpZ?֍;&Nhkc\oz/U{gRN%|Rls/vójy KIU;[T>W6qoAM;7cw[G\xӫyg}sJ!ge=+ǡEQ IQN딒I$́~S\(H`/Es#aƲo}Lu+cU=[vV_f=;uF障zikj3ޱ0~culw߁K%_J;CSlܜYvM6я[ f2XڙMuX32/7;k^>/k~%fRWbhհ/ƽYwKUWb? %I+kn֨bH魺}R_]eߛ_SG֊n_Eީ"&hs-[|^MOj{ȋn?ڨb7ZKj?"ۍ[Rqq3ֆ;FJVWYȪ>]n^MTS>F[S`ݴz~c*9_]qAn5Wr{nnSzӺ^^?֎Ԭhb2 &w7jVNO\~5 K#A65@_w򙱉)ցeUuؽ1.NEo{_wٿ;SܷK.fΡsֲ;*4a}eu[h[Af?@f'\>Փ22kSYsKuO~%7_ ~*/vYX/sSgh__}pW[}?C}/Me.d}}vV-XXڛSM4[b?bLKퟳؽo{=IOTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!UAdobe PhotoshopAdobe Photoshop CS48BIMhttp://ns.adobe.com/xap/1.0/ Adobed@      F]    !1AQa"Bq2R #br3C !q1AQa2"B3# ?h@YVܤÔ!0qy)o 9!TLQ39D=@Y>=}7ǬϚQg DܴHQCl Go. ݑs؃,`=jʋ/ΈΝP2{$1m0yq1KujF=I9?OSov-jS}2jmHt덖UvreL̴HPTLMûɪŽ4S;}-t\u}kފ[f=h꓉SIp߅8/"'0 #mm.]*@:jBq& ?t>].4ʬȠr*5PS.F:*Q鬑(N*JTD؜Ӌ${̕@!!$HCj P;{;D߹wJ\)ʼnBBY/S'dZ^$R^:.thB]~x^p59yO?y|2('a[kKHJK tzS%VxjLܼ30ʓ!DaOəcm~o*lmt}΂yUXٜ8PtbiFI'^B6"qZBH@n7n;k["ʙ+ Dv L 3a@7OxK@uI+8]BrE0R# z]>Z+əO u+-[2۵r91cǘ(D^1ִ"ы./ٯ#"V|en YIH{5~ͻN*[Re |g. I@zU.DWdۅ7v³pIqL>okt%rnWޛ,wTC|9{g!ѣF^6Tpd?-}B[SpԎ貮Ys&^R}L@ } qdƾ/0bzZE6놝/E!9TAÝe79{'#֭̅Jp;twvEz(Uz)G1qJDm?U"ijе/ۣ_=;a꿥K߲\%w ePAĻ @TZ1U1>p d-V!rEPqnT1{$qm'K5Kag&s9zLW,]Z3nrke[Q6bc]*e5@H ݰuhԞ,G,8꫕22fMŵgL֙4 hݻu*RkpPDYB:d2ev  6O*4l(+L,E#7Vag+dL7+v%ϾQCêJХXuj>9fv KK2H2iIv(7!BQcޱd[j$VDK3i!P;Y1@ͤu2@tT78h'}b~}o??+~a_: h@4 h@ukui-control-center/plugins/messages-task/about/res/manufacturers/NETGEAR.jpg0000644000175000017500000001054214201663716026220 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1! AQq"2B$5 aR#3% 1!AQaq2B"R$b5#346 ?L.8? 5 ϻA3'$ ovJAsIO$Ah\$QP 19$X(\LHT |-&XZ\QH&}%D 19&L{R vbJy$EJϼ1"i8 2ErbGR0fi2**BA3*&L4g݄Ґ\÷S$w0*W.}T3H NiƉ + =?o5_/oKp֤RE8*^:W9<̥q<@2";ɼɼl\[KSm$RzcV,L_2R eX:(x}{nUuFQJLeTʈ$XBƕh` nߍ=.Zݵv4N1|^DD0f#ΐМ+z|k/&VYxTޫdrM%Iy3+&hEpgyl˥C50JSXqE,oR,fYC^,RǏo 2"' CKz+@S Gb~aMd _ i1,4 ףQ yR!qTo6u|ݦDF$. (QQUރA֐ GMp֨ƣ" vȼɱЖ /NzSշ^LϒNIi?܌qޭ{íۍIJy"Zz ?n涟 yycE&Le% qBdVbz<\ |6TI\Rڜ_'EJWɾ]rUF4ʨ)#"dvWp̈OC a.ٮi#C޻ ,ΟKNd|*v37ƷXylNƤ.;vNeۚF!fHà:;y, xi@V=s5'*tG%2C㴘cǷGk\\32R9V]c~R޹rQh]Z:R>uw=H.Ah> UiyL 4#f,U(S6ͻCnV3 81*j9=1^gi,8ט*u} PΠt+eLW *=| &Y}l+ֶ䄞\[}+klj'Cŏ7GN(q;;+]^}kfQۏ{MHPGc2i,BSE1ʛ, cLa(6y7Z|@:1N r_X?CMP-՚ZR.].9V { `sjk_qC&+{&{/7(ܷAo1BɖkB[w[U\д޶TuChh0S{:/PU4(Eµ~fpMp >Y 7Ɔu5BvIwoz[^8J\H\*2hV={ (K\ H+pdžl:?cm-Od7D{xִ-_z돡b^R\Tt b9UWk(T*ݎsŽA/ jƹaë>U 4y~a'.}6VJߩnԕzZhaMLbSJND@[QL%e/6[&w(K,K=(@.[HLl=\\afewm|&W ʤV_S6 v>f]D :r.3کgCosmϷka:Ҳ2&RpDQ0r ^ZEUKcfk@sh;ie(M -.v$Yr"V`D aCE/ۃN~if}v.$r%Mu)83^ ܗkI'DvC-FWb4o 1nlߙ6;n0GH| ݄WP^M"d9/͗Yܺ hzv鵢w{{VJa2RCU,}p,!bTYaUXuKoK#5~_.g ^o- |fw|N^/6J공T}Lӽ!ݨ$KEEe$)v3f|frU⌂3UGɌ3FgwNj$j"jaSnu58~|= !Z k}X'(-R%zD;Ra#؟_LV@-FBZOMDP  p}6n#9jKoBԱ\4җ/,ArjmSp}w~"NW7垈Gt ^%pn88wl.,|,nLX$>i~H&}I);{1%Ċ*'4Dː|JŤ@? 5 ϻA3'$ ovJAsIO$Ah\$QP 19$X(\LHT |ukui-control-center/plugins/messages-task/about/res/manufacturers/MATROX.jpg0000644000175000017500000001213314201663716026143 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !Aq"2B Q$a#34 1!AQaq𑡱"BR2b3% ?M71H&ړAn>.H/A JQ$w +~҈&4e@mv@zSjfi6@HSoݩ4H&A74R yyKP2w (a@isFX$ڊ+`J>)>^fiKm^T 71H&ړAn>.H/A JQ$w +~҈&4e@mv@zSjfafRyexD1穆#EOصx-[Ԃ }ǐvS"FS}5sn2ߪ%((^vmK{OȐ'Kuv:: }=ٮ-5_$|+a$ўKxHn"7W׸L8?|jy)B4@5`YRZ)+pL wCfEy5_rH`a'ػ^}8-ڃɊuR9`h3$fܒQM$NCv=fכ:vZig ?7ͮ9i|bX;Gָg qR][׊+ZU 2:k) Ԙx'TӪL-DZfxe{"iCR g.@[Ht* !_W,@]W Kӯ2n3m5s_G]h\]r$F_CM+"/Vݣ )9<0>ʍwmWEEPb8d+C36<&PI8!U1JER8IP^c*7% v͙OC!au[~U%PgM1fq:tдI}Gf-4r:bi4TZ8uK^d÷RcqkyD`&fVQVˉ8[x{1Kľi?P8~7vGٓO)<Ŝwzw]dh9]7 *vv @Zu+ǣ[xA+=%(꽘+$;\>/^U2Xv`;֟]lR@ɪG#UgZX&bo¡FVS?oQnĵ0rʼn-š TS=ʜ?2+tgWS{/Zׇ]d/26O@ֱVPlZQWc]D* 0dpUMx};%sp8;A}Zbv\%HZ:#anPlUkOm0A5g +}gn&y}=l#fiY;Ǣ$aqcfX0meՎR徭ZWę:DݠDxy[tWVRYUqp{Xze((/ziH8ĸ|#k3inN].T#-<ƜE'2jz̸UEr:-bRgњo]5vrG|η'=Hm'b*X[X:4aћ-J2M畢@ 4^d|>'4 PWzJ'.]mYp'#7 ) ME(cq88$b ڝk1A+ܲr^B'.53ZʸTgH PP#F/T㎢ۘlj':;.A-0PR #)ʩ;oޖO:^~r1`fӯyًC5g;d2Ko*]>tS#A@RO-ԡy³zY= wk JHޤӮQ i*qfh?Վ)]LK~a$ ֊-oBX%n Ӝ.,_8lN~5!%}}Ajr<>-i)+:sSC?kH|7+r+!&IH`х DGy$C*d QS۞g69͍Wx`r/i?_Ͻ6fDJ/=n[>٩3`I& {%xђzNRp8k%]mޥbx]^f5_%I*\B$~IA7F$R 頏ڐ]ͥ(_;Z ˿xiD K2 6PA\=ZQL53MXjUɿ)BA7ԚqirE ~ AdobedF] 1!AqQ2B"aR3#Cs$!1AaQB"# ?ǣjGeѿV !:(oPQ tˡ) .+[(c,NøxQ]Sx2m].Po´QQD#~ʅNe] O8VxtQX؁Ge `vŠ"Omj8to#~F纎!T/Bw;(J~a³~"\5U,SF}J!;Qw)O¶Qw \.aQL셨v#̤.ꓡ #/BX<9e2{BRIvry&{  ^Ŭ h~h Y;d|Y )QN$r%9aX\0_BQ}H Q}ݶqlٳl@꬯G*yLs,uc9xMZ3X 6,ĴsK}~vIhE%Z@}umrZ{ajscݛ W(oܟSw7-$2V1ҭ.LL@Y1rYEWlz +h)@NNN¤cp\j=f-YE*3'n |eNcJϋ K6LCyǠ7a۴ru%-dvh:^?%k,ym >Z^tbTDM#bz꬙>? [7-Fp3d>?rgcqsGeFOIK\eD(yHRXEmnZǰҜC`s07&`10h7n^]ߥiM/\A*b9aZ^O_'bk5'NK8sr(&Ij۬1uՓYm0?Xio7 %Yg r+ȹ WDlhJE BʒI:-+Eu \CM2\g507?XXG$%3ƣպ٥QX?ǔ[,.cN[Zlׯ Ԓ;J ` +G&xS<QG]:T=NtӮkUT8kFZ>`G2}?i\=Og.sySa'_~ܜ/"-U-5B~H֗nirJVL#}0\zdl.x4xvuӨr--,/bĄ׽K;'}nݣKN5T\qO䯒N?ֹĺ?+E=Tc.%":~_;Y}Q|hG:ÕYۙ [DM|uezN69 XSNo&БYjڥk특LA?N.-νbrW4Yt1􍛅y 75ñzF߉Yajo2 *ީDud:!,3!2LjĖ@}AvoSԾX7vJTӧdS7T'2m].Po´QQD#~ʅNe] O8VxtQX؁Ge `vŠ"Omj8to#~F纎!T/Bw;(J~a³~" ;,p mXӰWqx+l^ Wqˣu'!,B7=tQߧ~EBS>];V QcjX.p𢻈[bukui-control-center/plugins/messages-task/about/res/manufacturers/LINKSYS.jpg0000644000175000017500000001016314201663716026266 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1!qAQ"2 Ba#$% 1!AQaBq$"Rb#STt2rs4d%Uu ?M+\1H&U$R RA5e /)G$P2u Q$4 4tTʟǯnInX 5) c0Mz:HQkAAu_ RI%erIiK-@iQA%rJ1l?FHT!Th//+%e%] |b/|H̞|q CoSW_KĘ7t8>?~ jl҉~A:ގ HÚ w#" *xqAuo\~O\-fLr]4!f|Қ,%J=It gɼBVH[UOÑMǐG.:M 0!Ǜۑ"y,BJr+nK\T#/G%7fx FH%}@`hǼ+xzZʚ*CD1-0H6 p8Qw㇍g\3fiK!y Ρ6܄S1TOVՙɝ+ǧ /ߑq+c$qmleΤ7]ػO81I[|׭`-vb,L|Zo[$q6`i<#i9 ?f"%d9}zR~^Q@8n KZޯzQX/LW/)='k&×y81`Il}]/oC/큦<:'gi)3ːe*j\֯y”Z. \ɧ1\eEMUpg=r 7c G*CtN{~v1 {6=gDbQ̶:͑"_ m*avxxF"*z.뀢Տ;U wN2*Ek-0û%\>.rc c쁏1:[2ɛ֫}3xz?>ʅ+Z"Ti|י}n~)l|W ?fq fy[w9q_'#x/<#lSV%o 2&c*&xqY0np[ a0$wH^lz38J1_TMY3CeZ`,*FIJH T x;8,Fdɯ-)o'8g\>TTSGRP ͉?q>Rs+:ƨ 7x"Q5U=uBWL|9B:::F>-c}n\`H,8ԬC xX A5/&}7;Ow5Tꊏvݼ;Q;Q%Wu[,vi-MhX#mh]2]P]!\OV{k8?3lgpkb_<ɝhR mA9jl*YwxW6snZӜ5๸f*^>(#ds왺FHsy~Fފã9(P[n^z{0bfKKKEhly;Bӧؾoׯlk7o\˷vOt ?k8Ép_gvq/j{ѿb?}m^)使%>>-]ϧ'o[ۄ>RJܰrkRa TtH&K H&TP2G$P28#ꡦKp@|y($_hNh^O_3MԵi4W&!Lf UGIj="My|#H.JQ$puT2L]z”I0 )sEH *($];)G2fji[MJB$^)z)rE PG]C”I~d\(a@RdTPI\@vR*eOT7Rukui-control-center/plugins/messages-task/about/res/manufacturers/VIRTUALBOX.jpg0000644000175000017500000000644114201663716026635 0ustar fengfengJFIFHHC  !"$"$Cdb" ;!1AQ"aq2R#bBr&CTUe,!1"A$a2QRqr ?(.m=H35b~CL`ih[WZ= nvoxU]^hl.,뢷<}iŹ2/]h - R/HcV\_q?AKClb8BEp n5ɲIg>G4|]p[S~ c+m!D%~QօkՆE^X!\@RmaĀ@#ҜZ1kXv\[wpzJRArW{Sq_S.':);NmZuT9Fxx3sIe#KƊߘ}86ҷbyӉX4؍+{+(!!56y)RI),Gi^wGW5{8- m%Gq=K$@'ovE+qx2EmVAk ޯ8́(1o^#1c9G_]x;G6XoT#y{}E:^]s.HuEC>Tu˸Ltm'RMJWa%Ƒ T{s|fk3|Sqo:9k`4$_1?TiuQ"]{Py]078RĒbJ R:% tn t nYiƦVE&>#I9Mѕלq6EWdVA]:ݾ@nڵcRTZB\ @jy-yXV==m/Z!(8(W$I}i%doM\ؑgEL$7!-oa'QE~k=.2M6ɞP;>J:妥- hÉ B`G0\`Tyk}uk*QF>%M}:A?e7mꛄt-= %*Hy|zֳ9[٥>W;;rn6t D㪕9=Sj}#5i aE 9p9隫'm2i֭5ld @f}NI*Q'u(C9˞?iVچ穮/^#J@Wn;k4^ ,aI*Vx&a ,./vEۗm\=^OV]-h;"Zzj>Q veJ@b\0:gM/3o\a̷)H#y֮wT'"oZe|$9 [5ޕq{IxA tczY듨ꕞU՚>tgk7Uv;<:q'lp)HZ mVKQ\ɁX\P@+hZ}w{ž %"ckն!Mmø=SiW1JڻCZۯȓ[ܖPOpg}D#*ڮe.*;'ӑ=j;Wy!o8)6-Ǻrdp#ﲝ]R_a$ި'iް̢fH ݛOQtOޝ;^$yO |\v};b }x@鞧N~%ċ,hh74ODk|FJF2:jJ 9hmiʞBkf;911<`rTQ\IQD!EQQEB`v! (B(((!?ukui-control-center/plugins/messages-task/about/res/manufacturers/SUPERGRAPHIC.jpg0000644000175000017500000001240014201663716027022 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !AqQ2B$4"#3D b%  1!AQaqB$"D52TdR34%U ?y8k\qG'PU8h$>NI OLz{5%<%dzR$f Ni`8h@9x>TzQi8k9`rqQLVRM0N#`}>M$xRS2_ JǬ5"Ji枙& #{HgњU' VtKӑ|\G,d U F9~R1J&+0tklJQ]A8{چ'wXj [yЫ Fo<=m~aA ro+>J :hTkL`*YmlvZ= zص rcC tgp}sѧ]jיzzOybJ6ljv2`&[Xd=LFIc#SB8vWz5oo3hMz=pɲx?[{{;!wvvSmbnm%9QֹD|3Nz{42L_Ar H`59IHjGR'4fQO7骎%En*.V$%,&E,-Ep]ʙccZE_~^wZ]l{ަn: .hxT`,{žZ9 me Qf՘cim-2la9B=Dbbu4R[eCq7܈USYIEY1L%Ӊ|Yꩌ:i5sw9cwM+м]ovŁq4d\Uo-M0rBjoظ#i|2 r*[P.xd6jF;^w#tN0ցjsx7;A}!`&7d=@P`kj*D;2Goy[<`^zښd>H\Wxm!Z4 v-,JPFC"x/iw5>eٱ=M*G*9Jdՙ#|he8.k*I$꣰c($+晸WwB0t 3)$~s U $N#VҬ~+gZ)dFHJډ#*)UWBuV:Q(W}k?G/˽dY!v'0ON9Bȗ3M%,KDֲ̙﷯X;v,B;K1K"0^ٟìLJC+_\Ƹec6TIS%N1kTڂu  >J>z-s>[H/./uR1l׵gn=u \4tQAkW*;]0% 9|_~09}xH޽6ĽHQ12{gY?+nM]s 5W4XU2Iq4Gq7Q/UYeW(Z PVH@!8g% kZ1`cY!iɭNǸŁ'ݲ&5) z*A'0OeW"?5!9rK=&jk4t!8Ǖǣziaӧ74fA4#G<"9n4x w7V $tj(/#M];u3&_O%@?Jtկ5`\c&<_􆮾#0T*'5zKnyn X+V3yUU4zH(l0]aZZy_;旛+UuU@y/ș+7W2-2I"Fۍ+~V8[^l:u )eY"`^D}|z`%hg8%r[ ɍLk|w-Zs3"5ݞ][\u膝 }\Zg>Z:u|mږH4٥^@I앱 t5Klm6+ל&JD#@cQsVVS) iU-#=+ ʤbǣK$X I@9q)LG^k`\{9|앶/R^Yj x5έܾ$+_d+P=}b, R^ &SQڊmbYw,ݧdKViqĖ12+ZfDbciGS !1l)[Cga|fC֚'4fEQFa0N=Z5I48Siq4SIO$~u4*G/ԉ*Szd$^z"}FjZNX~mATfգTL9&'OI?u0^!ԔL_Ar H`59IHjGR'4fukui-control-center/plugins/messages-task/about/res/manufacturers/SOYO.jpg0000644000175000017500000001657514201663716025740 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]      1 !AqB Q"2$&a#4b%3cTdE'7*  !1AQaq"24BRb&r#$ĒD3cd%6( ?y6bI.M6YF َhMϷnq";U&_E3Uq€ k82 +6x{5$Hg!—|(>#ΞDž liSרf_ud`h?lIgCOa ־ag> ^^H4$6mSc'Hx)XF-%X̂^c` @0ҢMM=r=nrqb;r`(B#$p=A;Zp$!UMZQDQvrń(DTF*gbMjrdW.yw}i&M3LTuӥ'P#ÛYk.,J14dNZ8Z'EVHIi~M:ͩr|1M[Z_LKav[- ^GE4B qsW;2kLJqn1z5 QXt=9y&AvZ[  KEs!@FSX^Ieɷ (eJoX)r[x6OS~b+K$^=ьXR BPCfoM`š5&lc]ebQu%H|:opBFv+B(_ARaV@%&zMɚg_,vA/[l%7} h(d!_W@\@P7Wq\&^a lon$Jֹ4mDT"w.9 Ar Z0+DUf~dJD1@Ht wЊj$fg y$ڶ%.S=_rORJl mϵZԢBvO+R+Ss:1WyJƔfy_ -{52W`zv̧ײ f3˓ö́Q0m:]ÌɩZmD[ :;X:F,4 ZXh4Wc '4ok L5,NX&("]-BAeퟅ_ :=8.KIVeͨq)/ę"X;(K`|,RSrO9޽M'?kH̸zav/w[Mw'7奐,:)sbsJ b%j9W&)%b,H HD )S ؚY9Ґu숨%~A,OR!D}S`{_~xYn B#)_G ʩ.a[_WMOqW$j'AVLhm/2S[HYwuhbge #sKXxE28pr.D'y|{/ If_p$fT9!WMY^rKMkE-1ImZd;Hd˩z+IJ)B/`f!N;&k1"(h (JWz;G?™k I}Q?eh^ 44 QɒJ䑦=Gf'k)%n'R~[ji,v6:rִ;˻ 1|O ޶]I ZlillEE[ss,{Y}vzByT= PG/&%ZbX]k)~uCEهam }oY6 67/[Hk]: -f#ƺ8ψ.Dž; ʙŸ6* X䓔҅G!7\lo4s)P E{?~ʶW2wE/@'Õ3+(h>mďvnY;/CE Oi{֪-)EH+,IfSAmJD1˳|y;)7+lPp HfR3ؼ2S0G{KkKi6a0-M=hyϩAMFZ]0Ԕd$Q!RʞQ=!sdReG%ByRV9,S#QH " []5INKg I[-!8 䂋Mc*jFDڵzgP%SQ\jljPJR&WZ,FwNaJ8B(,$O@g8yFsL9x^&2Aa.xqseԲD2P6XIXj#ey4]4vbi5xqRӒGӲ kƤN !+z` QLS&V58PqG+\haiV [@ټ';Eznl_꒫d'Gd3|BUmOv/ 4"^jpFL#XTK5L;9!MT% x=9a5D1C=ĀbIuj(Jt;SFKBJ[eL`H*T}@a rv~2DUu7`SyTɉ`'^{ZZ\m̶JN)_ZJ99VЅHT)yf#/pr~}춌ґXd5_sʛnG\/0^Yvc~b{<;1,/i|?3?{U9X|\x/*Q4'ۼo,ٻߵ{Kv`׻rPjv\'u~Nf?L&/Ż#ѮZC׏qxz=zÂ,7x.7.{kslc+N߷?w+˟16^y>@ٿ!ΰY}s]^zip?+c}}vu:_'@x-x+|Wrow}֊m};uNٿv`g/ܾv`>g"wwٳ>[4kɠOϘ?gOp|i?}uZ4v'.zzX\*kpzrs=~coukui-control-center/plugins/messages-task/about/res/manufacturers/XFX.jpg0000644000175000017500000001242614201663716025603 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !AQ"B aq2R#$3C4Tdx9 !1AQaq"2BRbrCDT% ?y8k^qK'I\ G ~ޭj CҔpDnL/ҋ Q܈ ~ZQL{Ui8krTU=I愉J@ u?-O;g2zia8`/涸@RNC9-XI[%Cok&MTّlopQ=Cq0(}^mtvY'#X*6-l:_R(ގp0kV卣WsIW" ,?UB+j *ZCk o׫, {,(CW013:1/]ܮKxiEɆ(Ҕcr\8jERq2sfq-D>ZKd1HaU;oLPPrS2)9?(kMuHDIġ_2j!UנDx=>r7?< 1 ⩞_]O5/]ܬQ (UL"Ry،]J JT\bGb!Y!z2`N%J)y}TnVEg~LOw{B{7hF[ab{"w6tک$X79L9o2LկӁ9!5tEE'"qxB4Q#=jt7uYhg hrRؤ^LR3\ #pvFxrQ=#Bt/bI[7ݷ7rЭ:za߂21!-@wf۴u4`=s؞d;9hyJq\WEɿݾ=@SL+1M6< ֡LGW'iFH'~V^Dy)VziSG8QULQ+Q/a8|G)z\3npMP?i6%ȤBT(UNi)lKPp^G僖{cAC?KW\ {{4 0m!qQ;os@Գ21XCm$ZHK25ݹ"i[$QØC],kfz6utwOnͥ8k8٭n:ج;,GEL^J_Eeo\e[%V1s͇WT$:Bx;6Cu9\SOakb1|QD8︀+wȾl Oz4ةp倥 "?p5I!N=ڲW(uTR Zbצ`'=A)q6괦 豸hDK B%IЕG("tR2&( 9*L  Qo՝ʨ=eldCAV3s:k[ڥ *n*SѨ_PkGW @Cի+emHCi A譥Rjްm~PXq۴b}>1 ̩0BCq"Cw w㯗6m v-Ҝ0v_!؆IHxx uqVtD;"":C˥טJ$f! ?ۂF:uRז}bX^=+xX}R0066FK* >Y.T;+t$AP'jQm)U /KɫS\߉D TBGeT2Es?ŃZ4{m:9V:ix`)l͉ы.iϨ?X^ n;W9K|-L]cbjeXĽ87":戃+*rcZʰPSӱ]In[ny۵r8}t:&AM:`]E}df%ti̖,oo|nGi]U5 kVE$;9UD9GYV#rMz\8|J{,lZq̣kWuĶjҦd/mJ7(J.5*(Q!9Oyas[8Wq`v[Y]7Z!dfTb2%=8e5Q$!y2B6@EI ȼn,.j]yCM1Ll) $Q>$-ʑ| akc-CrM_O`Aػc3sU[I+e+}N-57}3$< b8 l諿b,B9 ao\B G\P|͋jjdV#,-/ǵ`w ]L׏雽y>y_6+m"pYsu8cPc]]1d"y?́e /FCVx& )oj'bI[;1If)ukui-control-center/plugins/messages-task/about/res/manufacturers/ZOTAC.jpg0000644000175000017500000001433214201663716026014 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!AQ"2Bq$4& aD% !1AQaq"2B#$% 3C4D ?'Mt8Zuj;jA:H'_TofI/8"]!շ :j(0]?-]?OrHy\6"%keL^"E]1;"G@TsQ/XN*Vc bFL44!tBgzJT V4cBUd ?-qP>W6i䳭VۢRyHVŕc w32!L_&na[LYӻc%s\WekVQ5OuM#<#0GkXР~IqˋHc1[Ҫ׈-/P{5 $yZPi) ;gOk[S+xvFԍ;V ݓ"la:8*;N+9,+#ʖ4Xs::Ǵt^/-VC?pF/me%of4UgWYfeb1l٫*4ԅfYzOctf̔ۆ8m* bS|Lux]dSW8uJ 'ݲ&:0^o.nE27K8b} Ǯ2,FU"8$1懇8[ĮunH+G:pE^?O毹 IO$ «}g ɪvZU'RaUqU/$2)r?-8.[{b}#mדuP>G,,+gmīmHؒ9s$  ;* hk vfrŮi5,X 7#B? hz4DVibc\j}IRDR՝t8}K@C%vJ/ 5[#U!W4)հݡ Nm)E4ḻ?V;Z?>krm 2%tW]$_XBT" Ϩ9Ph;xkL"⿋LzO1EZZʎCy¦ثHT€j"Y<={KڞF_1^M'AJ#y]S&/Wo,`&{Jv1i,)|:hcH1R<"}q +8z9|AvWyBt:Ue{wȯY9^%p٦1-ډ x)(ɘbcnboBR//zYq$ZkJe mˑ-E ZjE܅駒e&*8o.HFP3,D.B&RuCDpѯw>MX  D;[vʂϴ\KX" %vKZ䵕q>69*/wuqj`'u,!ɹ|Q3{cͰM2Fl1k~2"=DCV!e{@/qbLO/Ʃ_9W6&euZN0*hXhMűje-*Sg6AV^ՠ \C)sM׫؁Ω dMOaJ$lc 'vvԽ辊 T꘾e) OQx GN8\ }['K[c+yvq|9J"|Da.*ٺcOB1JA1(u06ᶝ0x$`I,̜E-l'xwfYlI'6=D(#,= D"%@< ᔚACU۫p}=aWrX6) +ڳkr`ylH[NƠ!|CmOu@^1Vz ;zҷkZ|e{I^τ;}RCCqNTlp)L$DY \uQ\ yv(~򯒗78Z;ȵm|D/Ar/QZmvڃd\Hc#A8c&z.3nV,h5>gI[*q$=H^| P ʘRc]g[R"nt9[>&i~((H }۸mk\]V. ND0fI"%0I~/#M u{*؋vo{9'E0wo7@=;JYt.[HQ9|+6,X5D$Y!!^5z??1¼%-w%p ?[2[M)@<pwE0DWk+^C]-C!Ix3Ty efnm.tmc1,bpƭHPjS8DEy%#$ZJmR e-= ҵv@&4g{ N<%խV^4x??ӎXIZ4ip9 8`XB~oApZ9Nˋq m'EtjTn^1@a%ۺON\y{Vd  ɱ\D;3 }$"oޫGM.}"8V&n`- 5%pT< "-`GJ`V?N|T'mm0b;OXE|V[/aw8! H$pYZd8x3>6G;l̓"evğ&R(s|\ڱ,RqwZO2.%r5T_bpQ~v ʻQLʭejBI#F{a wqDGZ51mb`q'lka$9DGls_cbA.07yɭ\yn5v~)Nrx mw, hK{[""ddVμj ؽ͟((acħm}DķDJ%k۷rgoZoaw"ST HWk?Nus hxkzt }>*(v&̹ǒ[K=V3նA+V'xN+T/Z%(-^!BG }m\⹯!eeMy0x]kV@Ť; #;s3b˫+2^[ТlJݠlloj~e|oBi&WRn? G۸m6NbT`-TfChZ̕*#V m|ɱ,[ɉb n/o.~රl~\J>yM28oI,{]1RZ/.5\ I-&\]i[asнϬk`)u%VŦŋS&l'` µ4z4b}bv :Yt--,٥V~3J#beP "#LPL䛽JQRH>O)Kϻm)x|G&wl\SK&|)[#HLqsZ_QHs,XpY->Dݠ;܅駒w'_GQ+R %jA:ڥH/P{4%^JI0|^Ќ Ԁ歸)QA^hG~?vhukui-control-center/plugins/messages-task/about/res/manufacturers/QUANTUM.jpg0000644000175000017500000001023614201663716026265 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1!AQq a2B"#$b3TS45  1!AQaq2B$"R4#Tt%5 ?(Y^LЅ1H=*)f=P"&| #Kr(/"&W= $fL( +ːud(Tw"fb2ʁW?t!Lf$tJDT.HI.J9$ȆIxB&.h$"JA =>XLUS3"&c )gˢ?*D.hRI2!eysIi 4 2PvBzeO&ijXGH W\Qe~S=I2xӧPd$B-J򔒴VI$6xlmKE5juT2, ՍHj<NkO>lgsm4ี˗al2ERYHr*,weۈмe{f_Bӎ12Y{{>}Q}/gRe?cUT%HH3clߒT OjTva%ILa u '*5Wý7Ot}b[HF2pe;i5\"Hbul!!y ?Y7qپ5oR`{)⼸RJQ$)Q9D/Jt;0S|'jGOxz1&hu/oQT6'G5ȹKd)/,O-6[p"Nqa*8M`GO:n8lm4`'"P n j<++zٛlZΫ뾍)A-Ylm4k*IDjMCx#&qψZxlV{p녬&a=]%3Ιu+(+)A+FK),1 {tZ^p\ChЭ"kbw;Eֹ:٫M6GiŮY_ɳ6# &ٻY:~dZ\$}r#z345[3qd#Ȉ쥶rjMGwR6*QQ~_m2le"1:mJ BR' #fp˫n1dX]Y4KĀOl5=v Cń/CڄR+h]j5 u ~S @gmooM˷4dm3I_Ck;q{w*A=m+jN먲-pɐ;>%_=!\ |6tG57ێ0M!8C8@ZsaKHf+W/[zM2mn!n\&LjT?J<؄u}exbR>Gu6j#Zwڻ-5lGjի7-cރLMEo,-ISy Q,l%х?cjrћGudz.ռV}Pi\?4tP]Z~o9x)VH 3w #x~0l+PAz<D[9q~*; W>"b_FfM`.#Vi +(jgITP2z@ JюwX Σw:zw %fn)R痢?iDvm:O??Ւv)cG/t|sʊenh*Pr,Z֬Y-pu N>s5Fa1}{/ZԧU@c@iŊ䏨Owcb i9o_cD̬jNuUu3ЖDCwAVWӎŊ"ŏ@Zm(UfeT)ItN'B!e4nӼ/ԀK ~G9x:}>4|`[`-&uM8mKyAq`*O],!M,4;ѓ|Ƴ p<2䦽%ޏ|pJkwh̸dKMgao$¢@ ʒ90(6G[yxWГI `He)#fE ^}= ǫVб61]`6}rF) "-9U& Rp(Wo>f[1>o^*H~OɎGڽ=jTW[+XռR7mXBImHafd]R%9sBrI +˞L3H\ѦIE:{*};3Mukui-control-center/plugins/messages-task/about/res/manufacturers/TOYOTA.jpg0000644000175000017500000001073514201663716026156 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1!AqB Q"2$4 a#DF1!A2BQaq" ?LsLC) >XPF 930`!`t(9sBcmee@=AĮ|<ٕU*8=UY2;JdKWqgR &qLmmV`6<}/{pkig_n:zx~'+yp\]]V4٭Uɟ,zP!f>NB0L.aıd91 \%Pbsh0cP9rP{1+?v6ex6M7[A U -ZZ qq=K294-RP5Ig`RP!DCag mܸnR3Qg8w*|=+_imn/Z[[}j{wbVԪ-u\A4(9ԭXpsHXPJ @>:G㼩ž~su.zڮ;]6jv\wΰCf>NB0L.aıd91 \%Pbsh0cP9rP{1+?v6exow,>oSgLJۦǜL:}'ilքo`K_[m+A&-I+՜YE񩱽o͈X(Ofc#p{TɬI4릎v)In[;ݽF(@MGVLuV\a!&CsTRZKs pIm6k'$RggbVRUwʙDpQs:^CԲdK̑23gX drJݟ px 0([pW&.79](V\>;%W Doe|NR2ǥMެʄZQ=ź3o{Vߵ I{5YKg]A\ؤR; n3υU܈\"*xBf "7QiinQ$vbI3V\:+"T\m]X* Fq\CϘc*f0 XT\J('ݍ^>j?Snx:="ϟnICDhGXtW=XZfլ5(+p@ SHLU#DI]hVxWeWUB!dx}@⠲'GVC#/v S)RZe)J;֨+/̚;}Q? ڊ&䡆!k΍K΍` ҾA9DP j,1_$(nJj1,NgDUDgN]H!,U= I4o*pGg () _*":c s&^V #FYvj6[+Ke9:Xu Q.L%G6U,?(قэN0$P=s=DrYU%G HE, x 6h\U( -OW1ّǁb]d+KbIJǁU&RawW ~\񯖞񏖺{%7cfWc:򿧌}?ަD?;tt?8|/:ileֶKjY3$Rc[eT1E8&ZreLBquR5"n{ Pە3+}bW];[.2ԷDy-HrW'698J(=~8.UAnDWF`RϰL 5|MAW˚>gd Uwd!܀M`1|KOp?*Lt/s;*l%q[kJ#6p)Le2Q" 3* 3/;bD#P VP bJfH$6 ap*WFLZN ): _hm(Hضw% aaeYTqt:NUfRt@΍l$TRIˆ`X7HTV"zUr儢D^A_%|DIf'Hd2wu PaHC11gdzЧk̾ef=i$ALv V6%pt-k){EWP<3 V֮0=i.m5:MVҲxb$y\+%cY ,-"y{\N<ٕsS}WbR,5:!ej6mS m3xligJc1pH@8jQ8lRmB%*:%Ify+9D6XkHG֣ZU Zi() %ĵ0i&ړ\eІuƙ#1rrTbYΉέed~l*eぇ&v! ,k#}X`}0\щc0sc: JK16`22rbWyA>~l?ukui-control-center/plugins/messages-task/about/res/manufacturers/TYAN.jpg0000644000175000017500000001222114201663716025702 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1! AQq"2$ aBx34Td%56w(8H  !1AQaq𑡱"2BR#C$4Dt%6rST57 ?|Fk< #LI(N1:bLvC')sP%>I}B8"G?"4 $0G TD|(Y(L9`y3@G?Q`1&ctęOS:J|2pD.~!0D3G-<8&C q ,G =PL{Y&c3݀d)3CG?Q`1&~&$ϧd3X$Ľ]:[ }B8'G?nHLw0~{4ے~f@HCxhioJfn,Vvc^y-]-LrʫskԭG;1MX_:%aJnR+;9)p<"XCdyx/YO$C~5llx5o]MKٚ._U>YXR ݦi_&hTz?0ͫv"}ج FJ+rPM.M5uCt 4l*,nX"8Dyt(гj2TZ>UyBo_5% 5%,41 0Vr9hƍ5zADN iX7BDbg0k7gΕӨd0~b&XGWm:dGNNT^ڒ֥IJvaϒhk'iϚIstKPvbcmZaP*4?QXVNg-L}4-r?2UOj;Vg~ϡEeV+VoWV/?9^gpZ~",f4]Un 4<V 

k=Jm%$*ekIc ᒆۖexJ)҄K0 Φ `֚,2vIdS\D chѮ\("o$8l%|mb>bAfx-j_Z$UboksrRio?m@uaRtaŰdun";pnb՛=1fAҘ*&p<#i^;:r(:/(G*b/Ʀf@Qî%ZϸGӽpɸ` %Xvxg_(F.*4Rm#Y{@h2YbU%CV}:{fIrJ^Ԕtdp=vּWgֱҌy]՞EI=óP5*ښ/: 2ȉ\nnb=Iӛ]=M6"ڑtkFVk\V6nyiNǑAi-RBTi cԥMBq@ahaں*(5ǂpst{DS0p,/zV.ZWR dORBd%mLv\I;~kRw BoP-$dTii$Z[ej!rv'D$quq4!I ~"U1 bm1Ҽ)M͘cF<Y[VA ^2k;holEKu' &Hf$v2Ba;#Gk޵:s4z=ow=FDPihZ7eʹVVBQum#gԴ)$P@Glly]W]b|=Y6O$>_Moq"!/~)?hQ|F`y3@G?Q`1&ctęOS:J|2pD.~!0D3Li0BH`.A։PEQlFr(g(!1&~:bLǺ$3 %:u@&e\B`fÂ?VX?8I)r@H/bukui-control-center/plugins/messages-task/about/res/manufacturers/KINGTIGER.jpg0000644000175000017500000000737114201663716026464 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1! QqA2B$4%8X3v(aSDVHTd5&6 1AQ!aBq$"24Dt ?> < 41C4c_˙]Ɩ: ;_SEniR)Ta5uxnwCWyA<~*Wsn00_he9/\̇r4f)r(<7sJJiî`sһ 1R qC) A~. 4d?(7q0NÑA[TUsMGlsPO7_p"u<Ѧ{wL&O(3@PcndMXs4,vnLޛc}dTHmrƦm4ކUt~]_8Th\>iMr|'hv D?= \ Y~K?P!= /ugpL;q'uzKJ;}lSxև}KhbqXXoɡNJٚYymóK}}4p>S1v7e/c5ذ(8_OY}k8Y A8KW)%N \RpbC ``LL.[^'C65\Nk*T6ĮVYd^`hb/-۟:mϠec3y#,t)(@eF WGbӥXޠ7?}0vn(vk8*ӴL+k9SjHbKbsFE*c<„Cim'#YԺ1*F+eIRL )g$99*U4dӈUjԞ8UztQ7sz:q}4(rގr>Lw k_ Z^GU4T鴽\ef8*)SNLeQK0Ժ/>KMTFإ҇:%bL.,l#b3S?ͫǶퟵ2UHd֍IkX,$~$YLx,@ 2+i0*Ԇm8.Acd cpgHm%ÍL]^d;r]YL2> %?C2C X4ŕX$,6`#ؘyR0ꇇ¬)N3ž{Z}dV4ԫ!G%RG ك=`iS++ZH5]T8p+m^+ 4R3XO98r(& 103oxu޳)Է7+ԓ 6IYJEIOV~q 5 Xs 5Zp,Ye"%꿧rˬdTd.l @ӶME"gqT( 1[,MZ }4ɎoM.pCt&!@;GM_Sa$<o^KҒxw*ߦy-S((wp AdobedF]   1AQ !$qB4a2D%"TX#St5&FHA1!QaBq2RbT$4d%5"U ?Cމ/x4Ĩ[" nDr)Dꄼ~ TC.)PJmb%m[w /1*" ለ4=D0JQ0iu1z/_vK T!*[X[FCsLJ5xb" a`0 A-iRL|L^Kb@D:1킕iJ"V'~7 ABk:[G~JN^i\MF@pߝ [v]gdd.r<7.kEhH߭%jdc<KDܘφ[Xچ?5ddr$<'IQ56`8#j`M^J<ѫϛs]K[_6[eL<ѫsovwiD-_35v.m g-ZN^{^nNl([9i2t?7_- g-1Z:}WaofB,ZNh2}^_>gՄ=!sۇᝌ9f!YcM4-(;alnGT)I9̒Ԙ5Q B ?J4PaBÆ;^*私L) t"-Ri0S26OMK~Bl(> RxKF Я"҅p7^2Q߀F"fS6SuRu\Hzp0ΠԒPTUm/8vppxhhxqo.{hLY걘`K2O.ȩچsD#Q4mU&P+46=z”C #s)f}qz߷dXMxOPp|S98>? n=d ??'vvt r0m" O(}0'Wpe'K0]^npG:єg|-޼4 :T6\JB^B@MD*a x1PzbD; n0F=G;6뼔scNL$/6Y )iArj( isi#Ƴ8kG@T 'qӥ  A/fqg;+n;{,SnDZTYRJ(X A ?f|Q.v9ek ئab8M\ԑ# F Q'7Nw$sffi}Yoاy]Ю|SdU +;wGkDf#ba6_g6rt+T=stkչ|2FK1 aU޹<Ԫ.npsb+T?n8;st^-RS/!0tŧG~3v(nq19az~%M~m%INT^ p% Paƒ&36LR$zTP8Q>!"~Ǽ;>0na][t;-myK/1*" ለ4=D0JQ0iu1z/_vK T!*[X[FCsLJ5xb" a`0 A-iRL|L^Kb@D:1킕iJ"Vѫ!쵷qo" l^CX A{ikT7SuP+LGd`BR+嵈ukui-control-center/plugins/messages-task/about/res/manufacturers/OMNIVISION.jpg0000644000175000017500000004123014201663716026623 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:31 16:39:32]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOTI%)$_SzM:Ts} 乭-@DY4E~^[>!œ2S_ 35z8K~>ܗoȠr@2ÓrDNrN'iF~נIS}[c=Z-1A )PH)$EkzwNǕo?6\v ,ckfT7{XN3DƵ=C'"T:׳`;:m!-5v{twbcĶ́k.ۚk?Hr4lدLp y\pf7ٮM6353zWnVџsiV׋jUs[_V߫9UP6Ӗ{^N^a:}w{ zl) t:?GɊyqN9!#DY}Mz>{(<12틦?P1r0gL~0-Hsk?_VL91攱GL+?u5G3FrQ=%Gku|2ڟHbP67n{zlu#кR鹌mWeko~p:gF}_*%kk;ps_{Okѫ}7kgl3Z#wE /Apcjn\_\<ܾaLRhz_ܾղp1 8'ޝm6:^ѓokwuީSӛS1׻ԲX55VeVFVYnM\ NDZ.ӽrqKif5K=ZMȁsY?WiH䔌#)HH.~7.ۍCFg {7 7Q7]WGp8=hgM7~otKVmMc7X}Vçﲺ?@72vg wTI%)$IJI$RI$I%)$IOTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM%8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIMGF] AtherosQSa]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOTI%)$_SzM:Ts} 乭-@DY4E~^[>!œ2S_ 35z8K~>ܗoȠr@2ÓrDNrN'iF~נIS}[c=Z-1A )PH)$EkzwNǕo?6\v ,ckfT7{XN3DƵ=C'"T:׳`;:m!-5v{twbcĶ́k.ۚk?Hr4lدLp y\pf7ٮM6353zWnVџsiV׋jUs[_V߫9UP6Ӗ{^N^a:}w{ zl) t:?GɊyqN9!#DY}Mz>{(<12틦?P1r0gL~0-Hsk?_VL91攱GL+?u5G3FrQ=%Gku|2ڟHbP67n{zlu#кR鹌mWeko~p:gF}_*%kk;ps_{Okѫ}7kgl3Z#wE /Apcjn\_\<ܾaLRhz_ܾղp1 8'ޝm6:^ѓokwuީSӛS1׻ԲX55VeVFVYnM\ NDZ.ӽrqKif5K=ZMȁsY?WiH䔌#)HH.~7.ۍCFg {7 7Q7]WGp8=hgM7~otKVmMc7X}Vçﲺ?@72vg wTI%)$IJI$RI$I%)$IOTʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-03-31T16:39:32+08:00 2012-03-31T16:39:32+08:00 2012-03-31T16:39:32+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:d8c5e77a-7b0c-11e1-873b-c4fd423be6eb image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWN*UثWb]v*UثWN*Uث?O|ZĖJ_ִSC.HӶ.U<@LE(ߖdMo*PM?)擭UwrT,њ[28X6&K2DcdyϾY.p[ `aNBqey9zϫ\W1t5-C FB@$Q=fF,..]8e\IZ;v*^]SWgIӵ2s<)oonDݙi>f~LX8ш7ޕy_qӥ_'i1]hz$]C̣#JSÓˊ},a9Hw e~dF/u8ӧ]z uL."iS1_MJrd'q_eX&oS#\`aukq1x_UvE7䙍Y/2v݉9tyo~ `i?ހ$Vep*TK4yc__]]tzHfY8/D>T{%4=I.)z$/ٓ2z W*?Li;xx?}G5-Huiu[e在V[Ecr޻˩,_?N>̖ˠm&x8F8:1*[M>(^4Zd-0_c-yhZLqYAHc$UfLu>>fq 4%ҮnoY9I=f94:*FJ ]חc__Ҵ_\oݪi|oJ<毄>%^AѴ4]E{cY*.Μڟvsˬcs CE.'ݤ+(ۃ?k{CMoSoDxsxlrKtFTW=o2dK~Z|kygooĞ)BEQ\͞e8Og5>4e;cA'5un-nԙڠHe/ɽ0o~f`vyȎMԌOa=3o {_Ru=TcwW? l#[Sˠl5Ok+'PlOj]@;rGm/:ysuaA+}9V[XH6\JBfCּK}s(S|L|!TN*UثWb]v*UثWN*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/AOPEN.jpg0000644000175000017500000001165114201663716025777 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !AqQa"2B$4 W8XxRb#3CDՖG(  !1AQaqBU"2$4D3Tdt5'R#C%Ee6 ?>LWy3 #xLIT)N1:bLTĹ4 Of_~FH"C@[$H7.ղe&~Do 35f=8'LI?0)L܉\\bSr`2\=#EU!8 B;MnTc-yUEA"EIk3NhQC-JNLDe3 oX֯z{:VymgDkA{ @Ug U=gyލ^8|,yu^a{"xyzuu,węָ/+n>9띶Ir#XRHX^)eyN7DLE'OHܣK%bu)ԥSW'gﶅfJ3}زr#r$*ns69o>Oyj=it~LU߸T}h3[QL9{hn" #eg SCURf (;ɎTn |Vˤ}%IhohyDl 8/_+-X2@ADa('/SlVL^;.>l pQ;Tq\J̼˷6멹/A?@Ho-ڰ$J] J3qoI@"Y? $]}lؚ*l%(FHLaaK6c\Bϡ3];L Z@a !aO }9߷M>7R"}TL7r BK6oysz%e_407%|l&ЪQ:h6a!0̵ovdS)o[ۀ/\QrZ±bB'9c}ni,k-rG/j)~VSxr+qn~*[s7m[wk&o_^:;,:ۯb?3b֍ɉ}@X~7יZM+ w>[U/[޹.e"^!zVkdJWr<$KbsK+Q0l#hDb1064N'$ nq$xaB(^LixE8#v,}B]BZb~`@ԻoƓ,;VIiiMl8AZ5NO($_(alHM\l;hkxM< 8n FKrN%OT L=HK-y{\ŝ^f2P4#)̥M`sE7)HV՝3qx,1&ؑj~ֲ蛆ˉ I'RmCeV<"#]j7OULryF` 0 ʣi=O fVA(O@[58n16l?8X %;~_>8aewt7SlnYu˷F|ݜ J0V+c k}.֠Y֬跤jQ Q>9[k P*;18m@"!z[-*s0* -έmKA 0m؁#:bmKU3MqxEtRL i2 USH4Ҍ81cJZ2w-0X)q|AMcj;fFɞ\ Ydamي:mc L a#dKxt̵N62o1>yB@[xfۉՆԬHv¨K,BޡXUcZphZ{@n!qR`z*p pnR>(!+00Id9Wzo/-,'5> A-<<#l@ G)W;Ƥe^:cMsI1V7ߪ MGzZ:_PdLPp/rfUNϣUX54K0S\?w?/xo=w{/o-J6ѿ%|-*-HEBIQ>2 fH;'(Mˏ@Ŷ q/XئuK-chM,ԔMAM72]2CX(ɟJXZ5:8GQn\ ~Pu!#˟X@ SynLP#ːtwQ"|޿(ukui-control-center/plugins/messages-task/about/res/manufacturers/3COM.jpg0000644000175000017500000001043414201663716025634 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !"BAQ2#$ aq3sT%x9:y1!AQq2Ba" ?a= V(^ 67Bae жѩt1mlh[Yr"65r֮aHMРjXryCt7e[Sq2cS9=,?Z)8m&MoX䦢G'IԊkc눫DE#_~m—)MlhQU!L+vBhognM/w4f8Wv+\$z"87D= P>A8ڝ[ڛYtgvD{sj{ZU;{f)|@t~٧٫v`z@PlnRÐBm*qXw#Kjb wEUO$ v[ elTG'8 J @sG( QU\%ڟ嵦cYiK-o.35p:dLu j_Koqvh%KMrڏRRbxXٞcGlHb 7>Hfvbomgv*E%>ceŨhǴ[՗s8ycUGN\"穧;{N(qU7ci_xZmHS8#\21u"x5Һ VlCO&C%ȜY ]I7ІX\sbct(^z $ee$mkyXyWΌ r0%>A#,Q]wK1+ `@c ~DEaR<iuc==k;9m1?:9]s }=IiQѰ*cv׊㈭$R)Sm6Ҧǖu7u"gޓԛf@tN SJ/=c{Ҟ`4M귊cFmLV/4Gdm)Apr'<]7K%Ond5,J;7c3r gpQn"=pdD*7&Ef.킔`&Fa(=s/ʫnic8HT Qz&RJخ޷Р=lqAL!r&ho1UӔ˟K3\CĬؗD Norg2ENu!%1T99Q1?wOs"'J`:"%ʃUv˹Sw.tSPVh&!P/yGznxxfBq`cb  AdobedF] 1 q!AQ"2B$#4tw9  !1AQaB"q2$R#Dbr34tE7 ?Au)$pq8CE˯Œ!pBLHt)13F-&Ό&,!8A5 ar&|0S(I~p^!C  prl4Sbg W:Ky?ef7<^2V6K]oP%PyOE%.eqdxZwe]ukiPx?x2D Quo}vX.}5#ZP8 ˰or6mwn7,`ѻr5lq]) *@̢ L/Rۥ|S֑Jή;*)! Аt>8! oQh3P RgԾkGKo@dѦJԊĪ+8؜BUIW#J%Q2"x6 .?psCS9x[V)r-nj'P8;)x(CcmY-erTzj ☛57H [3ZXBQ')[KJ~H:mT_h(w*z Zzo/VD^ڇ\B;6ջW|ii_|C 5J*PHf+ԑՑE~AW<[M˶6dkӳ#KD3O Q͵9"TApll}/2W2&#H!gfF4IejǑ:jAS\ Br U jqu6L7@TT0oQa $ I"۬}OUjROT.!I*at6wk0ۘ춆6nYlԌ.j\kWrŢ)hokSWuH?)r7)zG&lz~Ǹv*XOTMIJ.'Ԑ7, Q iqzQFSyH ,ɲ0(Y~Lݞ8#~@z먤'mI. M~7C-1kc)ci ⍡WR'Y] pNզyOSH@Q.nrM.ҪkmE9TR1T֬J@=sY{L#XP{fHK_6sik?O͟6Oh6n=),λQ["2/OE]TB- GyT'iӎ~R/y[k[m ^C)t(*mx [/QL˕9 \FHUFhZ2f Sޒ0T0/k(|~- ̸0' BT򱯳(ҊWpL mscpI.nwr-jC@"Č+xxejTeLTT-sS':4Bp]Wa\~RR3'_h57]~v-i$K3@ sӓpR8TR_Sr&ۧy${gR ;M+%CmsbzE%* DEd3c!{;4wq+:4>G.w A;#@֝b/ͤѪ ć(!W=JV2]!I%L}TVw⊺|l B ޫۘչXt&nemP/#~y_eC3!Ll#WMH2d;e8xxܼW@ۭngP\fPBʽ:g󅎩vӤ 3nZ +VකBO6b3>צ^!C,h=6m{}~i}H&x(Wt+ݢeU ~R`CW!3r&hKW܅/C8Ƙ*3F7=՛W1YJ~bNQ>꬧T]뽉Dm&Ԟ@ݣ2 8A}aXM{㍶4m UUȒ~BĤh$FNYݵWRʋTNc22RKudy4}?(y>|OXAQs^Q":_rP=7,oRF'qr$ʏ|P_(L 9q#6%6R?R Q(ÐSߕx'[^ rĞRRJ(7/.퉵{h^Zⰶ1 d΅lD}&`19D,תEeI@(&pz[ﶩ6}v6*oE "aRSS(~v7ofDM,9ԑ{;SDrzt*$YXgd@J(֪)g69w-xu•5!{L ̞ǖQhSdI=S3'8DݿEg!WcHYdפU%J<B!@uZsNf:OPwآ7::Q.kj~{~Jt<-mn$ISZǩ)=EQB\I* ;nd ,*\r^n=E {>6!qJf\[MRj0bKjuҷYKom$Tⅲ3!b#-xyS:TA ^îAw5j%J7؋tA91i L4ʖUJ'H!~oUۻ→̃).-8PFp]†H7-;ׅ7.,ݞFh'KM2xS&It7=л!5N r hc:0 \!׆#&݅ `A vaL%!.]xa 38-bDEˠw}OǏ鉜7?ukui-control-center/plugins/messages-task/about/res/manufacturers/LOGITECH.jpg0000644000175000017500000001227214201663716026333 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1! qBA2Qa$Rb#3D%v8!1AQ"aq24$DB3st%5 ?NQơH'^GQ G٥73Ƿ;WfOl/ȶuUn&=#ē]yNw *}Cp^`c."fpH"zg7Eڣm-UI`5"2)\EЯBD Ģq0D;)'Ut٣Fi.Oq= Jݤ4[2Úh㌑nq3ȝ'g+ LR&=YԷ^\=F3HX{Wp殕w=>No-h."8!7%1NR) Sh D@@,WP(:j((^vwD{Jt@)BNڎ+:9|NO$g^FGd-\"R,7'؜p9[.MvEYʕ6`;3΋UzӬ\<&pA>j.s1 S~u-f쨓ITLx`ڏ$c( Ɨ:i/;Ni} "o-t\|R0&2 L=KQzѵv |r/ F,c0k0"\u #-X}jz]۟n!Elr/Ԛ.. 2`3LjhRpZYꍍIf'/ c:\FN6l !X- -zS;్.h6rנ5*ŎQx˝3aW%Nׅ9Yqnbayp=o׷swW݊:~-vsGc,ۋpLj#] "7 55G/@J;"| LSx%i:jQơH'^GQVz!ޭ%o)W" \a,4 B>,G `Conn[y P~;:ﹾpFu}aAYH-EXMB,Omx%3ZxDP}nL;xOjpscnXn{lzH1[?kg G.dcnEmdC#L>^ ErJ$ 63 GB„:I$Q~.zpWsEvaZ.GǤ6TqNGfRli+,"܈T>7~錵cXT n(A4SO+L8+ahPr'$p*A^YV9׫V(˱{f"9~Ŝ!Y^V :q2GDͨ:-̔m . 2dw.p%@J(^vwD{Jt@)BNڎ+W>)\Lԋx=(DQ!ld"[ݼ:A|ַ&ӯa OWW(W1+ºD9㔮=f`aj([<,Ƚv:F>B&8S>xܻgj^82KʉL֡M7+#>H|nlT%Y)ʧSh_Mz5`tۦ g @`0DjzҥJi2YdlFmJҡ-8ATJ pK݊ͺwV ekVXWs^:Q*Z5Vں["մ<$qF2 _\g#,q&'"wi%KStM=T.qW+Xt%b! Qf1o_$t@Q(L51MʁG'_HS {DV_pyY^r""Oѹ/T |"ZYրd hY3gQC%f1~rrxXk :Q/$d䘘Iq\zU .fԱ:]kI|6=D Jb8R9o^}-6~೽cK}#jI/ĢDJҰdd9X>oPpcZG@Q>\V7jo_i{HV] }q֋FYpyZ_p+}GoP_OYPUQNqiqqAyCLDZ䁏Q"e0 [RJO1el!ZNޅmvJխZ/~#n crH\J"&vH1BlM=Ҏȟ/S ZNZN5Qs<~ESV9 6U8Q̤ر\fR =XCfhUs`6(b`@@ Bb"(RI}"O(4J%rdRLD[H#/ PFT#.oH\mkoqL<خ̓aDD;'pnslfc}h"u$Z^)5yP)=Z{ Kϩ lS͆`n#fLЊۑcy9~͇8VF&eby9FcD=rBmvnpIfDSNDL`m(U_rVkDgQ2K֑ Wv5\$e[qun~8I*Vy$̪4@jM^G[n]5~[;E@nJ+ zDTx`+Vt)?ns<;tJ f$HҦwuێ \ wԘr7ѧÇA!%}ᣊ> ZNru1R ׻QEH'QipE_yy{x>&*az4 )%A4L^L1RK-5G/@J;"| LSx/ukui-control-center/plugins/messages-task/about/res/manufacturers/GIGABYTE.jpg0000644000175000017500000001317514201663716026333 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1! q"B$AQa2#D34%rCcud5EUF   !1AaQq2"$B4R#3Td5rҤ%Ee ?y6bIGrma(m`Mr4GɄFk{n+ݺ7QS:ʪ<⊛W shÆa Bn |=yQ,,>NrTͦRGZOL<~0N`ĝHg]oYkӏQx->9j(~yт%fEq#WIZJuSHzuHJ N@0}(0*`YbX0h ˰L 960o }E`,kN+an%jѮrggT7`ST2> VǺ)!LG&$'˽|פI@-xJ7T,o7`1@dSr1Z&uK\҄ewԕcNK'9 ϏrQL11=ueY*SAŵyi퍨C-@tzV>֖gJ5b K?ьث^KFx+P7bWs UP_P!Djk0 DGqRXIf "0ڲJX̞ =4[4W6jT-Gu{|.[umTm'UATZyd)91圶ˀL$ ^%=˔ʵTP F-Z$N)+(P%Z4u*VS\Ŧ@qcsO+0 ˰م!o}] {]8qOL>L*7HG/֤ޤ貔MYu*αxA9!P o{oX-QE"3BdorcZ>i15@4P?^WVZ=__;]jɶ)e"1Cqlx㱖Y[f#ȘC\DʮKLJ4xsoeG-]NXѨ7iss&Fu}nrZ{YBBO7Txy[0ǘ4N+ԗִS=%i9.O,< >Xk5IZt iEivnѸ'3P4st`0SO/Zl+7<@ 9R-5`o:=:ycnBe Zh60xs0Ę\v=X|>f$֓f&}AJ7|\PWׅ~73mBTLږ0׭nn5?b)^R)44n黢vfF-sXD96o{X{ZPұVߜgY,*G҉EfN g\/ްlq遑xlm0k{nMj71tUǭy Da*dҐxv^ k)|]&2CkidDBw^hUʻJ`0h<1DD[K'slMi$st#G WVO0YmtؤgP˓Z{˥-exn>C2erY 9NHu] _- !>>:OwA,3hcE*n"9TQHm^LUɇd CL z6@oZ/ zzz|>f+5هɁG&FRUg0vǻv|'ٿv :8z>93?7|15 '~RI˸c;v{2|Aœ+ڷB׿ֿxיg|Iq/ScvoХ1w]n6zm7gxu'q{q:޽b^M_>F6&|.ccX-ٽX;5T|⮬[#IWtӉA巳g6sCMٷxamB?s˝B a{sc컹_ofzx״>UuOKk'ɖ'r~{ܵ + Dl|+/`=x3n+_W}ko=A'wYe \˅Ǩ?w$N)w }r˩(5zkHzu^[W亿v?1YElsdTNiJx -\~ϭ7:)g7,Z}e8c-}_E=ٶ~=xJ%~unN9eUKfmw~]Zmv_]Mw_]?ٻoʫKժ3gS4POv;mߣU4Qm[,sDv}a;"9vZ>eO>Kꮦ8\@voorr<L/#|qnR+E76,s*C\Y;=C t_V1.5,w-sqT( (N][Z4155goYGqa GǧNQ}O?3}oc {l!ͮ67~ޗ1a5dz_ѭt 'ϧwլ3Ov~O}[@~ߴs(u41v. luMDo=A'wYe \˅Ǩ?w$N)w }r˩(5zkHzu^[W亿v?1YElsdTNiJx -\~ϭ7:)g7,Z}e8c-}_E=ٶ~=xJ%~unN9eUKfmw~]Zmv_]Mw_]?ٻoʫKժ3gS4POv;mߣU4Qm[,sDv}a;"9vZ>eO>Kꮦ8\@voorr<L/#|qnR+E76,s*C\Y;=C t_V1.5,w-sqT( (N][Z4155goYGqa GǧNQ}O?3}oc {l!ͮ67~ޗ1a5dz_ѭt 'ϧwլ3Ov~O}[@~ߴs(u41v. luMD 1 93 70 1 72/1 72/1 2 2012-04-16T09:35:02+08:00 2012-04-16T09:35:02+08:00 2012-04-16T09:35:02+08:00 Adobe Photoshop CS Windows uuid:d94422aa-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:65807ff1-8763-11e1-93bc-952fd8ae208c image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثW'NC&I?ӏZw'N em;tmmk'b1=@!,[w 0𭰻_̳]IgvԹ)q:_%8K/O8ih-,+)g[K9-[pZ~ q/?&Z/7,H.? GF+%NJoӉyG˾fP~!ŋI[rK%\%wz<6V7W*8"DNNiN*@ew$A˩F"PUs4bk$zfCs!d}Rz'厓zm_ZO\Ge~S]WlQomoΐk-m4inc.Z[CrÜNoַcaK-ﴉX$v1Ky+3Gaߒ-uI'o%Y4.B|gmH.Xc8'yeaYo4rq܅^#r>xD;LOV("qF#v (/yc"Mev(v*UثWoZ qWSqW5d8l<AXx-?o5cny?m?2O -tXam#dV>[wwH|'Տ˿ú??|0ysH?)$YwsGFI5` Ú7?xGs]qWq8U}*>ws]qWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/J&W.jpg0000644000175000017500000001217314201663716025523 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1 !AQq2B"#$d%5& !1AQaq"B$2#R34Dd ?M9741& VW"&`{4S==ZR 7&G.a&K0ܘ #`J>)>S%-&ڼroi cxL~HE0Mݥ7h# zz%nL]J.L1La0j(.G.|S"}=)JZMyP(&Z\`K)oGLpiJ8&K_Pܙ\b .(r`6P\] (DzmLS|jV3lڃ`?NM8g/"5>;kj=BB:~ДFh@7&+C ؐk:2!-(uՎ_rpAdܶBr{<~Y1 X]n4ȋZxq?SԧKH& 1}*OQtԵeib/႔I_8 `=OAKEJTSV&϶`) 贞5/ mҐX9maBQJT%`g Ep卸Oe62RWC6gG68#KSnZQ%8 siBQe<)7 .! %djkY$]{:|7}xW>KX!I:,Ȯ:J&־QѲ[K8$?R)y%1YcP"Uc}Rsr4NQSۙbKE=g^'aUWb(_`Rk[zØVEhѭ}s0rņܝ/$`I"ۈJf̥K?96 * :THz4zm og%.XlĉM52&,arKPٜ'53w?UU7ڷ*! wo2-,}dۈy㠶+bu=@U2]G"$̭C;Ak\>F}^#Ym3J9g>OQ➓&EVxiuYQIn\VU>EFod:> @:Nt_~V٩_^Wc6mY59kha pӵci;k>.wl^7v7]bd/<9ID~i6Uɢ$vCCҡ1S8=A=BP~y1dQ&ˎ.(D%,V8!No([r\:beoU^U83KsҹE:I98(C5j gW ̃{ WN ̉L1%P&.\S]]*EUƮ ι>ؼlQbnj$QL*@*ŢWzvv33ӯj<.Y6.M6 O0[[2DLj|='V҆!)h4m<ЈHJcHǀhSuV M//DO_:Wmb-r1(W dm+v[yDMi]E&DR2Gk/"rj^hON1o,cZΨXk#.QtVLN5INfLf6LZ{oϧJM {o囖[[ug٬ i+[m*v2!{ QRdGvԳ~9i均{8ڭ is EOrj0#V_"γ.S[6Z,Xu q%#$9;(JWqHS'fj ٣z7UE2S)nU<>]9!q]3\FZ˲wT#%GaTքzU.bKn:z7~̶ȧŞ[ȞNx{<[xG=]Nbcqqq]Oكmnǰ\16յXHS`jEr)n>. A0]ե(/ CrdrQra`4 ɀQAr9vp|41MRmʁG&77ԊS}\LOf?J`JQ2_:߬4iqFriG2'jb䥤WMM!Lo oթȦ "&~wOVd0u5 ɑ˿XiEɆ)7&mE=ҏdO7ukui-control-center/plugins/messages-task/about/res/manufacturers/PRIMAX.jpg0000644000175000017500000004204214201663716026133 0ustar fengfengJFIFHH$ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:05 13:43:13]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I9bI$I%)$IJI$RI$Zgַf\ыKir˧}`]R^'n:?9L1,t5'FBq?8@ xs-8Oh.7@S?Xlߩc sߠ佳V4._z8qQq3< .wT}FWA kcc[o&e^?yHevrnr"I]_c9"r3rcc|1q%S oy $d{/]k`Zqpnem;v7ɸ%V/VNw2&b7Zzė3oUvt@i> $ju^]z/ :H;nxkF Ԁx=2KZ1qzˀ/tw/xw_>~ٳD76/%1χd':?[n&Ck͵79OYϯ+ZMtp2ZK]CW]{u{!gV@#աRS˒Y8Nj!ӭV Kt,1ro2̬r6e[cSf5U-pi%Q`TI 1^_0Tif95;2j'3w+ͻtIt:y-~WOAee2X%D{u{z2Mm;J?q1m/.@S~#܏WOK镑.vM^Dz'eLtxWIԾu*ss} *  qj=c]S>PkCCAi/($G"3rqˋcW՚zo-C;d47{Ys~sZgPVDZsAk Y B]މ"gf8\V8Mǯ.tnbG[ S*՘3j]o^O[DN{?*/=[=I7HC& 7 x2|zI:I)dI:I)dI:I))"d)$d)$d)$d)$d)$ Photoshop 3.08BIM%8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM;F]eyfn]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM  ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I9bI$I%)$IJI$RI$Zgַf\ыKir˧}`]R^'n:?9L1,t5'FBq?8@ xs-8Oh.7@S?Xlߩc sߠ佳V4._z8qQq3< .wT}FWA kcc[o&e^?yHevrnr"I]_c9"r3rcc|1q%S oy $d{/]k`Zqpnem;v7ɸ%V/VNw2&b7Zzė3oUvt@i> $ju^]z/ :H;nxkF Ԁx=2KZ1qzˀ/tw/xw_>~ٳD76/%1χd':?[n&Ck͵79OYϯ+ZMtp2ZK]CW]{u{!gV@#աRS˒Y8Nj!ӭV Kt,1ro2̬r6e[cSf5U-pi%Q`TI 1^_0Tif95;2j'3w+ͻtIt:y-~WOAee2X%D{u{z2Mm;J?q1m/.@S~#܏WOK镑.vM^Dz'eLtxWIԾu*ss} *  qj=c]S>PkCCAi/($G"3rqˋcW՚zo-C;d47{Ys~sZgPVDZsAk Y B]މ"gf8\V8Mǯ.tnbG[ S*՘3j]o^O[DN{?*/=[=I7HC& 7 x2|zI:I)dI:I)dI:I))"d)$d)$d)$d)$d)$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-03-05T13:43:13+08:00 2012-03-05T13:43:13+08:00 2012-03-05T13:43:13+08:00 Adobe Photoshop CS Windows uuid:909f7135-6685-11e1-91d2-fc4f58cca079 adobe:docid:photoshop:909f7134-6685-11e1-91d2-fc4f58cca079 adobe:docid:photoshop:ef3e3a7f-6685-11e1-91d2-fc4f58cca079 image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?ZUثWb]v*UثWZUثWb]v*UثWZUت7pT_i'~\~aZݎd#:HW+^^aAt}Ysd1^C8Wb]^uY|".  Rٝstz8rGgxokkW7Y`z[SU-b1Yf&L##~{|.M tkgu%V@o\^#B2cC2OBirnegD7 ;`ѓ#͗x8ac/I?5|VfwGqdFR6#/WVbL=͏03܋/5{-uDf)"u9Fy6vohS8VK+_C{VFQ/./':xBb/i5y#5.O殧zg$"Q~(ǜ8jzŦ6_kNrps5_HK:#Å~g0uwO MӜ~j͖>vL&Nwͦ ,mVhj8!#Vп,kڗKAeN?PzF5x;/>\YL7tR4Ol:}=L\0ˎ/ &q-MNUxgW? 4W]1/r?S{SO6O:/c6ڽ;\` [40Sj:?z_#=ZPHŸ~ir7ϋ12~]KMn}FXŗZRr4$=q˦㘕]l_O,"\Szة̺-[""ĨM֤lj8#T p -HգJH 2B1٘(/]=MnjT** W陇Zjgῧ"徑收fscuiDxTmr:77]ِWji/XELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC  !"$"$CF]" < !1Aa2Qq"7Rt6CTr+!1Aq2Qa ?t(JR(JR(JRB(\HXo~l284uQ+ba{uMv;LT9n{b%)`5:*\-)6XA#ϒI;I=kxC&cً|A=w+fȢ/a$Tq'hۤkǐwu-%:(~5+/v-doUIYZݕ %mAI JGՀ@v]oyKnB^"s 0h5nw7H-ηKf\gFu%_Q^SOyO4m!Frp2jW足.\̹P~GE 2#V<`eݔAţ6= 95}FY]f+UMo6UJ{AR+R4Fx°nQ5C0؞{)3g! %ޮ?5%Z5h }5UO-{<_)J {]w6l~fXn6*N^ެlE )e+[ɶ =c[M&˯kLn3VRA55/D&t&Йv6qC)ܼ"Sx;zHg „Tْf7abbO~A)m=UU`#3_|-`6HIuRMcջFnoim.q:*}(oE_<5;~Wr^jiȮ9[( ؖ{^.-H-%hZOOj?iH_NT~QSe#8,l0aO }%)QT;($WLz*yY<;n}Mk:/ }u֓}8t*TĠi9wU:v`a!6M! JGڲR (JR(JR(JRukui-control-center/plugins/messages-task/about/res/manufacturers/SHARK.jpg0000644000175000017500000001164014201663716026003 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1!$ AQqB42RST5"r#3dt%&aCcDUX 1A!QaTq$42Bdt%"5RrD ?9*O;EĚRgYGEC;_S$c<4i>S[2K =ć ifXXMHtzf]AдlF>sL1);CWjˆe{GYGɍk?B'Z0W~)0G սPpS`~R}ϛ#2MmU&}P(k)1&Q&ĚzSk܀LKvvJ7&elL.a ,L/L-b`4](QL/MKd/*M|1&$׊$"QB܊bM{;)u)F̾8Q ׌!E逅lL#ˠw =ik&^ n\u|HIk֬ DbNRn3[Ɯ CM.mT6b:B{pE.k'c Y0J^S;&o^ /qϱ J:XTD$jG`l:Lf?*zڕYWO.uy+kB˫ͥlHl^qgCFrQ9md@@f`Ao@S2fS8&޹IcXF7,{c/G]`h* ֫ƄК۝@w̒alIA f 07.Zңa٬cry?qS Ml53>+d_>EMו5MVy=ӏ 4a@Xczʞd0-U6빗fcgѧ 5%+w3 {)FCg&&)4+`GOE,Su1|ZX40^&w03>_{w[D^cXfI nI M32٦zUBRDS& Bo/'<<.):㬋!LODJgLM>~$z4@]ΛqQ o(Eg;JϷGb?["""'5M|=u dZ^^q~m(k,Y,gqFEsAQUlQsIfmoNvʖ5$9B|$5%edYA''S$IѶ~sNU ?ZLJzTqK0ky~0E}_[דTnQ 6'liaZH}'^R\S7Qڹ.g~H^ÍDT>Gk=;bkP, mwg!3۠p:!mCHKH9-Ҕ~.6qMs@lRĤ>;ÉH%|ӝ^9{ ] Hkx^T82IQ&Pw}8c߸3ҦE &Rfˌ(i\On!YQGR^>QSBbMxMb)5-Ȧ$׳PBnL냏ؙ]xX^[іiAb<xi'QٽZ6G=S}aI:`!h۹1-{CP{$ñ aZRm:c!A0֌^ :lLQI}@hG %@Tɗ*w?/ukui-control-center/plugins/messages-task/about/res/manufacturers/WESTERN DIGITAL.jpg0000644000175000017500000001107014201663716027315 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF] 1 !qAQ2B"$% #58x1!AQa"Bq24uT67 ? *و*B@3݂h& ى4gՄ 9ӧS$?7`0T fLNie ʝďJ.v y,Z 3b  ` :brM a'HtĔIM +=Ĉ*Sr"`@re;#R˿݃5^K,g, $=&iνH}=XIR:z1%H&=2EfS0o#t.>6֚rWp xj9&}'b-3ܲK]d ֠(NL4`4:{PBDe?AK-k俵G}CwW3?8|88OCeصcѦbdlG7֭|).k$[eaMv;qdTd2]RdYrIrdV[;Ml: .ˬ+GhiLv:ůs[&n5";|=LܮHuM+2CDY.\DV[Z9\HD·GeoF-gN)g7L'iXuX^3@l"!C?ԕ:ϥSSM]Z+.vGsSI.v]NZ+eQ)奔 \ŗ;AMxWT:I ;8K6*T $YI dvtP6ּ8.֝]ij+xڸKS<j@RL돁lwxlփs\4$zb]=<@ޘiKe&[Cp~\r.}&<:UtSˍ-& LSXJ+.#\<[Qzo~Viֳ)qa0w"S1-:~@UYG~}Gsi }Xv鄲K I'hAP72Qnmr)@z!Z=cNʤC 5ԽZjSN͘\wETx^wr\ngJm2\,Ǎ[4:|^J3 L-(&mFRAFse~J( IS 4b[؁B\$xR&k5<9`׹+e-WxDt7U !t&5(d4 sziFG&'lL擫7[8S?{K7 FМքEI+)AMJ.EGHCF-6 OR+B]kv$˺yCo~yM0c^)Fs-U4IJ`fCZZ!PT d|i{˦k-rQhR0yO߯'BI7Q`ˋLUJDTX]X`: eŵW=?ⷁ$g/ kNϭ~//9ul-pmZ&kfmJ-g[ZjDR)h4 t*~m6{_E5MHkyno帒1cٴ/ ΐm5O& J'p-3쿜qÎniT3 欃8edTtg2_UiqrT*nL6uIKuxK7`p3")k-%q* 1J^rhRdV?OՎK޲[ҦS8#q\uK5O!6PqS-2zZ22M#$/*W"HI$CLX5I{W蟑>RYo;EQo۱NnZΞfܯ[uE?}}t̼RQuSoүګ*'|^aw.˟g0hbg [N ^&&}J8ZqmD"'QL|4i]i}YYk\ ^l?\;xߎ?*u/+=L&@x?C HūD[pѩe5 LA=eG$eI;St(K9(kųϹ3c|;'Zn:!ȾMO+S}+k;2\ZqiYb"dW#0A"ʾSQJpd *]Dzy0]C?œe2[م};t݉o}4ǘQF D6Fɱ@:KTCJ^HL Ӣ*#NEk{='u{~^[.r&䣀~Vmhl$F<0xB0n@9SءS%A3W~ATbA4g^NI>$Ν=I!p羘C4bsNX$S,WTv$xTwfbeUUgM ׳iϧ ?j@sOF$H~*o`\9$AP"Ӗ Õ;)݉*>]Xc9`pgF! 4Hu@3Oڐщ)*W{T3H'4E2pNwbGOjukui-control-center/plugins/messages-task/about/res/manufacturers/DFI.jpg0000644000175000017500000001475114201663716025543 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1 AQq"Ba2#$5w8RS4%Uu6  !1AQaq"2B5r#$4TE7R3Ddt%U6' ?y7c˓т13oEs 8&`Y7ux|)aKA̹w .c ,0],0v1\˗pzՂ3)1XݍVv2.uӝl+rhXkdT E]T1P-ARIu5d =N[TMJ[җF- :aS JX~uheLG?dz޺̔Ȓq6*,Ί@_5<=<tx? bq[MK 5YARŲ>YA[Q=jr C S Gw>U* -8&9zl3#H۩D6Do;xSgPjˇ;.e^@s⿭XU ˟ԗs~+X֟ρZyw[4e[lnjesR(9jY#"ζ>nh߈}?Ü9ӮޘZZP +T+4gmWɪ>Nm{3U4.e.C1W&ĕ4 'gV5Џd.)hiRЍ5xnd(& $drvYٗh(ǩɠF>;Dg[Euujބ\3J5ycfl#wXRNRv%FgPZzL2.w%l*jYRԎ*6S)`ØyG`Q5zHs?fyK2m#Q =q2f(!|~ O8Ea gYǹDvb%M' VxP^pw[z}Y2:vT};@/mOgy1n}9#bWM̒\c2 C};g=\iQ#A 1 =6<olm M4{ڊnUm`*-;,bkL[̝D͹4NR ^өQ),Aϛ 7]7Ĉu^]/1DKv^`rP˷kegoH;ew1}o-<~?bS7f5K_tDt712o5ZM\ c~ul8PZ=cnÊ@S5 rĬU9W3;RRxPoGo\⫭Ss%KHJXythjsLϽJ<_h #  w0Ȉ̌T M >|רH*WD ZYTdE*dPAh5g}uLyQPH`:65#%W>^qXېc| -exCP+ ^E :pWOM)\-=XɃGlvJxbrFӕSzDqJMuJ\ 7d`́UΌn)H"m}_cB!2u@kzG`(ǍH$uYk&]+Wau^U;q+V_0D`A2].@e@pj/YիDmѷ;gV?i`^;2!26:ITr4 LQ{9N!C_|g;7>O3vuWa};rPh=/Shd(իO!0D7fPb6s5Q)q1-BH ]UVN.ERqYAQXҤbczpgn{GRy$;Kx{ղǭ.+-e{΢|gPlZjlXQpN&D &`?1%h~P&G 9ƞ!eՏS. AyoToمX{&.dKI.zl]V0"̤EJTM Dy89\t[*QݍؕZuG]!g_,č9Daww<ݳfelmwM68[ -V~nm}˺gDѶNm1BB12rq*"ˈaiRR=qqO%2V}8*Nt6<ßY̘=m )nM`I-Zibj:Jk1F&BPDN#d"Uń$$ ٩8j&ԗM0ŒcQ`o7۰xN~=Yl 0,k:i$M#t`S, MUZc<"HC0=cyzW~1 kKu.wEɼMG"XyZ-Yr\T:O HXFޘSdŴ)hΞ.'C2y<ßSÅk ] 6nk0 '==o;&.ds.Se+{)d!\̕==/V+,$KT̴L&b .ޞZ-e b5ʏU0Pa.qZ}sXV[Njj'ʮة)ՍkVcA&2J)T" #5M1&0p[tD/17 @ {ڴij+y+#z:٫]MAUǷt5ycrDȸ I83z,NJc ǣf).nΰ9y;EfvRRMkW*r2qCՐ8qb}ڟvsO)%bz@)d ΋lLPϲ]1 Wy;C|/$F >P6c)k_vsj40H$n7ypzՆ-4oi7as ,7!c8&dW0oF ̀aYwɂ ÷Ռ702(4-e`-{dˆ_?ׂB5=pzՌm{},nukui-control-center/plugins/messages-task/about/res/manufacturers/EAGET.jpg0000644000175000017500000004222114201663716025757 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:06:15 09:59:12]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?4I%)$IJI$RI$I%)$IO4v\:ח~7\cclcSpˇqpqǏo+w[oO7V0s)gu[xլx`s`p."arOj&obISWfS{]\cls}T@.>b@hj'Dآ37!vYY_Yz6% hkH7moF?21-/e?9-DxjGA# zR22-,uKM‘el.{\ݿIO0򭾦,?{P篤^4C]PҎ۽G>}-hiN8'{0'| s(Y?r[]bſ3ٹXok r5bv~FJ'1ِ DtnmĹėjN:VkmbeѺU.n 9#|dK|"Y%{^yû;u uvH!|<5-N,0g֛w~gU(˫ҽ$25B`>4ܑ̘a8VN!#ri.8Ly81ϋ>s&"^#!!Uk,9{ ]^QM}skQA LmSUѺuVRqi:y& Dd?*|3hrr1[ab4 1ΐr>ǑUM槵ihU1ᆱ`s2IYV7&7 cW@-'wO4WݺHiJywe?ZQ?8Hk_$I2I%t$JS$WI2I)I$J_5_5_5_5_5_5 Photoshop 3.08BIM8BIM%F &Vڰw8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIMGF] authentec]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM 8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?4I%)$IJI$RI$I%)$IO4v\:ח~7\cclcSpˇqpqǏo+w[oO7V0s)gu[xլx`s`p."arOj&obISWfS{]\cls}T@.>b@hj'Dآ37!vYY_Yz6% hkH7moF?21-/e?9-DxjGA# zR22-,uKM‘el.{\ݿIO0򭾦,?{P篤^4C]PҎ۽G>}-hiN8'{0'| s(Y?r[]bſ3ٹXok r5bv~FJ'1ِ DtnmĹėjN:VkmbeѺU.n 9#|dK|"Y%{^yû;u uvH!|<5-N,0g֛w~gU(˫ҽ$25B`>4ܑ̘a8VN!#ri.8Ly81ϋ>s&"^#!!Uk,9{ ]^QM}skQA LmSUѺuVRqi:y& Dd?*|3hrr1[ab4 1ΐr>ǑUM槵ihU1ᆱ`s2IYV7&7 cW@-'wO4WݺHiJywe?ZQ?8Hk_$I2I%t$JS$WI2I)I$J_5_5_5_5_5_58BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-06-15T09:59:12+08:00 2012-06-15T09:59:12+08:00 2012-06-15T09:59:12+08:00 Adobe Photoshop CS Windows uuid:14e7de79-374b-11e1-96b9-84cebc0057bb adobe:docid:photoshop:14e7de78-374b-11e1-96b9-84cebc0057bb adobe:docid:photoshop:84691d4d-b68c-11e1-b9fb-e49a17428440 image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?.*UثWb]v*UثW.*UثWb]v*UثW.*UثWb]v*UثW.,h3oz7/5Q~=*BN \,8z~&*-w&&(1I M<@3~ikf$@n_;yf=r= 0[f^,V-8NG밌?\t'HKYcF<3S .\XebôG5h\rigD|EO0h˷d }E8x8poy;&#o2egM2HO/ɚeѴ \VdX~!`1vvyvܽ.Ktt v ,6 %Zz^*ϥɈ1tY06#-U^-kV ou欼~S25Q^BWr<>3:6s}k Mj[B0᯵pN$OF-n9`<(Eh~)йz@`UAgWvĿO<6'ʡ&Kx)~O' [?=e.{kReK`T}=Έ pAuL5ecGD-%Ԁa=ɭY|tϞ0&!^''i=lidq'_OE^yrMLqSI~A&lb3ˊ?@}.> ia?%'S MBH[7Fp@)nFqv??nlg.iLf%_uB̂[{iFw.YU(͞-1L\FRጧ08tі,1L |X. e$F(Lj)EG5Z`$u11>/%Z wxfe+ę~?ܵ{E1cI߳=N%mo[K"Ti$B#%[nX 7!5yeOfU#=JpiȐ2Kדsk͡HOYAS:jmUIΎX o' @/N?ҏ~󢊏DXWy!m)8O<*Y擟NX5F?-?ߦ.O;˷-49wvy*YIYj@yG:\7UУC S}acyF {K1<[<"<#28n_W0쬵;O^D&~ T1\Q<%i m PeIf (9#ӗa*3>fGFO+/l-7cRy]2qB\Fxz4˱<}=m|k"eDnR2B,q125/a1!q<\jm"I `r[ ִS8BPsu AdobedF]    1!A Qqa"2$ #GHS4d5u)BR3sDUW8Xh9 !1AQaq"2$4DBrst%57RST#Eu&V ?Q z #xLA3d%LA0JL}bCBf(9͆H "QZXޖ[ RTX9YFNuqle(%`IGc5Sb<: LJ%}bCB- |2Ï80D4j$D`Su`օ@ai!*'5ŶZÉQi[_VITH-SSEc b#(V?;S[)ugWld3?"PW mW0MqPб&L>{LjɏҁϭEe3CZGMy!g!!wKHcc#Z 8FO@R]Jaȡ0N ŏQ'OiJ6jJa Woaoؚ# j 2<%B֏_^}xWLbxJ/h'~t?F`0~`Kѧ^tIQÏ/ջh5FHn&w,m|C}[3|Mߜ^o8f~m˭3XeuaS3!ɃW?ɶ]GNJm>SD_mqlGZ<>K?RV`jﵻBB&߁2f{;e4sQP%( 40pfYL{/`uG{ϭ:I~@eZ> XNl:fXɁͫkeT;S {~V, Zg.cτau] l;J_oN w\&P%?)*q'd 4pa|"u+gӖ.btZ3lF,`;@X}x R_gc聤9[dp7ucB|U[ݘ@K\(4R "y%$HOT q蟡sVo4 ?+u [ʭn?k\ngb1QAf?"w XS$Siͯu,r/tj/56˰,|u7uU~#]vug{joo>*OJG-pϰ^,pM퉾+ܔfYU v{yx0 ;V@ngyd_-VRrp*)Uv2ΝVl$L|Irjq zeOȍ9'k#DzFFANjf>"+Y˧(k,= r;b(UK= APs :ZpQYjF2ڵc)nƩ!f# 7"n6S+uR#~ U4ifV6"6؄,:tϋب|Z3==-QY䬫,[u—ᵄO@)&3e7_NaŞ6}BV\z'8}aN4ck^1m̰xZqMG?N%QLmW׬́$oKT)NP]TY`J]"9;0Sh mSCt[V2 2j$֔03 G_kkgtOg}VjEdOZڱΈ/>,*y,lF.kٞCMCBmk-O3KmLe44(|t39Gҫ/-Gk<\Y25ZpȞu%LeBv_[O81:v#L[䝬\U\ɶ~j"5\5RF@`5=[^H8F1ei9gwR+#讓IK٩|f)鋈Q/$e|mΌ~V~neyDɓm3ɬw+,kH3a)KiHt=o~j봵Sw\ɕEgj±PP5j``,k| U*X۝jԚ+>awJUQ{5QM"U7Y/!Y9H//ťF权_@!6Y^>>Nsi'!W*Q}HQЊzFuZ4c&JwX 5rs@G"$$8˦59l,z`4F@M0iA;+øܴ l_@b z #xLA3d%LA0JL}bCBf(9͆HCaA0BhJ0!02q$xc"cp:( p&,8gN! S)|X0R¼ E6(cQb y&*b GBTdKS500Al7"Gpa"Så,&KR@64A-1E/ukui-control-center/plugins/messages-task/about/res/manufacturers/MARVELL.jpg0000644000175000017500000004417614201663716026247 0ustar fengfengJFIFHH IExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:04:16 09:36:14]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?8_?R+j[RSG 'R+j[RSG 'R+XX.gct~zqSIEhQwVhp ))~IE}8$4y C%='/]KO.Ȯ]cȿn'$>1;RSj[RR=?|~UWw/Y'qcˏEy~~OPvNK=)lە[z5d6?t]ZJ[N7N w&>W[nnN\ O$[ۙuovX8T,>*$[淽O?Z,?r uѩ)ﶪ=cbCy*}']ǡmLyUݓl=of1%9}Keu,ed\Zb6=7l `t}][j>lNG`6f?If I-6}]tk-65m"CD5^Fs^@ -X]OH`Z7;ԣH[\ůI\NE6<[.%6=F]I.V&9s i2IM|N1ߓ| X:ie $Ab_vqC,w k&w[4oPc U[p3:}nKOseog>g;g}I%?zyg$Wd9Wd fP<7{a^ï2U{lŧt*]Qv̈́}N̏bC'#Kmc̻1׶v{W~Ϊk Ѥsȸ3+#*}L/?亇Of{+kuFc#OΔ+'-Ĉ^㑍] ixc/PET[s3@|%E K='_Uzgfc2,hFcfnG=r٭oy캆gتe7ﱕDo;w+Q*C ^W{^Ȑ[yKiw8֋OD1;RSj[RR=?|~UWw/Y'qcˏEy~~OPvNK=)lە[z5d6?t]ZJ[N7N w&>W[nnN\ O$[ۙuovX8T,>*$[淽O?Z,?r uѩ)ﶪ=cbCy*}']ǡmLyUݓl=of1%9}Keu,ed\Zb6=7l `t}][j>lNG`6f?If I-6}]tk-65m"CD5^Fs^@ -X]OH`Z7;ԣH[\ůI\NE6<[.%6=F]I.V&9s i2IM|N1ߓ| X:ie $Ab_vqC,w k&w[4oPc U[p3:}nKOseog>g;g}I%?zyg$Wd9Wd fP<7{a^ï2U{lŧt*]Qv̈́}N̏bC'#Kmc̻1׶v{W~Ϊk Ѥsȸ3+#*}L/?亇Of{+kuFc#OΔ+'-Ĉ^㑍] ixc/PET[s3@|%E K='_Uzgfc2,hFcfnG=r٭oy캆gتe7ﱕDo;w+Q*C ^W{^Ȑ[yKiw8֋OD 1 93 70 1 72/1 72/1 2 2012-04-16T09:36:14+08:00 2012-04-16T09:36:14+08:00 2012-04-16T09:36:14+08:00 Adobe Photoshop CS Windows uuid:d94422aa-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:6307520c-8764-11e1-93bc-952fd8ae208c image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?FGqWohwFGqWohwFGqWohwFGqWohwFGqWohwFGqWoh1Wzxk?3ūIZEvU> uRqwh4[R. IJLI$JOtRĞڥ'NJY:I$Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM8BIM%F &Vڰw8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]asint]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOT._}v6 { {NHfu9lcdjzzRz7 d<2sc$;#?/2[?%$H)$IJI$RI$eWв#\͍ C7\Շ`wale2fӠc,k{k=J^3x-w.+#zt{q-5?ZsR rOO9?.CzBݙ,6.f1]YeCeY=V?;uluHVW[k`ִpQ)X 8( 3+fc`ߗu˸r]Vm~7iSe})̩}B=w5;]j}SUyOրA?Iԛ;2:Nh#kacm;'"pwWu_ͣ䞳zXG2uM}Wέ5v?{1[+-y;cD-[ .-INGD=[Q~IC 4rͻ䳤}fqsnǾA`HU =.ddmύ9n+FnMtsb}CwmRJy~wP6d}Ƣ[[_cƷmy^o},3nUu;lf͛Fȍ~$Uw⤒JXG)> IJLI$JOtRĞڥ'NJY:I$Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2011-12-21T10:11:46+08:00 2011-12-21T10:11:46+08:00 2011-12-21T10:11:46+08:00 Adobe Photoshop CS Windows uuid:d94422aa-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:f29b9da7-2b78-11e1-9c1d-e060394baa3b image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWN*UثWb]v*UثWI4yw>];P{ MbhY&F%%?/YdY |ۡkiz:+NtRd:Pvj/ei@[H^aثWb]v*UmƧcG$D"aRRVB v݇ r}_Qc6YKb:Ox̷]-CDcOIZφ>ͽw{zHK>BX?|rH^l[_,Yj-ek!DFmfG'2t3(mU|Klp~'.//g5W[R@k1V5wSb%u]N*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/MEGASTAR.jpg0000644000175000017500000001171414201663716026340 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !$4AQq "2B%5UWaR#DE(XTdteu&Vv'7H !1AQTaq4"B$D5U6VRd2#t%E ?>K"-%!91%+LbKG @!-րԅ0h  -! S*C H5f );څ/`O{܉HmdW b1%؅Ė@ KhnB4eAڈs)!ȂB0'D6^_X- ~z(Pv7b;Бr#Q_ /WK-֟=r={ճ<_|H;ہ[;3lNۭZ!$6et1B鳧UKN*ֶP I"7<$UҶY!VәLpҧOcEYuk( TZ.&M*d $mn䙥 D8N&*ފ3nc2sTL=m+*&Uẉvy3UٴB0Ɇ."bBsAO.Pje8yM&:\}qE@ ˭﷭﯀UURD7M&`k)dCDpk:6D)7TL-FZ=aF\ Gw9AT*(*E8kn {ӕf7!ia = %d&[SsU 2_4Ʋ鄉//&3r߀=n AIo=(2խXu#c7~KwDf;5C^J6od)ImPla4|BVq՚].7=^z*ZӴ٥e[@gzIS@oC }^$,%d:;ۃ%euM56ea0<+?*ZX s_nuSih<^'16ōOUm":K|/7RNEd :cI$6 v{^ۛnKʕ(XLZ:!ަ7żijLsSmSb_zbJ{%,k+w}dw7Si 5T$Φ!8nSF5-C ᅝEkskQanc(}O" ׃_1$`!lS0iۍN]MʘW6KLIK+K 6x0ց=wS٦t)w=C7^ w 5$Lo)e5E0glJH[;pчnbf fs+3!Xy8JSsXESt`˶ @8i5,:V8۬W`H,jRHgc]E)"3/53sVᴦӬ϶~,{r.zr4,_T*Zf?3]I7F|4hh:5!sDJd+$7L FNH^h!xJylxcb C_)^* Hl\]ꚲؽAM5MdtB{d_UqոrVI )M#H=g[K;61sZȟf I}t徬T* u%yΪ[]"LA}e;4qTzzG AdobedF]     1 !AQq"2B# aRCS$%6v7X1!AQ"Bq2arRV ?]y(U<>`i*])UsɘHf<mo z!w*7o(II@#ҨPqp~$Z=SJ& d`z(j*+||`heës:ʋS-i urrI|YM'!(zJ~޽aֈJN I]ɕYWQayc홹vC8RZV9֙+Mo/w%/z~Mw'?ߜ]Wbqv߅fv/gU\DzrojNA7+ A7F!&m!DpjX_>~ԫ 9v@z+Oљ]-&`d2ЂoѢVn>NCM AdobedF]    !1 AQq"#$2B4a3% RbdcD6Ww8 !1AQaq"B$42Rbrd%5(CtEcsDTUe&6F7 ?Mؒh˓̈́Q3oc& |N8&mp]a%P@c P, & }aioG=~FHzCtSP=#q阧( Qy-,7c w>$xLXͬ#U݇aq ɰmpt祆N1EV-'D^<_#A!(p{ zѹ.uw~7u=5lZ^Lp?c(^@m kwu> KP ;Z ST;Iyޒd9SU00NjEi*sL̚^iyyh 3zs7ekT>'؊L@@RᵫKޖ~Br޹/w#UJ{EQ7託̘}X!fpV>ֹjt\VI.Y#uydYz/^m"fuKݐ!i©RWKV f]T-%z-@RU4=Ԣ끻 Ukwx?Z:vِwG]TZb00U(Î.c6jյDBjri81bAp|XI^+5ZMؒf&,l1 ս֪ f;LeQ%cg:zevRGeQ(.{.;%jNKLwKyysHm]AUѩYet1mc4+Zf 6[.J.]x^Qn2sJkBV" sۏ ]"OTPɑ0.˶0gVx^0QZ1Ar mM/)fS*W Šԕ)p=@nCٷ)^pMx|QVe˿6+ ^ۏI2VüRс 2>M-a\)8lL[b&Rj*ftcٷajtl1y_1 J~ka$΍C"vJz+ eeVy3 XG=[(ƭQJӮ>#iɳTM06eVE)fpxBŒ!Tv\IfJ]ĥ@+],rp/%Q%H%Z mF=`b0qr|8s;11sϋs>Kn^omw)<} !ۮmH6JXg-vF48?H*$Mm ij,\MM4cYm%2lK)DOWMMGdۉrޘO&aJì+cES&8z7ϗqH^O-sc t&8d&7CQ/S abHtb YVg+f*ۘn"L* f!n;DEm@&3XkMdSe1%LyC7r"!ݤ]ij f&_LJ$ "CPtNʮ+*ZH348; |bNyךdPt Ƌ *5N)KIa"Gǖ{3ZGv{GGQXc+]꭪5q]6P9.&.kKdשiiGgv[.(!fTVG/ac^DD6У^;_Wf̙E?Iy l{wk&`x<t;T֟$<$qsjt6JRqGHs&ZT}..;jW]k HnV_zŗկr5HNQTymk77Djۘ9f*;(U_p]K]]y%:&n1`K5w}$B&P8:N, Sp y]U)t%&?0'͋:ّ.ˁp{iN>z:W{m!3kxm?PMƌ!LQ0qs(C.2}lSySkmkVSHF:01z{Pd44*Xk7; tjRh >a!Ȓ"ͻUңXʥ | ]_řq_EoRx d钥!Dbݧ}'#E'ow}o=g$/?wo^t/fLüs1;9?vIPjǤRy_%BnrY # - #I\Y|R%1=_76K}"emY<'1xs ŠqttۣP,Y SFAx@;4QR=b>tLxbczrLIeʔ9<6 s5=iwhG졸sKZ;KUMJ7>57= Z;^OwHfXZ>mvEk~#)2t̨ xIdFcudhSXR95%%$g^V "P ߄hjZY 2&''EYѦM 3Y8@ Bv* W%ҺJ&%dWʙa4/Uou/VeowMyg*-1Z4tn<,I6rGA:guD2՚OÖ\ZWٲTQ(dnӦgl!B+ynF4bu"Z!Rjz47i[TZ+h,ÙMءѯ/l}B|O矂"·u\}?Xk}^P1܄"'{-F g@o }oh]8k5~VM(K\W-|9 -u`Y FA8X4b ]Grn~_6y'B/GAh-7рybvKcui4STW8'爋$SQ,B&"\qHJ ~DHcKmj ;$w1 ~7ׅi&nU1wG0' ?M:v>_>.nϓـ*y;9w\X_vOwN/?V'v]=.Tb1+:^⺑5o"o7t)YavӑEyʕ܎äk©(h̞S˼ONMC~&zKvTXoOeHB"%3&Pfe)nC'zmZiݫI;Jw`FF{/n\ѭ6l-E'2=1rgQKavMBح=l|I}ak!󄖪_UgG[5LLS83CŠkOoZU*.JΕPyKD9~ikQ;VK26mn3#_1EQw8xLZy1ݗEͻUV2ʧJM/I,1ek7Ѯ*B>o wB飄O uK֨ett$i$=&x> k{\XU..2@pF&CgȔd'}YP_@=JieW K߽jۨRaZĶvL2h;>W901tڕJU@fo6/;JW*{;/00/^_U\"TZMXfP\p\bX/] Aw6ۦJXRX3 bRd'nZZ=~+JcyxKT]S!Gޜv> 6T:j^lIt ,5$ oOY[]&n䄠yʙSqy10.\S+DL7B/c2th7Z=# ߈.y-C暢9 . ֊v 3p) >^kEbkڄy%X!/;kG <1aN2~Š \ػmoӃCGܭԹk[ "46qjR?p04MI-bz(׽% v_THWvM)mǟc81m1޵2IaM. wQ8hhBN7 YZ o17YwPCirYe ï{.6~^gj@]RLT8wG9|v=R * ݘQtH36TEmUg4j HJ5רC/98ə i^ AG8b%g~ Dx ƆJMj]jfLM8&aO!7fpMv67Xo䳂 863Ã)ZC4i9hmJƪtg0a9yjyAaMs, 7Z=YKu6MډO>p#LCh\M^Pn8zTz|;廗OgMp!:WkkQF5mxD8ME+9zuy]ŤP(f{Q4%>n2ѽ6ӺF;" 1/v,F>*W,,  } YOY^FI`QqkvtnuNtiۙ unmRCdN^ҙL0lL'x_n+BqR"\>Q1VLO8KS|ظ%;:Sp.t OS mMیDZH}%ܵ&ѧ)vb ]efYKP|@%xMY]*2̕ax |Dji$kUc5,l<2|)i>$0!wdTƚhcwm=ޢHR@q?DY_x~sMjk.wFR (V #d¬8}fU0G͉Tm>VU>P< aQOqOBx#,ǬFJ5!i-Q}$K({bދAtݟ~gHjMC (zHyn HJuߩuU)5ǢJiS@ HfMah˿>ɰur])-V]O[ؠXvS]Φ"f@Nڥn:E:6E !/)Ch$1֧u=?RSC,ytc4Դ뽬LWP Y,uUn"QX16\WMvY f;nΆZζ]I"l(ɵAw>AZOY^FIeɿ (/_>Ƨ5|a;~v\?kf[`ڟu{xay?JaOƿɟy]γo{ Oʃ ns?!|o5`wւ~ݽu?&=^}nϟ?N}K )_T|#nÇ!P2~*U?c mwEzZ.8b8`!. 7c w>$xLXͬ#ukui-control-center/plugins/messages-task/about/res/manufacturers/G.SKILL.jpg0000644000175000017500000001360014201663716026174 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1 !Aq"2$QBa#4%6 RCvJ !1A"Qaq2 B$4UWr#T%57RtEGI ?4? xx&d2_X9F(9u m7C!t<ႂ} li4`#x 6 0;!ka 0]CŁ0!7AA˯8`ECl0 0 < [`I'D&VSW}W+n!Nmr\y$ 8ՍCjv̊T֡O=(o27U+P*v,u 2J5:0$$ل o$[l8J360)aBq8F\˘Vea#&RfgrUשMT31.nY:Cws33 \.эC/l#t]6 ]lA>?م ވbt@1D7CoWl޺C|E #;gܼeROUSATSUvć@NP)80.tz^͓mԪa{N)TɝSPFU@Hf9۳hwcMTmB%h@Ab{1͋7qttJя"abuEZ0*RFQlMw[Ǔ'm%) {W;Q(JSuN/&-Y/8P VG|9R+ϣ/Qezw9eq oIo /oW4w8誇;sݳ7XqKv'a/c1W<\8i<`pY)Js* 9b.֊{C9@!S=Ͼc:$j:c,P 21Fg$axKn%[l{Jù448#qe6)A@YS;1C0BP0+h4Md yȶL-#)ϰ#43E&{F-TZe-T-Mrv,)S$OݔoXLBe!|eܮ_C6'v\ƌʲ*"`D&jJ-3B]44 jPdj7IgUf"RzltOV#sJP5EA.[v{!#ΕLsODyz45"Nםj+#O {VY R#sPf5Jr-NHVHoI=UCEyU}G %+<9 ]&' +}d7mnIntI"B-ӷvW[m*ovMJ䛜DIJr(.M9tyYYUtLZtԐ%4)4 sFDӎ3'ࡊ[wۢ<$IۊIwqΕU$5[*H N^Tr-f _cP,lɇ ]3ʕkYoHV9FfJrntf VpN Ϋw1v%ܪ:);J/ c&@2˔ ;/GDct+jkOˎ[O'0$InDM7" 2"m~aqBPe ^"1d6rC&F4 RZӕ5R5 wM+!rV/6$O mzI"HBgU$FDʖTIHa #j%O]LlSi]CXoG7SӼ%# :$miR?tr>mÊ+X"Aj|B M)3:{Wj ruu{Дϛc=stx"PjNEM m?+$$I"zޑ_ɱ4LǎF<qa~HRr`87 -kvIY 5W1Fx5-~*N`-EINbQH!C&-E=`JdtɶUi/ ip$V1ҢVm L*' re̕Bi[n,HJ/ѳc E NMnS ˨s޵Z1"R Lޕ-*"O۱wFL~e{mN)tݙ-\Y)吐91Uk,14C \S;q+ te. kT\|h6_Y}}Қ /*0QQfJn2Q?@)ǣb'%X)moJ:MJJFQLFFFHRRa*U*+~;=fVjQtI?apG"[3j+&=<NNsbٸ ٳ=+7]帷Յ[) ۰B SHx4)UVSE،Z DP2c LjۃZ3Nx|6fW[v[+vۛPokD>24 "FC>JJ4H֊\ּJ6DDy$2xq@+֬;NTРJ˛U\@dWu(1X[N2:{ε_XN=B<@lyb:[k4ٽgZlPBˏ`75/l43yW( lÏx kmV+6]~!|a/Ưwi ߳~_Jכe}b8q~X0Wl44yW(ʸBl7 768/l44yW(?Nc/F-fLα%82% mȜv#gh/c>K~>Zaq ;EZʹ0ex;cF/tayi政t_%/Z.y=(eA_3'O<.chsǙ!~-+oGt|>MƱoͰ߿`z+޷rxELn(c&V0Myt<0MGɁ _ a, 6 ]y.aMi].6x`wDZM1: 95!k̈́j>Lx`}h P`L>dsPrt l:nL(B9t y#f/z?ukui-control-center/plugins/messages-task/about/res/manufacturers/INNOVISION.jpg0000644000175000017500000001534514201663716026634 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]      1 !AQaq"B#$2SD%& RbC5E!1AQaq"2B$%#3C4D&bcTd5E ?y8kd˓ՠ3qj ~8'՚uZ kK5h.^>Յ!8 72`k΃&3> xOja{-' b'@,#xgEs]I҅-($;髕- ˜UJP:$F)} j΍K_^- rmKIOғgN\1Ad}m$a{l5yfYIcrAY2"%ZfҪ$zL%)E2P(bp~A/@V4K`0/<,Oj$ FX?ypN3?iP6>[ *b&{QKͤF|-87LC‹50VDSkNg֡]A51eEIKs1)n^P]2Z3Jf:8$"Qv3uwzZu_ Q][U|gcߣٕ[iy"̕_ZnV1AuBuPZ*sXQZ_ {`aGVC!b@*bg3 mV#roJov$*ya% u 秉4G.+OiCb4ZN< .N?VXF ٪ Ku.Mm8 k=x]2#G`uE)/JZSB /J9DDhYVei<3T|'`vi $Ӟs"tR7As_;_GԣQZ$՞Rø4g8tGKR "͜shV;ֵ5EDȍoi Cԅ,j&\}C9w,VӑUKSMܡ\ϒUqte*@e+rd zoThJ) 0xv.-lOMLqߺlc^xYKg}uލ^Vu!zRrg|۰A@`=6Ͷ@ pK )(ۯEUk)K~e:˼ G<)q}}H[Gh4y\~ᅗx,tLFq[ f:Zj+kt-1weM5Ӫ9 R%)jLܢ,nG,Θ*.ˆleAF!vaV8X y;/^(l5,BƙW͟3DJSdIz" :HPU\u5Qvc=~^mRY )!s*]Hys9W_0k} \wV:HeS-ew8%BRG/)h6)ע0^RG^j"]rir$2(y86Xda?dLE2XZ0+xxg<:YaNp)r9ТR` W"q(psw,rҘVd;;ml{.ʽwAYu-|^HgW_q@zҩ P֕V @9\aQҜ"yMH QdmMBb8 /I lĵCnv oo\qkkrֈAH:a.!܄))Q%PG$n@E @#( y̲.W@Ӫ2mv l6='Zoe; @Z_GиEs`k!bKOU!- qV+ܢ)VPy5<5MSinaPW:iw]+}AHSk[AU ]ţΰJc_1U) .厌˚͓f/iK8P2Qa齴a⽺;k \z̯ߛ)8$C,'WZQ`V)Ϲict5}n1 BH/s6p9)CeӧmпW58̬&]*r+ָ_!6`t!Ba+IJe&_;JVHiE6_ $]o"tbXٶAknmzcl⍉Xbv+T}'H%RB*ͪYWĖx4#zƽHHX/-Uտ9}n&=sxAA%P2Rٰt=E:Q8W {E/ԗ,e?ݪŅh4ysC a=һ,UHQ6- ^ eA(^QNbZɢ"QzUGLqU~gA[%ȹ wy2eO6 3q[V-Q-jSڎTEmect ;YZM)j9'Y՝ ~{d,!k.ܲ7RBr4)pZh!3 GqB|׳QM5IT?BE1p;a]iR5B\dԙ=-ZUKQ[ƯV:[ݦZkyEV+opHk'$zgV?r$VlZV0]1bMZ@]e@`KmQes~vDڕՆdVJ4B.3~2TftBQKEBU4OJC D@*ʛ*$C6qnukͽZ~ {T[p(kHZo [k΢.AKh:E(䒰nbYʨP%Ѫx=},M0Dmʷ۞5_.W(%<**|vW:BK`i ?{ԭ~~$w2l\r^٬ũ>vp X }_lE̙f6$%>Zس$mSmoU034=*Jf!2:;KgHfEO'qp `m5I55 |N08Ym\pӵuŝ[LʜZso_I'󮵨W?2+FU8GaM&VMR.|"R' *Uo D$wx4ܶmg~9Bw+yab75uHA\D'#GȠ3u-цZ<ҕʌ%)@iMԤ*䒅 o2#J`}'rW"yBh t.[WVɨDx&ZFNgPV@d+ A2ebS4JeqoJiy# KX;j^#fTDF1PEP׻* ̩*U[cJ[9H#ư)UXS_fK3"ⴍs.sؑA e٣t:[6+DU v)NN*x9 @Lc+'OD\Ln9ӿ/\)˿W*Jr/8`f5-cT .6uN)-.ۚ% ,ZOQS} ,IlC D fJm/) B)zQ-&?6sîwe꣗]VtwupjPy;bdXs1)L9IkfqI,PcW)1LA:%f+.gk#uG$GUDVCwP, ˨sbݯ(J7d28bTNcx]j,/-5@B-DQ`ғ۾|i]C(e]:pw~~oI[{h4yQ-]-Zhzp[zjZ *O"I-C/c{1zJ|"#7r(StdCJbR%lLXd1w[$ܻt+LߩMQFw.S.YL%}],bvi:~{Eݽb-ęeZfčm,r6>f˾;k&R?YL䝘=5jCØy[[\ĻH\\hZ,F;-ST2廸ڙt{ZT |-9fLZ,?+wE*k9wC DZyl/nwbz}%ƦHP'xV*A ةO K6tzYCb`wa x 6h#3;_.rܖkZh$JbDVvi*jgIV$QB!^-@'c˘0nY>%tZ{n&"Û̒Fab]|#!Fh @!j,JJ*1-p 4:}/*Y*qU߱wo,Z>S6r}:P_HLd%~?D1Jg%cMYѡFJCa:]z}' ʑV~C̕_Id[,}:`pX-8{Z8ebnKxw:/y~JQGa Ȗ\L@꺔Gg7>G$5jo/*z]gs'su(ۻ Mw.` a-isfcHEH*(VW-5}@SPu8]YkHj*IN)0z[oHTW08Ѡe˷ܻɶ}[j~8w23ޟy}/K}OSrq k7|;𾋣}>wǓ_;r'ps۝J_|_z>=/Uxj\\_e Ty;o//~/kXdN?<3'{X+|/>5xVS}ڬX^ukui-control-center/plugins/messages-task/about/res/manufacturers/ETRON.jpg0000644000175000017500000005112614201663716026025 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:13 13:26:02]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO+.^O}=/ 94;Ӻ[]%}"[+4dYc+-f`kOؑ-> 5 wى}=הƇ๯o//3wC!}tǷ&6IٺC~[(p5Ya/uVϦ9AIsUɿ%eYS9́QWNmt2cA sl}Nn.-EyqJ A7gM++ 쬽:p52ݾ_՟:nc9 N}dVؒ#̂AK듮W+u*14k{جt"Q>ѱ[]wRݞq%^`qhtBqfhs=Gc˽7i6?z> Om},$zVk yomhupkٸ5s}I{ЩV3}ޛS_E_{1ӿH]]ͤ6I^mnYo}S7[Ŧnó&{kyYe m)m$zҿ9,os ].mw3~^Y__W?_L(' Kle-qk9iiunu]˿B,~JY@:qz|=?*Kf= Tl zks;+{oޭ~}'w[ٷū/],k.Knum,z?{^1Ӿ}?n J DoN/TI%)$IK'I$Uun6ݣ#ͮSI% !xǨ96Cq{Y0$Iܩ$ITʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM%8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM@@8BIM8BIM=F]sRyb]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO+.^O}=/ 94;Ӻ[]%}"[+4dYc+-f`kOؑ-> 5 wى}=הƇ๯o//3wC!}tǷ&6IٺC~[(p5Ya/uVϦ9AIsUɿ%eYS9́QWNmt2cA sl}Nn.-EyqJ A7gM++ 쬽:p52ݾ_՟:nc9 N}dVؒ#̂AK듮W+u*14k{جt"Q>ѱ[]wRݞq%^`qhtBqfhs=Gc˽7i6?z> Om},$zVk yomhupkٸ5s}I{ЩV3}ޛS_E_{1ӿH]]ͤ6I^mnYo}S7[Ŧnó&{kyYe m)m$zҿ9,os ].mw3~^Y__W?_L(' Kle-qk9iiunu]˿B,~JY@:qz|=?*Kf= Tl zks;+{oޭ~}'w[ٷū/],k.Knum,z?{^1Ӿ}?n J DoN/TI%)$IK'I$Uun6ݣ#ͮSI% !xǨ96Cq{Y0$Iܩ$ITʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-03-13T13:26:02+08:00 2012-03-13T13:26:02+08:00 2012-03-13T13:26:02+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:fccd5f49-6ccc-11e1-818a-a659f6cdec7a image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~Kpo=(;om2 #c0± -/o0}ǻ$Ttl,fgkJ}Iԟ:CmOzt_ ~]mWy/ׇqu)m{+1тpK@o-EKmܑ̀]'gc>}>Pgs2yN⦓{ sW|GUV6+0'2DcpT5S'Xk]<4z:v?O1o;>˵rP!vr}@)';o+];L[wL]ِIGܻ܂%6<IiaJiXV`2y$VBO<<}6v4X+}%H.$m:@$.:++{_X>mWۻW;GlX홸ك6FsZ>$cʎG>KN||=wgϝ=., u$׭k#+Ko&, *1#6پG&2fw: v+4}{sk0o n讆ϕ{1a9Qȼ9&KY[tVBZK "hԒcqP;(}_̮ #7>W-ޑ'ne6>?ڵɿ:7nc> ݥMUBhf*qBk9o{yRĎ\3xnFG%MA,Cbi|}۲:b6뽙׻|m=1=yjy5c WB֞}lFql3E*)i`.Y`|M]vg^nk1So'߿;g]$)gSC \~E96gøNlח9sPd)m bu1A$ZE|u*{YI!9"x;Mi&clڴ)~Aaz K_œW04\^ ,ͲT[EwVG PEc~G}@=d|z>]uy{)v[Bi cD>wۆur{ZXqv cg;'6Z 1+ gY` AaEkhlW۽Zxe#ƿVjp H55i#oql8(2 ز+7fXwto.d䕥defǒ:UvyڹbwVD0ZPb0(]9CIלmӽq;osf%ތ;Tor^߮L\2FK) hY ^y=^ptQ'Qm5 )Pi+[o۵n*;&4uT?ymퟞZKIb 11ozsҋ| ^h[T&;vhZy@]Łҫ>+`V٥ҷ݁,ENݿs8f1}͹jlQe\ H)5 /Hg/V[h[[ >Xk=*铣Yc:-ո=C]6:ʮaҌNAW8s9 gQ!fըіFoV k*$kQIXRjFOW?oW [k-rC9 d}˼s'+m@yV8Օo55yrKd'!xHڨ΅Uqq+l(wg~VKq=Ԙ,-N3iGZnT_58k&}2V̅}2[I?y$۹Si Wd]o yG5m0^ҝ`|}z|nN=a֘*¯\\}]l*3}3,NBJ:zLчAʩ#1QO87?gB޾qw=|mwٔ2)oUĖ^H4@Ir NgdLm?yV;8oo>O/{ ._??֏vx U_ 窚i: wWytL88˼OzÜ-#3qRugm^6*+$Upi"P".'L-/4nKNY"1UF[(AXT:#w74[>;yrx/z/;˸*kxݛiV*Yh*yhj њ3]I׺>ޤfl&vI7.("mlH,K&DV:QlO*b=m̮>ޘڟwvGٴٍ˸sjZ*tZffU]VV]ԞCo7~xRf崊R$ǘIHMFO7p|UڝwMvWg:f;vNUvnkTZulf}OrM=ESSBdm iZ@nI^iۭMo I-c1ʫ$.a% ƌ8punx߸x%keğ{dNvUWj2 S^5pԜ5Fz?۵ŻsAuxQMnV%Ëf#=Ɣ!$Yq0f~>`xwn;v. =O}cm%FG/7FϬYLlt%1GO2cg:Gj7WoỦv];wN725qr[B N!\MSk2xqȠwX4'j-a'i=M} d =<*ٴ.Q%.Bو$,Ef?5eaw2c݃~'휎٤em`kkWTsX2e7+shզsnǶj=M5®#rq\\FTx0Z`tURT]Gw|-Uds;Ko]c3|,Yb;uAM7`%0mD!gBQo!^ov&e$^ +Jæ«bSKSPmMOMulS"3gpۙ9}S3[5ZXV5s'#銃4$VM8|4jKyjKHݞ5y<>#0TduE:OfE~ꚏK3dOy>juV_ \Z}/j~-5x|m= uzO u֑ȷ67>SրW~ߪz֕?:EO~t1״/AaT+юSOSׂ^п,~T @L{kmm}ᷰmfi1&.9I~%UA]5`AGPUsԐ^!2:RC)AK]%Ch{2gnɴvR`mH28 *դg [%j1xLB8)ȞQ>QBte'2\˿޵ dS<^Q8-FqhƭڹL*ZJxii8 aaP Q(bB ,XTJĻ;%ً19$RI9$s}#Կ{U=h\_N3z6FEXk[[m5UݻT0Wh*u~kM7w/  m^=5:=K_u:0lq=RmnVu|p.tl#"(Y&QC<c&s\:]2n87b9Kd=6]z?\հ]i/gge*14{=n892;<}0 oL}fqAI6aށk]!HY;psP/qWSO.*eX d˽@չwI8bVK/45pۻ K1pZDht S!#~/-V qF^uӬuL"#k%~emů>uORYv7vQmW.o[MqV7:վ8VkcgmRϞ!(*V-0Ag? nUEキ6pcO5r`u\~nٳf+ Egk[\ lw.uBS,k{u-5VpzU X۫~{\75 [@xmPzc*6:5hk~uΝw@ʩgӹ\NkZ=K9iuח gjsomtRݛZA yCU_w^dkȬvK78Z~rrzWTʯֻvK=90NfC:թht#BSu۝Um$7nnKK$꫱g.S:p$k{K[Ukxԝ{nnw[]^KqŖVj|w Gu&6 p/w^QRIHMC~Lp0Sv/VIL*X+I)Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM8BIM%F &Vڰw8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]asint]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO'Md q˪}7^u4GtZE^n|eea? 6 ׈.VGdFSWmys31؁_꾹 .7]œԿ{U=h\_N3z6FEXk[[m5UݻT0Wh*u~kM7w/  m^=5:=K_u:0lq=RmnVu|p.tl#"(Y&QC<c&s\:]2n87b9Kd=6]z?\հ]i/gge*14{=n892;<}0 oL}fqAI6aށk]!HY;psP/qWSO.*eX d˽@չwI8bVK/45pۻ K1pZDht S!#~/-V qF^uӬuL"#k%~emů>uORYv7vQmW.o[MqV7:վ8VkcgmRϞ!(*V-0Ag? nUEキ6pcO5r`u\~nٳf+ Egk[\ lw.uBS,k{u-5VpzU X۫~{\75 [@xmPzc*6:5hk~uΝw@ʩgӹ\NkZ=K9iuח gjsomtRݛZA yCU_w^dkȬvK78Z~rrzWTʯֻvK=90NfC:թht#BSu۝Um$7nnKK$꫱g.S:p$k{K[Ukxԝ{nnw[]^KqŖVj|w Gu&6 p/w^QRIHMC~Lp0Sv/VIL*X+I)Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-03-31T15:41:54+08:00 2012-03-31T15:41:54+08:00 2012-03-31T15:41:54+08:00 Adobe Photoshop CS Windows uuid:d94422aa-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:e35da45c-7b04-11e1-873b-c4fd423be6eb image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثW$0Y&m;*=rB2]Hh+#q1#PAUȥv*UثRHy"(3=QM $D=aH#9[V"0q̏~99~ tݧؾ6ec6{TE*>RT18YNzi~dB'޸ e}~|G&Fa\5יE&Ǐ,\=1̫ӗ=tĎ}ךn.y~FAndZ%~Tʣأd3 edu31m<ϫ3P]RXc~cUT^X36,y>s_q()hZ`Glmdm&oXsĤ"j[,݉O}\??" T5 Ͽ77[i2s?ttaD/ڵigLXa?(Ǯ(WmWu}7Z44ӕ,#(+0_n9qCeF'/Zə| ei%ޙ<$n&FP&q o☔GGL%&T̞a򯜼$*Y6T,r:Utc.zY# Ǣ+lͦk˾\nUxgh!S+Kgݸ`I3 W[.=_ cT2~fj-k2Gy$G"a'2(|?y˖a xloZUߕǜ͢jw6Z)@B;N|s7괧$4ipC^#t.CU@;W5ˌJDDp8 oqWGī~"1Hׯ3=>|5|˼C/i-ꞔ\$uƩǓo2qщ7㟜CMR-]l UCW<`ʸx'τM$Njq+q3ϣd0 /Ou-RZ!p]:W.\{k82r \S[Yuc|%wiiOHrl2KuSUzN*h );UIZA+@cm=}nR7buDm"ti>/RG)8ߖ*y-p+S- a.]TsV~A]Kd_y C(mSM#}vIq;QXѨ?kn bմqDjj O|UN̺ʹ1](-ڊ7i RQx 3^zS UN*X6E b1TO+yz@#QC*F>PyPӦ*WP(H l6e&P-OoYFaF? O*ҴILeъˡܛ-Q B7dZ}Gx&B)Sm- X-Ŀe*N*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/NVIDIA.jpg0000644000175000017500000001150614201663716026106 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   !1 Q$aqB#4D A"3S%2RrCdt5u&csTEef(!1AQaq"2$4DTd5r3tE ??rGKQYގR*֍3&)j #-qYXl4jtˡeQ XJ18eg8 rT=kZ}管jb(D!EubVĜ?{ܸa|Ʈiw-Bܥ5Z;øKo[6ӆ1}șe"kD*8x"dϬ'݉h?z@i#=D2d>`:ZwQb=aW{z+i2O:B iPM"6VfJbD DBGHuh=Y}A<>KKv n VxA_%$T&q$&R#X.rMP E1 bS]`3t(TڲceB<ذQxޒ9cKl2 IUu$Ո0°L؍O;tw'<ug^UGMo|}EG#;W֟G~i19 8 \le{SؔkDOTi=:MDy5w >T :M2sefXа4" طi6{zW}8dD/NJ:o(գ2+6_! h'cin2cHݣY$I$#*"Xp| J8$Ó\Nh貣DƥzbTRh˞AGjdL·@˙N+GǗsRyx8[FU o%?5(ViJzk/*IyXҞƂ]w$n9y?'j 8I_֣y+o'67;'#QnjsS{Ӛ+ؤ7yr}2G{aIY+^I!.”՞ۙs3NE!a(HtI~,4e1lC*ۨVti:ޯoRrI)헾\paaw=&_Օx8$N3,*o"FhG$p.ݢUtM)NpVZBǾ5&59)Y?0crJѱBF;Fw``FJo|i/!.06Oo[Yq1rqiGvGM4y>ӂ(xWo1:GTj^m*o`6KLOJD嶘n3w>%< ʽOa^9o+c'2p/wҷvTdtS+5!=2d9 1(4\yg3>RV;Ez]EJTUrDPzTRRxQsnkӄh%s=.cJsh[|gyY/ U6[uuxģ%˯&F=}/պԙRR7 6k% x@$P &sm8-HR5F洅v6j$N/sJ18% 6nEDlTUmuaf͝+˂A:Op&/Et)9O*S M$ryG&Խ0U"8G8t=!(>4Ss3%Crd]jaAuo-Usu^SOq|tqp6m7b|b2^?|F.[_ n-55YVNYs|q/p#}[/쮑ochH_VՕ'~,b"=y0%I`r Wg~nIj*DIAss.LMNPytcozw¢XpN1SBp:@76A"7r]ٷ^}G)hԪM)TbnoVZU|儢AMm(L.v7 ;}.PJ yJn.V5^Vt!f=.L@gyüVTZtMT_Q%t+aέ VeLɝn2_RJ9;ivZ(zjN 8QRjp۞\򐢁5w#@%jsso&[ۿ8U3^:~ qh44H{Ki7xaX[kpj ڗnħ%а1:d`l3}mNBf曓Ƭ؛X˒!yn1+,*HGkC~!(FYzY9ys݋WHgRo M*lC p*h<&p2j@==/rP7ȼ+}v*{RtjñȨ~E&qC<c\w@f VT':t9E"C>D,Ss[.#ʸ$i]78JhX0;A|>KKv n VxAnkM2 ܍:WN2C!\&/X{ 04̗$eD=emRjsN&%Js5eȍ!9~'5R2?y/ċ~IozI3ZP:GTŒ]` RZ/RR @]`s`@GI08"0W_:2oiIY*LxWEJ#w7` )0{V}`%< kZb} rx=*>c2q|u_7>y]Y>mո սb0= c7SŌx/Rw5'"2"lt!i7v2]D6(x><^.aaBStՏ # ysalFvgb{&9FCTŃxؑ>ef髂 GQ\Az)[Q{ 8>W$T B'/:џ淩wt>zYwvi!p{V%ukui-control-center/plugins/messages-task/about/res/manufacturers/ABIT.jpg0000644000175000017500000000537714201663716025664 0ustar fengfengJFIFddDucky<Adobed       F] !1QғTA"Ӥaq2Ue'REb3DFfQ!1Aq2"CaRr3D$B#S ?P @(P @sm"/qچ.dyL ɫQݹS*\u^ݿΖ+jO]aښZjO]aښZjO]aښZjO]aښZjO]aښZjO]aښZjO]aښZjO]aښZjO]a孝ښZRxVԟ92;l6͟7¡jKOƴ(ޫwW>r9ҵC<|MΕ+NSǰ5sr6Ӄ _ں`<f_[7b^s<Ko˻M`@!Z܏4wݶ-_Zi!gu:PPH3C,zk;?meb͕;.'-d4I1'GfzsT9nx֕Xe'DFjҷא8>ӈd%QNTEkB]M[t 7:V|ݮzٟ^gZ1q)eU1·]W"qrȼˏ_8>gg>6~AڿחV}u $o*#.b:l85Ly޵ZZzv w=WZ8+*y?~/Oj$Y/D%B6.aR.REâno\0WzDaqI@0F*J\$~" :߯gE]Ċ .*"tkd2jI3swL?]j WaEl$6T&nUEE+RQRG1)Hl oN20#kr}AK$DƫJvR~ %qԳ/E=j?u>(XFn ZXM˦ةmTLkWڌUg8Ή䮶ϙ:ㆪDDʪJa]KG&,}Ωgķ= VjE4Ov~|/q/̴2oM6̇6W"2taTsg-4M*l :*[?Ӈ- Ns/t=AC2L7DI UO-CJ,FmGD`ԛaa3 3& .z3ԙ;)=9W.:n-p·&3rFub;A}IUy9[r%4*3x۬sU#cLp HUW_Yj\wj3:Fp۽Y 8o$J )oZ$c\,->{&DZJ_}KC淚*o%>Pe֍h*'ԩZ TCsWe.Ҏ|J:CHEQ gJNDyDUmugF᪑**:*K8nW,ɇ}ڪcĵ=4%P]Y[mTqC";)_%rUMn+ yg;kR O8A|Qzv+N1O8A|Qzv+N1O8A|Qzv)4/j/Y58`Ɲ AdobedF]   1! AQq"2Ba$%  !1A"Q2 aqB#Rr35 ?&䫎4rkc #LQaxQ  {xaMy1TrQ0LLTraGMD'oҵi4h41L_,GeF&L_ovLPš<) b0*aƘ /-ʘ 1* >Κ|LN4ߥji@ɯib&Xʍ0MGF& ?Q㗻**N"5ƍݑ3;H,]A:P1*f!DFg J_w~n 1@Q\s>bVsEXQW^1LN"ܦyDK`0ʸj7vQiP 1?Y1@ 99g +c=LHHćQ(e70f<3#OQ$SI_h9.~98^)²i)O>u-'[PvgMbL˚"1d+ u}P~Lnb Y|s\UT_ITJ_]Tm{t6i9ᑌ/`rbIP/TE 5jXZqI'J*htnJ72q 5Bu]hl8C(8mo_G[^]vGvV1͐\'Sn#bK?J E훼%9v+ * :mN #rF؉E"ToJqӉ4! ['Tz $V/{[fuO]6`c GG:wsbo񛒣gkW!:AV 1U(2OR^M,TUxk0L?1 *}xp$a#Z?k7~ Tnq5K#e}WKH#J$qnZnܩ4l닯*Y2&z@)к Kr @;B,[.A*>ϲ57ݪޭ-r4rm$BH⹗zQMEۋ="u܋/*MR5n:Ximw&\3"&&.B!b%#{UGݯN ǿMO.s˫Sm挝/([I'pRnAI&eiCFUX5Dy\gG =W jl:a=vRw569]'騕0 n2; c҈N:/sH{#%Hkׂ0ACˇsHp-.)h{?u_JYwNKYt[{g+A(RhxPN=ػK7w;~t쳘JrdL:dԋL폌 U CS f!檿~ }kI}৅ ^Biϸ` VO;)0195Vݾmt5~uPEԆf[e;tBڬEb^&LdS䔒w>iKB `nS~w6vLH4vMo}]ra~xT0K$NAꕩ Pj}ݫvYpc~mTVHbRKCVS/q].#.ʾYMg.blOTWur{}oEcuV5؀<ʶc)ZR4zjh*0 ssC͑%ڭG8p'I& ~ 紛4W-455Hq8^ܿ:vC7[󡖖I4V7UmfrQ@H[-1VY.cct0CBG@Tq ^tLSw}Cm۟SŻӭ(..ɻgz(bۄbOz4c-}pMr'NIE u0 5L=-t@12Nj1{}VvS{+4w>N.{ڦs-wŢ~=s d H^ӣwKr'L7$$4)fR'.cxE[C@ >*U ?u]ۭ-Ħkqb ωD¥din.n?oQhPinV@ ƣU%JZpWxWµ u}#Åj']'Mys]{39[e텁CsZ5T ;;کeOID8aDZ_LE,\ L'08[:Mo׎X"ltdN9>O+j<&M^F[>1Lاd`8|<:f).\3.wܕ!*tQyjڪ*p@@yZII$KTBwb6؄6,h{}$TPJۿXHE=#S3{</Jq a$mũO egư!a W\|=Gۻ6;H #$0ihk=A1k߼d,w$V]ZqvhR9P);AA/): LDc!8.cTr^sC;p- ]Ȁ fK=J0㭭k ԭ٪=]k3\G0#LFG9rM{埚jSį[s'E+XtK&m0ZnVLqqAne>P "뽱hӒ:kMn2#pDG9F%5S^ܝ10 e!yCDEĂNPʼ_q_!#3lVW$HmռiQˀkD$C>В٤;ɂM99Cmƶ<`nS%4R|88rՖDa0rN[|=I~"]ãFAM+4f=&{ɸq;T$Kޢwʖ9*di$FNM]JK%R q|tFXUQ+E|ntE.qBYq{m;}d&.pUH:Yh[GWq1 2v<diTQa1i鸸 J5jG#2}y)53H' M;]v k]rH:In#IkSPFl5].\5J-~`ocrIJZ{;#֎3rwT*W!P($# @ ZALađ$~c=нܶnnepF~% ❏adJ+knН@Fn˭\l2c1Z8V(9JC_9s8} %1oא?Rmom+&{xlK1$:&Dzk{담r]}˒ŤnеVhh̎2848!yIr s|<⾝Hdu5g[OKYMcdȮ1kK[$Rt+ƊܦƦj3bOZdtauVRT?2$F?q |GZYPJ@\ 2kO}g{NZFm60uHls!{y>@\\366|ZMk-'#?mW:WNdi52y)P9.-]VK n^ƏDžl~xysqtyg-J潮G4=DL]]a$~!H5qvB ܖ0BPE"r#f#3K (>XdtKt; k<dfҪ_=8slǬVlōsحCR5,g|Mz5ȅE*U:u/UL?hF Lԭk|?ww!pvpk#8#j1`1h^H5{;khlTZD@!T Ș^Mru I=`=@"3l2PJ䧈N<·Ǐއ;?}chyF%\FJ͞q%Sre A)f%yʗtnlyQ e礸ui:9'~#ä5- 86HV%)UCem^"NL<o3$8xyQӪ?8?ijyyhѧO4ׂiM~XCLs5vTij? / 5+DpZƕBu5e=jA:`pX˦Y߁*@\Sòi<,4EDѣI2ZB0JsRSqs+&:{8I*r½y1TrQ0LLTraGMD'oҵi4h41L_,GeF&L_ovLPš<) b0*aƘ /-ʘ 1* >Κ|LN4ߥji@ɯib&Xʍ0MGF& ?.4xS%A9SQ˯aFTÍ0^4[0bTQˠ|5iJukui-control-center/plugins/messages-task/about/res/manufacturers/HP.jpg0000644000175000017500000002026414201663716025444 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   ! 1ABQq"u8x9 a2S$Rb3CD%VG(X  !1AQaq"2su67R#5UBbr3$4T%ႃdE ?}ոm6ܫR+c\'\p'FSm9io MBB)U D]4Zt[P]U 'ڈdL>>vbt-D%RTdR":L!S%:b#L}tFwʥQOd" >׎ޕ[ų0r(=L׏Ty<:$֓海mwsa;!}Q4;ۧg% ۛ[-+{ʝdH*,=N=R.}6Ŷ;#FћnԴ5C|p:0=IGnFcї))"R}"Ր=6j6XDmb`04njMyg[xS-|PG$0NY+j~)=QISr2#a<˗FQ '+{s&NN/_fE~3DZWQ2e /JhM!if!!NԬS29$2"Xٵگq5~w~ɧ!P ' 1/l B,Aԩq|V+s($L TsdMSE$߆lzcP3bVL2&g9'~>㶔"ǥ3 `:%kXՇN__t9kWi>j~4ֿlzF;8&O+5չsQ-bpiӺ&CwT {9h䞞bOg|G[i}K;.N@%%o2v(X8J8IX$H#IM2dUThD(n DOVtWUHK>"0øDL4MC}#0x/6a}V ,GśVH[CϣԊugqSddN3,/hB]w i)ֲGR(EWZ\ɾXukPjeRup#yF=NjJAAZDÔJY l[d : r@j3$`%( u].RBҢFUN)?u7@dz]W]`^'RzRd?)R=OiGNW/dg%'K׋e3_aP-bpRt=}wJڎ:[T7z*d; ĕz-,!.RzI$ڂT?sC('s!pQcE<~JgpZioS+hwו@΄)z$D=tj<;XSf7vIji.I'ؓYgǖ@FٖZYaINJAZDϬ9K3nLWsY N2Ǭ{n<h[ek0oɦ;(3M_UK-ƄfU)}ý"YTܶl}hR%R6 :2[t%١Y@M UH2*Ln~ S'㚘u22Dt݋ 0(0JR;qVbфAm.3WolFnj*ַXvweeZ(ۆKgvd*PJfsSKڐrwu\Sk Y[ 71#|eB9`vXZK%@6uGeGeǏ2:+X D rPqY,􅜭$J8<~T0 Σ{n^8-qpL2|ɞ`W{&^וdDY fnM󐬷:LhMcYQ=546.f`BcMǸ+%흟l=vC9\9L̞\[]4s4u:N ߻qrR v]ۛ<xK\{pd.\֦@UGH{5Bo iME6ʜsH3}vTxË"FDLL)͎yt qPŨOBaoJQ"6;;NҌ"%+bq}5Z +I2II2`j#ؚitbr KVjbIfV282qomG- c |&c4sFq} 교^e8П~,jE8w}V;=,is#G'zgF&6eg'OBdELKͳDҴ/G@blLW2e$K˛G !ymᵅ称IpҮop\Dvԣ>Ρ铪5&՛T8<NCI7SfP;$Dpl:Ynޓ ~}SYR"gM Ȧ vἕske`AnNHd{d61h}{~?o gq3csyOnk?$b$9upI69 l92ImPݷe2Hܒ@<ۦۆ1Q|u.< jKd!:RFkoZ:v=:N+ΈĒ6Iyd*WIKɒCLլ^[-i0RP)kP soP)!=UH4aIfV282qomG- c |&c4sFq} 교^e8П~,jE8w}V;K?AeQd=19 ũ.fr@}껐 AA )Z/\YO6T1;ysktMKy5HۮȁX'OܝZ7֨vUN_}GU R \A*%&da _\f6صdVBfI=3ӈffeQ0V.4%s`kqR9f FQ϶3&mPJ!# J@ILCcZ[=s"pTԐ0$s6!i-DuǙb$+~ zʙj6V>jxù /㏓ HHaSܖU7eCK\l͍ h|{t94_7eOMTLJka9 jwv?]S%P~+B7T{*gS$קO_˭]_m<pl̉1T3 j`1R'~iF/Q *~0Au@4jO0Gx"M ZojwgT$+Nd85>ov{/ߘ3Xkv9TƝ;.I][tXמuMjqgo6͐pTu*LrgD;fwBZ<)I')# wCU|g~(3ì{ûZ©BXZaLrđ lD dP @_R6϶V҃b8ԁ9fb?Q~73 mSL(/Y$ (K(u;0Ҥ- Uƿìޅ$qŻ O9.&h\?ME\#4iNYs 2q=w>ZqR̗/!u{,[<6c`4 .e`@Vv+3qJRul+t&̲yU2#'2D;׻{yޜBR'|O+ zItCiʮmO躼1co((\ˋuꐧwhqLTZ,>*qTVꞸuZ[rHy A~?J)XI##3/|~M7\aBZNwGEx2~tKJw~Wgw5 jUԨY\1"":!k{K7H ;$8wk!ӻ[4iČn;%>jOϛQ#ӈ+nge>gAƶ|ڏ7Qk h#F AS:) rvTMT[ J4l>ΑMD޸[EdIlYV`͕ laQ!8,u3j &iXֹ`m*(1դ1tNr)TSIxO ';F|B7vL JbM"F]|ҙL)qazr֊(sqI"TKؚT;,0sFc)'BZ %Jt&X;+{bQ²^ ;f:vza #jnDSέ$1OLk Kkm[s+ԤVzG'%˅ʙ>AEtf= |ܙݙW'su1ȒXPQQSb !,M"BBS@^z@l,w+/PUOIWЦ@br? %U/&E/Jgwpf/H/ *6d刼3<ܸ]3̰&%j%C(jcնZTn9jV.zrkbҦ *dHLp=vQ`]Wh gG.yBqTB_=ʒCdH$=6攪V&o]Y钡L& %_: @0p3[jLL[msP6Hݢo5<:IJnlL2ƇPjS zZZ]z #FGUՕx\I#ǻ 襺~&5r{sݙSi[vS~0& SiW=:Q'['| 0 SEjSi@䤌d (˳2;)zsC߂1 i:5f{aO1'oe"q/pjmܫ9)Hv"P'X薲zkRPL\qVtZF1`ܐUM6I)*LJsI v1]TMEJmA[9H2U39l70om;(sF^qqBЁKvvW脒 Ƨ('3:[flͷȶ\/J瓷{QٹCqQT5'%RuqpiԐRA܊*aڢXqDS 6'X"S3dGG/NԄ?_5ɫ4\0 @G1.YJdvZvZb`()D-vFp{ƺ @2$LAj)kvtR޶rty 1ʳ&AQZĽ儊]RUwa%uMOfe!ol;ѶwVX>28i_p,;KUcw-m.FB"+rU!Z{[d5ޘ=ژ7Ӣ'"+35S:n+hHJIA-R2 ӟ3 4mT%<5B\h25\vk1s`I/gjV4'qu,cʵ@Tꦨ-Q9)D+ݛu,ty%S*)LxA泣jq]ҽV] i@ZR&%A'd;qv[b.Eb*y|7{u]= +Wjkdb]1 bөkj7 %C)'TBg <%Mҳ!ڪn \9W/4LcHðNZUg5bd]+KFԡSݙ=r;;&fVFMbD:jqwNSd̥4rG9L %BZ*\kwV b qc=42=2oɬQukui-control-center/plugins/messages-task/about/res/manufacturers/CISCO.jpg0000644000175000017500000001634114201663716025776 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1 Aq"BQ2$w av8:#346 !1AQaq"2Brs$4783t%56#Tu ?&9Cqɿ` AٌVQ ́ cQx|oь9ADlm9A2˸<`GzV3l*n@brosA7cn(=Q iǜo-!~|A;_^żn'<1ppXp5c>t1zsç#b~(NSr^l QN]>(|^ȫI \Q8;U*q]\@D(EB5D "0v` tΪԂO@qYvW $65æk!O vtWI*9;J(dgܨ[/{D)C,5wC*:Mw ˠf6K>DaPR[I: gP~Fcy:ј)|"jdhXWfJjPMI"Jb JP,3薭^f=#6H*n5wedªU,3ϷFX.y11=}!DGiYA _C]In8d~d%"3gHХ_?" \IYJ;9\8}"bCqZkh65rDKpFrխ+j   }r{ǡ+yu)\-4KS b%OVW:HPRe06E]MzUԦ P\:[Uw>}/++LkA7[E1`qaA_n jOl,F-7uYk6 s1eqJOu?CMjڢԹ_]cσ_HXus=h^[d╖m(Z.cg"ڈ\ 98p6ajgUӟʔgI+/ qI3`Ǿ?#o_a{fe}N[\qJ==sa)a/*?ݜu?<ܛ]n,1hTr(EMiKB%d=3:%9M@CψG5ӑp#VM3U>vj)X90#Q}2ԍ-R6h)!LiJYeښYY0E]n@,g=1lV[u/d1 `mVb{(ѧQb!x!@0AEN\Q4{ycEoݬ纐y9I$f8lmxhgU{hrk:Vnf#+&^!Ȓ jK1N@HS'WV+kPA9J@ϗ:%m#U:w_{276Оmӎx6WpuWm׋d~(cB! LobC!V&IHD]s,BY,闤ecϔZ*O_YT'LDaW>k}&(7JC7tewDc\IOJ>2l xvᛀԝa| s*51U4#ՏWD{hd>-o D})ePnhfjAD($Bb iwʊTfIzf֞ ٠!9;Ub吣'Ohm*'H˥a$AcˑQSVvnYf9*ORSu,fN=~ohjң6nfe rNەOn!2{ob{J-ȧ//wyq47S`~!]s;)a˳,bO j߾?'z.?;1>nwiW;.^[a 䟇~E.=7cu[kk/:iҳ\"ETZ- LsۢIQ:1AVeC`n@<(p'oV=ou7P6$5-G`y̒1">hzdwK};*MLuz՜w ȉd5iJaea*dE(}>S:|N(S-#z>U&CP$vN>fvu{rl'RD= é7֊tZթȌ1)8?zYbd 8z"jFjؔ"nŻlޚYrz\}\juAJj *eH)AIPLɐ(Ş~/۳"Z <"¢j!ga\j`QpEJ/&C{8]/o2* yI :uVvi\p7[-{ MR2oo%UiGURȭLJ J72WMT=0ō/=.+b Db*N$F!*|^H&&g#-f%,&%%G ^eK}AߏGٵR7Jj7I]?g"$qPM}Z^P^P_#y~rͺ쪒zINJEvԄ.1NTbciQ&IH̞Oi9;\ 8z&ѷHH%-g% q$HL5]MгNѥs0\V\5'#cS$%:/"Xcj* ?:^?(-fDa0NRX1ؼB˵Q}q"ˀNXE *JKy%dL95}QmMr}Wrx+ol9NR@ȸ<]R9ʜLL͕)]P9}}|u)یKJNLe3Og%D%d+^y|N{ӂr"Nݹ*lX^lY"PB!͗옡+˕+mK,&GfxU ]-,ݎi lPR1Sd=^ZY ǑI#ʨpE `:*2RQ(:Q`%dGnq+5ѹwj9E*Fxx }L$._W슴H?JNWNiJ=[[faYB;2Y+sFDָo H|xYAN*Xt["Y: 9NbկͻЕƬE&0g)8uU+;Jm\ j+2 P`6MjZz-'u@O Q8 򘉟 }8[+4᳄+L$HZ%$) VŇ?tê\6=]:䊰i+),VB!݇+eP`۔Vxa^5Jd~PwFP!C5+ @Df\㓸KbPR5R.URQyJs%+xoL& ))uosFt1[_=m=@˕S}W+kt&3HcOT+"EX9wr8X\+oU:XmI\S.H -]Zݔc>-,gFտ̵lD$ ]?5_%,8PcYRekv`Ku-"%3 xa陝qS->91n:{~ H(JUOfB`(am,tͱ!ƇiJɭi`q/.!7>FHt [ӄrWÖZMPiT' f^"k8 pp%+yO6슴:ҫEJU4ABuZz5J$F*juiT! S8)$*ɗD.i׫][LVgq"5kFmlHMt۷W7ﺭ!'쎦x%oBaqQIpٳ' NzJ<'i}ta1iSػO1G$āu1R 8J.QV~AȀ 6GU4c9d$"xypaf[+{d)X)%8 yM*?#ơ ``#JZzՑ4ҺҒY91D3qoҝQC[ >,RqQ".RN-RN!DJY7_N<ΙU X.q癌g;+QH/rF*aOx{pLzCͰ2LAjP+եZih7ޘ#AC@:&Q9*RܥI6wc|lTNȜSAE崦.҇ 6SWi PdPz^ޫ7М57^1Ar]hi&Q) T0R\8#c]Mљ idPVo_@ \!wj6|c!<^>㢫0Av>ZN)։\ڵ))#Yy%9b կ8Ɂ?3:emkLcHD tKs)@GufaQFO([Z֕ha]o=Dg2 `0_ˢLS2K>im)f8е*RLJBY5L E[ph`@Q%=_A6zp4{fTDi tq]azV5 i7a| 1979 17x;#pA7lj7`c{ 1((C2`퍧( 7c#Q9w>`OWmGukui-control-center/plugins/messages-task/about/res/manufacturers/HYNIX.jpg0000644000175000017500000001411014201663716026025 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1!q AQ2"B#$w9aRu&v8H  !1A"aQq2B$4 btu#C789RSsd5Uev ?xx'as#7u7y?)YDz'Fw3|r1ީ'8& )co'(*Fރ 1;ʳ7 ͮfFT'$)&8==y["tii|r[ JoU2Mi17q $"Kmk.# +_nPVN՚k8CAEv%T!j"f)PRH Dv\T}AP=)CcP#Q$.p<©o{6ߚ"2L&텪蕬R8 8P C17eo-]^ ZH 8O|1hKӦ] j/pF:ӞYK Ow8ϡMN5Z)MTI{TJLܟ:ck/?.fdQ)f]g(ΰ.# *D  Q0ٻjq9iն=Nޔg Rf}LrxJg~t&om8GU%x)eTSHltQ@S2TE1L)~Syt(vM1J.1%KI L$~kT;t-lӨ**BfIr# d%Mn5y6֯s2*V`g˟jnRbRnlpN&-!36`8Ӯ]BiЭ|ٕN lj22P滷؍ܪ]p j;HRPW0352Y{!L H/q1U9bG09krV$2-1~+zyxlZ0:[> %}OLH9IP  VRHuSmRKKŤ6.r]6i!W6ĥEkg.ݹeVߗw-Eҙ*M#́#V( vҊ$@Dd=W#67eҿPS2D3aa(WfA~-J{ZEl9_JyK#/LY>g1y)l=KnQBVtVk݁/E%7$) r)!,Y;˼n֠(2. JH3S~-~ݼ 4+KU3.Kii!_\LĠMXa==VO1Lj#$1~Q9?b[y}7K//ǻ|=xy+_˨S_w*;TqE{-BOe&e௤=%5;{욳_޺>=TYǥyxp{Oܟz^^Lqi]➢K6ghg\+%CjZL](Z,)IX$) |0wV]/ CT$p塢~K{Y'AUiu3.]if eVNW&ڙf&%5FMF:4j*z#G7PYVEY͙rnawhp١h ⒤0R#8-qgv#k-zҨH^jOS#ժKIts7ʚìqJzV2S\@t R^* 56@"EJW Yb֌Jq'3 HTkwd\{nY5ܸԮb$J@J̥NY'=2[ aoyຐ媂;R3/vjL)DLFtHUڹ.+oEQ^\) $eK2S#۽f;YAٶ莜񽮥4-S䖡JH7I6$SJqc\܂~*'M+߲kZQV -P%qaլnNdxRn16Y@L0#+[mH-JK򦹔R›hDD|8tjnk7[^`ޙ@lHd6yRPQ!R&@u5?kc{,#:d, ؉L؂zTPFAtivI`}ϣ$'Qid\T{M'YBGLte~#|ET]Օ <*+ BPv7>)RJS9J_h|b5Ld6 Bq<ڶ5Zi{ _+F։i$JDʔ5(F<4}*pb\g48LO݋߾ݰ;%pTA@m^46v3.QWa^G+7S֟3ػǽo7=teF=~h:r}l> xO1rOoDγr?͓&^9/(-h܌Ƭ5U*DxSӤZ:WD&D+km%bFg$t:w"=Jt BT,`'2g/;α6u[&+[J](u?D'wj;$D7nd&u2\μ(RШJvtb}>UӷF_QI)L9q_;2)hZSR+LFb+p:I*s3]rfD類%n)[@3:xUJ:9\U4,7H:uC \f&Ækuv vsKluU2_MrGd~yڜ<C2πܽճ?~RUx]$=漱xebxnv_q:-g#:}Ӑs C#s{dZ®cQaCR9ennò\{niqQm!JRuiP O9H|yjlmjT*H]iY\ P"7mm3JRD9ox~޻yjiJR 7GI'*=mTL/zhp%OK D"[v-ѹRSm*[IrIP3tZ*(z{) P @1#v n*tmڒ1P5P16o-م5x!+sKOOʙ39c}ڍULSmF =B2j@tJ%:-ѽMt7R¦> qxc>S=oU/ifltp<Z`|YFHD%q~J] @00:}g=wSŮo/᧎YO1||KiN`ur_t0l$g&X&/@?YIRr9DBg e)c,Vg 63 zO]3+7y;: (_^W=rtέUCec D@vϣh[[I$fI$̒cMy^7\N۽Ҟ\OTS-A! %% (7G ׈`G! 8tL(CP|0#炂~?f8/"i0rk#C׆Czx('as#ukui-control-center/plugins/messages-task/about/res/manufacturers/ELEPHANT.jpg0000644000175000017500000001301614201663716026332 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1!B AQq"$a24b%V7!1AQa3"BCq2 ?y;89OTN h0v0v>hA{Cq,{z.^V-u ;8h.^WPܮZN;.NÈe=PA;{-hrl띪ˠ 6 #ӁVR7bC'@zywmdWսv)!Ts B_"cI!ƤQe P#Nb|Y_lyiuoU H^}\6N\<$uF,{ƇVp̾@;mV`_kcҵf7P{gzLwWfar&r[#4fkHFiDb b"R1U/.U˗լB9_ R5JQMI\iO Q5UjڲpQ !V%̠?ߑ*B5Q_Nc:j+B<*M/ęšg:20X䱨/19;YEy{֨&14-G6goSu=35JLz N"T/hE]fݠծp)TJo3ijl1׌w8VV#UI!(zm*>$pcP9)}|Nu"-i jO񘮠aWbG *:$yBbҡڴ2%H%^7}u!,=M3Sc"7ѳR6./@K[U~ɝ%Q*\|͔=+p5b8S ݥks+Cv)puvZ r\.pD9)CoVXo[ްݟSy[jwVWnH&U2ʏ6|x#̢El[gRɱIOu6ڳ}Gk^Rk 3Q|JASb˟?Hxȹh|o1)ޕ9<&PljG c"\r}8ʷTSqrrs**EH)f~4I5Ur?u[b3dJͧ_^ύ{ 珉|3*Q^siw=+p31FFVj^֦mkl@*\.A>LR""v Xuݪa-D;!-5xc"'y2k Ss1G:|s.6+ƝyC+nÊF5&['2gl\Gg f1G"|e"0C`|c ~ۢ366 :q9 VcW9 5 :g8N2`7)LqBC+vY6}^ *[^ͪUN]5BVṺc֎lrK뙺S-yk|RlI$Ҁȉ yS^%jTkFړr0ӯbY4+[GV4P^~ڴj$1 6~!_ uVRT9Ws#sMҦގuWcjvU@i~':qZ6HE>K:]J!–8Q A~/9;s%*'r376**}R-juw|RN~X r̘D@E= =/qt)ofg~ )uh'Fa{|oOȸةg) Q N cyted "p\_19"PQ8kr+צ'CmU`ꉙ͞GUj&37WzZɀF\S!_PJ\b[V#.ԵBIwhZgLFWN l*y }uW&ŷkvhk7ӣbld|$3UB:17 \򫛡7D@ 7~}Hi5WU ı_e3TbUWE_&0Y-r9 ,zq)Eխ1xUi);>u?Lǫe_LU:k7|<HeS0=ȍS&ϓ>G&so^x}pq4\p"ttкbņ>ܧh1 U 9V׺o͌֟yQy`8*,G=gػ?` 7uYuB(J=ig䟸YbnoW:J)Rnj^lz-sdwg˵zV͔s}y~=4rM5NJ:'~&3ɀXALF5n ;k[PZIw*ZRY4YnUµdjvJQC?l"-JˡO@uKcXͰy*KjlG@X?Ɗ"vKO^X)6|Bҁsi(D[Mu@%,܍^CkBj)DQKQڱ`p],^ dɓ:%\S$WE ^49LSuGW{Q&(\ݞiZp۳I;6v!`њʑOwCҨDR$fSP8TU˵Ng;R0ΧLPhgSy)27#1#>&QQLx]w \zvp[A~'apB Oc$Сr)nN㮁 ArR=Wt?ukui-control-center/plugins/messages-task/about/res/manufacturers/RAZER.jpg0000644000175000017500000001566614201663716026032 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1Q AaqB9S$hY"4xRbr#3cD&WH)  !1A$Qaq"24TғDBRr#3b5ႢSct%& ?>IDqL;dsXM??8vh'+K7yq#nw~j g[xǯn|'z|}с13FSuμAe N䆢Ȋ3 TUKքݶ^@ۆVe Y5YHD3ޖ)x#*eZ@l$|xUs.ʶ:}Q|ؖPt\`C`ټO@>nGڑzT˭HCG@s6X&RX;-.!iN)ܧ/$YɤV)KV@ YVn`-ۑ5*R5-D@uD"f}hZ||غ:v_=%p6I'c:co`&f$ p lbJ(ѧwd>Gݽ;IpT]%AvoGTeB%)A[ZnLm(d;n[JVىm(]ЭUDyE)U.a路'c:co`'|VLO϶0ӡ{ ,81OI ꡶Ư ZZIGKlrPKoKՃm{F meN82đ,=(yGEO=Qjg7d"I8DA܈hl2Mrd:+v!inu B\.yb SѤU7NR jzEʉ^HFndDag[:5ʧYnmBKfrv'lrP2" P- hEhE~SIVxl&l>II"rL]"/PGSR8:v1]s.:i4?PZKwh~O:YQ5׏6o'g+;(gYoS#HuGhЖZJ Q& Գ+aUV6^3p]6rmejB5'pum[3k LRCˉbZ)WM}? 3!&v͚(-rcR4g5bȉ(7rΗ\LN*hXCܘ ՚1ȿt* *M*jZ5ʦrfLܐ b3Yc V\j -Z+j̍+re9,ijRtI.K- Klj#O4pG/2C!QEԠAU,WCx&VD- ڹJesaK9,GDȺN JYWsIv4Z6)c^ZbXa;o"(@SNNs|7=P[Miu@%(t N=Gj\&'jl!E@bzeSTRgvԫSBn5xڨR?&36#6@zaĞns/޷@bGKԃU'cnm:1/lGٓ iFT0_ԊSrWmUv Wl|XS%s0db3PZ>A̠l$PQ-}h͎& @?}wwI$pyU\dXL*V aV䝵uJCbؖIpBC%*zy\)-fm͚CnM~Q54&%YͻY',LAKo8)o-2+~5_Yy5cX*ow-T$sTvJ~ʐ  '4SXAk*!RWV}5$3!,[iyv;Hi(#j "j_q|J>_[K*V6 sLzvطjCc*Rp#ǿU+M_7nÊ1*Bժ;YIJUܾrlaFR,0PA=ܤj-g|UlKFDHbUSQ3Y)fIt&ȶV4Ƹ9Rm"Y6ʫI[r,LPݤ*⎤mNTӑaO[FY,r8ll+)'6%2e$.46Fz=fј;EbIߩ뤌BU@')H< cּ+6!2=sRtFP\HɖlI32L/5$[ف?#Aq>ohѽh#1@;Md;fW+.X}MֈyLBcہϳ辅v+.҂^* WfKҭ[Y1P;Cá?=iO<"aT%Xf~jRp臛 #enp@;] kAjGNw<TvVevGC~jTd*o633D @@Np+-)=R+ZMOg>EHj6۬mG1eǝ0xtqG(Eу%K x܈ijMjLkxپE+7jI9וYg)|,9J=jx~'U|zծRu7Ix5ej6Zv7Rյĉ"o)⅛y4߮ioTg3h iIFFQM[-gl8ha 9L ;Vo6-Wj$Xvme"c23n˃N#њs0ss3hqmf/w'Cz~||X|-{@9ppuotQ%vRPy5xj_܏Xz(KxxL>hu#1aOMĕ 䚚dD 4o|2 -zҬ}nқI <Nrÿ=δ~bv'1˻QN7!n_;,[F sm`$mbDGv,<%tyibJm[+ij+ڱOVjiv)uT_PP RS3?T.脸ЅӲ)(Nq4שׂbo+şWV}VK`miv~_}seXN}e9b_8}GG+<%X+ؓo?O^~W {)a pou~>k}`=_wp{e 5؊oW1!:?SW ?8p{dݟG/;jWh=O1A?j}Gd 2^~ق:W؋0> $&'TFȭFȚ[NJMdv[_^hS ,5bcH򌕪ZJd/aƞfp|4ohukui-control-center/plugins/messages-task/about/res/manufacturers/AVAGO.jpg0000644000175000017500000004346514201663716026002 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:30 10:21:38]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IO dz" >MѿRLjl5$ގWS'F#s];?+"ߩ~Vck1m)]G_k0)1uY:Kf6^CiH;D+$9}y ]n!k26+e@a?GRAaXJ~wK϶ʰs`oa;uUֿqiϨ`hV LW`UoFj˽knn3z2̽n$DLp{tM6^*pAo֏Ψ=7L⾮e3Zk,-mF]}[oQ^Z[CZ.2jWܱώR"3 =R}3!/ |zpieq_X7 bd1ٶ5OU3־[z Ǵ뵍ݱ.=Q$>vB\p$#7o84g'Đ=j/[{}(ݾ}ۗ?E9x.\斕nzo}(̝w"%+ՅÃa) LH*?ѽ®~zxY^4WK>ͻ~uY4u4G{Ϸ5#"ܜ ᵖ̐F~IOnIsZEϨ5L4LŒu߲F/_O3/*ΙUY间.Γk:+cSM}6Xv5yice[14sO8{.?(r"U,MѿRLjl5$ގWS'F#s];?+"ߩ~Vck1m)]G_k0)1uY:Kf6^CiH;D+$9}y ]n!k26+e@a?GRAaXJ~wK϶ʰs`oa;uUֿqiϨ`hV LW`UoFj˽knn3z2̽n$DLp{tM6^*pAo֏Ψ=7L⾮e3Zk,-mF]}[oQ^Z[CZ.2jWܱώR"3 =R}3!/ |zpieq_X7 bd1ٶ5OU3־[z Ǵ뵍ݱ.=Q$>vB\p$#7o84g'Đ=j/[{}(ݾ}ۗ?E9x.\斕nzo}(̝w"%+ՅÃa) LH*?ѽ®~zxY^4WK>ͻ~uY4u4G{Ϸ5#"ܜ ᵖ̐F~IOnIsZEϨ5L4LŒu߲F/_O3/*ΙUY间.Γk:+cSM}6Xv5yice[14sO8{.?(r"U, 1 93 70 1 72/1 72/1 2 2012-03-30T10:21:38+08:00 2012-03-30T10:21:38+08:00 2012-03-30T10:21:38+08:00 Adobe Photoshop CS Windows uuid:d94422aa-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:a5b0cfe5-7a0d-11e1-aae6-92eb3a8ba4a3 image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثW\0ZHN )cA8Ds9 {yJm,d1-H՚C nz45i5]x̣#)E:ǝsƿ4ڄWBX?9WX.+iʉ$dz+> 'Œ,dp Ge$5œ=??v o.[_i5]yK1!xPI?ܲȌlMN;K/8iu]0t(YWt#F@nU(K1 ?)CX|9c_'W?>M7ǜn}Ri>Vh8O##(daphD7,CZG5-SMGF^S"U*|ry0DFÉ2)лwDZҧ!g?8<0D:^w5Myw'0)l(?TM?!|ǭqV]Mcolq~?w?Z%XQw%V5 9yeB%$ HߋXpF%kN#,3@^]-^Q{;Cv17MJq9eN-Nj?:/5-;[hЋgEB! ҏv5йg<\I/̔1E?WWG8|Zor,Rv.LqT/.Iq䶫5[LTٚU<֭..ĒE3IWٵvPWU޵ws dF#9Z~X/RׯjցZ&h AdobedF]     1  !AqBQ2"$9a4tu6ַx1A!a2BQq" ?Mɿݠ~iX pQ/M\ /F˿hh d@h䱰X<_b${}Zb&897Ђo٭+A76 }]ɢˁ%Av9w a, 6kX=+Do["U]'&vM5b&DP xy4Yp$;}'.%mc+`E}kd]|巐xxAt%»rYv.0'o^Hj#I]̠61u=k⑄hyMī-+#ת/]jVު~Ÿl=BV8 IK8{J5vi|J|kJMm>[e3|D;Y=jxRہ%+Ј]fdWI J!boei9a:`jagy'qe]W6ެ^7_1CYŹ 3@0| "`(כz)FOBw?k|TxY~b#UHP1J &5>"-e+F6o4Yb.r;=ot&$I+oZbn1/w8 abW|T0xAkFd5qdʛgJr(Gp8ƇgOʨ0 A{@T1iU5\)nRZB.(qf7 ]\(jH%ӓ&Y@ED+Lʑ*\My3'\y㲌89Ëbi)^KP[r%9HRI w$L&8}L޵*TT6#lr,i >aQr.38'yhn) %-[TIzTRUb9'xdT|2s!cdo& u6$L{)/e%(us)xJ[oK&xOtoНV7C":_r,q#G\?fBx+q%)hdذQQ[KCzGSB:uE{6=FqS'c׈pbAnњ-)v. cK l;Q{{Xʕ$ARs{U=4FeZNSKb=iH&F[vo!eLS+LUv"8z^z Tf0 xZiOΆ2Xp)|vf7D?mV=@ꚩF.c [WU7 4CkX%:_VyěŮ}xJ d9;RY3PyN@V4J'RT=ӎЖR○icSˠ3ecKH% UlKF:OJD&xu16SU\phy{Ga{rmM+e|p*PkY"!2{Cug ΢ŐTȏO%ӖCE8qWUUUrJDW#u;^q!i&2ت@~J$nNZu*j(+Kyuٰ}țg#;4SJ6< 2" pn;)=!HU*d<^8VhCl2K]Y8-ǵךB#N:B l&55)+ CZ"?xIݘq, ЗLp`ہ P h +cZE2@:1v>k{qo_'j:z!6897Ђo٭+A76 }]ɢˁ%Av9w a, 6kX=+Do["U]'&vM5b&DP xy4Yp$;}'.%mc+`E}kd]kdbwB fQ|8(ojAw&.oYDߴ4U 4rX@mebr`h{lukui-control-center/plugins/messages-task/about/res/manufacturers/EXCELSTOR.jpg0000644000175000017500000004532114201663716026506 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2011:12:02 10:26:26]F&(.hHHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IODONއMޏshe{ vx#t̫zUm\ǵZ#]utRM(ycQfEU-sq֍)Hs7ELS~#mź̈́6朊;~~.eQtbjZ ]Wcl˵>tNOȭ[]c6[9]b0Mӌ籮k⬊-guͫKgEӤ2JӠ[5=fNOAƳhqu;kfʚ]hG}ƽ+5Vzl^n]*I{\qABl{eE^3ԉ{^H8lg{]iaW>tNOȭ[]c6[9]b0Mӌ籮k⬊-guͫKgEӤ2JӠ[5=fNOAƳhqu;kfʚ]hG}ƽ+5Vzl^n]*I{\qABl{eE^3ԉ{^H8lg{]iaW 1 93 70 1 72/1 72/1 2 2011-12-02T10:26:26+08:00 2011-12-02T10:26:26+08:00 2011-12-02T10:26:26+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:cf644b2a-1c8c-11e1-ae7e-db667b27342f image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~Բ uBc ( oz*S֚M47:}9׽uZmZ+/nuDxu~Nl.rw&qDc'ȦJn Ey(NleandQP++9 i] +B|@?"k?;Q7- aveV+tb0/ệP,MMW Eqw Doxѕi:X(Ej^ܬk>aBx|@bm|nz~QlNߘްٹܽjm}2mԒÏj)઩Oxm;/f4\ j50QZduo۞/n3+Rx<|^12ޟrAH }P˪Νۗ|gZq.ur=br|+ƕ!5*-g|wϻm}-ۼ2D%MEG{sͣm$3nЍ󾻏7ۻϧo쭫iu?~}DcPlviS=D O%5e?HBM c]+a'16SS 8FVr-pTmk9:l#^?K$]>X8ˣVr#ҺqW%7`m^˱Mp7`mmfj)^Fo%,pʔX9$+oj-濺JN0*@UɥI#uIg%ƈXq~@*`} }Wٕ&hTj0Qlt+`6hR=S)23~ܯ+KenE%3PsVH#F $7{E4 d,[{<.lO_5c^'l^R0_m-]!')ű#* QOkk^N;WQhÚS;/q^jضq}PxP5=͛vǎy݉л#nّb${ٰ\vG)ڝ9v[*aj7<)iH;w윋q70acVHբ B*iGD{򽥒 )PNAJSye}>_@}ożV?oOxi]NNgϬ~J}}+ٯ)>ۻwwB]{ 7ioՎlDeqcpPmMGM,)Pb$5L\*~$qoG)1č&D5n>Xܷ`S m6]ɫ> i"~|mKoT򝫂_o͵dlnݛcjmU^95 }>^Le5 4Ž|K{2_7Qf-KCG4CQ $_lYxmUg#B4)ANπ'77T¯Uڏ{}옷\mMv.Kj՛)u01uRYzkfxm6CY `d3)s]Y" KJf}Pjk1-NM=GNzK“RR:IjvG6qC@k.j{ϫ{'~G&I.ࡇzo῰ݽۘTlcpSdc3bB zX᭑ܯhl,I-gT5j rɥ* t˗vwϺLZʅ&P"SꋿƦ'67Ŏ鍧va$Ϋwa$؝mz'<'%}:]F]WP:N^s\mo./YX-9 ,¢2I:EGQ<}6n'+UIJ>($Sý{l(6퍡mnt6Z~=7'U  )55(5]ls^K{dgӈ^yj@rjr3.F [&<0z(_)o9B쯘!vWgq]nޙ^vm>s %DY)W3M(C}?eg6QĆFF& - 8U5 gvۺcpCJƎ2h3Ǣ[n;+Fn={~efrmL&'uݼ'C%Jcq42VGP\W$ͳmװmVpSOBn`6.p?t),Tʔxi)ZFر$fB\Iw;NgbY*MxytDX@`~^߲mw{]hI>Su$.|Sas᫦1X{S\%ԐxUVCQ96[c!;jM`qǧK3 lڬUHyS W#5VRˬVְ}ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ukui-control-center/plugins/messages-task/about/res/manufacturers/TOSHIBA.jpg0000644000175000017500000001156214201663716026227 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1! AQq2Ba"RS4FW   !1AQaq"2BR r%b34DTU ?&q_u!7A5QWAQR&T 0I~n^aJ.aK n" =hS75i4@ɯ 򨫠 )xA^ު~AuފS$PsT7CE˯0C07BJrRL4SUbHaMyTUa} oU? oE)_9*טR@R񂛡Ht`|)G)T 4mPԐj%moLO_XKVssrg(Gi 8ٰ}RpJ#- Z̯R 2F\Ӈ?gEkk??mmwEQI25نAEmGKcEt[LIߩK39Av)D[ci:;XiEQfͳs V 4diFhLvTSt7~PߌkT=B`-_3~LAXY4Q2wOs)sK`J;&DbbOލmr_0~}$.R(&<ԅZ*\DMY$(3Z5e |$~ƝmO;Ks|YܒWh)*|نTݶ>\jT]-'[É@'84G2_d$a vr?͞`ɟY]s|sBւSWq*P0v{v( |SƷLU+:+\YL'!*Tp/?Qibdq)#0:$:\RܢP9&mԕA RG%w+ z2׷X%R% +E {0(0֡AgI߿s IHy >&=t̮(=JR0 ^Hإ'8f}ߖHUNS#%1ȠSoE;pZGeI>/)n[μ~U%R`MMh@)"Cfe?'!ly'UgP'_z7%mYo Mr* aJuҐ2Mf|?hO*U Q|h|Knq&[,hQ{5G/a36,҂,JVA DA]ùu`tV;6Q@ 2[t|_lm :wAUMJX+SRJGhx7_M|=Cgs؆bGU(CHj]_svFtǒ42UN"+ʽ->)zVJ ya8z9zMV+Q"ihYbx4}ޏ8R^ @ryYVpzu}9qH9Nf R HH왱2[n=ܤ:e}w)H^q%q"6"k#zhm E <BzjZ:Ԍj)"SZ}fk6M7܌ʊ*g- G Bю3^*OQnϪ'T'AhT`Ytو;Vɷ)6g¹"X#lי#mNȒ~ZrOo7/pQV}#Lj7 avْ{l:-o&MU+k:7RZP P٥&g|*Sv6@3˜5ms*"ҘߌD*7lԝUu,&\ >S1ԝunfTj$;YR*y/d0Ȅ6 f Z>*1TjiW_u!7A5QWAQR&T 0I~n^aJ.aK n" =hS75i4@ɯ 򨫠 )xA^ު~AuފS$PsT7CE˯0C07BJrRL4SUbHaMyTUa} oU? oE)_9*טR@R񂛡Ht`|)G)T ukui-control-center/plugins/messages-task/about/res/manufacturers/HYUNDAI.jpg0000644000175000017500000000512214201663716026232 0ustar fengfengJFIFdd0ExifMM*1www.meitu.comC     C   F] }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?S ( ( (P{XiMU_h~⿃ $]o(tm5;;mu z) (OM'N\ӭJtAaƨ_]"xfєѤ= #YižկnuGQx<+7ӁM? <;6aw{[0K*thcGP0khq\t2.by}t͜%R;1@Z\}WK쫪^ܾst=FiW=?nE'ȓXE ~4qz= ~|= ?iԵ7ws$>v >zx?@Ͽ6v[)P&|:{!*2\r2{締Zw:+hE.vb'Ytց g<z;G4;y߈:|E<4Co t߉=_LJcoդ=H6pa ly`X? MOe9G y;^t=ğ~XQ(z tk>>TW#pGҀ (^|iKec EqazyWgRxmž/Hݕn`m*Ӌ[Ƒxg!0fܷA@Jk QBm!gۑ@w_{m"/ \xk[%~}cTL=kU4;-B@AFap= ՞)c-e%@EHPҀ,P@#}@c㦓>.ݍc.ovEW%FюyJڅb$8W_zf*𕥥hrB-ۺDęqCtCRqn 7߃bt\׼)g 5mnnopGХJ忊?~k>?ӵ/kWRx2K$clڮKRT/#kzaaX€ FoC<)imnSb$Q(htP,@@94uP@P@P@ukui-control-center/plugins/messages-task/about/res/manufacturers/GEIL.jpg0000644000175000017500000001145314201663716025655 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !AQqV a"2B#SR3$%EUu45&F7x!1AQaq32B$"b4TD5 ?&-qG&z76Q)m. SܨSSR~Pq(7&G.0&9nL.G.|S"|?F)KL_ %LR×9dIrƽ0^-@8l^EsMn.^˜:b&N;?T;~EA!§tuKN[?S; F; ӫhF#\To { 6r>#s})#^§t 0Wк{~Ϡ v0:?v_>ΥC `{G.o}QSb8>"7̨@?r/S;@KwVsܿ֜FΏJ{=6IɇL -U4io+ntfNo-P1ia"JҮgqH<R pIC1>|գ>5p۹|NR3uz@̙f{$ keM8\o[^v|$\XR5F ybE5NwWZ'T>1_I9-j6RR.ح{B䲻>!tsrFeM*T$wby.)UpxFƤa/7 uv'?Dj^WX F:EZ18u~?mE^3FcS G$}hVYуƫ3Iؐ0g?@]vʤ^TN#@of:R- G2?TI`rL'%Hre̱mG4n͛6Xcac0)7 *&*ycl:q~Ia|Gcx"ɜTwq p B%jn h}`Zԗ);X(K̳(} z˗?a7rnX`ݚij%n{^vnd"s\tL H8'o?g(D3\6&˭V}:trCI LM%vlTk|xfm~ao)m6ڔ9-XҧuQx.s.ZթpۙEZvT&0!VWJFM>uEҹ.V!d ykNl Mpǂ?I>UiygګzhduR`Mh/1d*SDo$8r<[ĺwR9n^H#oxeVҮF7Ֆo <~yA'E&Jgex;LblH3Pԩ11Qҹ+.lKci!}5F Q2tS .F,&)]F]𻷯Ě&ܝ=Jd,Mp{!,4b+ B|v`o]NjoE3C*oh R)i2ۂWD.L+g$ Z3I-0ta+yԿG п{ @/w`1=0SяNVLS!T9cZjR #LJf;>HB0۫:DT9a'lN6߂D1"Vܩ R6~Re ̥ ܰp̴7޹3~m0L[f p+Ko3B$y;C]!RT!y\KT@aR߅e1Ҧk8s$͜p &\Ҝ[0x{ʵث)Ӈ`b6 qYX_L,֮+;ԳMcԔ_5Vm8ܪPړ=$dnȝZWFCqȻeS +':@g na.C>G2ԃ#T*j# jy{;A9@j!W]em/fR<<*1`?wd)>Fy, -@-4y Lg\GXN*Aq5ţezjԞwZ赘,bjI*Z:군9Bە:C|d  4PT({W4Bvw\ޫ ɵ\hH_Ů ߧW' 9=ʹSr%(WHTȉ`J2bH6Չ!!jڥyB캘[i@X\^זN..u-p \3a0ۑG+Ck0g#EfV6"aFj^Nfgt^kTk::]4e@BbMt_zQn׶:OC qcQ.#,d0cp_=ޮ'3'f9#0 Ϲshu*1ƽLU9\"id]qdTV{J\ٷ8sR5D .9f_ל[m1S~yTźU=fוMo= :Vʦ7瞏Ѻ^U;vpi+Vʆ7_`Q=fmו-oN 4ݻnryV=g-ǕmoO}p!(Qr|ԡ6nGΏG~`; Be.w+1 g/,]Y8B-C4@/„=ʜua6WjJ96ԅ1& )LhpR&Bʘ.R8&KA29v(00r`6Pr9vx<1M\+ܼ}BFk {Ը)LogrOLhvvJ%Aܙx”\b \T0(@ QLx/ukui-control-center/plugins/messages-task/about/res/manufacturers/GALAXY.jpg0000644000175000017500000001122014201663716026112 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !Aq2BQa" #b3S$4D%5U: 1!AQaq2B"$4D5b#T% ?y/ƧqYzbD۔,H}:L\AeEl .䙊iZ݁#BŅLIj[ eZ|jxW r]W.޽k kZ^璫wRԥuY8ĝfluQLxL`E +?֗Ͷ/_1p??b|NS')~??8̰#jnVa=TbbC;gf?GLZiћڜ]$3sPҺ`C vZsNi&qNsouhe4:ce7Te:mI ܊1 jq\,ݪ$_էq`Sރ=1eCaʙDDr@3h2}|رrz XwV"g1i 5µϮ%Ϣf8&;kXar9x0{,`/ZyI,Ht0 )#cw.-H% fߚUs&TΪ8VniZ^y]q_e?zhm8+Z͹PGNt5ZAvYɲKm4],*FyƯUi]iY`g WN]JWL<󙆏~P:/*I96]nfnYw.#cTE>cn{j!qFR39ȹh p-^ٛ\ ?y]{#f8eѿ;[v^҅967!inKO?rZI'&}hR)C i /h!wުG}jUb"$mx sG07݋(bUA_/P7GK~w_ ߶ywXoVM1ZϵTԩ]h)^n3FFyu[L# .} ZViis7gx3fxa @k;GJ$u#MʖP!SZerx~L2NjE"Fa+>lz|˺ϣm>A~|4'+aP`G"32" 19FJ|3f hKk1+l@X`M|"ou0]Cͅ(ܙ/C$׼0Iލ2L #@ ;S"{%黔ZM1yP(a0M{*)j>-Ȧ ـ.”nLV!drQ$aoF&LEˠzՅ=-&rka c0&ؕI5FSGLPaJ7&K29u (az`0L"H=ŽȞznukui-control-center/plugins/messages-task/about/res/manufacturers/KINGFAST.jpg0000644000175000017500000000776014201663716026351 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1!QqA2B"$ C#4%1!AQa"Bq2Rbr#$DE ?&.8_uATf *$ TA5I? OeIO$ƒ%JטT*NiIW.#RFj-& 5TFa M uNI^R tTI/(2T]yH@TdP%rR ; 0kab|[l)vv8zRI`q$8ԛڶbl"lFn%\ƱYHM77l:-Iz+UC <|k&UX/KX5ZB=с841lf}-_룽6/oq0.kKE10𤪕U8?\ZKΊV+8/urtj+kw/7&'14VLkZѦ ^᷄j@]{SKw}t˓(Oz/&MhvAW]z׿ի% cketZ:Q(e^ͷǙ)T8ү[^p5NIû ]aV͡߃ݷHA4=> F0yd7lb.72O#9BWRV:˙Ȍ[kɒK `20+/l"GpRKR*bq=  q۹B-ַXi VEM/ u#ix2_&jͻ$kmr"1,C'SV9+&9X f[J@_P,VՉK>#,`{#VbՔpbKh#Q.̑܁S`|o2T|KUK^d6g ^pwz$Q-sm|v6 8w+fT2hAqRFQw`W7ڇ(EvtfHI1Nw%fjR?F&oS$s}~C P5P&%?U旒y;3ī1JF( 8*{|}'mZyft k HUL`| C{{^iq1~wvn^ &-p>_Pu+&=us;IL*i{HGRV+[poT[?(;~ij[2$bpLqӸohM}~mĵs]Z! 8@#clja zEPܼtQo]9~n>hҥ#qkVᓉi-q K>/3ۣ2!gV L$e,D O* h%O Wƿ~;olE[YC?Ζ][(kOGTb.1MIm?*/UMnW];+0.btJn!5UYPd ٽbfCuv9Kp a\\Hn G[\eidvpgseׯ@@+SvJ Wr dpǨ[^t6^}m9Fm'0 s~cEel:G r&)yf6ޑ\JmDr@) @] q!и=Zg+ʧr7)dq/Mo,H_37oWT_0^^@*q\3Ҷ;8;V_A[V ;#iQ9R 0i@ B#LXteUq RF .%BlBD AdobedF]   1 !q2AQaB$ "3#4%5RcDd6H !1AQaq2"BR3$4%b#Sd5U ?>LWy3@F=rtę4 gO%< z܉\08mɀByr`@Hd,Qw(LrQQbLBuf<8'LI?0@&eT#r$ys"C@❷&(I 9;Q"{}Eܢ2G?DDo 3 'LI@}T1@)DzRkש%4˥RIIqB ^D7_$]'U6-n=Hfں.-ʋm4 +D}.urm@"IRGm i']}j_tjbR6Nm7i>q6uy>(|]4Bߵr&5j3ب49ĜG:629ny=MĖTCjW5QHWF+6>)ٹm.-vTrqY3߭Hԋg,IZ0|=u,a Wu ɹlܲ2RI5Za@}O 0;Rpm'U*^)2?y֝{}S[&Q9@(41 fp s EM+8d>!:\ekVkTLlTj[EZ奣9s]',Q!L9RO.VIf:fmW_m>BnK#-/\<\bb[Z|ax6SRm}0_&WTƕܫ@Jo  nD1X/"yȟڋd66Z֑ uWNT'2GݐGZ̋k^W1.4qWu3JGtVڕDiz(BGIYGuIM/&X9Mz.q銬$QwV\[* N`EjWkxӍuZa SJ&G6lYhPH8C7C8rZxӵȘIXl%ؚ""pڒSs>KQ&rG4!03zr'Az]OsjU\B8ZVBJv0"/U &TD9LSRA^4ܜ>kddY"|yeIW30vmro8X@tzS~UMV֬SAH)4e䉎W~QUMxAvfNJU|FpÚh,T  ->hJkm䇎nzڦ|3ӑq Lk nDÄ5##%j0l\ɡ*Kѻ: [`h& 7eUqt@p3ƞ7u)=B"-Y(5+1b3C9C. Zl2M ]Z]u3@@ U\ى" k;Pֵu -Omʝ8]} 1}AFhpRQ(d q'چsM>YNCá1h59ǍҬ67v+][b2ie忄|;04 '((}d73Y}HNJ=DlfZ"H".8*졳T ſPJZ:Q~[2E2z7VWXe+Dt[:]eG}?$&_] ^BI~S0_Jϊ;۹$%fdԩ}8ޫ-_f2dhAjmWSRd&?O+RjؤsmB꽊,/8$m>r;4c&s &"00oOh@@ i鑑Pƣnek:V7g"dD<Rc㺓GT:~_.IhK KmDeoŏkJV-lTtZy ⱺ2o'ƹjZ8-f[s\|qXuUN[27ːs+jʉBrd'(V"^Nݍ47ҡ4nUth.mVьi)̳}#01h9O4* 5If4ȣ?Ӝw(|&F/)*ŹJK8iEfl9Ø*>D>35"0ހ֔BS OmשJ^lJ eqSj;b;\Cj2ZVnf=Vq= Fue6Iaj#"ώ1L׫q3o<>rBypM`Y!Ȇ);nLP#ːsvDv!bEe&~gN1:bL AdobedF]    1!AQq"2$WXBR3DE&#S4Tt%w9d5H  !1AQaq"$TU2Bd5R4t%7D& ?>M$<{&$ӽ i iC')tGJ3/|FHb!z` oOh]D+t. % [BK m.M.9 $w|"bLgP'Q'XFݽL#5}ɬ&$5uL!_<4 |}k򝹴;0=˨-v͡OѡE;Mh򟸷T~kӀQBgK@AK VҖ_0d)8\(WmqV]mm0Eȱ^$_Pm]*ڨF&bcq%{΋ʪ _SM.ie}` p<7ejW$LUŧ}]ClZzfKmQ\tn{^-o{r̋e?22v~Z\EΥ<_Ԏ-F#N1qޓZJs]z֗.#{kRw|ɽjWu3 #vzZ_YJy*ĩ1ay ?i1޳ZfYSd:guԲk{~RJ\ji}"n +Xċ ~ QdZ`EV"XmN+׮n%JmNR5wuBє75SOKo jٚ,MXlb|.pk5B+cTuLpPQr|Q*!'-o:WH5<-9Em]0ؔĐg'%) f<@1bav٥E?zjT?T q;maǁ!n|w ^̚mquAZȠWC4-7$l7=/|Wڽ~MlJW\_c?{9>Hu\a\;m|xxrxv%sU[hRӵ68S%LCo:~h& 1su?= 7Gyou圡M\3JOS>n'0t\B,U3fU~JH*KMztH@[X*&@In ɣ"h@k{.+I7s^apAߚ4lFTeJ M,*U);a(uIZA%ռ[146@ 454wzTTbrsrF!UC ,SW(r ;6*5˥!M)w9c);*.S,NhT9<̀4ꑟ8#r&h)hdXij~ʃ`֙Yq<426 }/Hy},Xܾݗ Rkē\)a\ތ<59ph2Yyɫ 4X nmKcx-mt|>GovMpnٶR'9'RͫXtS[1j3E93qY ŝ]ک];\$w@Xu)1)p=>\,bT%LAB!z[Y-?έ sgX8_}w1ܺd/ML+ IJ:BCaCx\6xea'oLq&790;\Q┩Fj*;޴V`|2_\vl3hͲă9YS4ki"IhBZ9Rt8$l_z1lFp~LWj$ڴC{Elo?6'=,_ws\«%M:A̲^8VcRi۶|r=ߡk3Cyy5kUʼ.Ug{\NhpN[[*Wz%w%:Z{)W w:<ƭٳYJ@7ҴcE98f_cܮTӭIpDo_6[p[o$mmWW*Q֥~ᘼOD1OdPj8(VC(a5E)]22Qἒc(6%{Îl(,ǖ$s#سX#N"AXc 2 Tϩƾ\2.?uO1[1Wk^vsBwQkVq (Cדc92![; /NCnЧ-JxSлo7~/|gO1[1U ^voJ_, Lм4{Ҧ*k7m=Og:gkZ~,]X>[2gQr_Sџ_-9d0_8Hյ]_xg_TU-hmY" v" {/:e dܡYM@F's,'.9ȝG$9Ml|5sr+]Ei I6ֹGOb6Ěwb:bM#ց:bM=Hde1.@&e؉];,D/L ؘ #ˠ:ځTH܅z.ղhQ؀(1&XNHnNOGR?LK::P%=ə{B6"GN@ z|6&D$vG'!^ukui-control-center/plugins/messages-task/about/res/manufacturers/MAXTOR.jpg0000644000175000017500000001016014201663716026141 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF] !1A Qq2$"BS4aDTERbr#3Cst%5&1!AQaqс2B ?<sM&! 1oF'aw&%aAPr JKq:`7`bWA>?̓r ÓɈe

    ih/̵#Qhi3)cu$v$vZ;1D{6ژy=A!Htwc%R@P 5$Y2kPShm07JnKC1"s6A#whu5K6,~V {UDt5ժ:dr~ ?lZdr=;Zpݲo?+"# Ա|)4g5-}' r7kU'i<,w+׈Y>|:qo9p)_{;<O鹮T@gpguk EoM u@F &[2 f=vnecW%zA]WUɵpy:d-oR64n.PZ+S30.ߤ>mVTo]_ZE%y8[a ҪBҪNAλru]RdQ52T9@D9Uk\p5k,h˴QYL[:ѦlheTM8dmjj4(Bg \11^<}BϏWoջN-C\:&΅ n(A"ЕJ2!EcxǘS.QZ ՘o$tm6tTT$r@m9;y($TJUI"?,F#m|Ju/x/0r CåSH* KA'EM Ӷ܆uA+s 6iC̠ZhD-[m՞5id=R-nU ~TֻH^-.}hP6oevY5ϳ=@"[Vqh3J Ҏ,{e189reJgf4"uXf #$6NΫ_-[6rqZM`pK2r2)~OX@?.…R&|؇d_󴟰q2t]J cp(`#PdppFR2U* @2×خ iT鵂TI(Mf -i05pjQž%P9#i q$q1+vKjxXETl9;<"^J~2Yb;sʧa+;<޶@ŧI];a6΍bŃo %_uS/xON]`eK/@}:>%Ҽ" Tɳ= uOtaܱ$J;'4Mc}V2a?^bcQkV5t-[R+z^G\.іfa1K!>XbCoJJ007Ej?c Zt=en"T5>?Bt(~„ >`bV V\%rK6*/?YDMr?̓rukui-control-center/plugins/messages-task/about/res/manufacturers/EAST.jpg0000644000175000017500000001142014201663716025663 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !AQq"2B$ 34aRr#C%&W!1AQa"qB# ?<1sMC) 6 ф?`C͉cdPw<]Y NC,`z݉_R~ J"lMC) 6 ф?`C͉cdPw<]Y NC,`z݉_R~ J"l>E sUFN5*@a1 T^8i8jVJT1!}f0CKI6 28 4^^FLdIEG.ChɍXEA%I뜠"bQJ2%!@06mųN{RWcӼ2B"@.8jF\+PTO蚚7jS 3`T5$ BV[6ȧ7EeskyosiD^Ju%QCUTj)! bgPOPvswnNAr:Cjh"J%APU*+)G,$* 0q~,qn-vTNeȎt,:rvQyk*?GVfnV<#7?\A~K}"laZWF}El2Rc) ':B]&0s14qi^EuՖGifƠۗ.W 5{ORK/QMb%wuTRP) ݛz9r9O'=y:S둭]9\r])j5=kр mT2 1.@ws!Z_Ts""PRὺmx5[ &uK+Zg{TޝT_V'^)ÝRo0aldNF+Q'$m/dW *_Ri2"fljIt[m$,D>/Y*SL۴8-IzL=Ji}ܠPT8GV~w1kp7+<๾\'|N{>Wp53B:i )cv9m-DWgH?6ƙXJ?P1 :Höΐj:ث{ S"ua!LO2e΅ɵx,='*KLS!(%G<}pڿCg;h[BMoj}bNǭ aߨJ&nӵ ng%j(bFh?߳|+;ʯ2Jet?3+uoVo}+x5ws\c-^Rrյjmm'dKLzpꥡ6tX|-{saWu!U:)&2>ۓsl8tt<>뜧r ,nf|~U;*]uon15m.Zuin1#J05tU"fW#  E#8g!soa筕oo$nZC{];-c+ۨj;kQ{[>ι֕Sqei,wJ>Q MV5oWvGw޺ ')VLciQ8Sfq8ppzg[ҫQcjҮ,R[WqKar)T|RFE*D2A  GtCMcYNTL]Լzr-išMyﲛRJIt$bM+&6eR"(E,|)]f4uVat,5ҵƐUηjopXAM5p^@R66ĩwi-#ʒM3Ӿѽ`5ռ WOnۗm1W$X+@V̥LiޯSofrvZ9ܹ 弣)8>]nx\ nl.1|uզ&#vGId Nj)Jm+ӑaN^S `F;1ڪK(rJR{^&([kNwg?uMdOr&hVi†YqiTY^**n?7ٽoNŚ&8҉iԨZզsCTŽeuV`5:`ٍ֪Yզ"${]!qyA>\21dU) 1JP;/fq̪32), *cBU4MB2Dq0[;a NUq{KgIR`eԮEC+XJ+`+j'3_*e&>oN6j$)мouBj EZmTǧoUF6]EJXUNj6B!$ C{2"T5#n(\ueif -KV+]5}s"ՋQ2O*eHss 1aJ`iF- Ď3xnnnB A +Vup )kR"Rmh+)SUHI+ '|oq@{y& \op5i4ށP^\Y;]J8)~+"yRԯ/,XiA` L%<,{2{==_f=MC) 6 ф?`C͉cdPw<]Y NC,%jPO]ZM`aɷوe<6`C&bt6z0hyy,z vA˷1+"u`6`rP{+PO]ukui-control-center/plugins/messages-task/about/res/manufacturers/POWERCOLOR.jpg0000644000175000017500000001165214201663716026631 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]      1!qAQ2B $ a"R#SDb3C4Td%E')  !1AQa"B q2$U4t%5rd&v79 ?pDL594?'bA&، SQU@&AE?K ' % a ~QX鞥C:e1!ys)JPDxct ̫xw]qf1+e5vUG\fBYz1J⾛ȈHc 4hT&a.dy]OY6mwAtCJB(HLFHm9\kBֲX͔`]O*%6Jd)Ī!t$kivI) qnZLY5PW4$^?&z[xۤk%;=$X+YX[.wSʐ$?݂MۆwO0&}Ƃ)'M r|+dѐvE*tRC4VDڲֆTGևs4YN(.3D(G(2 jT ܛmvh? n[FNDY`wV:qDE=(}܄ػr[B {4qx0f=Q\tR/m47!?FIpPҕ+Ã;:Ƀ?3aG{ː+Dkc7qNeLUߙ HIZ?qM'+[zXRZ_b1e Kq#F'h{nOy~c8.Hඵw1\Su7NfG> %]+NduUjRM+R*t:un(e\m [ϧy?m>;Q'¯KO #Pݴ+QWpߔ^!NA2$BP*2\'v%W6k/ z6uG/(hyg 鼭A' l$HQtdY,z*'3W TβW"^ r8TgDŽ6yF6};1+*2yV*g;_],Nl۠ &ņ:ƘwB/\U"1ȹb}e-'YI N|_EM.4slE dB_ !mPҺ}J^[hk6^\jVpgOڣ )Tr/EiTJ as0{<@ڧyvSkJ%%H;N# %Z/NY'/@|7μ$"Sa!6o~lb;ZM1 ;3.S=Y [2uLG~!{P2u4-sgϖs=6E)ZVK&КZL߅e F˛V9q .loԇ4^-{N|u"$ rw%o[gA5HT@%3nAZAP'NA0 rf`?Tf(ȳn~chȺ]нթnWVa2k[2c::qجnx6ob"ޑ[(ZTrsSID]QO Z-Vo@Y&O#2z<~J_POnٌ2Nq `. cAzBEc/XsmL(J-;~u, B .*@ac3s2Z$:2gM Q}(ОZFI(u\D2d 4>Yi?rC~"Jxh"A**$hTo'k+Hm00|ZDsFdfa[.OI:l32$smޒ? hv\Paw#+Ln^6[p[ٝI섊i.5y5D Yߋ*"?ߺ}KQy$ ,7m¼ka4&(|?vZ6t 4HǕP];@@n"F ~|k0yrf.AjƎD.[Rִ6,\lֻ6;6Xg_Edp !޲i͐9xr:&Py#41hjv]mե׭ ޽)s{tl7kvNXdյulO_w]* m*Jibd,!$AQ0ēanÍSĄ)D@2zX1UܢiQɯU``uɦ bpM0M| AdobedF]    1!AQq "2BR$#4 !1AQaqB"$#42RrDdt%& ?Ǔ ,qW&>B dA1]H&<#JQ$0orL\w(0 )uF\ ˀvu(TwjزaWL}1$&b="LyuPGH.!ˢI~`P\ Qa@Rꌹ$+QLT7e¯*\) cH&;M){)tE ꠏ\CE)GD2q$TrH *(2W.ԣ֙SobPV7Z$];g{Z{tY 순"bN_۬M@D {"i&݄;r, M7TKPdMAwMEʴ1izxlBhٲI-Nή?5;XS'Fkmԟ B]Oi|׈^QH'l 1dӍމFf {?<3[gF%S6|rFܠct KZg줅eR%f}dZTc]i4S&0Whߗg)q >,婸5#rnMۚRv'p6S 9v+OגF1Cy׸4>&Y:WN3[KB&y0Mihz>{ndN N\wD5&zc en}y=PCw\yܲJԔәl\fO'}rf\D2iG ap"a #yF`s^/l&SћUNyڳjɜy6%$@Lڇosu@iRUQnH%G;U.2s$9KfЬ.O͸be*wAZNFmzHTgncd{F,lnah/ F0 o֫g<x3?Gd6?R_1+TMi&F%ȜʐƘ 3H<1KUkQ^5B]r|[ wBVn`'?0Lr'yC>N?<,gxvlCz4y=K|Uz>=v1Qc/=B!U:ڷ"N,|fĖboLt$cnR -X_W[Zl͌mfu4qXaK uO<9Vo]\eBo,es,A`w1 $o90/%Z_] ~s o [$wbEXwn) +bsRs+fۺ>Uff:zp >Lr1?yyÁW }kit9k3JSC4=eI%˾Ԍull)+Wtc*=h-!ݧ!3eB8yDNd_8En:oOfjSfxzLL:z>_;jvw,7Mҫ9U{H24LeZੲ~wYAdX[> }JR|yB IaZ+5+TRnڸywv9m,%,UlS(r V7ۙBUG-^Q/f300_^geRC΁jjzTN]4ͥ"nJc};ʠRT72hš %umؼ \2FD*H)bJT7\k]Sb I#Mqo]k?c>?wlG_w](L+bZW&>B dA1]H&<#JQ$0orL\w(0 )uF\ 9( >ObI^T 1R0LwT$R RA1Au .R%uCer)FIK2TPd\;G2ӿSTŖ rc)a 6Hc˪>Aq]K$xR RTe 0\`wRZeO-&yP*HSA1RlH&#K)ǗU}Ԃ)J:$ Iˎ&.˒@aQApʟNuMS{ukui-control-center/plugins/messages-task/about/res/manufacturers/OCZ.jpg0000644000175000017500000001064214201663716025567 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !qAQa"2BR3ӔUSs4D5 !1AQ"qBa2R$VbrC4Tt& ?ǓJ,qS_e!Ls uIdA5]H&^<ԥKuCe9u$TTPd.QLw*jتiW&B j=T"M|R yyJ:$ $r)FIK1 4N]=ԣ֙IT7Uү*NM}1$]%)ztE z(#PRtI/IxR WX Z l=pA&Ψ-Ah8DmrF[@;6#\k:ˀ'Ol $/T7Uү*p^fyy{0.'T'%̇F{2e;2Fv)\N% D#3O<5TO,Dfq  < 7992$.僜9'-n+D{ᥑ9:2c8#k!AUqKq-?0~ҨDŽ's"?;0Z8*W^*3s*,k174K`P;}d$b?L gX59M,_޴Vm*9Zy&$9nwq:iEQ&%#0 8pCu>tg6n~q^ xϬ R~V.E]婩bǧJ*ۊDejoL'}V%|ฝ' t\bV;cߦX]!8 I9#[:%FF{6?UmSDQ[VJr]_9kc/ޫ0"=P |,9X %ב?)s{/!ڇZ32]4n\}$k/%;>%vc3dtLƀD7$Zb JmpO䗯 }%}X}$|Xz]q~rr=}x,.KR eHT#0RYQI0׾ꮋP9h$!OK_2~DPԪ(c݇O ßo/ #8|ŋ&ɞ?A[n?x1iczSRrK8}JX.Uү*~:)''nHf%-]r`4_mDxߒRDS8,/m{mir}k-'vKCoUvѰ 0zql£Ǭl#8S qeݗmC'M;;|-~OnݝgN6W=yZ?u_3`\J8̹xe3O¾"( $msSorT xKmbNs[vwXڴ_+5b_!_#8H9xa۽SY,cn3K &P:^1s/I8ec>?F̑&ؚ=\3PT0] qch![ǹ TG6ܜp?Y ypH!zr pǑWSXfH/OC, KW34JDl#hnǗVV:]Pʎ4?Ti@ Ю'V JKKu[;~}?bI ]NеaZkjxS2 k 2*a,B1bYGb rNE8df?0GTD=5V~Vy,o fx z1t(?R7fQ|K6x,q=Zso2VDmKTf֬ fK8I&P! e7Xr3PD=$HnDCP ٯM`n4Fn6l=oQt}GUتiWjnm-@  cvH@tĜduIdA5]H&^YҢjnHW572$AbKBݲqh#5 盗_N4LKŢOh[4Z6֠?AXr `ikuI(Ų phioPꗉDF-_I2dm짷=݋DM5)KH}5MUi4ʁS_e!Ls uIdA5]H&^<ԥKuCe9u$TTPd.QLw*jتiW&B j=T"M|R yyJ:$ $r)FIK1 4N]=ԣ֙IT7ukui-control-center/plugins/messages-task/about/res/manufacturers/OMEGA.jpg0000644000175000017500000000761614201663716025773 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1 !AqQ2B"s$4#C%1A!QBaq"# ?˃_t't +@5t D/@uN, -\:a,DJ%KHV.%/+E>؋Š;\1;tiXQק!}vAeH~io"| b"Pq,l"ZF2p.xA^b)F^-p2J g= eӲ .CKgaXKca1IwK O6"9;Ym%"4J7/wHL#yȤ%JS}XÃXbXQke5YoHc KH񵴧i/z4&R)37cH8EIP-2F45,hN\3Bw6^$ i-@Th)T(I1 1yUE0RqiBQ8sNz%%b!ĖV ٷ4y:&{c?d}UsqtrQJ4§_kZ2tFJP5JAKXd2N]k"!T9qԔaeCIp\>r(*Ns&j AN=J4k% KH3*quN녝txs}M?QϣNр0v"97n IUHs0M1OiXVLRFC3!NRxFB\0zCmRYgSÁ=GWjҢG 2ls5+US΀I5&2˜kˈ%sݼ roDZ|hqWZ7)RNp APHS[?1eBXa!(e4YxջW3Q-L'CmE\\tSkHA)72bK̛ UQe){WZU6_(n6U]@JU9['=:s"MebNlE|of^7e4sƛ˙#=eݘbE:(򶊔f8ym)k,k I 3eTHGJe3SnLQ\k>r.TDq\e{o,[6 a*НJov\DQBI KNjUZO0#!3'>b-4|aXWBq9տ!/k,u5[ 'Dp6/<ڮ3gf#'T : roşr흥t{vd^d(EǛ5 Ex^9QbؗΛO ѽt47( OC;dͺm~eڻo%qm%q>훍7]YYBϢHAIεXtDtyDT&jEK4۩F[[WO,YXq= guz#ܤ'166V'I}mSV*i0:5}[8 qU+S/Xǻ.q[Wqح;L>-&t+u޽uiAx禑>T:>CPeOg .=5۷d$ O0|086ˋfvkEġTi:ӎN-ECPazP[x!r_Шj(m-Cor#}lWZt|_Шj݉} N4>U6Œw%vA4wn?,S9l]IKQPR/B23.)m%/(^^,7/;/גn͖~rMYJcT&D QJѱzvr"rI;.uC- d*g-^B^3۪&x7T.U"' p?1&_92JOfrFZܜ.;zp/UzY9ҕw&:Zw+Vqit9< [= ?\fC-lm}7-ZT@T;p 6?%rOsYkGm:QFH'e wF Ϻ z{" :˧d\.w "%%c+"NlEbi. }Ѐk4Q}p(k]; $?4FvpPU(86-#Xtt 1w#b/CH8pk]ѥbD^ȅ!3]%Aıiäyӿzukui-control-center/plugins/messages-task/about/res/manufacturers/ASROCK.jpg0000644000175000017500000000700214201663716026112 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1! AQq"2B b3r#c$41A!aBQ# ?m}#2obrQ-kADQ4tQoը_Ȋw] }^-  62_b)kl] [F8z7h19B(ߖ(}:(7/E;OF.>g/NE@XkAzv`vhy5.mw oZQn>Ej"çEBif~aKbGe ;;4W؊}CVѶp#!ƩG՚ (:bc5؍3/#[U(-#7s5sgoȧQaaȓ%+ٸωR5In,5*5TrƪjsV'D uke:#go#0OuqKϿ&$c?fЖ^)kI@G#MEd"jЊu)抝+;FVlhơ/&y}\jN_Jk$ I}lݲ(M%w5 GLOvu%_^cG]?Psף~aKbGecs_.zswӓI Fdf IELU(u ïAۜ Wo+.&n+Br)I~-!$SI˷x<PT=]\5~ ]5L#xc%LD̖ )lǐi(:HBz֊yCKG4dXkn|N>ug HYi'%츃EH*N]6r׎Ska1K\ʿvgCUT8o>=!AxujC2yY=\>yŨn.7+5G 聙d,FmX#Ip.S9tbLlj< k@̚T2MOdq?|`2N{DXf2v1G_V^Y&፝֍LLkv͐)Ot-CUcl䯕a${[a+(RgҨlK MX$C(AuI-e5:Բoj=AZ׳FjNYN"R^5_o0x %lw'2\V^u aeVu6VS<_ 4Qkb?"Mw%)%aVs"QPVH9,lo?մmしv"kZ "٣~BDSthM?Psp"4T l@h쵁`fO[bj6qѿAFFDQOV"):z4Yt&9k8zw* 4vZX Ӱ{E}᭱t5mkeݠ~Zւqh(ߧP=,O5; [;-`@me=٢Sغukui-control-center/plugins/messages-task/about/res/manufacturers/AEXEA.jpg0000644000175000017500000001170514201663716025760 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1 !Aq"2BQ #$aRS& !1AQq"a2BC$4DV ?M1XM}B׆#E0MGՅ50uN)GD~9&G.C 2L5LT[`4Pd](Dx15MQi4@_f95LQatE0M}?Lu0]Cӻ Q2_8I˯Œ S 1#@ >i>? MS}ZM1yP(ل)a0Mxb;$S}X]L_o3#{1D˜l݁S '_viW%ev̲rN:jUo;.0+S7vܛ\߉y,`T'o=cWu-VJ{X 73%ao[ qm/C @ÞY5}rфc9"~Y/Qrv"uh\6: nQi,'N"$ ݢ115LT[`4Pd](Dx15MQi4@֚nݯ&lMuF[7n)Ok ރR/5Z3]%MUHs7 z[J6NSO~#fqKejR T|RviWwJ[p{Q8)/ӌvܟh?FJ?u=*nPEۣ!UխF-EfsꮓJ+!m,4]%e5UU) {B>6&U'N/Bw:N=O4QP)/`vx={Co(n.2{WV5Mnetgh@E0 ּԎrTM*!n1b1W6%,-ڝX٣^W%E@G-1/;y )}JlpDZ35ē(>ZGtvlQHVs8rVDR{gg1 /)9\늳~ N#+Ư7!⍖ yB s#(d'qLsmڥS4Ͷ[.C]F b F-y/xxy{rrv=v<˦+O>ka .y{i1Hߗjb`kp{ztXđ%U+TdhR4H'%$6k;M`swB-ۙ::-c>-(s oVr:Pv8i Qێ\sI>[1n"ҳ*›" #n\_>RpKLG>a_ TgKhkͷ>ڶ={o;jOgnE^.#UD:Gq}n-Te2ȁ&5ȶjH!_"Pjֿ:FQ70ݹvÁ\ԴTC?-sፙ%MAUݝ߫+s]z6L)#Vܗ?*V\_2*1KJ*ڽjpG@LO۪޼γן -z<`B1 @`\8E[Uqrtŵ 3kN3n%!Tz#86@] nY[ζWUg懕iğ~a1yڏƼʜHrlZ,5-Kp LC1:/m?gIkdN#k"qċ mYT< R9َ{9ZV(-Zit00ûulΨUL(\پņY# 8 Tdwv]F\fKn/n2vTAoZ98Dv^Q7úeܶ?# zCgo:`keK\̽8;1__=|m*y:[e.!knU5FttH@MBGT _HhUPT tOusAāCȕ+>ŝ.ss~ܜթpqqpۭZz?"*RRgs'CaU_{ ̙ڥUDjP[xp&yQȼyfA>EQL#yy4 6Fw Ų0=A1`~Sk:d;[il3 8 xkە{n~R>̫ʡ=7Z@JGaW:#?/L#̉\kkokWmA?F8ݼV%'JQ[9V7rlD*_7Ipߕjp^a:ʁܫ1giY!)Vcwd{|xpWNNK8Ck }G.F[MaQX-.9??⯤Z5-Kk MzʚT#uԵUn:DT >er[șM/ q.ZnZVmCx@Mnu@e8NRu$tS0=II=*tdO2@3e IpWG'dn-ʺv%F7'K+IءzÝ Z9bF=<}ܵzqƕ.K2,l6 @v ŗPq+]/}؇$׈aFIrL ˠz݅4ȟo&-&rk0&1)|0$tG vtLP(/}؇$׈aFIrL ˠz݅4ȟo&-&rk0&1)j>. 透 zwaJ:&Kv!29uQa`0ܓ"$raG2'ቪoukui-control-center/plugins/messages-task/about/res/manufacturers/GREAT WALL.jpg0000644000175000017500000001364514201663716026524 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1! AQq"2B#3$4a&!1AQaq"B$R2#4D3d% ?(z@PZ2۲&jN˶Q\uFn' 8v]) 6O_9FwFUoO~M[Trۨy׶ <hPTiQMWE-\EP&Eu^U=T [K~j-8%( Rr =~^:Ʃw*}8ʯB;De{SNJJ=Ӊ>cYV[EZLMI4)Z8 ܲbʞN5 < ^'lӼc-%FJI5؝ыzrR~ef^;:ؚM0%bN泵*iZ=w,jvBfU'Rv1+a=4{+wz(._O$p++>~u= ;R1|:p衶@M/W-Yhr׶C?[sRU(@k&SuEeڼ㼒JsaÖvM@S0! ޼޶rD+ZF*qTJ tH̹mRcW,@j2=dͭ@ĚWDp2Ǧ,>B[$Q`SutE On7^73``28X}*IJD+E.F L!v^p,ΓAzSod:$& YqM-B?!G: +3/YʊTe`"R@ GE3̓)>wQf.>i?TVꍖlҭTTr[*]2jr;O4nFkv8pY,"zRzxp.bPPME 5jjWّp:>mm`~ 8ԛ.͓@aQ;sq{0IRf޹ qgn'j`=aظeBl!nrFpW-,U…#P8aJz#WK5 [Z/q8Qc?8+{r^N]Qm^LjWA̪(-AM?~qG~ o}.ka7x*{i+L>cf)Tݷ9dk(]I{nA˛TR뭋HƤ4%Lª#P^*@rzmG4GPԔ$#/g<`X/I+ڽqNJY'2dIҁt(oS%s .-XRvػL*JҷaMuN3a@:ث[BRu7T-mW$`!TsgN- tvmjWbgnd.gk-92^Lhlh|bLWܚ[ͳ?ES-[dW[fX% l;#p[W2}{rQ-md࠴̂}483)~GI+ hYm^g|ܒ2&~!&*4ʉ xז[ ^\td-#I%5noH*>Cw@!ct6g-EjO}bӭy%2tWIhŭ.U4lrc1+*mc ˺Te3뱉&6pKЕzQU-t'DeGއelӞE*@B.r>\nVRna)b2npTLE$̷v&Hzmu)W .7/M iiMYr'2RBJQ7VzXTzHvF,ۀȚkW2'˅pYџ:jr' FI ;e3LefkU`]ڔbӕB7%s#,%MɭeJt31d{h+#ˆ4p+H.wq3|]sWaXcM&B+_L&5LR_͗]ttŕ]Y, )=D᎝=Щ{>η-({s,Ҁw.x=*E5Z>\ǙS$uj(ywARBD0UQһi<ݼcZ9ȵ*1L1:_[uOXLӶf1%R嶀|'ۗÖ6\|jaͧftenvMS^8T|h˘b|0BՇg)T+BB 6bq׽#$+2/J*СVOZ5*ƅC z"p 4"\èr,eRl&A^yg&!H{M=W7z^58uv遫 r_E"qN$6i퉳p{㟋U=ߙ*0Sڸʟ/&SDﴧt+PՒ cylx'`uh\J"qs<%MSBꋕ`\:ϪNw[8E{USZ"֍\ʙW /P2j)@1*H",PO/cJFToY-6[M2Ԥ#vQ-M9Lqafxܸ$vGzݙ"țI^ePUoG ^X{kpf\YpL[\M*LePU'.akՁ݆ taL!A9CA˯haFPX`0(ۣrޮCmU^Y#߮ H%gGU#Tޕ *75&-6p)lWnZVrTgT_1{pbgSE©K:&g df܇(S3IOJnyj6Qd[X\k TZSPkz~a$3|r2jצ *)93ϵ7NmGsoY)Y35T+rmw e˹JkݶfNDD xAp(G^a4 9Gǿ|s/y̺U?o^e}[=~zY Bi1ȧ'M|ϕ幤ڻWozPbW0rkc f$A 0A OVv.х0tKo .C a\ ] (᠟DZM1ގ_v0M{1& 0MGم 0Mzz u)2_;~(h9u (k X2 PraG &?ukui-control-center/plugins/messages-task/about/res/manufacturers/PINE.jpg0000644000175000017500000000752714201663716025677 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 !AQq2B֘) "wHX9Rbr#%Y1!AQ2BRq"ab ?M+<\NA5 A5ENCM|<ԇ]CRǐ`PQr*,NcJPt@{*WYE>OoFevV.M}U T Qu !&jC.cI~0v(t(u Bb1A\=+'2 ZM+q&SM{(MGS_5!DPT$;}:he,qׇD)rLY]1mODbr)|]xZҭ;y!_|P(dw;̘M!ftXBM,f"&9mc2C/D.eJ((̮J`eɯ^.QT1H~<<,y=DD|"#E)TߒN$qjwHeiL[{9MG}=ūon`Q@ۑg 3[#i7:ثr8JEREnH؅^}nbGe = .87/4ڑ7r84\g;{lX&l1PO %3h9`B"/:?H'>18?3ISƦ>i.#~\1![1ɻlɦF&ĹN-28H܌)Rj) |-k޻ULm-džw/;8~6Y}*N چ,S>`lWoKDZ;gaeN9O9>awg޼'bۄXWcCZi+`a!Y$qljS*dVg{֦㔓7g/p?d|p1^:s}R@,hg =G!!96hp=(eNփ)q7@J B+taeowyήxyv[;XS.(DK<3H),HP,e%q!G5OJn[&~Ok4cM*&>)8X"p_(mT(d I:kl/T%P :Wm-'WP/c?$_:Ϝz=q:yo|CT=uƜtYn/l^`_5{/OOʷ"_ߓL@*E==?-Ư_籽?t ۹'ixgO+ im܋4D>X H~wm܋4:ݱN~oX-(۹ /hubT?KKnW8wOfL^68BPkGKȵ.8˴^:v'lԷm.>%--8۹'e?Fc%hhv3:ױ]G?I>[w~88Iv؆Rd;960L0[&9{ڪCiql|rWyTD 4f\NA5 A5ENCM|<ԇ]CRǐ`PQr*,NcJP=\pQ""r@=8ܺB~(}tԿJ9&SM{(MGS_5!DPT$;}:\JK1SҀT.^3(wG_uZ|Nukui-control-center/plugins/messages-task/about/res/manufacturers/KINGSTEK.jpg0000644000175000017500000001202214201663716026345 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 q!A$Q"2BS4Rr#DT% dE67  1!AQa2RqB4T"r$dU#3Cc ?>?a>lHbǓ P!30C^)PfCp`zs )81V -`e!8=XR ylJtxP0z3A3ĉ(y0?/41Na˜5i7>p“a . X9Յ.pgĬ7@ҝ@7pl]VJfG,r?l֓JQ2:]>YN)le-Mn8XҲ(̚4#2q4kqpzVrem :f-7[.9Hn=xxprNSf3O]q5rXźRc6J*ǾixWH԰9My%mp?D2r0T815w:;\Ig"5QRT4h 1,oqN7k&7 'xtawBʊnJ^lWGJ\lp iq!i1ۚy9]E,dTma q_i13˖khnM/gn]?XG!7z~|[x1NY]dg>nhT0mjo*_P*&i#=C Jƥl7M p_?Vp[lJ8eYc판dMd T.D-&m*Ӵth,&wIe+aU JY/kzי!d>~HqGhP#UDNo"*weHL ,qV[Fd Pv'HTv`X(r6 +L`~'DRYUTΧ %4lōwvW|hvhM $11Muw6s=ea;6kYSCh3#ye=Z#9~2O ߷-9Y1<^-~'ۅʠ"@,$SNt7' uroV &ߵ}Zj`6WIrL0[JCuE66[9=<X)|g%5 B3f5gȟ5PXŹe2)yYI!Γ2Wmհ "VKp@vPM8au[r7&vJYU~ M5e64Yɤ;|-V0ˬ&v${> N%KM%8^t}< tN=4!@ç)Aqw}sh.i#<jshnXTPN߷_dXrcȋW1333"LCѿ&'pyZ﹊{ie;za;KѲi8(C4g@6Vvp<`hN!ABp8qO*8z/ [ē k $8Al[R@[Il*k-13^ {DjGGa"1)Xily=eWPZY%RޑXZEw7-nYa- (ljrlz3[? )"ux`8o`%|qUNd;~MT2UƐf1ơ5%QWMM$ YeT,A$"bDi2_n+leZT{1?6z,CUqYu2˭MUMF"2 䕝ɤx_yd8btN$-܋3hV2kJ lO~R؍ړLs'" m+kd8$o%2ຌVcow{πL>=u/4{a=wؽ;Wnnճx|q53·55ssC+<7aOktFX0z3A3ĉ(y0?/41Na˜5i7>p“a . X9Յ.pgĬ7@h?a>lHbǓ P!30C^)PfCp`zs )81V -`e!8=XR ylJtxP0z3A3ĉ(y0?/41Na˜5i7>p“a . X9Յ.pgĬ7@ukui-control-center/plugins/messages-task/about/res/manufacturers/VIMICRO.jpg0000644000175000017500000005307414201663716026252 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2011:12:02 10:29:03]F&(.zHHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?T۝,1i~aoWNox}۝,1i~aoWK~qIQ?ޯ&Ή4'Wx}۝,1i~aoWK~qIQ?ޯ&Ή4'Wx}۝,1i~aoWK~qܖ-o]}P_X[_M*.{6Wpۭks/OT*qa;swuY\zRIŮS};}nrk-vaemUٷYw 82L^iMF#F\PAWOw hÌLJ9K7;b^.6)I}2wkkc[+'q &+yin]I%6f;,u=7?#JH^~C۩%;qGtdaZݤܛr|/7r[Dp6fA^I!n":zGR~);2+ٌ;[;w~h޵e_U;7y%6luElQausJ960c^fي 6J]p\el=kT)s2k^kC^3ZڟwF ,>cdzXzi>wܬ??cm?"?X9+Zl[|'.~&.UOS)|.mӳ艹_Om}7{8S?+^̒󑑳c_4dTm w߯fEgҳ'w%[6?z~~^ܿ|9}h>N&EYX᭩-5 ;}4jr~wUNPq}}]}?u5kI8;o+ۗ~7z]k{;wZ^X־loe։$u'E{HǞq}"w'np2RֿO'^Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$jPhotoshop 3.08BIM%8BIMHH8BIM&?8BIM x8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]g*h-7]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLzJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?T۝,1i~aoWNox}۝,1i~aoWK~qIQ?ޯ&Ή4'Wx}۝,1i~aoWK~qIQ?ޯ&Ή4'Wx}۝,1i~aoWK~qܖ-o]}P_X[_M*.{6Wpۭks/OT*qa;swuY\zRIŮS};}nrk-vaemUٷYw 82L^iMF#F\PAWOw hÌLJ9K7;b^.6)I}2wkkc[+'q &+yin]I%6f;,u=7?#JH^~C۩%;qGtdaZݤܛr|/7r[Dp6fA^I!n":zGR~);2+ٌ;[;w~h޵e_U;7y%6luElQausJ960c^fي 6J]p\el=kT)s2k^kC^3ZڟwF ,>cdzXzi>wܬ??cm?"?X9+Zl[|'.~&.UOS)|.mӳ艹_Om}7{8S?+^̒󑑳c_4dTm w߯fEgҳ'w%[6?z~~^ܿ|9}h>N&EYX᭩-5 ;}4jr~wUNPq}}]}?u5kI8;o+ۗ~7z]k{;wZ^X־loe։$u'E{HǞq}"w'np2RֿO'^Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2011-12-02T10:29:03+08:00 2011-12-02T10:29:03+08:00 2011-12-02T10:29:03+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:56f21e22-1c8d-11e1-ae7e-db667b27342f image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~W/_?:co d7_7;?λg_(߿'֮|Me'•?Ͻ?u elQ0>.G jG.Aygm[:P>0~-@0m}y{?u>_\?|sooCuZ?[ν¯POooCuZ7?λggQɷ߿'֮|MeO[i?nW^\.@go_|*{ ux`|\Ҁ}l j_?lYm[:<_ /.@u?e?un6-ѫc${$W_S}#y6f_oBh==#`<|o2<{w7vmzLn.OegZFӴ $,YU-{3r$V DuAhghyq)-ͱQCU[E xyb_/_};^ܛno/6,Ԙ}`$<& +̳U7[PWE~iZ?P4MO=v8v~Yi^V%ҵt9,!ߝ[%q}SGgzbvFO֙^W!1KREi$,3cq}yLnJ;20 K 4O|/w4m"{FR'L&(j;ű{~6u?eQy YlR=5e4IET+ufE77|ߺzhE8XaBK鬎h@~?jk 휱GW3Idzhڰq 2`@Ł33}EnĴ˫(e2 s}=4 *#kfC\,)q߃xSuް:rlxO/AiOzAUX}v־iˬ~o}M{_NN&}']-ipO -mZ)lFO}O/6mͪ pѼ<}9Epn,9ESMiy sdo-`f0ju}OCNCy7 V(GEa5UM-{; N/h&nzӋ q$S񅯦2Rʡ'{=~lY?AL5tEd5uj"i/^g]lh#:#ʰT@Cn6޽A۟sy?3s;m$u؛j6':u2SWfRTd֥sgn~~}ivs̗+D2h=@FG¢V GQ?*+7{&EĺΔԇKcXz :Ck|~8>؝)3,7v/t[۟iz;( _fMQQCBLe, Oi㞹ޤ{Ne6F(D.feFԎB9JԚt9c~Twnf9F $j2NELevA"=;!+s{pFpPpborY*$JO_7_*k[Y6Cya6vC7iFr|:z|=d$T@%is_$!@wC yTBTEBWQiۛ9M1;k2I9*@'[F/zgvc->$?CiuEGclvYrݵ ROEm 8?\N) -5[OJdi:b#;E]QnUo~|fڛ{ /N|6s}u&W5>cf2l.{)ߊ(/MK6{[ywsFu$Wb.1]8PYrߕ6gs$ ,r1 IE4ԚMzʏocn =7򷴱_=Z}Ccebv= x{eY)`OK(|{{msSq4DFu2X8j6ܗ[Imu4MtВ$mP vGRݴ+f{7vE+ܘFjDf(钥4 2 [5Nwqy`f@JM?.kHo.ExF3[ŸfNO<7q_{N+s?XvvuUowO:q6J{`oκ9}-[ ntQEAV*wC%)WIm7}Y[F8\\!1:@8S v._(%2E)Wؿ?zr|wN;c7uۃq*R#W >'`H@bdjfZ]ȯ4^$ȧTQz6ܶn-YhةAcqL4w&oz6݃7_Elڸ4ٝpԋ*A5TJQ boemn?P/%HX!`tuZF\JĐҺX:d}jo/{2ùh+hr͜M6\.C/VjQ&JI(!ru#$+&`C*=5ڵP.ps9ZK]51~*H4~I'aoo}㻲gm*.ĨppC/I)jja<"0.eiG[fF&.b@dcF+>s4䕙c2bIa@ݔ'Z58=i{[7>G4gogtݛ=WSY]݆LF2'y3OSK’!}-DžQw5@D.悺J-: M0A5*@uw)}C>w3ݿ!:?1{i#wGjwNX}ϼ{c 2[KvC;X~ɜdXLtp'Iw"ܷ}y:K)T6tHJU閕t謌x%xu{"Y0!ָU>Ɲޟ\L`w3cfhh捈92 hVHU5mWۙɷdzLX_ި}:{{pգ6f!zW ]=8f0k9SbmuAud0eW ӥZ6Xmf PO_ޏ1r\5=i^[r'||oLG~uvbz#d6ЯgxUR}EfC TUol HBJ s&[ZuaJ̔TjT}iՇ2mfZ%Npytq3?)~~~3]y}vf6cUl\F~ejI2=W}TEJxH Dl J^ 8~=5FmϪ@ۭ,j{g{w-72o|1EUlQlڙvvwA#4{imC/(XQ8'u |Qcqc?>}`;+lv..6x]>emn+huc2ϑU̔1=l䵞=VAO/4 @J+ъkZ2 4 tJ[om뿓;/MWۘ_1T[glϠ[wmMfݖH2Ե3=[$ !l; k.3:v!`B J(ShR=f@!V}Γ`Uˑo+S{u~f{w;sζ7&sph XUp~^B( HHCjD=OE m;K3W\u,xt&Q|z+'$3; G<+3q](E_b$K[\1J zRʊ%RѸ5Fj4ɯvw]Qm$paSB2+NgM5MO52QQ<m$,k]I$c[4DlBM ;[}]kv8[D?\?6e/Ͽo˟~]9{u+rߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ukui-control-center/plugins/messages-task/about/res/manufacturers/SAPPHIRE.jpg0000644000175000017500000001673514201663716026360 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !qAQ"B2#$ aS4 !1AQaq"B23$4%bDRrCTdt5UF' ?<4 Nv('_vlpG١5 >VBP{ a ^ЌPrY2{Џl-f/t5Ѐ#6$Q 1d͛6c,8O.\t9Iަ7!^TzJtbodKԙD.uGQۻҕM w+*BaU@VYve`K3[i݄o,&_l*UĄ*G|9nQI;(Z=*0,o6u2!HPh#e?cxKLK/ܱAm%xc҄ȕzK%`Z<=GˆJ?kޡRMB6 qqےb`tpZ+@Mټ@;b˻;n4%3KPa:Z@}bJuE,);v.3_`}mNJhkEǐ&y(#jr'Dɲ.KUXTބC=;-*~?J9\94{a }lt@`h G72*>TPkJG|"Fbl`6g]J2ܫЂ d@Gȱs-ACO>;?Ǧ(a$)`LE錤8l(^P8XV-י?m˦mBc'qwAF+.zMߌI s:G) n+7ksi6U͊82/92_\Y'RzB3v]P&8c.G ) ?.@_<&wRSk _%ΎEpEa( $qq(Ho6e,13$wp7dW*nB;P绰6i̢r>%,إq2x|8A;E᳿]>]/om%¨r{wG_0Ĕ4G}^Nn{&Z,Ia2>gWH-& Oi"*Teڤkȃd%O> l3{{lY9U d'"ǜP6(nq2|D u+3S۠1 Of fT,>S 橄 `D -> ^bLύdv%o4' TE 6shiv: g;!mu< arȪCCw)+u7,{[.ב'H诱V7`OdE)U |}q7)|U bj岚tTȐUw~y+s *x\@,j%rNdMsڋHI&L1㌦!h^+-RKۙ,Effzv'H]0˾l1e*d_gk=Dy|SU$YsE8TC/mUpgr{Ӗ`{MvYKrZIJeH>gʍp?lG*egJfE?CI۳(GSz^4*P!ײ;io@6 oJ K™"\$>2,`P5GXɗ{և7Y i:it 0ru!A:eڡj[ٹІ6Fb$R,=|{ZsŝD 7m,aRyL2Mi}nj1܏Ş[G8 +["i(c&Lra0GOrُ|u3mQI)najP.fa\mQԑ]{eT?ptVq+[ 6I+hk b=7>ZS~=meh ^k2[nc}6 bt3l.aTe7#"Gch#?tPH߸{/TCjQ!M+v7ED7sc2X)l)VEn$ruا!1m,_N̻&V-oSItj,'2SaLT`*s,GVU .QSS Q n;"܉ KKj|(ۚ'@܁$lj2THP)Jii+4;c.5{`k6{{® ?]#6鍞]ug'4X#VXiD(O3T&W!VoLQj;n82I$65ڮM*aOXj7aL"P,¼YCLFZ5J{"e^ES< fX̖/HAظ0l;XiKُLi&YJ ̘PeoI:mPsJڞ$.IU+S17yȇGhceZkQYھ*&IlHvw$ J^#38˶VޓS5%48;pd};jz/SݯM9Zmc}L@٣'bV9HP&jkLJ{uW"R+)n:XuM{c4UvzheA~:&6.ISڕMl]1g3j|9.JYA82308g6k%JkQ*no\ ܄ᗅD@fIS#KY-%o8܊4u+IjtfD]f#շ$H BaZr D<}p'[5FiL2.؉Fc1%YPV+]9&P}e9 `xB5RP,eO KIQbl 98s _[8Wݒu~6_XN8=8^ՐHgxLW0^n-J)ƼAPr3p\uD1x֮5G*%q pmri/T8{7s^]a/v}}CrJe5|L@$Ѽz^W{Dy#ˊYk\O#oء2mSZvgiXko5d.v bu.~fVlܘ(m3sFq.1l# oWl?Rt1]wF6d*5T#˛c=ou6F,FNX$ZK3$`eˈjKC dn:ϧe2V9XMVlJ\WBq$,svf ˞j]h#;-udZ0L15WF6Ҫ*s.1> 6Զ~H2@pݴz3<%ЧU%UUX{A۸¢tEVMDS)Plc7+mnhGXN4\(!5E:ڔӖS&c'i7_NY)%lͻ62h7lN --)~#,3iEHf޸/Q>lҼNٳd5sSY^Z?={ |-9# @TZubۮTҐOWf[8U+!$~I\pl7B۴;M)1yc54LJbdmXda%/KU$ +S@#yzl"|a xӛe5SqNFJ]4fe\II(nBrD^yn^)<-/˃z+^_&:5_ <m_'wӷO)jk~|Wyq>dB¥,["jDkVؕԊyP:x$ ψq0*eYn|48^\rql/hD3:v;%.B䙥 4C1/"R3g)JeXj7‚ա1Xr4#(!ln\@tF 4#Y ukui-control-center/plugins/messages-task/about/res/manufacturers/FIC.jpg0000644000175000017500000001114514201663716025534 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !QqAaB2XS$4"R#Dt%F7GWH  !1AQaqT"BRғ$42#3rSDdtU ?y4rkR&U&5\L_ju)G~0u#^&e0TP\]<ԣΙT7RI^T 95) cxL^\`E. 5~J`d: ɑ˯XR SK2ܘ *(.G.jQL*bEү*1#@hsnP,@ 6(i vrm0stң$ SvLQ^<bD]Gg1Ym.aJ.N.+(?'bC_h?vH~/K֙6\>(.NF^Ӵ{^-Srą0&yU+P_ n-[3'[*;lT!FY uw=`Q+h:1o%eD'$ 06[w $C.i7O5.I0fcvvOsⶖbb@B{Fڦp & RD{Ѻ2xl7.{`֝⸑rKd;D$WS$ (wFn]cvo+&efVgM󕧴k}zɫc0$`"Lܠ@GboE;6?z͵1Ʊ~J-e+7sv&`DGPm>V>h2of8Bjڻ:ioeӍ>, yHX,:oGT lWQV?z8=xߩ?&˿TbrܭI 5cf#[K/Yf7kPEk"g#"CD&0-uG[)Ig  `JZsnw[}+X[Um׺{{׿ko圻vW~ן?oG8dzdo跰w^pܤiJ%TGG3O*`5U _2fi$ SĮp س C2o\hQM`2 ﶎNTVֈ'zi*q8[_A~Y6~}^ƥS(7O<׬+rb \QiQAr0ͰnrT\Li([x8B葂CiJo%An&XC.C F6޵ۓnKmדw3t"ȶf죵liZN6rH` ;qngsSN;F1&$rfVюD̹ap[ 'w+ns61/IK6y*+s <}-vvoE 0KMn=Fjsj wV'W}+{m?SI7B^@7A|gnc1Fg[45({i-G i$ 0ZC=E Ϊ5X|(?7jrӈrC9wt> rzo0-q6%2WuHP1Ρ]CY^h0QelhZnZOsVVSr;l0 ژ[Ծ,nmFSUnR"{JÐNm1<3ÇS; 1&@p^t՜Nd_qWJ`Y6gȬemJ#/^!m޾[H@0Yfoӳ̜_$Sư} \.]p017:|Y3O6{?ꬺ/. Q #QF&+ul@|5v}?;37YzK2 F6vr U<Ibw61)ZZdU_)(@WTGc[쉃`VT5t/c)锃eR}LU2=K'/;&7L; bixژ[ KZ [8Dm;47o:N'c62Niܘmbgl@ $E)wR3:OZ@ٔɨ*O./ƛ۸.`kQ(ިwяI^Z"F#OHf6[1~[iD4KV[ AdobedF]   1 !qAQ"2B#a43C$5  !1AQaq"2B4$Rb3%&#d5EG ?&XYNLB IE FR /v? As^)GܙN\\b\QAr@uaGze'削oV,^T 01$=ؓ\A3.>^~R %V!2 (0 0-"9rŽO &X93a cxH&{&f=\H&|)9{0KCre9sQra@aqF[,ErՅ锟&)%53>]i?LxStIOsEHC6kzZD?8xzU")Q %CQiZfLu Cgzz:dKIyŴ[x—TJK!QRtb,V r Fk`G柢;uV_20J=dm|&ϚDVHѿZvW.Apꔰ퍊%BCU@('&ʎT$rAӌ^.MN Lfڅ0'<*][q0nҕػepѫޭ `nX`> ۻUfr1KaLޣ{Y%wT "@16}zWYmeL" -n&R- ExLS hetquY|"mΦiƐ: 9~WGTS/xQ{TmL^qhd/|D#,˃04ݱkVn E- u*f'7RX@! tv.e{01 Eɩe՟-d{κ:n:%|}xb׆k{LBt^"Ͳ4¿DAs-)ݑ쉻izq[V%!ц wvnJݹrmKn0cФwJCY鯻.Zj5rtZF#bPZ_+'wQ|. _7ݦ#=jq -11K^(Uy$T-yrںQo-1("@>jSmI~Z osű}7c5e[Ƭ1&Xv~njcr=7_cxڍ52Dޠ^Dw @f&6҂ce DZ2@oM"1"+nJ 0qsדe<*$ehy>$kD-RF @MO?~; hkCOLŐt{VVMiCٚMu_ݧ6;/ھONzW=wywvsMUF̷ۧ[ěnWϯ=85 [4Q S@^PJ.$14 *  -3E)qjA8}TKntvrvUѤ LI'YR{9+}h(b Kwʽvݫ{b`12+(bZ] ]S7Rں$gz5]||@ vZ|(..&'əJfSfϤ ԊڔЪ7d `."8LhƚƵs-?+MޓgrQ.VԌ.oӼ~$op/]JH[FS+UDTJu) ;ӯh3J jp]L,736<[чU?֕ϋRm\!1ͤ{[Ď. 5Q2Ǘs?H pH!=4WAkmN)ϴl~T"Uluh=T\ga'Z]ߧUDL9!VRdpbPaÃ1.w-$kV"bO`R+k[k[*'[Eײ k)VFj c(?QMG9ߑw8UE`,#g=l:WK(tC++Zܼ| T@mDmLEތA!Kr鯦R*^ސD6:Jϋ[ilTa|5]F8md  ~M!.onLQ e}hLřZ1ٛ_RFD}j|޶vam3bz6su#[L>/ܾ׋Ymz8E5`B߭=^{ i00+##Mtj;ڮhEYnjVQ=I]p/C'OCI#YJqhڤ]7̔Ɏ n`0o|N3~l]OL#~ h9Wy{6nbfV?𿰺`$۽AH!o`E띨0M(o;t(ST'bfA(|*Tȥgra4 L2ch .2I4lEyh4{+kٙuN"ǒUcK:rZYp$\j=^jYs<4`F6Y}b f osM>!\۶ UaP)pZ¡Kž"V좡U,6vt)kVX3e޳?agVD0uͼ:g\N֚[{[>3ۖ]f&곂h(QiP )UNn٦}>!mVW#.Hr{l/ Q 5o]:TTK^>}gG ©?|VrǭH=<ڤ5e/JJMx-3LuGT ЧGD{e0l'~qIݭ9IZD3,7YqNZN ] |]3@jru%9CTH}+)ӣNERBS@Ȕ B)Cf>f.ToCj]gZ+V@]F\,Z." /yj/ ,P~XA8yօs.˺;D>Vq}R2>730/1VMWe)k@.0՚&w@.ڳԼwf٥c,[W9"WuTN+,H.;g AdobedF]       !1  AQq8a2$XxJ"b#3Dd%5&7(HhBCs4fvw)9i* !1Aa Q"2qBb#5Uu6v7(3c$4T8H)EWRSstV'ghI ?|ŷw^՜.;ZrhJUKٱ*4AmѬ&8E9f!.l 4مx )cƔ+dT GzwDXƼ ,f1ʻ}N:NJVnM a3u5g!%4,10;M#o6y%G8|] _$C&14I|X>-Iﷰ`7@C$Ciz :DK~o`pGlyN})}SxwW~<D/s0r3xw;&0ΰcK<|\}>xM"αr>.{}S?b;M#_6yr (Ae>;S?/<9hAe?JM&s/<9hc >~2wq 1;A_u'Pro廣zRWg'an~=`wL\_ YTf{l2F{mMߗ\jW^{DE Y}L :#׌F;tu1iRl7N(0Zc&ўzwajW^{DE MG+̂g!s:ЛM(()ʖ*TauHiCK=> %-'xw;a5qNt;cCh%JEJ 2l^ml6 kI5љwBpJpK*eLTLgj5'&uMTTՆ22Ж3M̥)S:c;L rfi:&]+{ߘod3eO&4| ?ʼ<5/TV,1X\FXʗdCmK7zW-rmF+璭l*nk|nk?~D,TE$^r$Tu&khQ ݡn|thݛPM[izLpUҟ BYNZlX(m֏Yg*rh* Uo5}ighmۻo Օ`~y8xe< n܅HtǦPԛ9=է4Wtdҕu^4hMZ 郭<٦[3MHz '{iٟm9np~R)(SvѹPIQHfhJ;6T3Kӟ\L}]i$ܺJy'c+*[983nL~LP5<iWN)ioWNns"DRG 3f9ZY C=RFȑ=%.Njmg[FYPtDm'q_/%Lؕb]2S V-7V=͕1i՚戾rݤ;nL,B^Kei$֡*`ʹ@'@ .Ў0OVeܹ^Ia8d\]bʓUu/(Ԅ]ּy9fтWZkLmRkee1V Oh9BLḛ;.@'[9Kz[ S̿s=q{5|Uŧ9p\ ̬SUfZf8.pvUƶR9tF 5LyĒI]:Dfc&'bJҪUk_`s.vrK#0Fϙ|/ᨺLԥunoW̥f`G斠POppAoN9#Av [Nj U` Y$rHQϑO(2^#,eQfM3uGFʂ7T T(i\SI ,}ҵdZ9C +@YUڂu$+fg)>gy;O>ljn[Sj/ mTksJML锲J@$hP14ӈqf ,e|Ս8Mk2'ad%Kvbm|K^4"+nTCu/Pp^,L2@e 9@a⊩e'ժʬU-gD{r8 Sw8ukui-control-center/plugins/messages-task/about/res/manufacturers/EMPIA.jpg0000644000175000017500000004476614201663716026005 0ustar fengfengJFIFHH ExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:03:28 15:44:52]F&(.nHHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$,@@C@4'|%@uV֨;^ E`uS:ȑwԆy{_~lv-륣}y)?P<5?gG3!p'p·aˁ|<_'Ro<c տ,4?h}bW3Ձ~@iV˾WtZ[rXˈk[ ŻOe q-t?Hedd~n;[o;'OMtӽ;YSt˝վ:5yVa4R3w]AoLt걨ca7YrlA"Ǹ)O/!Ous}MLΠ>^kX7\֌ll߯Lu2[e8啴4I~Ӻ7ޡMS_[~[w4),ycqYʨO%iZW>3Vl;׼ck?;7{y4|j,1G(6e|ˣ9fgԇF-78{~#PW5qk8 +T]9~;{ְjԘuZXI~qokt]XZ2H-:8: n@ܞ[Hncņ2FxrqE2'ksN==%ޭmuB\֮׋2%ظ[5%+vV~UVV--L9Nߩ?U[[y.w[8yTKbc|B{Ӟ,Rny}绥92I4U$.N6F[^7kHݷk}ڱ'?wIn>Sp䑷j4Kco]!|U|`wWf{-c'IlKaUMծ\ӱYe6d}ġ>T*ʁ\'Ck)9#<2ӎ%@Q301rŞپWq_w}&ѭu(ƯKCkj۾r4"Yj^/QuTI%,v%T|bM!1S!ĘINk{>k?˱W-4cRb?2@ŗ9T9s O?O6< IÒ7/=WH޴K:.V*ژ<"$ P7F'2d2'âI%"Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$hPhotoshop 3.08BIM8BIM%F &Vڰw8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]asint]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLnJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$,@@C@4'|%@uV֨;^ E`uS:ȑwԆy{_~lv-륣}y)?P<5?gG3!p'p·aˁ|<_'Ro<c տ,4?h}bW3Ձ~@iV˾WtZ[rXˈk[ ŻOe q-t?Hedd~n;[o;'OMtӽ;YSt˝վ:5yVa4R3w]AoLt걨ca7YrlA"Ǹ)O/!Ous}MLΠ>^kX7\֌ll߯Lu2[e8啴4I~Ӻ7ޡMS_[~[w4),ycqYʨO%iZW>3Vl;׼ck?;7{y4|j,1G(6e|ˣ9fgԇF-78{~#PW5qk8 +T]9~;{ְjԘuZXI~qokt]XZ2H-:8: n@ܞ[Hncņ2FxrqE2'ksN==%ޭmuB\֮׋2%ظ[5%+vV~UVV--L9Nߩ?U[[y.w[8yTKbc|B{Ӟ,Rny}绥92I4U$.N6F[^7kHݷk}ڱ'?wIn>Sp䑷j4Kco]!|U|`wWf{-c'IlKaUMծ\ӱYe6d}ġ>T*ʁ\'Ck)9#<2ӎ%@Q301rŞپWq_w}&ѭu(ƯKCkj۾r4"Yj^/QuTI%,v%T|bM!1S!ĘINk{>k?˱W-4cRb?2@ŗ9T9s O?O6< IÒ7/=WH޴K:.V*ژ<"$ P7F'2d2'âI%"Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-03-28T15:44:52+08:00 2012-03-28T15:44:52+08:00 2012-03-28T15:44:52+08:00 Adobe Photoshop CS Windows uuid:d94422aa-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:d94422a9-2b73-11e1-9c1d-e060394baa3b adobe:docid:photoshop:a39dce46-78a9-11e1-b50d-bb64171ab44e image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UتVyR%v 򜺌xQ8cRݠBhn՛ eG2rٹ* ?xU( e}RW_0«^hy9^'*aGsA88w;O/+t/"yI;ڛ].ف~+:W:.j'og;v8c[O(ZyFPGL{)M^ ?@^)ty;g$Yq-Fm:.:K-̪>`6Mj@?y&COkQsM8 UTI**ODMNr<[QǕ˓y2 J}!{f% y!m޽ND3e<|f<~R|hGn{dUtei(\#HBNKQRg!91憛kywJ.,,iȕy·G9CK#f'0-~fs_at2IkCNM" @?\h<!bH-H9j: LFrdz} ͧn19Gr_J8޷b]Ū<܆5:$?'*9T_0{y lU 6Z,DiTٸ٦#Y<#ؖ$ԓVs^;3SRr?3LM\A;7Ib*ҍ0RsG0x;s"v|4ϋn@REy@O҈V-rZ%OǩކuKv5݉6?o8ͣ? ^2j3]z>1ʻc'zhgAr_N*W+(Lfa4=8~?-vC,2@ִT4lȍVVG`ބx>vvA):$L/ hX~Qg[S{|??]NgF_LA--#KEEw.f>Y:rwusc;ĄEuw:\H+4~.|{G8%p@R?%v!" ϒ|s5ցEaq\ROˇ1CǓnJVõ5[N*UP7zwS=l}♯vV7NF-^X}2)TDќ6|iOgS9by:V0:/oBdџ$d{R2ī/SHX3KZ;J?5P.pøUUwɎQ"qTʼn[4Td{ &od ?8[‘/>`*C,nD[/kv*N*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/COMEON.jpg0000644000175000017500000001735014201663716026117 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]      !1 AQqB$a"Xx2r#%789  !1AQa"qB 2$47t%uwbr#CDdU8 ?!O GzCp}se4,{8lxW뗹YQEMq1Xaϒ] }j+]Xl&%(J' Prux4;:Uyr%GlLD q?Ӿ}#Z]f[ΥPkwMjƧ՟ijj!kW" SEljQJmvܖp:׌W3S(8$Q°աm:㫶?V所'c{G[}XR$&R JP0*8\^FѦmd*"SIv]ܘfHND&IRl SӰos[-;zp:wJLq{fVon,Mӷ8<5D-b(ȸ븚 ҚƖ[]}dӹy[Ҩ8+omDyk}n{Ut`" ,"30 IٛJgOn-q'QeNj8 $A"ZI '>dę%5=³ob>W߹êQ >}\\Qc1;ggO@4NU0ä~#8`/<akKχ40tF5YmœP0G܂b3Rkp"HfTU#%MvWڑߐl+p)wÁtGm/EJYۋ]E E J9L!<^ℰpˑ% nڝ$6w$gz/ BkFr{P. c(DfR%)b]]A}-ƅlUp}saBk|6̥W`We\1CxW] 1U6ӑh*N濊4pnUTu>e-c?61xF'?w}ߎ9DGj)UʐJ4SDcq2_c{/G4O5)Kkc}#JybVj;jki{5F:QX<$! D5er3K5ؔʀL 5 @%PP/(Mgܯh r_[Hu_< R)-/6LTL.Zm[Nԫd!@'$!,gO$ٗ՘-ˠVި춛SLPLr8bbhc=Mɍ+Υ I|gT,)Y+ۧ[ONHv5:k{w[mʳ2L@`e,YR5ۻ[5T05vV$Z%AP5U.G>#bTAQzGզq..C""z`0l$d"( HVog>y!! L?FUSӃA %j@+P11 f}#(!wŨAtlKRj1)g*X;:*֥fɥ7pP1 ȘqR˷'Pt ?u-Xo:@fZ$Dφ9d' ARZ+\ZϜ2d]*QuťxtuxA4guɑh$g8-Ρ,᳧9[o R96@Tݐ 4\W]/*ﭒ/3{M5Q#X T.v~h/cn\_ȵzΖ!҄ xD@8Dc/9< na eiҠ"PHcuq +lXR< ˁ℧6sַ"ڿ_5Q<.d""qmy"D%QV/aT\lc2N#Jm)P]"QSjcψVY(#% l 6շf,%*<>}YgSq;8n[sHL2}h{щvKOc:n,~bvo ]mZ/Xw_t!$s8=7m7zC:UCLh^;Z@KZU5$ $GJ5fLݮHR#ׁɚ4N& h*45LeiGo[S@ÎY8o~2k>RYͶ O8#LAQ \Lŭ$-lR$ߌѕwĔYM5 ĢLA(+tUB4PCQN3}X򼩄>39ÿ=SNֱ+ 1=rj<Ӗ>(D *5LY(̨eRYsFxP-6jW KhG+P ũ24E{n"/Ɣ[5ce<ǧ+ܪEw\6%ypUTH3IS!XJY`\RnbZ[%|2`3|(,kS:yr2RBGUΆu2&_W D SBc,P?omw5T^(hL c5`RɏRr63}K%+ӵex%@xDD% [aP" Au]4cP~/Gw m#k^tH>K])q!&^)2'ro1#fơ&,ce5^NwgC^|cYe0j J[/QUea] fH@ݻPaH礬6OD !F\rc'z:s:^2qW r!UHpզY0,܂sva+6cR$YnJ;IdkoQHoE鋢#EOQT^'탏It( N?GSUmAn!)JSndCLs)H$IC;G%LkRmzO(pRƪ~frRSˇ `Pz5IA3Q1Լu-])[re'{L~,S ."S̘!w;=E2ɒ!SQ u  .;T5합HE:Es&.Gh9LWeaX-ܺ+U ZM+L:p'!2#3ӹnb qUL.4r}]t,g>Y?]L nBROq+4***,OegO`.9MR'j@l:)sqV$=YInȠ ?d'Z=?P:nCKV% HS_,.UHX#fLa,+JQWn@Cg̨kDeH˱PŊ{W-[XoVmTiMc .G጖Ey1fE  *!պiԆP1ؽnU J;ƵpiOR=L ,g lc*%Gl:TK~X5$T4bU"%[ڛOGl}|d6_`e5ZWֶv,{K2D{ ѫ{BWʭcw䓁-!v\<\dX ]942!l4]4􏆺ek%PēðD@:*zVۦh䠑6GMBL('^RrHYE]̇<U BTLJ=Iz#ǎYnVdY CGa#ue]vfnR]Bs@s _FYSy*1P/,7qR%+Q])wCYVM:*O2#(=-MXR.U[N94I)<1+)FxN; "C@~REXM6X*hJ<=!CU)T-9UbTI<{ 3u/Qۏh]_l53R9AfTw ɡ3ZьS. ||_'U)b|9oqv ϛPjc.TJRotʄ| h;3av ȕO4qEQ0˽1D;-7{YQQ9+G.B5MЉ2_մ7u=x>Dd!at5}Wb۱Z0۴#Kt)%SdeR %yQl6qù+6%LI 9#!"TC+?+.RKe:j.9S>(y ;}#MGؗtfQ ..Хvp<0BC!PƏeO=BnxYn=j.ɨIe,7#ᴟJx ؾeye(9,>8&-Z;'N% drH L#D1Q%|')JN3N8~P Tlˆ@5ruf\WŴO>2k~m.x[--V3Q$,Y f<&Nni~ιM]='?m2*~Xb^uA<8:.<[(V1G!<0xa<0xa9{Jp Ghpp}:^8>`Ɣeo~7A:`yixN#,1`࿇ߡ cukui-control-center/plugins/messages-task/about/res/manufacturers/RAPOO.jpg0000644000175000017500000004004114201663716026010 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2012:04:13 11:27:05]F&(.ZHHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOD/]oS:+ Xև=5Zc|>RU>K̿nY:6K5sm5V}[f]n3Y~uvC}%=4/OEo(h`͋}{f]zkks :}{U>u}kWc}_}!Y&kC:PXmMk'褚}Y%_Qݝ ykfk欻~}yղj('mUhv5[wؒ)4zmXp綧Om˶CdoDz3wzꤧO)xzVT/1^5ny {[{W5>~SכڙI eF~/?Wrt2%fa~ߠ$%.ԇIf@>Pe[oOC1^C݌g;_\gkѾ}_G1\n㫶γ0hap53]_椗s hjN_<k %K,jtzƿ›2n lN̆dR&ٰ&>ͭ y>UYAtًU[4">++/]8G,͛?:k+Yҩ)-+jێmn9ib"\)VmvXX 7ܺoKl9yni۱i{/=eK-de6:3xk750m08:-oB_j`7Yg}{Ⱦ.ot?6^O?wMߤIOTI%)$IN_}dwAݷpg6I$$I)I$JRI$Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ HPhotoshop 3.08BIM%8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIMGF] AtherosQSa]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM v]FLZJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOD/]oS:+ Xև=5Zc|>RU>K̿nY:6K5sm5V}[f]n3Y~uvC}%=4/OEo(h`͋}{f]zkks :}{U>u}kWc}_}!Y&kC:PXmMk'褚}Y%_Qݝ ykfk欻~}yղj('mUhv5[wؒ)4zmXp綧Om˶CdoDz3wzꤧO)xzVT/1^5ny {[{W5>~SכڙI eF~/?Wrt2%fa~ߠ$%.ԇIf@>Pe[oOC1^C݌g;_\gkѾ}_G1\n㫶γ0hap53]_椗s hjN_<k %K,jtzƿ›2n lN̆dR&ٰ&>ͭ y>UYAtًU[4">++/]8G,͛?:k+Yҩ)-+jێmn9ib"\)VmvXX 7ܺoKl9yni۱i{/=eK-de6:3xk750m08:-oB_j`7Yg}{Ⱦ.ot?6^O?wMߤIOTI%)$IN_}dwAݷpg6I$$I)I$JRI$Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-04-13T11:27:05+08:00 2012-04-13T11:27:05+08:00 2012-04-13T11:27:05+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:2dcf6774-8517-11e1-a998-f15f6a1faa8a image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWI#*V[*V[]*Wb_ҐAryF}!hyI8Tx퀲'屸fpZCh?[r͚Ga'mMDr9q<"s+ON}û󯐒mN_[ӥk]BBg?j9Pq ^G|LDEFo|95o6.RH3B9XikA[<TU}Y"ʡN'x-´ír.G*X#qaQ8]o7Li`f臏<*SdH0\n@8%CMYKu ] 6P+;:ʮHEj~vG['fX>KH$%YPRz ~QԿ*k VG1 ߉*b+,_z|kuq9)JY+ǖ!:Ɣ?*n~ BK5**qP=77^_G>x/慗SXKX^Ս7MO~/ޭ-Šɥ[454Fc**%?B;~O"]MUÁ(ʀ -&Wq_8w\OG}/)5y"0E/!(؂K=>l!o:%Xj`t-k\74Y#B- :C~N/#cIʽ?O/q_ύ1N*UثV&|2wh?zЯ5?`=‡b]v*UN*UثWb]v*UثWN*UثWb]v*UثWukui-control-center/plugins/messages-task/about/res/manufacturers/PHOENIX.jpg0000644000175000017500000000761514201663716026254 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 !S$DAQq3T%H a2#E&VB4d5U6"CctFGwX  !1AaQ$DTt%d5BE&4Ue6' ?cnFܡcYsŌ{ЭǵHŌ}]~Ŝa֊:lAsgES1d0]$00{8Ȫ}%~NQ+)*չsn݆ܿ%ciU?}x\a}!8=t/Vɰ6ߧl5ܽY. gnufCnKՔ-Q@6'Qe"Q6Y(mNfs}.ՄBueB$>c.X@̳۬dL6짇$ej#oQ)Re;2^npV#]1KtF;'߼Yi&qs_*H- ZA'Oi88 ezd hIcbY?ZG{exD]Rjtb*kj]`<EbM_Sb? 0^K3)DV`5Bca T9m19ތԲDKY|8]ς>穦L;"kE^A|0K]\̿<>I @/Eqž|$D>Iヂ5Ƅ 99aϟ&,]р;\wr[Hq8>ov7G(ݐ6`MM>8ſ|<^10t }k ٮ(򼍿7)aJFc)*0e%)?\Y~xp?S*=Mbl#,A쮍XoX0յń[eZ _<#LpI?W]og> gǷ~bPRbi +)W3 B" LsjڃjQ!Ȅ=ˊML:[r&ʞW-,qF{wI=fCMk *QgFi5o2άR*:SɜX8O,Ÿ;leUܪNSEU&;=1JTXPڶFx-X7sppMRm#2^w]P.].S۬Dbݪn$Գ̘ h `6WO*_;Dfӻ`J=6NB^',l)s7|ᅮ܈H=^h5D7ꤪFL+9+SyaŁK4l Uʢ:5eA7p+&+%A2=%,(]@7p`aTyFE]̼ EWҋMua 6[BnKB}hC @*Ц 1J%,&Ƈ):;hݾjI(fNa)%%b9 ''~'Am6s,P2eYO焝| 4_ wb㬟L≄3ǁɣ8N<&y2N>!֦x“GkG;IoDkRUCśdk!@**Upß@9yL9,J*?u 8L"9-jg*Cy!5Ě]Xt|L?Pp9ª VY*]|岵(|3!CΠ pPCJ鿢vZGu!Z 57gϼ҆` :|}Y.KeJizg#r ]Mc,9W@y J{륪A[=3+%]&eg>濙eC}ը=)bf/vjAMȏɑ9*YҜ S92M, ]g7!L O!0Wꫢp!5ک:np|3g :\ZyI=@âaܪL=̼ O#2@i=4FW?:d9.ǭC Oq|-u$_j9Fpynroo@ pKIuc- Z@ppeߎ r&c(Q°W**w, ɨytiu(ēRi&݋QLcnUNIaqSPG8s#XH | D'(^q5ʕ9 Pʠ8 ܂0,Թ%M38YFGr,Gǀe7]g88c4*V0k^ɶʹyo l# i_>ͱ~oUh]d}׭"84*kNRmj gvٰ8UHSZڂ\kރf!eWY6 P\6k7Y8 P[6j+tՔwUI6({;4Ez>ښJ4({4ޓvb6R_b١+a YU<@I/MKV U SWg`äa6R V1Fh=QK.tz1c O:U'@͟.bf,F+fgvOO[?ukui-control-center/plugins/messages-task/about/res/manufacturers/AOC.jpg0000644000175000017500000000756714201663716025552 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1טAQ"2IaqB#$DT%34tHYRrCSd5՗Xh!1Aaq"BQ23C ?|s&fhbM%F$Z3F$D/1.vv, ڃywYZgR!މDAX=ʌ^{܋DpN{i_'Xy?0@k:Dz76Ӏqv^W#箞Kӿ퓧KT^(Ib?:{#x;0Εm{ZB3yyG<@B %m<.M k#iaнg]HG@]7]V ejhvz3B'|KlQk͒eE*k`p*3LIi=@B,GBFD'ڴ4n}o6gP߶mn4q5ĵ)LXHV(Ԙxۅ;LJ6hI;Im4=mrk𘲓g)dD7”+D\qcWmu77HK4Il_Qwg\*`ڨ-‰MIr[[IIT(TIwj"2[3U]4*:0nkQ˺űp5{aX6s+H+tN_JJuY|Q*j0X3Gƻ4KO%ft\oh<ԗr弈ތH\ h.&_;T% tYr 42ҖiQ%Է6y? 9ld:}ͩ'V[ ɮLӿ xRQ JĪtxf?{m/xu$L8FzkX|Z%2T;DzOWT+Т{a*y {\NJOL 3c|sce4S>J8 v=.e1j{tif/Sv<=[*%#؟4YJ̇VYmOm2c3̼yzn9ϢkK*v%Z'PҞWYȜ}Μ'6y`}wq[vGCth)o8I* t>Ls@~ݷrsOreܿ٠W&z.KpEb%ѨkJ[VJ-!^7'U94VY5@o]"tձCVY#")i *II iZc8cs:ZZd[y<ѐJްMj„^hCk!tUT8B\{J9B5Ւi7g]=Ǖl-#Lٖ#E΂pO'Igiͽ tօoFMMgeu#0&1y„]ZYe8NŪI\iHI%oi";vKC\VINHXdsr2bNWgZg:cr @)7ףĸS/FY#*%'MoZj,j8ѲfKEaJ|ְa:mTWQԢ8$9xLJ8J!!θݿM/MuZL;aYٗ ʗM9m6RNVPp+4Rg2ULM c6^/Vrw` 5Ow{lj~FKv$: @ J?7rJ?7@ v?ۓwM>>gy 6N 7{6<b8~N8D|{]Ɯߧ?VaӅj;-19:trZ V@\[Sr/n@irulN͂L} Ni:D2߰@iթ;HnU:? ҝӬ, um1 |N ;D8CBwNз$ޏ@y74Co,1&ѝ 1&gr!~щwóef_;F˿`#:9 <^A=CS_ukui-control-center/plugins/messages-task/about/res/manufacturers/M-ONE.jpg0000644000175000017500000001625014201663716025750 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1 qB!AQ"2$% !1AQaq"B$24R r%#3& ?y:s% 0G1 }A:~h/P&d_?ӈ pFPClPPz?NOŶ i:rt@0:\sA:q+(x GƇ`oaA% 8PPze6e { |[`֓'D շbg=Ks*aYÄ6$yzȌqt&r(<`I#qDzplk];TOvGqYKNttER^!_9+~~-K7|S wBBV-Lh>8#&凄hDqLeV6|ɏ>`x΋RFqIBbԾۡubm 2D7/rZ☲(, t$3#D{aNtɅnC%0Gɚş{*l߮ߵnМfw"Nh{-=cΥ@篻IVl5ZsC \]gd% 'RgΑlE!Vq+l@5z98\CJIdغG1 d' ZN-ǻ9z fDHsuQJ(Laj|vy'4 MKC:CaiF%MۥŐQB|`A=NzW)za|2$6p&iAPRA NϝvNR|>fwlUI셹Q*\\3hF9X0FauE}IΧPs)JlQ]ԭʰMT.KsRHbXq2MP{6bDFul5M]4ْٽM hq8~rͭ]:9jHL>KJ-> γHcV[F!uٜI&ˑNUN*՞ue:Ha!*[8SUܿ|RJ@eoUi\I*%,P']5s3kÖHF8jL5M9#UYRXa"p26)YB%J&-FwWփuJ2IĻ$ݻ'DnuRֆ2-̳9Kg_.kFJznCnH \S\´-nk4ԺBʪYylYbݼ`dU  }mRwL19Tܒ?W)0:# 24ۻyyI͑_[q[X,)0!2A t4Ekt򊐱WeW._^xȵϕ)|@LҝY. T}Uu>T:#ČHbp> b`i x#_Ѹ.}ڙ2EAΛmX#[/,ZYJ,hJ^PǞT8g_+*#g6FN`YBs$'*q~YyzϪ,ڤ54)Zc$ntV2@b\EWcobwҭzU*mjZU$n2I{2?de򊔳`V`&YvՖNlyju؝p'Fp&&m[H)@U_LU]aX@V&xD;p_`nXO)n |A罾TcIFމq$ dV?EhD>jΌ֤Ӫ:@*K v9N&0܁Ϝ I!.3=|^ȣ /xZ[-\ѹQ _G !K5.oB65 5 d+9H&lni+?3P:MW¥q&KU(IIr{zm ))(u1932v腯kgV5oX4G]`u[{Om;6@Wx$BZ9FBISP 1.g@s~)D4Uj Vԋϕd5jd\䆄,nq٨h棞2@z$=8Dhiw-㚁QwAW}K]O+qט>ȍ$3z`՛"I@"hVi^ZYlݤEvnqU?E*{@U.:Uo * [$rI  N-X̐ݗHJ]K 靸ѭo6S .m-غTVB*),&Ո WW>m*SLD Sx+RVlAS^4 St *k_S$' - I yVXU lqs.ҷ*'TOTCd[L++ItAmR๞W99VVpTÖ3 5@.[bn/@5H2]&q&VeyURl]KNI"HKNՌU&)DVHX)t5=\X[*uJʃh ˷Tݚ9')Ls-ǯ'TL;s{c^!'NN(`ЧڎbngqJ]dNl֖FW}"qԬs6/WIA  i-5'^b.*mRww+ d>s,H;WKsIJ}38R;\hWX[s.+$ MY$f.}̶:U)N*zX\Lut#XyWtJ5lgg92)3C-Sh@<N G} Ly_Z"SR׊vC/d*d.K8'I"*!d6¥R]'bGz/u dM. BɞqI DyhsYce^ݛX[\UO﮹-%JSqT%rgmbt\IL` *gՎXqX:o4\ryLj 3tIQsد y?iv#FR=czK"؍i'LUdNSvI<3[TAlR)e\-y[mɬM^~;-J]7R-yiAEIL({w<7v׆xglbg3gpح]vd.j\ olZ$,6`VڑZ11R%*B[jP\=>*~拰ݪv3%Nʴ%0Rw&lQ8 {yXmSMd;YkmYi'e6"IEP*U6 ƹfi(s\QU="m.^lꜪyWj-M Y4x0,8hnor2<݊bkFٱ[3h18[5|[ gd+X>ui'VuZgZ"_]wKi*t4XSA9 رL i;=ၶ$J©A65]BtJϽ&ɱ=w]vr+-EnՌSLע0.W@N:_U5 )m~S*nb{ޜ3tMCe|آ{!'NN<)F" ҧZj|#Wҩl*)Oş|G)" dFq_Wmj6 },Tݵ6'DVחh ~G7JHDIM鱥Ve|յ6Ԥ5g|V$bf@"I}ۛ#Ƈbb5”lDsYY&GRbPly}˚!|p'IˍFDPLS]P޷;|&軭ct\ +p ⣜ʲ\J& ĸ cioݸABiUuVFbclȵ2sIˈlRXR7tm+gByIjy%҆Y%#Xzða:w< Q 5rUU4>aCӣ̙V<[-B%\?xr8#D߽Mq֍W:j$tAer1FxĊ{X;#y Hqisb솴9: \.9 |<N쇂 C0Az0 yG((\|Â2`NP@t2=pG }>-^kIӓ# ˉYC>x }4?{} /r8#(!tN(C(\~pPukui-control-center/plugins/messages-task/about/res/manufacturers/A-DATA.jpg0000644000175000017500000001211414201663716026017 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1 !AQq "2B3aRr#sbS$4Td%5& !1AQaq"B#$C2b3Tt ?M1ZM~L!Lm k݉5 "&~TuOVrdh;lCbdrQbaz`0-Ab9tp|QڙQi4@_SB`bMb)j>-Ȧ 0]CՅ(ܙ/ؙX^ -b`4p2=xWxu }p黔\M1}P+ݵbnͪ Y˥nE.%TLu cjv$.~ Aгa5$*VrLܹ@QA&9 șf ɨ.Q0M}=UlrML3Qe"I4(%!C1bDY1;N޷ L@d0L8wbʳI)= ē,%&. N\$,ޏ*e/"b\,Y{:f鄥HGǍUb%|#KF11vbǔ[S #isܪdFMGTI{#.WĦǶB,= K,cWth֍\|y+EyC h_(˿9R27 -|0^7&ku~ϼ:0M1qT+_xګ!fZL:T󕤺 pN$FIg}96q_S|`ZǏ>䊓-V]k-#P3ZW߼,L=OP859M"[ieH̲ uF))4M)2h%]%TirZ j'uz#2._erhZsi. 2N\~`cuf{8p t}Wk<5:Jijeۀ [AN])j>A:Ju=KN-q-6E:i6@0DjY^>klEeR3b"Ғ? m[]suyϹK|NWσY=ϧ?#>W cRuUj'I : l˸yHj6NՌl$/y@> }W&ΙKEq(lUcԉM-j svzTW/jv44}QIwpp/!JPQIx{tFOf[>yϧJtߡЂ4z(VʬfVʟ ,!8*0G2X/Ukl[V 23%6l}a0j엧܅uO3 qTAQu,$5uE94Ժ%-GFC4۲ΩG^Ksa+afž5]qB=i$5$py^p"31KِM6fk?oIw=llUyO.SJI4b"\\N;e]5"8hУJ=ZZNK5UVCHޟ)qs8k{֖4^Ϫ+3jL<"f.l|W06kw-zܵqWn_zT+Im++$3˦ɳreܽYR!CS1&k0[{`v*t(f5Q3twZ.]9wNZL э6F!f.U.'M)8~ޟ@&/rL_> [J P+65;Ry ~&4J/M}\}vw>x ꚦZz iA1aCTQmx@~@W,Rk4ηseO)1b];փ1z`Gb ƂZiQFo$GxD26`YPDzlY'eըuMˉjΟV"@WL71UFhXM$]1íKt5g5/l#5X<k9<7/h;-J1-lQ`XGsCB%4f)؇g1IA2L^e4:JDw0!vOxK}jG͔jwV;E7 /`:g.~ lկr,"iAXabbqx)qIobzIO4rj[9ndAdʢJ`L%9A iek.e7w{T/ GP$CQq=c#~O>&$$~fb`)ʮ-QRB=+yN 8h p'92bܺޱ Aii4icot@A)X*6O0}gX|Z`F.$cޘ3Z%y܋9WPdH%_2OS.M fG~m94(ˤ/*_͑l\艦LFYHhK7k#(-$#v À?ű1dv=գ!G+$㛐; Ϝ|?Iy(Ȟh iTA&9D~p~~cl_*aßս0t\=&rka chL^IE0MG݅5`# zz%Ab#^‹ lL ˠ{ŽȟwĽ7rI/*B׻kLQanE0M}=)F~w؆׼0aoF["r2'1/Mܿukui-control-center/plugins/messages-task/about/res/manufacturers/LG.jpg0000644000175000017500000004537414201663716025450 0ustar fengfengJFIFHHExifMM*bj(1r2iHHAdobe Photoshop CS Windows2011:12:02 10:19:25]F&(.HHJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOU:i8.~KLYcc2\~M\讣w?\CU]2^kmWKoW%Gڹo(|G~}ku{~ϝHg}N*RvIcc=1r+ƫ&k @y1&~*K̾ߐϬ ecC+>+zy'$'AL\>u:> @%뵣?bwEX=\l 0nygIO:cmF;k基%zJ~;gMfwͶ0sW9׬-$潟svgť}Oōj@t躗oCN< fQa'x6_WoPiYx.7eX\K^ۍ`7v /= 5 K+e$pvgԵlEXg+X3~j:fvM.~3Xcuhfo^]oΚ׈?fC αzhy8VsjkymkWU[k`0x \dHr|<>󞹾cY?ԯzGNkj~\9nLcm/k]a@}_[|?k݄5<pg;9R\ΐ]ZA@twVՌޣ^LkX{u˝{ױs؝/K𨾢kx;wJC׾;#2+$;]>pY}mx{Oq=zn#SUM[4e"xwF] Ld::Hey8FÐ^yϩ=Sϫ*1DH[i>.$ms!_'?>1~ˁ^uëzǭA)JDDRI$I$$I)Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM%8BIMHH8BIM&?8BIM x8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIM?F]g*h-7]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOU:i8.~KLYcc2\~M\讣w?\CU]2^kmWKoW%Gڹo(|G~}ku{~ϝHg}N*RvIcc=1r+ƫ&k @y1&~*K̾ߐϬ ecC+>+zy'$'AL\>u:> @%뵣?bwEX=\l 0nygIO:cmF;k基%zJ~;gMfwͶ0sW9׬-$潟svgť}Oōj@t躗oCN< fQa'x6_WoPiYx.7eX\K^ۍ`7v /= 5 K+e$pvgԵlEXg+X3~j:fvM.~3Xcuhfo^]oΚ׈?fC αzhy8VsjkymkWU[k`0x \dHr|<>󞹾cY?ԯzGNkj~\9nLcm/k]a@}_[|?k݄5<pg;9R\ΐ]ZA@twVՌޣ^LkX{u˝{ױs؝/K𨾢kx;wJC׾;#2+$;]>pY}mx{Oq=zn#SUM[4e"xwF] Ld::Hey8FÐ^yϩ=Sϫ*1DH[i>.$ms!_'?>1~ˁ^uëzǭA)JDDRI$I$$I)Tʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMhttp://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2011-12-02T10:19:25+08:00 2011-12-02T10:19:25+08:00 2011-12-02T10:19:25+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:aedbd568-1c8b-11e1-ae7e-db667b27342f image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@F]      u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺU߿5wE|y/u2c7WWmH"ࠪwo,e5BYL*+k1D4_PuH@ZubG$PQQY؛diͽhDw~Y1?ʸ)k25.UGh8q4}F:9ڛ=ג-Z-۪H& MT:k5^`<?T|T Q3Z玞0y6W&ExSLhXǚܠaɷnE.#*|9tdCPʶ펱ӯ{^׺uVRUt(**"RGRu#ІVVVVR{^뗿uve:f:M {Q*ߙJm̘KׂlC r%Oԡ&>{-e/qr+]+e*RQO`1}EzXK dE{ecpq(|C"Cܣ-Z2q>_YZK{5{mj @0-uJ$2,B# h3N}/c1j)!2HܡgdyWo;KXcx(:GYxq~2%@5n]ew ͯR6]Ёs~tTYܽ7!8U18`zb;?%\v/rI4c>ʪZVۦjۆIopʬ,񇍔_:s׷{OoܛۇIѽ5E"'J:Q鎾c]6m+kU۳ CƗ+/u{qdL Sq`޷}i{es,Ɣߛ{ߛdÎoɈj)%xhq:jXY*upsMQ%QQ4[M=EDOrdNF#@jg2:ѷXO v2!;[m*h2;';MouKF}rZx`=`tg_t[wd;%x:vɛx|dbn j\=÷ E,5PG x^"oqkZ׽Z: d_ 3m=7^&N]e!7;3lc:(C\y]j3#utsy'1]˷/R%<0z9(y*9;rU#hhTmʈ.}t!1_ǵq SblR$MuLk5Mz ?v|ZZH)i"ryiI;i^VX۟v~oǹ{lS~o]-պ{rTn:Ng(<$lf˦Jd5M"6=6KV@^=Js͋jMoZIVBl*[c{Sv_Y}-鍿״kwf{w5.KwoM*谸RJLP2,|Eu :9{{WGl̻IkoEm ĞS)EQjH'[+vOPਦ?QHE]U r+i0#61- .(f5E>=o# Ro o1x:lun= 0A6^}T=j >'x|gH W?nي]ۏ'ZrI_z=mzWw~( E'ۙ fW(,y)J$I +>®!T$=׿xuPbeDzHW/Av1*1uU)GWu3h(SGVHuXفoo_Ͽv>x}7m~_W{O__%_~O7 ZMDZ:CO7v"~&[D7W]Hs߶^rN溯VVEnjm^ڍ?+2lȼ5*ASs^{m r o\QӼtF IsFlCoYU|{CW%5vݙi)7j<Ϙ`z頎GZjhc7d%f XO<21DDp*M] :7<׺u{{^׺uߺ^׽u~{ߺ^׽u~{ߺ^׽u~ߺ^׽u~{ߺ^׽u~{ߺ^׽u~ukui-control-center/plugins/messages-task/about/res/manufacturers/MAYA.jpg0000644000175000017500000001606614201663716025671 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1A Qq$TVa24%B#d&F"356v7GW  !1AQ"2aBr3STUqR#bC$4D%5 ?\a57" ~L']Xݐ`5{"aLL?h9>Bmӧ!t0>8>wBoiˣ}!}t1CCw{*H`u{ ;g nҮt[IPy} "eΐ{zw:g}C4= ߧiWzCޓ_ggO~Ү['C ,"IR4Ws{'V?Ÿģ1SegWsm(+4D$jq̢B9[獔!<q{7crܾ=%a˪ K@l [l\eJyً hZUJYY.eiL7[ 84CUGD JB:hV,089V\e٩@elqz#Px6_>xƥiylaMXeNmM,cb_(8?A/ \8reպTz]K0dO,wmuf7%ߦxr8x/NT5} p (N'|ʣ*ש5y?@GG<|xs׉tTs4 5-r`aAN`Q,bb+hh B~4C%A4J{@B{?IBWw+i^ڍFت)9% mPFh3IgcHBDq9{{ΛR YPC,pU X;N\3*+E^L>znAÓu9|ej3OFxKȱlGIb۰' mjeUl6\uwa9@ӕ QcS w.w8a2Q5䶙~ՎⵅHp(,CtqڧSiIms 468Gc֊w.m*urĕ+Ch%Tq@Fk#49x0B$Ћ0w_\]CbcƱ!JG^ꜻ'Y]F˜[[EZMxݒMZpq[]NؕG=;K¹$g6.XaF`cnrR@#>\N1k} winC930Oڰ)BP7 ɴfWG bH  pJ6Yt&==TJr@lYC0c7DATbǜܝVו:zP!Xk_kp!\ZPG#oN|'iY8+o;H< ]/bZ2)5 ^V;ҀzrQdGli圎L0Z" hB=7yCFbCZ ehui4.s9iCakll(6ഇ[ 1/^[jtP)h $p!tL 0C)Q01AX#Wȣ: i6`Wv6K j'@ecԕ՚l\' J;%1eT˭6[QĶ,F qލJDO>q@*bRA&M8cn>0z9etΙ9~bkQ9 kaUs]dh:g*[ysb'xݾ [4sRۜ=ڼh5k4iAlHKOp' ND0C-usDmqx ̩~V5HCiijZ\քDU`S1 q&`XjNY)4UhL$T qivS1N/mر}S۔z9}0@e 3gx-_ޛ"vβ9֦u BS(Kk6dNUw"q&Y9e:me$C(-%B\ fy~i%dS\Ygp\b3~&UcҿiހD"UmUQI<9^D8ק+N5!uadp"0)x[;m:IIIYa#˸macOoC2ЙvO&L4֓PT4Tb}"xg4dEY ^}cF68'mK8]վ K/=ݵ"Pdt7umm5FJu %*O*=D*QFH$M@J)RRI$Й,G3$i=j3\gKǛoB8) d:qnM:Xi "Ԓ֢K~>P1l:ZȜiEuzm%`=1 E al J- f#J0ߴ=jە̵.qz͑xӔc!겐,b Mܡ"9XWyyxUB2ʨJ|pjC\\Y)-fQ.sIn,D0w65V0#PK$5nhVH6J9\sRԀ*-%! PTAPNiq6YED[ͩmuO[N$ʵA9:a(CnZ[VOӚT:IG4I{b1r-V:;=C[$.>Eظ5UdpUn*ބV<)KA]&ԙH(`ns8963=տS4u- η v DU=-AgbLٷ|J z¿JZUYB-\,+" 7tpm 8ʹ5Pj%GGeQ5.A2/Q!2_@!tf@J.X\fS씧E4 I#ˈaܓ 8rU!Q=.atM,q"VBVB Dm ٰ*wwʭIfW{%Mym8tT.9UlJrjGK.>1 @ ͢0}Mh!ĮyLMGrS=!-]ꂡ0sap5\T;bmֆ*^RqPUY~R%Wȵ~*9ȂMtÔq{ϲl+gTS&af4mqg$A)j F_TӶsG o$v% WMj*= <}]k3c5U9Y[8!/4p=[,0K_h7BG%60c~}s lis)M };ѴQPiYpc$ ~Oy-3{d{cj{2^mV60McK2X[LmPG9vjz̆Nnq3"ъٗ h6홷LW9g6ir[IJ*$ڲ Im kGЈ(pc<jP5O4U\ T$=S@̲i"3a miaڽA=빚J^%oms'2qLSͿrI7$s70|&^ʳg2o jpR 'nP[M5`z,&Tp$yzr;bu79NEج29Ze6dKJo&zwDȻkue)Km5W8L )YIhUQM>ޙ2/&@$=Yc9SlX9`^[ J^v?(AɁ?+;_T%SiJl<男oiMS̮*0 C-{A9exE15DADxq(3h -q #Z,Z9X;-b*mg\"dl+ƣƱց Q  AnI`p Ĭec2S736.n'd?H|m/=W{*99oˍ` @+,,ļS9\08x1M!TЙ(AB0ˇ )&%|! 6Q"'蟱ل!S!iNC;ހ=@?vV?^# [}^-R$H#TN+6t[>ϰʼqUy{*+D":d G95T$B2\UTݑCOb-dށ|o‹dށ|97){7p;|߄#4绗3<_\@&?M#SNܮKLTٱz{]k~GM}Q;rzh;`u0jR\{uO~nOMͷ::{l.DZZ~Tڧvpw5\eY4SR{'EߓEЏIڰ-g쾖GM mK잖WMsM`'كF#=4?Q쾒OM~LD?m?uU}vOKQ쾒OM 1]>O,5zI4Uw=~+]qTٽ$Su#G47MeޒGM^o“BKWU}C#E&oI#~=YDa57" ~L']Xݐ`5{"aLL?h AdobedF]   1qAQ2B !$1A!QB"aq ?ǒ˒J NA/´QDxT/AnwQeI|Ǖga-a-DK V2r7*+E=<~յp2҃K+A.;Q [Yt_0qYE~!EXKQGRՌ\ ʊOOmEew /+JK:A/BDu]yVvr߈QV@QԱc+-prS[Qz  `̢ҹ_/ujoHg:z.=OǾUS y77#çݞmw# z95H]M3SOP95`9CiNCD){@CTՏ>~b%u ¡~" pۺ.K<;o( j (X@Z9Q^b)_\a/,]+nXSp Me)3<0 9ǙcR ͫ aT;ݸx_F-~:֎w+?<xiO/.8ٔƜ' ڍ`T{~9l=N2dHE3h{>U"XǦFUEkt`+ ^ٙlr[uu(ӣ^4]:?#woG 8sYX1oͽs*־>e fK)"\ a&#(1Bz[%Of0\2q/c V D%H>6&Cdb]MGȶweȹV`3O̿S^H3cĩV[ӌ^.R%U fHfO-ڦ{q>Ǧ<ߖsOb<>&c\Q*jFTYL:gNSb1yHk0~]rH^S7F2MtyUS>F*5IUQreQrH:4W4(rčwVŬdKcrUc3q ɘV_x'}>3ȷ]8"gh~Ls)cslӓaIJh,ҏe#ۊ)ZƇ4 C 5+XJ`NQ*k+w,O !?8Ȅ-/yTV3r&f76)SB(U[S(>4m)՜`((Sl)eG($S^25(*UYh$zi?͐Ν=:Jq?N/fIrxϐYB]N\晳ƇU|uRʥӊ4,{7h5Ĵ:jZ1/#)a8b(-+`d$$XYUU qSO3i^`^EN SեDYٱfut5$9l!9^/ v4ʯg4?;)ontjJUUuIG}`8 mD R= ki2ƚR36X:)Th(ݣя ]cE[_~{j\#i7%:&K'DۢS%W+A.;Q [Yt_0qYE~!EXKQGRՌ\ ʊOOmEew /+JK:A/BDu]yVvr߈QV@QԱc+-prS[Qzi-].K(1; ұD㺎KPmEA%U\Uu,l -X`1V^ZKWq˒J NA/´QDxT/AnwQeI|Ǖga-a-DK V2r7*+E=<~յukui-control-center/plugins/messages-task/about/res/manufacturers/NOKIA.jpg0000644000175000017500000001137014201663716025774 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 q!Q2BA"$a# R%w!1AQa"Bq42R$TbrғD%5Eu&V ?M+$\ cxH&JR RA5PGH.RpI/ ɕ˯0&.(Ңrtʟ/?uLSz-&yP*HSA5RW"MGR >Au/I~ nL]y(0 )qF7$+@e(Tybбi4ʁW&B *j="M|R y}K?eCrer)EɆ)K1 4\`{)G2SޅI^T \ӫOԌbwCۈTxaΌ+n +o˪~x}Ҟw[iM[Ui#*1P8oiٮi\LA z,5M߂eNJ[=UۻܑJ<߷eBͬd]# 'FUH[a5RIn cCۭoKZO/|{Պ^{G~.LAl3YH>=bxv53~5P^[ ػ+vfuwX9J죐qZZZA~>JIjǤ+kP.Zk}<76NrS1ꨌ*H`mX_銪˕Q#EJ\M^n[m ;ƯO-r23?UL)%khxd(/{:nu,A.F$in81;K1ˤgI"@$5߀kTyCl$0$"gdUcK7$<[ׅ<^/ *~=GCp'ѝTdgL$)-kpY`cZLG[jޖ[F:IxvGp-!^E3i&.P{$U ⷻúMn&i]t͠9Tk#UI#x5mX  ɄBzJfP:̠Y'~HvZJg ;z AWoGסǻ^S-߆hvj̓s WA'GJ|ڏs+?>5iBշ 4a.%-m<:aP)54u9 +7W-Y_^n(w./9Tt%U>Y6\G?zY~ PmߛRra6KP4wWW>Z5+Oc'k/[Vp' +ߵY²uc;NN5X-wwSĽ,omV @0۟@pnYf/ EX&<+`?WW8|Vy,w;zT{̱d#UV4pǏemoȻs53d<猰쉾)'݁ENu6Mǀ)D<=Hwʚ{(i|Wf2r~Kƚa Ī%1m8KԱdivS3"Z<Īp#˒ `i$}cidJbX/p7th(Dw/JTk -0-'#dJB+!|,ȹ }r=:qJ3c&9}1Tݍ0M+c Bt)xSW3Kvkt^ ѵgqL}[H^ZOC1t&<ظp]Xyxбi4ʁZu J-W7&~irm7Xzg H S(LƜm(ļRrsͳ ƾ2I B@%<2] WN{ˁ) >>ll|RrXI![$~@+BJ̱a\ `\ԕxdvkǺ[+KWEyi+&0EMD06;D[`jӺڞ5X)qN?^ޝQeڛ5:'/KR2N$J "YسFo._yPExaOCޛ-8:dQ1gǘM@2Y;xes[FJp#Jo?7slƋ9s 5T:WSP% ,+ sm݋g{nc@`ɮYY=#'xb+ :]_PH71ZGq.$ AV[2FD,68rl1c҉+JQRB])U\(@7C~?x(d2E9(" i Nʯ(q W@>^~8бi4ʁW&B *j="M|R y}K?eCrer)EɆ)K1 4\`{)G2SޅI^T 5RMyTȤQk蠏]C(_9*+^aJ.L1H \QE;J<>^~꘦,ZM*Uɯ7kʤE e._/E}_e)GAPܙ\ Qra@RnH *(.W.QLT7ukui-control-center/plugins/messages-task/about/res/manufacturers/OMRON.jpg0000644000175000017500000000730314201663716026026 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1 q !AQ2B":$tu'w8Xx91A!BQaq"23 ?L˓?v ƴA3A3/As] /1s* 0vZ "O?6beし&~'(A3h(f=X:(gو_H=X,_9c8r0T l@`쵁1.A+E> mŤ.L NPgQztQϧ:zYt$0sp"Ϙ`؀k,c(.\;0W}<˭tB sEݮȧi 9ӳF"J^W"aN!ĴzR@1k*שªT*jo5i-(҈i%ŭ˻ҳ=qT2_v Vn=;y~mc~v߮jQ6Ֆ6&WobJNr1%Mi¦Pr:CRV!ie:MHY ZeYi~gAci@H'RfEy߿zJESp;0r[QR1cI6>h"df_+!MwJD@TRfˉ'B%*$LQhS(']Eo}}rPvkkK[f{2 uŘOE;N#v26DJe:wIm{8EJF;oU^ړ{Yp7mmMiao{7V5]<][WzwF4/˔+'wgUԗpwGvm.}]m{hj[Z)$XX5N#Tf1 ɟVud ;8ekr۞[Jq}7mq_#|hλ^M·ܪ쁮Ɯtkj_D^SFV;\!-3LߒˣK0b!,VfL>5ŋUTĆmTu mQraNVL7⯦Gi1K̝ovjepUmq[rgWnhVijUә*Ew/K~e6gJɈKVNMURF(*rP a2hMq4OZ缿ЫkTɯ@VsS+SlT:f2T)MpT::чsK$دĕ=}<[7:J VRJu R9C9G1V4yKǔE]vHK+XKnv|9+2E[\\"hW͈pNHs>k6mt{}ɴވK"iY:ܙ;sJiS>QakKDΣS_jԏfFNoMWFQnuARVMhhKǺ9l݅&´!nүKR?z6"fJi BvP0eO75U{XMAs+ToKIƐ&6czr_sӷ]I{-^[b햺۵s'ɪU:ktQ/$}FW@DC62Tm|ZLp2݀&|LǫEL{1 \çBK>g.\ -  22:x፱yceɟLcZ V b OV .}\ [;-`@eeːuf Ob1i2q˓?v ƴA3A3/As] /1s* 0vZ "O?6ukui-control-center/plugins/messages-task/about/res/manufacturers/QDI.jpg0000644000175000017500000001456614201663716025562 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    !1 AQq2$a"B#4D%R3sTdt!1AQaq$"2TB4%DdE&Rb3t5U6V ?F93qi` 1oEs+F`peb(2"\}c M=;C.bŖ݌l4P{0#bi?oٌŋjmѿ#xb(ٌV"Qфe,E;́,14zw\1b,71.i`G~߳9jrVZuR7MQT搎~rk2w}l]LDz۱`cڤ x9*ytF͞maӔZ$P\;Sl!AbKkxCDrNTRIq)3H%^W3Ha=w*pL"fO:c%ՕEO/"J3J1Q?qڧF?NVYt3~slA&x897iʹ]5מXl5S,ಸO8px`np[hE>ya2S!NW74 y|b N&RL䴳dm2T/1ÖFvUFQRg`@Bq ^Z3dJxP%AÉF C\>%Zbo-IEʞ&zmeY٬q. 5d\W,h2Jl`|?X\Z)O9cЦQ*/o-H91Xas)oMn^Q+UNYNM6L͖źes8mx"]2Mɜ>Eed|HF9)|jW≛['ʬcM_𥷽go:ekK.fɺk[vK()jw8$L?(>>1-4gy*T9}Jd2IbQޕr_dS+tTH_aT39?4g$%#4cv"i Uʜr$E;p9p (hs+H ɮtU%UouG F+߫s[ȉ u@譗|`5oEXϳ/貛v[O"T## ޝ4k5eWq/zVTѥ)*ᙃn"nI+Gdk"nF@pӂjbIMP G*n>2E"dT;@iJ_-I:`PT$1pUT cAx6Hs3>'r\˯Z?#[m`-<0n@nPw%)ugu!SA/9}W{@mc J>-x `A\oA}g3^]|QTZFU}]Tf1) g,j-.y"JU@rG+_{H R0Lb"!KQʝ@39(FJO8wQ:m# .Igixۍ&PieWMYt(Qb$#8@Tb7,~a_8%gk ( ,-8!#Io >l5Rog)g>.#/p鳨#FιO qSI'*?C% {Tw4Ym0H=t Rɧ̤8%F2bO{XI?GYRXr)LV+bؾ8#!Ȥ72(N*҅R܈m!N(Kf#HL0<]D{XrIzTɬK0,#8^9և sQ8Τ snьCSYqo j~!P=PVRSQxQgUq}y9*]C*PK%^ahf(jyoV=EOy.O4|G>3dG8+{wxvrǻvc (iIEvGy5+dpr?LOb: }fVbXqvցU4kȇ5JIqsp# 찘wKK-eBK֞8QȇhK@vdMQ?n:I,-t}s4@?F(S5KM )'BZRA(iX3U'T![CՊEY֚tIf[4kMjM9!Sf\a J̕X< *U:*PPJ RX^j GH!0߃/Jk%Q]EUzQ4D* T.2hёQV#iTB*`<pje. -?ӭÌ3 XZwUkO}qo_j-i|dw[[R9Z! m)\ pEJX؎\Y.Adș"J68hl*k;7(%đpjixBWw8׌vܞKAv#e)s~,4KSt(]I/$^j٦6ݨ{8!\Q. [H8@Nt(O2~_ s2gMPבK7(ܥ<629ftd.7 :s`ʨ}f!<^G1l,;K!)E dN Yf _&CvQI]GoPS#ȓwn6;JQ8Dպ~iKZԙxCi/L=vÄѠ+9Q ~|m+u+3"ﱝyL%y.h"A ׍iQ.1H"+xi`c(T|JU gjd\񎬪7aUDMcvW ?o'>'~sd;pmN };ݏlZz7Xo E1\Q}XX7z0exyy%&x;}sON,@`qe 7c=;ؚOc1bv7@o7c"x82oa~N`K. M>v1&1 X @n6 zw=4b7ukui-control-center/plugins/messages-task/about/res/manufacturers/ECS.jpg0000644000175000017500000001037114201663716025545 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1! QqSXAa$2B34TH"#C%RrsDt5 !1AQUaTq"B$4D2R% ?Rİ!rAt9asFu}\m7EsQ]]Uk,Ԑ,QZSLIH\OI>WVDq0<-O |D?o6FIp'4.tDcx[_2K ͅcln~e,Lr2LL`re#}YW[@E8ܱGr -bkwo&rݛLS;%;ɗ~o7#n44N[ iʤO1}V%H׍2TO7Slq8R%^tP=<ؽSlqm.{)qz.uLp68RW /)^P}>ؽSlq6{)wz@J׽3/OV/s+Lh+MJzޛ|EB.[ZcGZmjS+j p6|eiݩO[vi~1V+s+Lh;M^JzޫUD[ZcG}kS } b=KƎ3֧;N^M8zeigiݭg\K*/,p .8ZB֍CΊ.+@I6h ۅah 8jqK5R .Tn}dԨXF1&)#FfPY}3OR {P2g\K%-ø 2Y9^KWZ\ԔohNCC<+(h0c֩DAQg5H_H9}kFQ2Q`1hF*0 X53g_cXY N&ceﱬv@ q\ŝa<-h^(-Er]z~EboQFVq8W@J4Ĝl]|UmMQ[>eִec.H)]1_SuWܙdK.P 3/Sqh/~z\/X)].N.#%7*Rf:U,~j3Xd4E(Hu< ʦ*Gol\pJ@>ъ[qXWV16j)ee1h%ӅqneByul)"LeeM.nݎ2b*"efM|"=prsTs0&"YD@?IJ9k:%(I94ˆ@w=y?SC^5V1L;1I4) fUG!Bqx,fXj_/kO]u:P)0"M|hPi@B%1-(RTu^V*^Ou7܉giD>Ya4E-t8M7s5uVz?Ճf:($n Ta<_*R@ZItɢRP/L%Tj&502OBJC1q8Dt^D,؛(oֱ>SZ>c X,et򡩋H2~ђecmu(w!;$ʭwPLH۴9aT Fed'fQ$qx4W)c]^^۽rxͨn\I[q'Lf3w/P~f\ ~p'0lZsڍ\3ncN{Qp4ANA/2ӞjGBp4Qp@p 2 Ew,2nQ8r| 5Ck!.hI=g3JiX5Bk#.I]6W^>+/5`lӺ^&֎ZqecV O˼k.{ץGK-j|R6]/ޓO-w]zTtY|M1{0PΓW-7]zTWl&ՃSvwL43:M6W^+^V_Lj]euwL4/]j+J/+/5>=f =| ץGJ헔Yg0 =| ץGJ헔6r 0Юu{l*]+^P|SnioW Ar| ץOv\kۃ7k겎 Q[L9h4M06'6wJw. 0n*Gvi icݰ7?HbKVcg, Q[L9h4M06'6wJw. 0n*Gvi icݰ7?HbKukui-control-center/plugins/messages-task/about/res/manufacturers/TRANSMETA.jpg0000644000175000017500000000665414201663716026502 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]  1!qAQ"2Ba#C%!1AQaqB"2 ?ǓjGeɿƒMVʅMDz T/Aw,_8Vtr( \@Qqڱ `+~<~U/&p2A&+eB&FM{ Oe[ /{:wU (ܸ@mXʅ˰vuE??*Vj8ro~Dqb&= ]ç-=՝\ *Wn\h 6eB;"kL0E'B⅐HmVzI}kAe:V!i" pM|W|3_]d򶓇'`uiD -!dm ; uD]·&ބ2,0PLH {S%XF(nm3HF 芝{^OPj$/ r3Wצ N$q4j@K7/Ӳ!_zh@7ՠԃ @,%;đ XJy,*SK!'-Ni)1Rjp/@4fU_#t =±HGNݲ6g魻Ge֡ԞsO  =6G+:]@.XAQ.?i"7ǫb[+edy0-ssJ"K:K}~$&0~~s;R@o_+'Ec*ȫwȳn asGmM$4嫔5^Yi#!Zh |^pzoSs*S3w;8RZ($buYk+Uf"# %%ٍT[N+Jf&\`M"b!q4K0vn2;rHx妶]]s.#T8G&sc&9ecXg>d+j&\.MGQ-b馢N_!ۛ,"⸌DeD3-6""?PUV!҂6 >k2&B e𪔲I<L⸎]$/潾_ڱ9$L'1N9)J1Ip6mes󍹗\w3,R|_Onʮ˔YK[liji74h"y~`m;Ӌ\YC<`_gE%NԐypFP/,_fj-EaA@<336O146fye"X¢Fܖz<`GM=ijPgw3p$$ȼsbͶ5N(n 햘L+Y6 5>L+dF_ȇlFˎϮV$ XqB%cT HJ=zr sjIZL]36:5d 35n mT]Xs*nN: ibnN*2ڔ:oH89!6c+2L1EG$/շCR,hB>x?_j-JI7[v,s!2%I4TPꖙ^ P h!^iwphw?/}U|[#81m].MPo¶T(n=lSmKT1PDżi.^Ga!$uOisj*w)oY8.D5@e㖙A1a\s7ФOj h)ohre1bv%t{$&z1 05'_+m*ۄ(sT[Ne@[ @N z4.eV`ַ49S$e4k V9Uo=f[xΦHE'ɭn4;e;k*wTyjhu.,Mf"hk0F:8:cݳ(PD DX!:qUg{I( XF`Uq5'iHSFמ%x:k-k,/Ǐʼ{5i6し& NA7[*A76(oP:{(I~YE˿%qFƂjT.];)VWq˓'T eA7_=Yl$pq"߈QTrAc*.Wqx\^ ZMeɿƒMVʅMDz T/Aw,_8Vtr( \@Qqڱ `+~<~U/ukui-control-center/plugins/messages-task/about/res/manufacturers/AMD.jpg0000644000175000017500000000742214201663716025537 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1 Q !Aq2Ba"$C%1A!QaBq"2brD ?L9&* NhA3Yt  _Yh$pqrr( T@Qmʰ">E}SZLeɟʃLV]"&cB&} ouZ /|+\ *BUj[d 21HG񀡄J~<~j.*8rg>H (Т n.aEK !.|BJ8ScZvt-1)&uDۺ{ZLg!zuA<5D淂e`j-̚&KrRRۚmmՁFHvC2N[tx#lҽo_w?ͯe\"|0gJZ2q4iP͇'*x j5OnaQ6Yci]9>RĚI+Y JϮJA9+ʡv~ ᬁwC-Rla S`SM\\ `~ps"z_fnq+mz(vEp 8&㿋?B~6c> |efi7 MWvƶWkʢ\}tJ0Э; u*RֆqŸ=`]¼_WlU9(Z=5?A;ZLgM]0~dQVknڒ_dv}JȽ/ qB(RjV "]iۧn[p5c[lvݽ];=dUrpE TTWAN[&Jq @ [Jȹ[-:_#^&uB}FHX͕nʒ".(}$gOW`t-i#o&CmlwDI39-zw-чZpHN2U bɵz _1eO%lV_ԃ*Z 0!1jTf-zC20TT(DxPS_S=G)/T-]]M=2%ǜQ2"l |iY7%ìḿ3wI vJ 4>\[-:5y"6 %V8K[# OA`s=ە1wyd.?!1,^؟f3+0/& Gcӧӷr^=<\}i')xv`gyؐܘ%:^E"4:0?cxҿNcrMGHpwzVe{rtXd:3AncENB/5Tʒ FX%֥kU?eLecӅKv,Ӫp(T;5ݽ9]B-DD51D#n*5 S/o3!yG ԋ_'JoKHCzx ̏U|ho^8ֺym}zO.ԚpJ'd)`?x]q&όRʓGcjcNDXbìSy10{}7{ ɨJO i,:3M;Cut.G$7#̙ٚO'*1XC`ooqk8ʧ,ckƟݕG;ri4s?JSؽ-&Up2A&|+.D1QD> \÷->B.\!* 5--MǸ<("~aR3->F-&U\19υe(f? 4(gۺ|" vQe±E˟%QFB* OǏҲ1i2し&* NhA3Yt  _Yh$pqrr( T@Qmʰ">E}Sukui-control-center/plugins/messages-task/about/res/manufacturers/MAXSUN.jpg0000644000175000017500000001174514201663716026154 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]    1!A$QqB4 a"2Ddt%eFH 35E#CcTu&'w(8 !1AQaq$4TV2BD%56"tudEUF7 ?>L"-&>!91&<+LbLG @!1@ KtqB4eֈsP)!@B`NǗ؉HmɄW ZH1&#ԅĘt%:8L2D9ˏ(BB YA `ypuKl0'cD6Pc&YcJ'yU hGhꩆT5K<}1^ }ko/⍟"@vkuz ~ R;uZ[GF{ίB L>UK9!||_t!~ aPO40rk*}ڼ#FVi8U &̚H2(Hd,%Z[m"wP> G*G|*Ymls3tNwD07uZ`m[h4VӑsK V2ӥ뽶ϘB^^%r%:w1Zw?i]fmO{X`X8p4I׹xT([u_5oưTJdigOvC*v[G$3-)*Sjw-b'z2ޤ4t/QU>BpoSGl?8)M,7b.*֘pZnwXwLAi +mNOK9S%Z'ܪ`le ;ò.oz?fZrK'ݮ\`6;9T葭;Ը)+2jNiZX.=0u܋5 n9mkƥM䤨$$ yeJ{sB.fDlalZ$ 4HЪc*+ЍW)/iIkdFL+qb[S][rvոw3t6n3A+`B"C"mQ I4an l\i9Tf7˗ \PviɤIQi5G0`:9UqO֭Dpz-ep4Gί媃*vSHKM읱.I$7'Qu01' |瞈 -,Ҭ)AAH}TIGw{Z#akT#> F{'{UԄ2flV*".%1U{NV5pT nsW˚s)usB! rz pi]Bɉ&>wt#m6'r7%ˉӖ_c=ܩ {V=8Bp%RA)EN$9X 2yd9'`_DI<bb8-3[bMA|+R>(YT9GQ>{,[2g]=SxdYYW.D,J{%t X,43n4c_N]H1R{6aN-_kyi-MUʎK&&ʥ*@ۑsh"28F|lCltpa ko%NTZ5ߧC}S4+j)gWN U usHQX̝+h1 #i$Z2;֦_x\2bQ{rŞ Հe6*/Ds4^,Ёɶb;y Z_Yi+TVHM"9QyE1V32& NT)i!I%\.J8phtErFck(t?zԻ kW6t.)Rgc$Mr y_7)i'Q<ʛ5qEo;GU|Ebb4. iECՔ\l./ŷ͋MEUμPdToWeJ7tVI&@sȆd]%C ţ^_ydݩw*]64mW6pʙRʝM\4g׆qc"'Bp[ql۪fkS_Qor$l -hsSeC|#8"G/W;,fl3d! X(Kmm&RK6#i Z=PqRUe2dһ>x&F[r*D5a0C"2^kL5k˽r:,^WLҡRIM>q\ٻ E HX;ͣLjr؆?g+?,9$6Y©*#2h7x8xs[=WIͭHL+OwEg|kR"L=rc7joY^gտF͊* MgO((:4h㿸;I X}?_aN,Kv<Sk9LdI&o)`&i=ŷ/h Kpvޑjd+0xtsztKO zB r `vަ4`l=YE>>`vަ<P% zl,"DoNoSp]hGKvK._ N ӟ hD?Ւ   l7~hDtdCD| 08}ӟ K㥫%}CDxYS%5ݧ?7-{H.TB۶h(lh5[i:S: AdobedF]    1 !Aq2B Q"#a$Df 1!AQBa"qR2#s$45 ?&˓_ڃMyVEMGF&BDPQeI}"טQR@Q@iXEˠyEwZxWx2^UDQQ PQ<׌cƠ}p+c{t8\kX /RUBv6@qOs chN ROKw,SZzJa+E۫6[pQ%5A23Saݘ\403*B5|OgVjp%T:i:c30ct},Z-hDe_%q =6ԩo˦uEnErA cZHTKmj}&fTHrIT6:;˚&/ fA300H)G@5¿\gCsYzo&tT#ҧVCy/6F,Z.+rO| 1\xOMnĐ.-w,w?Jdkvne~n/\_ӷhQW]k=[vl,mtXf*\=w*VOL `XaV"A: |%:пUb}RQPo8^zc^>Qk_aU\NRDzmzWcMF͒Rw.wfc^:I)Eqq[#1@+U?Yp?׵sS'zv ۜG8OːkwӖp ash9O?adT!|#lֻͥƓn{6qz;Lˁȯ&_IM'KK'|^=<)@{Q3|ڿ4w*ۢ+nvq (ǓP*I6}o1E"b9cl;v=6I`c|7쥼eM’RYjT(UjF/?`#IwT-TKAF;Mlux@R#+ _d6mBCP]}@]ln,f,ϻX:vts^0n 늱di=Ƀ2Wn<90%! [{nOoۡ]n9VhkI(3OZe h c,s3Cu""9zʤEw5/+`s=@D)sqK<8 $dFyz-'}v7.hZ5FWm۳aQniږb yK*\IՉŦdo"gnm=Q5ZrĕV 贾$>J uM#q9+Y߰G& bMrʋDXܲ5R;>$nX%IUrt@걅iPO|Ȕ "{`(Rl6c+cݾr#3r^e%Z앍KV r9fˮTfJQJ\M2b훲mdǘ.;܀ܜu/*t=*{~]2^7zv1;=]]lSI$s-S+30o,n^Բ컳s[7D~{r]Ӷ̗ck٫!+-6̐O/1ku-xh,s}*s2h$x/zs'q:6?Qv5vmc1X^XNݿg\/]LZSn. $@n3oEjًԽ!]NJَ ߷j/>3lq/;jcTg~ʸخTbd9ޯN ]Mf+2Z=ѻ#=$>@Z*õDzezgW>Ùwu'Q?bo֓Zִ55'/ҺH2f_GӹY)TZs1Ծ?SY,:5G6goPeHүOI9O :QV2qCm8k(v2FE=NWs }-{.egV̯G:U$T波nFGÝk[K2clRgMnWw%#?1ڿenI%?B'CϿGhq[PZRBQ`nqI5㴓Z֍p:IF1RI$TI%)$IJI$STʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ Photoshop 3.08BIM8BIM%F &Vڰw8BIMHNHN8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM 8BIM@@8BIM8BIMCF]sunplus]FnullboundsObjcRct1Top longLeftlongBtomlongFRghtlong]slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongFRghtlong]urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM ]FLJFIFHH Adobe_CMAdobed            F]"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IOTl\ .cUhߋ^='%q>ikS.T[9=koǯ&3x"~fc5g{j.sco"`DۦJgvCX:sZɟчԬOgڜIA'IJIVCc9K ?GCl>~]2^7zv1;=]]lSI$s-S+30o,n^Բ컳s[7D~{r]Ӷ̗ck٫!+-6̐O/1ku-xh,s}*s2h$x/zs'q:6?Qv5vmc1X^XNݿg\/]LZSn. $@n3oEjًԽ!]NJَ ߷j/>3lq/;jcTg~ʸخTbd9ޯN ]Mf+2Z=ѻ#=$>@Z*õDzezgW>Ùwu'Q?bo֓Zִ55'/ҺH2f_GӹY)TZs1Ծ?SY,:5G6goPeHүOI9O :QV2qCm8k(v2FE=NWs }-{.egV̯G:U$T波nFGÝk[K2clRgMnWw%#?1ڿenI%?B'CϿGhq[PZRBQ`nqI5㴓Z֍p:IF1RI$TI%)$IJI$STʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$ꤗʩ$8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIM2http://ns.adobe.com/xap/1.0/ 1 93 70 1 72/1 72/1 2 2012-01-05T11:13:11+08:00 2012-01-05T11:13:11+08:00 2012-01-05T11:13:11+08:00 Adobe Photoshop CS Windows uuid:f29b9da8-2b78-11e1-9c1d-e060394baa3b adobe:docid:photoshop:f29b9da7-2b78-11e1-9c1d-e060394baa3b adobe:docid:photoshop:14e7de78-374b-11e1-96b9-84cebc0057bb image/jpeg XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed         F]   s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWN*UثWb]v*UثWN*UثWb]v*UثWιi%%wvT^*͚8CmWm7JOmPvv"8NcG6illSj^sտ uF;+L@HCGpxRN_~<_>~= FXGԢ [ Ž~ qQ2?D3kcyrP5]+V۽̏? 22+Il }L8mæy癬T(Q8;+J8?gG_E%@[g53Xм?P@䙍XX?dXlzlģwXc/Y?Iy(88$h(l2kWb]I;qV=}YFݚ"TYKs&3^RәN՚_Sz AdobedF]  1A !Qq $4Dda2BW#t%նG  1A!QqTa2B$UEbr#34D%e ?4d+RS\ xԈI )ALH (HHcRw")‚L8oT+kX5a\\CIOQrnH.!R U$4&X2 0A" !HT"] DJ0R4]boՅrq5%>@nEɹ HTЙb$5!PwxPR"L()*ÏJҹvIۺV[^-۶Cd] ՎdN9ZG'* ygwq[>l^f[ou MjvK1& cu>@/aU#ϊɘZ%76*EVv@-}Kkn 6wIX 얶@. Sf9 `L;Ʊ)owIIhT列 fλ-Բ<#|+,qx¦]Ի>ō聆&lPI(ʜ(5!*^hsѕѧ.7dyU}2OGgUp"[9GIr4L6e3\WYd@.@8ߘ(f8E@~`IB&AsկS}EmORVh݄ƛF6.BoVɓ,nI>j4^鄊Rf߱峓N &α[`\٪p6hpZtu\9 C\mMLy+f^%wGfi@%'iε83#l y;QLj+-4eRcI?u*?2t/:upvˣ|35!T:ę P hkO`_7U]:wcJ1}g]*^kԯ)[O|?~^_6y;+՗y֧ ^ʖe(*Tulh6˔e W0ŚaaCrIf W;-mɒ'HR)O7Yd6ȡ0I_xަciM-3||EDO?zC{*N%5Ѽݒ]K+.em6L[C([TǍ=w|!)5U 0 T[]ʵ2hjJ'Hn:|[.X(%SZTY=F%XPDLfe~T%:YG^|Ikd W8]SuGbRh->Wgȴj\Ӣ`jUz*p#iU0C{k피YaO1IZIݱqWDbwzpM_fG>OdJǔ0Z?BPL fƺiX&L?+xa` pvυn57U?XSk_5>q7p>VxSl]Z7}|nu{oP*ͤw_"ɿ[*ZJ1;Z 7qđhCYՇ9->Ҕ6~{V]e r-Nk% ]@n_([Z B™"9 !#3[Bf2%B?(y Y[LY4t pifѭ]F*$Laa!\$Y=`ux^e5C ck!sN mx9-2fm$Muc0`{8HZV,Fdz~&//?BYvwz: wyj]t!zw[{WdnF[¤` E Hc! ْGL6 y46j\vhz͋0J}:ԯ~)I^>'>..Քmwcx"mϘ,z[\d&G|Ǩ͢dGVV|vUڞɶ%6joKB|χ{orFVCn"üoϰtZ;,W>W]0z?}XI%˵}ЗO lYD#9?2W<Pr:J!chvl34J%2nֱi7wVj¹\U 7pܐ\CƤ@H hLH e@a@DCE\()H&raSzMi\ZŤY rjJ}T‹rAq 12 ()  I jBrE PR"UɇuM7qrkuf+ˈq)Rw .M AdobedF]      !1AQa֗q"2$4t%5uG(HXBTdeRDE&vw8x  !1AQ"2BTaqS4R%Ub3s$5#Crc ?&FBcxoDuaě̅IL8xurB;!̾;>Ct4]P0E C1K< ~ `joFwJ<3n>L=\HkvBG?Y=k.dtYut7ݡOۃM {CYS:X,i6HO$b'Y? jdy5d7ݱw _t jީdYu\mۑ7pI`{GYw:=`!#j@=v_t=k$?;#夠W@=fXu?;#˯@?'y#;$4AdtPIojz'GgڼC:H0kE 3O=b#^dPHzGp|W܏j'O~vGIGv#no.0=vПϤ.:H+0{ۇPIȐmBMa3DA4k>vwi)(*_CW3,N *bI:oȱ2.&+5;p5UBd&\TՊCqgQ%%/8HI$)N9BiYgY&`<Ӛ/Z} RR h[UQ\ uOT:뉗r\ P6llkl`~g4+?MX' .CyAȧ%l= p˪lפn҄ݧaudH/u6Eu-5SR*we+)F:hMȲ.YwL!?‘#Ճ=_;d%1\Ut1hr܅j\Jrp296P(TeY@f |]vO/U3@H gpeF\ vJ4ݴzUR=L"(Nn"|s]v+LILWrMe1p :XͻSz3;+O %`qEąuuP&^C.kr-yWM36\urZJk#9ɯK85|ze"$0 ;4h*ƲlivZ  qC?kkƽ* qOZ#f7&.r0GgoGOCw+=-]+ 2_S(HT/YUQ XÓ\eS*z%w*ؠTThNU%eE4x+Dd Ex5<3tMSt2.w:D8@B Z.h.qF ֢EQu`ٲ%i(P8Lו,Fjءz"Ȯsӄ9|YDd2R:+̎R:A&IH9's:rvpPM򙮓Lr56+6~%_#p$~ٕK g9А0@P[beYm*kv/~:I]t Ua~zte%7aY 3 K8M'JYfֺ&߲j?݉(8P45J4g;Xs|[uC\=[!*.#NZKr&5Xs ]Ncwi=5T  L" ;P׻ yɧ2*iWθ1@rXMS̨6Veg -A`=' 3KεIa??ǦKʲ 7>LJʙɷa;Or;t.ק(싋ZTE@~3kYp3?K$Ee94ydZIf5ץD^Qş%'MOs] ȝu;7`3@f "4ܰ6~(¨X-@Qty=q°H;\' }LEmHClCwSgnDjxvFVefRh rPd)gH}ީ4/O} Wo2q߇O;cUOR/(NgOQ7u~1۪8 eGx6O; 2ئv335e}-yϝGX.l WQ؃Fcl80dׯ= Ѷ-r4;ʣౘ"n\>SN)9l[w>_BW|l"N a'yoD/wc>[=UE-++Đ*U‰ʄxqіQ%e$6ƓT.}xp+s"($n-[uG|E]EWsV8N#)S<2$HE)ͦn8&ShKd.}J)#'rMH@)vc v?,tXyE1L _XE ;x&9{ ;x&9{ ;x&9{ ;x&9{ ;x&9{,Od?q8b$- }T!?ʭ2yJ@#?u~^?~9KŅ%O>۹[Ü5a8 NΐxG8m_~'EH`~?2j7j߆i&#O+dVr>G;~9zDߤ`ᧅRG9RAuvl~˧uԂѿT! =. ׬MF .mrBaS>s uioÕ B,}.#:S&~0iӧrѿTQ~γT< 9>v>TRgjm^g`=v:GZC=Bd*OmʜMMяɿ΄0$؈É7 8W4 AdobedF]   !1 AQ"Baq2$#4t8xr3sD6V'HX   !1AQaq"2r$4Bb#T%UuRD57te&Vv ?-3"YK.!Һ^T TZT6rl̼jկ.kMWK&ؽ3G6K[{CٓǏ>!1CFiZBf \vE(P!7SZr#x# $W7!anvlYc=^3SrIzKQ'?hm`( zM"Q5 Uo_j4-&<$l*Lm Ye7 tVdU!J ַkݎF 8byu]6}$(l5kOjp˜A' =22~˜l$Sht<Y+FApBف(NLn@|tPXyb{TS:NEj g5攱*x57l(wp"%P;x埽f.hu.]M_}=`H}p@jhx41dy .S1DJc R:!H3VL'>H:8ȐbWTrt4G0>|c>U=uOtw}]_k~g׎9?_(鎰D!GqW{LAՔQֵ.қoǧ5[\3:fHG{Lr.N5;<]D|rr9ObXF1a`3iƨNA;pVߊcB*nș' 휁TT&_*Bo $9i-0dCfUG7z}6 L.Y4؍-@h?Eov)DjXSK]_^5wG µ$q@d+3zuJs7ݿeJXIs;[I2KR3?og ([neX'5+/ J!:gepVnW`=ZplqL0 =elwb?,f9Z5> dDpNC1tƖ'#%G|mlYU:}j$fJ b-1_QVV#d=gzJ?ch}ԩUIE*Fc1Zb Ωh-xNA:X2uag:A" ghUqgꚾh=G^D~ވ, 9\3<>M+T{pqrX35du#Tr2两Jb(DRqB {{Q Fy C>Ѫ I{쓪sZ&v0].Þ7sA lqI٢ -VЩѓ ⳵! ׸xXyJO7N.vՒZxuK9 Nvsd㾒V2:`˜0 Jð9[&sF( 4sy)ΥS{%RFH%Vb%lo>^~^:$bXyͨd3|_O0ƕzr~'@3rm ڬWpJ:˚IP*ɋnt|9"Fp|vkJj,J[l;[mG匣J]]<|f+h0"VxZegL""2ZLZ?TW]H&JL+ 23 CJ1XRĭMP)E8Ǫo1K[d \R_wZ@uā0wbHE>rtAyA$d1ys9㩟=b't/:Kw٬zԮ&pkpl ʭ:ګWz*()XrK-g ~z֨bɘm W(r'z8nڒ3W2nʒ6"pJ7*#4;I3`j*v\ b1"d^)|ku",m6j˓IB{a7;8xiE)}g<$_S.EPSHR );l/y|2K!'˶$8[cMQsԶ:ʀJ(;[9MlICCp S3RA#p9y=yAɨY*H:f%S3ʜZ>(_+1[}b]9%2SFߏߠyDND~^Ӹ}ܬ%CW&+b,Yp &0YU@=H`N)0zƲq%ÚjT jdiE4u3c@|ΜJ}|CW98UtVjeZbk&TOiD㗚lYByqxrߦ0&VvY%dnxR zK2andZNQon5f :rԬU.j@J ۅ(q 'f1an!Ʀ-6`g(ߒBȒFЭ{r\>p+gm;DP5]`P+ Q2eW F#FY,|ȩVJZ#'DM,!:+wfO(=L'r"I)E{#CU۽?.|9ۆLG~DN R,AFy0mS2[@2`쀏V[ui>I*Wt8]VvϮڑ HBd%)=>O)GU EmRykij)-ܺrJ.0^q"*[7GWBLxXul1L9%9U]QdC<I݁l&b\?TIn|Hz_n֩4zɨ5x^\Ѽ~SSgU.}PwkWɭ,ؾ6jL$eI.o"rD}|5"p$.`=Sy(9[]ؠ݀JmٔT6yɚ7ym'0L]C31r\GD'MhI4'_wOYƚp k.Kr¼,]ݫ:X6wIR(f6TA,&o`"C4OA( @mtMvYx6+ay&}բis(e-.N P z. e)Dy=| hbԔQosH PR#B* \XChi4\w24I[@8szcGkf|+gwm>ljB,jR]+#WC~V1w ~S:+H)}˲. e<&:ˠjbv6͍,4HmN-)rQe"xG' ]`DDV%?^|CDZ &#SX AdobedF]   !1AQ$ q4a23SD%FBRTu&V'Csdt5EU6GW  !1AQaq5V"2B$4DU6 #%dtEeF ?B]݌cBv¶É7`Ml8h`vC<^8vC67aFɷp@0y8|6BCw;p~ >.t/o QA ~>t\xu..R Inx|yp\n>˅pOesYn|O.a[;U)F41>rvt%`{A Qm1f#nG&t1rv-ҧ<s&/gKtqe_DCXu+fW#N>ڜin+?k'aGop''v -YH2z">(hp]}m.4s; )cOCy .~ ڹ^:|:&2;,D"j+O(S+dAUlc L \.9#cn;9'+mA!U&S>Zm*r2S$v\G#cnl'6Б,9&q0rnP@6B_-E rxi(ǶO,ܭ '؉gI_?Ùn>MH da&}sC d~ZM܈pv2BswM[/b'p{WWtBP6̧֥pH(Js2{9N_zc>rէeꄝhkgH=[B :u-),њNtNTXi ^$|DZ~+~4_43Ν;ռ-Zۺ[51U&,PR6Q[̩]YGΥ (g hTN, K?gN.'Aꣵ\,l*RyLĥiIT*Y96ڀv)Qc7tkZm2"w NhIW+,]T5j{7q$Yos+(̀Fs&mXw9Lר[,)OeYn,2C NQ<03!tQȯ+yvڻY Rݟ eB "*ClVKu'UϪ=6ZR@$z n*W G~.їFjƯ/;*YJۥjNvpowsV})%׮NՍu[jP =EHk9.JKm4PsLweL_:837:huw/"JwV7V{˗mf޷`-Me .- |KԥbqfrHJR91I+YVXm+a~ֺ ª4J3ҫHhH ٣-fGCigC~\_Z1ͫ@-Aq*bΎeu[}JP%Y=mn~AV/AZUK:S$rN3g9mN zjtiU7M\-6`N۝McX3`C-'m.ݹW3WXȸdjЅ7AzqR%U4y\ /'?/25sN;ƙgʩe-)|X4W5YEjU{κ]˸\1q07.BS6bl?DbuwR:qĐr&Aq!+&*jG  pS ZT*o+WXM%Y R -P-5 0-\Ø MJ$8 st:pB^Y`lZ-UL6&v"RBdڮʣmM#:~x^UoSnݖ%az:$Ự*dnʫE)"b՟[/HTBT !MHX*ۜWFG O.Fyo3({1{j-{Wj&$8sN5#82?,`ۆsԔ:{I@Ȼ+I#oׂI(wtl"n-=9Nܜ@q8,` Vx_tAPHKRV1EW)Ab@Udgdp6s)\i)$D10QΣh:miDܤ(>(ׯb_‘Rnj4d,$^ o&9JX%FIQ(]Pۤ,JQP 1YC2sr""VX>PZ/&!EjmvpN$K&]+Ƣ6B^ot˳m %;ĀГz^BNNsg; U,YCtGQĎDL|lxD>wɡT ? p !yAWiBO $,WF]S2mUkW (* A*m t2m#jEX u[Ɨi۳aGhYW3JgjyRXF[m"3Ir4&MO&4j*y1!&վ o^^pD{,QH޻s7}ψF87o ψC|( ~Ig![ʷYvV@iޯn;9?] [@8/QrpP5?"n^,` =xt7KWb;7mx7 c+FjDi!₿0LG1GWN0SLlS'IrG~,l ,V5\O3D7o1!<+&;xoDUwήf?ph~GKGތތ?5}v7- ~Gߝ?f_/v|^ߚIl,qGK= z3z3/vS_;Kb">#ήzfb_/׆|^ߙKl4 vuqt'[ћщ|:㰯^:wM4Avivq4za[*~9 :Lb8h(<#,Q]љ? KOUM4A<%NľTP=WOKyq'ՉG/FdžTn"k.ӫb0?}m ~yͿm_C*~9w3^j&fuLSGA;a[aě&I0;!Ğ/;!ě} 0d Mt<>![!ĻN?ACH {7m|(ukui-control-center/plugins/messages-task/about/res/manufacturers/HOMKEY.jpg0000644000175000017500000001115714201663716026132 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1!$ AqU QB4T%a2Dt#5&6V"b3cF) !1AQaq4B$D%52&6E"Td ?R,qGOSb:rJ_ˑJb; }Z]yșrdzs(0ʘs.U8nL:.GC=iftOo/ 0a;eI51@l0Փiـ:"G7[N="RЏe%dp}V`H<lwÅ eáf 0x̴nU3l,3vla3`dbl4VF1嗦WسGfTJ' qU%|#g+s͙TW~@ʦ+)Yl.sbo+` f^ެJ2v9;ג~%8ALV`,캘̺8ՎTRˀ 笰| VKW12fy0 ȶ5 d(uc5XоbVpCh!Y`g0U|ɚek$(ɽUA*ㅇ(TC5qjְgc9t$+!|.O+юC *TDImz0BS0Yg"!sK gh€c汗ہϿKs ME}Oe JuZدCݢs6tD4IU$n}T0#!8GsvQ}-sHbN<8lYD-M}4eJ<:Gk򓲡X0PvvjL'[f-̞SeGZ jwNgPqh/[oT(R,[1:u*Zj=殲?@6ޚN+ɬ.xܝzQtc†pԬ \[ yj],˛Y;ܜ`Lo[ u}c*}& SyF^ `!tCQ=̦ZɅASJG%aFr8!.@OGO,! y9BlZ|h*ǩTM?ޅ nwCMZLK7Φ0ض*K[HLM <5gA˃AB\X=HjAp~V Y:n# F:m#Z?'T[&ʍ!(4 ASd Ä~vQAyى`%1!a',OL,iӓ:g0rTdkOܦLO2 &A(OW3\{apzkmpVLHγzIb 6l0͝JNƬ(}~_y^|$Yzm`D >,*]d;7oS[Pu=aGjN ?ӱ|ISNy0>Na+%\jeӸyhO1D, F,mx@p;MH+n{4TIZA1sr)]=gOH ߚÕu;,!`j;:i[zG-0\["aaoE9l0| C?Ǚblr^vW^-v#*Z1*l/ ƌlfK2]b7i)Ycx"yr&0idR&V.EŒrC\v|yR9Ft򝙳fDFu/W{쎤)NXokX:* )BF86%.f3x ́ʠ0AWf lC=jS` ar'+nKӔS F_ jxDYG˔,0<jK+ẍ́v_~5~oR6[l:3=E0ΏJ(!c O*Eb`(z'`NJ^<Ŝ9Fe u [ഹBEceɯ^kmZks-L!H_NVS.Q"Mapagtҕ'i'r_!u:h&;K."dcأ=&q u(Cd Ũ5ѽZ,1g<ʻ4RNQQS"ȴY azZ s`PY4 /yH f\04DZ,:oÅ9QI]67?tyw ״ݙI6'ak)2VMZ ;1`A"0frĴGq+éϯY^0LW=a!qV$MxqH14&fʃ\F//ЪCnqY쎄S0(] g!^K`'Tcl]̕30e \G}((?|GC He+20ψ_[g+>[PÍl8Hģ ^gҸ߽iwesptf+uzR5=(FGwIv`?'.}K/mnYU,# =}{v&tX@ʍkI_j#0_<9eI!yH4]{z2/q9UPHrm8,~j<竱Hu"ڎ׹0}K Ta19c݈Yf,q7k99aKʮK<Ηɐ(]tڨU֭wUU+x5|1L8q&_pʷRˬIGOSb:rJ_ˑJb; }Z]yșrdzs(0ʘs.U8nL:.GC=i AdobedF]   1AQq2!B$# 3%1A!QaBq2"#$4DRr5' ?$d\R8OtG` 9+H$tE+R 0$`g շE utIS^喒Q 'q ZA&=PrVIWa˚ WI|!%rxA$3H9n (  #ڒӿ4-$9`rOH =Lz H,×4$tCJ0HfsVQ+AG%O&i{ZIFr*d*+zukרZThRZSS(C~)Q`wT=h>lL9D4Wt#ս YAEt)*Yu0- 0Ե n6@BiX/z=p;Crҳ;4.X 9I#\4W."V'ˢ37W;95mzii5r|Qm0E.i߭(4jqX yiTRƫ^Bsm՚h459q]V>nשtm}C@olߗ4_0orrxA$3H9n ( n ?z'qkԸOOۉ?n5Yv'dmǖ^'r[4vWqwet=k|XO+Bh(4=ᦝR4[ޠr(֞4R_t].e߫ HEpPYUVQ; a݄K6U2 mm>ZZrR] Wvܖ[41ø4FvpMڀXѨb4ƌ \\h*8-2̹e=og,\G pd‡*\ ,3dު)mhiه+;DK;&j3WO5wqT\øon­ƳdlSopX;ix+<Wo7;65a[bGv @MRZ5FxsՖ Bg7qA^ն5"k[pǼm?QE3axv"{n۳OY\kkŸ_ ܞGy;[lS'{EwKPb RZ9%ƅ#UuN~N͍/X+0r3ŊkʬN>㦤iworKO0ll ׫仆ۄ)85?Wo/3~ho7Ӭ[ %<;bFv,f布ƹslu5NG=Nq.vCEh/'>Qp|U=nM|8j1^]J9sA*I/7D8$Y#i5m %AdA{RTwfeg,I@)BA'#VIT|")rU_0opI\F jۂ@J"r:D/rI(X\R8OtG` 9+H$tE+R 0$`g շE utIS^喒Q 'q ZA&=PrVIWa˚ WI|!%rxA$3H9n (  #ڒӿ4ukui-control-center/plugins/messages-task/about/res/manufacturers/UMC.jpg0000644000175000017500000001145114201663716025557 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1! AQq2 aB$"rSdRC%U& !1AQaq"B2$T5Rb#3Ddt%' ?LdB&~"3\L>):J9&K!29sQa`!sFE; <"}_&i(XB&~"3\L>):J9&K!29:#0a5 %S!:ri>NFH4{XMb#HX0MQ6A >H[OLÊ9CԏH6& Ldzn(<&5ixLB8 r0j3oB;?Z0u:a. tx/M8a&hL /nm6M,x^EOD9)yGTٌ4Wٍ~֫DzS%{vJ\߄V#:Yiȗ#<@e Ao+"OLxᓈCGQ҄E$g+~r깍:Lŵrw*Vj~4io1DMȷܖZUֈB,aIv-,<\՛7lRc5%_~bzǝ /UMBKiQJ3'fB}ͽ0jI}ǽemXuwUn5cp=K,G4Y}X݀)eU)nT_ƫF,-.P@d# yvzT6FUh?('֐:~ *J%ߟU>**N#w~i|NĠ _ >%a)>xo%v7-z鲎R0.R-+&k eS($,|uu?הݹS'FD#k\rwe4T4cH#cp՞|њT݇(뀢KQWHUĞQ0jx2"&cL3mKӄ0vY/͜B/]ɂٜ!e߆<0!ʬioBuԆlƟ>Mq-0_+C-EyA,N93H^{Ixԥf{8+ۮz35Tk>wr$?[PҪv3jv 'xBPvVnA 2t39v5ynMŢۣ&j4 ;9uƭӧ(_PSYPT32%F vۜ. +4W5%4>lt+U[QvNڃwt#dtuuAbTbȸpH#ٛJ+/Pp'{;: zXn7䏝zbcXyܬ:D*d aoEri*~YrM@o}`3/UۍvEsaZۛi˘_Vt:Y2sF̂|CU6= HcC "jΦժ\tI(,N ?00HX}KKC58 Y;%֝7/r50 %+J6?5/{v-\ Nt(P910a>]nV"ݭ*ҰED&af/aasǀStrړ2L Nn<2WV} W9GͷY}ފo l}㺓n]oYFZ]Wv{{d~G^R_M. :=RdR 81L՛N e:Re݌ЅgaÏoc=>\\;MywwU/ZP 4-ࡁymD,ْ[ &t# {v‹Vf1G0 xhRԺg,9}D}b\4_֢~%-Q^PvLҜX;@ 0*`cso&YR[_ld.p`,XY7uF# = ^c2=R =$tTPpպΘTH?넵tb77QzrIo R.aOXq+X7?I)Hmaq8zrrIҍBzNwcɕ%]ҐHᇳԅ6{1|V5t=YS4XQ5 rw/2\A*| `FT:ҺCh-xkqzkit`0 ƀn3ǪEҲY<'U`m>936ԭξ/tW-OkN#-9`wZ63:'dRڿ HQ9hė:"M$1+kB21L:nFL3_?k-51ҵQ)-V;8 Yio+6q9VŌ>䬎~q oΟ`(N`ki$=WNFo|7_k(fTv0+E6D[{O+j][)vg\ΰU4% P .|^t9wVJt AdobedF]      1!AQaqB "2R3C$45EU6V#Sdt%u8x !1AQaqѡ"2BR$4r#t5&sTE6 ?y8b+~9`z'`t ǻxw{aK̈́rX`FPCX`0:˔00 @`G 01: 98s8aM<0N# w a _/`u(`8aBA<<akf6U^rSV2c9Jc0PK d~A~>`cYFI# FȲyjTD'pI^BH)Rc8)3 DG 8C({k1Ɖ zUWLT)M< 0ꕨ ҡLNXj VL48]=?]6s>"}a KD*RJPveKpf0iS1WƒV\* :d+%: P`, ǯ1/e>(?=VXU_7qߗɴxwѽܧ| oc۩p$VjJ`*+|a)TXS+v3PvzDs_Qyx`##ZR)Jtp7-e?T^U $}>iF&\7Et<4d4veB--=Yǡ1C^i"چlnm-X;2jvb(qZ%ir2ŧ8oJՌ)?,)*B;DA k٨T10EIhXymU[D1;IJыaQ(oCٔ*x^brҬ8U2O^[AL mvnZX1٘#la7.LU\|Rp['9*[-'vɄcQonK{q1P j2o=Mfőt Fۙ&>WEJw)RLF2T۪vXm4{J4_f ۝m&|gYrXl@Hi<2^49F1)M}!:0@F ;p}ClH#/JOYQ`b{fxaumݩw\PbkVLjJסB`?(DKqwj;#YYRq]49I\)):g jzMYΥ:49)ȮC XEc6uEgp֛6c 5V>|"⚗ڷDz^]ekuxtB '=5|+%Uh |DgNT]GA1>zG4J#Y۴g~':Mb[yX4Ժ'jksc eJkCZ1geA_(qǧ/=ioQuFYn{-gZozǯ#߸{|P;đ,@.SG.`Ö^0<*u&\ `5:QZ15OX<{岍% pyV!*{d%eR1pb6aڅiP|ͻdW /zW-F.RuvN%7:H4p_JU,%`r!'-"4"fi7s|s+W_4k/ʑˮ}:ؾD~#o,sw,^_&.Z _ii{HS e eu' hp.=2^q̡Yez=A*@ٚ`vao.t&Q理Bj_A$V ZgEn̕kdq|*=H$(-Z zqFu:ZgH qS\\o?C@i@^۪li&Eݖ“w~ Sʕy,1]+ooGS+yRbU̕RE}p nVTo+O\qS(N=mcTbxe%f\Mqju=ДgTf&T`-m"K[Яeu ޖ9?fl2r,)s1Ay;Hݥw"1q}9'H7BFi)@1.-Jk-ϹsrjDF,3dwB:>,VQ%6B@bS'oVڛ  *m)7X؝$kjLe1wWw8LY,79 @ȼbŋʭGӋj?.5aq}ŏ>]hMΫv..e2[o&U҂e.;y(y `vV- A A#Qn-ϰ!4>zRġWZ{w'$X_zy[߇/ʫb7eiJ#%V J u SEֽ^F\ISq䀌Ft}=o2ٳd?t{z[<~bHϒUt TuDz@sc@D2 qvMrvǴArΝ۸|Aى-1cS1: +{iK$R)lGI,}vH}n˔9;1S(^UJ Ӄ̫PχTp8;yA>^ءZc?hяRODC!ptLV2 r`gtWh+ ӣrW&5LNTԭu%ՠ cJ A(d 8=p$q %FLt:F*lw YBرuէF1Q+eዥYF0yx~e_yS-ؾXROp1*{Lg{=VUv U Zsr&j¦Ā"N " r|jK伝fiQAp% [in5-Βfm&eQTu(ԕQ.7Tgo^L@moYqˆr;~^HR1L(z<崋էsJ+gNZupH8&u#Pz:*R\*U Lr{Kq*aԘSYS2rSOֳPGhL![ymqc)iueK\QZbSP04K1ὗ"utͻųwS| f帎Z+/ dV"BhB:ښh*UUj%S?ԜaMP/g{6dV;4n͸jn"WzK1: 98s8aM<0N# w a _/`u(`8aBA AdobedF]    !1 QAq"2Ba#3$brs4D !1AQa"q2BR#b3c$D%rC4 ?<970A7a+&vAGf.<ִJy~M]ntkTC0l \F["s(3, \o6buK8^DKzZٵ7U("D/BQFS)!@SJ q5@#Lzf)DIP1@i9WfGTA9Vo=&@jJ'ڽ>;).4&.8B-=34@(WI]ޮ0w%JeD466K UB}mfkS [7!% uuҖԧ{Aփ!yUȬ1- 3g)s"?ìVutH$s7|vrU,\)Umk{zc1M!Ug\xc|t<y)'mXA־sy\@P)^f/c+ÌX#nuz)}ƶqՕA /cFYL@7:` a0噱^,ut_o[YaMd9!䶞كPkݸ?ɹKWCGlPr3ru7rL+eQ V]xԸ3avcqxq(zkfT*7A{{hz=a\t4Z<#0!:Mnmk? >L gK\Z;"JUV"W( *ύ% jMRG^ClY9ȬšA*<l*X)iPN)#J۫kI0LZ9>W1-I_:̚o p{?3mRO8*Aj21.8<Ppݍ&9w=Xagb|-^Vv3Mm%ȝ9{@WA[ ;+MO?MLE`V.#>2ǟpo¯KjΟA_Th"ݍ<^$.5ʒ `D$9U]J;2r1qg7_8?#ia0"TjFNB <Tؽ@u֖ÝSHC&Zz*aV i +ʅȍ]]Y%iz)YO@؀4D=!ᲣP4,Fj3Kbw]B/U7Qx_29Ms_=DQf RR@|Qͽ"+&#_I &c*c!hCYZsdc5v tN& W)tB@&Fd25C([9\c1].ʨ3Upb2 ͘YZbbiR`(#eKx}L#%ވ0kjqAjZ=bP,zLvwa2eU XMVYԂó]h?־]>=n 8f/%`nry~T?~$25Εl RNo pyt2ZpJ QP/8=l*UU]PZvM|$Zkv%yYƒDn>F2gR+Bjو糸OǭOمns`إ^i`DBIٶ6)#'46疕:qRO8sbUaNRtđ6EⒺQ\ʈҋČ\$8S1}Tߍr\Ijuk >~[[|'^@S$]GβSoGzYE!\/%~STҀb]-~4X8v)g|drp8K&IOGSMENغ7N_=0,8sL`N1T!2mHcm^H9jnܾ:}n&6CX]#.f|MWѯQ-לe.eV: 'TV\^"èc2CtBLw^`)Њ8ո^asF駋O}`*H#.؟9Tb^iWRS5?::ޛP(-fk^#4m:1D v5C ,"12ûg^jѼ} SX_=GEG UlT.+Cn4gV.W =Z\|(g <܇(#9yaіliIE%Nl1ϡ6^SWEZ M2)<ġz$˻zbPKߕZW5 =L.hamb2Èџ@p<RtoPsVqwU=n.LܲSi[mܒOߓ BˆF n&]- FyO}7@f5Op%lϵ1չhg-iL {Sȵ iv/^EӋSgE.B.1ԖDn%9L=Md0|%* P!3e(frId٪X`L;M@taRp"ֈcRdC@3P0ÖUz'#zNUsMj`9aX%$IXq"QsPGHU#R,VDV"įC84ޤ:Іˠ+妳P!E!N}>+E6֞c_\r7LpzyB)pVɜy=ZU;nrɨVLNc}KK|q\jƩW*5&c$uU z_.#-7"9v~Izb.BE'S$L1\ eLDʌyLbοrb%k HW0Zt;o(grܑ̳'6k){3ڂ\Yk]Vz٘/ k݌,ro` 6u%VMIVlv~C7=x\_YM|w_sc{ww7Vc+S&[sUng(ߣozVϾ |;;_sˇ-XwwossiT2/Yl˳}8{nމɤ&C&9w=Xbb|-^ukui-control-center/plugins/messages-task/about/res/manufacturers/ENNYAH.jpg0000644000175000017500000001100314201663716026106 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!qAQ2B a#"Rr3s$1!AQaq"BR2$DdS4T% ?Ǔj-qW&!Lf JIn=Թ"M=R zzJ9$I˿PL3H \ѦIE˰w|S*}=~3Mرi6ʁW&!Lf JIn=Թ"M=R zzJ9$I˿PL3H \ѦIE˰w|S*}=~3Mرi6ʁW&!Lf JIn=Թ"M=R zzJ9$I˿PL3W U]QI!2JubOnŁ3( 6mDtF9~l5šFf}-CZ "O޼drG^8p7-;uޝ0#zet ∆ku&Z[DcQ1GrF|ܮmKKQMP *>վss!3[9 VPshGi7&-.%_o6+rA梂1agÂ;roFZu*10.n?$޷E?nִ:\*~ -.TaFT;W8K,*}gK~9v_)(isX:Z#ui5: e/%_{C_0c5k|^'c:>ާ„ジ6[HG9U1nvR'SiNQ=Mix~?xx\cJ:*dhPY>Md}F]/ŒF nT&wJSaANfKzPצ0<}(j;mQAHa >奜|?Gŏ1MC?&:-W?< hx)@5^\UӺu\#I9+r 7ղ~ߞR[='& #cF(4Fz FFV~|+kET bvJz}T%ÄVlz*kyؼBfY?FLzA}̝k V\$L/,w6}%n73-W+:L1Nixd28O\[i&ScxKa27F{ x¨zt[mJ7k}BU( Q;w7t}p}*1.Fq>Uꊬ[ kWCҥm{Y3#7/䤑d>*Љ[^9H KklDUoP\r&tP#m7.,pK psY?WOrc11ͮDaTzּ7*g2\׵>v?G`~ 5WbŤگ*k <@y Sqb%P*Ux4MӞ0^LMnnӇ=޼ξNyk{b30.h;LsZ#EaQ5&@D.WRX 7 AJwo<!l3Qpee|0qqG"Z;^ܭ;Y- |?!>ִvI Fbl. ELi]ѯE2D:^07M$D|KVa#rO U= }/:-|a{{&C\ia&NYY-LkSE3.s $:v;mq(`gq4J6V=륾qU' c̮@PD"!XgH̆`>'!1J5.UMF$9ퟠƣAH5F' pOXJ2q [0,?mntGMvEU:cs{˄}#Agavũ& 0z{GE09cX󋑞2Z57)t#.=]R]}QzV+._g^ߠPNcĞ+&v'-LA*$Y`HMnEc5sUVKx{vk c ⍮hۛSENLj'Yzmz*kuرi6ʁW&!Lf JIn=Թ"M=R zzJ9$I˿PL3H \ѦIE˰w|S*}=~3Mرi6ʁW&!Lf JIn=Թ"M=R zzJ9$I˿PL3H \ѦIE˰w|S*}=~3Mرi6ʁW&!Lf JIn=Թ"M=R zzJ9$I˿PL3H \ѦIE˰w|S*}=~3Mؿukui-control-center/plugins/messages-task/about/res/manufacturers/SYMBOL.jpg0000644000175000017500000001100314201663716026131 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]     1 !AQq"2B #$4D3cdt%5֗ 1!AQaBqDE$t%u"2b45 ?>\Ff/ 7LQ57&/V};RS3OvHBjoN&mG`R:"~^߆lQmkrQE1F"ri7foOpjJw&iA\CR^ MmjGZOz-mnX =&(߳DNM1FܚbZIS^IN Jy9JB$?yT4JPdIC'ʺү+dan` xLQaz 6( %͗)Fқq]LrWƎ&)D囵8 &՘r`6ЀL~8H D͗0c&A'؏i)KRD:'-}<)+Yz܈*kT Ïws>;[3ЫGrȹ1[5.Y+2XKCEIK,ye~E =)ClQJ!1Ci7Vv~Mk+ &UG d%ƦαqYm[ .x|th"%غo4vQ)lWTmfdT ]m6QlO5N` 3=E1Jb@OV䃗 Z7 d^mӂb\a:+T? })1i&PvM$Qp 8 WWt@ XB-hx2ԳIwKhB{|#qAKUxEl[E&-DÔ ~fiG `m~Z#6C&+~JH&]V|?EVDh&PTk$[Ѵ9l KJצXQL7?jQiM1]Iƾ>ִII!-ztȌcy)(=iw<0*t@R 7E4}oWJQ G9)z:Js7?%_թq:5tqWrr.cv|O㲊qKc2_0)7/΂7EIU| 6o?5ʆ65yH4HfD$"trlCHdotpse R*j@C: :~oԎsg┿Ү,ǩ ӧ [9#|fׄ GP\&(LllGDE9^@kT:ks|TjDA~tgⴿ'Ί.)aS}w9%a*@"M_X*TѮWӾ^_.${Za1F6ZQϕ tIP[J<XkI22%eP]N;XW3ȵ\Bh_?XJ'JNJ9YaMqSVߺJʵRVY4FN\ȬLl(S1.eQ\gZ"KzA)5<7 p e;׳tu~ԚM}<3&'wSC>+g*>ud,1\侩ᮭ띱j_8T7QK՜T6zEznթI&e TQWn 3@ÇTxpizχ1 7tNq͕p6>H4ˎ.Qe4R/i>6 "u *R&{j s804ŧ!Vx jSO +Mc%vXcW*&rRڏw"7"@[s[/QR 5v'֛Zzv.XLл; RtҜHeJBVzd$眆U]Vj_N<#;ŭX0q0 gXæVK:s^m 8y^[@&FDj}R|m;T5L2_̬M] gֽN suIiVRӣUKy -T"""}!--}4BfY\6gtl<ȈI C›r1$t` @;Y'U9(tLJ ٘w M*W $rӡCוXt[Q{ATcsHr4E2>t]g4ZtOR"VBRKXYشUkѝL3Ytw:"ùxe%'IRVsNIx!+@k8j ܵ,LGa`m5EmGPUhɦ(}LQI>bѩ)ܙoArzw Hrz`57 #Ӱ{ݩj?/oE(`(oj ~94Sri7i'LSyz5%;4 h.TNT/Lr`6Ѐzv`{#R'hVѶ,AT^o٢'&qjnM1F^$)w/Frfʑߴ5!ʅޜ.LNvuD ؿukui-control-center/plugins/messages-task/about/res/manufacturers/UBUNTUKYLIN.jpg0000644000175000017500000007071214201663716026771 0ustar fengfengdExifMM*bj(1r2i ' 'Adobe Photoshop CC (Macintosh)2014:11:13 20:09:42jj"*(2*HH Adobe_CMAdobed            jj"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?#sݣ1>.?jûe8a,ÿ̇;Xtklъzx r+J<1u-ѕ[??ɻ-QSRL!F )|["۶D,lҊGyy@Y)b5lq]L #˄8IggK׷%QQ~8|8Oڡƹ2hq12f.9!/)QnYnYNMl,Ҋ<ơ"& (xt\b< p{K&ʼܳJ+c"a6e5^^8a!DYblH^ƌYYPޅEϤk4үregGiS7=ԩf~c<3O׫ddOF×#˘,X`?R=[seB?z}rxqkY0e'Ⱥr93K[s0_['6#*~\Q懳$N(ʍqpW~)&Ox.ğ fdWd:AХ[obvoiN\3W)}χ6NP90y<'O#b?7NqgU}_3W]m?o{g+Xg'u* < 8A\ga-c/K)$RP_k+ntjJoQ0 .C2d(rgw9xF|a)×N$qѫ]tkM2|ܶ'NfC]sKLT#Z1ǟ)ɏj|IX92 {R[cZ4:vΓ ={?ZXu12|6||ѹU8Fr`KoC'zeprQ(T~oZ- OD%ZxhqN)P&4<< YybNX??Ǝ\Oja}p;WL;vܸFZ[7/޵:ju,~[Gܞ[u,]"di ű$9#<DN9dB\-5#C GP8? '1Ǒ^R@?[Rޛ>3˟.f122U<8I-nԃ.g6",~ݏ$Ƈː.sHp彏J̓GRytynsQxhz{<5}zfC_=WzzVnA¶;H2GmgX_n$SPΑ}%eWsC]tq6^Y}L[;K6YQ|Qǯ-ӏ+XYg{+{faInhs$q23sH|Gj7ÎŹ>_y1 Ik|yiHKc;){P 4~e$lthFx0\eω r?~Q'YpU]ugˉi~n;mˠܼA?ӿr dK'qVzc2@<ϖ$.2#!26IħRN(Ҍn%VGkUG8 ~'~ |/ Lia?~k_·w ֒ƎDTW3),ɦs1YwCL(mnB2!mB'QR~\0NwbGx> ${x i+VRU|OD޻\^X j|c{߹<n/{m-p\Qc؏զwIܿ_d5w?T]?M&$˝mIv)SLYDW5'\G.w%LY'4ZoΏkj_3gP 9T\8sͯI.ԿKg_?xEW ŲGOTLqZW/^CvJgXPhotoshop 3.08BIM%8BIM: printOutputPstSboolInteenumInteImg printSixteenBitbool printerNameTEXTprintProofSetupObjch!h7n proofSetupBltnenum builtinProof proofCMYK8BIM;-printOutputOptionsCptnboolClbrboolRgsMboolCrnCboolCntCboolLblsboolNgtvboolEmlDboolIntrboolBckgObjcRGBCRd doub@oGrn doub@oBl doub@oBrdTUntF#RltBld UntF#RltRsltUntF#Pxl@R vectorDataboolPgPsenumPgPsPgPCLeftUntF#RltTop UntF#RltScl UntF#Prc@YcropWhenPrintingboolcropRectBottomlong cropRectLeftlong cropRectRightlong cropRectToplong8BIMHH8BIM&?8BIM 8BIM8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM08BIM-8BIM@@8BIM8BIMKjj ubuntukylinjjnullboundsObjcRct1Top longLeftlongBtomlongjRghtlongjslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongjRghtlongjurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM8BIM Fjj@* Adobe_CMAdobed            jj"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?#sݣ1>.?jûe8a,ÿ̇;Xtklъzx r+J<1u-ѕ[??ɻ-QSRL!F )|["۶D,lҊGyy@Y)b5lq]L #˄8IggK׷%QQ~8|8Oڡƹ2hq12f.9!/)QnYnYNMl,Ҋ<ơ"& (xt\b< p{K&ʼܳJ+c"a6e5^^8a!DYblH^ƌYYPޅEϤk4үregGiS7=ԩf~c<3O׫ddOF×#˘,X`?R=[seB?z}rxqkY0e'Ⱥr93K[s0_['6#*~\Q懳$N(ʍqpW~)&Ox.ğ fdWd:AХ[obvoiN\3W)}χ6NP90y<'O#b?7NqgU}_3W]m?o{g+Xg'u* < 8A\ga-c/K)$RP_k+ntjJoQ0 .C2d(rgw9xF|a)×N$qѫ]tkM2|ܶ'NfC]sKLT#Z1ǟ)ɏj|IX92 {R[cZ4:vΓ ={?ZXu12|6||ѹU8Fr`KoC'zeprQ(T~oZ- OD%ZxhqN)P&4<< YybNX??Ǝ\Oja}p;WL;vܸFZ[7/޵:ju,~[Gܞ[u,]"di ű$9#<DN9dB\-5#C GP8? '1Ǒ^R@?[Rޛ>3˟.f122U<8I-nԃ.g6",~ݏ$Ƈː.sHp彏J̓GRytynsQxhz{<5}zfC_=WzzVnA¶;H2GmgX_n$SPΑ}%eWsC]tq6^Y}L[;K6YQ|Qǯ-ӏ+XYg{+{faInhs$q23sH|Gj7ÎŹ>_y1 Ik|yiHKc;){P 4~e$lthFx0\eω r?~Q'YpU]ugˉi~n;mˠܼA?ӿr dK'qVzc2@<ϖ$.2#!26IħRN(Ҍn%VGkUG8 ~'~ |/ Lia?~k_·w ֒ƎDTW3),ɦs1YwCL(mnB2!mB'QR~\0NwbGx> ${x i+VRU|OD޻\^X j|c{߹<n/{m-p\Qc؏զwIܿ_d5w?T]?M&$˝mIv)SLYDW5'\G.w%LY'4ZoΏkj_3gP 9T\8sͯI.ԿKg_?xEW ŲGOTLqZW/^CvJg8BIM!SAdobe PhotoshopAdobe Photoshop CC8BIMhttp://ns.adobe.com/xap/1.0/ Adobed@jj     u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?n%[Kgpf$ۻu+#jƧT!h$b#>!C hO0ۑyqլm´CK)R¨ #teVbBon)7I`̅jw|}W,;g8ݥl] ժԣldhn?2~g{G,zeTD?DK~\H}гjP(ޝf F׷{7g'#9~훢HYݟtb&ӫ{v1m`h[cdv_ь~yc7g:ſcZϱO+rw/%7KſM9?S|n9]L@Ga6[*=-ɉ}=aQؿedv?k?7a|n=;˱/bn/(l$e;eoGa7?MڃnsgNv;#nK>-i_q[jNaow-?Gd|Flٺ/_pA0?;?}ɿ;!n:2)=^Fg_Yt G2Mt3UzX\~^jfa7%MTV hi.}E+7t?|+ܠy15(u8cQznwŷ+d֢ cԭcuRjjyU)dEduVR$\]\Y^BD]Oe4 }g%ͽvҠea t{|j4F-qs{wE *k{y-l[r 摏Idc,=55>#^l}㟭y}aiin-qWUz׿ABM߹k3Khsn+f(s?B-[JcHqQWU4\Hn*,n]ǀ/9_ܹ_o[lZY"5nBASRhI[;nͻ|n\v!V `QEKzM2"+sXu/Xfjonb{rf?2nqSpmlABT:D>umi{Qr僀ElWLjʭrjTg)?;"|<͵nnh6+7.yW>\ K}WM_lvkk͚{FV]CZ{*[R}>.T5#`uf4jAz%֩oL.J/XPA!tF>^r/3/+` * e?:xNb~f<[uu ODOџdKs,Nn9[!@u{'b8-څj*z'_ݫ׻),R ; 6lηFO$|é2#XIb97D VV %k W0so*o"GR]XUYXT2 du紸X!HxM`E0>?"tM5$?S75̢|xGmCwŨZIvWpc}6k @Lu]=sIy7 W;C=i76Y16y)wxA?1aѺ/9_IoSV}?O =_2Qd+Izɉ6=N\T=nI[o?C[~ܟ_RzۛӦ<ਛ!JZo"Ii)WrN .H{s={֜.\n0," *وH_ʣ̊tkyf}K]m..JcD@gws5yJn?9VGYO6>iP)\lIHa}"nCn6ջ&]4h^H-FըT){q,VuHZAt/:{m3I(Ym5B|MlO u|_ɹ?,A{$*XA"I*Qnhn `e|"D%Q], HHGG,N aoL\ϼs'n@񓬸Ҷofė?GY>mrZGm]u߽tKmVcSeB]*r &KkK{˹+HGrK;8 1<=cuխO*Gh 'fO<]_Viq0$,^/Z1K;g3߷r= 2\G,aX8+BdmJA?{忺8{~ŒE+K ; ӯH1^DXе־ca''X}.=ntܩ|qK7[=ɀXZ%1I}̭GW*ZXԗR4eG5ZoO+-VL~6 uF"3 &'e'9cuS-ոؿgӴ>̷{[߻~}ye\ۧՈ(T ꠅEY2hi4YdV?ޙsߴx\7 BA,+Iz&u'Tx&6("jܭ;5dS\ulI,Yf$I$}N@bjOKM 5#T5MX1r}&̻%{:C 1gI*",@tAn[O.m_CkM48K(,M|j$ޥy 1xSxsE1ZVr 'Г#IuľZn_t7޼V][ "p2{tDGm;.#'Yiy-I0Ĕꌖ?b=NJO_&\|b㠓!,UTRROwԮ~<6c=hnfel#Tw?LF[QZ;/'2ǖ_i,ZY3$^)uJ *6kӤAfj/GU6kWEZ(Q!e2MGQ E*()}}>{?|o6w,mͣm#༁Yziڗ9HIqW_;+r~sr^2HOlS4 PC{ -u6ܸZ^I㤊(!|Mc$xA ßq^O7ԛA$I-("~% }[}?~ڢ7H6XZ`"o:KBP9D5Ε\L++e'e$y (TtBdY#?I"pRT#D>GmۅՅ %Ѳ: hG),MJ;HOEO^h=O}>$ᶢ]؛{ci) ҽ|'+׵l;MbQuf?Rkc$Pua˺_/o(ٿx獋Ṟ?+'[z˾Բ%)_мzsS]\~}@qi]rf?1m}L-@fHR&:[V{ pI_|;kw|^{XmMG׮p&C翜Щm,UZYAk'ԨNgsbuiUcOGIGV̊UhurH9O5^lb[quyn {QrE&v <,eV /#5tZ؛pT`SI2Tk]S26 4T3FgϸޓfTwJ;5̺cg/mhtV2Y^?_R(kݺH.m-1 Q/#sFf|HTْiJSQGQQ11"y@=/7>{1M-$t=˶[u3$u*&O}s/|`d9)#`Jr⳶W`+Tx_,'LGc]yxqYH6& CwF0Rd)b W[v?fvkkiRSI;ƘP ]Ϲrg,nnoBP%=kcEUg+vGv. GμhwUUѵN_?WlhXc Y,K/,K)'qQm!/ԬAjoVUA5nɼ[r_8nW&w'QPR]+crR '[h28ە[ fJ~ J4 C%SIGML6URIlUkc#r8տ'4֑]cHTTi8V4=d{ZlVsG*4r%p#xJpN< ˩b5ӑ`6>SB7Z}<s6Mזl+R7=]cʇmmUzRE FQՌ.ۙsfasS 3kO['*u}հK|- qfv{O:}.Xi/vgX)BK\켺z %d3>9*#~$"' nޟg/vf@Fjv? z`}M|2$vFR9e)OCZjZ9gD9֦ ԅ$ w!"?꯽W_wc =ھ]kZ7x<R,` ?q/?gv7ME XuFH܈eܨ֟ =N譃aUQʞ ֘ d`P܍7 d_Gs?5\s WSE! $dB@Y[@?H_2Cʰrgs<_Q*ܼ$r:+3C_N6yMa;1-.m=5Z.>5~縤y[Midx4O19F܃ǿK8ۮ`BkຏQo,Q ^^m[qrmC%Um5%5>++K3dAHjrUdeS ZdKh 0P# KfrGyMDu?{_m.}iv/*33Ha* ~P q_{~;Ol\𤬓 5.d*eo`%HJsV†F%Awq߶ r3>."&@#_{==l 1’c$q\xfs||ߛ:}:dRdĈ3{xb]㘎'YYUqE5$. =-nbil#pҡY[u3:р(v{9cc7ܹwhB{U]QZ[SJ@%u_[{u۰e`y+5'j`V8icyG>s.=PS8aYT.)CVRk JyKS~\L3:i1H(NA/[dqx܅rÎEt*#cFOU>kn{%2h&кu)Ǯ{ ]odI0-k*#IF]LA<댹.$(N.zB-NޚoOYTSS:ϿOEn\AjE-U?_EqORe\ʀ}S[<}Mr*&Zz%@ѭn.S'/GQ)6}jղw)g 7DmA8ų&J w mm)]V~9$!$Q+Wm5uOQi#=? '(rTYtmlO^yRq{ɾxWOq_&hϔˬf}ݶ|&"woNE~O5YUVAHTY6%KjSU;͏2gdU60?Ͼwc7(n9s,"/UCx7:uI@j&W10X"|x{Wql[s/.n$R. Œ Y&B t<{&-1TR#{ 9+E|z)Oc!O;6^PM i"}]bXyw 2̲=PMȣĵxnCܽl{ȟn6B|-nb";ԎC+xI 0(KCۛ!jPIUKSG+0USnj$m<*ud2Ȥܓa/<cVgfm0NOniu4juCPX)k/6#gWg?_sL-_ :)XmsFp8w8i{6}9omakSŌ=*ܴd0 ['xw1%3!aM ̕$VcLJ+xQQJpۖ>^>;;Ao2r'5=0Wxة"5+pe!wr+9(sv P9P:&/`T:˨{ Wa%ˏߑ&H%ХA@Q&0}8N"oܵ/ډ_uۭf[Y+GiC#9U@::F&<ɿ+>ڧ3YHPg-:(9ܟs ]MO(0NGȒ*u-ՀWݭĹM)šP?P~&ϼ#ejjqFYj*QT;44 fwGlq{- rXgP+QHQŒCY1,Ɂ^{Uo~}rOqmX1 ID_S8QY[~=Su<Q*j|xd:M3F6 Ci؟['n~q<GiuʖG$Sh@Al?0_y]M%[-[[so9m$=A pY(XZ]Tzlfr(RO+ HaAL/{d8='s؍_%eDd)+mes3L`dQc޿^>ҡdQyHJHzaCBcf!+I#3Vc&Y):9%b_q{eygeٹwdH6 HE`5$E.c߷~l7Ƹ7+ɮ%cS$4{rZI$M^uQ~; 2XdPlO|ӦcosӅ9|ҟge/_3_fuyV]("=/Z&Gn9uONk@]W5?sv7p<l<}Ws\5fr 3[6#)|OPhjvJcڹᬎ`lu̸쵤U~3y2ޛ }kY=(KwnHJj j衻yeǻ~nCu<=V:F$yً9*EHdI9ݧ4B56f[ }}ofn'm%ܡ -[%Q# HU@UUI+k߽+m=k=㹑\\K 1"R(fwWQ-=EmeLT4qy+'` 9(B$*1s0<{<}:Cy$U@xRH͜|˻6vo养=#(ݛ@$(ɖ)ڔ 5:d1WQNduh.R¨5?]cR[`H'syD{Ҍ HۺW^eTD'>w{r!y^Iuz*HElKE %$JȆU\GzJVr!Bm>Jb<ǡ>]\){uQ=?ZgMo q_|J^v_V37?"gZVajOn1͙jj52Vi"ˤ ޯofvEǾ}$ , Cw?_y(4| GUM;B%!џٌVBpxE}/ۓǼc~3CCuyݢijIY54t5-, 84}ʎ OWCW^wg64mӷcIiK j,M#DNo| &|,Hįu +fXʎr:%OrPmTw,AcQ@fqKyhQcjۻknˀUU*1U$P)[J VT *o7ϻ=A!/bC=KG+qZ2~{m>n,G_BHY-e(+YU4vN%dWdFF#UHqT`G׮:zOY#I%69$#?,ݑdFSm"uQ tvCULfB ]_#Z&G?O/ .9f9AkܯխU|=K\pXQiRXO/_ݺg7qNodfY÷2D@W57Dt%nnQ!`U_#il[;([Ъ.='}v}nMID@+HМPNwEf%BQ11}/o0B`cU\SBG: ~C\aSRz,qB3*X=bbozt@I?O}$/O^Gmީs:$=2`j|'F_U9XʳKYSB;sz(?gd_ҹe33C:Hh]MC88=UW+0LhS`-LWcK-wۥC%C-@?,QN)}佴m9ciocEEZ BzY ^-M5 4M&>h2`.o +")}`BA>uI٪UB)ٍ%oo>@$"7g\֥8o&K P6$I :X܏BM;WP:fa1`-=>ʟy-V{M޺ٹZ8Q^r}._|kKc&$8§uvxTUv#yJI~`=\|_>F*6ȋJFGM6SEdԞ*ڪ9E)Sr+x_'ojB$T=cFS9B ́r9AA,'?UpMcj2 V`"ꍡik+* 4Ay,~}o}oi fr>Hhٷ.`-ܥp''du,Wd䧯TǕG#yZ:v09|/suOqyu-,F•_BZBP|2҂0Ҿ\ƒ?}+7yy vc+h!0!,A7|R}s䶕f;T-.LS╉-j]q;nc^}[dPʲߩ@0^8bk۞g{˗c[5g,#!I>dOE&^#>{t5i6S>7OOb(} gqeRY)79$hN펢m^{qses)lNQS%I:y&޿ctg`DY&SYjϛʀ CG zwݏ:A8׿qw?S/'Sى gZ ?wL[JHa\ 6>Ѯeo.3VC=4_P*q?Z5DXRX#1CqK|),,'qgsep):2CѣL)$XG?ޖ}x}9;UK~Akǝ)>pR׶t 86#ߏރݢo8n>>_kz'aᶖV!.&I)/ @%J*x m@ͿMqjxH*j5ZORO,r7)lM.l3 3ZF#|S_Vb:OEGO:F̪~9 Yп{ߺP?AߺI?W}u<~׺xu^׿{ߺ^u/c=tE}?}}t{{^ukui-control-center/plugins/messages-task/about/res/manufacturers/MICRON.jpg0000644000175000017500000001135014201663716026120 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF] 1 !AQq"2BSTRr#$4a3CDӔ1!AQaq2B"$R#4D%5 ?8W'~&Ԩ;WIt jQ?ޫ5C$Tڔ-lLTڔb-X#?.%Qv.%0UJsW;_+@#u(R??4 Q}WˀY+V?\ Y*?07ISo7k|RQ z*$rA.1S?H>yp ҴB=3hSL6>|RBn(īH\u(G0_.0U ϣIXiZ!G*-?k h@:#2S:` #ğ4(dpZ Z]/oĻ~bk8t=bڗ u3F-y>h4ˀvA>;SewT`GL}@ә+_/ɅE.o y0. 8Y{y1Y{y1Y/x,)Ef4qQؽ6D\ qvRT5 lmiDEuSQy&9+MW% jÐ/ Z SW8dD%_♍wnu(`25wUeJHzjVTF+9Du% |tS  gԛU[ura7wp֎\ԝZQ{|{"jaԫ-W*21e%ktSy Ϋ6w<”ҚbqՋeIkWEUu¬IM$OC F,1V \nF4=JqDk`ZC[+J&_ݳ7g_]YWjhhBM$h':+PztHTsB4@vg$ⳏћjii5ә6?^#$zRψ7+Ki9)7DO>DlQXfy lp >t#7a3*jrtls9Cv3⁡:jÅ#>/ͲN֦,^kj[!aI(y, z{^]zyq D?8zV@|~S( lԍ“L֞1hĥ3[BӞ߇WKqo(eĎȻG0&ҽsrBW+w$2<`.f](YIgٖ )=)jRNto5}In[H©;Z&W5!6=$Ep vuyo]Gܿf>]p;o55޾ v8mpҶuou[~uȝSCREke RUGH9ZQ|9di@8Q]?{KvMҁ.,p{ܳ5狍r %WͲ5k>6I#|?] ,dK)ShӆN9ԥ.h4G@̝Z8 dU `:Xǧ\ϯuʘKK'S as UU/mU1 >7Ţ+MXh~'f:ަjCrNBdHpDSu~ZrϘq[GGUn ڴ0Ӌ/^]d_l53KqvĂ` \|_BpvA~UmeMz 4ItI#*;t?D:of\+u“b;6ٝX=ڻ)WIJN˘KA+b^ԏHs gD-8G_JtUc Vɺ.a;~!$zh89畜~QCƫvz;E zG˛˱5Է&^&p8ܙcem\KJ8fsVwUH+`FdJDb` }Yh.͌& p~\(Oo[ Gb^JeVd\>O<v](L):K4?{`ENɚS! _X~>w $#%8q\3HU8 {O@6Zư (}UJŔ/Bb\HՌ[B=IKԱ?eՓnXQH"E,ʌ ^n` 9tUU!=ι=5 }]8|-Iդb$ R|=uOڊ֟mlukbRe +djEu`wGQ+ HlJeg1,Wjmcӟ/FlE]/VܨiZL4l[*}ݹwŢ^%hJ*t=O[.x>j60>V 7fn_g A^ڏz[_.mTdfmXc8ʏ$0e92J;GT:V~Z ]MpO'!9m-5c,%Rf 9fkX)K3]jE3Lm)JQTsnKUſgԿ$,Dt`F%ɾes^_kwl@o{S6bMS=.H Lhuv0%ň`yC f .hlPA,(Dy~L|ZMrma c&LI`G6v)dr #o(aD ` #`wŅȞ/ىoIM!Lbɉ4Lh0"&ޮ?0]”rL_!dr (a`0,Arxޙ13M_ukui-control-center/plugins/messages-task/about/res/manufacturers/MACY.jpg0000644000175000017500000001166714201663716025675 0ustar fengfengExifII*Duckyd)http://ns.adobe.com/xap/1.0/ AdobedF]   1!Aq QB$"24aR#c&!1AQaq"B$4D%2TR#d ?&QZ⧓?t!Ls g$"&c )g"\çd)GDpmrL= 2L5H]Q$"%<pxBOo&(XO&~B$dIE"LǺDR$ϧ? DNR2O.{Bdj.IEJyr).߄MS{[&Q LЅ1$IȓdDt.IOd~se!2\(0 !uF\(  ]*L9`CF?M/ɌrͳUGQ cNhѠiye4>a̿u:|mC+}8xDaoB<88Uݨ^iI(70˸LT.L#k CtN(PBD$zcIkKu/.FR#lތpb(؜5OiV>ѭy9=\DPїf fP,LTNa$GMǪ{Ţ.fZ{Q=k[SiΥ/(*tާ+xxm!]zזqIĪpI$+.܈#qQ?45+ugeUL <$9:]oytgn=Jቕ$w1O+]Zں5q8-;d1Θv yAhBPiJ(( @B=i`Yy%>-*v#F$F7J|-j$P_7[)+ߕ?yp~.};6&?vfr1ᶌcB1چa,;,y!t.ked)a⁵sZTT-J:Ka;Myx̻3h>^6w`!Xv{ B-`2>=Sy_Եzϧ#W6>S{acAr"6#!0r76I'&ܱg'cә-pt#e_f7h7P-CEzPۼ;""(DTS]QryPlԘe. #$^[/ O i@Kth[Ɛƞyhfv@}d&%[>a.9& B< +q %iD*( \jwuY<v8`N t/B a4^}Y0Z}侚UvH5ϴaUgp΋?t[oG\^G\`+C:f\W4:A {yf}nO3l[Ո_y #y\Pꂫ6^Tg)a"LD$R${tEO&}=2V7*Ds*uxl 嵲MT֖,H v@rO[ f//;gKdg&=a֪lHuDb?v8gDanv،A6&AT?搰ؤj1ĞLG ť2M1-Ԁw늰hF1Vj5F\(a|>s&\<#(>]:*L9`< cH=&3]H>);!&DpmrEO.{Bdj.IEJyr).߄MS{[&Q LЅ1$IȓdDt.IOd~se!2\(0 !uF\(  ]/ukui-control-center/plugins/messages-task/about/res/logo.png0000644000175000017500000001652214201663716023224 0ustar fengfengPNG  IHDR>1qxIDATx] U_^.F2;X_4tgDH|[*FF|cG*([Eѣ8@ߺu}g̜{Eyٳg{֣jՓv#oQ_"*mLD]c,#%DD4^ YU'x׉hm R j}":'oh8џh|`%5:UojODGѩDy Dt)]6:bZl~}m- E&e->MVDty\ LՊW/&z<ù۰:OD+hf`ۨU^V:"ZhMuzheڋC}mKD}VMZhZD4j5n_`0ܭ"k9 " dzhYk#_b% D3)٪g~L`+r=noDtF6#=`4={u9ޗ^ ^ax9jub;˦_9)m_حVLgT$/QW"f3hG&lo_AWcxAVV7[vyE؉,:"gj5DV+&h 5 LDL#DtJL,Vq_%S΍Sn/,"zjuT:h992GbdB[wͩ_hk3o XvAcX$}>9'D wv'i@0Us<} ˌYsSV|^C[tj"u~`)(1Q:ѕXG&(c_1D֫xscVCűph<W'q}c9p?C9W&v`n "8o<dlظmj?ؾ.'Dc۠?{S}ٹ][V/L(g8 蚘X7D=VQ"sYmFDt:+i xHcڎn# \DD O8<\`cGBՏRW v&&9[:HsR~c}]>D4" x7MMAOў ~P34C`h4AцD;[`>."z 0rXeo*䯴ػۡLsV0̿dPn&2VP{DzCD ?0ѫVo158P Hf6uDRف΂+d" m1KL#zc1sjKq.I"xZg[aV3-KRtՇXvTm뵗IhՊnCDCne'r]!:=MF1juƽXYXGLσ(Kz8%<8<ޗ/Rԉ3NjA震eQZeyjAcsV gNZ2m%nA)oȷTwAo :0Gn0?01cą*ӯj;VApJ phFV`1vxՀ q9d1̹˜+0QghpfZ>X AYLo ^Ч:_3p5eBDWW?xwe=ZmN9edwǘ<L|=:L8B~#Lc$wJK X10`3#H`boD%&[k+'b~ϦL+ ޷8drp&Pͥ+oe=.9˲bC[y, ^/a<7II*VptoݝpYo&\_^}01sҚ ?aIO0#rv`ixdmtt&K cr"OE9Tj ÉX^^va{bۉaG!Kժ&SDN"! >͡bɢȹpGaw)bȥ ^>j1k@B=r^&]ĶGp`?++{g9l88y p'jŞlzw:Nj5I6L8I/Ι"Vpoؙ`&l8ǀq~#qޑ<50Ѽm$$JQ\I# .p1ZG&q+s {6`#(l)r ~b\J0c%z/; L4?弫,`ot`F;VyYnORjX,! hL0 Ya^F#Ku@P_~kbal/rA``afvVt6 @tY#Zm oWVܞP`Ihx Wpi?>!ķVO%%9YJ#! X)",|c0+%EO2~`q S, ~}:) x/㦎ZdJU@̆2.jugB0o_%?$g΃p|Jě\ h?kоX8KRD&veZ#|7 d +azkK ^_r; 3L[+m!kgcs†[P?$K!rKY_XX)b6Ror !U6kZ%@E5 gj$T ;&w 7CA̺ bV^G=&|J/qWc/Bu:b)^r%D3Ii @CX5!ߥ=pìV;yY<$EOj-d|F.`5,XGa5)[\.TCh@}}iR6[~Ф|խlOhg:\W B#D`ǡAYꁔ׵U-z/8] K3,1dJ$fzKq8No42G̹nu[텕පPթ!VQ !SmMxw s!.MKx ]$޶/tM$H;@"9zńI=yyiTJyF#xxR9~hb?Xȧ$`{mU u~njᎄa_)P pݻY><< Ϙ>R |8XF)ǫGɘI"c$.c d0Uu1/Dx_[37pEҸc>0҄&H>#Xp<$R&YۗtCrOf1`[#9Y;<qǘ|i'^tKWqPXRg]("e+l;~R7zfȺ2f49 "z0[PY ds$DZ[o ٭L;O:嘏*Q)EBU/̭<.)C"i_$ZZ\;@~;"XAD|*/c{MP~"}Ιd? Ήr5FC,PHHXn{x{";n ||=+Ƒza_,58<.Yr& cߜk\v\Z,@.^7I88'qBUW #"1c8!0q3Yc݁,E5ٟdngob.X#Y@bp8b?!tN֋M1L9MCL YZ2rt`9ROPʚEb=]aLrEu>%duLNEMRTXº!6DЧi}cY @3k\]RMDH 89x*=0%'sY|ڿL=bg\ }Ϋp`ѕ'2c,Dw1<&F򻻇{7 Ձ†=qm0 cbgQj6WUb&xvf+uy}I<2/~Sqjπ̃w,}-Y"Dnb̼iQ B}u/ƥ=2':/8 WQ yb\H$ 2xO#p=Xՙ/5aQw \84. :z(燄40]&Rppq@fmScvju-uvKmXIawyq% /]Cľ38`Ѱ!vU&PpV i.に.$1ԅ~c?xd^Ezf XIC{PPg[o.S`Lb2Ď>ńї |}R9+y XoH9hJ[;=ڻPv%Rw}\IPQύ!!V19 QRzP=8RN.AHk*)xieƊU.P4+cñRɫN/Fc Ffa.lHє*)k>Ɓ_CcCb&GJ"ׁ?MNZm%F*qq0KuCp19>'Y4B]`pPzMI~nIєji+ A |=B]'‰Yq_ ̂Mqw^ # N1-7V kb=?GRqb夔E܅%ITALoӟ8LD6O6&*0$ԅ` gb ?|:C]/d WpPŀ+ua7ܿ>J4ס.j\є.Cy^ u8,6ª4hJ~[[b$r{cQЫAC&Zk)rP~lyxJHJޞ9)Iem (0/ԅ.`'=[ke%?b`|s*8J?/i@Cj1އ 7#4QYְD5mY: ESzVc^ 3Lr^g+J8g+g5.쏺{"?0q܂!ES&ԅadqPf¦9#k!8hJC]8yQ4 _f$ܵHxCSOŏo90_[넾C ;^Z4%OUQ "9[+am9߄$m bK(á%k5 >/ L.,/ѯ.%?3I^MAD|ɛ}_'IENDB`ukui-control-center/plugins/messages-task/about/res/img.qrc0000644000175000017500000001766114201663716023046 0ustar fengfeng manufacturers/3COM.jpg manufacturers/A-DATA.jpg manufacturers/ABIT.jpg manufacturers/ACER.jpg manufacturers/ADATA.jpg manufacturers/AEXEA.jpg manufacturers/ALI.jpg manufacturers/AMD.jpg manufacturers/AMI.jpg manufacturers/AOC.jpg manufacturers/AOPEN.jpg manufacturers/APACER.jpg manufacturers/APPLE.jpg manufacturers/ASINT.jpg manufacturers/ASROCK.jpg manufacturers/ASUS.jpg manufacturers/ASZ.jpg manufacturers/ATHEROS.jpg manufacturers/ATI.jpg manufacturers/AUO.jpg manufacturers/AUTHENTEC.jpg manufacturers/AVAGO.jpg manufacturers/AVEO.jpg manufacturers/B&DATA.jpg manufacturers/B-LINK.jpg manufacturers/BENQ.jpg manufacturers/BIOSTAR.jpg manufacturers/BROADCOM.jpg manufacturers/CANON.jpg manufacturers/CHAINTECH.jpg manufacturers/CHICONY.jpg manufacturers/CISCO.jpg manufacturers/COLORFUL.jpg manufacturers/COMEON.jpg manufacturers/CORSAIR.jpg manufacturers/CREATIVE.jpg manufacturers/D-LINK.jpg manufacturers/DELL.jpg manufacturers/DFI.jpg manufacturers/DTK.jpg manufacturers/E-MU.jpg manufacturers/EAGET.jpg manufacturers/EAST.jpg manufacturers/ECS.jpg manufacturers/ELEPHANT.jpg manufacturers/ELIXIR.jpg manufacturers/ELSA.jpg manufacturers/EMPIA.jpg manufacturers/ENLON.jpg manufacturers/ENNYAH.jpg manufacturers/ETRON.jpg manufacturers/EXCELSTOR.jpg manufacturers/FIC.jpg manufacturers/FOUNDER.jpg manufacturers/FUJITSU.jpg manufacturers/G.SKILL.jpg manufacturers/GAINWARO.jpg manufacturers/GALAXY.jpg manufacturers/GAMEN.jpg manufacturers/GEIL.jpg manufacturers/GIGABYTE.jpg manufacturers/GREAT WALL.jpg manufacturers/HASEE.jpg manufacturers/HITACHI.jpg manufacturers/HOMKEY.jpg manufacturers/HP.jpg manufacturers/HYNIX.jpg manufacturers/HYUNDAI.jpg manufacturers/IBM.jpg manufacturers/INNOVISION.jpg manufacturers/INTEL.jpg manufacturers/IOMEGA.jpg manufacturers/J&W.jpg manufacturers/JETWAY.jpg manufacturers/JJM.jpg manufacturers/KINGBOX.jpg manufacturers/KINGFAST.jpg manufacturers/KINGMAX.jpg manufacturers/KINGSPEC.jpg manufacturers/KINGSTEK.jpg manufacturers/KINGSTON.jpg manufacturers/KINGTIGER.jpg manufacturers/LEADTEK.jpg manufacturers/LENOVO.jpg manufacturers/LG.jpg manufacturers/LINKSYS.jpg manufacturers/LITEON.jpg manufacturers/LITTLE TIGER.jpg manufacturers/LOGITECH.jpg manufacturers/M-ONE.jpg manufacturers/M_AUDIO.jpg manufacturers/MACY.jpg manufacturers/MAGIC-PRO.jpg manufacturers/MARVELL.jpg manufacturers/MATROX.jpg manufacturers/MAXSUN.jpg manufacturers/MAXTOR.jpg manufacturers/MAYA.jpg manufacturers/MEGASTAR.jpg manufacturers/MICRON.jpg manufacturers/MICROSOFT.jpg manufacturers/MMC.jpg manufacturers/MOTOROLA.jpg manufacturers/MSI.jpg manufacturers/MUSILAND .jpg manufacturers/NEC.jpg manufacturers/NETGEAR.jpg manufacturers/NOKIA.jpg manufacturers/NVIDIA.jpg manufacturers/OCZ.jpg manufacturers/OMEGA.jpg manufacturers/OMNIVISION.jpg manufacturers/OMRON.jpg manufacturers/ONDA.jpg manufacturers/ONKYO.jpg manufacturers/PANASONIC.jpg manufacturers/PHILIPS.jpg manufacturers/PHOENIX.jpg manufacturers/PINE.jpg manufacturers/PIONEER.jpg manufacturers/PIXART.jpg manufacturers/PLDS.jpg manufacturers/POWERCOLOR.jpg manufacturers/PRIMAX.jpg manufacturers/QDI.jpg manufacturers/QIMONDA.jpg manufacturers/QUANTUM.jpg manufacturers/RALINK.jpg manufacturers/RAPOO.jpg manufacturers/RAZER.jpg manufacturers/REALTEK.jpg manufacturers/SAMSUNG.jpg manufacturers/SANYO.jpg manufacturers/SAPPHIRE.jpg manufacturers/SEAGATE.jpg manufacturers/SHARK.jpg manufacturers/SIEMENS.jpg manufacturers/SIS.jpg manufacturers/SMP.jpg manufacturers/SONIX.jpg manufacturers/SONY.jpg manufacturers/SOYO.jpg manufacturers/SPARK.jpg manufacturers/SUNPLUS.jpg manufacturers/SUPERGRAPHIC.jpg manufacturers/SUPOX.jpg manufacturers/SYMBOL.jpg manufacturers/SYNTEK.jpg manufacturers/T&W.jpg manufacturers/TAIYANFA.jpg manufacturers/TDK.jpg manufacturers/TEKRAM.jpg manufacturers/TERRATEC.jpg manufacturers/TEXAS.jpg manufacturers/TONGFANG.jpg manufacturers/TOSHIBA.jpg manufacturers/TOYOTA.jpg manufacturers/TP-LINK.jpg manufacturers/TRANSMETA.jpg manufacturers/TRUST.jpg manufacturers/TSSTCORP.jpg manufacturers/TYAN.jpg manufacturers/UBUNTUKYLIN.jpg manufacturers/UMC.jpg manufacturers/UNIKA.jpg manufacturers/VIA.jpg manufacturers/VIMICRO.jpg manufacturers/VIRTUALBOX.jpg manufacturers/WESTERN DIGITAL.jpg manufacturers/WINBOND.jpg manufacturers/XFX.jpg manufacturers/YESTON.jpg manufacturers/ZOTAC.jpg manufacturers/ZTE.jpg logo.svg logo.png ukui-control-center/plugins/messages-task/about/trialdialog.h0000644000175000017500000000236414201663716023430 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TRIALDIALOG_H #define TRIALDIALOG_H #include #include #include "Label/titlelabel.h" class TrialDialog : public QDialog { Q_OBJECT public: TrialDialog(QWidget *parent); ~TrialDialog(); private: void initUi(QDialog *mTrialDialog); private: TitleLabel *mTitleLabel; QLabel *mContentLabel_1; QTextBrowser *mContentLabel_2; QLabel *mContentLabel_3; QLabel *mContentLabel_4; QLabel *mContentLabel_5; }; #endif // TRIALDIALOG_H ukui-control-center/plugins/messages-task/about/trialdialog.cpp0000644000175000017500000000650714201663716023766 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "trialdialog.h" #include #include #include TrialDialog::TrialDialog(QWidget *parent): QDialog(parent) { this->setWindowFlags(Qt::Dialog); setWindowTitle(tr("Set")); initUi(this); } TrialDialog::~TrialDialog() { } void TrialDialog::initUi(QDialog *mTrialDialog) { mTrialDialog->setFixedSize(560,560); QVBoxLayout *mverticalLayout = new QVBoxLayout(mTrialDialog); mverticalLayout->setSpacing(0); mverticalLayout->setContentsMargins(32, 32, 32, 24); QHBoxLayout *mTitleLayout = new QHBoxLayout; mTitleLabel = new TitleLabel(mTrialDialog); mTitleLabel->setFixedHeight(30); mTitleLayout->addStretch(); mTitleLayout->addWidget(mTitleLabel); mTitleLayout->addStretch(); mTitleLabel->setText(tr("Yinhe Kylin OS(Trail Version) Disclaimer")); mverticalLayout->addLayout(mTitleLayout,Qt::AlignTop); mverticalLayout->addSpacing(24); QVBoxLayout *mContentLayout = new QVBoxLayout; mContentLayout->setContentsMargins(0, 0, 0, 0); mContentLabel_2 = new QTextBrowser(mTrialDialog); mContentLabel_2->setFixedHeight(364); mContentLabel_2->setText(tr("Dear customer:\n Thank you for trying Yinhe Kylin OS(trail version)! This version is free for users who only try out, no commercial purpose is permitted. The trail period lasts one year and it starts from the ex-warehouse time of the OS. No after-sales service is provided during the trail stage. If any security problems occurred when user put important files or do any commercial usage in system, all consequences are taken by users. Kylin software Co., Ltd. take no legal risk in trail version.\n During trail stage,if you want any technology surpport or activate the system, please buy“Yinhe Kylin Operating System”official version or authorization by contacting 400-089-1870.")); mContentLabel_2->adjustSize(); mContentLayout->addWidget(mContentLabel_2); mContentLayout->addStretch(); QHBoxLayout *mContentLayout_1 = new QHBoxLayout; mContentLabel_4 = new QLabel(mTrialDialog); mContentLabel_4->setText(tr("Kylin software Co., Ltd.")); mContentLayout_1->addStretch(); mContentLayout_1->addWidget(mContentLabel_4); mContentLayout->addLayout(mContentLayout_1); QHBoxLayout *mContentLayout_2 = new QHBoxLayout; mContentLabel_5 = new QLabel(mTrialDialog); mContentLabel_5->setText(tr("www.Kylinos.cn")); mContentLayout_2->addStretch(); mContentLayout_2->addWidget(mContentLabel_5); mContentLayout->addLayout(mContentLayout_2); mverticalLayout->addLayout(mContentLayout); } ukui-control-center/plugins/devices/0000755000175000017500000000000014201663716016520 5ustar fengfengukui-control-center/plugins/devices/mousecontrol/0000755000175000017500000000000014201663716021251 5ustar fengfengukui-control-center/plugins/devices/mousecontrol/mousecontrol.ui0000644000175000017500000013260314201663716024346 0ustar fengfeng MouseControl 0 0 800 710 0 0 16777215 16777215 Template 0 0 0 0 0 20 20 25 0 0 0 0 Mouse Key Settings true title1# 0 0 0 100 0 100 16777215 Main button true right hand lefthandbuttonGroup Qt::Horizontal QSizePolicy::Fixed 50 20 left hand lefthandbuttonGroup Qt::Horizontal 40 20 0 0 0 100 0 100 16777215 Mouse wheel true Qt::Horizontal 40 20 0 0 0 Move the pointer as it hover over the inactive window true Qt::Horizontal QSizePolicy::Fixed 25 20 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Fixed 20 35 0 0 Cursor Settiings true title1# 0 0 0 100 0 100 16777215 Cursor themes true Qt::Horizontal QSizePolicy::Fixed 20 20 0 0 true Qt::Horizontal 40 20 0 0 100 0 100 16777215 Speed true 0 0 30 0 30 16777215 Slow true 100 1000 50 50 Qt::Horizontal Qt::Horizontal QSizePolicy::Fixed 15 20 0 0 Fast true Qt::Horizontal 40 20 0 0 100 0 100 16777215 Sensitivity true 0 0 30 0 30 16777215 Low true 100 1000 50 50 Qt::Horizontal Qt::Horizontal QSizePolicy::Fixed 15 20 0 0 High true Qt::Horizontal 40 20 0 0 100 0 100 16777215 Visibility true Hide pointers while typing Qt::Horizontal QSizePolicy::Fixed 50 20 Show position of pointer when the Control key is pressed Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Fixed 20 35 0 0 Related settings true title1# touchpad settings true Qt::Horizontal 40 20 cursor settings true Qt::Horizontal 40 20 Qt::Vertical 20 40 25 20 25 0 0 0 0 Touchpad Settings true title1# 15 0 0 Enabled touchpad true Qt::Vertical QSizePolicy::Fixed 20 35 25 0 0 0 0 0 0 General Settings true title1# 0 Disable touchpad while typing Qt::Horizontal 40 20 0 Enable mouse clicks with touchpad Qt::Horizontal 40 20 15 Disable rolling: Qt::Vertical QSizePolicy::Expanding 20 40 25 0 0 0 0 Vertical &edge scrolling rollingbuttonGroup &Horizontal edge scrolling rollingbuttonGroup &Vertical two-finger scrolling rollingbuttonGroup Horizontal two-&finger scrolling rollingbuttonGroup None rollingbuttonGroup Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Vertical 20 40 25 20 25 0 0 0 0 Cursor And Pointersize true title1# 620 50 620 50 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Make the cursor pointer easier to see</p></body></html> Qt::Vertical QSizePolicy::Fixed 20 35 25 0 0 0 0 0 0 Change Cursor Weight true title1# 15 0 0 thin true Qt::Horizontal 0 0 coarse true Qt::Horizontal QSizePolicy::Fixed 25 20 90 30 90 30 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Fixed 20 35 0 0 Change Pointersize true title1# 50 smaller - 100%(default) cursorsizebuttonGroup medium - 125% cursorsizebuttonGroup larger - 150% cursorsizebuttonGroup Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Fixed 20 25 Reset Qt::Horizontal 40 20 Qt::Vertical 20 40 ukui-control-center/plugins/devices/mousecontrol/mousecontrol.pro0000644000175000017500000000146514201663716024532 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-08-22T11:12:59 # #------------------------------------------------- include(../../../env.pri) include(../../pluginsComponent/pluginsComponent.pri) QT += widgets x11extras #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = $$qtLibraryTarget(mousecontrol) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} TEMPLATE = lib CONFIG += plugin INCLUDEPATH += ../../.. \ /usr/include/kylinsdk \ LIBS += -L$$[QT_INSTALL_LIBS] -lmouseclient -ltouchpadclient -lXi -lgsettings-qt CONFIG += link_pkgconfig c++11 PKGCONFIG += gsettings-qt #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ mousecontrol.cpp HEADERS += \ mousecontrol.h FORMS += \ mousecontrol.ui INSTALLS += target ukui-control-center/plugins/devices/mousecontrol/mousecontrol.h0000644000175000017500000000730114201663716024154 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef MOUSECONTROL_H #define MOUSECONTROL_H #include #include #include "mainui/interface.h" #include #include #include #include #include #include "kylin-mouse-interface.h" #include "../../pluginsComponent/switchbutton.h" #include "../../pluginsComponent/customwidget.h" #define CURSORS_THEMES_PATH "/usr/share/icons/" #define GNOME_TOUCHPAD_SCHEMA "org.gnome.desktop.peripherals.touchpad" #define GNOME_ACTIVE_TOUCHPAD_KEY "send-events" #define GNOME_TOUCHPAD_CLICK_KEY "tap-to-click" #define GNOME_DISABLE_WHILE_TYPEING_KEY "disable-while-typing" #define GNOME_DISABLE_SCROLLING_KEY "natural-scroll" #define GNOME_SCROLLING_EDGE_KEY "edge-scrolling-enabled" #define GNOME_SCROLLING_TWO_KEY "two-finger-scrolling-enabled" #define TOUCHPAD_SCHEMA "org.ukui.peripherals-touchpad" #define ACTIVE_TOUCHPAD_KEY "touchpad-enabled" #define DISABLE_WHILE_TYPING_KEY "disable-while-typing" #define TOUCHPAD_CLICK_KEY "tap-to-click" #define V_EDGE_KEY "vertical-edge-scrolling" #define H_EDGE_KEY "horizontal-edge-scrolling" #define V_FINGER_KEY "vertical-two-finger-scrolling" #define H_FINGER_KEY "horizontal-two-finger-scrolling" /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif namespace Ui { class MouseControl; } class MouseControl : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: MouseControl(); ~MouseControl() Q_DECL_OVERRIDE; QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; CustomWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; void component_init(); void status_init(); bool find_synaptics(); bool _supports_xinput_devices(); private: Ui::MouseControl *ui; QString pluginName; int pluginType; CustomWidget * pluginWidget; SwitchButton * activeBtn; // QGSettings * tpsettings; QGSettings * gnomeSettings; QStringList _get_cursors_themes(); void _refresh_touchpad_widget_status(); void _refresh_rolling_btn_status(); private slots: void mouseprimarykey_changed_slot(int id); void cursor_themes_changed_slot(QString text); void speed_value_changed_slot(int value); void sensitivity_value_changed_slot(int value); void show_pointer_position_slot(bool status); void active_touchpad_changed_slot(bool status); void disable_while_typing_clicked_slot(bool status); void touchpad_click_clicked_slot(bool status); void rolling_enable_clicked_slot(bool status); void rolling_kind_changed_slot(QAbstractButton * basebtn, bool status); void cursor_size_changed_slot(); }; #endif // MOUSECONTROL_H ukui-control-center/plugins/devices/mousecontrol/mousecontrol.cpp0000644000175000017500000003477014201663716024521 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "mousecontrol.h" #include "ui_mousecontrol.h" #include //放在.h中报错,放.cpp不报错 extern "C" { #include #include //#include } #define NONE_ID 0 #define CURSORSIZE_SMALLER 18 #define CURSORSIZE_MEDIUM 32 #define CURSORSIZE_LARGER 48 XDevice* _device_is_touchpad (XDeviceInfo * deviceinfo); bool _device_has_property (XDevice * device, const char * property_name); struct KindsRolling : QObjectUserData{ QString kind; }; MouseControl::MouseControl() { ui = new Ui::MouseControl; pluginWidget = new CustomWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); pluginName = tr("mousecontrol"); pluginType = DEVICES; // const QByteArray id(TOUCHPAD_SCHEMA); // tpsettings = new QGSettings(id); const QByteArray idd(GNOME_TOUCHPAD_SCHEMA); gnomeSettings = new QGSettings(idd); InitDBusMouse(); component_init(); status_init(); } MouseControl::~MouseControl() { delete ui; ui = nullptr; DeInitDBusMouse(); } QString MouseControl::get_plugin_name(){ return pluginName; } int MouseControl::get_plugin_type(){ return pluginType; } CustomWidget * MouseControl::get_plugin_ui(){ return pluginWidget; } void MouseControl::plugin_delay_control(){ } void MouseControl::component_init(){ // ui->lefthandbuttonGroup->setId(ui->rightRadioBtn, 0); ui->lefthandbuttonGroup->setId(ui->leftRadioBtn, 1); // Cursors themes QStringList themes = _get_cursors_themes(); ui->CursorthemesComboBox->addItem(tr("Default")); ui->CursorthemesComboBox->addItems(themes); // add switchbtn for active touchpad activeBtn = new SwitchButton(pluginWidget); ui->activeHLayout->addWidget(activeBtn); ui->activeHLayout->addStretch(); //无接口可用暂时屏蔽鼠标滚轮设置 // for (int i = 0; i < ui->horizontalLayout_2->count(); ++i) { // QLayoutItem * it = ui->horizontalLayout_2->itemAt(i); //// it->widget()->hide(); //这种遍历无法得知类型,弹簧控件没有hide方法,导致段错误 // } ui->label_3->hide(); ui->comboBox->hide(); ui->label_4->hide(); ui->checkBox->hide(); //不存在触摸板设备,则隐藏触摸板设置按钮 if (!find_synaptics()) ui->touchpadBtn->hide(); // hide helper radiobutton ui->noneRadioButton->hide(); // set buttongroup id ui->rollingbuttonGroup->setId(ui->noneRadioButton, NONE_ID); // set user data rolling radiobutton KindsRolling * vedge = new KindsRolling(); vedge->kind = V_EDGE_KEY; ui->vedgeRadioBtn->setUserData(Qt::UserRole, vedge); KindsRolling * hedge = new KindsRolling(); hedge->kind = H_EDGE_KEY; ui->hedgeRadioBtn->setUserData(Qt::UserRole, hedge); KindsRolling * vfinger = new KindsRolling(); vfinger->kind = V_FINGER_KEY; ui->vfingerRadioBtn->setUserData(Qt::UserRole, vfinger); KindsRolling * hfinger = new KindsRolling(); hfinger->kind = H_FINGER_KEY; ui->hfingerRadioBtn->setUserData(Qt::UserRole, hfinger); // set buttongroup id ui->cursorsizebuttonGroup->setId(ui->smallerRadioBtn, CURSORSIZE_SMALLER); ui->cursorsizebuttonGroup->setId(ui->mediumRadioBtn, CURSORSIZE_MEDIUM); ui->cursorsizebuttonGroup->setId(ui->largerRadioBtn, CURSORSIZE_LARGER); } void MouseControl::status_init(){ if (kylin_hardware_mouse_get_lefthanded()) ui->leftRadioBtn->setChecked(true); else ui->rightRadioBtn->setChecked(true); //cursor theme QString curtheme = kylin_hardware_mouse_get_cursortheme(); if (curtheme == "") ui->CursorthemesComboBox->setCurrentIndex(0); else ui->CursorthemesComboBox->setCurrentText(curtheme); double mouse_acceleration = kylin_hardware_mouse_get_motionacceleration();//当前系统指针加速值,-1为系统默认 int mouse_threshold = kylin_hardware_mouse_get_motionthreshold();//当前系统指针灵敏度,-1为系统默认 //当从接口获取的是-1,则代表系统默认值,真实值需要从底层获取 if (mouse_threshold == -1 || static_cast(mouse_acceleration) == -1){ // speed sensitivity int accel_numerator, accel_denominator, threshold; //当加速值和灵敏度为系统默认的-1时,从底层获取到默认的具体值 XGetPointerControl(QX11Info::display(), &accel_numerator, &accel_denominator, &threshold); qDebug() << "--->" << accel_numerator << accel_denominator << threshold; kylin_hardware_mouse_set_motionacceleration(static_cast(accel_numerator/accel_denominator)); kylin_hardware_mouse_set_motionthreshold(threshold); } //set speed // qDebug() << kylin_hardware_mouse_get_motionacceleration() << kylin_hardware_mouse_get_motionthreshold(); ui->speedSlider->setValue(static_cast(kylin_hardware_mouse_get_motionacceleration())*100); //set sensitivity ui->sensitivitySlider->setValue(kylin_hardware_mouse_get_motionthreshold()*100); //set visibility position ui->posCheckBtn->setChecked(kylin_hardware_mouse_get_locatepointer()); connect(ui->CursorthemesComboBox, SIGNAL(currentTextChanged(QString)), this, SLOT(cursor_themes_changed_slot(QString))); connect(ui->lefthandbuttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(mouseprimarykey_changed_slot(int))); connect(ui->speedSlider, SIGNAL(valueChanged(int)), this, SLOT(speed_value_changed_slot(int))); connect(ui->sensitivitySlider, SIGNAL(valueChanged(int)), this, SLOT(sensitivity_value_changed_slot(int))); connect(ui->posCheckBtn, SIGNAL(clicked(bool)), this, SLOT(show_pointer_position_slot(bool))); connect(ui->touchpadBtn, &QPushButton::clicked, this, [=]{ui->StackedWidget->setCurrentIndex(1);}); connect(ui->cursorBtn, &QPushButton::clicked, this, [=]{ui->StackedWidget->setCurrentIndex(2);}); //touchpad settings // activeBtn->setChecked(tpsettings->get(ACTIVE_TOUCHPAD_KEY).toBool()); if (gnomeSettings->get(GNOME_ACTIVE_TOUCHPAD_KEY).toString() == "enabled") activeBtn->setChecked(true); else activeBtn->setChecked(false); _refresh_touchpad_widget_status(); // disable touchpad when typing // ui->disablecheckBox->setChecked(tpsettings->get(DISABLE_WHILE_TYPING_KEY).toBool()); ui->disablecheckBox->setChecked(gnomeSettings->get(GNOME_DISABLE_WHILE_TYPEING_KEY).toBool()); // enable touchpad click // ui->tpclickcheckBox->setChecked(tpsettings->get(TOUCHPAD_CLICK_KEY).toBool()); ui->tpclickcheckBox->setChecked(gnomeSettings->get(GNOME_TOUCHPAD_CLICK_KEY).toBool()); // scrolling // ui->vedgeRadioBtn->setChecked(tpsettings->get(V_EDGE_KEY).toBool()); // ui->hedgeRadioBtn->setChecked(tpsettings->get(H_EDGE_KEY).toBool()); // ui->vfingerRadioBtn->setChecked(tpsettings->get(V_FINGER_KEY).toBool()); // ui->hfingerRadioBtn->setChecked(tpsettings->get(H_FINGER_KEY).toBool()); // ui->noneRadioButton->setChecked(false); // if (ui->rollingbuttonGroup->checkedButton() == nullptr) // ui->rollingCheckBtn->setChecked(true); // else // ui->rollingCheckBtn->setChecked(false); // _refresh_rolling_btn_status(); ui->rollingCheckBtn->setChecked(!(gnomeSettings->get(GNOME_SCROLLING_EDGE_KEY).toBool() || gnomeSettings->get(GNOME_SCROLLING_TWO_KEY).toBool())); ui->rollingWidget->hide(); connect(activeBtn, SIGNAL(checkedChanged(bool)), this, SLOT(active_touchpad_changed_slot(bool))); connect(ui->disablecheckBox, SIGNAL(clicked(bool)), this, SLOT(disable_while_typing_clicked_slot(bool))); connect(ui->tpclickcheckBox, SIGNAL(clicked(bool)), this, SLOT(touchpad_click_clicked_slot(bool))); connect(ui->rollingCheckBtn, SIGNAL(clicked(bool)), this, SLOT(rolling_enable_clicked_slot(bool))); // connect(ui->rollingbuttonGroup, SIGNAL(buttonToggled(QAbstractButton*,bool)), this, SLOT(rolling_kind_changed_slot(QAbstractButton*, bool))); //cursor settings int cursorsize = kylin_hardware_mouse_get_cursorsize(); if (cursorsize <= CURSORSIZE_SMALLER) ui->smallerRadioBtn->setChecked(true); else if (cursorsize <= CURSORSIZE_MEDIUM) ui->mediumRadioBtn->setChecked(true); else ui->largerRadioBtn->setChecked(true); connect(ui->cursorsizebuttonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(cursor_size_changed_slot())); //reset connect(ui->resetBtn, &QPushButton::clicked, this, [=]{ui->smallerRadioBtn->setChecked(true);}); } bool MouseControl::find_synaptics(){ XDeviceInfo *device_info; int n_devices; bool retval; if (_supports_xinput_devices() == false) return true; device_info = XListInputDevices (QX11Info::display(), &n_devices); if (device_info == nullptr) return false; retval = false; for (int i = 0; i < n_devices; i++) { XDevice *device; device = _device_is_touchpad (&device_info[i]); if (device != nullptr) { retval = true; break; } } if (device_info != nullptr) XFreeDeviceList (device_info); return retval; } XDevice* _device_is_touchpad (XDeviceInfo *deviceinfo) { XDevice *device; if (deviceinfo->type != XInternAtom (QX11Info::display(), XI_TOUCHPAD, true)) return nullptr; device = XOpenDevice (QX11Info::display(), deviceinfo->id); if(device == nullptr) { qDebug()<<"device== null"; return nullptr; } if (_device_has_property (device, "libinput Tapping Enabled") || _device_has_property (device, "Synaptics Off")) { return device; } XCloseDevice (QX11Info::display(), device); return nullptr; } bool _device_has_property (XDevice * device, const char * property_name){ Atom realtype, prop; int realformat; unsigned long nitems, bytes_after; unsigned char *data; prop = XInternAtom (QX11Info::display(), property_name, True); if (!prop) return false; if ((XGetDeviceProperty (QX11Info::display(), device, prop, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data) == Success) && (realtype != None)) { XFree (data); return true; } return false; } bool MouseControl::_supports_xinput_devices(){ int op_code, event, error; return XQueryExtension (QX11Info::display(), "XInputExtension", &op_code, &event, &error); } QStringList MouseControl::_get_cursors_themes(){ QStringList themes; QDir themesDir(CURSORS_THEMES_PATH); if (themesDir.exists()){ foreach (QString dirname, themesDir.entryList(QDir::Dirs)){ if (dirname == "." || dirname == "..") continue; QString fullpath(CURSORS_THEMES_PATH + dirname); QDir themeDir(CURSORS_THEMES_PATH + dirname + "/cursors/"); if (themeDir.exists()) themes.append(dirname); } } return themes; } void MouseControl::_refresh_touchpad_widget_status(){ if (activeBtn->isChecked()) ui->touchpadWidget->show(); else ui->touchpadWidget->hide(); } void MouseControl::_refresh_rolling_btn_status(){ if (ui->rollingCheckBtn->isChecked()) ui->rollingWidget->hide(); else ui->rollingWidget->show(); } void MouseControl::mouseprimarykey_changed_slot(int id){ kylin_hardware_mouse_set_lefthanded(id); } void MouseControl::cursor_themes_changed_slot(QString text){ QString value = text; if (text == tr("Default")) value = ""; QByteArray ba = value.toLatin1(); kylin_hardware_mouse_set_cursortheme(ba.data()); } void MouseControl::speed_value_changed_slot(int value){ kylin_hardware_mouse_set_motionacceleration(static_cast(value/ui->speedSlider->maximum()*10)); } void MouseControl::sensitivity_value_changed_slot(int value){ kylin_hardware_mouse_set_motionthreshold(10*value/ui->sensitivitySlider->maximum()); } void MouseControl::show_pointer_position_slot(bool status){ kylin_hardware_mouse_set_locatepointer(status); } void MouseControl::active_touchpad_changed_slot(bool status){ // tpsettings->set(ACTIVE_TOUCHPAD_KEY, status); if (status) gnomeSettings->set(GNOME_ACTIVE_TOUCHPAD_KEY, "enabled"); else gnomeSettings->set(GNOME_ACTIVE_TOUCHPAD_KEY, "disabled"); _refresh_touchpad_widget_status(); } void MouseControl::disable_while_typing_clicked_slot(bool status){ // tpsettings->set(DISABLE_WHILE_TYPING_KEY, status); gnomeSettings->set(GNOME_DISABLE_WHILE_TYPEING_KEY, status); } void MouseControl::touchpad_click_clicked_slot(bool status){ // tpsettings->set(TOUCHPAD_CLICK_KEY, status); gnomeSettings->set(GNOME_TOUCHPAD_CLICK_KEY, status); } void MouseControl::rolling_enable_clicked_slot(bool status){ // if (status) // ui->noneRadioButton->setChecked(true); // _refresh_rolling_btn_status(); if (status){ gnomeSettings->set(GNOME_SCROLLING_EDGE_KEY, !status); gnomeSettings->set(GNOME_SCROLLING_TWO_KEY, !status); } else{ gnomeSettings->set(GNOME_SCROLLING_EDGE_KEY, !status); } } void MouseControl::rolling_kind_changed_slot(QAbstractButton *basebtn, bool status){ if (ui->rollingbuttonGroup->checkedId() != NONE_ID) ui->rollingCheckBtn->setChecked(false); if (basebtn->text() == "None") return; QRadioButton * button = dynamic_cast(basebtn); QString kind = static_cast(button->userData(Qt::UserRole))->kind; // tpsettings->set(kind, status); } void MouseControl::cursor_size_changed_slot(){ kylin_hardware_mouse_set_cursorsize(ui->cursorsizebuttonGroup->checkedId()); } ukui-control-center/plugins/devices/shortcut/0000755000175000017500000000000014201663716020373 5ustar fengfengukui-control-center/plugins/devices/shortcut/keymap.cpp0000644000175000017500000000212414201663671022364 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "keymap.h" KeyMap::KeyMap() { metaColor = QMetaEnum::fromType(); } KeyMap::~KeyMap() { } QString KeyMap::keycodeTokeystring(int code){ return metaColor.valueToKey(code); //未匹配到则返回空 } ukui-control-center/plugins/devices/shortcut/defineshortcutitem.h0000644000175000017500000000356514201663671024462 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef DEFINESHORTCUTITEM_H #define DEFINESHORTCUTITEM_H #include #include class QLabel; class QPushButton; class CustomLineEdit; class DefineShortcutItem : public QFrame { Q_OBJECT public: explicit DefineShortcutItem(QString name, QString binding); ~DefineShortcutItem(); public: QWidget * widgetComponent(); QLabel * labelComponent(); QPushButton * btnComponent(); CustomLineEdit * lineeditComponent(); public: void setDeleteable(bool deleteable); void setUpdateable(bool updateable); void setShortcutName(QString newName); void setShortcutBinding(QString newBinding); protected: virtual void enterEvent(QEvent *); virtual void leaveEvent(QEvent *); virtual void mouseDoubleClickEvent(QMouseEvent * e); private: QWidget * pWidget; QLabel * pLabel; CustomLineEdit * pLineEdit; QPushButton * pButton; private: bool _deleteable; bool _updateable; Q_SIGNALS: void updateShortcutSignal(); }; #endif // DEFINESHORTCUTITEM_H ukui-control-center/plugins/devices/shortcut/shortcut.ui0000644000175000017500000001035314201663716022607 0ustar fengfeng Shortcut 0 0 847 664 550 0 960 16777215 Shortcut 0 0 32 0 0 System Shortcut 2 Qt::Vertical QSizePolicy::Fixed 20 24 0 0 Custom Shortcut 8 0 2 0 60 16777215 60 8 0 0 0 0 0 0 0 Qt::Vertical 17 231 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/shortcut/addshortcutdialog.cpp0000644000175000017500000003424214201663716024610 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "addshortcutdialog.h" #include "ui_addshortcutdialog.h" #include "CloseButton/closebutton.h" #include "realizeshortcutwheel.h" #define DEFAULTPATH "/usr/share/applications/" extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); addShortcutDialog::addShortcutDialog(QList generalEntries, QList customEntries, QWidget *parent) : QDialog(parent), ui(new Ui::addShortcutDialog), gsPath(""), systemEntry(generalEntries), customEntry(customEntries), keyIsAvailable(false) { ui->setupUi(this); editSeq = QKeySequence(""); editName = ""; keyIsAvailable = 0; execIsAvailable = false; nameIsAvailable = false; initSetup(); slotsSetup(); limitInput(); } addShortcutDialog::~addShortcutDialog() { delete ui; ui = nullptr; } void addShortcutDialog::initSetup() { setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); setWindowTitle(tr("Add custom shortcut")); ui->titleLabel->setStyleSheet("QLabel{color: palette(windowText);}"); ui->noteLabel->setPixmap(QPixmap("://img/plugins/shortcut/note.png")); ui->execLineEdit->setReadOnly(true); ui->noteLabel->setVisible(false); ui->label_4->setStyleSheet("color: red"); ui->label_4->setText(""); ui->certainBtn->setDisabled(true); shortcutLine = new ShortcutLine(systemEntry, customEntry); ui->horizontalLayout_2->addWidget(shortcutLine); shortcutLine->setFixedWidth(302); shortcutLine->setPlaceholderText(tr("Please enter a shortcut")); connect(shortcutLine, &ShortcutLine::shortCutAvailable, this, [=](const int &flag){ if (flag == 0 || (flag == -2 && editSeq == shortcutLine->keySequence())) { //快捷键正常 keyIsAvailable = 3; } else if(flag == -2) { //快捷键冲突 keyIsAvailable = 1; } else { //快捷键不可用 keyIsAvailable = 2; } refreshCertainChecked(3); }); } void addShortcutDialog::slotsSetup() { connect(ui->openBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) openProgramFileDialog(); }); connect(ui->execLineEdit, &QLineEdit::textChanged, [=](QString text){ if (text.endsWith("desktop") || (!g_file_test(text.toLatin1().data(), G_FILE_TEST_IS_DIR) && g_file_test(text.toLatin1().data(), G_FILE_TEST_IS_EXECUTABLE))) { execIsAvailable = true; } else { execIsAvailable = false; } refreshCertainChecked(1); }); connect(ui->nameLineEdit, &QLineEdit::textChanged, [=](){ QStringList customName; QString text = ui->nameLineEdit->text(); if (customEntry.isEmpty()) { nameIsAvailable = true; } else { for (KeyEntry *ckeyEntry : customEntry) { customName << ckeyEntry->nameStr; if (customName.contains(text) && text != editName) { nameIsAvailable = false; } else { nameIsAvailable = true; } } } refreshCertainChecked(2); }); connect(ui->cancelBtn, &QPushButton::clicked, [=] { close(); }); connect(ui->certainBtn, &QPushButton::clicked, [=] { emit shortcutInfoSignal(gsPath, ui->nameLineEdit->text(), selectedfile, shortcutLine->keySequence().toString()); close(); }); connect(this, &addShortcutDialog::finished, [=] { gsPath = ""; ui->nameLineEdit->clear(); ui->execLineEdit->clear(); ui->nameLineEdit->setFocus(Qt::ActiveWindowFocusReason); }); } void addShortcutDialog::setTitleText(QString text) { ui->titleLabel->setText(text); } void addShortcutDialog::setUpdateEnv(QString path, QString name, QString exec) { gsPath = path; ui->nameLineEdit->setText(name); ui->execLineEdit->setText(exec); } void addShortcutDialog::limitInput() { // 大小写字母数字中文 QRegExp rx("[a-zA-Z0-9\u4e00-\u9fa5]+"); QRegExpValidator *regValidator = new QRegExpValidator(rx); // 输入限制 ui->nameLineEdit->setValidator(regValidator); // 字符长度限制 // ui->nameLineEdit->setMaxLength(10); } QString addShortcutDialog::keyToLib(QString key) { if (key.contains("+")) { QStringList keys = key.split("+"); if (keys.count() == 2) { QString lower = keys.at(1); QString keyToLib = "<" + keys.at(0) + ">" + lower.toLower(); return keyToLib; } else if (keys.count() == 3) { QString lower = keys.at(2); QString keyToLib = "<" + keys.at(0) + ">" + "<" + keys.at(1) + ">" + lower.toLower(); return keyToLib; } } return key; } void addShortcutDialog::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QPainterPath rectPath; rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); // 画一个黑底 QPixmap pixmap(this->rect().size()); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); // 模糊这个黑底 QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); pixmapPainter2.setRenderHint(QPainter::Antialiasing); pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); pixmapPainter2.setPen(Qt::transparent); pixmapPainter2.setBrush(Qt::transparent); pixmapPainter2.drawPath(rectPath); // 绘制阴影 p.drawPixmap(this->rect(), pixmap, pixmap.rect()); // 绘制一个背景 p.save(); p.fillPath(rectPath, palette().color(QPalette::Base)); p.restore(); } void addShortcutDialog::openProgramFileDialog() { QString filters = tr("Desktop files(*.desktop)"); QFileDialog fd(this); fd.setDirectory(DEFAULTPATH); fd.setAcceptMode(QFileDialog::AcceptOpen); fd.setViewMode(QFileDialog::List); fd.setNameFilter(filters); fd.setFileMode(QFileDialog::ExistingFile); fd.setWindowTitle(tr("select desktop")); fd.setLabelText(QFileDialog::Reject, tr("Cancel")); if (fd.exec() != QDialog::Accepted) return; selectedfile = fd.selectedFiles().first(); QString exec = selectedfile.section("/", -1, -1); ui->execLineEdit->setText(exec); } void addShortcutDialog::refreshCertainChecked(int triggerFlag) { ui->label_4->setText(""); if (!execIsAvailable || keyIsAvailable != 3 || !nameIsAvailable) { ui->noteLabel->setVisible(true); ui->certainBtn->setDisabled(true); switch (triggerFlag) { case 1: if (!execIsAvailable) { ui->label_4->setText(tr("Invalid application")); //程序无效 } else if (keyIsAvailable == 1 && !shortcutLine->text().isEmpty()) { ui->label_4->setText(tr("Shortcut conflict")); //快捷键冲突 } else if (keyIsAvailable == 2 && !shortcutLine->text().isEmpty()) { ui->label_4->setText(tr("Invalid shortcut")); //快捷键无效 } else if (!nameIsAvailable && !ui->nameLineEdit->text().isEmpty()) { ui->label_4->setText(tr("Name repetition")); //名称重复 } else { ui->noteLabel->setVisible(false); } break; case 2: if (!nameIsAvailable) { ui->label_4->setText(tr("Name repetition")); //名称重复 } else if (keyIsAvailable == 1 && !shortcutLine->text().isEmpty()) { ui->label_4->setText(tr("Shortcut conflict")); //快捷键冲突 } else if (keyIsAvailable == 2 && !shortcutLine->text().isEmpty()) { ui->label_4->setText(tr("Invalid shortcut")); //快捷键无效 } else if (!execIsAvailable && !ui->execLineEdit->text().isEmpty()) { ui->label_4->setText(tr("Invalid application")); //程序无效 } else { ui->noteLabel->setVisible(false); } break; case 3: if (keyIsAvailable == 1) { ui->label_4->setText(tr("Shortcut conflict")); //快捷键冲突 } else if (keyIsAvailable == 2) { ui->label_4->setText(tr("Invalid shortcut")); //快捷键无效 } else if (!execIsAvailable && !ui->execLineEdit->text().isEmpty()) { ui->label_4->setText(tr("Invalid application")); //程序无效 } else if (!nameIsAvailable && !ui->nameLineEdit->text().isEmpty()) { ui->label_4->setText(tr("Name repetition")); //名称重复 } else { ui->noteLabel->setVisible(false); } break; default: ui->label_4->setText(tr("Unknown error")); //未知问题,不会触发 break; } } else { ui->noteLabel->setVisible(false); ui->certainBtn->setDisabled(false); } } bool addShortcutDialog::conflictWithGlobalShortcuts(const QKeySequence &keySequence) { QHash> clashing; for (int i = 0; i < keySequence.count(); ++i) { QKeySequence keys(keySequence[i]); if (!KGlobalAccel::isGlobalShortcutAvailable(keySequence)) { clashing.insert(keySequence, KGlobalAccel::getGlobalShortcutsByKey(keys)); } } if (clashing.isEmpty()) { return false; } else { qDebug() << "conflict With Global Shortcuts"; } return true; } bool addShortcutDialog::conflictWithStandardShortcuts(const QKeySequence &seq) { KStandardShortcut::StandardShortcut ssc = KStandardShortcut::find(seq); if (ssc != KStandardShortcut::AccelNone) { qDebug() << "conflict With Standard Shortcuts"; return true; } return false; } bool addShortcutDialog::conflictWithSystemShortcuts(const QKeySequence &seq) { QString systemKeyStr = keyToLib(seq.toString()); if (systemKeyStr.contains("Ctrl")) { systemKeyStr.replace("Ctrl", "Control"); } for (KeyEntry *ckeyEntry : systemEntry) { if (systemKeyStr == ckeyEntry->valueStr) { qDebug() << "conflictWithSystemShortcuts" << seq; return true; } } return false; } bool addShortcutDialog::conflictWithCustomShortcuts(const QKeySequence &seq) { QString customKeyStr = keyToLib(seq.toString()); for (KeyEntry *ckeyEntry : customEntry) { if (customKeyStr == ckeyEntry->bindingStr) { qDebug() << "conflictWithCustomShortcuts" << seq; return true; } } return false; } bool addShortcutDialog::isKeyAvailable(const QKeySequence &seq) { QString keyStr = seq.toString(); if (!keyStr.contains("+")) { qDebug() << "is not Available"; return false; } else if (keyStr.contains("Num") || keyStr.contains("Space") || keyStr.contains("Meta") || keyStr.contains("Ins") || keyStr.contains("Home") || keyStr.contains("PgUp") || keyStr.contains("Del") || keyStr.contains("End") || keyStr.contains("PgDown") || keyStr.contains("Print") || keyStr.contains("Backspace") || keyStr.contains("ScrollLock") || keyStr.contains("Return") || keyStr.contains("Enter") || keyStr.contains("Tab") || keyStr.contains("CapsLock") || keyStr.contains("Left") || keyStr.contains("Right") || keyStr.contains("Up") || keyStr.contains("Down") || keyStr.contains("Clear Grab")) { qDebug() << "is not Available"; return false; } else { QStringList keys = keyStr.split("+"); if (keys.count() == 4) { qDebug() << "is not Available"; return false; } else { QString key = keys.at(keys.count() - 1); if (!key.contains(QRegExp("[A-Z]")) && !key.contains(QRegExp("[a-z]")) && !key.contains(QRegExp("[0-9]"))) { qDebug() << "is not Available"; return false; } } } return true; } void addShortcutDialog::setExecText(const QString &text) { selectedfile = text; QString exec = selectedfile.section("/", -1, -1); ui->execLineEdit->setText(exec); } void addShortcutDialog::setNameText(const QString &text) { editName = text; ui->nameLineEdit->setText(text); } void addShortcutDialog::setKeyText(const QString &text) { QString showText = text; showText = showText.replace("<",""); showText = showText.replace(">"," + "); QString endStr = showText.mid(showText.length() - 1, 1); showText = showText.mid(0, showText.length() - 1) + endStr.toUpper(); shortcutLine->setText(showText); QKeySequence seq(showText.replace(" ", "")); //去掉空格 editSeq = seq; shortcutLine->setKeySequence(seq); } void addShortcutDialog::setKeyIsAvailable(const int key) { keyIsAvailable = key; } ukui-control-center/plugins/devices/shortcut/customlineedit.h0000644000175000017500000000303514201663671023575 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef CUSTOMLINEEDIT_H #define CUSTOMLINEEDIT_H #include #include //#include #include class CustomLineEdit : public QLineEdit { Q_OBJECT public: explicit CustomLineEdit(QString shortcut, QWidget *parent = 0); ~CustomLineEdit(); virtual void focusOutEvent(QFocusEvent * evt); virtual void focusInEvent(QFocusEvent * evt); virtual void keyReleaseEvent(QKeyEvent * evt); public: void setFlagStatus(bool checked); void updateOldShow(QString newStr); private: QString _oldshortcut; QString _wait; bool flag; Q_SIGNALS: void shortcutCodeSignals(QList); }; #endif // CUSTOMLINEEDIT_H ukui-control-center/plugins/devices/shortcut/addshortcutdialog.h0000644000175000017500000000551314201663716024254 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef ADDSHORTCUTDIALOG_H #define ADDSHORTCUTDIALOG_H #include #include #include #include #include #include #include #include "keyentry.h" #include "shortcutline.h" namespace Ui { class addShortcutDialog; } class addShortcutDialog : public QDialog { Q_OBJECT public: explicit addShortcutDialog(QList generalEntries, QList customEntries, QWidget *parent = nullptr); ~addShortcutDialog(); public: void initSetup(); void slotsSetup(); void setTitleText(QString text); void openProgramFileDialog(); void setUpdateEnv(QString path, QString name, QString exec); void refreshCertainChecked(int triggerFlag); //1:输入了程序,2:输入了名字, 3:输入了快捷键 void limitInput(); bool conflictWithStandardShortcuts(const QKeySequence &seq); bool conflictWithGlobalShortcuts(const QKeySequence &seq); bool conflictWithSystemShortcuts(const QKeySequence &seq); bool conflictWithCustomShortcuts(const QKeySequence &seq); bool isKeyAvailable(const QKeySequence &seq); QString keyToLib(QString key); void setExecText(const QString &text); void setNameText(const QString &text); void setKeyText(const QString &text); void setKeyIsAvailable(const int key); protected: void paintEvent(QPaintEvent *); private: Ui::addShortcutDialog *ui; private: QString gsPath; QString selectedfile; QList systemEntry; QList customEntry; ShortcutLine *shortcutLine = nullptr; QString editName; QKeySequence editSeq; int keyIsAvailable; //快捷键有冲突/不可用/正常三种情况,1:冲突,2:不可用,3:正常 bool nameIsAvailable; bool execIsAvailable; Q_SIGNALS: void shortcutInfoSignal(QString path, QString name, QString exec, QString key); }; #endif // ADDSHORTCUTDIALOG_H ukui-control-center/plugins/devices/shortcut/customlineedit.cpp0000644000175000017500000000754014201663671024135 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "customlineedit.h" #include CustomLineEdit::CustomLineEdit(QString shortcut, QWidget *parent) : QLineEdit(parent), _oldshortcut(shortcut) { _wait = tr("New Shortcut..."); flag = true; setFocusPolicy(Qt::ClickFocus); } CustomLineEdit::~CustomLineEdit() { } void CustomLineEdit::focusInEvent(QFocusEvent *evt){ this->setText(_wait); flag = true; } void CustomLineEdit::focusOutEvent(QFocusEvent *evt){ if (this->text() == _wait) this->setText(_oldshortcut); flag = false; } void CustomLineEdit::setFlagStatus(bool checked){ flag = checked; } void CustomLineEdit::keyReleaseEvent(QKeyEvent *evt){ QList tmpList; if (evt->key() == Qt::Key_Escape){ this->clearFocus(); } if (int(evt->modifiers()) == Qt::NoModifier && evt->key() != 0 && flag){ //判断当前text,屏蔽掉多余的keyRelease事件触发 tmpList.append(evt->key()); // qDebug() << evt->key() << evt->text(); } else if (evt->modifiers() == Qt::ControlModifier && evt->key() != 0 && flag){ tmpList.append(Qt::Key_Control); tmpList.append(evt->key()); // qDebug() << "Ctr + " << evt->key() << evt->text() << (int)Qt::ControlModifier << (int)Qt::Key_Control; } else if (evt->modifiers() == Qt::AltModifier && evt->key() != 0 && flag){ tmpList.append(Qt::Key_Alt); tmpList.append(evt->key()); // qDebug() << "Alt + " << evt->key() << evt->text(); } else if (evt->modifiers() == Qt::ShiftModifier && evt->key() != 0 && flag){ tmpList.append(Qt::Key_Shift); tmpList.append(evt->key()); // qDebug() << "Shift + " << evt->key() << evt->text(); } else if ((evt->modifiers() == (Qt::ControlModifier | Qt::AltModifier)) && evt->key() != 0 && flag){ tmpList.append(Qt::Key_Control); tmpList.append(Qt::Key_Alt); tmpList.append(evt->key()); // qDebug() << "Ctr + Alt" << evt->key() << evt->text(); } else if ((evt->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) && evt->key() != 0 && flag){ tmpList.append(Qt::Key_Control); tmpList.append(Qt::Key_Shift); tmpList.append(evt->key()); // qDebug() << "Ctr + shift" << evt->key() << evt->text(); } else if ((evt->modifiers() == (Qt::AltModifier | Qt::ShiftModifier)) && evt->key() != 0 && flag){ tmpList.append(Qt::Key_Alt); tmpList.append(Qt::Key_Shift); tmpList.append(evt->key()); // qDebug() << "Alt + shift" << evt->key() << evt->text(); } else if ((evt->modifiers() == (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier) && evt->key() != 0 && flag)){ tmpList.append(Qt::Key_Control); tmpList.append(Qt::Key_Alt); tmpList.append(Qt::Key_Shift); tmpList.append(evt->key()); } if (tmpList.length() > 0){ emit shortcutCodeSignals(tmpList); // this->clearFocus(); } } void CustomLineEdit::updateOldShow(QString newStr){ _oldshortcut = newStr; } ukui-control-center/plugins/devices/shortcut/shortcutline.h0000644000175000017500000000455514201663716023300 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SHORTCUTLINE_H #define SHORTCUTLINE_H #include #include #include #include #include #include "keyentry.h" class ShortcutLine : public QLineEdit { Q_OBJECT public: ShortcutLine(QList generalEntries, QList customEntries, QWidget *parent = nullptr); ~ShortcutLine(); protected: void keyPressEvent(QKeyEvent *event); //键盘按下事件 void keyReleaseEvent(QKeyEvent *event); //键盘松开事件 void focusInEvent(QFocusEvent *e); //焦点进入事件 void focusOutEvent(QFocusEvent *e); //焦点退出事件 private: QString firstKey, secondKey, thirdKey; bool shortCutObtainedFlag; QList systemEntry; QList customEntry; QKeySequence seq; public: void initInputKeyAndText(const bool &clearText); bool lastKeyIsAvailable(const int &key, const int &keyCode); bool conflictWithGlobalShortcuts(const QKeySequence &keySequence); bool conflictWithStandardShortcuts(const QKeySequence &seq); bool conflictWithSystemShortcuts(const QKeySequence &seq); bool conflictWithCustomShortcuts(const QKeySequence &seq); QString keyToLib(QString key); void shortCutObtained(const bool &flag, const int &keyNum = 0); //true:success but may be conflicted, false: invalid QString keyToString(int keyValue); QKeySequence keySequence(); void setKeySequence(QKeySequence setSeq); Q_SIGNALS: void shortCutAvailable(const int &flag); //0:success, -1:shortcut invalid, -2:shortcut conflict }; #endif // SHORTCUTLINE_H ukui-control-center/plugins/devices/shortcut/keymap.h0000644000175000017500000000756114201663671022043 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef KEYMAP_H #define KEYMAP_H #include #include class KeyMap : public QObject { Q_OBJECT public: explicit KeyMap(); ~KeyMap(); QString keycodeTokeystring(int code); public: QMetaEnum metaColor; enum CCKey{ Escape = 0x01000000, // misc keys Tab = 0x01000001, Backtab = 0x01000002, Backspace = 0x01000003, Return = 0x01000004, Enter = 0x01000005, Insert = 0x01000006, Delete = 0x01000007, Pause = 0x01000008, Print = 0x01000009, // print screen SysReq = 0x0100000a, Clear = 0x0100000b, Home = 0x01000010, // cursor movement End = 0x01000011, Left = 0x01000012, Up = 0x01000013, Right = 0x01000014, Down = 0x01000015, PageUp = 0x01000016, PageDown = 0x01000017, Shift = 0x01000020, // modifiers Control = 0x01000021, Meta = 0x01000022, Alt = 0x01000023, CapsLock = 0x01000024, NumLock = 0x01000025, ScrollLock = 0x01000026, F1 = 0x01000030, // function keys F2 = 0x01000031, F3 = 0x01000032, F4 = 0x01000033, F5 = 0x01000034, F6 = 0x01000035, F7 = 0x01000036, F8 = 0x01000037, F9 = 0x01000038, F10 = 0x01000039, F11 = 0x0100003a, F12 = 0x0100003b, Super_L = 0x01000053, // extra keys Super_R = 0x01000054, Menu = 0x01000055, Hyper_L = 0x01000056, Hyper_R = 0x01000057, Help = 0x01000058, Direction_L = 0x01000059, Direction_R = 0x01000060, Space = 0x20, // 7 bit printable ASCII Any = Space, Exclam = 0x21, QuoteDbl = 0x22, NumberSign = 0x23, Dollar = 0x24, Percent = 0x25, Ampersand = 0x26, Apostrophe = 0x27, ParenLeft = 0x28, ParenRight = 0x29, Asterisk = 0x2a, Plus = 0x2b, Comma = 0x2c, Minus = 0x2d, Period = 0x2e, Slash = 0x2f, K_0 = 0x30, K_1 = 0x31, K_2 = 0x32, K_3 = 0x33, K_4 = 0x34, K_5 = 0x35, K_6 = 0x36, K_7 = 0x37, K_8 = 0x38, K_9 = 0x39, Colon = 0x3a, Semicolon = 0x3b, Less = 0x3c, Equal = 0x3d, Greater = 0x3e, Question = 0x3f, At = 0x40, A = 0x41, B = 0x42, C = 0x43, D = 0x44, E = 0x45, F = 0x46, G = 0x47, H = 0x48, I = 0x49, J = 0x4a, K = 0x4b, L = 0x4c, M = 0x4d, N = 0x4e, O = 0x4f, P = 0x50, Q = 0x51, R = 0x52, S = 0x53, T = 0x54, U = 0x55, V = 0x56, W = 0x57, X = 0x58, Y = 0x59, Z = 0x5a, }; Q_ENUM(CCKey) }; #endif // KEYMAP_H ukui-control-center/plugins/devices/shortcut/shortcutline.cpp0000644000175000017500000003000414201663716023617 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include "shortcutline.h" #define SNULL "NULL" #define SCTRL "Ctrl" #define SALT "Alt" #define SSHIFT "Shift" int allowKey[] = { // 0-9 -/+ A-Z ,/. Qt::Key_0, Qt::Key_1, Qt::Key_2, Qt::Key_3, Qt::Key_4, Qt::Key_5, Qt::Key_6, Qt::Key_7, Qt::Key_8, Qt::Key_9, Qt::Key_Minus, Qt::Key_Equal, Qt::Key_A, Qt::Key_B, Qt::Key_C, Qt::Key_D, Qt::Key_E, Qt::Key_F, Qt::Key_G, Qt::Key_H, Qt::Key_I, Qt::Key_J, Qt::Key_K, Qt::Key_L, Qt::Key_M, Qt::Key_N, Qt::Key_O, Qt::Key_P, Qt::Key_Q, Qt::Key_R, Qt::Key_S, Qt::Key_T, Qt::Key_U, Qt::Key_V, Qt::Key_W, Qt::Key_X, Qt::Key_Y, Qt::Key_Z, Qt::Key_Comma, Qt::Key_Period }; int numKey[] = { Qt::Key_0, Qt::Key_1, Qt::Key_2, Qt::Key_3, Qt::Key_4, Qt::Key_5, Qt::Key_6, Qt::Key_7, Qt::Key_8, Qt::Key_9, Qt::Key_Minus, Qt::Key_Equal, Qt::Key_Period }; ShortcutLine::ShortcutLine(QList generalEntries, QList customEntries, QWidget *parent) : QLineEdit(parent), systemEntry(generalEntries), customEntry(customEntries) { // this->setReadOnly(true); initInputKeyAndText(true); } ShortcutLine::~ShortcutLine() { } void ShortcutLine::initInputKeyAndText(const bool &clearText) { firstKey = SNULL; secondKey = SNULL; thirdKey = SNULL; if (true == clearText) { this->setText(""); shortCutObtainedFlag = false; } } void ShortcutLine::keyPressEvent(QKeyEvent *e) { if (e->isAutoRepeat()) { //一直按着导致触发的事件,不再处理 return; } int keyValue = e->key(); int keyCode = e->nativeVirtualKey(); // qDebug()<<"0x"<setText(firstKey + QString(" + ")); } else { //第一个键不是三个辅助键中的其中一个 this->setText(firstKey); //显示一下,增强用户交互性 qApp->processEvents(); usleep(200000); shortCutObtained(false); //快捷键获取失败 return; } } else if(secondKey == SNULL){ /*第二个键是辅助键中的另外一个*/ if ((keyValue == Qt::Key_Control || keyValue == Qt::Key_Alt || keyValue == Qt::Key_Shift) && keyToString(keyValue) != firstKey) { secondKey = keyToString(keyValue); this->setText(firstKey + QString(" + ") + secondKey + QString(" + ")); } else { //第二个键是主键(最后一个键) if (lastKeyIsAvailable(keyValue, keyCode)) { // 合法 secondKey = keyToString(keyValue); shortCutObtained(true, 2); } else { //非法 shortCutObtained(false); return; } } } else if(thirdKey == SNULL) { //第三个键只能是主键 if (lastKeyIsAvailable(keyValue, keyCode)) { // 合法 thirdKey = keyToString(keyValue); shortCutObtained(true, 3); } else { //非法 shortCutObtained(false); } } } void ShortcutLine::keyReleaseEvent(QKeyEvent *e) { if (e->isAutoRepeat()) { //一直按着导致触发的事件 return; } if (true == shortCutObtainedFlag) { //快捷键输入完毕 initInputKeyAndText(false); } else { //快捷键输入放弃 initInputKeyAndText(true); } } void ShortcutLine::focusInEvent(QFocusEvent *e) { this->grabKeyboard(); QLineEdit::focusInEvent(e); initInputKeyAndText(false); } void ShortcutLine::focusOutEvent(QFocusEvent *e) { this->releaseKeyboard(); QLineEdit::focusOutEvent(e); } void ShortcutLine::shortCutObtained(const bool &flag, const int &keyNum) { if (true == flag && (2 == keyNum || 3 == keyNum)) { shortCutObtainedFlag = true; if (2 == keyNum) { seq = QKeySequence(firstKey + QString("+") + secondKey); this->setText(firstKey + QString(" + ") + secondKey); } else { seq = QKeySequence(firstKey + QString("+") + secondKey + QString("+") + thirdKey); this->setText(firstKey + QString(" + ") + secondKey + QString(" + ") + thirdKey); } if (conflictWithGlobalShortcuts(seq) || conflictWithStandardShortcuts(seq) || conflictWithSystemShortcuts(seq) || conflictWithCustomShortcuts(seq)) { //快捷键冲突 Q_EMIT shortCutAvailable(-2); } else { Q_EMIT shortCutAvailable(0); } } else { //快捷键无效 shortCutObtainedFlag = false; initInputKeyAndText(true); Q_EMIT shortCutAvailable(-1); } } bool ShortcutLine::lastKeyIsAvailable(const int &keyValue, const int &keyCode) { for (int i = 0; i < sizeof(numKey) / sizeof(int); ++i) { if (keyValue == numKey[i] && keyValue != keyCode) { //数字键盘上的 return false; } } for (u_int i = 0; i < sizeof(allowKey) / sizeof(int); ++i) { if (keyValue == allowKey[i]) { return true; } } return false; } QKeySequence ShortcutLine::keySequence() { return this->seq; } bool ShortcutLine::conflictWithGlobalShortcuts(const QKeySequence &keySequence) { QHash > clashing; for (int i = 0; i < keySequence.count(); ++i) { QKeySequence keys(keySequence[i]); if (!KGlobalAccel::isGlobalShortcutAvailable(keySequence)) { clashing.insert(keySequence, KGlobalAccel::getGlobalShortcutsByKey(keys)); } } if (clashing.isEmpty()) { return false; } else { qDebug() << "conflict With Global Shortcuts"; } return true; } bool ShortcutLine::conflictWithStandardShortcuts(const QKeySequence &seq) { KStandardShortcut::StandardShortcut ssc = KStandardShortcut::find(seq); if (ssc != KStandardShortcut::AccelNone) { qDebug() << "conflict With Standard Shortcuts"; return true; } return false; } bool ShortcutLine::conflictWithSystemShortcuts(const QKeySequence &seq) { QString systemKeyStr = keyToLib(seq.toString()); if (systemKeyStr.contains("Ctrl")) { systemKeyStr.replace("Ctrl", "Control"); } for (KeyEntry *ckeyEntry : systemEntry) { if (systemKeyStr == ckeyEntry->valueStr) { qDebug() << "conflictWithSystemShortcuts" << seq; return true; } } return false; } bool ShortcutLine::conflictWithCustomShortcuts(const QKeySequence &seq) { QString customKeyStr = keyToLib(seq.toString()); for (KeyEntry *ckeyEntry : customEntry) { if (customKeyStr == ckeyEntry->bindingStr) { qDebug() << "conflictWithCustomShortcuts" << seq; return true; } } return false; } QString ShortcutLine::keyToLib(QString key) { if (key.contains("+")) { QStringList keys = key.split("+"); if (keys.count() == 2) { QString lower = keys.at(1); QString keyToLib = "<" + keys.at(0) + ">" + lower.toLower(); return keyToLib; } else if (keys.count() == 3) { QString lower = keys.at(2); QString keyToLib = "<" + keys.at(0) + ">" + "<" + keys.at(1) + ">" + lower.toLower(); return keyToLib; } } return key; } void ShortcutLine::setKeySequence(QKeySequence setSeq){ this->seq = setSeq; } QString ShortcutLine::keyToString(int keyValue) { QString keyValue_QT_KEY;//表示意义 //键盘上大部分键值对应的都是其表示的ASCII码值 keyValue_QT_KEY = QString(keyValue); //对于特殊意义的键值[无法用ASCII码展示] switch (keyValue) { case Qt::Key_Escape: keyValue_QT_KEY = QString("Esc"); break; case Qt::Key_Tab: keyValue_QT_KEY = QString("Tab"); break; case Qt::Key_CapsLock: keyValue_QT_KEY = QString("CapsLock"); break; case Qt::Key_Shift: keyValue_QT_KEY = QString(SSHIFT); break; case Qt::Key_Control: keyValue_QT_KEY = QString(SCTRL); break; case Qt::Key_Alt: keyValue_QT_KEY = QString(SALT); break; case Qt::Key_Backspace: keyValue_QT_KEY = QString("Backspace"); break; case Qt::Key_Meta: keyValue_QT_KEY = QString("Win"); break; case Qt::Key_Return: keyValue_QT_KEY = QString("Enter(main)"); break; case Qt::Key_Enter: keyValue_QT_KEY = QString("Enter(num)"); break; case Qt::Key_Home: keyValue_QT_KEY = QString("Home"); break; case Qt::Key_End: keyValue_QT_KEY = QString("End"); break; case Qt::Key_PageUp: keyValue_QT_KEY = QString("PageUp"); break; case Qt::Key_PageDown: keyValue_QT_KEY = QString("PageDown"); break; case Qt::Key_Insert: keyValue_QT_KEY = QString("Insert"); break; case Qt::Key_Up: keyValue_QT_KEY = QString::fromLocal8Bit("↑"); break; case Qt::Key_Right: keyValue_QT_KEY = QString::fromLocal8Bit("→"); break; case Qt::Key_Left: keyValue_QT_KEY = QString::fromLocal8Bit("←"); break; case Qt::Key_Down: keyValue_QT_KEY = QString::fromLocal8Bit("↓"); break; case Qt::Key_Delete: keyValue_QT_KEY = QString("Del"); break; case Qt::Key_Space: keyValue_QT_KEY = QString("Space"); break; case Qt::Key_F1: keyValue_QT_KEY = QString("F1"); break; case Qt::Key_F2: keyValue_QT_KEY = QString("F2"); break; case Qt::Key_F3: keyValue_QT_KEY = QString("F3"); break; case Qt::Key_F4: keyValue_QT_KEY = QString("F4"); break; case Qt::Key_F5: keyValue_QT_KEY = QString("F5"); break; case Qt::Key_F6: keyValue_QT_KEY = QString("F6"); break; case Qt::Key_F7: keyValue_QT_KEY = QString("F7"); break; case Qt::Key_F8: keyValue_QT_KEY = QString("F8"); break; case Qt::Key_F9: keyValue_QT_KEY = QString("F9"); break; case Qt::Key_F10: keyValue_QT_KEY = QString("F10"); break; case Qt::Key_F11: keyValue_QT_KEY = QString("F11"); break; case Qt::Key_F12: keyValue_QT_KEY = QString("F12"); break; case Qt::Key_NumLock: keyValue_QT_KEY = QString("NumLock"); break; case Qt::Key_ScrollLock: keyValue_QT_KEY = QString("ScrollLock"); break; case Qt::Key_Pause: keyValue_QT_KEY = QString("Pause"); break; } return keyValue_QT_KEY; } ukui-control-center/plugins/devices/shortcut/realizeshortcutwheel.cpp0000644000175000017500000000406614201663671025361 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "realizeshortcutwheel.h" QList listExistsCustomShortcutPath(){ char ** childs; int len; DConfClient * client = dconf_client_new(); childs = dconf_client_list (client, KEYBINDINGS_CUSTOM_DIR, &len); g_object_unref (client); QList vals; for (int i = 0; childs[i] != NULL; i++){ if (dconf_is_rel_dir (childs[i], NULL)){ char * val = g_strdup (childs[i]); vals.append(val); } } g_strfreev (childs); return vals; } QString findFreePath(){ int i = 0; char * dir; bool found; QList existsdirs; existsdirs = listExistsCustomShortcutPath(); for (; i < MAX_CUSTOM_SHORTCUTS; i++){ found = true; dir = QString("custom%1/").arg(i).toLatin1().data(); for (int j = 0; j < existsdirs.count(); j++) if (!g_strcmp0(dir, existsdirs.at(j))){ found = false; break; } if (found) break; } if (i == MAX_CUSTOM_SHORTCUTS){ // qDebug() << "Keyboard Shortcuts" << "Too many custom shortcuts"; return ""; } return QString("%1%2").arg(KEYBINDINGS_CUSTOM_DIR).arg(QString(dir)); } ukui-control-center/plugins/devices/shortcut/keyentry.h0000644000175000017500000000212714201663716022420 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef KEYENTRY_H #define KEYENTRY_H #include typedef struct _KeyEntry KeyEntry; struct _KeyEntry { QString gsSchema; QString keyStr; QString valueStr; QString descStr; QString gsPath; QString nameStr; QString bindingStr; QString actionStr; }; Q_DECLARE_METATYPE(KeyEntry *) #endif // KEYENTRY_H ukui-control-center/plugins/devices/shortcut/shortcut.h0000644000175000017500000000546514201663716022431 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef SHORTCUT_H #define SHORTCUT_H #include #include #include #include #include #include #include #include "shell/interface.h" #include "keymap.h" #include "addshortcutdialog.h" #include "getshortcutworker.h" #include "HoverWidget/hoverwidget.h" #include "ImageUtil/imageutil.h" QT_BEGIN_NAMESPACE namespace Ui { class Shortcut; } QT_END_NAMESPACE class Shortcut : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Shortcut(); ~Shortcut(); public: QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void setupComponent(); void setupConnect(); void initFunctionStatus(); void appendGeneralItems(QMap > shortcutsMap); void appendCustomItems(); void buildCustomItem(KeyEntry *nkeyEntry); QWidget *buildGeneralWidget(QString schema, QMap subShortcutsMap); void createNewShortcut(QString path, QString name, QString exec, QString key, bool buildFlag = true); void deleteCustomShortcut(QString path); bool keyIsForbidden(QString key); void connectToServer(); QMap MergerOfTheSamekind(QMap desktopMap); QString keyToUI(QString key); QString keyToLib(QString key); private: Ui::Shortcut *ui; QString pluginName; int pluginType; QWidget *pluginWidget; HoverWidget *addWgt; private: QThread *pThread; GetShortcutWorker *pWorker; KeyMap *pKeyMap; QDBusInterface *cloudInterface; bool isCloudService; bool mFirstLoad; private slots: void shortcutChangedSlot(); Q_SIGNALS: void hideDelBtn(); }; #endif // SHORTCUT_H ukui-control-center/plugins/devices/shortcut/defineshortcutitem.cpp0000644000175000017500000000675314201663671025017 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "defineshortcutitem.h" #include #include #include #include #include "customlineedit.h" DefineShortcutItem::DefineShortcutItem(QString name, QString binding) { _deleteable = false; _updateable = false; QHBoxLayout * baseHorLayout = new QHBoxLayout(this); baseHorLayout->setSpacing(16); baseHorLayout->setMargin(0); pWidget = new QWidget(this); QHBoxLayout * mainHorLayout = new QHBoxLayout(pWidget); mainHorLayout->setSpacing(0); mainHorLayout->setContentsMargins(16, 0, 24, 0); pWidget->setLayout(mainHorLayout); pLabel = new QLabel(pWidget); pLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); pLabel->setText(name); pLineEdit = new CustomLineEdit(binding, pWidget); // pLineEdit->setStyleSheet("QLineEdit{border: none;}"); pLineEdit->setAlignment(Qt::AlignRight); pLineEdit->setText(binding); pLineEdit->setReadOnly(true); pLineEdit->setFixedWidth(200); pButton = new QPushButton(this); pButton->setText(tr("Delete")); pButton->setFixedWidth(64); pButton->hide(); QSizePolicy btnSizePolicy = pButton->sizePolicy(); btnSizePolicy.setVerticalPolicy(QSizePolicy::Expanding); pButton->setSizePolicy(btnSizePolicy); mainHorLayout->addWidget(pLabel); mainHorLayout->addStretch(); mainHorLayout->addWidget(pLineEdit); baseHorLayout->addWidget(pWidget); baseHorLayout->addWidget(pButton); setLayout(baseHorLayout); } DefineShortcutItem::~DefineShortcutItem() { } QWidget * DefineShortcutItem::widgetComponent(){ return pWidget; } QLabel * DefineShortcutItem::labelComponent(){ return pLabel; } CustomLineEdit * DefineShortcutItem::lineeditComponent(){ return pLineEdit; } QPushButton * DefineShortcutItem::btnComponent(){ return pButton; } void DefineShortcutItem::setDeleteable(bool deleteable){ _deleteable = deleteable; } void DefineShortcutItem::setUpdateable(bool updateable){ _updateable = updateable; } void DefineShortcutItem::setShortcutName(QString newName){ pLabel->setText(newName); } void DefineShortcutItem::setShortcutBinding(QString newBinding){ pLineEdit->setText(newBinding); pLineEdit->updateOldShow(newBinding); } void DefineShortcutItem::enterEvent(QEvent *) { if (_deleteable){ pButton->show(); } } void DefineShortcutItem::leaveEvent(QEvent *) { if (_deleteable){ pButton->hide(); } } void DefineShortcutItem::mouseDoubleClickEvent(QMouseEvent *e){ if (e->button() == Qt::LeftButton && _updateable){ //emit updateShortcutSignal(); } QWidget::mouseDoubleClickEvent(e); } ukui-control-center/plugins/devices/shortcut/shortcut.pro0000644000175000017500000000255114201663716022773 0ustar fengfenginclude(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/closebutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets dbus KXmlGui KGlobalAccel greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(shortcut) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ /usr/include/dconf LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -ldconf CONFIG += link_pkgconfig c++11 PKGCONFIG += gio-2.0 \ gio-unix-2.0 \ gsettings-qt \ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ addshortcutdialog.cpp \ customlineedit.cpp \ defineshortcutitem.cpp \ getshortcutworker.cpp \ keymap.cpp \ realizeshortcutwheel.cpp \ shortcut.cpp \ shortcutline.cpp HEADERS += \ addshortcutdialog.h \ customlineedit.h \ defineshortcutitem.h \ getshortcutworker.h \ keyentry.h \ keymap.h \ realizeshortcutwheel.h \ shortcut.h \ shortcutline.h FORMS += \ addshortcutdialog.ui \ shortcut.ui INSTALLS += target ukui-control-center/plugins/devices/shortcut/realizeshortcutwheel.h0000644000175000017500000000345414201663716025026 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef REALIZESHORTCUTWHEEL_H #define REALIZESHORTCUTWHEEL_H #include #include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif extern "C" { #include #include #include #include } #define KEYBINDINGS_DESKTOP_SCHEMA "org.ukui.SettingsDaemon.plugins.media-keys" #define KEYBINDINGS_SYSTEM_SCHEMA "org.gnome.desktop.wm.keybindings" #define KEYBINDINGS_CUSTOM_SCHEMA "org.ukui.control-center.keybinding" #define KEYBINDINGS_CUSTOM_DIR "/org/ukui/desktop/keybindings/" #define MAX_SHORTCUTS 1000 #define ACTION_KEY "action" #define BINDING_KEY "binding" #define NAME_KEY "name" #define DEFAULT_BINDING "disable" #define MAX_CUSTOM_SHORTCUTS 1000 QList listExistsCustomShortcutPath(); QString findFreePath(); #endif // REALIZESHORTCUTWHEEL_H ukui-control-center/plugins/devices/shortcut/getshortcutworker.h0000644000175000017500000000252314201663671024353 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef GETSHORTCUTWORKER_H #define GETSHORTCUTWORKER_H #include #include class GetShortcutWorker : public QObject { Q_OBJECT public: explicit GetShortcutWorker(); ~GetShortcutWorker(); public: void run(); Q_SIGNALS: void generalShortcutGenerate(QString schema, QString key, QString value); void customShortcutGenerate(QString path, QString name, QString bindingkey, QString action); void workerComplete(); }; #endif // GETSHORTCUTWORKER_H ukui-control-center/plugins/devices/shortcut/addshortcutdialog.ui0000644000175000017500000003071714201663716024446 0ustar fengfeng addShortcutDialog 0 0 470 326 470 326 470 326 Dialog 0 32 32 32 32 24 0 0 Qt::Horizontal 40 20 0 9 16 0 0 Exec Qt::Horizontal 40 20 207 36 207 36 80 36 80 36 Qt::NoFocus Open 0 0 0 Name Qt::Horizontal 40 20 302 36 302 36 Key Qt::Horizontal 40 20 0 36 16777215 36 0 0 0 0 0 16 16 Qt::Horizontal 40 20 302 0 302 16777215 QFrame::NoFrame QFrame::Raised 0 16 0 0 0 0 4 24 24 24 24 TextLabel TextLabel Qt::Vertical 20 40 8 Qt::Horizontal 40 20 120 36 120 36 Qt::NoFocus Cancel 120 36 120 36 Save true TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/shortcut/getshortcutworker.cpp0000644000175000017500000001013014201663671024677 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "getshortcutworker.h" #include #include "realizeshortcutwheel.h" GetShortcutWorker::GetShortcutWorker() { } GetShortcutWorker::~GetShortcutWorker() { } void GetShortcutWorker::run() { // list system shortcut QByteArray id(KEYBINDINGS_SYSTEM_SCHEMA); GSettings *systemgsettings; if (QGSettings::isSchemaInstalled(id)) { systemgsettings = g_settings_new(KEYBINDINGS_SYSTEM_SCHEMA); } else { return; } char **skeys = g_settings_list_keys(systemgsettings); for (int i = 0; skeys[i] != NULL; i++) { // 切换为mutter后,原先为string的变为字符串数组,这块只取了字符串数组的第一个元素 GVariant *variant = g_settings_get_value(systemgsettings, skeys[i]); gsize size = g_variant_get_size(variant); char **tmp = const_cast(g_variant_get_strv(variant, &size)); char *str = tmp[0]; // 保存系统快捷键 QString key = QString(skeys[i]); QString value = QString(str); if (value != "") { generalShortcutGenerate(KEYBINDINGS_SYSTEM_SCHEMA, key, value); } } g_strfreev(skeys); g_object_unref(systemgsettings); // list desktop shortcut GSettings *desktopsettings = NULL; if (QGSettings::isSchemaInstalled(KEYBINDINGS_DESKTOP_SCHEMA)) { desktopsettings = g_settings_new(KEYBINDINGS_DESKTOP_SCHEMA); char **dkeys = g_settings_list_keys(desktopsettings); for (int i = 0; dkeys[i] != NULL; i++) { // 跳过非快捷键 if (!g_strcmp0(dkeys[i], "active") || !g_strcmp0(dkeys[i], "volume-step") || !g_strcmp0(dkeys[i], "priority") || !g_strcmp0(dkeys[i], "enable-osd")) continue; GVariant *variant = g_settings_get_value(desktopsettings, dkeys[i]); gsize size = g_variant_get_size(variant); char *str = const_cast(g_variant_get_string(variant, &size)); // 保存桌面快捷键 QString key = QString(dkeys[i]); QString value = QString(str); if (value.contains("KP_Delete")) { value = "Del"; generalShortcutGenerate(KEYBINDINGS_DESKTOP_SCHEMA, key, value); } if (value != "" && !value.contains("XF86") && !value.contains("KP_")) { generalShortcutGenerate(KEYBINDINGS_DESKTOP_SCHEMA, key, value); } } g_strfreev(dkeys); g_object_unref(desktopsettings); } // list custdom shortcut QList existsPath = listExistsCustomShortcutPath(); for (char *path : existsPath) { QString strFullPath = QString(KEYBINDINGS_CUSTOM_DIR); strFullPath.append(path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray bba(strFullPath.toLatin1().data()); QGSettings *settings = new QGSettings(ba, bba, this); QString pathStr = strFullPath; QString actionStr = settings->get(ACTION_KEY).toString(); QString bindingStr = settings->get(BINDING_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); customShortcutGenerate(pathStr, nameStr, bindingStr, actionStr); } emit workerComplete(); } ukui-control-center/plugins/devices/shortcut/shortcut.cpp0000644000175000017500000005204214201663716022755 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "shortcut.h" #include "ui_shortcut.h" #include #include #include "customlineedit.h" #include "realizeshortcutwheel.h" #include "defineshortcutitem.h" #include "Label/fixlabel.h" /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif #include #include #define ITEMHEIGH 36 #define TITLEWIDGETHEIGH 40 #define SYSTEMTITLEWIDGETHEIGH 50 #define UKUI_STYLE_SCHEMA "org.ukui.style" #define SYSTEM_FONT_EKY "system-font-size" // 快捷键屏蔽键 QStringList forbiddenKeys = { // Navigation keys "Home", "Left", "Up", "Right", "Down", "Page_Up", "Page_Down", "End", "Tab", // Return "Return", "Enter", "Space", }; QList generalEntries; QList customEntries; Shortcut::Shortcut() : mFirstLoad(true) { pluginName = tr("Shortcut"); pluginType = DEVICES; } Shortcut::~Shortcut() { if (!mFirstLoad) { delete ui; ui = nullptr; delete pKeyMap; pKeyMap = nullptr; } } QString Shortcut::get_plugin_name() { return pluginName; } int Shortcut::get_plugin_type() { return pluginType; } QWidget *Shortcut::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; ui = new Ui::Shortcut; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); pKeyMap = new KeyMap; isCloudService = false; setupComponent(); setupConnect(); initFunctionStatus(); connectToServer(); } return pluginWidget; } void Shortcut::plugin_delay_control() { } const QString Shortcut::name() const { return QStringLiteral("shortcut"); } void Shortcut::connectToServer() { cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", "/org/kylinssoclient/path", "org.freedesktop.kylinssoclient.interface", QDBusConnection::sessionBus()); if (!cloudInterface->isValid()) { qDebug() << "fail to connect to service"; qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); return; } QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), QString( "org.freedesktop.kylinssoclient.interface"), "shortcutChanged", this, SLOT(shortcutChangedSlot())); // 将以后所有DBus调用的超时设置为 milliseconds cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 } void Shortcut::setupComponent() { //~ contents_path /shortcut/System Shortcut ui->systemLabel->setText(tr("System Shortcut")); //~ contents_path /shortcut/Customize Shortcut ui->customLabel->setText(tr("Customize Shortcut")); QWidget *systemTitleWidget = new QWidget; QVBoxLayout *systemVerLayout = new QVBoxLayout(systemTitleWidget); systemTitleWidget->setFixedHeight(SYSTEMTITLEWIDGETHEIGH); systemTitleWidget->setStyleSheet("QWidget{background: palette(window);" "border: none; border-radius: 4px}"); systemVerLayout->setSpacing(0); systemVerLayout->setContentsMargins(16, 15, 19, 0); QLabel *titleLabel = new QLabel(systemTitleWidget); titleLabel->setText(tr("System Shortcut")); systemVerLayout->addWidget(titleLabel); systemVerLayout->addStretch(); systemTitleWidget->setLayout(systemVerLayout); addWgt = new HoverWidget(""); addWgt->setObjectName("addwgt"); addWgt->setMinimumSize(QSize(580, 50)); addWgt->setMaximumSize(QSize(960, 50)); QPalette pal; QBrush brush = pal.highlight(); //获取window的色值 QColor highLightColor = brush.color(); QString stringColor = QString("rgba(%1,%2,%3)") //叠加20%白色 .arg(highLightColor.red()*0.8 + 255*0.2) .arg(highLightColor.green()*0.8 + 255*0.2) .arg(highLightColor.blue()*0.8 + 255*0.2); addWgt->setStyleSheet(QString("HoverWidget#addwgt{background: palette(button); \ border-radius: 4px;}\ HoverWidget:hover:!pressed#addwgt{background: %1; \ border-radius: 4px;}").arg(stringColor)); QHBoxLayout *addLyt = new QHBoxLayout; QLabel *iconLabel = new QLabel(); //~ contents_path /shortcut/Add custom shortcut QLabel *textLabel = new QLabel(tr("Add custom shortcut")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); iconLabel->setProperty("useIconHighlightEffect", true); iconLabel->setProperty("iconHighlightEffectMode", 1); addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); // 悬浮改变Widget状态 connect(addWgt, &HoverWidget::enterWidget, this, [=](){ iconLabel->setProperty("useIconHighlightEffect", false); iconLabel->setProperty("iconHighlightEffectMode", 0); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: white;"); }); // 还原状态 connect(addWgt, &HoverWidget::leaveWidget, this, [=](){ iconLabel->setProperty("useIconHighlightEffect", true); iconLabel->setProperty("iconHighlightEffectMode", 1); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: palette(windowText);"); }); ui->addLyt->addWidget(addWgt); } void Shortcut::setupConnect() { connect(addWgt, &HoverWidget::widgetClicked, this, [=](){ addShortcutDialog *addDialog = new addShortcutDialog(generalEntries, customEntries, pluginWidget); addDialog->setTitleText(QObject::tr("Customize Shortcut")); connect(addDialog, &addShortcutDialog::shortcutInfoSignal, [=](QString path, QString name, QString exec, QString key){ createNewShortcut(path, name, exec, key); }); addDialog->exec(); }); } void Shortcut::initFunctionStatus() { generalEntries.clear(); customEntries.clear(); // 使用线程获取快捷键 pThread = new QThread; pWorker = new GetShortcutWorker; if (isCloudService == false) { connect(pWorker, &GetShortcutWorker::generalShortcutGenerate, this, [=](QString schema, QString key, QString value){ // qDebug() << "general shortcut" << schema << key << value; KeyEntry *generalKeyEntry = new KeyEntry; generalKeyEntry->gsSchema = schema; generalKeyEntry->keyStr = key; generalKeyEntry->valueStr = value; generalEntries.append(generalKeyEntry); }); } connect(pWorker, &GetShortcutWorker::customShortcutGenerate, this, [=](QString path, QString name, QString binding, QString action){ // qDebug() << "custom shortcut" << path << name << binding; KeyEntry *customKeyEntry = new KeyEntry; customKeyEntry->gsSchema = KEYBINDINGS_CUSTOM_SCHEMA; customKeyEntry->gsPath = path; customKeyEntry->nameStr = name; customKeyEntry->bindingStr = binding; customKeyEntry->actionStr = action; customEntries.append(customKeyEntry); }); connect(pWorker, &GetShortcutWorker::workerComplete, this, [=] { pThread->quit(); // 退出事件循环 pThread->wait(); // 释放资源 }); pWorker->moveToThread(pThread); connect(pThread, &QThread::started, pWorker, &GetShortcutWorker::run); connect(pThread, &QThread::finished, this, [=] { QMap systemMap; QMap desktopMap; // 最新快捷键数据 for (int i = 0; i < generalEntries.count(); i++) { if (generalEntries[i]->gsSchema == KEYBINDINGS_DESKTOP_SCHEMA) { desktopMap.insert(generalEntries[i]->keyStr, generalEntries[i]->valueStr); } else if (generalEntries[i]->gsSchema == KEYBINDINGS_SYSTEM_SCHEMA) { systemMap.insert(generalEntries[i]->keyStr, generalEntries[i]->valueStr); } } desktopMap = MergerOfTheSamekind(desktopMap); QMap > generalMaps; if (desktopMap.count() != 0) { generalMaps.insert("Desktop", desktopMap); } // 构建系统快捷键界面 appendGeneralItems(generalMaps); // 构建自定义快捷键界面 appendCustomItems(); isCloudService = false; }); connect(pThread, &QThread::finished, pWorker, &GetShortcutWorker::deleteLater); pThread->start(); } QMap Shortcut:: MergerOfTheSamekind(QMap desktopMap) { QMap::iterator it = desktopMap.begin(); for (; it != desktopMap.end(); it++) { QString name = it.key().at(it.key().size() - 1); QString name_modification = it.key().left(it.key().length() - 1); if (name == '2') { desktopMap[name_modification] = desktopMap[name_modification]+" or "+it.value(); desktopMap.erase(it); it = desktopMap.begin()+1;// 除之后要将指针指向后面一个 } } return desktopMap; } QWidget *Shortcut::buildGeneralWidget(QString schema, QMap subShortcutsMap) { GSettingsSchema *pSettings; QString domain; if (schema == "Desktop") { pSettings = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory( "/usr/share/glib-2.0/schemas/", g_settings_schema_source_get_default(), FALSE, NULL), KEYBINDINGS_DESKTOP_SCHEMA, FALSE); domain = "ukui-settings-daemon"; } else if (schema == "System") { pSettings = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory( "/usr/share/glib-2.0/schemas/", g_settings_schema_source_get_default(), FALSE, NULL), KEYBINDINGS_SYSTEM_SCHEMA, FALSE); domain = "gsettings-desktop-schemas"; } else { return NULL; } QWidget *pWidget = new QWidget; pWidget->setAttribute(Qt::WA_DeleteOnClose); QVBoxLayout *pVerLayout = new QVBoxLayout(pWidget); pVerLayout->setSpacing(2); pVerLayout->setContentsMargins(0, 0, 0, 16); pWidget->setLayout(pVerLayout); QMap::iterator it = subShortcutsMap.begin(); for (; it != subShortcutsMap.end(); it++) { QWidget *gWidget = new QWidget; gWidget->setFixedHeight(TITLEWIDGETHEIGH); gWidget->setStyleSheet( "QWidget{background: palette(window); border: none; border-radius: 4px}"); QHBoxLayout *gHorLayout = new QHBoxLayout(gWidget); gHorLayout->setSpacing(24); gHorLayout->setContentsMargins(16, 0, 19, 0); QByteArray ba = domain.toLatin1(); QByteArray ba1 = it.key().toLatin1(); GSettingsSchemaKey *keyObj = g_settings_schema_get_key(pSettings, ba1.data()); char *i18nKey; QLabel *nameLabel = new QLabel(gWidget); i18nKey = const_cast(g_dgettext(ba.data(), g_settings_schema_key_get_summary( keyObj))); nameLabel->setText(QString(i18nKey)); nameLabel->setToolTip(QString(i18nKey)); QFontMetrics fontMetrics(nameLabel->font()); QLabel *bindingLabel = new QLabel(gWidget); bindingLabel->setText(it.value()); bindingLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); nameLabel->setText(fontMetrics.elidedText(QString(i18nKey), Qt::ElideRight, 180)); const QByteArray styleID(UKUI_STYLE_SCHEMA); if (QGSettings::isSchemaInstalled(styleID)) { QGSettings *styleUKUI = new QGSettings(styleID, QByteArray(), this); connect(styleUKUI, &QGSettings::changed, this, [=](const QString &key){ if (key == "systemFontSize") { QFontMetrics fm(nameLabel->font()); nameLabel->setText(fm.elidedText(QString(i18nKey), Qt::ElideRight, 180)); } }); } QHBoxLayout *tHorLayout = new QHBoxLayout(); QSpacerItem *horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); tHorLayout->addItem(horizontalSpacer); tHorLayout->addWidget(bindingLabel); tHorLayout->setMargin(0); gHorLayout->addWidget(nameLabel); gHorLayout->addStretch(); gHorLayout->addLayout(tHorLayout); gWidget->setLayout(gHorLayout); pVerLayout->addWidget(gWidget); g_settings_schema_key_unref(keyObj); } g_settings_schema_unref(pSettings); return pWidget; } void Shortcut::appendGeneralItems(QMap > shortcutsMap) { QMap >::iterator it = shortcutsMap.begin(); for (; it != shortcutsMap.end(); it++) { QWidget *gWidget = buildGeneralWidget(it.key(), it.value()); if (gWidget != NULL) { gWidget->setMaximumWidth(960); ui->verticalLayout->addWidget(gWidget); } } } void Shortcut::appendCustomItems() { for (KeyEntry *ckeyEntry : customEntries) { buildCustomItem(ckeyEntry); } } void Shortcut::buildCustomItem(KeyEntry *nkeyEntry) { HoverWidget *customWid = new HoverWidget(""); QHBoxLayout *customWidLayout = new QHBoxLayout(customWid); QFrame *infoFrame = new QFrame(customWid); QHBoxLayout *infoLayout = new QHBoxLayout(infoFrame); QPushButton *delBtn = new QPushButton(customWid); QPushButton *editBtn = new QPushButton(customWid); FixLabel *nameLabel = new FixLabel(customWid); FixLabel *bindingLabel = new FixLabel(customWid); ui->verticalLayout_3->addWidget(customWid); customWid->setObjectName("customWid"); customWid->setStyleSheet("HoverWidget#customWid{background: palette(base);}"); customWidLayout->setMargin(0); customWidLayout->setSpacing(16); customWid->setMinimumSize(QSize(550, 50)); customWid->setMaximumSize(QSize(960, 50)); customWid->setAttribute(Qt::WA_DeleteOnClose); infoFrame->setFrameShape(QFrame::Shape::Box); customWidLayout->addWidget(infoFrame); infoLayout->setContentsMargins(16, 0, 16, 0); infoLayout->addWidget(nameLabel); infoLayout->addStretch(); infoLayout->addWidget(bindingLabel); customWidLayout->addWidget(editBtn); customWidLayout->addWidget(delBtn); nameLabel->setText(nkeyEntry->nameStr); bindingLabel->setText(nkeyEntry->bindingStr); delBtn->setText(tr("Delete")); delBtn->setFixedSize(98, 36); delBtn->hide(); editBtn->setText(tr("Edit")); editBtn->setFixedSize(98, 36); editBtn->hide(); connect(customWid, &HoverWidget::enterWidget, this, [=](){ delBtn->show(); editBtn->show(); }); connect(customWid, &HoverWidget::leaveWidget, this, [=](){ delBtn->hide(); editBtn->hide(); }); connect(delBtn, &QPushButton::clicked, this, [=](){ customWid->deleteLater(); deleteCustomShortcut(nkeyEntry->gsPath); customEntries.removeOne(nkeyEntry); }); connect(editBtn, &QPushButton::clicked, this, [=](){ addShortcutDialog *addDialog = new addShortcutDialog(generalEntries, customEntries, pluginWidget); addDialog->setTitleText(QObject::tr("Edit Shortcut")); addDialog->setExecText(nkeyEntry->actionStr); addDialog->setNameText(nkeyEntry->nameStr); addDialog->setKeyText(nkeyEntry->bindingStr); addDialog->setKeyIsAvailable(3); connect(addDialog, &addShortcutDialog::shortcutInfoSignal, [=](QString path, QString name, QString exec, QString key){ deleteCustomShortcut(nkeyEntry->gsPath); customEntries.removeOne(nkeyEntry); //移除旧的 createNewShortcut(path, name, exec, key, false); //创建新的 nkeyEntry->actionStr = exec; nkeyEntry->nameStr = name; nkeyEntry->bindingStr= key; nameLabel->setText(name); nameLabel->setToolTip(name); bindingLabel->setText(addDialog->keyToLib(key)); }); addDialog->exec(); }); } QString Shortcut::keyToUI(QString key) { if (key.contains("+")) { QStringList keys = key.split("+"); QString keyToUI = keys.join(" "); return keyToUI; } return key; } QString Shortcut::keyToLib(QString key) { if (key.contains("+")) { QStringList keys = key.split("+"); if (keys.count() == 2) { QString lower = keys.at(1); QString keyToLib = "<" + keys.at(0) + ">" + lower.toLower(); qDebug() << "count = 2,keyToLib = " << keyToLib; return keyToLib; } else if (keys.count() == 3) { QString lower = keys.at(2); QString keyToLib = "<" + keys.at(0) + ">" + "<" + keys.at(1) + ">" + lower.toLower(); qDebug() << "count = 3,keyToLib = " << keyToLib; return keyToLib; } } qDebug() << "count = 1,keyToLib = " << key; return key; } void Shortcut::createNewShortcut(QString path, QString name, QString exec, QString key, bool buildFlag) { qDebug() << "createNewShortcut" << path << name << exec << key; QString availablepath; if (path.isEmpty()) { availablepath = findFreePath(); // 创建快捷键 // 更新数据 KeyEntry *nKeyentry = new KeyEntry; nKeyentry->gsPath = availablepath; nKeyentry->nameStr = name; nKeyentry->bindingStr = keyToLib(key); nKeyentry->actionStr = exec; customEntries.append(nKeyentry); if (true == buildFlag) buildCustomItem(nKeyentry); } else { availablepath = path; // 更新快捷键 // 更新数据 int i = 0; for (; i < customEntries.count(); i++) { if (customEntries[i]->gsPath == availablepath) { customEntries[i]->nameStr = name; customEntries[i]->actionStr = exec; break; } } } const QByteArray id(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray idd(availablepath.toLatin1().data()); QGSettings *settings = new QGSettings(id, idd, this); settings->set(BINDING_KEY, keyToLib(key)); settings->set(NAME_KEY, name); settings->set(ACTION_KEY, exec); delete settings; settings = nullptr; } void Shortcut::deleteCustomShortcut(QString path) { if (path.isEmpty()) return; QProcess p(0); QStringList args; char *fullpath = path.toLatin1().data(); QString cmd = "dconf"; args.append("reset"); args.append("-f"); args.append(fullpath); p.execute(cmd, args);// command是要执行的命令,args是参数 qDebug()<<"wait for finish"; p.waitForFinished(-1); qDebug()<verticalLayout_3->count()) { QWidget *p = ui->verticalLayout_3->takeAt(0)->widget(); ui->verticalLayout_3->removeWidget(p); p->deleteLater(); } isCloudService = true; initFunctionStatus(); } ukui-control-center/plugins/devices/audio/0000755000175000017500000000000014201663716017621 5ustar fengfengukui-control-center/plugins/devices/audio/audio.cpp0000644000175000017500000000311714201663716021430 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "audio.h" #include "ui_audio.h" #include Audio::Audio() : mFirstLoad(true) { pluginName = tr("Audio"); pluginType = DEVICES; } Audio::~Audio() { if (!mFirstLoad) { delete ui; } } QString Audio::get_plugin_name() { return pluginName; } int Audio::get_plugin_type() { return pluginType; } QWidget *Audio::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; ui = new Ui::Audio; pluginWidget = new UkmediaMainWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); } return pluginWidget; } void Audio::plugin_delay_control(){ } const QString Audio::name() const { return QStringLiteral("audio"); } ukui-control-center/plugins/devices/audio/ukmedia_output_widget.h0000644000175000017500000000704214201663716024377 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef UKMEDIAOUTPUTWIDGET_H #define UKMEDIAOUTPUTWIDGET_H #include #include #include #include #include #include #include #include #include #include "ukui_custom_style.h" #include "ukui_list_widget_item.h" #include "customstyle.h" #include class AudioSlider : public QSlider { Q_OBJECT public: AudioSlider(QWidget *parent = nullptr); ~AudioSlider(); friend class UkmediaInputWidget; Q_SIGNALS: void silderPressSignal(); void silderReleaseSignal(); protected: void mousePressEvent(QMouseEvent *ev) { int value = 0; int currentX = ev->pos().x(); double per = currentX * 1.0 / this->width(); if ((this->maximum() - this->minimum()) >= 50) { //减小鼠标点击像素的影响 value = qRound(per*(this->maximum() - this->minimum())) + this->minimum(); if (value <= (this->maximum() / 2 - this->maximum() / 10 + this->minimum() / 10)) { value = qRound(per*(this->maximum() - this->minimum() - 1)) + this->minimum(); } else if (value > (this->maximum() / 2 + this->maximum() / 10 + this->minimum() / 10)) { value = qRound(per*(this->maximum() - this->minimum() + 1)) + this->minimum(); } else { value = qRound(per*(this->maximum() - this->minimum())) + this->minimum(); } } else { value = qRound(per*(this->maximum() - this->minimum())) + this->minimum(); } this->setValue(value); QSlider::mousePressEvent(ev); } void mouseReleaseEvent(QMouseEvent *ev) { if(mousePress){ Q_EMIT silderReleaseSignal(); } mousePress = false; QSlider::mouseReleaseEvent(ev); } private: bool mousePress = false; }; class UkmediaOutputWidget : public QWidget { Q_OBJECT public: explicit UkmediaOutputWidget(QWidget *parent = nullptr); ~UkmediaOutputWidget(); friend class UkmediaMainWidget; Q_SIGNALS: public Q_SLOTS: private: QWidget *m_pOutputWidget; QFrame *m_pOutputDeviceWidget; QFrame *m_pMasterVolumeWidget; QFrame *m_pChannelBalanceWidget; QListWidget *m_pOutputListWidget; TitleLabel *m_pOutputLabel; QLabel *m_pOutputDeviceLabel; QLabel *m_pOpVolumeLabel; QLabel *m_pOpVolumePercentLabel; QLabel *m_pOpBalanceLabel; QLabel *m_pLeftBalanceLabel; QLabel *m_pRightBalanceLabel; UkuiButtonDrawSvg *m_pOutputIconBtn; AudioSlider *m_pOpVolumeSlider; UkmediaVolumeSlider *m_pOpBalanceSlider; QVBoxLayout *m_pVlayout; QString sliderQss; }; #endif // UKMEDIAOUTPUTWIDGET_H ukui-control-center/plugins/devices/audio/ukmedia_slider_tip_label_helper.cpp0000644000175000017500000001254414201663716026666 0ustar fengfeng/* * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 #include #include #include #include #include #include #include #include #include #include #include "ukui_custom_style.h" MediaSliderTipLabel::MediaSliderTipLabel(){ setAttribute(Qt::WA_TranslucentBackground); } MediaSliderTipLabel::~MediaSliderTipLabel(){ } void MediaSliderTipLabel::paintEvent(QPaintEvent *e) { QStyleOptionFrame opt; initStyleOption(&opt); QStylePainter p(this); // p.setBrush(QBrush(QColor(0x1A,0x1A,0x1A,0x4C))); p.setBrush(QBrush(QColor(0xFF,0xFF,0xFF,0x33))); p.setPen(Qt::NoPen); p.drawRoundedRect(this->rect(), 1, 1); QPainterPath path; path.addRoundedRect(opt.rect,6,6); p.setRenderHint(QPainter::Antialiasing); setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); p.drawPrimitive(QStyle::PE_PanelTipLabel, opt); this->setProperty("blurRegion", QRegion(QRect(0, 0, 1, 1))); QLabel::paintEvent(e); } SliderTipLabelHelper::SliderTipLabelHelper(QObject *parent) :QObject(parent) { m_pTiplabel = new MediaSliderTipLabel(); m_pTiplabel->setWindowFlags(Qt::ToolTip); qApp->installEventFilter(new AppEventFilter(this)); m_pTiplabel->setFixedSize(52,30); m_pTiplabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); } void SliderTipLabelHelper::registerWidget(QWidget *w) { w->removeEventFilter(this); w->installEventFilter(this); } void SliderTipLabelHelper::unregisterWidget(QWidget *w) { w->removeEventFilter(this); } bool SliderTipLabelHelper::eventFilter(QObject *obj, QEvent *e) { auto slider = qobject_cast(obj); if (obj == slider) { switch (e->type()) { case QEvent::MouseMove: { QMouseEvent *event = static_cast(e); mouseMoveEvent(obj, event); return false; } case QEvent::MouseButtonRelease: { QMouseEvent *event = static_cast(e); mouseReleaseEvent(obj, event); return false; } case QEvent::MouseButtonPress:{ QMouseEvent *event = static_cast(e); mousePressedEvent(obj,event); } default: return false; } } return QObject::eventFilter(obj,e); } void SliderTipLabelHelper::mouseMoveEvent(QObject *obj, QMouseEvent *e) { Q_UNUSED(e); QRect rect; QStyleOptionSlider m_option; auto slider = qobject_cast(obj); slider->initStyleOption(&m_option); rect = slider->style()->subControlRect(QStyle::CC_Slider, &m_option,QStyle::SC_SliderHandle,slider); QPoint gPos = slider->mapToGlobal(rect.topLeft()); QString percent; percent = QString::number(slider->value()); percent.append("%"); m_pTiplabel->setText(percent); m_pTiplabel->move(gPos.x()-(m_pTiplabel->width()/2)+9,gPos.y()-m_pTiplabel->height()-1); m_pTiplabel->show(); } void SliderTipLabelHelper::mouseReleaseEvent(QObject *obj, QMouseEvent *e) { Q_UNUSED(obj); Q_UNUSED(e); m_pTiplabel->hide(); } void SliderTipLabelHelper::mousePressedEvent(QObject *obj, QMouseEvent *e) { Q_UNUSED(e); QStyleOptionSlider m_option; auto slider = qobject_cast(obj); QRect rect; //获取鼠标的位置,这里并不能直接从ev中取值(因为如果是拖动的话,鼠标开始点击的位置没有意义了) double pos = e->pos().x() / (double)slider->width(); slider->setValue(pos *(slider->maximum() - slider->minimum()) + slider->minimum()); //向父窗口发送自定义事件event type,这样就可以在父窗口中捕获这个事件进行处理 QEvent evEvent(static_cast(QEvent::User + 1)); QCoreApplication::sendEvent(obj, &evEvent); int value = pos *(slider->maximum() - slider->minimum()) + slider->minimum(); slider->initStyleOption(&m_option); rect = slider->style()->subControlRect(QStyle::CC_Slider, &m_option,QStyle::SC_SliderHandle,slider); QPoint gPos = slider->mapToGlobal(rect.topLeft()); QString percent; percent = QString::number(slider->value());//(m_option.sliderValue); percent.append("%"); m_pTiplabel->setText(percent); m_pTiplabel->move(gPos.x()-(m_pTiplabel->width()/2)+9,gPos.y()-m_pTiplabel->height()-1); m_pTiplabel->show(); } // AppEventFilter AppEventFilter::AppEventFilter(SliderTipLabelHelper *parent) : QObject(parent) { m_wm = parent; } bool AppEventFilter::eventFilter(QObject *obj, QEvent *e) { Q_UNUSED(obj); Q_UNUSED(e); return false; } ukui-control-center/plugins/devices/audio/customstyle.h0000644000175000017500000001760214201663716022373 0ustar fengfeng/* * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 #include #include "ukmedia_slider_tip_label_helper.h" /*! * \brief The CustomStyle class * \details * 自定义QStyle * 基于QProxyStyle,默认使用QProxyStyle的实例绘制控件,你需要针对某一个控件重新实现若干对应的接口。 * QProxyStyle可以从现有的qt style实例化,我们只需要知道这个style的名字即可。 * 这种做法带来了不错的扩展性和自由度,因为我们不需要将某个style的代码直接引入我们的项目中, * 也能够“继承”这个style类进行二次开发。 * * 下面的方法展现了QStyle的所有的接口,使用QStyle进行控件的绘制使得qt应用能够进行风格的切换, * 从而达到不修改项目源码却对应用外观产生巨大影响的效果。 * * \note * 需要注意QStyle与QSS并不兼容,因为QSS本身其实上也是QStyle的一种实现,对一个控件而言,本身理论上只能 * 在同一时间调用唯一一个QStyle进行绘制。 */ class CustomStyle : public QProxyStyle { Q_OBJECT public: explicit CustomStyle(const QString &proxyStyleName = "windows", QObject *parent = nullptr); ~CustomStyle(); /*! * \brief drawComplexControl * \param control 比如ScrollBar,对应CC枚举类型 * \param option * \param painter * \param widget * \details * drawComplexControl用于绘制具有子控件的复杂控件,它本身一般不直接绘制控件, * 而是通过QStyle的其它方法将复杂控件分解成子控件再调用其它的draw方法绘制。 * 如果你需要重新实现一个复杂控件的绘制方法,首先考虑的应该是在不改变它原有的绘制流程的情况下, * 对它调用到的其它方法进行重写。 * * 如果你不想使用原有的绘制流程,那你需要重写这个接口,然后自己实现一切, * 包括背景的绘制,子控件的位置和状态计算,子控件的绘制等。 * 所以,你需要对这个控件有足够的了解之后再尝试直接重写这个接口。 */ virtual void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const; /*! * \brief drawControl * \param element 比如按钮,对应CE枚举类型 * \param option * \param painter * \param widget * \details * drawControl用于绘制基本控件元素,它本身一般只负责绘制控件的一部分或者一层。 * 如果你想要知道控件具体如何绘制,你需要同时研究这个控件的源码和QStyle中的源码, * 因为它们都有可能改变控件的绘制流程。 * * QStyle一般会遵循QCommonStyle的绘制流程,QCommenStyle是大部分主流style的最基类, * 它本身不能完全称之为一个主题,如果你直接使用它,你的控件将不能被正常绘制,因为它有可能只是 * 在特定的时候执行了特定却未实现的绘制方法,它更像一个框架或者规范。 */ virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const; virtual void drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const; virtual void drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const; /*! * \brief drawPrimitive * \param element 背景绘制,对应PE枚举类型 * \param option * \param painter * \param widget * \details * drawPrimitive用于绘制控件背景,比如按钮和菜单的背景, * 我们一般需要判断控件的状态来绘制不同的背景, * 比如按钮的hover和点击效果。 */ virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const; virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const; virtual QStyle::SubControl hitTestComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget = nullptr) const; virtual QRect itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const; virtual QRect itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const; //virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget); virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const; /*! * \brief polish * \param widget * \details * polish用于对widget进行预处理,一般我们可以在polish中修改其属性, * 另外,polish是对动画和特效实现而言十分重要的一个方法, * 通过polish我们能够使widget和特效和动画形成对应关系。 */ virtual void polish(QWidget *widget); virtual void polish(QApplication *application); virtual void polish(QPalette &palette); virtual void unpolish(QWidget *widget); virtual void unpolish(QApplication *application); virtual QSize sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget = nullptr) const; virtual QIcon standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const; virtual QPalette standardPalette() const; /*! * \brief styleHint * \param hint 对应的枚举是SH * \param option * \param widget * \param returnData * \return * \details * styleHint比较特殊,通过它我们能够改变一些控件的绘制流程或者方式,比如说QMenu是否可以滚动。 */ virtual int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const; /*! * \brief subControlRect * \param control * \param option * \param subControl * \param widget * \return * \details * subControlRect返回子控件的位置和大小信息,这个方法一般在内置流程中调用, * 如果我们要重写某个绘制方法,可能需要用到它 */ virtual QRect subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget = nullptr) const; /*! * \brief subElementRect * \param element * \param option * \param widget * \return * \details * 与subControlRect类似 */ virtual QRect subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget = nullptr) const; Q_SIGNALS: public Q_SLOTS: private: SliderTipLabelHelper *m_helpTip; }; #endif // CUSTOMSTYLE_H ukui-control-center/plugins/devices/audio/ukmedia_input_widget.h0000644000175000017500000000360014201663716024172 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef UKMEDIAINPUTWIDGET_H #define UKMEDIAINPUTWIDGET_H #include #include #include #include #include "ukmedia_output_widget.h" #include #include #include #include #include "ukui_custom_style.h" class UkmediaInputWidget : public QWidget { Q_OBJECT public: explicit UkmediaInputWidget(QWidget *parent = nullptr); ~UkmediaInputWidget(); friend class UkmediaMainWidget; Q_SIGNALS: private: QWidget *m_pInputWidget; QFrame *m_pInputDeviceWidget; QFrame *m_pVolumeWidget; QFrame *m_pInputLevelWidget; QListWidget *m_pInputListWidget; TitleLabel *m_pInputLabel; QLabel *m_pInputDeviceLabel; QLabel *m_pIpVolumeLabel; QLabel *m_pInputLevelLabel; QLabel *m_pIpVolumePercentLabel; UkuiButtonDrawSvg *m_pInputIconBtn; AudioSlider *m_pIpVolumeSlider; QProgressBar *m_pInputLevelProgressBar; QString sliderQss; QVBoxLayout *m_pVlayout; }; #endif // UKMEDIAINPUTWIDGET_H ukui-control-center/plugins/devices/audio/customstyle.cpp0000644000175000017500000003516614201663716022733 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "customstyle.h" #include #include #include #include CustomStyle::CustomStyle(const QString &proxyStyleName, QObject *parent) : QProxyStyle (proxyStyleName) { Q_UNUSED(parent); m_helpTip = new SliderTipLabelHelper(this); } CustomStyle::~CustomStyle() { } void CustomStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { if(control == CC_ToolButton) { /// 我们需要获取ToolButton的详细信息,通过qstyleoption_cast可以得到 /// 对应的option,通过拷贝构造函数得到一份备份用于绘制子控件 /// 我们一般不用在意option是怎么得到的,大部分的Qt控件都能够提供了option的init方法 } return QProxyStyle::drawComplexControl(control, option, painter, widget); } void CustomStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { switch (element) { case CE_ProgressBar: { if (const QStyleOptionProgressBar *pb = qstyleoption_cast(option)) { QStyleOptionProgressBar subopt = *pb; subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget); proxy()->drawControl(CE_ProgressBarGroove, &subopt, painter, widget); subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget); proxy()->drawControl(CE_ProgressBarContents, &subopt, painter, widget); //这是这个控件的当前进度的文字,你那边看情况是否需要绘制 // if (pb->textVisible) { // subopt.rect = subElementRect(SE_ProgressBarLabel, pb, widget); // proxy()->drawControl(CE_ProgressBarLabel, &subopt, painter, widget); // } return; } break; } case CE_ProgressBarGroove: { //这是这个控件的背景,你那边看情况是否绘制 return; if (const QStyleOptionProgressBar *pbg = qstyleoption_cast(option)) { const bool enable = pbg->state &State_Enabled; painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); painter->setBrush(pbg->palette.brush(enable ? QPalette::Active : QPalette::Disabled, QPalette::Window)); painter->drawRect(pbg->rect); painter->restore(); return; } break; } case CE_ProgressBarContents: { if (const QStyleOptionProgressBar *bar = qstyleoption_cast(option)) { if (bar->progress == bar->maximum) return; const bool enable = bar->state & QStyle::State_Enabled; const bool vertical = bar->orientation == Qt::Vertical; const bool inverted = bar->invertedAppearance; qint64 minimum = qint64(bar->minimum); qint64 maximum = qint64(bar->maximum); qint64 progress = qint64(bar->progress); qint64 totalSteps = qMax(Q_INT64_C(1), maximum - minimum); qint64 progressSteps = progress - bar->minimum; qint64 progressBarWidth = progressSteps * (vertical ? bar->rect.height() : bar->rect.width()) / totalSteps; int ProgressBarItem_Width = 4; int ProgressBarItem_Distance = 16; int distance = ProgressBarItem_Distance + ProgressBarItem_Width; int num = progressBarWidth / distance; int totalnum = (vertical ? bar->rect.height() : bar->rect.width()) / distance; bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical; if (inverted) reverse = !reverse; int ProgressBarItem_Hight = 16; QRect drawRect(bar->rect); if (vertical) { drawRect.setWidth(ProgressBarItem_Hight); } else { drawRect.setHeight(ProgressBarItem_Hight); } drawRect.moveCenter(bar->rect.center()); QRect itemRect(drawRect); painter->save(); painter->setPen(Qt::NoPen); painter->setRenderHints(QPainter::Antialiasing, true); for (int var = 0; var < totalnum; ++var) { if (var < num) { if (enable) painter->setBrush(bar->palette.brush(QPalette::Active, QPalette::Highlight)); else painter->setBrush(bar->palette.color(QPalette::Active, QPalette::Highlight).light(150)); } else { painter->setBrush(bar->palette.brush(enable ? QPalette::Active : QPalette::Disabled, QPalette::Button)); } if (vertical) itemRect.setRect(drawRect.left(), !reverse ? drawRect.top() + var * distance : drawRect.bottom() - ProgressBarItem_Width - var * distance, drawRect.width(), ProgressBarItem_Width); else itemRect.setRect(reverse ? drawRect.right() - ProgressBarItem_Width - var * distance : drawRect.left() + var * distance, drawRect.top(), ProgressBarItem_Width, drawRect.height()); painter->drawRoundedRect(itemRect, ProgressBarItem_Width/2, ProgressBarItem_Width/2); } painter->restore();; return; } break; } default: break; } return QProxyStyle::drawControl(element, option, painter, widget); } void CustomStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const { return QProxyStyle::drawItemPixmap(painter, rectangle, alignment, pixmap); } void CustomStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole) const { return QProxyStyle::drawItemText(painter, rectangle, alignment, palette, enabled, text, textRole); } //绘制简单的颜色圆角等 void CustomStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { switch (element) { //绘制 ToolButton case PE_PanelButtonTool:{ painter->save(); painter->setRenderHint(QPainter::Antialiasing,true); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0xff,0xff,0xff,0x00)); painter->drawRoundedRect(option->rect,4,4); if (option->state & State_MouseOver) { if (option->state & State_Sunken) { painter->setRenderHint(QPainter::Antialiasing,true); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0xff,0xff,0xff,0x14)); painter->drawRoundedRect(option->rect,4,4); qDebug() << " 点击按钮"; } else { painter->setRenderHint(QPainter::Antialiasing,true); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0xff,0xff,0xff,0x1f)); painter->drawRoundedRect(option->rect,4,4); qDebug() << "悬停按钮"; } } painter->restore(); return; } case PE_PanelTipLabel:{ painter->save(); painter->setRenderHint(QPainter::Antialiasing,true); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0xff,0xff,0x00,0xff)); painter->drawRoundedRect(option->rect,4,4); painter->restore(); return; }break; case PE_PanelButtonCommand:{ painter->save(); painter->setRenderHint(QPainter::TextAntialiasing,true); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0xff,0xff,0xff,0x00)); if (option->state & State_MouseOver) { if (option->state & State_Sunken) { painter->setRenderHint(QPainter::Antialiasing,true); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0x3d,0x6b,0xe5,0xff)); painter->drawRoundedRect(option->rect,4,4); } else { painter->setRenderHint(QPainter::Antialiasing,true); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0xff,0xff,0xff,0x1f)); painter->drawRoundedRect(option->rect.adjusted(2,2,-2,-2),4,4); } } painter->restore(); return; }break; } return QProxyStyle::drawPrimitive(element, option, painter, widget); } QPixmap CustomStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const { return QProxyStyle::generatedIconPixmap(iconMode, pixmap, option); } QStyle::SubControl CustomStyle::hitTestComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget) const { return QProxyStyle::hitTestComplexControl(control, option, position, widget); } QRect CustomStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const { return QProxyStyle::itemPixmapRect(rectangle, alignment, pixmap); } QRect CustomStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const { return QProxyStyle::itemTextRect(metrics, rectangle, alignment, enabled, text); } // int CustomStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { switch (metric){ case PM_ProgressBarChunkWidth: { int ProgressBarItem_Width = 4; int ProgressBarItem_Distance = 16; return ProgressBarItem_Width + ProgressBarItem_Distance; } case PM_ToolBarIconSize:{ return (int)48*qApp->devicePixelRatio(); } default: break; } return QProxyStyle::pixelMetric(metric, option, widget); } // void CustomStyle::polish(QWidget *widget) { if (widget) { if (widget->inherits("QTipLabel")) { widget->setAttribute(Qt::WA_TranslucentBackground); QPainterPath path; auto rect = widget->rect(); rect.adjust(0,0,0,0); path.addRoundedRect(rect,6,6); widget->setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); } } if (widget) { if (widget->inherits("QLable")) { const_cast (widget)->setAttribute(Qt::WA_TranslucentBackground); widget->setAttribute(Qt::WA_TranslucentBackground); QPainterPath path; auto rect = widget->rect(); rect.adjust(0,0,0,0); path.addRoundedRect(rect,6,6); widget->setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); } } if (widget){ widget->setAttribute(Qt::WA_Hover); widget->inherits("QSlider"); m_helpTip->registerWidget(widget); widget->installEventFilter(this); } return QProxyStyle::polish(widget); } void CustomStyle::polish(QApplication *application) { return QProxyStyle::polish(application); } // void CustomStyle::polish(QPalette &palette) { // return QProxyStyle::polish(palette); // QProxyStyle::polish(palette); // palette.setBrush(QPalette::Foreground, Qt::black); QColor lightBlue(200, 0, 0); palette.setBrush(QPalette::Highlight, lightBlue); } void CustomStyle::unpolish(QWidget *widget) { return QProxyStyle::unpolish(widget); } void CustomStyle::unpolish(QApplication *application) { return QProxyStyle::unpolish(application); } QSize CustomStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const { QSize newSize = contentsSize; switch (type) { case CT_ProgressBar: { qDebug()<pixelMetric(QStyle::PM_ProgressBarChunkWidth, option, widget); newSize.setWidth(cw * ProgressBarItem_Num); return newSize; } default: break; } return QProxyStyle::sizeFromContents(type, option, contentsSize, widget); } QIcon CustomStyle::standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { return QProxyStyle::standardIcon(standardIcon, option, widget); } QPalette CustomStyle::standardPalette() const { return QProxyStyle::standardPalette(); } //如果需要背景透明也许需要用到这个函数 int CustomStyle::styleHint(QStyle::StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const { switch (hint) { /// 让ScrollView viewport的绘制区域包含scrollbar和corner widget /// 这个例子中没有什么作用,如果我们需要绘制一个背景透明的滚动条 /// 这个style hint对我们的意义应该很大,因为我们希望视图能够帮助 /// 我们填充滚动条的背景区域,否则当背景透明时底下会出现明显的分割 case SH_ScrollView_FrameOnlyAroundContents: { return false; } default: break; } return QProxyStyle::styleHint(hint, option, widget, returnData); } QRect CustomStyle::subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget) const { return QProxyStyle::subControlRect(control, option, subControl, widget); } QRect CustomStyle::subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget) const { switch (element) { case SE_ProgressBarGroove: case SE_ProgressBarContents: return option->rect; default: break; } return QProxyStyle::subElementRect(element, option, widget); } ukui-control-center/plugins/devices/audio/ukmedia_output_widget.cpp0000644000175000017500000001630214201663716024731 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "ukmedia_output_widget.h" #include "ukui_list_widget_item.h" #include #include AudioSlider::AudioSlider(QWidget *parent) { Q_UNUSED(parent); } AudioSlider::~AudioSlider() { } UkmediaOutputWidget::UkmediaOutputWidget(QWidget *parent) : QWidget(parent) { // QFILEDEVICE_H m_pOutputListWidget = new QListWidget(this); m_pOutputListWidget->setFixedHeight(250); m_pOutputListWidget->setStyleSheet( "QListWidget{" "background-color:palette(base);" "padding-left:8;" "padding-right:20;" "padding-top:8;" "padding-bottom:8;}" "QListWidget::item{" "border-radius:6px;}" /**列表项扫过*/ "QListWidget::item:hover{" "background-color:rgba(55,144,250,0.5);}" /**列表项选中*/ "QListWidget::item::selected{" "background-color:rgba(55,144,250,1);" "border-width:0;}"); //加载qss样式文件 QFile QssFile("://combox.qss"); QssFile.open(QFile::ReadOnly); if (QssFile.isOpen()){ sliderQss = QLatin1String(QssFile.readAll()); QssFile.close(); } else { qDebug()<<"combox.qss is not found"<setFrameShape(QFrame::Shape::Box); m_pMasterVolumeWidget->setFrameShape(QFrame::Shape::Box); m_pChannelBalanceWidget->setFrameShape(QFrame::Shape::Box); //设置大小 m_pOutputWidget->setMinimumSize(550,422); m_pOutputWidget->setMaximumSize(960,422); m_pOutputDeviceWidget->setMinimumSize(550,319); m_pOutputDeviceWidget->setMaximumSize(960,319); m_pMasterVolumeWidget->setMinimumSize(550,50); m_pMasterVolumeWidget->setMaximumSize(960,50); m_pChannelBalanceWidget->setMinimumSize(550,50); m_pChannelBalanceWidget->setMaximumSize(960,50); m_pOutputLabel = new TitleLabel(this); m_pOutputLabel->setText(tr("Output")); m_pOutputLabel->setStyleSheet("QLabel{color: palette(windowText);}"); //~ contents_path /audio/Output Device m_pOutputDeviceLabel = new QLabel(tr("Output Device:"),m_pOutputWidget); //~ contents_path /audio/Master Volume m_pOpVolumeLabel = new QLabel(tr("Master Volume"),m_pMasterVolumeWidget); m_pOutputIconBtn = new UkuiButtonDrawSvg(m_pMasterVolumeWidget); m_pOpVolumeSlider = new AudioSlider(m_pMasterVolumeWidget); m_pOpVolumePercentLabel = new QLabel(m_pMasterVolumeWidget); //~ contents_path /audio/Balance m_pOpBalanceLabel = new QLabel(tr("Balance"),m_pChannelBalanceWidget); m_pLeftBalanceLabel = new QLabel(tr("Left"),m_pChannelBalanceWidget); m_pOpBalanceSlider = new UkmediaVolumeSlider(m_pChannelBalanceWidget,true); m_pRightBalanceLabel = new QLabel(tr("Right"),m_pChannelBalanceWidget); m_pOpVolumeSlider->setOrientation(Qt::Horizontal); m_pOpBalanceSlider->setOrientation(Qt::Horizontal); m_pOpVolumeSlider->setRange(0,100); m_pOutputIconBtn->setFocusPolicy(Qt::NoFocus); QVBoxLayout *outputDeviceLayout = new QVBoxLayout(); m_pOutputDeviceLabel->setFixedSize(150,32); outputDeviceLayout->addWidget(m_pOutputDeviceLabel); outputDeviceLayout->addWidget(m_pOutputListWidget); m_pOutputDeviceWidget->setLayout(outputDeviceLayout); outputDeviceLayout->layout()->setContentsMargins(16,14,16,14); //主音量添加布局 QHBoxLayout *masterLayout = new QHBoxLayout(m_pMasterVolumeWidget); m_pOpVolumeLabel->setFixedSize(150,32); m_pOutputIconBtn->setFixedSize(24,24); m_pOpVolumeSlider->setFixedHeight(20); m_pOpVolumePercentLabel->setFixedSize(55,24); masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); masterLayout->addWidget(m_pOpVolumeLabel); masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); masterLayout->addWidget(m_pOutputIconBtn); masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); masterLayout->addWidget(m_pOpVolumeSlider); masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); masterLayout->addWidget(m_pOpVolumePercentLabel); masterLayout->addItem(new QSpacerItem(10,20,QSizePolicy::Fixed)); masterLayout->setSpacing(0); m_pMasterVolumeWidget->setLayout(masterLayout); m_pMasterVolumeWidget->layout()->setContentsMargins(0,0,0,0); //声道平衡添加布局 QHBoxLayout *soundLayout = new QHBoxLayout(m_pChannelBalanceWidget); m_pOpBalanceLabel->setFixedSize(150,32); m_pLeftBalanceLabel->setFixedSize(36,24); m_pOpBalanceSlider->setFixedHeight(20); m_pRightBalanceLabel->setFixedSize(55,28); soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pOpBalanceLabel); soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pLeftBalanceLabel); soundLayout->addItem(new QSpacerItem(4,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pOpBalanceSlider); soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pRightBalanceLabel); soundLayout->addItem(new QSpacerItem(10,20,QSizePolicy::Fixed)); soundLayout->setSpacing(0); m_pChannelBalanceWidget->setLayout(soundLayout); m_pChannelBalanceWidget->layout()->setContentsMargins(0,0,0,0); //进行整体布局 m_pVlayout = new QVBoxLayout; m_pVlayout->addWidget(m_pOutputDeviceWidget); m_pVlayout->addWidget(m_pMasterVolumeWidget); m_pVlayout->addWidget(m_pChannelBalanceWidget); m_pVlayout->setSpacing(1); m_pOutputWidget->setLayout(m_pVlayout); m_pOutputWidget->layout()->setContentsMargins(0,0,0,0); QVBoxLayout *vLayout1 = new QVBoxLayout(this); vLayout1->addWidget(m_pOutputLabel); vLayout1->addItem(new QSpacerItem(16,0,QSizePolicy::Fixed)); vLayout1->addWidget(m_pOutputWidget); this->setLayout(vLayout1); this->layout()->setContentsMargins(0,0,0,0); m_pOutputDeviceWidget->setObjectName("outputDeviceWidget"); m_pMasterVolumeWidget->setObjectName("masterVolumeWidget"); //设置样式 m_pOutputLabel->setObjectName("m_pOutputLabel"); } UkmediaOutputWidget::~UkmediaOutputWidget() { } ukui-control-center/plugins/devices/audio/ukui_custom_style.cpp0000644000175000017500000001565214201663716024125 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "ukui_custom_style.h" #include #include #include #include #include #include #include #include UkuiMediaSliderTipLabel::UkuiMediaSliderTipLabel(){ setAttribute(Qt::WA_TranslucentBackground); } UkuiMediaSliderTipLabel::~UkuiMediaSliderTipLabel(){ } void UkuiMediaSliderTipLabel::paintEvent(QPaintEvent *e) { QStyleOptionFrame opt; initStyleOption(&opt); QStylePainter p(this); // p.setBrush(QBrush(QColor(0x1A,0x1A,0x1A,0x4C))); p.setBrush(QBrush(QColor(0xFF,0xFF,0xFF,0x33))); p.setPen(Qt::NoPen); p.drawRoundedRect(this->rect(), 1, 1); QPainterPath path; path.addRoundedRect(opt.rect,6,6); p.setRenderHint(QPainter::Antialiasing); setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); p.drawPrimitive(QStyle::PE_PanelTipLabel, opt); this->setProperty("blurRegion", QRegion(QRect(0, 0, 1, 1))); QLabel::paintEvent(e); } UkmediaVolumeSlider::UkmediaVolumeSlider(QWidget *parent,bool needTip) { Q_UNUSED(parent); if (needTip) { state = needTip; m_pTiplabel = new UkuiMediaSliderTipLabel(); m_pTiplabel->setWindowFlags(Qt::ToolTip); // qApp->installEventFilter(new AppEventFilter(this)); m_pTiplabel->setFixedSize(52,30); m_pTiplabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); } } void UkmediaVolumeSlider::mousePressEvent(QMouseEvent *ev) { int value = 0; int currentX = ev->pos().x(); double per = currentX * 1.0 / this->width(); if ((this->maximum() - this->minimum()) >= 50) { //减小鼠标点击像素的影响 value = qRound(per*(this->maximum() - this->minimum())) + this->minimum(); if (value <= (this->maximum() / 2 - this->maximum() / 10 + this->minimum() / 10)) { value = qRound(per*(this->maximum() - this->minimum() - 1)) + this->minimum(); } else if (value > (this->maximum() / 2 + this->maximum() / 10 + this->minimum() / 10)) { value = qRound(per*(this->maximum() - this->minimum() + 1)) + this->minimum(); } else { value = qRound(per*(this->maximum() - this->minimum())) + this->minimum(); } } else { value = qRound(per*(this->maximum() - this->minimum())) + this->minimum(); } this->setValue(value); QSlider::mousePressEvent(ev); } void UkmediaVolumeSlider::mouseReleaseEvent(QMouseEvent *e) { if(mousePress){ Q_EMIT silderReleaseSignal(); } mousePress = false; QSlider::mouseReleaseEvent(e); } void UkmediaVolumeSlider::initStyleOption(QStyleOptionSlider *option) { QSlider::initStyleOption(option); } void UkmediaVolumeSlider::leaveEvent(QEvent *e) { if (state) { m_pTiplabel->hide(); } } void UkmediaVolumeSlider::enterEvent(QEvent *e) { if (state) { m_pTiplabel->show(); } } void UkmediaVolumeSlider::paintEvent(QPaintEvent *e) { QRect rect; QStyleOptionSlider m_option; QSlider::paintEvent(e); if (state) { this->initStyleOption(&m_option); rect = this->style()->subControlRect(QStyle::CC_Slider, &m_option,QStyle::SC_SliderHandle,this); QPoint gPos = this->mapToGlobal(rect.topLeft()); QString percent; percent = QString::number(this->value()); percent.append("%"); m_pTiplabel->setText(percent); m_pTiplabel->move(gPos.x()-(m_pTiplabel->width()/2)+9,gPos.y()-m_pTiplabel->height()-1); } } UkmediaVolumeSlider::~UkmediaVolumeSlider() { } void UkuiButtonDrawSvg::init(QImage img, QColor color) { mImage = img; mColor = color; } void UkuiButtonDrawSvg::paintEvent(QPaintEvent *event) { QStyleOption opt; opt.init(this); QPainter p(this); p.setBrush(QBrush(QColor(0x13,0x13,0x14,0x00))); p.setPen(Qt::NoPen); QPainterPath path; opt.rect.adjust(0,0,0,0); path.addRoundedRect(opt.rect,6,6); p.setRenderHint(QPainter::Antialiasing); // 反锯齿; p.drawRoundedRect(opt.rect,6,6); setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } QRect UkuiButtonDrawSvg::IconGeometry() { QRect res = QRect(QPoint(0,0),QSize(24,24)); res.moveCenter(QRect(0,0,width(),height()).center()); return res; } void UkuiButtonDrawSvg::draw(QPaintEvent* e) { Q_UNUSED(e); QPainter painter(this); QRect iconRect = IconGeometry(); if (mImage.size() != iconRect.size()) { mImage = mImage.scaled(iconRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); QRect r = mImage.rect(); r.moveCenter(iconRect.center()); iconRect = r; } this->setProperty("fillIconSymbolicColor", true); filledSymbolicColoredPixmap(mImage,mColor); painter.drawImage(iconRect, mImage); } bool UkuiButtonDrawSvg::event(QEvent *event) { switch (event->type()) { case QEvent::Paint: draw(static_cast(event)); break; case QEvent::Move: case QEvent::Resize: { QRect rect = IconGeometry(); } break; case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: event->accept(); break; default: break; } return QPushButton::event(event); } UkuiButtonDrawSvg::UkuiButtonDrawSvg(QWidget *parent) { Q_UNUSED(parent); } UkuiButtonDrawSvg::~UkuiButtonDrawSvg() { } QPixmap UkuiButtonDrawSvg::filledSymbolicColoredPixmap(QImage &img, QColor &baseColor) { for (int x = 0; x < img.width(); x++) { for (int y = 0; y < img.height(); y++) { auto color = img.pixelColor(x, y); if (color.alpha() > 0) { int hue = color.hue(); if (!qAbs(hue - symbolic_color.hue()) < 10) { color.setRed(baseColor.red()); color.setGreen(baseColor.green()); color.setBlue(baseColor.blue()); img.setPixelColor(x, y, color); } } } } return QPixmap::fromImage(img); } ukui-control-center/plugins/devices/audio/ukmedia_sound_effects_widget.cpp0000644000175000017500000003163414201663716026225 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "ukmedia_sound_effects_widget.h" #include #include #include #include UkuiMessageBox::UkuiMessageBox() { } UkmediaSoundEffectsWidget::UkmediaSoundEffectsWidget(QWidget *parent) : QWidget(parent) { m_pThemeWidget = new QFrame(this); m_pAlertSoundWidget = new QFrame(this); m_pAlertSoundSwitchWidget = new QFrame(this); m_pAlertSoundVolumeWidget = new QFrame(this); m_pStartupMusicWidget = new QFrame(this); m_pPoweroffMusicWidget = new QFrame(this); m_pLagoutWidget = new QFrame(this); m_pWakeupMusicWidget = new QFrame(this); m_pVolumeChangeWidget = new QFrame(this); m_pThemeWidget->setFrameShape(QFrame::Shape::Box); m_pAlertSoundWidget->setFrameShape(QFrame::Shape::Box); m_pStartupMusicWidget->setFrameShape(QFrame::Shape::Box); m_pLagoutWidget->setFrameShape(QFrame::Shape::Box); m_pAlertSoundSwitchWidget->setFrameShape(QFrame::Shape::Box); m_pAlertSoundVolumeWidget->setFrameShape(QFrame::Shape::Box); m_pWakeupMusicWidget->setFrameShape(QFrame::Shape::Box); m_pVolumeChangeWidget->setFrameShape(QFrame::Shape::Box); m_pPoweroffMusicWidget->setFrameShape(QFrame::Shape::Box); //~ contents_path /audio/System Sound m_pSoundEffectLabel = new TitleLabel(this); m_pSoundEffectLabel->setText(tr("System Sound")); m_pSoundEffectLabel->setStyleSheet("QLabel{color: palette(windowText);}"); //~ contents_path /audio/Sound Theme m_pSoundThemeLabel = new QLabel(tr("Sound Theme"),m_pThemeWidget); m_pSoundThemeCombobox = new QComboBox(m_pThemeWidget); //~ contents_path /audio/Alert Sound m_pShutdownlabel = new QLabel(tr("Alert Sound"),m_pAlertSoundWidget); m_pAlertSoundCombobox = new QComboBox(m_pAlertSoundWidget); //~ contents_path /audio/Alert Volume m_pAlertSoundLabel = new QLabel(tr("Alert Volume"),m_pAlertSoundVolumeWidget); m_pAlertVolumeLabel = new QLabel(m_pAlertSoundVolumeWidget); m_pAlertSlider = new UkmediaVolumeSlider(m_pAlertSoundVolumeWidget); m_pAlertIconBtn = new UkuiButtonDrawSvg(m_pAlertSoundVolumeWidget); m_pAlertSlider->setRange(0,100); QSize iconSize(24,24); m_pAlertIconBtn->setFocusPolicy(Qt::NoFocus); // m_pAlertIconBtn->setFlat(true); m_pAlertIconBtn->setFixedSize(24,24); m_pAlertIconBtn->setIconSize(iconSize); m_pAlertSlider->setOrientation(Qt::Horizontal); QPalette paleteAppIcon = m_pAlertIconBtn->palette(); paleteAppIcon.setColor(QPalette::Highlight,Qt::transparent); paleteAppIcon.setBrush(QPalette::Button,QBrush(QColor(1,1,1,0))); m_pAlertIconBtn->setPalette(paleteAppIcon); // m_pAlertIconBtn->setProperty("useIconHighlightEffect",true); // m_pAlertIconBtn->setProperty("iconHighlightEffectMode",true); m_pAlertSoundSwitchLabel = new QLabel(tr("Beep Switch"),m_pAlertSoundSwitchWidget); m_pPoweroffMusicLabel = new QLabel(tr("Poweroff Music"),m_pPoweroffMusicWidget); m_pStartupMusicLabel = new QLabel(tr("Startup Music"),m_pStartupMusicWidget); m_pWakeupMusicLabel = new QLabel(tr("Wakeup Music"),m_pWakeupMusicWidget); m_pVolumeChangeLabel = new QLabel(tr("Volume Change"),m_pVolumeChangeWidget); m_pLagoutLabel = new QLabel(tr("Logout Music"),m_pLagoutWidget); m_pLagoutCombobox = new QComboBox(m_pLagoutWidget); m_pStartupButton = new SwitchButton(m_pStartupMusicWidget); m_pLogoutButton = new SwitchButton(m_pLagoutWidget); m_pWakeupMusicButton = new SwitchButton(m_pWakeupMusicWidget); m_pPoweroffButton = new SwitchButton(m_pPoweroffMusicWidget); m_pVolumeChangeCombobox = new QComboBox(m_pVolumeChangeWidget); m_pAlertSoundSwitchButton = new SwitchButton(m_pAlertSoundSwitchWidget); //设置大小 m_pThemeWidget->setMinimumSize(550,50); m_pThemeWidget->setMaximumSize(960,50); m_pAlertSoundWidget->setMinimumSize(550,50); m_pAlertSoundWidget->setMaximumSize(960,50); m_pStartupMusicWidget->setMinimumSize(550,50); m_pStartupMusicWidget->setMaximumSize(960,50); m_pLagoutWidget->setMinimumSize(550,50); m_pLagoutWidget->setMaximumSize(960,50); m_pAlertSoundSwitchWidget->setMinimumSize(550,50); m_pAlertSoundSwitchWidget->setMaximumSize(960,50); m_pWakeupMusicWidget->setMinimumSize(550,50); m_pWakeupMusicWidget->setMaximumSize(960,50); m_pVolumeChangeWidget->setMinimumSize(550,50); m_pVolumeChangeWidget->setMaximumSize(960,50); m_pPoweroffMusicWidget->setMinimumSize(550,50); m_pPoweroffMusicWidget->setMaximumSize(960,50); m_pAlertSoundVolumeWidget->setMinimumSize(550,50); m_pAlertSoundVolumeWidget->setMaximumSize(960,50); m_pSoundEffectLabel->setFixedSize(150,32); m_pSoundThemeLabel->setFixedSize(150,32); m_pShutdownlabel->setFixedSize(150,32); m_pLagoutLabel->setFixedSize(150,32); m_pWakeupMusicLabel->setFixedSize(150,32); m_pVolumeChangeLabel->setFixedSize(150,32); m_pPoweroffMusicLabel->setFixedSize(150,32); m_pSoundThemeCombobox->setMinimumSize(50,32); m_pSoundThemeCombobox->setMaximumSize(900,32); m_pAlertSoundCombobox->setMinimumSize(50,32); m_pAlertSoundCombobox->setMaximumSize(900,32); m_pLagoutCombobox->setMinimumSize(50,32); m_pLagoutCombobox->setMaximumSize(900,32); m_pVolumeChangeCombobox->setMinimumSize(50,32); m_pVolumeChangeCombobox->setMaximumSize(900,32); //添加布局 QHBoxLayout *themeLayout = new QHBoxLayout(m_pThemeWidget); themeLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); themeLayout->addWidget(m_pSoundThemeLabel); themeLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); themeLayout->addWidget(m_pSoundThemeCombobox); themeLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); themeLayout->setSpacing(0); m_pThemeWidget->setLayout(themeLayout); m_pThemeWidget->layout()->setContentsMargins(0,0,0,0); QHBoxLayout *AlertLayout = new QHBoxLayout(m_pAlertSoundWidget); AlertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); AlertLayout->addWidget(m_pShutdownlabel); AlertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); AlertLayout->addWidget(m_pAlertSoundCombobox); AlertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); AlertLayout->setSpacing(0); m_pAlertSoundWidget->setLayout(AlertLayout); m_pAlertSoundWidget->layout()->setContentsMargins(0,0,0,0); //开机音乐设置开关 QHBoxLayout *startupLayout = new QHBoxLayout(m_pStartupMusicWidget); startupLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); startupLayout->addWidget(m_pStartupMusicLabel); startupLayout->addWidget(m_pStartupButton); startupLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); startupLayout->setSpacing(0); m_pStartupMusicWidget->setLayout(startupLayout); m_pStartupMusicWidget->layout()->setContentsMargins(0,0,0,0); //注销提示音布局 QHBoxLayout *lagoutLayout = new QHBoxLayout(m_pLagoutWidget); lagoutLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); lagoutLayout->addWidget(m_pLagoutLabel); lagoutLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Expanding)); // lagoutLayout->addWidget(m_pLagoutCombobox); lagoutLayout->addWidget(m_pLogoutButton); lagoutLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); lagoutLayout->setSpacing(0); m_pLagoutWidget->setLayout(lagoutLayout); m_pLagoutWidget->layout()->setContentsMargins(0,0,0,0); // m_pLagoutWidget->setVisible(false); m_pLagoutCombobox->setVisible(false); //提示音开关布局 QHBoxLayout *alertSoundLayout = new QHBoxLayout(m_pAlertSoundSwitchWidget); alertSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); alertSoundLayout->addWidget(m_pAlertSoundSwitchLabel); alertSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Expanding)); // lagoutLayout->addWidget(m_pLagoutCombobox); alertSoundLayout->addWidget(m_pAlertSoundSwitchButton); alertSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); alertSoundLayout->setSpacing(0); m_pAlertSoundSwitchWidget->setLayout(alertSoundLayout); m_pAlertSoundSwitchWidget->layout()->setContentsMargins(0,0,0,0); //提示音大小 QHBoxLayout *alertLayout = new QHBoxLayout(m_pAlertSoundVolumeWidget); m_pAlertSoundLabel->setFixedSize(150,32); m_pAlertSlider->setFixedHeight(20); m_pAlertVolumeLabel->setFixedSize(40,24); alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); alertLayout->addWidget(m_pAlertSoundLabel); alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); alertLayout->addWidget(m_pAlertIconBtn); alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); alertLayout->addWidget(m_pAlertSlider); alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); alertLayout->addWidget(m_pAlertVolumeLabel); alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); alertLayout->setSpacing(0); m_pAlertSoundVolumeWidget->setLayout(alertLayout); m_pAlertSoundVolumeWidget->layout()->setContentsMargins(0,0,0,0); //窗口关闭提示音 QHBoxLayout *wakeupMusicLayout = new QHBoxLayout(m_pWakeupMusicWidget); wakeupMusicLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); wakeupMusicLayout->addWidget(m_pWakeupMusicLabel); wakeupMusicLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Expanding)); wakeupMusicLayout->addWidget(m_pWakeupMusicButton); wakeupMusicLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); wakeupMusicLayout->setSpacing(0); m_pWakeupMusicWidget->setLayout(wakeupMusicLayout); m_pWakeupMusicWidget->layout()->setContentsMargins(0,0,0,0); //音量改变提示音 QHBoxLayout *volumeChangedLayout = new QHBoxLayout(m_pVolumeChangeWidget); volumeChangedLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); volumeChangedLayout->addWidget(m_pVolumeChangeLabel); volumeChangedLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); volumeChangedLayout->addWidget(m_pVolumeChangeCombobox); volumeChangedLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); volumeChangedLayout->setSpacing(0); m_pVolumeChangeWidget->setLayout(volumeChangedLayout); m_pVolumeChangeWidget->layout()->setContentsMargins(0,0,0,0); //关机提示音 QHBoxLayout *poweroffLayout = new QHBoxLayout(m_pPoweroffMusicWidget); poweroffLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); poweroffLayout->addWidget(m_pPoweroffMusicLabel); poweroffLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Expanding)); poweroffLayout->addWidget(m_pPoweroffButton); poweroffLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); poweroffLayout->setSpacing(0); m_pPoweroffMusicWidget->setLayout(poweroffLayout); m_pPoweroffMusicWidget->layout()->setContentsMargins(0,0,0,0); //进行整体布局 m_pSoundLayout = new QVBoxLayout(this); m_pSoundLayout->addWidget(m_pSoundEffectLabel); m_pSoundLayout->addItem(new QSpacerItem(16,8,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pStartupMusicWidget); m_pSoundLayout->addItem(new QSpacerItem(16,1,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pPoweroffMusicWidget); m_pSoundLayout->addItem(new QSpacerItem(16,1,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pLagoutWidget); m_pSoundLayout->addItem(new QSpacerItem(16,1,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pWakeupMusicWidget); m_pSoundLayout->addItem(new QSpacerItem(16,6,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pAlertSoundSwitchWidget); // m_pSoundLayout->addWidget(m_pAlertSoundVolumeWidget); m_pSoundLayout->addItem(new QSpacerItem(16,7,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pThemeWidget); m_pSoundLayout->addWidget(m_pAlertSoundWidget); // vLayout->addWidget(m_pWindowClosedWidget); m_pSoundLayout->addWidget(m_pVolumeChangeWidget); // vLayout->addWidget(m_pSettingSoundWidget); this->setLayout(m_pSoundLayout); m_pSoundLayout->setSpacing(1); this->layout()->setContentsMargins(0,0,0,0); m_pAlertSoundVolumeWidget->hide(); } UkmediaSoundEffectsWidget::~UkmediaSoundEffectsWidget() { } ukui-control-center/plugins/devices/audio/ukmedia_volume_control.cpp0000644000175000017500000017216514201663716025107 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "ukmedia_volume_control.h" #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include //pa_sink_info *m_pDefaultSink; /* Used for profile sorting */ int reconnect_timeout; struct profile_prio_compare { bool operator() (pa_card_profile_info2 const * const lhs, pa_card_profile_info2 const * const rhs) const { if (lhs->priority == rhs->priority) return strcmp(lhs->name, rhs->name) > 0; return lhs->priority > rhs->priority; } }; struct sink_port_prio_compare { bool operator() (const pa_sink_port_info& lhs, const pa_sink_port_info& rhs) const { if (lhs.priority == rhs.priority) return strcmp(lhs.name, rhs.name) > 0; return lhs.priority > rhs.priority; } }; struct source_port_prio_compare { bool operator() (const pa_source_port_info& lhs, const pa_source_port_info& rhs) const { if (lhs.priority == rhs.priority) return strcmp(lhs.name, rhs.name) > 0; return lhs.priority > rhs.priority; } }; UkmediaVolumeControl::UkmediaVolumeControl(): canRenameDevices(false), m_connected(false), m_config_filename(nullptr) { profileNameMap.clear(); connectToPulse(this); } /* * 设置输出设备静音 */ bool UkmediaVolumeControl::setSinkMute(bool status) { pa_operation* o; if (!(o = pa_context_set_sink_mute_by_index(getContext(), sinkIndex, status, nullptr, nullptr))) { showError(tr("pa_context_set_sink_volume_by_index() failed").toUtf8().constData()); return false; } return true; } /* * 设置输出设备音量 */ bool UkmediaVolumeControl::setSinkVolume(int index,int value) { pa_cvolume v = m_pDefaultSink->volume; v.channels = channel; for (int i=0;ivolume; v.channels = 2; for (int i=0;ivolume; v.channels = channel; for (int i=0;ivolume; v.channels = 2; for (int i=0;ivolume; v.channels = 2; for (int i=0;isecond); clientNames.erase(i); } } static void updatePorts(UkmediaVolumeControl *d, std::map &ports) { std::map::iterator it; PortInfo p; for (auto & port : d->dPorts) { QByteArray desc; it = ports.find(port.first); if (it == ports.end()) continue; p = it->second; desc = p.description; if (p.available == PA_PORT_AVAILABLE_YES) desc += UkmediaVolumeControl::tr(" (plugged in)").toUtf8().constData(); else if (p.available == PA_PORT_AVAILABLE_NO) { if (p.name == "analog-output-speaker" || p.name == "analog-input-microphone-internal") desc += UkmediaVolumeControl::tr(" (unavailable)").toUtf8().constData(); else desc += UkmediaVolumeControl::tr(" (unplugged)").toUtf8().constData(); } port.second = desc; qDebug() << "updatePorts" << p.name << p.description; } Q_EMIT d->updatePortSignal(); it = ports.find(d->activePort); if (it != ports.end()) { p = it->second; // d->setLatencyOffset(p.latency_offset); } } static void setIconByName(QLabel* label, const char* name) { QIcon icon = QIcon::fromTheme(name); int size = label->style()->pixelMetric(QStyle::PM_ToolBarIconSize); QPixmap pix = icon.pixmap(size, size); label->setPixmap(pix); } void UkmediaVolumeControl::updateCard(UkmediaVolumeControl *c, const pa_card_info &info) { bool is_new = false; const char *description; QMap tempInput; QMap tempOutput; QList profileName; QMapportMap; QMapinputPortNameLabelMap; QMap profilePriorityMap; std::set profile_priorities; description = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_DESCRIPTION); hasSinks = c->hasSources = false; profile_priorities.clear(); for (pa_card_profile_info2 ** p_profile = info.profiles2; *p_profile != nullptr; ++p_profile) { // c->hasSinks = c->hasSinks || ((*p_profile)->n_sinks > 0); // c->hasSources = c->hasSources || ((*p_profile)->n_sources > 0); profile_priorities.insert(*p_profile); profileName.append((*p_profile)->name); profilePriorityMap.insertMulti((*p_profile)->name,(*p_profile)->priority); } cardProfilePriorityMap.insertMulti(info.index,profilePriorityMap); c->ports.clear(); for (uint32_t i = 0; i < info.n_ports; ++i) { PortInfo p; p.name = info.ports[i]->name; p.description = info.ports[i]->description; p.priority = info.ports[i]->priority; p.available = info.ports[i]->available; p.direction = info.ports[i]->direction; p.latency_offset = info.ports[i]->latency_offset; for (pa_card_profile_info2 ** p_profile = info.ports[i]->profiles2; *p_profile != nullptr; ++p_profile) p.profiles.push_back((*p_profile)->name); if (p.direction == 1 && p.available != PA_PORT_AVAILABLE_NO) { // portMap.insertMulti(p.name,p.description.data()); qDebug() << " add sink port name "<< info.index << p.name << p.description.data(); tempOutput.insertMulti(p.name,p.description.data()); QList portProfileName; for (auto p_profile : p.profiles) { portProfileName.append(p_profile.data()); QString portName = p.description.data(); QString profileName = p_profile.data(); profileNameMap.insertMulti(portName,profileName); qDebug() << "ctf profilename map insert -----------" << p.description.data() << p_profile.data(); } cardProfileMap.insertMulti(info.index,portProfileName); } else if (p.direction == 2 && p.available != PA_PORT_AVAILABLE_NO){ qDebug() << " add source port name "<< info.index << p.name << p.description.data(); tempInput.insertMulti(p.name,p.description.data()); for (auto p_profile : p.profiles) { inputPortNameLabelMap.insertMulti(p.description.data(),p_profile.data()); } inputPortProfileNameMap.insert(info.index,inputPortNameLabelMap); } c->ports[p.name] = p; } inputPortMap.insert(info.index,tempInput); outputPortMap.insert(info.index,tempOutput); cardActiveProfileMap.insert(info.index,info.active_profile->name); c->profiles.clear(); for (auto p_profile : profile_priorities) { bool hasNo = false, hasOther = false; std::map::iterator portIt; QByteArray desc = p_profile->description; for (portIt = c->ports.begin(); portIt != c->ports.end(); portIt++) { PortInfo port = portIt->second; if (std::find(port.profiles.begin(), port.profiles.end(), p_profile->name) == port.profiles.end()) continue; if (port.available == PA_PORT_AVAILABLE_NO) hasNo = true; else { hasOther = true; break; } } if (hasNo && !hasOther) desc += tr(" (unplugged)").toUtf8().constData(); if (!p_profile->available) desc += tr(" (unavailable)").toUtf8().constData(); c->profiles.push_back(std::pair(p_profile->name, desc)); if (p_profile->n_sinks == 0 && p_profile->n_sources == 0) c->noInOutProfile = p_profile->name; } c->activeProfile = info.active_profile ? info.active_profile->name : ""; /* Because the port info for sinks and sources is discontinued we need * to update the port info for them here. */ updatePorts(c,c->ports); if (is_new) updateDeviceVisibility(); Q_EMIT checkDeviceSelectionSianal(&info); // c->updating = false; } /* * Update output device when the default output device or port is updated */ bool UkmediaVolumeControl::updateSink(UkmediaVolumeControl *w,const pa_sink_info &info) { bool is_new = false; m_defaultSinkVolume = info.volume; channel = info.volume.channels; QMaptemp; int volume; if (info.volume.channels >= 2) volume = MAX(info.volume.values[0],info.volume.values[1]); else volume = info.volume.values[0]; //默认的输出音量 if (info.name && strcmp(defaultSinkName.data(),info.name) == 0) { sinkIndex= info.index; balance = pa_cvolume_get_balance(&info.volume,&info.channel_map); defaultChannelMap = info.channel_map; channelMap = info.channel_map; if (info.active_port) { if (strcmp(sinkPortName.toLatin1().data(),info.active_port->name) != 0) { sinkPortName = info.active_port->name; QTimer::singleShot(100, this, SLOT(timeoutSlot())); } else sinkPortName = info.active_port->name; } defaultOutputCard = info.card; if (sinkVolume != volume || sinkMuted != info.mute) { sinkVolume = volume; sinkMuted = info.mute; Q_EMIT updateVolume(sinkVolume,sinkMuted); } } if (info.ports) { for (pa_sink_port_info ** sinkPort = info.ports; *sinkPort != nullptr; ++sinkPort) { temp.insertMulti(info.name,(*sinkPort)->name); } sinkPortMap.insert(info.card,temp); qDebug() << "updateSink" << info.volume.channels << info.active_port->description << info.active_port->name << sinkVolume <<"balance:" <::iterator cw; std::set port_priorities; port_priorities.clear(); for (uint32_t i=0; iports.clear(); } if (is_new) updateDeviceVisibility(); return is_new; } /* * stream suspend callback */ static void suspended_callback(pa_stream *s, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (pa_stream_is_suspended(s)) w->updateVolumeMeter(pa_stream_get_device_index(s), PA_INVALID_INDEX, -1); } void UkmediaVolumeControl::readCallback(pa_stream *s, size_t length, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); const void *data; double v; int index; index = pa_stream_get_device_index(s); QString str = pa_stream_get_device_name(s); QString sss = w->defaultSourceName; if (/*index == w->sourceIndex &&*/ strcmp(str.toLatin1().data(),sss.toLatin1().data()) == 0) { if (pa_stream_peek(s, &data, &length) < 0) { w->showError(UkmediaVolumeControl::tr("Failed to read data from stream").toUtf8().constData()); return; } } else { return; } if (!data) { /* nullptr data means either a hole or empty buffer. * Only drop the stream when there is a hole (length > 0) */ if (length) pa_stream_drop(s); return; } assert(length > 0); assert(length % sizeof(float) == 0); v = ((const float*) data)[length / sizeof(float) -1]; pa_stream_drop(s); if (v < 0) v = 0; if (v > 1) v = 1; if (index == w->sourceIndex && strcmp(str.toLatin1().data(),sss.toLatin1().data()) == 0 && !strstr(str.toLatin1().data(),"monitor")){ w->updateVolumeMeter(index, pa_stream_get_monitor_stream(s), v); } } pa_stream* UkmediaVolumeControl::createMonitorStreamForSource(uint32_t source_idx, uint32_t stream_idx = -1, bool suspend = false) { pa_stream *s; char t[16]; pa_buffer_attr attr; pa_sample_spec ss; pa_stream_flags_t flags; ss.channels = 1; ss.format = PA_SAMPLE_FLOAT32; ss.rate = 25; memset(&attr, 0, sizeof(attr)); attr.fragsize = sizeof(float); attr.maxlength = (uint32_t) -1; snprintf(t, sizeof(t), "%u", source_idx); m_pPaContext = getContext(); if (!(s = pa_stream_new(getContext(), tr("Peak detect").toUtf8().constData(), &ss, nullptr))) { showError(tr("Failed to create monitoring stream").toUtf8().constData()); return nullptr; } if (stream_idx != (uint32_t) -1) pa_stream_set_monitor_stream(s, stream_idx); pa_stream_set_read_callback(s, readCallback, this); pa_stream_set_suspended_callback(s, suspended_callback, this); flags = (pa_stream_flags_t) (PA_STREAM_DONT_MOVE | PA_STREAM_PEAK_DETECT | PA_STREAM_ADJUST_LATENCY | (suspend ? PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND : PA_STREAM_NOFLAGS) /*| (!showVolumeMetersCheckButton->isChecked() ? PA_STREAM_START_CORKED : PA_STREAM_NOFLAGS)*/); if (pa_stream_connect_record(s, t, &attr, flags) < 0) { showError(tr("Failed to connect monitoring stream").toUtf8().constData()); pa_stream_unref(s); return nullptr; } return s; } void UkmediaVolumeControl::updateSource(const pa_source_info &info) { bool is_new = false; int volume; if (info.volume.channels >= 2) volume = MAX(info.volume.values[0],info.volume.values[1]); else volume = info.volume.values[0]; //默认的输出音量 if (info.name && strcmp(defaultSourceName.data(),info.name) == 0) { if (info.active_port) { if (strcmp(sourcePortName.toLatin1().data(),info.active_port->name) != 0) { sourcePortName = info.active_port->name; QTimer::singleShot(100, this, SLOT(timeoutSlot())); } else sourcePortName = info.active_port->name; } sourceIndex = info.index; defaultInputCard = info.card; if (sourceVolume != volume || sourceMuted != info.mute) { sourceVolume = volume; sourceMuted = info.mute; Q_EMIT updateSourceVolume(sourceVolume,sourceMuted); } } if (info.index == sourceIndex && !sourceOutputVector.contains(info.index) && pa_context_get_server_protocol_version(getContext()) >= 13) { sourceOutputVector.append(info.index); peak = createMonitorStreamForSource(info.index, -1, !!(info.flags & PA_SOURCE_NETWORK)); } QMaptemp; if(info.ports) { for (pa_source_port_info ** sourcePort = info.ports; *sourcePort != nullptr; ++sourcePort) { temp.insertMulti(info.name,(*sourcePort)->name); } sourcePortMap.insert(info.card,temp); } qDebug() << "update source"; if (is_new) updateDeviceVisibility(); } void UkmediaVolumeControl::setIconFromProplist(QLabel *icon, pa_proplist *l, const char *def) { const char *t; if ((t = pa_proplist_gets(l, PA_PROP_MEDIA_ICON_NAME))) goto finish; if ((t = pa_proplist_gets(l, PA_PROP_WINDOW_ICON_NAME))) goto finish; if ((t = pa_proplist_gets(l, PA_PROP_APPLICATION_ICON_NAME))) goto finish; if ((t = pa_proplist_gets(l, PA_PROP_MEDIA_ROLE))) { if (strcmp(t, "video") == 0 || strcmp(t, "phone") == 0) goto finish; if (strcmp(t, "music") == 0) { t = "audio"; goto finish; } if (strcmp(t, "game") == 0) { t = "applications-games"; goto finish; } if (strcmp(t, "event") == 0) { t = "dialog-information"; goto finish; } } t = def; finish: setIconByName(icon, t); } void UkmediaVolumeControl::updateSinkInput(const pa_sink_input_info &info) { const char *t; if ((t = pa_proplist_gets(info.proplist, "module-stream-restore.id"))) { if (t && strcmp(t, "sink-input-by-media-role:event") == 0) { g_debug("%s", tr("Ignoring sink-input due to it being designated as an event and thus handled by the Event widget").toUtf8().constData()); return; } } const gchar *description = pa_proplist_gets(info.proplist, PA_PROP_APPLICATION_NAME); const gchar *appId = pa_proplist_gets(info.proplist, PA_PROP_APPLICATION_ID); //没制定应用名称的不加入到应用音量中 if (description && !strstr(description,"QtPulseAudio")) { if (!info.corked) { sinkInputMap.insert(description,info.volume.values[0]); if (appId && !sinkInputList.contains(description)) { sinkInputList.append(description); Q_EMIT addSinkInputSignal(description,appId,info.index); } } else { Q_EMIT removeSinkInputSignal(description); sinkInputList.removeAll(description); QMap::iterator it; for(it = sinkInputMap.begin();it!=sinkInputMap.end();) { if(it.key() == description) { sinkInputMap.erase(it); break; } ++it; } } } } void UkmediaVolumeControl::updateSourceOutput(const pa_source_output_info &info) { const char *app; if ((app = pa_proplist_gets(info.proplist, PA_PROP_APPLICATION_ID))) if (app && strcmp(app, "org.PulseAudio.pavucontrol") == 0 || strcmp(app, "org.gnome.VolumeControl") == 0 || strcmp(app, "org.kde.kmixd") == 0) return; const gchar *description = pa_proplist_gets(info.proplist, PA_PROP_APPLICATION_NAME); const gchar *appId = pa_proplist_gets(info.proplist, PA_PROP_APPLICATION_ID); //没制定应用名称的不加入到应用音量中 if (description && !strstr(description,"QtPulseAudio")) { if (appId && !info.corked) { sourceOutputMap.insert(description,info.volume.values[0]); Q_EMIT addSourceOutputSignal(description,appId,info.index); } else { Q_EMIT removeSourceOutputSignal(description); QMap::iterator it; for(it = sourceOutputMap.begin();it!=sourceOutputMap.end();) { if(it.key() == description) { sourceOutputMap.erase(it); break; } ++it; } } } } void UkmediaVolumeControl::updateClient(const pa_client_info &info) { g_free(clientNames[info.index]); clientNames[info.index] = g_strdup(info.name); } void UkmediaVolumeControl::updateServer(const pa_server_info &info) { m_pServerInfo = &info; defaultSourceName = info.default_source_name ? info.default_source_name : ""; defaultSinkName = info.default_sink_name ? info.default_sink_name : ""; qDebug() << "default_sink" << info.default_sink_name << "default_source" << info.default_source_name; } void UkmediaVolumeControl::updateVolumeMeter(uint32_t index, uint32_t sinkInputIdx, double v) { Q_UNUSED(index); Q_UNUSED(sinkInputIdx); if (lastPeak >= DECAY_STEP) if (v < lastPeak - DECAY_STEP) v = lastPeak - DECAY_STEP; lastPeak = v; Q_EMIT peakChangedSignal(v); } static guint idleSource = 0; gboolean idleCb(gpointer data) { ((UkmediaVolumeControl*) data)->reallyUpdateDeviceVisibility(); idleSource = 0; return FALSE; } void UkmediaVolumeControl::setConnectionState(gboolean connected) { if (m_connected != connected) { m_connected = connected; if (m_connected) { // connectingLabel->hide(); // notebook->show(); } else { // notebook->hide(); // connectingLabel->show(); } } } void UkmediaVolumeControl::updateDeviceVisibility() { if (idleSource) return; idleSource = g_idle_add(idleCb, this); } void UkmediaVolumeControl::reallyUpdateDeviceVisibility() { bool is_empty = true; // for (auto & sinkInputWidget : sinkInputWidgets) { // SinkInputWidget* w = sinkInputWidget.second; // if (sinkWidgets.size() > 1) { // w->directionLabel->show(); // w->deviceButton->show(); // } else { // w->directionLabel->hide(); // w->deviceButton->hide(); // } // if (showSinkInputType == SINK_INPUT_ALL || w->type == showSinkInputType) { // w->show(); // is_empty = false; // } else // w->hide(); // } // if (eventRoleWidget) // is_empty = false; // if (is_empty) // noStreamsLabel->show(); // else // noStreamsLabel->hide(); is_empty = true; // for (auto & sourceOutputWidget : sourceOutputWidgets) { // SourceOutputWidget* w = sourceOutputWidget.second; // if (sourceWidgets.size() > 1) { // w->directionLabel->show(); // w->deviceButton->show(); // } else { // w->directionLabel->hide(); // w->deviceButton->hide(); // } // if (showSourceOutputType == SOURCE_OUTPUT_ALL || w->type == showSourceOutputType) { // w->show(); // is_empty = false; // } else // w->hide(); // } // if (is_empty) // noRecsLabel->show(); // else // noRecsLabel->hide(); // is_empty = true; // for (auto & sinkWidget : sinkWidgets) { // SinkWidget* w = sinkWidget.second; // if (showSinkType == SINK_ALL || w->type == showSinkType) { // w->show(); // is_empty = false; // } else // w->hide(); // } // if (is_empty) // noSinksLabel->show(); // else // noSinksLabel->hide(); // is_empty = true; // for (auto & cardWidget : cardWidgets) { // CardWidget* w = cardWidget.second; // w->show(); // is_empty = false; // } // if (is_empty) // noCardsLabel->show(); // else // noCardsLabel->hide(); // is_empty = true; // for (auto & sourceWidget : sourceWidgets) { // SourceWidget* w = sourceWidget.second; // if (showSourceType == SOURCE_ALL || // w->type == showSourceType || // (showSourceType == SOURCE_NO_MONITOR && w->type != SOURCE_MONITOR)) { // w->show(); // is_empty = false; // } else // w->hide(); // } // if (is_empty) // noSourcesLabel->show(); // else // noSourcesLabel->hide(); // /* Hmm, if I don't call hide()/show() here some widgets will never // * get their proper space allocated */ // sinksVBox->hide(); // sinksVBox->show(); // sourcesVBox->hide(); // sourcesVBox->show(); // streamsVBox->hide(); // streamsVBox->show(); // recsVBox->hide(); // recsVBox->show(); // cardsVBox->hide(); // cardsVBox->show(); } void UkmediaVolumeControl::removeCard(uint32_t index) { // if (!cardWidgets.count(index)) // return; // delete cardWidgets[index]; // cardWidgets.erase(index); updateDeviceVisibility(); } void UkmediaVolumeControl::removeSink(uint32_t index) { QMap::iterator it; for (it=sinkMap.begin();it!=sinkMap.end();) { if (it.key() == index) { qDebug() << "removeSink" << index; sinkMap.erase(it); break; } ++it; } updateDeviceVisibility(); } void UkmediaVolumeControl::removeSource(uint32_t index) { QMap::iterator it; for (it=sourceMap.begin();it!=sourceMap.end();) { if (it.key() == index) { qDebug() << "removeSource" << index; sourceMap.erase(it); break; } ++it; } updateDeviceVisibility(); } void UkmediaVolumeControl::removeSinkInput(uint32_t index) { updateDeviceVisibility(); } void UkmediaVolumeControl::removeSourceOutput(uint32_t index) { updateDeviceVisibility(); } void UkmediaVolumeControl::removeClient(uint32_t index) { g_free(clientNames[index]); clientNames.erase(index); } void UkmediaVolumeControl::setConnectingMessage(const char *string) { QByteArray markup = ""; if (!string) markup += tr("Establishing connection to PulseAudio. Please wait...").toUtf8().constData(); else markup += string; markup += ""; // connectingLabel->setText(QString::fromUtf8(markup)); } void UkmediaVolumeControl::showError(const char *txt) { char buf[256]; snprintf(buf, sizeof(buf), "%s: %s", txt, pa_strerror(pa_context_errno(context))); qDebug() <get_window()->set_cursor(); w->setConnectionState(true); } } void UkmediaVolumeControl::cardCb(pa_context *c, const pa_card_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Card callback failure").toUtf8().constData()); return; } if (eol > 0) { decOutstanding(w); return; } w->cardMap.insert(i->index,i->name); w->updateCard(w,*i); } void UkmediaVolumeControl::sinkIndexCb(pa_context *c, const pa_sink_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Card callback failure").toUtf8().constData()); return; } if (eol > 0) { return; } w->sinkIndex= i->index; } void UkmediaVolumeControl::sourceIndexCb(pa_context *c, const pa_source_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Source callback failure").toUtf8().constData()); return; } if (eol > 0) { return; } w->sourceIndex = i->index; } void UkmediaVolumeControl::sinkCb(pa_context *c, const pa_sink_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Sink callback failure").toUtf8().constData()); return; } if (eol > 0) { decOutstanding(w); return; } w->m_pDefaultSink = i; qDebug() << "SinkCb" <name <m_pDefaultSink->name << i->volume.values[0] ; w->sinkMap.insert(i->index,i->name); w->updateSink(w,*i); } void UkmediaVolumeControl::sourceCb(pa_context *c, const pa_source_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Source callback failure").toUtf8().constData()); return; } if (eol > 0) { decOutstanding(w); return; } qDebug() << "sourceCb" << i->name << i->description << i->volume.values[PA_CHANNELS_MAX]; w->sourceMap.insert(i->index,i->name); w->updateSource(*i); } void UkmediaVolumeControl::sinkInputCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Sink input callback failure").toUtf8().constData()); return; } if (eol > 0) { decOutstanding(w); return; } w->updateSinkInput(*i); } void UkmediaVolumeControl::sourceOutputCb(pa_context *c, const pa_source_output_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Source output callback failure").toUtf8().constData()); return; } if (eol > 0) { if (n_outstanding > 0) { /* At this point all notebook pages have been populated, so * let's open one that isn't empty */ } decOutstanding(w); return; } if (i->name) qDebug() << "sourceOutputCb" << i->name << i->source <sourceOutputVector.contains(i->index)) { w->sourceOutputVector.append(i->index); w->updateSourceOutput(*i); qDebug() << "sourceOutputVector.append(i->index)" << i->source; } } void UkmediaVolumeControl::clientCb(pa_context *c, const pa_client_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Client callback failure").toUtf8().constData()); return; } if (eol > 0) { decOutstanding(w); return; } // qDebug() << "clientCb" << i->name; w->updateClient(*i); } void UkmediaVolumeControl::serverInfoCb(pa_context *, const pa_server_info *i, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (!i) { w->showError(QObject::tr("Server info callback failure").toUtf8().constData()); return; } pa_operation *o; //默认的输出设备改变时需要获取默认的输出音量 if(!(o = pa_context_get_sink_info_by_name(w->getContext(),i->default_sink_name,sinkIndexCb,w))) { } if(!(o = pa_context_get_source_info_by_name(w->getContext(),i->default_source_name,sourceIndexCb,w))) { } qDebug() << "serverInfoCb" << i->user_name << i->default_sink_name << i->default_source_name; w->updateServer(*i); QTimer::singleShot(100, w, SLOT(timeoutSlot())); decOutstanding(w); } void UkmediaVolumeControl::timeoutSlot() { Q_EMIT deviceChangedSignal(); } void UkmediaVolumeControl::extStreamRestoreReadCb( pa_context *c, const pa_ext_stream_restore_info *i, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { decOutstanding(w); g_debug(QObject::tr("Failed to initialize stream_restore extension: %s").toUtf8().constData(), pa_strerror(pa_context_errno(c))); return; } if (eol > 0) { decOutstanding(w); return; } // qDebug() << "extStreamRestoreReadCb" << i->name; // w->updateRole(*i); } void UkmediaVolumeControl::extStreamRestoreSubscribeCb(pa_context *c, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); pa_operation *o; if (!(o = pa_ext_stream_restore_read(c, extStreamRestoreReadCb, w))) { w->showError(QObject::tr("pa_ext_stream_restore_read() failed").toUtf8().constData()); return; } qDebug() << "extStreamRestoreSubscribeCb" ; pa_operation_unref(o); } void UkmediaVolumeControl::extDeviceManagerReadCb( pa_context *c, const pa_ext_device_manager_info *, int eol, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); if (eol < 0) { decOutstanding(w); g_debug(QObject::tr("Failed to initialize device manager extension: %s").toUtf8().constData(), pa_strerror(pa_context_errno(c))); return; } w->canRenameDevices = true; if (eol > 0) { decOutstanding(w); return; } qDebug() << "extDeviceManagerReadCb"; /* Do something with a widget when this part is written */ } void UkmediaVolumeControl::extDeviceManagerSubscribeCb(pa_context *c, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); pa_operation *o; if (!(o = pa_ext_device_manager_read(c, extDeviceManagerReadCb, w))) { w->showError(QObject::tr("pa_ext_device_manager_read() failed").toUtf8().constData()); return; } qDebug() << "extDeviceManagerSubscribeCb"; pa_operation_unref(o); } void UkmediaVolumeControl::subscribeCb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { case PA_SUBSCRIPTION_EVENT_SINK: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) w->removeSink(index); else { pa_operation *o; if (!(o = pa_context_get_sink_info_by_index(c, index, sinkCb, w))) { w->showError(QObject::tr("pa_context_get_sink_info_by_index() failed").toUtf8().constData()); return; } pa_operation_unref(o); } break; case PA_SUBSCRIPTION_EVENT_SOURCE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) w->removeSource(index); else { pa_operation *o; if (!(o = pa_context_get_source_info_by_index(c, index, sourceCb, w))) { w->showError(QObject::tr("pa_context_get_source_info_by_index() failed").toUtf8().constData()); return; } pa_operation_unref(o); } break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) w->removeSinkInput(index); else { pa_operation *o; if (!(o = pa_context_get_sink_input_info(c, index, sinkInputCb, w))) { w->showError(QObject::tr("pa_context_get_sink_input_info() failed").toUtf8().constData()); return; } pa_operation_unref(o); } break; case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) w->removeSourceOutput(index); else { pa_operation *o; if (!(o = pa_context_get_source_output_info(c, index, sourceOutputCb, w))) { w->showError(QObject::tr("pa_context_get_sink_input_info() failed").toUtf8().constData()); return; } pa_operation_unref(o); } break; case PA_SUBSCRIPTION_EVENT_CLIENT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) w->removeClient(index); else { pa_operation *o; if (!(o = pa_context_get_client_info(c, index, clientCb, w))) { w->showError(QObject::tr("pa_context_get_client_info() failed").toUtf8().constData()); return; } pa_operation_unref(o); } break; case PA_SUBSCRIPTION_EVENT_SERVER: { pa_operation *o; if (!(o = pa_context_get_server_info(c, serverInfoCb, w))) { w->showError(QObject::tr("pa_context_get_server_info() failed").toUtf8().constData()); return; } pa_operation_unref(o); } break; case PA_SUBSCRIPTION_EVENT_CARD: //remove card if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { qDebug() << "remove cards------"; //移除outputPort w->removeOutputPortMap(index); w->removeInputPortMap(index); w->removeCardMap(index); w->removeCardProfileMap(index); w->removeProfileMap(); w->removeInputProfile(); w->removeCard(index); Q_EMIT w->updatePortSignal(); } else { pa_operation *o; if (!(o = pa_context_get_card_info_by_index(c, index, cardCb, w))) { w->showError(QObject::tr("pa_context_get_card_info_by_index() failed").toUtf8().constData()); return; } pa_operation_unref(o); } break; } } void UkmediaVolumeControl::contextStateCallback(pa_context *c, void *userdata) { UkmediaVolumeControl *w = static_cast(userdata); g_assert(c); switch (pa_context_get_state(c)) { case PA_CONTEXT_UNCONNECTED: case PA_CONTEXT_CONNECTING: case PA_CONTEXT_AUTHORIZING: case PA_CONTEXT_SETTING_NAME: break; case PA_CONTEXT_READY: { pa_operation *o; qDebug() << "pa_context_get_state" << "PA_CONTEXT_READY" << pa_context_get_state(c); reconnect_timeout = 1; /* Create event widget immediately so it's first in the list */ pa_context_set_subscribe_callback(c, subscribeCb, w); if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) (PA_SUBSCRIPTION_MASK_SINK| PA_SUBSCRIPTION_MASK_SOURCE| PA_SUBSCRIPTION_MASK_SINK_INPUT| PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT| PA_SUBSCRIPTION_MASK_CLIENT| PA_SUBSCRIPTION_MASK_SERVER| PA_SUBSCRIPTION_MASK_CARD), nullptr, nullptr))) { w->showError(QObject::tr("pa_context_subscribe() failed").toUtf8().constData()); return; } pa_operation_unref(o); /* Keep track of the outstanding callbacks for UI tweaks */ n_outstanding = 0; if (!(o = pa_context_get_server_info(c, serverInfoCb, w))) { w->showError(QObject::tr("pa_context_get_server_info() failed").toUtf8().constData()); return; } pa_operation_unref(o); n_outstanding++; if (!(o = pa_context_get_client_info_list(c, clientCb, w))) { w->showError(QObject::tr("pa_context_client_info_list() failed").toUtf8().constData()); return; } pa_operation_unref(o); n_outstanding++; if (!(o = pa_context_get_card_info_list(c, cardCb, w))) { w->showError(QObject::tr("pa_context_get_card_info_list() failed").toUtf8().constData()); return; } pa_operation_unref(o); n_outstanding++; if (!(o = pa_context_get_sink_info_list(c, sinkCb, w))) { w->showError(QObject::tr("pa_context_get_sink_info_list() failed").toUtf8().constData()); return; } pa_operation_unref(o); n_outstanding++; if (!(o = pa_context_get_source_info_list(c, sourceCb, w))) { w->showError(QObject::tr("pa_context_get_source_info_list() failed").toUtf8().constData()); return; } pa_operation_unref(o); n_outstanding++; if (!(o = pa_context_get_sink_input_info_list(c, sinkInputCb, w))) { w->showError(QObject::tr("pa_context_get_sink_input_info_list() failed").toUtf8().constData()); return; } pa_operation_unref(o); n_outstanding++; if (!(o = pa_context_get_source_output_info_list(c, sourceOutputCb, w))) { w->showError(QObject::tr("pa_context_get_source_output_info_list() failed").toUtf8().constData()); return; } pa_operation_unref(o); n_outstanding++; Q_EMIT w->paContextReady(); break; } case PA_CONTEXT_FAILED: w->setConnectionState(false); w->updateDeviceVisibility(); pa_context_unref(w->m_pPaContext); w->m_pPaContext = nullptr; if (reconnect_timeout > 0) { g_debug("%s", QObject::tr("Connection failed, attempting reconnect").toUtf8().constData()); // g_timeout_add_seconds(reconnect_timeout, connectToPulse, w); } return; case PA_CONTEXT_TERMINATED: default: return; } } pa_context* UkmediaVolumeControl::getContext(void) { return context; } gboolean UkmediaVolumeControl::connectToPulse(gpointer userdata) { pa_glib_mainloop *m = pa_glib_mainloop_new(g_main_context_default()); api = pa_glib_mainloop_get_api(m); pa_proplist *proplist = pa_proplist_new(); pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, QObject::tr("Ukui Media Volume Control").toUtf8().constData()); pa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "org.PulseAudio.pavucontrol"); pa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "audio-card"); pa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "PACKAGE_VERSION"); context = pa_context_new_with_proplist(api, nullptr, proplist); g_assert(context); pa_proplist_free(proplist); pa_context_set_state_callback(getContext(), contextStateCallback, this); if (pa_context_connect(getContext(), nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) { if (pa_context_errno(getContext()) == PA_ERR_INVALID) { /*w->setConnectingMessage(QObject::tr("Connection to PulseAudio failed. Automatic retry in 5s\n\n" "In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties\n" "or default-server in client.conf is misconfigured.\n" "This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window.\n" "If this is the case, then PulseAudio should autospawn again, or if this is not configured you should\n" "run start-pulseaudio-x11 manually.").toUtf8().constData());*/ qFatal("connect pulseaudio failed") ; } else { // g_timeout_add_seconds(5,connectToPulse,w); } } return false; } /* * 根据名称获取sink input音量 */ int UkmediaVolumeControl::getSinkInputVolume(const gchar *name) { QMap::iterator it; int value = 0; for(it = sinkInputMap.begin();it!=sinkInputMap.end();) { if(it.key() == name) { qDebug() << "getSinkInputVolume" << "name:" <::iterator it; int value = 0; for(it = sourceOutputMap.begin();it!=sourceOutputMap.end();) { if(it.key() == name) { qDebug() << "getSourceOutputVolume" << "name:" <(userdata); if (eol < 0) { if (pa_context_errno(c) == PA_ERR_NOENTITY) return; w->showError(QObject::tr("Sink input callback failure").toUtf8().constData()); return; } if (eol > 0) { decOutstanding(w); return; } w->sinkInputMuted = i->mute; if (i->volume.channels >= 2) w->sinkInputVolume = MAX(i->volume.values[0],i->volume.values[1]); else w->sinkInputVolume = i->volume.values[0]; qDebug() << "sinkInputCallback" <sinkInputVolume <name; } /* * 更新output port map */ void UkmediaVolumeControl::updateOutputPortMap() { QMap::iterator at; QMap::iterator cardNameMap; // if (firstEntry == true) { // for(at = outputPortMap.begin();at!=w->outputPortMap.end();) // { // UkuiListWidgetItem *itemW = new UkuiListWidgetItem(w); // QListWidgetItem * item = new QListWidgetItem(w->m_pOutputWidget->m_pOutputListWidget); // item->setSizeHint(QSize(200,64)); //QSize(120, 40) spacing: 12px; // w->m_pOutputWidget->m_pOutputListWidget->blockSignals(true); // w->m_pOutputWidget->m_pOutputListWidget->setItemWidget(item, itemW); // w->m_pOutputWidget->m_pOutputListWidget->blockSignals(false); // QString cardName; // for(cardNameMap = w->cardMap.begin();cardNameMap!=w->cardMap.end();) // { // if (cardNameMap.key() == at.key()) { // cardName = cardNameMap.value(); // break; // } // ++cardNameMap; // } // itemW->setLabelText(at.value(),cardName); // w->m_pOutputWidget->m_pOutputListWidget->blockSignals(true); // w->m_pOutputWidget->m_pOutputListWidget->insertItem(i++,item); // w->m_pOutputWidget->m_pOutputListWidget->blockSignals(false); // ++at; // } // for(at = w->inputPortLabelMap.begin();at!=w->inputPortLabelMap.end();) // { // UkuiListWidgetItem *itemW = new UkuiListWidgetItem(w); // QListWidgetItem * item = new QListWidgetItem(w->m_pInputWidget->m_pInputListWidget); // item->setSizeHint(QSize(200,64)); //QSize(120, 40) spacing: 12px; // w->m_pInputWidget->m_pInputListWidget->setItemWidget(item, itemW); // QString cardName; // for(cardNameMap = w->cardMap.begin();cardNameMap!=w->cardMap.end();) // { // if (cardNameMap.key() == at.key()) { // cardName = cardNameMap.value(); // break; // } // ++cardNameMap; // } // itemW->setLabelText(at.value(),cardName); // w->m_pInputWidget->m_pInputListWidget->blockSignals(true); // w->m_pInputWidget->m_pInputListWidget->insertItem(i++,item); // w->m_pInputWidget->m_pInputListWidget->blockSignals(false); // ++at; // } // } // else { // //记录上一次output label // for (i=0;im_pOutputWidget->m_pOutputListWidget->count();i++) { // QListWidgetItem *item = w->m_pOutputWidget->m_pOutputListWidget->item(i); // UkuiListWidgetItem *wid = (UkuiListWidgetItem *)w->m_pOutputWidget->m_pOutputListWidget->itemWidget(item); // int index; // for (at=w->cardMap.begin();at!=w->cardMap.end();) { // if (wid->deviceLabel->text() == at.value()) { // index = at.key(); // break; // } // ++at; // } // w->currentOutputPortLabelMap.insertMulti(index,wid->portLabel->text()); // w->m_pCurrentOutputPortLabelList->append(wid->portLabel->text()); // w->m_pCurrentOutputCardList->append(wid->deviceLabel->text()); // //qDebug() << index << "current output item ************" << item->text() <portLabel->text() << w->m_pOutputPortLabelList->count() ;//<< w->m_pOutputPortLabelList->at(i); // } // for (i=0;im_pInputWidget->m_pInputListWidget->count();i++) { // QListWidgetItem *item = w->m_pInputWidget->m_pInputListWidget->item(i); // UkuiListWidgetItem *wid = (UkuiListWidgetItem *)w->m_pInputWidget->m_pInputListWidget->itemWidget(item); // int index; // int count; // for (at=w->cardMap.begin();at!=w->cardMap.end();) { // if (wid->deviceLabel->text() == at.value()) { // index = at.key(); // break; // } // ++at; // ++count; // } // w->currentInputPortLabelMap.insertMulti(index,wid->portLabel->text()); // w->m_pCurrentInputPortLabelList->append(wid->portLabel->text()); // w->m_pCurrentInputCardList->append(wid->deviceLabel->text()); // qDebug() <<"current input port label insert " << index << wid->deviceLabel->text(); // } //// w->m_pInputWidget->m_pInputListWidget->blockSignals(true); //// w->deleteNotAvailableOutputPort(); //// w->addAvailableOutputPort(); //// w->deleteNotAvailableInputPort(); //// w->addAvailableInputPort(); //// w->m_pInputWidget->m_pInputListWidget->blockSignals(false); // } } /* * 移除指定索引的output port */ void UkmediaVolumeControl::removeOutputPortMap(int index) { QMap>::iterator it; for (it=outputPortMap.begin();it!=outputPortMap.end();) { if (it.key() == index) { qDebug() << "removeoutputport" <>::iterator it; for (it=inputPortMap.begin();it!=inputPortMap.end();) { if (it.key() == index) { inputPortMap.erase(it); break; } ++it; } } /* * 移除指定索引的card */ void UkmediaVolumeControl::removeCardMap(int index) { QMap::iterator it; for (it=cardMap.begin();it!=cardMap.end();) { if (it.key() == index) { cardMap.erase(it); break; } ++it; } } void UkmediaVolumeControl::removeCardProfileMap(int index) { QMap>::iterator it; QMap>::iterator at; for (it=cardProfileMap.begin();it!=cardProfileMap.end();) { if (it.key() == index) { cardProfileMap.erase(it); break; } ++it; } for (at=cardProfilePriorityMap.begin();at!=cardProfilePriorityMap.cend();) { if (at.key() == index) { cardProfilePriorityMap.erase(at); break; } ++at; } } void UkmediaVolumeControl::removeProfileMap() { QMap::iterator it; for (it=profileNameMap.begin();it!=profileNameMap.end();) { qDebug() << "ctf ------------" << profileNameMap.count(); qDebug() << "removeProfileMap" <>::iterator it; QMap::iterator at; QMap portMap; for (it=outputPortMap.begin();it!=outputPortMap.end();) { portMap = it.value(); for (at=portMap.begin();at!=portMap.end();) { if (at.value() == name) return true; ++at; } ++it; } return false; } void UkmediaVolumeControl::removeInputProfile() { QMap>::iterator it; QMap::iterator at; QMap temp; for (it=inputPortProfileNameMap.begin();it!=inputPortProfileNameMap.end();) { temp = it.value(); for (at=temp.begin();at!=temp.end();) { if (!isExitInputPort(at.value())) { it = inputPortProfileNameMap.erase(it); return; } ++at; } ++it; } } bool UkmediaVolumeControl::isExitInputPort(QString name) { QMap>::iterator it; QMap::iterator at; QMap portMap; for (it=inputPortMap.begin();it!=inputPortMap.end();) { portMap = it.value(); for (at=portMap.begin();at!=portMap.end();) { if (at.value() == name) return true; ++at; } ++it; } return false; } ukui-control-center/plugins/devices/audio/ukmedia_sound_effects_widget.h0000644000175000017500000000523314201663716025666 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef UKMEDIASOUNDEFFECTSWIDGET_H #define UKMEDIASOUNDEFFECTSWIDGET_H #include #include #include #include #include #include #include "ukui_custom_style.h" #include "SwitchButton/switchbutton.h" class UkuiMessageBox : public QMessageBox { public: explicit UkuiMessageBox(); }; class UkmediaSoundEffectsWidget : public QWidget { Q_OBJECT public: explicit UkmediaSoundEffectsWidget(QWidget *parent = nullptr); ~UkmediaSoundEffectsWidget(); friend class UkmediaMainWidget; Q_SIGNALS: public Q_SLOTS: private: QFrame *m_pThemeWidget; QFrame *m_pAlertSoundWidget; QFrame *m_pLagoutWidget; QFrame *m_pAlertSoundSwitchWidget; QFrame *m_pAlertSoundVolumeWidget; QFrame *m_pWakeupMusicWidget; QFrame *m_pVolumeChangeWidget; QFrame *m_pStartupMusicWidget; QFrame *m_pPoweroffMusicWidget; QString qss; QStyledItemDelegate *itemDelegate; TitleLabel *m_pSoundEffectLabel; QLabel *m_pSoundThemeLabel; QLabel *m_pShutdownlabel; QLabel *m_pLagoutLabel; QLabel *m_pAlertSoundSwitchLabel; QLabel *m_pAlertSoundLabel; QLabel *m_pAlertVolumeLabel; QLabel *m_pWakeupMusicLabel; QLabel *m_pVolumeChangeLabel; QLabel *m_pPoweroffMusicLabel; QLabel *m_pStartupMusicLabel; QComboBox *m_pSoundThemeCombobox; QComboBox *m_pAlertSoundCombobox; QComboBox *m_pLagoutCombobox; QComboBox *m_pVolumeChangeCombobox; QVBoxLayout *m_pSoundLayout; SwitchButton *m_pStartupButton; SwitchButton *m_pPoweroffButton; SwitchButton *m_pLogoutButton; SwitchButton *m_pAlertSoundSwitchButton; SwitchButton *m_pWakeupMusicButton; UkmediaVolumeSlider *m_pAlertSlider; UkuiButtonDrawSvg *m_pAlertIconBtn; }; #endif // UKMEDIASOUNDEFFECTSWIDGET_H ukui-control-center/plugins/devices/audio/ukmedia_input_widget.cpp0000644000175000017500000001414014201663716024526 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "ukmedia_input_widget.h" #include #include #include UkmediaInputWidget::UkmediaInputWidget(QWidget *parent) : QWidget(parent) { m_pInputWidget = new QWidget(this); m_pInputDeviceWidget = new QFrame(m_pInputWidget); m_pVolumeWidget = new QFrame(m_pInputWidget); m_pInputLevelWidget = new QFrame(m_pInputWidget); m_pInputListWidget = new QListWidget(this); m_pInputListWidget->setFixedHeight(250); m_pInputListWidget->setStyleSheet( "QListWidget{" "background-color:palette(base);" "padding-left:8;" "padding-right:20;" "padding-top:8;" "padding-bottom:8;}" "QListWidget::item{" "border-radius:6px;}" /**列表项扫过*/ "QListWidget::item:hover{" "background-color:rgba(55,144,250,0.5);}" /**列表项选中*/ "QListWidget::item::selected{" "background-color:rgba(55,144,250,1);" "border-width:0;}"); m_pInputDeviceWidget->setFrameShape(QFrame::Shape::Box); m_pVolumeWidget->setFrameShape(QFrame::Shape::Box); m_pInputLevelWidget->setFrameShape(QFrame::Shape::Box); //设置大小 m_pInputWidget->setMinimumSize(550,422); m_pInputWidget->setMaximumSize(960,422); m_pInputDeviceWidget->setMinimumSize(550,319); m_pInputDeviceWidget->setMaximumSize(960,319); m_pVolumeWidget->setMinimumSize(550,50); m_pVolumeWidget->setMaximumSize(960,50); m_pInputLevelWidget->setMinimumSize(550,50); m_pInputLevelWidget->setMaximumSize(960,50); m_pInputLabel = new TitleLabel(this); m_pInputLabel->setText(tr("Input")); m_pInputLabel->setStyleSheet("color: palette(windowText);}"); //~ contents_path /audio/Input Device m_pInputDeviceLabel = new QLabel(tr("Input Device:"),m_pInputWidget); //~ contents_path /audio/Volume m_pIpVolumeLabel = new QLabel(tr("Volume"),m_pVolumeWidget); m_pInputIconBtn = new UkuiButtonDrawSvg(m_pVolumeWidget); m_pIpVolumeSlider = new AudioSlider(); m_pIpVolumePercentLabel = new QLabel(m_pVolumeWidget); //~ contents_path /audio/Input Level m_pInputLevelLabel = new QLabel(tr("Input Level"),m_pInputLevelWidget); m_pInputLevelProgressBar = new QProgressBar(m_pInputLevelWidget); m_pInputLevelProgressBar->setStyle(new CustomStyle); m_pInputLevelProgressBar->setTextVisible(false); m_pIpVolumeSlider->setOrientation(Qt::Horizontal); m_pIpVolumeSlider->setRange(0,100); m_pInputIconBtn->setFocusPolicy(Qt::NoFocus); //输入设备添加布局 QVBoxLayout *m_pInputDeviceLayout = new QVBoxLayout(m_pInputDeviceWidget); m_pInputDeviceLabel->setFixedSize(150,32); m_pInputDeviceLayout->addWidget(m_pInputDeviceLabel); m_pInputDeviceLayout->addWidget(m_pInputListWidget); m_pInputDeviceLayout->setSpacing(0); m_pInputDeviceWidget->setLayout(m_pInputDeviceLayout); m_pInputDeviceLayout->layout()->setContentsMargins(16,14,16,14); //主音量添加布局 QHBoxLayout *m_pMasterLayout = new QHBoxLayout(m_pVolumeWidget); m_pIpVolumeLabel->setFixedSize(150,32); m_pInputIconBtn->setFixedSize(24,24); m_pIpVolumeSlider->setFixedHeight(20); m_pIpVolumePercentLabel->setFixedSize(55,24); m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pMasterLayout->addWidget(m_pIpVolumeLabel); m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pMasterLayout->addWidget(m_pInputIconBtn); m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pMasterLayout->addWidget(m_pIpVolumeSlider); m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Maximum)); m_pMasterLayout->addWidget(m_pIpVolumePercentLabel); m_pMasterLayout->addItem(new QSpacerItem(10,20,QSizePolicy::Maximum)); m_pMasterLayout->setSpacing(0); m_pVolumeWidget->setLayout(m_pMasterLayout); m_pVolumeWidget->layout()->setContentsMargins(0,0,0,0); //声道平衡添加布局 QHBoxLayout *m_pSoundLayout = new QHBoxLayout(m_pInputLevelWidget); m_pInputLevelLabel->setFixedSize(150,32); m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pInputLevelLabel); m_pSoundLayout->addItem(new QSpacerItem(18,20,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pInputLevelProgressBar); m_pSoundLayout->setSpacing(0); m_pInputLevelWidget->setLayout(m_pSoundLayout); m_pInputLevelWidget->layout()->setContentsMargins(0,0,0,0); //进行整体布局 m_pVlayout = new QVBoxLayout(m_pInputWidget); m_pVlayout->addWidget(m_pInputDeviceWidget); m_pVlayout->addWidget(m_pVolumeWidget); m_pVlayout->addWidget(m_pInputLevelWidget); m_pVlayout->setSpacing(1); m_pInputWidget->setLayout(m_pVlayout); m_pInputWidget->layout()->setContentsMargins(0,0,0,0); QVBoxLayout *m_pVlayout1 = new QVBoxLayout(this); m_pVlayout1->addWidget(m_pInputLabel); m_pVlayout1->addItem(new QSpacerItem(16,4,QSizePolicy::Fixed)); m_pVlayout1->addWidget(m_pInputWidget); this->setLayout(m_pVlayout1); this->layout()->setContentsMargins(0,0,0,0); } UkmediaInputWidget::~UkmediaInputWidget() { } ukui-control-center/plugins/devices/audio/ukmedia_main_widget.cpp0000644000175000017500000031040514201663716024316 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "ukmedia_main_widget.h" #include #include #include #include #include #include #include #include #include #include #include #define MATE_DESKTOP_USE_UNSTABLE_API #define VERSION "1.12.1" #define GVC_DIALOG_DBUS_NAME "org.mate.VolumeControl" #define KEY_SOUNDS_SCHEMA "org.ukui.sound" #define GVC_SOUND_SOUND (xmlChar *) "sound" #define GVC_SOUND_NAME (xmlChar *) "name" #define GVC_SOUND_FILENAME (xmlChar *) "filename" #define SOUND_SET_DIR "/usr/share/ukui-media/sounds" #define KEYBINDINGS_CUSTOM_SCHEMA "org.ukui.media.sound" #define KEYBINDINGS_CUSTOM_DIR "/org/ukui/sound/keybindings/" #define MAX_CUSTOM_SHORTCUTS 1000 #define FILENAME_KEY "filename" #define NAME_KEY "name" guint appnum = 0; extern bool isCheckBluetoothInput; enum { SOUND_TYPE_UNSET, SOUND_TYPE_OFF, SOUND_TYPE_DEFAULT_FROM_THEME, SOUND_TYPE_BUILTIN, SOUND_TYPE_CUSTOM }; UkmediaMainWidget::UkmediaMainWidget(QWidget *parent) : QWidget(parent) { m_pVolumeControl = new UkmediaVolumeControl; initWidget(); m_pSoundList = new QStringList; m_pThemeNameList = new QStringList; m_pThemeDisplayNameList = new QStringList; m_pSoundNameList = new QStringList; m_pSoundThemeList = new QStringList; m_pSoundThemeDirList = new QStringList; m_pSoundThemeXmlNameList = new QStringList; initGsettings(); setupThemeSelector(this); updateTheme(this); //报警声音,从指定路径获取报警声音文件 populateModelFromDir(this,SOUND_SET_DIR); //初始化combobox的值 comboboxCurrentTextInit(); time = new QTimer(); dealSlot(); } /* * 初始化界面 */ void UkmediaMainWidget::initWidget() { m_pOutputWidget = new UkmediaOutputWidget(); m_pInputWidget = new UkmediaInputWidget(); m_pSoundWidget = new UkmediaSoundEffectsWidget(); firstEntry = true; mThemeName = UKUI_THEME_WHITE; QVBoxLayout *m_pvLayout = new QVBoxLayout(); m_pvLayout->addWidget(m_pOutputWidget); m_pvLayout->addWidget(m_pInputWidget); m_pvLayout->addWidget(m_pSoundWidget); m_pvLayout->addSpacing(32); m_pvLayout->addSpacerItem(new QSpacerItem(20,0,QSizePolicy::Fixed,QSizePolicy::Expanding)); m_pvLayout->setSpacing(40); this->setLayout(m_pvLayout); this->setMinimumWidth(582); this->setMaximumWidth(910); this->layout()->setContentsMargins(0,0,31,0); //设置滑动条的最大值为100 m_pInputWidget->m_pIpVolumeSlider->setMaximum(100); m_pOutputWidget->m_pOpVolumeSlider->setMaximum(100); m_pOutputWidget->m_pOpBalanceSlider->setMaximum(100); m_pOutputWidget->m_pOpBalanceSlider->setMinimum(-100); m_pOutputWidget->m_pOpBalanceSlider->setSingleStep(100); m_pInputWidget->m_pInputLevelProgressBar->setMaximum(100); } QList UkmediaMainWidget::listExistsPath() { char ** childs; int len; DConfClient * client = dconf_client_new(); childs = dconf_client_list (client, KEYBINDINGS_CUSTOM_DIR, &len); g_object_unref (client); QList vals; for (int i = 0; childs[i] != NULL; i++){ if (dconf_is_rel_dir (childs[i], NULL)){ char * val = g_strdup (childs[i]); vals.append(val); } } g_strfreev (childs); return vals; } QString UkmediaMainWidget::findFreePath(){ int i = 0; char * dir; bool found; QList existsdirs; existsdirs = listExistsPath(); for (; i < MAX_CUSTOM_SHORTCUTS; i++){ found = true; dir = QString("custom%1/").arg(i).toLatin1().data(); for (int j = 0; j < existsdirs.count(); j++) if (!g_strcmp0(dir, existsdirs.at(j))){ found = false; break; } if (found) break; } if (i == MAX_CUSTOM_SHORTCUTS){ qDebug() << "Keyboard Shortcuts" << "Too many custom shortcuts"; return ""; } return QString("%1%2").arg(KEYBINDINGS_CUSTOM_DIR).arg(QString(dir)); } void UkmediaMainWidget::addValue(QString name,QString filename) { //在创建setting表时,先判断是否存在该设置,存在时不创建 QList existsPath = listExistsPath(); for (char * path : existsPath) { char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); char * allpath = strcat(prepath, path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray bba(allpath); if(QGSettings::isSchemaInstalled(ba)) { QGSettings * settings = new QGSettings(ba, bba); QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); g_warning("full path: %s", allpath); qDebug() << filenameStr << FILENAME_KEY <set(FILENAME_KEY, filename); settings->set(NAME_KEY, name); } } /* * 初始化gsetting */ void UkmediaMainWidget::initGsettings() { //获取声音gsettings值 m_pSoundSettings = g_settings_new (KEY_SOUNDS_SCHEMA); g_signal_connect (G_OBJECT (m_pSoundSettings), "changed", G_CALLBACK (onKeyChanged), this); //检测系统主题 if (QGSettings::isSchemaInstalled(UKUI_THEME_SETTING)){ m_pThemeSetting = new QGSettings(UKUI_THEME_SETTING); if (m_pThemeSetting->keys().contains("styleName")) { mThemeName = m_pThemeSetting->get(UKUI_THEME_NAME).toString(); } connect(m_pThemeSetting, SIGNAL(changed(const QString &)),this,SLOT(ukuiThemeChangedSlot(const QString &))); } //检测设计开关机音乐 if (QGSettings::isSchemaInstalled(UKUI_SWITCH_SETTING)) { m_pBootSetting = new QGSettings(UKUI_SWITCH_SETTING); if (m_pBootSetting->keys().contains("startupMusic")) { bool startup = m_pBootSetting->get(UKUI_STARTUP_MUSIC_KEY).toBool(); m_pSoundWidget->m_pStartupButton->setChecked(startup); } if (m_pBootSetting->keys().contains("poweroffMusic")) { bool poweroff = m_pBootSetting->get(UKUI_POWEROFF_MUSIC_KEY).toBool(); m_pSoundWidget->m_pPoweroffButton->setChecked(poweroff); } if (m_pBootSetting->keys().contains("logoutMusic")) { bool logout = m_pBootSetting->get(UKUI_LOGOUT_MUSIC_KEY).toBool(); m_pSoundWidget->m_pLogoutButton->setChecked(logout); } if (m_pBootSetting->keys().contains("weakupMusic")) { bool m_hasMusic = m_pBootSetting->get(UKUI_WAKEUP_MUSIC_KEY).toBool(); m_pSoundWidget->m_pWakeupMusicButton->setChecked(m_hasMusic); } connect(m_pBootSetting,SIGNAL(changed(const QString &)),this,SLOT(bootMusicSettingsChanged())); } bool status = g_settings_get_boolean(m_pSoundSettings, EVENT_SOUNDS_KEY); m_pSoundWidget->m_pAlertSoundSwitchButton->setChecked(status); } /* * 处理槽函数 */ void UkmediaMainWidget::dealSlot() { QTimer::singleShot(100, this, SLOT(initVoulmeSlider())); connect(m_pInputWidget->m_pInputIconBtn,SIGNAL(clicked()),this,SLOT(inputMuteButtonSlot())); connect(m_pOutputWidget->m_pOutputIconBtn,SIGNAL(clicked()),this,SLOT(outputMuteButtonSlot())); // connect(m_pSoundWidget->m_pAlertIconBtn,SIGNAL(clicked()),this,SLOT(alertSoundVolumeChangedSlot())); connect(m_pSoundWidget->m_pStartupButton,SIGNAL(checkedChanged(bool)),this,SLOT(startupButtonSwitchChangedSlot(bool))); connect(m_pSoundWidget->m_pPoweroffButton,SIGNAL(checkedChanged(bool)),this,SLOT(poweroffButtonSwitchChangedSlot(bool))); connect(m_pSoundWidget->m_pLogoutButton,SIGNAL(checkedChanged(bool)),this,SLOT(logoutMusicButtonSwitchChangedSlot(bool))); connect(m_pSoundWidget->m_pWakeupMusicButton,SIGNAL(checkedChanged(bool)),this,SLOT(wakeButtonSwitchChangedSlot(bool))); connect(m_pSoundWidget->m_pAlertSoundSwitchButton,SIGNAL(checkedChanged(bool)),this,SLOT(alertSoundButtonSwitchChangedSlot(bool))); //输出音量控制 //输出滑动条音量控制 timeSlider = new QTimer(this); connect(timeSlider,SIGNAL(timeout()),this,SLOT(timeSliderSlot())); //输出滑动条改变 connect(m_pOutputWidget->m_pOpVolumeSlider,SIGNAL(valueChanged(int)),this,SLOT(outputWidgetSliderChangedSlot(int))); // connect(m_pOutputWidget->m_pOpVolumeSlider,&AudioSlider::silderPressSignal,this,[=](){ // mousePress = true; // mouseReleaseState = false; // }); // connect(m_pOutputWidget->m_pOpVolumeSlider,&AudioSlider::silderReleaseSignal,this,[=](){ // mouseReleaseState = true; // }); //输入滑动条音量控制 connect(m_pInputWidget->m_pIpVolumeSlider,SIGNAL(valueChanged(int)),this,SLOT(inputWidgetSliderChangedSlot(int))); //输入等级 connect(m_pVolumeControl,SIGNAL(peakChangedSignal(double)),this,SLOT(peakVolumeChangedSlot(double))); connect(m_pVolumeControl,SIGNAL(updatePortSignal()),this,SLOT(updateDevicePort())); connect(m_pVolumeControl,SIGNAL(deviceChangedSignal()),this,SLOT(updateListWidgetItemSlot())); //切换输出设备或者音量改变时需要同步更新音量 connect(m_pVolumeControl,&UkmediaVolumeControl::updateVolume,this,[=](int value,bool state){ QString percent = QString::number(paVolumeToValue(value)); float balanceVolume = m_pVolumeControl->getBalanceVolume(); m_pOutputWidget->m_pOpVolumePercentLabel->setText(percent+"%"); m_pOutputWidget->m_pOpVolumeSlider->blockSignals(true); m_pOutputWidget->m_pOpBalanceSlider->blockSignals(true); m_pOutputWidget->m_pOpBalanceSlider->setValue(balanceVolume*100); m_pOutputWidget->m_pOpVolumeSlider->setValue(paVolumeToValue(value)); m_pOutputWidget->m_pOpVolumeSlider->blockSignals(false); m_pOutputWidget->m_pOpBalanceSlider->blockSignals(false); themeChangeIcons(); initListWidgetItem(); }); connect(m_pVolumeControl,&UkmediaVolumeControl::updateSourceVolume,this,[=](int value,bool state){ QString percent = QString::number(paVolumeToValue(value)); m_pInputWidget->m_pIpVolumePercentLabel->setText(percent+"%"); m_pInputWidget->m_pIpVolumeSlider->blockSignals(true); m_pInputWidget->m_pIpVolumeSlider->setValue(paVolumeToValue(value)); m_pInputWidget->m_pIpVolumeSlider->blockSignals(false); themeChangeIcons(); }); connect(m_pOutputWidget->m_pOpBalanceSlider,SIGNAL(valueChanged(int)),this,SLOT(balanceSliderChangedSlot(int))); //点击报警音量时播放报警声音 // connect(m_pSoundWidget->m_pAlertSlider,SIGNAL(valueChanged(int)),this,SLOT(alertVolumeSliderChangedSlot(int))); connect(m_pSoundWidget->m_pAlertSoundCombobox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboxIndexChangedSlot(int))); connect(m_pSoundWidget->m_pLagoutCombobox ,SIGNAL(currentIndexChanged(int)),this,SLOT(comboxIndexChangedSlot(int))); connect(m_pSoundWidget->m_pSoundThemeCombobox,SIGNAL(currentIndexChanged(int)),this,SLOT(themeComboxIndexChangedSlot(int))); connect(m_pSoundWidget->m_pVolumeChangeCombobox,SIGNAL(currentIndexChanged (int)),this,SLOT(volumeChangedComboboxChangeSlot(int))); connect(m_pOutputWidget->m_pOutputListWidget,SIGNAL(currentRowChanged(int )),this,SLOT(outputListWidgetCurrentRowChangedSlot(int))); connect(m_pInputWidget->m_pInputListWidget,SIGNAL(currentRowChanged(int )),this,SLOT(inputListWidgetCurrentRowChangedSlot(int))); } /* * 初始化滑动条的值 */ void UkmediaMainWidget::initVoulmeSlider() { int sinkVolume = paVolumeToValue(m_pVolumeControl->getSinkVolume()); int sourceVolume = paVolumeToValue(m_pVolumeControl->getSourceVolume()); QString percent = QString::number(sinkVolume); float balanceVolume = m_pVolumeControl->getBalanceVolume(); m_pOutputWidget->m_pOpVolumePercentLabel->setText(percent+"%"); percent = QString::number(sourceVolume); m_pInputWidget->m_pIpVolumePercentLabel->setText(percent+"%"); m_pOutputWidget->m_pOpVolumeSlider->blockSignals(true); m_pOutputWidget->m_pOpBalanceSlider->blockSignals(true); m_pInputWidget->m_pIpVolumeSlider->blockSignals(true); m_pOutputWidget->m_pOpBalanceSlider->setValue(balanceVolume*100); m_pOutputWidget->m_pOpVolumeSlider->setValue(sinkVolume); m_pInputWidget->m_pIpVolumeSlider->setValue(sourceVolume); m_pOutputWidget->m_pOpVolumeSlider->blockSignals(false); m_pOutputWidget->m_pOpBalanceSlider->blockSignals(false); m_pInputWidget->m_pIpVolumeSlider->blockSignals(false); themeChangeIcons(); initListWidgetItem(); } /* * 初始化output/input list widget的选项 */ void UkmediaMainWidget::initListWidgetItem() { QString outputCardName = findCardName(m_pVolumeControl->defaultOutputCard,m_pVolumeControl->cardMap); QString outputPortLabel = findOutputPortLabel(m_pVolumeControl->defaultOutputCard,m_pVolumeControl->sinkPortName); findOutputListWidgetItem(outputCardName,outputPortLabel); qDebug() <<"initListWidgetItem" << m_pVolumeControl->defaultOutputCard << outputCardName <sinkPortName << outputPortLabel; QString inputCardName = findCardName(m_pVolumeControl->defaultInputCard,m_pVolumeControl->cardMap); QString inputPortLabel = findInputPortLabel(m_pVolumeControl->defaultInputCard,m_pVolumeControl->sourcePortName); findInputListWidgetItem(inputCardName,inputPortLabel); } void UkmediaMainWidget::themeChangeIcons() { int nInputValue = paVolumeToValue(m_pVolumeControl->getSourceVolume()); int nOutputValue = paVolumeToValue(m_pVolumeControl->getSinkVolume()); bool inputStatus = m_pVolumeControl->getSourceMute(); bool outputStatus = m_pVolumeControl->getSinkMute(); inputVolumeDarkThemeImage(nInputValue,inputStatus); outputVolumeDarkThemeImage(nOutputValue,outputStatus); m_pOutputWidget->m_pOutputIconBtn->repaint(); m_pInputWidget->m_pInputIconBtn->repaint(); } /* * 滑动条值转换成音量值 */ int UkmediaMainWidget::valueToPaVolume(int value) { return value / UKMEDIA_VOLUME_NORMAL * PA_VOLUME_NORMAL; } /* * 音量值转换成滑动条值 */ int UkmediaMainWidget::paVolumeToValue(int value) { return (value / PA_VOLUME_NORMAL * UKMEDIA_VOLUME_NORMAL) + 0.5; } QPixmap UkmediaMainWidget::drawDarkColoredPixmap(const QPixmap &source) { // QColor currentcolor=HighLightEffect::getCurrentSymbolicColor(); QColor gray(255,255,255); QImage img = source.toImage(); for (int x = 0; x < img.width(); x++) { for (int y = 0; y < img.height(); y++) { auto color = img.pixelColor(x, y); if (color.alpha() > 0) { if (qAbs(color.red()-gray.red())<20 && qAbs(color.green()-gray.green())<20 && qAbs(color.blue()-gray.blue())<20) { color.setRed(0); color.setGreen(0); color.setBlue(0); img.setPixelColor(x, y, color); } else { color.setRed(0); color.setGreen(0); color.setBlue(0); img.setPixelColor(x, y, color); } } } } return QPixmap::fromImage(img); } QPixmap UkmediaMainWidget::drawLightColoredPixmap(const QPixmap &source) { // QColor currentcolor=HighLightEffect::getCurrentSymbolicColor(); QColor gray(255,255,255); QColor standard (0,0,0); QImage img = source.toImage(); for (int x = 0; x < img.width(); x++) { for (int y = 0; y < img.height(); y++) { auto color = img.pixelColor(x, y); if (color.alpha() > 0) { if (qAbs(color.red()-gray.red())<20 && qAbs(color.green()-gray.green())<20 && qAbs(color.blue()-gray.blue())<20) { color.setRed(255); color.setGreen(255); color.setBlue(255); img.setPixelColor(x, y, color); } else { color.setRed(255); color.setGreen(255); color.setBlue(255); img.setPixelColor(x, y, color); } } } } return QPixmap::fromImage(img); } void UkmediaMainWidget::alertIconButtonSetIcon(bool state,int value) { QImage image; QColor color = QColor(0,0,0,216); if (mThemeName == UKUI_THEME_WHITE) { color = QColor(0,0,0,216); } else if (mThemeName == UKUI_THEME_BLACK) { color = QColor(255,255,255,216); } m_pSoundWidget->m_pAlertIconBtn->mColor = color; if (state) { image = QImage("/usr/share/ukui-media/img/audio-volume-muted.svg"); m_pSoundWidget->m_pAlertIconBtn->mImage = image; } else if (value <= 0) { image = QImage("/usr/share/ukui-media/img/audio-volume-muted.svg"); m_pSoundWidget->m_pAlertIconBtn->mImage = image; } else if (value > 0 && value <= 33) { image = QImage("/usr/share/ukui-media/img/audio-volume-low.svg"); m_pSoundWidget->m_pAlertIconBtn->mImage = image; } else if (value >33 && value <= 66) { image = QImage("/usr/share/ukui-media/img/audio-volume-medium.svg"); m_pSoundWidget->m_pAlertIconBtn->mImage = image; } else { image = QImage("/usr/share/ukui-media/img/audio-volume-high.svg"); m_pSoundWidget->m_pAlertIconBtn->mImage = image; } } void UkmediaMainWidget::createAlertSound(UkmediaMainWidget *pWidget) { const GList *list; m_pOutputWidget->m_pOutputListWidget->clear(); m_pInputWidget->m_pInputListWidget->clear(); cardMap.clear(); outputPortNameMap.clear(); outputPortMap.clear(); inputPortMap.clear(); inputPortNameMap.clear(); outputPortLabelMap.clear(); inputPortLabelMap.clear(); m_pVolumeControl->inputPortProfileNameMap.clear(); m_pVolumeControl->cardProfileMap.clear(); m_pVolumeControl->cardProfilePriorityMap.clear(); inputCardStreamMap.clear(); outputCardStreamMap.clear(); } /* 初始化combobox的值 */ void UkmediaMainWidget::comboboxCurrentTextInit() { QList existsPath = listExistsPath(); for (char * path : existsPath) { char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); char * allpath = strcat(prepath, path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray bba(allpath); if(QGSettings::isSchemaInstalled(ba)) { QGSettings * settings = new QGSettings(ba, bba); QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); int index = 0; for (int i=0;icount();i++) { QString str = m_pSoundList->at(i); if (str.contains(filenameStr,Qt::CaseSensitive)) { index = i; break; } } if (nameStr == "alert-sound") { QString displayName = m_pSoundNameList->at(index); m_pSoundWidget->m_pAlertSoundCombobox->setCurrentText(displayName); continue; } if (nameStr == "window-close") { QString displayName = m_pSoundNameList->at(index); continue; } else if (nameStr == "volume-changed") { QString displayName = m_pSoundNameList->at(index); m_pSoundWidget->m_pVolumeChangeCombobox->setCurrentText(displayName); continue; } else if (nameStr == "system-setting") { QString displayName = m_pSoundNameList->at(index); continue; } } else { continue; } } } /* 是否播放开机音乐 */ void UkmediaMainWidget::startupButtonSwitchChangedSlot(bool status) { bool bBootStatus = true; if (m_pBootSetting->keys().contains("startupMusic")) { bBootStatus = m_pBootSetting->get(UKUI_STARTUP_MUSIC_KEY).toBool(); if (bBootStatus != status) { m_pBootSetting->set(UKUI_STARTUP_MUSIC_KEY,status); } } } /* 是否播放关机音乐 */ void UkmediaMainWidget::poweroffButtonSwitchChangedSlot(bool status) { bool bBootStatus = true; if (m_pBootSetting->keys().contains("poweroffMusic")) { bBootStatus = m_pBootSetting->get(UKUI_POWEROFF_MUSIC_KEY).toBool(); if (bBootStatus != status) { m_pBootSetting->set(UKUI_POWEROFF_MUSIC_KEY,status); } } } /* 是否播放注销音乐 */ void UkmediaMainWidget::logoutMusicButtonSwitchChangedSlot(bool status) { bool bBootStatus = true; if (m_pBootSetting->keys().contains("logoutMusic")) { bBootStatus = m_pBootSetting->get(UKUI_LOGOUT_MUSIC_KEY).toBool(); if (bBootStatus != status) { m_pBootSetting->set(UKUI_LOGOUT_MUSIC_KEY,status); } } } /* 是否播放唤醒音乐 */ void UkmediaMainWidget::wakeButtonSwitchChangedSlot(bool status) { bool bBootStatus = true; if (m_pBootSetting->keys().contains("weakupMusic")) { bBootStatus = m_pBootSetting->get(UKUI_WAKEUP_MUSIC_KEY).toBool(); if (bBootStatus != status) { m_pBootSetting->set(UKUI_WAKEUP_MUSIC_KEY,status); } } } /* 提示音的开关 */ void UkmediaMainWidget::alertSoundButtonSwitchChangedSlot(bool status) { g_settings_set_boolean (m_pSoundSettings, EVENT_SOUNDS_KEY, status); /* if (status == true) { m_pSoundWidget->m_pAlertSoundVolumeWidget->show(); m_pSoundWidget->m_pSoundLayout->insertWidget(5,m_pSoundWidget->m_pAlertSoundVolumeWidget); } else { m_pSoundWidget->m_pAlertSoundVolumeWidget->hide(); m_pSoundWidget->m_pSoundLayout->removeWidget(m_pSoundWidget->m_pAlertSoundVolumeWidget); } */ } void UkmediaMainWidget::bootMusicSettingsChanged() { bool bBootStatus = true; bool status; if (m_pBootSetting->keys().contains("startupMusic")) { bBootStatus = m_pBootSetting->get(UKUI_STARTUP_MUSIC_KEY).toBool(); if (status != bBootStatus ) { m_pSoundWidget->m_pStartupButton->setChecked(bBootStatus); } } if (m_pBootSetting->keys().contains("poweroffMusic")) { bBootStatus = m_pBootSetting->get(UKUI_POWEROFF_MUSIC_KEY).toBool(); if (status != bBootStatus ) { m_pSoundWidget->m_pPoweroffButton->setChecked(bBootStatus); } } if (m_pBootSetting->keys().contains("logoutMusic")) { bBootStatus = m_pBootSetting->get(UKUI_LOGOUT_MUSIC_KEY).toBool(); if (status != bBootStatus ) { m_pSoundWidget->m_pLogoutButton->setChecked(bBootStatus); } } if (m_pBootSetting->keys().contains("weakupMusic")) { bBootStatus = m_pBootSetting->get(UKUI_WAKEUP_MUSIC_KEY).toBool(); if (status != bBootStatus ) { m_pSoundWidget->m_pWakeupMusicButton->setChecked(bBootStatus); } } } /* 系统主题更改 */ void UkmediaMainWidget::ukuiThemeChangedSlot(const QString &themeStr) { if (m_pThemeSetting->keys().contains("styleName")) { mThemeName = m_pThemeSetting->get(UKUI_THEME_NAME).toString(); } int nInputValue = getInputVolume(); int nOutputValue = getOutputVolume(); bool inputStatus = m_pVolumeControl->getSourceMute(); bool outputStatus = m_pVolumeControl->getSinkMute(); inputVolumeDarkThemeImage(nInputValue,inputStatus); outputVolumeDarkThemeImage(nOutputValue,outputStatus); m_pOutputWidget->m_pOutputIconBtn->repaint(); m_pSoundWidget->m_pAlertIconBtn->repaint(); m_pInputWidget->m_pInputIconBtn->repaint(); } /* 获取输入音量值 */ int UkmediaMainWidget::getInputVolume() { return m_pInputWidget->m_pIpVolumeSlider->value(); } /* 获取输出音量值 */ int UkmediaMainWidget::getOutputVolume() { return m_pOutputWidget->m_pOpVolumeSlider->value(); } /* 深色主题时输出音量图标 */ void UkmediaMainWidget::outputVolumeDarkThemeImage(int value,bool status) { QImage image; QColor color = QColor(0,0,0,216); if (mThemeName == UKUI_THEME_WHITE || mThemeName == "ukui-default") { color = QColor(0,0,0,216); } else if (mThemeName == UKUI_THEME_BLACK || mThemeName == "ukui-dark") { color = QColor(255,255,255,216); } m_pOutputWidget->m_pOutputIconBtn->mColor = color; if (status) { image = QIcon::fromTheme("audio-volume-muted-symbolic").pixmap(24,24).toImage(); } else if (value <= 0) { image = QIcon::fromTheme("audio-volume-muted-symbolic").pixmap(24,24).toImage(); } else if (value > 0 && value <= 33) { image = QIcon::fromTheme("audio-volume-low-symbolic").pixmap(24,24).toImage(); } else if (value >33 && value <= 66) { image = QIcon::fromTheme("audio-volume-medium-symbolic").pixmap(24,24).toImage(); } else { image = QIcon::fromTheme("audio-volume-high-symbolic").pixmap(24,24).toImage(); } m_pOutputWidget->m_pOutputIconBtn->mImage = image; } /* 输入音量图标 */ void UkmediaMainWidget::inputVolumeDarkThemeImage(int value,bool status) { QImage image; QColor color = QColor(0,0,0,190); if (mThemeName == UKUI_THEME_WHITE || mThemeName == "ukui-default") { color = QColor(0,0,0,190); } else if (mThemeName == UKUI_THEME_BLACK || mThemeName == "ukui-dark") { color = QColor(255,255,255,190); } m_pInputWidget->m_pInputIconBtn->mColor = color; if (status) { image = QIcon::fromTheme("microphone-sensitivity-muted-symbolic").pixmap(24,24).toImage(); } else if (value <= 0) { image = QIcon::fromTheme("microphone-sensitivity-muted-symbolic").pixmap(24,24).toImage(); } else if (value > 0 && value <= 33) { image = QIcon::fromTheme("microphone-sensitivity-low-symbolic").pixmap(24,24).toImage(); } else if (value >33 && value <= 66) { image = QIcon::fromTheme("microphone-sensitivity-medium-symbolic").pixmap(24,24).toImage(); } else { image = QIcon::fromTheme("microphone-sensitivity-high-symbolic").pixmap(24,24).toImage(); } m_pInputWidget->m_pInputIconBtn->mImage = image; } void UkmediaMainWidget::onKeyChanged (GSettings *settings,gchar *key,UkmediaMainWidget *m_pWidget) { Q_UNUSED(settings); g_debug("on key changed"); if (!strcmp (key, EVENT_SOUNDS_KEY) || !strcmp (key, SOUND_THEME_KEY) || !strcmp (key, INPUT_SOUNDS_KEY)) { updateTheme (m_pWidget); } } /* 更新主题 */ void UkmediaMainWidget::updateTheme (UkmediaMainWidget *m_pWidget) { g_debug("update theme"); char *pThemeName; gboolean feedBackEnabled; gboolean eventsEnabled; feedBackEnabled = g_settings_get_boolean(m_pWidget->m_pSoundSettings, INPUT_SOUNDS_KEY); eventsEnabled = g_settings_get_boolean(m_pWidget->m_pSoundSettings,EVENT_SOUNDS_KEY); // eventsEnabled = FALSE; if (eventsEnabled) { pThemeName = g_settings_get_string (m_pWidget->m_pSoundSettings, SOUND_THEME_KEY); } else { pThemeName = g_strdup (NO_SOUNDS_THEME_NAME); } qDebug() << "updateTheme" << pThemeName; //设置combox的主题 setComboxForThemeName (m_pWidget, pThemeName); updateAlertsFromThemeName (m_pWidget, pThemeName); } /* 设置主题名到combox */ void UkmediaMainWidget::setupThemeSelector (UkmediaMainWidget *m_pWidget) { g_debug("setup theme selector"); GHashTable *hash; const char * const *dataDirs; const char *m_pDataDir; char *dir; guint i; /* Add the theme names and their display name to a hash table, * makes it easy to avoid duplicate themes */ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); dataDirs = g_get_system_data_dirs (); for (i = 0; dataDirs[i] != nullptr; i++) { dir = g_build_filename (dataDirs[i], "sounds", nullptr); soundThemeInDir (m_pWidget,hash, dir); } m_pDataDir = g_get_user_data_dir (); dir = g_build_filename (m_pDataDir, "sounds", nullptr); soundThemeInDir (m_pWidget,hash, dir); /* If there isn't at least one theme, make everything * insensitive, LAME! */ if (g_hash_table_size (hash) == 0) { g_warning ("Bad setup, install the freedesktop sound theme"); g_hash_table_destroy (hash); return; } /* Add the themes to a combobox */ g_hash_table_destroy (hash); } /* 主题名所在目录 */ void UkmediaMainWidget::soundThemeInDir (UkmediaMainWidget *m_pWidget,GHashTable *hash,const char *dir) { Q_UNUSED(hash); qDebug() << "sound theme in dir" << dir; GDir *d; const char *m_pName; d = g_dir_open (dir, 0, nullptr); if (d == nullptr) { return; } while ((m_pName = g_dir_read_name (d)) != nullptr) { char *m_pDirName, *m_pIndex, *m_pIndexName; /* Look for directories */ m_pDirName = g_build_filename (dir, m_pName, nullptr); if (g_file_test (m_pDirName, G_FILE_TEST_IS_DIR) == FALSE) { continue; } /* Look for index files */ m_pIndex = g_build_filename (m_pDirName, "index.theme", nullptr); /* Check the name of the theme in the index.theme file */ m_pIndexName = loadIndexThemeName (m_pIndex, nullptr); if (m_pIndexName == nullptr) { continue; } gchar * themeName = g_settings_get_string (m_pWidget->m_pSoundSettings, SOUND_THEME_KEY); //设置主题到combox中 qDebug() << "sound theme in dir" << "displayname:" << m_pIndexName << "theme name:" << m_pName << "theme:"<< themeName; //屏蔽ubuntu custom 主题 if (m_pName && !strstr(m_pName,"ubuntu") && !strstr(m_pName,"freedesktop") && !strstr(m_pName,"custom")) { m_pWidget->m_pThemeDisplayNameList->append(m_pIndexName); m_pWidget->m_pThemeNameList->append(m_pName); m_pWidget->m_pSoundWidget->m_pSoundThemeCombobox->addItem(m_pIndexName); } } g_dir_close (d); } /* 加载下标的主题名 */ char *UkmediaMainWidget::loadIndexThemeName (const char *index,char **parent) { g_debug("load index theme name"); GKeyFile *file; char *indexname = nullptr; gboolean hidden; file = g_key_file_new (); if (g_key_file_load_from_file (file, index, G_KEY_FILE_KEEP_TRANSLATIONS, nullptr) == FALSE) { g_key_file_free (file); return nullptr; } /* Don't add hidden themes to the list */ hidden = g_key_file_get_boolean (file, "Sound Theme", "Hidden", nullptr); if (!hidden) { indexname = g_key_file_get_locale_string (file,"Sound Theme","Name",nullptr,nullptr); /* Save the parent theme, if there's one */ if (parent != nullptr) { *parent = g_key_file_get_string (file,"Sound Theme","Inherits",nullptr); } } g_key_file_free (file); return indexname; } /* 设置combox的主题名 */ void UkmediaMainWidget::setComboxForThemeName (UkmediaMainWidget *m_pWidget,const char *name) { g_debug("set combox for theme name"); gboolean found; int count = 0; /* If the name is empty, use "freedesktop" */ if (name == nullptr || *name == '\0') { name = "freedesktop"; } QString value; int index = -1; while(!found) { value = m_pWidget->m_pThemeNameList->at(count); found = (value != "" && value == name); count++; if( count >= m_pWidget->m_pThemeNameList->size() || found) { count = 0; break; } } if (m_pWidget->m_pThemeNameList->contains(name)) { index = m_pWidget->m_pThemeNameList->indexOf(name); value = m_pWidget->m_pThemeNameList->at(index); m_pWidget->m_pSoundWidget->m_pSoundThemeCombobox->setCurrentIndex(index); } /* When we can't find the theme we need to set, try to set the default * one "freedesktop" */ if (found) { } else if (strcmp (name, "freedesktop") != 0) {//设置为默认的主题 qDebug() << "设置为默认的主题" << "freedesktop"; g_debug ("not found, falling back to fdo"); setComboxForThemeName (m_pWidget, "freedesktop"); } } /* 更新报警音 */ void UkmediaMainWidget::updateAlertsFromThemeName (UkmediaMainWidget *m_pWidget,const gchar *m_pName) { g_debug("update alerts from theme name"); if (strcmp (m_pName, CUSTOM_THEME_NAME) != 0) { /* reset alert to default */ updateAlert (m_pWidget, DEFAULT_ALERT_ID); } else { int sound_type; char *linkname; linkname = nullptr; sound_type = getFileType ("bell-terminal", &linkname); g_debug ("Found link: %s", linkname); if (sound_type == SOUND_TYPE_CUSTOM) { updateAlert (m_pWidget, linkname); } } } /* 更新报警声音 */ void UkmediaMainWidget::updateAlert (UkmediaMainWidget *pWidget,const char *alertId) { Q_UNUSED(alertId) g_debug("update alert"); QString themeStr; char *theme; char *parent; gboolean is_custom; gboolean is_default; gboolean add_custom = false; gboolean remove_custom = false; QString nameStr; int index = -1; /* Get the current theme's name, and set the parent */ index = pWidget->m_pSoundWidget->m_pSoundThemeCombobox->currentIndex(); if (index != -1) { themeStr = pWidget->m_pThemeNameList->at(index); nameStr = pWidget->m_pThemeNameList->at(index); } else { themeStr = "freedesktop"; nameStr = "freedesktop"; } QByteArray ba = themeStr.toLatin1(); theme = ba.data(); QByteArray baParent = nameStr.toLatin1(); parent = baParent.data(); is_custom = strcmp (theme, CUSTOM_THEME_NAME) == 0; is_default = strcmp (alertId, DEFAULT_ALERT_ID) == 0; if (! is_custom && is_default) { /* remove custom just in case */ remove_custom = TRUE; } else if (! is_custom && ! is_default) { createCustomTheme (parent); saveAlertSounds(pWidget->m_pSoundWidget->m_pSoundThemeCombobox, alertId); add_custom = TRUE; } else if (is_custom && is_default) { saveAlertSounds(pWidget->m_pSoundWidget->m_pSoundThemeCombobox, alertId); /* after removing files check if it is empty */ if (customThemeDirIsEmpty ()) { remove_custom = TRUE; } } else if (is_custom && ! is_default) { saveAlertSounds(pWidget->m_pSoundWidget->m_pSoundThemeCombobox, alertId); } if (add_custom) { setComboxForThemeName (pWidget, CUSTOM_THEME_NAME); } else if (remove_custom) { setComboxForThemeName (pWidget, parent); } } /* 获取声音文件类型 */ int UkmediaMainWidget::getFileType (const char *sound_name,char **linked_name) { g_debug("get file type"); char *name, *filename; *linked_name = nullptr; name = g_strdup_printf ("%s.disabled", sound_name); filename = customThemeDirPath (name); if (g_file_test (filename, G_FILE_TEST_IS_REGULAR) != FALSE) { return SOUND_TYPE_OFF; } /* We only check for .ogg files because those are the * only ones we create */ name = g_strdup_printf ("%s.ogg", sound_name); filename = customThemeDirPath (name); g_free (name); if (g_file_test (filename, G_FILE_TEST_IS_SYMLINK) != FALSE) { *linked_name = g_file_read_link (filename, nullptr); g_free (filename); return SOUND_TYPE_CUSTOM; } g_free (filename); return SOUND_TYPE_BUILTIN; } /* 自定义主题路径 */ char *UkmediaMainWidget::customThemeDirPath (const char *child) { g_debug("custom theme dir path"); static char *dir = nullptr; const char *data_dir; if (dir == nullptr) { data_dir = g_get_user_data_dir (); dir = g_build_filename (data_dir, "sounds", CUSTOM_THEME_NAME, nullptr); } if (child == nullptr) return g_strdup (dir); return g_build_filename (dir, child, nullptr); } /* 获取报警声音文件的路径 */ void UkmediaMainWidget::populateModelFromDir (UkmediaMainWidget *m_pWidget,const char *dirname)//从目录查找报警声音文件 { g_debug("populate model from dir"); GDir *d; const char *name; char *path; d = g_dir_open (dirname, 0, nullptr); if (d == nullptr) { return; } while ((name = g_dir_read_name (d)) != nullptr) { if (! g_str_has_suffix (name, ".xml")) { continue; } QString themeName = name; QStringList temp = themeName.split("-"); themeName = temp.at(0); if (!m_pWidget->m_pSoundThemeList->contains(themeName)) { m_pWidget->m_pSoundThemeList->append(themeName); m_pWidget->m_pSoundThemeDirList->append(dirname); m_pWidget->m_pSoundThemeXmlNameList->append(name); } path = g_build_filename (dirname, name, nullptr); } char *pThemeName = g_settings_get_string (m_pWidget->m_pSoundSettings, SOUND_THEME_KEY); int themeIndex; if(m_pWidget->m_pSoundThemeList->contains(pThemeName)) { themeIndex = m_pWidget->m_pSoundThemeList->indexOf(pThemeName); if (themeIndex < 0 ) return; } else { themeIndex = 1; } QString dirName = m_pWidget->m_pSoundThemeDirList->at(themeIndex); QString xmlName = m_pWidget->m_pSoundThemeXmlNameList->at(themeIndex); path = g_build_filename (dirName.toLatin1().data(), xmlName.toLatin1().data(), nullptr); m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(true); m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->clear(); m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(false); populateModelFromFile (m_pWidget, path); //初始化声音主题 g_free (path); g_dir_close (d); } /* 获取报警声音文件 */ void UkmediaMainWidget::populateModelFromFile (UkmediaMainWidget *m_pWidget,const char *filename) { g_debug("populate model from file"); xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child; gboolean exists; exists = g_file_test (filename, G_FILE_TEST_EXISTS); if (! exists) { return; } doc = xmlParseFile (filename); if (doc == nullptr) { return; } root = xmlDocGetRootElement (doc); for (child = root->children; child; child = child->next) { if (xmlNodeIsText (child)) { continue; } if (xmlStrcmp (child->name, GVC_SOUND_SOUND) != 0) { continue; } populateModelFromNode (m_pWidget, child); } xmlFreeDoc (doc); } /* 从节点查找声音文件并加载到组合框中 */ void UkmediaMainWidget::populateModelFromNode (UkmediaMainWidget *m_pWidget,xmlNodePtr node) { g_debug("populate model from node"); xmlNodePtr child; xmlChar *filename; xmlChar *name; filename = nullptr; name = xmlGetAndTrimNames (node); for (child = node->children; child; child = child->next) { if (xmlNodeIsText (child)) { continue; } if (xmlStrcmp (child->name, GVC_SOUND_FILENAME) == 0) { filename = xmlNodeGetContent (child); } else if (xmlStrcmp (child->name, GVC_SOUND_NAME) == 0) { /* EH? should have been trimmed */ } } gchar * themeName = g_settings_get_string (m_pWidget->m_pSoundSettings, SOUND_THEME_KEY); //将找到的声音文件名设置到combox中 if (filename != nullptr && name != nullptr) { m_pWidget->m_pSoundList->append((const char *)filename); m_pWidget->m_pSoundNameList->append((const char *)name); m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->addItem((char *)name); m_pWidget->m_pSoundWidget->m_pLagoutCombobox->addItem((char *)name); m_pWidget->m_pSoundWidget->m_pVolumeChangeCombobox->addItem((char *)name); } xmlFree (filename); xmlFree (name); } /* Adapted from yelp-toc-pager.c */ xmlChar *UkmediaMainWidget::xmlGetAndTrimNames (xmlNodePtr node) { g_debug("xml get and trim names"); xmlNodePtr cur; xmlChar *keep_lang = nullptr; xmlChar *value; int j, keep_pri = INT_MAX; const gchar * const * langs = g_get_language_names (); value = nullptr; for (cur = node->children; cur; cur = cur->next) { if (! xmlStrcmp (cur->name, GVC_SOUND_NAME)) { xmlChar *cur_lang = nullptr; int cur_pri = INT_MAX; cur_lang = xmlNodeGetLang (cur); if (cur_lang) { for (j = 0; langs[j]; j++) { if (g_str_equal (cur_lang, langs[j])) { cur_pri = j; break; } } } else { cur_pri = INT_MAX - 1; } if (cur_pri <= keep_pri) { if (keep_lang) xmlFree (keep_lang); if (value) xmlFree (value); value = xmlNodeGetContent (cur); keep_lang = cur_lang; keep_pri = cur_pri; } else { if (cur_lang) xmlFree (cur_lang); } } } /* Delete all GVC_SOUND_NAME nodes */ cur = node->children; while (cur) { xmlNodePtr p_this = cur; cur = cur->next; if (! xmlStrcmp (p_this->name, GVC_SOUND_NAME)) { xmlUnlinkNode (p_this); xmlFreeNode (p_this); } } return value; } /* * 播放报警声音 */ void UkmediaMainWidget::playAlretSoundFromPath (UkmediaMainWidget *w,QString path) { g_debug("play alert sound from path"); gchar * themeName = g_settings_get_string (w->m_pSoundSettings, SOUND_THEME_KEY); if (strcmp (path.toLatin1().data(), DEFAULT_ALERT_ID) == 0) { if (themeName != NULL) { caPlayForWidget (w, 0, CA_PROP_APPLICATION_NAME, _("Sound Preferences"), CA_PROP_EVENT_ID, "bell-window-system", CA_PROP_CANBERRA_XDG_THEME_NAME, themeName, CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"), CA_PROP_CANBERRA_CACHE_CONTROL, "never", CA_PROP_APPLICATION_ID, "org.mate.VolumeControl", #ifdef CA_PROP_CANBERRA_ENABLE CA_PROP_CANBERRA_ENABLE, "1", #endif NULL); } else { caPlayForWidget (w, 0, CA_PROP_APPLICATION_NAME, _("Sound Preferences"), CA_PROP_EVENT_ID, "bell-window-system", CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"), CA_PROP_CANBERRA_CACHE_CONTROL, "never", CA_PROP_APPLICATION_ID, "org.mate.VolumeControl", #ifdef CA_PROP_CANBERRA_ENABLE CA_PROP_CANBERRA_ENABLE, "1", #endif NULL); } } else { caPlayForWidget (w, 0, CA_PROP_APPLICATION_NAME, _("Sound Preferences"), CA_PROP_MEDIA_FILENAME, path.toLatin1().data(), CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"), CA_PROP_CANBERRA_CACHE_CONTROL, "never", CA_PROP_APPLICATION_ID, "org.mate.VolumeControl", #ifdef CA_PROP_CANBERRA_ENABLE CA_PROP_CANBERRA_ENABLE, "1", #endif NULL); } } /* 点击combox播放声音 */ void UkmediaMainWidget::comboxIndexChangedSlot(int index) { g_debug("combox index changed slot"); QString sound_name = m_pSoundList->at(index); updateAlert(this,sound_name.toLatin1().data()); playAlretSoundFromPath(this,sound_name); QString fileName = m_pSoundList->at(index); QStringList list = fileName.split("/"); QString soundName = list.at(list.count()-1); QStringList eventIdList = soundName.split("."); QString eventId = eventIdList.at(0); QList existsPath = listExistsPath(); for (char * path : existsPath) { char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); char * allpath = strcat(prepath, path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray bba(allpath); if(QGSettings::isSchemaInstalled(ba)) { QGSettings * settings = new QGSettings(ba, bba); // QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); if (nameStr == "alert-sound") { settings->set(FILENAME_KEY,eventId); return; } } else { continue; } } } /* 设置窗口关闭的提示音 */ void UkmediaMainWidget::windowClosedComboboxChangedSlot(int index) { QString fileName = m_pSoundList->at(index); QStringList list = fileName.split("/"); QString soundName = list.at(list.count()-1); QStringList eventIdList = soundName.split("."); QString eventId = eventIdList.at(0); QList existsPath = listExistsPath(); for (char * path : existsPath) { char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); char * allpath = strcat(prepath, path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray bba(allpath); if(QGSettings::isSchemaInstalled(ba)) { QGSettings * settings = new QGSettings(ba, bba); // QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); if (nameStr == "window-close") { settings->set(FILENAME_KEY,eventId); return; } } else { continue; } } } /* 设置音量改变的提示声音 */ void UkmediaMainWidget::volumeChangedComboboxChangeSlot(int index) { QString sound_name = m_pSoundList->at(index); // updateAlert(this,sound_name.toLatin1().data()); playAlretSoundFromPath(this,sound_name); QString fileName = m_pSoundList->at(index); QStringList list = fileName.split("/"); QString soundName = list.at(list.count()-1); QStringList eventIdList = soundName.split("."); QString eventId = eventIdList.at(0); QList existsPath = listExistsPath(); for (char * path : existsPath) { char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); char * allpath = strcat(prepath, path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray bba(allpath); if(QGSettings::isSchemaInstalled(ba)) { QGSettings * settings = new QGSettings(ba, bba); // QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); if (nameStr == "volume-changed") { settings->set(FILENAME_KEY,eventId); return; } } else { continue; } } } void UkmediaMainWidget::settingMenuComboboxChangedSlot(int index) { QString fileName = m_pSoundList->at(index); QStringList list = fileName.split("/"); QString soundName = list.at(list.count()-1); QStringList eventIdList = soundName.split("."); QString eventId = eventIdList.at(0); QList existsPath = listExistsPath(); for (char * path : existsPath) { char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); char * allpath = strcat(prepath, path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray bba(allpath); if(QGSettings::isSchemaInstalled(ba)) { QGSettings * settings = new QGSettings(ba, bba); QString nameStr = settings->get(NAME_KEY).toString(); if (nameStr == "system-setting") { settings->set(FILENAME_KEY,eventId); return; } } else { continue; } } } /* 点击输入音量按钮静音 */ void UkmediaMainWidget::inputMuteButtonSlot() { m_pVolumeControl->setSourceMute(!m_pVolumeControl->sourceMuted); inputVolumeDarkThemeImage(paVolumeToValue(m_pVolumeControl->sourceVolume),!m_pVolumeControl->sourceMuted); m_pOutputWidget->m_pOutputIconBtn->repaint(); } /* 点击输出音量按钮静音 */ void UkmediaMainWidget::outputMuteButtonSlot() { m_pVolumeControl->setSinkMute(!m_pVolumeControl->sinkMuted); outputVolumeDarkThemeImage(paVolumeToValue(m_pVolumeControl->sinkVolume),!m_pVolumeControl->sinkMuted); m_pOutputWidget->m_pOutputIconBtn->repaint(); } /* 点击声音主题实现主题切换 */ void UkmediaMainWidget::themeComboxIndexChangedSlot(int index) { Q_UNUSED(index); g_debug("theme combox index changed slot"); if (index == -1) { return; } //设置系统主题 QString theme = m_pThemeNameList->at(index); QByteArray ba = theme.toLatin1(); const char *m_pThemeName = ba.data(); if (strcmp(m_pThemeName,"freedesktop") == 0) { int index = 0; for (int i=0;icount();i++) { QString str = m_pSoundList->at(i); if (str.contains("gudou",Qt::CaseSensitive)) { index = i; break; } } QString displayName = m_pSoundNameList->at(index); m_pSoundWidget->m_pAlertSoundCombobox->setCurrentText(displayName); } QString dirName = m_pSoundThemeDirList->at(index); int themeIndex = m_pSoundThemeList->indexOf(m_pThemeName); if (themeIndex < 0 ) return; //qDebug() << "index changed:" << m_pSoundThemeXmlNameList->at(themeIndex) << m_pThemeNameList->at(index) << m_pThemeName << dirName.toLatin1().data() ;//<< path; QString xmlName = m_pSoundThemeXmlNameList->at(themeIndex); const gchar *path = g_build_filename (dirName.toLatin1().data(), xmlName.toLatin1().data(), nullptr); m_pSoundList->clear(); m_pSoundNameList->clear(); m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(true); m_pSoundWidget->m_pLagoutCombobox->blockSignals(true); m_pSoundWidget->m_pVolumeChangeCombobox->blockSignals(true); m_pSoundWidget->m_pAlertSoundCombobox->clear(); m_pSoundWidget->m_pLagoutCombobox->clear(); m_pSoundWidget->m_pVolumeChangeCombobox->clear(); m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(false); m_pSoundWidget->m_pLagoutCombobox->blockSignals(false); m_pSoundWidget->m_pVolumeChangeCombobox->blockSignals(false); populateModelFromFile (this, path); /* special case for no sounds */ if (strcmp (m_pThemeName, NO_SOUNDS_THEME_NAME) == 0) { //设置提示音关闭 g_settings_set_boolean (m_pSoundSettings, EVENT_SOUNDS_KEY, FALSE); return; } else { g_settings_set_boolean (m_pSoundSettings, EVENT_SOUNDS_KEY, TRUE); } } /* 滚动输出音量滑动条 */ void UkmediaMainWidget::outputWidgetSliderChangedSlot(int value) { int volume = valueToPaVolume(value); m_pVolumeControl->getDefaultSinkIndex(); m_pVolumeControl->setSinkVolume(m_pVolumeControl->sinkIndex,volume); qDebug() << "outputWidgetSliderChangedSlot" << value <m_pOpVolumePercentLabel->setText(percent); m_pOutputWidget->m_pOutputIconBtn->repaint(); } void UkmediaMainWidget::timeSliderSlot() { if(mouseReleaseState){ int value = m_pOutputWidget->m_pOpVolumeSlider->value(); QString percent; bool status = false; percent = QString::number(value); int volume = value*65536/100; if (value <= 0) { status = true; percent = QString::number(0); } else { if (firstEnterSystem) { } else { } } firstEnterSystem = false; outputVolumeDarkThemeImage(value,status); percent.append("%"); m_pOutputWidget->m_pOpVolumePercentLabel->setText(percent); m_pOutputWidget->m_pOutputIconBtn->repaint(); mouseReleaseState = false; mousePress = false; timeSlider->stop(); } else{ timeSlider->start(50); } } /* 滚动输入滑动条 */ void UkmediaMainWidget::inputWidgetSliderChangedSlot(int value) { int volume = valueToPaVolume(value); m_pVolumeControl->setSourceVolume(m_pVolumeControl->sourceIndex,volume); //输入图标修改成深色主题 inputVolumeDarkThemeImage(value,m_pVolumeControl->sourceMuted); m_pInputWidget->m_pInputIconBtn->repaint(); QString percent = QString::number(value); value = value * 65536 / 100; percent.append("%"); m_pInputWidget->m_pInputIconBtn->repaint(); m_pInputWidget->m_pIpVolumePercentLabel->setText(percent); } /* * 平衡值改变 */ void UkmediaMainWidget::balanceSliderChangedSlot(int value) { gdouble volume = value/100.0; value = valueToPaVolume(m_pOutputWidget->m_pOpVolumeSlider->value()); m_pVolumeControl->setBalanceVolume(m_pVolumeControl->sinkIndex,value,volume); qDebug() << "balanceSliderChangedSlot" <= 0) { m_pInputWidget->m_pInputLevelProgressBar->setEnabled(true); int value = qRound(v * m_pInputWidget->m_pInputLevelProgressBar->maximum()); m_pInputWidget->m_pInputLevelProgressBar->setValue(value); } else { m_pInputWidget->m_pInputLevelProgressBar->setEnabled(false); m_pInputWidget->m_pInputLevelProgressBar->setValue(0); } } /* * 更新设备端口 */ void UkmediaMainWidget::updateDevicePort() { QMap>::iterator it; QMap::iterator at; QMap temp; currentInputPortLabelMap.clear(); currentOutputPortLabelMap.clear(); if (firstEntry == true) { for(it = m_pVolumeControl->outputPortMap.begin();it!=m_pVolumeControl->outputPortMap.end();) { temp = it.value(); for (at=temp.begin();at!=temp.end();) { qDebug() << "updateDevicePort" << firstEntry << it.key() << at.value(); QString cardName = findCardName(it.key(),m_pVolumeControl->cardMap); addOutputListWidgetItem(at.value(),cardName); ++at; } ++it; } for(it = m_pVolumeControl->inputPortMap.begin();it!=m_pVolumeControl->inputPortMap.end();) { temp = it.value(); for (at=temp.begin();at!=temp.end();) { qDebug() << "updateDevicePort" << firstEntry << it.key() << at.value(); QString cardName = findCardName(it.key(),m_pVolumeControl->cardMap); addInputListWidgetItem(at.value(),cardName); ++at; } ++it; } } else { //记录上一次output label for (int i=0;im_pOutputListWidget->count();i++) { QMap::iterator at; QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(i); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); int index; for (at=m_pVolumeControl->cardMap.begin();at!=m_pVolumeControl->cardMap.end();) { if (wid->deviceLabel->text() == at.value()) { index = at.key(); break; } ++at; } currentOutputPortLabelMap.insertMulti(index,wid->portLabel->text()); qDebug() << index << "current output item ************" << wid->deviceLabel->text() <portLabel->text() ;//<< w->m_pOutputPortLabelList->at(i); } for (int i=0;im_pInputListWidget->count();i++) { QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(i); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); int index; int count; QMap::iterator at; for (at=m_pVolumeControl->cardMap.begin();at!=m_pVolumeControl->cardMap.end();) { if (wid->deviceLabel->text() == at.value()) { index = at.key(); break; } ++at; ++count; } currentInputPortLabelMap.insertMulti(index,wid->portLabel->text()); } m_pInputWidget->m_pInputListWidget->blockSignals(true); deleteNotAvailableOutputPort(); addAvailableOutputPort(); deleteNotAvailableInputPort(); addAvailableInputPort(); m_pInputWidget->m_pInputListWidget->blockSignals(false); } if (m_pOutputWidget->m_pOutputListWidget->count() > 0 || m_pInputWidget->m_pInputListWidget->count()) { firstEntry = false; } } void UkmediaMainWidget::updateListWidgetItemSlot() { qDebug() << "updateListWidgetItemSlot---------"; initListWidgetItem(); } /* * output list widget选项改变,设置对应的输出设备 */ void UkmediaMainWidget::outputListWidgetCurrentRowChangedSlot(int row) { //当所有可用的输出设备全部移除,台式机才会出现该情况 if (row == -1) return; QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(row); if (item == nullptr) { qDebug() <<"output current item is null"; } UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); QListWidgetItem *inputCurrrentItem = m_pInputWidget->m_pInputListWidget->currentItem(); UkuiListWidgetItem *inputWid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(inputCurrrentItem); bool isContainBlue = inputDeviceContainBluetooth(); //当输出设备从蓝牙切换到其他设备时,需将蓝牙声卡的配置文件切换为a2dp-sink if (isContainBlue && (strstr(m_pVolumeControl->defaultSourceName,"headset_head_unit") || strstr(m_pVolumeControl->defaultSourceName,"bt_sco_sink"))) { QString cardName = blueCardName(); setCardProfile(cardName,"a2dp_sink"); } QMap::iterator it; QMap>::iterator inputProfileMap; QString endOutputProfile = ""; QString endInputProfile = ""; int count,i; for (it=m_pVolumeControl->profileNameMap.begin(),i=0;it!= m_pVolumeControl->profileNameMap.end();++i) { if (it.key() == wid->portLabel->text()) { count = i; endOutputProfile = it.value(); } ++it; } if (inputCurrrentItem != nullptr) { QMap ::iterator it; QMap temp; int index = findCardIndex(inputWid->deviceLabel->text(),m_pVolumeControl->cardMap); for (inputProfileMap=m_pVolumeControl->inputPortProfileNameMap.begin(),count=0;inputProfileMap!= m_pVolumeControl->inputPortProfileNameMap.end();count++) { if (inputProfileMap.key() == index) { temp = inputProfileMap.value(); for(it = temp.begin(); it != temp.end();){ if(it.key() == inputWid->portLabel->text()){ endInputProfile = it.value(); } ++it; } } ++inputProfileMap; } } qDebug() << "outputListWidgetCurrentRowChangedSlot" << row << wid->deviceLabel->text() << endOutputProfile <deviceLabel->text() == inputWid->deviceLabel->text()) || \ wid->deviceLabel->text() == "alsa_card.platform-sound_DA_combine_v5" && inputWid->deviceLabel->text() == "3a.algo") { QString setProfile = endOutputProfile; if (!endOutputProfile.contains("input:analog-stereo") || !endOutputProfile.contains("HiFi")) { setProfile += "+"; setProfile +=endInputProfile; } setCardProfile(wid->deviceLabel->text(),setProfile); setDefaultOutputPortDevice(wid->deviceLabel->text(),wid->portLabel->text()); } //如果选择的输入输出设备不是同一块声卡,需要设置一个优先级高的配置文件 else { int index = findCardIndex(wid->deviceLabel->text(),m_pVolumeControl->cardMap); QMap >::iterator it; QString profileName; for(it=m_pVolumeControl->cardProfileMap.begin();it!=m_pVolumeControl->cardProfileMap.end();) { if (it.key() == index) { if (strstr(endOutputProfile.toLatin1().data(),"headset_head_unit")) endOutputProfile = "a2dp_sink"; profileName = findHighPriorityProfile(index,endOutputProfile); } ++it; } QString setProfile = profileName; setCardProfile(wid->deviceLabel->text(),setProfile); setDefaultOutputPortDevice(wid->deviceLabel->text(),wid->portLabel->text()); } qDebug() << "active output port:" << wid->portLabel->text(); } /* * input list widget选项改变,设置对应的输入设备 */ void UkmediaMainWidget::inputListWidgetCurrentRowChangedSlot(int row) { //当所有可用的输入设备全部移除,台式机才会出现该情况 if (row == -1) return; QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); QListWidgetItem *outputCurrrentItem = m_pOutputWidget->m_pOutputListWidget->currentItem(); UkuiListWidgetItem *outputWid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(outputCurrrentItem); bool isContainBlue = inputDeviceContainBluetooth(); qDebug() << "inputListWidgetCurrentRowChangedSlot" << row << isContainBlue << m_pVolumeControl->defaultSourceName; //当输出设备从蓝牙切换到其他设备时,需将蓝牙声卡的配置文件切换为a2dp-sink if (isContainBlue && (strstr(m_pVolumeControl->defaultSinkName,"headset_head_unit") || strstr(m_pVolumeControl->defaultSourceName,"bt_sco_source"))) { QString cardName = blueCardName(); setCardProfile(cardName,"a2dp_sink"); } if(wid->deviceLabel->text().contains("bluez_card")) { isCheckBluetoothInput = true; } else { isCheckBluetoothInput = false; } QMap>::iterator it; QMap temp; QMap::iterator at; QString endOutputProfile = ""; QString endInputProfile = ""; int index = findCardIndex(wid->deviceLabel->text(),m_pVolumeControl->cardMap); for (it=m_pVolumeControl->inputPortProfileNameMap.begin();it!= m_pVolumeControl->inputPortProfileNameMap.end();) { if (it.key() == index) { temp = it.value(); for(at=temp.begin();at!=temp.end();){ if(at.key() == wid->portLabel->text()){ endInputProfile = at.value(); } ++at; } } ++it; } if (outputCurrrentItem != nullptr) { for (at=m_pVolumeControl->profileNameMap.begin();at!= m_pVolumeControl->profileNameMap.end();) { if (at.key() == outputWid->portLabel->text()) { endOutputProfile = at.value(); } ++at; } } //如果选择的输入输出设备为同一个声卡,则追加指定输入输出端口属于的配置文件 if (outputCurrrentItem != nullptr && wid->deviceLabel->text() == outputWid->deviceLabel->text()) { QString setProfile; //有些声卡的配置文件默认只有输入/输出设备或者配置文件包含了输出输入设备,因此只需要取其中一个配置文件即可 if (endOutputProfile == "a2dp-sink" || endInputProfile == "headset_head_unit" || endOutputProfile == "HiFi" ) { setProfile += endInputProfile; } else { setProfile += endOutputProfile; setProfile += "+"; setProfile +=endInputProfile; } setCardProfile(wid->deviceLabel->text(),setProfile); setDefaultInputPortDevice(wid->deviceLabel->text(),wid->portLabel->text()); } //如果选择的输入输出设备不是同一块声卡,需要设置一个优先级高的配置文件 else { int index = findCardIndex(wid->deviceLabel->text(),m_pVolumeControl->cardMap); QMap >::iterator it; QString profileName; for(it=m_pVolumeControl->cardProfileMap.begin();it!=m_pVolumeControl->cardProfileMap.end();) { if (it.key() == index) { QStringList list= it.value(); profileName = findHighPriorityProfile(index,endInputProfile); if (list.contains(endOutputProfile)) { } } ++it; } QString setProfile = profileName; setCardProfile(wid->deviceLabel->text(),setProfile); setDefaultInputPortDevice(wid->deviceLabel->text(),wid->portLabel->text()); } qDebug() << "active input port:" << wid->portLabel->text() << isCheckBluetoothInput; } gboolean UkmediaMainWidget::saveAlertSounds (QComboBox *combox,const char *id) { const char *sounds[3] = { "bell-terminal", "bell-window-system", NULL }; char *path; if (strcmp (id, DEFAULT_ALERT_ID) == 0) { deleteOldFiles (sounds); deleteDisabledFiles (sounds); } else { deleteOldFiles (sounds); deleteDisabledFiles (sounds); addCustomFile (sounds, id); } /* And poke the directory so the theme gets updated */ path = customThemeDirPath(NULL); if (utime (path, NULL) != 0) { g_warning ("Failed to update mtime for directory '%s': %s", path, g_strerror (errno)); } g_free (path); return FALSE; } void UkmediaMainWidget::deleteOldFiles (const char **sounds) { guint i; for (i = 0; sounds[i] != NULL; i++) { deleteOneFile (sounds[i], "%s.ogg"); } } void UkmediaMainWidget::deleteOneFile (const char *sound_name, const char *pattern) { GFile *file; char *name, *filename; name = g_strdup_printf (pattern, sound_name); filename = customThemeDirPath(name); g_free (name); file = g_file_new_for_path (filename); g_free (filename); cappletFileDeleteRecursive (file, NULL); g_object_unref (file); } void UkmediaMainWidget::deleteDisabledFiles (const char **sounds) { guint i; for (i = 0; sounds[i] != NULL; i++) { deleteOneFile (sounds[i], "%s.disabled"); } } void UkmediaMainWidget::addCustomFile (const char **sounds, const char *filename) { guint i; for (i = 0; sounds[i] != NULL; i++) { GFile *file; char *name, *path; /* We use *.ogg because it's the first type of file that * libcanberra looks at */ name = g_strdup_printf ("%s.ogg", sounds[i]); path = customThemeDirPath(name); g_free (name); /* In case there's already a link there, delete it */ g_unlink (path); file = g_file_new_for_path (path); g_free (path); /* Create the link */ g_file_make_symbolic_link (file, filename, NULL, NULL); g_object_unref (file); } } /** * capplet_file_delete_recursive : * @file : * @error : * * A utility routine to delete files and/or directories, * including non-empty directories. **/ gboolean UkmediaMainWidget::cappletFileDeleteRecursive (GFile *file, GError **error) { GFileInfo *info; GFileType type; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, error); if (info == NULL) { return FALSE; } type = g_file_info_get_file_type (info); g_object_unref (info); if (type == G_FILE_TYPE_DIRECTORY) { return directoryDeleteRecursive (file, error); } else { return g_file_delete (file, NULL, error); } } gboolean UkmediaMainWidget::directoryDeleteRecursive (GFile *directory, GError **error) { GFileEnumerator *enumerator; GFileInfo *info; gboolean success = TRUE; enumerator = g_file_enumerate_children (directory, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, error); if (enumerator == NULL) return FALSE; while (success && (info = g_file_enumerator_next_file (enumerator, NULL, NULL))) { GFile *child; child = g_file_get_child (directory, g_file_info_get_name (info)); if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { success = directoryDeleteRecursive (child, error); } g_object_unref (info); if (success) success = g_file_delete (child, NULL, error); } g_file_enumerator_close (enumerator, NULL, NULL); if (success) success = g_file_delete (directory, NULL, error); return success; } void UkmediaMainWidget::createCustomTheme (const char *parent) { GKeyFile *keyfile; char *data; char *path; /* Create the custom directory */ path = customThemeDirPath(NULL); g_mkdir_with_parents (path, 0755); g_free (path); /* Set the data for index.theme */ keyfile = g_key_file_new (); g_key_file_set_string (keyfile, "Sound Theme", "Name", _("Custom")); g_key_file_set_string (keyfile, "Sound Theme", "Inherits", parent); g_key_file_set_string (keyfile, "Sound Theme", "Directories", "."); data = g_key_file_to_data (keyfile, NULL, NULL); g_key_file_free (keyfile); /* Save the index.theme */ path = customThemeDirPath ("index.theme"); g_file_set_contents (path, data, -1, NULL); g_free (path); g_free (data); customThemeUpdateTime (); } /* This function needs to be called after each individual * changeset to the theme */ void UkmediaMainWidget::customThemeUpdateTime (void) { char *path; path = customThemeDirPath (NULL); utime (path, NULL); g_free (path); } gboolean UkmediaMainWidget::customThemeDirIsEmpty (void) { char *dir; GFile *file; gboolean is_empty; GFileEnumerator *enumerator; GFileInfo *info; GError *error = NULL; dir = customThemeDirPath(NULL); file = g_file_new_for_path (dir); g_free (dir); is_empty = TRUE; enumerator = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &error); if (enumerator == NULL) { g_warning ("Unable to enumerate files: %s", error->message); g_error_free (error); goto out; } while (is_empty && (info = g_file_enumerator_next_file (enumerator, NULL, NULL))) { if (strcmp ("index.theme", g_file_info_get_name (info)) != 0) { is_empty = FALSE; } g_object_unref (info); } g_file_enumerator_close (enumerator, NULL, NULL); out: g_object_unref (file); return is_empty; } int UkmediaMainWidget::caPlayForWidget(UkmediaMainWidget *w, uint32_t id, ...) { va_list ap; int ret; ca_proplist *p; if ((ret = ca_proplist_create(&p)) < 0) return ret; if ((ret = caProplistSetForWidget(p, w)) < 0) return -1; va_start(ap, id); ret = caProplistMergeAp(p, ap); va_end(ap); if (ret < 0) return -1; ca_context *c ; ca_context_create(&c); ret = ca_context_play_full(c, id, p, NULL, NULL); return ret; } int UkmediaMainWidget::caProplistMergeAp(ca_proplist *p, va_list ap) { int ret; for (;;) { const char *key, *value; if (!(key = va_arg(ap, const char*))) break; if (!(value = va_arg(ap, const char*))) return CA_ERROR_INVALID; if ((ret = ca_proplist_sets(p, key, value)) < 0) return ret; } return CA_SUCCESS; } int UkmediaMainWidget::caProplistSetForWidget(ca_proplist *p, UkmediaMainWidget *widget) { int ret; const char *t; QScreen *screen; gint x = -1; gint y = -1; gint width = -1; gint height = -1; gint screen_width = -1; gint screen_height = -1; if ((t = widget->windowTitle().toLatin1().data())) if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_NAME, t)) < 0) return ret; if (t) if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ID, t)) < 0) return ret; if ((t = widget->windowIconText().toLatin1().data())) if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ICON_NAME, t)) < 0) return ret; if (screen = qApp->primaryScreen()) { if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_SCREEN, "%i", 0)) < 0) return ret; } width = widget->size().width(); height = widget->size().height(); if (width > 0) if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_WIDTH, "%i", width)) < 0) return ret; if (height > 0) if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HEIGHT, "%i", height)) < 0) return ret; if (x >= 0 && width > 0) { screen_width = qApp->primaryScreen()->size().width(); x += width/2; x = CA_CLAMP(x, 0, screen_width-1); /* We use these strange format strings here to avoid that libc * applies locale information on the formatting of floating * numbers. */ if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HPOS, "%i.%03i", (int) (x/(screen_width-1)), (int) (1000.0*x/(screen_width-1)) % 1000)) < 0) return ret; } if (y >= 0 && height > 0) { screen_height = qApp->primaryScreen()->size().height(); y += height/2; y = CA_CLAMP(y, 0, screen_height-1); if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_VPOS, "%i.%03i", (int) (y/(screen_height-1)), (int) (1000.0*y/(screen_height-1)) % 1000)) < 0) return ret; } return CA_SUCCESS; } UkmediaMainWidget::~UkmediaMainWidget() { } /* * 添加output port到output list widget */ void UkmediaMainWidget::addOutputListWidgetItem(QString portName, QString cardName) { UkuiListWidgetItem *itemW = new UkuiListWidgetItem(this); int i = m_pOutputWidget->m_pOutputListWidget->count(); QListWidgetItem * item = new QListWidgetItem(m_pOutputWidget->m_pOutputListWidget); item->setSizeHint(QSize(200,64)); //QSize(120, 40) spacing: 12px; m_pOutputWidget->m_pOutputListWidget->blockSignals(true); m_pOutputWidget->m_pOutputListWidget->setItemWidget(item, itemW); m_pOutputWidget->m_pOutputListWidget->blockSignals(false); itemW->setLabelText(portName,cardName); m_pOutputWidget->m_pOutputListWidget->blockSignals(true); m_pOutputWidget->m_pOutputListWidget->insertItem(i,item); m_pOutputWidget->m_pOutputListWidget->blockSignals(false); } /* * 添加input port到input list widget */ void UkmediaMainWidget::addInputListWidgetItem(QString portName, QString cardName) { UkuiListWidgetItem *itemW = new UkuiListWidgetItem(this); int i = m_pInputWidget->m_pInputListWidget->count(); QListWidgetItem * item = new QListWidgetItem(m_pInputWidget->m_pInputListWidget); item->setSizeHint(QSize(200,64)); //QSize(120, 40) spacing: 12px; m_pInputWidget->m_pInputListWidget->setItemWidget(item, itemW); itemW->setLabelText(portName,cardName); m_pInputWidget->m_pInputListWidget->blockSignals(true); m_pInputWidget->m_pInputListWidget->insertItem(i,item); m_pInputWidget->m_pInputListWidget->blockSignals(false); } /* * 移除output list widget上不可用的输出端口 */ void UkmediaMainWidget::deleteNotAvailableOutputPort() { qDebug() << "deleteNotAvailableOutputPort"; //删除不可用的输出端口 QMap::iterator it; for(it=currentOutputPortLabelMap.begin();it!=currentOutputPortLabelMap.end();) { //没找到,需要删除 if (outputPortIsNeedDelete(it.key(),it.value())) { int index = indexOfOutputPortInOutputListWidget(it.value()); if (index == -1) return; m_pOutputWidget->m_pOutputListWidget->blockSignals(true); QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->takeItem(index); m_pOutputWidget->m_pOutputListWidget->removeItemWidget(item); m_pOutputWidget->m_pOutputListWidget->blockSignals(false); it = currentOutputPortLabelMap.erase(it); continue; } ++it; } // m_pVolumeControl->removeProfileMap(); } /* * 在input list widget删除不可用的端口 */ void UkmediaMainWidget::deleteNotAvailableInputPort() { //删除不可用的输入端口 QMap::iterator it; for(it=currentInputPortLabelMap.begin();it!=currentInputPortLabelMap.end();) { //没找到,需要删除 if (inputPortIsNeedDelete(it.key(),it.value())) { int index = indexOfInputPortInInputListWidget(it.value()); if (index == -1) return; m_pInputWidget->m_pInputListWidget->blockSignals(true); QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->takeItem(index); m_pInputWidget->m_pInputListWidget->removeItemWidget(item); m_pInputWidget->m_pInputListWidget->blockSignals(false); it = currentInputPortLabelMap.erase(it); continue; } ++it; } // m_pVolumeControl->removeInputProfile(); } /* * 添加可用的输出端口到output list widget */ void UkmediaMainWidget::addAvailableOutputPort() { QMap>::iterator at; QMap::iterator it; QMap tempMap; int i = m_pOutputWidget->m_pOutputListWidget->count(); //增加端口 for(at=m_pVolumeControl->outputPortMap.begin();at!=m_pVolumeControl->outputPortMap.end();) { tempMap = at.value(); for (it=tempMap.begin();it!=tempMap.end();) { //需添加到list widget if (outputPortIsNeedAdd(at.key(),it.value())) { qDebug() << "add output list widget" << at.key()<< it.value(); UkuiListWidgetItem *itemW = new UkuiListWidgetItem(this); QListWidgetItem * item = new QListWidgetItem(m_pOutputWidget->m_pOutputListWidget); item->setSizeHint(QSize(200,64)); //QSize(120, 40) spacing: 12px; m_pOutputWidget->m_pOutputListWidget->blockSignals(true); m_pOutputWidget->m_pOutputListWidget->setItemWidget(item, itemW); m_pOutputWidget->m_pOutputListWidget->blockSignals(false); itemW->setLabelText(it.value(),findCardName(at.key(),m_pVolumeControl->cardMap)); currentOutputPortLabelMap.insertMulti(at.key(),it.value()); m_pOutputWidget->m_pOutputListWidget->blockSignals(true); m_pOutputWidget->m_pOutputListWidget->insertItem(i,item); m_pOutputWidget->m_pOutputListWidget->blockSignals(false); } ++it; } ++at; } } /* * 添加可用的输入端口到input list widget */ void UkmediaMainWidget::addAvailableInputPort() { QMap>::iterator at; QMap::iterator it; QMap tempMap; int i = m_pInputWidget->m_pInputListWidget->count(); //增加端口 for(at=m_pVolumeControl->inputPortMap.begin();at!=m_pVolumeControl->inputPortMap.end();) { tempMap = at.value(); for (it=tempMap.begin();it!=tempMap.end();) { //需添加到list widget if (inputPortIsNeedAdd(at.key(),it.value())) { UkuiListWidgetItem *itemW = new UkuiListWidgetItem(this); QListWidgetItem * item = new QListWidgetItem(m_pInputWidget->m_pInputListWidget); item->setSizeHint(QSize(200,64)); //QSize(120, 40) spacing: 12px; m_pInputWidget->m_pInputListWidget->blockSignals(true); m_pInputWidget->m_pInputListWidget->setItemWidget(item, itemW); m_pInputWidget->m_pInputListWidget->blockSignals(false); itemW->setLabelText(it.value(),findCardName(at.key(),m_pVolumeControl->cardMap)); currentInputPortLabelMap.insertMulti(at.key(),it.value()); m_pInputWidget->m_pInputListWidget->blockSignals(true); m_pInputWidget->m_pInputListWidget->insertItem(i,item); m_pInputWidget->m_pInputListWidget->blockSignals(false); } ++it; } ++at; } } /* * 当前的输出端口是否应该在output list widget上删除 */ bool UkmediaMainWidget::outputPortIsNeedDelete(int index, QString name) { QMap>::iterator it; QMap::iterator at; QMap portMap; for(it = m_pVolumeControl->outputPortMap.begin();it!=m_pVolumeControl->outputPortMap.end();) { if (it.key() == index) { portMap = it.value(); for (at=portMap.begin();at!=portMap.end();) { if (name == at.value()) { return false; } ++at; } } ++it; } return true; } /* * 当前的输出端口是否应该添加到output list widget上 */ bool UkmediaMainWidget::outputPortIsNeedAdd(int index, QString name) { QMap::iterator it; for(it=currentOutputPortLabelMap.begin();it!=currentOutputPortLabelMap.end();) { if ( index == it.key() && name == it.value()) { return false; } ++it; } return true; } /* * 当前的输出端口是否应该在input list widget上删除 */ bool UkmediaMainWidget::inputPortIsNeedDelete(int index, QString name) { QMap>::iterator it; QMap::iterator at; QMap portMap; for(it = m_pVolumeControl->inputPortMap.begin();it!=m_pVolumeControl->inputPortMap.end();) { if (it.key() == index) { portMap = it.value(); for (at=portMap.begin();at!=portMap.end();) { if (name == at.value()) { return false; } ++at; } } ++it; } return true; } /* * 当前的输出端口是否应该添加到input list widget上 */ bool UkmediaMainWidget::inputPortIsNeedAdd(int index, QString name) { QMap::iterator it; for(it=currentInputPortLabelMap.begin();it!=currentInputPortLabelMap.end();) { if ( index == it.key() && name == it.value()) { return false; } ++it; } return true; } //查找指定声卡名的索引 int UkmediaMainWidget::findCardIndex(QString cardName, QMap cardMap) { QMap::iterator it; for(it=cardMap.begin();it!=cardMap.end();) { if (it.value() == cardName) { return it.key(); } ++it; } return -1; } /* * 根据声卡索引查找声卡名 */ QString UkmediaMainWidget::findCardName(int index,QMap cardMap) { QMap::iterator it; for(it=cardMap.begin();it!=cardMap.end();) { if (it.key() == index) { return it.value(); } ++it; } return ""; } /* 查找名称为PortLbael 的portName */ QString UkmediaMainWidget::findOutputPortName(int index,QString portLabel) { QMap>::iterator it; QMapportMap; QMap::iterator tempMap; QString portName = ""; for (it = m_pVolumeControl->outputPortMap.begin();it != m_pVolumeControl->outputPortMap.end();) { if (it.key() == index) { portMap = it.value(); for (tempMap = portMap.begin();tempMap!=portMap.end();) { if (tempMap.value() == portLabel) { portName = tempMap.key(); break; } ++tempMap; } } ++it; } return portName; } /* 查找名称为PortName 的portLabel */ QString UkmediaMainWidget::findOutputPortLabel(int index,QString portName) { QMap>::iterator it; QMapportMap; QMap::iterator tempMap; QString portLabel = ""; for (it = m_pVolumeControl->outputPortMap.begin();it != m_pVolumeControl->outputPortMap.end();) { if (it.key() == index) { portMap = it.value(); for (tempMap = portMap.begin();tempMap!=portMap.end();) { qDebug() <<"findOutputPortLabel" <>::iterator it; QMapportMap; QMap::iterator tempMap; QString portName = ""; for (it = m_pVolumeControl->inputPortMap.begin();it != m_pVolumeControl->inputPortMap.end();) { if (it.key() == index) { portMap = it.value(); for (tempMap = portMap.begin();tempMap!=portMap.end();) { if (tempMap.value() == portLabel) { portName = tempMap.key(); break; } ++tempMap; } } ++it; } return portName; } /* 查找名称为PortName 的portLabel */ QString UkmediaMainWidget::findInputPortLabel(int index,QString portName) { QMap>::iterator it; QMapportMap; QMap::iterator tempMap; QString portLabel = ""; for (it = m_pVolumeControl->inputPortMap.begin();it != m_pVolumeControl->inputPortMap.end();) { if (it.key() == index) { portMap = it.value(); for (tempMap = portMap.begin();tempMap!=portMap.end();) { if (tempMap.key() == portName) { portLabel = tempMap.value(); break; } ++tempMap; } } ++it; } return portLabel; } QString UkmediaMainWidget::findHighPriorityProfile(int index,QString profile) { QMap>::iterator it; int priority = 0; QString profileName = ""; QMap profileNameMap; QMap::iterator tempMap; QString cardStr = findCardName(index,m_pVolumeControl->cardMap); QString profileStr = findCardActiveProfile(index) ; QStringList list = profileStr.split("+"); QString includeProfile = ""; if (list.count() >1) { if (profile.contains("output")) { includeProfile = list.at(1); } else if (profile.contains("input")){ includeProfile = list.at(0); } qDebug() << "profile str" <cardProfilePriorityMap.begin();it!=m_pVolumeControl->cardProfilePriorityMap.end();) { if (it.key() == index) { profileNameMap = it.value(); for (tempMap=profileNameMap.begin();tempMap!=profileNameMap.end();) { // qDebug() << "findHighPriorityProfile" << includeProfile < priority) { priority = tempMap.value(); profileName = tempMap.key(); } ++tempMap; } } ++it; } qDebug() << "profile str----------" <m_pOutputListWidget->count();row++) { QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(row); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); qDebug() << "findOutputListWidgetItem" << "card name:" << cardName << "portLabel" << wid->portLabel->text() << "deviceLabel:" << wid->deviceLabel->text(); if (wid->deviceLabel->text() == cardName && wid->portLabel->text() == portLabel) { m_pOutputWidget->m_pOutputListWidget->blockSignals(true); m_pOutputWidget->m_pOutputListWidget->setCurrentRow(row); m_pOutputWidget->m_pOutputListWidget->blockSignals(false); break; } } } void UkmediaMainWidget::findInputListWidgetItem(QString cardName,QString portLabel) { qDebug() <<"findInputListWidgetItem" << cardName << m_pInputWidget->m_pInputListWidget->count(); for (int row=0;rowm_pInputListWidget->count();row++) { QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); qDebug() << "findInputListWidgetItem" << "card name:" << cardName << "portLabel:" << wid->portLabel->text() << "deviceLabel:" << wid->deviceLabel->text() << "port" << portLabel; if (wid->deviceLabel->text() == cardName && wid->portLabel->text() == portLabel) { m_pInputWidget->m_pInputListWidget->blockSignals(true); m_pInputWidget->m_pInputListWidget->setCurrentRow(row); m_pInputWidget->m_pInputListWidget->blockSignals(false); if (wid->deviceLabel->text().contains("bluez_card")) isCheckBluetoothInput = true; qDebug() << "set input list widget" << row; break; } } } /* * 输入设备中是否包含蓝牙设备 */ bool UkmediaMainWidget::inputDeviceContainBluetooth() { for (int row=0;rowm_pInputListWidget->count();row++) { QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); if (wid->deviceLabel->text().contains("bluez")) { return true; } } return false; } QString UkmediaMainWidget::blueCardName() { for (int row=0;rowm_pInputListWidget->count();row++) { QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); if (wid->deviceLabel->text().contains("bluez")) { return wid->deviceLabel->text(); } } return ""; } int UkmediaMainWidget::indexOfOutputPortInOutputListWidget(QString portName) { for (int row=0;rowm_pOutputListWidget->count();row++) { QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(row); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); if (wid->portLabel->text() == portName) { return row; } } return -1; } int UkmediaMainWidget::indexOfInputPortInInputListWidget(QString portName) { for (int row=0;rowm_pInputListWidget->count();row++) { QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); if (wid->portLabel->text() == portName) { return row; } } return -1; } /* 记录输入stream的card name */ void UkmediaMainWidget::inputStreamMapCardName (QString streamName,QString cardName) { if (inputCardStreamMap.count() == 0) { inputCardStreamMap.insertMulti(streamName,cardName); } QMap::iterator it; for (it=inputCardStreamMap.begin();it!=inputCardStreamMap.end();) { if (it.value() == cardName) { break; } if (it == inputCardStreamMap.end()-1) { qDebug() << "inputCardSreamMap " << streamName << cardName; inputCardStreamMap.insertMulti(streamName,cardName); } ++it; } } /* 记录输出stream的card name */ void UkmediaMainWidget::outputStreamMapCardName(QString streamName, QString cardName) { if (outputCardStreamMap.count() == 0) { outputCardStreamMap.insertMulti(streamName,cardName); } QMap::iterator it; for (it=outputCardStreamMap.begin();it!=outputCardStreamMap.end();) { if (it.value() == cardName) { break; } if (it == outputCardStreamMap.end()-1) { qDebug() << "outputCardStreamMap " << streamName << cardName; outputCardStreamMap.insertMulti(streamName,cardName); } ++it; } } /* 找输入stream对应的card name */ QString UkmediaMainWidget::findInputStreamCardName(QString streamName) { QString cardName; QMap::iterator it; for (it=inputCardStreamMap.begin();it!=inputCardStreamMap.end();) { if (it.key() == streamName) { cardName = it.value(); qDebug() << "findInputStreamCardName:" << cardName; break; } ++it; } return cardName; } /* 找输出stream对应的card name */ QString UkmediaMainWidget::findOutputStreamCardName(QString streamName) { QString cardName; QMap::iterator it; for (it=outputCardStreamMap.begin();it!=outputCardStreamMap.end();) { if (it.key() == streamName) { cardName = it.value(); break; } ++it; } return cardName; } /* * 设置声卡的配置文件 */ void UkmediaMainWidget::setCardProfile(QString name, QString profile) { int index = findCardIndex(name,m_pVolumeControl->cardMap); m_pVolumeControl->setCardProfile(index,profile.toLatin1().data()); qDebug() << "set profile" << profile << index ; } /* * 设置默认的输出设备端口 */ void UkmediaMainWidget::setDefaultOutputPortDevice(QString devName, QString portName) { int cardIndex = findCardIndex(devName,m_pVolumeControl->cardMap); QString portStr = findOutputPortName(cardIndex,portName); QTimer *timer = new QTimer; timer->start(50); connect(timer,&QTimer::timeout,[=](){ QString sinkStr = findPortSink(cardIndex,portStr); /*默认的stream 和设置的stream相同 需要更新端口*/ if (strcmp(sinkStr.toLatin1().data(),m_pVolumeControl->defaultSinkName) == 0) { m_pVolumeControl->setSinkPort(sinkStr.toLatin1().data(),portStr.toLatin1().data()); } else { m_pVolumeControl->setDefaultSink(sinkStr.toLatin1().data()); m_pVolumeControl->setSinkPort(sinkStr.toLatin1().data(),portStr.toLatin1().data()); } qDebug() << "set default output" << portName <cardMap); QString portStr = findInputPortName(cardIndex,portName); QTimer *timer = new QTimer; timer->start(50); connect(timer,&QTimer::timeout,[=](){ QString sourceStr = findPortSource(cardIndex,portStr); /*默认的stream 和设置的stream相同 需要更新端口*/ if (strcmp(sourceStr.toLatin1().data(),m_pVolumeControl->defaultSourceName) == 0) { m_pVolumeControl->setSourcePort(sourceStr.toLatin1().data(),portStr.toLatin1().data()); } else { m_pVolumeControl->setDefaultSource(sourceStr.toLatin1().data()); m_pVolumeControl->setSourcePort(sourceStr.toLatin1().data(),portStr.toLatin1().data()); } qDebug() << "set default input" << portName <::iterator it; for (it=m_pVolumeControl->cardActiveProfileMap.begin();it!=m_pVolumeControl->cardActiveProfileMap.end();) { if (it.key() == index) { activeProfileName = it.value(); break; } ++it; } return activeProfileName; } /* * Find the corresponding sink according to the port name */ QString UkmediaMainWidget::findPortSink(int cardIndex,QString portName) { QMap>::iterator it; QMap portNameMap; QMap::iterator tempMap; QString sinkStr = ""; for (it=m_pVolumeControl->sinkPortMap.begin();it!=m_pVolumeControl->sinkPortMap.end();) { // qDebug() <<"find port sink" << it.value() <<"portname:" << portName << "it.key"<< it.key() << "sink:" <>::iterator it; QMap portNameMap; QMap::iterator tempMap; QString sourceStr = ""; for (it=m_pVolumeControl->sourcePortMap.begin();it!=m_pVolumeControl->sourcePortMap.end();) { if (it.key() == cardIndex) { portNameMap = it.value(); for (tempMap=portNameMap.begin();tempMap!=portNameMap.end();) { qDebug() << "findportsource ===" < #include #include #include #include #include "Label/titlelabel.h" static QColor symbolic_color = Qt::gray; class UkuiMediaSliderTipLabel:public QLabel { public: UkuiMediaSliderTipLabel(); ~UkuiMediaSliderTipLabel(); protected: void paintEvent(QPaintEvent*); }; class UkmediaVolumeSlider : public QSlider { Q_OBJECT public: // UkmediaVolumeSlider(QWidget *parent = nullptr); UkmediaVolumeSlider(QWidget *parent = nullptr,bool needTip = false); void initStyleOption(QStyleOptionSlider *option); ~UkmediaVolumeSlider(); private: UkuiMediaSliderTipLabel *m_pTiplabel; bool state = false; bool mousePress =false; Q_SIGNALS: void silderPressedSignal(); void silderReleaseSignal(); protected: void mousePressEvent(QMouseEvent *ev); void mouseReleaseEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e) { // setCursor(QCursor(Qt::OpenHandCursor)); // m_displayLabel->move((this->width()-m_displayLabel->width())*this->value()/(this->maximum()-this->minimum()),3); QSlider::mouseMoveEvent(e); } void leaveEvent(QEvent *e); void enterEvent(QEvent *e); void paintEvent(QPaintEvent *e); }; class UkuiButtonDrawSvg:public QPushButton { Q_OBJECT public: UkuiButtonDrawSvg(QWidget *parent = nullptr); ~UkuiButtonDrawSvg(); QPixmap filledSymbolicColoredPixmap(QImage &source, QColor &baseColor); QRect IconGeometry(); void draw(QPaintEvent* e); void init(QImage image ,QColor color); friend class UkmediaMainWidget; protected: void paintEvent(QPaintEvent *event); bool event(QEvent *e); private: QImage mImage; QColor mColor; bool mousePress = false; }; #endif // UKUICUSTOMSTYLE_H ukui-control-center/plugins/devices/audio/ukmedia_volume_control.h0000644000175000017500000002350714201663716024547 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef UKMEDIAVOLUMECONTROL_H #define UKMEDIAVOLUMECONTROL_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DECAY_STEP .04 static int n_outstanding = 0; class PortInfo { public: QByteArray name; QByteArray description; uint32_t priority; int available; int direction; int64_t latency_offset; std::vector profiles; }; class UkmediaVolumeControl : public QObject{ Q_OBJECT public: UkmediaVolumeControl(); virtual ~UkmediaVolumeControl(); void updateCard(UkmediaVolumeControl *c,const pa_card_info &info); bool updateSink(UkmediaVolumeControl *c,const pa_sink_info &info); void updateSource(const pa_source_info &info); void updateSinkInput(const pa_sink_input_info &info); void updateSourceOutput(const pa_source_output_info &info); void updateClient(const pa_client_info &info); void updateServer(const pa_server_info &info); void updateVolumeMeter(uint32_t source_index, uint32_t sink_input_index, double v); // void updateRole(const pa_ext_stream_restore_info &info); void updateDeviceInfo(const pa_ext_device_restore_info &info) ; bool setSinkMute(bool status); //设置输出设备静音状态 bool setSinkVolume(int index,int value); //设置输出设备音量值 bool setSourceMute(bool status); //设置输入设备静音状态 bool setSourceVolume(int index,int value); //设置输入设备音量值 bool setBalanceVolume(int index,int value,float balance); //设置平衡值 bool getSinkMute(); //获取输出设备静音状态 int getSinkVolume(); //获取输出设备音量值 bool getSourceMute(); //获取输入设备静音状态 int getSourceVolume(); //获取输入设备音量值 float getBalanceVolume();//获取平衡音量 int getDefaultSinkIndex(); int getSinkInputVolume(const gchar *name); //根据name获取sink input的音量值 void setSinkInputVolume(int index,int value); //设置sink input 音量值 void setSinkInputMuted(int index,bool status); //设置sink input 静音状态 int getSourceOutputVolume(const gchar *name); //根据name获取source output的音量值 bool setCardProfile(int index,const gchar *name); //设置声卡的配置文件 bool setDefaultSink(const gchar *name); //设置默认的输出设备 bool setDefaultSource(const gchar *name); //设置默认的输入设备 bool setSinkPort(const gchar *sinkName ,const gchar *portName); //设置输出设备的端口 bool setSourcePort(const gchar *sourceName, const gchar *portName); //设置输入设备的端口 void setSourceOutputVolume(int index, int value); void setSourceOutputMuted(int index, bool status); void removeCard(uint32_t index); void removeSink(uint32_t index); void removeSource(uint32_t index); void removeSinkInput(uint32_t index); void removeSourceOutput(uint32_t index); void removeClient(uint32_t index); void setConnectingMessage(const char *string = NULL); void showError(const char *txt); static void decOutstanding(UkmediaVolumeControl *w); static void sinkIndexCb(pa_context *c, const pa_sink_info *i, int eol, void *userdata); static void sourceIndexCb(pa_context *c, const pa_source_info *i, int eol, void *userdata); static void readCallback(pa_stream *s, size_t length, void *userdata); static void cardCb(pa_context *, const pa_card_info *i, int eol, void *userdata); static void sinkCb(pa_context *c, const pa_sink_info *i, int eol, void *userdata); static void sourceCb(pa_context *, const pa_source_info *i, int eol, void *userdata); static void sinkInputCb(pa_context *, const pa_sink_input_info *i, int eol, void *userdata); static void sinkInputCallback(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); //不更新sink input static void sourceOutputCb(pa_context *, const pa_source_output_info *i, int eol, void *userdata); static void clientCb(pa_context *, const pa_client_info *i, int eol, void *userdata); static void serverInfoCb(pa_context *, const pa_server_info *i, void *userdata); static void extStreamRestoreReadCb(pa_context *,const pa_ext_stream_restore_info *i,int eol,void *userdata); static void extStreamRestoreSubscribeCb(pa_context *c, void *userdata); // void ext_device_restore_read_cb(pa_context *,const pa_ext_device_restore_info *i,int eol,void *userdata); // static void ext_device_restore_subscribe_cb(pa_context *c, pa_device_type_t type, uint32_t idx, void *userdata); static void extDeviceManagerReadCb(pa_context *,const pa_ext_device_manager_info *,int eol,void *userdata); static void extDeviceManagerSubscribeCb(pa_context *c, void *userdata); static void subscribeCb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, void *userdata); static void contextStateCallback(pa_context *c, void *userdata); pa_context* getContext(void); gboolean connectToPulse(gpointer userdata); void updateOutputPortMap(); void removeOutputPortMap(int index); //移除指定索引的output port void removeInputPortMap(int index); //移除指定索引的input port void removeCardMap(int index); //移除指定索引的 card void removeCardProfileMap(int index); //移除声卡profile map void removeProfileMap(); bool isExitOutputPort(QString name); void removeInputProfile(); bool isExitInputPort(QString name); std::vector< std::pair > profiles; std::map ports; QByteArray activeProfile; QByteArray noInOutProfile; QByteArray lastActiveProfile; QVector sourceOutputVector; //存储source output索引 bool hasSinks; bool hasSources; pa_cvolume m_defaultSinkVolume; const pa_sink_info *m_pDefaultSink; pa_context* m_pPaContext; std::map clientNames; int sinkVolume; //输出音量 int sourceVolume; //输入音量 bool sinkMuted; //输出静音状态 bool sourceMuted; //输入静音状态 int sinkInputVolume; //sink input 音量 bool sinkInputMuted; //sink input 静音状态 float balance; //平衡音量值 int channel; //通道数 QString sinkPortName; //输出设备端口名 QString sourcePortName; //输入设备端口名 int defaultOutputCard; int defaultInputCard; pa_channel_map defaultChannelMap; friend class UkmediaMainWidget; pa_stream *peak; double lastPeak; QByteArray name; QByteArray description; uint32_t index, card_index; bool offsetButtonEnabled; pa_channel_map channelMap; pa_cvolume volume; std::vector< std::pair > dPorts; QByteArray activePort; QMap sinkMap; //输出设备 QMap sourceMap; //输入设备 QMap> outputPortMap; //输出端口 QMap> inputPortMap; //输入端口 QMap profileNameMap; //声卡输出配置文件 QMap>inputPortProfileNameMap; //声卡输入配置文件 QMap> cardProfilePriorityMap; //记录声卡优先级配置文件 QMap> cardProfileMap; QMap cardMap; QMap> sinkPortMap; QMap> sourcePortMap; QMap cardActiveProfileMap; Q_SIGNALS: void paContextReady(); void updateVolume(int value,bool state); void updateSourceVolume(int value,bool state); void addSinkInputSignal(const gchar* name,const gchar *id,int index); void removeSinkInputSignal(const gchar* name); void addSourceOutputSignal(const gchar* name,const gchar *id,int index); void removeSourceOutputSignal(const gchar* name); void checkDeviceSelectionSianal(const pa_card_info *info); void peakChangedSignal(double v); void updatePortSignal(); void deviceChangedSignal(); protected Q_SLOTS: void timeoutSlot(); public: void setConnectionState(gboolean connected); void updateDeviceVisibility(); void reallyUpdateDeviceVisibility(); pa_stream* createMonitorStreamForSource(uint32_t source_idx, uint32_t stream_idx, bool suspend); void setIconFromProplist(QLabel *icon, pa_proplist *l, const char *name); pa_context *context; QByteArray defaultSinkName, defaultSourceName; bool canRenameDevices; const pa_server_info *m_pServerInfo; const pa_source_info *m_pDefaultSource; int sinkIndex; int sourceIndex; pa_mainloop_api* api; QStringList sinkInputList; QMap sinkInputMap; QMap sourceOutputMap; private: gboolean m_connected; gchar* m_config_filename; }; #endif // UKMEDIAVOLUMECONTROL_H ukui-control-center/plugins/devices/audio/audio.h0000644000175000017500000000317014201663716021074 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef AUDIO_H #define AUDIO_H #include #include #include #include #include "shell/interface.h" #include "ukmedia_main_widget.h" namespace Ui { class Audio; } class Audio : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Audio(); ~Audio(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; private: Ui::Audio *ui; QString pluginName; int pluginType; UkmediaMainWidget *pluginWidget; bool mFirstLoad; }; #endif // AUDIO_H ukui-control-center/plugins/devices/audio/ukmedia_slider_tip_label_helper.h0000644000175000017500000000346614201663716026336 0ustar fengfeng/* * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 #include #include "ukui_custom_style.h" class MediaSliderTipLabel:public QLabel { public: MediaSliderTipLabel(); ~MediaSliderTipLabel(); protected: void paintEvent(QPaintEvent*); }; class SliderTipLabelHelper : public QObject { Q_OBJECT friend class AppEventFilter; public: SliderTipLabelHelper(QObject *parent = nullptr); ~SliderTipLabelHelper() {} void registerWidget(QWidget *w); void unregisterWidget(QWidget *w); bool eventFilter(QObject *obj, QEvent *e); void mouseMoveEvent(QObject *obj, QMouseEvent *e); void mouseReleaseEvent(QObject *obj, QMouseEvent *e); void mousePressedEvent(QObject *obj,QMouseEvent *e); private: MediaSliderTipLabel *m_pTiplabel; }; class AppEventFilter : public QObject { friend class SliderTipLabelHelper; Q_OBJECT private: explicit AppEventFilter(SliderTipLabelHelper *parent); ~AppEventFilter() {} bool eventFilter(QObject *obj, QEvent *e); SliderTipLabelHelper *m_wm = nullptr; }; #endif // SLIDERTIPLABELHELPER_H ukui-control-center/plugins/devices/audio/ukui_list_widget_item.h0000644000175000017500000000405614201663716024370 0ustar fengfeng#ifndef UKUILISTWIDGETITEM_H #define UKUILISTWIDGETITEM_H /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include #include #include #include #include #include #include class UkuiListWidget : public QListWidget { Q_OBJECT public: UkuiListWidget(QWidget *parent = nullptr); ~UkuiListWidget(); protected: void paintEvent(QPaintEvent*event) { int i; for (i = 0 ;i < this->count();i++) { QListWidgetItem *item = this->item(i); // item->setTextColor(QColor(0,0,0,0)); delete item; } QListWidget::paintEvent(event); } }; class UkuiListWidgetItem : public QWidget { Q_OBJECT public: UkuiListWidgetItem(QWidget *parent = 0); ~UkuiListWidgetItem(); public: void setLabelText(QString portText,QString deviceLabel); // void setLabelTextIsWhite(bool selected); void setSelected(bool selected); // QString text(); QString portName; QLabel * portLabel; QLabel * deviceLabel; protected: // void paintEvent(QPaintEvent *event); void mousePressEvent(QMouseEvent *ev); private: QWidget * widget; }; #endif // UKUILISTWIDGETITEM_H ukui-control-center/plugins/devices/audio/ukmedia_main_widget.h0000644000175000017500000003050614201663716023764 0ustar fengfeng /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef WIDGET_H #define WIDGET_H #include #include "ukmedia_volume_control.h" #include "ukmedia_output_widget.h" #include "ukmedia_input_widget.h" #include "ukmedia_sound_effects_widget.h" #include "ukui_list_widget_item.h" #include #include #include #include #include #include #include #include extern "C" { #include #include #include #include #include #include #include #include #include } #include #include #include #include #include #include #include #include #define UKUI_THEME_SETTING "org.ukui.style" #define UKUI_THEME_NAME "style-name" #define UKUI_THEME_WHITE "ukui-white" #define UKUI_THEME_BLACK "ukui-black" #define UKUI_INPUT_REAR_MIC "analog-input-rear-mic" //后置麦克风 #define UKUI_INPUT_FRONT_MIC "analog-input-front-mic" //前置麦克风 #define UKUI_OUTPUT_HEADPH "analog-output-headphones" //模拟耳机 #define KEYBINDINGS_CUSTOM_SCHEMA "org.ukui.media.sound" #define KEYBINDINGS_CUSTOM_DIR "/org/ukui/sound/keybindings/" #define MAX_CUSTOM_SHORTCUTS 1000 #define FILENAME_KEY "filename" #define NAME_KEY "name" #define KEY_SOUNDS_SCHEMA "org.ukui.sound" #define UKUI_SWITCH_SETTING "org.ukui.session" #define UKUI_STARTUP_MUSIC_KEY "startup-music" #define UKUI_POWEROFF_MUSIC_KEY "poweroff-music" #define UKUI_LOGOUT_MUSIC_KEY "logout-music" #define UKUI_WAKEUP_MUSIC_KEY "weakup-music" #define EVENT_SOUNDS_KEY "event-sounds" #define INPUT_SOUNDS_KEY "input-feedback-sounds" #define SOUND_THEME_KEY "theme-name" #define DEFAULT_ALERT_ID "__default" #define CUSTOM_THEME_NAME "__custom" #define NO_SOUNDS_THEME_NAME "__no_sounds" #define PA_VOLUME_NORMAL 65536.0 #define UKMEDIA_VOLUME_NORMAL 100.0 #ifdef __GNUC__ #define CA_CLAMP(x, low, high) \ __extension__ ({ typeof(x) _x = (x); \ typeof(low) _low = (low); \ typeof(high) _high = (high); \ ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \ }) #else #define CA_CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) #endif typedef enum { GVC_LEVEL_SCALE_LINEAR, GVC_LEVEL_SCALE_LOG } LevelScale; class UkmediaMainWidget : public QWidget { Q_OBJECT public: UkmediaMainWidget(QWidget *parent = nullptr); ~UkmediaMainWidget(); void initWidget(); //初始化界面 void initGsettings(); //初始化gsetting值 void dealSlot(); //处理槽函数 void initListWidgetItem(); //初始化output/input list widget的选项 int valueToPaVolume(int value); //滑动条值转换成音量 int paVolumeToValue(int value); //音量值转换成滑动条值 void themeChangeIcons(); static int connectContext(gpointer userdata); static int caProplistMergeAp(ca_proplist *p, va_list ap); static int caPlayForWidget(UkmediaMainWidget *w, uint32_t id, ...); static int caProplistSetForWidget(ca_proplist *p, UkmediaMainWidget *widget); QPixmap drawDarkColoredPixmap(const QPixmap &source); QPixmap drawLightColoredPixmap(const QPixmap &source); void alertIconButtonSetIcon(bool state,int value); void createAlertSound(UkmediaMainWidget *w); void inputVolumeDarkThemeImage(int value,bool status); void outputVolumeDarkThemeImage(int value,bool status); int getInputVolume(); int getOutputVolume(); void comboboxCurrentTextInit(); QList listExistsPath(); QString findFreePath(); void addValue(QString name,QString filename); static void onKeyChanged (GSettings *settings,gchar *key,UkmediaMainWidget *w); static void updateTheme (UkmediaMainWidget *w); static void setupThemeSelector (UkmediaMainWidget *w); static void soundThemeInDir (UkmediaMainWidget *w,GHashTable *hash,const char *dir); static char *loadIndexThemeName (const char *index,char **parent); static void setComboxForThemeName (UkmediaMainWidget *w,const char *name); static void updateAlertsFromThemeName (UkmediaMainWidget *w,const gchar *name); static void updateAlert (UkmediaMainWidget *w,const char *alert_id); static int getFileType (const char *sound_name,char **linked_name); static char *customThemeDirPath (const char *child); static void populateModelFromDir (UkmediaMainWidget *w,const char *dirname); static void populateModelFromFile (UkmediaMainWidget *w,const char *filename); static void populateModelFromNode (UkmediaMainWidget *w,xmlNodePtr node); static xmlChar *xmlGetAndTrimNames (xmlNodePtr node); static void playAlretSoundFromPath (UkmediaMainWidget *w,QString path); static gboolean saveAlertSounds (QComboBox *combox,const char *id); static void deleteOldFiles (const char **sounds); static void deleteOneFile (const char *sound_name, const char *pattern); static void deleteDisabledFiles (const char **sounds); static void addCustomFile (const char **sounds, const char *filename); static gboolean cappletFileDeleteRecursive (GFile *file, GError **error); static gboolean directoryDeleteRecursive (GFile *directory, GError **error); static void createCustomTheme (const char *parent); static void customThemeUpdateTime (void); static gboolean customThemeDirIsEmpty (void); void addOutputListWidgetItem(QString portName,QString cardName); //添加output listWidget item void addInputListWidgetItem(QString portName, QString cardName); //添加input listwidget item void deleteNotAvailableOutputPort(); void deleteNotAvailableInputPort(); void addAvailableOutputPort(); void addAvailableInputPort(); bool outputPortIsNeedDelete(int index,QString name);//port是否需要在outputListWidget删除 bool outputPortIsNeedAdd(int index,QString name);//port是否需要在outputListWidget删除 bool inputPortIsNeedDelete(int index,QString name);//port是否需要在inputListWidget删除 bool inputPortIsNeedAdd(int index,QString name);//port是否需要在inputListWidget删除 int findCardIndex(QString cardName, QMap cardMap);//查找声卡指定的索引 QString findCardName(int index,QMap cardMap); QString findHighPriorityProfile(int index,QString profile); void findOutputListWidgetItem(QString cardName,QString portLabel); void findInputListWidgetItem(QString cardName,QString portLabel); QString findPortSink(int cardIndex,QString portName); QString findPortSource(int cardIndex,QString portName); bool inputDeviceContainBluetooth(); int indexOfOutputPortInOutputListWidget(QString portName); int indexOfInputPortInInputListWidget(QString portName); void inputStreamMapCardName(QString streamName,QString cardName); void outputStreamMapCardName(QString streamName,QString cardName); QString findInputStreamCardName(QString streamName); QString findOutputStreamCardName(QString streamName); bool exitBluetoochDevice(); QString blueCardName(); //记录蓝牙声卡名称 QString findOutputPortName(int index,QString portLabel); //找到outputPortLabel对应的portName QString findInputPortName(int index,QString portLabel); //找到inputPortLabel对应的portName QString findOutputPortLabel(int index,QString portName); //查找名为portName对应的portLabel QString findInputPortLabel(int index,QString portName); //查找名为portName对应的portLabel void setCardProfile(QString name,QString profile); //设置声卡的配置文件 void setDefaultOutputPortDevice(QString devName,QString portName); //设置默认的输出端口 void setDefaultInputPortDevice(QString devName,QString portName); //设置默认的输入端口 QString findCardActiveProfile(int index); //查找声卡的active profile private Q_SLOTS: void initVoulmeSlider(); //初始化音量滑动条的值 void themeComboxIndexChangedSlot(int index); //主题下拉框改变 void comboxIndexChangedSlot(int index); void outputWidgetSliderChangedSlot(int v); //输出音量改变 void inputWidgetSliderChangedSlot(int v); //输入滑动条更改 void inputMuteButtonSlot(); //输入音量静音控制 void outputMuteButtonSlot(); //输出音量静音控制 void balanceSliderChangedSlot(int v); //平衡值改变 void peakVolumeChangedSlot(double v); //输入等级 void updateDevicePort(); //更新设备端口 void updateListWidgetItemSlot(); void timeSliderSlot(); void ukuiThemeChangedSlot(const QString &); void startupButtonSwitchChangedSlot(bool status); //开机音乐开关 void poweroffButtonSwitchChangedSlot(bool status); //关机音乐开关 void logoutMusicButtonSwitchChangedSlot(bool status); //注销音乐开关 void wakeButtonSwitchChangedSlot(bool status); //唤醒音乐开关 void alertSoundButtonSwitchChangedSlot(bool status); void bootMusicSettingsChanged(); void windowClosedComboboxChangedSlot(int index); void volumeChangedComboboxChangeSlot(int index); void settingMenuComboboxChangedSlot(int index); // void alertVolumeSliderChangedSlot(int value); // void alertSoundVolumeChangedSlot(); void outputListWidgetCurrentRowChangedSlot(int row); //output list widget选项改变 void inputListWidgetCurrentRowChangedSlot(int row); //input list widget选项改变 private: UkmediaInputWidget *m_pInputWidget; UkmediaOutputWidget *m_pOutputWidget; UkmediaSoundEffectsWidget *m_pSoundWidget; UkmediaVolumeControl *m_pVolumeControl; QStringList *m_pSoundList; QStringList *m_pThemeDisplayNameList; QStringList *m_pThemeNameList; QStringList *m_pSoundThemeList; QStringList *m_pSoundThemeDirList; QStringList *m_pSoundThemeXmlNameList; QStringList *m_pSoundNameList; QStringList *eventList; QStringList *eventIdNameList; GSettings *m_pSoundSettings; QGSettings *m_pBootSetting; QGSettings *m_pThemeSetting; // QGSettings *m_pWindowClosedSetting; QString mThemeName; bool m_hasMusic; bool firstEnterSystem = true; const gchar* m_privOutputPortLabel = ""; int callBackCount = 0; bool firstEntry = true; QMap cardMap; QMap> outputPortMap; QMap> inputPortMap; QMap outputPortNameMap; QMap inputPortNameMap; QMap outputPortLabelMap; QMap currentOutputPortLabelMap; QMap currentInputPortLabelMap; QMap inputPortLabelMap; // QMap profileNameMap; // QMap inputPortProfileNameMap; // QMap> cardProfileMap; // QMap> cardProfilePriorityMap; QMap inputCardStreamMap; QMap outputCardStreamMap; // QMap> sinkPortMap; // QMap> sourcePortMap; bool updatePort = true; bool setDefaultstream = true; int reconnectTime; QTimer *time; QTimer *timeSlider; bool mousePress = false; bool mouseReleaseState = false; QTimer *timeSliderBlance; bool mousePressBlance = false; bool mouseReleaseStateBlance = false; }; #endif // WIDGET_H ukui-control-center/plugins/devices/audio/audio.pro0000644000175000017500000000267614201663716021457 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-05-30T09:45:54 # #------------------------------------------------- include(../../../env.pri) QT += widgets xml dbus TEMPLATE = lib CONFIG += plugin include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) INCLUDEPATH += ../../.. \ $$PROJECT_COMPONENTSOURCE \ TARGET = $$qtLibraryTarget(audio) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} CONFIG += c++11 \ no_keywords link_pkgconfig PKGCONFIG += gio-2.0 \ libxml-2.0 \ Qt5Multimedia \ gsettings-qt \ libcanberra \ dconf \ libpulse \ libpulse-mainloop-glib #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ audio.cpp \ ukmedia_input_widget.cpp \ ukmedia_main_widget.cpp \ ukmedia_output_widget.cpp \ ukmedia_sound_effects_widget.cpp \ ukmedia_volume_control.cpp \ ukui_custom_style.cpp \ customstyle.cpp \ ukmedia_slider_tip_label_helper.cpp \ ukui_list_widget_item.cpp HEADERS += \ audio.h \ ukmedia_input_widget.h \ ukmedia_main_widget.h \ ukmedia_output_widget.h \ ukmedia_sound_effects_widget.h \ ukmedia_volume_control.h \ ukui_custom_style.h \ customstyle.h \ ukmedia_slider_tip_label_helper.h \ ukui_list_widget_item.h FORMS += \ audio.ui INSTALLS += target ukui-control-center/plugins/devices/audio/ukui_list_widget_item.cpp0000644000175000017500000000661414201663716024725 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "ukui_list_widget_item.h" #include #include #include #include //#include #include bool isCheckBluetoothInput; UkuiListWidget::UkuiListWidget(QWidget *parent) : QListWidget(parent) { } UkuiListWidget::~UkuiListWidget() { } UkuiListWidgetItem::UkuiListWidgetItem(QWidget *parent) : QWidget(parent) { this->setFixedSize(500,64); QVBoxLayout *vLayout = new QVBoxLayout; portLabel = new QLabel(this); deviceLabel = new QLabel(this); portLabel->setFixedSize(600,24); deviceLabel->setFixedSize(600,24); vLayout->addWidget(portLabel); vLayout->addWidget(deviceLabel); this->setLayout(vLayout); this->show(); } UkuiListWidgetItem::~UkuiListWidgetItem() { } void UkuiListWidgetItem::setSelected(bool selected){ if (selected) { widget->setStyleSheet("QWidget{background: #3D6BE5; border-radius: 4px;}"); } else { widget->setStyleSheet("QListWidget::Item:hover{background:#FF3D6BE5;border-radius: 4px;}"); } } void UkuiListWidgetItem::setLabelText(QString portLabel, QString deviceLabel){ this->portLabel->setText(portLabel); this->deviceLabel->setText(deviceLabel); } void UkuiListWidgetItem::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); qDebug() << "Mouse Press Event" << this->portLabel->text() << this->deviceLabel->text() << isCheckBluetoothInput; //蓝牙输入去除勾选 if (this->deviceLabel->text().contains("bluez_card")) { if (isCheckBluetoothInput == false) isCheckBluetoothInput = true; else { isCheckBluetoothInput = false; QString cmd = "pactl set-card-profile "+this->deviceLabel->text()+" a2dp_sink"; system(cmd.toLocal8Bit().data()); } } } //void UkuiListWidgetItem::paintEvent(QPaintEvent *event) //{ // QStyleOption opt; // opt.init(this); // QPainter p(this); //// double transparence = transparency * 255; // QColor color = palette().color(QPalette::Base); //// color.setAlpha(transparence); // QBrush brush = QBrush(color); // p.setBrush(brush); // p.setPen(Qt::NoPen); // QPainterPath path; // opt.rect.adjust(0,0,0,0); // path.addRoundedRect(opt.rect,6,6); // p.setRenderHint(QPainter::Antialiasing); // 反锯齿; // p.drawRoundedRect(opt.rect,6,6); // setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); //// QWidget::paintEvent(event); //} ukui-control-center/plugins/devices/audio/audio.ui0000644000175000017500000000206014201663716021257 0ustar fengfeng Audio 0 0 800 710 0 0 16777215 16777215 Audio 0 0 0 32 48 ukui-control-center/plugins/devices/printer/0000755000175000017500000000000014201663716020203 5ustar fengfengukui-control-center/plugins/devices/printer/printer.h0000644000175000017500000000371414201663716022044 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef PRINTER_H #define PRINTER_H #include #include #include #include "shell/interface.h" #include "HoverWidget/hoverwidget.h" #include "ImageUtil/imageutil.h" #include "HoverBtn/hoverbtn.h" namespace Ui { class Printer; } class Printer : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Printer(); ~Printer(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void initTitleLabel(); void initComponent(); void runExternalApp(); void setLabelText(QLabel *label,QString text); bool eventFilter(QObject *obj, QEvent *event); private: Ui::Printer *ui; QString pluginName; int pluginType; QWidget * pluginWidget; HoverWidget * mAddWgt; bool mFirstLoad; QTimer *mTimer; public slots: void refreshPrinterDevSlot(); }; #endif // PRINTER_H ukui-control-center/plugins/devices/printer/printer.ui0000644000175000017500000001314014201663716022224 0ustar fengfeng Printer 0 0 800 710 0 0 16777215 16777215 Printer 0 0 0 32 48 550 0 960 16777215 0 0 0 0 0 8 0 0 0 Add Printers And Scanners true 0 60 16777215 60 0 0 0 0 0 0 0 16 Qt::Vertical QSizePolicy::Fixed 20 16 0 0 List Of Existing Printers true 550 0 960 16777215 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/printer/printer.pro0000644000175000017500000000150514201663716022411 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-02-28T14:09:42 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/hoverbtn.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets printsupport TEMPLATE = lib CONFIG += plugin \ link_pkgconfig PKGCONFIG += gsettings-qt TARGET = $$qtLibraryTarget(printer) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ printer.cpp HEADERS += \ printer.h FORMS += \ printer.ui INSTALLS += target ukui-control-center/plugins/devices/printer/printer.cpp0000644000175000017500000002025314201663716022374 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "printer.h" #include "ui_printer.h" #include #include #include #include #define ITEMFIXEDHEIGH 58 Printer::Printer() : mFirstLoad(true) { pluginName = tr("Printer"); pluginType = DEVICES; } Printer::~Printer() { if (!mFirstLoad) { delete ui; ui = nullptr; } } QString Printer::get_plugin_name() { return pluginName; } int Printer::get_plugin_type() { return pluginType; } QWidget *Printer::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; ui = new Ui::Printer; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); //~ contents_path /printer/Add Printers And Scanners ui->titleLabel->setText(tr("Add Printers And Scanners")); // 禁用选中效果 ui->listWidget->setFocusPolicy(Qt::NoFocus); ui->listWidget->setSelectionMode(QAbstractItemView::NoSelection); initTitleLabel(); initComponent(); refreshPrinterDevSlot(); } return pluginWidget; } void Printer::plugin_delay_control() { } const QString Printer::name() const { return QStringLiteral("printer"); } void Printer::initTitleLabel() { ui->listWidget->setSpacing(1); } void Printer::initComponent() { mAddWgt = new HoverWidget("", pluginWidget); mAddWgt->setObjectName("mAddwgt"); mAddWgt->setMinimumSize(QSize(580, 50)); mAddWgt->setMaximumSize(QSize(960, 50)); QPalette pal; QBrush brush = pal.highlight(); //获取window的色值 QColor highLightColor = brush.color(); QString stringColor = QString("rgba(%1,%2,%3)") //叠加20%白色 .arg(highLightColor.red()*0.8 + 255*0.2) .arg(highLightColor.green()*0.8 + 255*0.2) .arg(highLightColor.blue()*0.8 + 255*0.2); mAddWgt->setStyleSheet(QString("HoverWidget#mAddwgt{background: palette(button);\ border-radius: 4px;}\ HoverWidget:hover:!pressed#mAddwgt{background: %1;\ border-radius: 4px;}").arg(stringColor)); ui->listWidget->setStyleSheet("QListWidget::Item:hover{background:palette(base);}"); QHBoxLayout *addLyt = new QHBoxLayout; QLabel *iconLabel = new QLabel(); QLabel *textLabel = new QLabel(tr("Add printers and scanners")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); iconLabel->setProperty("useIconHighlightEffect", true); iconLabel->setProperty("iconHighlightEffectMode", 1); addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); mAddWgt->setLayout(addLyt); connect(mAddWgt, &HoverWidget::widgetClicked, this, [=](QString mname) { Q_UNUSED(mname) runExternalApp(); }); // 悬浮改变Widget状态 connect(mAddWgt, &HoverWidget::enterWidget, this, [=](){ iconLabel->setProperty("useIconHighlightEffect", false); iconLabel->setProperty("iconHighlightEffectMode", 0); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: white;"); }); // 还原状态 connect(mAddWgt, &HoverWidget::leaveWidget, this, [=](){ iconLabel->setProperty("useIconHighlightEffect", true); iconLabel->setProperty("iconHighlightEffectMode", 1); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: palette(windowText);"); }); ui->addLyt->addWidget(mAddWgt); mTimer = new QTimer(this); connect(mTimer, &QTimer::timeout, this, [=] { refreshPrinterDevSlot(); }); mTimer->start(1000); } void Printer::refreshPrinterDevSlot() { QStringList printer = QPrinterInfo::availablePrinterNames(); for (int num = 0; num < printer.count(); num++) { QStringList env = QProcess::systemEnvironment(); env << "LANG=en_US.UTF-8"; QProcess *process = new QProcess; process->setEnvironment(env); process->start("lpstat -p "+printer.at(num)); process->waitForFinished(); QString ba = process->readAllStandardOutput(); delete process; QString printer_stat = QString(ba.data()); // 标志位flag用来判断该打印机是否可用,flag1用来决定是否新增窗口(为真则加) bool flag = printer_stat.contains("disable", Qt::CaseSensitive) || printer_stat.contains("Unplugged or turned off", Qt::CaseSensitive); // bool flag = false; bool flag1 = true; // 遍历窗口列表,判断列表中是否已经存在该打印机,若存在,便判断该打印机是否可用,不可用则从列表中删除该打印机窗口 for (int j = 0; j < ui->listWidget->count(); j++) { QString itemData = ui->listWidget->item(j)->data(Qt::UserRole).toString(); if (!itemData.compare(printer.at(num))) { if (flag) { ui->listWidget->takeItem(j); flag1 = false; break; } flag1 = false; break; } } // if (!flag && flag1) { HoverBtn *printerItem = new HoverBtn(printer.at(num), pluginWidget); printerItem->installEventFilter(this); connect(printerItem,&HoverBtn::resize,[=](){ setLabelText(printerItem->mPitLabel,printer.at(num)); }); QIcon printerIcon = QIcon::fromTheme("printer"); printerItem->mPitIcon->setPixmap(printerIcon.pixmap(printerIcon.actualSize(QSize(24, 24)))); QListWidgetItem *item = new QListWidgetItem(ui->listWidget); item->setData(Qt::UserRole, printer.at(num)); item->setSizeHint(QSize(QSizePolicy::Expanding, 50)); ui->listWidget->setItemWidget(item, printerItem); } } } void Printer::runExternalApp() { QString cmd = "system-config-printer"; QProcess process(this); process.startDetached(cmd); } void Printer::setLabelText(QLabel *label, QString text) { QFontMetrics fontMetrics(label->font()); int fontSize = fontMetrics.width(text); if (fontSize > label->width()) { label->setText(fontMetrics.elidedText(text, Qt::ElideRight, label->width())); label->setToolTip(text); } else { label->setText(text); label->setToolTip(""); } } bool Printer::eventFilter(QObject *obj, QEvent *event) { QString strObjName(obj->metaObject()->className()); if (strObjName == "HoverBtn") { if (event->type() == QEvent::Resize) { HoverBtn *mBtn = static_cast(obj); if (mBtn) { mBtn->mPitLabel->setFixedWidth(mBtn->width() - 50); emit mBtn->resize(); } } return false; } } ukui-control-center/plugins/devices/touchpad/0000755000175000017500000000000014201663716020327 5ustar fengfengukui-control-center/plugins/devices/touchpad/touchpad.h0000644000175000017500000000457514201663716022322 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef TOUCHPAD_H #define TOUCHPAD_H #include #include #include #include #include #include #include #include #include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" const QString kSession = "wayland"; namespace Ui { class Touchpad; } class Touchpad : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: explicit Touchpad(); ~Touchpad(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void setupComponent(); void initConnection(); void initTouchpadStatus(); QString _findKeyScrollingType(); private: void setModuleVisible(bool visible); void isWaylandPlatform(); void initWaylandDbus(); void initWaylandTouchpadStatus(); void initWaylandConnection(); private: Ui::Touchpad *ui; QString pluginName; int pluginType; QWidget * pluginWidget; private: SwitchButton * enableBtn; SwitchButton * typingBtn; SwitchButton * clickBtn; SwitchButton * mMouseDisTouchBtn; QGSettings * tpsettings; bool mFirstLoad; bool mIsWayland; bool mExistTouchpad; QDBusInterface *mWaylandIface; QDBusInterface *mDeviceIface; }; #endif // TOUCHPAD_H ukui-control-center/plugins/devices/touchpad/touchpad.ui0000644000175000017500000002754114201663716022506 0ustar fengfeng Touchpad 0 0 775 493 Touchpad 2 0 0 32 48 0 0 Touchpad Settings Qt::Vertical QSizePolicy::Fixed 20 6 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 Mouse to disable touchpad Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 Enabled touchpad Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 Disable touchpad while typing Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 Enable mouse clicks with touchpad Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 128 0 128 16777215 Scrolling 0 30 16777215 30 16 No touchpad found Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/touchpad/touchpad.cpp0000644000175000017500000002700714201663716022650 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "touchpad.h" #include "ui_touchpad.h" #include #include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif #include #include #define TOUCHPAD_SCHEMA "org.ukui.peripherals-touchpad" #define ACTIVE_TOUCHPAD_KEY "touchpad-enabled" #define DISABLE_WHILE_TYPING_KEY "disable-while-typing" #define TOUCHPAD_CLICK_KEY "tap-to-click" #define V_EDGE_KEY "vertical-edge-scrolling" #define H_EDGE_KEY "horizontal-edge-scrolling" #define V_FINGER_KEY "vertical-two-finger-scrolling" #define H_FINGER_KEY "horizontal-two-finger-scrolling" #define N_SCROLLING "none" #define MOUSE_DISBALE_TOUCHPAD "disable-on-external-mouse" bool findSynaptics(); bool _supportsXinputDevices(); XDevice* _deviceIsTouchpad (XDeviceInfo * deviceinfo); bool _deviceHasProperty (XDevice * device, const char * property_name); Touchpad::Touchpad() : mFirstLoad(true) { pluginName = tr("Touchpad"); pluginType = DEVICES; } Touchpad::~Touchpad() { if (!mFirstLoad) { delete ui; ui = nullptr; } } QString Touchpad::get_plugin_name(){ return pluginName; } int Touchpad::get_plugin_type(){ return pluginType; } QWidget *Touchpad::get_plugin_ui(){ if (mFirstLoad) { mFirstLoad = false; ui = new Ui::Touchpad; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); //~ contents_path /touchpad/Touchpad Settings ui->titleLabel->setText(tr("Touchpad Settings")); initWaylandDbus(); isWaylandPlatform(); setupComponent(); ui->scrollingTypeComBox->setView(new QListView()); const QByteArray id(TOUCHPAD_SCHEMA); if (QGSettings::isSchemaInstalled(TOUCHPAD_SCHEMA)){ tpsettings = new QGSettings(id, QByteArray(), this); initConnection(); if (findSynaptics() || mExistTouchpad) { qDebug() << "Touch Devices Available"; ui->tipLabel->hide(); initTouchpadStatus(); ui->enableFrame->hide(); } else { ui->clickFrame->hide(); ui->enableFrame->hide(); ui->scrollingFrame->hide(); ui->typingFrame->hide(); ui->touchapdDisableFrame->hide(); } } } return pluginWidget; } void Touchpad::plugin_delay_control(){ } const QString Touchpad::name() const { return QStringLiteral("touchpad"); } void Touchpad::setupComponent(){ enableBtn = new SwitchButton(pluginWidget); ui->enableHorLayout->addWidget(enableBtn); typingBtn = new SwitchButton(pluginWidget); ui->typingHorLayout->addWidget(typingBtn); clickBtn = new SwitchButton(pluginWidget); ui->clickHorLayout->addWidget(clickBtn); mMouseDisTouchBtn = new SwitchButton(pluginWidget); ui->touchapdDisableLyt->addWidget(mMouseDisTouchBtn); if (mIsWayland) { ui->scrollingTypeComBox->addItem(tr("Disable rolling"), N_SCROLLING); ui->scrollingTypeComBox->addItem(tr("Edge scrolling"), V_EDGE_KEY); ui->scrollingTypeComBox->addItem(tr("Two-finger scrolling"), V_FINGER_KEY); } else { ui->scrollingTypeComBox->addItem(tr("Disable rolling"), N_SCROLLING); ui->scrollingTypeComBox->addItem(tr("Vertical edge scrolling"), V_EDGE_KEY); ui->scrollingTypeComBox->addItem(tr("Horizontal edge scrolling"), H_EDGE_KEY); ui->scrollingTypeComBox->addItem(tr("Vertical two-finger scrolling"), V_FINGER_KEY); ui->scrollingTypeComBox->addItem(tr("Horizontal two-finger scrolling"), H_FINGER_KEY); } } void Touchpad::initConnection() { connect(enableBtn, &SwitchButton::checkedChanged, [=](bool checked){ tpsettings->set(ACTIVE_TOUCHPAD_KEY, checked); setModuleVisible(checked); }); connect(typingBtn, &SwitchButton::checkedChanged, [=](bool checked){ tpsettings->set(DISABLE_WHILE_TYPING_KEY, checked); }); connect(clickBtn, &SwitchButton::checkedChanged, [=](bool checked){ tpsettings->set(TOUCHPAD_CLICK_KEY, checked); }); connect(mMouseDisTouchBtn, &SwitchButton::checkedChanged, [=](bool checked){ tpsettings->set(MOUSE_DISBALE_TOUCHPAD, checked); }); connect(ui->scrollingTypeComBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ Q_UNUSED(index) //旧滚动类型设置为false,跳过N_SCROLLING QString oldType = _findKeyScrollingType(); if (QString::compare(oldType, N_SCROLLING) != 0) { tpsettings->set(oldType, false); } //新滚动类型设置为true,跳过N_SCROLLING QString data = ui->scrollingTypeComBox->currentData().toString(); if (QString::compare(data, N_SCROLLING) != 0) tpsettings->set(data, true); if (QString::compare(data, N_SCROLLING) == 0) { tpsettings->set(V_EDGE_KEY,false); tpsettings->set(H_EDGE_KEY,false); tpsettings->set(V_FINGER_KEY,false); tpsettings->set(H_FINGER_KEY,false); } }); } void Touchpad::initTouchpadStatus(){ //初始化启用按钮 enableBtn->blockSignals(true); enableBtn->setChecked(tpsettings->get(ACTIVE_TOUCHPAD_KEY).toBool()); enableBtn->blockSignals(false); // 初始化打字禁用 typingBtn->blockSignals(true); typingBtn->setChecked(tpsettings->get(DISABLE_WHILE_TYPING_KEY).toBool()); typingBtn->blockSignals(false); // 初始化触摸板点击 clickBtn->blockSignals(true); clickBtn->setChecked(tpsettings->get(TOUCHPAD_CLICK_KEY).toBool()); clickBtn->blockSignals(false); // 插入鼠标时候禁用触摸板 mMouseDisTouchBtn->blockSignals(true); mMouseDisTouchBtn->setChecked(tpsettings->get(MOUSE_DISBALE_TOUCHPAD).toBool()); mMouseDisTouchBtn->blockSignals(false); //初始化滚动 ui->scrollingTypeComBox->blockSignals(true); ui->scrollingTypeComBox->setCurrentIndex(ui->scrollingTypeComBox->findData(_findKeyScrollingType())); ui->scrollingTypeComBox->blockSignals(false); } QString Touchpad::_findKeyScrollingType(){ if (tpsettings->get(V_EDGE_KEY).toBool()) return V_EDGE_KEY; if (tpsettings->get(H_EDGE_KEY).toBool()) return H_EDGE_KEY; if (tpsettings->get(V_FINGER_KEY).toBool()) return V_FINGER_KEY; if (tpsettings->get(H_FINGER_KEY).toBool()) return H_FINGER_KEY; return N_SCROLLING; } void Touchpad::setModuleVisible(bool visible) { ui->typingFrame->setVisible(visible); ui->clickFrame->setVisible(visible); ui->scrollingFrame->setVisible(visible); } void Touchpad::isWaylandPlatform() { QString sessionType = getenv("XDG_SESSION_TYPE"); if (!sessionType.compare(kSession, Qt::CaseSensitive)) { mIsWayland = true; } else { mIsWayland = false; } } void Touchpad::initWaylandDbus() { mWaylandIface = new QDBusInterface("org.ukui.KWin", "/org/ukui/KWin/InputDevice", "org.ukui.KWin.InputDeviceManager", QDBusConnection::sessionBus(), this); if (mWaylandIface->isValid()) { initWaylandTouchpadStatus(); } } void Touchpad::initWaylandTouchpadStatus() { QVariant deviceReply = mWaylandIface->property("devicesSysNames"); if (deviceReply.isValid()) { QStringList deviceList = deviceReply.toStringList(); for (QString device : deviceList) { QDBusInterface *deviceIface = new QDBusInterface("org.ukui.KWin", "/org/ukui/KWin/InputDevice/"+ device, "org.ukui.KWin.InputDevice", QDBusConnection::sessionBus(), this); if (deviceIface->isValid() && deviceIface->property("touchpad").toBool()) { mExistTouchpad = true; return; } } } mExistTouchpad = false; } void Touchpad::initWaylandConnection() { connect(enableBtn, &SwitchButton::checkedChanged, this, [=](bool checked){ mDeviceIface->setProperty("enabled", checked); }); connect(clickBtn, &SwitchButton::checkedChanged, this, [=](bool checked){ mDeviceIface->setProperty("tapToClick", checked); }); } bool findSynaptics(){ XDeviceInfo *device_info; int n_devices; bool retval; if (_supportsXinputDevices() == false) return true; device_info = XListInputDevices (QX11Info::display(), &n_devices); if (device_info == nullptr) return false; retval = false; for (int i = 0; i < n_devices; i++) { XDevice *device; device = _deviceIsTouchpad (&device_info[i]); if (device != nullptr) { retval = true; break; } } if (device_info != nullptr) XFreeDeviceList (device_info); return retval; } bool _supportsXinputDevices(){ int op_code, event, error; return XQueryExtension (QX11Info::display(), "XInputExtension", &op_code, &event, &error); } XDevice* _deviceIsTouchpad (XDeviceInfo *deviceinfo){ XDevice *device; if (deviceinfo->type != XInternAtom (QX11Info::display(), XI_TOUCHPAD, true)) return nullptr; device = XOpenDevice (QX11Info::display(), deviceinfo->id); if(device == nullptr) { qDebug()<<"device== null"; return nullptr; } if (_deviceHasProperty(device, "libinput Tapping Enabled") || _deviceHasProperty(device, "Synaptics Off")) { return device; } XCloseDevice (QX11Info::display(), device); return nullptr; } bool _deviceHasProperty(XDevice *device, const char *property_name){ Atom realtype, prop; int realformat; unsigned long nitems, bytes_after; unsigned char *data; prop = XInternAtom (QX11Info::display(), property_name, True); if (!prop) return false; if ((XGetDeviceProperty (QX11Info::display(), device, prop, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data) == Success) && (realtype != None)) { XFree (data); return true; } return false; } ukui-control-center/plugins/devices/touchpad/touchpad.pro0000644000175000017500000000215114201663716022657 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2020-02-26T16:15:07 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets x11extras dbus greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(touchpad) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ #LIBS += -L$$[QT_INSTALL_LIBS] -ltouchpadclient -lXi -lgsettings-qt LIBS += -L$$[QT_INSTALL_LIBS] -lXi -lgsettings-qt CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gsettings-qt \ xi \ x11 DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ touchpad.cpp HEADERS += \ touchpad.h FORMS += \ touchpad.ui INSTALLS += target ukui-control-center/plugins/devices/projection/0000755000175000017500000000000014201663716020674 5ustar fengfengukui-control-center/plugins/devices/projection/projection.h0000644000175000017500000000521114201663716023220 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef PROJECTION_H #define PROJECTION_H #include #include #include #include #include #include #include #include "shell/interface.h" #include "HoverWidget/hoverwidget.h" #include "ImageUtil/imageutil.h" #include "SwitchButton/switchbutton.h" #include "changeprojectionname.h" namespace Ui { class Projection; } class Projection : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Projection(); ~Projection(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; bool getWifiStatus(); void setWifiStatus(bool status); public: void initComponent(); void showChangeProjectionNameDialog(); void changeProjectionName(QString name); protected: bool eventFilter(QObject *watched, QEvent *event); private: Ui::Projection *ui; QString pluginName; int pluginType; QWidget * pluginWidget; HoverWidget * addWgt; SwitchButton *projectionBtn; QLabel *m_pin; bool enter = false; QString hostName; private: QTimer * pTimer; QDBusInterface *m_pServiceInterface; bool m_bbluetoothStatus; QGSettings * qtSettings; bool m_autoclose = false; void catchsignal(); void delaymsec(int msec); int get_process_status(void); void init_button_status(int); public slots: void projectionButtonClickSlots(bool status); void projectionPinSlots(QString type,QString pin); void netPropertiesChangeSlot(QMap property); }; #endif // PROJECTION_H ukui-control-center/plugins/devices/projection/changeprojectionname.cpp0000644000175000017500000000647714201663716025601 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "changeprojectionname.h" #include "ui_changeprojectionname.h" #include extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); ChangeProjectionName::ChangeProjectionName(QWidget *parent) : QDialog(parent), ui(new Ui::ChangeProjectionName) { ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); // setWindowFlags(Qt::WindowCloseButtonHint); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); ui->saveBtn->setEnabled(false); connect(ui->lineEdit, &QLineEdit::textChanged, this, [=](QString txt){ if (txt.toLocal8Bit().length() > 31){ ui->tipLabel->setText(tr("Name is too long, change another one.")); ui->saveBtn->setEnabled(false); }else { ui->tipLabel->setText(tr("")); } if (!txt.isEmpty() && ui->tipLabel->text().isEmpty()){ ui->saveBtn->setEnabled(true); } else { ui->saveBtn->setEnabled(false); } }); connect(ui->cancelBtn, &QPushButton::clicked, [=]{ close(); }); connect(ui->saveBtn, &QPushButton::clicked, [=]{ emit sendNewProjectionName(ui->lineEdit->text()); close(); }); } ChangeProjectionName::~ChangeProjectionName() { delete ui; } void ChangeProjectionName::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QPainterPath rectPath; rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); // 画一个黑底 QPixmap pixmap(this->rect().size()); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); // 模糊这个黑底 QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); pixmapPainter2.setRenderHint(QPainter::Antialiasing); pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); pixmapPainter2.setPen(Qt::transparent); pixmapPainter2.setBrush(Qt::transparent); pixmapPainter2.drawPath(rectPath); // 绘制阴影 p.drawPixmap(this->rect(), pixmap, pixmap.rect()); // 绘制一个背景 p.save(); p.fillPath(rectPath,palette().color(QPalette::Base)); p.restore(); } ukui-control-center/plugins/devices/projection/projection.ui0000644000175000017500000003050214201663716023407 0ustar fengfeng Projection 0 0 800 710 0 0 16777215 16777215 Printer 0 0 0 0 0 0 0 Projection true 550 0 16777215 16777215 0 0 0 0 0 8 0 0 64 16777215 64 QFrame::Box QFrame::Raised 0 0 0 0 true 0 0 8 8 0 0 0 0 0 0 30 15 22 15 22 Qt::Horizontal 588 15 msg info true 0 184 label for set size Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 20 200 0 0 128 128 128 128 Qt::LeftToRight :/touping.png msg Qt::AlignCenter true Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/projection/touping.png0000644000175000017500000000742514201663716023077 0ustar fengfengPNG  IHDR>aIDATx^]Yl g $B H()R"(_1HI~H " ">1y¾`cm+:˔^W뮷t] Su%ٛ 08>} ΁Ohs 7 08>} ΁Ohs WHՄŌє€3ƞSJ[cմ}U]]UB{չi)[+++rvKD"}B焐^th_]]ݙJb_۷/=z4:t(),,$yyyou7oH{{;ywyƶp8Tj`dĉFpԩSVUUU r]2 x/vӶyg?~p8 G -y*y78q;Pqɓz4Nttt62h 6,X@˴!gZ`$??_K 0v_@]x)xb, Rϟe y%h4A>}Z /_v l#͏O1Fp ءP:?v 8I@/$h ly Կ3x`+!!N5+WӦMV =h aĈQx&AΝcU+IDFEFim!BhtKxܹt2Z:n9seOᖅ1sMurk(OAv >:a'@pݜk=fAܓ5&[ZZzryc[( c |9|(??GEEŻ$K%Θ1Cb=5ɭŠA~'V/h'c1x9;?sz8c5mdBO*NLE\?''p1N4p4bN) 5+SFx8X J'd82`֦2 M#"Q[Y&A0|"Z@T[PUU.}HpNZWW+ն]``4 _`6 P}xv8ł&H2oY^Nx`G3h"ҝVpx#j00څ}e^%Kߏ;n@QVX+K1ј~<uR Mcw2h|yXNF䑰уL/ ~//~x9@Ϝ@6U\0(!@ޫoUsJW}ǥlV m /WpRo۲㏖)!p89G'v PͷGlчK S?@J R4+#e;YM"4Ys dsQP. ui`3d3r f+MMM'3'2evpz !e66liXiH2$Gi&Q'Űr2Yֆّj H~@ ĐKdƻx:냆|$`trR-}gˊJ,) l mב˄UF=n{T={R@ϭa8TѝמWa6nj pSZBƍE=R"v.vy5T3 ko gb|U-觔ҿc( 2 l$x!w_Gf#u Y 0;+[)ZX BLaf6CpM~5ݑ#HJD_D"}B wzWL--m* xApgUK8y6hMu%e aAAcER=uQ=r;w}cd_zΨ܉qrCkݻ:;;QI˭ү7mʜDXL5HYYr w.y0gwڥ3y?uƍ>q`*w9 ۷c^1JJ6lgtXԸve'={] 6|FwFfV.|ʂTGH8fj IH DW6!3ʼΥG)'ɇcKtM\<%@9 `p|F@o4@9 `p|F@o4@iHXIENDB`ukui-control-center/plugins/devices/projection/projection.pro0000644000175000017500000000204714201663716023575 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-02-28T14:09:42 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets QT += core gui widgets dbus TEMPLATE = lib CONFIG += plugin CONFIG += link_pkgconfig PKGCONFIG += gsettings-qt TARGET = $$qtLibraryTarget(projection) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ INCLUDEPATH += /usr/lib/gcc/aarch64-linux-gnu/9/include/ #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ projection.cpp \ changeprojectionname.cpp HEADERS += \ projection.h \ changeprojectionname.h FORMS += \ projection.ui \ changeprojectionname.ui \ INSTALLS += target RESOURCES += \ pic.qrc ukui-control-center/plugins/devices/projection/projection.cpp0000644000175000017500000003236114201663716023561 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "projection.h" #include "ui_projection.h" #include #include #include #include #include #define ITEMFIXEDHEIGH 58 #define THEME_QT_SCHEMA "org.ukui.style" #define MODE_QT_KEY "style-name" #define SYSTEM_CMD_ERROR -1 enum { NOT_SUPPORT_P2P = 0, SUPPORT_P2P_WITHOUT_DEV, SUPPORT_P2P_PERFECT, OP_NO_RESPONSE, NO_SERVICE }; enum { PROJECTION_RUNNING = 256, DAEMON_NOT_RUNNING = 512 }; Projection::Projection() { pluginName = tr("Projection"); pluginType = DEVICES; ui = new Ui::Projection; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_StyledBackground,true); pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); projectionBtn = new SwitchButton(pluginWidget); // ui->pinframe->hide(); init_button_status(get_process_status()); // qDebug()<<"---- Projection contructed, then subscribe slot func "; connect(projectionBtn, SIGNAL(checkedChanged(bool)), this, SLOT(projectionButtonClickSlots(bool))); // m_pin = new QLabel(pluginWidget); // ui->label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); ui->label->setStyleSheet("QLabel{color: palette(windowText);}"); //~ contents_path /projection/Open Projection ui->titleLabel->setText(tr("Open Projection")); ui->titleLabel->setStyleSheet("QLabel{color: palette(windowText);}"); m_pServiceInterface = new QDBusInterface("org.freedesktop.miracleagent", "/org/freedesktop/miracleagent", "org.freedesktop.miracleagent.op", QDBusConnection::sessionBus()); QString path=QDir::homePath()+"/.config/miracast.ini"; QSettings *setting=new QSettings(path,QSettings::IniFormat); setting->beginGroup("projection"); bool bo=setting->contains("host"); qDebug()<property("Hostname").value(); setting->setValue("host",hostName); setting->sync(); setting->endGroup(); initComponent(); }else { hostName = setting->value("host").toString(); } //ui->projectionNameWidget->setFixedHeight(40); ui->projectionName->setText(hostName); ui->projectionNameChange->setProperty("useIconHighlightEffect", 0x8); ui->projectionNameChange->setPixmap(QIcon::fromTheme("document-edit-symbolic").pixmap(ui->projectionNameChange->size())); ui->projectionNameWidget->installEventFilter(this); ui->horizontalLayout->addWidget(projectionBtn); initComponent(); } void Projection::changeProjectionName(QString name){ qDebug() << name; QString path=QDir::homePath()+"/.config/miracast.ini"; QSettings *setting=new QSettings(path,QSettings::IniFormat); setting->beginGroup("projection"); setting->setValue("host",name); setting->sync(); setting->endGroup(); m_pServiceInterface->call("UiSetName",name); ui->projectionName->setText(name); } void Projection::showChangeProjectionNameDialog(){ ChangeProjectionName * dialog = new ChangeProjectionName(); connect(dialog, &ChangeProjectionName::sendNewProjectionName, [=](QString name){ changeProjectionName(name); }); dialog->exec(); } bool Projection::getWifiStatus() { QDBusInterface interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus() ); // 获取当前wifi是否打开 QDBusReply m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); if (m_result.isValid()) { bool status = m_result.value().toBool(); return status; } else { qDebug()<<"org.freedesktop.NetworkManager get invalid"<start(program, arg); nmcliCmd->waitForStarted(); } bool Projection::eventFilter(QObject *watched, QEvent *event){ if (watched == ui->projectionNameWidget){ if (event->type() == QEvent::MouseButtonPress){ QMouseEvent * mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton ){ showChangeProjectionNameDialog(); } } } return QObject::eventFilter(watched, event); } void Projection::catchsignal() { while (1) { m_pServiceInterface = new QDBusInterface("org.freedesktop.miracle.wifi", "/org/freedesktop/miracle/wifi/ui", "org.freedesktop.miracle.wifi.ui", QDBusConnection::systemBus()); if (m_pServiceInterface->isValid()) { connect(m_pServiceInterface,SIGNAL(PinCode(QString, QString)),this,SLOT(projectionPinSlots(QString,QString))); return; }else { delete m_pServiceInterface; delaymsec(1000); } } \ } void Projection::delaymsec(int msec) { QTime dieTime = QTime::currentTime().addMSecs(msec); while( QTime::currentTime() < dieTime ) QCoreApplication::processEvents(QEventLoop::AllEvents, 100); } Projection::~Projection() { delete ui; delete m_pServiceInterface; } QString Projection::get_plugin_name(){ QFile server("/usr/bin/miracle-wifid"); QFile agent("/usr/bin/miracle-agent"); if(!server.exists() || !agent.exists()) return NULL; return pluginName; } int Projection::get_plugin_type(){ return pluginType; } int Projection::get_process_status(void) { int res; do{ res = system("checkDaemonRunning.sh"); }while(SYSTEM_CMD_ERROR == res); return res; } void Projection::init_button_status(int status) { // qDebug()<<"---- button init status "<setChecked(true); } else { projectionBtn->setChecked(false);//projection not switch-on, or daemon programs not running at all } } QWidget *Projection::get_plugin_ui(){ int res; int projectionstatus; res = get_process_status(); init_button_status(res); if (res == DAEMON_NOT_RUNNING){ projectionstatus = NO_SERVICE; } else{ QDBusMessage result = m_pServiceInterface->call("PreCheck"); QList outArgs = result.arguments(); projectionstatus = outArgs.at(0).value(); qDebug() << "---->" << projectionstatus; } ui->widget->hide(); ui->label->hide(); ui->label_3->hide(); ui->widget_2->show(); ui->label_setsize->setText(""); //First, we check whether service process is running if (NO_SERVICE == projectionstatus) { ui->label_2->setText(tr("Service exception,please restart the system")); ui->projectionNameWidget->setEnabled(false); projectionBtn->setEnabled(false); } //Then let's check whether hardware is ok else if (NOT_SUPPORT_P2P == projectionstatus) { ui->label_2->setText(tr("Network card is not detected or the driver is not supported.")); ui->projectionNameWidget->setEnabled(false); projectionBtn->setEnabled(false); } else if (SUPPORT_P2P_WITHOUT_DEV == projectionstatus || SUPPORT_P2P_PERFECT == projectionstatus) { if(getWifiStatus()) { qDebug()<<"wifi is on now"; if(SUPPORT_P2P_WITHOUT_DEV == projectionstatus) ui->label_3->setText(tr("Please keep WLAN on;\nWireless-network functions will be invalid when the screen projection on")); if(SUPPORT_P2P_PERFECT == projectionstatus) ui->label_3->setText(tr("Please keep WLAN on;\nWireless will be temporarily disconnected when the screen projection on")); ui->widget->show(); ui->label->show(); ui->label_3->show(); ui->widget_2->hide(); ui->projectionNameWidget->setEnabled(true); projectionBtn->setEnabled(true); ui->label_setsize->setText(tr("After opening the switch button,open the projection screen in the mobile phone drop-down menu,follow the prompts.See the user manual for details")); } else { qDebug()<<"wifi is off now"; ui->label_2->setText(tr("WLAN is off, please turn on WLAN")); ui->projectionNameWidget->setEnabled(false); projectionBtn->setEnabled(false); } } else if (OP_NO_RESPONSE == projectionstatus) { ui->label_2->setText(tr("Wireless network card is busy. Please try again later")); ui->projectionNameWidget->setEnabled(false); projectionBtn->setEnabled(false); } //监听WLAN开关 QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager"), "org.freedesktop.NetworkManager", "PropertiesChanged", this, SLOT(netPropertiesChangeSlot(QMap))); return pluginWidget; } void Projection::netPropertiesChangeSlot(QMap property) { if (property.keys().contains("WirelessEnabled")) { qDebug()<<"WLAN status changed"; get_plugin_ui(); } } void Projection::plugin_delay_control(){ } const QString Projection::name() const { return QStringLiteral("projection"); } void Projection::projectionPinSlots(QString type, QString pin) { if (type.contains("clear")) { //m_pin->clear(); } else { qDebug()<setText(pin); } } void Projection::projectionButtonClickSlots(bool status) { QDBusInterface interface( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QString appname = tr("projection"); quint32 notify_id = 0; QString app_icon = "kylin-miracast"; QString tilte = tr("Projection is ")+ QString(status?tr("on"):tr("off")); QString body = status?tr("Please enable or refresh the scan at the projection device"):tr("You need to turn on the projection again"); qint32 timeout = 5000; QStringList arry1; QVariantMap arry2; if (status){ QDBusMessage result = m_pServiceInterface->call("Start",ui->projectionName->text(),""); QList outArgs = result.arguments(); int res = outArgs.at(0).value(); if(res) { ui->label_3->setText(tr("Failed to execute. Please reopen the page later")); }else { interface.call(QLatin1String("Notify"),appname,notify_id,app_icon,tilte,body,arry1,arry2,timeout); } } else { m_pServiceInterface->call("Stop"); interface.call(QLatin1String("Notify"),appname,notify_id,app_icon,tilte,body,arry1,arry2,timeout); } } void Projection::initComponent(){ addWgt = new HoverWidget(""); addWgt->setObjectName("addwgt"); addWgt->setMinimumSize(QSize(580, 64)); addWgt->setMaximumSize(QSize(16777215, 64)); addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(base); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #2FB3E8; border-radius: 4px;}"); QHBoxLayout *addLyt = new QHBoxLayout; QLabel * iconLabel = new QLabel(); QLabel * textLabel = new QLabel(tr("Add Bluetooths")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); addLyt->addItem(new QSpacerItem(8,10,QSizePolicy::Fixed)); addLyt->addWidget(iconLabel); addLyt->addItem(new QSpacerItem(16,10,QSizePolicy::Fixed)); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); addWgt->hide(); } ukui-control-center/plugins/devices/projection/changeprojectionname.ui0000644000175000017500000001431414201663716025421 0ustar fengfeng ChangeProjectionName 0 0 500 208 500 208 500 208 Change Username false false 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 8 32 32 32 24 Changename Qt::Horizontal 40 20 100 36 100 36 ChangeProjectionname 320 36 320 36 16 Qt::Horizontal 40 20 100 33 100 33 Cancel 100 33 100 33 Save TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/projection/changeprojectionname.h0000644000175000017500000000237714201663716025241 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef CHANGEPROJECTIONNAME_H #define CHANGEPROJECTIONNAME_H #include #include #include namespace Ui { class ChangeProjectionName; } class ChangeProjectionName : public QDialog { Q_OBJECT public: explicit ChangeProjectionName(QWidget *parent = nullptr); ~ChangeProjectionName(); private: Ui::ChangeProjectionName *ui; protected: void paintEvent(QPaintEvent *); Q_SIGNALS: void sendNewProjectionName(QString name); }; #endif // CHANGEUSERNAME_H ukui-control-center/plugins/devices/projection/pic.qrc0000644000175000017500000000020114201663716022147 0ustar fengfeng touping.png ukui-control-center/plugins/devices/mouse/0000755000175000017500000000000014201663716017650 5ustar fengfengukui-control-center/plugins/devices/mouse/mousecontrol.ui0000644000175000017500000011231314201663716022741 0ustar fengfeng MouseControl 0 0 800 817 0 0 16777215 16777215 Template 2 0 0 32 48 0 0 Mouse Key Settings Qt::Vertical QSizePolicy::Fixed 20 6 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 128 0 128 16777215 Hand habit 0 30 16777215 30 550 50 960 50 QFrame::Box QFrame::Plain 0 16 0 16 0 0 0 0 136 0 16777215 16777215 mouse wheel speed Qt::Vertical 10 40 0 0 40 0 16777215 16777215 Slow 1 10 1 Qt::Horizontal 0 0 40 0 16777215 16777215 Qt::LeftToRight Fast Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 550 60 960 60 QFrame::Box QFrame::Plain 0 16 0 16 0 0 0 0 136 0 16777215 16777215 Doubleclick delay Qt::Vertical 10 40 0 0 40 0 16777215 16777215 Short 170 1000 100 100 Qt::Horizontal 0 0 40 0 16777215 16777215 Long Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Horizontal QSizePolicy::Fixed 40 20 Qt::Vertical QSizePolicy::Fixed 20 38 0 0 Pointer Settings Qt::Vertical QSizePolicy::Fixed 20 6 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 0 136 0 136 16777215 Speed Qt::Vertical 10 40 0 0 40 0 16777215 16777215 Slow 100 1000 50 50 Qt::Horizontal 0 0 40 0 16777215 16777215 Qt::LeftToRight Fast Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 136 0 136 16777215 Acceleration 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 128 0 16777215 16777215 Visibility Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 128 0 128 16777215 Pointer size 0 30 16777215 30 Qt::Vertical QSizePolicy::Fixed 20 38 0 0 Cursor Settings Qt::Vertical QSizePolicy::Fixed 20 6 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 Enable flashing on text area Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 136 0 136 16777215 Cursor weight 0 0 40 0 40 16777215 Thin Qt::Horizontal 0 0 50 0 50 16777215 Coarse Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Horizontal QSizePolicy::Fixed 16 20 80 30 80 30 550 50 960 50 QFrame::Box 0 16 0 16 0 0 0 0 136 0 136 16777215 Cursor speed 0 0 40 0 40 16777215 Slow 100 2500 200 200 Qt::Horizontal false 0 0 40 0 40 16777215 Fast Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/mouse/mouse.pro0000644000175000017500000000206414201663716021524 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-08-22T11:12:59 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets x11extras dbus #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(mouse) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ LIBS += -L$$[QT_INSTALL_LIBS] -lXi -lgsettings-qt #LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt ##加载gio库和gio-unix库 CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gio-2.0 \ gio-unix-2.0 \ gsettings-qt \ x11 #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ mousecontrol.cpp HEADERS += \ mousecontrol.h FORMS += \ mousecontrol.ui INSTALLS += target ukui-control-center/plugins/devices/mouse/mousecontrol.h0000644000175000017500000000475414201663716022564 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef MOUSECONTROL_H #define MOUSECONTROL_H #include #include #include #include #include #include #include #include #include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" namespace Ui { class MouseControl; } class MyLabel : public QLabel { Q_OBJECT public: MyLabel(); ~MyLabel(); public: QGSettings * mSettings; protected: void mouseDoubleClickEvent(QMouseEvent *event); }; class MouseControl : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: MouseControl(); ~MouseControl() Q_DECL_OVERRIDE; QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; void initSearchText(); void setupComponent(); void initHandHabitStatus(); void initPointerStatus(); void initCursorStatus(); void initWheelStatus(); private slots: void mouseSizeChange(); private: Ui::MouseControl *ui; QWidget * pluginWidget; SwitchButton * visiblityBtn; SwitchButton * flashingBtn; SwitchButton * mAccelBtn; QGSettings *settings; QGSettings *sesstionSetttings; QGSettings *desktopSettings; QGSettings *mThemeSettings; int pluginType; QString leftStr; QString rightStr; QString pluginName; QStringList mouseKeys; bool mFirstLoad; }; #endif // MOUSECONTROL_H ukui-control-center/plugins/devices/mouse/mousecontrol.cpp0000644000175000017500000003663414201663716023121 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "mousecontrol.h" #include "ui_mousecontrol.h" #include #include #include #include #include #include #include #include #include #include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif #include #include #include #define MOUSE_SCHEMA "org.ukui.peripherals-mouse" #define HAND_KEY "left-handed" #define DOUBLE_CLICK_KEY "double-click" #define LOCATE_KEY "locate-pointer" #define CURSOR_SIZE_KEY "cursor-size" #define ACCELERATION_KEY "motion-acceleration" #define THRESHOLD_KEY "motion-threshold" #define WHEEL_KEY "wheel-speed" #define ACCEL_KEY "mouse-accel" #define SESSION_SCHEMA "org.ukui.session" #define SESSION_MOUSE_KEY "mouse-size-changed" #define DESKTOP_SCHEMA "org.mate.interface" #define CURSOR_BLINK_KEY "cursor-blink" #define CURSOR_BLINK_TIME_KEY "cursor-blink-time" #define THEME_SCHEMA "org.ukui.style" MyLabel::MyLabel() { setAttribute(Qt::WA_DeleteOnClose); QSizePolicy pSizePolicy = this->sizePolicy(); pSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); pSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); this->setSizePolicy(pSizePolicy); setFixedSize(QSize(54, 28)); setScaledContents(true); setPixmap(QPixmap(":/img/plugins/mouse/double-click-off.png")); const QByteArray id(MOUSE_SCHEMA); if (QGSettings::isSchemaInstalled(id)){ mSettings = new QGSettings(id, QByteArray(), this); } this->setToolTip(tr("double-click to test")); } MyLabel::~MyLabel() { } void MyLabel::mouseDoubleClickEvent(QMouseEvent *event) { Q_UNUSED(event); int delay = mSettings->get(DOUBLE_CLICK_KEY).toInt(); setPixmap(QPixmap(":/img/plugins/mouse/double-click-on.png")); QTimer::singleShot(delay, this, [=]{ setPixmap(QPixmap(":/img/plugins/mouse/double-click-off.png")); }); } MouseControl::MouseControl() : mFirstLoad(true) { pluginName = tr("Mouse"); pluginType = DEVICES; } MouseControl::~MouseControl() { if (!mFirstLoad) { delete ui; ui = nullptr; } } QString MouseControl::get_plugin_name() { return pluginName; } int MouseControl::get_plugin_type() { return pluginType; } QWidget *MouseControl::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; ui = new Ui::MouseControl; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); initSearchText(); //初始化鼠标设置GSettings const QByteArray id(MOUSE_SCHEMA); const QByteArray sessionId(SESSION_SCHEMA); const QByteArray idd(DESKTOP_SCHEMA); const QByteArray themeId(THEME_SCHEMA); if (QGSettings::isSchemaInstalled(sessionId) && QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(idd)) { sesstionSetttings = new QGSettings(sessionId, QByteArray(), this); settings = new QGSettings(id, QByteArray(), this); desktopSettings = new QGSettings(idd, QByteArray(), this); mThemeSettings = new QGSettings(themeId, QByteArray(), this); mouseKeys = settings->keys(); setupComponent(); initHandHabitStatus(); initPointerStatus(); initCursorStatus(); initWheelStatus(); } } return pluginWidget; } void MouseControl::plugin_delay_control() { } const QString MouseControl::name() const { return QStringLiteral("mouse"); } void MouseControl::initSearchText() { //~ contents_path /mouse/mouse wheel speed ui->slowLabel->setText(tr("mouse wheel speed")); //~ contents_path /mouse/Hand habit ui->handLabel->setText(tr("Hand habit")); //~ contents_path /mouse/Doubleclick delay ui->delayLabel->setText(tr("Doubleclick delay")); //~ contents_path /mouse/Speed ui->speedLabel->setText(tr("Speed")); ui->label_2->setMinimumWidth(50); ui->label_3->setMinimumWidth(50); //~ contents_path /mouse/Acceleration ui->accelLabel->setText(tr("Acceleration")); //~ contents_path /mouse/Visibility ui->visLabel->setText(tr("Visibility")); //~ contents_path /mouse/Pointer size ui->sizeLabel->setText(tr("Pointer size")); //~ contents_path /mouse/Enable flashing on text area ui->flashLabel->setText(tr("Enable flashing on text area")); //~ contents_path /mouse/Cursor speed ui->cursorspdLabel->setText(tr("Cursor speed")); ui->label_17->setMinimumWidth(50); ui->label_18->setMinimumWidth(50); ui->label_6->setMinimumWidth(50); ui->label_7->setMinimumWidth(50); ui->label_21->setMinimumWidth(50); ui->label_22->setMinimumWidth(50); } void MouseControl::setupComponent() { ui->cursorWeightFrame->hide(); //设置左手右手鼠标控件 ui->handHabitComBox->addItem(tr("Lefthand"), true); ui->handHabitComBox->addItem(tr("Righthand"), false); ui->doubleClickHorLayout->addWidget(new MyLabel()); //设置指针可见性控件 visiblityBtn = new SwitchButton(pluginWidget); ui->visibilityHorLayout->addWidget(visiblityBtn); // 鼠标加速度控件 mAccelBtn = new SwitchButton(pluginWidget); mAccelBtn->setChecked(settings->get(ACCEL_KEY).toBool()); ui->accelLayout->addStretch(); ui->accelLayout->addWidget(mAccelBtn); //设置指针大小 ui->pointerSizeComBox->setMaxVisibleItems(5); ui->pointerSizeComBox->addItem(tr("Default(Recommended)"), 24); //100% ui->pointerSizeComBox->addItem(tr("Medium"), 32); //125% ui->pointerSizeComBox->addItem(tr("Large"), 48); //150% //设置鼠标滚轮是否显示 if (!mouseKeys.contains("wheelSpeed")) { ui->midSpeedFrame->setVisible(false); } //设置启用光标闪烁 flashingBtn = new SwitchButton(pluginWidget); ui->enableFlashingHorLayout->addWidget(flashingBtn); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->handHabitComBox, static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ #else connect(ui->handHabitComBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { #endif Q_UNUSED(index) settings->set(HAND_KEY, ui->handHabitComBox->currentData().toBool()); }); connect(ui->doubleclickHorSlider, &QSlider::sliderReleased, [=] { settings->set(DOUBLE_CLICK_KEY, ui->doubleclickHorSlider->value()); qApp->setDoubleClickInterval(ui->doubleclickHorSlider->value()); }); connect(ui->pointerSpeedSlider, &QSlider::valueChanged, [=](int value) { settings->set(ACCELERATION_KEY, static_cast(value)/ui->pointerSpeedSlider->maximum()*10); }); connect(visiblityBtn, &SwitchButton::checkedChanged, [=](bool checked) { settings->set(LOCATE_KEY, checked); }); connect(ui->pointerSizeComBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseControl::mouseSizeChange); connect(flashingBtn, &SwitchButton::checkedChanged, [=](bool checked) { ui->cursorSpeedFrame->setVisible(checked); desktopSettings->set(CURSOR_BLINK_KEY, checked); mThemeSettings->set(CURSOR_BLINK_KEY, checked); if (!checked) { mThemeSettings->set(CURSOR_BLINK_TIME_KEY, 0); } else { int mValue = ui->cursorSpeedSlider->maximum() - ui->cursorSpeedSlider->value() + ui->cursorSpeedSlider->minimum(); mThemeSettings->set(CURSOR_BLINK_TIME_KEY, mValue); } }); connect(ui->midHorSlider, &QSlider::sliderReleased, [=] { settings->set(WHEEL_KEY, ui->midHorSlider->value()); }); connect(settings,&QGSettings::changed,[=] (const QString &key){ if(key == "locatePointer") { visiblityBtn->blockSignals(true); visiblityBtn->setChecked(settings->get(LOCATE_KEY).toBool()); visiblityBtn->blockSignals(false); } else if(key == "mouseAccel") { ui->doubleclickHorSlider->blockSignals(true); mAccelBtn->setChecked(settings->get(ACCEL_KEY).toBool()); ui->doubleclickHorSlider->blockSignals(false); } else if(key == "doubleClick") { int dc = settings->get(DOUBLE_CLICK_KEY).toInt(); ui->doubleclickHorSlider->blockSignals(true); ui->doubleclickHorSlider->setValue(dc); ui->doubleclickHorSlider->blockSignals(false); } else if(key == "wheelSpeed") { ui->midHorSlider->setValue(settings->get(WHEEL_KEY).toInt()); } else if(key == "motionAcceleration") { ui->pointerSpeedSlider->blockSignals(true); ui->pointerSpeedSlider->setValue(static_cast(settings->get(ACCELERATION_KEY).toDouble()*100)); ui->pointerSpeedSlider->blockSignals(false); } else if(key == "leftHanded") { int handHabitIndex = ui->handHabitComBox->findData(settings->get(HAND_KEY).toBool()); ui->handHabitComBox->blockSignals(true); ui->handHabitComBox->setCurrentIndex(handHabitIndex); ui->handHabitComBox->blockSignals(false); } else if(key == "cursorSize") { int pointerSizeIndex = ui->pointerSizeComBox->findData(settings->get(CURSOR_SIZE_KEY).toInt()); ui->pointerSizeComBox->blockSignals(true); ui->pointerSizeComBox->setCurrentIndex(pointerSizeIndex); ui->pointerSizeComBox->blockSignals(false); } }); connect(desktopSettings,&QGSettings::changed,[=](const QString &key) { if(key == "cursorBlinkTime") { ui->cursorSpeedSlider->blockSignals(true); int mValue = ui->cursorSpeedSlider->maximum() - desktopSettings->get(CURSOR_BLINK_TIME_KEY).toInt() + ui->cursorSpeedSlider->minimum(); ui->cursorSpeedSlider->setValue(mValue); ui->cursorSpeedSlider->blockSignals(false); } else if(key == "cursorBlink") { flashingBtn->blockSignals(true); flashingBtn->setChecked(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); ui->cursorSpeedFrame->setVisible(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); flashingBtn->blockSignals(false); } }); connect(ui->cursorSpeedSlider, &QSlider::sliderReleased, [=] { int mValue = ui->cursorSpeedSlider->maximum() - ui->cursorSpeedSlider->value() + ui->cursorSpeedSlider->minimum(); desktopSettings->set(CURSOR_BLINK_TIME_KEY, mValue); mThemeSettings->set(CURSOR_BLINK_TIME_KEY, mValue); }); connect(mAccelBtn, &SwitchButton::checkedChanged, this, [=] (bool checked) { settings->set(ACCEL_KEY, checked); }); } void MouseControl::initHandHabitStatus() { int handHabitIndex = ui->handHabitComBox->findData(settings->get(HAND_KEY).toBool()); ui->handHabitComBox->blockSignals(true); ui->handHabitComBox->setCurrentIndex(handHabitIndex); ui->handHabitComBox->blockSignals(false); int dc = settings->get(DOUBLE_CLICK_KEY).toInt(); ui->doubleclickHorSlider->blockSignals(true); ui->doubleclickHorSlider->setValue(dc); ui->doubleclickHorSlider->blockSignals(false); } void MouseControl::initPointerStatus() { //当前系统指针加速值,-1为系统默认 double mouse_acceleration = settings->get(ACCELERATION_KEY).toDouble(); //当前系统指针灵敏度,-1为系统默认 int mouse_threshold = settings->get(THRESHOLD_KEY).toInt(); //当从接口获取的是-1,则代表系统默认值,真实值需要从底层获取 if (mouse_threshold == -1 || static_cast(mouse_acceleration) == -1) { // speed sensitivity int accel_numerator, accel_denominator, threshold; //当加速值和灵敏度为系统默认的-1时,从底层获取到默认的具体值 XGetPointerControl(QX11Info::display(), &accel_numerator, &accel_denominator, &threshold); settings->set(ACCELERATION_KEY, static_cast(accel_numerator/accel_denominator)); settings->set(THRESHOLD_KEY, threshold); } //初始化指针速度控件 ui->pointerSpeedSlider->blockSignals(true); ui->pointerSpeedSlider->setValue(static_cast(settings->get(ACCELERATION_KEY).toDouble()*100)); ui->pointerSpeedSlider->blockSignals(false); //初始化可见性控件 visiblityBtn->blockSignals(true); visiblityBtn->setChecked(settings->get(LOCATE_KEY).toBool()); visiblityBtn->blockSignals(false); //初始化指针大小 int sizeIndex = ui->pointerSizeComBox->findData(settings->get(CURSOR_SIZE_KEY).toInt()); ui->pointerSizeComBox->blockSignals(true); ui->pointerSizeComBox->setCurrentIndex(sizeIndex); ui->pointerSizeComBox->blockSignals(false); } void MouseControl::initCursorStatus() { flashingBtn->blockSignals(true); flashingBtn->setChecked(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); ui->cursorSpeedFrame->setVisible(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); flashingBtn->blockSignals(false); ui->cursorSpeedSlider->blockSignals(true); int mValue = ui->cursorSpeedSlider->maximum() - desktopSettings->get(CURSOR_BLINK_TIME_KEY).toInt() + ui->cursorSpeedSlider->minimum(); ui->cursorSpeedSlider->setValue(mValue); ui->cursorSpeedSlider->blockSignals(false); } void MouseControl::initWheelStatus() { ui->midHorSlider->blockSignals(true); if (mouseKeys.contains("wheelSpeed")) { ui->midHorSlider->setValue(settings->get(WHEEL_KEY).toInt()); } ui->midHorSlider->blockSignals(false); } void MouseControl::mouseSizeChange() { settings->set(CURSOR_SIZE_KEY, ui->pointerSizeComBox->currentData().toInt()); QStringList keys = sesstionSetttings->keys(); if (keys.contains("mouseSizeChanged")) { sesstionSetttings->set(SESSION_MOUSE_KEY, true); } QString filename = QDir::homePath() + "/.config/kcminputrc"; QSettings *mouseSettings = new QSettings(filename, QSettings::IniFormat); mouseSettings->beginGroup("Mouse"); mouseSettings->setValue("cursorSize", ui->pointerSizeComBox->currentData().toInt()); mouseSettings->endGroup(); delete mouseSettings; mouseSettings = nullptr; QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange"); QList args; args.append(5); args.append(0); message.setArguments(args); QDBusConnection::sessionBus().send(message); } ukui-control-center/plugins/devices/bluetooth/0000755000175000017500000000000014201663716020525 5ustar fengfengukui-control-center/plugins/devices/bluetooth/bluetooth.cpp0000644000175000017500000000262114201663716023237 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "bluetooth.h" #include Bluetooth::Bluetooth() : mFirstLoad(true) { pluginName = tr("Bluetooth"); pluginType = DEVICES; } Bluetooth::~Bluetooth() { if (!mFirstLoad) { // delete pluginWidget; } } QString Bluetooth::get_plugin_name() { return pluginName; } int Bluetooth::get_plugin_type() { return pluginType; } QWidget *Bluetooth::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; pluginWidget = new BlueToothMain; } return pluginWidget; } void Bluetooth::plugin_delay_control() { } const QString Bluetooth::name() const { return QStringLiteral("bluetooth"); } ukui-control-center/plugins/devices/bluetooth/bluetoothmain.cpp0000644000175000017500000021374514201663716024117 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "bluetoothmain.h" #include #include #include #include #include #include #include //#include #include #include "Label/titlelabel.h" #include enum rfkill_type { RFKILL_TYPE_ALL = 0, RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_UWB, RFKILL_TYPE_WIMAX, RFKILL_TYPE_WWAN, }; enum rfkill_operation { RFKILL_OP_ADD = 0, RFKILL_OP_DEL, RFKILL_OP_CHANGE, RFKILL_OP_CHANGE_ALL, }; struct rfkill_event { uint32_t idx; uint8_t type; uint8_t op; uint8_t soft; uint8_t hard; }; enum { OPT_b = (1 << 0), /* must be = 1 */ OPT_u = (1 << 1), OPT_l = (1 << 2), }; static guint watch = 0; bool spe_bt_node = false; bool not_hci_node = true; bool M_power_on = false; bool M_adapter_flag = false; static gboolean rfkill_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[32]; struct rfkill_event *event = (struct rfkill_event *)buf; char sysname[PATH_MAX]; ssize_t len; int fd, id; if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) return FALSE; fd = g_io_channel_unix_get_fd(chan); memset(buf, 0, sizeof(buf)); len = read(fd, buf, sizeof(buf)); if (len < 0) { if (errno == EAGAIN) return TRUE; return FALSE; } if (len != sizeof(struct rfkill_event)) return TRUE; qDebug("RFKILL event idx %u type %u op %u soft %u hard %u", event->idx, event->type, event->op, event->soft, event->hard); if (event->type != RFKILL_TYPE_BLUETOOTH && event->type != RFKILL_TYPE_ALL) { qDebug() << Q_FUNC_INFO << "Not bt====" ; return TRUE; } memset(sysname, 0, sizeof(sysname)); snprintf(sysname, sizeof(sysname) - 1, "/sys/class/rfkill/rfkill%u/name", event->idx); fd = open(sysname, O_RDONLY); if (fd < 0) { qDebug () << Q_FUNC_INFO << __LINE__; return TRUE; } if (read(fd, sysname, sizeof(sysname) - 1) < 4) { close(fd); qDebug () << Q_FUNC_INFO << __LINE__; return TRUE; } close(fd); if (g_str_has_prefix(sysname, "tpacpi_bluetooth_sw") == TRUE) { spe_bt_node = true; qDebug () << Q_FUNC_INFO << "spe_bt_node:" << spe_bt_node << __LINE__; if (event->soft) { not_hci_node = true ; qDebug () << Q_FUNC_INFO << "event->soft:" << event->soft << __LINE__; } else not_hci_node = false ; } else if (g_str_has_prefix(sysname, "hci") == TRUE) { qDebug () << Q_FUNC_INFO << "not_hci_node:FALSE" << __LINE__; not_hci_node = false; } else { qDebug () << Q_FUNC_INFO << "not_hci_node:TRUE" << __LINE__; not_hci_node = true; } return TRUE; } void rfkill_init(void) { qDebug () << Q_FUNC_INFO << __LINE__; int fd; GIOChannel *channel; fd = open("/dev/rfkill", O_RDWR); if (fd < 0) { return; } channel = g_io_channel_unix_new(fd); g_io_channel_set_close_on_unref(channel, TRUE); watch = g_io_add_watch(channel, GIOCondition(G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR), rfkill_event, NULL); g_io_channel_unref(channel); } void rfkill_set_idx(void) { qDebug () << Q_FUNC_INFO << __LINE__; struct rfkill_event event; int rf_fd; int mode; int rf_type; int rf_idx; unsigned rf_opt = 0; /* Must have one or two params */ mode = O_RDWR | O_NONBLOCK; rf_type = RFKILL_TYPE_BLUETOOTH; rf_idx = -1; rf_fd = open("/dev/rfkill", mode); memset(&event, 0, sizeof(event)); if (rf_type >= 0) { event.type = rf_type; event.op = RFKILL_OP_CHANGE_ALL; } if (rf_idx >= 0) { event.idx = rf_idx; event.op = RFKILL_OP_CHANGE; } /* Note: OPT_b == 1 */ event.soft = (rf_opt & OPT_b); write(rf_fd, &event, sizeof(event)); } void rfkill_exit(void) { if (watch == 0) return; g_source_remove(watch); watch = 0; } BlueToothMain::BlueToothMain(QWidget *parent) : QMainWindow(parent) { rfkill_init(); //rfkill_set_idx();//会导致蓝牙自启动 if(QGSettings::isSchemaInstalled("org.ukui.bluetooth")) { settings = new QGSettings("org.ukui.bluetooth"); Default_Adapter = settings->get("adapter-address").toString(); qDebug() << "GSetting Value: " << Default_Adapter/* << finally_connect_the_device << paired_device_address*/; } StackedWidget = new QStackedWidget(this); this->setCentralWidget(StackedWidget); //初始化正常蓝牙界面 InitMainWindowUi(); //初始化异常蓝牙界面 InitMainWindowError(); //初始化所有计时器 InitAllTimer(); //初始化蓝牙管理器 InitBluetoothManager(); //刷新界面状态 RefreshWindowUiState(); MonitorSleepSignal(); } BlueToothMain::~BlueToothMain() { delete settings; settings = nullptr; delete device_list; device_list = nullptr; //clearAllDeviceItemUi(); } void BlueToothMain::InitAllTimer() { qDebug() << Q_FUNC_INFO << __LINE__; btPowerBtnTimer = new QTimer(); btPowerBtnTimer->setInterval(8000); connect(btPowerBtnTimer,&QTimer::timeout,this,[=] { qDebug() << Q_FUNC_INFO << "btPowerBtnTimer:timeout "; btPowerBtnTimer->stop(); open_bluetooth->setEnabled(true); }); //30s扫描清理一次 discovering_timer = new QTimer(this); discovering_timer->setInterval(28000); connect(discovering_timer,&QTimer::timeout,this,[=]{ qDebug() << __FUNCTION__ << "discovering_timer:timeout" << __LINE__ ; discovering_timer->stop(); clearUiShowDeviceList(); QTimer::singleShot(2000,this,[=]{ Discovery_device_address.clear(); discovering_timer->start(); }); }); m_timer = new QTimer(this); m_timer->setInterval(100); connect(m_timer,&QTimer::timeout,this,&BlueToothMain::Refresh_load_Label_icon); IntermittentScann_timer_count = 0; IntermittentScann_timer= new QTimer(this); IntermittentScann_timer->setInterval(2000); connect(IntermittentScann_timer,&QTimer::timeout,this,[=] { qDebug() << __FUNCTION__ << "IntermittentScann_timer_count:" << IntermittentScann_timer_count << __LINE__ ; IntermittentScann_timer->stop(); if (IntermittentScann_timer_count >= 2) { IntermittentScann_timer_count = 0; IntermittentScann_timer->stop(); this->startDiscovery(); discovering_timer->start(); } else { if (1 == IntermittentScann_timer_count%2) { this->stopDiscovery(); } else { this->startDiscovery(); } IntermittentScann_timer->start(); } IntermittentScann_timer_count++; }); //开启时延迟2s后开启扫描,留点设备回连时间 delayStartDiscover_timer = new QTimer(this); delayStartDiscover_timer->setInterval(2000); connect(delayStartDiscover_timer,&QTimer::timeout,this,[=] { qDebug() << __FUNCTION__ << "delayStartDiscover_timer:timeout" << __LINE__ ; delayStartDiscover_timer->stop(); this->startDiscovery(); IntermittentScann_timer->start(); IntermittentScann_timer_count = 0; }); poweronAgain_timer = new QTimer(); poweronAgain_timer->setInterval(3000); connect(poweronAgain_timer,&QTimer::timeout,this,[=]{ qDebug() << __FUNCTION__ << "adapterPoweredChanged again" << __LINE__; poweronAgain_timer->stop(); adapterPoweredChanged(true); }); } void BlueToothMain::InitBluetoothManager() { m_manager = new BluezQt::Manager(this); job = m_manager->init(); job->exec(); qDebug() << m_manager->isOperational() << m_manager->isBluetoothBlocked(); updateAdaterInfoList(); m_localDevice = getDefaultAdapter(); if (nullptr == m_localDevice) { qDebug() << Q_FUNC_INFO << "m_localDevice is nullptr"; } connectManagerChanged(); } /* * InitMainWindowUi: */ void BlueToothMain::InitMainWindowUi() { //初始化显示框架 normal_main_widget = new QWidget(this); normal_main_widget->setObjectName("normalWidget"); main_layout = new QVBoxLayout(normal_main_widget); main_layout->setSpacing(40); main_layout->setContentsMargins(0,0,30,10); frame_top = new QWidget(normal_main_widget); frame_top->setObjectName("frame_top"); frame_top->setMinimumSize(582,239); frame_top->setMaximumSize(1000,239); frame_middle = new QWidget(normal_main_widget); frame_middle->setObjectName("frame_middle"); frame_bottom = new QWidget(normal_main_widget); frame_bottom->setObjectName("frame_bottom"); frame_bottom->setMinimumWidth(582); frame_bottom->setMaximumWidth(1000); main_layout->addWidget(frame_top,1,Qt::AlignTop); main_layout->addWidget(frame_middle,1,Qt::AlignTop); main_layout->addWidget(frame_bottom,1,Qt::AlignTop); main_layout->addStretch(10); InitMainWindowTopUi(); InitMainWindowMiddleUi(); InitMainWindowBottomUi(); StackedWidget->addWidget(normal_main_widget); } void BlueToothMain::RefreshWindowUiState() { qDebug() << Q_FUNC_INFO << __LINE__; if (nullptr != m_manager) { RefreshMainWindowTopUi(); RefreshMainWindowMiddleUi(); RefreshMainWindowBottomUi(); if(m_manager->adapters().size() == 0) { not_hci_node = true; M_adapter_flag = false; if (spe_bt_node) ShowSpecialMainWindow(); else ShowErrorMainWindow(); return; } else { M_adapter_flag = true; ShowNormalMainWindow(); } adapterConnectFun(); } } void BlueToothMain::InitMainWindowTopUi() { qDebug() << Q_FUNC_INFO << __LINE__; //~ contents_path /bluetooth/Bluetooth TitleLabel *label_1 = new TitleLabel(frame_top); label_1->setText(tr("Bluetooth")); label_1->resize(100,25); QVBoxLayout *top_layout = new QVBoxLayout(); top_layout->setSpacing(8); top_layout->setContentsMargins(0,0,0,0); top_layout->addWidget(label_1); QVBoxLayout *layout = new QVBoxLayout(); layout->setSpacing(2); layout->setContentsMargins(0,0,0,0); top_layout->addLayout(layout); QFrame *frame_1 = new QFrame(frame_top); frame_1->setMinimumWidth(582); frame_1->setFrameShape(QFrame::Shape::Box); frame_1->setFixedHeight(50); frame_1->setAutoFillBackground(true); layout->addWidget(frame_1); QHBoxLayout *frame_1_layout = new QHBoxLayout(frame_1); frame_1_layout->setSpacing(10); frame_1_layout->setContentsMargins(16,0,16,0); //~ contents_path /bluetooth/Turn on Bluetooth label_2 = new QLabel(tr("Turn on :"),frame_1); label_2->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_1_layout->addWidget(label_2); bluetooth_name = new BluetoothNameLabel(frame_1,300,38); connect(bluetooth_name,&BluetoothNameLabel::send_adapter_name,this,&BlueToothMain::change_adapter_name); connect(this,&BlueToothMain::adapter_name_changed,bluetooth_name,&BluetoothNameLabel::set_label_text); frame_1_layout->addWidget(bluetooth_name); frame_1_layout->addStretch(); open_bluetooth = new SwitchButton(frame_1); open_bluetooth->setEnabled(true); connect(open_bluetooth,SIGNAL(checkedChanged(bool)),this,SLOT(onClick_Open_Bluetooth(bool))); frame_1_layout->addWidget(open_bluetooth); frame_2 = new QFrame(frame_top); frame_2->setMinimumWidth(582); frame_2->setFrameShape(QFrame::Shape::Box); frame_2->setFixedHeight(50); //if(adapter_address_list.size() <= 1) frame_2->setVisible(false); frame_top->setMinimumSize(582,187); frame_top->setMaximumSize(1000,187); layout->addWidget(frame_2); QHBoxLayout *frame_2_layout = new QHBoxLayout(frame_2); frame_2_layout->setSpacing(10); frame_2_layout->setContentsMargins(16,0,16,0); QLabel *label_3 = new QLabel(tr("Bluetooth adapter"),frame_2); label_3->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_2_layout->addWidget(label_3); frame_2_layout->addStretch(); adapter_name_list.clear(); adapter_list = new QComboBox(frame_2); adapter_list->clear(); adapter_list->setMinimumWidth(300); adapter_list->addItems(adapter_name_list); connect(adapter_list,SIGNAL(currentIndexChanged(int)),this,SLOT(adapterComboxChanged(int))); frame_2_layout->addWidget(adapter_list); QFrame *frame_3 = new QFrame(frame_top); frame_3->setMinimumWidth(582); frame_3->setFrameShape(QFrame::Shape::Box); frame_3->setFixedHeight(50); layout->addWidget(frame_3); QHBoxLayout *frame_3_layout = new QHBoxLayout(frame_3); frame_3_layout->setSpacing(10); frame_3_layout->setContentsMargins(16,0,16,0); //~ contents_path /bluetooth/Show icon on taskbar QLabel *label_4 = new QLabel(tr("Show icon on taskbar"),frame_3); label_4->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_3_layout->addWidget(label_4); frame_3_layout->addStretch(); show_panel = new SwitchButton(frame_3); frame_3_layout->addWidget(show_panel); if(settings) show_panel->setChecked(settings->get("tray-show").toBool()); else { show_panel->setChecked(false); show_panel->setDisabledFlag(false); } connect(show_panel,&SwitchButton::checkedChanged,this,&BlueToothMain::set_tray_visible); qDebug () << Q_FUNC_INFO << "spe_bt_node:" << spe_bt_node << "not_hci_node:" << not_hci_node; QFrame *frame_4 = new QFrame(frame_top); frame_4->setMinimumWidth(582); frame_4->setFrameShape(QFrame::Shape::Box); frame_4->setFixedHeight(50); layout->addWidget(frame_4); QHBoxLayout *frame_4_layout = new QHBoxLayout(frame_4); frame_4_layout->setSpacing(10); frame_4_layout->setContentsMargins(16,0,16,0); //~ contents_path /bluetooth/Discoverable QLabel *label_5 = new QLabel(tr("Discoverable by nearby Bluetooth devices"),frame_4); label_5->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_4_layout->addWidget(label_5); frame_4_layout->addStretch(); switch_discover = new SwitchButton(frame_4); frame_4_layout->addWidget(switch_discover); connect(switch_discover,&SwitchButton::checkedChanged,this,&BlueToothMain::set_discoverable); frame_top->setLayout(top_layout); } void BlueToothMain::RefreshMainWindowTopUi() { qDebug () << Q_FUNC_INFO << "in" ; if (spe_bt_node && not_hci_node) { bluetooth_name->setVisible(false); } else { if (nullptr != m_localDevice) { bluetooth_name->set_dev_name(m_localDevice->name()); bluetooth_name->setVisible(m_localDevice->isPowered()); } } if (nullptr != m_localDevice) { open_bluetooth->setChecked(m_localDevice->isPowered()); adapterPoweredChanged(m_localDevice->isPowered()); switch_discover->setChecked(m_localDevice->isDiscoverable()); frame_bottom->setVisible(m_localDevice->isPowered()); frame_middle->setVisible(m_localDevice->isPowered()); } else { frame_bottom->setVisible(false); frame_middle->setVisible(false); } if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() == 1)) { frame_2->setVisible(false); frame_top->setMinimumSize(582,187); frame_top->setMaximumSize(1000,187); } else if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() > 1)) { if(!frame_2->isVisible()) frame_2->setVisible(true); frame_top->setMinimumSize(582,239); frame_top->setMaximumSize(1000,239); } qDebug () << Q_FUNC_INFO << "end" ; } void BlueToothMain::addAdapterList(QString newAdapterAddress,QString newAdapterName) { qDebug () << Q_FUNC_INFO << __LINE__ ; if (adapter_address_list.indexOf(newAdapterAddress) == -1) { adapter_address_list << newAdapterAddress ; adapter_name_list << newAdapterName ; qDebug () << Q_FUNC_INFO << ""; adapter_list->addItem(newAdapterName); if (nullptr != m_localDevice) { int current_index = adapter_address_list.indexOf(m_localDevice->address()); adapter_list->setCurrentIndex(current_index); } } qDebug () << Q_FUNC_INFO << adapter_address_list << __LINE__ ; qDebug () << Q_FUNC_INFO << adapter_name_list << __LINE__ ; } void BlueToothMain::removeAdapterList(QString adapterAddress,QString adapterName) { qDebug () << Q_FUNC_INFO << adapterName << adapterAddress <<__LINE__ ; qDebug () << Q_FUNC_INFO << adapter_address_list << __LINE__ ; qDebug () << Q_FUNC_INFO << adapter_name_list << __LINE__ ; int index = adapter_address_list.indexOf(adapterAddress); if(index < adapter_address_list.size() && index < adapter_name_list.size()) { qDebug () << Q_FUNC_INFO << "removeAdapterList index:" << index ; if (index != -1) { adapter_address_list.removeAt(index); adapter_name_list.removeAt(index); // qDebug () << Q_FUNC_INFO << "disconnect of adapter_list" ; disconnect(adapter_list, SIGNAL(currentIndexChanged(int)), nullptr, nullptr); adapter_list->clear(); adapter_list->addItems(adapter_name_list); //adapter_list->removeItem(index); qDebug () << Q_FUNC_INFO << "add connect of adapter_list" ; connect(adapter_list,SIGNAL(currentIndexChanged(int)),this,SLOT(adapterComboxChanged(int))); if (adapter_address_list.size() >= 1 && adapter_name_list.size() >= 1) adapterComboxChanged(0); } } qDebug () << Q_FUNC_INFO << adapter_address_list << __LINE__ ; qDebug () << Q_FUNC_INFO << adapter_name_list << __LINE__ ; } void BlueToothMain::RefreshMainWindowMiddleUi() { qDebug () << Q_FUNC_INFO << "in" ; if (nullptr == m_localDevice) return; myDevShowFlag = false; Discovery_device_address.clear(); last_discovery_device_address.clear(); for(int i = 0;i < m_localDevice->devices().size(); i++) { qDebug() << m_localDevice->devices().at(i)->name() << m_localDevice->devices().at(i)->type(); addMyDeviceItemUI(m_localDevice->devices().at(i)); } device_list_layout->addStretch(); qDebug() << Q_FUNC_INFO << m_localDevice->devices().size() << myDevShowFlag; qDebug() << Q_FUNC_INFO << m_localDevice->isPowered(); if(m_localDevice->isPowered()) { if(myDevShowFlag) frame_middle->setVisible(true); else frame_middle->setVisible(false); } } void BlueToothMain::RefreshMainWindowBottomUi() { qDebug () << Q_FUNC_INFO << "in" ; if (nullptr == m_localDevice) return; if(m_localDevice->isPowered()) { frame_bottom->setVisible(true); if (m_localDevice->isDiscovering()) m_timer->start(); //delayStartDiscover_timer->start(); } else { frame_bottom->setVisible(false); } } /* * * */ void BlueToothMain::InitMainWindowMiddleUi() { qDebug()<< Q_FUNC_INFO << __LINE__; QVBoxLayout *middle_layout = new QVBoxLayout(frame_middle); middle_layout->setSpacing(8); middle_layout->setContentsMargins(0,0,0,0); paired_dev_layout = new QVBoxLayout(); paired_dev_layout->setSpacing(2); paired_dev_layout->setContentsMargins(0,0,0,0); TitleLabel *middle_label = new TitleLabel(frame_middle); middle_label->setText(tr("My Devices")); middle_label->resize(72,25); middle_layout->addWidget(middle_label,Qt::AlignTop); middle_layout->addLayout(paired_dev_layout,Qt::AlignTop); frame_middle->setLayout(middle_layout); } void BlueToothMain::InitMainWindowBottomUi() { qDebug()<< Q_FUNC_INFO << __LINE__; QHBoxLayout *title_layout = new QHBoxLayout(); title_layout->setSpacing(10); title_layout->setContentsMargins(0,0,10,0); //~ contents_path /bluetooth/Other Devices TitleLabel *label_1 = new TitleLabel(frame_bottom); label_1->setText(tr("Other Devices")); label_1->resize(72,25); loadLabel = new QLabel(frame_bottom); loadLabel->setFixedSize(24,24); if (!m_timer) { m_timer = new QTimer(this); m_timer->setInterval(100); connect(m_timer,&QTimer::timeout,this,&BlueToothMain::Refresh_load_Label_icon); } title_layout->addWidget(label_1); title_layout->addStretch(); title_layout->addWidget(loadLabel); QVBoxLayout *bottom_layout = new QVBoxLayout(frame_bottom); bottom_layout->setSpacing(8); bottom_layout->setContentsMargins(0,0,0,0); bottom_layout->addLayout(title_layout); device_list = new QWidget(); bottom_layout->addWidget(device_list); device_list_layout = new QVBoxLayout(device_list); device_list_layout->setSpacing(2); device_list_layout->setContentsMargins(0,0,0,0); device_list_layout->setAlignment(Qt::AlignTop); device_list->setLayout(device_list_layout); frame_bottom->setLayout(bottom_layout); } void BlueToothMain::ShowNormalMainWindow() { qDebug()<< Q_FUNC_INFO << __LINE__; normal_main_widget->setObjectName("normalWidget"); if (m_manager->adapters().size() > 1) { if(!frame_2->isVisible()) frame_2->setVisible(true); frame_top->setMinimumSize(582,239); frame_top->setMaximumSize(1000,239); } else { if(frame_2->isVisible()) frame_2->setVisible(false); frame_top->setMinimumSize(582,187); frame_top->setMaximumSize(1000,187); } StackedWidget->setCurrentWidget(normal_main_widget); } void BlueToothMain::ShowSpecialMainWindow() { qDebug()<< Q_FUNC_INFO << __LINE__; normal_main_widget->setObjectName("SpeNoteWidget"); bluetooth_name->setVisible(false); if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() == 1)) { frame_top->setMinimumSize(582,187); frame_top->setMaximumSize(1000,187); } else if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() > 1)) { if(!frame_2->isVisible()) frame_2->setVisible(true); frame_top->setMinimumSize(582,239); frame_top->setMaximumSize(1000,239); } frame_middle->setVisible(false); frame_bottom->setVisible(false); StackedWidget->setCurrentWidget(normal_main_widget); } void BlueToothMain::InitMainWindowError() { qDebug()<< Q_FUNC_INFO << __LINE__; errorWidget = new QWidget(); QVBoxLayout *errorWidgetLayout = new QVBoxLayout(errorWidget); QLabel *errorWidgetIcon = new QLabel(errorWidget); QLabel *errorWidgetTip0 = new QLabel(errorWidget); errorWidget->setObjectName("errorWidget"); errorWidgetLayout->setSpacing(10); errorWidgetLayout->setMargin(0); errorWidgetLayout->setContentsMargins(0,0,0,0); errorWidgetIcon->setFixedSize(56,56); errorWidgetTip0->resize(200,30); errorWidgetTip0->setFont(QFont("Noto Sans CJK SC",18,QFont::Bold)); if (QIcon::hasThemeIcon("dialog-warning")) { errorWidgetIcon->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(56,56)); } errorWidgetTip0->setText(tr("Bluetooth adapter is abnormal !")); errorWidgetLayout->addStretch(10); errorWidgetLayout->addWidget(errorWidgetIcon,1,Qt::AlignCenter); errorWidgetLayout->addWidget(errorWidgetTip0,1,Qt::AlignCenter); errorWidgetLayout->addStretch(10); StackedWidget->addWidget(errorWidget); } void BlueToothMain::ShowErrorMainWindow() { qDebug()<< Q_FUNC_INFO << __LINE__; this->setObjectName("errorWidget"); StackedWidget->setCurrentWidget(errorWidget); } void BlueToothMain::connectManagerChanged() { qDebug() << Q_FUNC_INFO << __LINE__; // &BluezQt::Manager::operationalChanged // &BluezQt::Manager::bluetoothOperationalChanged // &BluezQt::Manager::bluetoothBlockedChanged // &BluezQt::Manager::adapterAdded // &BluezQt::Manager::adapterRemoved // &BluezQt::Manager::adapterChanged // &BluezQt::Manager::deviceAdded // &BluezQt::Manager::deviceRemoved // &BluezQt::Manager::deviceChanged // &BluezQt::Manager::usableAdapterChanged // &BluezQt::Manager::allAdaptersRemoved connect(m_manager,&BluezQt::Manager::adapterAdded,this,[=](BluezQt::AdapterPtr adapter) { qDebug() << Q_FUNC_INFO << "adapterAdded"; m_localDevice = getDefaultAdapter(); adapterConnectFun(); addAdapterList(adapter->address(),adapter->name()); qDebug() << Q_FUNC_INFO << adapter_address_list << "===" << adapter_name_list; not_hci_node = false; M_adapter_flag = true; if (spe_bt_node && M_power_on) { //not_hci_node = false; if(m_manager->adapters().size() == 1) onClick_Open_Bluetooth(true); } qDebug() << Q_FUNC_INFO << StackedWidget->currentWidget()->objectName() << __LINE__; ; ShowNormalMainWindow(); // if (this->centralWidget()->objectName() == "errorWidget" || // this->centralWidget()->objectName() == "SpeNoteWidget") // { // ShowNormalMainWindow(); // //RefreshMainWindowMiddleUi(); // } // else // { // ShowNormalMainWindow(); // //RefreshWindowUiState(); // } }); connect(m_manager,&BluezQt::Manager::adapterRemoved,this,[=](BluezQt::AdapterPtr adapter) { qDebug() << Q_FUNC_INFO << "adapterRemoved"; qDebug() << Q_FUNC_INFO << "Removed" << adapter->address() << adapter->name(); removeAdapterList(adapter->address(),adapter->name()); qDebug() << Q_FUNC_INFO << __LINE__ << adapter_list->count() << adapter_address_list << adapter_name_list; m_localDevice = getDefaultAdapter(); adapterConnectFun(); qDebug() << Q_FUNC_INFO << "adapter_address_list : " << adapter_address_list.size() << __LINE__; if (adapter_address_list.size() == 0) { M_adapter_flag = false; not_hci_node = true; qDebug() << Q_FUNC_INFO << StackedWidget->currentWidget()->objectName() << __LINE__; ; if (StackedWidget->currentWidget()->objectName() == "normalWidget") { if (spe_bt_node) ShowSpecialMainWindow(); else ShowErrorMainWindow(); } } else if (adapter_address_list.size() >= 1) { ShowNormalMainWindow(); } }); connect(m_manager,&BluezQt::Manager::adapterChanged,this,[=](BluezQt::AdapterPtr adapter) { //qDebug() << Q_FUNC_INFO << "adapterChanged" ; //qDebug() << Q_FUNC_INFO << adapter->name() << adapter->address(); if(nullptr != m_localDevice) { //qDebug() << Q_FUNC_INFO << "adapterChanged=======" ; if (m_localDevice->address() == adapter.data()->address()) m_localDevice = adapter; } else { //m_localDevice = adapter; } }); connect(m_manager,&BluezQt::Manager::usableAdapterChanged,this,[=](BluezQt::AdapterPtr adapter) { qDebug() << Q_FUNC_INFO << "usableAdapterChanged" ; }); connect(m_manager,&BluezQt::Manager::allAdaptersRemoved,this,[=] { qDebug() << Q_FUNC_INFO << "allAdaptersRemoved" ; clearAllTimer(); }); } void BlueToothMain::adapterConnectFun() { qDebug() << Q_FUNC_INFO << __LINE__; if (nullptr == m_localDevice) { qDebug() << Q_FUNC_INFO << "error: m_localDevice is nullptr"; return; } connect(m_localDevice.data(),&BluezQt::Adapter::nameChanged,this,&BlueToothMain::adapterNameChanged); connect(m_localDevice.data(),&BluezQt::Adapter::poweredChanged,this,&BlueToothMain::adapterPoweredChanged); connect(m_localDevice.data(),&BluezQt::Adapter::deviceAdded,this,&BlueToothMain::serviceDiscovered); connect(m_localDevice.data(),&BluezQt::Adapter::deviceChanged,this,&BlueToothMain::serviceDiscoveredChange); connect(m_localDevice.data(),&BluezQt::Adapter::deviceRemoved,this,&BlueToothMain::adapterDeviceRemove); connect(m_localDevice.data(),&BluezQt::Adapter::discoverableChanged, this, [=](bool discoverable) { switch_discover->setChecked(discoverable); }); connect(m_localDevice.data(),&BluezQt::Adapter::discoveringChanged,this,[=](bool discover) { if(discover){ m_timer->start(); loadLabel->setVisible(true); } else { m_timer->stop(); loadLabel->setVisible(false); } }); qDebug() << Q_FUNC_INFO << "end"; } //============================================================DT /* * Initialize the fixed UI in the upper half of the interface * */ void BlueToothMain::InitMainTopUI() { qDebug() << Q_FUNC_INFO << __LINE__; //~ contents_path /bluetooth/Bluetooth TitleLabel *label_1 = new TitleLabel(frame_top); label_1->setText(tr("Bluetooth")); label_1->resize(100,25); QVBoxLayout *top_layout = new QVBoxLayout(); top_layout->setSpacing(8); top_layout->setContentsMargins(0,0,0,0); top_layout->addWidget(label_1); QVBoxLayout *layout = new QVBoxLayout(); layout->setSpacing(2); layout->setContentsMargins(0,0,0,0); top_layout->addLayout(layout); QFrame *frame_1 = new QFrame(frame_top); frame_1->setMinimumWidth(582); frame_1->setFrameShape(QFrame::Shape::Box); frame_1->setFixedHeight(50); frame_1->setAutoFillBackground(true); layout->addWidget(frame_1); QHBoxLayout *frame_1_layout = new QHBoxLayout(frame_1); frame_1_layout->setSpacing(10); frame_1_layout->setContentsMargins(16,0,16,0); //~ contents_path /bluetooth/Turn on Bluetooth label_2 = new QLabel(tr("Turn on :"),frame_1); label_2->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_1_layout->addWidget(label_2); bluetooth_name = new BluetoothNameLabel(frame_1,300,38); connect(bluetooth_name,&BluetoothNameLabel::send_adapter_name,this,&BlueToothMain::change_adapter_name); connect(this,&BlueToothMain::adapter_name_changed,bluetooth_name,&BluetoothNameLabel::set_label_text); frame_1_layout->addWidget(bluetooth_name); frame_1_layout->addStretch(); if (spe_bt_node && not_hci_node) { bluetooth_name->setVisible(false); } //if (NULL == open_bluetooth) open_bluetooth = new SwitchButton(frame_1); frame_1_layout->addWidget(open_bluetooth); frame_2 = new QFrame(frame_top); frame_2->setMinimumWidth(582); frame_2->setFrameShape(QFrame::Shape::Box); frame_2->setFixedHeight(50); if(adapter_address_list.size() <= 1) frame_2->setVisible(false); layout->addWidget(frame_2); QHBoxLayout *frame_2_layout = new QHBoxLayout(frame_2); frame_2_layout->setSpacing(10); frame_2_layout->setContentsMargins(16,0,16,0); QLabel *label_3 = new QLabel(tr("Bluetooth adapter"),frame_2); label_3->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_2_layout->addWidget(label_3); frame_2_layout->addStretch(); adapter_list = new QComboBox(frame_2); adapter_list->clear(); adapter_list->setMinimumWidth(300); adapter_list->addItems(adapter_name_list); if (spe_bt_node && not_hci_node) { adapter_list->setCurrentIndex(0); } else adapter_list->setCurrentIndex(adapter_address_list.indexOf(m_localDevice->address())); connect(adapter_list,SIGNAL(currentIndexChanged(int)),this,SLOT(adapterComboxChanged(int))); frame_2_layout->addWidget(adapter_list); QFrame *frame_3 = new QFrame(frame_top); frame_3->setMinimumWidth(582); frame_3->setFrameShape(QFrame::Shape::Box); frame_3->setFixedHeight(50); layout->addWidget(frame_3); QHBoxLayout *frame_3_layout = new QHBoxLayout(frame_3); frame_3_layout->setSpacing(10); frame_3_layout->setContentsMargins(16,0,16,0); //~ contents_path /bluetooth/Show icon on taskbar QLabel *label_4 = new QLabel(tr("Show icon on taskbar"),frame_3); label_4->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_3_layout->addWidget(label_4); frame_3_layout->addStretch(); show_panel = new SwitchButton(frame_3); frame_3_layout->addWidget(show_panel); if(settings){ show_panel->setChecked(settings->get("tray-show").toBool()); }else{ show_panel->setChecked(false); show_panel->setDisabledFlag(false); } connect(show_panel,&SwitchButton::checkedChanged,this,&BlueToothMain::set_tray_visible); qDebug () << Q_FUNC_INFO << "spe_bt_node:" << spe_bt_node << "not_hci_node:" << not_hci_node; QFrame *frame_4 = new QFrame(frame_top); frame_4->setMinimumWidth(582); frame_4->setFrameShape(QFrame::Shape::Box); frame_4->setFixedHeight(50); layout->addWidget(frame_4); QHBoxLayout *frame_4_layout = new QHBoxLayout(frame_4); frame_4_layout->setSpacing(10); frame_4_layout->setContentsMargins(16,0,16,0); //~ contents_path /bluetooth/Discoverable QLabel *label_5 = new QLabel(tr("Discoverable by nearby Bluetooth devices"),frame_4); label_5->setStyleSheet("QLabel{\ width: 56px;\ height: 20px;\ font-weight: 400;\ line-height: 20px;}"); frame_4_layout->addWidget(label_5); frame_4_layout->addStretch(); switch_discover = new SwitchButton(frame_4); frame_4_layout->addWidget(switch_discover); if (spe_bt_node && not_hci_node) { //switch_discover->setVisible(false); } else { //switch_discover->setVisible(true); switch_discover->setChecked(m_localDevice->isDiscoverable()); connect(switch_discover,&SwitchButton::checkedChanged,this,&BlueToothMain::set_discoverable); connect(m_localDevice.data(), &BluezQt::Adapter::discoverableChanged, this, [=](bool discoverable){ switch_discover->setChecked(discoverable); }); } connect(open_bluetooth,SIGNAL(checkedChanged(bool)),this,SLOT(onClick_Open_Bluetooth(bool))); frame_top->setLayout(top_layout); } void BlueToothMain::InitMainMiddleUI() { QVBoxLayout *middle_layout = new QVBoxLayout(frame_middle); middle_layout->setSpacing(8); middle_layout->setContentsMargins(0,0,0,0); paired_dev_layout = new QVBoxLayout(); paired_dev_layout->setSpacing(2); paired_dev_layout->setContentsMargins(0,0,0,0); TitleLabel *middle_label = new TitleLabel(frame_middle); middle_label->setText(tr("My Devices")); middle_label->resize(72,25); middle_layout->addWidget(middle_label,Qt::AlignTop); middle_layout->addLayout(paired_dev_layout,Qt::AlignTop); frame_middle->setLayout(middle_layout); } void BlueToothMain::InitMainbottomUI() { QHBoxLayout *title_layout = new QHBoxLayout(); title_layout->setSpacing(10); title_layout->setContentsMargins(0,0,10,0); //~ contents_path /bluetooth/Other Devices TitleLabel *label_1 = new TitleLabel(frame_bottom); label_1->setText(tr("Other Devices")); label_1->resize(72,25); loadLabel = new QLabel(frame_bottom); loadLabel->setFixedSize(24,24); if (!m_timer) { m_timer = new QTimer(this); m_timer->setInterval(100); connect(m_timer,&QTimer::timeout,this,&BlueToothMain::Refresh_load_Label_icon); } discovering_timer = new QTimer(this); discovering_timer->setInterval(28000); connect(discovering_timer,&QTimer::timeout,this,[=]{ qDebug() << __FUNCTION__ << "discovering_timer:timeout" << __LINE__ ; discovering_timer->stop(); clearUiShowDeviceList(); QTimer::singleShot(2000,this,[=]{ Discovery_device_address.clear(); discovering_timer->start(); }); }); IntermittentScann_timer_count = 0; IntermittentScann_timer= new QTimer(this); IntermittentScann_timer->setInterval(2000); connect(IntermittentScann_timer,&QTimer::timeout,this,[=] { qDebug() << __FUNCTION__ << "IntermittentScann_timer_count:" << IntermittentScann_timer_count << __LINE__ ; IntermittentScann_timer->stop(); if (IntermittentScann_timer_count >= 2) { IntermittentScann_timer_count = 0; IntermittentScann_timer->stop(); this->startDiscovery(); discovering_timer->start(); } else { if (1 == IntermittentScann_timer_count%2) { this->stopDiscovery(); } else { this->startDiscovery(); } IntermittentScann_timer->start(); } IntermittentScann_timer_count++; }); //开启时延迟1.8s后开启扫描,留点设备回连时间 delayStartDiscover_timer = new QTimer(this); delayStartDiscover_timer->setInterval(2000); connect(delayStartDiscover_timer,&QTimer::timeout,this,[=] { qDebug() << __FUNCTION__ << "delayStartDiscover_timer:timeout" << __LINE__ ; delayStartDiscover_timer->stop(); this->startDiscovery(); IntermittentScann_timer->start(); IntermittentScann_timer_count = 0; }); title_layout->addWidget(label_1); title_layout->addStretch(); title_layout->addWidget(loadLabel); QVBoxLayout *bottom_layout = new QVBoxLayout(frame_bottom); bottom_layout->setSpacing(8); bottom_layout->setContentsMargins(0,0,0,0); bottom_layout->addLayout(title_layout); device_list = new QWidget(); bottom_layout->addWidget(device_list); device_list_layout = new QVBoxLayout(device_list); device_list_layout->setSpacing(2); device_list_layout->setContentsMargins(0,0,0,0); device_list_layout->setAlignment(Qt::AlignTop); device_list->setLayout(device_list_layout); frame_bottom->setLayout(bottom_layout); } void BlueToothMain::startDiscovery() { qDebug() << Q_FUNC_INFO << __LINE__; if (nullptr == m_localDevice) { qDebug() << Q_FUNC_INFO << "m_localDevice is nullptr !!!" << __LINE__ ; } if (!m_localDevice->isDiscovering()) { m_localDevice->startDiscovery(); } } void BlueToothMain::stopDiscovery() { qDebug() << Q_FUNC_INFO << __LINE__; if (nullptr == m_localDevice) { qDebug() << Q_FUNC_INFO << "m_localDevice is nullptr !!!" << __LINE__ ; } if (m_localDevice->isDiscovering()) { m_localDevice->stopDiscovery(); } } void BlueToothMain::adapterChanged() { connect(m_manager,&BluezQt::Manager::adapterRemoved,this,[=](BluezQt::AdapterPtr adapter){ qDebug() << Q_FUNC_INFO << __LINE__; int i = adapter_address_list.indexOf(adapter.data()->address()); qDebug() << Q_FUNC_INFO << __LINE__ << adapter_list->count() << adapter_address_list << adapter_name_list << i; adapter_name_list.removeAt(i); adapter_address_list.removeAll(adapter.data()->address()); if (m_manager->adapters().size()) { adapter_list->removeItem(i); } qDebug() << Q_FUNC_INFO << __LINE__; if((adapter_address_list.size() == adapter_name_list.size())&&(adapter_name_list.size() == 1)){ frame_2->setVisible(false); frame_top->setMinimumSize(582,135); frame_top->setMaximumSize(1000,135); } qDebug() << Q_FUNC_INFO << adapter_address_list.size(); if (adapter_address_list.size() == 0) { not_hci_node = true; if (this->centralWidget()->objectName() == "normalWidget") { if (spe_bt_node) showSpeNoteMainWindow(); else showMainWindowError(); } } qDebug() << Q_FUNC_INFO << __LINE__; }); connect(m_manager,&BluezQt::Manager::adapterAdded,this,[=](BluezQt::AdapterPtr adapter){ if (adapter_address_list.indexOf(adapter.data()->address()) == -1) { adapter_address_list << adapter.data()->address(); adapter_name_list << adapter.data()->name(); } qDebug() << Q_FUNC_INFO << adapter_address_list << "===" << adapter_name_list; m_localDevice = getDefaultAdapter(); M_adapter_flag = true ; if (spe_bt_node && M_power_on) { onClick_Open_Bluetooth(true); } // cleanPairDevices(); adapterConnectFun(); if (this->centralWidget()->objectName() == "errorWidget" || this->centralWidget()->objectName() == "SpeNoteWidget") { ShowNormalMainWindow(); } if (m_manager->adapters().size() > 1) { adapter_list->clear(); adapter_list->addItems(adapter_name_list); adapter_list->setCurrentIndex(adapter_address_list.indexOf(m_localDevice.data()->name())); } if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() == 1)){ frame_top->setMinimumSize(582,187); frame_top->setMaximumSize(1000,187); }else if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() > 1)){ if(!frame_2->isVisible()) frame_2->setVisible(true); frame_top->setMinimumSize(582,239); frame_top->setMaximumSize(1000,239); } }); connect(m_manager,&BluezQt::Manager::adapterChanged,this,[=](BluezQt::AdapterPtr adapter){ qDebug() << Q_FUNC_INFO <<__LINE__; if (m_localDevice->address() == adapter.data()->address()) m_localDevice = adapter; }); connect(m_manager,&BluezQt::Manager::usableAdapterChanged,this,[=](BluezQt::AdapterPtr adapter){ qDebug() << Q_FUNC_INFO <<__LINE__; }); } void BlueToothMain::updateUIWhenAdapterChanged() { qDebug() << Q_FUNC_INFO << __LINE__; adapterConnectFun(); //==============初始化蓝牙信息和基础信息==================================== bluetooth_name->set_dev_name(m_localDevice->name()); if(m_localDevice->isPowered()) { qDebug() << Q_FUNC_INFO << __LINE__; open_bluetooth->setChecked(true); bluetooth_name->setVisible(true); if(!frame_bottom->isVisible()) frame_bottom->setVisible(true); } else { qDebug() << Q_FUNC_INFO << m_manager->isBluetoothBlocked() << __LINE__; //open_bluetooth->setChecked(false); bluetooth_name->setVisible(false); frame_bottom->setVisible(false); frame_middle->setVisible(false); } //===========================END========================================== // =============清空我的设备和蓝牙发现设备栏布局下的所有设备item================= cleanPairDevices(); // ========================END=========================================== qDebug() << Q_FUNC_INFO <devices().size(); myDevShowFlag = false; Discovery_device_address.clear(); last_discovery_device_address.clear(); for(int i = 0;i < m_localDevice->devices().size(); i++) { qDebug() << m_localDevice->devices().at(i)->name() << m_localDevice->devices().at(i)->type(); addMyDeviceItemUI(m_localDevice->devices().at(i)); } device_list_layout->addStretch(); qDebug() << Q_FUNC_INFO << m_localDevice->devices().size() << myDevShowFlag; if(m_localDevice->isPowered()){ if(myDevShowFlag) frame_middle->setVisible(true); else frame_middle->setVisible(false); } if(m_localDevice->isPowered()) { if (m_localDevice->isDiscovering()) m_timer->start(); delayStartDiscover_timer->start(); } } void BlueToothMain::removeDeviceItemUI(QString address) { qDebug() << Q_FUNC_INFO << address << last_discovery_device_address.indexOf(address) <<__LINE__; if(last_discovery_device_address.indexOf(address) != -1){ DeviceInfoItem *item = device_list->findChild(address); if(item){ device_list_layout->removeWidget(item); item->setParent(NULL); delete item; item = nullptr; Discovery_device_address.removeAll(address); }else{ qDebug() << Q_FUNC_INFO << "NULL"<<__LINE__; return; } }else{ DeviceInfoItem *item = frame_middle->findChild(address); if(item){ paired_dev_layout->removeWidget(item); item->setParent(NULL); delete item; item = nullptr; if(frame_middle->children().size() == 2){ frame_middle->setVisible(false); } }else{ qDebug() << Q_FUNC_INFO << "NULL"<<__LINE__; return; } } last_discovery_device_address.removeAll(address); } void BlueToothMain::addMyDeviceItemUI(BluezQt::DevicePtr device) { qDebug() << __FUNCTION__ << device->name() << device->address() << device->type() << __LINE__; DeviceInfoItem *item = frame_middle->findChild(device->address()); if (item) { myDevShowFlag = true; return; } if ((m_localDevice != nullptr) && m_localDevice->isPowered() && !frame_middle->isVisible()) frame_middle->setVisible(true); connect(device.data(),&BluezQt::Device::typeChanged,this,[=](BluezQt::Device::Type changeType){ DeviceInfoItem *item = device_list->findChild(device->address()); if (item) { item->refresh_device_icon(changeType); } }); if (device && device->isPaired()) { DeviceInfoItem *item = new DeviceInfoItem(); item->setObjectName(device->address()); connect(item,SIGNAL(sendConnectDevice(QString)),this,SLOT(receiveConnectsignal(QString))); connect(item,SIGNAL(sendDisconnectDeviceAddress(QString)),this,SLOT(receiveDisConnectSignal(QString))); connect(item,SIGNAL(sendDeleteDeviceAddress(QString)),this,SLOT(receiveRemoveSignal(QString))); connect(item,SIGNAL(sendPairedAddress(QString)),this,SLOT(change_device_parent(QString))); connect(item,SIGNAL(connectComplete()),this,SLOT(startBluetoothDiscovery())); QGSettings *changeTheme; const QByteArray id_Theme("org.ukui.style"); if (QGSettings::isSchemaInstalled(id_Theme)) changeTheme = new QGSettings(id_Theme); connect(changeTheme, &QGSettings::changed, this, [=] (const QString &key){ if (key == "iconThemeName"){ DeviceInfoItem *item = frame_middle->findChild(device->address()); if (item) item->refresh_device_icon(device->type()); } }); if(device->isConnected()) item->initInfoPage(device->name(), DEVICE_STATUS::LINK, device); else item->initInfoPage(device->name(), DEVICE_STATUS::UNLINK, device); myDevShowFlag = true; paired_dev_layout->addWidget(item,Qt::AlignTop); } return; } void BlueToothMain::startBluetoothDiscovery() { if (!m_localDevice->isDiscovering()) m_localDevice->startDiscovery(); discovering_timer->start(); } void BlueToothMain::MonitorSleepSignal() { if (QDBusConnection::systemBus().connect("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "PrepareForSleep", this, SLOT(MonitorSleepSlot(bool)))){ qDebug() << Q_FUNC_INFO << "PrepareForSleep signal connected successfully to slot"; } else { qDebug() << Q_FUNC_INFO << "PrepareForSleep signal connected was not successful"; } } //void BlueToothMain::showNormalMainWindow() //{ // qDebug() << Q_FUNC_INFO << __LINE__; // normal_main_widget = new QWidget(this); // normal_main_widget->setObjectName("normalWidget"); // this->setCentralWidget(normal_main_widget); // main_layout = new QVBoxLayout(normal_main_widget); // main_layout->setSpacing(40); // main_layout->setContentsMargins(0,0,30,10); // frame_top = new QWidget(normal_main_widget); // frame_top->setObjectName("frame_top"); // if(m_manager->adapters().size() > 1){ // frame_top->setMinimumSize(582,239); // frame_top->setMaximumSize(1000,239); // }else{ // frame_top->setMinimumSize(582,187); // frame_top->setMaximumSize(1000,187); // } // frame_middle = new QWidget(normal_main_widget); // frame_middle->setObjectName("frame_middle"); // frame_bottom = new QWidget(normal_main_widget); // frame_bottom->setObjectName("frame_bottom"); // frame_bottom->setMinimumWidth(582); // frame_bottom->setMaximumWidth(1000); // main_layout->addWidget(frame_top,1,Qt::AlignTop); // main_layout->addWidget(frame_middle,1,Qt::AlignTop); // main_layout->addWidget(frame_bottom,1,Qt::AlignTop); // main_layout->addStretch(10); // Discovery_device_address.clear(); // last_discovery_device_address.clear(); // InitMainTopUI(); // InitMainMiddleUI(); // InitMainbottomUI(); // this->setLayout(main_layout); // MonitorSleepSignal(); // updateUIWhenAdapterChanged(); //} void BlueToothMain::showMainWindowError() { errorWidget = new QWidget(); QVBoxLayout *errorWidgetLayout = new QVBoxLayout(errorWidget); QLabel *errorWidgetIcon = new QLabel(errorWidget); QLabel *errorWidgetTip0 = new QLabel(errorWidget); QLabel *errorWidgetTip1 = new QLabel(errorWidget); errorWidget->setObjectName("errorWidget"); errorWidgetLayout->setSpacing(10); errorWidgetLayout->setMargin(0); errorWidgetLayout->setContentsMargins(0,0,0,0); errorWidgetIcon->setFixedSize(56,56); errorWidgetTip0->resize(200,30); errorWidgetTip0->setFont(QFont("Noto Sans CJK SC",18,QFont::Bold)); errorWidgetTip1->resize(200,30); if (QIcon::hasThemeIcon("dialog-warning")) { errorWidgetIcon->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(56,56)); } errorWidgetTip0->setText(tr("Bluetooth adapter is abnormal !")); errorWidgetTip1->setText(tr("You can refer to the rfkill command for details.")); errorWidgetLayout->addStretch(10); errorWidgetLayout->addWidget(errorWidgetIcon,1,Qt::AlignCenter); errorWidgetLayout->addWidget(errorWidgetTip0,1,Qt::AlignCenter); errorWidgetLayout->addWidget(errorWidgetTip1,1,Qt::AlignCenter); errorWidgetLayout->addStretch(10); //this->setCentralWidget(errorWidget); //delete normal_main_widget; //normal_main_widget = NULL; } void BlueToothMain::showSpeNoteMainWindow() { qDebug() << Q_FUNC_INFO << __LINE__; QWidget *SpeNoteWidget = new QWidget(); SpeNoteWidget->setObjectName("SpeNoteWidget"); this->setCentralWidget(SpeNoteWidget); main_layout = new QVBoxLayout(SpeNoteWidget); main_layout->setSpacing(40); main_layout->setContentsMargins(0,0,30,10); frame_top = new QWidget(SpeNoteWidget); frame_top->setObjectName("frame_top"); if(m_manager->adapters().size() > 1){ frame_top->setMinimumSize(582,239); frame_top->setMaximumSize(1000,239); }else{ frame_top->setMinimumSize(582,187); frame_top->setMaximumSize(1000,187); } main_layout->addWidget(frame_top,1,Qt::AlignTop); main_layout->addStretch(10); InitMainTopUI(); this->setLayout(main_layout); } void BlueToothMain::updateAdaterInfoList() { qDebug () << Q_FUNC_INFO << __LINE__; adapter_address_list.clear(); adapter_name_list.clear(); if(m_manager->adapters().size()) { for(int i = 0; i < m_manager->adapters().size(); i++) { qDebug() << Q_FUNC_INFO << m_manager->adapters().at(i)->address() << m_manager->adapters().at(i)->name() << __LINE__; adapter_address_list << m_manager->adapters().at(i)->address(); adapter_name_list << m_manager->adapters().at(i)->name(); } //加入adapter_list adapter_list->addItems(adapter_name_list); if(nullptr != m_localDevice) adapter_list->setCurrentIndex(adapter_name_list.indexOf(m_localDevice->name())); } qDebug () << Q_FUNC_INFO << "adapter_address_list:" << adapter_address_list; qDebug () << Q_FUNC_INFO << "adapter_name_list:" << adapter_name_list; } BluezQt::AdapterPtr BlueToothMain::getDefaultAdapter() { qDebug() << Q_FUNC_INFO << __LINE__; BluezQt::AdapterPtr value = nullptr; if (!m_manager->adapters().size()) { return nullptr; } else { if(m_manager->adapters().size() == 1) { value = m_manager->adapters().at(0); } else { if(adapter_address_list.indexOf(Default_Adapter) != -1) { value = m_manager->adapterForAddress(Default_Adapter); } else { value = m_manager->adapterForAddress(adapter_address_list.at(0)); } } } if(settings) settings->set("adapter-address",QVariant::fromValue(value->address())); qDebug() << Q_FUNC_INFO << value.data()->name() << value.data()->address(); return value; } void BlueToothMain::cleanPairDevices() { qDebug() << Q_FUNC_INFO << __LINE__; QLayoutItem *child; while ((child = paired_dev_layout->takeAt(0)) != 0) { qDebug() << Q_FUNC_INFO << __LINE__; if(child->widget()) { child->widget()->setParent(NULL); } delete child; child = nullptr; } while ((child = device_list_layout->takeAt(0)) != 0) { qDebug() << Q_FUNC_INFO << __LINE__; if(child->widget()) { child->widget()->setParent(NULL); } delete child; child = nullptr; } } void BlueToothMain::MonitorSleepSlot(bool value) { qDebug() << Q_FUNC_INFO << value; if (!value) { if (sleep_status) { adapterPoweredChanged(true); poweronAgain_timer->start(); } else adapterPoweredChanged(false); } else { sleep_status = m_localDevice->isPowered(); qDebug() << Q_FUNC_INFO << "The state before sleep:"<adapters().size()) { foreach (BluezQt::DevicePtr dev, m_localDevice->devices()) { qDebug() << Q_FUNC_INFO << dev->name(); if (!dev->isPaired()) m_localDevice->removeDevice(dev); } } } void BlueToothMain::clearAllTimer() { qDebug() << Q_FUNC_INFO << __LINE__; IntermittentScann_timer_count = 0; if (discovering_timer->isActive()) discovering_timer->stop(); if (delayStartDiscover_timer->isActive()) delayStartDiscover_timer->stop(); if (IntermittentScann_timer->isActive()) IntermittentScann_timer->stop(); if (poweronAgain_timer->isActive()) poweronAgain_timer->stop(); if(m_timer->isActive()) m_timer->stop(); } void BlueToothMain::onClick_Open_Bluetooth(bool ischeck) { if (ischeck) qDebug() << Q_FUNC_INFO << "User Turn on bluetooth" << __LINE__ ; else qDebug() << Q_FUNC_INFO << "User Turn off bluetooth" << __LINE__ ; open_bluetooth->setEnabled(false); btPowerBtnTimer->start(); if(ischeck) { if (spe_bt_node && not_hci_node) { M_power_on = true; rfkill_set_idx(); } qDebug() << Q_FUNC_INFO << "spe_bt_node:" << spe_bt_node; qDebug() << Q_FUNC_INFO << "not_hci_node" << not_hci_node; qDebug() << Q_FUNC_INFO << "M_adapter_flag" << M_adapter_flag; if (!not_hci_node && M_adapter_flag && (nullptr != m_localDevice)) { if (!spe_bt_node && m_manager->isBluetoothBlocked()) m_manager->setBluetoothBlocked(false); BluezQt::PendingCall *call = m_localDevice->setPowered(true); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *p) { if(p->error() == 0) { qDebug() << Q_FUNC_INFO << "Success to turn on Bluetooth:" << m_localDevice->isPowered(); } else { //poweronAgain_timer->start(); qDebug() << "Failed to turn on Bluetooth:" << p->errorText(); } //switch_discover->setEnabled(true); }); } } else { if (nullptr == m_localDevice) { qDebug() << Q_FUNC_INFO << "m_localDevice is nullptr!!!" << __LINE__ ; return ; } M_power_on = false; adapterPoweredChanged(false); //断电后先删除所有扫描到的蓝牙设备 clearAllDeviceItemUi(); clearAllTimer(); BluezQt::PendingCall *call = m_localDevice->setPowered(false); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *p){ if(p->error() == 0) { qDebug() << Q_FUNC_INFO << "Success to turn off Bluetooth:" << m_localDevice->isPowered(); if (!spe_bt_node) m_manager->setBluetoothBlocked(true); } else qDebug() << "Failed to turn off Bluetooth:" << p->errorText(); }); } qDebug() << Q_FUNC_INFO << "end" << __LINE__ ; } void BlueToothMain::addOneBluetoothDeviceItemUi(BluezQt::DevicePtr device) { DeviceInfoItem *item = device_list->findChild(device->address()); if (item) { return ; } connect(device.data(),&BluezQt::Device::typeChanged,this,[=](BluezQt::Device::Type changeType){ DeviceInfoItem *item = device_list->findChild(device->address()); if (item) { item->refresh_device_icon(changeType); } }); if(!last_discovery_device_address.contains(device->address())) { DeviceInfoItem *item = new DeviceInfoItem(device_list); item->setObjectName(device->address()); connect(item,SIGNAL(sendConnectDevice(QString)),this,SLOT(receiveConnectsignal(QString))); connect(item,SIGNAL(sendDisconnectDeviceAddress(QString)),this,SLOT(receiveDisConnectSignal(QString))); connect(item,SIGNAL(sendDeleteDeviceAddress(QString)),this,SLOT(receiveRemoveSignal(QString))); connect(item,SIGNAL(sendPairedAddress(QString)),this,SLOT(change_device_parent(QString))); connect(item,SIGNAL(connectComplete()),this,SLOT(startBluetoothDiscovery())); QGSettings *changeTheme; const QByteArray id_Theme("org.ukui.style"); if (QGSettings::isSchemaInstalled(id_Theme)) changeTheme = new QGSettings(id_Theme); connect(changeTheme, &QGSettings::changed, this, [=] (const QString &key){ if (key == "iconThemeName"){ DeviceInfoItem *item = device_list->findChild(device->address()); if (item) item->refresh_device_icon(device->type()); } }); item->initInfoPage(device->name(), DEVICE_STATUS::UNLINK, device); if(device->name() == device->address()) device_list_layout->addWidget(item,Qt::AlignTop); else { device_list_layout->insertWidget(0,item,0,Qt::AlignTop); } last_discovery_device_address << device->address(); } } void BlueToothMain::serviceDiscovered(BluezQt::DevicePtr device) { qDebug() << Q_FUNC_INFO << device->type() << device->name() << device->address() << device->uuids().size(); if(device->isPaired()){ addMyDeviceItemUI(device); return; } if(device->uuids().size() == 0 && device->name().split("-").length() == 6 && device->type() == BluezQt::Device::Uncategorized){ qDebug() << Q_FUNC_INFO << device->name() << device->type(); return; } if(Discovery_device_address.contains(device->address())){ addOneBluetoothDeviceItemUi(device); return; } addOneBluetoothDeviceItemUi(device); Discovery_device_address << device->address(); } void BlueToothMain::clearUiShowDeviceList() { for (int i = 0 ; i < last_discovery_device_address.size() ; i++) { //剔除重新开始扫描时,不在设备列表中的device if (! Discovery_device_address.contains(last_discovery_device_address.at(i))){ //removeDeviceItemUI(last_discovery_device_address.at(i)); receiveRemoveSignal(last_discovery_device_address.at(i)); } } } void BlueToothMain::serviceDiscoveredChange(BluezQt::DevicePtr device) { qDebug() << Q_FUNC_INFO << device->type() << device->name() << device->address() << device->uuids().size() << device->rssi(); if(device->uuids().size() == 0 && device->name().split("-").length() == 6 && device->type() == BluezQt::Device::Uncategorized){ return; } if(device->isPaired() || device->isConnected()) { qDebug() << Q_FUNC_INFO << "device is Paired or Connected" << __LINE__; return; } if(Discovery_device_address.contains(device->address())){ addOneBluetoothDeviceItemUi(device); return; } addOneBluetoothDeviceItemUi(device); Discovery_device_address << device->address(); } void BlueToothMain::receiveConnectsignal(QString device) { if (m_localDevice->isDiscovering()) { clearAllTimer(); m_localDevice->stopDiscovery(); } QDBusMessage m = QDBusMessage::createMethodCall("org.ukui.bluetooth","/org/ukui/bluetooth","org.ukui.bluetooth","connectToDevice"); m << device; qDebug() << Q_FUNC_INFO << m.arguments().at(0).value() <<__LINE__; // 发送Message QDBusMessage response = QDBusConnection::sessionBus().call(m); // 判断Method是否被正确返回 // if (response.type()== QDBusMessage::ReplyMessage) // { // // QDBusMessage的arguments不仅可以用来存储发送的参数,也用来存储返回值; // bRet = response.arguments().at(0).toBool(); // } // else { // qDebug()<<"Message In fail!\n"; // } // qDebug() << Q_FUNC_INFO << __LINE__; // qDebug()<<"bRet:"<() <<__LINE__; // 发送Message QDBusMessage response = QDBusConnection::sessionBus().call(m); } void BlueToothMain::receiveRemoveSignal(QString address) { // QDBusMessage m = QDBusMessage::createMethodCall("org.ukui.bluetooth","/org/ukui/bluetooth","org.ukui.bluetooth","removeDevice"); // m << address; // qDebug() << Q_FUNC_INFO << m.arguments().at(0).value() <<__LINE__; // // 发送Message // QDBusMessage response = QDBusConnection::sessionBus().call(m); qDebug() << Q_FUNC_INFO << address; removeDeviceItemUI(address); m_localDevice->removeDevice(m_localDevice->deviceForAddress(address)); } void BlueToothMain::Refresh_load_Label_icon() { if(StackedWidget->currentWidget()->objectName() == "normalWidget") { if(i == 0) i = 7; loadLabel->setPixmap(QIcon::fromTheme("ukui-loading-"+QString::number(i,10)).pixmap(24,24)); loadLabel->update(); i--; } } void BlueToothMain::set_tray_visible(bool value) { settings->set("tray-show",QVariant::fromValue(value)); } void BlueToothMain::set_discoverable(bool value) { qDebug() << Q_FUNC_INFO << value; if (nullptr == m_localDevice) return; if(value) { if(m_localDevice->discoverableTimeout() != 0) m_localDevice->setDiscoverableTimeout(0); } m_localDevice->setDiscoverable(value); } void BlueToothMain::change_adapter_name(const QString &name) { m_localDevice->setName(name); } void BlueToothMain::change_device_parent(const QString &address) { qDebug() << Q_FUNC_INFO ; if(!frame_middle->isVisible()){ frame_middle->setVisible(true); } DeviceInfoItem *item = device_list->findChild(address); if(item){ device_list_layout->removeWidget(item); item->setParent(frame_middle); paired_dev_layout->addWidget(item); Discovery_device_address.removeAll(address); last_discovery_device_address.removeAll(address); }else{ return; } } //void BlueToothMain::delay_adapterPoweredChanged(bool value) //{ // if (value) // { // QTimer::singleShot(1000,this,[=]{ // adapterPoweredChanged(value); // }); // } // else // { // adapterPoweredChanged(value); // } //} void BlueToothMain::adapterPoweredChanged(bool value) { btPowerBtnTimer->stop(); open_bluetooth->setEnabled(true); qDebug() << Q_FUNC_INFO << value; if(settings) settings->set("switch",QVariant::fromValue(value)); if(value) { bluetooth_name->set_dev_name(m_localDevice->name()); bluetooth_name->setVisible(true); frame_bottom->setVisible(true); if(myDevShowFlag) frame_middle->setVisible(true); if (!open_bluetooth->isChecked()) open_bluetooth->setChecked(true); //延时2S开启扫描,给用户回连缓冲 delayStartDiscover_timer->start(); //this->startDiscovery(); } else { if (bluetooth_name->isVisible()) bluetooth_name->setVisible(false); if (open_bluetooth->isChecked()) open_bluetooth->setChecked(false); if (frame_bottom->isVisible()) frame_bottom->setVisible(false); if(frame_middle->isVisible()) frame_middle->setVisible(false); if (!paired_dev_layout->isEmpty()) myDevShowFlag = true ; else myDevShowFlag = false ; if(nullptr != m_localDevice && m_localDevice->isDiscovering()){ m_localDevice->stopDiscovery(); } } //switch_discover->setChecked(value); qDebug() << Q_FUNC_INFO << "end" << __LINE__; } void BlueToothMain::adapterComboxChanged(int i) { qDebug() << Q_FUNC_INFO << i << adapter_address_list.at(i) << adapter_name_list.at(i) << adapter_address_list << adapter_name_list; if(i != -1) { if (i >= m_manager->adapters().size()) { return; } else { m_localDevice = m_manager->adapterForAddress(adapter_address_list.at(i)); if (m_localDevice.isNull()) return; m_localDevice->stopDiscovery(); updateUIWhenAdapterChanged(); if(settings) settings->set("adapter-address",QVariant::fromValue(adapter_address_list.at(i))); Default_Adapter = adapter_address_list.at(i); } } else { if(open_bluetooth->isChecked()) { qDebug() << __FUNCTION__<< "index - i : "<< i << __LINE__ ; open_bluetooth->setChecked(false); open_bluetooth->setDisabledFlag(false); } if(frame_middle->isVisible()) { frame_middle->setVisible(false); } } } void BlueToothMain::adapterNameChanged(const QString &name) { emit this->adapter_name_changed(name); //设备名字改变,同时改变combox的当前设备名字 int index; index = adapter_address_list.indexOf(m_localDevice->address()); adapter_name_list.removeAt(index); adapter_name_list.insert(index,name); adapter_list->setItemText(index,name); } void BlueToothMain::adapterDeviceRemove(BluezQt::DevicePtr ptr) { // qDebug() << Q_FUNC_INFO << ptr.data()->address() << ptr.data()->name(); removeDeviceItemUI(ptr.data()->address()); } ukui-control-center/plugins/devices/bluetooth/deviceinfoitem.h0000644000175000017500000000605614201663716023677 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef DEVICEINFOITEM_H #define DEVICEINFOITEM_H #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ITEM_WIDTH 220 #define ITEM_WIDTH1 130 #define BTN_1_X 215 #define BTN_2_X 90 #define BTN_1_WIDTH 120 #define BTN_2_WIDTH 85 class DeviceInfoItem : public QWidget { Q_OBJECT public: explicit DeviceInfoItem(QWidget *parent = nullptr); ~DeviceInfoItem(); void initInfoPage(QString d_name = "",DEVICE_STATUS status = DEVICE_STATUS::NOT,BluezQt::DevicePtr device = nullptr); QString get_dev_name(); void changeDevStatus(bool); void setDevConnectedIcon(bool); void AnimationInit(); void refresh_device_icon(BluezQt::Device::Type changeType); protected: void resizeEvent(QResizeEvent *event); void enterEvent(QEvent *event); void leaveEvent(QEvent *event); signals: void sendConnectDevice(QString); void sendDisconnectDeviceAddress(QString); void sendDeleteDeviceAddress(QString); void send_this_item_is_pair(); void sendPairedAddress(QString); void connectComplete(); private slots: void onClick_Connect_Btn(bool); void onClick_Disconnect_Btn(bool); void onClick_Delete_Btn(bool); void updateDeviceStatus(DEVICE_STATUS status = DEVICE_STATUS::NOT); void GSettingsChanges(const QString &key); private: QGSettings *item_gsettings = nullptr; QWidget *parent_widget = nullptr; QLabel *device_icon = nullptr; QLabel *device_name = nullptr; QLabel *device_status = nullptr; BluezQt::DevicePtr device_item = nullptr; QPushButton *connect_btn = nullptr; QPushButton *disconnect_btn = nullptr; QPushButton *del_btn = nullptr; DEVICE_STATUS d_status; QFrame *info_page = nullptr; QTimer *icon_timer = nullptr; QTimer *connect_timer = nullptr; int i = 7; QPropertyAnimation *enter_action = nullptr; QPropertyAnimation *leave_action = nullptr; bool AnimationFlag = false; QTimer *mouse_timer = nullptr; }; #endif // DEVICEINFOITEM_H ukui-control-center/plugins/devices/bluetooth/deviceinfoitem.cpp0000644000175000017500000003236314201663716024232 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "deviceinfoitem.h" DeviceInfoItem::DeviceInfoItem(QWidget *parent) : QWidget(parent) { if(QGSettings::isSchemaInstalled("org.ukui.style")){ item_gsettings = new QGSettings("org.ukui.style"); connect(item_gsettings,&QGSettings::changed,this,&DeviceInfoItem::GSettingsChanges); } this->setMinimumSize(580,50); this->setMaximumSize(1000,50); // this->setStyleSheet("background:white;"); info_page = new QFrame(this); info_page->setFrameShape(QFrame::Shape::Box); // info_page->setStyleSheet("background:blue;"); info_page->setGeometry(0,0,this->width(),this->height()); QHBoxLayout *info_page_layout = new QHBoxLayout(info_page); info_page_layout->setSpacing(8); info_page_layout->setContentsMargins(16,0,16,0); device_icon = new QLabel(info_page); info_page_layout->addWidget(device_icon); device_name = new QLabel(info_page); info_page_layout->addWidget(device_name); info_page_layout->addStretch(); device_status = new QLabel(info_page); info_page_layout->addWidget(device_status); connect_btn = new QPushButton(tr("Connect"),this); connect_btn->setVisible(false); connect(connect_btn,SIGNAL(clicked(bool)),this,SLOT(onClick_Connect_Btn(bool))); disconnect_btn = new QPushButton(tr("Disconnect"),this); disconnect_btn->setVisible(false); connect(disconnect_btn,SIGNAL(clicked(bool)),this,SLOT(onClick_Disconnect_Btn(bool))); del_btn = new QPushButton(tr("Remove"),this); del_btn->setVisible(false); connect(del_btn,SIGNAL(clicked(bool)),this,SLOT(onClick_Delete_Btn(bool))); } DeviceInfoItem::~DeviceInfoItem() { } void DeviceInfoItem::initInfoPage(QString d_name, DEVICE_STATUS status, BluezQt::DevicePtr device) { this->setObjectName(device->address()); connect(device.data(),&BluezQt::Device::pairedChanged,this,[=](bool paird){ qDebug() << Q_FUNC_INFO << "pairedChanged" << paird; changeDevStatus(paird); }); connect(device.data(),&BluezQt::Device::connectedChanged,this,[=](bool connected){ qDebug() << Q_FUNC_INFO << "connectedChanged" << connected; setDevConnectedIcon(connected); }); connect(device.data(),&BluezQt::Device::nameChanged,this,[=](QString name){ qDebug() << Q_FUNC_INFO << "nameChanged" << name; device_name->setText(name); }); QIcon icon_status; refresh_device_icon(device->type()); if(d_name.isEmpty()){ return; } device_name->setText(d_name); d_status = status; device_item = device; if(d_status == DEVICE_STATUS::LINK){ icon_status = QIcon::fromTheme("ukui-dialog-success"); device_status->setPixmap(icon_status.pixmap(QSize(24,24))); } // else if(status == DEVICE_STATUS::UNLINK){ // icon_status = QIcon::fromTheme("software-update-available-symbolic"); // device_status->setPixmap(icon_status.pixmap(QSize(24,24))); // } if(item_gsettings->get("style-name").toString() == "ukui-black" || item_gsettings->get("style-name").toString() == "ukui-dark") { device_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); device_icon->setProperty("useIconHighlightEffect", 0x10); device_status->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); device_status->setProperty("useIconHighlightEffect", 0x10); } AnimationInit(); } void DeviceInfoItem::refresh_device_icon(BluezQt::Device::Type changeType) { qDebug() << __FUNCTION__ << "device changeType" << changeType << __LINE__; QIcon icon_device; if(changeType == BluezQt::Device::Computer){ icon_device = QIcon::fromTheme("computer-symbolic"); }else if(changeType == BluezQt::Device::Phone){ icon_device = QIcon::fromTheme("phone-apple-iphone-symbolic"); }else if((changeType == BluezQt::Device::Headset)||(changeType == BluezQt::Device::Headphones)){ icon_device = QIcon::fromTheme("audio-headphones-symbolic"); }else if(changeType == BluezQt::Device::Mouse){ icon_device = QIcon::fromTheme("input-mouse-symbolic"); }else if(changeType == BluezQt::Device::Keyboard){ icon_device = QIcon::fromTheme("input-keyboard-symbolic"); }else if(changeType == BluezQt::Device::AudioVideo){ icon_device = QIcon::fromTheme("audio-card"); }else{ icon_device = QIcon::fromTheme("bluetooth-symbolic"); } device_icon->setPixmap(icon_device.pixmap(QSize(24,24))); device_icon->update(); } QString DeviceInfoItem::get_dev_name() { return device_item->name(); } void DeviceInfoItem::resizeEvent(QResizeEvent *event) { // this->resize(event->size()); info_page->resize(event->size()); } void DeviceInfoItem::enterEvent(QEvent *event) { AnimationFlag = true; if (device_status->isVisible()) { if (LINK == d_status) { device_status->setToolTip(tr("Device connected")); } else { device_status->setToolTip(tr("Device not connected")); } //else //״̬Ϊһлʱ //{ // device_status->setToolTip(tr("Connecting device")); //} } mouse_timer->start(); } void DeviceInfoItem::leaveEvent(QEvent *event) { // QDateTime current_date_time = QDateTime::currentDateTime(); // QString current_time = current_date_time.toString("hh:mm:ss.zzz "); // qDebug() << Q_FUNC_INFO << current_time; AnimationFlag = false; disconnect_btn->setVisible(false); connect_btn->setVisible(false); del_btn->setVisible(false); leave_action->setStartValue(QRect(0, 0, info_page->width(), info_page->height())); leave_action->setEndValue(QRect(0, 0, this->width(), info_page->height())); leave_action->start(); } void DeviceInfoItem::onClick_Connect_Btn(bool isclicked) { if(!icon_timer&&!connect_timer){ icon_timer = new QTimer(this); icon_timer->setInterval(100); connect_timer = new QTimer(this); connect_timer->setInterval(10000); connect(connect_timer,&QTimer::timeout,this,[=]{ if(icon_timer->isActive()){ icon_timer->stop(); device_status->setPixmap(QIcon::fromTheme("emblem-danger").pixmap(QSize(24,24))); device_status->update(); } connect_timer->stop(); emit connectComplete(); }); emit sendConnectDevice(device_item->address()); i = 7; if(!device_status->isVisible()) device_status->setVisible(true); connect(icon_timer,&QTimer::timeout,this,[=]{ if(i == -1) i = 7; device_status->setPixmap(QIcon::fromTheme("ukui-loading-"+QString::number(i,10)).pixmap(24,24)); device_status->update(); i--; }); connect_timer->start(10000); icon_timer->start(100); }else{ emit sendConnectDevice(device_item->address()); connect_timer->start(10000); icon_timer->start(100); if(!device_status->isVisible()) device_status->setVisible(true); } } void DeviceInfoItem::onClick_Disconnect_Btn(bool isclicked) { // qDebug() << Q_FUNC_INFO; emit sendDisconnectDeviceAddress(device_item->address()); } void DeviceInfoItem::onClick_Delete_Btn(bool isclicked) { // qDebug() << Q_FUNC_INFO; // this->setVisible(false); emit sendDeleteDeviceAddress(device_item->address()); } void DeviceInfoItem::changeDevStatus(bool pair) { if(icon_timer && icon_timer->isActive()) icon_timer->stop(); if(pair){ if (!device_item->isConnected()){ device_status->setVisible(false); d_status = DEVICE_STATUS::UNLINK; }else{ device_status->setVisible(true); d_status = DEVICE_STATUS::LINK; QIcon icon_status = QIcon::fromTheme("ukui-dialog-success"); device_status->setPixmap(icon_status.pixmap(QSize(24,24))); } emit sendPairedAddress(device_item->address()); }else{ // QIcon icon_status = QIcon::fromTheme("software-installed-symbolic"); // device_status->setPixmap(icon_status.pixmap(QSize(24,24))); } emit connectComplete(); } void DeviceInfoItem::setDevConnectedIcon(bool connected) { if(icon_timer && icon_timer->isActive()) icon_timer->stop(); if(connected && device_item->isPaired()){ d_status = DEVICE_STATUS::LINK; device_status->setVisible(true); QIcon icon_status = QIcon::fromTheme("ukui-dialog-success"); device_status->setPixmap(icon_status.pixmap(QSize(24,24))); if(connect_btn->isVisible()){ connect_btn->setVisible(false); disconnect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); disconnect_btn->setVisible(true); } emit connectComplete(); }else{ if(disconnect_btn->isVisible()){ disconnect_btn->setVisible(false); connect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); connect_btn->setVisible(true); } d_status = DEVICE_STATUS::UNLINK; device_status->setVisible(false); } } void DeviceInfoItem::AnimationInit() { mouse_timer = new QTimer(this); mouse_timer->setInterval(300); connect(mouse_timer,&QTimer::timeout,this,[=]{ if(AnimationFlag){ if(leave_action->state() != QAbstractAnimation::Running){ enter_action->setStartValue(QRect(0, 0, info_page->width(), info_page->height())); enter_action->setEndValue(QRect(0, 0, info_page->width()-((device_item->isPaired() && device_item->type() != BluezQt::Device::Mouse && device_item->type() != BluezQt::Device::Keyboard)?ITEM_WIDTH:ITEM_WIDTH1), info_page->height())); enter_action->start(); } } mouse_timer->stop(); }); enter_action = new QPropertyAnimation(info_page,"geometry"); enter_action->setDuration(0); enter_action->setEasingCurve(QEasingCurve::OutQuad); connect(enter_action,&QPropertyAnimation::finished,this,[=]{ if (device_item->isPaired()) { if (device_item->type() != BluezQt::Device::Mouse && device_item->type() != BluezQt::Device::Keyboard) { if (d_status == DEVICE_STATUS::LINK){ disconnect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); disconnect_btn->setVisible(true); }else if (d_status == DEVICE_STATUS::UNLINK){ connect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); connect_btn->setVisible(true); } del_btn->setGeometry(this->width()-BTN_2_X,2,BTN_2_WIDTH,45); del_btn->setVisible(true); }else{ del_btn->setGeometry(this->width()-125,2,BTN_1_WIDTH,45); del_btn->setVisible(true); } } else { connect_btn->setGeometry(this->width()-125,2,BTN_1_WIDTH,45); connect_btn->setVisible(true); } }); leave_action = new QPropertyAnimation(info_page,"geometry"); leave_action->setDuration(0); leave_action->setEasingCurve(QEasingCurve::InQuad); } void DeviceInfoItem::updateDeviceStatus(DEVICE_STATUS status) { QIcon icon_status; if(status == DEVICE_STATUS::LINK){ icon_status = QIcon::fromTheme("emblem-default"); device_status->setPixmap(icon_status.pixmap(QSize(24,24))); }else if(status == DEVICE_STATUS::UNLINK){ icon_status = QIcon::fromTheme("emblem-important"); device_status->setPixmap(icon_status.pixmap(QSize(24,24))); } } void DeviceInfoItem::GSettingsChanges(const QString &key) { qDebug() << Q_FUNC_INFO << key; if(key == "styleName"){ if(item_gsettings->get("style-name").toString() == "ukui-black" || item_gsettings->get("style-name").toString() == "ukui-dark") { device_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); device_icon->setProperty("useIconHighlightEffect", 0x10); device_status->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); device_status->setProperty("useIconHighlightEffect", 0x10); }else{ device_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::black)); device_icon->setProperty("useIconHighlightEffect", 0x10); device_status->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); device_status->setProperty("useIconHighlightEffect", 0x10); } } } ukui-control-center/plugins/devices/bluetooth/bluetooth.pro0000644000175000017500000000317114201663716023256 0ustar fengfenginclude(../../../env.pri) QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets dbus BluezQt TEMPLATE = lib CONFIG += plugin \ += c++11 \ link_pkgconfig PKGCONFIG += gsettings-qt gio-2.0 LIBS += -L /usr/lib/x86_64-linux-gnur -l KF5BluezQt -lgio-2.0 -lglib-2.0 TARGET = $$qtLibraryTarget(bluetooth) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # QT_NO_WARNING_OUTPUT \ # QT_NO_DEBUG_OUTPUT # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ bluetooth.cpp \ bluetoothmain.cpp \ bluetoothnamelabel.cpp \ deviceinfoitem.cpp \ loadinglabel.cpp # mylayout.cpp HEADERS += \ bluetooth.h \ bluetoothmain.h \ bluetoothnamelabel.h \ config.h \ deviceinfoitem.h \ loadinglabel.h # mylayout.h # Default rules for deployment. INSTALLS += target FORMS += ukui-control-center/plugins/devices/bluetooth/bluetoothnamelabel.cpp0000644000175000017500000002070314201663716025101 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "bluetoothnamelabel.h" BluetoothNameLabel::BluetoothNameLabel(QWidget *parent, int x, int y): QWidget(parent) { // qDebug() << Q_FUNC_INFO << x << y; this->setAutoFillBackground(true); this->setObjectName("BluetoothNameLabel"); this->setStyleSheet("QWidget{border: none;border-radius:2px;}"); this->setFixedSize(x,y); hLayout = new QHBoxLayout(this); hLayout->setContentsMargins(5,0,5,0); hLayout->setSpacing(0); m_label = new QLabel(this); m_label->resize(10,10); m_label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); //m_label->setGeometry(2,2,this->width()-3,this->height()-3); // m_label->setStyleSheet("QLabel{\ // width: 250px;\ // height: 20px;\ // font-family: PingFangSC-Regular, PingFang SC;\ // font-weight: 420;\ // line-height: 20px;}"); // m_label->setIndent(2); // m_label->setStyleSheet("QLabel{\ // width: 280px;\ // height: 20px;\ // font-family: PingFangSC-Regular, PingFang SC;\ // font-weight: 420;\ // line-height: 20px;}"); hLayout->addWidget(m_label); icon_pencil = new QLabel(this); icon_pencil->setGeometry(this->width()-200,2,43,this->height()-3); icon_pencil->setPixmap(QIcon::fromTheme("document-edit-symbolic").pixmap(20,20)); icon_pencil->setToolTip(tr("Double-click to change the device name")); hLayout->addWidget(icon_pencil); hLayout->addStretch(1); m_lineedit = new QLineEdit(this); m_lineedit->setEchoMode(QLineEdit::Normal); //m_lineedit->setAlignment(Qt::AlignCenter); m_lineedit->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); connect(m_lineedit,&QLineEdit::editingFinished,this,&BluetoothNameLabel::LineEdit_Input_Complete); m_lineedit->setGeometry(2,2,this->width()-3,this->height()-3); m_lineedit->setVisible(false); if(QGSettings::isSchemaInstalled("org.ukui.style")){ settings = new QGSettings("org.ukui.style"); if(settings->get("style-name").toString() == "ukui-black" || settings->get("style-name").toString() == "ukui-dark") { style_flag = true; icon_pencil->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); icon_pencil->setProperty("useIconHighlightEffect", 0x10); } else style_flag = false; switch (settings->get("systemFontSize").toInt()) { case 11: case 12: case 13: font_width = 100; break; case 14: font_width = 70; break; case 15: case 16: font_width = 50; break; default: break; } qDebug() << Q_FUNC_INFO << connect(settings,&QGSettings::changed,this,&BluetoothNameLabel::settings_changed); } } BluetoothNameLabel::~BluetoothNameLabel() { } void BluetoothNameLabel::set_dev_name(const QString &dev_name) { QFont ft; QFontMetrics fm(ft); //QString text = fm.elidedText(dev_name, Qt::ElideMiddle, font_width); QString text = fm.elidedText(dev_name, Qt::ElideMiddle, this->width()); //m_label->setText(tr("Can now be found as \"%1\"").arg(text)); m_label->setText(text); m_label->setToolTip(tr("Can now be found as \"%1\"").arg(dev_name)); //m_label->adjustSize(); m_label->update(); device_name = dev_name; } void BluetoothNameLabel::dev_name_limit_fun() { if (!messagebox) { messagebox = new QMessageBox(QMessageBox::NoIcon, tr("Tip"), tr("The length of the device name does not exceed %1 characters !").arg(QString::number(DEVNAMELENGTH)), QMessageBox::Ok); if (messagebox->exec() == QMessageBox::Ok || messagebox->exec() == QMessageBox::Close) { set_label_text(device_name); delete messagebox; messagebox = NULL; } } } void BluetoothNameLabel::mouseDoubleClickEvent(QMouseEvent *event) { Q_UNUSED(event); m_label->setVisible(false); icon_pencil->setVisible(false); m_lineedit->setText(device_name); m_lineedit->setVisible(true); m_lineedit->setFocus(); } void BluetoothNameLabel::leaveEvent(QEvent *event) { Q_UNUSED(event); if(!m_lineedit->isVisible()) this->setStyleSheet("QWidget{border:none;border-radius:2px;}"); } void BluetoothNameLabel::enterEvent(QEvent *event) { Q_UNUSED(event); // QPalette palette; // palette.setColor(QPalette::Background, QColor(Qt::white)); // this->setPalette(palette); // this->update(); if(style_flag) { this->setStyleSheet("QWidget#BluetoothNameLabel{background-color:black;border:none;border-radius:2px;}"); icon_pencil->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); icon_pencil->setProperty("useIconHighlightEffect", 0x10); } else { this->setStyleSheet("QWidget#BluetoothNameLabel{background-color:white;border:none;border-radius:2px;}"); } } void BluetoothNameLabel::LineEdit_Input_Complete() { qDebug() << Q_FUNC_INFO; if (m_lineedit->text().isEmpty()) { m_lineedit->setText(device_name); m_lineedit->update(); this->setStyleSheet("QWidget{border:none;border-radius:2px;}"); } if(device_name == m_lineedit->text()){ set_label_text(device_name); }else{ if (m_lineedit->text().length() > DEVNAMELENGTH) { dev_name_limit_fun(); } else { device_name = m_lineedit->text(); emit this->send_adapter_name(m_lineedit->text()); } } this->setStyleSheet("QWidget{border:none;border-radius:2px;}"); } void BluetoothNameLabel::set_label_text(const QString &value) { m_lineedit->setVisible(false); QFont ft; QFontMetrics fm(ft); //QString text = fm.elidedText(m_lineedit->text(), Qt::ElideMiddle, font_width); QString text = fm.elidedText(value, Qt::ElideMiddle, this->width()); //m_label->setText(tr("Can now be found as \"%1\"").arg(text)); m_label->setText(text); m_label->setToolTip(tr("Can now be found as \"%1\"").arg(device_name)); m_label->setVisible(true); icon_pencil->setVisible(true); } void BluetoothNameLabel::settings_changed(const QString &key) { qDebug() << Q_FUNC_INFO <get("style-name").toString() == "ukui-black" || settings->get("style-name").toString() == "ukui-dark") { icon_pencil->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); icon_pencil->setProperty("useIconHighlightEffect", 0x10); style_flag = true; } else style_flag = false; }else if(key == "systemFontSize"){ QFont ft; ft.setPixelSize(settings->get("systemFontSize").toInt()); switch (settings->get("systemFontSize").toInt()) { case 11: case 12: case 13: font_width = 100; break; case 14: font_width = 70; break; case 15: case 16: font_width = 50; break; default: break; } QFontMetrics fm(ft); //QString text = fm.elidedText(device_name, Qt::ElideMiddle, font_width); QString text = fm.elidedText(device_name, Qt::ElideMiddle,this->width()); m_label->setText(text); //m_label->setText(tr("Can now be found as \"%1\"").arg(text)); m_label->setVisible(true); icon_pencil->setVisible(true); } } ukui-control-center/plugins/devices/bluetooth/loadinglabel.cpp0000644000175000017500000000305314201663716023647 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "loadinglabel.h" LoadingLabel::LoadingLabel(QObject *parent) { m_timer = new QTimer(this); m_timer->setInterval(100); connect(m_timer,SIGNAL(timeout()),this,SLOT(Refresh_icon())); this->setPixmap(QIcon::fromTheme("ukui-loading-"+QString("%1").arg(i)).pixmap(this->width(),this->height())); } LoadingLabel::~LoadingLabel() { // delete m_timer; } void LoadingLabel::setTimerStop() { m_timer->start(); } void LoadingLabel::setTimerStart() { m_timer->stop(); } void LoadingLabel::setTimeReresh(int m) { m_timer->setInterval(m); } void LoadingLabel::Refresh_icon() { qDebug() << Q_FUNC_INFO; if(i == 8) i = 0; this->setPixmap(QIcon::fromTheme("ukui-loading-"+QString::number(i,10)).pixmap(this->width(),this->height())); this->update(); i++; } ukui-control-center/plugins/devices/bluetooth/bluetoothnamelabel.h0000644000175000017500000000376114201663716024553 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef BLUETOOTHNAMELABEL_H #define BLUETOOTHNAMELABEL_H #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEVNAMELENGTH 20 class BluetoothNameLabel : public QWidget { Q_OBJECT public: BluetoothNameLabel(QWidget *parent = nullptr, int x = 200,int y = 40); ~BluetoothNameLabel(); void set_dev_name(const QString &dev_name); void dev_name_limit_fun(); protected: void mouseDoubleClickEvent(QMouseEvent *event); void leaveEvent(QEvent *event); void enterEvent(QEvent *event); signals: void send_adapter_name(const QString &value); public slots: void LineEdit_Input_Complete(); void set_label_text(const QString &value); void settings_changed(const QString &key); private: QGSettings *settings; bool style_flag = false; QLabel *m_label = nullptr; QLabel *icon_pencil=nullptr; QLineEdit *m_lineedit = nullptr; QString device_name; int font_width; QMessageBox *messagebox = nullptr; QHBoxLayout *hLayout = nullptr; }; #endif // BLUETOOTHNAMELABEL_H ukui-control-center/plugins/devices/bluetooth/bluetooth.h0000644000175000017500000000271114201663716022704 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef BLUETOOTH_H #define BLUETOOTH_H #include #include #include "shell/interface.h" #include "bluetoothmain.h" class Bluetooth : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Bluetooth(); ~Bluetooth(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; private: QString pluginName; int pluginType; BlueToothMain * pluginWidget; bool mFirstLoad; }; #endif // BLUETOOTH_H ukui-control-center/plugins/devices/bluetooth/config.h0000644000175000017500000000171214201663716022144 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef CONFIG_H #define CONFIG_H enum DEVICE_TYPE{ PC = 0, PHONE, HEADSET, OTHER, Mouse, }; enum DEVICE_STATUS{ LINK = 0, UNLINK, ERROR, NOT, }; #endif // CONFIG_H ukui-control-center/plugins/devices/bluetooth/bluetoothmain.h0000644000175000017500000001375014201663716023556 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef BLUETOOTHMAIN_H #define BLUETOOTHMAIN_H #include "SwitchButton/switchbutton.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "deviceinfoitem.h" #include "bluetoothnamelabel.h" class BlueToothMain : public QMainWindow { Q_OBJECT public: BlueToothMain(QWidget *parent = nullptr); ~BlueToothMain(); void InitMainTopUI(); void InitMainMiddleUI(); void InitMainbottomUI(); void startDiscovery(); void stopDiscovery(); void adapterChanged(); void updateUIWhenAdapterChanged(); void removeDeviceItemUI(QString address); void addMyDeviceItemUI(BluezQt::DevicePtr); void MonitorSleepSignal(); //void showNormalMainWindow(); void showMainWindowError(); void showSpeNoteMainWindow(); void updateAdaterInfoList(); BluezQt::AdapterPtr getDefaultAdapter(); void adapterConnectFun(); void cleanPairDevices(); protected: void leaveEvent(QEvent *event); signals: void adapter_name_changed(const QString &name); private slots: void onClick_Open_Bluetooth(bool); void serviceDiscovered(BluezQt::DevicePtr); void serviceDiscoveredChange(BluezQt::DevicePtr); void receiveConnectsignal(QString); void receiveDisConnectSignal(QString); void receiveRemoveSignal(QString); void Refresh_load_Label_icon(); void set_tray_visible(bool); void set_discoverable(bool); void change_adapter_name(const QString &name); void change_device_parent(const QString &address); void adapterPoweredChanged(bool value); //void delay_adapterPoweredChanged(bool value); void adapterComboxChanged(int i); void adapterNameChanged(const QString &name); void adapterDeviceRemove(BluezQt::DevicePtr ptr); void MonitorSleepSlot(bool value); void startBluetoothDiscovery(); private: //============================================================================ QGSettings *settings = nullptr; QString Default_Adapter; QStringList paired_device_address; QString finally_connect_the_device; QStringList Discovery_device_address; QStringList last_discovery_device_address; QLabel *label_2 = nullptr; QLabel *loadLabel = nullptr; QPushButton *discover_refresh; QTimer *m_timer = nullptr; QTimer *discovering_timer =nullptr; QTimer *delayStartDiscover_timer =nullptr; QTimer *IntermittentScann_timer =nullptr; QTimer *poweronAgain_timer =nullptr; int IntermittentScann_timer_count = 0 ; int i = 7; bool myDevShowFlag = false; bool sleep_status = false; void clearUiShowDeviceList(); void addOneBluetoothDeviceItemUi(BluezQt::DevicePtr); void clearAllDeviceItemUi(); void clearAllTimer(); //============================================================================ //new QStackedWidget *StackedWidget = nullptr; BluezQt::Manager *m_manager = nullptr; BluezQt::InitManagerJob *job = nullptr; BluezQt::AdapterPtr m_localDevice = nullptr; SwitchButton *open_bluetooth = nullptr; SwitchButton *show_panel = nullptr; SwitchButton *switch_discover = nullptr; QVBoxLayout *main_layout = nullptr; QFrame *frame_2 = nullptr; QComboBox *adapter_list = nullptr; QWidget *normal_main_widget = nullptr; QWidget *frame_top = nullptr; QWidget *frame_middle = nullptr; QVBoxLayout *paired_dev_layout = nullptr; QWidget *frame_bottom = nullptr; BluetoothNameLabel *bluetooth_name = nullptr; QVBoxLayout *bottom_layout = nullptr; QScrollArea *device_area = nullptr; QWidget * device_list = nullptr; QVBoxLayout *device_list_layout = nullptr; QStringList adapter_address_list; QStringList adapter_name_list; QTimer * btPowerBtnTimer = nullptr; void InitMainWindowUi(); void InitMainWindowTopUi(); void InitMainWindowMiddleUi(); void InitMainWindowBottomUi(); void ShowNormalMainWindow(); void ShowSpecialMainWindow(); QWidget *errorWidget ; void InitMainWindowError(); void ShowErrorMainWindow(); void RefreshWindowUiState(); void RefreshMainWindowTopUi(); void RefreshMainWindowMiddleUi(); void RefreshMainWindowBottomUi(); void InitBluetoothManager(); //void connectAdapterChanged(); void connectManagerChanged(); void addAdapterList(QString newAdapterAddress,QString newAdapterName); void removeAdapterList(QString adapterAddress,QString adapterName); void InitAllTimer(); }; #endif // BLUETOOTHMAIN_H ukui-control-center/plugins/devices/bluetooth/loadinglabel.h0000644000175000017500000000233214201663716023313 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef LOADINGLABEL_H #define LOADINGLABEL_H #include #include #include #include #include #include class LoadingLabel : public QLabel { public: explicit LoadingLabel(QObject *parent = nullptr); ~LoadingLabel(); void setTimerStop(); void setTimerStart(); void setTimeReresh(int); private slots: void Refresh_icon(); private: QTimer *m_timer; int i; }; #endif // LOADINGLABEL_H ukui-control-center/plugins/devices/keyboard/0000755000175000017500000000000014201663716020320 5ustar fengfengukui-control-center/plugins/devices/keyboard/keyboardlayout.h0000644000175000017500000000266014201663671023533 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef KEYBOARDLAYOUT_H #define KEYBOARDLAYOUT_H #include #include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif typedef struct _Layout Layout; struct _Layout{ QString desc; QString name; }; class KeyboardLayout : public QWidget { Q_OBJECT public: explicit KeyboardLayout(); ~KeyboardLayout(); void data_init(); QString kbd_get_description_by_id(const char *visible); }; #endif // KEYBOARDLAYOUT_H ukui-control-center/plugins/devices/keyboard/keyboardcontrol.ui0000644000175000017500000007242214201663716024067 0ustar fengfeng KeyboardControl 0 0 642 690 0 0 16777215 16777215 0 0 0 32 48 550 0 960 16777215 0 0 0 0 0 8 0 0 0 Keys Settings true 2 0 0 50 16777215 50 QFrame::Box 0 0 0 0 0 0 16 16 0 0 Enable repeat key true Qt::Horizontal 40 20 0 50 16777215 50 QFrame::Box 0 0 0 0 0 16 16 16 0 0 128 0 128 16777215 Delay 0 0 Short 200 2100 1 Qt::Horizontal 0 0 Long 0 50 16777215 50 QFrame::Box 0 0 0 0 0 16 16 16 0 0 128 0 128 16777215 Speed 0 0 Slow 10 110 1 Qt::Horizontal 0 0 Fast 0 50 16777215 50 QFrame::Box 0 0 0 0 0 48 16 16 0 0 Input characters to test the repetition effect: true Qt::Horizontal 40 20 200 35 200 35 0 50 16777215 50 QFrame::Box QFrame::Plain 0 0 0 0 0 0 16 16 0 0 Tip of keyboard true Qt::Horizontal 40 20 0 50 16777215 50 0 0 0 0 0 0 16 16 0 0 Enable numlock true Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Fixed 20 32 0 0 Input Settings true 8 0 0 50 16777215 50 QFrame::Box 0 0 0 0 0 48 16 16 0 0 Keyboard layout true Qt::Horizontal 40 20 260 30 260 30 0 60 16777215 60 0 0 0 0 0 8 0 0 120 0 120 16777215 Input Set Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/devices/keyboard/tastenbrett.h0000644000175000017500000000234614201663671023035 0ustar fengfeng/* Copyright 2019 Harald Sitter 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 . */ #ifndef TASTENBRETT_H #define TASTENBRETT_H #include class Tastenbrett { public: static QString path(); static bool exists(); static void launch(const QString &model, const QString &layout, const QString &variant, const QString &options, const QString &title = QString()); }; #endif // TASTENBRETT_H ukui-control-center/plugins/devices/keyboard/keyboardlayout.cpp0000644000175000017500000001051414201663716024063 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "keyboardlayout.h" #include #include #include XklEngine * engine; XklConfigRegistry * config_registry; static void KeyboardXkb_get_countries(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list); static void KeyboardXkb_get_languages(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list); static void KeyboardXkb_get_available_countries(XklConfigRegistry *config_registry, XklConfigItem * parent_config_item, XklConfigItem *config_item, QList *list); static void KeyboardXkb_get_available_languages(XklConfigRegistry *config_registry, XklConfigItem * parent_config_item, XklConfigItem *config_item, QList *list); QList languages; QList countries; KeyboardLayout::KeyboardLayout() { data_init(); char * id = QString("ee").toLatin1().data(); QString desc = kbd_get_description_by_id(id); } KeyboardLayout::~KeyboardLayout() { } void KeyboardLayout::data_init(){ engine = xkl_engine_get_instance (QX11Info::display()); config_registry = xkl_config_registry_get_instance (engine); xkl_config_registry_load (config_registry, false); xkl_config_registry_foreach_country(config_registry,(ConfigItemProcessFunc)KeyboardXkb_get_countries, NULL); xkl_config_registry_foreach_language(config_registry,(ConfigItemProcessFunc)KeyboardXkb_get_languages, NULL); // char * country_id = QString("EE").toLatin1().data(); // xkl_config_registry_foreach_country_variant (config_registry, country_id, (TwoConfigItemsProcessFunc)KeyboardXkb_get_available_countries, NULL); // char * language_id = QString("est").toLatin1().data(); // xkl_config_registry_foreach_language_variant (config_registry, language_id, (TwoConfigItemsProcessFunc)KeyboardXkb_get_available_languages, NULL); } QString KeyboardLayout::kbd_get_description_by_id(const char *visible){ char *l, *sl, *v, *sv; if (matekbd_keyboard_config_get_descriptions(config_registry, visible, &sl, &l, &sv, &v)) visible = matekbd_keyboard_config_format_full_layout (l, v); return QString(const_cast(visible)); } static void KeyboardXkb_get_countries(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list){ Layout item; item.desc = config_item->description; item.name = config_item->name; qDebug()<<"countries" << "desc = "<append(item); countries.append(item); } static void KeyboardXkb_get_languages(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list){ Layout item; item.desc = config_item->description; item.name = config_item->name; qDebug()<<"languages" << "desc = "<append(item); languages.append(item); } static void KeyboardXkb_get_available_countries(XklConfigRegistry *config_registry, XklConfigItem * parent_config_item, XklConfigItem *config_item, QList *list){ const gchar *xkb_id = config_item ? matekbd_keyboard_config_merge_items (parent_config_item->name, config_item->name) : parent_config_item->name; g_warning("------------->%s", xkb_id); } static void KeyboardXkb_get_available_languages(XklConfigRegistry *config_registry, XklConfigItem *parent_config_item, XklConfigItem *config_item, QList *list){ KeyboardXkb_get_available_countries(config_registry, parent_config_item, config_item, NULL); } ukui-control-center/plugins/devices/keyboard/kbdlayoutmanager.h0000644000175000017500000000377614201663671024037 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef KBDLAYOUTMANAGER_H #define KBDLAYOUTMANAGER_H #include #include #include #include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif typedef struct _Layout Layout; struct _Layout{ QString desc; QString name; }; namespace Ui { class LayoutManager; } class KbdLayoutManager : public QDialog { Q_OBJECT public: explicit KbdLayoutManager(QWidget *parent = 0); ~KbdLayoutManager(); QString kbd_get_description_by_id(const char *visible); void kbd_trigger_available_countries(char * countryid); void kbd_trigger_available_languages(char * languageid); void configRegistry(); void setupComponent(); void setupConnect(); void rebuildSelectListWidget(); void rebuildVariantCombo(); void rebuild_listwidget(); void preview(); void installedNoSame(); protected: void paintEvent(QPaintEvent * event); private: Ui::LayoutManager *ui; QStringList layoutsList; QGSettings * kbdsettings; }; #endif // KBDLAYOUTMANAGER_H ukui-control-center/plugins/devices/keyboard/preview/0000755000175000017500000000000014201663716022001 5ustar fengfengukui-control-center/plugins/devices/keyboard/preview/geometry_parser.h0000644000175000017500000001270614201663671025367 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef GEOMETRY_PARSER_H #define GEOMETRY_PARSER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "geometry_components.h" namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace phx = boost::phoenix; namespace iso = boost::spirit::iso8859_1; namespace grammar { struct keywords : qi::symbols { keywords(); }; template struct GeometryParser : qi::grammar { //comments qi::rulecomments, ignore; qi::rulelocalDimension, priority; //general non-terminals qi::rulename; qi::ruledescription; qi::ruleinput; //non-terminals for shape qi::ruleshape; qi::ruleshapeDef; qi::ruleshapeC; qi::ruleset; qi::rulesetap; qi::ruleseta; qi::rulecornerRadius; qi::rulecordinatea; qi::rulecordinates; //non-terminals for key qi::rulekeygap; qi::rulekeyName; qi::rulekeyShape; qi::rulekeyColor; qi::rulekeyDesc; qi::rulekeys; qi::rulerow; qi::rulesection; //non-terminals related to local data qi::rulelocalShape; qi::rulelocalColor; //Geometry non-terminals qi::rulegeomShape; qi::rulegeomTop, geomVertical; qi::rulegeomLeft; qi::rulegeomRowTop; qi::rulegeomRowLeft; qi::rulegeomGap; qi::rulegeomAtt; qi::ruleangle; qi::ruletop; qi::ruleleft; qi::rulewidth; qi::ruleheight; qi::rulestart; Geometry geom; keywords keyword; double shapeLenX, shapeLenY, approxLenX, approxLenY, keyCordiX, keyCordiY, KeyOffset; GeometryParser(); //functions for shape void getShapeName(std::string n); void setCord(); void setApprox(); //functions for section void sectionName(std::string n); void setSectionShape(std::string n); void setSectionTop(double a); void setSectionLeft(double a); void setSectionAngle(double a); void sectioninit(); //functions for row void setRowShape(std::string n); void setRowTop(double a); void setRowLeft(double a); void rowinit(); void addRow(); //functions for key void setKeyName(std::string n); void setKeyShape(std::string n); void setKeyNameandShape(std::string n); void setKeyOffset(); void setKeyCordi(); //functions for geometry void setGeomShape(std::string n); void getName(std::string n); void getDescription(std::string n); //functions for alignment void setVerticalRow(); void setVerticalSection(); void setVerticalGeometry(); }; Geometry parseGeometry(const QString &model); QString getGeometry(QString geometryFile, QString geometryName); QString includeGeometry(QString geometry); QString getGeometryStrContent(QString geometryStr); QString findGeometryBaseDir(); } #endif //geometry_parser ukui-control-center/plugins/devices/keyboard/preview/keysymhelper.h0000644000175000017500000000217314201663671024676 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KEYSYMHELPER_H #define KEYSYMHELPER_H #include #include class KeySymHelper { public: KeySymHelper(); QString getKeySymbol(const QString &opton); bool isFailed() const { return nill >= 120; } private: QMap keySymbolMap; int nill; }; #endif // KEYSYMHELPER_H ukui-control-center/plugins/devices/keyboard/preview/keyboard_config.cpp0000644000175000017500000001545714201663671025646 0ustar fengfeng/* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "keyboard_config.h" #include "debug.h" #include #include static const char* const SWITCHING_POLICIES[] = {"Global", "Desktop", "WinClass", "Window", nullptr }; static const char LIST_SEPARATOR[] = ","; //static const char* DEFAULT_LAYOUT = "us"; static const char DEFAULT_MODEL[] = "pc104"; static const QString CONFIG_FILENAME(QStringLiteral("kxkbrc")); static const QString CONFIG_GROUPNAME(QStringLiteral("Layout")); const int KeyboardConfig::NO_LOOPING = -1; KeyboardConfig::KeyboardConfig() { setDefaults(); } QString KeyboardConfig::getSwitchingPolicyString(SwitchingPolicy switchingPolicy) { return SWITCHING_POLICIES[switchingPolicy]; } static int findStringIndex(const char* const strings[], const QString& toFind, int defaultIndex) { for(int i=0; strings[i] != nullptr; i++) { if( toFind == strings[i] ) { return i; } } return defaultIndex; } void KeyboardConfig::setDefaults() { keyboardModel = DEFAULT_MODEL; resetOldXkbOptions = false; xkbOptions.clear(); // init layouts options configureLayouts = false; layouts.clear(); // layouts.append(LayoutUnit(DEFAULT_LAYOUT)); layoutLoopCount = NO_LOOPING; // switch control options switchingPolicy = SWITCH_POLICY_GLOBAL; // stickySwitching = false; // stickySwitchingDepth = 2; // display options showIndicator = true; indicatorType = SHOW_LABEL; showSingle = false; } static KeyboardConfig::IndicatorType getIndicatorType(bool showFlag, bool showLabel) { if( showFlag ) { if( showLabel ) return KeyboardConfig::SHOW_LABEL_ON_FLAG; else return KeyboardConfig::SHOW_FLAG; } else { return KeyboardConfig::SHOW_LABEL; } } void KeyboardConfig::load() { KConfigGroup config(KSharedConfig::openConfig( CONFIG_FILENAME, KConfig::NoGlobals ), CONFIG_GROUPNAME); keyboardModel = config.readEntry("Model", ""); resetOldXkbOptions = config.readEntry("ResetOldOptions", false); QString options = config.readEntry("Options", ""); xkbOptions = options.split(LIST_SEPARATOR, QString::SkipEmptyParts); configureLayouts = config.readEntry("Use", false); QString layoutsString = config.readEntry("LayoutList", ""); QStringList layoutStrings = layoutsString.split(LIST_SEPARATOR, QString::SkipEmptyParts); // if( layoutStrings.isEmpty() ) { // layoutStrings.append(DEFAULT_LAYOUT); // } layouts.clear(); foreach(const QString& layoutString, layoutStrings) { layouts.append(LayoutUnit(layoutString)); } if( layouts.isEmpty() ) { configureLayouts = false; } layoutLoopCount = config.readEntry("LayoutLoopCount", NO_LOOPING); QString layoutMode = config.readEntry("SwitchMode", "Global"); switchingPolicy = static_cast(findStringIndex(SWITCHING_POLICIES, layoutMode, SWITCH_POLICY_GLOBAL)); showIndicator = config.readEntry("ShowLayoutIndicator", true); bool showFlag = config.readEntry("ShowFlag", false); bool showLabel = config.readEntry("ShowLabel", true); indicatorType = getIndicatorType(showFlag, showLabel); showSingle = config.readEntry("ShowSingle", false); QString labelsStr = config.readEntry("DisplayNames", ""); QStringList labels = labelsStr.split(LIST_SEPARATOR, QString::KeepEmptyParts); for(int i=0; i KeyboardConfig::getDefaultLayouts() const { QList defaultLayoutList; int i = 0; foreach(const LayoutUnit& layoutUnit, layouts) { defaultLayoutList.append(layoutUnit); if( layoutLoopCount != KeyboardConfig::NO_LOOPING && i >= layoutLoopCount-1 ) break; i++; } return defaultLayoutList; } QList KeyboardConfig::getExtraLayouts() const { if( layoutLoopCount == KeyboardConfig::NO_LOOPING ) return QList(); return layouts.mid(layoutLoopCount, layouts.size()); } ukui-control-center/plugins/devices/keyboard/preview/keyboardlayout.h0000644000175000017500000000422614201663671025214 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KEYBOARDLAYOUT_NEW_H #define KEYBOARDLAYOUT_NEW_H #include "keyaliases.h" #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(KEYBOARD_PREVIEW) class KbKey { private: QList symbols; int symbolCount; public: QString keyName; KbKey(); void setKeyName(QString n); void addSymbol(QString n, int i); QString getSymbol(int i); int getSymbolCount() { return symbolCount; } void display(); }; class KbLayout { private: QList include; QString name; int keyCount, includeCount, level; bool parsedSymbol; public: QList keyList; QString country; KbLayout(); void setName(QString n); void addInclude(QString n); void addKey(); QString getInclude(int i); int findKey(QString n); void setLevel(int lvl) { level = lvl; } int getLevel() { return level; } int getKeyCount() { return keyCount; } int getIncludeCount() { return includeCount; } QString getLayoutName() const { return name; } void setParsedSymbol(bool state) { parsedSymbol = state; } bool getParsedSymbol() { return parsedSymbol; } void display(); }; #endif //KEYBOARDLAYOUT_NEW_H ukui-control-center/plugins/devices/keyboard/preview/symbol_parser.cpp0000644000175000017500000002123614201663671025372 0ustar fengfeng/* * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "symbol_parser.h" #include "xkb_rules.h" #include #include #include #include #include namespace grammar { symbol_keywords::symbol_keywords() { add("key", 2)("include", 1)("//", 3)("*/", 4); } levels::levels() { add("ONE", 1)("TWO", 2)("THREE", 3)("FOUR", 4)("SIX", 6)("EIGHT", 8); } template SymbolParser::SymbolParser() : SymbolParser::base_type(start) { using qi::lexeme; using qi::char_; using qi::lit; using qi::_1; using qi::_val; using qi::int_; using qi::double_; using qi::eol; newKey = 0; name %= '"' >> +(char_ - '"') >> '"'; group = lit("Group") >> int_; comments = lexeme[lit("//") >> *(char_ - eol || symbolKeyword - eol) >> eol || lit("/*") >> *(char_ - lit("*/") || symbolKeyword - lit("*/")) >> lit("*/")]; include = lit("include") >> name[phx::bind(&SymbolParser::getInclude, this, _1)]; type = lit("type") >> '[' >> group >> lit(']') >> lit('=') >> lit("\"") >> *(char_ - lvl) >> *lvl[phx::bind(&SymbolParser::setLevel, this, _1)] >> *(char_ - lvl - '"') >> lit("\""); symbol = +(char_ - ',' - ']'); symbols = *(lit("symbols") >> '[' >> group >> lit(']') >> lit('=')) >> '[' >> symbol[phx::bind(&SymbolParser::getSymbol, this, _1)] >> *(',' >> symbol[phx::bind(&SymbolParser::getSymbol, this, _1)]) >> ']'; keyName = '<' >> *(char_ - '>') >> '>'; key = (lit("key") >> keyName[phx::bind(&SymbolParser::addKeyName, this, _1)] >> '{' >> *(type >> ',') >> symbols >> *(',' >> type) >> lit("};")) || lit("key") >> lit(".") >> type >> lit(";"); ee = *(char_ - symbolKeyword - '{') >> '{' >> *(char_ - '}' - ';') >> lit("};"); start = *(char_ - lit("xkb_symbols") || comments) >> lit("xkb_symbols") >> name[phx::bind(&SymbolParser::setName, this, _1)] >> '{' >> *(key[phx::bind(&SymbolParser::addKey, this)] || include || ee || char_ - '}' - symbolKeyword || comments) >> lit("};") >> *(comments || char_); } template void SymbolParser::getSymbol(std::string n) { int index = layout.keyList[keyIndex].getSymbolCount(); layout.keyList[keyIndex].addSymbol(QString::fromUtf8(n.data(), n.size()), index); //qCDebug(KEYBOARD_PREVIEW) << "adding symbol: " << QString::fromUtf8(n.data(), n.size()); //qCDebug(KEYBOARD_PREVIEW) << "added symbol: " << layout.keyList[keyIndex].getSymbol(index) << " in " << keyIndex << " at " << index; } template void SymbolParser::addKeyName(std::string n) { QString kname = QString::fromUtf8(n.data(), n.size()); if (kname.startsWith(QLatin1String("Lat"))) { kname = alias.getAlias(layout.country, kname); } keyIndex = layout.findKey(kname); //qCDebug(KEYBOARD_PREVIEW) << layout.getKeyCount(); if (keyIndex == -1) { layout.keyList[layout.getKeyCount()].keyName = kname; keyIndex = layout.getKeyCount(); newKey = 1; } // qCDebug(KEYBOARD_PREVIEW) << "key at" << keyIndex; } template void SymbolParser::addKey() { if (newKey == 1) { layout.addKey(); newKey = 0; //qCDebug(KEYBOARD_PREVIEW) << "new key"; } } template void SymbolParser::getInclude(std::string n) { layout.addInclude(QString::fromUtf8(n.data(), n.size())); } template void SymbolParser::setName(std::string n) { layout.setName(QString::fromUtf8(n.data(), n.size())); //qCDebug(KEYBOARD_PREVIEW) << layout.getLayoutName(); } template void SymbolParser::setLevel(int lvl) { if (lvl > layout.getLevel()) { layout.setLevel(lvl); qCDebug(KEYBOARD_PREVIEW) << lvl; } } QString findSymbolBaseDir() { QString xkbDir = Rules::findXkbDir(); return QStringLiteral("%1/symbols/").arg(xkbDir); } QString findLayout(const QString &layout, const QString &layoutVariant) { QString symbolBaseDir = findSymbolBaseDir(); QString symbolFile = symbolBaseDir.append(layout); QFile sfile(symbolFile); if (!sfile.open(QIODevice::ReadOnly | QIODevice::Text)) { //qCDebug(KEYBOARD_PREVIEW) << "unable to open the file"; return QStringLiteral("I/O ERROR"); } QString scontent = sfile.readAll(); sfile.close(); QStringList scontentList = scontent.split(QStringLiteral("xkb_symbols")); QString variant; QString input; if (layoutVariant.isEmpty()) { input = scontentList.at(1); input.prepend("xkb_symbols"); } else { int current = 1; while (layoutVariant != variant && current < scontentList.size()) { input = scontentList.at(current); QString symbolCont = scontentList.at(current); int index = symbolCont.indexOf(QStringLiteral("\"")); symbolCont = symbolCont.mid(index); index = symbolCont.indexOf(QStringLiteral("{")); symbolCont = symbolCont.left(index); symbolCont = symbolCont.remove(QStringLiteral(" ")); variant = symbolCont.remove(QStringLiteral("\"")); input.prepend("xkb_symbols"); current++; } } return input; } KbLayout parseSymbols(const QString &layout, const QString &layoutVariant) { using boost::spirit::iso8859_1::space; typedef std::string::const_iterator iterator_type; typedef grammar::SymbolParser SymbolParser; SymbolParser symbolParser; symbolParser.layout.country = layout; QString input = findLayout(layout, layoutVariant); if (input == QLatin1String("I/O ERROR")) { symbolParser.layout.setParsedSymbol(false); return symbolParser.layout; } std::string parserInput = input.toUtf8().constData(); std::string::const_iterator iter = parserInput.begin(); std::string::const_iterator end = parserInput.end(); bool success = phrase_parse(iter, end, symbolParser, space); if (success && iter == end) { qCDebug(KEYBOARD_PREVIEW) << "Symbols Parsing succeeded"; symbolParser.layout.setParsedSymbol(true); } else { qWarning() << "Symbols Parsing failed\n" << input; symbolParser.layout.setParsedSymbol(false); } for (int currentInclude = 0; currentInclude < symbolParser.layout.getIncludeCount(); currentInclude++) { QString include = symbolParser.layout.getInclude(currentInclude); QStringList includeFile = include.split(QStringLiteral("(")); if (includeFile.size() == 2) { QString file = includeFile.at(0); QString layout = includeFile.at(1); layout.remove(QStringLiteral(")")); input = findLayout(file, layout); } else { QString a; a.clear(); input = findLayout(includeFile.at(0), a); } parserInput = input.toUtf8().constData(); std::string::const_iterator iter = parserInput.begin(); std::string::const_iterator end = parserInput.end(); success = phrase_parse(iter, end, symbolParser, space); if (success && iter == end) { qCDebug(KEYBOARD_PREVIEW) << "Symbols Parsing succeeded"; symbolParser.layout.setParsedSymbol(true); } else { qCDebug(KEYBOARD_PREVIEW) << "Symbols Parsing failed\n"; qCDebug(KEYBOARD_PREVIEW) << input; symbolParser.layout.setParsedSymbol(false); } } //s.layout.display(); if (symbolParser.layout.getParsedSymbol()) { return symbolParser.layout; } else { return parseSymbols(QStringLiteral("us"), QStringLiteral("basic")); } } } ukui-control-center/plugins/devices/keyboard/preview/kbpreviewframe.h0000644000175000017500000000446614201663671025175 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KBPREVIEWFRAME_H #define KBPREVIEWFRAME_H #include "keyboardlayout.h" #include "keysymhelper.h" #include "keyaliases.h" #include #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(KEYBOARD_PREVIEW) class Geometry; class GShape; class KbPreviewFrame : public QFrame { Q_OBJECT private: static const int width = 1100, height = 490; KeySymHelper symbol; Aliases alias; QStringList tooltip; QList tipPoint; int l_id; Geometry &geometry; float scaleFactor; KbLayout keyboardLayout; void drawKeySymbols(QPainter &painter, QPoint temp[], const GShape &s, const QString &name); void drawShape(QPainter &painter, const GShape &s, int x, int y, int i, const QString &name); int itemAt(const QPoint &pos); protected: bool event(QEvent *event) override; public: explicit KbPreviewFrame(QWidget *parent = nullptr); ~KbPreviewFrame() override; void paintEvent(QPaintEvent *event) override; void generateKeyboardLayout(const QString &layout, const QString &layoutVariant, const QString &model); int getWidth() const; int getHeight() const; int getLevel() { return keyboardLayout.getLevel(); } void setL_id(int lId) { l_id = lId; repaint(); } QString getLayoutName() const { return keyboardLayout.getLayoutName(); } float getScaleFactor() { return scaleFactor; } }; #endif // KBPREVIEWFRAME_H ukui-control-center/plugins/devices/keyboard/preview/keyboardpainter.cpp0000644000175000017500000000601414201663671025671 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "keyboardpainter.h" #include "geometry_components.h" #include #include #include #include KeyboardPainter::KeyboardPainter(): kbDialog(new QDialog(this)), kbframe(new KbPreviewFrame(this)), exitButton(new QPushButton(tr("Close"), this)), levelBox(new QComboBox(this)) { this->setFixedSize(1250, 600); kbframe->setFixedSize(1100, 490); exitButton->setFixedSize(120, 30); levelBox->setFixedSize(360, 30); QVBoxLayout *vLayout = new QVBoxLayout(this); QHBoxLayout *hLayout = new QHBoxLayout(); hLayout->addWidget(exitButton, 0, Qt::AlignLeft); hLayout->addWidget(levelBox, 0, Qt::AlignRight); hLayout->addSpacing(30); vLayout->addWidget(kbframe); vLayout->addLayout(hLayout); connect(exitButton, &QPushButton::clicked, this, &KeyboardPainter::close); connect(levelBox, SIGNAL(activated(int)), this, SLOT(levelChanged(int))); setWindowTitle(kbframe->getLayoutName()); levelBox->setVisible(false); } void KeyboardPainter::generateKeyboardLayout(const QString &layout, const QString &variant, const QString &model, const QString &title) { kbframe->generateKeyboardLayout(layout, variant, model); kbframe->setFixedSize(getWidth(), getHeight()); kbDialog->setFixedSize(getWidth(), getWidth()); setWindowTitle(title); int level = kbframe->getLevel(); if (level > 4) { levelBox->addItem(tr("Keyboard layout levels"), (tr("Level %1, %2").arg(3, 4))); for (int i = 5; i <= level; i += 2) { levelBox->addItem(tr("Keyboard layout levels"), (tr("Level %1, %2").arg(i, i + 1))); } } else { levelBox->setVisible(false); } } void KeyboardPainter::levelChanged(int l_id) { kbframe->setL_id(l_id); } int KeyboardPainter::getHeight() { int height = kbframe->getHeight(); height = kbframe->getScaleFactor() * height + 50; return height; } int KeyboardPainter::getWidth() { int width = kbframe->getWidth(); width = kbframe->getScaleFactor() * width + 20; return width; } KeyboardPainter::~KeyboardPainter() { delete kbframe; kbframe = nullptr; delete exitButton; exitButton = nullptr; delete levelBox; levelBox = nullptr; } ukui-control-center/plugins/devices/keyboard/preview/keysym2ucs.cpp0000644000175000017500000021272414201663671024633 0ustar fengfeng/* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $XFree86$ * This module converts keysym values into the corresponding ISO 10646-1 * (UCS, Unicode) values. * * The array keysymtab[] contains pairs of X11 keysym values for graphical * characters and the corresponding Unicode value. The function * keysym2ucs() maps a keysym onto a Unicode value using a binary search, * therefore keysymtab[] must remain SORTED by keysym value. * * The keysym -> UTF-8 conversion will hopefully one day be provided * by Xlib via XmbLookupString() and should ideally not have to be * done in X applications. But we are not there yet. * * We allow to represent any UCS character in the range U+00000000 to * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. * This admittedly does not cover the entire 31-bit space of UCS, but * it does cover all of the characters up to U+10FFFF, which can be * represented by UTF-16, and more, and it is very unlikely that higher * UCS codes will ever be assigned by ISO. So to get Unicode character * U+ABCD you can directly use keysym 0x1000abcd. * * NOTE: The comments in the table below contain the actual character * encoded in UTF-8, so for viewing and editing best use an editor in * UTF-8 mode. * * Author: Markus G. Kuhn , University of Cambridge, June 1999 * * Special thanks to Richard Verhoeven for preparing * an initial draft of the mapping table. */ #include "keysym2ucs.h" struct codepair { unsigned short keysym; unsigned short ucs; } keysymtab[] = { { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */ { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ { 0x08a1, 0x23b7 }, /* leftradical ⎷ RADICAL SYMBOL BOTTOM */ { 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ { 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ { 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ LEFT SQUARE BRACKET UPPER CORNER */ { 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ LEFT SQUARE BRACKET LOWER CORNER */ { 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ RIGHT SQUARE BRACKET UPPER CORNER */ { 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ RIGHT SQUARE BRACKET LOWER CORNER */ { 0x08ab, 0x239b }, /* topleftparens ⎛ LEFT PARENTHESIS UPPER HOOK */ { 0x08ac, 0x239d }, /* botleftparens ⎝ LEFT PARENTHESIS LOWER HOOK */ { 0x08ad, 0x239e }, /* toprightparens ⎞ RIGHT PARENTHESIS UPPER HOOK */ { 0x08ae, 0x23a0 }, /* botrightparens ⎠ RIGHT PARENTHESIS LOWER HOOK */ { 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ LEFT CURLY BRACKET MIDDLE PIECE */ { 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ RIGHT CURLY BRACKET MIDDLE PIECE */ /* 0x08b1 topleftsummation ? ??? */ /* 0x08b2 botleftsummation ? ??? */ /* 0x08b3 topvertsummationconnector ? ??? */ /* 0x08b4 botvertsummationconnector ? ??? */ /* 0x08b5 toprightsummation ? ??? */ /* 0x08b6 botrightsummation ? ??? */ /* 0x08b7 rightmiddlesummation ? ??? */ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ { 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */ { 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ { 0x08dd, 0x222a }, /* union ∪ UNION */ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ { 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 */ { 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 */ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ { 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 */ { 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 */ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ { 0x0aaa, 0x2013 }, /* endash – EN DASH */ { 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ { 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */ { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ /* 0x0abf marker ? ??? */ { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ /* 0x0acb trademarkincircle ? ??? */ { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ { 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ /* 0x0ad5 permille ? ??? */ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ /* 0x0ada hexagram ? ??? */ { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ { 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */ { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ { 0x0af1, 0x2020 }, /* dagger † DAGGER */ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ { 0x0afc, 0x2038 }, /* caret ‸ CARET */ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ /* 0x0aff cursor ? ??? */ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ { 0x0bc2, 0x22a5 }, /* downtack ⊥ UP TACK */ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ { 0x0bce, 0x22a4 }, /* uptack ⊤ DOWN TACK */ { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ { 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */ { 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ { 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ { 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ { 0x13a4, 0x20ac }, /* Euro € EURO SIGN */ { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ /* Combining symbols */ { 0xfe50, 0x0300 }, /* dead_grave */ { 0xfe51, 0x0301 }, /* dead_acute" */ { 0xfe52, 0x0302 }, /* dead_circumflex" */ { 0xfe53, 0x0303 }, /* dead_tilde" */ { 0xfe54, 0x0304 }, /* dead_macron" */ { 0xfe55, 0x0306 }, /* dead_breve" */ { 0xfe56, 0x0307 }, /* dead_abovedot" */ { 0xfe57, 0x0308 }, /* dead_diaeresis" */ { 0xfe58, 0x030A }, /* dead_abovering" */ { 0xfe59, 0x030B }, /* dead_doubleacute" */ { 0xfe5a, 0x030C }, /* dead_caron" */ { 0xfe5b, 0x0327 }, /* dead_cedilla" */ { 0xfe5c, 0x0328 }, /* dead_ogonek" */ { 0xfe60, 0x0323 }, /* dead_belowdot */ /* Special function keys. */ { 0xff08, 0x0008 }, /* XK_BackSpace */ { 0xff09, 0x0009 }, /* XK_Tab */ { 0xff0a, 0x000a }, /* XK_Linefeed */ { 0xff0d, 0x000d }, /* XK_Return */ { 0xff13, 0x0013 }, /* XK_Pause */ { 0xff1b, 0x001b }, /* XK_Escape */ { 0xff50, 0x0001 }, /* XK_Home */ { 0xff51, 0x001c }, /* XK_Left */ { 0xff52, 0x001e }, /* XK_Up */ { 0xff53, 0x001d }, /* XK_Right */ { 0xff54, 0x001f }, /* XK_Down */ { 0xff55, 0x000b }, /* XK_Prior */ { 0xff56, 0x000c }, /* XK_Next */ { 0xff57, 0x0004 }, /* XK_End */ { 0xff6a, 0x0005 }, /* XK_Help */ { 0xffff, 0x007f }, /* XK_Delete */ }; long keysym2ucs(KeySym keysym) { int min = 0; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; int mid; /* first check for Latin-1 characters (1:1 mapping) */ if ((keysym >= 0x0020 && keysym <= 0x007e) || (keysym >= 0x00a0 && keysym <= 0x00ff)) { return keysym; } /* also check for directly encoded 24-bit UCS characters */ if ((keysym & 0xff000000) == 0x01000000) { return keysym & 0x00ffffff; } /* binary search in table */ while (max >= min) { mid = (min + max) / 2; if (keysymtab[mid].keysym < keysym) { min = mid + 1; } else if (keysymtab[mid].keysym > keysym) { max = mid - 1; } else { /* found it */ return keysymtab[mid].ucs; } } /* no matching Unicode value found */ return -1; } ukui-control-center/plugins/devices/keyboard/preview/x11_helper.cpp0000644000175000017500000003420514201663671024461 0ustar fengfeng/* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "x11_helper.h" #include "debug.h" #define explicit explicit_is_keyword_in_cpp #include #undef explicit #include #include #include #include #include #include #include #include #include #include // more information about the limit https://bugs.freedesktop.org/show_bug.cgi?id=19501 const int X11Helper::MAX_GROUP_COUNT = 4; const int X11Helper::ARTIFICIAL_GROUP_LIMIT_COUNT = 8; const char X11Helper::LEFT_VARIANT_STR[] = "("; const char X11Helper::RIGHT_VARIANT_STR[] = ")"; bool X11Helper::xkbSupported(int* xkbOpcode) { if (!QX11Info::isPlatformX11()) { return false; } // Verify the Xlib has matching XKB extension. int major = XkbMajorVersion; int minor = XkbMinorVersion; if (!XkbLibraryVersion(&major, &minor)) { qCWarning(KCM_KEYBOARD) << "Xlib XKB extension " << major << '.' << minor << " != " << XkbMajorVersion << '.' << XkbMinorVersion; return false; } // Verify the X server has matching XKB extension. int opcode_rtrn; int error_rtrn; int xkb_opcode; if( ! XkbQueryExtension(QX11Info::display(), &opcode_rtrn, &xkb_opcode, &error_rtrn, &major, &minor)) { qCWarning(KCM_KEYBOARD) << "X server XKB extension " << major << '.' << minor << " != " << XkbMajorVersion << '.' << XkbMinorVersion; return false; } if( xkbOpcode != nullptr ) { *xkbOpcode = xkb_opcode; } return true; } void X11Helper::switchToNextLayout() { int size = getLayoutsList().size(); //TODO: could optimize a bit as we don't need the layouts - just count int group = (X11Helper::getGroup() + 1) % size; X11Helper::setGroup(group); } void X11Helper::scrollLayouts(int delta) { int size = getLayoutsList().size(); //TODO: could optimize a bit as we don't need the layouts - just count int group = X11Helper::getGroup() + delta; group = group < 0 ? size - ((-group) % size) : group % size; X11Helper::setGroup(group); } QStringList X11Helper::getLayoutsListAsString(const QList& layoutsList) { QStringList stringList; foreach(const LayoutUnit& layoutUnit, layoutsList) { stringList << layoutUnit.toString(); } return stringList; } bool X11Helper::setLayout(const LayoutUnit& layout) { QList currentLayouts = getLayoutsList(); int idx = currentLayouts.indexOf(layout); if( idx == -1 || idx >= X11Helper::MAX_GROUP_COUNT ) { qCWarning(KCM_KEYBOARD) << "Layout" << layout.toString() << "is not found in current layout list" << getLayoutsListAsString(currentLayouts); return false; } return X11Helper::setGroup((unsigned int)idx); } bool X11Helper::setDefaultLayout() { return X11Helper::setGroup(0); } bool X11Helper::isDefaultLayout() { return X11Helper::getGroup() == 0; } LayoutUnit X11Helper::getCurrentLayout() { if (!QX11Info::isPlatformX11()) { return LayoutUnit(); } QList currentLayouts = getLayoutsList(); unsigned int group = X11Helper::getGroup(); if( group < (unsigned int)currentLayouts.size() ) return currentLayouts[group]; qCWarning(KCM_KEYBOARD) << "Current group number" << group << "is outside of current layout list" << getLayoutsListAsString(currentLayouts); return LayoutUnit(); } LayoutSet X11Helper::getCurrentLayouts() { LayoutSet layoutSet; QList currentLayouts = getLayoutsList(); layoutSet.layouts = currentLayouts; unsigned int group = X11Helper::getGroup(); if( group < (unsigned int)currentLayouts.size() ) { layoutSet.currentLayout = currentLayouts[group]; } else { qCWarning(KCM_KEYBOARD) << "Current group number" << group << "is outside of current layout list" << getLayoutsListAsString(currentLayouts); layoutSet.currentLayout = LayoutUnit(); } return layoutSet; } //static QString addNum(const QString& str, int n) //{ // QString format("%1%2"); // if( str.length() >= 3 ) return format.arg(str.left(2)).arg(n); // return format.arg(str).arg(n); //} QList X11Helper::getLayoutsList() { if (!QX11Info::isPlatformX11()) { return QList(); } XkbConfig xkbConfig; QList layouts; if( X11Helper::getGroupNames(QX11Info::display(), &xkbConfig, X11Helper::LAYOUTS_ONLY) ) { for(int i=0; i" << endl; // qCDebug(KCM_KEYBOARD) << group; // xcb_void_cookie_t cookie; // cookie = xcb_xkb_latch_lock_state(QX11Info::connection(), // XCB_XKB_ID_USE_CORE_KBD, // 0, 0, // 1, // group, // 0, 0, 0 // ); // xcb_generic_error_t *error = nullptr; // error = xcb_request_check(QX11Info::connection(), cookie); // if (error) { // qCDebug(KCM_KEYBOARD) << "Couldn't change the group" << error->error_code; // return false; // } return true; } unsigned int X11Helper::getGroup() { XkbStateRec xkbState; XkbGetState( QX11Info::display(), XkbUseCoreKbd, &xkbState ); return xkbState.group; } bool X11Helper::getGroupNames(Display* display, XkbConfig* xkbConfig, FetchType fetchType) { static const char OPTIONS_SEPARATOR[] = ","; Atom real_prop_type; int fmt; unsigned long nitems, extra_bytes; char *prop_data = nullptr; Status ret; Atom rules_atom = XInternAtom(display, _XKB_RF_NAMES_PROP_ATOM, False); /* no such atom! */ if (rules_atom == None) { /* property cannot exist */ qCWarning(KCM_KEYBOARD) << "Failed to fetch layouts from server:" << "could not find the atom" << _XKB_RF_NAMES_PROP_ATOM; return false; } ret = XGetWindowProperty(display, DefaultRootWindow(display), rules_atom, 0L, _XKB_RF_NAMES_PROP_MAXLEN, False, XA_STRING, &real_prop_type, &fmt, &nitems, &extra_bytes, (unsigned char **) (void *) &prop_data); /* property not found! */ if (ret != Success) { qCWarning(KCM_KEYBOARD) << "Failed to fetch layouts from server:" << "Could not get the property"; return false; } /* has to be array of strings */ if ((extra_bytes > 0) || (real_prop_type != XA_STRING) || (fmt != 8)) { if (prop_data) XFree(prop_data); qCWarning(KCM_KEYBOARD) << "Failed to fetch layouts from server:" << "Wrong property format"; return false; } // qCDebug(KCM_KEYBOARD) << "prop_data:" << nitems << prop_data; QStringList names; for(char* p=prop_data; p-prop_data < (long)nitems && p != nullptr; p += strlen(p)+1) { names.append( p ); // qDebug() << " " << p; } if( names.count() < 4 ) { //{ rules, model, layouts, variants, options } XFree(prop_data); return false; } if( fetchType == ALL || fetchType == LAYOUTS_ONLY ) { QStringList layouts = names[2].split(OPTIONS_SEPARATOR); QStringList variants = names[3].split(OPTIONS_SEPARATOR); for(int ii=0; iilayouts << (layouts[ii] != nullptr ? layouts[ii] : QLatin1String("")); xkbConfig->variants << (ii < variants.count() && variants[ii] != nullptr ? variants[ii] : QLatin1String("")); } qCDebug(KCM_KEYBOARD) << "Fetched layout groups from X server:" << "\tlayouts:" << xkbConfig->layouts << "\tvariants:" << xkbConfig->variants; } if( fetchType == ALL || fetchType == MODEL_ONLY ) { xkbConfig->keyboardModel = (names[1] != nullptr ? names[1] : QLatin1String("")); qCDebug(KCM_KEYBOARD) << "Fetched keyboard model from X server:" << xkbConfig->keyboardModel; } if( fetchType == ALL ) { if( names.count() >= 5 ) { QString options = (names[4] != nullptr ? names[4] : QLatin1String("")); xkbConfig->options = options.split(OPTIONS_SEPARATOR); qCDebug(KCM_KEYBOARD) << "Fetched xkbOptions from X server:" << options; } } XFree(prop_data); return true; } XEventNotifier::XEventNotifier(): xkbOpcode(-1) { if( QCoreApplication::instance() == nullptr ) { qCWarning(KCM_KEYBOARD) << "Layout Widget won't work properly without QCoreApplication instance"; } } void XEventNotifier::start() { qCDebug(KCM_KEYBOARD) << "qCoreApp" << QCoreApplication::instance(); if( QCoreApplication::instance() != nullptr && X11Helper::xkbSupported(&xkbOpcode) ) { registerForXkbEvents(QX11Info::display()); // start the event loop QCoreApplication::instance()->installNativeEventFilter(this); } } void XEventNotifier::stop() { if( QCoreApplication::instance() != nullptr ) { //TODO: unregister // XEventNotifier::unregisterForXkbEvents(QX11Info::display()); // stop the event loop QCoreApplication::instance()->removeNativeEventFilter(this); } } bool XEventNotifier::isXkbEvent(xcb_generic_event_t* event) { // qDebug() << "event response type:" << (event->response_type & ~0x80) << xkbOpcode << ((event->response_type & ~0x80) == xkbOpcode + XkbEventCode); return (event->response_type & ~0x80) == xkbOpcode + XkbEventCode; } bool XEventNotifier::processOtherEvents(xcb_generic_event_t* /*event*/) { return true; } bool XEventNotifier::processXkbEvents(xcb_generic_event_t* event) { _xkb_event *xkbevt = reinterpret_cast<_xkb_event *>(event); if( XEventNotifier::isGroupSwitchEvent(xkbevt) ) { // qDebug() << "group switch event"; emit(layoutChanged()); } else if( XEventNotifier::isLayoutSwitchEvent(xkbevt) ) { // qDebug() << "layout switch event"; emit(layoutMapChanged()); } return true; } bool XEventNotifier::nativeEventFilter(const QByteArray &eventType, void *message, long *) { // qDebug() << "event type:" << eventType; if (eventType == "xcb_generic_event_t") { xcb_generic_event_t* ev = static_cast(message); if( isXkbEvent(ev) ) { processXkbEvents(ev); } else { processOtherEvents(ev); } } return false; } //bool XEventNotifier::x11Event(XEvent * event) //{ // // qApp->x11ProcessEvent ( event ); // if( isXkbEvent(event) ) { // processXkbEvents(event); // } // else { // processOtherEvents(event); // } // return QWidget::x11Event(event); //} bool XEventNotifier::isGroupSwitchEvent(_xkb_event* xkbEvent) { // XkbEvent *xkbEvent = (XkbEvent*) event; #define GROUP_CHANGE_MASK \ ( XkbGroupStateMask | XkbGroupBaseMask | XkbGroupLatchMask | XkbGroupLockMask ) return xkbEvent->any.xkbType == XkbStateNotify && (xkbEvent->state_notify.changed & GROUP_CHANGE_MASK); } bool XEventNotifier::isLayoutSwitchEvent(_xkb_event* xkbEvent) { // XkbEvent *xkbEvent = (XkbEvent*) event; return //( (xkbEvent->any.xkb_type == XkbMapNotify) && (xkbEvent->map.changed & XkbKeySymsMask) ) || /* || ( (xkbEvent->any.xkb_type == XkbNamesNotify) && (xkbEvent->names.changed & XkbGroupNamesMask) || )*/ (xkbEvent->any.xkbType == XkbNewKeyboardNotify); } int XEventNotifier::registerForXkbEvents(Display* display) { int eventMask = XkbNewKeyboardNotifyMask | XkbStateNotifyMask; if( ! XkbSelectEvents(display, XkbUseCoreKbd, eventMask, eventMask) ) { qCWarning(KCM_KEYBOARD) << "Couldn't select desired XKB events"; return false; } return true; } static const char LAYOUT_VARIANT_SEPARATOR_PREFIX[] = "("; static const char LAYOUT_VARIANT_SEPARATOR_SUFFIX[] = ")"; static QString& stripVariantName(QString& variant) { if( variant.endsWith(LAYOUT_VARIANT_SEPARATOR_SUFFIX) ) { int suffixLen = strlen(LAYOUT_VARIANT_SEPARATOR_SUFFIX); return variant.remove(variant.length()-suffixLen, suffixLen); } return variant; } LayoutUnit::LayoutUnit(const QString& fullLayoutName) { QStringList lv = fullLayoutName.split(LAYOUT_VARIANT_SEPARATOR_PREFIX); layout = lv[0]; variant = lv.size() > 1 ? stripVariantName(lv[1]) : QLatin1String(""); } QString LayoutUnit::toString() const { if( variant.isEmpty() ) return layout; return layout + LAYOUT_VARIANT_SEPARATOR_PREFIX+variant+LAYOUT_VARIANT_SEPARATOR_SUFFIX; } const int LayoutUnit::MAX_LABEL_LENGTH = 3; ukui-control-center/plugins/devices/keyboard/preview/geometry_parser.cpp0000644000175000017500000004711414201663671025723 0ustar fengfeng/* * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "geometry_parser.h" #include "geometry_components.h" #include "xkb_rules.h" #include #include #include #include #include #include #include "config-workspace.h" namespace grammar { keywords::keywords() { add ("shape", 1) ("height", 2) ("width", 3) ("description", 4) ("keys", 5) ("row", 6) ("section", 7) ("key", 8) ("//", 9) ("/*", 10) ; } template GeometryParser::GeometryParser(): GeometryParser::base_type(start) { using qi::lexeme; using qi::char_; using qi::lit; using qi::_1; using qi::_val; using qi::int_; using qi::double_; using qi::eol; name = '"' >> +(char_ - '"') >> '"'; ignore = (lit("outline") || lit("overlay") || lit("text")) >> *(char_ - lit("};")) >> lit("};") || lit("solid") >> *(char_ - lit("};")) >> lit("};") || lit("indicator") >> *(char_ - ';' - '{') >> ';' || '{' >> *(char_ - lit("};")) >> lit("};") || lit("indicator") >> '.' >> lit("shape") >> '=' >> name >> ';'; comments = lexeme[ lit("//") >> *(char_ - eol || keyword - eol) >> eol || lit("/*") >> *(char_ - lit("*/") || keyword - lit("*/")) >> lit("*/") ]; cordinates = ('[' >> double_[phx::ref(shapeLenX) = _1] >> ',' >> double_[phx::ref(shapeLenY) = _1] >> ']') || '[' >> double_ >> "," >> double_ >> ']' ; cordinatea = '[' >> double_[phx::ref(approxLenX) = _1] >> "," >> double_[phx::ref(approxLenY) = _1] >> ']'; set = '{' >> cordinates >> *(',' >> cordinates) >> '}'; setap = '{' >> cordinatea >> *(',' >> cordinatea) >> '}'; seta = '{' >> cordinates[phx::bind(&GeometryParser::setCord, this)] >> *(',' >> cordinates[phx::bind(&GeometryParser::setCord, this)]) >> '}' ; description = lit("description") >> '=' >> name[phx::bind(&GeometryParser::getDescription, this, _1)] >> ';'; cornerRadius = (lit("cornerRadius") || lit("corner")) >> '=' >> double_; shapeDef = lit("shape") >> name[phx::bind(&GeometryParser::getShapeName, this, _1)] >> '{' >> *(lit("approx") >> '=' >> setap[phx::bind(&GeometryParser::setApprox, this)] >> ',' || cornerRadius >> ',' || comments) >> seta >> *((',' >> (set || lit("approx") >> '=' >> setap[phx::bind(&GeometryParser::setApprox, this)] || cornerRadius) || comments)) >> lit("};") ; keyName = '<' >> +(char_ - '>') >> '>'; keyShape = *(lit("key.")) >> lit("shape") >> '=' >> name[phx::bind(&GeometryParser::setKeyShape, this, _1)] || name[phx::bind(&GeometryParser::setKeyShape, this, _1)]; keyColor = lit("color") >> '=' >> name; keygap = lit("gap") >> '=' >> double_[phx::ref(KeyOffset) = _1] || double_[phx::ref(KeyOffset) = _1]; keyDesc = keyName[phx::bind(&GeometryParser::setKeyNameandShape, this, _1)] || '{' >> (keyName[phx::bind(&GeometryParser::setKeyNameandShape, this, _1)] || keyShape || keygap[phx::bind(&GeometryParser::setKeyOffset, this)] || keyColor) >> *((',' >> (keyName || keyShape || keygap[phx::bind(&GeometryParser::setKeyOffset, this)] || keyColor)) || comments) >> '}'; keys = lit("keys") >> '{' >> keyDesc[phx::bind(&GeometryParser::setKeyCordi, this)] >> *((*lit(',') >> keyDesc[phx::bind(&GeometryParser::setKeyCordi, this)] >> *lit(',')) || comments) >> lit("};"); geomShape = ((lit("key.shape") >> '=' >> name[phx::bind(&GeometryParser::setGeomShape, this, _1)]) || (lit("key.color") >> '=' >> name)) >> ';'; geomLeft = lit("section.left") >> '=' >> double_[phx::ref(geom.sectionLeft) = _1] >> ';'; geomTop = lit("section.top") >> '=' >> double_[phx::ref(geom.sectionTop) = _1] >> ';'; geomRowTop = lit("row.top") >> '=' >> double_[phx::ref(geom.rowTop) = _1] >> ';'; geomRowLeft = lit("row.left") >> '=' >> double_[phx::ref(geom.rowLeft) = _1] >> ';'; geomGap = lit("key.gap") >> '=' >> double_[phx::ref(geom.keyGap) = _1] >> ';'; geomVertical = *lit("row.") >> lit("vertical") >> '=' >> (lit("True") || lit("true")) >> ';'; geomAtt = geomLeft || geomTop || geomRowTop || geomRowLeft || geomGap; top = lit("top") >> '=' >> double_ >> ';'; left = lit("left") >> '=' >> double_ >> ';'; row = lit("row")[phx::bind(&GeometryParser::rowinit, this)] >> '{' >> *(top[phx::bind(&GeometryParser::setRowTop, this, _1)] || left[phx::bind(&GeometryParser::setRowLeft, this, _1)] || localShape[phx::bind(&GeometryParser::setRowShape, this, _1)] || localColor || comments || geomVertical[phx::bind(&GeometryParser::setVerticalRow, this)] || keys ) >> lit("};") || ignore || geomVertical[phx::bind(&GeometryParser::setVerticalSection, this)]; angle = lit("angle") >> '=' >> double_ >> ';'; localShape = lit("key.shape") >> '=' >> name[_val = _1] >> ';'; localColor = lit("key.color") >> '=' >> name >> ';'; localDimension = (lit("height") || lit("width")) >> '=' >> double_ >> ';'; priority = lit("priority") >> '=' >> double_ >> ';'; section = lit("section")[phx::bind(&GeometryParser::sectioninit, this)] >> name[phx::bind(&GeometryParser::sectionName, this, _1)] >> '{' >> *(top[phx::bind(&GeometryParser::setSectionTop, this, _1)] || left[phx::bind(&GeometryParser::setSectionLeft, this, _1)] || angle[phx::bind(&GeometryParser::setSectionAngle, this, _1)] || row[phx::bind(&GeometryParser::addRow, this)] || localShape[phx::bind(&GeometryParser::setSectionShape, this, _1)] || geomAtt || localColor || localDimension || priority || comments) >> lit("};") || geomVertical[phx::bind(&GeometryParser::setVerticalGeometry, this)]; shapeC = lit("shape") >> '.' >> cornerRadius >> ';'; shape = shapeDef || shapeC; input = '{' >> +(width || height || comments || ignore || description || (char_ - keyword - '}' || shape[phx::bind(&Geometry::addShape, &geom)] || section[phx::bind(&Geometry::addSection, &geom)] || geomAtt || geomShape )) >> '}'; width = lit("width") >> '=' >> double_[phx::bind(&Geometry::setWidth, &geom, _1)] >> ";"; height = lit("height") >> '=' >> double_[phx::bind(&Geometry::setHeight, &geom, _1)] >> ";"; start %= *(lit("default")) >> lit("xkb_geometry") >> name[phx::bind(&GeometryParser::getName, this, _1)] >> input >> ';' >> *(comments || char_ - lit("xkb_geometry")); } template void GeometryParser::setCord() { geom.setShapeCord(shapeLenX, shapeLenY); } template void GeometryParser::setSectionShape(std::string n) { geom.sectionList[geom.getSectionCount()].setShapeName(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::getName(std::string n) { geom.setName(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::getDescription(std::string n) { geom.setDescription(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::getShapeName(std::string n) { geom.setShapeName(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::setGeomShape(std::string n) { geom.setKeyShape(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::setRowShape(std::string n) { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); geom.sectionList[secn].rowList[rown].setShapeName(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::setApprox() { geom.setShapeApprox(approxLenX, approxLenY); } template void GeometryParser::addRow() { geom.sectionList[geom.getSectionCount()].addRow(); } template void GeometryParser::sectionName(std::string n) { geom.sectionList[geom.getSectionCount()].setName(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::rowinit() { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); double tempTop = geom.sectionList[secn].getTop(); QString tempShape = geom.sectionList[secn].getShapeName(); geom.sectionList[secn].rowList[rown].setTop(tempTop); geom.sectionList[secn].rowList[rown].setLeft(geom.sectionList[secn].getLeft()); geom.sectionList[secn].rowList[rown].setShapeName(tempShape); keyCordiX = geom.sectionList[secn].rowList[rown].getLeft(); keyCordiY = geom.sectionList[secn].rowList[rown].getTop(); tempTop = geom.sectionList[secn].getVertical(); geom.sectionList[secn].rowList[rown].setVertical(tempTop); } template void GeometryParser::sectioninit() { int secn = geom.getSectionCount(); geom.sectionList[secn].setTop(geom.sectionTop); geom.sectionList[secn].setLeft(geom.sectionLeft); keyCordiX = geom.sectionList[secn].getLeft(); keyCordiY = geom.sectionList[secn].getTop(); geom.sectionList[secn].setShapeName(geom.getKeyShape()); geom.sectionList[secn].setVertical(geom.getVertical()); } template void GeometryParser::setRowTop(double a) { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); double tempTop = geom.sectionList[secn].getTop(); geom.sectionList[secn].rowList[rown].setTop(a + tempTop); keyCordiY = geom.sectionList[secn].rowList[rown].getTop(); } template void GeometryParser::setRowLeft(double a) { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); double tempLeft = geom.sectionList[secn].getLeft(); geom.sectionList[secn].rowList[rown].setLeft(a + tempLeft); keyCordiX = geom.sectionList[secn].rowList[rown].getLeft(); } template void GeometryParser::setSectionTop(double a) { //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount" << geom.sectionCount; int secn = geom.getSectionCount(); geom.sectionList[secn].setTop(a + geom.sectionTop); keyCordiY = geom.sectionList[secn].getTop(); } template void GeometryParser::setSectionLeft(double a) { //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount" << geom.sectionCount; int secn = geom.getSectionCount(); geom.sectionList[secn].setLeft(a + geom.sectionLeft); keyCordiX = geom.sectionList[secn].getLeft(); } template void GeometryParser::setSectionAngle(double a) { //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount" << geom.sectionCount; int secn = geom.getSectionCount(); geom.sectionList[secn].setAngle(a); } template void GeometryParser::setVerticalRow() { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); geom.sectionList[secn].rowList[rown].setVertical(1); } template void GeometryParser::setVerticalSection() { int secn = geom.getSectionCount(); geom.sectionList[secn].setVertical(1); } template void GeometryParser::setVerticalGeometry() { geom.setVertical(1); } template void GeometryParser::setKeyName(std::string n) { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); //qCDebug(KEYBOARD_PREVIEW) << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn; geom.sectionList[secn].rowList[rown].keyList[keyn].setKeyName(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::setKeyShape(std::string n) { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); //qCDebug(KEYBOARD_PREVIEW) << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn; geom.sectionList[secn].rowList[rown].keyList[keyn].setShapeName(QString::fromUtf8(n.data(), n.size())); } template void GeometryParser::setKeyNameandShape(std::string n) { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); setKeyName(n); setKeyShape(geom.sectionList[secn].rowList[rown].getShapeName().toUtf8().constData()); } template void GeometryParser::setKeyOffset() { //qCDebug(KEYBOARD_PREVIEW) << "\nhere\n"; int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); //qCDebug(KEYBOARD_PREVIEW) << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn; geom.sectionList[secn].rowList[rown].keyList[keyn].setOffset(KeyOffset); } template void GeometryParser::setKeyCordi() { int secn = geom.getSectionCount(); int rown = geom.sectionList[secn].getRowCount(); int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); int vertical = geom.sectionList[secn].rowList[rown].getVertical(); Key key = geom.sectionList[secn].rowList[rown].keyList[keyn]; if (vertical == 0) { keyCordiX += key.getOffset(); } else { keyCordiY += key.getOffset(); } geom.sectionList[secn].rowList[rown].keyList[keyn].setKeyPosition(keyCordiX, keyCordiY); QString shapeStr = key.getShapeName(); if (shapeStr.isEmpty()) { shapeStr = geom.getKeyShape(); } GShape shapeObj = geom.findShape(shapeStr); int a = shapeObj.size(vertical); if (vertical == 0) { keyCordiX += a + geom.keyGap; } else { keyCordiY += a + geom.keyGap; } geom.sectionList[secn].rowList[rown].addKey(); } Geometry parseGeometry(const QString &model) { using boost::spirit::iso8859_1::space; typedef std::string::const_iterator iterator_type; typedef grammar::GeometryParser GeometryParser; GeometryParser geometryParser; Rules::GeometryId geoId = Rules::getGeometryId(model); QString geometryFile = geoId.fileName; QString geometryName = geoId.geoName; qCDebug(KEYBOARD_PREVIEW) << "looking for model" << model << "geometryName" << geometryName << "in" << geometryFile; QString input = getGeometry(geometryFile, geometryName); if (! input.isEmpty()) { geometryParser.geom = Geometry(); input = includeGeometry(input); std::string parserInput = input.toUtf8().constData(); std::string::const_iterator iter = parserInput.begin(); std::string::const_iterator end = parserInput.end(); bool success = phrase_parse(iter, end, geometryParser, space); if (success && iter == end) { // qCDebug(KEYBOARD_PREVIEW) << "Geometry parsing succeeded for" << input.left(20); geometryParser.geom.setParsing(true); return geometryParser.geom; } else { qCritical() << "Geometry parsing failed for\n\t" << input.left(30); geometryParser.geom.setParsing(false); } } if (geometryParser.geom.getParsing()) { return geometryParser.geom; } qCritical() << "Failed to get geometry" << geometryParser.geom.getName() << "falling back to pc104"; return parseGeometry(QStringLiteral("pc104")); } QString includeGeometry(QString geometry) { QStringList lines = geometry.split(QStringLiteral("\n")); int includeLine = -1; QString includeLineStr; QString startLine = lines[0]; for (int i = 0; i < lines.size(); i++) { includeLineStr = lines[i]; lines[i] = lines[i].remove(QStringLiteral(" ")); lines[i] = lines[i].remove(QStringLiteral("\r")); if (lines[i].startsWith(QLatin1String("include"))) { includeLine = i; break; } } if (includeLine == -1) { return geometry; } geometry = geometry.remove(includeLineStr); lines[includeLine] = lines[includeLine].remove(QStringLiteral("include")); lines[includeLine] = lines[includeLine].remove(QStringLiteral("\"")); lines[includeLine] = lines[includeLine].remove(QStringLiteral(")")); if (lines[includeLine].contains(QStringLiteral("("))) { QString includeFile = lines[includeLine].split(QStringLiteral("("))[0]; QString includeGeom = lines[includeLine].split(QStringLiteral("("))[1]; qCDebug(KEYBOARD_PREVIEW) << "looking to include " << "geometryName" << includeGeom << "in" << includeFile; QString includeStr = getGeometry(includeFile, includeGeom); includeStr = getGeometryStrContent(includeStr); geometry = geometry.remove(startLine); geometry = geometry.prepend(includeStr); geometry = geometry.prepend(startLine); includeGeometry(geometry); } return geometry; } QString getGeometryStrContent(QString geometryStr) { int k = geometryStr.indexOf(QStringLiteral("{")); int k2 = geometryStr.lastIndexOf(QLatin1String("};")); geometryStr = geometryStr.mid(k + 1, k2 - k - 2); return geometryStr; } QString getGeometry(QString geometryFile, QString geometryName) { QString xkbParentDir = findGeometryBaseDir(); geometryFile.prepend(xkbParentDir); QFile gfile(geometryFile); if (!gfile.open(QIODevice::ReadOnly | QIODevice::Text)) { qCritical() << "Unable to open the file" << geometryFile; return QString(); } QString gcontent = gfile.readAll(); gfile.close(); QStringList gcontentList = gcontent.split(QStringLiteral("xkb_geometry ")); int current = 0; for (int i = 1; i < gcontentList.size(); i++) { if (gcontentList[i].startsWith("\"" + geometryName + "\"")) { current = i; break; } } if (current != 0) { return gcontentList[current].prepend("xkb_geometry "); } else { return QString(); } } QString findGeometryBaseDir() { QString xkbDir = Rules::findXkbDir(); return QStringLiteral("%1/geometry/").arg(xkbDir); } } ukui-control-center/plugins/devices/keyboard/preview/keyaliases.h0000644000175000017500000000214614201663671024307 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ALIASES_H #define ALIASES_H #include class Aliases { private: QMapqwerty; QMapazerty; QMapqwertz; QString findaliasdir(); public: Aliases(); QString getAlias(const QString &type, const QString &name); }; #endif // ALIASES_H ukui-control-center/plugins/devices/keyboard/preview/keyaliases.cpp0000644000175000017500000000673014201663671024645 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "keyaliases.h" #include "xkb_rules.h" #include #include #include #include #include #include #include #include #include #include "config-workspace.h" Aliases::Aliases() { QString filename = findaliasdir(); QFile file(filename); file.open(QIODevice::ReadOnly | QIODevice::Text); QString content = file.readAll(); file.close(); QListals; als = content.split(QStringLiteral("xkb_keycodes")); for (int i = 1; i < als.size(); i++) { QString temp = als.at(i); temp = temp.remove(QStringLiteral(" ")); temp = temp.remove(QStringLiteral("\n")); temp = temp.remove(QStringLiteral("\"")); temp = temp.remove(QStringLiteral(">")); temp = temp.remove(QStringLiteral("<")); temp = temp.remove(QStringLiteral(";")); temp = temp.remove(QStringLiteral("}")); temp = temp.remove(QStringLiteral("{")); QListalskeys; alskeys = temp.split(QStringLiteral("alias")); if (temp.startsWith(QLatin1String("qwerty"))) { for (int k = 1; k < alskeys.size(); k++) { QString tmp = alskeys.at(k); int inofeq = tmp.indexOf(QStringLiteral("=")); QString lat = tmp.left(inofeq); QString key = tmp.mid(inofeq + 1); qwerty[lat] = key; } } if (temp.startsWith(QLatin1String("azerty"))) { for (int k = 1; k < alskeys.size(); k++) { QString tmp = alskeys.at(k); int inofeq = tmp.indexOf(QStringLiteral("=")); QString lat = tmp.left(inofeq); QString key = tmp.mid(inofeq + 1); azerty[lat] = key; } } if (temp.startsWith(QLatin1String("qwertz"))) { for (int k = 1; k < alskeys.size(); k++) { QString tmp = alskeys.at(k); int inofeq = tmp.indexOf(QStringLiteral("=")); QString lat = tmp.left(inofeq); QString key = tmp.mid(inofeq + 1); qwertz[lat] = key; } } } } QString Aliases::getAlias(const QString &cname, const QString &name) { QMessageBox q; QString a = name; if (cname == QLatin1String("ma") || cname == QLatin1String("be") || cname == QLatin1String("fr")) { a = azerty.value(name); } else { a = qwerty.value(name); } return a; } QString Aliases::findaliasdir() { QString xkbDir = Rules::findXkbDir(); return QStringLiteral("%1/keycodes/aliases").arg(xkbDir); } ukui-control-center/plugins/devices/keyboard/preview/config-workspace.h0000644000175000017500000001213314201663716025413 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* config-workspace.h. Generated by cmake from config-workspace.h.cmake */ /* #undef HAVE_QIMAGEBLITZ */ /* Define if you have DPMS support */ #define HAVE_DPMS 1 /* Define if you have the DPMSCapable prototype in */ /* #undef HAVE_DPMSCAPABLE_PROTO */ /* Define if you have the DPMSInfo prototype in */ /* #undef HAVE_DPMSINFO_PROTO */ /* Defines if your system has the libfontconfig library */ #define HAVE_FONTCONFIG 1 /* Defines if your system has the freetype library */ #define HAVE_FREETYPE 1 /* Define if you have gethostname */ /* #undef HAVE_GETHOSTNAME */ /* Define if you have the gethostname prototype */ /* #undef HAVE_GETHOSTNAME_PROTO */ /* Define to 1 if you have the `getpeereid' function. */ /* #undef HAVE_GETPEEREID */ /* Defines if you have Solaris' libkstat */ /* #undef HAVE_KSTAT */ /* Define if you have long long as datatype */ /* #undef HAVE_LONG_LONG */ /* Define to 1 if you have the `nice' function. */ /* #undef HAVE_NICE */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SASL_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SASL_SASL_H */ /* Define to 1 if you have the `setpriority' function. */ #define HAVE_SETPRIORITY 1 /* Define to 1 if you have the `sigaction' function. */ /* #undef HAVE_SIGACTION */ /* Define to 1 if you have the `sigset' function. */ /* #undef HAVE_SIGSET */ /* Define to 1 if you have statvfs */ #define HAVE_STATVFS 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_STRING_H */ /* Define if you have the struct ucred */ /* #undef HAVE_STRUCT_UCRED */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_LOADAVG_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_MOUNT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STATFS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STATVFS_H 1 /* Define to 1 if you have statfs(). */ #define HAVE_STATFS 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_SELECT_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_TYPES_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_VFS_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_WAIT_H */ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define if you have unsetenv */ /* #undef HAVE_UNSETENV */ /* Define if you have the unsetenv prototype */ /* #undef HAVE_UNSETENV_PROTO */ /* Define if you have usleep */ /* #undef HAVE_USLEEP */ /* Define if you have the usleep prototype */ /* #undef HAVE_USLEEP_PROTO */ /* Define to 1 if you have the `vsnprintf' function. */ /* #undef HAVE_VSNPRINTF */ /* Define to 1 if you have the Wayland libraries. */ /* #undef WAYLAND_FOUND */ /* KDE's default home directory */ /* #undef KDE_DEFAULT_HOME */ /* KDE's binaries directory */ #define KDE_BINDIR "bin" /* KDE's configuration directory */ #define KDE_CONFDIR "/etc/xdg" /* KDE's static data directory */ #define KDE_DATADIR "share" /* Define where your java executable is */ #undef PATH_JAVA /* Define to 1 if you can safely include both and . */ /* #undef TIME_WITH_SYS_TIME */ /* xkb resources directory */ #define XKBDIR "/usr/share/X11/xkb" /* KWin binary name */ #define KWIN_BIN "kwin_x11" /* Number of bits in a file offset, on hosts where this is settable. */ #define _FILE_OFFSET_BITS 64 /* Define 1 if the Breeze window decoration was found */ #define HAVE_BREEZE_DECO 1 #ifdef HAVE_BREEZE_DECO #define BREEZE_KDECORATION_PLUGIN_ID "org.kde.breeze" #endif /* * On HP-UX, the declaration of vsnprintf() is needed every time ! */ /* type to use in place of socklen_t if not defined */ #define kde_socklen_t socklen_t #define WORKSPACE_VERSION_STRING "5.16.5" ukui-control-center/plugins/devices/keyboard/preview/debug.h0000644000175000017500000000040314201663671023235 0ustar fengfeng// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT! #ifndef ECM_QLOGGINGCATEGORY_KCM_KEYBOARD_DEBUG_H #define ECM_QLOGGINGCATEGORY_KCM_KEYBOARD_DEBUG_H #include Q_DECLARE_LOGGING_CATEGORY(KCM_KEYBOARD) #endif ukui-control-center/plugins/devices/keyboard/preview/keyboardlayout.cpp0000644000175000017500000000474414201663671025554 0ustar fengfeng/* * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "keyboardlayout.h" #include #include #include KbKey::KbKey() { symbolCount = 0; symbols << QString(); } void KbKey::setKeyName(QString n) { keyName = n; } void KbKey::addSymbol(QString n, int i) { if (!symbols.contains(n)) { symbols[i] = n; symbolCount++; symbols << QString(); } } QString KbKey::getSymbol(int i) { if (i < symbolCount) { return symbols[i]; } else { return QString(); } } void KbKey::display() { qCDebug(KEYBOARD_PREVIEW) << keyName << " : "; for (int i = 0; i < symbolCount; i++) { qCDebug(KEYBOARD_PREVIEW) << "\t" << symbols[i]; } } KbLayout::KbLayout() { keyCount = 0; includeCount = 0; level = 4; keyList << KbKey(); include << QString(); parsedSymbol = true; } void KbLayout::setName(QString n) { name = n; } void KbLayout::addInclude(QString n) { if (!include.contains(n)) { include[includeCount] = n; includeCount++; include << QString(); } } void KbLayout :: addKey() { keyCount++; keyList << KbKey(); } QString KbLayout :: getInclude(int i) { if (i < includeCount) { return include[i]; } else { return QString(); } } int KbLayout :: findKey(QString n) { for (int i = 0 ; i < keyCount ; i++) { if (keyList[i].keyName == n) { return i; } } return -1; } void KbLayout::display() { // qCDebug(KEYBOARD_PREVIEW) << name << "\n"; // for(int i = 0; i #include #include #include Q_DECLARE_LOGGING_CATEGORY(KEYBOARD_PREVIEW) class GShape { private: QString sname; QPoint approx; QList cordii; int cordi_count; public: GShape(); void setCordinate(double a, double b); void setApprox(double a, double b); QPoint getCordii(int i) const; void display(); double size(int vertical) const; void setShapeName(const QString &n) { sname = n; } QPoint getApprox() const { return approx; } QString getShapeName() { return sname; } int getCordi_count() const { return cordi_count; } }; class Key { private: QString name, shapeName; double offset; QPoint position; public: Key(); void setKeyPosition(double x, double y); void setOffset(double o) { offset = o; } void setKeyName(const QString &n) { name = n; } void setShapeName(const QString &n) { shapeName = n; } QString getName() { return name; } QString getShapeName() { return shapeName; } double getOffset() { return offset; } QPoint getPosition() { return position; } void showKey(); }; class Row { private: double top, left; int keyCount, vertical; QString shapeName; public : QList keyList; Row(); void addKey(); void setTop(double t) { top = t; } void setLeft(double l) { left = l; } void setVertical(int v) { vertical = v; } void setShapeName(const QString &n) { shapeName = n; } double getTop() { return top; } double getLeft() { return left; } int getKeyCount() { return keyCount; } int getVertical() { return vertical; } QString getShapeName() { return shapeName; } void displayRow(); }; class Section { private: QString name, shapeName; double top, left, angle; int rowCount, vertical; public: QList rowList; Section(); void addRow(); void setName(const QString &n) { name = n; } void setShapeName(const QString &n) { shapeName = n; } void setTop(double t) { top = t; } void setLeft(double l) { left = l; } void setAngle(double a) { angle = a; } void setVertical(int v) { vertical = v; } QString getName() { return name; } QString getShapeName() { return shapeName; } double getTop() { return top; } double getLeft() { return left; } double getAngle() { return angle; } int getVertical() { return vertical; } int getRowCount() { return rowCount; } void displaySection(); }; class Geometry { private: QString name, description, keyShape; int shape_count, vertical; int sectionCount; public: QList shapes; QList
    sectionList; double width, height, sectionTop, sectionLeft, rowTop, rowLeft, keyGap; bool parsedGeometry; Geometry(); void setWidth(double a) { width = a; } void setParsing(bool state) { parsedGeometry = state; } void setHeight(double a) { height = a; } void setName(const QString &n) { name = n; } void setDescription(const QString &d) { description = d; } void setKeyShape(const QString &s) { keyShape = s; } void setVertical(int v) { vertical = v; } double getWidth() { return width; } double getHeight() { return height; } QString getName() { return name; } QString getDescription() { return description; } QString getKeyShape() { return keyShape; } int getVertical() { return vertical; } int getShapeCount() { return shape_count; } int getSectionCount() { return sectionCount; } bool getParsing() { return parsedGeometry; } void setShapeName(const QString &n); void setShapeCord(double a, double b); void setShapeApprox(double a, double b); void addShape(); void display(); void addSection(); GShape findShape(const QString &name); }; #endif //geometry_componets.h ukui-control-center/plugins/devices/keyboard/preview/symbol_parser.h0000644000175000017500000000571114201663671025037 0ustar fengfeng/* * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SYMBOL_PARSER_H #define SYMBOL_PARSER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "keyboardlayout.h" #include "keyaliases.h" namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace phx = boost::phoenix; namespace iso = boost::spirit::iso8859_1; namespace grammar { struct symbol_keywords : qi::symbols { symbol_keywords(); }; struct levels : qi::symbols { levels(); }; template struct SymbolParser : qi::grammar { SymbolParser(); qi::rulestart; qi::rulename; qi::rulekeyName; qi::rulesymbols; qi::rulekey; qi::ruletype; qi::rulegroup; qi::rulesymbol; qi::rulecomments; qi::ruleee; qi::ruleinclude; KbLayout layout; int keyIndex, newKey; symbol_keywords symbolKeyword; levels lvl; Aliases alias; void getSymbol(std::string n); void addKeyName(std::string n); void getInclude(std::string n); void addKey(); void setName(std::string n); void setLevel(int lvl); }; KbLayout parseSymbols(const QString &layout, const QString &layoutVariant); QString findSymbolBaseDir(); } #endif //SYMBOL_PARSER_H ukui-control-center/plugins/devices/keyboard/preview/keysymhelper.cpp0000644000175000017500000000470514201663671025234 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "keysymhelper.h" #include "keysym2ucs.h" #include #include #include #include KeySymHelper::KeySymHelper() { nill = 0; } QString KeySymHelper::getKeySymbol(const QString &opton) { if (keySymbolMap.contains(opton)) { return keySymbolMap[opton]; } const char *str = opton.toLatin1().data(); #if 0 //TODO: figure out how to use this so we don't need our own symkey2ucs mapping int res = Xutf8LookupString(XIC ic, XKeyPressedEvent * event, char *buffer_return, int bytes_buffer, KeySym * keysym_return, Status * status_return); #else KeySym keysym = XStringToKeysym(str); //TODO: make it more generic // if( keysym == 0xfe03 ) // return "L3"; long ucs = keysym2ucs(keysym); // if( ucs == -1 && (keysym >= 0xFE50 && keysym <= 0xFE5F) ) { // ucs = 0x0300 + (keysym & 0x000F); // qWarning() << "Got dead symbol" << QString("0x%1").arg(keysym, 0, 16) << "named" << opton << "will use" << QString("0x%1").arg(ucs, 0, 16) << "as UCS"; // } if (ucs == -1) { nill++; qWarning() << "No mapping from keysym:" << QStringLiteral("0x%1").arg(keysym, 0, 16) << "named:" << opton << "to UCS"; return ""; } QString ucsStr = QString(QChar((int)ucs)); // Combining Diacritical Marks if (ucs >= 0x0300 && ucs <= 0x036F) { ucsStr = " " + ucsStr + " "; } // qWarning() << "--" << opton << "keysym: " << keysym << QString("0x%1").arg(keysym, 0, 16) << "keysym2string" << XKeysymToString(keysym) // << "---" << QString("0x%1").arg(ucs, 0, 16) << ucsStr; keySymbolMap[opton] = ucsStr; return ucsStr; #endif } ukui-control-center/plugins/devices/keyboard/preview/debug.cpp0000644000175000017500000000043614201663671023576 0ustar fengfeng// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT! #include "debug.h" #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) Q_LOGGING_CATEGORY(KCM_KEYBOARD, "org.kde.kcm_keyboard", QtWarningMsg) #else Q_LOGGING_CATEGORY(KCM_KEYBOARD, "org.kde.kcm_keyboard") #endif ukui-control-center/plugins/devices/keyboard/preview/keyboard_config.h0000644000175000017500000000462314201663671025304 0ustar fengfeng/* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KEYBOARD_CONFIG_H_ #define KEYBOARD_CONFIG_H_ #include "x11_helper.h" #include #include #include #include #include /** * This class provides configuration options for keyboard module */ class KeyboardConfig { public: static const int MAX_LABEL_LEN = 3; static const int NO_LOOPING; // = -1; enum SwitchingPolicy { SWITCH_POLICY_GLOBAL = 0, SWITCH_POLICY_DESKTOP = 1, SWITCH_POLICY_APPLICATION = 2, SWITCH_POLICY_WINDOW = 3 }; enum IndicatorType { SHOW_LABEL = 0, SHOW_FLAG = 1, SHOW_LABEL_ON_FLAG = 2 }; QString keyboardModel; // resetOldXkbOptions is now also "set xkb options" bool resetOldXkbOptions; QStringList xkbOptions; // init layouts options bool configureLayouts; QList layouts; int layoutLoopCount; // switch control options SwitchingPolicy switchingPolicy; // bool stickySwitching; // int stickySwitchingDepth; // display options bool showIndicator; IndicatorType indicatorType; bool showSingle; KeyboardConfig(); QList getDefaultLayouts() const; QList getExtraLayouts() const; bool isFlagShown() const { return indicatorType == SHOW_FLAG || indicatorType == SHOW_LABEL_ON_FLAG; } bool isLabelShown() const { return indicatorType == SHOW_LABEL || indicatorType == SHOW_LABEL_ON_FLAG; } void setDefaults(); void load(); void save(); static QString getSwitchingPolicyString(SwitchingPolicy switchingPolicy); }; #endif /* KEYBOARD_CONFIG_H_ */ ukui-control-center/plugins/devices/keyboard/preview/xkb_rules.h0000644000175000017500000000765714201663671024167 0ustar fengfeng/* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef XKB_RULES_H_ #define XKB_RULES_H_ #include #include #include #include "config-keyboard.h" struct ConfigItem { QString name; QString description; }; template inline T* findByName(QList list, QString name) { foreach(T* info, list) { if( info->name == name ) return info; } return nullptr; } struct VariantInfo: public ConfigItem { QList languages; const bool fromExtras; VariantInfo(bool fromExtras_): fromExtras(fromExtras_) {} }; struct LayoutInfo: public ConfigItem { QList variantInfos; QList languages; const bool fromExtras; // LayoutInfo() {} LayoutInfo(bool fromExtras_): fromExtras(fromExtras_) {} ~LayoutInfo() { foreach(VariantInfo* variantInfo, variantInfos) delete variantInfo; } VariantInfo* getVariantInfo(const QString& variantName) const { return findByName(variantInfos, variantName); } bool isLanguageSupportedByLayout(const QString& lang) const; bool isLanguageSupportedByDefaultVariant(const QString& lang) const; bool isLanguageSupportedByVariants(const QString& lang) const; bool isLanguageSupportedByVariant(const VariantInfo* variantInfo, const QString& lang) const; }; struct ModelInfo: public ConfigItem { QString vendor; }; struct OptionInfo: public ConfigItem { }; struct OptionGroupInfo: public ConfigItem { QList optionInfos; bool exclusive; ~OptionGroupInfo() { foreach(OptionInfo* opt, optionInfos) delete opt; } const OptionInfo* getOptionInfo(const QString& optionName) const { return findByName(optionInfos, optionName); } }; struct Rules { enum ExtrasFlag { NO_EXTRAS, READ_EXTRAS }; static const char XKB_OPTION_GROUP_SEPARATOR; QList layoutInfos; QList modelInfos; QList optionGroupInfos; QString version; Rules(); ~Rules() { foreach(LayoutInfo* layoutInfo, layoutInfos) delete layoutInfo; foreach(ModelInfo* modelInfo, modelInfos) delete modelInfo; foreach(OptionGroupInfo* optionGroupInfo, optionGroupInfos) delete optionGroupInfo; } const LayoutInfo* getLayoutInfo(const QString& layoutName) const { return findByName(layoutInfos, layoutName); } const OptionGroupInfo* getOptionGroupInfo(const QString& optionGroupName) const { return findByName(optionGroupInfos, optionGroupName); } static Rules* readRules(ExtrasFlag extrasFlag); static Rules* readRules(Rules* rules, const QString& filename, bool fromExtras); static QString getRulesName(); static QString findXkbDir(); #ifdef NEW_GEOMETRY class GeometryId { public: QString fileName; QString geoName; GeometryId(const QString& fileName_, const QString& geoName_): fileName(fileName_), geoName(geoName_) {} GeometryId& operator=(const GeometryId& geoId) { fileName = geoId.fileName; geoName = geoId.geoName; return *this; } }; static GeometryId getGeometryId(const QString& model); #endif }; #endif /* XKB_RULES_H_ */ ukui-control-center/plugins/devices/keyboard/preview/keysym2ucs.h0000644000175000017500000000164414201663671024275 0ustar fengfeng/* * Copyright (C) 2012 Andriy Rysin (arysin@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KEYSYM2UCS_H #define KEYSYM2UCS_H #include #include extern long keysym2ucs(KeySym keysym); #endif ukui-control-center/plugins/devices/keyboard/preview/xkb_rules.cpp0000644000175000017500000004164014201663671024510 0ustar fengfeng/* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "xkb_rules.h" #include "config-workspace.h" #include "debug.h" #include #include #include #include // for Qt::escape #include #include //#include //#include #include "x11_helper.h" // for findXkbRuleFile #include #include #include #include #include #include #include "config-workspace.h" class RulesHandler : public QXmlDefaultHandler { public: RulesHandler(Rules* rules_, bool fromExtras_): rules(rules_), fromExtras(fromExtras_){} bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes) override; bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName) override; bool characters(const QString &str) override; // bool fatalError(const QXmlParseException &exception); // QString errorString() const; private: // QString getString(const QString& text); QStringList path; Rules* rules; const bool fromExtras; }; static QString translate_xml_item(const QString& itemText) { if (itemText.isEmpty()) { // i18n warns on empty input strings return itemText; } //messages are already extracted from the source XML files by xkb //the characters '<' and '>' (but not '"') are HTML-escaped in the xkeyboard-config translation files, so we need to convert them before/after looking up the translation //note that we cannot use QString::toHtmlEscaped() here because that would convert '"' as well QString msgid(itemText); return i18nd("xkeyboard-config", msgid.replace(QLatin1Literal("<"), QLatin1Literal("<")).replace(QLatin1Literal(">"), QLatin1Literal(">")).toUtf8()).replace(QLatin1Literal("<"), QLatin1Literal("<")).replace(QLatin1Literal(">"), QLatin1Literal(">")); } static QString translate_description(ConfigItem* item) { return item->description.isEmpty() ? item->name : translate_xml_item(item->description); } static bool notEmpty(const ConfigItem* item) { return ! item->name.isEmpty(); } template void removeEmptyItems(QList& list) { #ifdef __GNUC__ #if __GNUC__ == 4 && (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 3) || (__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ < 4) #warning Compiling with a workaround for GCC < 4.8.3 || GCC < 4.7.4 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58800 Q_FOREACH(T* x, list) { ConfigItem *y = static_cast(x); if (y->name.isEmpty()) { list.removeAll(x); } } #else QtConcurrent::blockingFilter(list, notEmpty); #endif #endif } static void postProcess(Rules* rules) { //TODO remove elements with empty names to safeguard us removeEmptyItems(rules->layoutInfos); removeEmptyItems(rules->modelInfos); removeEmptyItems(rules->optionGroupInfos); // setlocale(LC_ALL, ""); // bindtextdomain("xkeyboard-config", LOCALE_DIR); foreach(ModelInfo* modelInfo, rules->modelInfos) { modelInfo->vendor = translate_xml_item(modelInfo->vendor); modelInfo->description = translate_description(modelInfo); } foreach(LayoutInfo* layoutInfo, rules->layoutInfos) { layoutInfo->description = translate_description(layoutInfo); removeEmptyItems(layoutInfo->variantInfos); foreach(VariantInfo* variantInfo, layoutInfo->variantInfos) { variantInfo->description = translate_description(variantInfo); } } foreach(OptionGroupInfo* optionGroupInfo, rules->optionGroupInfos) { optionGroupInfo->description = translate_description(optionGroupInfo); removeEmptyItems(optionGroupInfo->optionInfos); foreach(OptionInfo* optionInfo, optionGroupInfo->optionInfos) { optionInfo->description = translate_description(optionInfo); } } } Rules::Rules(): version(QStringLiteral("1.0")) { } QString Rules::getRulesName() { if (!QX11Info::isPlatformX11()) { return QString(); } XkbRF_VarDefsRec vd; char *tmp = nullptr; if (XkbRF_GetNamesProp(QX11Info::display(), &tmp, &vd) && tmp != nullptr ) { // qCDebug(KCM_KEYBOARD) << "namesprop" << tmp ; const QString name(tmp); XFree(tmp); return name; } return {}; } QString Rules::findXkbDir() { return QStringLiteral(XKBDIR); } static QString findXkbRulesFile() { QString rulesFile; QString rulesName = Rules::getRulesName(); const QString xkbDir = Rules::findXkbDir(); if ( ! rulesName.isNull() ) { rulesFile = QStringLiteral("%1/rules/%2.xml").arg(xkbDir, rulesName); } else { // default to evdev rulesFile = QStringLiteral("%1/rules/evdev.xml").arg(xkbDir); } return rulesFile; } static void mergeRules(Rules* rules, Rules* extraRules) { rules->modelInfos.append( extraRules->modelInfos ); rules->optionGroupInfos.append( extraRules->optionGroupInfos ); // need to iterate and merge? QList layoutsToAdd; foreach(LayoutInfo* extraLayoutInfo, extraRules->layoutInfos) { LayoutInfo* layoutInfo = findByName(rules->layoutInfos, extraLayoutInfo->name); if( layoutInfo != nullptr ) { layoutInfo->variantInfos.append( extraLayoutInfo->variantInfos ); layoutInfo->languages.append( extraLayoutInfo->languages ); } else { layoutsToAdd.append(extraLayoutInfo); } } rules->layoutInfos.append(layoutsToAdd); qCDebug(KCM_KEYBOARD) << "Merged from extra rules:" << extraRules->layoutInfos.size() << "layouts," << extraRules->modelInfos.size() << "models," << extraRules->optionGroupInfos.size() << "option groups"; // base rules now own the objects - remove them from extra rules so that it does not try to delete them extraRules->layoutInfos.clear(); extraRules->modelInfos.clear(); extraRules->optionGroupInfos.clear(); } const char Rules::XKB_OPTION_GROUP_SEPARATOR = ':'; Rules* Rules::readRules(ExtrasFlag extrasFlag) { Rules* rules = new Rules(); QString rulesFile = findXkbRulesFile(); if( ! readRules(rules, rulesFile, false) ) { delete rules; rules = nullptr; return nullptr; } if( extrasFlag == Rules::READ_EXTRAS ) { QRegExp regex(QStringLiteral("\\.xml$")); Rules* rulesExtra = new Rules(); QString extraRulesFile = rulesFile.replace(regex, QStringLiteral(".extras.xml")); if( readRules(rulesExtra, extraRulesFile, true) ) { // not fatal if it fails mergeRules(rules, rulesExtra); } delete rulesExtra; rulesExtra = nullptr; } return rules; } Rules* Rules::readRules(Rules* rules, const QString& filename, bool fromExtras) { QFile file(filename); if( !file.open(QFile::ReadOnly | QFile::Text) ) { qCCritical(KCM_KEYBOARD) << "Cannot open the rules file" << file.fileName(); return nullptr; } RulesHandler rulesHandler(rules, fromExtras); QXmlSimpleReader reader; reader.setContentHandler(&rulesHandler); reader.setErrorHandler(&rulesHandler); QXmlInputSource xmlInputSource(&file); qCDebug(KCM_KEYBOARD) << "Parsing xkb rules from" << file.fileName(); if( ! reader.parse(xmlInputSource) ) { qCCritical(KCM_KEYBOARD) << "Failed to parse the rules file" << file.fileName(); return nullptr; } postProcess(rules); return rules; } bool RulesHandler::startElement(const QString &/*namespaceURI*/, const QString &/*localName*/, const QString &qName, const QXmlAttributes &attributes) { path << QString(qName); QString strPath = path.join(QStringLiteral("/")); if( strPath.endsWith(QLatin1String("layoutList/layout/configItem")) ) { rules->layoutInfos << new LayoutInfo(fromExtras); } else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant")) ) { rules->layoutInfos.last()->variantInfos << new VariantInfo(fromExtras); } else if( strPath.endsWith(QLatin1String("modelList/model")) ) { rules->modelInfos << new ModelInfo(); } else if( strPath.endsWith(QLatin1String("optionList/group")) ) { rules->optionGroupInfos << new OptionGroupInfo(); rules->optionGroupInfos.last()->exclusive = (attributes.value(QStringLiteral("allowMultipleSelection")) != QLatin1String("true")); } else if( strPath.endsWith(QLatin1String("optionList/group/option")) ) { rules->optionGroupInfos.last()->optionInfos << new OptionInfo(); } else if( strPath == ("xkbConfigRegistry") && ! attributes.value(QStringLiteral("version")).isEmpty() ) { rules->version = attributes.value(QStringLiteral("version")); qCDebug(KCM_KEYBOARD) << "xkbConfigRegistry version" << rules->version; } return true; } bool RulesHandler::endElement(const QString &/*namespaceURI*/, const QString &/*localName*/, const QString &/*qName*/) { path.removeLast(); return true; } bool RulesHandler::characters(const QString &str) { if( !str.trimmed().isEmpty() ) { QString strPath = path.join(QStringLiteral("/")); if( strPath.endsWith(QLatin1String("layoutList/layout/configItem/name")) ) { if( rules->layoutInfos.last() != nullptr ) { rules->layoutInfos.last()->name = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "name:" << str; } // skipping invalid entry } else if( strPath.endsWith(QLatin1String("layoutList/layout/configItem/description")) ) { rules->layoutInfos.last()->description = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "descr:" << str; } else if( strPath.endsWith(QLatin1String("layoutList/layout/configItem/languageList/iso639Id")) ) { rules->layoutInfos.last()->languages << str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tlang:" << str; } else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant/configItem/name")) ) { rules->layoutInfos.last()->variantInfos.last()->name = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tvariant name:" << str; } else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant/configItem/description")) ) { rules->layoutInfos.last()->variantInfos.last()->description = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tvariant descr:" << str; } else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant/configItem/languageList/iso639Id")) ) { rules->layoutInfos.last()->variantInfos.last()->languages << str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tvlang:" << str; } else if( strPath.endsWith(QLatin1String("modelList/model/configItem/name")) ) { rules->modelInfos.last()->name = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "name:" << str; } else if( strPath.endsWith(QLatin1String("modelList/model/configItem/description")) ) { rules->modelInfos.last()->description = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tdescr:" << str; } else if( strPath.endsWith(QLatin1String("modelList/model/configItem/vendor")) ) { rules->modelInfos.last()->vendor = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tvendor:" << str; } else if( strPath.endsWith(QLatin1String("optionList/group/configItem/name")) ) { rules->optionGroupInfos.last()->name = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "name:" << str; } else if( strPath.endsWith(QLatin1String("optionList/group/configItem/description")) ) { rules->optionGroupInfos.last()->description = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tdescr:" << str; } else if( strPath.endsWith(QLatin1String("optionList/group/option/configItem/name")) ) { rules->optionGroupInfos.last()->optionInfos.last()->name = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "name:" << str; } else if( strPath.endsWith(QLatin1String("optionList/group/option/configItem/description")) ) { rules->optionGroupInfos.last()->optionInfos.last()->description = str.trimmed(); // qCDebug(KCM_KEYBOARD) << "\tdescr:" << str; } } return true; } bool LayoutInfo::isLanguageSupportedByLayout(const QString& lang) const { if( languages.contains(lang) || isLanguageSupportedByVariants(lang) ) return true; // // return yes if no languages found in layout or its variants // if( languages.empty() ) { // foreach(const VariantInfo* info, variantInfos) { // if( ! info->languages.empty() ) // return false; // } // return true; // } return false; } bool LayoutInfo::isLanguageSupportedByVariants(const QString& lang) const { foreach(const VariantInfo* info, variantInfos) { if( info->languages.contains(lang) ) return true; } return false; } bool LayoutInfo::isLanguageSupportedByDefaultVariant(const QString& lang) const { if( languages.contains(lang) ) return true; if( languages.empty() && isLanguageSupportedByVariants(lang) ) return true; return false; } bool LayoutInfo::isLanguageSupportedByVariant(const VariantInfo* variantInfo, const QString& lang) const { if( variantInfo->languages.contains(lang) ) return true; // if variant has no languages try to "inherit" them from layout if( variantInfo->languages.empty() && languages.contains(lang) ) return true; return false; } #ifdef NEW_GEOMETRY Rules::GeometryId Rules::getGeometryId(const QString& model) { QString xkbDir = Rules::findXkbDir(); QString rulesName = Rules::getRulesName(); QString ruleFileName = QStringLiteral("%1/rules/%2").arg(xkbDir, rulesName); QFile ruleFile(ruleFileName); GeometryId defaultGeoId(QStringLiteral("pc"), QStringLiteral("pc104")); if ( ! ruleFile.open(QIODevice::ReadOnly | QIODevice::Text) ){ qCCritical(KCM_KEYBOARD) << "Unable to open file" << ruleFileName; return defaultGeoId; } QString modelGeoId = model; bool inTable = false; QTextStream in(&ruleFile); while (!in.atEnd()) { QString line = in.readLine().trimmed(); if( line.isEmpty() || QRegExp(QStringLiteral("^\\s*//")).indexIn(line) != -1 ) continue; QRegExp modelGroupRegex(QStringLiteral("!\\s*(\\$[a-zA-Z0-9_]+)\\s*=(.*)")); if( modelGroupRegex.indexIn(line) != -1 ) { QStringList parts = modelGroupRegex.capturedTexts(); QString groupName = parts[1]; QStringList models = parts[2].split(QRegExp(QStringLiteral("\\s+")), QString::SkipEmptyParts); // qCDebug(KCM_KEYBOARD) << "modelGroup definition" << groupName << ":" << models; if( models.contains(model) ) { modelGeoId = groupName; } continue; } if( inTable ) { QRegExp modelTableEntry (QStringLiteral("\\s*(\\$?[a-zA-Z0-9_]+|\\*)\\s*=\\s*([a-zA-Z0-9_]+)\\(([a-zA-Z0-9_%]+)\\)")); if( modelTableEntry.indexIn(line) == -1 ) { if( QRegExp(QStringLiteral("^!\\s*")).indexIn(line) != -1 ) break; qCWarning(KCM_KEYBOARD) << "could not parse geometry line" << line; continue; } QStringList parts = modelTableEntry.capturedTexts(); QString modelName = parts[1]; QString fileName = parts[2]; QString geoName = parts[3]; if( geoName == QLatin1String("%m") ) { geoName = model; } if( modelName == QLatin1String("*") ) { defaultGeoId = GeometryId(fileName, geoName); } // qCDebug(KCM_KEYBOARD) << "geo entry" << modelName << fileName << geoName; if( modelName == model ) { return GeometryId(fileName, geoName); } continue; } QRegExp modelTableHeader (QStringLiteral("!\\s+model\\s*=\\s*geometry")); if( modelTableHeader.indexIn(line) != -1 ) { inTable = true; continue; } } return defaultGeoId; } #endif ukui-control-center/plugins/devices/keyboard/preview/config-keyboard.h0000644000175000017500000000162114201663716025215 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef CONFIG_KEYBOARD_H #define CONFIG_KEYBOARD_H #define HAVE_XINPUT /* #undef HAVE_UDEV */ #define NEW_GEOMETRY #endif // CONFIG_KEYBOARD_H ukui-control-center/plugins/devices/keyboard/preview/x11_helper.h0000644000175000017500000001702214201663671024124 0ustar fengfeng/* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef X11_HELPER_H_ #define X11_HELPER_H_ #include #include #include #include #include #include #include //#include //union _xkb_event; //class xcb_generic_event_t; // TODO: remove this when we can include xcb/xkb.h namespace { typedef struct _xcb_xkb_map_notify_event_t { uint8_t response_type; uint8_t xkbType; uint16_t sequence; xcb_timestamp_t time; uint8_t deviceID; uint8_t ptrBtnActions; uint16_t changed; xcb_keycode_t minKeyCode; xcb_keycode_t maxKeyCode; uint8_t firstType; uint8_t nTypes; xcb_keycode_t firstKeySym; uint8_t nKeySyms; xcb_keycode_t firstKeyAct; uint8_t nKeyActs; xcb_keycode_t firstKeyBehavior; uint8_t nKeyBehavior; xcb_keycode_t firstKeyExplicit; uint8_t nKeyExplicit; xcb_keycode_t firstModMapKey; uint8_t nModMapKeys; xcb_keycode_t firstVModMapKey; uint8_t nVModMapKeys; uint16_t virtualMods; uint8_t pad0[2]; } _xcb_xkb_map_notify_event_t; typedef struct _xcb_xkb_state_notify_event_t { uint8_t response_type; uint8_t xkbType; uint16_t sequence; xcb_timestamp_t time; uint8_t deviceID; uint8_t mods; uint8_t baseMods; uint8_t latchedMods; uint8_t lockedMods; uint8_t group; int16_t baseGroup; int16_t latchedGroup; uint8_t lockedGroup; uint8_t compatState; uint8_t grabMods; uint8_t compatGrabMods; uint8_t lookupMods; uint8_t compatLoockupMods; uint16_t ptrBtnState; uint16_t changed; xcb_keycode_t keycode; uint8_t eventType; uint8_t requestMajor; uint8_t requestMinor; } _xcb_xkb_state_notify_event_t; typedef union { /* All XKB events share these fields. */ struct { uint8_t response_type; uint8_t xkbType; uint16_t sequence; xcb_timestamp_t time; uint8_t deviceID; } any; _xcb_xkb_map_notify_event_t map_notify; _xcb_xkb_state_notify_event_t state_notify; } _xkb_event; } class XEventNotifier : public QObject, public QAbstractNativeEventFilter { Q_OBJECT Q_SIGNALS: void layoutChanged(); void layoutMapChanged(); public: XEventNotifier(); ~XEventNotifier() override {} virtual void start(); virtual void stop(); protected: // bool x11Event(XEvent * e); virtual bool processOtherEvents(xcb_generic_event_t* e); virtual bool processXkbEvents(xcb_generic_event_t* e); bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override; private: int registerForXkbEvents(Display* display); bool isXkbEvent(xcb_generic_event_t* event); bool isGroupSwitchEvent(_xkb_event* event); bool isLayoutSwitchEvent(_xkb_event* event); int xkbOpcode; }; struct XkbConfig { QString keyboardModel; QStringList layouts; QStringList variants; QStringList options; bool isValid() { return ! layouts.empty(); } }; struct LayoutUnit { static const int MAX_LABEL_LENGTH; //TODO: move these to private? QString layout; QString variant; LayoutUnit() {} explicit LayoutUnit(const QString& fullLayoutName); LayoutUnit(const QString& layout_, const QString& variant_) { layout = layout_; variant = variant_; } /*explicit*/ LayoutUnit(const LayoutUnit& layoutUnit) { layout = layoutUnit.layout; variant = layoutUnit.variant; displayName = layoutUnit.displayName; shortcut = layoutUnit.shortcut; } QString getRawDisplayName() const { return displayName; } QString getDisplayName() const { return !displayName.isEmpty() ? displayName : layout; } void setDisplayName(const QString& name) { displayName = name; } void setShortcut(const QKeySequence& shortcut) { this->shortcut = shortcut; } QKeySequence getShortcut() const { return shortcut; } bool isEmpty() const { return layout.isEmpty(); } bool isValid() const { return ! isEmpty(); } bool operator==(const LayoutUnit& layoutItem) const { return layout==layoutItem.layout && variant==layoutItem.variant; } bool operator!=(const LayoutUnit& layoutItem) const { return ! (*this == layoutItem); } QString toString() const; private: QString displayName; QKeySequence shortcut; }; struct LayoutSet { QList layouts; LayoutUnit currentLayout; LayoutSet() {} LayoutSet(const LayoutSet& currentLayouts) { this->layouts = currentLayouts.layouts; this->currentLayout = currentLayouts.currentLayout; } bool isValid() const { return currentLayout.isValid() && layouts.contains(currentLayout); } bool operator == (const LayoutSet& currentLayouts) const { return this->layouts == currentLayouts.layouts && this->currentLayout == currentLayouts.currentLayout; } LayoutSet& operator = (const LayoutSet& currentLayouts) { this->layouts = currentLayouts.layouts; this->currentLayout = currentLayouts.currentLayout; return *this; } QString toString() const { QString str(currentLayout.toString()); str += QLatin1String(": "); foreach(const LayoutUnit& layoutUnit, layouts) { str += layoutUnit.toString() + " "; } return str; } static QString toString(const QList& layoutUnits) { QString str; foreach(const LayoutUnit& layoutUnit, layoutUnits) { str += layoutUnit.toString() + ","; } return str; } }; class X11Helper { public: static const int MAX_GROUP_COUNT; static const int ARTIFICIAL_GROUP_LIMIT_COUNT; static const char LEFT_VARIANT_STR[]; static const char RIGHT_VARIANT_STR[]; static bool xkbSupported(int* xkbOpcode); static void switchToNextLayout(); static void scrollLayouts(int delta); static bool isDefaultLayout(); static bool setDefaultLayout(); static bool setLayout(const LayoutUnit& layout); static LayoutUnit getCurrentLayout(); static LayoutSet getCurrentLayouts(); static QList getLayoutsList(); static QStringList getLayoutsListAsString(const QList& layoutsList); enum FetchType { ALL, LAYOUTS_ONLY, MODEL_ONLY }; static bool getGroupNames(Display* dpy, XkbConfig* xkbConfig, FetchType fetchType); private: static unsigned int getGroup(); static bool setGroup(unsigned int group); }; #endif /* X11_HELPER_H_ */ ukui-control-center/plugins/devices/keyboard/preview/geometry_components.cpp0000644000175000017500000001266614201663671026620 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "geometry_components.h" #include #include #include Q_LOGGING_CATEGORY(KEYBOARD_PREVIEW, "keyboard_preview") GShape::GShape() { cordi_count = 0; } void GShape::setCordinate(double a, double b) { cordii << QPoint(a, b); cordi_count++; } void GShape::setApprox(double a, double b) { a -= approx.x(); b -= approx.y(); approx = QPoint(a, b); } QPoint GShape :: getCordii(int i) const { if (i < cordi_count) { return cordii[i]; } return QPoint(); } void GShape::display() { qCDebug(KEYBOARD_PREVIEW) << "shape: " << sname << "\n"; qCDebug(KEYBOARD_PREVIEW) << "(" << approx.x() << "," << approx.y() << ");"; for (int i = 0; i < cordi_count; i++) { qCDebug(KEYBOARD_PREVIEW) << cordii[i]; } } double GShape::size(int vertical) const { if (!cordii.isEmpty()) { if (vertical == 0) { if (approx.x() == 0 && approx.y() == 0) { int max = 0; for (int i = 0; i < cordi_count; i++) { if (max < cordii[i].x()) { max = cordii[i].x(); } } return max; } else { return approx.x(); } } else { if (approx.x() == 0 && approx.y() == 0) { int max = 0; for (int i = 0; i < cordi_count; i++) { if (max < cordii[i].y()) { max = cordii[i].y(); } } return max; } return approx.y(); } } return 0; } Key::Key() { offset = 0; } void Key::setKeyPosition(double x, double y) { position = QPoint(x, y); } void Key::showKey() { qCDebug(KEYBOARD_PREVIEW) << "\n\tKey: " << name << "\tshape: " << shapeName << "\toffset: " << offset; qCDebug(KEYBOARD_PREVIEW) << "\tposition" << position; } Row::Row() { top = 0; left = 0; keyCount = 0; vertical = 0; keyList << Key(); } void Row::addKey() { //qCDebug(KEYBOARD_PREVIEW) << "keyCount: " << keyCount; keyCount++; keyList << Key(); } void Row::displayRow() { qCDebug(KEYBOARD_PREVIEW) << "\nRow: (" << left << "," << top << ")\n"; qCDebug(KEYBOARD_PREVIEW) << "vertical: " << vertical; for (int i = 0; i < keyCount; i++) { keyList[i].showKey(); } } Section::Section() { top = 0; left = 0; angle = 0; rowCount = 0; vertical = 0; rowList << Row(); } void Section::addRow() { //qCDebug(KEYBOARD_PREVIEW) << "\nrowCount: " << rowCount; rowCount++; rowList << Row(); } void Section::displaySection() { //qCDebug(KEYBOARD_PREVIEW) << "\nSection: " << name << "\n\tposition: (" << left << "," << top << ");" << angle << "\n"; //qCDebug(KEYBOARD_PREVIEW) << "vertical: " << vertical; for (int i = 0; i < rowCount; i++) { qCDebug(KEYBOARD_PREVIEW) << "\n\t"; rowList[i].displayRow(); } } Geometry::Geometry() { sectionTop = 0; sectionLeft = 0; rowTop = 0; rowLeft = 0; keyGap = 0; shape_count = 0; width = 0; height = 0; sectionCount = 0; vertical = 0; sectionList << Section(); shapes << GShape(); keyShape = QStringLiteral("NORM"); parsedGeometry = true; } void Geometry::setShapeName(const QString &n) { shapes[shape_count].setShapeName(n); } void Geometry::setShapeCord(double a, double b) { shapes[shape_count].setCordinate(a, b); } void Geometry::setShapeApprox(double a, double b) { shapes[shape_count].setApprox(a, b); } void Geometry::addShape() { shape_count++; shapes << GShape(); } void Geometry::display() { qCDebug(KEYBOARD_PREVIEW) << name << "\n" << description << "\nwidth:" << width << "\nheight:" << height << "\n" << "sectionTop:" << sectionTop; qCDebug(KEYBOARD_PREVIEW) << "\nsectionLeft:" << sectionLeft << "\nrowTop:" << rowTop << "\nrowLeft:" << rowLeft << "\nkeyGap: " << keyGap << "\nkeyShape:" << keyShape << "\n"; qCDebug(KEYBOARD_PREVIEW) << "vertical:" << vertical; for (int i = 0; i < shape_count; i++) { shapes[i].display(); } for (int j = 0; j < sectionCount; j++) { sectionList[j].displaySection(); } } void Geometry::addSection() { //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount: " << sectionCount; sectionCount++; sectionList << Section(); } GShape Geometry::findShape(const QString &name) { GShape l; for (int i = 0; i < shape_count; i++) { if (shapes[i].getShapeName() == name) { return shapes[i]; } } return l; } ukui-control-center/plugins/devices/keyboard/preview/keyboardpainter.h0000644000175000017500000000263514201663671025343 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KEYBOARDPAINTER_H #define KEYBOARDPAINTER_H #include "kbpreviewframe.h" #include class QPushButton; class QComboBox; class KeyboardPainter : public QDialog { Q_OBJECT public: explicit KeyboardPainter(); ~KeyboardPainter() override; void generateKeyboardLayout(const QString &layout, const QString &variant, const QString &model, const QString &title); int getHeight(); int getWidth(); public Q_SLOTS: void levelChanged(int l_id); private: QDialog *kbDialog; KbPreviewFrame *kbframe; QPushButton *exitButton; QComboBox *levelBox; }; #endif // KEYBOARDPAINTER_H ukui-control-center/plugins/devices/keyboard/preview/kbpreviewframe.cpp0000644000175000017500000002734214201663671025526 0ustar fengfeng/* * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) * * 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kbpreviewframe.h" #include "geometry_parser.h" #include "geometry_components.h" #include "keyboardlayout.h" #include "symbol_parser.h" #include #include #include #include #include #include #include #include #include static const QColor keyBorderColor("#d4d4d4"); static const QColor lev12color(Qt::black); static const QColor lev34color("#0033FF"); static const QColor unknownSymbolColor("#FF3300"); static const int xOffset[] = {10, 10, -15, -15 }; static const int yOffset[] = {5, -20, 5, -20 }; static const QColor color[] = { lev12color, lev12color, lev34color, lev34color }; static const int keyLevel[3][4] = { { 1, 0, 3, 2}, { 1, 0, 5, 4}, { 1, 0, 7, 6} }; static const QRegExp fkKey(QStringLiteral("^FK\\d+$")); KbPreviewFrame::KbPreviewFrame(QWidget *parent) : QFrame(parent), geometry(*new Geometry()) { setFrameStyle(QFrame::Box); setFrameShadow(QFrame::Sunken); setMouseTracking(true); scaleFactor = 1; l_id = 0; } KbPreviewFrame::~KbPreviewFrame() { delete &geometry; } int KbPreviewFrame::getWidth() const { return geometry.width; } int KbPreviewFrame::getHeight() const { return geometry.height; } //writes text on the keys call only by paintevent void KbPreviewFrame::drawKeySymbols(QPainter &painter, QPoint temp[], const GShape &s, const QString &name) { int keyindex = keyboardLayout.findKey(name); int szx = scaleFactor * s.size(0) / 2 < 20 ? scaleFactor * s.size(0) / 3 : 20; int szy = scaleFactor * s.size(1) / 2 < 20 ? scaleFactor * s.size(1) / 3 : 20; QFont kbfont; if (szx > szy) { kbfont.setPointSize(szy / 2 < 9 ? szy : 9); } else { kbfont.setPointSize(szx / 2 < 9 ? szx / 2 : 9); } painter.setFont(kbfont); int cordinate[] = {0, 3, 1, 2}; float tooltipX = 0, toolTipY = 0; QString tip; if (keyindex != -1) { KbKey key = keyboardLayout.keyList.at(keyindex); for (int level = 0; level < (key.getSymbolCount() < 4 ? key.getSymbolCount() : 4); level++) { if (keyLevel[l_id][level] < key.getSymbolCount()) { QString txt = symbol.getKeySymbol(key.getSymbol(keyLevel[l_id][level])); QColor txtColor = txt[0] == -1 ? unknownSymbolColor : color[level]; painter.setPen(txtColor); painter.drawText(temp[cordinate[level]].x() + xOffset[level]*scaleFactor / 2.5, temp[cordinate[level]].y() + yOffset[level]*scaleFactor / 2.5, szx, szy, Qt::AlignTop, txt); QString currentSymbol = key.getSymbol(keyLevel[l_id][level]); currentSymbol = currentSymbol.size() < 3 ? currentSymbol.append("\t") : currentSymbol; if (level == 0) { tip.append(currentSymbol); } else { tip.append("\n" + currentSymbol); } } } for (int i = 0 ; i < 4; i++) { tooltipX += temp[i].x(); toolTipY += temp[i].y(); } tooltipX = tooltipX / 4; toolTipY = toolTipY / 4; QPoint tooltipPoint = QPoint(tooltipX, toolTipY); tooltip.append(tip); tipPoint.append(tooltipPoint); } else { painter.setPen(Qt::black); if (name.contains(fkKey)) { QString tempName = name; tempName.remove(QStringLiteral("K")); painter.drawText(temp[0].x() + s.size(0) - 10, temp[0].y() + 3 * scaleFactor * s.size(1) / 5, tempName); } else { painter.setFont(kbfont); painter.drawText(temp[0].x() + s.size(0) - 10, temp[0].y() + 3 * scaleFactor * s.size(1) / 5, name); } tip = name; for (int i = 0 ; i < 4; i++) { tooltipX += temp[i].x(); toolTipY += temp[i].y(); } tooltipX = tooltipX / 4; toolTipY = toolTipY / 4; QPoint tooltipPoint = QPoint(tooltipX, toolTipY); tooltip.append(tip); tipPoint.append(tooltipPoint); } } //draws key shape on QFrame called only by paint event void KbPreviewFrame::drawShape(QPainter &painter, const GShape &s, int x, int y, int i, const QString &name) { painter.setPen(Qt::black); int cordi_count = s.getCordi_count(); if (geometry.sectionList[i].getAngle() == 0) { if (cordi_count == 1) { int width = s.getCordii(0).x(); int height = s.getCordii(0).y(); painter.drawRoundedRect(scaleFactor * x + 2, scaleFactor * y, scaleFactor * width, scaleFactor * height, 4, 4); QPoint temp[4]; temp[0] = QPoint(scaleFactor * x, scaleFactor * y); temp[1] = QPoint(scaleFactor * (s.getCordii(0).x() + x), scaleFactor * y); temp[2] = QPoint(scaleFactor * (s.getCordii(0).x() + x), scaleFactor * (s.getCordii(0).y() + y)); temp[3] = QPoint(scaleFactor * (x), scaleFactor * (s.getCordii(0).y() + y)); drawKeySymbols(painter, temp, s, name); } else { QVarLengthArray temp(cordi_count); for (int i = 0; i < cordi_count; i++) { temp[i].setX(scaleFactor * (s.getCordii(i).x() + x + 1)); temp[i].setY(scaleFactor * (s.getCordii(i).y() + y + 1)); } painter.drawPolygon(temp.data(), cordi_count); drawKeySymbols(painter, temp.data(), s, name); // no length passed here, is this safe? } } else { QVarLengthArray temp(cordi_count == 1 ? 4 : cordi_count); int size; if (cordi_count == 1) { temp[0] = QPoint(x, y); temp[1] = QPoint(s.getCordii(0).x() + x, y); temp[2] = QPoint(s.getCordii(0).x() + x, s.getCordii(0).y() + y); temp[3] = QPoint(x, s.getCordii(0).y() + y); size = 4; } else { size = cordi_count; for (int i = 0; i < cordi_count; i++) { temp[i].setX((s.getCordii(i).x() + x + 1)); temp[i].setY((s.getCordii(i).y() + y + 1)); } } double refX, refY; refX = geometry.sectionList[i].getLeft(); refY = geometry.sectionList[i].getTop(); //qCDebug(KEYBOARD_PREVIEW) <<"\ntransform"; for (int j = 0; j < size; j++) { double x = temp[j].x() - refX; double y = temp[j].y() - refY; //qCDebug(KEYBOARD_PREVIEW) <<"(" <"; float theta = (3.1459 * geometry.sectionList[i].getAngle()) / 180; double x_ = x * cos(theta) - y * sin(theta); //qCDebug(KEYBOARD_PREVIEW) <<"x_= " <type() == QEvent::ToolTip) { QHelpEvent *helpEvent = static_cast(event); int index = itemAt(helpEvent->pos()); if (index != -1) { QToolTip::showText(helpEvent->globalPos(), tooltip.at(index)); } else { QToolTip::hideText(); event->ignore(); } return true; } return QWidget::event(event); } void KbPreviewFrame::paintEvent(QPaintEvent *) { if (geometry.getParsing() && keyboardLayout.getParsedSymbol()) { QPainter painter(this); QFont kbfont; kbfont.setPointSize(9); painter.setFont(kbfont); painter.setBrush(QBrush("#C3C8CB")); painter.setRenderHint(QPainter::Antialiasing); const int strtx = 0, strty = 0, endx = geometry.getWidth(), endy = geometry.getHeight(); painter.setPen("#EDEEF2"); painter.drawRect(strtx, strty, scaleFactor * endx + 60, scaleFactor * endy + 60); painter.setPen(Qt::black); painter.setBrush(QBrush("#EDEEF2")); for (int i = 0; i < geometry.getSectionCount(); i++) { painter.setPen(Qt::black); for (int j = 0; j < geometry.sectionList[i].getRowCount(); j++) { int keyn = geometry.sectionList[i].rowList[j].getKeyCount(); for (int k = 0; k < keyn; k++) { Key temp = geometry.sectionList[i].rowList[j].keyList[k]; int x = temp.getPosition().x(); int y = temp.getPosition().y(); GShape s; s = geometry.findShape(temp.getShapeName()); QString name = temp.getName(); drawShape(painter, s, x, y, i, name); } } } if (symbol.isFailed()) { painter.setPen(keyBorderColor); painter.drawRect(strtx, strty, endx, endy); const int midx = 470, midy = 240; painter.setPen(lev12color); painter.drawText(midx, midy, tr("No preview found")); } } else { QMessageBox errorBox; errorBox.setText(tr("Unable to open Preview !")); errorBox.exec(); } } // this function draws the keyboard preview on a QFrame void KbPreviewFrame::generateKeyboardLayout(const QString &layout, const QString &layoutVariant, const QString &model) { qDebug() << " generateKeyboardLayout " << endl; geometry = grammar::parseGeometry(model); int endx = geometry.getWidth(), endy = geometry.getHeight(); QDesktopWidget *desktopWidget = qApp->desktop(); QRect screenGeometry = desktopWidget->screenGeometry(); int screenWidth = screenGeometry.width(); scaleFactor = 2.5; while (scaleFactor * endx + screenWidth / 20 > screenWidth) { scaleFactor -= 0.2; } qCDebug(KEYBOARD_PREVIEW) << "scale factor: 2.5 ->" << scaleFactor; setFixedSize(scaleFactor * endx + 60, scaleFactor * endy + 60); qCDebug(KEYBOARD_PREVIEW) << screenWidth << ":" << scaleFactor << scaleFactor *endx + 60 << scaleFactor *endy + 60; keyboardLayout = grammar::parseSymbols(layout, layoutVariant); } //this functions give the index of the tooltip over which mouse hovers int KbPreviewFrame::itemAt(const QPoint &pos) { int distance = 10000; int closest = 0; for (int i = 0; i < tipPoint.size(); i++) { int temp = sqrt((pos.x() - tipPoint.at(i).x()) * (pos.x() - tipPoint.at(i).x()) + (pos.y() - tipPoint.at(i).y()) * (pos.y() - tipPoint.at(i).y())); if (distance > temp) { distance = temp; closest = i; } } if (distance < 25) { return closest; } return -1; } ukui-control-center/plugins/devices/keyboard/keyboard.pro0000644000175000017500000000431214201663716022642 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-08-22T11:12:59 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/closebutton.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets x11extras KWindowSystem xml KGuiAddons KCoreAddons concurrent KConfigCore KConfigGui KI18n #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(keyboard) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ /usr/include/KF5 \ /usr/include/xcb \ LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lX11 -lxkbfile CONFIG += link_pkgconfig \ C++11 PKGCONFIG += libmatekbd \ gsettings-qt \ #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ keyboardcontrol.cpp \ kbdlayoutmanager.cpp \ \# tastenbrett.cpp preview/debug.cpp \ preview/geometry_components.cpp \ preview/geometry_parser.cpp \ preview/kbpreviewframe.cpp \ preview/keyaliases.cpp \ preview/keyboard_config.cpp \ preview/keyboardlayout.cpp \ preview/keyboardpainter.cpp \ preview/keysym2ucs.cpp \ preview/keysymhelper.cpp \ preview/symbol_parser.cpp \ preview/x11_helper.cpp \ preview/xkb_rules.cpp HEADERS += \ keyboardcontrol.h \ kbdlayoutmanager.h \ \# tastenbrett.h preview/config-keyboard.h \ preview/config-workspace.h \ preview/debug.h \ preview/geometry_components.h \ preview/geometry_parser.h \ preview/kbpreviewframe.h \ preview/keyaliases.h \ preview/keyboard_config.h \ preview/keyboardlayout.h \ preview/keyboardpainter.h \ preview/keysym2ucs.h \ preview/keysymhelper.h \ preview/symbol_parser.h \ preview/x11_helper.h \ preview/xkb_rules.h FORMS += \ keyboardcontrol.ui \ kbdlayoutmanager.ui \ layoutmanager.ui INSTALLS += target ukui-control-center/plugins/devices/keyboard/keyboardcontrol.cpp0000644000175000017500000002423514201663716024233 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "keyboardcontrol.h" #include "ui_keyboardcontrol.h" #include #include #include #include #define KEYBOARD_SCHEMA "org.ukui.peripherals-keyboard" #define REPEAT_KEY "repeat" #define DELAY_KEY "delay" #define RATE_KEY "rate" #define KBD_LAYOUTS_SCHEMA "org.mate.peripherals-keyboard-xkb.kbd" #define KBD_LAYOUTS_KEY "layouts" #define CC_KEYBOARD_OSD_SCHEMA "org.ukui.control-center.osd" #define CC_KEYBOARD_OSD_KEY "show-lock-tip" KeyboardControl::KeyboardControl() : mFirstLoad(true) { pluginName = tr("Keyboard"); pluginType = DEVICES; } KeyboardControl::~KeyboardControl() { if (!mFirstLoad) { delete ui; ui = nullptr; if (settingsCreate) { // delete kbdsettings; delete settings; settings = nullptr; } } } QString KeyboardControl::get_plugin_name() { return pluginName; } int KeyboardControl::get_plugin_type() { return pluginType; } QWidget *KeyboardControl::get_plugin_ui() { if (mFirstLoad) { ui = new Ui::KeyboardControl; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); mFirstLoad = false; settingsCreate = false; setupStylesheet(); setupComponent(); // 初始化键盘通用设置GSettings const QByteArray id(KEYBOARD_SCHEMA); // 初始化键盘布局GSettings // const QByteArray idd(KBD_LAYOUTS_SCHEMA); // 初始化按键提示GSettings const QByteArray iid(CC_KEYBOARD_OSD_SCHEMA); // 控制面板自带GSettings,不再判断是否安装 osdSettings = new QGSettings(iid); if (QGSettings::isSchemaInstalled(id)){ settingsCreate = true; // kbdsettings = new QGSettings(idd); settings = new QGSettings(id); //构建布局管理器对象 layoutmanagerObj = new KbdLayoutManager(pluginWidget); setupConnect(); initGeneralStatus(); rebuildLayoutsComBox(); } } return pluginWidget; } void KeyboardControl::plugin_delay_control() { } const QString KeyboardControl::name() const { return QStringLiteral("keyboard"); } void KeyboardControl::setupStylesheet(){ //~ contents_path /keyboard/Enable repeat key ui->enableLabel->setText(tr("Enable repeat key")); //~ contents_path /keyboard/Delay ui->delayLabel->setText(tr("Delay")); //~ contents_path /keyboard/Speed ui->speedLabel->setText(tr("Speed")); //~ contents_path /keyboard/Input characters to test the repetition effect: ui->repeatLabel->setText(tr("Input characters to test the repetition effect:")); //~ contents_path /keyboard/Tip of keyboard ui->tipLabel->setText(tr("Tip of keyboard")); ui->layoutLabel->setText(tr("Keyboard layout")); //~ contents_path /keyboard/Input Set ui->inputSettingsBtn->setText(tr("Input Set")); } void KeyboardControl::setupComponent(){ // addWgt = new HoverWidget(""); // addWgt->setObjectName("addwgt"); // addWgt->setMinimumSize(QSize(580, 50)); // addWgt->setMaximumSize(QSize(960, 50)); // addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); ui->layoutFrame_0->hide(); ui->addLytWidget->hide(); // QHBoxLayout *addLyt = new QHBoxLayout; // QLabel * iconLabel = new QLabel(); // QLabel * textLabel = new QLabel(tr("Install layouts")); // QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); // iconLabel->setPixmap(pixgray); // addLyt->addWidget(iconLabel); // addLyt->addWidget(textLabel); // addLyt->addStretch(); // addWgt->setLayout(addLyt); // 悬浮改变Widget状态 // connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname) { // Q_UNUSED(mname); // QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); // iconLabel->setPixmap(pixgray); // textLabel->setStyleSheet("color: palette(base);"); // }); // 还原状态 // connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname) { // Q_UNUSED(mname); // QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); // iconLabel->setPixmap(pixgray); // textLabel->setStyleSheet("color: palette(windowText);"); // }); // ui->addLyt->addWidget(addWgt); // 隐藏未开发功能 ui->repeatFrame_5->hide(); // 重复输入开关按钮 keySwitchBtn = new SwitchButton(pluginWidget); ui->enableHorLayout->addWidget(keySwitchBtn); // 按键提示开关按钮 tipKeyboardSwitchBtn = new SwitchButton(pluginWidget); ui->tipKeyboardHorLayout->addWidget(tipKeyboardSwitchBtn); // 小键盘开关按钮 numLockSwitchBtn = new SwitchButton(pluginWidget); ui->numLockHorLayout->addWidget(numLockSwitchBtn); } void KeyboardControl::setupConnect(){ connect(keySwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked) { setKeyboardVisible(checked); settings->set(REPEAT_KEY, checked); }); connect(ui->delayHorSlider, &QSlider::valueChanged, this, [=](int value) { settings->set(DELAY_KEY, value); }); connect(ui->speedHorSlider, &QSlider::valueChanged, this, [=](int value) { settings->set(RATE_KEY, value); }); connect(settings,&QGSettings::changed,this,[=](const QString &key) { if(key == "rate") { ui->speedHorSlider->setValue(settings->get(RATE_KEY).toInt()); } else if(key == "repeat") { keySwitchBtn->setChecked(settings->get(REPEAT_KEY).toBool()); setKeyboardVisible(keySwitchBtn->isChecked()); } else if(key == "delay") { ui->delayHorSlider->setValue(settings->get(DELAY_KEY).toInt()); } }); connect(osdSettings,&QGSettings::changed,this,[=](const QString &key) { if(key == "showLockTip") { tipKeyboardSwitchBtn->blockSignals(true); tipKeyboardSwitchBtn->setChecked(osdSettings->get(CC_KEYBOARD_OSD_KEY).toBool()); tipKeyboardSwitchBtn->blockSignals(false); } }); // connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname) { // Q_UNUSED(mname); // KbdLayoutManager * templayoutManager = new KbdLayoutManager; // templayoutManager->exec(); // }); // connect(ui->resetBtn, &QPushButton::clicked, this, [=] { // kbdsettings->reset(KBD_LAYOUTS_KEY); // if ("zh_CN" == QLocale::system().name()) { // kbdsettings->set(KBD_LAYOUTS_KEY, "cn"); // } else { // kbdsettings->set(KBD_LAYOUTS_KEY, "us"); // } // }); connect(ui->inputSettingsBtn, &QPushButton::clicked, this, [=]{ QProcess process; process.startDetached("fcitx-config-gtk3"); }); // connect(kbdsettings, &QGSettings::changed, [=](QString key) { // if (key == KBD_LAYOUTS_KEY) // rebuildLayoutsComBox(); // }); connect(tipKeyboardSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked) { osdSettings->set(CC_KEYBOARD_OSD_KEY, checked); }); //#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) // connect(ui->layoutsComBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ //#else // connect(ui->layoutsComBox, QOverload::of(&QComboBox::currentIndexChanged), [=](int index) { //#endif // QStringList layoutsList; // layoutsList.append(ui->layoutsComBox->currentData(Qt::UserRole).toString()); // for (int i = 0; i < ui->layoutsComBox->count(); i++){ // QString id = ui->layoutsComBox->itemData(i, Qt::UserRole).toString(); // if (i != index) //跳过当前item // layoutsList.append(id); // } // kbdsettings->set(KBD_LAYOUTS_KEY, layoutsList); // }); } void KeyboardControl::initGeneralStatus() { //设置按键重复状态 keySwitchBtn->setChecked(settings->get(REPEAT_KEY).toBool()); setKeyboardVisible(keySwitchBtn->isChecked()); //设置按键重复的延时 ui->delayHorSlider->setValue(settings->get(DELAY_KEY).toInt()); //设置按键重复的速度 ui->speedHorSlider->setValue(settings->get(RATE_KEY).toInt()); tipKeyboardSwitchBtn->blockSignals(true); tipKeyboardSwitchBtn->setChecked(osdSettings->get(CC_KEYBOARD_OSD_KEY).toBool()); tipKeyboardSwitchBtn->blockSignals(false); } void KeyboardControl::rebuildLayoutsComBox() { // QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); // ui->layoutsComBox->blockSignals(true); //清空键盘布局下拉列表 // ui->layoutsComBox->clear(); //重建键盘布局下拉列表 // for (QString layout : layouts) { // ui->layoutsComBox->addItem(layoutmanagerObj->kbd_get_description_by_id(const_cast(layout.toLatin1().data())), layout); // } // ui->layoutsComBox->blockSignals(false); // if (0 == ui->layoutsComBox->count()) { // ui->layoutsComBox->setVisible(false); // } else { // ui->layoutsComBox->setVisible(true); // } } void KeyboardControl::setKeyboardVisible(bool checked) { ui->repeatFrame_1->setVisible(checked); ui->repeatFrame_2->setVisible(checked); ui->repeatFrame_3->setVisible(checked); } ukui-control-center/plugins/devices/keyboard/org.ukui.control-center.keybinding.gschema.xml0000644000175000017500000000137214201663671031275 0ustar fengfeng '' Keybinding Keybinding associated with a custom shortcut. '' Command Command associated with a custom keybinding. '' Name Description associated with a custom keybinding. ukui-control-center/plugins/devices/keyboard/tastenbrett.cpp0000644000175000017500000000405014201663671023362 0ustar fengfeng/* Copyright 2019 Harald Sitter 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 . */ #include "tastenbrett.h" #include #include #include #include QString Tastenbrett::path() { static QString path; if (!path.isNull()) { return path; } // Find relative to KCM (when run from build dir) path = QStandardPaths::findExecutable("tastenbrett", { qEnvironmentVariable("QT_PLUGIN_PATH"), qApp->applicationDirPath() }); if (!path.isNull()) { return path; } return QStandardPaths::findExecutable("tastenbrett"); } bool Tastenbrett::exists() { return !path().isNull(); } void Tastenbrett::launch(const QString &model, const QString &layout, const QString &variant, const QString &options, const QString &title) { if (!exists()) { return; } QProcess p; p.setProgram(path()); QStringList args { "--model", model, "--layout", layout, "--variant", variant, "--options", options }; if (!title.isEmpty()) { args << "-title" << title; } qDebug() << args; p.setArguments(args); p.setProcessChannelMode(QProcess::ForwardedChannels); p.startDetached(); } ukui-control-center/plugins/devices/keyboard/kbdlayoutmanager.ui0000644000175000017500000001705714201663671024222 0ustar fengfeng KbdLayoutManager 0 0 742 432 742 432 742 432 Form 30 25 35 25 10 330 0 330 16777215 10 C buttonGroup 0 0 0 0 0 0 32 16777215 32 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Fixed 20 20 L buttonGroup 0 0 0 0 0 0 32 16777215 32 Qt::Horizontal 40 20 Qt::Vertical 20 40 10 Variant 0 32 16777215 32 Qt::Horizontal 40 20 0 32 16777215 32 Add Qt::Vertical 20 40 ukui-control-center/plugins/devices/keyboard/kbdlayoutmanager.cpp0000644000175000017500000003160114201663716024356 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "kbdlayoutmanager.h" #include "ui_layoutmanager.h" #include "preview/keyboardpainter.h" #include "CloseButton/closebutton.h" #include #include #include extern "C" { #include #include } #define MAXNUM 4 #define KBD_LAYOUTS_SCHEMA "org.mate.peripherals-keyboard-xkb.kbd" #define KBD_LAYOUTS_KEY "layouts" XklEngine * engine; XklConfigRegistry * config_registry; static void kbd_set_countries(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list); static void kbd_set_languages(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list); static void kbd_set_available_countries(XklConfigRegistry *config_registry, XklConfigItem * parent_config_item, XklConfigItem *config_item, QList *list); static void kbd_set_available_languages(XklConfigRegistry *config_registry, XklConfigItem * parent_config_item, XklConfigItem *config_item, QList *list); QList languages; QList countries; QStringList availablelayoutsList; extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); KbdLayoutManager::KbdLayoutManager(QWidget *parent) : QDialog(parent), ui(new Ui::LayoutManager) { ui->setupUi(this); this->setWindowTitle(tr("Add Layout")); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); ui->titleLabel->setStyleSheet("QLabel{color: palette(windowText);}"); ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); ui->variantFrame->setFrameShape(QFrame::Shape::Box); configRegistry(); const QByteArray id(KBD_LAYOUTS_SCHEMA); if (QGSettings::isSchemaInstalled(id)){ kbdsettings = new QGSettings(id); setupComponent(); setupConnect(); } } KbdLayoutManager::~KbdLayoutManager() { delete ui; ui = nullptr; if (QGSettings::isSchemaInstalled(KBD_LAYOUTS_SCHEMA)){ delete kbdsettings; kbdsettings = nullptr; } } void KbdLayoutManager::configRegistry(){ engine = xkl_engine_get_instance (QX11Info::display()); config_registry = xkl_config_registry_get_instance (engine); xkl_config_registry_load (config_registry, false); xkl_config_registry_foreach_country(config_registry,(ConfigItemProcessFunc)kbd_set_countries, NULL); xkl_config_registry_foreach_language(config_registry,(ConfigItemProcessFunc)kbd_set_languages, NULL); } void KbdLayoutManager::setupComponent(){ ui->countryRadioButton->setChecked(true); //设置listwidget无点击 ui->listWidget->setFocusPolicy(Qt::NoFocus); ui->listWidget->setSelectionMode(QAbstractItemView::NoSelection); rebuildSelectListWidget(); rebuildVariantCombo(); rebuild_listwidget(); } void KbdLayoutManager::setupConnect(){ connect(ui->closeBtn, &CloseButton::clicked, [=]{ close(); }); connect(ui->cancelBtn, &QPushButton::clicked, [=]{ close(); }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->buttonGroup, static_cast(&QButtonGroup::buttonClicked), [=]{ #else connect(ui->buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), [=]{ #endif rebuildSelectListWidget(); rebuildVariantCombo(); }); connect(ui->selectListWidget, &QListWidget::currentItemChanged, [=]{ rebuildVariantCombo(); }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->variantComboBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ #else connect(ui->variantComboBox, QOverload::of(&QComboBox::currentIndexChanged), [=](int index) { #endif Q_UNUSED(index) if (index != -1) installedNoSame(); }); connect(ui->installBtn, &QPushButton::clicked, this, [=]{ QString layout = ui->variantComboBox->currentData().toString(); QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); layouts.append(layout); kbdsettings->set(KBD_LAYOUTS_KEY, layouts); rebuild_listwidget(); }); connect(ui->PreBtn, &QPushButton::clicked, this, &KbdLayoutManager::preview); } void KbdLayoutManager::installedNoSame(){ //最多4个布局,来自GTK控制面板,原因未知 QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); if (layouts.length() < MAXNUM && !layouts.contains(ui->variantComboBox->currentData(Qt::UserRole).toString())) ui->installBtn->setEnabled(true); else ui->installBtn->setEnabled(false); } void KbdLayoutManager::rebuildSelectListWidget(){ ui->selectListWidget->blockSignals(true); ui->selectListWidget->clear(); if (ui->countryRadioButton->isChecked()){ for (Layout keylayout : countries){ if (keylayout.name == "TW") continue; QListWidgetItem * item = new QListWidgetItem(ui->selectListWidget); item->setText(keylayout.desc); item->setData(Qt::UserRole, keylayout.name); ui->selectListWidget->addItem(item); } } else if (ui->languageRadioButton->isChecked()){ for (Layout keylayout : languages){ QListWidgetItem * item = new QListWidgetItem(ui->selectListWidget); item->setText(keylayout.desc); item->setData(Qt::UserRole, keylayout.name); ui->selectListWidget->addItem(item); } } ui->selectListWidget->setCurrentRow(0); ui->selectListWidget->blockSignals(false); } void KbdLayoutManager::rebuildVariantCombo(){ QString id = ui->selectListWidget->currentItem()->data(Qt::UserRole).toString(); availablelayoutsList.clear(); char * iid = id.toLatin1().data(); if (ui->countryRadioButton->isChecked()) kbd_trigger_available_countries(iid); else if (ui->languageRadioButton->isChecked()) kbd_trigger_available_languages(iid); ui->variantComboBox->clear(); for (QString name : availablelayoutsList){ QString desc = kbd_get_description_by_id(const_cast(name.toLatin1().data())); ui->variantComboBox->blockSignals(true); ui->variantComboBox->addItem(desc, name); ui->variantComboBox->blockSignals(false); } installedNoSame(); } void KbdLayoutManager::rebuild_listwidget(){ installedNoSame(); ui->listWidget->clear(); QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); for (QString layout : layouts){ QString desc = kbd_get_description_by_id(const_cast(layout.toLatin1().data())); //自定义widget QWidget * layoutWidget = new QWidget(); layoutWidget->setAttribute(Qt::WA_DeleteOnClose); QHBoxLayout * mainHLayout = new QHBoxLayout(layoutWidget); QLabel * layoutLabel = new QLabel(layoutWidget); QPushButton * layoutdelBtn = new QPushButton(layoutWidget); layoutdelBtn->setText(tr("Del")); connect(layoutdelBtn, &QPushButton::clicked, this, [=]{ QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); layouts.removeOne(layout); kbdsettings->set(KBD_LAYOUTS_KEY, layouts); rebuild_listwidget(); }); mainHLayout->addWidget(layoutLabel); mainHLayout->addStretch(); mainHLayout->addWidget(layoutdelBtn); layoutWidget->setLayout(mainHLayout); QListWidgetItem * item = new QListWidgetItem(ui->listWidget); item->setData(Qt::UserRole, layout); item->setSizeHint(QSize(ui->listWidget->width(), 50)); layoutLabel->setText(desc); QFontMetrics fontWidth(layoutLabel->font()); QString elideNote = fontWidth.elidedText(desc, Qt::ElideRight, 100); layoutLabel->setText(elideNote); layoutLabel->setToolTip(desc); ui->listWidget->addItem(item); ui->listWidget->setItemWidget(item, layoutWidget); } if (!ui->listWidget->count()) { ui->installedFrame->setVisible(false); } else { ui->installedFrame->setVisible(true); } } void KbdLayoutManager::preview() { QString variantID; QString layoutID = ui->variantComboBox->currentData(Qt::UserRole).toString(); QStringList layList = layoutID.split('\t'); for (int i = 0; i < layList.length(); i++) { if (0 == i) { layoutID = layList.at(0); } if (1 == i) { variantID = layList.at(1); } } KeyboardPainter* layoutPreview = new KeyboardPainter(); qDebug() << " layoutID:" << layoutID << "variantID:" << variantID <generateKeyboardLayout(layoutID, variantID, "pc104", ""); layoutPreview->setWindowTitle(tr("Keyboard Preview")); layoutPreview->setModal(true); layoutPreview->exec(); } void KbdLayoutManager::kbd_trigger_available_countries(char *countryid){ xkl_config_registry_foreach_country_variant (config_registry, countryid, (TwoConfigItemsProcessFunc)kbd_set_available_countries, NULL); } void KbdLayoutManager::kbd_trigger_available_languages(char *languageid){ xkl_config_registry_foreach_language_variant (config_registry, languageid, (TwoConfigItemsProcessFunc)kbd_set_available_languages, NULL); } QString KbdLayoutManager::kbd_get_description_by_id(const char *visible){ char *l, *sl, *v, *sv; if (matekbd_keyboard_config_get_descriptions(config_registry, visible, &sl, &l, &sv, &v)) visible = matekbd_keyboard_config_format_full_layout (l, v); return QString(const_cast(visible)); } static void kbd_set_countries(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list){ Q_UNUSED(config_registry); Q_UNUSED(list); Layout item; item.desc = config_item->description; item.name = config_item->name; countries.append(item); } static void kbd_set_languages(XklConfigRegistry *config_registry, XklConfigItem *config_item, QList *list){ Q_UNUSED(config_registry); Q_UNUSED(list); Layout item; item.desc = config_item->description; item.name = config_item->name; languages.append(item); } static void kbd_set_available_countries(XklConfigRegistry *config_registry, XklConfigItem * parent_config_item, XklConfigItem *config_item, QList *list){ Q_UNUSED(config_registry); Q_UNUSED(list); const gchar *xkb_id = config_item ? matekbd_keyboard_config_merge_items (parent_config_item->name, config_item->name) : parent_config_item->name; availablelayoutsList.append(QString(const_cast(xkb_id))); } static void kbd_set_available_languages(XklConfigRegistry *config_registry, XklConfigItem *parent_config_item, XklConfigItem *config_item, QList *list){ Q_UNUSED(list); kbd_set_available_countries(config_registry, parent_config_item, config_item, NULL); } void KbdLayoutManager::paintEvent(QPaintEvent *event){ Q_UNUSED(event); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QPainterPath rectPath; rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); // 画一个黑底 QPixmap pixmap(this->rect().size()); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); // 模糊这个黑底 QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); pixmapPainter2.setRenderHint(QPainter::Antialiasing); pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); pixmapPainter2.setPen(Qt::transparent); pixmapPainter2.setBrush(Qt::transparent); pixmapPainter2.drawPath(rectPath); // 绘制阴影 p.drawPixmap(this->rect(), pixmap, pixmap.rect()); // 绘制一个背景 p.save(); p.fillPath(rectPath,palette().color(QPalette::Base)); p.restore(); } ukui-control-center/plugins/devices/keyboard/keyboardcontrol.h0000644000175000017500000000444314201663716023677 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef KEYBOARDCONTROL_H #define KEYBOARDCONTROL_H #include #include #include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" #include "HoverWidget/hoverwidget.h" #include "ImageUtil/imageutil.h" #include "kbdlayoutmanager.h" namespace Ui { class KeyboardControl; } class QGSettings; class KeyboardControl : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: KeyboardControl(); ~KeyboardControl() Q_DECL_OVERRIDE; QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; void setupStylesheet(); void setupComponent(); void setupConnect(); void initGeneralStatus(); void rebuildLayoutsComBox(); void setKeyboardVisible(bool checked); private: Ui::KeyboardControl *ui; QString pluginName; int pluginType; QWidget * pluginWidget; QGSettings * settings; // QGSettings * kbdsettings; QGSettings * osdSettings; SwitchButton * keySwitchBtn; SwitchButton * tipKeyboardSwitchBtn; SwitchButton * numLockSwitchBtn; KbdLayoutManager * layoutmanagerObj; HoverWidget * addWgt; bool settingsCreate; bool mFirstLoad; }; #endif // KEYBOARDCONTROL_H ukui-control-center/plugins/devices/keyboard/layoutmanager.ui0000644000175000017500000003471414201663716023540 0ustar fengfeng LayoutManager 0 0 572 594 572 594 572 594 Dialog 0 0 15 15 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0 36 16777215 36 QFrame::StyledPanel QFrame::Raised 0 0 0 0 0 0 16 0 0 Manager Keyboard Layout Qt::Horizontal 40 20 32 32 32 32 24 32 16 32 48 24 240 0 240 16777215 QFrame::StyledPanel QFrame::Raised 16 0 0 0 0 32 0 0 Language buttonGroup 0 0 Country buttonGroup Qt::Horizontal 40 20 QFrame::StyledPanel QFrame::Raised 0 0 Variant 240 0 240 16777215 QFrame::StyledPanel QFrame::Raised 16 0 0 0 0 0 0 Layout installed Qt::Vertical QSizePolicy::Fixed 20 24 8 120 36 120 36 Preview Qt::Horizontal 40 20 120 36 120 36 Cancel 120 36 120 36 Install TitleLabel QLabel
    Label/titlelabel.h
    CloseButton QPushButton
    CloseButton/closebutton.h
    ukui-control-center/plugins/network/0000755000175000017500000000000014201663716016567 5ustar fengfengukui-control-center/plugins/network/network.pro0000644000175000017500000000010414201663716020775 0ustar fengfengTEMPLATE = subdirs SUBDIRS = \ netconnect \ vpn \ proxy ukui-control-center/plugins/network/proxy/0000755000175000017500000000000014201663716017750 5ustar fengfengukui-control-center/plugins/network/proxy/proxy.h0000644000175000017500000000550314201663716021305 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef PROXY_H #define PROXY_H #include #include #include #include #include "certificationdialog.h" #include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif #include #include struct GSData { QString key; QString schema; }; typedef enum{ NONE, MANUAL, AUTO }ProxyMode; //自定义类型使用QVariant需要使用 Q_DECLARE_METATYPE 注册 Q_DECLARE_METATYPE(ProxyMode) Q_DECLARE_METATYPE(GSData) namespace Ui { class Proxy; } class Proxy : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Proxy(); ~Proxy(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void initSearchText(); void setupStylesheet(); void setupComponent(); void setupConnect(); void initProxyModeStatus(); void initAutoProxyStatus(); void initManualProxyStatus(); void initIgnoreHostStatus(); void manualProxyTextChanged(QString txt); void showCertificationDialog(); int _getCurrentProxyMode(); void _setSensitivity(); private: Ui::Proxy *ui; QString pluginName; int pluginType; QWidget * pluginWidget; private: SwitchButton * autoSwitchBtn; SwitchButton * manualSwitchBtn; QGSettings * proxysettings; QGSettings * httpsettings; QGSettings * securesettings; QGSettings * ftpsettings; QGSettings * sockssettings; bool settingsCreate; bool mFirstLoad; public slots: void proxyModeChangedSlot(bool checked); }; #endif // PROXY_H ukui-control-center/plugins/network/proxy/proxy.cpp0000644000175000017500000003223414201663716021641 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "proxy.h" #include "ui_proxy.h" #include #define PROXY_SCHEMA "org.gnome.system.proxy" #define PROXY_MODE_KEY "mode" #define PROXY_AUTOCONFIG_URL_KEY "autoconfig-url" #define IGNORE_HOSTS_KEY "ignore-hosts" #define HTTP_PROXY_SCHEMA "org.gnome.system.proxy.http" #define HTTP_USE_AUTH_KEY "use-authentication" #define HTTP_AUTH_USER_KEY "authentication-user" #define HTTP_AUTH_PASSWD_KEY "authentication-password" #define HTTPS_PROXY_SCHEMA "org.gnome.system.proxy.https" #define FTP_PROXY_SCHEMA "org.gnome.system.proxy.ftp" #define SOCKS_PROXY_SCHEMA "org.gnome.system.proxy.socks" #define PROXY_HOST_KEY "host" #define PROXY_PORT_KEY "port" Proxy::Proxy() : mFirstLoad(true) { ui = new Ui::Proxy; pluginName = tr("Proxy"); pluginType = NETWORK; } Proxy::~Proxy() { if (!mFirstLoad) { delete ui; ui = nullptr; if (settingsCreate){ delete proxysettings; proxysettings = nullptr; delete httpsettings; httpsettings = nullptr; delete securesettings; securesettings = nullptr; delete ftpsettings; ftpsettings = nullptr; delete sockssettings; sockssettings = nullptr; } } } QString Proxy::get_plugin_name() { return pluginName; } int Proxy::get_plugin_type() { return pluginType; } QWidget *Proxy::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); settingsCreate = false; const QByteArray id(PROXY_SCHEMA); const QByteArray idd(HTTP_PROXY_SCHEMA); const QByteArray iddd(HTTPS_PROXY_SCHEMA); const QByteArray iid(FTP_PROXY_SCHEMA); const QByteArray iiid(SOCKS_PROXY_SCHEMA); initSearchText(); setupStylesheet(); setupComponent(); if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(idd) && QGSettings::isSchemaInstalled(iddd) && QGSettings::isSchemaInstalled(iid) && QGSettings::isSchemaInstalled(iiid)){ settingsCreate = true; proxysettings = new QGSettings(id); httpsettings = new QGSettings(idd); securesettings = new QGSettings(iddd); ftpsettings = new QGSettings(iid); sockssettings = new QGSettings(iiid); setupConnect(); initProxyModeStatus(); initAutoProxyStatus(); initManualProxyStatus(); initIgnoreHostStatus(); } else { qCritical() << "Xml needed by Proxy is not installed"; } } return pluginWidget; } void Proxy::plugin_delay_control(){ } const QString Proxy::name() const { return QStringLiteral("proxy"); } void Proxy::initSearchText() { //~ contents_path /proxy/Auto proxy ui->autoLabel->setText(tr("Auto proxy")); //~ contents_path /proxy/Manual proxy ui->manualLabel->setText(tr("Manual proxy")); } void Proxy::setupStylesheet(){ } void Proxy::setupComponent(){ //添加自动配置代理开关按钮 autoSwitchBtn = new SwitchButton(ui->autoFrame); autoSwitchBtn->setObjectName("auto"); ui->autoHorLayout->addWidget(autoSwitchBtn); //添加手动配置代理开关按钮 manualSwitchBtn = new SwitchButton(ui->manualFrame); manualSwitchBtn->setObjectName("manual"); ui->manualHorLayout->addWidget(manualSwitchBtn); ui->cetificationBtn->hide(); //QLineEdit 设置数据 GSData httpHostData; httpHostData.schema = HTTP_PROXY_SCHEMA; httpHostData.key = PROXY_HOST_KEY; ui->httpHostLineEdit->setProperty("gData", QVariant::fromValue(httpHostData)); GSData httpsHostData; httpsHostData.schema = HTTPS_PROXY_SCHEMA; httpsHostData.key = PROXY_HOST_KEY; ui->httpsHostLineEdit->setProperty("gData", QVariant::fromValue(httpsHostData)); GSData ftpHostData; ftpHostData.schema = FTP_PROXY_SCHEMA; ftpHostData.key = PROXY_HOST_KEY; ui->ftpHostLineEdit->setProperty("gData", QVariant::fromValue(ftpHostData)); GSData socksHostData; socksHostData.schema = SOCKS_PROXY_SCHEMA; socksHostData.key = PROXY_HOST_KEY; ui->socksHostLineEdit->setProperty("gData", QVariant::fromValue(socksHostData)); GSData httpPortData; httpPortData.schema = HTTP_PROXY_SCHEMA; httpPortData.key = PROXY_PORT_KEY; ui->httpPortLineEdit->setProperty("gData", QVariant::fromValue(httpPortData)); GSData httpsPortData; httpsPortData.schema = HTTPS_PROXY_SCHEMA; httpsPortData.key = PROXY_PORT_KEY; ui->httpsPortLineEdit->setProperty("gData", QVariant::fromValue(httpsPortData)); GSData ftpPortData; ftpPortData.schema = FTP_PROXY_SCHEMA; ftpPortData.key = PROXY_PORT_KEY; ui->ftpPortLineEdit->setProperty("gData", QVariant::fromValue(ftpPortData)); GSData socksPortData; socksPortData.schema = SOCKS_PROXY_SCHEMA; socksPortData.key = PROXY_PORT_KEY; ui->socksPortLineEdit->setProperty("gData", QVariant::fromValue(socksPortData)); } void Proxy::setupConnect(){ connect(autoSwitchBtn, SIGNAL(checkedChanged(bool)), this, SLOT(proxyModeChangedSlot(bool))); connect(manualSwitchBtn, SIGNAL(checkedChanged(bool)), this, SLOT(proxyModeChangedSlot(bool))); connect(ui->urlLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){proxysettings->set(PROXY_AUTOCONFIG_URL_KEY, QVariant(txt));}); connect(ui->httpHostLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->httpsHostLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->ftpHostLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->socksHostLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->httpPortLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->httpsPortLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->ftpPortLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->socksPortLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); // connect(ui->cetificationBtn, &QPushButton::clicked, [=](bool checked){ // Q_UNUSED(checked) // showCertificationDialog(); // }); connect(ui->ignoreHostTextEdit, &QTextEdit::textChanged, this, [=](){ QString text = ui->ignoreHostTextEdit->toPlainText(); QStringList hostStringList = text.split(";"); proxysettings->set(IGNORE_HOSTS_KEY, QVariant(hostStringList)); }); } void Proxy::initProxyModeStatus(){ int mode = _getCurrentProxyMode(); autoSwitchBtn->blockSignals(true); manualSwitchBtn->blockSignals(true); if (mode == AUTO){ autoSwitchBtn->setChecked(true); } else if (mode == MANUAL){ manualSwitchBtn->setChecked(true); } else{ autoSwitchBtn->setChecked(false); manualSwitchBtn->setChecked(false); } autoSwitchBtn->blockSignals(false); manualSwitchBtn->blockSignals(false); _setSensitivity(); } void Proxy::initAutoProxyStatus(){ ui->urlLineEdit->blockSignals(true); //设置当前url QString urlString = proxysettings->get(PROXY_AUTOCONFIG_URL_KEY).toString(); ui->urlLineEdit->setText(urlString); ui->urlLineEdit->blockSignals(false); } void Proxy::initManualProxyStatus(){ //信号阻塞 ui->httpHostLineEdit->blockSignals(true); ui->httpsHostLineEdit->blockSignals(true); ui->ftpHostLineEdit->blockSignals(true); ui->socksHostLineEdit->blockSignals(true); ui->httpPortLineEdit->blockSignals(true); ui->httpsPortLineEdit->blockSignals(true); ui->ftpPortLineEdit->blockSignals(true); ui->socksPortLineEdit->blockSignals(true); //HTTP QString httphost = httpsettings->get(PROXY_HOST_KEY).toString(); ui->httpHostLineEdit->setText(httphost); int httpport = httpsettings->get(PROXY_PORT_KEY).toInt(); ui->httpPortLineEdit->setText(QString::number(httpport)); //HTTPS QString httpshost = securesettings->get(PROXY_HOST_KEY).toString(); ui->httpsHostLineEdit->setText(httpshost); int httpsport = securesettings->get(PROXY_PORT_KEY).toInt(); ui->httpsPortLineEdit->setText(QString::number(httpsport)); //FTP QString ftphost = ftpsettings->get(PROXY_HOST_KEY).toString(); ui->ftpHostLineEdit->setText(ftphost); int ftppost = ftpsettings->get(PROXY_PORT_KEY).toInt(); ui->ftpPortLineEdit->setText(QString::number(ftppost)); //SOCKS QString sockshost = sockssettings->get(PROXY_HOST_KEY).toString(); ui->socksHostLineEdit->setText(sockshost); int socksport = sockssettings->get(PROXY_PORT_KEY).toInt(); ui->socksPortLineEdit->setText(QString::number(socksport)); //解除信号阻塞 ui->httpHostLineEdit->blockSignals(false); ui->httpsHostLineEdit->blockSignals(false); ui->ftpHostLineEdit->blockSignals(false); ui->socksHostLineEdit->blockSignals(false); ui->httpPortLineEdit->blockSignals(false); ui->httpsPortLineEdit->blockSignals(false); ui->ftpPortLineEdit->blockSignals(false); ui->socksPortLineEdit->blockSignals(false); } void Proxy::initIgnoreHostStatus(){ ui->ignoreHostTextEdit->blockSignals(true); //设置当前ignore host QStringList ignorehost = proxysettings->get(IGNORE_HOSTS_KEY).toStringList(); ui->ignoreHostTextEdit->setPlainText(ignorehost.join(";")); ui->ignoreHostTextEdit->blockSignals(false); } int Proxy::_getCurrentProxyMode(){ GSettings * proxygsettings; proxygsettings = g_settings_new(PROXY_SCHEMA); int mode = g_settings_get_enum(proxygsettings, PROXY_MODE_KEY); g_object_unref(proxygsettings); return mode; } void Proxy::_setSensitivity(){ //自动配置代理界面敏感性 bool autoChecked = autoSwitchBtn->isChecked(); ui->urlFrame->setVisible(autoChecked); //手动配置代理界面敏感性 bool manualChecked = manualSwitchBtn->isChecked(); ui->httpFrame->setVisible(manualChecked); ui->httpsFrame->setVisible(manualChecked); ui->ftpFrame->setVisible(manualChecked); ui->socksFrame->setVisible(manualChecked); } void Proxy::showCertificationDialog(){ QDialog * certificationDialog = new CertificationDialog(pluginWidget); certificationDialog->setAttribute(Qt::WA_DeleteOnClose); certificationDialog->show(); } void Proxy::manualProxyTextChanged(QString txt){ //获取被修改控件 QObject * pobject = this->sender(); QLineEdit * who = dynamic_cast(pobject); //获取控件保存的用户数据 GSData currentData = who->property("gData").value(); QString schema = currentData.schema; QString key = currentData.key; //构建临时QGSettings const QByteArray id = schema.toUtf8(); const QByteArray iidd(id.data()); QGSettings * setting = new QGSettings(iidd); setting->set(key, QVariant(txt)); delete setting; setting = nullptr; } void Proxy::proxyModeChangedSlot(bool checked){ GSettings * proxygsettings; proxygsettings = g_settings_new(PROXY_SCHEMA); //两个switchbutton要达到互斥的效果,自定义按钮暂时未支持添加buttongroup QObject * object = QObject::sender(); if (object->objectName() == "auto"){ //区分哪个switchbutton if (checked){ if (manualSwitchBtn->isChecked()) manualSwitchBtn->setChecked(false); g_settings_set_enum(proxygsettings, PROXY_MODE_KEY, AUTO); } else{ if (!manualSwitchBtn->isChecked()) g_settings_set_enum(proxygsettings, PROXY_MODE_KEY, NONE); } } else{ if (checked){ if (autoSwitchBtn->isChecked()) autoSwitchBtn->setChecked(false); g_settings_set_enum(proxygsettings, PROXY_MODE_KEY, MANUAL); } else{ if (!autoSwitchBtn->isChecked()) g_settings_set_enum(proxygsettings, PROXY_MODE_KEY, NONE); } } g_object_unref(proxygsettings); _setSensitivity(); } ukui-control-center/plugins/network/proxy/proxy.pro0000644000175000017500000000200314201663716021646 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-06-29T13:59:06 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(proxy) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt ##加载gio库和gio-unix库,用于获取和设置enum类型的gsettings CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gio-2.0 \ gio-unix-2.0 \ gsettings-qt \ #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ proxy.cpp \ certificationdialog.cpp HEADERS += \ proxy.h \ certificationdialog.h FORMS += \ proxy.ui \ certificationdialog.ui INSTALLS += targetukui-control-center/plugins/network/proxy/proxy.ui0000644000175000017500000007131314201663716021475 0ustar fengfeng Proxy 0 0 800 724 0 0 16777215 16777215 Proxy 2 0 0 32 30 0 0 Auto Proxy true Qt::Vertical QSizePolicy::Fixed 20 6 550 50 960 50 QFrame::Box 0 0 0 0 0 0 16 16 0 0 Auto proxy true Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 0 0 0 0 16 16 0 0 Auto url true Qt::Horizontal 40 20 320 32 320 32 Qt::Vertical QSizePolicy::Fixed 20 38 0 0 Manual Proxy true Qt::Vertical QSizePolicy::Fixed 20 6 550 50 960 50 QFrame::Box 0 0 0 0 0 0 16 16 0 0 Manual proxy true Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 0 0 0 0 8 16 16 0 0 115 0 115 16777215 Http Proxy 160 32 160 32 Qt::Horizontal QSizePolicy::Fixed 8 20 0 0 Port 122 32 122 32 80 32 80 32 Cetification Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 0 0 0 0 8 16 16 0 0 115 0 115 16777215 Https Proxy 160 32 160 32 Qt::Horizontal QSizePolicy::Fixed 8 20 0 0 Port 122 32 122 32 Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 0 0 0 0 8 16 16 0 0 115 0 115 16777215 Ftp Proxy 160 32 160 32 Qt::Horizontal QSizePolicy::Fixed 8 20 0 0 Port 122 32 122 32 Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 0 0 0 0 0 8 16 16 0 0 115 0 115 16777215 Socks Proxy 160 32 160 32 Qt::Horizontal QSizePolicy::Fixed 8 20 0 0 Port 122 32 122 32 Qt::Horizontal 40 20 550 180 960 180 QFrame::Box 0 0 0 0 0 8 16 24 16 24 0 0 List of ignored hosts. more than one entry, please separate with english semicolon(;) true Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/network/proxy/certificationdialog.cpp0000644000175000017500000000567514201663716024474 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "certificationdialog.h" #include "ui_certificationdialog.h" #include #include "SwitchButton/switchbutton.h" #include CertificationDialog::CertificationDialog(QWidget *parent) : QDialog(parent), ui(new Ui::CertificationDialog) { ui->setupUi(this); this->setWindowTitle(tr("Certification")); const QByteArray id(HTTP_PROXY_SCHEMA); cersettings = new QGSettings(id); component_init(); status_init(); } CertificationDialog::~CertificationDialog() { delete ui; ui = nullptr; delete cersettings; cersettings = nullptr; } void CertificationDialog::component_init(){ ui->pwdLineEdit->setEchoMode(QLineEdit::Password); activeSwitchBtn = new SwitchButton; activeSwitchBtn->setAttribute(Qt::WA_DeleteOnClose); ui->activeHLayout->addWidget(activeSwitchBtn); ui->activeHLayout->addStretch(); } void CertificationDialog::status_init(){ //获取认证状态 bool status = cersettings->get(HTTP_AUTH_KEY).toBool(); activeSwitchBtn->setChecked(status); ui->widget->setEnabled(status); //获取用户名密码 QString user = cersettings->get(HTTP_AUTH_USER_KEY).toString(); ui->userLineEdit->setText(user); QString pwd = cersettings->get(HTTP_AUTH_PASSWD_KEY).toString(); ui->pwdLineEdit->setText(pwd); connect(activeSwitchBtn, SIGNAL(checkedChanged(bool)), this, SLOT(active_status_changed_slot(bool))); connect(ui->closePushBtn, SIGNAL(released()), this, SLOT(close())); connect(ui->userLineEdit, SIGNAL(textChanged(QString)), this, SLOT(user_edit_changed_slot(QString))); connect(ui->pwdLineEdit, SIGNAL(textChanged(QString)), this, SLOT(pwd_edit_changed_slot(QString))); } void CertificationDialog::active_status_changed_slot(bool status){ ui->widget->setEnabled(status); cersettings->set(HTTP_AUTH_KEY, QVariant(status)); } void CertificationDialog::user_edit_changed_slot(QString edit){ cersettings->set(HTTP_AUTH_USER_KEY, QVariant(edit)); } void CertificationDialog::pwd_edit_changed_slot(QString edit){ cersettings->set(HTTP_AUTH_PASSWD_KEY, QVariant(edit)); } ukui-control-center/plugins/network/proxy/certificationdialog.h0000644000175000017500000000337314201663716024132 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef CERTIFICATIONDIALOG_H #define CERTIFICATIONDIALOG_H #include #define HTTP_PROXY_SCHEMA "org.gnome.system.proxy.http" #define HTTP_AUTH_KEY "use-authentication" #define HTTP_AUTH_USER_KEY "authentication-user" #define HTTP_AUTH_PASSWD_KEY "authentication-password" namespace Ui { class CertificationDialog; } class SwitchButton; class QGSettings; class CertificationDialog : public QDialog { Q_OBJECT public: explicit CertificationDialog(QWidget *parent = 0); ~CertificationDialog(); public: void component_init(); void status_init(); private: Ui::CertificationDialog *ui; QGSettings * cersettings; SwitchButton * activeSwitchBtn; private slots: void active_status_changed_slot(bool status); void user_edit_changed_slot(QString edit); void pwd_edit_changed_slot(QString edit); }; #endif // CERTIFICATIONDIALOG_H ukui-control-center/plugins/network/proxy/certificationdialog.ui0000644000175000017500000002377514201663671024330 0ustar fengfeng CertificationDialog 0 0 500 246 500 246 500 246 UserCertification 0 0 0 0 0 20 20 25 Qt::Vertical QSizePolicy::Fixed 20 10 10 20 0 0 UserCertification true 0 0 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 60 20 0 0 60 0 60 16777215 User: 180 0 180 16777215 Qt::Horizontal 40 20 0 Qt::Horizontal QSizePolicy::Fixed 60 20 0 0 60 0 60 16777215 Passwd: 180 0 180 16777215 Qt::Horizontal 40 20 Qt::Horizontal 40 20 Close Qt::Horizontal QSizePolicy::Fixed 40 20 Qt::Vertical QSizePolicy::Fixed 20 80 ukui-control-center/plugins/network/vpn/0000755000175000017500000000000014201663716017372 5ustar fengfengukui-control-center/plugins/network/vpn/vpn.h0000644000175000017500000000337114201663716020352 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef VPN_H #define VPN_H #include #include #include "shell/interface.h" #include "HoverWidget/hoverwidget.h" #include "ImageUtil/imageutil.h" namespace Ui { class Vpn; } class Vpn : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Vpn(); ~Vpn(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void initComponent(); void runExternalApp(); protected: // bool eventFilter(QObject *watched, QEvent *event); private: Ui::Vpn *ui; QString pluginName; int pluginType; QWidget * pluginWidget; HoverWidget * addWgt; bool mFirstLoad; }; #endif // VPN_H ukui-control-center/plugins/network/vpn/vpn.pro0000644000175000017500000000145114201663716020720 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-06-29T13:53:10 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets TEMPLATE = lib CONFIG += plugin \ += c++11 \ link_pkgconfig PKGCONFIG += gsettings-qt TARGET = $$qtLibraryTarget(vpn) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ LIBS += -lpolkit-qt5-core-1 #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ vpn.cpp HEADERS += \ vpn.h FORMS += \ vpn.ui INSTALLS += target ukui-control-center/plugins/network/vpn/vpn.cpp0000644000175000017500000001003614201663716020701 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "vpn.h" #include "ui_vpn.h" #include #include Vpn::Vpn() : mFirstLoad(true) { pluginName = tr("Vpn"); pluginType = NETWORK; } Vpn::~Vpn() { if (!mFirstLoad) { delete ui; ui = nullptr; } } QString Vpn::get_plugin_name(){ return pluginName; } int Vpn::get_plugin_type(){ return pluginType; } QWidget *Vpn::get_plugin_ui(){ if (mFirstLoad) { mFirstLoad = false; ui = new Ui::Vpn; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); initComponent(); } return pluginWidget; } void Vpn::plugin_delay_control(){ } const QString Vpn::name() const { return QStringLiteral("vpn"); } void Vpn::initComponent(){ addWgt = new HoverWidget(""); addWgt->setObjectName("addwgt"); addWgt->setMinimumSize(QSize(580, 50)); addWgt->setMaximumSize(QSize(960, 50)); QPalette pal; QBrush brush = pal.highlight(); //获取window的色值 QColor highLightColor = brush.color(); QString stringColor = QString("rgba(%1,%2,%3)") //叠加20%白色 .arg(highLightColor.red()*0.8 + 255*0.2) .arg(highLightColor.green()*0.8 + 255*0.2) .arg(highLightColor.blue()*0.8 + 255*0.2); addWgt->setStyleSheet(QString("HoverWidget#addwgt{background: palette(button);\ border-radius: 4px;}\ HoverWidget:hover:!pressed#addwgt{background: %1;\ border-radius: 4px;}").arg(stringColor)); QHBoxLayout *addLyt = new QHBoxLayout; QLabel * iconLabel = new QLabel(); //~ contents_path /vpn/Add vpn connect QLabel * textLabel = new QLabel(tr("Add vpn connect")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); iconLabel->setProperty("useIconHighlightEffect", true); iconLabel->setProperty("iconHighlightEffectMode", 1); addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname){ runExternalApp(); }); // 悬浮改变Widget状态 connect(addWgt, &HoverWidget::enterWidget, this, [=](){ iconLabel->setProperty("useIconHighlightEffect", false); iconLabel->setProperty("iconHighlightEffectMode", 0); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: white;"); }); // 还原状态 connect(addWgt, &HoverWidget::leaveWidget, this, [=](){ iconLabel->setProperty("useIconHighlightEffect", true); iconLabel->setProperty("iconHighlightEffectMode", 1); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: palette(windowText);"); }); ui->addLyt->addWidget(addWgt); } void Vpn::runExternalApp(){ QString cmd = "nm-connection-editor"; QProcess process(this); process.startDetached(cmd); } ukui-control-center/plugins/network/vpn/vpn.ui0000644000175000017500000000600514201663716020535 0ustar fengfeng Vpn 0 0 800 710 0 0 16777215 16777215 Vpn 8 0 0 32 60 0 0 Add Vpn Connect 550 60 960 60 0 0 0 0 0 8 0 8 Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/network/netconnect/0000755000175000017500000000000014201663716020727 5ustar fengfengukui-control-center/plugins/network/netconnect/netconnectwork.cpp0000644000175000017500000000356014201663716024502 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "netconnectwork.h" #include #include NetconnectWork::NetconnectWork() { } NetconnectWork::~NetconnectWork() { } void NetconnectWork::run(bool status) { QString wifiStatus = status ? "on" : "off"; QString program = "nmcli"; QStringList arg; arg << "radio" << "wifi" << wifiStatus; QProcess *nmcliCmd = new QProcess(this); nmcliCmd->start(program, arg); nmcliCmd->waitForFinished(); emit complete(); } bool NetconnectWork::getWifiIsOpen() { QDBusInterface interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus() ); // 获取当前wifi是否打开 QDBusReply m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); if (m_result.isValid()) { bool status = m_result.value().toBool(); return status; } else { qDebug()<<"org.freedesktop.NetworkManager get invalid"< #include #include #include class NetDetail : public QFrame { Q_OBJECT public: NetDetail(bool isWlan, QWidget *parent = nullptr); void setSSID(const QString &ssid); void setSpeed(const QString &speed); void setProtocol(const QString &protocol); void setSecType(const QString &secType); void setHz(const QString &hz); void setChan(const QString &chan); void setBandWidth(const QString &chan); void setIPV4(const QString &ipv4); void setIPV4Dns(const QString &ipv4Dns); void setIPV4Mask(const QString &netMask); void setIPV4Gateway(const QString &gateWay); void setIPV6(const QString &ipv6); void setIPV6Prefix(const QString &prefix); void setIPV6Gt(const QString &gateWay); void setMac(const QString &mac); private: void initUI(); public: QLabel *mSSID; QLabel *mSpeed; QLabel *mProtocol; QLabel *mSecType; QLabel *mHz; QLabel *mChan; QLabel *mBandWidth; QLabel *mIPV4; QLabel *mIPV4Gt; QLabel *mIPV4Dns; QLabel *mIPV4Mask; QLabel *mIPV6; QLabel *mIPV6Prefix; QLabel *mIPV6Gt; QLabel *mMac; private: QFormLayout *mDetailLayout; bool mIsWlan; }; #endif // NETDETAIL_H ukui-control-center/plugins/network/netconnect/netconnect.h0000644000175000017500000001275014201663716023245 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef NETCONNECT_H #define NETCONNECT_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "netconnectwork.h" #include "shell/interface.h" #include "SwitchButton/switchbutton.h" #include "netdetail.h" #include "commonComponent/HoverBtn/hoverbtn.h" enum { DISCONNECTED, NOINTERNET, CONNECTED }; typedef enum { LOOPBACK, ETHERNET, WIFI }NetType; typedef struct _CardInfo{ QString name; NetType type; bool status; }CardInfo; namespace Ui { class NetConnect; } typedef struct ActiveConInfo_s { QString strConName; QString strConUUID; QString strConType; QString strSecType; QString strChan; QString strSpeed; QString strMac; QString strHz; QString strIPV4Address; QString strIPV4Prefix; QString strIPV4Dns; QString strIPV4GateWay; QString strBandWidth; QString strIPV6Address; QString strIPV6GateWay; QString strIPV6Prefix; }ActiveConInfo; class NetConnect : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: NetConnect(); ~NetConnect(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void initSearchText(); void initComponent(); void rebuildNetStatusComponent(QString iconPath, QMap netNameMap); void rebuildWifiActComponent(QString iconPath, QMap netNameMap); void rebuildAvailComponent(QString iconpath, QString netName, QString type); void runExternalApp(); void runKylinmApp(QString netName, QString type); bool getwifiisEnable(); int getActiveConInfo(QList& qlActiveConInfo); private: Ui::NetConnect *ui; QString pluginName; int pluginType; QWidget *pluginWidget; QDBusInterface *m_interface = nullptr; QDBusInterface *kdsDbus = nullptr; SwitchButton *wifiBtn; QMap connectedWifi; QMap wifiList; QMap actLanNames; QMap preActLan; QMap actWifiNames; QMap preActWifi; QMap noneAct; QStringList wifilist; QThread *pThread; NetconnectWork *pNetWorker; QStringList TwifiList; QStringList TlanList; QStringList lanList; bool mFirstLoad; bool mIsLanVisible = false; bool mIsWlanVisible = false; QList mActiveInfo; QTimer *refreshTimer; int runCount; QString prefreChan; QString mPreWifiConnectedName; QString mPreLanConnectedName; QString connectWifi; private: int setSignal(QString lv); QStringList execGetLanList(); int getWifiListDone(QVector wifislist, QStringList lanList); QString geiWifiChan(); QString getWifiSpeed(); bool getInitStatus(); bool getWifiStatus(); bool getHasWirelessCard(); void clearContent(); void deleteNetworkDone(QString); void addNetworkDone(QString); void _buildWidgetForItem(QString); void initNetworkMap(); void setWifiBtnDisable(); void setNetDetailVisible(); // 设置网络刷新状态 QString wifiIcon(bool isLock, int strength); QList getDbusMap(const QDBusMessage &dbusMessage); private slots: void wifiSwitchSlot(bool status); void getNetList(); void netPropertiesChangeSlot(QMap property); void netDetailSlot(NetDetail *netDetail,QString netName, bool status, HoverBtn * deviceItem); void netDetailSlot(NetDetail *wlanDetail, QString netName, bool status); void netDetailOpen(NetDetail *netDetail,QString netName); void refreshNetInfoTimerSlot(); void refreshNetInfoSlot(); signals: void refresh(); }; Q_DECLARE_METATYPE(QList); #endif // NETCONNECT_H ukui-control-center/plugins/network/netconnect/netconnect.pro0000644000175000017500000000171014201663716023610 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-06-29T13:45:31 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/hoverbtn.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets network dbus gui core TEMPLATE = lib CONFIG += plugin TARGET = $$qtLibraryTarget(netconnect) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt CONFIG += c++11 \ link_pkgconfig \ PKGCONFIG += gsettings-qt \ #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ netconnect.cpp \ netconnectwork.cpp \ netdetail.cpp HEADERS += \ netconnect.h \ netconnectwork.h \ netdetail.h FORMS += \ netconnect.ui INSTALLS += target ukui-control-center/plugins/network/netconnect/netconnectwork.h0000644000175000017500000000217514201663716024150 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef NETCONNECTWORK_H #define NETCONNECTWORK_H #include #include #include #include class NetconnectWork : public QObject { Q_OBJECT public: explicit NetconnectWork(); ~NetconnectWork(); public: void run(bool status); private: bool getWifiIsOpen(); Q_SIGNALS: void complete(); }; #endif // NETCONNECTWORK_H ukui-control-center/plugins/network/netconnect/netconnect.ui0000644000175000017500000001554514201663716023440 0ustar fengfeng NetConnect 0 0 800 710 0 0 16777215 16777215 NetConnect 0 0 Netconnect Status true 1 Qt::Vertical QSizePolicy::Fixed 20 32 550 50 960 50 0 0 0 0 0 0 Available Network true Qt::Horizontal 40 20 Refresh 550 50 960 50 QFrame::Box 18 0 9 0 118 0 open wifi Qt::Horizontal 523 20 1 120 36 16777215 36 Network settings Qt::Horizontal 40 20 Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/network/netconnect/netdetail.cpp0000644000175000017500000000731114201663716023406 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "netdetail.h" NetDetail::NetDetail(bool isWlan, QWidget *parent) : mIsWlan(isWlan), QFrame(parent) { this->setFrameShape(QFrame::Shape::Box); this->setMaximumWidth(960); initUI(); } void NetDetail::setSSID(const QString &ssid) { this->mSSID->setText(ssid); } void NetDetail::setProtocol(const QString &protocol) { this->mProtocol->setText(protocol); } void NetDetail::setSecType(const QString &secType) { this->mSecType->setText(secType); } void NetDetail::setHz(const QString &hz) { this->mHz->setText(hz); } void NetDetail::setChan(const QString &chan) { this->mChan->setText(chan); } void NetDetail::setSpeed(const QString &speed) { this->mSpeed->setText(speed); } void NetDetail::setBandWidth(const QString &bd) { this->mBandWidth->setText(bd); } void NetDetail::setIPV4(const QString &ipv4) { this->mIPV4->setText(ipv4); } void NetDetail::setIPV4Dns(const QString &ipv4Dns) { this->mIPV4Dns->setText(ipv4Dns); } void NetDetail::setIPV4Mask(const QString &netMask) { this->mIPV4Mask->setText(netMask); } void NetDetail::setIPV4Gateway(const QString &gateWay) { this->mIPV4Gt->setText(gateWay); } void NetDetail::setIPV6(const QString &ipv6) { this->mIPV6->setText(ipv6); } void NetDetail::setIPV6Prefix(const QString &prefix) { this->mIPV6Prefix->setText(prefix); } void NetDetail::setIPV6Gt(const QString &gateWay) { this->mIPV6Gt->setText(gateWay); } void NetDetail::setMac(const QString &mac) { this->mMac->setText(mac); } void NetDetail::initUI() { mDetailLayout = new QFormLayout(this); mDetailLayout->setContentsMargins(41, 0, 0, 0); mSSID = new QLabel(this); mProtocol = new QLabel(this); mSecType = new QLabel(this); mHz = new QLabel(this); mChan = new QLabel(this); mSpeed = new QLabel(this); mBandWidth = new QLabel(this); mIPV4 = new QLabel(this); mIPV4Dns = new QLabel(this); mIPV4Gt = new QLabel(this); mIPV4Mask = new QLabel(this); mIPV6 = new QLabel(this); mIPV6Prefix= new QLabel(this); mIPV6Gt = new QLabel(this); mMac = new QLabel(this); mDetailLayout->addRow(tr("SSID:"), mSSID); mDetailLayout->addRow(tr("Protocol"), mProtocol); if (mIsWlan) { mDetailLayout->addRow(tr("Security Type:"), mSecType); mDetailLayout->addRow(tr("Hz:"), mHz); mDetailLayout->addRow(tr("Chan:"), mChan); mDetailLayout->addRow(tr("Link Speed(rx/tx):"), mSpeed); } mDetailLayout->addRow(tr("BandWidth:"), mBandWidth); mDetailLayout->addRow(tr("IPV4:"), mIPV4); mDetailLayout->addRow(tr("IPV4 Dns:"), mIPV4Dns); mDetailLayout->addRow(tr("IPV4 GateWay:"), mIPV4Gt); mDetailLayout->addRow(tr("IPV4 Prefix:"), mIPV4Mask); mDetailLayout->addRow(tr("IPV6:"), mIPV6); mDetailLayout->addRow(tr("IPV6 Prefix:"), mIPV6Prefix); mDetailLayout->addRow(tr("IPV6 GateWay:"), mIPV6Gt); mDetailLayout->addRow(tr("Mac:"), mMac); } ukui-control-center/plugins/network/netconnect/netconnect.cpp0000644000175000017500000013460214201663716023601 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "netconnect.h" #include "ui_netconnect.h" #include "../shell/utils/utils.h" #include #include #include #include #include #include #include #define ITEMHEIGH 50 #define CONTROL_CENTER_WIFI "org.ukui.control-center.wifi.switch" const QString KWifiSymbolic = "network-wireless-signal-excellent"; const QString KWifiLockSymbolic = "network-wireless-secure-signal-excellent"; const QString KWifiGood = "network-wireless-signal-good"; const QString KWifiLockGood = "network-wireless-secure-signal-good"; const QString KWifiOK = "network-wireless-signal-ok"; const QString KWifiLockOK = "network-wireless-secure-signal-ok"; const QString KWifiLow = "network-wireless-signal-low"; const QString KWifiLockLow = "network-wireless-secure-signal-low"; const QString KWifiNone = "network-wireless-signal-none"; const QString KWifiLockNone = "network-wireless-secure-signal-none"; const QString KLanSymbolic = ":/img/plugins/netconnect/eth.svg"; const QString NoNetSymbolic = ":/img/plugins/netconnect/nonet.svg"; bool sortByVal(const QPair &l, const QPair &r) { return (l.second < r.second); } NetConnect::NetConnect() : mFirstLoad(true) { pluginName = tr("Connect"); pluginType = NETWORK; } NetConnect::~NetConnect() { if (!mFirstLoad) { delete ui; ui = nullptr; } delete m_interface; } QString NetConnect::get_plugin_name() { return pluginName; } int NetConnect::get_plugin_type() { return pluginType; } QWidget *NetConnect::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; ui = new Ui::NetConnect; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(pluginWidget); refreshTimer = new QTimer(); qDBusRegisterMetaType>(); m_interface = new QDBusInterface("com.kylin.network", "/com/kylin/network", "com.kylin.network", QDBusConnection::sessionBus()); if(!m_interface->isValid()) { qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message()); } initSearchText(); initComponent(); } return pluginWidget; } void NetConnect::plugin_delay_control() { } const QString NetConnect::name() const { return QStringLiteral("netconnect"); } void NetConnect::initSearchText() { //~ contents_path /netconnect/Netconnect Status ui->titleLabel->setText(tr("Netconnect Status")); //~ contents_path /netconnect/open WLAN ui->openLabel->setText(tr("open WLAN")); //~ contents_path /netconnect/Network settings ui->detailBtn->setText(tr("Network settings")); } void NetConnect::initComponent() { wifiBtn = new SwitchButton(pluginWidget); ui->openWIifLayout->addWidget(wifiBtn); kdsDbus = new QDBusInterface("org.ukui.kds", \ "/", \ "org.ukui.kds.interface", \ QDBusConnection::systemBus()); // 接收到系统创建网络连接的信号时刷新可用网络列表 QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager/Settings"), "org.freedesktop.NetworkManager.Settings", "NewConnection", this, SLOT(getNetList(void))); // 接收到系统删除网络连接的信号时刷新可用网络列表 QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager/Settings"), "org.freedesktop.NetworkManager.Settings", "ConnectionRemoved", this, SLOT(getNetList(void))); // 接收到系统更改网络连接属性时把判断是否已刷新的bool值置为false QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager"), "org.freedesktop.NetworkManager", "PropertiesChanged", this, SLOT(netPropertiesChangeSlot(QMap))); // 无线网络断开或连接时刷新可用网络列表 connect(m_interface, SIGNAL(getWifiListFinished()), this, SLOT(refreshNetInfoTimerSlot())); connect(refreshTimer, SIGNAL(timeout()), this, SLOT(getNetList())); // 有线网络断开或连接时刷新可用网络列表 connect(m_interface,SIGNAL(actWiredConnectionChanged()), this, SLOT(getNetList())); // 网络配置信息发生变化时刷新可用网络列表 connect(m_interface,SIGNAL(configurationChanged()), this, SLOT(refreshNetInfoSlot())); connect(ui->RefreshBtn, &QPushButton::clicked, this, [=](bool checked) { Q_UNUSED(checked) setWifiBtnDisable(); if (m_interface) { m_interface->call("requestRefreshWifiList"); } //若没有无线网卡驱动或无线网络开关为关闭状态则不用再去发信号给kylin-nm,直接刷新有线网络列表即可 if (!getWifiStatus() || !getHasWirelessCard()) { getNetList(); } }); connect(ui->detailBtn, &QPushButton::clicked, this, [=](bool checked) { Q_UNUSED(checked) runExternalApp(); }); if (getwifiisEnable()) { wifiBtn->setChecked(getInitStatus()); } connect(wifiBtn, &SwitchButton::checkedChanged, this,[=](bool checked) { wifiBtn->blockSignals(true); wifiSwitchSlot(checked); wifiBtn->blockSignals(false); }); ui->RefreshBtn->setEnabled(false); wifiBtn->setEnabled(false); ui->openWifiFrame->setVisible(false); emit ui->RefreshBtn->clicked(true); ui->verticalLayout_2->setContentsMargins(0, 0, 32, 0); } void NetConnect::refreshNetInfoTimerSlot() { refreshTimer->start(200); } //获取当前机器是否有无线网卡设备 bool NetConnect::getHasWirelessCard(){ QProcess *wirlessPro = new QProcess(this); wirlessPro->start("nmcli device"); wirlessPro->waitForFinished(); QString output = wirlessPro->readAll(); if (output.contains("wifi")) { return true; } else { return false; } } void NetConnect::refreshNetInfoSlot() { emit ui->RefreshBtn->clicked(true); } void NetConnect::rebuildWifiActComponent(QString iconPath, QMap netNameMap) { bool hasNet = false; QMap::ConstIterator iter = netNameMap.constBegin(); while(iter != netNameMap.constEnd()) { if (iter.key() == "无连接" || iter.key() == "No net") { hasNet = true; } NetDetail *wlanDetail = new NetDetail(true, pluginWidget); wlanDetail->setVisible(false); QWidget *frame = new QWidget; frame->setContentsMargins(0,0,0,0); QVBoxLayout * vLayout = new QVBoxLayout; vLayout->setContentsMargins(0,0,0,0); QString wifiName; if (connectWifi != "--" && connectWifi != iter.key()) { wifiName = connectWifi; } else { wifiName = iter.key(); } HoverBtn * deviceItem; if (!hasNet) { deviceItem = new HoverBtn(iter.key(), false, pluginWidget); } else { deviceItem = new HoverBtn(iter.key(), true, pluginWidget); } deviceItem->mPitLabel->setText(wifiName); if (!hasNet) { deviceItem->mDetailLabel->setText(tr("Connected")); } else { deviceItem->mDetailLabel->setText(""); } QIcon searchIcon = QIcon::fromTheme(iconPath); deviceItem->mPitIcon->setProperty("useIconHighlightEffect", 0x10); deviceItem->mPitIcon->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); deviceItem->mAbtBtn->setMinimumWidth(100); deviceItem->mAbtBtn->setText(tr("Detail")); //若网络详情已展开,刷新网络时,未变更的网络详情页依然保持展开状态 if (iter.value()) { netDetailOpen(wlanDetail,deviceItem->mName); wlanDetail->setVisible(actWifiNames.value(iter.key())); } connect(deviceItem->mAbtBtn, &QPushButton::clicked, this, [=] { netDetailSlot(wlanDetail,deviceItem->mName, iter.value()); }); vLayout->addWidget(deviceItem); vLayout->addWidget(wlanDetail); frame->setLayout(vLayout); ui->detailLayOut->addWidget(frame); ++iter; } } void NetConnect::rebuildNetStatusComponent(QString iconPath, QMap netNameMap) { bool hasNet = false; QMap::ConstIterator iter = netNameMap.constBegin(); while(iter != netNameMap.constEnd()) { NetDetail *lanDetail = new NetDetail(false, pluginWidget); lanDetail->setVisible(false); QVBoxLayout * vLayout = new QVBoxLayout; vLayout->setContentsMargins(0,0,0,0); QWidget *frame = new QWidget; frame->setContentsMargins(0,0,0,0); if (iter.key() == "无连接" || iter.key() == "No net") { hasNet = true; } HoverBtn * deviceItem; if (!hasNet) { deviceItem = new HoverBtn(iter.key(), false, pluginWidget); } else { deviceItem = new HoverBtn(iter.key(), true, pluginWidget); } deviceItem->mPitLabel->setText(iter.key()); if (!hasNet) { deviceItem->mDetailLabel->setText(tr("Connected")); } else { deviceItem->mDetailLabel->setText(""); } QIcon searchIcon = QIcon::fromTheme(iconPath); deviceItem->mPitIcon->setProperty("useIconHighlightEffect", 0x10); deviceItem->mPitIcon->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); deviceItem->mAbtBtn->setMinimumWidth(100); deviceItem->mAbtBtn->setText(tr("Detail")); //若网络详情已展开,刷新网络时,未变更的网络详情页依然保持展开状态 if (iter.value()) { netDetailOpen(lanDetail,deviceItem->mName); lanDetail->setVisible(actLanNames.value(iter.key())); } connect(deviceItem->mAbtBtn, &QPushButton::clicked, this, [=] { netDetailSlot(lanDetail, deviceItem->mName, iter.value(), deviceItem); }); vLayout->addWidget(deviceItem); vLayout->addWidget(lanDetail); frame->setLayout(vLayout); ui->detailLayOut->addWidget(frame); ++iter; } } void NetConnect::getNetList() { refreshTimer->stop(); wifiBtn->blockSignals(true); wifiBtn->setChecked(getInitStatus()); wifiBtn->blockSignals(false); this->TlanList.clear(); this->wifilist.clear(); QDBusReply> reply = m_interface->call("getWifiList"); if (!reply.isValid()) { qWarning() << "value method called failed!"; } this->TlanList = execGetLanList(); if (getWifiStatus() && reply.value().length() == 1 && getHasWirelessCard()) { qDebug()<<"kylin-nm reply is empty"<<__LINE__; QElapsedTimer time; time.start(); while (time.elapsed() < 300) { QCoreApplication::processEvents(); } if (m_interface) { m_interface->call("requestRefreshWifiList"); } getNetList(); } else { connectWifi.clear(); if (reply.value().length() != 0) { if (reply.value().at(0).at(0) != "--") { connectWifi = reply.value().at(0).at(0); } else { connectWifi = "--"; } } else { connectWifi = "--"; } if (getWifiListDone(reply, this->TlanList) == -1) { qDebug()<<"getWifiListDone return is error"; getNetList(); } else { for (int i = 1; i < reply.value().length(); i++) { QString wifiName; wifiName = reply.value().at(i).at(0); if (reply.value().at(i).at(2) != NULL && reply.value().at(i).at(2) != "--") { wifiName += "lock"; } QString signal = reply.value().at(i).at(1); int sign = this->setSignal(signal); wifilist.append(wifiName + QString::number(sign)); } QString iconamePath; for (int i = 0; i < wifilist.size(); i++) { if (!wifiBtn->isChecked()) { break; } QString wifiInfo = wifilist.at(i); bool isLock = wifiInfo.contains("lock"); QString wifiName = wifiInfo.left(wifiInfo.size() - 1); int wifiStrength = wifiInfo.right(1).toInt(); wifiName = isLock ? wifiName.remove("lock") : wifiName; iconamePath = wifiIcon(isLock, wifiStrength); rebuildAvailComponent(iconamePath, wifiName, "wifi"); } for (int i = 0; i < this->lanList.length(); i++) { rebuildAvailComponent(KLanSymbolic , lanList.at(i), "ethernet"); } setNetDetailVisible(); } } } void NetConnect::netPropertiesChangeSlot(QMap property) { if (property.keys().contains("WirelessEnabled")) { setWifiBtnDisable(); if (m_interface) { m_interface->call("requestRefreshWifiList"); } } } //网络详情页填充 void NetConnect::netDetailOpen(NetDetail *netDetail,QString netName){ foreach (ActiveConInfo netInfo, mActiveInfo) { if (!netInfo.strConName.compare(netName, Qt::CaseInsensitive)) { if (!netInfo.strConType.compare("802-3-ethernet", Qt::CaseInsensitive)) { netDetail->setSSID(netInfo.strConName); netDetail->setProtocol(netInfo.strConType); netDetail->setIPV4(netInfo.strIPV4Address); netDetail->setIPV4Dns(netInfo.strIPV4Dns); netDetail->setIPV4Gateway(netInfo.strIPV4GateWay); netDetail->setIPV4Mask(netInfo.strIPV4Prefix); netDetail->setIPV6(netInfo.strIPV6Address); netDetail->setIPV6Prefix(netInfo.strIPV6Prefix); netDetail->setIPV6Gt(netInfo.strIPV6GateWay); netDetail->setMac(netInfo.strMac); netDetail->setBandWidth(netInfo.strBandWidth); } else { QString wifiName; if (connectWifi != "--" && connectWifi != netInfo.strConName) { wifiName = connectWifi; } else { wifiName = netInfo.strConName; } netDetail->setSSID(wifiName); netDetail->setProtocol(netInfo.strConType); netDetail->setSecType(netInfo.strSecType); netDetail->setHz(netInfo.strHz); netDetail->setChan(netInfo.strChan); netDetail->setSpeed(netInfo.strSpeed); netDetail->setIPV4(netInfo.strIPV4Address); netDetail->setIPV4Mask(netInfo.strIPV4Prefix); netDetail->setIPV4Dns(netInfo.strIPV4Dns); netDetail->setIPV4Gateway(netInfo.strIPV4GateWay); netDetail->setIPV6(netInfo.strIPV6Address); netDetail->setIPV6Prefix(netInfo.strIPV6Prefix); netDetail->setIPV6Gt(netInfo.strIPV6GateWay); netDetail->setMac(netInfo.strMac); netDetail->setBandWidth(netInfo.strBandWidth); } } } } //无线网络详情页构建 void NetConnect::netDetailSlot(NetDetail *wlanDetail, QString netName, bool status) { foreach (ActiveConInfo netInfo, mActiveInfo) { if (!netInfo.strConName.compare(netName, Qt::CaseInsensitive)) { status = !status; QMap::Iterator iter; if (!actWifiNames.isEmpty()) { iter = actWifiNames.find(netName); if (iter != actWifiNames.end()) { iter.value() = status; } } QString wifiName; if (connectWifi != "--" && connectWifi != netInfo.strConName) { wifiName = connectWifi; } else { wifiName = netInfo.strConName; } wlanDetail->setSSID(wifiName); wlanDetail->setProtocol(netInfo.strConType); wlanDetail->setSecType(netInfo.strSecType); wlanDetail->setHz(netInfo.strHz); wlanDetail->setChan(netInfo.strChan); wlanDetail->setSpeed(netInfo.strSpeed); wlanDetail->setIPV4(netInfo.strIPV4Address); wlanDetail->setIPV4Mask(netInfo.strIPV4Prefix); wlanDetail->setIPV4Dns(netInfo.strIPV4Dns); wlanDetail->setIPV4Gateway(netInfo.strIPV4GateWay); wlanDetail->setIPV6(netInfo.strIPV6Address); wlanDetail->setIPV6Prefix(netInfo.strIPV6Prefix); wlanDetail->setIPV6Gt(netInfo.strIPV6GateWay); wlanDetail->setMac(netInfo.strMac); wlanDetail->setBandWidth(netInfo.strBandWidth); wlanDetail->setVisible(actWifiNames.value(netName)); preActWifi.insert(netName, status); } } } //有线网络详情页构建 void NetConnect::netDetailSlot(NetDetail *netDetail,QString netName, bool status, HoverBtn * deviceItem) { foreach (ActiveConInfo netInfo, mActiveInfo) { if (!netInfo.strConName.compare(netName, Qt::CaseInsensitive)) { status = !status; QMap::Iterator iter; if (!actLanNames.isEmpty()) { iter = actLanNames.find(netName); if (iter != actLanNames.end()) { iter.value() = status; } } netDetail->setSSID(netInfo.strConName); netDetail->setProtocol(netInfo.strConType); if (netInfo.strConType == "bluetooth") { netDetail->setBandWidth("- -"); } else { netDetail->setBandWidth(netInfo.strBandWidth); } netDetail->setIPV4(netInfo.strIPV4Address); netDetail->setIPV4Dns(netInfo.strIPV4Dns); netDetail->setIPV4Gateway(netInfo.strIPV4GateWay); netDetail->setIPV4Mask(netInfo.strIPV4Prefix); netDetail->setIPV6(netInfo.strIPV6Address); netDetail->setIPV6Prefix(netInfo.strIPV6Prefix); netDetail->setIPV6Gt(netInfo.strIPV6GateWay); netDetail->setMac(netInfo.strMac); netDetail->setVisible(actLanNames.value(netName)); deviceItem->mAbtBtn->setVisible(true); preActLan.insert(netName, status); } } } void NetConnect::rebuildAvailComponent(QString iconPath, QString netName, QString type) { HoverBtn * wifiItem = new HoverBtn(netName, false, pluginWidget); wifiItem->mPitLabel->setText(netName); QIcon searchIcon = QIcon::fromTheme(iconPath); if (iconPath != KLanSymbolic && iconPath != NoNetSymbolic) { wifiItem->mPitIcon->setProperty("useIconHighlightEffect", 0x10); } wifiItem->mPitIcon->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); wifiItem->mAbtBtn->setMinimumWidth(100); wifiItem->mAbtBtn->setText(tr("Connect")); connect(wifiItem->mAbtBtn, &QPushButton::clicked, this, [=] { runKylinmApp(netName,type); }); ui->availableLayout->addWidget(wifiItem); } void NetConnect::runExternalApp() { QString cmd = "nm-connection-editor"; QProcess process(this); process.startDetached(cmd); } void NetConnect::runKylinmApp(QString netName, QString type) { m_interface->call("showPb",type,netName); } bool NetConnect::getwifiisEnable() { QDBusInterface m_interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", QDBusConnection::systemBus() ); QDBusReply> obj_reply = m_interface.call("GetAllDevices"); if (!obj_reply.isValid()) { qDebug()<<"execute dbus method 'GetAllDevices' is invalid in func getObjectPath()"; } QList obj_paths = obj_reply.value(); foreach (QDBusObjectPath obj_path, obj_paths) { QDBusInterface interface( "org.freedesktop.NetworkManager", obj_path.path(), "org.freedesktop.DBus.Introspectable", QDBusConnection::systemBus() ); QDBusReply reply = interface.call("Introspect"); if (!reply.isValid()) { qDebug()<<"execute dbus method 'Introspect' is invalid in func getObjectPath()"; } if(reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wired") != -1) { } else if (reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wireless") != -1) { return true; } } return false ; } QStringList NetConnect::execGetLanList() { QProcess *lanPro = new QProcess(this); QString shellOutput = ""; lanPro->start("nmcli -f type,device,name connection show"); lanPro->waitForFinished(); QString output = lanPro->readAll(); shellOutput += output; QStringList slist = shellOutput.split("\n"); return slist; } bool NetConnect::getWifiStatus() { QDBusInterface interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus() ); // 获取当前wifi是否打开 QDBusReply m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); if (m_result.isValid()) { bool status = m_result.value().toBool(); return status; } else { qDebug()<<"org.freedesktop.NetworkManager get invalid"< getwifislist, QStringList getlanList) { clearContent(); qDebug()<<"clear wifi and lan list "; mActiveInfo.clear(); QString speed = getWifiSpeed(); if (!speed.contains("/") && runCount < 2) { qDebug()<<"Acquisition speed cycle"; QElapsedTimer time; time.start(); while (time.elapsed() < 1000) { QCoreApplication::processEvents(); } runCount ++; return -1; } else { if (getActiveConInfo(mActiveInfo) == -1) { QElapsedTimer time; time.start(); while (time.elapsed() < 500) { QCoreApplication::processEvents(); } return -1; } else { runCount = 0; bool isNullSpeed = false; if (!speed.contains("/")) { speed = "null/" + speed; } else if (speed == "/") { qDebug()<<"speed is null"; isNullSpeed = true; } if (!getwifislist.isEmpty() && getwifislist.length() != 1) { connectedWifi.clear(); wifiList.clear(); QString actWifiName; int index = 0; while (index < mActiveInfo.size()) { if (mActiveInfo[index].strConType == "wifi" || mActiveInfo[index].strConType == "802-11-wireless") { actWifiName = QString(mActiveInfo[index].strConName); break; } index++; } QString wname; QString lockType; QString chan = geiWifiChan(); QString freq; for (int i = 0; i < getwifislist.size(); ++i) { if (getwifislist.at(i).at(0) == actWifiName) { qDebug()<<"length is:"<setSignal(getwifislist.at(i).at(1))); } else if (connectWifi != "--" && getwifislist.at(i).at(0) == connectWifi && getwifislist.at(i).at(0) != actWifiName) { qDebug()<<"ssid is not euqal to wifiname"; qDebug()<<"wname = "<setSignal(getwifislist.at(i).at(1))); } } } if (!getlanList.isEmpty()) { qDebug()<<"lan list work start"<<__LINE__; lanList.clear(); int indexLan = 0; while (indexLan < mActiveInfo.size()) { if (mActiveInfo[indexLan].strConType == "ethernet" || mActiveInfo[indexLan].strConType == "802-3-ethernet" || mActiveInfo[indexLan].strConType == "bluetooth"){ actLanNames.insert(mActiveInfo[indexLan].strConName, false); } indexLan ++; } //若有线网络详情已展开,刷新网络时,未变更的网络详情页依然保持展开状态 if (!preActLan.isEmpty()) { qDebug()<<"netdetail page flag settings"; QMap::ConstIterator iterator = preActLan.constBegin(); while(iterator != preActLan.constEnd()) { QMap::Iterator Iter; if (!actLanNames.isEmpty()) { Iter = actLanNames.find(iterator.key()); if (Iter != actLanNames.end()) { Iter.value() = iterator.value(); } } ++iterator; } } // 填充可用网络列表 QString headLine = getlanList.at(0); int indexDevice, indexName; headLine = headLine.trimmed(); bool isChineseExist = headLine.contains(QRegExp("[\\x4e00-\\x9fa5]+")); if (isChineseExist) { indexDevice = headLine.indexOf("设备") + 2; indexName = headLine.indexOf("名称") + 4; } else { indexDevice = headLine.indexOf("DEVICE"); indexName = headLine.indexOf("NAME"); } for (int i =1 ;i < getlanList.length(); i++) { QString line = getlanList.at(i); QString ltype = line.mid(0, indexDevice).trimmed(); QString nname = line.mid(indexName).trimmed(); if (ltype != "wifi" && ltype != "" && ltype != "--") { this->lanList << nname; } } } if (!this->actLanNames.isEmpty()) { QMap::ConstIterator iter = actLanNames.constBegin(); while(iter != actLanNames.constEnd()) { QString actLanName = iter.key(); this->lanList.removeOne(actLanName); ++iter; } } if (!this->connectedWifi.isEmpty()) { QMap::iterator iter = this->connectedWifi.begin(); QString connectedWifiName = iter.key(); int strength = iter.value(); bool isLock = connectedWifiName.contains("lock"); connectedWifiName = isLock ? connectedWifiName.remove("lock") : connectedWifiName; QString iconamePah; iconamePah = wifiIcon(isLock, strength); actWifiNames.insert(connectedWifiName,false); //若有线网络详情已展开,刷新网络时,未变更的网络详情页依然保持展开状态 if (!preActWifi.isEmpty()) { QMap::ConstIterator iterator = preActWifi.constBegin(); while(iterator != preActWifi.constEnd()) { QMap::Iterator Iter; if (!actWifiNames.isEmpty()) { Iter = actWifiNames.find(iterator.key()); if (Iter != actWifiNames.end()) { Iter.value() = iterator.value(); } } ++iterator; } } rebuildWifiActComponent(iconamePah, actWifiNames); } if (!this->actLanNames.isEmpty()) { QString lanIconamePah = KLanSymbolic; rebuildNetStatusComponent(lanIconamePah, this->actLanNames); } if (this->connectedWifi.isEmpty() && this->actLanNames.isEmpty()) { noneAct.insert(tr("No net"),false); rebuildNetStatusComponent(NoNetSymbolic , this->noneAct); } return 1; } } } QString NetConnect::getWifiSpeed() { qDebug()<<"getWifiSpeed start"<<__LINE__; QString program = "nmcli"; QStringList arg; QStringList strlist; QString strArray; QString deviceInfo; arg << "device"; QProcess *nmcliCmd = new QProcess(this); nmcliCmd->start(program, arg); nmcliCmd->waitForFinished(); QString nmcilInfo = nmcliCmd->readAll(); foreach (QString line, nmcilInfo.split("\n")) { line.replace(QRegExp("[\\s]+"), " "); strlist.append(line); } for (int i = 0; i < strlist.size(); i++) { strArray = strlist.at(i); if (strArray.contains("wifi")) { deviceInfo = strArray; break; } } for (int i = 0; i < deviceInfo.length(); i++) { if (deviceInfo.at(i) == " ") { deviceInfo = deviceInfo.left(i); break; } } qDebug()<<"获取到的无线网卡设备名:"<start(str, args); lanPro->waitForFinished(); QString rxSpeed; QString txSpeed; QString output; QStringList slist; output = lanPro->readAll(); qDebug()<<"终端打印信息:"<= '0' && rxSpeed.at(i).toLatin1() <= '9'){ uSpeed.append(rxSpeed.at(i)); } } for (int i = 0; i < txSpeed.length(); i++) { if (txSpeed.at(i) == ".") { break; } else if (txSpeed.at(i).toLatin1() >= '0' && txSpeed.at(i).toLatin1() <= '9'){ dSpeed.append(txSpeed.at(i)); } } if (uSpeed == "" && dSpeed == "") { return "/"; } else if (uSpeed == "" && dSpeed != "") { return dSpeed; } return uSpeed + "/" + dSpeed; } QString NetConnect::geiWifiChan() { QProcess *lanPro = new QProcess(this); bool isHas = false; QStringList slist; lanPro->start("nmcli -f in-use,chan device wifi"); lanPro->waitForFinished(); QString output = lanPro->readAll(); foreach (QString line, output.split("\n")) { line.replace(QRegExp("[\\s]+"), ""); slist.append(line); } for (int i = 0; i < slist.length(); i++) { QString str = slist.at(i); if (str.contains("*")) { isHas = true; } } if (isHas) { for (int i = 0; i < slist.length(); i++) { QString str = slist.at(i); if (str.contains("*")) { str.remove("*"); prefreChan = str; return str; } } } else { return prefreChan; } } bool NetConnect::getInitStatus() { QDBusInterface interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus() ); // 获取当前wifi是否打开 QDBusReply m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); if (m_result.isValid()) { bool status = m_result.value().toBool(); return status; } else { qDebug()<<"org.freedesktop.NetworkManager get invalid"<availableLayout->layout() != NULL) { QLayoutItem* item; while ((item = ui->availableLayout->layout()->takeAt(0)) != NULL ) { delete item->widget(); delete item; item = nullptr; } } if (ui->detailLayOut->layout() != NULL) { QLayoutItem* item; while ((item = ui->detailLayOut->layout()->takeAt(0)) != NULL) { delete item->widget(); delete item; item = nullptr; } } this->connectedWifi.clear(); this->actLanNames.clear(); this->actWifiNames.clear(); this->wifiList.clear(); this->lanList.clear(); this->TlanList.clear(); this->TwifiList.clear(); this->noneAct.clear(); } void NetConnect::setWifiBtnDisable() { ui->RefreshBtn->setText(tr("Refreshing...")); ui->RefreshBtn->setEnabled(false); wifiBtn->setEnabled(false); ui->openWifiFrame->setVisible(false); this->clearContent(); } void NetConnect::setNetDetailVisible() { bool wifiSt = getwifiisEnable(); wifiBtn->setEnabled(wifiSt); ui->openWifiFrame->setVisible(wifiSt); ui->RefreshBtn->setEnabled(true); ui->RefreshBtn->setText(tr("Refresh")); } QList NetConnect::getDbusMap(const QDBusMessage &dbusMessage) { QList outArgsIpv4 = dbusMessage.arguments(); if (!outArgsIpv4.isEmpty()) { QVariant firstIpv4 = outArgsIpv4.at(0); QDBusVariant dbvFirstIpv4 = firstIpv4.value(); QVariant vFirstIpv4 = dbvFirstIpv4.variant(); const QDBusArgument &dbusArgIpv4 = vFirstIpv4.value(); QList mDatasIpv4; dbusArgIpv4 >> mDatasIpv4; return mDatasIpv4; } else { QList emptyList; return emptyList; } } QString NetConnect::wifiIcon(bool isLock, int strength) { switch (strength) { case 1: return isLock ? KWifiLockSymbolic : KWifiSymbolic; case 2: return isLock ? KWifiLockGood : KWifiGood; case 3: return isLock ? KWifiLockOK : KWifiOK; case 4: return isLock ? KWifiLockLow : KWifiLow; case 5: return isLock ? KWifiLockNone : KWifiNone; default: return ""; } } int NetConnect::setSignal(QString lv) { int signal = lv.toInt(); int signalLv = 0; if (signal > 75) { signalLv = 1; } else if (signal > 55 && signal <= 75) { signalLv = 2; } else if (signal > 35 && signal <= 55) { signalLv = 3; } else if (signal > 15 && signal <= 35) { signalLv = 4; } else if (signal <= 15) { signalLv = 5; } return signalLv; } void NetConnect::wifiSwitchSlot(bool status) { pThread = new QThread(); pNetWorker = new NetconnectWork; pNetWorker->moveToThread(pThread); connect(pThread, &QThread::finished, pThread, &QThread::deleteLater); connect(pThread, &QThread::started, pNetWorker,[=]{ qDebug()<<"thread set wifi status start"; pNetWorker->run(status); qDebug()<<"thread set wifi status end="; }); connect(pNetWorker, &NetconnectWork::complete,[=](){ pThread->quit(); pThread->destroyed(); }); pThread->start(); } int NetConnect::getActiveConInfo(QList& qlActiveConInfo) { ActiveConInfo activeNet; QDBusInterface interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus() ); QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager", "ActiveConnections"); QList outArgs = result.arguments(); QVariant first = outArgs.at(0); QDBusVariant dbvFirst = first.value(); QVariant vFirst = dbvFirst.variant(); const QDBusArgument &dbusArgs = vFirst.value(); QDBusObjectPath objPath; dbusArgs.beginArray(); while (!dbusArgs.atEnd()) { dbusArgs >> objPath; QDBusInterface interfacePro("org.freedesktop.NetworkManager", objPath.path(), "org.freedesktop.NetworkManager.Connection.Active", QDBusConnection::systemBus()); QVariant replyType = interfacePro.property("Type"); QVariant replyUuid = interfacePro.property("Uuid"); QVariant replyId = interfacePro.property("Id"); activeNet.strConName = replyId.toString(); activeNet.strConType = replyType.toString(); activeNet.strConUUID = replyUuid.toString(); QString replyIPV4Path = interfacePro.property("Ip4Config") .value() .path(); //如果此时获取的path为"/",说明出现异常,则需要进行异常处理 // IPV4信息 if (replyIPV4Path == "/") { return -1; } else { QDBusInterface IPV4ifc("org.freedesktop.NetworkManager", replyIPV4Path, "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); QDBusMessage replyIpv4 = IPV4ifc.call("Get", "org.freedesktop.NetworkManager.IP4Config", "AddressData"); if (!IPV4ifc.isValid()) { qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message()); } QList datasIpv4 = getDbusMap(replyIpv4); if (!datasIpv4.isEmpty()) { activeNet.strIPV4Address = datasIpv4.at(0).value("address").toString(); activeNet.strIPV4Prefix = datasIpv4.at(0).value("prefix").toString(); } else { qWarning()<<"Ipv4 data reply empty!";\ return -1; } QDBusMessage replyIPV4Dns = IPV4ifc.call("Get", "org.freedesktop.NetworkManager.IP4Config", "NameserverData"); QList datasIpv4Dns = getDbusMap(replyIPV4Dns); if (!datasIpv4Dns.isEmpty()) { activeNet.strIPV4Dns = datasIpv4Dns.at(0).value("address").toString(); } else { qWarning()<<"Ipv4 Dns data reply empty!"; } QDBusMessage replyIPV4Gt = IPV4ifc.call("Get", "org.freedesktop.NetworkManager.IP4Config", "Gateway"); if (!replyIPV4Gt.arguments().isEmpty()) { QVariant ipv4Gt = replyIPV4Gt.arguments().at(0) .value() .variant(); activeNet.strIPV4GateWay = ipv4Gt.toString(); } else { qWarning()<<"Ipv4 reply empty!"; return -1; } // IPV6信息 QString replyIpv6Path = interfacePro.property("Ip6Config") .value() .path(); QDBusInterface IPV6ifc("org.freedesktop.NetworkManager", replyIpv6Path, "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); if (!IPV6ifc.isValid()) { qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message()); } QDBusMessage replyIPV6 = IPV6ifc.call("Get", "org.freedesktop.NetworkManager.IP6Config", "AddressData"); QList dataIPV6 = getDbusMap(replyIPV6); if (!dataIPV6.isEmpty()) { activeNet.strIPV6Address = dataIPV6.at(0).value("address").toString(); activeNet.strIPV6Prefix = dataIPV6.at(0).value("prefix").toString(); } else { qWarning()<<"Ipv6 data reply empty!"; } QDBusMessage replyIPV6Gt = IPV6ifc.call("Get", "org.freedesktop.NetworkManager.IP6Config", "GateWay"); if (!replyIPV6Gt.arguments().isEmpty()) { QVariant IPV6Gt = replyIPV6Gt.arguments().at(0) .value() .variant(); activeNet.strIPV6GateWay = IPV6Gt.toString().isEmpty() ? "" : IPV6Gt.toString(); } else { qWarning()<<"Ipv6 info reply empty!"; return -1; } // 设备信息 auto replyDevicesPaths = interfacePro.property("Devices") .value>(); if (!replyDevicesPaths.isEmpty()) { if (!activeNet.strConType.compare("802-3-ethernet", Qt::CaseInsensitive)) { QDBusInterface netDeviceifc("org.freedesktop.NetworkManager", replyDevicesPaths.at(0).path(), "org.freedesktop.NetworkManager.Device.Wired", QDBusConnection::systemBus()); activeNet.strBandWidth = netDeviceifc.property("Speed").toString() + "Mb/s"; activeNet.strMac = netDeviceifc.property("HwAddress").toString().toLower(); } else if (!activeNet.strConType.compare("bluetooth", Qt::CaseInsensitive)){ QDBusInterface netDeviceifc("org.freedesktop.NetworkManager", replyDevicesPaths.at(0).path(), "org.freedesktop.NetworkManager.Device.Bluetooth", QDBusConnection::systemBus()); activeNet.strBandWidth = netDeviceifc.property("Speed").toString() + "Mb/s"; activeNet.strMac = netDeviceifc.property("HwAddress").toString().toLower(); } else { QDBusInterface netDeviceifc("org.freedesktop.NetworkManager", replyDevicesPaths.at(0).path(), "org.freedesktop.NetworkManager.Device.Wireless", QDBusConnection::systemBus()); activeNet.strBandWidth = netDeviceifc.property("Bitrate").toString() + "Mb/s"; activeNet.strMac = netDeviceifc.property("HwAddress").toString().toLower(); } } else { qWarning()<<"Reply for Devices Paths empty!"; return -1; } qlActiveConInfo.append(activeNet); } } dbusArgs.endArray(); return 1; } ukui-control-center/plugins/network/vino/0000755000175000017500000000000014201663716017542 5ustar fengfengukui-control-center/plugins/network/vino/vino.cpp0000644000175000017500000000261514201663716021225 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "vino.h" Vino::Vino() : mFirstLoad(true) { pluginName = tr("Vino"); pluginType = NETWORK; } Vino::~Vino() { } QString Vino::get_plugin_name() { return pluginName; } int Vino::get_plugin_type() { return pluginType; } QWidget *Vino::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; // will delete by takewidget pluginWidget = new ShareMain; } return pluginWidget; } void Vino::plugin_delay_control() { } const QString Vino::name() const { return QStringLiteral("vino"); } ukui-control-center/plugins/network/vino/vino.h0000644000175000017500000000304214201663716020665 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef VINO_H #define VINO_H #include #include #include #include "shell/interface.h" #include "sharemain.h" class Vino : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: Vino(); ~Vino(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; private: QString pluginName; int pluginType; ShareMain* pluginWidget; bool mFirstLoad; }; #endif // VINO_H ukui-control-center/plugins/network/vino/sharemain.h0000644000175000017500000000611714201663716021667 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef SHAREMAIN_H #define SHAREMAIN_H #include #include #include #include #include #include #include #include #include #include #include #include #include "SwitchButton/switchbutton.h" #include "inputpwddialog.h" #include "Label/titlelabel.h" const QByteArray kVinoSchemas = "org.gnome.Vino"; const QString kVinoViewOnlyKey = "view-only"; const QString kVinoPromptKey = "prompt-enabled"; const QString kAuthenticationKey = "authentication-methods"; const QString kVncPwdKey = "vnc-password"; const QByteArray kUkccVnoSchmas = "org.ukui.control-center.vino"; const QString kUkccPromptKey = "remote"; enum RequestPwd { NOPWD, NEEDPWD }; class ShareMain : public QWidget { Q_OBJECT public: ShareMain(QWidget *parent = nullptr); ~ShareMain(); private: QFrame *mEnableFrame; QFrame *mViewFrame; QFrame *mSecurityFrame; QFrame *mSecurityPwdFrame; QFrame *mNoticeWFrame; QFrame *mNoticeOFrame; QFrame *mNoticeNFrame; SwitchButton *mEnableBtn; // 允许其他人查看桌面 SwitchButton *mViewBtn; // 允许连接控制屏幕 SwitchButton *mAccessBtn; // 为本机确认每次访问 SwitchButton *mPwdBtn; // 要求用户输入密码 QRadioButton *mNoticeWBtn; QRadioButton *mNoticeOBtn; QRadioButton *mNoticeNBtn; TitleLabel *mShareTitleLabel; TitleLabel *mSecurityTitleLabel; QLabel *mEnableLabel; QLabel *mViewLabel; QLabel *mAccessLabel; QLabel *mPwdsLabel; QLabel *mNoticeTitleLabel; QLabel *mNoticeWLabel; QLabel *mNoticeOLabel; QLabel *mNoticeNLabel; QPushButton *mPwdinputBtn; QVBoxLayout *mVlayout; QGSettings *mVinoGsetting; QString secpwd; private: void initUI(); void initConnection(); void initShareStatus(bool isConnnect, bool isPwd); void initEnableStatus(); void setFrameVisible(bool visible); void setVinoService(bool status); private slots: void enableSlot(bool status); void viewBoxSlot(bool status); void accessSlot(bool status); void pwdEnableSlot(bool status); void pwdInputSlot(); }; #endif // SHAREMAIN_H ukui-control-center/plugins/network/vino/sharemain.cpp0000644000175000017500000001772314201663716022227 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "sharemain.h" #include #include #include #include #include #include #include #include #include ShareMain::ShareMain(QWidget *parent) : QWidget(parent) { mVlayout = new QVBoxLayout(this); mVlayout->setContentsMargins(0, 0, 32, 0); initUI(); initConnection(); } ShareMain::~ShareMain() { } void ShareMain::initUI() { mShareTitleLabel = new TitleLabel(this); //~ contents_path /vino/Share mShareTitleLabel->setText(tr("Share")); mEnableFrame = new QFrame(this); mEnableFrame->setFrameShape(QFrame::Shape::Box); mEnableFrame->setMinimumSize(550, 50); mEnableFrame->setMaximumSize(960, 50); QHBoxLayout *enableHLayout = new QHBoxLayout(); mEnableBtn = new SwitchButton(this); mEnableLabel = new QLabel(tr("Allow others to view your desktop"), this); enableHLayout->addWidget(mEnableLabel); enableHLayout->addStretch(); enableHLayout->addWidget(mEnableBtn); mEnableFrame->setLayout(enableHLayout); mViewFrame = new QFrame(this); mViewFrame->setFrameShape(QFrame::Shape::Box); mViewFrame->setMinimumSize(550, 50); mViewFrame->setMaximumSize(960, 50); QHBoxLayout *viewHLayout = new QHBoxLayout(); mViewBtn = new SwitchButton(this); mViewLabel = new QLabel(tr("Allow connection to control screen"), this); viewHLayout->addWidget(mViewLabel); viewHLayout->addStretch(); viewHLayout->addWidget(mViewBtn); mViewFrame->setLayout(viewHLayout); mSecurityTitleLabel = new TitleLabel(this); //~ contents_path /vino/Security mSecurityTitleLabel->setText(tr("Security")); mSecurityFrame = new QFrame(this); mSecurityFrame->setFrameShape(QFrame::Shape::Box); mSecurityFrame->setMinimumSize(550, 50); mSecurityFrame->setMaximumSize(960, 50); QHBoxLayout *secHLayout = new QHBoxLayout(); mAccessBtn = new SwitchButton(this); mAccessLabel = new QLabel(tr("You must confirm every visit for this machine"), this); secHLayout->addWidget(mAccessLabel); secHLayout->addStretch(); secHLayout->addWidget(mAccessBtn); mSecurityFrame->setLayout(secHLayout); mSecurityPwdFrame = new QFrame(this); mSecurityPwdFrame->setFrameShape(QFrame::Shape::Box); mSecurityPwdFrame->setMinimumSize(550, 50); mSecurityPwdFrame->setMaximumSize(960, 50); QHBoxLayout *pwdHLayout = new QHBoxLayout(); mPwdBtn = new SwitchButton(this); mPwdsLabel = new QLabel(tr("Require user to enter this password: "), this); mPwdinputBtn = new QPushButton(this); mPwdinputBtn->setContentsMargins(26,8,26,8); mPwdinputBtn->setFixedSize(QSize(120, 36)); pwdHLayout->addWidget(mPwdsLabel); pwdHLayout->addWidget(mPwdinputBtn); pwdHLayout->addStretch(); pwdHLayout->addWidget(mPwdBtn); mSecurityPwdFrame->setLayout(pwdHLayout); mVlayout->addWidget(mShareTitleLabel); mVlayout->addWidget(mEnableFrame); mVlayout->addWidget(mViewFrame); mVlayout->addSpacing(32); mVlayout->setSpacing(8); mVlayout->addWidget(mSecurityTitleLabel); mVlayout->addWidget(mSecurityFrame); mVlayout->addWidget(mSecurityPwdFrame); mVlayout->addStretch(); } void ShareMain::initConnection() { QByteArray id(kVinoSchemas); if (QGSettings::isSchemaInstalled(id)) { mVinoGsetting = new QGSettings(kVinoSchemas, QByteArray(), this); initEnableStatus(); connect(mEnableBtn, &SwitchButton::checkedChanged, this, &ShareMain::enableSlot); connect(mViewBtn, &SwitchButton::checkedChanged, this, &ShareMain::viewBoxSlot); connect(mAccessBtn, &SwitchButton::checkedChanged, this, &ShareMain::accessSlot); connect(mPwdBtn, &SwitchButton::checkedChanged, this, &ShareMain::pwdEnableSlot); connect(mPwdinputBtn, &QPushButton::clicked, this, &ShareMain::pwdInputSlot); } } void ShareMain::initEnableStatus() { bool isShared = mVinoGsetting->get(kVinoViewOnlyKey).toBool(); bool secPwd = mVinoGsetting->get(kVinoPromptKey).toBool(); QString pwd = mVinoGsetting->get(kAuthenticationKey).toString(); secpwd = mVinoGsetting->get(kVncPwdKey).toString(); mAccessBtn->setChecked(secPwd); mViewBtn->setChecked(!isShared); if (pwd == "vnc") { if (secpwd == "keyring") { mPwdBtn->setChecked(false); mPwdinputBtn->hide(); mVinoGsetting->set(kAuthenticationKey, "none"); } else { mPwdBtn->setChecked(true); mPwdinputBtn->setText(QByteArray::fromBase64(secpwd.toLatin1())); } } else { mPwdBtn->setChecked(false); mPwdinputBtn->setVisible(false); } // 查看vino服务是否起来 QProcess *process = new QProcess; process->start("systemctl", QStringList() << "--user" << "is-active" << "vino-server.service"); process->waitForFinished(); setFrameVisible((process->readAllStandardOutput().replace("\n", "") == "active")); delete process; } void ShareMain::setFrameVisible(bool visible) { mEnableBtn->setChecked(visible); mViewFrame->setVisible(visible); mSecurityFrame->setVisible(visible); mSecurityPwdFrame->setVisible(visible); mSecurityTitleLabel->setVisible(visible); } void ShareMain::setVinoService(bool status) { QDBusInterface vinoIfc("org.ukui.SettingsDaemon", "/org/ukui/SettingsDaemon/Sharing", "org.ukui.SettingsDaemon.Sharing", QDBusConnection::sessionBus()); if (vinoIfc.isValid()) { if (status) { vinoIfc.call("EnableService", "vino-server"); } else { vinoIfc.call("DisableService", "vino-server"); } } } void ShareMain::enableSlot(bool status) { setFrameVisible(status); setVinoService(status); } void ShareMain::viewBoxSlot(bool status) { mVinoGsetting->set(kVinoViewOnlyKey, !status); } void ShareMain::accessSlot(bool status) { if (status) { mVinoGsetting->set(kVinoPromptKey, true); } else { mVinoGsetting->set(kVinoPromptKey, false); } } void ShareMain::pwdEnableSlot(bool status) { if (status) { mPwdinputBtn->setVisible(secpwd == "keyring" ? false:true); mPwdinputBtn->setText(QByteArray::fromBase64(mVinoGsetting->get(kVncPwdKey).toString().toLatin1())); pwdInputSlot(); mPwdinputBtn->setVisible(status); if (mVinoGsetting->get(kAuthenticationKey).toString() == "none") { mPwdBtn->setChecked(false); } } else { mPwdinputBtn->setVisible(false); mVinoGsetting->set(kAuthenticationKey, "none"); } } void ShareMain::pwdInputSlot() { InputPwdDialog *mwindow = new InputPwdDialog(mVinoGsetting,this); mwindow->exec(); secpwd = mVinoGsetting->get(kVncPwdKey).toString(); mPwdinputBtn->setText(QByteArray::fromBase64(secpwd.toLatin1())); } ukui-control-center/plugins/network/vino/vino.pro0000644000175000017500000000240614201663716021241 0ustar fengfenginclude(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets dbus TEMPLATE = lib CONFIG += plugin link_pkgconfig PKGCONFIG += gsettings-qt TARGET = $$qtLibraryTarget(vino) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE\ $$PROJECT_ROOTDIR \ # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ inputpwddialog.cpp \ sharemain.cpp \ vino.cpp HEADERS += \ inputpwddialog.h \ sharemain.h \ vino.h FORMS += # Default rules for deployment. INSTALLS += target ukui-control-center/plugins/network/vino/inputpwddialog.h0000644000175000017500000000277414201663716022757 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef INPUTPWDDIALOG_H #define INPUTPWDDIALOG_H #include #include #include #include #include namespace Ui { class InputPwdDialog; } class InputPwdDialog : public QDialog { Q_OBJECT public: InputPwdDialog(QGSettings *Keygsettiings,QWidget *parent = nullptr); ~InputPwdDialog(); private: QGSettings *mgsettings; QPushButton *mCancelBtn; QPushButton *mConfirmBtn; QLabel *mHintLabel; QLineEdit *mpwd; QByteArray secPwd; bool mfirstload; bool mstatus; private: void setupInit(); void initConnect(); bool eventFilter(QObject *wcg, QEvent *event); private slots: void mpwdInputSlot(const QString &pwd); }; #endif // INPUTPWDDIALOG_H ukui-control-center/plugins/network/vino/inputpwddialog.cpp0000644000175000017500000001113514201663716023301 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "inputpwddialog.h" #include #include #include #include #include #include #include "sharemain.h" InputPwdDialog::InputPwdDialog(QGSettings *Keygsettiings,QWidget *parent) : QDialog(parent), mgsettings(Keygsettiings) { setupInit(); initConnect(); } InputPwdDialog::~InputPwdDialog() { } void InputPwdDialog::setupInit() { setWindowTitle(tr("Set Password")); this->setFixedSize(380, 161); this->setMinimumSize(QSize(380, 161)); this->setMaximumSize(QSize(380, 161)); mpwd = new QLineEdit(this); mpwd->setAttribute(Qt::WA_InputMethodEnabled, false); //限制中文输入法 mpwd->setGeometry(32, 25, 316,42); // mpwd->setFocus(); // mpwd->clearFocus(); mpwd->installEventFilter(this); this->installEventFilter(this); mfirstload = true; mstatus = false; mHintLabel = new QLabel(this); mHintLabel->setGeometry(32,67,316,28); mHintLabel->setContentsMargins(8,2,8,2); mHintLabel->setStyleSheet("color:red;"); mCancelBtn = new QPushButton(this); mCancelBtn->setContentsMargins(36,6,36,6); mCancelBtn->setGeometry(112,99,110,33); mCancelBtn->setText(tr("Cancel")); mConfirmBtn = new QPushButton(this); mConfirmBtn->setContentsMargins(36,6,36,6); mConfirmBtn->setGeometry(238,99,110,33); mConfirmBtn->setText(tr("Confirm")); if(QByteArray::fromBase64(mgsettings->get(kVncPwdKey).toString().toLatin1()).length() <= 8) { if (mgsettings->get(kVncPwdKey).toString() == "keyring") { mpwd->setText(""); mConfirmBtn->setEnabled(false); mHintLabel->setText(tr("Password can not be blank")); mHintLabel->setVisible(true); } else { mpwd->setText(QByteArray::fromBase64(mgsettings->get(kVncPwdKey).toString().toLatin1())); } } } void InputPwdDialog::mpwdInputSlot(const QString &pwd) { Q_UNUSED(pwd); mstatus = true; mConfirmBtn->setEnabled(true); if (pwd.length() <= 8 && !pwd.isEmpty()) { QByteArray text = pwd.toLocal8Bit(); secPwd = text.toBase64(); mHintLabel->setVisible(false); } else if (pwd.isEmpty()) { mConfirmBtn->setEnabled(false); mHintLabel->setText(tr("Password can not be blank")); mHintLabel->setStyleSheet("color:red;"); mHintLabel->setVisible(true); secPwd = NULL; } else { mHintLabel->setText(tr("less than or equal to 8")); mHintLabel->setStyleSheet("color:red;"); mHintLabel->setVisible(true); mpwd->setText(pwd.mid(0, 8)); QByteArray text = pwd.mid(0, 8).toLocal8Bit(); secPwd = text.toBase64(); } } void InputPwdDialog::initConnect() { connect(mCancelBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) this->close(); }); connect(mConfirmBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) if (mstatus && secPwd.length() == 0) { return; } else if (!mstatus){ mgsettings->set(kAuthenticationKey, "vnc"); this->close(); } else { mgsettings->set(kVncPwdKey, secPwd); mgsettings->set(kAuthenticationKey, "vnc"); this->close(); } }); //使用textEdited信号是为了防止密码框setText时触发信号 connect(mpwd, &QLineEdit::textEdited, this, &InputPwdDialog::mpwdInputSlot); } bool InputPwdDialog::eventFilter(QObject *wcg, QEvent *event) { //过滤 if(wcg==mpwd){ if(event->type() == QEvent::MouseButtonPress){ if(mpwd->hasFocus()){ if (mfirstload) { mpwd->setText(""); mfirstload = false; } } } } return QWidget::eventFilter(wcg,event); } ukui-control-center/plugins/system/0000755000175000017500000000000014201663716016422 5ustar fengfengukui-control-center/plugins/system/touchscreen/0000755000175000017500000000000014201663716020744 5ustar fengfengukui-control-center/plugins/system/touchscreen/qml.qrc0000644000175000017500000000017714201663716022251 0ustar fengfeng qml/Output.qml qml/main.qml ukui-control-center/plugins/system/touchscreen/touchserialquery.h0000644000175000017500000000166214201663716024532 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TOUCHSERIALQUERY_H #define TOUCHSERIALQUERY_H int findSerialFromId(int touchid,char *touchname,char *_touchserial,char *devnode,int maxlen); #endif // TOUCHSERIALQUERY_H ukui-control-center/plugins/system/touchscreen/xinputmanager.h0000644000175000017500000000267614201663716024012 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef XINPUTMANAGER_H #define XINPUTMANAGER_H #include "monitorinputtask.h" #include #include class XinputManager : public QObject { Q_OBJECT public: XinputManager(QObject *parent = nullptr); void start(); void stop(); Q_SIGNALS: void sigStartThread(); void xinputSlaveAdded(int device_id); void xinputSlaveRemoved(int device_id); private: void init(); private: QThread *m_pManagerThread; QMutex m_runningMutex; MonitorInputTask *m_pMonitorInputTask; private Q_SLOTS: void onSlaveAdded(int device_id); void onSlaveRemoved(int device_id); private: void SetPenRotation(int device_id); }; #endif // XINPUTMANAGER_H ukui-control-center/plugins/system/touchscreen/declarative/0000755000175000017500000000000014201663716023227 5ustar fengfengukui-control-center/plugins/system/touchscreen/declarative/qmlscreen.cpp0000644000175000017500000002755214201663716025737 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qmlscreen.h" #include "qmloutputcomponent.h" #include "qmloutput.h" #include #include #include #include Q_DECLARE_METATYPE(KScreen::OutputPtr) QMLScreen::QMLScreen(QQuickItem *parent) : QQuickItem(parent) { connect(this, &QMLScreen::widthChanged, this, &QMLScreen::viewSizeChanged); connect(this, &QMLScreen::heightChanged, this, &QMLScreen::viewSizeChanged); } QMLScreen::~QMLScreen() { qDeleteAll(m_outputMap); m_outputMap.clear(); } KScreen::ConfigPtr QMLScreen::config() const { return m_config; } void QMLScreen::setConfig(const KScreen::ConfigPtr &config) { qDeleteAll(m_outputMap); m_outputMap.clear(); m_manuallyMovedOutputs.clear(); m_bottommost = m_leftmost = m_rightmost = m_topmost = nullptr; m_connectedOutputsCount = 0; m_enabledOutputsCount = 0; if (m_config) { m_config->disconnect(this); } m_config = config; connect(m_config.data(), &KScreen::Config::outputAdded, this, [this](const KScreen::OutputPtr &output) { addOutput(output); updateOutputsPlacement(); }); connect(m_config.data(), &KScreen::Config::outputRemoved, this, &QMLScreen::removeOutput); //qDebug()<<"所要拿取的配置为------>"<outputs()) { // qDebug()<<"\noutput类型----debug------>"<"<(output))<<" "<output()->isConnected() && qmlOutput->output()->isEnabled()) { //qDebug()<<"qmlOutput---->"<dockToNeighbours(); } } } void QMLScreen::addOutput(const KScreen::OutputPtr &output) { //qDebug()<<"qmlscreen.cpp-------> output类型------->"<setParentItem(this); qmloutput->setZ(m_outputMap.count()); connect(output.data(), &KScreen::Output::isConnectedChanged, this, &QMLScreen::outputConnectedChanged); connect(output.data(), &KScreen::Output::isEnabledChanged, this, &QMLScreen::outputEnabledChanged); connect(output.data(), &KScreen::Output::posChanged, this, &QMLScreen::outputPositionChanged); connect(qmloutput, &QMLOutput::yChanged, [this, qmloutput]() { qmlOutputMoved(qmloutput); }); connect(qmloutput, &QMLOutput::xChanged, [this, qmloutput]() { qmlOutputMoved(qmloutput); }); //在这里点击上面小屏幕 connect(qmloutput, SIGNAL(clicked()), this, SLOT(setActiveOutput())); qmloutput->updateRootProperties(); } void QMLScreen::removeOutput(int outputId) { for (const KScreen::OutputPtr &output : m_outputMap.keys()) { if (output->id() == outputId) { QMLOutput *qmlOutput = m_outputMap.take(output); qmlOutput->setParentItem(nullptr); qmlOutput->setParent(nullptr); qmlOutput->deleteLater(); return; } } } int QMLScreen::connectedOutputsCount() const { return m_connectedOutputsCount; } int QMLScreen::enabledOutputsCount() const { return m_enabledOutputsCount; } QMLOutput *QMLScreen::primaryOutput() const { Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { if (qmlOutput->output()->isPrimary()) { return qmlOutput; } } return nullptr; } QList QMLScreen::outputs() const { return m_outputMap.values(); } void QMLScreen::setActiveOutput(QMLOutput *output) { Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { if (qmlOutput->z() > output->z()) { qmlOutput->setZ(qmlOutput->z() - 1); } } output->setZ(m_outputMap.count()); //选中屏幕 output->setFocus(true); Q_EMIT focusedOutputChanged(output); } QSize QMLScreen::maxScreenSize() const { //qDebug()<<"m_config->screen()->maxSize()--->"<screen()->maxSize()<screen()->maxSize(); } float QMLScreen::outputScale() const { return m_outputScale; } void QMLScreen::outputConnectedChanged() { int connectedCount = 0; Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { if (output->isConnected()) { ++connectedCount; } } if (connectedCount != m_connectedOutputsCount) { m_connectedOutputsCount = connectedCount; Q_EMIT connectedOutputsCountChanged(); updateOutputsPlacement(); } } void QMLScreen::outputEnabledChanged() { const KScreen::OutputPtr output(qobject_cast(sender()), [](void *){}); if (output->isEnabled()) { updateOutputsPlacement(); } int enabledCount = 0; Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { if (output->isEnabled()) { ++enabledCount; } } if (enabledCount == m_enabledOutputsCount) { m_enabledOutputsCount = enabledCount; Q_EMIT enabledOutputsCountChanged(); } } void QMLScreen::outputPositionChanged() { /* TODO: Reposition the QMLOutputs */ } void QMLScreen::qmlOutputMoved(QMLOutput *qmlOutput) { //qDebug()<<"qmlOutputMoved------>"<isCloneMode()) { return; } if (!m_manuallyMovedOutputs.contains(qmlOutput)) m_manuallyMovedOutputs.append(qmlOutput); updateCornerOutputs(); if (m_leftmost) { m_leftmost->setOutputX(0); } if (m_topmost) { m_topmost->setOutputY(0); } if (qmlOutput == m_leftmost) { Q_FOREACH (QMLOutput *other, m_outputMap) { if (other == m_leftmost) { continue; } if (!other->output()->isConnected() || !other->output()->isEnabled()) { continue; } other->setOutputX(float(other->x() - m_leftmost->x()) / outputScale()); } } else if (m_leftmost) { qmlOutput->setOutputX(float(qmlOutput->x() - m_leftmost->x()) / outputScale()); } if (qmlOutput == m_topmost) { Q_FOREACH (QMLOutput *other, m_outputMap) { if (other == m_topmost) { continue; } if (!other->output()->isConnected() || !other->output()->isEnabled()) { continue; } other->setOutputY(float(other->y() - m_topmost->y()) / outputScale()); } } else if (m_topmost) { qmlOutput->setOutputY(float(qmlOutput->y() - m_topmost->y()) / outputScale()); } } void QMLScreen::viewSizeChanged() { updateOutputsPlacement(); } void QMLScreen::updateCornerOutputs() { m_leftmost = nullptr; m_topmost = nullptr; m_rightmost = nullptr; m_bottommost = nullptr; Q_FOREACH (QMLOutput *output, m_outputMap) { if (!output->output()->isConnected() || !output->output()->isEnabled()) { continue; } QMLOutput *other = m_leftmost; if (!other || output->x() < other->x()) { m_leftmost = output; } if (!other || output->y() < other->y()) { m_topmost = output; } if (!other || output->x() + output->width() > other->x() + other->width()) { m_rightmost = output; } if (!other || output->y() + output->height() > other->y() + other->height()) { m_bottommost = output; } } } void QMLScreen::setOutputScale(float scale) { if (qFuzzyCompare(scale, m_outputScale)) return; m_outputScale = scale; emit outputScaleChanged(); } //应该是画坐标的地方? void QMLScreen::updateOutputsPlacement() { //qDebug()<<"updateOutputsPlacement---->"<(item); if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled()) { continue; } if (qmlOutput->outputX() + qmlOutput->currentOutputWidth() > initialActiveScreenSize.width()) { // qDebug()<outputX()<currentOutputWidth()<outputX() + qmlOutput->currentOutputWidth()); } if (qmlOutput->outputY() + qmlOutput->currentOutputHeight() > initialActiveScreenSize.height()) { initialActiveScreenSize.setHeight(qmlOutput->outputY() + qmlOutput->currentOutputHeight()); } } auto initialScale = outputScale(); //qDebug() << " -----debug0--->outputScale" << initialScale; auto scale = initialScale; qreal lastX = -1.0; do { auto activeScreenSize = initialActiveScreenSize * scale; const QPointF offset((width() - activeScreenSize.width()) / 2.0, (height() - activeScreenSize.height()) / 2.0); // qDebug() << " ----------debug1--->offset-->" << offset; lastX = -1.0; qreal lastY = -1.0; Q_FOREACH (QQuickItem *item, childItems()) { QMLOutput *qmlOutput = qobject_cast(item); if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled() || m_manuallyMovedOutputs.contains(qmlOutput)) { continue; } qmlOutput->blockSignals(true); qmlOutput->setPosition(QPointF(offset.x() + (qmlOutput->outputX() * scale), offset.y() + (qmlOutput->outputY() * scale))); lastX = qMax(lastX, qmlOutput->position().x() + qmlOutput->width() / initialScale * scale); lastY = qMax(lastY, qmlOutput->position().y()); // qDebug()<<"坐标---->"<blockSignals(false); } Q_FOREACH (QQuickItem *item, childItems()) { QMLOutput *qmlOutput = qobject_cast(item); if (qmlOutput->output()->isConnected() && !qmlOutput->output()->isEnabled() && !m_manuallyMovedOutputs.contains(qmlOutput)) { qmlOutput->blockSignals(true); qmlOutput->setPosition(QPointF(lastX, lastY)); lastX += qmlOutput->width() / initialScale * scale; qmlOutput->blockSignals(false); } } // calculate the scale dynamically, so all screens fit to the dialog if (lastX > width()) { scale *= 0.8; } } while (lastX > width()); // Use a timer to avoid binding loop on width() QTimer::singleShot(0, this, [scale, this] { setOutputScale(scale); }); } ukui-control-center/plugins/system/touchscreen/declarative/qmloutput.cpp0000644000175000017500000004336614201663716026021 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qmloutput.h" #include "qmlscreen.h" #include #include #include #include #include const static int sMargin = 0; const static int sSnapArea = 20; const static int sSnapAlignArea = 6; Q_DECLARE_METATYPE(KScreen::ModePtr) bool operator>(const QSize &sizeA, const QSize &sizeB) { return ((sizeA.width() > sizeB.width()) && (sizeA.height() > sizeB.height())); } QMLOutput::QMLOutput(QQuickItem *parent): QQuickItem(parent), m_screen(nullptr), m_cloneOf(nullptr), m_leftDock(nullptr), m_topDock(nullptr), m_rightDock(nullptr), m_bottomDock(nullptr), m_isCloneMode(false) { connect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); connect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); } KScreen::Output* QMLOutput::output() const { return m_output.data(); } KScreen::OutputPtr QMLOutput::outputPtr() const { return m_output; } void QMLOutput::setOutputPtr(const KScreen::OutputPtr &output) { //qDebug()<<"setOutputPtr------> qmloutput"<currentMode(); if (!mode) { if (m_output->isConnected()) { mode = bestMode(); if (!mode) { return 1000; } m_output->setCurrentModeId(mode->id()); } else { return 1000; } } //qDebug()<<"mode->size().height()---->"<size()<size().height() ;/// m_output->scale(); } //返回上面小屏幕宽度 int QMLOutput::currentOutputWidth() const { if (!m_output) { return 0; } KScreen::ModePtr mode = m_output->currentMode(); if (!mode) { if (m_output->isConnected()) { mode = bestMode(); if (!mode) { return 1000; } m_output->setCurrentModeId(mode->id()); } else { return 1000; } } #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) return mode->size().width();// / m_output->scale(); #else return mode->size().width() / m_output->scale(); #endif } void QMLOutput::currentModeIdChanged() { //qDebug()<<"currentModeIdChanged---->"<outputScale(); setX((m_screen->width() - newWidth) / 2); const float newHeight = currentOutputHeight() * m_screen->outputScale(); setY((m_screen->height() - newHeight) / 2); } else { if (m_rightDock) { QMLOutput *rightDock = m_rightDock; float newWidth = currentOutputWidth() * m_screen->outputScale(); setX(rightDock->x() - newWidth); setRightDockedTo(rightDock); } if (m_bottomDock) { QMLOutput *bottomDock = m_bottomDock; float newHeight = currentOutputHeight() * m_screen->outputScale(); setY(bottomDock->y() - newHeight); setBottomDockedTo(bottomDock); } } Q_EMIT currentOutputSizeChanged(); } int QMLOutput::outputX() const { //qDebug()<<"outputX--->"<pos().x()<pos().x(); } void QMLOutput::setOutputX(int x) { // qDebug()<<"setOutputX--->"<pos().rx() == x) { return; } QPoint pos = m_output->pos(); pos.setX(x); m_output->setPos(pos); Q_EMIT outputXChanged(); } int QMLOutput::outputY() const { //qDebug()<<"outputY--->"<pos().y()<pos().y(); } void QMLOutput::setOutputY(int y) { // qDebug()<<"setOutputY--->"<pos().ry() == y) { return; } QPoint pos = m_output->pos(); pos.setY(y); m_output->setPos(pos); Q_EMIT outputYChanged(); } bool QMLOutput::isCloneMode() const { return m_isCloneMode; } void QMLOutput::setIsCloneMode(bool isCloneMode) { if (m_isCloneMode == isCloneMode) { return; } m_isCloneMode = isCloneMode; Q_EMIT isCloneModeChanged(); } void QMLOutput::dockToNeighbours() { //qDebug()<<"dockToNeighbours---->"<outputs()) { if (otherQmlOutput == this) { continue; } if (!otherQmlOutput->output()->isConnected() || !otherQmlOutput->output()->isEnabled()) { continue; } const QRect geom = m_output->geometry(); const QRect otherGeom = otherQmlOutput->output()->geometry(); //qDebug()<<"geom is ------>"<modes(); KScreen::ModePtr bestMode; Q_FOREACH (const KScreen::ModePtr &mode, modes) { if (!bestMode || (mode->size() > bestMode->size())) { bestMode = mode; } } return bestMode; } bool QMLOutput::collidesWithOutput(QObject *other) { QQuickItem* otherItem = qobject_cast(other); return boundingRect().intersects(otherItem->boundingRect()); } bool QMLOutput::maybeSnapTo(QMLOutput *other) { //qDebug()<<"maybeSnapTo---->"<x(); const qreal y2 = other->y(); const qreal height2 = other->height(); const qreal width2 = other->width(); const qreal centerX2 = x2 + (width2 / 2.0); const qreal centerY2 = y2 + (height2 / 2.0); /* left of other */ if ((x() + width() > x2 - sSnapArea) && (x() + width() < x2 + sSnapArea) && (y() + height() > y2) && (y() < y2 + height2)) { setX(x2 - width() + sMargin); centerX = x() + (width() / 2.0); setRightDockedTo(other); other->setLeftDockedTo(this); //output.cloneOf = null; /* output is snapped to other on left and their * upper sides are aligned */ if ((y() < y2 + sSnapAlignArea) && (y() > y2 - sSnapAlignArea)) { setY(y2); return true; } /* output is snapped to other on left and they * are centered */ if ((centerY < centerY2 + sSnapAlignArea) && (centerY > centerY2 - sSnapAlignArea)) { setY(centerY2 - (height() / 2.0)); return true; } /* output is snapped to other on left and their * bottom sides are aligned */ if ((y() + height() < y2 + height2 + sSnapAlignArea) && (y() + height() > y2 + height2 - sSnapAlignArea)) { setY(y2 + height2 - height()); return true; } return true; } /* output is right of other */ if ((x() > x2 + width2 - sSnapArea) && (x() < x2 + width2 + sSnapArea) && (y() + height() > y2) && (y() < y2 + height2)) { setX(x2 + width2 - sMargin); centerX = x() + (width() / 2.0); setLeftDockedTo(other); other->setRightDockedTo(this); //output.cloneOf = null; /* output is snapped to other on right and their * upper sides are aligned */ if ((y() < y2 + sSnapAlignArea) && (y() > y2 - sSnapAlignArea)) { setY(y2); return true; } /* output is snapped to other on right and they * are centered */ if ((centerY < centerY2 + sSnapAlignArea) && (centerY > centerY2 - sSnapAlignArea)) { setY(centerY2 - (height() / 2.0)); return true; } /* output is snapped to other on right and their * bottom sides are aligned */ if ((y() + height() < y2 + height2 + sSnapAlignArea) && (y() + height() > y2 + height2 - sSnapAlignArea)) { setY(y2 + height2 - height()); return true; } return true; } /* output is above other */ if ((y() + height() > y2 - sSnapArea) && (y() + height() < y2 + sSnapArea) && (x() + width() > x2) && (x() < x2 + width2)) { setY(y2 - height() + sMargin); centerY = y() + (height() / 2.0); setBottomDockedTo(other); other->setTopDockedTo(this); //output.cloneOf = null; /* output is snapped to other on top and their * left sides are aligned */ if ((x() < x2 + sSnapAlignArea) && (x() > x2 - sSnapAlignArea)) { setX(x2); return true; } /* output is snapped to other on top and they * are centered */ if ((centerX < centerX2 + sSnapAlignArea) && (centerX > centerX2 - sSnapAlignArea)) { setX(centerX2 - (width() / 2.0)); return true; } /* output is snapped to other on top and their * right sides are aligned */ if ((x() + width() < x2 + width2 + sSnapAlignArea) && (x() + width() > x2 + width2 - sSnapAlignArea)) { setX(x2 + width2 - width()); return true; } return true; } /* output is below other */ if ((y() > y2 + height2 - sSnapArea) && (y() < y2 + height2 + sSnapArea) && (x() + width() > x2) && (x() < x2 + width2)) { setY(y2 + height2 - sMargin); centerY = y() + (height() / 2.0); setTopDockedTo(other); other->setBottomDockedTo(this); //output.cloneOf = null; /* output is snapped to other on bottom and their * left sides are aligned */ if ((x() < x2 + sSnapAlignArea) && (x() > x2 - sSnapAlignArea)) { setX(x2); return true; } /* output is snapped to other on bottom and they * are centered */ if ((centerX < centerX2 + sSnapAlignArea) && (centerX > centerX2 - sSnapAlignArea)) { setX(centerX2 - (width() / 2.0)); return true; } /* output is snapped to other on bottom and their * right sides are aligned */ if ((x() + width() < x2 + width2 + sSnapAlignArea) && (x() + width() > x2 + width2 - sSnapAlignArea)) { setX(x2 + width2 - width()); return true; } return true; } if ((x() + width()) > 550) { setPosition(QPointF(550 - width(), y())); } if ((y() + height()) > 300) { setPosition(QPointF(x(), 350 - height())); } // 矩形是否相交 if (!(x() + width() < x2 || x2 + width2 < x() || y() > y2 +height2 || y2 > y() + height()) && (x() != x2 || y() != y2) && other->output()->isConnected()) { if ((x() + width() > x2) && (x() < x2)) { setX(x2 - width() + sMargin); setRightDockedTo(other); other->setLeftDockedTo(this); } else if ((x() < x2 + width2) && (x() + width() > x2 + width2)) { setX(x2 + width2 - sMargin); setLeftDockedTo(other); other->setRightDockedTo(this); } else if ((y() + height() > y2) && (y() < y2 + height2)) { setY(y2 - height() + sMargin); setBottomDockedTo(other); other->setTopDockedTo(this); } else if ((y() < y2 + height2) && (y() + height() > y2 + height2)) { setY(y2 + height2 - sMargin); setTopDockedTo(other); other->setBottomDockedTo(this); } } if (x() == x2 && y() == y2 && other->output()->isConnected()) { if (x() == 0) { setX(x() + width()); } else if (x() + width() == 550){ setX(x() - width()); } } return false; } void QMLOutput::moved() { // qDebug()<<"moved----->"< siblings = screen()->childItems(); // First, if we have moved, then unset the "cloneOf" flag setCloneOf(nullptr); disconnect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); disconnect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); Q_FOREACH (QQuickItem *sibling, siblings) { QMLOutput *otherOutput = qobject_cast(sibling); if (!otherOutput || otherOutput == this) { continue; } if (!maybeSnapTo(otherOutput)) { if (m_leftDock == otherOutput) { m_leftDock->undockRight(); undockLeft(); } if (m_topDock == otherOutput) { m_topDock->undockBottom(); undockTop(); } if (m_rightDock == otherOutput) { m_rightDock->undockLeft(); undockRight(); } if (m_bottomDock == otherOutput) { m_bottomDock->undockTop(); undockBottom(); } } } connect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); connect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); Q_EMIT moved(m_output->name()); } /* Transformation of an item (rotation of the MouseArea) is only visual. * The coordinates and dimensions are still the same (when you rotated * 100x500 rectangle by 90 deg, it will still be 100x500, although * visually it will be 500x100). * * This method calculates the real-visual coordinates and dimensions of * the MouseArea and updates root item to match them. This makes snapping * work correctly regardless off visual rotation of the output */ //旋转时计算坐标更改方向 void QMLOutput::updateRootProperties() { //qDebug()<<"updateRootProperties----->"<isHorizontal() ? currentOutputWidth() : currentOutputHeight()) * m_screen->outputScale(); const float transformedHeight = (m_output->isHorizontal() ? currentOutputHeight() : currentOutputWidth()) * m_screen->outputScale(); const float transformedX = x() + (width() / 2.0) - (transformedWidth / 2.0); const float transformedY = y() + (height() / 2.0) - (transformedHeight / 2.0); //qDebug()<<"transformedWidth: "< 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef QMLSCREEN_H #define QMLSCREEN_H #include #include #include "qmloutput.h" class QQmlEngine; namespace KScreen { class Output; class Config; } class QMLScreen : public QQuickItem { Q_OBJECT Q_PROPERTY(QSize maxScreenSize READ maxScreenSize CONSTANT) Q_PROPERTY(int connectedOutputsCount READ connectedOutputsCount NOTIFY connectedOutputsCountChanged) Q_PROPERTY(int enabledOutputsCount READ enabledOutputsCount NOTIFY enabledOutputsCountChanged) Q_PROPERTY(float outputScale READ outputScale NOTIFY outputScaleChanged) public: explicit QMLScreen(QQuickItem *parent = nullptr); ~QMLScreen() override; int connectedOutputsCount() const; int enabledOutputsCount() const; QMLOutput* primaryOutput() const; QList outputs() const; QSize maxScreenSize() const; float outputScale() const; KScreen::ConfigPtr config() const; void setConfig(const KScreen::ConfigPtr &config); void updateOutputsPlacement(); void setActiveOutput(QMLOutput *output); public Q_SLOTS: void setActiveOutput() { setActiveOutput(qobject_cast(sender())); } Q_SIGNALS: void connectedOutputsCountChanged(); void enabledOutputsCountChanged(); void outputScaleChanged(); void focusedOutputChanged(QMLOutput *output); private Q_SLOTS: void addOutput(const KScreen::OutputPtr &output); void removeOutput(int outputId); void outputConnectedChanged(); void outputEnabledChanged(); void outputPositionChanged(); void viewSizeChanged(); private: void qmlOutputMoved(QMLOutput *qmlOutput); void updateCornerOutputs(); void setOutputScale(float scale); KScreen::ConfigPtr m_config; QHash m_outputMap; QVector m_manuallyMovedOutputs; int m_connectedOutputsCount = 0; int m_enabledOutputsCount = 0; float m_outputScale = 1.0 / 8.0;//缩放比例 QMLOutput *m_leftmost = nullptr; QMLOutput *m_topmost = nullptr; QMLOutput *m_rightmost = nullptr; QMLOutput *m_bottommost = nullptr; }; #endif // QMLSCREEN_H ukui-control-center/plugins/system/touchscreen/declarative/qmloutputcomponent.cpp0000644000175000017500000000364114201663716027734 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qmloutputcomponent.h" #include "qmloutput.h" #include "qmlscreen.h" #include #include #include #include #include #include Q_DECLARE_METATYPE(KScreen::OutputPtr) Q_DECLARE_METATYPE(QMLScreen*) QMLOutputComponent::QMLOutputComponent(QQmlEngine *engine, QMLScreen *parent): QQmlComponent(engine, parent), m_engine(engine) { loadUrl(QUrl("qrc:/qml/Output.qml")); } QMLOutputComponent::~QMLOutputComponent() { } QMLOutput* QMLOutputComponent::createForOutput(const KScreen::OutputPtr &output) { QObject *instance = beginCreate(m_engine->rootContext()); if (!instance) { qWarning() << errorString(); return nullptr; } bool success = instance->setProperty("outputPtr", QVariant::fromValue(qobject_cast(output))); Q_ASSERT(success); success = instance->setProperty("screen", QVariant::fromValue(qobject_cast(parent()))); Q_ASSERT(success); Q_UNUSED(success); completeCreate(); return qobject_cast(instance); } ukui-control-center/plugins/system/touchscreen/declarative/qmloutput.h0000644000175000017500000001234314201663716025455 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef QMLOUTPUT_H #define QMLOUTPUT_H #include #include class QStandardItemModel; class QAbstractItemModel; class ModesProxyModel; class QMLScreen; class QMLOutput : public QQuickItem { Q_OBJECT Q_PROPERTY(KScreen::Output* output READ output NOTIFY outputChanged) Q_PROPERTY(KScreen::OutputPtr outputPtr READ outputPtr WRITE setOutputPtr NOTIFY outputChanged) Q_PROPERTY(bool isCloneMode READ isCloneMode WRITE setIsCloneMode NOTIFY isCloneModeChanged) Q_PROPERTY(QMLScreen* screen READ screen WRITE setScreen NOTIFY screenChanged) Q_PROPERTY(QMLOutput* cloneOf READ cloneOf WRITE setCloneOf NOTIFY cloneOfChanged) Q_PROPERTY(QMLOutput* leftDockedTo READ leftDockedTo WRITE setLeftDockedTo RESET undockLeft NOTIFY leftDockedToChanged) Q_PROPERTY(QMLOutput* topDockedTo READ topDockedTo WRITE setTopDockedTo RESET undockTop NOTIFY topDockedToChanged) Q_PROPERTY(QMLOutput* rightDockedTo READ rightDockedTo WRITE setRightDockedTo RESET undockRight NOTIFY rightDockedToChanged) Q_PROPERTY(QMLOutput* bottomDockedTo READ bottomDockedTo WRITE setBottomDockedTo RESET undockBottom NOTIFY bottomDockedToChanged) Q_PROPERTY(int currentOutputHeight READ currentOutputHeight NOTIFY currentOutputSizeChanged) Q_PROPERTY(int currentOutputWidth READ currentOutputWidth NOTIFY currentOutputSizeChanged) /* Workaround for possible QML bug when calling output.pos.y = VALUE works, * but output.pos.x = VALUE has no effect */ Q_PROPERTY(int outputX READ outputX WRITE setOutputX NOTIFY outputXChanged) Q_PROPERTY(int outputY READ outputY WRITE setOutputY NOTIFY outputYChanged) public: enum { ModeRole = Qt::UserRole, ModeIdRole, SizeRole, RefreshRateRole }; explicit QMLOutput(QQuickItem *parent = nullptr); KScreen::Output* output() const; // For QML KScreen::OutputPtr outputPtr() const; void setOutputPtr(const KScreen::OutputPtr &output); QMLScreen* screen() const; void setScreen(QMLScreen *screen); QMLOutput* leftDockedTo() const; void setLeftDockedTo(QMLOutput *output); void undockLeft(); QMLOutput* topDockedTo() const; void setTopDockedTo(QMLOutput *output); void undockTop(); QMLOutput* rightDockedTo() const; void setRightDockedTo(QMLOutput *output); void undockRight(); QMLOutput* bottomDockedTo() const; void setBottomDockedTo(QMLOutput *output); void undockBottom(); Q_INVOKABLE bool collidesWithOutput(QObject *other); Q_INVOKABLE bool maybeSnapTo(QMLOutput *other); void setCloneOf(QMLOutput *other); QMLOutput* cloneOf() const; int currentOutputHeight() const; int currentOutputWidth() const; int outputX() const; void setOutputX(int x); int outputY() const; void setOutputY(int y); void setIsCloneMode(bool isCloneMode); bool isCloneMode() const; void dockToNeighbours(); public Q_SLOTS: void updateRootProperties(); Q_SIGNALS: void changed(); void moved(const QString &self); /* Property notifications */ void outputChanged(); void screenChanged(); void cloneOfChanged(); void currentOutputSizeChanged(); void leftDockedToChanged(); void topDockedToChanged(); void rightDockedToChanged(); void bottomDockedToChanged(); void outputYChanged(); void outputXChanged(); void isCloneModeChanged(); private Q_SLOTS: void moved(); void currentModeIdChanged(); private: /** * Returns the biggest resolution available assuming it's the preferred one */ KScreen::ModePtr bestMode() const; KScreen::OutputPtr m_output; QMLScreen *m_screen; QMLOutput *m_cloneOf; QMLOutput *m_leftDock; QMLOutput *m_topDock; QMLOutput *m_rightDock; QMLOutput *m_bottomDock; bool m_isCloneMode; }; #endif // QMLOUTPUT_H ukui-control-center/plugins/system/touchscreen/declarative/qmloutputcomponent.h0000644000175000017500000000242114201663716027374 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef QMLOUTPUTCOMPONENT_H #define QMLOUTPUTCOMPONENT_H #include #include class QMLScreen; class QMLOutput; class QMLOutputComponent : public QQmlComponent { Q_OBJECT public: explicit QMLOutputComponent(QQmlEngine *engine, QMLScreen *parent); ~QMLOutputComponent() override; QMLOutput* createForOutput(const KScreen::OutputPtr &output); private: QQmlEngine *m_engine; }; #endif // QMLOUTPUTCOMPONENT_H ukui-control-center/plugins/system/touchscreen/qml/0000755000175000017500000000000014201663716021535 5ustar fengfengukui-control-center/plugins/system/touchscreen/qml/Output.qml0000644000175000017500000002214314201663716023552 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ import QtQuick 2.1 import QtGraphicalEffects 1.0 import org.kde.kscreen 1.0 QMLOutput { id: root; signal clicked(); signal primaryTriggered(string self); signal enabledToggled(string self); signal mousePressed(); signal mouseReleased(); property bool isDragged: monitorMouseArea.drag.active; property bool isDragEnabled: true; property bool isToggleButtonVisible: false; property bool hasMoved: false; width: monitorMouseArea.width; height: monitorMouseArea.height; visible: (opacity > 0); opacity: output.connected ? 1.0 : 0.0; Component.onCompleted: { root.updateRootProperties(); } SystemPalette { id: palette; } MouseArea { id: monitorMouseArea; width: root.currentOutputWidth * screen.outputScale; height: root.currentOutputHeight * screen.outputScale anchors.centerIn: parent; //是否激活时的透明度 opacity: root.output.enabled ? 1.0 : 0.3; transformOrigin: Item.Center; rotation: { if (output.rotation === KScreenOutput.None) { return 0; } else if (output.rotation === KScreenOutput.Left) { return 270; } else if (output.rotation === KScreenOutput.Inverted) { return 180; } else { return 90; } } hoverEnabled: true; preventStealing: true; drag { target: root.isDragEnabled && !root.isCloneMode ? root : null; axis: Drag.XandYAxis; minimumX: 0; maximumX: screen.maxScreenSize.width - root.width; minimumY: 0; maximumY: screen.maxScreenSize.height - root.height; filterChildren: false; } drag.onActiveChanged: { /* If the drag is shorter then the animation then make sure * we won't end up in an inconsistent state */ // console.log("宽度------>"+width) // console.log("高度------>"+height) if (dragActiveChangedAnimation.running) { dragActiveChangedAnimation.complete(); } dragActiveChangedAnimation.running = true; } onPressed: root.clicked(); /* FIXME: This could be in 'Behavior', but MouseArea had * some complaints...to tired to investigate */ PropertyAnimation { id: dragActiveChangedAnimation; target: monitor; property: "opacity"; from: monitorMouseArea.drag.active ? 0.7 : 1.0 to: monitorMouseArea.drag.active ? 1.0 : 0.7 duration: 100; easing.type: "OutCubic"; } Behavior on opacity { PropertyAnimation { property: "opacity"; easing.type: "OutCubic"; duration: 250; } } Behavior on rotation { RotationAnimation { easing.type: "OutCubic" duration: 250; direction: RotationAnimation.Shortest; } } Behavior on width { PropertyAnimation { property: "width"; easing.type: "OutCubic"; duration: 150; } } Behavior on height { PropertyAnimation { property: "height"; easing.type: "OutCubic"; duration: 150; } } Rectangle { id: monitor; anchors.fill: parent; //圆角 radius: 8; //是否点击到屏幕 color: root.focus? "#3D6BE5" : "#AEACAD"; smooth: true; clip: true; border { color: root.focus ? "#3498DB" : "#AED6F1"; width: 1; Behavior on color { PropertyAnimation { duration: 150; } } } Rectangle { id: posLabel; y: 4; x: 4; width: childrenRect.width + 5; height: childrenRect.height + 2; radius: 8; opacity: root.output.enabled && monitorMouseArea.drag.active ? 1.0 : 0.0; visible: opacity != 0.0; color: "#101010"; Text { id: posLabelText; text: root.outputX + "," + root.outputY; color: "white"; y: 2; x: 2; } } Item { //文字位置 y: ((parent.height - orientationPanel.height) / 2) - (implicitHeight / 2) anchors { left: parent.left; right: parent.right; leftMargin: 5; rightMargin: 5; } Text { id: nameLabel text: if (root.isCloneMode === true) { return ""; } else if (root.output.type !== KScreenOutput.Panel && root.output.edid && root.output.edid.name) { return root.output.edid.name; } else { return ""; } //上面文字颜色 color: "#FFFFFF"; font.pixelSize: 12; anchors { horizontalCenter: parent.horizontalCenter; bottom: labelVendor.top; topMargin: 5; } } Text { id: labelVendor; text: if (root.isCloneMode) { return ("Unified Outputs"); } else if (root.output.type === KScreenOutput.Panel) { return ("Laptop Screen"); } else if (root.output.edid && root.output.edid.vendor) { return root.output.edid.vendor; } else { return root.output.name; } anchors { verticalCenter: parent.verticalCenter; left: parent.left; right: parent.right; } horizontalAlignment: Text.AlignHCenter; //下面文字颜色 //color: palette.text; color: "#FFFFFF"; font.pixelSize: 10; elide: Text.ElideRight; } Text { id: label text: (labelVendor.text === root.output.name) ? "" : root.output.name color: palette.text; font.pixelSize: 10; anchors { horizontalCenter: parent.horizontalCenter; top: labelVendor.bottom; topMargin: 5; } } } } Item { id: orientationPanelContainer; anchors.fill: monitor; visible: false Rectangle { id: orientationPanel; //注释底部不会变色拖动时候 // anchors { // left: parent.left; // right: parent.right; // bottom: parent.bottom; // } height: 10; //color: root.focus ? palette.highlight : palette.shadow; //底部颜色 color: palette.highlight ; smooth: true; Behavior on color { PropertyAnimation { duration: 150; } } } } OpacityMask { anchors.fill: orientationPanelContainer; source: orientationPanelContainer; maskSource: monitor; } } Behavior on opacity { PropertyAnimation { duration: 200; easing.type: "OutCubic"; } } } ukui-control-center/plugins/system/touchscreen/qml/main.qml0000644000175000017500000000364014201663716023177 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ import QtQuick 2.1 import QtQuick.Controls 1.1 as Controls //import org.kde.plasma.core 2.0 as PlasmaCore //import org.kde.kquickcontrols 2.0 import org.kde.kscreen 1.0 Item { id: root; property variant virtualScreen: null; objectName: "root"; focus: true; SystemPalette { id: palette; } Rectangle { id: background; anchors.fill: parent; focus: true; // color: "#000000"; color: "transparent"; // color: palette.button; // opacity: 0.6; // radius: 6 //设置矩形圆角弧度 FocusScope { id: outputViewFocusScope; anchors.fill: parent; focus: true; QMLScreen { id: outputView; anchors.fill: parent; clip: true; objectName: "outputView"; } } Column { anchors { left: parent.left; //right: identifyButton.left; bottom: parent.bottom; margins: 5; } spacing: 5; } } } ukui-control-center/plugins/system/touchscreen/qml/ui_touchscreen.h0000644000175000017500000001414714201663716024734 0ustar fengfeng/******************************************************************************** ** Form generated from reading UI file 'touchscreen.ui' ** ** Created by: Qt User Interface Compiler version 5.12.8 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ #ifndef UI_TOUCHSCREEN_H #define UI_TOUCHSCREEN_H #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class Ui_TouchScreen { public: QFrame *screenframe; QHBoxLayout *horizontalLayout; QLabel *monitorLabel; QComboBox *monitorCombo; QFrame *screenframe_2; QHBoxLayout *horizontalLayout_2; QLabel *touchLabel; QComboBox *touchscreenCombo; QWidget *layoutWidget; QFormLayout *formLayout; QPushButton *mapButton; QPushButton *CalibrationButton; QSpacerItem *horizontalSpacer_4; QLabel *touchscreenLabel; QLabel *touchnameContent; void setupUi(QWidget *TouchScreen) { if (TouchScreen->objectName().isEmpty()) TouchScreen->setObjectName(QString::fromUtf8("TouchScreen")); TouchScreen->resize(917, 349); screenframe = new QFrame(TouchScreen); screenframe->setObjectName(QString::fromUtf8("screenframe")); screenframe->setGeometry(QRect(0, 110, 741, 50)); screenframe->setMinimumSize(QSize(550, 50)); screenframe->setMaximumSize(QSize(960, 50)); screenframe->setFrameShape(QFrame::Box); horizontalLayout = new QHBoxLayout(screenframe); horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); monitorLabel = new QLabel(screenframe); monitorLabel->setObjectName(QString::fromUtf8("monitorLabel")); monitorLabel->setMinimumSize(QSize(118, 30)); monitorLabel->setMaximumSize(QSize(118, 30)); horizontalLayout->addWidget(monitorLabel); monitorCombo = new QComboBox(screenframe); monitorCombo->setObjectName(QString::fromUtf8("monitorCombo")); monitorCombo->setMinimumSize(QSize(200, 0)); monitorCombo->setMaximumSize(QSize(16777215, 30)); monitorCombo->setStyleSheet(QString::fromUtf8("")); horizontalLayout->addWidget(monitorCombo); screenframe_2 = new QFrame(TouchScreen); screenframe_2->setObjectName(QString::fromUtf8("screenframe_2")); screenframe_2->setGeometry(QRect(0, 170, 741, 50)); screenframe_2->setMinimumSize(QSize(550, 50)); screenframe_2->setMaximumSize(QSize(960, 50)); screenframe_2->setFrameShape(QFrame::Box); horizontalLayout_2 = new QHBoxLayout(screenframe_2); horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); touchLabel = new QLabel(screenframe_2); touchLabel->setObjectName(QString::fromUtf8("touchLabel")); touchLabel->setMinimumSize(QSize(118, 30)); touchLabel->setMaximumSize(QSize(118, 30)); horizontalLayout_2->addWidget(touchLabel); touchscreenCombo = new QComboBox(screenframe_2); touchscreenCombo->setObjectName(QString::fromUtf8("touchscreenCombo")); touchscreenCombo->setMinimumSize(QSize(200, 0)); touchscreenCombo->setMaximumSize(QSize(16777215, 30)); touchscreenCombo->setStyleSheet(QString::fromUtf8("")); horizontalLayout_2->addWidget(touchscreenCombo); layoutWidget = new QWidget(TouchScreen); layoutWidget->setObjectName(QString::fromUtf8("layoutWidget")); layoutWidget->setGeometry(QRect(0, 230, 741, 38)); formLayout = new QFormLayout(layoutWidget); formLayout->setObjectName(QString::fromUtf8("formLayout")); formLayout->setContentsMargins(0, 0, 0, 0); mapButton = new QPushButton(layoutWidget); mapButton->setObjectName(QString::fromUtf8("mapButton")); mapButton->setMinimumSize(QSize(120, 36)); mapButton->setMaximumSize(QSize(16777215, 36)); mapButton->setLayoutDirection(Qt::LeftToRight); CalibrationButton = new QPushButton(layoutWidget); CalibrationButton->setObjectName(QString::fromUtf8("CalibrationButton")); CalibrationButton->setMinimumSize(QSize(120, 36)); CalibrationButton->setMaximumSize(QSize(16777215, 36)); CalibrationButton->setLayoutDirection(Qt::LeftToRight); CalibrationButton->setGeometry(QRect(100,100,100,22)); formLayout->setWidget(0, QFormLayout::LabelRole, mapButton); horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); formLayout->setItem(0, QFormLayout::FieldRole, horizontalSpacer_4); touchscreenLabel = new QLabel(TouchScreen); touchscreenLabel->setObjectName(QString::fromUtf8("touchscreenLabel")); touchscreenLabel->setGeometry(QRect(0, 0, 913, 22)); touchnameContent = new QLabel(TouchScreen); touchnameContent->setObjectName(QString::fromUtf8("touchnameContent")); touchnameContent->setGeometry(QRect(0, 230, 431, 22)); QWidget::setTabOrder(monitorCombo, touchscreenCombo); QWidget::setTabOrder(touchscreenCombo, mapButton); retranslateUi(TouchScreen); QMetaObject::connectSlotsByName(TouchScreen); } // setupUi void retranslateUi(QWidget *TouchScreen) { TouchScreen->setWindowTitle(QApplication::translate("TouchScreen", "TouchScreen", nullptr)); monitorLabel->setText(QApplication::translate("TouchScreen", "monitor", nullptr)); touchLabel->setText(QApplication::translate("TouchScreen", "touch screen", nullptr)); mapButton->setText(QApplication::translate("TouchScreen", "map", nullptr)); touchscreenLabel->setText(QApplication::translate("TouchScreen", "TouchScreen", nullptr)); } // retranslateUi }; namespace Ui { class TouchScreen: public Ui_TouchScreen {}; } // namespace Ui QT_END_NAMESPACE #endif // UI_TOUCHSCREEN_H ukui-control-center/plugins/system/touchscreen/monitorinputtask.h0000644000175000017500000000524614201663716024556 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef MONITORINPUTTASK_H #define MONITORINPUTTASK_H #include #include #include #include #include #include #include #include #include class MonitorInputTask : public QObject { Q_OBJECT public: bool m_running; public: static MonitorInputTask* instance(QObject *parent = nullptr); public Q_SLOTS: void StartManager(); Q_SIGNALS: /*! * \brief slaveAdded 从设备添加 * \param device_id */ void slaveAdded(int device_id); /*! * \brief slaveRemoved 从设备移除 * \param device_id */ void slaveRemoved(int device_id); /*! * \brief masterAdded 主分支添加 * \param device_id */ void masterAdded(int device_id); /*! * \brief masterRemoved 主分支移除 * \param device_id */ void masterRemoved(int device_id); /*! * \brief deviceEnable 设备启用 * \param device_id */ void deviceEnable(int device_id); /*! * \brief deviceDisable 设备禁用 * \param device_id */ void deviceDisable(int device_id); /*! * \brief slaveAttached 从设备附加 * \param device_id */ void slaveAttached(int device_id); /*! * \brief slaveDetached 从设备分离 * \param device_id */ void slaveDetached(int device_id); private: MonitorInputTask(QObject *parent = nullptr); void initConnect(); /*! * \brief ListeningToInputEvent 监听所有输入设备的事件 */ void ListeningToInputEvent(); /*! * \brief EventSift 筛选出发生事件的设备ID * \param event 所有设备的事件信息 * \param flag 当前发生的事件 * \return 查找失败 return -1; 查找成功 return device_id; */ int EventSift(XIHierarchyEvent *event, int flag); }; #endif // MONITORINPUTTASK_H ukui-control-center/plugins/system/touchscreen/touchscreen.ui0000644000175000017500000001750514201663716023635 0ustar fengfeng TouchScreen 0 0 779 461 TouchScreen 0 0 32 48 TouchScreen 550 50 16777215 50 QFrame::Box 118 30 118 30 Monitor monitorCombo 200 0 16777215 30 false 550 50 16777215 50 QFrame::Box 118 30 118 30 touch id touchscreenCombo 200 0 16777215 30 550 50 16777215 50 QFrame::Box QFrame::Plain true 118 30 118 30 input device TextLabel 120 36 16777215 36 Qt::LeftToRight map 120 36 16777215 36 Qt::LeftToRight calibration Qt::Horizontal 268 20 16 No touch screen found Qt::Vertical 558 150 TitleLabel QLabel
    Label/titlelabel.h
    monitorCombo touchscreenCombo mapButton
    ukui-control-center/plugins/system/touchscreen/touchscreen.pro0000644000175000017500000000365114201663716024015 0ustar fengfeng include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/closebutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) QT += widgets core gui quickwidgets quick xml KScreen KI18n KConfigCore KConfigWidgets KWidgetsAddons dbus TEMPLATE = lib CONFIG += c++11 link_pkgconfig plugin # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS UI_DIR=./ # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 TARGET = $$qtLibraryTarget(touchscreen) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INSTALLS += target INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -ludev PKGCONFIG += gsettings-qt \ gtk+-3.0 \ # glib-2.0 \ mate-desktop-2.0 \ libudev \ SOURCES += \ declarative/qmloutput.cpp \ declarative/qmloutputcomponent.cpp \ declarative/qmlscreen.cpp \ monitorinputtask.cpp \ touchscreen.cpp \ touchserialquery.cpp \ utils.cpp \ widget.cpp \ xinputmanager.cpp HEADERS += \ declarative/qmloutput.h \ declarative/qmloutputcomponent.h \ declarative/qmlscreen.h \ monitorinputtask.h \ touchscreen.h \ touchserialquery.h \ utils.h \ widget.h \ xinputmanager.h FORMS += \ touchscreen.ui RESOURCES += \ qml.qrc ukui-control-center/plugins/system/touchscreen/widget.h0000644000175000017500000000767314201663716022415 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef WIDGET_H #define WIDGET_H // #include #include #include #include #include #include #include #include #include #include #include #include #include class QLabel; class QMLOutput; class QMLScreen; class PrimaryOutputCombo; class QPushButton; class QComboBox; class QStyledItemDelegate; class XinputManager; namespace KScreen { class ConfigOperation; } namespace Ui { class TouchScreen; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget() override; void setConfig(const KScreen::ConfigPtr &config); KScreen::ConfigPtr currentConfig() const; void slotFocusedOutputChangedNoParam(); void initConnection(); void initui(); QString getScreenName(QString name = ""); bool event(QEvent *event); protected: Q_SIGNALS: void changed(); private Q_SLOTS: void slotFocusedOutputChanged(QMLOutput *output); void slotOutputConnectedChanged(); void outputAdded(const KScreen::OutputPtr &output); void outputRemoved(int outputId); void touchscreenAdded(); void touchscreenRemoved(); void curOutoutChanged(int index); void curTouchScreenChanged(int index); void primaryOutputSelected(int index); public Q_SLOTS: void maptooutput(); void CalibratTouch(); private: void loadQml(); void save(QString touchname,QString touchid,QString screenname); void initTouchConfig(QString touchserial,QString touchname,QString screenname); void writeTouchConfig(); void writeTouchConfig(QString touchname,QString touchid,QString touchserial,QString devnode ,QString screenname); bool Configserialisexit(QString touchserial,QString devnode,QString touchname); void cleanTouchConfig(int touchcount); int compareserial(int touchcount); int comparescreenname(QString _touchserial,QString _touchname ,QString _screenname); void resetPrimaryCombo(); void resettouchscreenCombo(); void addOutputToMonitorCombo(const KScreen::OutputPtr &output); void addTouchScreenToTouchCombo(const QString touchscreenname ); bool findTouchScreen(); QString findTouchScreenName(int devicesid); KScreen::OutputPtr findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info); private: Ui::TouchScreen *ui; XinputManager *m_pXinputManager; QMLScreen *mScreen = nullptr; QSettings *configIni; QDir *qdir; QString CurTouchScreenName = ""; QString CurMonitorName = ""; QString CurDevicesName=""; int CurTouchscreenNum; #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) KScreen::ConfigPtr mConfig ; KScreen::ConfigPtr mPrevConfig ; //这是outPutptr结果 KScreen::OutputPtr res ; #else KScreen::ConfigPtr mConfig = nullptr; KScreen::ConfigPtr mPrevConfig = nullptr; // outPutptr结果 KScreen::OutputPtr res = nullptr; #endif QButtonGroup *singleButton; bool mOriApply; bool mConfigChanged = false; bool mOnBattery = false; bool m_blockChanges = false; }; #endif // WIDGET_H ukui-control-center/plugins/system/touchscreen/touchserialquery.cpp0000644000175000017500000001347014201663716025065 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include static int find_event_from_touchId(int pId ,char *_event,char *devnode,int max_len) { Display *_dpy = XOpenDisplay(NULL); int ret = -1; if(NULL == _dpy || NULL == _event) { printf("[%s%d] NULL ptr. \n", __FUNCTION__, __LINE__); return ret; } int i = 0; int j = 0; int num_devices = 0; XDeviceInfo *pXDevs_info = NULL; XDevice *pXDev = NULL; unsigned char *cNode = NULL; const char cName[] = "event"; const char *cEvent = NULL; int nprops = 0; Atom *props = NULL; char *name; Atom act_type; int act_format; unsigned long nitems, bytes_after; unsigned char *data; pXDevs_info = XListInputDevices(_dpy, &num_devices); for(i = 0; i < num_devices; i++) { pXDev = XOpenDevice(_dpy, pXDevs_info[i].id); if (!pXDev) { printf("unable to open device '%s'\n", pXDevs_info[i].name); continue; } props = XListDeviceProperties(_dpy, pXDev, &nprops); if (!props) { printf("Device '%s' does not report any properties.\n", pXDevs_info[i].name); continue; } //printf("pId=%d, pXDevs_info[i].id=%d \n",pId,pXDevs_info[i].id); if(pId == pXDevs_info[i].id) { for(j = 0; j < nprops; j++) { name = XGetAtomName(_dpy, props[j]); if(0 != strcmp(name, "Device Node")) { continue; } XGetDeviceProperty(_dpy, pXDev, props[j], 0, 1000, False, AnyPropertyType, &act_type, &act_format, &nitems, &bytes_after, &data); cNode = data; } if(NULL == cNode) { continue; } cEvent = strstr((const char*)cNode, cName); if(NULL == cEvent) { continue; } strcpy(devnode,(const char*)cNode); strncpy(_event, cEvent, max_len>0?(max_len-1):max_len); //printf("cNode=%s,cEvent=%s,_event=%s\n",cNode,cEvent,_event); ret = Success; break; } } return ret; } static int find_serial_from_event(char *_name, char *_event, char *_serial, int max_len) { int ret = -1; if((NULL == _name) || (NULL == _event)) { printf("[%s%d] NULL ptr. \n", __FUNCTION__, __LINE__); return ret; } struct udev *udev; struct udev_enumerate *enumerate; struct udev_list_entry *devices, *dev_list_entry; struct udev_device *dev; udev = udev_new(); enumerate = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(enumerate, "input"); udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); udev_list_entry_foreach(dev_list_entry, devices) { const char *pPath; const char *pEvent; const char cName[] = "event"; pPath = udev_list_entry_get_name(dev_list_entry); //printf("[%s%d] path: %s\n",__FUNCTION__, __LINE__, pPath); dev = udev_device_new_from_syspath(udev, pPath); //touchScreen is usb_device dev = udev_device_get_parent_with_subsystem_devtype( dev, "usb", "usb_device"); if (!dev) { //printf("Unable to find parent usb device. \n"); continue; } const char *pProduct = udev_device_get_sysattr_value(dev,"product"); pEvent = strstr(pPath, cName); if(NULL == pEvent || (NULL == pProduct)) { continue; } //printf("pEvent=%s,_event=%s\n",pEvent,_event); //printf("_name=%s,pProduct=%s\n",_name,pProduct); char *ret=strstr(_name, pProduct); if((NULL!=ret) && (0 == strcmp(_event, pEvent))) { const char *pSerial = udev_device_get_sysattr_value(dev, "serial"); //printf(" _serial:%s\n pSerial: %s\n",_serial, pSerial); if(NULL == pSerial) { continue; } strncpy(_serial, pSerial, max_len>0?(max_len-1):max_len); ret = Success; //printf(" _serial:%s\n pSerial: %s\n",_serial, pSerial); break; } udev_device_unref(dev); } udev_enumerate_unref(enumerate); udev_unref(udev); return ret; } int findSerialFromId(int touchid,char *touchname,char *_touchserial,char *devnode,int maxlen) { char event[32]={0}; int ret=find_event_from_touchId(touchid, event,devnode, 32); ret=find_serial_from_event(touchname, event,_touchserial,maxlen); if(!strcmp(_touchserial,"")) strncpy(_touchserial,"kydefault",maxlen>0?(maxlen-1):maxlen); return ret; } ukui-control-center/plugins/system/touchscreen/monitorinputtask.cpp0000644000175000017500000001130014201663716025075 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "monitorinputtask.h" //#include "xinputmanager.h" MonitorInputTask* MonitorInputTask::instance(QObject *parent) { static MonitorInputTask *_instance = nullptr; QMutex mutex; mutex.lock(); if(!_instance) _instance = new MonitorInputTask(parent); mutex.unlock(); return _instance; } MonitorInputTask::MonitorInputTask(QObject *parent): QObject(parent), m_running(false) { initConnect(); } void MonitorInputTask::initConnect() { } void MonitorInputTask::StartManager() { qDebug() << "info: [MonitorInputTask][StartManager]: thread id = " << QThread::currentThreadId(); QTimer::singleShot(0, this, &MonitorInputTask::ListeningToInputEvent); } int MonitorInputTask::EventSift(XIHierarchyEvent *event, int flag) { int device_id = -1; int cnt = event->num_info; XIHierarchyInfo *event_list = event->info; for(int i = 0;i < cnt;i++) { if(event_list[i].flags & flag) { device_id = event_list[i].deviceid; } } return device_id; } void MonitorInputTask::ListeningToInputEvent() { qDebug() << "info: [MonitorInputTask][ListeningToInputEvent]: Start ListeningToInputEvent!"; Display *display = NULL; // open display display = XOpenDisplay(NULL); if (display == NULL) { qDebug() << "info: [MonitorInputTask][ListeningToInputEvent]: Failed to open display."; return; } XIEventMask mask[2]; XIEventMask *m; Window win; win = DefaultRootWindow(display); m = &mask[0]; m->deviceid = XIAllDevices; m->mask_len = XIMaskLen(XI_LASTEVENT); m->mask = (unsigned char*)calloc(m->mask_len, sizeof(char)); XISetMask(m->mask, XI_HierarchyChanged); m = &mask[1]; m->deviceid = XIAllMasterDevices; m->mask_len = XIMaskLen(XI_LASTEVENT); m->mask = (unsigned char*)calloc(m->mask_len, sizeof(char)); XISelectEvents(display, win, &mask[0], 2); XSync(display, False); free(mask[0].mask); free(mask[1].mask); mask[0].mask = NULL; mask[1].mask = NULL; while(true) { XEvent ev; XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; XNextEvent(display, (XEvent*)&ev); // 判断当前事件监听是否还要继续 // 保证效率 m_running[*bool] 的访问不需要加锁 if(!m_running) break; if (XGetEventData(display, cookie) && cookie->type == GenericEvent) { if(XI_HierarchyChanged == cookie->evtype) { XIHierarchyEvent *hev = (XIHierarchyEvent*)cookie->data; if(hev->flags & XIMasterRemoved) { Q_EMIT masterRemoved(EventSift(hev, XIMasterRemoved)); } else if(hev->flags & XISlaveAdded) { Q_EMIT slaveAdded(EventSift(hev, XISlaveAdded)); } else if(hev->flags & XISlaveRemoved) { Q_EMIT slaveRemoved(EventSift(hev, XISlaveRemoved)); } else if(hev->flags & XISlaveAttached) { Q_EMIT slaveAttached(EventSift(hev, XISlaveAttached)); } else if(hev->flags & XISlaveDetached) { Q_EMIT slaveDetached(EventSift(hev, XISlaveDetached)); } else if(hev->flags & XIDeviceEnabled) { Q_EMIT deviceEnable(EventSift(hev, XIDeviceEnabled)); } else if(hev->flags & XIDeviceDisabled) { Q_EMIT deviceDisable(EventSift(hev, XIDeviceDisabled)); } else if(hev->flags & XIMasterAdded) { Q_EMIT masterAdded(EventSift(hev, XIMasterAdded)); } } } XFreeEventData(display, cookie); } XDestroyWindow(display, win); } ukui-control-center/plugins/system/touchscreen/utils.cpp0000644000175000017500000000334614201663716022616 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "utils.h" #include #include QString Utils::outputName(const KScreen::OutputPtr& output) { return outputName(output.data()); } QString Utils::outputName(const KScreen::Output *output) { if (output->edid()) { // The name will be "VendorName ModelName (ConnectorName)", // but some components may be empty. QString name; if (!(output->edid()->vendor().isEmpty())) { name = output->edid()->vendor() + QLatin1Char(' '); } if (!output->edid()->name().isEmpty()) { name += output->edid()->name() + QLatin1Char(' '); } if (!name.trimmed().isEmpty()) { //return name + QLatin1Char('(') + output->name() + QLatin1Char(')'); return output->name(); } } return output->name(); } QString Utils::sizeToString(const QSize &size) { return QStringLiteral("%1x%2").arg(size.width()).arg(size.height()); } ukui-control-center/plugins/system/touchscreen/utils.h0000644000175000017500000000217314201663716022260 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef UTILS_H #define UTILS_H #include #include #include #include //获取显示器名字和ID类 namespace Utils { QString outputName(const KScreen::Output *output); QString outputName(const KScreen::OutputPtr &output); QString sizeToString(const QSize &size); } #endif // UTILS_H ukui-control-center/plugins/system/touchscreen/touchscreen.cpp0000644000175000017500000000343714201663716024001 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "touchscreen.h" #include "ui_touchscreen.h" #include #include #include #include TouchScreen::TouchScreen() : mFirstLoad(true) { pluginName = tr("TouchScreen"); pluginType = SYSTEM; } TouchScreen::~TouchScreen() { } QWidget *TouchScreen::get_plugin_ui() { if (mFirstLoad) { mFirstLoad = false; pluginWidget = new Widget; QObject::connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, [&](KScreen::ConfigOperation *op) { QThread::usleep(20000); pluginWidget->setConfig(qobject_cast(op)->config()); }); } return pluginWidget; } QString TouchScreen::get_plugin_name() { return pluginName; } int TouchScreen::get_plugin_type() { return pluginType; } void TouchScreen::plugin_delay_control() { } const QString TouchScreen::name() const { return QStringLiteral("touchscreen"); } ukui-control-center/plugins/system/touchscreen/widget.cpp0000644000175000017500000005176514201663716022751 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define MATE_DESKTOP_USE_UNSTABLE_API #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "declarative/qmloutput.h" #include "declarative/qmlscreen.h" #include "utils.h" #include "ui_touchscreen.h" #include "widget.h" #include "touchserialquery.h" #include "xinputmanager.h" #ifdef signals #undef signals #endif #define QML_PATH "kcm_kscreen/qml/" #define UKUI_CONTORLCENTER_PANEL_SCHEMAS "org.ukui.control-center.panel.plugins" #define FONT_RENDERING_DPI "org.ukui.SettingsDaemon.plugins.xsettings" #define ADVANCED_SCHEMAS "org.ukui.session.required-components" #define ADVANCED_KEY "windowmanager" #define TOUCHSCREEN_CFG_PATH "/.config/touchcfg.ini" Q_DECLARE_METATYPE(KScreen::OutputPtr) Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::TouchScreen()) { qRegisterMetaType(); gdk_init(NULL, NULL); m_pXinputManager=new XinputManager; m_pXinputManager->start(); ui->setupUi(this); ui->touchscreenLabel->setStyleSheet("QLabel{color: palette(windowText);}"); //~ contents_path /touchscreen/touch id ui->touchLabel->setText(tr("touch id")); //~ contents_path /touchscreen/monitor ui->monitorLabel->setText(tr("Monitor")); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) oriApply = true; #else mOriApply = false; #endif initConnection(); initui(); loadQml(); } void Widget::initui(){ if (findTouchScreen()){ qDebug() << "Touch Screen Devices Available"; ui->tipLabel->hide(); ui->screenFrame->show(); ui->touchscreenFrame->show(); ui->deviceinfoFrame->show(); ui->mapButton->show(); ui->CalibrationButton->show(); //initTouchScreenStatus(); } else { qDebug() << "Touch Screen Devices Unavailable"; ui->screenFrame->hide(); ui->touchscreenFrame->hide(); ui->deviceinfoFrame->hide(); ui->mapButton->hide(); ui->CalibrationButton->hide(); ui->tipLabel->show(); } } void Widget::loadQml() { } Widget::~Widget() { //clearOutputIdentifiers(); delete ui; ui = nullptr; } //接收触摸事件 bool Widget::event(QEvent *event) { switch( event->type() ) { case QEvent::TouchBegin: { QTouchEvent* touch = static_cast(event); QList touch_list = touch->touchPoints(); touch_list.at(0).pos().x(); touch_list.at(0).pos().y(); event->accept(); return true; } case QEvent::TouchUpdate: { QTouchEvent* touch = static_cast(event); if(touch->touchPointStates() & Qt::TouchPointPressed){ //判断是否有触摸点处于TouchPointPressed或TouchPointMoved或TouchPointStationary或TouchPointReleased } event->accept(); return true; } case QEvent::TouchEnd: { //QTouchEvent* touch = static_cast(event); event->accept(); return true; } default:break; } return QWidget::event(event); } void Widget::setConfig(const KScreen::ConfigPtr &config) { if (mConfig) { KScreen::ConfigMonitor::instance()->removeConfig(mConfig); for (const KScreen::OutputPtr &output : mConfig->outputs()) { output->disconnect(this); } mConfig->disconnect(this); } mConfig = config; mPrevConfig = config->clone(); KScreen::ConfigMonitor::instance()->addConfig(mConfig); resetPrimaryCombo(); resettouchscreenCombo(); connect(mConfig.data(), &KScreen::Config::outputAdded, this, &Widget::outputAdded); connect(mConfig.data(), &KScreen::Config::outputRemoved, this, &Widget::outputRemoved); for (const KScreen::OutputPtr &output : mConfig->outputs()) { outputAdded(output); } } KScreen::ConfigPtr Widget::currentConfig() const { return mConfig; } void Widget::resetPrimaryCombo() { // Don't emit currentIndexChanged when resetting bool blocked = ui->monitorCombo->blockSignals(true); ui->monitorCombo->clear(); ui->monitorCombo->blockSignals(blocked); if (!mConfig) { return; } for (auto &output: mConfig->outputs()) { addOutputToMonitorCombo(output); } } void Widget::resettouchscreenCombo() { // Don't emit currentIndexChanged when resetting bool blocked = ui->touchscreenCombo->blockSignals(true); ui->touchscreenCombo->clear(); ui->touchscreenCombo->blockSignals(blocked); findTouchScreen(); } void Widget::addOutputToMonitorCombo(const KScreen::OutputPtr &output) { // 注释后让他显示全部屏幕下拉框 if (!output->isConnected()) { return; } ui->monitorCombo->addItem(Utils::outputName(output), output->id()); if (output->isPrimary()) { Q_ASSERT(mConfig); int lastIndex = ui->monitorCombo->count() - 1; ui->monitorCombo->setCurrentIndex(lastIndex); } } //这里从屏幕点击来读取输出 void Widget::slotFocusedOutputChanged(QMLOutput *output) { //读取屏幕点击选择下拉框 Q_ASSERT(mConfig); int index = output->outputPtr().isNull() ? 0 : ui->monitorCombo->findData(output->outputPtr()->id()); if (index == -1 || index == ui->monitorCombo->currentIndex()) { return; } ui->monitorCombo->setCurrentIndex(index); } void Widget::slotOutputConnectedChanged() { resetPrimaryCombo(); } // FIXME: Copy-pasted from KDED's Serializer::findOutput() KScreen::OutputPtr Widget::findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info) { KScreen::OutputList outputs = config->outputs(); Q_FOREACH(const KScreen::OutputPtr &output, outputs) { if (!output->isConnected()) { continue; } const QString outputId = (output->edid() && output->edid()->isValid()) ? output->edid()->hash() : output->name(); if (outputId != info[QStringLiteral("id")].toString()) { continue; } QVariantMap posInfo = info[QStringLiteral("pos")].toMap(); QPoint point(posInfo[QStringLiteral("x")].toInt(), posInfo[QStringLiteral("y")].toInt()); output->setPos(point); output->setPrimary(info[QStringLiteral("primary")].toBool()); output->setEnabled(info[QStringLiteral("enabled")].toBool()); output->setRotation(static_cast(info[QStringLiteral("rotation")].toInt())); QVariantMap modeInfo = info[QStringLiteral("mode")].toMap(); QVariantMap modeSize = modeInfo[QStringLiteral("size")].toMap(); QSize size(modeSize[QStringLiteral("width")].toInt(), modeSize[QStringLiteral("height")].toInt()); const KScreen::ModeList modes = output->modes(); Q_FOREACH(const KScreen::ModePtr &mode, modes) { if (mode->size() != size) { continue; } if (QString::number(mode->refreshRate()) != modeInfo[QStringLiteral("refresh")].toString()) { continue; } output->setCurrentModeId(mode->id()); break; } return output; } return KScreen::OutputPtr(); } void Widget::outputAdded(const KScreen::OutputPtr &output) { connect(output.data(), &KScreen::Output::isConnectedChanged, this, &Widget::slotOutputConnectedChanged); //addOutputToMonitorCombo(output); } void Widget::outputRemoved(int outputId) { KScreen::OutputPtr output = mConfig->output(outputId); if (!output.isNull()) { output->disconnect(this); } const int index = ui->monitorCombo->findData(outputId); if (index == -1) { return; } if (index == ui->monitorCombo->currentIndex()) { // We'll get the actual primary update signal eventually // Don't emit currentIndexChanged const bool blocked = ui->monitorCombo->blockSignals(true); ui->monitorCombo->setCurrentIndex(0); ui->monitorCombo->blockSignals(blocked); } ui->monitorCombo->removeItem(index); } void Widget::touchscreenAdded() { initui(); resettouchscreenCombo(); } void Widget::touchscreenRemoved() { initui(); resettouchscreenCombo(); } void Widget::primaryOutputSelected(int index) { if (!mConfig) { return; } const KScreen::OutputPtr newPrimary = index == 0 ? KScreen::OutputPtr() : mConfig->output(ui->monitorCombo->itemData(index).toInt()); if (newPrimary == mConfig->primaryOutput()) { return; } mConfig->setPrimaryOutput(newPrimary); Q_EMIT changed(); } void Widget::initConnection() { connect(ui->monitorCombo, static_cast(&QComboBox::currentIndexChanged), this, &Widget::curOutoutChanged); connect(ui->touchscreenCombo, static_cast(&QComboBox::currentIndexChanged), this, &Widget::curTouchScreenChanged); // TODO: Find out why adjusting the screen orientation does not take effect connect(ui->mapButton, &QPushButton::clicked, this, [=]() { maptooutput(); }); connect(ui->CalibrationButton, &QPushButton::clicked, this, [=]() { CalibratTouch(); }); connect(m_pXinputManager, &XinputManager::xinputSlaveAdded, this, &Widget::touchscreenAdded); connect(m_pXinputManager, &XinputManager::xinputSlaveRemoved, this, &Widget::touchscreenRemoved); } void Widget::curOutoutChanged(int index) { const KScreen::OutputPtr &output=mConfig->output(ui->monitorCombo->itemData(index).toInt()); CurMonitorName = output.data()->name(); } void Widget::curTouchScreenChanged(int index) { int CurDevicesId; CurTouchScreenName= ui->touchscreenCombo->itemText(ui->touchscreenCombo->currentIndex()); CurDevicesId=ui->touchscreenCombo->itemText(ui->touchscreenCombo->currentIndex()).toInt(); CurDevicesName=findTouchScreenName(CurDevicesId); ui->touchnameContent->setText(CurDevicesName); } //触摸映射 void Widget::maptooutput() { Display *dpy=XOpenDisplay(NULL); QLibrary lib("/usr/lib/libkysset.so"); std::string touchstr = CurTouchScreenName.toStdString(); std::string monitorstr = CurMonitorName.toStdString(); const char* _CurTouchScreenName = touchstr.c_str(); const char* _CurMonitorName = monitorstr.c_str(); if(lib.load()){ typedef int(*MapToOutput)(Display *,const char *,const char *); MapToOutput _maptooutput=(MapToOutput)lib.resolve("MapToOutput"); if(!_maptooutput){ qDebug("maptooutput resolve failed!\n"); }else{ int ret=_maptooutput(dpy,_CurTouchScreenName,_CurMonitorName); if(!ret){ save(CurDevicesName,CurTouchScreenName,CurMonitorName); //保存映射关系 }else{ qDebug("MapToOutput exe failed ! ret=%d\n",ret); } } lib.unload(); }else{ qDebug("/usr/lib/libkysset.so not found!\n"); } XCloseDisplay(dpy); } /*触摸校准 * 通过dbus信号与kylin-xinput-calibration应用交互 * 发送触摸校准事件并传递相关参数 */ void Widget::CalibratTouch() { QDBusMessage msg =QDBusMessage::createSignal("/com/control/center/calibrator", "com.control.center.calibrator.interface", "calibratorEvent"); msg<<(CurTouchScreenName+","+CurMonitorName); QDBusConnection::systemBus().send(msg); } void Widget::addTouchScreenToTouchCombo(const QString touchscreenname ){ ui->touchscreenCombo->addItem(touchscreenname); } //识别触摸屏设备 bool Widget::findTouchScreen(){ int ndevices = 0; bool retval=false; CurTouchscreenNum=0; Display *dpy = XOpenDisplay(NULL); XIDeviceInfo *info = XIQueryDevice(dpy, XIAllDevices, &ndevices); QString devicesid=""; for (int i = 0; i < ndevices; i++) { XIDeviceInfo* dev = &info[i]; // 判断当前设备是不是触摸屏 if(dev->use != XISlavePointer) continue; if(!dev->enabled) continue; for (int j = 0; j < dev->num_classes; j++) { if (dev->classes[j]->type == XITouchClass) { devicesid = tr("%1").arg(dev->deviceid); addTouchScreenToTouchCombo(devicesid); retval = true; CurTouchscreenNum++; } } } XIFreeDeviceInfo(info); XCloseDisplay(dpy); return retval; } //获取触摸屏名称 QString Widget::findTouchScreenName(int devicesid){ int ndevices = 0; Display *dpy = XOpenDisplay(NULL); XIDeviceInfo *info = XIQueryDevice(dpy, XIAllDevices, &ndevices); QString devicesname=""; for (int i = 0; i < ndevices; i++) { XIDeviceInfo* dev = &info[i]; // 判断当前设备是不是触摸屏 if(dev->use != XISlavePointer) continue; if(!dev->enabled) continue; for (int j = 0; j < dev->num_classes; j++) { if (dev->classes[j]->type == XITouchClass) { if(dev->deviceid==devicesid) { devicesname=dev->name; return devicesname; } } } } } /* *判断映射关系保存时,屏幕是否已更换,不同屏幕通过touch serial区分 *通过配置中保存的touch name及touch id获取对应touch serial *然后用该touch serial与配置文件中的touch serial作比较,如果相同则触摸屏设备没有更换 *否则清空配置文件重新记录 */ int Widget::compareserial(int touchcount){ for(int i=1;i<=touchcount;i++) { QString str = QString::number(i); QString mapoption = "MAP"+str; QString serial = mapoption+"/serial"; QString name = mapoption+"/name"; QString id = mapoption+"/id"; QString touchname = configIni->value(name).toString(); QString touchserial = configIni->value(serial).toString(); if( (touchname == "") && (touchserial == "") ) continue; int touchid = configIni->value(id).toInt(); char _touchserial[32]={0}; char _devnode[32]={0}; std::string namestr = touchname.toStdString(); char * _touchname=(char *)namestr.c_str(); findSerialFromId(touchid,_touchname,_touchserial,_devnode,32); //qDebug("_touchserial=%s\n",_touchserial); QString Qtouchserial(_touchserial); //qDebug("Qtouchserial=%s\n",Qtouchserial.toStdString().data()); //qDebug("touchserial=%s\n",touchserial.toStdString().data()); if(Qtouchserial!=touchserial){ return -1; } } return Success; } /* *比较配置文件中同一触摸屏与显示器的映射关系 *如不同则保存最新的映射关系 */ int Widget::comparescreenname(QString _touchserial,QString _touchname,QString _screenname){ int touchcount=configIni->value("COUNT/num").toInt(); for(int i=1;i<=touchcount;i++) { QString str = QString::number(i); QString mapoption = "MAP"+str; QString serial = mapoption+"/serial"; QString scrname = mapoption+"/scrname"; QString name = mapoption+"/name"; QString screenname = configIni->value(scrname).toString(); QString touchserial = configIni->value(serial).toString(); QString touchname = configIni->value(name).toString(); //qDebug("Qtouchserial=%s\n",screenname.toStdString().data()); //qDebug("touchserial=%s\n",touchserial.toStdString().data()); if((_touchserial==touchserial) && (_touchname==touchname)){ if(screenname!=_screenname){ configIni->remove(mapoption); } } } return Success; } //清空配置文件 void Widget::cleanTouchConfig(int touchcount){ configIni->setValue("COUNT/num",0); for(int i=1;i<=touchcount;i++) { QString str = QString::number(i); QString mapoption = "MAP"+str; configIni->remove(mapoption); } } //对配置文件进行预处理 void Widget::initTouchConfig(QString touchserial,QString touchname,QString screenname) { qdir = new QDir; QString homepath = qdir->homePath(); QString touchcfgpath = homepath + TOUCHSCREEN_CFG_PATH; //触摸屏映射关系配置文件路径 configIni = new QSettings(touchcfgpath, QSettings::IniFormat); int touchcount = configIni->value("COUNT/num").toInt(); int devicecount = configIni->value("COUNT/device_num").toInt(); if(!touchcount) return ; if(devicecount != CurTouchscreenNum) cleanTouchConfig(touchcount); if(1 == CurTouchscreenNum) cleanTouchConfig(touchcount); if(compareserial(touchcount)!=0){ cleanTouchConfig(touchcount); qDebug("compareserial cleanTouchConfig\n"); } comparescreenname(touchserial,touchname,screenname); } /* *判断配置文件中是否已有该触摸屏配置 * 并返回相应状态 */ bool Widget::Configserialisexit(QString touchserial, QString devnode ,QString touchname){ bool devicesisexit=0; int touchcount=configIni->value("COUNT/num").toInt(); for(int i=0;i<=touchcount;i++){ QString numstr = QString::number(i); QString mapoption = "MAP"+numstr; QString serial = mapoption+"/serial"; QString node = mapoption+"/devnode"; QString name = mapoption+"/name"; QString _touchserial = configIni->value(serial).toString(); QString _devnode = configIni->value(node).toString(); QString _touchname = configIni->value(name).toString(); if(_touchserial == touchserial && _devnode == devnode && _touchname == touchname){ devicesisexit=1; break; } } if(devicesisexit) return TRUE; else return FALSE; } //写入配置文件,保存触摸映射关系 void Widget::writeTouchConfig(QString touchname,QString touchid,QString touchserial,QString devnode,QString screenname) { int touchcount = configIni->value("COUNT/num").toInt(); bool devicesisexit = Configserialisexit(touchserial,devnode,touchname); if(devicesisexit && touchcount) //如果配置文件中已存在该触摸屏配置,则不重复写入 return; QString str = QString::number(touchcount+1); QString mapoption = "MAP"+str; QString serial = mapoption+"/serial"; QString node = mapoption+"/devnode"; QString name = mapoption+"/name"; QString id = mapoption+"/id"; QString scrname = mapoption+"/scrname"; configIni->setValue( "COUNT/num" ,touchcount+1); configIni->setValue( "COUNT/device_num" ,CurTouchscreenNum); configIni->setValue( name ,touchname); configIni->setValue( id ,touchid); configIni->setValue( serial ,touchserial); configIni->setValue( node ,devnode); configIni->setValue( scrname ,screenname); } /*保存触摸映射关系 *对保存过程中的各种异常情况做处理 *如避免重复保存、更换屏幕后删除原映射关系、多屏情况下各屏映射关系保存 */ void Widget::save(QString touchname,QString touchid,QString screenname) { char _touchserial[32]={0}; char _devnode[32]={0}; std::string str = touchname.toStdString(); char * _touchname=(char *)str.c_str(); findSerialFromId(touchid.toInt(),_touchname,_touchserial,_devnode,32); QString touchserial(_touchserial); QString devnode(_devnode); initTouchConfig(touchserial,touchname,screenname); //保存之前先对配置文集进行处理 writeTouchConfig(touchname,touchid,touchserial,devnode,screenname);//将触摸映射关系写入配置文件 } ukui-control-center/plugins/system/touchscreen/touchscreen.h0000644000175000017500000000302114201663716023433 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TOUCHSCREEN_H #define TOUCHSCREEN_H #include #include #include #include "shell/interface.h" #include "widget.h" namespace Ui { class TouchScreen; } class TouchScreen : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: TouchScreen(); ~TouchScreen(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; private: Ui::TouchScreen *ui; QString pluginName; int pluginType; Widget * pluginWidget; bool mFirstLoad; }; #endif // TOUCHSCREEN_H ukui-control-center/plugins/system/touchscreen/xinputmanager.cpp0000644000175000017500000000442614201663716024340 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "xinputmanager.h" #include #include XinputManager::XinputManager(QObject *parent): QObject(parent) { init(); } void XinputManager::init() { m_pMonitorInputTask = MonitorInputTask::instance(); connect(this, &XinputManager::sigStartThread, m_pMonitorInputTask, &MonitorInputTask::StartManager); connect(m_pMonitorInputTask, &MonitorInputTask::slaveAdded, this, &XinputManager::onSlaveAdded); connect(m_pMonitorInputTask, &MonitorInputTask::slaveRemoved, this, &XinputManager::onSlaveRemoved); m_pManagerThread = new QThread(this); m_pMonitorInputTask->moveToThread(m_pManagerThread); } void XinputManager::start() { qDebug() << "info: [XinputManager][start]: thread id = " << QThread::currentThreadId(); m_runningMutex.lock(); m_pMonitorInputTask->m_running = true; m_runningMutex.unlock(); m_pManagerThread->start(); Q_EMIT sigStartThread(); } void XinputManager::stop() { if(m_pManagerThread->isRunning()) { m_runningMutex.lock(); m_pMonitorInputTask->m_running = false; m_runningMutex.unlock(); m_pManagerThread->quit(); } } void XinputManager::onSlaveAdded(int device_id) { qDebug() << "info: [XinputManager][onSlaveAdded]: Slave Device(id =" << device_id << ") Added!"; Q_EMIT xinputSlaveAdded(device_id); } void XinputManager::onSlaveRemoved(int device_id) { qDebug() << "info: [XinputManager][onslaveRemoved]: Slave Device(id =" << device_id << ") Removed!"; Q_EMIT xinputSlaveRemoved(device_id); } ukui-control-center/plugins/system/power/0000755000175000017500000000000014201663716017556 5ustar fengfengukui-control-center/plugins/system/power/power.pro0000644000175000017500000000135514201663716021440 0ustar fengfenginclude(../../../env.pri) QT += widgets dbus TEMPLATE = lib CONFIG += plugin include($$PROJECT_COMPONENTSOURCE/comboxframe.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) TARGET = $$qtLibraryTarget(power) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INSTALLS += target INCLUDEPATH += \ $$PROJECT_ROOTDIR \ $$PROJECT_COMPONENTSOURCE LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lupower-glib CONFIG += \ link_pkgconfig \ c++11 PKGCONFIG += gsettings-qt \ gio-2.0 \ gio-unix-2.0 \ upower-glib FORMS += HEADERS += \ power.h \ powermacrodata.h SOURCES += \ power.cpp ukui-control-center/plugins/system/power/power.ui0000644000175000017500000010573114201663716021260 0ustar fengfeng Power 0 0 800 772 0 0 16777215 16777215 Form 0 0 0 32 48 550 0 960 16777215 0 0 0 0 0 8 20 0 0 select power plan true 0 50 16777215 50 QFrame::Box 0 0 0 0 0 10 16 16 0 0 Balance (suggest) true 0 0 Autobalance energy and performance with available hardware true Qt::Horizontal 40 20 0 0 powerModeBtnGroup 0 50 16777215 50 QFrame::Box 0 0 0 0 0 10 16 16 0 0 Saving true 0 0 Minimize performance true Qt::Horizontal 40 20 0 0 powerModeBtnGroup 2 10 0 50 16777215 50 QFrame::Box 0 0 0 0 0 10 16 16 0 0 Custom true 0 0 Users develop personalized power plans true Qt::Horizontal 40 20 0 0 powerModeBtnGroup 0 118 16777215 118 QFrame::Box 16 0 0 0 0 24 16 16 0 0 120 36 120 36 Power supply true true powerTypeBtnGroup 0 0 120 36 120 36 Battery powered true true powerTypeBtnGroup Qt::Horizontal 40 20 48 16 16 0 0 300 0 16777215 16777215 Change PC sleep time: false 0 0 0 0 16777215 32 0 50 16777215 50 QFrame::Box 0 0 0 0 0 48 16 16 0 0 300 0 16777215 16777215 Change DP close time: false 0 0 0 0 16777215 32 0 50 16777215 50 QFrame::Box QFrame::Plain 0 0 0 0 0 48 16 16 0 0 300 0 16777215 16777215 When close lid: 0 50 16777215 50 QFrame::Box QFrame::Plain 0 0 0 0 0 48 16 16 0 0 300 0 16777215 16777215 Screen darkens use battery: 0 32 16777215 32 Qt::Vertical QSizePolicy::Fixed 20 32 0 0 General Settings 0 50 16777215 50 QFrame::Box 0 0 0 0 0 48 16 16 0 0 300 0 16777215 16777215 Power icon: 0 0 0 0 16777215 32 Qt::Vertical 20 40 TitleLabel QLabel
    Label/titlelabel.h
    ukui-control-center/plugins/system/power/power.h0000644000175000017500000000774614201663716021101 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef POWER_H #define POWER_H #include #include #include #include #include #include #include "shell/interface.h" #include "Label/titlelabel.h" #include "commonComponent/ComboxFrame/comboxframe.h" #include "SwitchButton/switchbutton.h" namespace Ui { class Power; } class Power : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: explicit Power(); ~Power(); public: QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; public: void InitUI(QWidget *widget); void retranslateUi(); void resetui(); void initSearText(); void setupComponent(); void setupConnect(); void initCustomPlanStatus(); void isLidPresent(); void isHibernateSupply(); bool isExitBattery(); double getBattery(); bool QLabelSetText(QLabel *label, QString string); private: QWidget *pluginWidget; QGSettings *settings; QGSettings *sessionSetting; QGSettings *stylesettings; QGSettings *sessionsettings; QGSettings *screensettings; QString pluginName; int pluginType; TitleLabel *CustomTitleLabel; TitleLabel *PowerPlanTitleLabel; TitleLabel *BatteryPlanTitleLabel; QLabel *mSleepPwdLabel; QLabel *mWakenPwdLabel; QLabel *mPowerKeyLabel; QLabel *mCloseLabel; QLabel *mSleepLabel; QLabel *mCloseLidLabel; QLabel *mPowerLabel; QLabel *mBatteryLabel; QLabel *mDarkenLabel; QLabel *mLowpowerLabel1; QLabel *mLowpowerLabel2; QLabel *mNoticeLabel; QLabel *mLowSaveLabel; QLabel *mBatterySaveLabel; QLabel *mDisplayTimeLabel; QFrame *mSleepPwdFrame; QFrame *mWakenPwdFrame; QFrame *mPowerKeyFrame; QFrame *mCloseFrame; QFrame *mSleepFrame; QFrame *mCloseLidFrame; QFrame *mPowerFrame; QFrame *mBatteryFrame; QFrame *mDarkenFrame; QFrame *mLowpowerFrame; QFrame *mNoticeLFrame; QFrame *mLowSaveFrame; QFrame *mBatterySaveFrame; QFrame *mDisplayTimeFrame; QComboBox *mPowerKeyComboBox; QComboBox *mCloseComboBox; QComboBox *mSleepComboBox; QComboBox *mCloseLidComboBox; QComboBox *mPowerComboBox; QComboBox *mBatteryComboBox; QComboBox *mDarkenComboBox; QComboBox *mLowpowerComboBox1; QComboBox *mLowpowerComboBox2; QComboBox *mNoticeComboBox; SwitchButton *mSleepPwdBtn; SwitchButton *mWakenPwdBtn; SwitchButton *mLowSaveBtn; SwitchButton *mBatterySaveBtn; SwitchButton *mDisplayTimeBtn; QStringList buttonStringList; QStringList sleepStringList; QStringList closeStringList; QStringList closeLidStringList; QStringList PowerplanStringList; QStringList BatteryplanStringList; QStringList DarkenStringList; QStringList LowpowerStringList; bool mFirstLoad; bool isExitsLid; bool isExitHibernate; bool hasBat; }; #endif // POWER_H ukui-control-center/plugins/system/power/powermacrodata.h0000644000175000017500000000600714201663671022742 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef POWERMACRODATA_H #define POWERMACRODATA_H #define UKUI_QUICK_OPERATION_PANEL "org.ukui.quick-operation.panel" #define ENERGYSAVINGMODE "energysavingmode" #define IDLE_DIM_AC "idle-dim-ac" #define IDLE_DIM_BA "idle-dim-battery" #define BRIGHTNESS_AC "brightness-ac" #define POWERMANAGER_SCHEMA "org.ukui.power-manager" #define ICONPOLICY "icon-policy" #define SLEEP_COMPUTER_AC_KEY "sleep-computer-ac" #define SLEEP_COMPUTER_BATT_KEY "sleep-computer-battery" #define SLEEP_DISPLAY_AC_KEY "sleep-display-ac" #define SLEEP_DISPLAY_BATT_KEY "sleep-display-battery" #define BUTTON_LID_AC_KEY "button-lid-ac" #define BUTTON_LID_BATT_KET "button-lid-battery" #define BUTTON_SUSPEND_KEY "button-suspend" #define BUTTON_POWER_KEY "button-power" #define IDLE_DIM_TIME_KEY "idle-dim-time" #define HIBERNATE_KEY "after-idle-action" #define PER_ACTION_KEY "percentage-action" #define ACTION_CRI_BTY "action-critical-battery" #define PER_ACTION_CRI "percentage-critical" #define POWER_POLICY_AC "power-policy-ac" #define POWER_POLICY_BATTARY "power-policy-battery" #define LOCK_BLANK_SCREEN "lock-blank-screen" #define PERCENTAGE_LOW "percentage-low" #define LOW_BATTERY_AUTO_SAVE "low-battery-auto-save" #define ON_BATTERY_AUTO_SAVE "on-battery-auto-save" #define DISPLAY_LEFT_TIME_OF_CHARGE_AND_DISCHARGE "dispaly-left-time-of-charge-and-discharge" #define SCREENSAVER_SCHEMA "org.ukui.screensaver" #define SLEEP_ACTIVATION_ENABLED "sleep-activation-enabled" #define SCREENLOCK_LOCK_KEY "lock-enabled" #define SCREENLOCK_ACTIVE_KEY "idle-activation-enabled" #define PRESENT_VALUE "present" #define ALWAYS_VALUE "always" #define CHARGE_VALUE "charge" #define SESSION_SCHEMA "org.ukui.session" #define IDLE_DELAY_KEY "idle-delay" #define FIXES 60 #define PERSONALSIE_SCHEMA "org.ukui.control-center.personalise" #define PERSONALSIE_POWER_KEY "custompower" #define ISWHICHCHECKED "ischecked" #define POWER_MODE "power-mode" #define STYLE_FONT_SCHEMA "org.ukui.style" #endif // POWERMACRODATA_H ukui-control-center/plugins/system/power/power.cpp0000644000175000017500000010203214201663716021414 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "power.h" #include "powermacrodata.h" #include #include #include #include #include #include #include "../../../shell/utils/utils.h" /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ #ifdef signals #undef signals #endif #include "libupower-glib/upower.h" typedef enum { BALANCE, SAVING, CUSTDOM }MODE; typedef enum { PRESENT, ALWAYS }ICONDISPLAY; Power::Power() : mFirstLoad(true) { pluginName = tr("Power"); pluginType = SYSTEM; } Power::~Power() { if (!mFirstLoad) { } } QString Power::get_plugin_name() { return pluginName; } int Power::get_plugin_type() { return pluginType; } QWidget * Power::get_plugin_ui() { if (mFirstLoad) { pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); InitUI(pluginWidget); isLidPresent(); isHibernateSupply(); isExitBattery(); initSearText(); resetui(); const QByteArray styleID(STYLE_FONT_SCHEMA); const QByteArray id(POWERMANAGER_SCHEMA); const QByteArray iid(SESSION_SCHEMA); const QByteArray iiid(SCREENSAVER_SCHEMA); if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(styleID) && QGSettings::isSchemaInstalled(iid) && QGSettings::isSchemaInstalled(iiid)) { settings = new QGSettings(id, QByteArray(), this); stylesettings = new QGSettings(styleID, QByteArray(), this); sessionsettings = new QGSettings(iid, QByteArray(), this); screensettings = new QGSettings(iiid, QByteArray(), this); setupComponent(); initCustomPlanStatus(); setupConnect(); connect(stylesettings,&QGSettings::changed,[=](QString key) { if("systemFont" == key || "systemFontSize" == key) { retranslateUi(); } }); connect(settings,&QGSettings::changed,[=](QString key){ initCustomPlanStatus(); }); } } return pluginWidget; } void Power::plugin_delay_control() { } const QString Power::name() const { return QStringLiteral("power"); } void Power::InitUI(QWidget *widget) { QVBoxLayout *mverticalLayout = new QVBoxLayout(widget); mverticalLayout->setSpacing(0); mverticalLayout->setContentsMargins(0, 0, 32, 40); QWidget *Powerwidget = new QWidget(widget); Powerwidget->setMinimumSize(QSize(550, 0)); Powerwidget->setMaximumSize(QSize(960, 16777215)); QVBoxLayout *PowerLayout = new QVBoxLayout(Powerwidget); PowerLayout->setContentsMargins(0, 0, 0, 0); PowerLayout->setSpacing(1); CustomTitleLabel = new TitleLabel(Powerwidget); PowerLayout->addWidget(CustomTitleLabel); PowerLayout->addSpacing(7); mSleepPwdFrame = new QFrame(Powerwidget); mSleepPwdFrame->setMinimumSize(QSize(550, 60)); mSleepPwdFrame->setMaximumSize(QSize(960, 60)); mSleepPwdFrame->setFrameShape(QFrame::Box); QHBoxLayout *mSleepPwdLayout = new QHBoxLayout(mSleepPwdFrame); mSleepPwdLayout->setContentsMargins(16, 0, 16, 0); mSleepPwdLabel = new QLabel(mSleepPwdFrame); mSleepPwdLabel->setMinimumSize(550,60); mSleepPwdBtn = new SwitchButton(mSleepPwdFrame); mSleepPwdLayout->addWidget(mSleepPwdLabel); mSleepPwdLayout->addStretch(); mSleepPwdLayout->addWidget(mSleepPwdBtn); PowerLayout->addWidget(mSleepPwdFrame); mWakenPwdFrame = new QFrame(Powerwidget); mWakenPwdFrame->setMinimumSize(QSize(550, 49)); mWakenPwdFrame->setMaximumSize(QSize(960, 49)); mWakenPwdFrame->setFrameShape(QFrame::Box); QHBoxLayout *mWakenPwdLayout = new QHBoxLayout(mWakenPwdFrame); mWakenPwdLayout->setContentsMargins(16, 0, 16, 0); mWakenPwdLabel = new QLabel(mWakenPwdFrame); mWakenPwdLabel->setMinimumSize(550,49); mWakenPwdBtn = new SwitchButton(mWakenPwdFrame); mWakenPwdLayout->addWidget(mWakenPwdLabel); mWakenPwdLayout->addStretch(); mWakenPwdLayout->addWidget(mWakenPwdBtn); PowerLayout->addWidget(mWakenPwdFrame); mPowerKeyFrame = new QFrame(Powerwidget); mPowerKeyFrame->setObjectName("mpowerkeyframe"); mPowerKeyFrame->setMinimumSize(QSize(550, 69)); mPowerKeyFrame->setMaximumSize(QSize(960, 69)); mPowerKeyFrame->setFrameShape(QFrame::Box); QHBoxLayout *mPowerKeyLayout = new QHBoxLayout(mPowerKeyFrame); mPowerKeyLayout->setContentsMargins(16, 0, 16, 0); mPowerKeyLabel = new QLabel(mPowerKeyFrame); mPowerKeyLabel->setMinimumSize(550,69); mPowerKeyComboBox = new QComboBox(mPowerKeyFrame); mPowerKeyComboBox->setFixedHeight(40); mPowerKeyComboBox->setMinimumWidth(200); mPowerKeyLayout->addWidget(mPowerKeyLabel); mPowerKeyLayout->addWidget(mPowerKeyComboBox); PowerLayout->addWidget(mPowerKeyFrame); mCloseFrame = new QFrame(Powerwidget); mCloseFrame->setObjectName("mcloseframe"); mCloseFrame->setMinimumSize(QSize(550, 60)); mCloseFrame->setMaximumSize(QSize(960, 60)); mCloseFrame->setFrameShape(QFrame::Box); QHBoxLayout *mCloseLayout = new QHBoxLayout(mCloseFrame); mCloseLayout->setContentsMargins(16, 0, 16, 0); mCloseLabel = new QLabel(mCloseFrame); mCloseLabel->setMinimumSize(550,60); mCloseComboBox = new QComboBox(mCloseFrame); mCloseComboBox->setFixedHeight(40); mCloseComboBox->setMinimumWidth(200); mCloseLayout->addWidget(mCloseLabel); mCloseLayout->addWidget(mCloseComboBox); PowerLayout->addWidget(mCloseFrame); PowerLayout->addSpacing(1); mSleepFrame = new QFrame(Powerwidget); mSleepFrame->setObjectName("msleepframe"); mSleepFrame->setMinimumSize(QSize(550, 59)); mSleepFrame->setMaximumSize(QSize(960, 59)); mSleepFrame->setFrameShape(QFrame::Box); QHBoxLayout *mSleepLayout = new QHBoxLayout(mSleepFrame); mSleepLayout->setContentsMargins(16, 0, 16, 0); mSleepLabel = new QLabel(mSleepFrame); mSleepLabel->setMinimumSize(550,59); mSleepComboBox = new QComboBox(mSleepFrame); mSleepComboBox->setFixedHeight(40); mSleepComboBox->setMinimumWidth(200); mSleepLayout->addWidget(mSleepLabel); mSleepLayout->addWidget(mSleepComboBox); PowerLayout->addWidget(mSleepFrame); mCloseLidFrame = new QFrame(Powerwidget); mCloseLidFrame->setObjectName("mcloselidframe"); mCloseLidFrame->setMinimumSize(QSize(550, 59)); mCloseLidFrame->setMaximumSize(QSize(960, 59)); mCloseLidFrame->setFrameShape(QFrame::Box); QHBoxLayout *mCloseLidLayout = new QHBoxLayout(mCloseLidFrame); mCloseLidLayout->setContentsMargins(16, 0, 16, 0); mCloseLidLabel = new QLabel(mCloseLidFrame); mCloseLidLabel->setMinimumSize(550,59); mCloseLidComboBox = new QComboBox(mCloseLidFrame); mCloseLidComboBox->setFixedHeight(40); mCloseLidComboBox->setMinimumWidth(200); mCloseLidLayout->addWidget(mCloseLidLabel); mCloseLidLayout->addWidget(mCloseLidComboBox); PowerLayout->addWidget(mCloseLidFrame); PowerLayout->addSpacing(39); PowerPlanTitleLabel = new TitleLabel(Powerwidget); PowerLayout->addWidget(PowerPlanTitleLabel); PowerLayout->addSpacing(7); mPowerFrame = new QFrame(Powerwidget); mPowerFrame->setObjectName("mpowerframe"); mPowerFrame->setMinimumSize(QSize(550, 60)); mPowerFrame->setMaximumSize(QSize(960, 60)); mPowerFrame->setFrameShape(QFrame::Box); QHBoxLayout *mPowerLayout = new QHBoxLayout(mPowerFrame); mPowerLayout->setContentsMargins(16, 0, 16, 0); mPowerLabel = new QLabel(mPowerFrame); mPowerLabel->setMinimumSize(550,60); mPowerComboBox = new QComboBox(mPowerFrame); mPowerComboBox->setFixedHeight(40); mPowerComboBox->setMinimumWidth(200); mPowerLayout->addWidget(mPowerLabel); mPowerLayout->addWidget(mPowerComboBox); PowerLayout->addWidget(mPowerFrame); mBatteryFrame = new QFrame(Powerwidget); mBatteryFrame->setObjectName("mbatteryframe"); mBatteryFrame->setMinimumSize(QSize(550, 59)); mBatteryFrame->setMaximumSize(QSize(960, 59)); mBatteryFrame->setFrameShape(QFrame::Box); QHBoxLayout *mBatteryLayout = new QHBoxLayout(mBatteryFrame); mBatteryLayout->setContentsMargins(16, 0, 16, 0); mBatteryLabel = new QLabel(mBatteryFrame); mBatteryLabel->setMinimumSize(550,59); mBatteryComboBox = new QComboBox(mBatteryFrame); mBatteryComboBox->setFixedHeight(40); mBatteryComboBox->setMinimumWidth(200); mBatteryLayout->addWidget(mBatteryLabel); mBatteryLayout->addWidget(mBatteryComboBox); PowerLayout->addWidget(mBatteryFrame); PowerLayout->addSpacing(40); BatteryPlanTitleLabel = new TitleLabel(Powerwidget); PowerLayout->addWidget(BatteryPlanTitleLabel); PowerLayout->addSpacing(7); mDarkenFrame = new QFrame(Powerwidget); mDarkenFrame->setObjectName("mdarkenframe"); mDarkenFrame->setMinimumSize(QSize(550, 59)); mDarkenFrame->setMaximumSize(QSize(960, 59)); mDarkenFrame->setFrameShape(QFrame::Box); QHBoxLayout *mDarkenLayout = new QHBoxLayout(mDarkenFrame); mDarkenLayout->setContentsMargins(16, 0, 16, 0); mDarkenLabel = new QLabel(mDarkenFrame); mDarkenLabel->setMinimumSize(550,59); mDarkenComboBox = new QComboBox(mDarkenFrame); mDarkenComboBox->setFixedHeight(40); mDarkenComboBox->setMinimumWidth(200); mDarkenLayout->addWidget(mDarkenLabel); mDarkenLayout->addWidget(mDarkenComboBox); PowerLayout->addWidget(mDarkenFrame); mLowpowerFrame = new QFrame(Powerwidget); mLowpowerFrame->setObjectName("mlowpowerframe"); mLowpowerFrame->setMinimumSize(QSize(550, 60)); mLowpowerFrame->setMaximumSize(QSize(960, 60)); mLowpowerFrame->setFrameShape(QFrame::Box); mLowpowerLabel1 = new QLabel(mLowpowerFrame); mLowpowerLabel1->setFixedSize(84,60); mLowpowerLabel2 = new QLabel(mLowpowerFrame); mLowpowerLabel2->setFixedSize(72,60); QHBoxLayout *mLowpowerLayout = new QHBoxLayout(mLowpowerFrame); mLowpowerLayout->setContentsMargins(16, 0, 16, 0); mLowpowerComboBox1 = new QComboBox(mLowpowerFrame); mLowpowerComboBox1->setFixedSize(70, 40); mLowpowerComboBox2 = new QComboBox(mLowpowerFrame); mLowpowerComboBox2->setFixedHeight(40); mLowpowerComboBox2->setMinimumWidth(200); mLowpowerLayout->setSpacing(16); mLowpowerLayout->addWidget(mLowpowerLabel1); mLowpowerLayout->addWidget(mLowpowerComboBox1); mLowpowerLayout->addWidget(mLowpowerLabel2); mLowpowerLayout->addSpacerItem(new QSpacerItem(284, 20, QSizePolicy::Maximum)); mLowpowerLayout->addWidget(mLowpowerComboBox2); PowerLayout->addWidget(mLowpowerFrame); mNoticeLFrame = new QFrame(Powerwidget); mNoticeLFrame->setObjectName("mnoticeframe"); mNoticeLFrame->setMinimumSize(QSize(550, 60)); mNoticeLFrame->setMaximumSize(QSize(960, 60)); mNoticeLFrame->setFrameShape(QFrame::Box); QHBoxLayout *mNoticeLayout = new QHBoxLayout(mNoticeLFrame); mNoticeLayout->setContentsMargins(16, 0, 16, 0); mNoticeLabel = new QLabel(mNoticeLFrame); mNoticeLabel->setMinimumSize(550,59); mNoticeComboBox = new QComboBox(mNoticeLFrame); mNoticeComboBox->setFixedHeight(40); mNoticeComboBox->setMinimumWidth(200); mNoticeLayout->addWidget(mNoticeLabel); mNoticeLayout->addWidget(mNoticeComboBox); PowerLayout->addWidget(mNoticeLFrame); mLowSaveFrame = new QFrame(Powerwidget); mLowSaveFrame->setObjectName("mlowsaveframe"); mLowSaveFrame->setMinimumSize(QSize(550, 60)); mLowSaveFrame->setMaximumSize(QSize(960, 60)); mLowSaveFrame->setFrameShape(QFrame::Box); QHBoxLayout *mLowSaveLayout = new QHBoxLayout(mLowSaveFrame); mLowSaveLayout->setContentsMargins(16, 0, 16, 0); mLowSaveLabel = new QLabel(mLowSaveFrame); mLowSaveLabel->setMinimumSize(550,59); mLowSaveBtn = new SwitchButton(mLowSaveFrame); mLowSaveLayout->addWidget(mLowSaveLabel); mLowSaveLayout->addStretch(); mLowSaveLayout->addWidget(mLowSaveBtn); PowerLayout->addWidget(mLowSaveFrame); mBatterySaveFrame = new QFrame(Powerwidget); mBatterySaveFrame->setObjectName("mbatterysaveframe"); mBatterySaveFrame->setMinimumSize(QSize(550, 60)); mBatterySaveFrame->setMaximumSize(QSize(960, 60)); mBatterySaveFrame->setFrameShape(QFrame::Box); QHBoxLayout *mBatterySaveLayout = new QHBoxLayout(mBatterySaveFrame); mBatterySaveLayout->setContentsMargins(16, 0, 16, 0); mBatterySaveLabel = new QLabel(mBatterySaveFrame); mBatterySaveLabel->setMinimumSize(550,59); mBatterySaveBtn = new SwitchButton(mBatterySaveFrame); mBatterySaveLayout->addWidget(mBatterySaveLabel); mBatterySaveLayout->addStretch(); mBatterySaveLayout->addWidget(mBatterySaveBtn); PowerLayout->addWidget(mBatterySaveFrame); mDisplayTimeFrame = new QFrame(Powerwidget); mDisplayTimeFrame->setObjectName("mdisplaytimeframe"); mDisplayTimeFrame->setMinimumSize(QSize(550, 60)); mDisplayTimeFrame->setMaximumSize(QSize(960, 60)); mDisplayTimeFrame->setFrameShape(QFrame::Box); QHBoxLayout *mDisplayTimeLayout = new QHBoxLayout(mDisplayTimeFrame); mDisplayTimeLayout->setContentsMargins(16, 0, 16, 0); mDisplayTimeLabel = new QLabel(mDisplayTimeFrame); mDisplayTimeLabel->setMinimumSize(550,59); mDisplayTimeBtn = new SwitchButton(mDisplayTimeFrame); mDisplayTimeLayout->addWidget(mDisplayTimeLabel); mDisplayTimeLayout->addStretch(); mDisplayTimeLayout->addWidget(mDisplayTimeBtn); PowerLayout->addWidget(mDisplayTimeFrame); mverticalLayout->addWidget(Powerwidget); mverticalLayout->addStretch(); retranslateUi(); } void Power::retranslateUi() { if (QLabelSetText(mSleepPwdLabel, tr("Require password when sleep/hibernation"))) { mSleepPwdLabel->setToolTip(tr("Require password when sleep/hibernation")); } if (QLabelSetText(mWakenPwdLabel, tr("Password required when waking up the screen"))) { mSleepPwdLabel->setToolTip(tr("Password required when waking up the screen")); } if (QLabelSetText(mPowerKeyLabel, tr("Press the power button"))) { mPowerKeyLabel->setToolTip("Press the power button"); } if (QLabelSetText(mCloseLabel, tr("Time to close display"))) { mCloseLabel->setToolTip(tr("Time to close display")); } if (QLabelSetText(mSleepLabel, tr("Time to sleep"))) { mSleepLabel->setToolTip(tr("Time to sleep")); } if (QLabelSetText(mCloseLidLabel, tr("Notebook cover"))) { mCloseLidLabel->setToolTip(tr("Notebook cover")); } if (QLabelSetText(mPowerLabel, tr("Using power"))) { mPowerLabel->setToolTip(tr("Using power")); } if (QLabelSetText(mBatteryLabel, tr("Using battery"))) { mBatteryLabel->setToolTip(tr("Using power")); } if (QLabelSetText(mDarkenLabel, tr(" Time to darken"))) { mDarkenLabel->setToolTip(tr(" Time to darken")); } if (QLabelSetText(mLowpowerLabel1, tr("Battery level is lower than"))) { mLowpowerLabel1->setToolTip(tr("Battery level is lower than")); } mLowpowerLabel2->setText(tr("Run")); if (QLabelSetText(mNoticeLabel, tr("Low battery notification"))) { mNoticeLabel->setToolTip(tr("Low battery notification")); } if (QLabelSetText(mLowSaveLabel, tr("Automatically run saving mode when low battery"))) { mLowSaveLabel->setToolTip(tr("Automatically run saving mode when the low battery")); } if (QLabelSetText(mBatterySaveLabel, tr("Automatically run saving mode when using battery"))) { mBatterySaveLabel->setToolTip(tr("Automatically run saving mode when using battery")); } if (QLabelSetText(mDisplayTimeLabel, tr("Display remaining charging time and usage time"))) { mDisplayTimeLabel->setToolTip(tr("Display remaining charging time and usage time")); } } void Power::resetui() { //9X0隐藏这些设置项 if (Utils::isWayland()) { mNoticeLFrame->hide(); mLowSaveFrame->hide(); mBatterySaveFrame->hide(); mDisplayTimeFrame->hide(); mWakenPwdFrame->hide(); mCloseFrame->hide(); } //不存在盖子隐藏该项 if (!isExitsLid) { mCloseLidFrame->hide(); } //不存在电池隐藏这些设置项 if (!hasBat) { mBatteryFrame->hide(); BatteryPlanTitleLabel->hide(); mDarkenFrame->hide(); mLowpowerFrame->hide(); mNoticeLFrame->hide(); mLowSaveFrame->hide(); mBatterySaveFrame->hide(); mDisplayTimeFrame->hide(); } } void Power::initSearText() { //~ contents_path /power/General CustomTitleLabel->setText(tr("General")); //~ contents_path /power/Select Powerplan PowerPlanTitleLabel->setText(tr("Select Powerplan")); //~ contents_path /power/Battery saving plan BatteryPlanTitleLabel->setText((tr("Battery saving plan"))); } void Power::setupComponent() { // 合盖 closeLidStringList << tr("nothing") << tr("blank") << tr("suspend") << tr("shutdown"); mCloseLidComboBox->insertItem(0, closeLidStringList.at(0), "nothing"); mCloseLidComboBox->insertItem(1, closeLidStringList.at(1), "blank"); mCloseLidComboBox->insertItem(2, closeLidStringList.at(2), "suspend"); mCloseLidComboBox->insertItem(3, closeLidStringList.at(3), "shutdown"); if (!Utils::isWayland() && isExitHibernate){ closeLidStringList << tr("hibernate"); mCloseLidComboBox->insertItem(4, closeLidStringList.at(4), "hibernate"); } //按下电源键时 buttonStringList << tr("interactive") << tr("suspend") << tr("shutdown") << tr("hibernate"); mPowerKeyComboBox->insertItem(0, buttonStringList.at(0), "interactive"); mPowerKeyComboBox->insertItem(1, buttonStringList.at(1), "suspend"); mPowerKeyComboBox->insertItem(2, buttonStringList.at(2), "shutdown"); if (isExitHibernate) { mPowerKeyComboBox->insertItem(3, buttonStringList.at(3), "hibernate"); } //关闭显示器 closeStringList << tr("5min") << tr("10minn") << tr("15min") << tr("30min") << tr("1h") << tr("2h") << tr("never"); mCloseComboBox->insertItem(0, closeStringList.at(0), QVariant::fromValue(5)); mCloseComboBox->insertItem(1, closeStringList.at(1), QVariant::fromValue(10)); mCloseComboBox->insertItem(2, closeStringList.at(2), QVariant::fromValue(15)); mCloseComboBox->insertItem(3, closeStringList.at(3), QVariant::fromValue(30)); mCloseComboBox->insertItem(4, closeStringList.at(4), QVariant::fromValue(60)); mCloseComboBox->insertItem(5, closeStringList.at(5), QVariant::fromValue(120)); mCloseComboBox->insertItem(6, closeStringList.at(6), QVariant::fromValue(0)); //睡眠 sleepStringList << tr("10min") << tr("15min") << tr("30min") << tr("1h") << tr("2h") << tr("3h") << tr("never"); mSleepComboBox->insertItem(0, sleepStringList.at(0), QVariant::fromValue(10)); mSleepComboBox->insertItem(1, sleepStringList.at(1), QVariant::fromValue(15)); mSleepComboBox->insertItem(2, sleepStringList.at(2), QVariant::fromValue(30)); mSleepComboBox->insertItem(3, sleepStringList.at(3), QVariant::fromValue(60)); mSleepComboBox->insertItem(4, sleepStringList.at(4), QVariant::fromValue(120)); mSleepComboBox->insertItem(5, sleepStringList.at(5), QVariant::fromValue(180)); mSleepComboBox->insertItem(6, sleepStringList.at(6), QVariant::fromValue(0)); //电源计划 PowerplanStringList << tr("Balance Model") << tr("Save Model")<insertItem(0, PowerplanStringList.at(0), "Balance Model"); mPowerComboBox->insertItem(1, PowerplanStringList.at(1), "Save Model"); mPowerComboBox->insertItem(2, PowerplanStringList.at(2), "Performance Model"); BatteryplanStringList << tr("Balance Model") << tr("Save Model")<insertItem(0, BatteryplanStringList.at(0), "Balance Model"); mBatteryComboBox->insertItem(1, BatteryplanStringList.at(1), "Save Model"); mBatteryComboBox->insertItem(2, BatteryplanStringList.at(2), "Performance Model"); //变暗 DarkenStringList << tr("1min") << tr("5min") << tr("10min") << tr("20min") << tr("never"); mDarkenComboBox->insertItem(0, DarkenStringList.at(0), QVariant::fromValue(1)); mDarkenComboBox->insertItem(1, DarkenStringList.at(1), QVariant::fromValue(5)); mDarkenComboBox->insertItem(2, DarkenStringList.at(2), QVariant::fromValue(10)); mDarkenComboBox->insertItem(3, DarkenStringList.at(3), QVariant::fromValue(20)); mDarkenComboBox->insertItem(4, DarkenStringList.at(4), QVariant::fromValue(0)); //低电量时执行 LowpowerStringList << tr("nothing") << tr("blank") << tr("suspend") << tr("shutdown"); mLowpowerComboBox2->insertItem(0, LowpowerStringList.at(0), "nothing"); mLowpowerComboBox2->insertItem(1, LowpowerStringList.at(1), "blank"); mLowpowerComboBox2->insertItem(2, LowpowerStringList.at(2), "suspend"); mLowpowerComboBox2->insertItem(3, LowpowerStringList.at(3), "shutdown"); if (isExitHibernate){ LowpowerStringList << tr("hibernate"); mLowpowerComboBox2->insertItem(4, LowpowerStringList.at(4), "hibernate"); } //低电量通知 for (int i = 1; i < 5; i++) { mNoticeComboBox->insertItem(i-1, QString("%1%").arg(i*10)); } //电池低电量范围 int batteryRemain = settings->get(PER_ACTION_CRI).toInt(); for(int i = 5; i < batteryRemain; i++) { mLowpowerComboBox1->insertItem(i - 5, QString("%1%").arg(i)); } } void Power::setupConnect() { connect(mSleepPwdBtn,&SwitchButton::checkedChanged, [=](bool checked){ screensettings->set(SLEEP_ACTIVATION_ENABLED,checked); }); connect(mWakenPwdBtn,&SwitchButton::checkedChanged, [=](bool checked){ settings->set(LOCK_BLANK_SCREEN,checked); }); connect(mPowerKeyComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { settings->set(BUTTON_POWER_KEY, mPowerKeyComboBox->itemData(index)); }); connect(mCloseComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { Q_UNUSED(index) settings->set(SLEEP_DISPLAY_AC_KEY, QVariant(mCloseComboBox->currentData(Qt::UserRole).toInt() * 60)); settings->set(SLEEP_DISPLAY_BATT_KEY, QVariant(mCloseComboBox->currentData(Qt::UserRole).toInt() * 60)); }); connect(mSleepComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { Q_UNUSED(index) settings->set(SLEEP_COMPUTER_AC_KEY, QVariant(mSleepComboBox->currentData(Qt::UserRole).toInt() * 60)); settings->set(SLEEP_COMPUTER_BATT_KEY, QVariant(mSleepComboBox->currentData(Qt::UserRole).toInt() * 60)); }); connect(mCloseLidComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { settings->set(BUTTON_LID_AC_KEY, mCloseLidComboBox->itemData(index)); settings->set(BUTTON_LID_BATT_KET, mCloseLidComboBox->itemData(index)); }); if (settings->keys().contains("powerPolicyAc") && settings->keys().contains("powerPolicyBattery")) { connect(mPowerComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { if (index == 2) { settings->set(POWER_POLICY_AC, 0); } else { settings->set(POWER_POLICY_AC, index + 1); } }); connect(mBatteryComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { //当开启了 低电量自动开启节能模式 时,在此低电量范围内调整电池计划,则自动关闭 低电量自动开启节能模式 if (!Utils::isWayland() && settings->keys().contains("lowBatteryAutoSave")) { if (mLowSaveBtn->isChecked() && getBattery() <= settings->get(PERCENTAGE_LOW).toDouble()) { mLowSaveBtn->setChecked(false); } } if (index == 2) { settings->set(POWER_POLICY_BATTARY, 0); } else { settings->set(POWER_POLICY_BATTARY, index + 1); } }); } connect(mDarkenComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { Q_UNUSED(index) settings->set(IDLE_DIM_TIME_KEY, QVariant(mDarkenComboBox->currentData(Qt::UserRole).toInt() * 60)); }); connect(mLowpowerComboBox1, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { settings->set(PER_ACTION_KEY, index + 5); }); connect(mLowpowerComboBox2, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { settings->set(ACTION_CRI_BTY, mLowpowerComboBox2->itemData(index)); }); connect(mNoticeComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { settings->set(PERCENTAGE_LOW, (index + 1)*10); }); connect(mLowSaveBtn,&SwitchButton::checkedChanged, [=](bool checked){ settings->set(LOW_BATTERY_AUTO_SAVE,checked); }); connect(mBatterySaveBtn,&SwitchButton::checkedChanged, [=](bool checked){ settings->set(ON_BATTERY_AUTO_SAVE,checked); }); connect(mDisplayTimeBtn,&SwitchButton::checkedChanged, [=](bool checked){ settings->set(DISPLAY_LEFT_TIME_OF_CHARGE_AND_DISCHARGE,checked); }); } void Power::initCustomPlanStatus() { // 信号阻塞 mPowerKeyComboBox->blockSignals(true); mCloseComboBox->blockSignals(true); mSleepComboBox->blockSignals(true); mCloseLidComboBox->blockSignals(true); mPowerComboBox->blockSignals(true); mBatteryComboBox->blockSignals(true); mDarkenComboBox->blockSignals(true); mLowpowerComboBox1->blockSignals(true); mLowpowerComboBox2->blockSignals(true); mNoticeComboBox->blockSignals(true); mSleepPwdBtn->blockSignals(true); mWakenPwdBtn->blockSignals(true); mLowSaveBtn->blockSignals(true); mBatterySaveBtn->blockSignals(true); mDisplayTimeBtn->blockSignals(true); mPowerKeyComboBox->setCurrentIndex(mPowerKeyComboBox->findData(settings->get(BUTTON_POWER_KEY).toString())); mSleepComboBox->setCurrentIndex(mSleepComboBox->findData(settings->get(SLEEP_COMPUTER_AC_KEY).toInt() / FIXES)); mCloseComboBox->setCurrentIndex(mCloseComboBox->findData(settings->get(SLEEP_DISPLAY_AC_KEY).toInt() / FIXES)); mCloseLidComboBox->setCurrentIndex(mCloseLidComboBox->findData(settings->get(BUTTON_LID_AC_KEY).toString())); //避免不存在该键值,出现闪退情况 if (settings->keys().contains("powerPolicyAc") && settings->keys().contains("powerPolicyBattery")) { if (1 == settings->get(POWER_POLICY_AC).toInt()) { mPowerComboBox->setCurrentIndex(mPowerComboBox->findData("Balance Model")); } else if (2 == settings->get(POWER_POLICY_AC).toInt()) { mPowerComboBox->setCurrentIndex(mPowerComboBox->findData("Save Model")); } else { mPowerComboBox->setCurrentIndex(mPowerComboBox->findData("Performance Model")); } if (1 == settings->get(POWER_POLICY_BATTARY).toInt()) { mBatteryComboBox->setCurrentIndex(mBatteryComboBox->findData("Balance Model")); } else if (2 == settings->get(POWER_POLICY_BATTARY).toInt()){ mBatteryComboBox->setCurrentIndex(mBatteryComboBox->findData("Save Model")); } else { mBatteryComboBox->setCurrentIndex(mBatteryComboBox->findData("Performance Model")); } } else { mPowerComboBox->setEnabled(false); mBatteryComboBox->setEnabled(false); } mDarkenComboBox->setCurrentIndex(mDarkenComboBox->findData(settings->get(IDLE_DIM_TIME_KEY).toInt() / FIXES)); mLowpowerComboBox1->setCurrentIndex(settings->get(PER_ACTION_KEY).toInt() - 5); mLowpowerComboBox2->setCurrentIndex(mLowpowerComboBox2->findData(settings->get(ACTION_CRI_BTY).toString())); mNoticeComboBox->setCurrentIndex(settings->get(PERCENTAGE_LOW).toInt()/10 - 1); mSleepPwdBtn->setChecked(screensettings->get(SLEEP_ACTIVATION_ENABLED).toBool()); mWakenPwdBtn->setChecked(settings->get(LOCK_BLANK_SCREEN).toBool()); if (settings->keys().contains("lowBatteryAutoSave") && settings->keys().contains("onBatteryAutoSave") && settings->keys().contains("dispalyLeftTimeOfChargeAndDischarge")) { mLowSaveBtn->setChecked(settings->get(LOW_BATTERY_AUTO_SAVE).toBool()); mBatterySaveBtn->setChecked(settings->get(ON_BATTERY_AUTO_SAVE).toBool()); mDisplayTimeBtn->setChecked(settings->get(DISPLAY_LEFT_TIME_OF_CHARGE_AND_DISCHARGE).toBool()); } else { mLowSaveFrame->hide(); mBatterySaveFrame->hide(); mDisplayTimeFrame->hide(); } // 信号阻塞解除 mPowerKeyComboBox->blockSignals(false); mCloseComboBox->blockSignals(false); mSleepComboBox->blockSignals(false); mCloseLidComboBox->blockSignals(false); mPowerComboBox->blockSignals(false); mBatteryComboBox->blockSignals(false); mDarkenComboBox->blockSignals(false); mLowpowerComboBox1->blockSignals(false); mLowpowerComboBox2->blockSignals(false); mNoticeComboBox->blockSignals(false); mSleepPwdBtn->blockSignals(false); mWakenPwdBtn->blockSignals(false); mLowSaveBtn->blockSignals(false); mBatterySaveBtn->blockSignals(false); mDisplayTimeBtn->blockSignals(false); } void Power::isLidPresent() { QDBusInterface *LidInterface = new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus(),this); if (!LidInterface->isValid()) { qDebug() << "Create UPower Lid Interface Failed : " << QDBusConnection::systemBus().lastError(); return; } QDBusReply LidInfo; LidInfo = LidInterface->call("Get", "org.freedesktop.UPower", "LidIsPresent"); isExitsLid = LidInfo.value().toBool(); } void Power::isHibernateSupply() { QDBusInterface *HibernateInterface = new QDBusInterface("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus(),this); if (!HibernateInterface->isValid()) { qDebug() << "Create login1 Hibernate Interface Failed : " << QDBusConnection::systemBus().lastError(); return; } QDBusReply HibernateInfo; HibernateInfo = HibernateInterface->call("CanHibernate"); isExitHibernate = HibernateInfo == "yes"?true:false; } bool Power::isExitBattery() { /* 默认机器没有电池 */ hasBat = false; QDBusInterface *brightnessInterface = new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower/devices/DisplayDevice", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus(), this); if (!brightnessInterface->isValid()) { qDebug() << "Create UPower Interface Failed : " << QDBusConnection::systemBus().lastError(); return false; } QDBusReply briginfo; briginfo = brightnessInterface ->call("Get", "org.freedesktop.UPower.Device", "PowerSupply"); if (briginfo.value().toBool()) { hasBat = true ; } return hasBat; } double Power::getBattery() { QDBusInterface *BatteryInterface = new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower/devices/battery_BAT0", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus(),this); if (!BatteryInterface->isValid()) { qDebug() << "Create UPower Battery Interface Failed : " << QDBusConnection::systemBus().lastError(); return 0; } QDBusReply BatteryInfo; BatteryInfo = BatteryInterface->call("Get", "org.freedesktop.UPower.Device", "Percentage"); return BatteryInfo.value().toDouble(); } bool Power::QLabelSetText(QLabel *label, QString string) { bool is_over_length = false; QFontMetrics fontMetrics(label->font()); int fontSize = fontMetrics.width(string); QString str = string; if (fontSize > (label->width()-5)) { str = fontMetrics.elidedText(string, Qt::ElideRight, label->width()); is_over_length = true; } label->setText(str); return is_over_length; } ukui-control-center/plugins/system/display/0000755000175000017500000000000014205370757020073 5ustar fengfengukui-control-center/plugins/system/display/scalesize.h0000644000175000017500000000345314201663716022227 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SCALESIZE_H #define SCALESIZE_H #include const QSize KRsolution(1920, 1080); const QVector k150Scale{QSize(1280, 1024), QSize(1440, 900), QSize(1600, 900), QSize(1680, 1050), QSize(1920, 1080), QSize(1920, 1200), QSize(1680, 1280), QSize(2048, 1080), QSize(2048, 1280), QSize(2160, 1440), QSize(2560, 1440), QSize(3840, 2160)}; const QVector k175Scale{QSize(2048, 1080), QSize(2048, 1280), QSize(2160, 1440), QSize(2560, 1440), QSize(3840, 2160)}; const QVector k200Scale{QSize(2048, 1080),QSize(2048, 1280), QSize(2160, 1440), QSize(2560, 1440), QSize(3840, 2160)}; const QVector k250Scale{QSize(2560, 1440), QSize(3840, 2160)}; const QVector k275Scale{QSize(3840, 2160)}; #define SCALE_SCHEMAS "org.ukui.SettingsDaemon.plugins.xsettings" #define SCALE_KEY "scaling-factor" extern QSize mScaleSize; extern double mScaleres; #endif // SCALESIZE_H ukui-control-center/plugins/system/display/qml.qrc0000644000175000017500000000017714201663716021374 0ustar fengfeng qml/Output.qml qml/main.qml ukui-control-center/plugins/system/display/controlpanel.h0000644000175000017500000000361714201663716022747 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef CONTROLPANEL_H #define CONTROLPANEL_H #include #include class QVBoxLayout; class OutputConfig; class UnifiedOutputConfig; class QLabel; class QCheckBox; class QSlider; class QComboBox; const QString kSession = "wayland"; class ControlPanel : public QFrame { Q_OBJECT public: explicit ControlPanel(QWidget *parent = nullptr); ~ControlPanel() override; void setConfig(const KScreen::ConfigPtr &config); void setUnifiedOutput(const KScreen::OutputPtr &output); void activateOutputNoParam(); private: void isWayland(); public Q_SLOTS: void activateOutput(const KScreen::OutputPtr &output); void slotOutputConnectedChanged(); Q_SIGNALS: void changed(); void scaleChanged(double scale); private Q_SLOTS: void addOutput(const KScreen::OutputPtr &output, bool connectChanged); void removeOutput(int outputId); public: QVBoxLayout *mLayout; private: KScreen::ConfigPtr mConfig; QList mOutputConfigs; UnifiedOutputConfig *mUnifiedOutputCfg; KScreen::OutputPtr mCurrentOutput; bool mIsWayland; }; #endif // CONTROLPANEL_H ukui-control-center/plugins/system/display/controlpanel.cpp0000644000175000017500000001242514201663716023277 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "controlpanel.h" #include "outputconfig.h" #include "unifiedoutputconfig.h" #include "utils.h" #include #include #include #include #include QSize mScaleSize = QSize(); ControlPanel::ControlPanel(QWidget *parent) : QFrame(parent), mUnifiedOutputCfg(nullptr) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); mLayout = new QVBoxLayout(this); mLayout->setContentsMargins(0, 0, 0, 0); isWayland(); } ControlPanel::~ControlPanel() { } void ControlPanel::setConfig(const KScreen::ConfigPtr &config) { qDeleteAll(mOutputConfigs); mOutputConfigs.clear(); delete mUnifiedOutputCfg; mUnifiedOutputCfg = nullptr; if (mConfig) { mConfig->disconnect(this); } mConfig = config; connect(mConfig.data(), &KScreen::Config::outputAdded, this, [=](const KScreen::OutputPtr &output) { addOutput(output, false); }); connect(mConfig.data(), &KScreen::Config::outputRemoved, this, &ControlPanel::removeOutput); for (const KScreen::OutputPtr &output : mConfig->outputs()) { addOutput(output, false); } } void ControlPanel::addOutput(const KScreen::OutputPtr &output, bool connectChanged) { if (!connectChanged) { connect(output.data(), &KScreen::Output::isConnectedChanged, this, &ControlPanel::slotOutputConnectedChanged); } if (!output->isConnected()) return; OutputConfig *outputCfg = new OutputConfig(this); outputCfg->setVisible(false); outputCfg->setShowScaleOption(mConfig->supportedFeatures().testFlag(KScreen::Config::Feature::PerOutputScaling)); outputCfg->setOutput(output); connect(outputCfg, &OutputConfig::changed, this, &ControlPanel::changed); connect(outputCfg, &OutputConfig::scaleChanged, this, &ControlPanel::scaleChanged); mLayout->addWidget(outputCfg); mOutputConfigs << outputCfg; if (mIsWayland) { activateOutput(mCurrentOutput); } } void ControlPanel::removeOutput(int outputId) { if (mUnifiedOutputCfg) { mUnifiedOutputCfg->setVisible(false); } for (OutputConfig *outputCfg : mOutputConfigs) { if (!outputCfg || !outputCfg->output()) { continue; } if (outputCfg->output()->id() == outputId) { mOutputConfigs.removeOne(outputCfg); outputCfg->deleteLater(); outputCfg = nullptr; } else { if (outputCfg->output()->isConnected()) { outputCfg->setVisible(true); } else { outputCfg->setVisible(false); } } } } void ControlPanel::activateOutput(const KScreen::OutputPtr &output) { // Ignore activateOutput when in unified mode if (mUnifiedOutputCfg && mUnifiedOutputCfg->isVisible()) { return; } mCurrentOutput = output; Q_FOREACH (OutputConfig *cfg, mOutputConfigs) { cfg->setVisible(cfg->output()->id() == output->id()); } } void ControlPanel::activateOutputNoParam() { // Ignore activateOutput when in unified mode if (mUnifiedOutputCfg) { return; } Q_FOREACH (OutputConfig *cfg, mOutputConfigs) { cfg->setVisible(cfg->output()->id() == 66); } } void ControlPanel::isWayland() { QString sessionType = getenv("XDG_SESSION_TYPE"); if (!sessionType.compare(kSession, Qt::CaseSensitive)) { mIsWayland = true; } else { mIsWayland = false; } } void ControlPanel::setUnifiedOutput(const KScreen::OutputPtr &output) { Q_FOREACH (OutputConfig *config, mOutputConfigs) { if (!config->output()->isConnected()) { continue; } // 隐藏下面控制 config->setVisible(output == nullptr); } if (output.isNull()) { mUnifiedOutputCfg->deleteLater(); mUnifiedOutputCfg = nullptr; } else { mUnifiedOutputCfg = new UnifiedOutputConfig(mConfig, this); mUnifiedOutputCfg->setOutput(output); mUnifiedOutputCfg->setVisible(true); mLayout->insertWidget(mLayout->count() - 2, mUnifiedOutputCfg); connect(mUnifiedOutputCfg, &UnifiedOutputConfig::changed, this, &ControlPanel::changed); } } void ControlPanel::slotOutputConnectedChanged() { const KScreen::OutputPtr output(qobject_cast(sender()), [](void *){ }); if (output->isConnected()) { addOutput(output, true); } else { removeOutput(output->id()); } } ukui-control-center/plugins/system/display/declarative/0000755000175000017500000000000014201663716022352 5ustar fengfengukui-control-center/plugins/system/display/declarative/qmlscreen.cpp0000644000175000017500000004222614201663716025055 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qmlscreen.h" #include "qmloutputcomponent.h" #include "qmloutput.h" #include #include #include #include #include Q_DECLARE_METATYPE(KScreen::OutputPtr) QMLScreen::QMLScreen(QQuickItem *parent) : QQuickItem(parent) { connect(this, &QMLScreen::widthChanged, this, &QMLScreen::viewSizeChanged); connect(this, &QMLScreen::heightChanged, this, &QMLScreen::viewSizeChanged); setX100GPU(); } QMLScreen::~QMLScreen() { qDeleteAll(m_outputMap); m_outputMap.clear(); } KScreen::ConfigPtr QMLScreen::config() const { return m_config; } void QMLScreen::setConfig(const KScreen::ConfigPtr &config) { qDeleteAll(m_outputMap); m_outputMap.clear(); m_manuallyMovedOutputs.clear(); m_bottommost = m_leftmost = m_rightmost = m_topmost = nullptr; m_connectedOutputsCount = 0; m_enabledOutputsCount = 0; if (m_config) { m_config->disconnect(this); } m_config = config; connect(m_config.data(), &KScreen::Config::outputAdded, this, [this](const KScreen::OutputPtr &output) { QTimer::singleShot(1000, this, [=]{ addOutput(output); updateOutputsPlacement(); }); }); connect(m_config.data(), &KScreen::Config::outputRemoved, this, &QMLScreen::removeOutput); for (const KScreen::OutputPtr &output : m_config->outputs()) { addOutput(output); } updateOutputsPlacement(); for (QMLOutput *qmlOutput : m_outputMap) { if (qmlOutput->output()->isConnected() && qmlOutput->output()->isEnabled()) { qmlOutput->dockToNeighbours(); } } } void QMLScreen::addOutput(const KScreen::OutputPtr &output) { QMLOutputComponent comp(qmlEngine(this), this); QMLOutput *qmloutput = comp.createForOutput(output); if (!qmloutput) { qWarning() << "Failed to create QMLOutput"; return; } m_outputMap.insert(output, qmloutput); qmloutput->setParentItem(this); qmloutput->setZ(m_outputMap.count()); connect(output.data(), &KScreen::Output::isConnectedChanged, this, &QMLScreen::outputConnectedChanged); connect(output.data(), &KScreen::Output::isEnabledChanged, this, &QMLScreen::outputEnabledChanged); connect(output.data(), &KScreen::Output::posChanged, this, &QMLScreen::outputPositionChanged); connect(qmloutput, &QMLOutput::yChanged, [this, qmloutput]() { qmlOutputMoved(qmloutput); }); connect(qmloutput, &QMLOutput::xChanged, [this, qmloutput]() { qmlOutputMoved(qmloutput); }); // 在这里点击上面小屏幕 connect(qmloutput, SIGNAL(clicked()), this, SLOT(setActiveOutput())); connect(qmloutput, SIGNAL(mouseReleased(bool)), this, SLOT(setScreenPos(bool))); connect(qmloutput, SIGNAL(rotationChanged(bool)), this, SLOT(setScreenPos(bool))); connect(qmloutput, SIGNAL(widthChanged(bool)), this, SLOT(setScreenPos(bool))); connect(qmloutput, SIGNAL(heightChanged(bool)), this, SLOT(setScreenPos(bool))); qmloutput->updateRootProperties(); } void QMLScreen::removeOutput(int outputId) { for (const KScreen::OutputPtr &output : m_outputMap.keys()) { if (output->id() == outputId) { QMLOutput *qmlOutput = m_outputMap.take(output); qmlOutput->setParentItem(nullptr); qmlOutput->setParent(nullptr); // TODO:bug51346 // qmlOutput->deleteLater(); return; } } } int QMLScreen::connectedOutputsCount() const { return m_connectedOutputsCount; } int QMLScreen::enabledOutputsCount() const { return m_enabledOutputsCount; } QMLOutput *QMLScreen::primaryOutput() const { Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { if (qmlOutput->output()->isPrimary()) { return qmlOutput; } } return nullptr; } QList QMLScreen::outputs() const { return m_outputMap.values(); } void QMLScreen::setActiveOutput(QMLOutput *output) { Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { if (qmlOutput->z() > output->z()) { qmlOutput->setZ(qmlOutput->z() - 1); } } output->setZ(m_outputMap.count()); // 中屏幕 output->setFocus(true); Q_EMIT focusedOutputChanged(output); } void QMLScreen::setScreenCenterPos() { // 组成最大矩形四个边的位置,分别对应左上(1),右下(2)的xy坐标值 qreal localX1 = -1, localX2 = -1, localY1 = -1, localY2 = -1; qreal mX1 = 0, mY1 = 0, mX2 = 0, mY2 = 0; // 矩形中点坐标 qreal moveX = 0, moveY = 0;// 移动的值 bool firstFlag = true; Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { if (qmlOutput->output()->isConnected()) { if (firstFlag == true || localX1 > qmlOutput->x()) { localX1 = qmlOutput->x(); } if (firstFlag == true || localX2 < qmlOutput->x() + qmlOutput->width()) { localX2 = qmlOutput->x() + qmlOutput->width(); } if (firstFlag == true || localY1 > qmlOutput->y()) { localY1 = qmlOutput->y(); } if (firstFlag == true || localY2 < qmlOutput->y() + qmlOutput->height()) { localY2 = qmlOutput->y() + qmlOutput->height(); } firstFlag = false; } } mX1 = localX1 + (localX2-localX1)/2; mY1 = localY1 + (localY2-localY1)/2; mX2 = (width() - (localX2 - localX1))/2 + (localX2-localX1)/2; mY2 = (height() - (localY2 - localY1))/2 + (localY2-localY1)/2; moveX = mX2 - mX1; moveY = mY2 - mY1; Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { qmlOutput->blockSignals(true); qmlOutput->setX(qmlOutput->x() + moveX); qmlOutput->setY(qmlOutput->y() + moveY); qmlOutput->blockSignals(false); } } void QMLScreen::setScreenPos(QMLOutput *output, bool isReleased) { QPointF posBefore = output->position(); // 镜像模式下跳过屏幕旋转处理 if (output->isCloneMode()) { return; } float x1 = 0, y1 = 0; float width1 = 0, height1 = 0; float x2 = 0, y2 = 0; float width2 = 0, height2 = 0; x1 = output->x(); y1 = output->y(); width1 = output->width(); height1 = output->height(); int connectedScreen = 0; QMLOutput *other = NULL; Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { if (qmlOutput->output()->isConnected()) { connectedScreen++; } if (qmlOutput != output && qmlOutput->output()->isConnected()) { other = qmlOutput; x2 = other->x(); y2 = other->y(); width2 = other->width(); height2 = other->height(); } } if (connectedScreen < 2) { setScreenCenterPos(); return; } if (!((x1 + width1 == x2) || (y1 == y2 + height2) || (x1 == x2 + width2) || (y1 + height1 == y2))) { if (x1 + width1 < x2) { output->setX(x2 - width1); output->setY(y2); } else if (y1 > y2 + height2) { output->setX(x2); output->setY(y2 + height2); } else if (x1 > x2 + width2) { output->setX(x2 + width2); output->setY(y2); } else if (y1 + height1 < y2) { output->setX(x2); output->setY(y2 - height1); } // 矩形是否相交 if (!(x1 + width1 <= x2 || x2 + width2 <= x1 || y1 >= y2 +height2 || y2 >= y1 + height1) && (x1 != x2 || y1 != y2) && other != NULL && other->output()->isConnected()) { if ((x1 + width1 > x2) && (x1 < x2)) { output->setX(x2 - width1); } else if ((x1 < x2 + width2) && (x1 + width1 > x2 + width2)) { output->setX(x2 + width2); } else if ((y1 + height() > y2) && (y1 < y2 + height2)) { output->setY(y2 - height1); } else if ((y1 < y2 + height2) && (y1 + height1 > y2 + height2)) { output->setY(y2 + height2); } } } if (mIsX100) { // PX100需求 x1 = output->x(); y1 = output->y(); width1 = output->width(); height1 = output->height(); Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { if (qmlOutput->output()->isConnected()) { connectedScreen++; } if (qmlOutput != output && qmlOutput->output()->isConnected()) { other = qmlOutput; x2 = other->x(); y2 = other->y(); width2 = other->width(); height2 = other->height(); } } // 对上下左右四种情况进行处理 if (qFuzzyCompare(x1 + width1, x2) && !qFuzzyCompare(y1, y2)) { other->setY(y1); } else if (qFuzzyCompare(x2 + width2, x1) && !qFuzzyCompare(y1, y2)) { output->setY(y2); } else if (qFuzzyCompare(y1 + height1, y2) && !qFuzzyCompare(x1, x2)) { other->setX(x1); } else if (qFuzzyCompare(y2 + height2, y1) && !qFuzzyCompare(x1, x2)) { output->setX(x2); } } setScreenCenterPos(); QPointF posAfter = output->position(); if (isReleased && !(posBefore == posAfter)) { Q_EMIT released(); } } void QMLScreen::setActiveOutputByCombox(int screenId) { QHash::const_iterator it = m_outputMap.constBegin(); while (it != m_outputMap.constEnd()) { if (screenId == it.key()->id()) { setActiveOutput(it.value()); return; } it++; } } QSize QMLScreen::maxScreenSize() const { return m_config->screen()->maxSize(); } float QMLScreen::outputScale() const { return m_outputScale; } void QMLScreen::outputConnectedChanged() { int connectedCount = 0; Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { if (output->isConnected()) { ++connectedCount; } } if (connectedCount != m_connectedOutputsCount) { m_connectedOutputsCount = connectedCount; Q_EMIT connectedOutputsCountChanged(); updateOutputsPlacement(); } } void QMLScreen::outputEnabledChanged() { const KScreen::OutputPtr output(qobject_cast(sender()), [](void *){ }); if (output->isEnabled()) { // bug#68442 // updateOutputsPlacement(); } int enabledCount = 0; Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { if (output->isEnabled()) { ++enabledCount; } } if (enabledCount == m_enabledOutputsCount) { m_enabledOutputsCount = enabledCount; Q_EMIT enabledOutputsCountChanged(); } } void QMLScreen::outputPositionChanged() { /* TODO: Reposition the QMLOutputs */ } void QMLScreen::qmlOutputMoved(QMLOutput *qmlOutput) { if (qmlOutput->isCloneMode()) { return; } if (!m_manuallyMovedOutputs.contains(qmlOutput)) m_manuallyMovedOutputs.append(qmlOutput); updateCornerOutputs(); if (m_leftmost) { m_leftmost->setOutputX(0); } if (m_topmost) { m_topmost->setOutputY(0); } if (qmlOutput == m_leftmost) { Q_FOREACH (QMLOutput *other, m_outputMap) { if (other == m_leftmost) { continue; } if (!other->output()->isConnected() || !other->output()->isEnabled()) { continue; } other->setOutputX(float(other->x() - m_leftmost->x()) / outputScale()); } } else if (m_leftmost) { qmlOutput->setOutputX(float(qmlOutput->x() - m_leftmost->x()) / outputScale()); } if (qmlOutput == m_topmost) { Q_FOREACH (QMLOutput *other, m_outputMap) { if (other == m_topmost) { continue; } if (!other->output()->isConnected() || !other->output()->isEnabled()) { continue; } other->setOutputY(float(other->y() - m_topmost->y()) / outputScale()); } } else if (m_topmost) { qmlOutput->setOutputY(float(qmlOutput->y() - m_topmost->y()) / outputScale()); } } void QMLScreen::viewSizeChanged() { //TO fix bug#85240 // updateOutputsPlacement(); setScreenCenterPos(); } void QMLScreen::updateCornerOutputs() { m_leftmost = nullptr; m_topmost = nullptr; m_rightmost = nullptr; m_bottommost = nullptr; Q_FOREACH (QMLOutput *output, m_outputMap) { if (!output->output()->isConnected() || !output->output()->isEnabled()) { continue; } QMLOutput *other = m_leftmost; if (!other || output->x() < other->x()) { m_leftmost = output; } if (!other || output->y() < other->y()) { m_topmost = output; } if (!other || output->x() + output->width() > other->x() + other->width()) { m_rightmost = output; } if (!other || output->y() + output->height() > other->y() + other->height()) { m_bottommost = output; } } } void QMLScreen::setOutputScale(float scale) { if (qFuzzyCompare(scale, m_outputScale)) return; m_outputScale = scale; emit outputScaleChanged(); } void QMLScreen::setX100GPU() { QProcess *gpuPro = new QProcess(); gpuPro->start("lspci"); gpuPro->waitForFinished(); QString output = gpuPro->readAll(); mIsX100 = output.contains("X100"); } // 画坐标 void QMLScreen::updateOutputsPlacement() { if (width() <= 0) return; QSizeF initialActiveScreenSize; Q_FOREACH (QQuickItem *item, childItems()) { QMLOutput *qmlOutput = qobject_cast(item); if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled()) { continue; } if (qmlOutput->outputX() + qmlOutput->currentOutputWidth() > initialActiveScreenSize.width()) { initialActiveScreenSize.setWidth(qmlOutput->outputX() + qmlOutput->currentOutputWidth()); } if (qmlOutput->outputY() + qmlOutput->currentOutputHeight() > initialActiveScreenSize.height()) { initialActiveScreenSize.setHeight( qmlOutput->outputY() + qmlOutput->currentOutputHeight()); } } auto initialScale = outputScale(); auto scale = initialScale; qreal lastX = -1.0; do { auto activeScreenSize = initialActiveScreenSize * scale; const QPointF offset((width() - activeScreenSize.width()) / 2.0, (height() - activeScreenSize.height()) / 2.0); lastX = -1.0; qreal lastY = -1.0; Q_FOREACH (QQuickItem *item, childItems()) { QMLOutput *qmlOutput = qobject_cast(item); if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled() || m_manuallyMovedOutputs.contains(qmlOutput)) { continue; } qmlOutput->blockSignals(true); qmlOutput->setPosition(QPointF(offset.x() + (qmlOutput->outputX() * scale), offset.y() + (qmlOutput->outputY() * scale))); lastX = qMax(lastX, qmlOutput->position().x() + qmlOutput->width() / initialScale * scale); lastY = qMax(lastY, qmlOutput->position().y()); qmlOutput->blockSignals(false); } Q_FOREACH (QQuickItem *item, childItems()) { QMLOutput *qmlOutput = qobject_cast(item); if (qmlOutput->output()->isConnected() && !qmlOutput->output()->isEnabled() && !m_manuallyMovedOutputs.contains(qmlOutput)) { qmlOutput->blockSignals(true); qmlOutput->setPosition(QPointF(lastX, lastY)); lastX += qmlOutput->width() / initialScale * scale; qmlOutput->blockSignals(false); } } // calculate the scale dynamically, so all screens fit to the dialog if (lastX > width()) { scale *= 0.8; } } while (lastX > width()); // Use a timer to avoid binding loop on width() QTimer::singleShot(0, this, [scale, this] { setOutputScale(scale); }); } ukui-control-center/plugins/system/display/declarative/qmloutput.cpp0000644000175000017500000003772614201663716025147 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qmloutput.h" #include "qmlscreen.h" #include #include #include #include #include const static int sMargin = 0; const static int sSnapArea = 20; const static int sSnapAlignArea = 6; Q_DECLARE_METATYPE(KScreen::ModePtr) bool operator>(const QSize &sizeA, const QSize &sizeB) { return ((sizeA.width() > sizeB.width()) && (sizeA.height() > sizeB.height())); } QMLOutput::QMLOutput(QQuickItem *parent): QQuickItem(parent), m_screen(nullptr), m_cloneOf(nullptr), m_leftDock(nullptr), m_topDock(nullptr), m_rightDock(nullptr), m_bottomDock(nullptr), m_isCloneMode(false) { connect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); connect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); } KScreen::Output* QMLOutput::output() const { return m_output.data(); } KScreen::OutputPtr QMLOutput::outputPtr() const { return m_output; } void QMLOutput::setOutputPtr(const KScreen::OutputPtr &output) { Q_ASSERT(m_output.isNull()); m_output = output; Q_EMIT outputChanged(); connect(m_output.data(), &KScreen::Output::rotationChanged, this, &QMLOutput::updateRootProperties); connect(m_output.data(), &KScreen::Output::currentModeIdChanged, this, &QMLOutput::currentModeIdChanged); } QMLScreen *QMLOutput::screen() const { return m_screen; } void QMLOutput::setScreen(QMLScreen *screen) { Q_ASSERT(m_screen == nullptr); m_screen = screen; Q_EMIT screenChanged(); } void QMLOutput::setLeftDockedTo(QMLOutput *output) { if (m_leftDock == output) { return; } m_leftDock = output; Q_EMIT leftDockedToChanged(); } QMLOutput *QMLOutput::leftDockedTo() const { return m_leftDock; } void QMLOutput::undockLeft() { setLeftDockedTo(nullptr); } void QMLOutput::setTopDockedTo(QMLOutput *output) { if (m_topDock == output) { return; } m_topDock = output; Q_EMIT topDockedToChanged(); } QMLOutput *QMLOutput::topDockedTo() const { return m_topDock; } void QMLOutput::undockTop() { setTopDockedTo(nullptr); } void QMLOutput::setRightDockedTo(QMLOutput *output) { if (m_rightDock == output) { return; } m_rightDock = output; Q_EMIT rightDockedToChanged(); } QMLOutput *QMLOutput::rightDockedTo() const { return m_rightDock; } void QMLOutput::undockRight() { setRightDockedTo(nullptr); } void QMLOutput::setBottomDockedTo(QMLOutput *output) { if (m_bottomDock == output) { return; } m_bottomDock = output; Q_EMIT bottomDockedToChanged(); } QMLOutput *QMLOutput::bottomDockedTo() const { return m_bottomDock; } void QMLOutput::undockBottom() { setBottomDockedTo(nullptr); } void QMLOutput::setCloneOf(QMLOutput* other) { if (m_cloneOf == other) { return; } m_cloneOf = other; Q_EMIT cloneOfChanged(); } QMLOutput* QMLOutput::cloneOf() const { return m_cloneOf; } int QMLOutput::currentOutputHeight() const { if (!m_output) { return 0; } KScreen::ModePtr mode = m_output->currentMode(); if (!mode) { if (m_output->isConnected()) { mode = bestMode(); if (!mode) { return 1000; } m_output->setCurrentModeId(mode->id()); } else { return 1000; } } return mode->size().height() / m_output->scale(); } int QMLOutput::currentOutputWidth() const { if (!m_output) { return 0; } KScreen::ModePtr mode = m_output->currentMode(); if (!mode) { if (m_output->isConnected()) { mode = bestMode(); if (!mode) { return 1000; } m_output->setCurrentModeId(mode->id()); } else { return 1000; } } return mode->size().width() / m_output->scale(); } void QMLOutput::currentModeIdChanged() { //qDebug()<<"currentModeIdChanged---->"<outputScale(); setX((m_screen->width() - newWidth) / 2); const float newHeight = currentOutputHeight() * m_screen->outputScale(); setY((m_screen->height() - newHeight) / 2); } else { if (m_rightDock) { QMLOutput *rightDock = m_rightDock; float newWidth = currentOutputWidth() * m_screen->outputScale(); setX(rightDock->x() - newWidth); setRightDockedTo(rightDock); } if (m_bottomDock) { QMLOutput *bottomDock = m_bottomDock; float newHeight = currentOutputHeight() * m_screen->outputScale(); setY(bottomDock->y() - newHeight); setBottomDockedTo(bottomDock); } } Q_EMIT currentOutputSizeChanged(); } int QMLOutput::outputX() const { //qDebug()<<"outputX--->"<pos().x()<pos().x(); } void QMLOutput::setOutputX(int x) { // qDebug()<<"setOutputX--->"<pos().rx() == x) { return; } QPoint pos = m_output->pos(); pos.setX(x); m_output->setPos(pos); Q_EMIT outputXChanged(); } int QMLOutput::outputY() const { //qDebug()<<"outputY--->"<pos().y()<pos().y(); } void QMLOutput::setOutputY(int y) { // qDebug()<<"setOutputY--->"<pos().ry() == y) { return; } QPoint pos = m_output->pos(); pos.setY(y); m_output->setPos(pos); Q_EMIT outputYChanged(); } bool QMLOutput::isCloneModeShow() const { return m_cloneModeShow; } bool QMLOutput::isCloneMode() const { return m_isCloneMode; } void QMLOutput::setIsCloneMode(bool isCloneMode, bool cloneModeShow) { m_cloneModeShow = cloneModeShow; m_isCloneMode = isCloneMode; Q_EMIT isCloneModeChanged(); } void QMLOutput::dockToNeighbours() { //qDebug()<<"dockToNeighbours---->"<outputs()) { if (otherQmlOutput == this) { continue; } if (!otherQmlOutput->output()->isConnected() || !otherQmlOutput->output()->isEnabled()) { continue; } const QRect geom = m_output->geometry(); const QRect otherGeom = otherQmlOutput->output()->geometry(); //qDebug()<<"geom is ------>"<modes(); KScreen::ModePtr bestMode; Q_FOREACH (const KScreen::ModePtr &mode, modes) { if (!bestMode || (mode->size() > bestMode->size())) { bestMode = mode; } } return bestMode; } bool QMLOutput::collidesWithOutput(QObject *other) { QQuickItem* otherItem = qobject_cast(other); return boundingRect().intersects(otherItem->boundingRect()); } bool QMLOutput::maybeSnapTo(QMLOutput *other) { qreal centerX = x() + (width() / 2.0); qreal centerY = y() + (height() / 2.0); const qreal x2 = other->x(); const qreal y2 = other->y(); const qreal height2 = other->height(); const qreal width2 = other->width(); const qreal centerX2 = x2 + (width2 / 2.0); const qreal centerY2 = y2 + (height2 / 2.0); /* left of other */ if ((x() + width() > x2 - sSnapArea) && (x() + width() < x2 + sSnapArea) && (y() + height() > y2) && (y() < y2 + height2)) { setX(x2 - width() + sMargin); centerX = x() + (width() / 2.0); setRightDockedTo(other); other->setLeftDockedTo(this); //output.cloneOf = null; /* output is snapped to other on left and their * upper sides are aligned */ if ((y() < y2 + sSnapAlignArea) && (y() > y2 - sSnapAlignArea)) { setY(y2); return true; } /* output is snapped to other on left and they * are centered */ if ((centerY < centerY2 + sSnapAlignArea) && (centerY > centerY2 - sSnapAlignArea)) { setY(centerY2 - (height() / 2.0)); return true; } /* output is snapped to other on left and their * bottom sides are aligned */ if ((y() + height() < y2 + height2 + sSnapAlignArea) && (y() + height() > y2 + height2 - sSnapAlignArea)) { setY(y2 + height2 - height()); return true; } return true; } /* output is right of other */ if ((x() > x2 + width2 - sSnapArea) && (x() < x2 + width2 + sSnapArea) && (y() + height() > y2) && (y() < y2 + height2)) { setX(x2 + width2 - sMargin); centerX = x() + (width() / 2.0); setLeftDockedTo(other); other->setRightDockedTo(this); //output.cloneOf = null; /* output is snapped to other on right and their * upper sides are aligned */ if ((y() < y2 + sSnapAlignArea) && (y() > y2 - sSnapAlignArea)) { setY(y2); return true; } /* output is snapped to other on right and they * are centered */ if ((centerY < centerY2 + sSnapAlignArea) && (centerY > centerY2 - sSnapAlignArea)) { setY(centerY2 - (height() / 2.0)); return true; } /* output is snapped to other on right and their * bottom sides are aligned */ if ((y() + height() < y2 + height2 + sSnapAlignArea) && (y() + height() > y2 + height2 - sSnapAlignArea)) { setY(y2 + height2 - height()); return true; } return true; } /* output is above other */ if ((y() + height() > y2 - sSnapArea) && (y() + height() < y2 + sSnapArea) && (x() + width() > x2) && (x() < x2 + width2)) { setY(y2 - height() + sMargin); centerY = y() + (height() / 2.0); setBottomDockedTo(other); other->setTopDockedTo(this); //output.cloneOf = null; /* output is snapped to other on top and their * left sides are aligned */ if ((x() < x2 + sSnapAlignArea) && (x() > x2 - sSnapAlignArea)) { setX(x2); return true; } /* output is snapped to other on top and they * are centered */ if ((centerX < centerX2 + sSnapAlignArea) && (centerX > centerX2 - sSnapAlignArea)) { setX(centerX2 - (width() / 2.0)); return true; } /* output is snapped to other on top and their * right sides are aligned */ if ((x() + width() < x2 + width2 + sSnapAlignArea) && (x() + width() > x2 + width2 - sSnapAlignArea)) { setX(x2 + width2 - width()); return true; } return true; } /* output is below other */ if ((y() > y2 + height2 - sSnapArea) && (y() < y2 + height2 + sSnapArea) && (x() + width() > x2) && (x() < x2 + width2)) { setY(y2 + height2 - sMargin); centerY = y() + (height() / 2.0); setTopDockedTo(other); other->setBottomDockedTo(this); //output.cloneOf = null; /* output is snapped to other on bottom and their * left sides are aligned */ if ((x() < x2 + sSnapAlignArea) && (x() > x2 - sSnapAlignArea)) { setX(x2); return true; } /* output is snapped to other on bottom and they * are centered */ if ((centerX < centerX2 + sSnapAlignArea) && (centerX > centerX2 - sSnapAlignArea)) { setX(centerX2 - (width() / 2.0)); return true; } /* output is snapped to other on bottom and their * right sides are aligned */ if ((x() + width() < x2 + width2 + sSnapAlignArea) && (x() + width() > x2 + width2 - sSnapAlignArea)) { setX(x2 + width2 - width()); return true; } return true; } return false; } void QMLOutput::moved() { const QList siblings = screen()->childItems(); // First, if we have moved, then unset the "cloneOf" flag setCloneOf(nullptr); disconnect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); disconnect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); Q_FOREACH (QQuickItem *sibling, siblings) { QMLOutput *otherOutput = qobject_cast(sibling); if (!otherOutput || otherOutput == this) { continue; } if (!maybeSnapTo(otherOutput)) { if (m_leftDock == otherOutput) { m_leftDock->undockRight(); undockLeft(); } if (m_topDock == otherOutput) { m_topDock->undockBottom(); undockTop(); } if (m_rightDock == otherOutput) { m_rightDock->undockLeft(); undockRight(); } if (m_bottomDock == otherOutput) { m_bottomDock->undockTop(); undockBottom(); } } } connect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); connect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); Q_EMIT moved(m_output->name()); } /* Transformation of an item (rotation of the MouseArea) is only visual. * The coordinates and dimensions are still the same (when you rotated * 100x500 rectangle by 90 deg, it will still be 100x500, although * visually it will be 500x100). * * This method calculates the real-visual coordinates and dimensions of * the MouseArea and updates root item to match them. This makes snapping * work correctly regardless off visual rotation of the output */ //旋转时计算坐标更改方向 void QMLOutput::updateRootProperties() { //qDebug()<<"updateRootProperties----->"<isHorizontal() ? currentOutputWidth() : currentOutputHeight()) * m_screen->outputScale(); const float transformedHeight = (m_output->isHorizontal() ? currentOutputHeight() : currentOutputWidth()) * m_screen->outputScale(); const float transformedX = x() + (width() / 2.0) - (transformedWidth / 2.0); const float transformedY = y() + (height() / 2.0) - (transformedHeight / 2.0); //qDebug()<<"transformedWidth: "< 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef QMLSCREEN_H #define QMLSCREEN_H #include #include #include "qmloutput.h" class QQmlEngine; namespace KScreen { class Output; class Config; } class QMLScreen : public QQuickItem { Q_OBJECT Q_PROPERTY(QSize maxScreenSize READ maxScreenSize CONSTANT) Q_PROPERTY(int connectedOutputsCount READ connectedOutputsCount NOTIFY connectedOutputsCountChanged) Q_PROPERTY(int enabledOutputsCount READ enabledOutputsCount NOTIFY enabledOutputsCountChanged) Q_PROPERTY(float outputScale READ outputScale NOTIFY outputScaleChanged) public: explicit QMLScreen(QQuickItem *parent = nullptr); ~QMLScreen() override; int connectedOutputsCount() const; int enabledOutputsCount() const; QMLOutput *primaryOutput() const; QList outputs() const; QSize maxScreenSize() const; float outputScale() const; KScreen::ConfigPtr config() const; void setConfig(const KScreen::ConfigPtr &config); void updateOutputsPlacement(); void setActiveOutput(QMLOutput *output); void setScreenPos(QMLOutput *output, bool isReleased); void setScreenCenterPos(); public Q_SLOTS: void setActiveOutput() { setActiveOutput(qobject_cast(sender())); } void setActiveOutputByCombox(int screenId); void setScreenPos(bool isReleased) { setScreenPos(qobject_cast(sender()), isReleased); } Q_SIGNALS: void connectedOutputsCountChanged(); void enabledOutputsCountChanged(); void outputScaleChanged(); void focusedOutputChanged(QMLOutput *output); void released(); private Q_SLOTS: void addOutput(const KScreen::OutputPtr &output); void removeOutput(int outputId); void outputConnectedChanged(); void outputEnabledChanged(); void outputPositionChanged(); void viewSizeChanged(); private: void qmlOutputMoved(QMLOutput *qmlOutput); void updateCornerOutputs(); void setOutputScale(float scale); void setX100GPU(); bool mIsX100; KScreen::ConfigPtr m_config; QHash m_outputMap; QVector m_manuallyMovedOutputs; int m_connectedOutputsCount = 0; int m_enabledOutputsCount = 0; float m_outputScale = 1.0 / 14.0;// 缩放比例 QMLOutput *m_leftmost = nullptr; QMLOutput *m_topmost = nullptr; QMLOutput *m_rightmost = nullptr; QMLOutput *m_bottommost = nullptr; }; #endif // QMLSCREEN_H ukui-control-center/plugins/system/display/declarative/qmloutputcomponent.cpp0000644000175000017500000000364114201663671027057 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qmloutputcomponent.h" #include "qmloutput.h" #include "qmlscreen.h" #include #include #include #include #include #include Q_DECLARE_METATYPE(KScreen::OutputPtr) Q_DECLARE_METATYPE(QMLScreen*) QMLOutputComponent::QMLOutputComponent(QQmlEngine *engine, QMLScreen *parent): QQmlComponent(engine, parent), m_engine(engine) { loadUrl(QUrl("qrc:/qml/Output.qml")); } QMLOutputComponent::~QMLOutputComponent() { } QMLOutput* QMLOutputComponent::createForOutput(const KScreen::OutputPtr &output) { QObject *instance = beginCreate(m_engine->rootContext()); if (!instance) { qWarning() << errorString(); return nullptr; } bool success = instance->setProperty("outputPtr", QVariant::fromValue(qobject_cast(output))); Q_ASSERT(success); success = instance->setProperty("screen", QVariant::fromValue(qobject_cast(parent()))); Q_ASSERT(success); Q_UNUSED(success); completeCreate(); return qobject_cast(instance); } ukui-control-center/plugins/system/display/declarative/qmloutput.h0000644000175000017500000001272614201663716024605 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef QMLOUTPUT_H #define QMLOUTPUT_H #include #include class QStandardItemModel; class QAbstractItemModel; class ModesProxyModel; class QMLScreen; class QMLOutput : public QQuickItem { Q_OBJECT Q_PROPERTY(KScreen::Output *output READ output NOTIFY outputChanged) Q_PROPERTY(KScreen::OutputPtr outputPtr READ outputPtr WRITE setOutputPtr NOTIFY outputChanged) Q_PROPERTY(bool isCloneMode READ isCloneMode WRITE setIsCloneMode NOTIFY isCloneModeChanged) Q_PROPERTY(bool isCloneModeShow READ isCloneModeShow WRITE setIsCloneMode NOTIFY isCloneModeChanged) Q_PROPERTY(QMLScreen* screen READ screen WRITE setScreen NOTIFY screenChanged) Q_PROPERTY(QMLOutput* cloneOf READ cloneOf WRITE setCloneOf NOTIFY cloneOfChanged) Q_PROPERTY(QMLOutput* leftDockedTo READ leftDockedTo WRITE setLeftDockedTo RESET undockLeft NOTIFY leftDockedToChanged) Q_PROPERTY(QMLOutput* topDockedTo READ topDockedTo WRITE setTopDockedTo RESET undockTop NOTIFY topDockedToChanged) Q_PROPERTY(QMLOutput* rightDockedTo READ rightDockedTo WRITE setRightDockedTo RESET undockRight NOTIFY rightDockedToChanged) Q_PROPERTY(QMLOutput* bottomDockedTo READ bottomDockedTo WRITE setBottomDockedTo RESET undockBottom NOTIFY bottomDockedToChanged) Q_PROPERTY(int currentOutputHeight READ currentOutputHeight NOTIFY currentOutputSizeChanged) Q_PROPERTY(int currentOutputWidth READ currentOutputWidth NOTIFY currentOutputSizeChanged) /* Workaround for possible QML bug when calling output.pos.y = VALUE works, * but output.pos.x = VALUE has no effect */ Q_PROPERTY(int outputX READ outputX WRITE setOutputX NOTIFY outputXChanged) Q_PROPERTY(int outputY READ outputY WRITE setOutputY NOTIFY outputYChanged) public: enum { ModeRole = Qt::UserRole, ModeIdRole, SizeRole, RefreshRateRole }; explicit QMLOutput(QQuickItem *parent = nullptr); KScreen::Output *output() const; // For QML KScreen::OutputPtr outputPtr() const; void setOutputPtr(const KScreen::OutputPtr &output); QMLScreen *screen() const; void setScreen(QMLScreen *screen); QMLOutput *leftDockedTo() const; void setLeftDockedTo(QMLOutput *output); void undockLeft(); QMLOutput *topDockedTo() const; void setTopDockedTo(QMLOutput *output); void undockTop(); QMLOutput *rightDockedTo() const; void setRightDockedTo(QMLOutput *output); void undockRight(); QMLOutput *bottomDockedTo() const; void setBottomDockedTo(QMLOutput *output); void undockBottom(); Q_INVOKABLE bool collidesWithOutput(QObject *other); Q_INVOKABLE bool maybeSnapTo(QMLOutput *other); void setCloneOf(QMLOutput *other); QMLOutput *cloneOf() const; int currentOutputHeight() const; int currentOutputWidth() const; int outputX() const; void setOutputX(int x); int outputY() const; void setOutputY(int y); void setIsCloneMode(bool isCloneMode, bool cloneModeShow = false); bool isCloneMode() const; bool isCloneModeShow() const; void dockToNeighbours(); public Q_SLOTS: void updateRootProperties(); Q_SIGNALS: void changed(); void moved(const QString &self); /* Property notifications */ void outputChanged(); void screenChanged(); void cloneOfChanged(); void currentOutputSizeChanged(); void leftDockedToChanged(); void topDockedToChanged(); void rightDockedToChanged(); void bottomDockedToChanged(); void outputYChanged(); void outputXChanged(); void isCloneModeChanged(); private Q_SLOTS: void moved(); void currentModeIdChanged(); private: /** * Returns the biggest resolution available assuming it's the preferred one */ KScreen::ModePtr bestMode() const; KScreen::OutputPtr m_output; QMLScreen *m_screen; QMLOutput *m_cloneOf; QMLOutput *m_leftDock; QMLOutput *m_topDock; QMLOutput *m_rightDock; QMLOutput *m_bottomDock; bool m_isCloneMode; bool m_cloneModeShow; }; #endif // QMLOUTPUT_H ukui-control-center/plugins/system/display/declarative/qmloutputcomponent.h0000644000175000017500000000241314201663671026520 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef QMLOUTPUTCOMPONENT_H #define QMLOUTPUTCOMPONENT_H #include #include class QMLScreen; class QMLOutput; class QMLOutputComponent : public QQmlComponent { Q_OBJECT public: explicit QMLOutputComponent(QQmlEngine *engine, QMLScreen *parent); ~QMLOutputComponent() override; QMLOutput *createForOutput(const KScreen::OutputPtr &output); private: QQmlEngine *m_engine; }; #endif // QMLOUTPUTCOMPONENT_H ukui-control-center/plugins/system/display/display.h0000644000175000017500000000325014201663716021705 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef DISPLAYSET_H #define DISPLAYSET_H #include #include #include #include "shell/interface.h" #include "widget.h" namespace Ui { class DisplayWindow; } class DisplaySet : public QObject, CommonInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) public: DisplaySet(); ~DisplaySet(); QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; const QString name() const Q_DECL_OVERRIDE; private: void requestBackend(); private: Ui::DisplayWindow *ui; QString pluginName; int pluginType; Widget *pluginWidget; bool mFirstLoad; }; #endif // DISPLAYSET_H ukui-control-center/plugins/system/display/qml/0000755000175000017500000000000014201663716020660 5ustar fengfengukui-control-center/plugins/system/display/qml/Output.qml0000644000175000017500000001731114201663716022676 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ import QtQuick 2.1 import QtGraphicalEffects 1.0 import org.kde.kscreen 1.0 QMLOutput { id: root; signal clicked(); signal primaryTriggered(string self); signal enabledToggled(string self); signal mousePressed(); signal mouseReleased(bool isReleased); signal positionChanged(bool isReleased); signal rotationChanged(bool isReleased); signal widthChanged(bool isReleased); signal heightChanged(bool isReleased); property bool isDragged: monitorMouseArea.drag.active; property bool isDragEnabled: true; property bool isToggleButtonVisible: false; property bool hasMoved: false; width: monitorMouseArea.width; height: monitorMouseArea.height; visible: (opacity > 0 && ((isCloneMode && isCloneModeShow) || !isCloneMode)); opacity: output.connected ? 1.0 : 0.0; Component.onCompleted: { root.updateRootProperties(); } SystemPalette { id: palette; } MouseArea { id: monitorMouseArea; width: { if (output.rotation === KScreenOutput.None || output.rotation === KScreenOutput.Inverted) { return root.currentOutputWidth * screen.outputScale; } else { return root.currentOutputHeight * screen.outputScale; } } height: { if (output.rotation === KScreenOutput.None || output.rotation === KScreenOutput.Inverted) { return root.currentOutputHeight * screen.outputScale; } else { return root.currentOutputWidth * screen.outputScale; } } anchors.centerIn: parent; //是否激活时的透明度 opacity: root.output.enabled ? 1.0 : 0.3; transformOrigin: Item.Center; rotation: 0; hoverEnabled: true; preventStealing: true; drag { target: root.isDragEnabled && !root.isCloneMode ? root : null; axis: Drag.XandYAxis; minimumX: 0; maximumX: screen.maxScreenSize.width - root.width; minimumY: 0; maximumY: screen.maxScreenSize.height - root.height; filterChildren: false; } drag.onActiveChanged: { /* If the drag is shorter then the animation then make sure * we won't end up in an inconsistent state */ if (dragActiveChangedAnimation.running) { dragActiveChangedAnimation.complete(); } dragActiveChangedAnimation.running = true; } onPressed: root.clicked(); onReleased: root.mouseReleased(true) onRotationChanged: root.rotationChanged(false); onWidthChanged: root.widthChanged(false); onHeightChanged: root.heightChanged(false); /* FIXME: This could be in 'Behavior', but MouseArea had * some complaints...to tired to investigate */ PropertyAnimation { id: dragActiveChangedAnimation; target: monitor; property: "opacity"; from: monitorMouseArea.drag.active ? 0.7 : 1.0 to: monitorMouseArea.drag.active ? 1.0 : 0.7 duration: 100; easing.type: "OutCubic"; } Behavior on opacity { PropertyAnimation { property: "opacity"; easing.type: "OutCubic"; duration: 250; } } Behavior on rotation { RotationAnimation { easing.type: "OutCubic" duration: 250; direction: RotationAnimation.Shortest; } } Behavior on width { PropertyAnimation { property: "width"; easing.type: "OutCubic"; duration: 150; } } Behavior on height { PropertyAnimation { property: "height"; easing.type: "OutCubic"; duration: 150; } } Rectangle { id: monitor; anchors.fill: parent; //圆角 radius: 8; //是否点击到屏幕 color: root.focus? "#3D6BE5" : "#AEACAD"; smooth: true; clip: true; border { color: root.focus ? "#3498DB" : "#AED6F1"; width: 1; Behavior on color { PropertyAnimation { duration: 150; } } } Rectangle { id: posLabel; y: 4; x: 4; width: childrenRect.width + 5; height: childrenRect.height + 2; radius: 8; opacity: root.output.enabled && monitorMouseArea.drag.active ? 1.0 : 0.0; visible: opacity != 0.0; color: "#101010"; Text { id: posLabelText; text: root.outputX + "," + root.outputY; color: "white"; y: 2; x: 2; } } Item { //文字位置 y: ((parent.height - orientationPanel.height) / 2) - (implicitHeight / 2) anchors { left: parent.left; right: parent.right; leftMargin: 5; rightMargin: 5; } Text { id: labelVendor; text: if (root.isCloneMode) { return ("Unified Outputs"); } else { return root.output.name; } anchors { verticalCenter: parent.verticalCenter; left: parent.left; right: parent.right; } horizontalAlignment: Text.AlignHCenter; color: "#FFFFFF"; font.pixelSize: 12; elide: Text.ElideRight; } } } Item { id: orientationPanelContainer; anchors.fill: monitor; visible: false Rectangle { id: orientationPanel; height: 10; //底部颜色 color: palette.highlight ; smooth: true; Behavior on color { PropertyAnimation { duration: 150; } } } } OpacityMask { anchors.fill: orientationPanelContainer; source: orientationPanelContainer; maskSource: monitor; } } Behavior on opacity { PropertyAnimation { duration: 200; easing.type: "OutCubic"; } } } ukui-control-center/plugins/system/display/qml/main.qml0000644000175000017500000000350614201663671022323 0ustar fengfeng/* Copyright (C) 2012 Dan Vratil 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 2.1 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 Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ import QtQuick 2.1 import QtQuick.Controls 1.1 as Controls import org.kde.kscreen 1.0 Item { id: root; property variant virtualScreen: null; objectName: "root"; focus: true; SystemPalette { id: palette; } MouseArea { anchors.fill: parent; focus: true; Rectangle { id: background; anchors.fill: parent; focus: true; color: "transparent"; FocusScope { id: outputViewFocusScope; anchors.fill: parent; focus: true; QMLScreen { id: outputView; anchors.fill: parent; clip: true; objectName: "outputView"; } } Column { anchors { left: parent.left; bottom: parent.bottom; margins: 5; } spacing: 5; } } } } ukui-control-center/plugins/system/display/slider.cpp0000644000175000017500000000346114201663716022061 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "slider.h" #include #include #include #include Slider::Slider() : QSlider(Qt::Horizontal) { scaleList << "1.0" << "1.25" << "1.5" << "1.75" << "2.0"; this->setMinimumHeight(50); } void Slider::paintEvent(QPaintEvent *e) { QSlider::paintEvent(e); auto painter = new QPainter(this); painter->setPen(QPen(Qt::black)); auto rect = this->geometry(); int numTicks = (maximum() - minimum())/tickInterval(); QFontMetrics fontMetrics = QFontMetrics(this->font()); if (this->orientation() == Qt::Horizontal) { int fontHeight = fontMetrics.height(); for (int i = 0; i <= numTicks; i++) { int tickNum = minimum() + (tickInterval() * i); int tickX = (((rect.width()/numTicks) * i) - (fontMetrics.width(QString::number(tickNum))/2)); int tickY = rect.height()/2 + fontHeight + 2; painter->drawText(QPoint(tickX + 0.1, tickY), this->scaleList.at(i)); } } painter->end(); } ukui-control-center/plugins/system/display/displayperformancedialog.cpp0000644000175000017500000001603414201663716025646 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "displayperformancedialog.h" #include "ui_displayperformancedialog.h" #include "CloseButton/closebutton.h" #include #include #include #include #include #include #include #define ADVANCED_SCHEMAS "org.ukui.session.required-components" #define ADVANCED_KEY "windowmanager" #define WM_CHOOSER_CONF "/etc/kylin-wm-chooser/default.conf" #define WM_CHOOSER_CONF_TMP "/tmp/default.conf" extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); DisplayPerformanceDialog::DisplayPerformanceDialog(QWidget *parent) : QDialog(parent), ui(new Ui::DisplayPerformanceDialog) { ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); ui->titleLabel->setStyleSheet("QLabel{color: palette(windowText);}"); ui->label->setAlignment(Qt::AlignTop); ui->label_2->setAlignment(Qt::AlignTop); ui->label_3->setAlignment(Qt::AlignTop); ui->label_4->setAlignment(Qt::AlignTop); ui->label_5->setAlignment(Qt::AlignTop); ui->label_6->setAlignment(Qt::AlignTop); ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); const QByteArray id(ADVANCED_SCHEMAS); settings = new QGSettings(id); confSettings = new QSettings(WM_CHOOSER_CONF, QSettings::NativeFormat); setupComponent(); setupConnect(); initModeStatus(); initThresholdStatus(); } DisplayPerformanceDialog::~DisplayPerformanceDialog() { delete ui; ui = nullptr; delete settings; settings = nullptr; delete confSettings; confSettings = nullptr; } void DisplayPerformanceDialog::setupComponent(){ ui->performanceRadioBtn->setProperty("wm", "mutter"); ui->compatibleRadioBtn->setProperty("wm", "marco"); ui->autoRadioBtn->setProperty("wm", "kylin-wm-chooser"); } void DisplayPerformanceDialog::setupConnect(){ connect(ui->closeBtn, &CloseButton::clicked, [=]{ close(); }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->buttonGroup, static_cast(&QButtonGroup::buttonClicked), [=](QAbstractButton * button){ #else connect(ui->buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), [=](QAbstractButton * button){ #endif QString mode = button->property("wm").toString(); settings->set(ADVANCED_KEY, mode); }); connect(ui->autoRadioBtn, &QRadioButton::toggled, this, [=](bool checked){ ui->lineEdit->setEnabled(checked); ui->applyBtn->setEnabled(checked); ui->resetBtn->setEnabled(checked); }); connect(ui->applyBtn, &QPushButton::clicked, this, [=]{ changeConfValue(); }); connect(ui->resetBtn, &QPushButton::clicked, this, [=]{ ui->lineEdit->setText("256"); changeConfValue(); }); } void DisplayPerformanceDialog::initModeStatus(){ QString mode = settings->get(ADVANCED_KEY).toString(); if (mode == ui->performanceRadioBtn->property("wm").toString()){ ui->performanceRadioBtn->blockSignals(true); ui->performanceRadioBtn->setChecked(true); ui->performanceRadioBtn->blockSignals(false); } else if (mode == ui->compatibleRadioBtn->property("wm").toString()){ ui->compatibleRadioBtn->blockSignals(true); ui->compatibleRadioBtn->setChecked(true); ui->compatibleRadioBtn->blockSignals(false); } else{ ui->autoRadioBtn->blockSignals(true); ui->autoRadioBtn->setChecked(true); ui->autoRadioBtn->blockSignals(false); } } void DisplayPerformanceDialog::initThresholdStatus(){ confSettings->beginGroup("mutter"); QString value = confSettings->value("threshold").toString(); ui->lineEdit->blockSignals(true); ui->lineEdit->setText(value); ui->lineEdit->blockSignals(false); confSettings->endGroup(); } void DisplayPerformanceDialog::changeConfValue(){ if (!QFile::copy(WM_CHOOSER_CONF, WM_CHOOSER_CONF_TMP)) return; QSettings * tempSettings = new QSettings(WM_CHOOSER_CONF_TMP, QSettings::NativeFormat); tempSettings->beginGroup("mutter"); tempSettings->setValue("threshold", ui->lineEdit->text()); tempSettings->endGroup(); delete tempSettings; tempSettings = nullptr; //替换kylin-wm-chooser QDBusInterface * sysinterface = new QDBusInterface("com.control.center.qt.systemdbus", "/", "com.control.center.interface", QDBusConnection::systemBus()); if (!sysinterface->isValid()){ qCritical() << "Create Client Interface Failed When Copy Face File: " << QDBusConnection::systemBus().lastError(); return; } QString cmd = QString("mv %1 %2").arg(WM_CHOOSER_CONF_TMP).arg(WM_CHOOSER_CONF); QProcess::execute(cmd); delete sysinterface; sysinterface = nullptr; } void DisplayPerformanceDialog::paintEvent(QPaintEvent *event){ Q_UNUSED(event); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QPainterPath rectPath; rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); // 画一个黑底 QPixmap pixmap(this->rect().size()); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); // 模糊这个黑底 QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); pixmapPainter2.setRenderHint(QPainter::Antialiasing); pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); pixmapPainter2.setPen(Qt::transparent); pixmapPainter2.setBrush(Qt::transparent); pixmapPainter2.drawPath(rectPath); // 绘制阴影 p.drawPixmap(this->rect(), pixmap, pixmap.rect()); // 绘制一个背景 p.save(); p.fillPath(rectPath,palette().color(QPalette::Base)); p.restore(); } ukui-control-center/plugins/system/display/resolutionslider.h0000644000175000017500000000326314201663716023652 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef RESOLUTIONSLIDER_H #define RESOLUTIONSLIDER_H #include #include #include class QSlider; class QLabel; class QComboBox; class QStyledItemDelegate; class ResolutionSlider : public QWidget { Q_OBJECT public: explicit ResolutionSlider(const KScreen::OutputPtr &output, QWidget *parent = nullptr); ~ResolutionSlider() override; QSize currentResolution() const; QSize getMaxResolution() const; void setResolution(const QSize &size); Q_SIGNALS: void resolutionChanged(const QSize &size, bool emitFlag = true); void resolutionsave(const QSize &size); public Q_SLOTS: void slotValueChanged(int); void slotOutputModeChanged(); private: void init(); private: KScreen::OutputPtr mOutput; QList mModes; QList mExcludeModes; QComboBox *mComboBox = nullptr; bool mIsWayland = false; }; #endif // RESOLUTIONSLIDER_H ukui-control-center/plugins/system/display/unifiedoutputconfig.cpp0000644000175000017500000003140214201663716024665 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "unifiedoutputconfig.h" #include "resolutionslider.h" #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool operator<(const QSize &s1, const QSize &s2) { return s1.width() * s1.height() < s2.width() * s2.height(); } template<> bool qMapLessThanKey(const QSize &s1, const QSize &s2) { return s1 < s2; } UnifiedOutputConfig::UnifiedOutputConfig(const KScreen::ConfigPtr &config, QWidget *parent) : OutputConfig(parent), mConfig(config) { } UnifiedOutputConfig::~UnifiedOutputConfig() { } void UnifiedOutputConfig::setOutput(const KScreen::OutputPtr &output) { mOutput = output; mClones.clear(); mClones.reserve(mOutput->clones().count()); Q_FOREACH (int id, mOutput->clones()) { mClones << mConfig->output(id); } mClones << mOutput; OutputConfig::setOutput(output); } void UnifiedOutputConfig::initUi() { QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setContentsMargins(0, 0, 0, 0); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); KScreen::OutputPtr fakeOutput = createFakeOutput(); mResolution = new ResolutionSlider(fakeOutput, this); mResolution->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); mResolution->setMinimumSize(402, 30); connect(mOutput.data(), &KScreen::Output::currentModeIdChanged, this, &UnifiedOutputConfig::slotRestoreResoltion); connect(mOutput.data(), &KScreen::Output::rotationChanged, this, &UnifiedOutputConfig::slotRestoreRatation); QLabel *resLabel = new QLabel(this); resLabel->setText(tr("resolution")); resLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); resLabel->setMinimumSize(118, 30); resLabel->setMaximumSize(118, 30); QHBoxLayout *resLayout = new QHBoxLayout(); resLayout->addWidget(resLabel); resLayout->addWidget(mResolution); QFrame *resFrame = new QFrame(this); resFrame->setFrameShape(QFrame::Shape::Box); resFrame->setLayout(resLayout); resFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); resFrame->setMinimumSize(552, 50); resFrame->setMaximumSize(960, 50); vbox->addWidget(resFrame); connect(mResolution, &ResolutionSlider::resolutionChanged, this, &UnifiedOutputConfig::slotResolutionChanged); // 方向下拉框 mRotation = new QComboBox(this); mRotation->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); mRotation->setMinimumSize(402, 30); mRotation->setMaximumSize(16777215, 30); QLabel *rotateLabel = new QLabel(this); rotateLabel->setText(tr("orientation")); rotateLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); rotateLabel->setMinimumSize(118, 30); rotateLabel->setMaximumSize(118, 30); mRotation->addItem(tr("arrow-up"), KScreen::Output::None); mRotation->addItem(tr("90° arrow-right"), KScreen::Output::Right); mRotation->addItem(tr("arrow-down"), KScreen::Output::Inverted); mRotation->addItem(tr("90° arrow-left"), KScreen::Output::Left); int index = mRotation->findData(mOutput->rotation()); mRotation->setCurrentIndex(index); connect(mRotation, static_cast(&QComboBox::currentIndexChanged), this, &UnifiedOutputConfig::slotRotationChangedDerived); QHBoxLayout *roatateLayout = new QHBoxLayout(); roatateLayout->addWidget(rotateLabel); roatateLayout->addWidget(mRotation); QFrame *rotateFrame = new QFrame(this); rotateFrame->setFrameShape(QFrame::Shape::Box); rotateFrame->setLayout(roatateLayout); rotateFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); rotateFrame->setMinimumSize(552, 50); rotateFrame->setMaximumSize(960, 50); vbox->addWidget(rotateFrame); // 统一输出刷新率下拉框 mRefreshRate = new QComboBox(this); mRefreshRate->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); mRefreshRate->setMinimumSize(402, 30); mRefreshRate->setMaximumSize(16777215, 30); QLabel *freshLabel = new QLabel(this); freshLabel->setText(tr("frequency")); freshLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); freshLabel->setMinimumSize(118, 30); freshLabel->setMaximumSize(118, 30); mRefreshRate->addItem(tr("auto"), -1); QHBoxLayout *freshLayout = new QHBoxLayout(); freshLayout->addWidget(freshLabel); freshLayout->addWidget(mRefreshRate); QFrame *freshFrame = new QFrame(this); freshFrame->setFrameShape(QFrame::Shape::Box); freshFrame->setLayout(freshLayout); vbox->addWidget(freshFrame); freshFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); freshFrame->setMinimumSize(552, 50); freshFrame->setMaximumSize(960, 50); slotResolutionChanged(mResolution->currentResolution()); connect(mRefreshRate, static_cast(&QComboBox::activated), this, &UnifiedOutputConfig::slotRefreshRateChanged); QObject::connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, [&](KScreen::ConfigOperation *op) { KScreen::ConfigPtr sConfig = qobject_cast(op)->config(); KScreen::OutputPtr sOutput = sConfig -> primaryOutput(); for (int i = 0; i < mRefreshRate->count(); ++i) { if (!sOutput.isNull() && !sOutput->currentMode().isNull() && mRefreshRate->itemText(i) == tr("%1 Hz").arg(QLocale().toString(sOutput->currentMode()->refreshRate()))) { mRefreshRate->setCurrentIndex(i); } } }); } KScreen::OutputPtr UnifiedOutputConfig::createFakeOutput() { // Find set of common resolutions QMap commonSizes; Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { QList processedSizes; Q_FOREACH (const KScreen::ModePtr &mode, clone->modes()) { // Make sure we don't count some modes multiple times because of different // refresh rates if (processedSizes.contains(mode->size())) { continue; } processedSizes << mode->size(); if (commonSizes.contains(mode->size())) { commonSizes[mode->size()]++; } else { commonSizes.insert(mode->size(), 1); } } } KScreen::OutputPtr fakeOutput(new KScreen::Output); // This will give us list of resolution that are shared by all outputs QList commonResults = commonSizes.keys(mClones.count()); // If there are no common resolution, fallback to smallest preferred mode if (commonResults.isEmpty()) { QSize smallestMode; Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { if (!smallestMode.isValid() || clone->preferredMode()->size() < smallestMode) { smallestMode = clone->preferredMode()->size(); } } commonResults << smallestMode; } std::sort(commonResults.begin(), commonResults.end()); KScreen::ModeList modes; Q_FOREACH (const QSize &size, commonResults) { KScreen::ModePtr mode(new KScreen::Mode); mode->setSize(size); mode->setId(Utils::sizeToString(size)); mode->setName(mode->id()); modes.insert(mode->id(), mode); } fakeOutput->setModes(modes); if (!mOutput->currentModeId().isEmpty()) { fakeOutput->setCurrentModeId(Utils::sizeToString(mOutput->currentMode()->size())); } else { fakeOutput->setCurrentModeId(Utils::sizeToString(commonResults.last())); } return fakeOutput; } void UnifiedOutputConfig::slotResolutionChanged(const QSize &size) { // Ignore disconnected outputs if (!size.isValid()) { return; } QVectorVrefresh; for (int i = mRefreshRate->count(); i >= 0; --i) { mRefreshRate->removeItem(i); } Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { const QString &id = findBestMode(clone, size); if (id.isEmpty()) { // FIXME: Error? return; } clone->setCurrentModeId(id); clone->setPos(QPoint(0, 0)); QList modes; Q_FOREACH (const KScreen::ModePtr &mode, clone->modes()) { if (mode->size() == size) { modes << mode; } } QVectorVrefreshTemp; for (int i = 0, total = modes.count(); i < total; ++i) { const KScreen::ModePtr mode = modes.at(i); bool alreadyExisted = false; //判断该显示器的刷新率是否有重复的,确保同一刷新率在一个屏幕上只出现一次 for (int j = 0; j < VrefreshTemp.size(); ++j) { if (tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())) == VrefreshTemp[j]) { alreadyExisted = true; break; } } if (alreadyExisted == false) { //不添加重复的项 VrefreshTemp.append(tr("%1 Hz").arg(QLocale().toString(mode->refreshRate()))); } } for (int i = 0; i < VrefreshTemp.size(); ++i) { Vrefresh.append(VrefreshTemp[i]); } } for (int i = 0; i < Vrefresh.size(); ++i) { if (Vrefresh.count(Vrefresh[i]) == mClones.size()) { //该刷新率出现次数等于屏幕数,即每个屏幕都有该刷新率 bool existFlag = false; for (int j = 0; j < mRefreshRate->count(); ++j) { //已经存在就不再添加 if (Vrefresh[i] == mRefreshRate->itemText(j)) { existFlag = true; break; } } if (existFlag == false) { //不存在添加到容器中 mRefreshRate->addItem(Vrefresh[i]); } } } if (mRefreshRate->count() == 0) { mRefreshRate->addItem(tr("auto"), -1); } Q_EMIT changed(); } void UnifiedOutputConfig::slotRefreshRateChanged(int index) { if (index == 0) { index = 1; } Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { Q_FOREACH (const KScreen::ModePtr &mode, clone->modes()) { if (mode->size() == mResolution->currentResolution() && \ tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())) == mRefreshRate->itemText(index)) { clone->setCurrentModeId(mode->id()); } } } } QString UnifiedOutputConfig::findBestMode(const KScreen::OutputPtr &output, const QSize &size) { float refreshRate = 0; QString id; Q_FOREACH (const KScreen::ModePtr &mode, output->modes()) { if (mode->size() == size && mode->refreshRate() > refreshRate) { refreshRate = mode->refreshRate(); id = mode->id(); } } return id; } // 统一输出方向信号改变 void UnifiedOutputConfig::slotRotationChangedDerived(int index) { KScreen::Output::Rotation rotation = static_cast(mRotation->itemData(index).toInt()); Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { if (clone->isConnected() && clone->isEnabled()) { clone->blockSignals(true); clone->setRotation(rotation); clone->setPos(QPoint(0, 0)); clone->blockSignals(false); } } Q_EMIT changed(); } void UnifiedOutputConfig::slotRestoreResoltion() { if (!mOutput->currentMode().isNull() && !(mResolution->currentResolution() == mOutput->currentMode()->size())) { mResolution->setResolution(mOutput->currentMode()->size()); } } void UnifiedOutputConfig::slotRestoreRatation() { mRotation->blockSignals(true); mRotation->setCurrentIndex(mRotation->findData(mOutput->rotation())); mRotation->blockSignals(false); } ukui-control-center/plugins/system/display/display.pro0000644000175000017500000000306414201663716022261 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2019-02-20T15:36:43 # #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/closebutton.pri) include($$PROJECT_COMPONENTSOURCE/label.pri) include($$PROJECT_COMPONENTSOURCE/uslider.pri) QT += widgets core gui quickwidgets quick xml KScreen dbus concurrent TEMPLATE = lib CONFIG += c++11 link_pkgconfig plugin TARGET = $$qtLibraryTarget(display) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} INSTALLS += target INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt PKGCONFIG += gsettings-qt \ SOURCES += \ brightnessFrame.cpp \ display.cpp \ declarative/qmloutput.cpp \ declarative/qmloutputcomponent.cpp \ declarative/qmlscreen.cpp \ controlpanel.cpp \ outputconfig.cpp \ resolutionslider.cpp \ unifiedoutputconfig.cpp \ utils.cpp \ widget.cpp \ displayperformancedialog.cpp HEADERS += \ brightnessFrame.h \ colorinfo.h \ display.h \ declarative/qmloutput.h \ declarative/qmloutputcomponent.h \ declarative/qmlscreen.h \ controlpanel.h \ outputconfig.h \ resolutionslider.h \ scalesize.h \ unifiedoutputconfig.h \ utils.h \ widget.h \ displayperformancedialog.h FORMS += \ display.ui \ displayperformancedialog.ui RESOURCES += \ qml.qrc ukui-control-center/plugins/system/display/display.cpp0000644000175000017500000000501414201663716022240 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 of the License, 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include "display.h" #include "ui_display.h" #include #include #include #include #include DisplaySet::DisplaySet() : mFirstLoad(true) { pluginName = tr("Display"); pluginType = SYSTEM; } DisplaySet::~DisplaySet() { } QWidget *DisplaySet::get_plugin_ui() { if (mFirstLoad) { requestBackend(); mFirstLoad = false; pluginWidget = new Widget; QObject::connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, [&](KScreen::ConfigOperation *op) { pluginWidget->setConfig(qobject_cast(op)->config(), true); }); } return pluginWidget; } QString DisplaySet::get_plugin_name() { return pluginName; } int DisplaySet::get_plugin_type() { return pluginType; } void DisplaySet::plugin_delay_control() { } const QString DisplaySet::name() const { return QStringLiteral("display"); } void DisplaySet::requestBackend() { QDBusInterface screenIft("org.kde.KScreen", "/", "org.kde.KScreen", QDBusConnection::sessionBus()); if (!screenIft.isValid()) { QProcess process; process.start("uname -m"); process.waitForFinished(); QString output = process.readAll(); output = output.simplified(); QString command = "/usr/lib/" + output + "-linux-gnu" +"/libexec/kf5/kscreen_backend_launcher"; QProcess::startDetached(command); } } ukui-control-center/plugins/system/display/widget.h0000644000175000017500000001574314201663716021535 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef WIDGET_H #define WIDGET_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "outputconfig.h" #include "SwitchButton/switchbutton.h" #include "brightnessFrame.h" #include "screenConfig.h" class QLabel; class QMLOutput; class QMLScreen; class ControlPanel; class PrimaryOutputCombo; class QPushButton; class QComboBox; class QQuickView; class QQuickWidget; class QStyledItemDelegate; typedef enum { SUN, CUSTOM, }MODE; namespace KScreen { class ConfigOperation; } namespace Ui { class DisplayWindow; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget() override; void setConfig(const KScreen::ConfigPtr &config, bool showBrightnessFrameFlag = false); KScreen::ConfigPtr currentConfig() const; void initConnection(); QString getScreenName(QString name = ""); void initTemptSlider(); bool writeFile(const QString &filePath); void writeGlobal(const KScreen::OutputPtr &output); bool writeGlobalPart(const KScreen::OutputPtr &output, QVariantMap &info, const KScreen::OutputPtr &fallback); QString globalFileName(const QString &hash); QVariantMap getGlobalData(KScreen::OutputPtr output); float converToScale(const int value); int scaleToSlider(const float value); void initUiComponent(); void setScreenKDS(QString kdsConfig); void setActiveScreen(QString status = ""); void addBrightnessFrame(QString name, bool openFlag, QString edidHash); void showBrightnessFrame(const int flag = 0); QList getPreScreenCfg(); void setPreScreenCfg(KScreen::OutputList screens); void changescale(); QDBusInterface *dbusEdid = nullptr; protected: bool eventFilter(QObject *object, QEvent *event) override; Q_SIGNALS: void changed(); void nightModeChanged(const bool nightMode) const; void redShiftValidChanged(const bool isValid) const; private Q_SLOTS: void slotFocusedOutputChanged(QMLOutput *output); void slotOutputEnabledChanged(); void slotOutputConnectedChanged(); void slotUnifyOutputs(); void slotIdentifyButtonClicked(bool checked = true); void slotIdentifyOutputs(KScreen::ConfigOperation *op); void clearOutputIdentifiers(); void outputAdded(const KScreen::OutputPtr &output, bool connectChanged); void outputRemoved(int outputId, bool connectChanged); void primaryOutputSelected(int index); void primaryOutputChanged(const KScreen::OutputPtr &output); void showNightWidget(bool judge); void showCustomWiget(int index); void slotThemeChanged(bool judge); void primaryButtonEnable(bool); // 按钮选择主屏确认按钮 void mainScreenButtonSelect(int index); // 是否禁用设置主屏按钮 void checkOutputScreen(bool judge); // 是否禁用屏幕 void setNightMode(const bool nightMode); // 设置夜间模式 void initNightStatus(); // 初始化夜间模式 void nightChangedSlot(QHash nightArg); void callMethod(QRect geometry, QString name);// 设置wayland主屏幕 QString getPrimaryWaylandScreen(); void isWayland(); void kdsScreenchangeSlot(QString status); void applyNightModeSlot(); void delayApply(); public Q_SLOTS: void save(); void scaleChangedSlot(double scale); void changedSlot(); void propertiesChangedSlot(QString, QMap, QStringList); private: void loadQml(); void resetPrimaryCombo(); void addOutputToPrimaryCombo(const KScreen::OutputPtr &output); KScreen::OutputPtr findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info); void setHideModuleInfo(); void setTitleLabel(); void writeScale(double scale); void initGSettings(); void setcomBoxScale(); void initNightUI(); bool isRestoreConfig(); // 是否恢复应用之前的配置 bool isCloneMode(); bool isBacklight(); bool isLaptopScreen(); bool isVisibleBrightness(); QString getCpuInfo(); QString getMonitorType(); int getPrimaryScreenID(); void setScreenIsApply(bool isApply); private: Ui::DisplayWindow *ui; QMLScreen *mScreen = nullptr; KScreen::ConfigPtr mConfig = nullptr; KScreen::ConfigPtr mPrevConfig = nullptr; ControlPanel *mControlPanel = nullptr; OutputConfig *mOutputConfig = nullptr; // 设置主显示器相关控件 QList mOutputIdentifiers; QTimer *mOutputTimer = nullptr; QString mCPU; QString mDir; QStringList mPowerKeys; SwitchButton *mNightButton = nullptr; SwitchButton *mCloseScreenButton = nullptr; SwitchButton *mUnifyButton = nullptr; SwitchButton *mThemeButton = nullptr; QLabel *nightLabel = nullptr; QGSettings *mGsettings = nullptr; QGSettings *scaleGSettings = nullptr; QGSettings *mPowerGSettings = nullptr; QSettings *mQsettings = nullptr; QButtonGroup *singleButton; QSharedPointer mUPowerInterface; QSharedPointer mUkccInterface; QHash mNightConfig; double mScreenScale = 1.0; double scaleres = 1.0; QSize mScaleSizeRes = QSize(); bool mIsNightMode = false; bool mRedshiftIsValid = false; bool mIsScaleChanged = false; bool mOriApply; bool mConfigChanged = false; bool mOnBattery = false; bool mBlockChanges = false; bool mFirstLoad = true; bool mIsWayland = false; bool mIsBattery = false; bool mIsScreenAdd = false; bool mIsRestore = false; bool mIsSCaleRes = false; bool mIsChange = false; QString firstAddOutputName; QShortcut *mApplyShortcut; QVector BrightnessFrameV; //BrightnessFrame *currentBrightnessFrame; bool exitFlag = false; QString mKDSCfg; bool unifySetconfig = false; }; #endif // WIDGET_H ukui-control-center/plugins/system/display/colorinfo.h0000644000175000017500000000262614201663716022240 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef COLORINFO_H #define COLORINFO_H #include #include #include #include struct ColorInfo { QString arg; QDBusVariant out; }; QDBusArgument &operator<<(QDBusArgument &argument, const ColorInfo &mystruct) { argument.beginStructure(); argument << mystruct.arg << mystruct.out; argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, ColorInfo &mystruct) { argument.beginStructure(); argument >> mystruct.arg >> mystruct.out; argument.endStructure(); return argument; } Q_DECLARE_METATYPE(ColorInfo) #endif // COLORINFO_H ukui-control-center/plugins/system/display/resolutionslider.cpp0000644000175000017500000001143114201663716024201 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "resolutionslider.h" #include "utils.h" #include "scalesize.h" #include #include #include #include #include #include #include #include static bool sizeLessThan(const QSize &sizeA, const QSize &sizeB) { return sizeA.width() * sizeA.height() < sizeB.width() * sizeB.height(); } ResolutionSlider::ResolutionSlider(const KScreen::OutputPtr &output, QWidget *parent) : QWidget(parent), mOutput(output) { QString sessionType = getenv("XDG_SESSION_TYPE"); if (sessionType.compare("wayland", Qt::CaseSensitive)) { mExcludeModes.push_back(QSize(1152, 864)); } connect(output.data(), &KScreen::Output::currentModeIdChanged, this, &ResolutionSlider::slotOutputModeChanged); connect(output.data(), &KScreen::Output::modesChanged, this, &ResolutionSlider::init); init(); } ResolutionSlider::~ResolutionSlider() { } void ResolutionSlider::init() { this->setMinimumSize(402, 30); this->setMaximumSize(1677215, 30); mModes.clear(); Q_FOREACH (const KScreen::ModePtr &mode, mOutput->modes()) { if (mModes.contains(mode->size()) || mode->size().width() * mode->size().height() < 1024 * 768 || mExcludeModes.contains(mode->size()) || mode->size().width() < 1024) { continue; } mModes << mode->size(); } std::sort(mModes.begin(), mModes.end(), sizeLessThan); delete layout(); delete mComboBox; mComboBox = nullptr; QGridLayout *layout = new QGridLayout(this); // Avoid double margins layout->setContentsMargins(0, 0, 0, 0); if (!mModes.empty()) { std::reverse(mModes.begin(), mModes.end()); mComboBox = new QComboBox(this); mComboBox->setMinimumSize(402, 30); mComboBox->setMaximumSize(1677215, 30); int currentModeIndex = -1; int preferredModeIndex = -1; Q_FOREACH (const QSize &size, mModes) { #ifdef __sw_64__ if (size.width() < int(1920)) { continue; } #endif mComboBox->addItem(Utils::sizeToString(size)); if (mOutput->currentMode() && (mOutput->currentMode()->size() == size)) { currentModeIndex = mComboBox->count() - 1; } else if (mOutput->preferredMode() && (mOutput->preferredMode()->size() == size)) { preferredModeIndex = mComboBox->count() - 1; } } if (currentModeIndex != -1) { mComboBox->setCurrentIndex(currentModeIndex); } else if (preferredModeIndex != -1) { mComboBox->setCurrentIndex(preferredModeIndex); } layout->addWidget(mComboBox, 0, 0, 1, 1); connect(mComboBox, static_cast(&QComboBox::currentIndexChanged), this, &ResolutionSlider::slotValueChanged, Qt::UniqueConnection); Q_EMIT resolutionChanged(mModes.at(mComboBox->currentIndex()), false); } } QSize ResolutionSlider::currentResolution() const { if (mModes.isEmpty()) { return QSize(); } if (mModes.size() < 2) { return mModes.first(); } const int i = mComboBox->currentIndex(); return i > -1 ? mModes.at(i) : QSize(); } QSize ResolutionSlider::getMaxResolution() const { if (mModes.isEmpty()) { return QSize(); } return mModes.first(); } void ResolutionSlider::setResolution(const QSize &size) { mComboBox->blockSignals(true); mComboBox->setCurrentIndex(mModes.indexOf(size)); mComboBox->blockSignals(false); } void ResolutionSlider::slotOutputModeChanged() { if (!mOutput->currentMode()) { return; } if (mComboBox) { mComboBox->blockSignals(true); mComboBox->setCurrentIndex(mModes.indexOf(mOutput->currentMode()->size())); mComboBox->blockSignals(false); } } void ResolutionSlider::slotValueChanged(int value) { const QSize &size = mModes.at(value); Q_EMIT resolutionChanged(size); } ukui-control-center/plugins/system/display/utils.cpp0000644000175000017500000000231014201663716021727 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "utils.h" #include #include #include "../../../shell/utils/utils.h" QString Utils::outputName(const KScreen::OutputPtr &output) { return output->name(); } QString Utils::outputName(const KScreen::Output *output) { return kOutput.at(output->type()); } QString Utils::sizeToString(const QSize &size) { return QStringLiteral("%1x%2").arg(size.width()).arg(size.height()); } ukui-control-center/plugins/system/display/utils.h0000644000175000017500000000253214201663716021402 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef KSCREEN_KCM_UTILS_H #define KSCREEN_KCM_UTILS_H #include #include #include #include #include const QStringList kOutput { "Unknown", "VGA", "DVI", "DVII", "DVIA", "DVID", "HDMI", "eDP-1", "TV", "TVComposite", "TVSVideo", "TVComponent", "TVSCART", "TVC4", "DP-1" }; namespace Utils { QString outputName(const KScreen::Output *output); QString outputName(const KScreen::OutputPtr &output); QString sizeToString(const QSize &size); } #endif ukui-control-center/plugins/system/display/unifiedoutputconfig.h0000644000175000017500000000327014201663716024334 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef UNIFIEDOUTPUTCONFIG_H #define UNIFIEDOUTPUTCONFIG_H #include "outputconfig.h" namespace KScreen { class Output; class Config; } class UnifiedOutputConfig : public OutputConfig { Q_OBJECT public: explicit UnifiedOutputConfig(const KScreen::ConfigPtr &config, QWidget *parent); ~UnifiedOutputConfig() override; void setOutput(const KScreen::OutputPtr &output) override; private Q_SLOTS: void slotResolutionChanged(const QSize &size); // 统一输出后调整屏幕方向统一代码 void slotRotationChangedDerived(int index); void slotRestoreResoltion(); void slotRestoreRatation(); void slotRefreshRateChanged(int index); private: void initUi() override; KScreen::OutputPtr createFakeOutput(); QString findBestMode(const KScreen::OutputPtr &output, const QSize &size); private: KScreen::ConfigPtr mConfig; QList mClones; }; #endif // UNIFIEDOUTPUTCONFIG_H ukui-control-center/plugins/system/display/screenConfig.h0000644000175000017500000000323514201663716022650 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SCREENCONFIG_H #define SCREENCONFIG_H #include #include struct ScreenConfig { QString screenId; QString screenModeId; int screenPosX; int screenPosY; friend QDBusArgument &operator<<(QDBusArgument &argument, const ScreenConfig &screenStruct) { argument.beginStructure(); argument << screenStruct.screenId << screenStruct.screenModeId << screenStruct.screenPosX << screenStruct.screenPosY; argument.endStructure(); return argument; } friend const QDBusArgument &operator>>(const QDBusArgument &argument, ScreenConfig &screenStruct) { argument.beginStructure(); argument >> screenStruct.screenId >> screenStruct.screenModeId >> screenStruct.screenPosX >> screenStruct.screenPosY; argument.endStructure(); return argument; } }; Q_DECLARE_METATYPE(ScreenConfig) #endif // SCREENCONFIG_H ukui-control-center/plugins/system/display/widget.cpp0000644000175000017500000021064714205370757022074 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "widget.h" #include "controlpanel.h" #include "declarative/qmloutput.h" #include "declarative/qmlscreen.h" #include "utils.h" #include "ui_display.h" #include "displayperformancedialog.h" #include "colorinfo.h" #include "scalesize.h" #include "../../../shell/utils/utils.h" #include "../../../shell/mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef signals #undef signals #endif #define QML_PATH "kcm_kscreen/qml/" #define UKUI_CONTORLCENTER_PANEL_SCHEMAS "org.ukui.control-center.panel.plugins" #define THEME_NIGHT_KEY "themebynight" #define FONT_RENDERING_DPI "org.ukui.SettingsDaemon.plugins.xsettings" #define SCALE_KEY "scaling-factor" #define MOUSE_SIZE_SCHEMAS "org.ukui.peripherals-mouse" #define CURSOR_SIZE_KEY "cursor-size" #define POWER_SCHMES "org.ukui.power-manager" #define POWER_KEY "brightness-ac" #define ADVANCED_SCHEMAS "org.ukui.session.required-components" #define ADVANCED_KEY "windowmanager" const QString kCpu = "ZHAOXIN"; const QString kLoong = "Loongson"; const QString tempDayBrig = "6500"; Q_DECLARE_METATYPE(KScreen::OutputPtr) Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::DisplayWindow()) { dbusEdid = new QDBusInterface("org.kde.KScreen", "/backend", "org.kde.kscreen.Backend", QDBusConnection::sessionBus()); qRegisterMetaType(); ui->setupUi(this); ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); ui->quickWidget->setContentsMargins(0, 0, 0, 9); firstAddOutputName = ""; mCloseScreenButton = new SwitchButton(this); ui->showScreenLayout->addWidget(mCloseScreenButton); mUnifyButton = new SwitchButton(this); ui->unionLayout->addWidget(mUnifyButton); qDBusRegisterMetaType(); setHideModuleInfo(); initNightUI(); isWayland(); QProcess *process = new QProcess; process->start("lsb_release -r"); process->waitForFinished(); QByteArray ba = process->readAllStandardOutput(); QString osReleaseCrude = QString(ba.data()); QStringList res = osReleaseCrude.split(":"); QString osRelease = res.length() >= 2 ? res.at(1) : ""; osRelease = osRelease.simplified(); const QByteArray idd(ADVANCED_SCHEMAS); if (QGSettings::isSchemaInstalled(idd) && osRelease == "V10") { ui->advancedBtn->show(); ui->advancedHorLayout->setContentsMargins(9, 8, 9, 32); } else { ui->advancedBtn->hide(); ui->advancedHorLayout->setContentsMargins(9, 0, 9, 0); } setTitleLabel(); initGSettings(); initTemptSlider(); initUiComponent(); initNightStatus(); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) ui->nightframe->setVisible(false); #else ui->nightframe->setVisible(this->mRedshiftIsValid); #endif mNightButton->setChecked(this->mIsNightMode); showNightWidget(mNightButton->isChecked()); initConnection(); loadQml(); connect(ui->scaleCombo, static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ scaleChangedSlot(ui->scaleCombo->itemData(index).toDouble()); }); connect(scaleGSettings,&QGSettings::changed,this,[=](QString key){ if (!key.compare("scalingFactor", Qt::CaseSensitive)) { double scale = scaleGSettings->get(key).toDouble(); if (ui->scaleCombo->findData(scale) == -1) { scale = 1.0; } ui->scaleCombo->blockSignals(true); ui->scaleCombo->setCurrentText(QString::number(scale * 100) + "%"); ui->scaleCombo->blockSignals(false); } }); } Widget::~Widget() { clearOutputIdentifiers(); delete ui; ui = nullptr; } bool Widget::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::Resize) { if (mOutputIdentifiers.contains(qobject_cast(object))) { QResizeEvent *e = static_cast(event); const QRect screenSize = object->property("screenSize").toRect(); QRect geometry(QPoint(0, 0), e->size()); geometry.moveCenter(screenSize.center()); static_cast(object)->setGeometry(geometry); // Pass the event further } } return QObject::eventFilter(object, event); } void Widget::setConfig(const KScreen::ConfigPtr &config, bool showBrightnessFrameFlag) { if (mConfig) { KScreen::ConfigMonitor::instance()->removeConfig(mConfig); for (const KScreen::OutputPtr &output : mConfig->outputs()) { output->disconnect(this); } mConfig->disconnect(this); } mConfig = config; mPrevConfig = config->clone(); KScreen::ConfigMonitor::instance()->addConfig(mConfig); resetPrimaryCombo(); changescale(); connect(mConfig.data(), &KScreen::Config::outputAdded, this, [=](const KScreen::OutputPtr &output){ outputAdded(output, false); }); connect(mConfig.data(), &KScreen::Config::outputRemoved, this, [=](int outputId){ outputRemoved(outputId, false); }); connect(mConfig.data(), &KScreen::Config::primaryOutputChanged, this, &Widget::primaryOutputChanged); for (const KScreen::OutputPtr &output : mConfig->outputs()) { if (output->isConnected()) { connect(output.data(), &KScreen::Output::currentModeIdChanged, this, [=]() { if (output->currentMode()) { if (ui->scaleCombo) { changescale(); } } }); } } // 上面屏幕拿取配置 mScreen->setConfig(mConfig); mControlPanel->setConfig(mConfig); mUnifyButton->setEnabled(mConfig->connectedOutputs().count() > 1); ui->unionframe->setVisible(mConfig->outputs().count() > 1); for (const KScreen::OutputPtr &output : mConfig->outputs()) { if (false == unifySetconfig) { outputAdded(output, false); } else { //解决统一输出之后connect信号不再触发的问题 connect(output.data(), &KScreen::Output::isConnectedChanged, this, &Widget::slotOutputConnectedChanged); connect(output.data(), &KScreen::Output::isEnabledChanged, this, &Widget::slotOutputEnabledChanged); } } unifySetconfig = false; // 择主屏幕输出 QMLOutput *qmlOutput = mScreen->primaryOutput(); if (qmlOutput) { mScreen->setActiveOutput(qmlOutput); } else { if (!mScreen->outputs().isEmpty()) { mScreen->setActiveOutput(mScreen->outputs().at(0)); // 择一个主屏幕,避免闪退现象 primaryButtonEnable(true); } } slotOutputEnabledChanged(); if (mFirstLoad) { if (isCloneMode()) { mUnifyButton->blockSignals(true); mUnifyButton->setChecked(true); mUnifyButton->blockSignals(false); slotUnifyOutputs(); } } mFirstLoad = false; if (showBrightnessFrameFlag == true) { showBrightnessFrame(); //初始化的时候,显示 } } KScreen::ConfigPtr Widget::currentConfig() const { return mConfig; } void Widget::loadQml() { qmlRegisterType("org.kde.kscreen", 1, 0, "QMLOutput"); qmlRegisterType("org.kde.kscreen", 1, 0, "QMLScreen"); qmlRegisterType("org.kde.kscreen", 1, 0, "KScreenOutput"); qmlRegisterType("org.kde.kscreen", 1, 0, "KScreenEdid"); qmlRegisterType("org.kde.kscreen", 1, 0, "KScreenMode"); ui->quickWidget->setSource(QUrl("qrc:/qml/main.qml")); QQuickItem *rootObject = ui->quickWidget->rootObject(); mScreen = rootObject->findChild(QStringLiteral("outputView")); connect(mScreen, &QMLScreen::released, this, [=]() { delayApply(); }); if (!mScreen) { return; } connect(mScreen, &QMLScreen::focusedOutputChanged, this, &Widget::slotFocusedOutputChanged); } void Widget::resetPrimaryCombo() { // Don't emit currentIndexChanged when resetting bool blocked = ui->primaryCombo->blockSignals(true); ui->primaryCombo->clear(); ui->primaryCombo->blockSignals(blocked); if (!mConfig) { return; } for (auto &output: mConfig->outputs()) { addOutputToPrimaryCombo(output); } } void Widget::addOutputToPrimaryCombo(const KScreen::OutputPtr &output) { // 注释后让他显示全部屏幕下拉框 if (!output->isConnected()) { return; } ui->primaryCombo->addItem(Utils::outputName(output), output->id()); if (output->isPrimary() && !mIsWayland) { Q_ASSERT(mConfig); int lastIndex = ui->primaryCombo->count() - 1; ui->primaryCombo->setCurrentIndex(lastIndex); } } // 这里从屏幕点击来读取输出 void Widget::slotFocusedOutputChanged(QMLOutput *output) { mControlPanel->activateOutput(output->outputPtr()); // 读取屏幕点击选择下拉框 Q_ASSERT(mConfig); int index = output->outputPtr().isNull() ? 0 : ui->primaryCombo->findData(output->outputPtr()->id()); if (index == -1 || index == ui->primaryCombo->currentIndex()) { return; } ui->primaryCombo->setCurrentIndex(index); } void Widget::slotOutputEnabledChanged() { // 点击禁用屏幕输出后的改变 resetPrimaryCombo(); setActiveScreen(mKDSCfg); int enabledOutputsCount = 0; Q_FOREACH (const KScreen::OutputPtr &output, mConfig->outputs()) { for (int i = 0; i < BrightnessFrameV.size(); ++i) { if (BrightnessFrameV[i]->getOutputName() == Utils::outputName(output)) { BrightnessFrameV[i]->setOutputEnable(output->isEnabled()); break; } } if (output->isEnabled()) { ++enabledOutputsCount; for (int i = 0; i < BrightnessFrameV.size(); ++i) { if (BrightnessFrameV[i]->getOutputName() == Utils::outputName(output) && !BrightnessFrameV[i]->getSliderEnable()) { BrightnessFrameV[i]->runConnectThread(true); } } } if (enabledOutputsCount > 1) { break; } } mUnifyButton->setEnabled(enabledOutputsCount > 1); ui->unionframe->setVisible(enabledOutputsCount > 1); } void Widget::slotOutputConnectedChanged() { const KScreen::OutputPtr output(qobject_cast(sender()), [](void *){}); if (output->isConnected()) { outputAdded(output, true); } else { outputRemoved(output->id(), true); } resetPrimaryCombo(); mainScreenButtonSelect(ui->primaryCombo->currentIndex()); } void Widget::slotUnifyOutputs() { QMLOutput *base = mScreen->primaryOutput(); QList clones; if (!base) { for (QMLOutput *output: mScreen->outputs()) { if (output->output()->isConnected() && output->output()->isEnabled()) { base = output; break; } } if (!base) { // WTF? return; } } for (QMLOutput *output: mScreen->outputs()) { if (output) { if (mUnifyButton->isChecked() && output == base) { output->setIsCloneMode(true, true); } else { output->setIsCloneMode(mUnifyButton->isChecked(), false); } } } // 取消统一输出 if (!mUnifyButton->isChecked()) { bool isExistCfg = QFile::exists((QDir::homePath() + "/.config/ukui/ukcc-screenPreCfg.json")); if (mKDSCfg.isEmpty() && isExistCfg) { KScreen::OutputList screens = mPrevConfig->connectedOutputs(); QList preScreenCfg = getPreScreenCfg(); int posX = preScreenCfg.at(0).screenPosX; bool isOverlap = false; for (int i = 1; i< preScreenCfg.count(); i++) { if (posX == preScreenCfg.at(i).screenPosX) { isOverlap = true; setScreenKDS("expand"); break; } } Q_FOREACH(ScreenConfig cfg, preScreenCfg) { Q_FOREACH(KScreen::OutputPtr output, screens) { if (!cfg.screenId.compare(output->name()) && !isOverlap) { output->setCurrentModeId(cfg.screenModeId); output->setPos(QPoint(cfg.screenPosX, cfg.screenPosY)); } } } } else { setScreenKDS("expand"); } unifySetconfig = true; setConfig(mPrevConfig); ui->primaryCombo->setEnabled(true); mCloseScreenButton->setEnabled(true); ui->showMonitorframe->setVisible(true); ui->primaryCombo->setEnabled(true); } else if (mUnifyButton->isChecked()) { // Clone the current config, so that we can restore it in case user // breaks the cloning mPrevConfig = mConfig->clone(); if (!mFirstLoad) { setPreScreenCfg(mPrevConfig->connectedOutputs()); } for (QMLOutput *output: mScreen->outputs()) { if (output != mScreen->primaryOutput()) { output->output()->setRotation(mScreen->primaryOutput()->output()->rotation()); } if (!output->output()->isConnected()) { continue; } if (!output->output()->isEnabled()) { continue; } if (!base) { base = output; } output->setOutputX(0); output->setOutputY(0); output->output()->setPos(QPoint(0, 0)); output->output()->setClones(QList()); if (base != output) { clones << output->output()->id(); output->setCloneOf(base); } } base->output()->setClones(clones); mScreen->updateOutputsPlacement(); // 关闭开关 mCloseScreenButton->setEnabled(false); ui->showMonitorframe->setVisible(false); ui->primaryCombo->setEnabled(false); ui->mainScreenButton->setEnabled(false); mControlPanel->setUnifiedOutput(base->outputPtr()); } } // FIXME: Copy-pasted from KDED's Serializer::findOutput() KScreen::OutputPtr Widget::findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info) { KScreen::OutputList outputs = config->outputs(); Q_FOREACH (const KScreen::OutputPtr &output, outputs) { if (!output->isConnected()) { continue; } const QString outputId = (output->edid() && output->edid()->isValid()) ? output->edid()->hash() : output->name(); if (outputId != info[QStringLiteral("id")].toString()) { continue; } QVariantMap posInfo = info[QStringLiteral("pos")].toMap(); QPoint point(posInfo[QStringLiteral("x")].toInt(), posInfo[QStringLiteral("y")].toInt()); output->setPos(point); output->setPrimary(info[QStringLiteral("primary")].toBool()); output->setEnabled(info[QStringLiteral("enabled")].toBool()); output->setRotation(static_cast(info[QStringLiteral("rotation")]. toInt())); QVariantMap modeInfo = info[QStringLiteral("mode")].toMap(); QVariantMap modeSize = modeInfo[QStringLiteral("size")].toMap(); QSize size(modeSize[QStringLiteral("width")].toInt(), modeSize[QStringLiteral("height")].toInt()); const KScreen::ModeList modes = output->modes(); Q_FOREACH (const KScreen::ModePtr &mode, modes) { if (mode->size() != size) { continue; } if (QString::number(mode->refreshRate()) != modeInfo[QStringLiteral("refresh")].toString()) { continue; } output->setCurrentModeId(mode->id()); break; } return output; } return KScreen::OutputPtr(); } void Widget::setHideModuleInfo() { mCPU = getCpuInfo(); // if (!mCPU.startsWith(kCpu, Qt::CaseInsensitive)) { //fix bug#78013 ui->quickWidget->setAttribute(Qt::WA_AlwaysStackOnTop); ui->quickWidget->setClearColor(Qt::transparent); // } } void Widget::setTitleLabel() { //~ contents_path /display/monitor ui->primaryLabel->setText(tr("monitor")); //~ contents_path /display/screen zoom ui->scaleLabel->setText(tr("screen zoom")); } void Widget::writeScale(double scale) { if (scale != scaleGSettings->get(SCALE_KEY).toDouble()) { mIsScaleChanged = true; } if (mIsScaleChanged) { if (!mIsChange) { QMessageBox::information(this->topLevelWidget(), tr("Information"), tr("Some applications need to be logouted to take effect")); } else { // 非主动切换缩放率,则不弹提示弹窗 mIsChange = false; } } else { return; } mIsScaleChanged = false; int cursize; QByteArray iid(MOUSE_SIZE_SCHEMAS); if (QGSettings::isSchemaInstalled(MOUSE_SIZE_SCHEMAS)) { QGSettings cursorSettings(iid); if (1.0 == scale) { cursize = 24; } else if (2.0 == scale) { cursize = 48; } else if (3.0 == scale) { cursize = 96; } else { cursize = 24; } QStringList keys = scaleGSettings->keys(); if (keys.contains("scalingFactor")) { scaleGSettings->set(SCALE_KEY, scale); } cursorSettings.set(CURSOR_SIZE_KEY, cursize); Utils::setKwinMouseSize(cursize); } } void Widget::initGSettings() { QByteArray id(UKUI_CONTORLCENTER_PANEL_SCHEMAS); // if (QGSettings::isSchemaInstalled(id)) { // mGsettings = new QGSettings(id, QByteArray(), this); // if (mGsettings->keys().contains(THEME_NIGHT_KEY)) { // mThemeButton->setChecked(mGsettings->get(THEME_NIGHT_KEY).toBool()); // } // } else { // qDebug() << Q_FUNC_INFO << "org.ukui.control-center.panel.plugins not install"; // return; // } QByteArray scaleId(FONT_RENDERING_DPI); if (QGSettings::isSchemaInstalled(scaleId)) { scaleGSettings = new QGSettings(scaleId, QByteArray(), this); } } void Widget::setcomBoxScale() { int scale = 1; QComboBox *scaleCombox = findChild(QString("scaleCombox")); if (scaleCombox) { scale = ("100%" == scaleCombox->currentText() ? 1 : 2); } writeScale(scale); } void Widget::initNightUI() { //~ contents_path /display/unify output ui->unifyLabel->setText(tr("unify output")); QHBoxLayout *nightLayout = new QHBoxLayout(ui->nightframe); //~ contents_path /display/night mode nightLabel = new QLabel(tr("night mode"), this); mNightButton = new SwitchButton(this); nightLayout->addWidget(nightLabel); nightLayout->addStretch(); nightLayout->addWidget(mNightButton); // QHBoxLayout *themeLayout = new QHBoxLayout(ui->themeFrame); // mThemeButton = new SwitchButton(this); // themeLayout->addWidget(new QLabel(tr("Theme follow night mode"))); // themeLayout->addStretch(); // themeLayout->addWidget(mThemeButton); } bool Widget::isRestoreConfig() { int cnt = 15; int ret = -100; MainWindow *mainWindow = static_cast(this->topLevelWidget()); QMessageBox msg(mainWindow); connect(mainWindow, &MainWindow::posChanged, this, [=,&msg]() { QTimer::singleShot(8, this, [=,&msg]() { //窗管会移动窗口,等待8ms,确保在窗管移动之后再move,时间不能太长,否则会看到移动的路径 QRect rect = this->topLevelWidget()->geometry(); int msgX = 0, msgY = 0; msgX = rect.x() + rect.width()/2 - 380/2; msgY = rect.y() + rect.height()/2 - 130/2; msg.move(msgX, msgY); }); }); if (mConfigChanged) { msg.setWindowTitle(tr("Hint")); msg.setText(tr("After modifying the resolution or refresh rate, " "due to compatibility issues between the display device and the graphics card, " "the display may be abnormal or unable to display\n" "the settings will be saved after 14 seconds")); msg.addButton(tr("Save"), QMessageBox::RejectRole); msg.addButton(tr("Not Save"), QMessageBox::AcceptRole); QTimer cntDown; QObject::connect(&cntDown, &QTimer::timeout, [&msg, &cnt, &cntDown, &ret]()->void { if (--cnt < 0) { cntDown.stop(); msg.hide(); msg.close(); } else { msg.setText(QString(tr("After modifying the resolution or refresh rate, " "due to compatibility issues between the display device and the graphics card, " "the display may be abnormal or unable to display \n" "the settings will be saved after %1 seconds")).arg(cnt)); msg.show(); } }); cntDown.start(1000); QRect rect = this->topLevelWidget()->geometry(); int msgX = 0, msgY = 0; msgX = rect.x() + rect.width()/2 - 380/2; msgY = rect.y() + rect.height()/2 - 130/2; msg.move(msgX, msgY); ret = msg.exec(); } disconnect(mainWindow, &MainWindow::posChanged, 0, 0); bool res = false; switch (ret) { case QMessageBox::AcceptRole: res = false; break; case QMessageBox::RejectRole: if (mIsSCaleRes) { QStringList keys = scaleGSettings->keys(); if (keys.contains("scalingFactor")) { scaleGSettings->set(SCALE_KEY,scaleres); } mIsSCaleRes = false; } res = true; break; } return res; } QString Widget::getCpuInfo() { return Utils::getCpuInfo(); } bool Widget::isCloneMode() { KScreen::OutputPtr output = mConfig->primaryOutput(); if (!output) { return false; } if (mConfig->connectedOutputs().count() >= 2) { foreach (KScreen::OutputPtr secOutput, mConfig->connectedOutputs()) { if (secOutput->pos() != output->pos() || !secOutput->isEnabled() || secOutput->size() == QSize(-1, -1)) { return false; } } } else { return false; } return true; } bool Widget::isBacklight() { QString cmd = "ukui-power-backlight-helper --get-max-brightness"; QProcess process; process.start(cmd); process.waitForFinished(); QString result = process.readAllStandardOutput().trimmed(); QString pattern("^[0-9]*$"); QRegExp reg(pattern); return reg.exactMatch(result); } QString Widget::getMonitorType() { QString monitor = ui->primaryCombo->currentText(); QString type; if (monitor.contains("VGA", Qt::CaseInsensitive)) { type = "4"; } else { type = "8"; } return type; } bool Widget::isLaptopScreen() { int index = ui->primaryCombo->currentIndex(); KScreen::OutputPtr output = mConfig->output(ui->primaryCombo->itemData(index).toInt()); if (output->type() == KScreen::Output::Type::Panel) { return true; } return false; } bool Widget::isVisibleBrightness() { if ((mIsBattery && isLaptopScreen()) || (mIsWayland && !mIsBattery) || (!mIsWayland && mIsBattery)) { return true; } return false; } int Widget::getPrimaryScreenID() { QString primaryScreen = getPrimaryWaylandScreen(); int screenId; for (const KScreen::OutputPtr &output : mConfig->outputs()) { if (!output->name().compare(primaryScreen, Qt::CaseInsensitive)) { screenId = output->id(); } } return screenId; } void Widget::setScreenIsApply(bool isApply) { mIsScreenAdd = !isApply; } void Widget::showNightWidget(bool judge) { if (judge) { ui->sunframe->setVisible(true); ui->customframe->setVisible(true); ui->temptframe->setVisible(true); ui->themeFrame->setVisible(false); } else { ui->sunframe->setVisible(false); ui->customframe->setVisible(false); ui->temptframe->setVisible(false); ui->themeFrame->setVisible(false); } if (judge && ui->customradioBtn->isChecked()) { showCustomWiget(CUSTOM); } else { showCustomWiget(SUN); } } void Widget::showCustomWiget(int index) { if (SUN == index) { ui->opframe->setVisible(false); ui->clsframe->setVisible(false); } else if (CUSTOM == index) { ui->opframe->setVisible(true); ui->clsframe->setVisible(true); } } void Widget::slotThemeChanged(bool judge) { if (mGsettings->keys().contains(THEME_NIGHT_KEY)) { mGsettings->set(THEME_NIGHT_KEY, judge); } } void Widget::clearOutputIdentifiers() { mOutputTimer->stop(); qDeleteAll(mOutputIdentifiers); mOutputIdentifiers.clear(); } void Widget::addBrightnessFrame(QString name, bool openFlag, QString edidHash) { if (mIsBattery && name != firstAddOutputName) //笔记本非内置 return; for (int i = 0; i < BrightnessFrameV.size(); ++i) { //已经有了 if (name == BrightnessFrameV[i]->getOutputName()) { if (edidHash != BrightnessFrameV[i]->getEdidHash()) {//更换了同一接口的显示器 BrightnessFrameV[i]->updateEdidHash(edidHash); BrightnessFrameV[i]->setSliderEnable(false); BrightnessFrameV[i]->runConnectThread(openFlag); } BrightnessFrameV[i]->setOutputEnable(openFlag); return; } } BrightnessFrame *frame = nullptr; if (mIsBattery && name == firstAddOutputName) { frame = new BrightnessFrame(name, true); } else if(!mIsBattery) { frame = new BrightnessFrame(name, false, edidHash); } if (frame != nullptr) { BrightnessFrameV.push_back(frame); ui->unifyBrightLayout->addWidget(frame); frame->runConnectThread(openFlag); } } void Widget::outputAdded(const KScreen::OutputPtr &output, bool connectChanged) { if (firstAddOutputName == "" && output->isConnected()) { firstAddOutputName = Utils::outputName(output); } if (output->isConnected()) { QDBusReply replyEdid = dbusEdid->call("getEdid",output->id()); const quint8 *edidData = reinterpret_cast(replyEdid.value().constData()); QCryptographicHash hash(QCryptographicHash::Md5); hash.reset(); hash.addData(reinterpret_cast(edidData), 128); QString edidHash = QString::fromLatin1(hash.result().toHex()); QString name = Utils::outputName(output); qDebug()<<"(outputAdded) displayName:"< edidHash:"<id(); addBrightnessFrame(name, output->isEnabled(), edidHash); } // 刷新缩放选项,监听新增显示屏的mode变化 changescale(); if (output->isConnected()) { connect(output.data(), &KScreen::Output::currentModeIdChanged, this, [=]() { if (output->currentMode()) { if (ui->scaleCombo) { ui->scaleCombo->blockSignals(true); changescale(); ui->scaleCombo->blockSignals(false); } } }); } if (!connectChanged) { connect(output.data(), &KScreen::Output::isConnectedChanged, this, &Widget::slotOutputConnectedChanged); connect(output.data(), &KScreen::Output::isEnabledChanged, this, &Widget::slotOutputEnabledChanged); } addOutputToPrimaryCombo(output); if (!mFirstLoad) { bool isCloneMode_m = isCloneMode(); if (isCloneMode_m != mUnifyButton->isChecked()) mIsScreenAdd = true; mUnifyButton->setChecked(isCloneMode_m); QTimer::singleShot(2000, this, [=] { mainScreenButtonSelect(ui->primaryCombo->currentIndex()); }); } ui->unionframe->setVisible(mConfig->connectedOutputs().count() > 1); mUnifyButton->setEnabled(mConfig->connectedOutputs().count() > 1); showBrightnessFrame(); } void Widget::outputRemoved(int outputId, bool connectChanged) { KScreen::OutputPtr output = mConfig->output(outputId); for (int i = 0; i < BrightnessFrameV.size(); ++i) { if (!output.isNull() && BrightnessFrameV[i]->getOutputName() == Utils::outputName(output)) { BrightnessFrameV[i]->setOutputEnable(false); } } // 刷新缩放选项 changescale(); if (!connectChanged) { if (!output.isNull()) { output->disconnect(this); } } const int index = ui->primaryCombo->findData(outputId); if (index != -1) { if (index == ui->primaryCombo->currentIndex()) { // We'll get the actual primary update signal eventually // Don't emit currentIndexChanged const bool blocked = ui->primaryCombo->blockSignals(true); ui->primaryCombo->setCurrentIndex(0); ui->primaryCombo->blockSignals(blocked); } ui->primaryCombo->removeItem(index); } // 检查统一输出-防止移除后没有屏幕可显示 if (mUnifyButton->isChecked()) { for (QMLOutput *qmlOutput: mScreen->outputs()) { if (qmlOutput) { qmlOutput->setIsCloneMode(false, false); } } } ui->unionframe->setVisible(mConfig->connectedOutputs().count() > 1); mUnifyButton->blockSignals(true); mUnifyButton->setChecked(mConfig->connectedOutputs().count() > 1); mUnifyButton->blockSignals(false); mainScreenButtonSelect(ui->primaryCombo->currentIndex()); showBrightnessFrame(); } void Widget::primaryOutputSelected(int index) { if (!mConfig) { return; } const KScreen::OutputPtr newPrimary = index == 0 ? KScreen::OutputPtr() : mConfig->output(ui->primaryCombo->itemData(index).toInt()); if (newPrimary == mConfig->primaryOutput()) { return; } mConfig->setPrimaryOutput(newPrimary); } // 主输出 void Widget::primaryOutputChanged(const KScreen::OutputPtr &output) { Q_ASSERT(mConfig); int index = output.isNull() ? 0 : ui->primaryCombo->findData(output->id()); if (index == -1 || index == ui->primaryCombo->currentIndex()) { return; } ui->primaryCombo->setCurrentIndex(index); } void Widget::slotIdentifyButtonClicked(bool checked) { Q_UNUSED(checked); connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, &Widget::slotIdentifyOutputs); } void Widget::slotIdentifyOutputs(KScreen::ConfigOperation *op) { if (op->hasError()) { return; } const KScreen::ConfigPtr config = qobject_cast(op)->config(); const QString qmlPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(QML_PATH "OutputIdentifier.qml")); mOutputTimer->stop(); clearOutputIdentifiers(); /* Obtain the current active configuration from KScreen */ Q_FOREACH (const KScreen::OutputPtr &output, config->outputs()) { if (!output->isConnected() || !output->currentMode()) { continue; } const KScreen::ModePtr mode = output->currentMode(); QQuickView *view = new QQuickView(); view->setFlags(Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint); view->setResizeMode(QQuickView::SizeViewToRootObject); view->setSource(QUrl::fromLocalFile(qmlPath)); view->installEventFilter(this); QQuickItem *rootObj = view->rootObject(); if (!rootObj) { qWarning() << "Failed to obtain root item"; continue; } QSize deviceSize, logicalSize; if (output->isHorizontal()) { deviceSize = mode->size(); } else { deviceSize = QSize(mode->size().height(), mode->size().width()); } #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) #else if (config->supportedFeatures() & KScreen::Config::Feature::PerOutputScaling) { // no scale adjustment needed on Wayland logicalSize = deviceSize; } else { logicalSize = deviceSize / devicePixelRatioF(); } #endif rootObj->setProperty("outputName", Utils::outputName(output)); rootObj->setProperty("modeName", Utils::sizeToString(deviceSize)); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) view->setProperty("screenSize", QRect(output->pos(), deviceSize)); #else view->setProperty("screenSize", QRect(output->pos(), logicalSize)); #endif mOutputIdentifiers << view; } for (QQuickView *view: mOutputIdentifiers) { view->show(); } mOutputTimer->start(2500); } void Widget::callMethod(QRect geometry, QString name) { auto scale = 1; QDBusInterface waylandIfc("org.ukui.SettingsDaemon", "/org/ukui/SettingsDaemon/wayland", "org.ukui.SettingsDaemon.wayland", QDBusConnection::sessionBus()); QDBusReply reply = waylandIfc.call("scale"); if (reply.isValid()) { scale = reply.value(); } QDBusMessage message = QDBusMessage::createMethodCall("org.ukui.SettingsDaemon", "/org/ukui/SettingsDaemon/wayland", "org.ukui.SettingsDaemon.wayland", "priScreenChanged"); message << geometry.x() / scale << geometry.y() / scale << geometry.width() / scale << geometry.height() / scale << name; QDBusConnection::sessionBus().send(message); } QString Widget::getPrimaryWaylandScreen() { QDBusInterface screenIfc("org.ukui.SettingsDaemon", "/org/ukui/SettingsDaemon/wayland", "org.ukui.SettingsDaemon.wayland", QDBusConnection::sessionBus()); QDBusReply screenReply = screenIfc.call("priScreenName"); if (screenReply.isValid()) { return screenReply.value(); } return QString(); } void Widget::isWayland() { QString sessionType = getenv("XDG_SESSION_TYPE"); if (!sessionType.compare(kSession, Qt::CaseSensitive)) { mIsWayland = true; } else { mIsWayland = false; } } void Widget::applyNightModeSlot() { if (((ui->opHourCom->currentIndex() < ui->clHourCom->currentIndex()) || (ui->opHourCom->currentIndex() == ui->clHourCom->currentIndex() && ui->opMinCom->currentIndex() <= ui->clMinCom->currentIndex())) && CUSTOM == singleButton->checkedId() && mNightButton->isChecked()) { QMessageBox::warning(this, tr("Warning"), tr("Open time should be earlier than close time!")); return; } setNightMode(mNightButton->isChecked()); } void Widget::setScreenKDS(QString kdsConfig) { KScreen::OutputList screens = mConfig->connectedOutputs(); if (kdsConfig == "expand") { Q_FOREACH(KScreen::OutputPtr output, screens) { if (!output.isNull() && !mUnifyButton->isChecked()) { output->setEnabled(true); output->setCurrentModeId("0"); } } KScreen::OutputList screensPre = mPrevConfig->connectedOutputs(); KScreen::OutputPtr mainScreen = mPrevConfig->primaryOutput(); mainScreen->setPos(QPoint(0, 0)); KScreen::OutputPtr preIt = mainScreen; QMap::iterator nowIt = screensPre.begin(); while (nowIt != screensPre.end()) { if (nowIt.value() != mainScreen) { nowIt.value()->setPos(QPoint(preIt->pos().x() + preIt->size().width(), 0)); KScreen::ModeList modes = preIt->modes(); Q_FOREACH (const KScreen::ModePtr &mode, modes) { if (preIt->currentModeId() == mode->id()) { if (preIt->rotation() != KScreen::Output::Rotation::Left && preIt->rotation() != KScreen::Output::Rotation::Right) { nowIt.value()->setPos(QPoint(preIt->pos().x() + mode->size().width(), 0)); } else { nowIt.value()->setPos(QPoint(preIt->pos().x() + mode->size().height(), 0)); } } } preIt = nowIt.value(); } nowIt++; } } else { Q_FOREACH(KScreen::OutputPtr output, screens) { if (!output.isNull()) { output->setEnabled(true); } } delayApply(); } } void Widget::setActiveScreen(QString status) { int activeScreenId = 1; int enableCount = 0; int connectCount = 0; Q_FOREACH(const KScreen::OutputPtr &output, mConfig->connectedOutputs()) { connectCount++; enableCount = (output->isEnabled() ? (++enableCount) : enableCount); } if (status == "second") { activeScreenId = connectCount; } for (int index = 0; index <= ui->primaryCombo->count(); index++) { KScreen::OutputPtr output = mConfig->output(ui->primaryCombo->itemData(index).toInt()); if (status.isEmpty() && connectCount > enableCount && !output.isNull() && output->isEnabled()) { ui->primaryCombo->setCurrentIndex(index); } if (!status.isEmpty() && !output.isNull() && activeScreenId == output->id()) { ui->primaryCombo->setCurrentIndex(index); } } } // 等相关包上传 //通过win+p修改,不存在按钮影响亮度显示的情况,直接就应用了,此时每个屏幕的openFlag是没有修改的,需要单独处理(setScreenKDS) void Widget::kdsScreenchangeSlot(QString status) { QTimer::singleShot(2500, this, [=] { //需要延时 bool isCheck = (status == "copy") ? true : false; mKDSCfg = status; if (mKDSCfg != "copy" && !mUnifyButton->isChecked()) { delayApply();; } mPrevConfig = mConfig->clone(); if (mConfig->connectedOutputs().count() >= 2) { mUnifyButton->setChecked(isCheck); } Q_FOREACH(KScreen::OutputPtr output, mConfig->connectedOutputs()) { if (output.isNull()) continue; for (int i = 0; i < BrightnessFrameV.size(); ++i) { if (BrightnessFrameV[i]->getOutputName() == Utils::outputName(output)) { BrightnessFrameV[i]->setOutputEnable(output->isEnabled()); } } } if (true == isCheck ) { showBrightnessFrame(1); } else { showBrightnessFrame(2); } }); } void Widget::delayApply() { QTimer::singleShot(200, this, [=]() { // kds与插拔不触发应用操作 if (mKDSCfg.isEmpty() && !mIsScreenAdd) { save(); } else { mPrevConfig = mConfig->clone(); } mKDSCfg.clear(); mIsScreenAdd = false; }); } void Widget::save() { qDebug() << Q_FUNC_INFO << ": apply the screen config" << this->currentConfig()->connectedOutputs(); if (!this) { return; } const KScreen::ConfigPtr &config = this->currentConfig(); bool atLeastOneEnabledOutput = false; Q_FOREACH (const KScreen::OutputPtr &output, config->outputs()) { if (output->isEnabled()) { atLeastOneEnabledOutput = true; } if (!output->isConnected()) continue; QMLOutput *base = mScreen->primaryOutput(); if (!base) { for (QMLOutput *output: mScreen->outputs()) { if (output->output()->isConnected() && output->output()->isEnabled()) { base = output; break; } } if (!base) { // WTF? return; } } } if (!atLeastOneEnabledOutput) { QMessageBox::warning(this, tr("Warning"), tr("please insure at least one output!")); mCloseScreenButton->setChecked(true); return; } if (!KScreen::Config::canBeApplied(config)) { QMessageBox::information(this->topLevelWidget(), tr("Warning"), tr("Sorry, your configuration could not be applied.\nCommon reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU.")); return; } mBlockChanges = true; /* Store the current config, apply settings */ auto *op = new KScreen::SetConfigOperation(config); /* Block until the operation is completed, otherwise KCMShell will terminate * before we get to execute the Operation */ op->exec(); // The 1000ms is a bit "random" here, it's what works on the systems I've tested, but ultimately, this is a hack // due to the fact that we just can't be sure when xrandr is done changing things, 1000 doesn't seem to get in the way QTimer::singleShot(1000, this, [=]() { mBlockChanges = false; mConfigChanged = false; }); int enableScreenCount = 0; KScreen::OutputPtr enableOutput; for (const KScreen::OutputPtr &output : mConfig->outputs()) { if (output->isEnabled()) { enableOutput = output; enableScreenCount++; } } if (isRestoreConfig()) { auto *op = new KScreen::SetConfigOperation(mPrevConfig); op->exec(); } else { mPrevConfig = mConfig->clone(); QString hash = config->connectedOutputsHash(); writeFile(mDir % hash); } setActiveScreen(); for (int i = 0; i < BrightnessFrameV.size(); ++i) { //应用成功再更新屏幕是否开启的状态,判断亮度条是否打开 for (KScreen::OutputPtr output : mConfig->outputs()) { if (BrightnessFrameV[i]->getOutputName() == Utils::outputName(output)) { BrightnessFrameV[i]->setOutputEnable(output->isEnabled()); } } } int flag = mUnifyButton->isChecked() ? 1 : 2; showBrightnessFrame(flag); //成功应用之后,重新显示亮度条,传入是否统一输出,1表示打开,2表示关闭 } QVariantMap metadata(const KScreen::OutputPtr &output) { QVariantMap metadata; metadata[QStringLiteral("name")] = output->name(); if (!output->edid() || !output->edid()->isValid()) { return metadata; } metadata[QStringLiteral("fullname")] = output->edid()->deviceId(); return metadata; } QString Widget::globalFileName(const QString &hash) { QString s_dirPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) %QStringLiteral("/kscreen/"); QString dir = s_dirPath % QStringLiteral("outputs/"); if (!QDir().mkpath(dir)) { return QString(); } return QString(); } QVariantMap Widget::getGlobalData(KScreen::OutputPtr output) { QFile file(globalFileName(output->hashMd5())); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Failed to open file" << file.fileName(); return QVariantMap(); } QJsonDocument parser; return parser.fromJson(file.readAll()).toVariant().toMap(); } void Widget::writeGlobal(const KScreen::OutputPtr &output) { // get old values and subsequently override QVariantMap info = getGlobalData(output); if (!writeGlobalPart(output, info, nullptr)) { return; } QFile file(globalFileName(output->hashMd5())); if (!file.open(QIODevice::WriteOnly)) { qWarning() << "Failed to open global output file for writing! " << file.errorString(); return; } file.write(QJsonDocument::fromVariant(info).toJson()); return; } bool Widget::writeGlobalPart(const KScreen::OutputPtr &output, QVariantMap &info, const KScreen::OutputPtr &fallback) { info[QStringLiteral("id")] = output->hash(); info[QStringLiteral("metadata")] = metadata(output); info[QStringLiteral("rotation")] = output->rotation(); // Round scale to four digits info[QStringLiteral("scale")] = int(output->scale() * 10000 + 0.5) / 10000.; QVariantMap modeInfo; float refreshRate = -1.; QSize modeSize; if (output->currentMode() && output->isEnabled()) { refreshRate = output->currentMode()->refreshRate(); modeSize = output->currentMode()->size(); } else if (fallback && fallback->currentMode()) { refreshRate = fallback->currentMode()->refreshRate(); modeSize = fallback->currentMode()->size(); } if (refreshRate < 0 || !modeSize.isValid()) { return false; } modeInfo[QStringLiteral("refresh")] = refreshRate; QVariantMap modeSizeMap; modeSizeMap[QStringLiteral("width")] = modeSize.width(); modeSizeMap[QStringLiteral("height")] = modeSize.height(); modeInfo[QStringLiteral("size")] = modeSizeMap; info[QStringLiteral("mode")] = modeInfo; return true; } bool Widget::writeFile(const QString &filePath) { const KScreen::OutputList outputs = mConfig->outputs(); const auto oldConfig = mPrevConfig; KScreen::OutputList oldOutputs; if (oldConfig) { oldOutputs = oldConfig->outputs(); } QVariantList outputList; for (const KScreen::OutputPtr &output : outputs) { QVariantMap info; const auto oldOutputIt = std::find_if(oldOutputs.constBegin(), oldOutputs.constEnd(), [output](const KScreen::OutputPtr &out) { return out->hashMd5() == output->hashMd5(); }); const KScreen::OutputPtr oldOutput = oldOutputIt != oldOutputs.constEnd() ? *oldOutputIt : nullptr; if (!output->isConnected()) { continue; } writeGlobalPart(output, info, oldOutput); info[QStringLiteral("primary")] = output->isPrimary(); info[QStringLiteral("enabled")] = output->isEnabled(); auto setOutputConfigInfo = [&info](const KScreen::OutputPtr &out) { if (!out) { return; } QVariantMap pos; pos[QStringLiteral("x")] = out->pos().x(); pos[QStringLiteral("y")] = out->pos().y(); info[QStringLiteral("pos")] = pos; }; setOutputConfigInfo(output->isEnabled() ? output : oldOutput); if (output->isEnabled()) { // try to update global output data writeGlobal(output); } outputList.append(info); } QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { qWarning() << "Failed to open config file for writing! " << file.errorString(); return false; } file.write(QJsonDocument::fromVariant(outputList).toJson()); qDebug() << "Config saved on: " << file.fileName(); return true; } void Widget::scaleChangedSlot(double scale) { if (scaleGSettings->get(SCALE_KEY).toDouble() != scale) { mIsScaleChanged = true; } else { mIsScaleChanged = false; } writeScale(scale); } void Widget::changedSlot() { mConfigChanged = true; } void Widget::propertiesChangedSlot(QString property, QMap propertyMap, QStringList propertyList) { Q_UNUSED(property); Q_UNUSED(propertyList); if (propertyMap.keys().contains("OnBattery")) { mOnBattery = propertyMap.value("OnBattery").toBool(); } } // 是否禁用主屏按钮 void Widget::mainScreenButtonSelect(int index) { if (!mConfig || ui->primaryCombo->count() <= 0) { return; } const KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); int connectCount = mConfig->connectedOutputs().count(); if (newPrimary == mConfig->primaryOutput() || mUnifyButton->isChecked() || !newPrimary->isEnabled()) { ui->mainScreenButton->setEnabled(false); } else { ui->mainScreenButton->setEnabled(true); } if (!newPrimary->isEnabled()) { ui->scaleCombo->setEnabled(false); } else { ui->scaleCombo->setEnabled(true); } // 设置是否勾选 mCloseScreenButton->setEnabled(true); ui->showMonitorframe->setVisible(connectCount > 1 && !mUnifyButton->isChecked()); // 初始化时不要发射信号 mCloseScreenButton->blockSignals(true); mCloseScreenButton->setChecked(newPrimary->isEnabled()); mCloseScreenButton->blockSignals(false); mControlPanel->activateOutput(newPrimary); mScreen->setActiveOutputByCombox(newPrimary->id()); } // 设置主屏按钮 void Widget::primaryButtonEnable(bool status) { Q_UNUSED(status); if (!mConfig) { return; } int index = ui->primaryCombo->currentIndex(); ui->mainScreenButton->setEnabled(false); const KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); mConfig->setPrimaryOutput(newPrimary); } void Widget::checkOutputScreen(bool judge) { ui->primaryCombo->blockSignals(true); int index = ui->primaryCombo->currentIndex(); KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); KScreen::OutputPtr mainScreen = mConfig->primaryOutput(); if (!mainScreen) { mConfig->setPrimaryOutput(newPrimary); } mainScreen = mConfig->primaryOutput(); newPrimary->setEnabled(judge); int enabledOutput = 0; Q_FOREACH (KScreen::OutputPtr outptr, mConfig->outputs()) { if (outptr->isEnabled()) { enabledOutput++; } if (mainScreen != outptr && outptr->isConnected()) { newPrimary = outptr; } if (enabledOutput >= 2) { // 设置副屏在主屏右边 newPrimary->setPos(QPoint(mainScreen->pos().x() + mainScreen->geometry().width(), mainScreen->pos().y())); } } ui->primaryCombo->setCurrentIndex(index); ui->primaryCombo->blockSignals(false); } void Widget::initConnection() { // connect(mThemeButton, SIGNAL(checkedChanged(bool)), this, SLOT(slotThemeChanged(bool))); connect(ui->primaryCombo, static_cast(&QComboBox::currentIndexChanged), this, &Widget::mainScreenButtonSelect); connect(ui->mainScreenButton, &QPushButton::clicked, this, [=](bool status){ primaryButtonEnable(status); delayApply(); }); mControlPanel = new ControlPanel(this); connect(mControlPanel, &ControlPanel::changed, this, &Widget::changed); connect(this, &Widget::changed, this, [=]() { changedSlot(); delayApply(); }); connect(mControlPanel, &ControlPanel::scaleChanged, this, &Widget::scaleChangedSlot); ui->controlPanelLayout->addWidget(mControlPanel); connect(ui->advancedBtn, &QPushButton::clicked, this, [=] { DisplayPerformanceDialog *dialog = new DisplayPerformanceDialog(this); dialog->exec(); }); connect(mUnifyButton, &SwitchButton::checkedChanged, [this] { slotUnifyOutputs(); /* bug#54275 避免拔插触发save() setScreenIsApply(true); */ delayApply(); showBrightnessFrame(); }); connect(mCloseScreenButton, &SwitchButton::checkedChanged, this, [=](bool checked) { checkOutputScreen(checked); delayApply(); changescale(); }); connect(mNightButton, &SwitchButton::checkedChanged, this, [=](bool status){ showNightWidget(status); applyNightModeSlot(); }); connect(ui->opHourCom, QOverload::of(&QComboBox::currentIndexChanged), this, [=]{ applyNightModeSlot();; }); connect(ui->opMinCom, QOverload::of(&QComboBox::currentIndexChanged), this, [=]{ applyNightModeSlot(); }); connect(ui->clHourCom, QOverload::of(&QComboBox::currentIndexChanged), this, [=]{ applyNightModeSlot();; }); connect(ui->clMinCom, QOverload::of(&QComboBox::currentIndexChanged), this, [=]{ applyNightModeSlot(); }); connect(ui->temptSlider, &QSlider::valueChanged, this, [=]{ applyNightModeSlot(); }); connect(singleButton, QOverload::of(&QButtonGroup::buttonClicked), this, [=](int index){ showCustomWiget(index); applyNightModeSlot(); }); QDBusConnection::sessionBus().connect(QString(), QString("/"), "org.ukui.ukcc.session.interface", "screenChanged", this, SLOT(kdsScreenchangeSlot(QString))); QDBusConnection::sessionBus().connect(QString(), QString("/ColorCorrect"), "org.ukui.kwin.ColorCorrect", "nightColorConfigChanged", this, SLOT(nightChangedSlot(QHash))); mOutputTimer = new QTimer(this); connect(mOutputTimer, &QTimer::timeout, this, &Widget::clearOutputIdentifiers); mApplyShortcut = new QShortcut(QKeySequence("Ctrl+A"), this); connect(mApplyShortcut, SIGNAL(activated()), this, SLOT(save())); connect(ui->primaryCombo, static_cast(&QComboBox::currentIndexChanged),//////////////// this, [=](int index) { // mainScreenButtonSelect(index); showBrightnessFrame(); //当前屏幕框变化的时候,显示,此时不判断 }); } void Widget::initTemptSlider() { ui->temptSlider->setRange(1.1*1000, 6500); ui->temptSlider->setTracking(true); for (int i = 0; i < 24; i++) { ui->opHourCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); ui->clHourCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); } for (int i = 0; i < 60; i++) { ui->opMinCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); ui->clMinCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); } } void Widget::setNightMode(const bool nightMode) { QDBusInterface colorIft("org.ukui.KWin", "/ColorCorrect", "org.ukui.kwin.ColorCorrect", QDBusConnection::sessionBus()); if (!colorIft.isValid()) { qWarning() << "create org.ukui.kwin.ColorCorrect failed"; return; } if (!nightMode) { mNightConfig["Active"] = false; } else { mNightConfig["Active"] = true; if (ui->sunradioBtn->isChecked()) { mNightConfig["EveningBeginFixed"] = "17:55:01"; mNightConfig["MorningBeginFixed"] = "05:04:00"; mNightConfig["Mode"] = 2; } else if (ui->customradioBtn->isChecked()) { mNightConfig["EveningBeginFixed"] = ui->opHourCom->currentText() + ":" + ui->opMinCom->currentText() + ":00"; mNightConfig["MorningBeginFixed"] = ui->clHourCom->currentText() + ":" + ui->clMinCom->currentText() + ":00"; mNightConfig["Mode"] = 2; } mNightConfig["NightTemperature"] = ui->temptSlider->value(); } colorIft.call("setNightColorConfig", mNightConfig); } void Widget::initUiComponent() { ui->frame->setVisible(false); mDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) %QStringLiteral("/kscreen/") %QStringLiteral("" /*"configs/"*/); singleButton = new QButtonGroup(); singleButton->addButton(ui->sunradioBtn); singleButton->addButton(ui->customradioBtn); singleButton->setId(ui->sunradioBtn, SUN); singleButton->setId(ui->customradioBtn, CUSTOM); MODE value = ui->customradioBtn->isChecked() == SUN ? SUN : CUSTOM; showNightWidget(mNightButton->isChecked()); if (mNightButton->isChecked()) { showCustomWiget(value); } QDBusInterface brightnessInterface("org.freedesktop.UPower", "/org/freedesktop/UPower/devices/DisplayDevice", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); if (!brightnessInterface.isValid()) { qDebug() << "Create UPower Interface Failed : " << QDBusConnection::systemBus().lastError(); return; } mIsBattery = isBacklight(); mUPowerInterface = QSharedPointer( new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus())); if (!mUPowerInterface.get()->isValid()) { qDebug() << "Create UPower Battery Interface Failed : " << QDBusConnection::systemBus().lastError(); return; } QDBusReply batteryInfo; batteryInfo = mUPowerInterface.get()->call("Get", "org.freedesktop.UPower", "OnBattery"); if (batteryInfo.isValid()) { mOnBattery = batteryInfo.value().toBool(); } mUPowerInterface.get()->connection().connect("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(propertiesChangedSlot(QString, QMap, QStringList))); mUkccInterface = QSharedPointer( new QDBusInterface("org.ukui.ukcc.session", "/", "org.ukui.ukcc.session.interface", QDBusConnection::sessionBus())); } void Widget::initNightStatus() { QDBusInterface colorIft("org.ukui.KWin", "/ColorCorrect", "org.ukui.kwin.ColorCorrect", QDBusConnection::sessionBus()); if (colorIft.isValid() && !mIsWayland) { this->mRedshiftIsValid = true; } else { qWarning() << "create org.ukui.kwin.ColorCorrect failed"; return; } QDBusMessage result = colorIft.call("nightColorInfo"); QList outArgs = result.arguments(); QVariant first = outArgs.at(0); QDBusArgument dbvFirst = first.value(); QVariant vFirst = dbvFirst.asVariant(); const QDBusArgument &dbusArgs = vFirst.value(); QVector nightColor; dbusArgs.beginArray(); while (!dbusArgs.atEnd()) { ColorInfo color; dbusArgs >> color; nightColor.push_back(color); } dbusArgs.endArray(); for (ColorInfo it : nightColor) { mNightConfig.insert(it.arg, it.out.variant()); } this->mIsNightMode = mNightConfig["Active"].toBool(); ui->temptSlider->setValue(mNightConfig["CurrentColorTemperature"].toInt()); if (mNightConfig["EveningBeginFixed"].toString() == "17:55:01") { ui->sunradioBtn->setChecked(true); } else { ui->customradioBtn->setChecked(true); QString openTime = mNightConfig["EveningBeginFixed"].toString(); QString ophour = openTime.split(":").at(0); QString opmin = openTime.split(":").at(1); ui->opHourCom->setCurrentIndex(ophour.toInt()); ui->opMinCom->setCurrentIndex(opmin.toInt()); QString cltime = mNightConfig["MorningBeginFixed"].toString(); QString clhour = cltime.split(":").at(0); QString clmin = cltime.split(":").at(1); ui->clHourCom->setCurrentIndex(clhour.toInt()); ui->clMinCom->setCurrentIndex(clmin.toInt()); } } void Widget::nightChangedSlot(QHash nightArg) { if (this->mRedshiftIsValid) { mNightButton->blockSignals(true); mNightButton->setChecked(nightArg["Active"].toBool()); showNightWidget(mNightButton->isChecked()); mNightButton->blockSignals(false); } } /* 总结: 亮度条怎么显示和实际的屏幕状态有关,与按钮选择状态关系不大: * 实际为镜像模式,就显示所有屏幕的亮度(笔记本外显除外,笔记本外显任何情况均隐藏,这里未涉及)。 * 实际为扩展模式,就显示当前选中的屏幕亮度,如果当前选中复制模式,则亮度条隐藏不显示,应用之后再显示所有亮度条; * 实际为单屏模式,即另一个屏幕关闭,则显示打开屏幕的亮度,关闭的显示器不显示亮度 * *ps: by feng chao */ //不能在这里面设置配置信息,会引出很多问题(如:mUnifyButton->setChecked) void Widget::showBrightnessFrame(const int flag) { bool allShowFlag = true; allShowFlag = isCloneMode(); ui->unifyBrightFrame->setFixedHeight(0); if (flag == 0 && allShowFlag == false && mUnifyButton->isChecked()) { //选中了镜像模式,实际是扩展模式 } else if ((allShowFlag == true && flag == 0) || flag == 1) { //镜像模式/即将成为镜像模式 int frameHeight = 0; for (int i = 0; i < BrightnessFrameV.size(); ++i) { if (!BrightnessFrameV[i]->getOutputEnable()) continue; frameHeight = frameHeight + 54; BrightnessFrameV[i]->setOutputEnable(true); BrightnessFrameV[i]->setTextLabelName(tr("Brightness") + QString("(") + BrightnessFrameV[i]->getOutputName() + QString(")")); BrightnessFrameV[i]->setVisible(true); } ui->unifyBrightFrame->setFixedHeight(frameHeight); } else { for (int i = 0; i < BrightnessFrameV.size(); ++i) { if (ui->primaryCombo->currentText() == BrightnessFrameV[i]->getOutputName() && BrightnessFrameV[i]->getOutputEnable()) { ui->unifyBrightFrame->setFixedHeight(52); BrightnessFrameV[i]->setTextLabelName(tr("Brightness")); BrightnessFrameV[i]->setVisible(true); //不能break,要把其他的frame隐藏 } else { BrightnessFrameV[i]->setVisible(false); } } } if (ui->unifyBrightFrame->height() > 0) { ui->unifyBrightFrame->setVisible(true); } else { ui->unifyBrightFrame->setVisible(false); } } QList Widget::getPreScreenCfg() { QDBusMessage msg = mUkccInterface.get()->call("getPreScreenCfg"); if(msg.type() == QDBusMessage::ErrorMessage) { qWarning() << "get pre screen cfg failed"; } QDBusArgument argument = msg.arguments().at(0).value(); QList infos; argument >> infos; QList preScreenCfg; for (int i = 0; i < infos.size(); i++){ ScreenConfig cfg; infos.at(i).value() >> cfg; preScreenCfg.append(cfg); } return preScreenCfg; } void Widget::setPreScreenCfg(KScreen::OutputList screens) { QMap::iterator nowIt = screens.begin(); QVariantList retlist; while (nowIt != screens.end()) { ScreenConfig cfg; cfg.screenId = nowIt.value()->name(); cfg.screenModeId = nowIt.value()->currentModeId(); cfg.screenPosX = nowIt.value()->pos().x(); cfg.screenPosY = nowIt.value()->pos().y(); QVariant variant = QVariant::fromValue(cfg); retlist << variant; nowIt++; } mUkccInterface.get()->call("setPreScreenCfg", retlist); QVariantList outputList; Q_FOREACH(QVariant variant, retlist) { ScreenConfig screenCfg = variant.value(); QVariantMap map; map["id"] = screenCfg.screenId; map["modeid"] = screenCfg.screenModeId; map["x"] = screenCfg.screenPosX; map["y"] = screenCfg.screenPosY; outputList << map; } QString filePath = QDir::homePath() + "/.config/ukui/ukcc-screenPreCfg.json"; QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { qWarning() << "Failed to open config file for writing! " << file.errorString(); } file.write(QJsonDocument::fromVariant(outputList).toJson()); } void Widget::changescale() { mScaleSizeRes = QSize(); for (const KScreen::OutputPtr &output : mConfig->outputs()) { if (output->isEnabled()) { // 作判空判断,防止控制面板闪退 if (output->currentMode()) { if (mScaleSizeRes == QSize()) { mScaleSizeRes = output->currentMode()->size(); } else { mScaleSizeRes = mScaleSizeRes.width() < output->currentMode()->size().width()?mScaleSizeRes:output->currentMode()->size(); } } else { return; } } } if (mScaleSizeRes != QSize(0,0)) { QSize scalesize = mScaleSizeRes; ui->scaleCombo->blockSignals(true); ui->scaleCombo->clear(); ui->scaleCombo->addItem("100%", 1.0); if (scalesize.width() > 1024 ) { ui->scaleCombo->addItem("125%", 1.25); } if (scalesize.width() == 1920 ) { ui->scaleCombo->addItem("150%", 1.5); } if (scalesize.width() > 1920) { ui->scaleCombo->addItem("150%", 1.5); ui->scaleCombo->addItem("175%", 1.75); } if (scalesize.width() >= 2160) { ui->scaleCombo->addItem("200%", 2.0); } if (scalesize.width() > 2560) { ui->scaleCombo->addItem("225%", 2.25); } if (scalesize.width() > 3072) { ui->scaleCombo->addItem("250%", 2.5); } if (scalesize.width() > 3840) { ui->scaleCombo->addItem("275%", 2.75); } double scale; QStringList keys = scaleGSettings->keys(); if (keys.contains("scalingFactor")) { scale = scaleGSettings->get(SCALE_KEY).toDouble(); } if (ui->scaleCombo->findData(scale) == -1) { //记录分辨率切换时,新分辨率不存在的缩放率,在用户点击恢复设置时写入 mIsSCaleRes = true; //记录是否因分辨率导致的缩放率变化 mIsChange = true; scaleres = scale; scale = 1.0; } ui->scaleCombo->setCurrentText(QString::number(scale * 100) + "%"); scaleChangedSlot(scale); ui->scaleCombo->blockSignals(false); mScaleSizeRes = QSize(); } } ukui-control-center/plugins/system/display/outputconfig.cpp0000644000175000017500000002575414201663716023336 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "outputconfig.h" #include "resolutionslider.h" #include "utils.h" #include "scalesize.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ComboBox/combobox.h" double mScaleres = 0; const float kExcludeRate = 50.00; OutputConfig::OutputConfig(QWidget *parent) : QWidget(parent), mOutput(nullptr) { } OutputConfig::OutputConfig(const KScreen::OutputPtr &output, QWidget *parent) : QWidget(parent) { setOutput(output); } OutputConfig::~OutputConfig() { } void OutputConfig::setTitle(const QString &title) { mTitle->setText(title); } void OutputConfig::initUi() { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setContentsMargins(0, 0, 0, 0); vbox->setSpacing(2); // 分辨率下拉框 mResolution = new ResolutionSlider(mOutput, this); mResolution->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); QLabel *resLabel = new QLabel(this); //~ contents_path /display/resolution resLabel->setText(tr("resolution")); resLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); resLabel->setFixedSize(118, 30); QHBoxLayout *resLayout = new QHBoxLayout(); resLayout->addWidget(resLabel); resLayout->addWidget(mResolution); QFrame *resFrame = new QFrame(this); resFrame->setFrameShape(QFrame::Shape::Box); resFrame->setLayout(resLayout); resFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); resFrame->setMinimumSize(552, 50); resFrame->setMaximumSize(960, 50); vbox->addWidget(resFrame); connect(mResolution, &ResolutionSlider::resolutionChanged, this, [=](QSize size, bool emitFlag){ slotResolutionChanged(size, emitFlag); }); // 方向下拉框 mRotation = new QComboBox(this); mRotation->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); QLabel *rotateLabel = new QLabel(this); //~ contents_path /display/orientation rotateLabel->setText(tr("orientation")); rotateLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); rotateLabel->setFixedSize(118, 30); QHBoxLayout *rotateLayout = new QHBoxLayout(); rotateLayout->addWidget(rotateLabel); rotateLayout->addWidget(mRotation); QFrame *rotateFrame = new QFrame(this); rotateFrame->setFrameShape(QFrame::Shape::Box); rotateFrame->setLayout(rotateLayout); rotateFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); rotateFrame->setMinimumSize(550, 50); rotateFrame->setMaximumSize(960, 50); mRotation->addItem(tr("arrow-up"), KScreen::Output::None); mRotation->addItem(tr("90° arrow-right"), KScreen::Output::Right); mRotation->addItem(tr("90° arrow-left"), KScreen::Output::Left); mRotation->addItem(tr("arrow-down"), KScreen::Output::Inverted); connect(mRotation, static_cast(&QComboBox::activated), this, &OutputConfig::slotRotationChanged); mRotation->setCurrentIndex(mRotation->findData(mOutput->rotation())); vbox->addWidget(rotateFrame); // 刷新率下拉框 mRefreshRate = new QComboBox(this); QLabel *freshLabel = new QLabel(this); //~ contents_path /display/frequency freshLabel->setText(tr("frequency")); freshLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); freshLabel->setFixedSize(118, 30); QHBoxLayout *freshLayout = new QHBoxLayout(); freshLayout->addWidget(freshLabel); freshLayout->addWidget(mRefreshRate); QFrame *freshFrame = new QFrame(this); freshFrame->setFrameShape(QFrame::Shape::Box); freshFrame->setLayout(freshLayout); freshFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); freshFrame->setMinimumSize(550, 50); freshFrame->setMaximumSize(960, 50); mRefreshRate->addItem(tr("auto"), -1); vbox->addWidget(freshFrame); slotResolutionChanged(mResolution->currentResolution(), false); connect(mRefreshRate, static_cast(&QComboBox::activated), this, &OutputConfig::slotRefreshRateChanged); // 缩放率下拉框 QFrame *scaleFrame = new QFrame(this); scaleFrame->setFrameShape(QFrame::Shape::Box); scaleFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); scaleFrame->setMinimumSize(550, 50); scaleFrame->setMaximumSize(960, 50); QHBoxLayout *scaleLayout = new QHBoxLayout(scaleFrame); mScaleCombox = new QComboBox(this); mScaleCombox->setObjectName("scaleCombox"); QLabel *scaleLabel = new QLabel(this); //~ contents_path /display/screen zoom scaleLabel->setText(tr("screen zoom")); scaleLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); scaleLabel->setFixedSize(118, 30); scaleLayout->addWidget(scaleLabel); scaleLayout->addWidget(mScaleCombox); vbox->addWidget(scaleFrame); scaleFrame->hide(); slotEnableWidget(); initConnection(); } void OutputConfig::initConnection() { connect(mOutput.data(), &KScreen::Output::isConnectedChanged, this, [=]() { if (!mOutput->isConnected()) { setVisible(false); } }); connect(mOutput.data(), &KScreen::Output::rotationChanged, this, [=]() { const int index = mRotation->findData(mOutput->rotation()); mRotation->blockSignals(true); mRotation->setCurrentIndex(index); mRotation->blockSignals(false); }); connect(mOutput.data(), &KScreen::Output::currentModeIdChanged, this, [=]() { if (mOutput->currentMode()) { if (mRefreshRate) { mRefreshRate->blockSignals(true); slotResolutionChanged(mOutput->currentMode()->size(), false); mRefreshRate->blockSignals(false); } } }); connect(mOutput.data(), &KScreen::Output::isEnabledChanged, this, [=]{ slotEnableWidget(); }); } QString OutputConfig::scaleToString(double scale) { return QString::number(scale * 100) + "%"; } void OutputConfig::setOutput(const KScreen::OutputPtr &output) { mOutput = output; initUi(); } KScreen::OutputPtr OutputConfig::output() const { return mOutput; } void OutputConfig::slotResolutionChanged(const QSize &size, bool emitFlag) { // Ignore disconnected outputs if (!size.isValid()) { return; } QString modeID; KScreen::ModePtr selectMode; KScreen::ModePtr currentMode = mOutput->currentMode(); QList modes; Q_FOREACH (const KScreen::ModePtr &mode, mOutput->modes()) { if (mode->size() == size) { selectMode = mode; modes << mode; } } // Q_ASSERT(currentMode); if (!selectMode) return; modeID = selectMode->id(); // Don't remove the first "Auto" item - prevents ugly flicker of the combobox // when changing resolution for (int i = mRefreshRate->count(); i >= 2; --i) { mRefreshRate->removeItem(i - 1); } for (int i = 0, total = modes.count(); i < total; ++i) { const KScreen::ModePtr mode = modes.at(i); bool alreadyExisted = false; for (int j = 0; j < mRefreshRate->count(); ++j) { if (tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())) == mRefreshRate->itemText(j)) { alreadyExisted = true; break; } } if (alreadyExisted == false && mode->refreshRate() >= kExcludeRate) { //不添加已经存在的项 mRefreshRate->addItem(tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())), mode->id()); } // If selected refresh rate is other then what we consider the "Auto" value // - that is it's not the highest resolution - then select it, otherwise // we stick with "Auto" if (mode == selectMode && mRefreshRate->count() > 1 && emitFlag) { // i + 1 since 0 is auto mRefreshRate->setCurrentIndex(mRefreshRate->count() - 1); } } if (!emitFlag) { int index = 0; if (currentMode) { //避免闪退 index = mRefreshRate->findData(currentMode->id()); } if (index < 0) { //当某个分辨率下所有的刷新率都 < kExcludeRate时,findData会失败,此时显示自动 index = 0; } mRefreshRate->setCurrentIndex(index); } if (!modeID.isEmpty() && emitFlag) { mOutput->setCurrentModeId(modeID); } if (emitFlag) Q_EMIT changed(); } void OutputConfig::slotRotationChanged(int index) { KScreen::Output::Rotation rotation = static_cast(mRotation->itemData(index).toInt()); mOutput->blockSignals(true); mOutput->setRotation(rotation); mOutput->blockSignals(false); Q_EMIT changed(); } void OutputConfig::slotRefreshRateChanged(int index) { QString modeId; if (index == 0) { // Item 0 is "Auto" - "Auto" is equal to highest refresh rate (at least // that's how I understand it, and since the combobox is sorted in descending // order, we just pick the second item from top modeId = mRefreshRate->itemData(1).toString(); } else { modeId = mRefreshRate->itemData(index).toString(); } qDebug() << "modeId is:" << modeId << endl; mOutput->setCurrentModeId(modeId); Q_EMIT changed(); } void OutputConfig::slotScaleChanged(int index) { Q_EMIT scaleChanged(mScaleCombox->itemData(index).toDouble()); } void OutputConfig::slotEnableWidget() { bool isEnable = mOutput.data()->isEnabled(); mResolution->setEnabled(isEnable); mRotation->setEnabled(isEnable); mRefreshRate->setEnabled(isEnable); } void OutputConfig::setShowScaleOption(bool showScaleOption) { mShowScaleOption = showScaleOption; if (mOutput) { initUi(); } } bool OutputConfig::showScaleOption() const { return mShowScaleOption; } // 拿取配置 void OutputConfig::initConfig(const KScreen::ConfigPtr &config) { mConfig = config; } ukui-control-center/plugins/system/display/outputconfig.h0000644000175000017500000000505014201663716022766 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef OUTPUTCONFIG_H #define OUTPUTCONFIG_H #include #include #include #include #include class QCheckBox; class ResolutionSlider; class QLabel; class QStyledItemDelegate; namespace Ui { class KScreenWidget; } class OutputConfig : public QWidget { Q_OBJECT public: explicit OutputConfig(QWidget *parent); explicit OutputConfig(const KScreen::OutputPtr &output, QWidget *parent = nullptr); ~OutputConfig() override; virtual void setOutput(const KScreen::OutputPtr &output); KScreen::OutputPtr output() const; void setTitle(const QString &title); void setShowScaleOption(bool showScaleOption); bool showScaleOption() const; void initConfig(const KScreen::ConfigPtr &config); protected Q_SLOTS: void slotResolutionChanged(const QSize &size, bool emitFlag); void slotRotationChanged(int index); void slotRefreshRateChanged(int index); void slotScaleChanged(int index); void slotEnableWidget(); Q_SIGNALS: void changed(); void scaleChanged(double scale); protected: virtual void initUi(); private: void initConnection(); QString scaleToString(double scale); protected: KScreen::OutputPtr mOutput; QLabel *mTitle = nullptr; QCheckBox *mEnabled = nullptr; ResolutionSlider *mResolution = nullptr; QComboBox *mRotation = nullptr; QComboBox *mScale = nullptr; QComboBox *mRefreshRate = nullptr; QComboBox *mMonitor = nullptr; QComboBox *mScaleCombox = nullptr; bool mShowScaleOption = false; bool mIsFirstLoad = true; #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) KScreen::ConfigPtr mConfig; #else KScreen::ConfigPtr mConfig = nullptr; #endif QGSettings *mDpiSettings = nullptr; }; #endif // OUTPUTCONFIG_H ukui-control-center/plugins/system/display/display.ui0000644000175000017500000006112214201663716022075 0ustar fengfeng DisplayWindow 0 0 945 1188 Form 0 0 32 48 Display Qt::Vertical QSizePolicy::Fixed 12 0 550 0 960 16777215 QFrame::Box 0 0 0 0 550 300 960 300 2 550 50 960 50 QFrame::Box 118 30 118 30 monitor 200 0 16777215 30 120 30 150 30 11 Qt::NoFocus as main 1 QLayout::SetNoConstraint 550 50 960 50 QFrame::Box QFrame::Raised 118 30 118 30 QFrame::NoFrame screen zoom 16777215 30 true 0 0 550 50 960 50 QFrame::Box 118 30 16777215 30 open monitor Qt::Horizontal 78 29 0 9 8 9 32 120 36 120 36 Advanced Qt::Horizontal 40 20 550 50 960 50 QFrame::Box unify output Qt::Horizontal 98 17 0 106 QFrame::NoFrame QFrame::Raised 2 0 0 0 0 2 2 550 50 960 50 QFrame::Box 550 50 960 50 QFrame::Box 550 50 960 50 QFrame::Box 118 30 16777215 30 follow the sunrise and sunset(17:55-05:04) Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 118 30 16777215 30 custom time Qt::Horizontal 40 20 550 50 960 50 QFrame::Box 118 30 16777215 30 opening time Qt::Horizontal 40 20 80 32 80 32 80 32 80 32 550 50 960 50 QFrame::Box closing time Qt::Horizontal 40 20 80 32 80 32 80 32 80 32 550 50 960 50 QFrame::Box 118 30 16777215 30 color temperature warm 0 0 Qt::Horizontal cold Qt::Vertical 20 40 QQuickWidget QWidget
    QtQuickWidgets/QQuickWidget
    TitleLabel QLabel
    Label/titlelabel.h
    Uslider QSlider
    Uslider/uslider.h
    ukui-control-center/plugins/system/display/displayperformancedialog.ui0000644000175000017500000007540314201663716025506 0ustar fengfeng DisplayPerformanceDialog 0 0 580 646 580 646 580 646 Dialog 0 0 9 9 9 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0 QLayout::SetDefaultConstraint 0 0 0 36 16777215 36 QFrame::StyledPanel QFrame::Raised 0 0 0 0 0 0 Qt::Horizontal 40 20 32 32 32 32 0 0 0 0 16777215 16777215 8 QLayout::SetDefaultConstraint 32 16 32 32 0 0 Display Advanced Settings Qt::ScrollBarAsNeeded Qt::ScrollBarAlwaysOff true 0 0 501 538 2 0 50 16777215 50 QFrame::Box QFrame::Plain 0 0 0 0 0 0 16 0 0 Performance buttonGroup Qt::Horizontal 40 20 0 0 0 0 16777215 16777215 QFrame::Box QFrame::Plain 8 16 0 16 0 0 0 false Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. true 0 0 (Note: not support connect graphical with xmanager on windows.) true 2 0 50 16777215 50 QFrame::Box QFrame::Plain 0 0 0 0 0 0 16 0 0 Compatible buttonGroup Qt::Horizontal 40 20 0 0 0 0 16777215 16777215 QFrame::Box QFrame::Plain 8 16 0 16 0 0 0 Applicable to machine with integrated graphics, there is no 3D graphics acceleration. true 0 0 (Note: need connect graphical with xmanager on windows, use this option.) true 2 0 50 16777215 50 QFrame::Box QFrame::Plain 0 0 0 0 0 0 16 0 0 Automatic buttonGroup Qt::Horizontal 40 20 0 0 0 0 16777215 16777215 QFrame::Box QFrame::Plain 8 16 0 16 0 0 0 Auto select according to environment, delay the login time (about 0.5 sec). true 16 0 0 Threshold: 0 0 0 0 Apply 0 0 Reset 0 0 (Note: select this option to use 3D graphics acceleration and xmanager.) true TitleLabel QLabel
    Label/titlelabel.h
    CloseButton QPushButton
    CloseButton/closebutton.h
    ukui-control-center/plugins/system/display/brightnessFrame.cpp0000644000175000017500000001557614201663716023734 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "brightnessFrame.h" #include #include #include #include #include #include #include #include #define POWER_SCHMES "org.ukui.power-manager" #define POWER_KEY "brightness-ac" #define POWER_KEY_C "brightnessAc" BrightnessFrame::BrightnessFrame(const QString &name, const bool &isBattery, const QString &edidHash, QWidget *parent) : QFrame(parent) { this->setFixedHeight(50); this->setMinimumWidth(550); this->setMaximumWidth(960); this->setFrameShape(QFrame::Shape::Box); QHBoxLayout *layout = new QHBoxLayout(this); layout->setSpacing(6); layout->setMargin(9); labelName = new FixLabel(this); labelName->setFixedWidth(118); slider = new Uslider(Qt::Horizontal, this); slider->setRange(10, 100); labelValue = new QLabel(this); labelValue->setFixedWidth(35); labelValue->setAlignment(Qt::AlignRight); layout->addWidget(labelName); layout->addWidget(slider); layout->addWidget(labelValue); this->outputEnable = true; this->connectFlag = true; this->exitFlag = false; this->isBattery = isBattery; this->outputName = name; this->edidHash = edidHash; this->threadRunFlag = false; labelValue->setText("0"); //最低亮度10,获取前显示为0 slider->setEnabled(false); //成功连接了再改为true,否则表示无法修改亮度 } BrightnessFrame::~BrightnessFrame() { exitFlag = true; threadRun.waitForFinished(); } void BrightnessFrame::setTextLabelName(QString text) { this->labelName->setText(text); } void BrightnessFrame::setTextLabelValue(QString text) { this->labelValue->setText(text); } void BrightnessFrame::runConnectThread(const bool &openFlag) { outputEnable = openFlag; if (false == isBattery) { if (true == threadRunFlag) return; threadRun = QtConcurrent::run([=]{ threadRunFlag = true; if ("" == this->edidHash) { threadRunFlag = false; return; } int brightnessValue = getDDCBrighthess(); if (brightnessValue < 0 || !slider || exitFlag) { threadRunFlag = false; return; } slider->setValue(brightnessValue); setTextLabelValue(QString::number(brightnessValue)); slider->setEnabled(true); disconnect(slider,&QSlider::valueChanged,this,0); connect(slider, &QSlider::valueChanged, this, [=](){ qDebug()<get(POWER_KEY).toInt(); setTextLabelValue(QString::number(brightnessValue)); slider->setValue(brightnessValue); slider->setEnabled(true); disconnect(slider,&QSlider::valueChanged,this,0); connect(slider, &QSlider::valueChanged, this, [=](){ qDebug()< reply; while (--times) { if (this->edidHash == "" || exitFlag) return -1; reply = ukccIfc.call("getDisplayBrightness", this->edidHash); if (reply.isValid() && reply.value() >= 0 && reply.value() <= 100) { return reply.value(); } sleep(2); } return -1; } void BrightnessFrame::setDDCBrightness(const int &value) { if (this->edidHash == "") return; QDBusInterface ukccIfc("com.control.center.qt.systemdbus", "/", "com.control.center.interface", QDBusConnection::systemBus()); if (mLock.tryLock()) { ukccIfc.call("setDisplayBrightness", QString::number(value), this->edidHash); mLock.unlock(); } } void BrightnessFrame::updateEdidHash(const QString &edid) { this->edidHash = edid; } QString BrightnessFrame::getEdidHash() { return this->edidHash; } ukui-control-center/plugins/system/display/slider.h0000644000175000017500000000201514201663716021520 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SLIDER_H #define SLIDER_H #include #include #include #include class Slider : public QSlider { public: Slider(); void paintEvent(QPaintEvent *ev); private: QStringList scaleList; }; #endif // SLIDER_H ukui-control-center/plugins/system/display/brightnessFrame.h0000644000175000017500000000404614201663716023367 0ustar fengfeng/* * Copyright 2021 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 2 of the License, 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef BRIGHTNESSFRAME_H #define BRIGHTNESSFRAME_H #include #include #include #include #include "Uslider/uslider.h" #include #include #include