1 //===========================================
2 // Lumina-DE source code
3 // Copyright (c) 2014, Ken Moore
4 // Available under the 3-clause BSD license
5 // See the LICENSE file for full details
6 //===========================================
7 #ifdef __linux__
8 #include <QDebug>
9 #include "LuminaOS.h"
10 #include <unistd.h>
11 #include <stdio.h> // Needed for BUFSIZ
12
13 //can't read xbrightness settings - assume invalid until set
14 static int screenbrightness = -1;
15
OSName()16 QString LOS::OSName(){ return "Linux"; }
17
18 //OS-specific prefix(s)
19 // NOTE: PREFIX, L_ETCDIR, L_SHAREDIR are defined in the OS-detect.pri project file and passed in
LuminaShare()20 QString LOS::LuminaShare(){ return (L_SHAREDIR+"/lumina-desktop/"); } //Install dir for Lumina share files
AppPrefix()21 QString LOS::AppPrefix(){ return "/usr/"; } //Prefix for applications
SysPrefix()22 QString LOS::SysPrefix(){ return "/usr/"; } //Prefix for system
23
24 //OS-specific application shortcuts (*.desktop files)
ControlPanelShortcut()25 QString LOS::ControlPanelShortcut(){ return ""; } //system control panel
AppStoreShortcut()26 QString LOS::AppStoreShortcut(){ return ""; } //graphical app/pkg manager
27 //OS-specific RSS feeds (Format: QStringList[ <name>::::<url> ]; )
RSSFeeds()28 QStringList LOS::RSSFeeds(){ return QStringList(); }
29
30 // ==== ExternalDevicePaths() ====
ExternalDevicePaths()31 QStringList LOS::ExternalDevicePaths(){
32 //Returns: QStringList[<type>::::<filesystem>::::<path>]
33 //Note: <type> = [USB, HDRIVE, DVD, SDCARD, UNKNOWN]
34 QStringList devs = LUtils::getCmdOutput("mount");
35 //Now check the output
36 for(int i=0; i<devs.length(); i++){
37 if(devs[i].startsWith("/dev/")){
38 devs[i] = devs[i].simplified();
39 QString type = devs[i].section(" ",0,0);
40 type.remove("/dev/");
41 //Determine the type of hardware device based on the dev node
42 if(type.startsWith("sd") || type.startsWith("nvme")){ type = "HDRIVE"; }
43 else if(type.startsWith("sr")){ type="DVD"; }
44 else if(type.contains("mapper")){ type="LVM"; }
45 else{ type = "UNKNOWN"; }
46 //Now put the device in the proper output format
47 devs[i] = type+"::::"+devs[i].section(" ",4,4)+"::::"+devs[i].section(" ",2,2);
48 }else{
49 //invalid device - remove it from the list
50 devs.removeAt(i);
51 i--;
52 }
53 }
54 return devs;
55 }
56
57 //Read screen brightness information
ScreenBrightness()58 int LOS::ScreenBrightness(){
59 //Returns: Screen Brightness as a percentage (0-100, with -1 for errors)
60 if(screenbrightness==-1){
61 if(QFile::exists(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/.currentxbrightness")){
62 int val = LUtils::readFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/.currentxbrightness").join("").simplified().toInt();
63 screenbrightness = val;
64 }
65 }
66 return screenbrightness;
67
68 }
69
70 //Set screen brightness
setScreenBrightness(int percent)71 void LOS::setScreenBrightness(int percent){
72 //ensure bounds
73 if(percent<0){percent=0;}
74 else if(percent>100){ percent=100; }
75 // float pf = percent/100.0; //convert to a decimel
76 //Run the command
77 QString cmd = "xbacklight -set %1";
78 // cmd = cmd.arg( QString::number( int(65535*pf) ) );
79 cmd = cmd.arg( QString::number( percent ) );
80 int ret = LUtils::runCmd(cmd);
81 //Save the result for later
82 if(ret!=0){ screenbrightness = -1; }
83 else{ screenbrightness = percent; }
84 LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/.currentxbrightness", QStringList() << QString::number(screenbrightness), true);
85
86 }
87
88 //Read the current volume
audioVolume()89 int LOS::audioVolume(){ //Returns: audio volume as a percentage (0-100, with -1 for errors)
90 QString info = LUtils::getCmdOutput("amixer get Master").join("").simplified();;
91 int out = -1;
92 int start_position, end_position;
93 QString current_volume;
94 if(!info.isEmpty()){
95 start_position = info.indexOf("[");
96 start_position++;
97 end_position = info.indexOf("%");
98 current_volume = info.mid(start_position, end_position - start_position);
99 out = current_volume.toInt();
100 }
101 return out;
102
103
104 }
105
106 //Set the current volume
setAudioVolume(int percent)107 void LOS::setAudioVolume(int percent){
108 if(percent<0){percent=0;}
109 else if(percent>100){percent=100;}
110 QString info = "amixer set Master " + QString::number(percent) + "%";
111 //Run Command
112 LUtils::runCmd(info);
113 }
114
115 //Change the current volume a set amount (+ or -)
changeAudioVolume(int percentdiff)116 void LOS::changeAudioVolume(int percentdiff){
117 int old_volume = audioVolume();
118 int new_volume = old_volume + percentdiff;
119 if (new_volume < 0)
120 new_volume = 0;
121 if (new_volume > 100)
122 new_volume = 100;
123 qDebug() << "Setting new volume to: " << new_volume;
124 setAudioVolume(new_volume);
125 }
126
127 //Check if a graphical audio mixer is installed
hasMixerUtility()128 bool LOS::hasMixerUtility(){
129 return QFile::exists(LOS::AppPrefix() + "bin/pavucontrol");
130 }
131
132 //Launch the graphical audio mixer utility
startMixerUtility()133 void LOS::startMixerUtility(){
134 QProcess::startDetached(LOS::AppPrefix() + "bin/pavucontrol");
135 }
136
137 //Check for user system permission (shutdown/restart)
userHasShutdownAccess()138 bool LOS::userHasShutdownAccess(){
139 return true; //not implemented yet
140 }
141
142 //Check for whether the system is safe to power off (no updates being perfomed)
systemPerformingUpdates()143 bool LOS::systemPerformingUpdates(){
144 return false; //Not implemented yet
145 }
146
147 //Return the details of any updates which are waiting to apply on shutdown
systemPendingUpdates()148 QString LOS::systemPendingUpdates(){
149 return "";
150 }
151
152 //System Shutdown
systemShutdown(bool)153 void LOS::systemShutdown(bool){ //start poweroff sequence
154 //INPUT: skip updates (true/false)
155 QProcess::startDetached("shutdown -P -h now");
156 }
157
158 //System Restart
systemRestart(bool)159 void LOS::systemRestart(bool){ //start reboot sequence
160 //INPUT: skip updates (true/false)
161 QProcess::startDetached("shutdown -r now");
162 }
163
164 //Check for suspend support
systemCanSuspend()165 bool LOS::systemCanSuspend(){
166 return false;
167 }
168
169 //Put the system into the suspend state
systemSuspend()170 void LOS::systemSuspend(){
171
172 }
173
174 //Battery Availability
hasBattery()175 bool LOS::hasBattery(){
176 QString my_status = LUtils::getCmdOutput("acpi -b").join("");
177 bool no_battery = my_status.contains("No support");
178 if (no_battery) return false;
179 return true;
180 }
181
182 //Battery Charge Level
batteryCharge()183 int LOS::batteryCharge(){ //Returns: percent charge (0-100), anything outside that range is counted as an error
184 QString my_status = LUtils::getCmdOutput("acpi -b").join("");
185 int my_start = my_status.indexOf("%");
186 // get the number right before the % sign
187 int my_end = my_start;
188 my_start--;
189 while ( (my_status[my_start] != ' ') && (my_start > 0) )
190 my_start--;
191 my_start++;
192 int my_charge = my_status.mid(my_start, my_end - my_start).toInt();
193 if ( (my_charge < 0) || (my_charge > 100) ) return -1;
194 return my_charge;
195 }
196
197 //Battery Charging State
198 // Many possible values are returned if the laptop is plugged in
199 // these include "Unknown, Full and No support.
200 // However, it seems just one status is returned when running
201 // on battery and that is "Discharging". So if the value we get
202 // is NOT Discharging then we assume the battery is charging.
batteryIsCharging()203 bool LOS::batteryIsCharging(){
204 QString my_status = LUtils::getCmdOutput("acpi -b").join("");
205 bool discharging = my_status.contains("Discharging");
206 if (discharging) return false;
207 return true;
208 }
209
210 //Battery Time Remaining
batterySecondsLeft()211 int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
212 return 0; //not implemented yet for Linux
213 }
214
215 //File Checksums
Checksums(QStringList filepaths)216 QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
217 QStringList info = LUtils::getCmdOutput("md5sum \""+filepaths.join("\" \"")+"\"");
218 for(int i=0; i<info.length(); i++){
219 // first: md5sum: = error ; second: there's always one empty entry generated by getCmdOutput
220 if( info[i].startsWith("md5sum:") || info[i].isEmpty()){ info.removeAt(i); i--; }
221 else{
222 //Strip out the extra information
223 info[i] = info[i].section(" ",0,0);
224 }
225 }
226 return info;
227 }
228
229 //file system capacity
FileSystemCapacity(QString dir)230 QString LOS::FileSystemCapacity(QString dir) { //Return: percentage capacity as give by the df command
231 QStringList mountInfo = LUtils::getCmdOutput("df \"" + dir+"\"");
232 QString::SectionFlag skipEmpty = QString::SectionSkipEmpty;
233 //we take the 5th word on the 2 line
234 QString capacity = mountInfo[1].section(" ",4,4, skipEmpty) + " used";
235 return capacity;
236 }
237
CPUTemperatures()238 QStringList LOS::CPUTemperatures(){ //Returns: List containing the temperature of any CPU's ("50C" for example)
239 return QStringList(); //not implemented yet
240 }
241
CPUUsagePercent()242 int LOS::CPUUsagePercent(){ //Returns: Overall percentage of the amount of CPU cycles in use (-1 for errors)
243 return -1; //not implemented yet
244 }
245
MemoryUsagePercent()246 int LOS::MemoryUsagePercent(){
247 return -1; //not implemented yet
248 }
249
DiskUsage()250 QStringList LOS::DiskUsage(){ //Returns: List of current read/write stats for each device
251 return QStringList(); //not implemented yet
252 }
253
254 #endif
255