├── .github ├── FUNDING.yml └── workflows │ └── ci-mac.yaml ├── .gitignore ├── .gitmodules ├── Assets ├── battery.png ├── cpu.png ├── datetime.png ├── gpu.png ├── memory.png ├── network.png ├── statusbar.png └── temperature.png ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── statusbar.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── statusbar.xcscheme └── statusbar ├── SB ├── Helpers │ ├── Casts.hpp │ ├── String.cpp │ ├── String.hpp │ └── Vector.hpp ├── Instruments │ ├── BatteryInfo.cpp │ ├── BatteryInfo.hpp │ ├── CPULoad.cpp │ ├── CPULoad.hpp │ ├── GPULoad.cpp │ ├── GPULoad.hpp │ ├── Internal │ │ ├── IOHID-Internal.h │ │ ├── IOHID.cpp │ │ ├── IOHID.hpp │ │ ├── SMC-Internal.h │ │ ├── SMC.cpp │ │ └── SMC.hpp │ ├── MemoryInfo.cpp │ ├── MemoryInfo.hpp │ ├── NetworkInfo.cpp │ ├── NetworkInfo.hpp │ ├── TemperatureInfo.cpp │ └── TemperatureInfo.hpp ├── Options.cpp ├── Options.hpp ├── SleepManager.cpp ├── SleepManager.hpp ├── UI │ ├── Color.cpp │ ├── Color.hpp │ ├── ColorPair.cpp │ ├── ColorPair.hpp │ ├── Screen.cpp │ ├── Screen.hpp │ ├── Window.cpp │ └── Window.hpp ├── UUID.cpp ├── UUID.hpp ├── UpdateQueue.cpp └── UpdateQueue.hpp └── main.cpp /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: macmade 2 | -------------------------------------------------------------------------------- /.github/workflows/ci-mac.yaml: -------------------------------------------------------------------------------- 1 | name: ci-mac 2 | on: [push] 3 | jobs: 4 | ci: 5 | runs-on: macos-latest 6 | strategy: 7 | matrix: 8 | run-config: 9 | - { scheme: 'statusbar', configuration: 'Debug', project: 'statusbar.xcodeproj', build: 1, analyze: 1, test: 0, info: 1, destination: 'platform=macOS' } 10 | - { scheme: 'statusbar', configuration: 'Release', project: 'statusbar.xcodeproj', build: 1, analyze: 1, test: 0, info: 1, destination: 'platform=macOS' } 11 | steps: 12 | 13 | - uses: actions/checkout@v1 14 | with: 15 | submodules: 'recursive' 16 | 17 | - uses: macmade/action-xcodebuild@v1.0.0 18 | 19 | - uses: macmade/action-slack@v1.0.0 20 | if: ${{ always() }} 21 | env: 22 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 23 | with: 24 | channel: '#ci' 25 | status: ${{ job.status }} 26 | title: ${{ matrix.run-config[ 'scheme' ] }} - ${{ matrix.run-config[ 'configuration' ] }} 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac Finder 2 | .DS_Store 3 | .Trashes 4 | Icon? 5 | 6 | # Thumbnails 7 | ._* 8 | 9 | # Files that might appear on external disk 10 | .Spotlight-V100 11 | .Trashes 12 | 13 | # Windows 14 | Thumbs.db 15 | 16 | # Xcode 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | *.xccheckout 22 | *.profraw 23 | !default.pbxuser 24 | !default.mode1v3 25 | !default.mode2v3 26 | !default.perspectivev3 27 | xcuserdata 28 | 29 | # VisualStudio 30 | *.suo 31 | *.sdf 32 | *.opensdf 33 | *.vcxproj.user 34 | *.csproj.user 35 | ipch 36 | .vs 37 | *.VC.db 38 | 39 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Submodules/xcconfig"] 2 | path = Submodules/xcconfig 3 | url = https://github.com/macmade/xcconfig.git 4 | -------------------------------------------------------------------------------- /Assets/battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/battery.png -------------------------------------------------------------------------------- /Assets/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/cpu.png -------------------------------------------------------------------------------- /Assets/datetime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/datetime.png -------------------------------------------------------------------------------- /Assets/gpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/gpu.png -------------------------------------------------------------------------------- /Assets/memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/memory.png -------------------------------------------------------------------------------- /Assets/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/network.png -------------------------------------------------------------------------------- /Assets/statusbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/statusbar.png -------------------------------------------------------------------------------- /Assets/temperature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/statusbar/c5ef3fc0d6cc4517730d6e3b213930dfd7a62657/Assets/temperature.png -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | xs-labs.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | statusbar 2 | ========= 3 | 4 | [![Build Status](https://img.shields.io/github/actions/workflow/status/macmade/statusbar/ci-mac.yaml?label=macOS&logo=apple)](https://github.com/macmade/statusbar/actions/workflows/ci-mac.yaml) 5 | [![Issues](http://img.shields.io/github/issues/macmade/statusbar.svg?logo=github)](https://github.com/macmade/statusbar/issues) 6 | ![Status](https://img.shields.io/badge/status-active-brightgreen.svg?logo=git) 7 | ![License](https://img.shields.io/badge/license-mit-brightgreen.svg?logo=open-source-initiative) 8 | [![Contact](https://img.shields.io/badge/follow-@macmade-blue.svg?logo=twitter&style=social)](https://twitter.com/macmade) 9 | [![Sponsor](https://img.shields.io/badge/sponsor-macmade-pink.svg?logo=github-sponsors&style=social)](https://github.com/sponsors/macmade) 10 | 11 | ### About 12 | 13 | Statusbar for your terminal: 14 | 15 | ![Screenshot](Assets/statusbar.png "Screenshot") 16 | ![CPU](Assets/cpu.png "CPU") 17 | ![GPU](Assets/gpu.png "GPU") 18 | ![Memory](Assets/memory.png "Memory") 19 | ![Battery](Assets/battery.png "Battery") 20 | ![Temperature](Assets/temperature.png "Temperature") 21 | ![Network](Assets/network.png "Network") 22 | ![DateTime](Assets/datetime.png "DateTime") 23 | 24 | ### Installation 25 | 26 | ``` 27 | brew install --HEAD macmade/tap/statusbar 28 | ``` 29 | 30 | For updates, run: 31 | 32 | ``` 33 | brew reinstall macmade/tap/statusbar 34 | ``` 35 | 36 | ### Usage 37 | 38 | ``` 39 | Usage: statusbar [OPTIONS] 40 | 41 | Options: 42 | 43 | --help Show the help dialog 44 | --cpu Display CPU load 45 | --gpu Display GPU load 46 | --memory Display memory usage 47 | --temperature Display temperature 48 | --battery Display battery charge 49 | --network Display network address 50 | --date Display current date 51 | --time Display current time 52 | --no-cpu Don't display CPU load 53 | --no-gpu Don't display GPU load 54 | --no-memory Don't display memory usage 55 | --no-temperature Don't display temperature 56 | --no-battery Don't display battery charge 57 | --no-network Don't display network address 58 | --no-date Don't display current date 59 | --no-time Don't display current time 60 | --cpu-color Color for CPU load 61 | --gpu-color Color for GPU load 62 | --memory-color Color for memory usage 63 | --temperature-color Color for temperature 64 | --battery-color Color for battery charge 65 | --network-color Color for network address 66 | --date-color Color for current date 67 | --time-color Color for current time 68 | 69 | Available Colors: red, yellow, green, cyan, blue, magenta, black, white, clear 70 | ``` 71 | 72 | License 73 | ------- 74 | 75 | Project is released under the terms of the MIT License. 76 | 77 | Repository Infos 78 | ---------------- 79 | 80 | Owner: Jean-David Gadina - XS-Labs 81 | Web: www.xs-labs.com 82 | Blog: www.noxeos.com 83 | Twitter: @macmade 84 | GitHub: github.com/macmade 85 | LinkedIn: ch.linkedin.com/in/macmade/ 86 | StackOverflow: stackoverflow.com/users/182676/macmade 87 | -------------------------------------------------------------------------------- /statusbar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /statusbar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /statusbar.xcodeproj/xcshareddata/xcschemes/statusbar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 57 | 58 | 59 | 60 | 66 | 68 | 74 | 75 | 76 | 77 | 79 | 80 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /statusbar/SB/Helpers/Casts.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_CASTS_HPP 26 | #define SB_CASTS_HPP 27 | 28 | #include 29 | 30 | namespace SB 31 | { 32 | template 33 | < 34 | typename _T_, 35 | typename _U_, 36 | typename std::enable_if 37 | < 38 | std::is_integral< _T_ >::value 39 | && std::is_integral< _U_ >::value 40 | && std::is_unsigned< _T_ >::value 41 | && std::is_unsigned< _U_ >::value 42 | > 43 | ::type * = nullptr 44 | > 45 | _T_ numeric_cast( _U_ v ) 46 | { 47 | if( std::numeric_limits< _T_ >::max() < std::numeric_limits< _U_ >::max() && v > std::numeric_limits< _T_ >::max() ) 48 | { 49 | throw std::runtime_error( "Bad numeric cast" ); 50 | } 51 | 52 | return static_cast< _T_ >( v ); 53 | } 54 | 55 | template 56 | < 57 | typename _T_, 58 | typename _U_, 59 | typename std::enable_if 60 | < 61 | std::is_integral< _T_ >::value 62 | && std::is_integral< _U_ >::value 63 | && std::is_signed< _T_ >::value 64 | && std::is_signed< _U_ >::value 65 | > 66 | ::type * = nullptr 67 | > 68 | _T_ numeric_cast( _U_ v ) 69 | { 70 | if( std::numeric_limits< _T_ >::max() < std::numeric_limits< _U_ >::max() && v > std::numeric_limits< _T_ >::max() ) 71 | { 72 | throw std::runtime_error( "Bad numeric cast" ); 73 | } 74 | 75 | if( std::numeric_limits< _T_ >::min() > std::numeric_limits< _U_ >::min() && v < std::numeric_limits< _T_ >::min() ) 76 | { 77 | throw std::runtime_error( "Bad numeric cast" ); 78 | } 79 | 80 | return static_cast< _T_ >( v ); 81 | } 82 | 83 | template 84 | < 85 | typename _T_, 86 | typename _U_, 87 | typename std::enable_if 88 | < 89 | std::is_integral< _T_ >::value 90 | && std::is_integral< _U_ >::value 91 | && std::is_signed< _T_ >::value 92 | && std::is_unsigned< _U_ >::value 93 | > 94 | ::type * = nullptr 95 | > 96 | _T_ numeric_cast( _U_ v ) 97 | { 98 | if( std::numeric_limits< _T_ >::max() < std::numeric_limits< _U_ >::max() && v > std::numeric_limits< _T_ >::max() ) 99 | { 100 | throw std::runtime_error( "Bad numeric cast" ); 101 | } 102 | 103 | return static_cast< _T_ >( v ); 104 | } 105 | 106 | template 107 | < 108 | typename _T_, 109 | typename _U_, 110 | typename std::enable_if 111 | < 112 | std::is_integral< _T_ >::value 113 | && std::is_integral< _U_ >::value 114 | && std::is_unsigned< _T_ >::value 115 | && std::is_signed< _U_ >::value 116 | > 117 | ::type * = nullptr 118 | > 119 | _T_ numeric_cast( _U_ v ) 120 | { 121 | if( v < 0 ) 122 | { 123 | throw std::runtime_error( "Bad numeric cast" ); 124 | } 125 | 126 | if( std::numeric_limits< _T_ >::max() < std::numeric_limits< _U_ >::max() && v > std::numeric_limits< _T_ >::max() ) 127 | { 128 | throw std::runtime_error( "Bad numeric cast" ); 129 | } 130 | 131 | return static_cast< _T_ >( v ); 132 | } 133 | 134 | template 135 | < 136 | typename _T_, 137 | typename _U_, 138 | typename std::enable_if 139 | < 140 | std::is_integral< _T_ >::value 141 | && std::is_unsigned< _T_ >::value 142 | && std::is_floating_point< _U_ >::value 143 | > 144 | ::type * = nullptr 145 | > 146 | _T_ numeric_cast( _U_ v ) 147 | { 148 | if( v < 0 ) 149 | { 150 | throw std::runtime_error( "Bad numeric cast" ); 151 | } 152 | 153 | if( v > std::numeric_limits< _T_ >::max() ) 154 | { 155 | throw std::runtime_error( "Bad numeric cast" ); 156 | } 157 | 158 | return static_cast< _T_ >( v ); 159 | } 160 | 161 | template 162 | < 163 | typename _T_, 164 | typename _U_, 165 | typename std::enable_if 166 | < 167 | std::is_integral< _T_ >::value 168 | && std::is_signed< _T_ >::value 169 | && std::is_floating_point< _U_ >::value 170 | > 171 | ::type * = nullptr 172 | > 173 | _T_ numeric_cast( _U_ v ) 174 | { 175 | if( v > std::numeric_limits< _T_ >::max() ) 176 | { 177 | throw std::runtime_error( "Bad numeric cast" ); 178 | } 179 | 180 | if( v < std::numeric_limits< _T_ >::min() ) 181 | { 182 | throw std::runtime_error( "Bad numeric cast" ); 183 | } 184 | 185 | return static_cast< _T_ >( v ); 186 | } 187 | 188 | template 189 | < 190 | typename _T_, 191 | typename _U_, 192 | typename std::enable_if 193 | < 194 | std::is_floating_point< _T_ >::value 195 | && std::is_integral< _U_ >::value 196 | > 197 | ::type * = nullptr 198 | > 199 | _T_ numeric_cast( _U_ v ) 200 | { 201 | return static_cast< _T_ >( v ); 202 | } 203 | } 204 | 205 | #endif /* SB_CASTS_HPP */ 206 | -------------------------------------------------------------------------------- /statusbar/SB/Helpers/String.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Helpers/String.hpp" 26 | #include 27 | #include 28 | 29 | namespace SB 30 | { 31 | namespace String 32 | { 33 | std::string format( const char * format, ... ) 34 | { 35 | va_list ap; 36 | std::string s; 37 | 38 | va_start( ap, format ); 39 | 40 | int size = vsnprintf( nullptr, 0, format, ap ); 41 | 42 | if( size > 0 ) 43 | { 44 | char * cp = static_cast< char * >( calloc( 1, static_cast< size_t >( size ) + 1 ) ); 45 | 46 | if( cp != nullptr ) 47 | { 48 | vsnprintf( cp, static_cast< size_t >( size + 1 ), format, ap ); 49 | 50 | s = cp; 51 | } 52 | 53 | free( cp ); 54 | } 55 | 56 | va_end( ap ); 57 | 58 | return s; 59 | } 60 | 61 | std::string bytesToHumanReadable( uint64_t bytes ) 62 | { 63 | if( bytes < 1024ULL ) 64 | { 65 | return String::format( "%lluB", bytes ); 66 | } 67 | else if( bytes < 1024ULL * 1024ULL ) 68 | { 69 | return String::format( "%.02fKB", static_cast< double >( bytes ) / static_cast< double >( 1024ULL ) ); 70 | } 71 | else if( bytes < 1024ULL * 1024ULL * 1024ULL ) 72 | { 73 | return String::format( "%.02fMB", static_cast< double >( bytes ) / static_cast< double >( 1024ULL * 1024ULL ) ); 74 | } 75 | else if( bytes < 1024ULL * 1024ULL * 1024ULL * 1024ULL ) 76 | { 77 | return String::format( "%.02fGB", static_cast< double >( bytes ) / static_cast< double >( 1024ULL * 1024ULL * 1024ULL ) ); 78 | } 79 | 80 | return String::format( "%.02fTB", static_cast< double >( bytes ) / static_cast< double >( 1024ULL * 1024ULL * 1024ULL * 1024ULL ) ); 81 | } 82 | 83 | bool hasSuffix( const std::string & str, const std::string & suffix ) 84 | { 85 | std::string::size_type pos = str.find( suffix ); 86 | 87 | if( str.length() >= suffix.length() && pos == str.length() - suffix.length() ) 88 | { 89 | return true; 90 | } 91 | 92 | return false; 93 | } 94 | 95 | std::string fourCC( uint32_t c ) 96 | { 97 | uint8_t c1 = static_cast< uint8_t >( ( c >> 24 ) & 0xFF ); 98 | uint8_t c2 = static_cast< uint8_t >( ( c >> 16 ) & 0xFF ); 99 | uint8_t c3 = static_cast< uint8_t >( ( c >> 8 ) & 0xFF ); 100 | uint8_t c4 = static_cast< uint8_t >( ( c >> 0 ) & 0xFF ); 101 | 102 | return String::format( "%c%c%c%c", c1, c2, c3, c4 ); 103 | } 104 | 105 | std::string toLower( const std::string & s ) 106 | { 107 | std::string ret( s ); 108 | 109 | std::transform( ret.begin(), ret.end(), ret.begin(), ::tolower ); 110 | 111 | return ret; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /statusbar/SB/Helpers/String.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_STRING_HPP 26 | #define SB_STRING_HPP 27 | 28 | #include 29 | 30 | namespace SB 31 | { 32 | namespace String 33 | { 34 | std::string format( const char * format, ... ) __printflike( 1, 2 ); 35 | std::string bytesToHumanReadable( uint64_t bytes ); 36 | bool hasSuffix( const std::string & str, const std::string & suffix ); 37 | std::string fourCC( uint32_t c ); 38 | std::string toLower( const std::string & s ); 39 | } 40 | } 41 | 42 | #endif /* SB_STRING_HPP */ 43 | -------------------------------------------------------------------------------- /statusbar/SB/Helpers/Vector.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_VECTOR_HPP 26 | #define SB_VECTOR_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | namespace Vector 35 | { 36 | template< typename T, typename U > 37 | T reduce( const std::vector< U > & vector, T initialValue, const std::function< T( T, U ) > & func ) 38 | { 39 | T ret = initialValue; 40 | 41 | if( func != nullptr ) 42 | { 43 | for( const auto & value: vector ) 44 | { 45 | ret = func( ret, value ); 46 | } 47 | } 48 | 49 | return ret; 50 | } 51 | } 52 | } 53 | 54 | #endif /* SB_VECTOR_HPP */ 55 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/BatteryInfo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/BatteryInfo.hpp" 26 | #include "SB/UpdateQueue.hpp" 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | class BatteryInfo::IMPL 35 | { 36 | public: 37 | 38 | IMPL( int64_t capacity, bool charging, bool isAvailable ); 39 | IMPL( const IMPL & o ); 40 | ~IMPL(); 41 | 42 | int64_t _capacity; 43 | bool _isCharging; 44 | bool _isAvailable; 45 | 46 | static void init(); 47 | static void observe(); 48 | static BatteryInfo getBatteryInfo(); 49 | 50 | static std::recursive_mutex * rmtx; 51 | static BatteryInfo * info; 52 | static bool observing; 53 | }; 54 | 55 | void BatteryInfo::startObserving() 56 | { 57 | BatteryInfo::IMPL::init(); 58 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 59 | 60 | if( IMPL::observing ) 61 | { 62 | return; 63 | } 64 | 65 | IMPL::observing = true; 66 | 67 | SB::UpdateQueue::shared().registerUpdate( [] { IMPL::observe(); } ); 68 | } 69 | 70 | BatteryInfo BatteryInfo::current() 71 | { 72 | BatteryInfo::IMPL::init(); 73 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 74 | 75 | return *( IMPL::info ); 76 | } 77 | 78 | BatteryInfo::BatteryInfo( int64_t capacity, bool isCharging, bool isAvailable ): 79 | impl( std::make_unique< IMPL >( capacity, isCharging, isAvailable ) ) 80 | {} 81 | 82 | BatteryInfo::BatteryInfo( const BatteryInfo & o ): 83 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 84 | {} 85 | 86 | BatteryInfo::BatteryInfo( BatteryInfo && o ) noexcept: 87 | impl( std::move( o.impl ) ) 88 | {} 89 | 90 | BatteryInfo::~BatteryInfo() 91 | {} 92 | 93 | BatteryInfo & BatteryInfo::operator =( BatteryInfo o ) 94 | { 95 | swap( *( this ), o ); 96 | 97 | return *( this ); 98 | } 99 | 100 | int64_t BatteryInfo::capacity() const 101 | { 102 | return this->impl->_capacity; 103 | } 104 | 105 | bool BatteryInfo::isCharging() const 106 | { 107 | return this->impl->_isCharging; 108 | } 109 | 110 | bool BatteryInfo::isAvailable() const 111 | { 112 | return this->impl->_isAvailable; 113 | } 114 | 115 | void swap( BatteryInfo & o1, BatteryInfo & o2 ) 116 | { 117 | using std::swap; 118 | 119 | swap( o1.impl, o2.impl ); 120 | } 121 | 122 | BatteryInfo::IMPL::IMPL( int64_t capacity, bool isCharging, bool isAvailable ): 123 | _capacity( capacity ), 124 | _isCharging( isCharging ), 125 | _isAvailable( isAvailable ) 126 | {} 127 | 128 | BatteryInfo::IMPL::IMPL( const IMPL & o ): 129 | _capacity( o._capacity ), 130 | _isCharging( o._isCharging ), 131 | _isAvailable( o._isAvailable ) 132 | {} 133 | 134 | BatteryInfo::IMPL::~IMPL() 135 | {} 136 | 137 | void BatteryInfo::IMPL::init() 138 | { 139 | static std::once_flag once; 140 | 141 | std::call_once 142 | ( 143 | once, 144 | [] 145 | { 146 | rmtx = new std::recursive_mutex(); 147 | info = new BatteryInfo( 0, false, false ); 148 | } 149 | ); 150 | } 151 | 152 | void BatteryInfo::IMPL::observe() 153 | { 154 | BatteryInfo current = IMPL::getBatteryInfo(); 155 | 156 | { 157 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 158 | 159 | delete IMPL::info; 160 | 161 | IMPL::info = new BatteryInfo( current ); 162 | } 163 | } 164 | 165 | BatteryInfo BatteryInfo::IMPL::getBatteryInfo() 166 | { 167 | CFTypeRef blob = IOPSCopyPowerSourcesInfo(); 168 | 169 | if( blob == nullptr ) 170 | { 171 | return { 0, false, false }; 172 | } 173 | 174 | CFArrayRef sources = IOPSCopyPowerSourcesList( blob ); 175 | 176 | if( sources == nullptr ) 177 | { 178 | CFRelease( blob ); 179 | 180 | return { 0, false, false }; 181 | } 182 | 183 | for( CFIndex i = 0; i < CFArrayGetCount( sources ); i++ ) 184 | { 185 | CFDictionaryRef description = IOPSGetPowerSourceDescription( blob, CFArrayGetValueAtIndex( sources, i ) ); 186 | 187 | if( description == nullptr ) 188 | { 189 | continue; 190 | } 191 | 192 | CFStringRef type = reinterpret_cast< CFStringRef >( CFDictionaryGetValue( description, CFSTR( "Type" ) ) ); 193 | CFBooleanRef charging = reinterpret_cast< CFBooleanRef >( CFDictionaryGetValue( description, CFSTR( "Is Charging" ) ) ); 194 | CFBooleanRef charged = reinterpret_cast< CFBooleanRef >( CFDictionaryGetValue( description, CFSTR( "Is Charged" ) ) ); 195 | CFNumberRef capacity = reinterpret_cast< CFNumberRef >( CFDictionaryGetValue( description, CFSTR( "Current Capacity" ) ) ); 196 | 197 | if( type == nullptr || CFGetTypeID( type ) != CFStringGetTypeID() || CFEqual( type, CFSTR( "InternalBattery" ) ) == false ) 198 | { 199 | continue; 200 | } 201 | 202 | if( charging == nullptr || CFGetTypeID( charging ) != CFBooleanGetTypeID() ) 203 | { 204 | continue; 205 | } 206 | 207 | if( capacity == nullptr || CFGetTypeID( capacity ) != CFNumberGetTypeID() ) 208 | { 209 | continue; 210 | } 211 | 212 | int64_t currentCapacity = 0; 213 | 214 | CFNumberGetValue( capacity, kCFNumberSInt64Type, ¤tCapacity ); 215 | 216 | CFRelease( sources ); 217 | CFRelease( blob ); 218 | 219 | return 220 | { 221 | currentCapacity, 222 | CFBooleanGetValue( charging ) == 1 || ( charged != nullptr && CFBooleanGetValue( charged ) == 1 ), 223 | true 224 | }; 225 | } 226 | 227 | CFRelease( sources ); 228 | CFRelease( blob ); 229 | 230 | return { 0, false, false }; 231 | } 232 | 233 | std::recursive_mutex * BatteryInfo::IMPL::rmtx = nullptr; 234 | BatteryInfo * BatteryInfo::IMPL::info = nullptr; 235 | bool BatteryInfo::IMPL::observing = false; 236 | } 237 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/BatteryInfo.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_BATTERY_INFO_HPP 26 | #define SB_BATTERY_INFO_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace SB 34 | { 35 | class BatteryInfo 36 | { 37 | public: 38 | 39 | static void startObserving(); 40 | static BatteryInfo current(); 41 | 42 | BatteryInfo( const BatteryInfo & o ); 43 | BatteryInfo( BatteryInfo && o ) noexcept; 44 | ~BatteryInfo(); 45 | 46 | BatteryInfo & operator =( BatteryInfo o ); 47 | 48 | int64_t capacity() const; 49 | bool isCharging() const; 50 | bool isAvailable() const; 51 | 52 | friend void swap( BatteryInfo & o1, BatteryInfo & o2 ); 53 | 54 | private: 55 | 56 | BatteryInfo( int64_t capacity, bool isCharging, bool isAvailable ); 57 | 58 | class IMPL; 59 | std::unique_ptr< IMPL > impl; 60 | }; 61 | } 62 | 63 | #endif /* SB_BATTERY_INFO_HPP */ 64 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/CPULoad.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/CPULoad.hpp" 26 | #include "SB/Helpers/Vector.hpp" 27 | #include "SB/SleepManager.hpp" 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace SB 34 | { 35 | class CPULoad::IMPL 36 | { 37 | public: 38 | 39 | IMPL( double user, double system, double idle, double total ); 40 | IMPL( const IMPL & o ); 41 | ~IMPL(); 42 | 43 | double _user; 44 | double _system; 45 | double _idle; 46 | double _total; 47 | 48 | typedef struct 49 | { 50 | int64_t user; 51 | int64_t system; 52 | int64_t idle; 53 | int64_t nice; 54 | } 55 | CPULoadInfo; 56 | 57 | static void init(); 58 | static void observe() __attribute__( ( noreturn ) ); 59 | static std::vector< CPULoadInfo > getCPULoadInfo(); 60 | 61 | static std::recursive_mutex * rmtx; 62 | static CPULoad * load; 63 | static bool observing; 64 | static bool sleeping; 65 | static UUID * sleepRegistration; 66 | }; 67 | 68 | void CPULoad::startObserving() 69 | { 70 | CPULoad::IMPL::init(); 71 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 72 | 73 | if( IMPL::observing ) 74 | { 75 | return; 76 | } 77 | 78 | IMPL::observing = true; 79 | 80 | std::thread( [] { CPULoad::IMPL::observe(); } ).detach(); 81 | } 82 | 83 | CPULoad CPULoad::current() 84 | { 85 | CPULoad::IMPL::init(); 86 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 87 | 88 | return *( IMPL::load ); 89 | } 90 | 91 | CPULoad::CPULoad( double user, double system, double idle, double total ): 92 | impl( std::make_unique< IMPL >( user, system, idle, total ) ) 93 | {} 94 | 95 | CPULoad::CPULoad( const CPULoad & o ): 96 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 97 | {} 98 | 99 | CPULoad::CPULoad( CPULoad && o ) noexcept: 100 | impl( std::move( o.impl ) ) 101 | {} 102 | 103 | CPULoad::~CPULoad() 104 | {} 105 | 106 | CPULoad & CPULoad::operator =( CPULoad o ) 107 | { 108 | swap( *( this ), o ); 109 | 110 | return *( this ); 111 | } 112 | 113 | double CPULoad::user() const 114 | { 115 | return this->impl->_user; 116 | } 117 | 118 | double CPULoad::system() const 119 | { 120 | return this->impl->_system; 121 | } 122 | 123 | double CPULoad::idle() const 124 | { 125 | return this->impl->_idle; 126 | } 127 | 128 | double CPULoad::total() const 129 | { 130 | return this->impl->_total; 131 | } 132 | 133 | void swap( CPULoad & o1, CPULoad & o2 ) 134 | { 135 | using std::swap; 136 | 137 | swap( o1.impl, o2.impl ); 138 | } 139 | 140 | CPULoad::IMPL::IMPL( double user, double system, double idle, double total ): 141 | _user( user ), 142 | _system( system ), 143 | _idle( idle ), 144 | _total( total ) 145 | {} 146 | 147 | CPULoad::IMPL::IMPL( const IMPL & o ): 148 | _user( o._user ), 149 | _system( o._system ), 150 | _idle( o._idle ), 151 | _total( o._total ) 152 | {} 153 | 154 | CPULoad::IMPL::~IMPL() 155 | {} 156 | 157 | void CPULoad::IMPL::init() 158 | { 159 | static std::once_flag once; 160 | 161 | std::call_once 162 | ( 163 | once, 164 | [] 165 | { 166 | rmtx = new std::recursive_mutex(); 167 | load = new CPULoad( 0, 0, 0, 0 ); 168 | sleeping = false; 169 | sleepRegistration = new UUID 170 | ( 171 | SleepManager::shared().subscribe 172 | ( 173 | []( SleepManager::Event e ) 174 | { 175 | std::lock_guard< std::recursive_mutex > l( *( rmtx ) ); 176 | 177 | if( e == SleepManager::Event::WillSleep ) 178 | { 179 | sleeping = true; 180 | } 181 | else if( e == SleepManager::Event::DidPowerOn ) 182 | { 183 | sleeping = false; 184 | } 185 | } 186 | ) 187 | ); 188 | } 189 | ); 190 | } 191 | 192 | void CPULoad::IMPL::observe() 193 | { 194 | while( true ) 195 | { 196 | if( sleeping ) 197 | { 198 | std::this_thread::sleep_for( std::chrono::seconds( 5 ) ); 199 | 200 | continue; 201 | } 202 | 203 | std::vector< CPULoadInfo > info1 = IMPL::getCPULoadInfo(); 204 | 205 | std::this_thread::sleep_for( std::chrono::seconds( 1 ) ); 206 | 207 | std::vector< CPULoadInfo > info2 = IMPL::getCPULoadInfo(); 208 | 209 | int64_t user1 = Vector::reduce< int64_t, CPULoadInfo >( info1, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.user; } ); 210 | int64_t user2 = Vector::reduce< int64_t, CPULoadInfo >( info2, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.user; } ); 211 | int64_t system2 = Vector::reduce< int64_t, CPULoadInfo >( info2, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.system; } ); 212 | int64_t system1 = Vector::reduce< int64_t, CPULoadInfo >( info1, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.system; } ); 213 | int64_t idle1 = Vector::reduce< int64_t, CPULoadInfo >( info1, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.idle; } ); 214 | int64_t idle2 = Vector::reduce< int64_t, CPULoadInfo >( info2, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.idle; } ); 215 | int64_t nice1 = Vector::reduce< int64_t, CPULoadInfo >( info1, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.nice; } ); 216 | int64_t nice2 = Vector::reduce< int64_t, CPULoadInfo >( info2, 0, []( int64_t r, CPULoadInfo v ) -> int64_t { return r + v.nice; } ); 217 | 218 | double user = static_cast< double >( user2 - user1 ); 219 | double system = static_cast< double >( system2 - system1 ); 220 | double idle = static_cast< double >( idle2 - idle1 ); 221 | double used = static_cast< double >( ( user2 - user1 ) + ( system2 - system1 ) + ( nice2 - nice1 ) ); 222 | double total = used + static_cast< double >( idle2 - idle1 ); 223 | 224 | { 225 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 226 | 227 | delete IMPL::load; 228 | 229 | IMPL::load = new CPULoad 230 | ( 231 | ( user / total ) * 100.0, 232 | ( system / total ) * 100.0, 233 | ( idle / total ) * 100.0, 234 | ( used / total ) * 100.0 235 | ); 236 | } 237 | } 238 | } 239 | 240 | std::vector< CPULoad::IMPL::CPULoadInfo > CPULoad::IMPL::getCPULoadInfo() 241 | { 242 | std::vector< CPULoad::IMPL::CPULoadInfo > info = {}; 243 | natural_t cpuCount = 0; 244 | processor_info_array_t cpuLoadInfo = nullptr; 245 | mach_msg_type_number_t cpuLoadInfoCount = 0; 246 | 247 | if 248 | ( 249 | host_processor_info 250 | ( 251 | mach_host_self(), 252 | PROCESSOR_CPU_LOAD_INFO, 253 | &cpuCount, 254 | &cpuLoadInfo, 255 | &cpuLoadInfoCount 256 | ) 257 | != KERN_SUCCESS || cpuLoadInfo == nullptr 258 | ) 259 | { 260 | return info; 261 | } 262 | 263 | for( natural_t i = 0; i < cpuCount; i++ ) 264 | { 265 | info.push_back 266 | ( 267 | { 268 | cpuLoadInfo[ ( i * CPU_STATE_MAX ) + CPU_STATE_USER ], 269 | cpuLoadInfo[ ( i * CPU_STATE_MAX ) + CPU_STATE_SYSTEM ], 270 | cpuLoadInfo[ ( i * CPU_STATE_MAX ) + CPU_STATE_IDLE ], 271 | cpuLoadInfo[ ( i * CPU_STATE_MAX ) + CPU_STATE_NICE ] 272 | } 273 | ); 274 | } 275 | 276 | vm_deallocate( mach_task_self(), reinterpret_cast< vm_address_t >( cpuLoadInfo ), sizeof( processor_info_array_t ) * cpuLoadInfoCount ); 277 | 278 | return info; 279 | } 280 | 281 | std::recursive_mutex * CPULoad::IMPL::rmtx = nullptr; 282 | CPULoad * CPULoad::IMPL::load = nullptr; 283 | bool CPULoad::IMPL::observing = false; 284 | bool CPULoad::IMPL::sleeping = false; 285 | UUID * CPULoad::IMPL::sleepRegistration = nullptr; 286 | } 287 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/CPULoad.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_CPU_LOAD_HPP 26 | #define SB_CPU_LOAD_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace SB 34 | { 35 | class CPULoad 36 | { 37 | public: 38 | 39 | static void startObserving(); 40 | static CPULoad current(); 41 | 42 | CPULoad( const CPULoad & o ); 43 | CPULoad( CPULoad && o ) noexcept; 44 | ~CPULoad(); 45 | 46 | CPULoad & operator =( CPULoad o ); 47 | 48 | double user() const; 49 | double system() const; 50 | double idle() const; 51 | double total() const; 52 | 53 | friend void swap( CPULoad & o1, CPULoad & o2 ); 54 | 55 | private: 56 | 57 | CPULoad( double user, double system, double idle, double total ); 58 | 59 | class IMPL; 60 | std::unique_ptr< IMPL > impl; 61 | }; 62 | } 63 | 64 | #endif /* SB_CPU_LOAD_HPP */ 65 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/GPULoad.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/GPULoad.hpp" 26 | #include "SB/UpdateQueue.hpp" 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace SB 34 | { 35 | class GPULoad::IMPL 36 | { 37 | public: 38 | 39 | IMPL( double percent ); 40 | IMPL( const IMPL & o ); 41 | ~IMPL(); 42 | 43 | double _percent; 44 | 45 | static void init(); 46 | static void observe(); 47 | static GPULoad getGPULoad(); 48 | 49 | static std::recursive_mutex * rmtx; 50 | static GPULoad * info; 51 | static bool observing; 52 | }; 53 | 54 | void GPULoad::startObserving() 55 | { 56 | GPULoad::IMPL::init(); 57 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 58 | 59 | if( IMPL::observing ) 60 | { 61 | return; 62 | } 63 | 64 | IMPL::observing = true; 65 | 66 | SB::UpdateQueue::shared().registerUpdate( [] { IMPL::observe(); } ); 67 | } 68 | 69 | GPULoad GPULoad::current() 70 | { 71 | GPULoad::IMPL::init(); 72 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 73 | 74 | return *( IMPL::info ); 75 | } 76 | 77 | GPULoad::GPULoad( double percent ): 78 | impl( std::make_unique< IMPL >( percent ) ) 79 | {} 80 | 81 | GPULoad::GPULoad( const GPULoad & o ): 82 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 83 | {} 84 | 85 | GPULoad::GPULoad( GPULoad && o ) noexcept: 86 | impl( std::move( o.impl ) ) 87 | {} 88 | 89 | GPULoad::~GPULoad() 90 | {} 91 | 92 | GPULoad & GPULoad::operator =( GPULoad o ) 93 | { 94 | swap( *( this ), o ); 95 | 96 | return *( this ); 97 | } 98 | 99 | double GPULoad::percent() const 100 | { 101 | return this->impl->_percent; 102 | } 103 | 104 | void swap( GPULoad & o1, GPULoad & o2 ) 105 | { 106 | using std::swap; 107 | 108 | swap( o1.impl, o2.impl ); 109 | } 110 | 111 | GPULoad::IMPL::IMPL( double percent ): 112 | _percent( percent ) 113 | {} 114 | 115 | GPULoad::IMPL::IMPL( const IMPL & o ): 116 | _percent( o._percent ) 117 | {} 118 | 119 | GPULoad::IMPL::~IMPL() 120 | {} 121 | 122 | void GPULoad::IMPL::init() 123 | { 124 | static std::once_flag once; 125 | 126 | std::call_once 127 | ( 128 | once, 129 | [] 130 | { 131 | rmtx = new std::recursive_mutex(); 132 | info = new GPULoad( 0 ); 133 | } 134 | ); 135 | } 136 | 137 | void GPULoad::IMPL::observe() 138 | { 139 | GPULoad current = IMPL::getGPULoad(); 140 | 141 | { 142 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 143 | 144 | delete IMPL::info; 145 | 146 | IMPL::info = new GPULoad( current ); 147 | } 148 | } 149 | 150 | GPULoad GPULoad::IMPL::getGPULoad() 151 | { 152 | CFMutableDictionaryRef matching = IOServiceMatching( kIOAcceleratorClassName ); 153 | io_iterator_t iterator; 154 | 155 | if( IOServiceGetMatchingServices( kIOMasterPortDefault, matching, &iterator ) != kIOReturnSuccess ) 156 | { 157 | return { -1 }; 158 | } 159 | 160 | io_registry_entry_t entry; 161 | double device = -1; 162 | double renderer = -1; 163 | double tiler = -1; 164 | 165 | while( ( entry = IOIteratorNext( iterator ) ) ) 166 | { 167 | CFMutableDictionaryRef properties; 168 | 169 | if( IORegistryEntryCreateCFProperties( entry, &properties, kCFAllocatorDefault, kNilOptions ) != kIOReturnSuccess ) 170 | { 171 | IOObjectRelease( entry ); 172 | 173 | continue; 174 | } 175 | 176 | CFDictionaryRef stats = static_cast< CFDictionaryRef >( CFDictionaryGetValue( properties, CFSTR( "PerformanceStatistics" ) ) ); 177 | 178 | if( stats != nullptr && CFGetTypeID( stats ) == CFDictionaryGetTypeID() ) 179 | { 180 | CFNumberRef cfDevice = static_cast< CFNumberRef >( CFDictionaryGetValue( stats, CFSTR( "Device Utilization %" ) ) ); 181 | CFNumberRef cfRenderer = static_cast< CFNumberRef >( CFDictionaryGetValue( stats, CFSTR( "Renderer Utilization %" ) ) ); 182 | CFNumberRef cfTiler = static_cast< CFNumberRef >( CFDictionaryGetValue( stats, CFSTR( "Tiler Utilization %" ) ) ); 183 | 184 | if( cfDevice != nullptr && CFGetTypeID( cfDevice ) == CFNumberGetTypeID() ) 185 | { 186 | CFNumberGetValue( cfDevice, kCFNumberDoubleType, &device ); 187 | } 188 | 189 | if( cfRenderer != nullptr && CFGetTypeID( cfRenderer ) == CFNumberGetTypeID() ) 190 | { 191 | CFNumberGetValue( cfRenderer, kCFNumberDoubleType, &renderer ); 192 | } 193 | 194 | if( cfTiler != nullptr && CFGetTypeID( cfTiler ) == CFNumberGetTypeID() ) 195 | { 196 | CFNumberGetValue( cfTiler, kCFNumberDoubleType, &tiler ); 197 | } 198 | } 199 | 200 | CFRelease( properties ); 201 | IOObjectRelease( entry ); 202 | } 203 | 204 | IOObjectRelease( iterator ); 205 | 206 | return { std::max( std::max( device, renderer ), tiler ) }; 207 | } 208 | 209 | std::recursive_mutex * GPULoad::IMPL::rmtx = nullptr; 210 | GPULoad * GPULoad::IMPL::info = nullptr; 211 | bool GPULoad::IMPL::observing = false; 212 | } 213 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/GPULoad.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_GPU_LOAD_HPP 26 | #define SB_GPU_LOAD_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | class GPULoad 35 | { 36 | public: 37 | 38 | static void startObserving(); 39 | static GPULoad current(); 40 | 41 | GPULoad( const GPULoad & o ); 42 | GPULoad( GPULoad && o ) noexcept; 43 | ~GPULoad(); 44 | 45 | GPULoad & operator =( GPULoad o ); 46 | 47 | double percent() const; 48 | 49 | friend void swap( GPULoad & o1, GPULoad & o2 ); 50 | 51 | private: 52 | 53 | GPULoad( double percent ); 54 | 55 | class IMPL; 56 | std::unique_ptr< IMPL > impl; 57 | }; 58 | } 59 | 60 | #endif /* SB_GPU_LOAD_HPP */ 61 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/Internal/IOHID-Internal.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_IOHID_INTERNAL_HPP 26 | #define SB_IOHID_INTERNAL_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | /* @see https://opensource.apple.com/source/IOHIDFamily/ */ 35 | 36 | enum class IOHIDPage: int64_t 37 | { 38 | IOHIDPageAppleVendor = 0xFF00, 39 | IOHIDPageAppleVendorKeyboard = 0xFF01, 40 | IOHIDPageAppleVendorMouse = 0xFF02, 41 | IOHIDPageAppleVendorAccelerometer = 0xFF03, 42 | IOHIDPageAppleVendorAmbientLightSensor = 0xFF04, 43 | IOHIDPageAppleVendorTemperatureSensor = 0xFF05, 44 | IOHIDPageAppleVendorHeadset = 0xFF07, 45 | IOHIDPageAppleVendorPowerSensor = 0xFF08, 46 | IOHIDPageAppleVendorSmartCover = 0xFF09, 47 | IOHIDPageAppleVendorPlatinum = 0xFF0A, 48 | IOHIDPageAppleVendorLisa = 0xFF0B, 49 | IOHIDPageAppleVendorMotion = 0xFF0C, 50 | IOHIDPageAppleVendorBattery = 0xFF0D, 51 | IOHIDPageAppleVendorIRRemote = 0xFF0E, 52 | IOHIDPageAppleVendorDebug = 0xFF0F, 53 | IOHIDPageAppleVendorFilteredEvent = 0xFF50, 54 | IOHIDPageAppleVendorMultitouch = 0xFF60, 55 | IOHIDPageAppleVendorDisplay = 0xFF92, 56 | IOHIDPageAppleVendorTopCase = 0x00FF 57 | }; 58 | 59 | enum class IOHIDUsageAppleVendor: int64_t 60 | { 61 | IOHIDUsageAppleVendorTopCase = 0x01, 62 | IOHIDUsageAppleVendorDisplay = 0x02, 63 | IOHIDUsageAppleVendorAccelerometer = 0x03, 64 | IOHIDUsageAppleVendorAmbientLightSensor = 0x04, 65 | IOHIDUsageAppleVendorTemperatureSensor = 0x05, 66 | IOHIDUsageAppleVendorKeyboard = 0x06, 67 | IOHIDUsageAppleVendorHeadset = 0x07, 68 | IOHIDUsageAppleVendorProximitySensor = 0x08, 69 | IOHIDUsageAppleVendorGyro = 0x09, 70 | IOHIDUsageAppleVendorCompass = 0x0A, 71 | IOHIDUsageAppleVendorDeviceManagement = 0x0B, 72 | IOHIDUsageAppleVendorTrackpad = 0x0C, 73 | IOHIDUsageAppleVendorTopCaseReserved = 0x0D, 74 | IOHIDUsageAppleVendorMotion = 0x0E, 75 | IOHIDUsageAppleVendorKeyboardBacklight = 0x0F, 76 | IOHIDUsageAppleVendorDeviceMotionLite = 0x10, 77 | IOHIDUsageAppleVendorForce = 0x11, 78 | IOHIDUsageAppleVendorBluetoothRadio = 0x12, 79 | IOHIDUsageAppleVendorOrb = 0x13, 80 | IOHIDUsageAppleVendorAccessoryBattery = 0x14 81 | }; 82 | 83 | enum class IOHIDUsageAppleVendorPowerSensor: int64_t 84 | { 85 | IOHIDUsageAppleVendorPowerSensorPower = 0x1, 86 | IOHIDUsageAppleVendorPowerSensorCurrent = 0x2, 87 | IOHIDUsageAppleVendorPowerSensorVoltage = 0x3 88 | }; 89 | 90 | enum class IOHIDEvent: int64_t 91 | { 92 | IOHIDEventTypeNULL = 0x00, 93 | IOHIDEventTypeVendorDefined = 0x01, 94 | IOHIDEventTypeButton = 0x02, 95 | IOHIDEventTypeKeyboard = 0x03, 96 | IOHIDEventTypeTranslation = 0x04, 97 | IOHIDEventTypeRotation = 0x05, 98 | IOHIDEventTypeScroll = 0x06, 99 | IOHIDEventTypeScale = 0x07, 100 | IOHIDEventTypeZoom = 0x08, 101 | IOHIDEventTypeVelocity = 0x09, 102 | IOHIDEventTypeOrientation = 0x0A, 103 | IOHIDEventTypeDigitizer = 0x0B, 104 | IOHIDEventTypeAmbientLightSensor = 0x0C, 105 | IOHIDEventTypeAccelerometer = 0x0D, 106 | IOHIDEventTypeProximity = 0x0E, 107 | IOHIDEventTypeTemperature = 0x0F, 108 | IOHIDEventTypeNavigationSwipe = 0x10, 109 | IOHIDEventTypeSwipe = IOHIDEventTypeNavigationSwipe, 110 | IOHIDEventTypeMouse = 0x11, 111 | IOHIDEventTypeProgress = 0x12, 112 | IOHIDEventTypeCount = 0x13, 113 | IOHIDEventTypeGyro = 0x14, 114 | IOHIDEventTypeCompass = 0x15, 115 | IOHIDEventTypeZoomToggle = 0x16, 116 | IOHIDEventTypeDockSwipe = 0x17, 117 | IOHIDEventTypeSymbolicHotKey = 0x18, 118 | IOHIDEventTypePower = 0x19, 119 | IOHIDEventTypeBrightness = 0x1A, 120 | IOHIDEventTypeFluidTouchGesture = 0x1B, 121 | IOHIDEventTypeBoundaryScroll = 0x1C, 122 | IOHIDEventTypeReset = 0x1D 123 | }; 124 | 125 | #define IOHIDEventFieldBase( _type_ ) ( _type_ << 16 ) 126 | 127 | enum class IOHIDEventField: int64_t 128 | { 129 | IOHIDEventFieldTemperatureLevel = IOHIDEventFieldBase( static_cast< int64_t >( IOHIDEvent::IOHIDEventTypeTemperature ) ), 130 | IOHIDEventFieldPowerMeasurement = IOHIDEventFieldBase( static_cast< int64_t >( IOHIDEvent::IOHIDEventTypePower ) ), 131 | IOHIDEventFieldAmbientLightMeasurement = IOHIDEventFieldBase( static_cast< int64_t >( IOHIDEvent::IOHIDEventTypeAmbientLightSensor ) ) 132 | }; 133 | 134 | extern "C" 135 | { 136 | extern IOHIDEventSystemClientRef IOHIDEventSystemClientCreate( CFAllocatorRef ); 137 | extern void IOHIDEventSystemClientSetMatching( IOHIDEventSystemClientRef, CFDictionaryRef ); 138 | extern CFTypeRef IOHIDServiceClientCopyEvent( IOHIDServiceClientRef, int64_t, int64_t, int64_t ); 139 | extern CFDictionaryRef IOHIDServiceClientCopyProperties( IOHIDServiceClientRef, CFArrayRef ); 140 | extern double IOHIDEventGetFloatValue( CFTypeRef, int64_t ); 141 | } 142 | 143 | #endif /* SB_IOHID_INTERNAL_HPP */ 144 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/Internal/IOHID.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/Internal/IOHID.hpp" 26 | 27 | namespace SB 28 | { 29 | namespace IOHID 30 | { 31 | std::map< std::string, double > read( IOHIDEventSystemClientRef client, int64_t page, int64_t usage, int64_t eventType, int64_t eventField ) 32 | { 33 | if( client == nullptr ) 34 | { 35 | return {}; 36 | } 37 | 38 | CFDictionaryRef filter = nullptr; 39 | 40 | { 41 | CFNumberRef cfPage = CFNumberCreate( nullptr, kCFNumberSInt64Type, &page ); 42 | CFNumberRef cfUsage = CFNumberCreate( nullptr, kCFNumberSInt64Type, &usage ); 43 | 44 | CFTypeRef keys[] = { CFSTR( "PrimaryUsagePage" ), CFSTR( "PrimaryUsage" ) }; 45 | CFTypeRef values[] = { cfPage, cfUsage }; 46 | 47 | filter = CFDictionaryCreate( nullptr, keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); 48 | 49 | CFRelease( cfPage ); 50 | CFRelease( cfUsage ); 51 | } 52 | 53 | IOHIDEventSystemClientSetMatching( client, filter ); 54 | CFRelease( filter ); 55 | 56 | CFArrayRef services = IOHIDEventSystemClientCopyServices( client ); 57 | 58 | if( services == nullptr ) 59 | { 60 | return {}; 61 | } 62 | 63 | std::map< std::string, double > values; 64 | 65 | for( CFIndex i = 0; i < CFArrayGetCount( services ); i++ ) 66 | { 67 | IOHIDServiceClientRef service = reinterpret_cast< IOHIDServiceClientRef >( const_cast< void * >( CFArrayGetValueAtIndex( services, i ) ) ); 68 | CFStringRef name = reinterpret_cast< CFStringRef >( IOHIDServiceClientCopyProperty( service, CFSTR( "Product" ) ) ); 69 | CFTypeRef event = IOHIDServiceClientCopyEvent( service, eventType, 0, 0 ); 70 | 71 | if( name != nullptr && event != nullptr ) 72 | { 73 | double value = IOHIDEventGetFloatValue( event, eventField ); 74 | const char * cName = CFStringGetCStringPtr( name, kCFStringEncodingUTF8 ); 75 | 76 | if( cName != nullptr ) 77 | { 78 | values[ cName ] = value; 79 | } 80 | } 81 | 82 | if( name != nullptr ) { CFRelease( name ); } 83 | if( event != nullptr ) { CFRelease( event ); } 84 | } 85 | 86 | CFRelease( services ); 87 | 88 | return values; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/Internal/IOHID.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_IOHID_HPP 26 | #define SB_IOHID_HPP 27 | 28 | #include "SB/Instruments/Internal/IOHID-Internal.h" 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | namespace IOHID 35 | { 36 | std::map< std::string, double > read( IOHIDEventSystemClientRef client, int64_t page, int64_t usage, int64_t eventType, int64_t eventField ); 37 | } 38 | } 39 | 40 | #endif /* SB_IOHID_HPP */ 41 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/Internal/SMC-Internal.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_SMC_INTERNAL_HPP 26 | #define SB_SMC_INTERNAL_HPP 27 | 28 | #include 29 | 30 | /* 31 | * Reference: 32 | * - https://github.com/apple-oss-distributions/IOKitUser 33 | * - https://opensource.apple.com/source/IOKitUser/ 34 | * - https://opensource.apple.com/source/IOKitUser/IOKitUser-647.6/pwr_mgt.subproj/IOPMLibPrivate.c 35 | */ 36 | 37 | /* Do not modify - defined by AppleSMC.kext */ 38 | enum 39 | { 40 | kSMCKeyNotFound = 0x84 41 | }; 42 | 43 | /* Do not modify - defined by AppleSMC.kext */ 44 | enum 45 | { 46 | kSMCSuccess = 0, 47 | kSMCError = 1 48 | }; 49 | 50 | /* Do not modify - defined by AppleSMC.kext */ 51 | enum 52 | { 53 | kSMCUserClientOpen = 0, 54 | kSMCUserClientClose = 1, 55 | kSMCHandleYPCEvent = 2, 56 | kSMCReadKey = 5, 57 | kSMCWriteKey = 6, 58 | kSMCGetKeyCount = 7, 59 | kSMCGetKeyFromIndex = 8, 60 | kSMCGetKeyInfo = 9 61 | }; 62 | 63 | /* Do not modify - defined by AppleSMC.kext */ 64 | typedef struct 65 | { 66 | unsigned char major; 67 | unsigned char minor; 68 | unsigned char build; 69 | unsigned char reserved; 70 | unsigned short release; 71 | } 72 | SMCVersion; 73 | 74 | /* Do not modify - defined by AppleSMC.kext */ 75 | typedef struct 76 | { 77 | uint16_t version; 78 | uint16_t length; 79 | uint32_t cpuPLimit; 80 | uint32_t gpuPLimit; 81 | uint32_t memPLimit; 82 | } 83 | SMCPLimitData; 84 | 85 | /* Do not modify - defined by AppleSMC.kext */ 86 | typedef struct 87 | { 88 | uint32_t dataSize; 89 | uint32_t dataType; 90 | uint8_t dataAttributes; 91 | } 92 | SMCKeyInfoData; 93 | 94 | /* Do not modify - defined by AppleSMC.kext */ 95 | typedef struct 96 | { 97 | uint32_t key; 98 | SMCVersion vers; 99 | SMCPLimitData pLimitData; 100 | SMCKeyInfoData keyInfo; 101 | uint8_t result; 102 | uint8_t status; 103 | uint8_t data8; 104 | uint32_t data32; 105 | uint8_t bytes[ 32 ]; 106 | } 107 | SMCParamStruct; 108 | 109 | extern const uint32_t kSMCKeyNKEY; 110 | extern const uint32_t kSMCKeyACID; 111 | 112 | #endif /* SB_SMC_INTERNAL_HPP */ 113 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/Internal/SMC.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/Internal/SMC.hpp" 26 | #include 27 | 28 | #pragma clang diagnostic push 29 | #pragma clang diagnostic ignored "-Wfour-char-constants" 30 | 31 | const uint32_t kSMCKeyNKEY = '#KEY'; 32 | const uint32_t kSMCKeyACID = 'ACID'; 33 | 34 | #pragma clang diagnostic push 35 | 36 | namespace SB 37 | { 38 | namespace SMC 39 | { 40 | bool callSMCFunction( io_connect_t connection, uint32_t function, const SMCParamStruct & input, SMCParamStruct & output ) 41 | { 42 | if( connection == IO_OBJECT_NULL ) 43 | { 44 | return false; 45 | } 46 | 47 | size_t inputSize = sizeof( SMCParamStruct ); 48 | size_t outputSize = sizeof( SMCParamStruct ); 49 | kern_return_t result = IOConnectCallMethod( connection, kSMCUserClientOpen, nullptr, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr ); 50 | 51 | if( result != kIOReturnSuccess ) 52 | { 53 | return false; 54 | } 55 | 56 | result = IOConnectCallStructMethod( connection, function, &input, inputSize, &output, &outputSize ); 57 | 58 | IOConnectCallMethod( connection, kSMCUserClientClose, nullptr, 0, nullptr, 0, nullptr, nullptr, nullptr, nullptr ); 59 | 60 | return result == kIOReturnSuccess; 61 | } 62 | 63 | bool readSMCKeyInfo( io_connect_t connection, SMCKeyInfoData & info, uint32_t key, std::map< uint32_t, SMCKeyInfoData > & cache ) 64 | { 65 | if( connection == IO_OBJECT_NULL || key == 0 ) 66 | { 67 | return false; 68 | } 69 | 70 | if( cache.find( key ) != cache.end() ) 71 | { 72 | info = cache[ key ]; 73 | 74 | return true; 75 | } 76 | 77 | SMCParamStruct input; 78 | SMCParamStruct output; 79 | 80 | bzero( &input, sizeof( SMCParamStruct ) ); 81 | bzero( &output, sizeof( SMCParamStruct ) ); 82 | 83 | input.data8 = kSMCGetKeyInfo; 84 | input.key = key; 85 | 86 | if( SMC::callSMCFunction( connection, kSMCHandleYPCEvent, input, output ) == false ) 87 | { 88 | return false; 89 | } 90 | 91 | if( output.result != kSMCSuccess ) 92 | { 93 | return false; 94 | } 95 | 96 | info = output.keyInfo; 97 | cache[ key ] = output.keyInfo; 98 | 99 | return true; 100 | } 101 | 102 | bool readSMCKey( io_connect_t connection, uint32_t & key, uint32_t index ) 103 | { 104 | if( connection == IO_OBJECT_NULL ) 105 | { 106 | return false; 107 | } 108 | 109 | SMCParamStruct input; 110 | SMCParamStruct output; 111 | 112 | bzero( &input, sizeof( SMCParamStruct ) ); 113 | bzero( &output, sizeof( SMCParamStruct ) ); 114 | 115 | input.data8 = kSMCGetKeyFromIndex; 116 | input.data32 = index; 117 | 118 | if( SMC::callSMCFunction( connection, kSMCHandleYPCEvent, input, output ) == false ) 119 | { 120 | return false; 121 | } 122 | 123 | if( output.result != kSMCSuccess ) 124 | { 125 | return false; 126 | } 127 | 128 | key = output.key; 129 | 130 | return true; 131 | } 132 | 133 | bool readSMCKey( io_connect_t connection, uint32_t key, uint8_t * buffer, uint32_t & maxSize, SMCKeyInfoData & keyInfo, std::map< uint32_t, SMCKeyInfoData > & cache ) 134 | { 135 | if( connection == IO_OBJECT_NULL || key == 0 || buffer == nullptr ) 136 | { 137 | return false; 138 | } 139 | 140 | SMCKeyInfoData info; 141 | 142 | if( SMC::readSMCKeyInfo( connection, info, key, cache ) == false ) 143 | { 144 | return false; 145 | } 146 | 147 | SMCParamStruct input; 148 | SMCParamStruct output; 149 | 150 | bzero( &input, sizeof( SMCParamStruct ) ); 151 | bzero( &output, sizeof( SMCParamStruct ) ); 152 | 153 | input.key = key; 154 | input.data8 = kSMCReadKey; 155 | input.keyInfo.dataSize = info.dataSize; 156 | 157 | if( SMC::callSMCFunction( connection, kSMCHandleYPCEvent, input, output ) == false ) 158 | { 159 | return false; 160 | } 161 | 162 | if( output.result != kSMCSuccess ) 163 | { 164 | return false; 165 | } 166 | 167 | if( maxSize < info.dataSize ) 168 | { 169 | return false; 170 | } 171 | 172 | keyInfo = info; 173 | maxSize = info.dataSize; 174 | 175 | bzero( buffer, maxSize ); 176 | 177 | for( uint32_t i = 0; i < info.dataSize; i++ ) 178 | { 179 | if( key == kSMCKeyACID ) 180 | { 181 | buffer[ i ] = output.bytes[ i ]; 182 | } 183 | else 184 | { 185 | buffer[ i ] = output.bytes[ info.dataSize - ( i + 1 ) ]; 186 | } 187 | } 188 | 189 | return true; 190 | } 191 | 192 | uint32_t readSMCKeyCount( io_connect_t connection, std::map< uint32_t, SMCKeyInfoData > & cache ) 193 | { 194 | uint8_t data[ 8 ]; 195 | uint32_t size = sizeof( data ); 196 | SMCKeyInfoData keyInfo; 197 | 198 | bzero( data, size ); 199 | 200 | if( SMC::readSMCKey( connection, kSMCKeyNKEY, data, size, keyInfo, cache ) == false ) 201 | { 202 | return 0; 203 | } 204 | 205 | return SMC::readInteger( data, size ); 206 | } 207 | 208 | uint32_t readInteger( uint8_t * data, uint32_t size ) 209 | { 210 | uint32_t n = 0; 211 | 212 | if( size > sizeof( uint32_t ) ) 213 | { 214 | return 0; 215 | } 216 | 217 | for( uint32_t i = 0; i < size; i++ ) 218 | { 219 | n |= static_cast< uint32_t >( data[ i ] ) << ( i * 8 ); 220 | } 221 | 222 | return n; 223 | } 224 | 225 | uint32_t readUInt32( uint8_t * data, uint32_t size ) 226 | { 227 | if( size != 4 ) 228 | { 229 | return 0; 230 | } 231 | 232 | uint32_t u1 = static_cast< uint32_t >( data[ 0 ] ) << 24; 233 | uint32_t u2 = static_cast< uint32_t >( data[ 1 ] ) << 16; 234 | uint32_t u3 = static_cast< uint32_t >( data[ 2 ] ) << 8; 235 | uint32_t u4 = static_cast< uint32_t >( data[ 3 ] ) << 0; 236 | 237 | return u1 | u2 | u3 | u4; 238 | } 239 | 240 | uint64_t readUInt64( uint8_t * data, uint32_t size ) 241 | { 242 | if( size != 8 ) 243 | { 244 | return 0; 245 | } 246 | 247 | uint64_t u1 = static_cast< uint64_t >( data[ 0 ] ) << 56; 248 | uint64_t u2 = static_cast< uint64_t >( data[ 1 ] ) << 48; 249 | uint64_t u3 = static_cast< uint64_t >( data[ 2 ] ) << 40; 250 | uint64_t u4 = static_cast< uint64_t >( data[ 3 ] ) << 32; 251 | uint64_t u5 = static_cast< uint64_t >( data[ 4 ] ) << 24; 252 | uint64_t u6 = static_cast< uint64_t >( data[ 5 ] ) << 16; 253 | uint64_t u7 = static_cast< uint64_t >( data[ 6 ] ) << 8; 254 | uint64_t u8 = static_cast< uint64_t >( data[ 7 ] ) << 0; 255 | 256 | return u1 | u2 | u3 | u4 | u5 | u6 | u7 | u8; 257 | } 258 | 259 | double readFloat32( uint8_t * data, uint32_t size ) 260 | { 261 | if( size != 4 ) 262 | { 263 | return 0; 264 | } 265 | 266 | uint32_t u32 = SMC::readUInt32( data, size ); 267 | 268 | if( u32 == 0 ) 269 | { 270 | return 0; 271 | } 272 | 273 | return static_cast< double >( *( reinterpret_cast< float * >( &u32 ) ) ); 274 | } 275 | 276 | double readIOFloat( uint8_t * data, uint32_t size ) 277 | { 278 | if( size != 8 ) 279 | { 280 | return 0; 281 | } 282 | 283 | uint64_t u64 = SMC::readUInt64( data, size ); 284 | 285 | if( u64 == 0 ) 286 | { 287 | return 0; 288 | } 289 | 290 | double integral = static_cast< double >( u64 >> 16 ); 291 | double mask = pow( 2.0, 16.0 ) - 1; 292 | double fractional = static_cast< double >( u64 & static_cast< uint64_t >( mask ) ) / static_cast< double >( 1 << 16 ); 293 | 294 | return integral + fractional; 295 | } 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/Internal/SMC.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_SMC_HPP 26 | #define SB_SMC_HPP 27 | 28 | #include "SB/Instruments/Internal/SMC-Internal.h" 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | namespace SMC 35 | { 36 | bool callSMCFunction( io_connect_t connection, uint32_t function, const SMCParamStruct & input, SMCParamStruct & output ); 37 | bool readSMCKeyInfo( io_connect_t connection, SMCKeyInfoData & info, uint32_t key, std::map< uint32_t, SMCKeyInfoData > & cache ); 38 | bool readSMCKey( io_connect_t connection, uint32_t & key, uint32_t index ); 39 | bool readSMCKey( io_connect_t connection, uint32_t key, uint8_t * buffer, uint32_t & maxSize, SMCKeyInfoData & keyInfo, std::map< uint32_t, SMCKeyInfoData > & cache ); 40 | uint32_t readSMCKeyCount( io_connect_t connection, std::map< uint32_t, SMCKeyInfoData > & cache ); 41 | uint32_t readInteger( uint8_t * data, uint32_t size ); 42 | uint32_t readUInt32( uint8_t * data, uint32_t size ); 43 | uint64_t readUInt64( uint8_t * data, uint32_t size ); 44 | double readFloat32( uint8_t * data, uint32_t size ); 45 | double readFloat32( uint8_t * data, uint32_t size ); 46 | double readIOFloat( uint8_t * data, uint32_t size ); 47 | } 48 | } 49 | 50 | #endif /* SB_SMC_HPP */ 51 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/MemoryInfo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/MemoryInfo.hpp" 26 | #include "SB/UpdateQueue.hpp" 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | namespace SB 36 | { 37 | class MemoryInfo::IMPL 38 | { 39 | public: 40 | 41 | IMPL( uint64_t total, uint64_t wired, uint64_t active, uint64_t inactive, uint64_t free, uint64_t purgeable, uint64_t speculative ); 42 | IMPL( const IMPL & o ); 43 | ~IMPL(); 44 | 45 | uint64_t _total; 46 | uint64_t _wired; 47 | uint64_t _active; 48 | uint64_t _inactive; 49 | uint64_t _free; 50 | uint64_t _purgeable; 51 | uint64_t _speculative; 52 | 53 | static void init(); 54 | static void observe(); 55 | static MemoryInfo getMemoryInfo(); 56 | 57 | static std::recursive_mutex * rmtx; 58 | static MemoryInfo * info; 59 | static bool observing; 60 | }; 61 | 62 | void MemoryInfo::startObserving() 63 | { 64 | MemoryInfo::IMPL::init(); 65 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 66 | 67 | if( IMPL::observing ) 68 | { 69 | return; 70 | } 71 | 72 | IMPL::observing = true; 73 | 74 | SB::UpdateQueue::shared().registerUpdate( [] { IMPL::observe(); } ); 75 | } 76 | 77 | MemoryInfo MemoryInfo::current() 78 | { 79 | MemoryInfo::IMPL::init(); 80 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 81 | 82 | return *( IMPL::info ); 83 | } 84 | 85 | MemoryInfo::MemoryInfo( uint64_t total, uint64_t wired, uint64_t active, uint64_t inactive, uint64_t free, uint64_t purgeable, uint64_t speculative ): 86 | impl( std::make_unique< IMPL >( total, wired, active, inactive, free, purgeable, speculative ) ) 87 | {} 88 | 89 | MemoryInfo::MemoryInfo( const MemoryInfo & o ): 90 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 91 | {} 92 | 93 | MemoryInfo::MemoryInfo( MemoryInfo && o ) noexcept: 94 | impl( std::move( o.impl ) ) 95 | {} 96 | 97 | MemoryInfo::~MemoryInfo() 98 | {} 99 | 100 | MemoryInfo & MemoryInfo::operator =( MemoryInfo o ) 101 | { 102 | swap( *( this ), o ); 103 | 104 | return *( this ); 105 | } 106 | 107 | uint64_t MemoryInfo::total() const 108 | { 109 | return this->impl->_total; 110 | } 111 | 112 | uint64_t MemoryInfo::wired() const 113 | { 114 | return this->impl->_wired; 115 | } 116 | 117 | uint64_t MemoryInfo::active() const 118 | { 119 | return this->impl->_active; 120 | } 121 | 122 | uint64_t MemoryInfo::inactive() const 123 | { 124 | return this->impl->_inactive; 125 | } 126 | 127 | uint64_t MemoryInfo::free() const 128 | { 129 | return this->impl->_free; 130 | } 131 | 132 | uint64_t MemoryInfo::purgeable() const 133 | { 134 | return this->impl->_purgeable; 135 | } 136 | 137 | uint64_t MemoryInfo::speculative() const 138 | { 139 | return this->impl->_speculative; 140 | } 141 | 142 | uint64_t MemoryInfo::used() const 143 | { 144 | return ( ( this->wired() + this->active() + this->inactive() ) - this->speculative() ) - this->purgeable(); 145 | } 146 | 147 | double MemoryInfo::percentUsed() const 148 | { 149 | uint64_t total = this->total(); 150 | uint64_t used = this->used(); 151 | 152 | if( total == 0 ) 153 | { 154 | return 0; 155 | } 156 | 157 | return 100.0 * ( static_cast< double >( used ) / static_cast< double >( total ) ); 158 | } 159 | 160 | void swap( MemoryInfo & o1, MemoryInfo & o2 ) 161 | { 162 | using std::swap; 163 | 164 | swap( o1.impl, o2.impl ); 165 | } 166 | 167 | MemoryInfo::IMPL::IMPL( uint64_t total, uint64_t wired, uint64_t active, uint64_t inactive, uint64_t free, uint64_t purgeable, uint64_t speculative ): 168 | _total( total ), 169 | _wired( wired ), 170 | _active( active ), 171 | _inactive( inactive ), 172 | _free( free ), 173 | _purgeable( purgeable ), 174 | _speculative( speculative ) 175 | {} 176 | 177 | MemoryInfo::IMPL::IMPL( const IMPL & o ): 178 | _total( o._total ), 179 | _wired( o._wired ), 180 | _active( o._active ), 181 | _inactive( o._inactive ), 182 | _free( o._free ), 183 | _purgeable( o._purgeable ), 184 | _speculative( o._speculative ) 185 | {} 186 | 187 | MemoryInfo::IMPL::~IMPL() 188 | {} 189 | 190 | void MemoryInfo::IMPL::init() 191 | { 192 | static std::once_flag once; 193 | 194 | std::call_once 195 | ( 196 | once, 197 | [] 198 | { 199 | rmtx = new std::recursive_mutex(); 200 | info = new MemoryInfo( 0, 0, 0, 0, 0, 0, 0 ); 201 | } 202 | ); 203 | } 204 | 205 | void MemoryInfo::IMPL::observe() 206 | { 207 | MemoryInfo current = IMPL::getMemoryInfo(); 208 | 209 | { 210 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 211 | 212 | delete IMPL::info; 213 | 214 | IMPL::info = new MemoryInfo( current ); 215 | } 216 | } 217 | 218 | MemoryInfo MemoryInfo::IMPL::getMemoryInfo() 219 | { 220 | uint64_t total = 0; 221 | 222 | { 223 | int name[ 2 ] = { CTL_HW, HW_MEMSIZE }; 224 | size_t length = sizeof( total ); 225 | 226 | if( sysctl( name, 2, &total, &length, nullptr, 0 ) != 0 || total == 0 ) 227 | { 228 | return { 0, 0, 0, 0, 0, 0, 0 }; 229 | } 230 | } 231 | 232 | int name[ 2 ] = { CTL_HW, HW_PAGESIZE }; 233 | int pageSize = 0; 234 | size_t length = sizeof( pageSize ); 235 | 236 | if( sysctl( name, 2, &pageSize, &length, nullptr, 0 ) != 0 ) 237 | { 238 | return { 0, 0, 0, 0, 0, 0, 0 }; 239 | } 240 | 241 | mach_msg_type_number_t count = HOST_VM_INFO_COUNT; 242 | vm_statistics_data_t vmStat; 243 | 244 | if( host_statistics( mach_host_self(), HOST_VM_INFO, reinterpret_cast< host_info_t >( &vmStat ), &count ) != KERN_SUCCESS ) 245 | { 246 | return { 0, 0, 0, 0, 0, 0, 0 }; 247 | } 248 | 249 | uint64_t wired = static_cast< uint64_t >( pageSize ) * vmStat.wire_count; 250 | uint64_t active = static_cast< uint64_t >( pageSize ) * vmStat.active_count; 251 | uint64_t inactive = static_cast< uint64_t >( pageSize ) * vmStat.inactive_count; 252 | uint64_t free = static_cast< uint64_t >( pageSize ) * vmStat.free_count; 253 | uint64_t purgeable = static_cast< uint64_t >( pageSize ) * vmStat.purgeable_count; 254 | uint64_t speculative = static_cast< uint64_t >( pageSize ) * vmStat.speculative_count; 255 | 256 | return { total, wired, active, inactive, free, purgeable, speculative }; 257 | } 258 | 259 | std::recursive_mutex * MemoryInfo::IMPL::rmtx = nullptr; 260 | MemoryInfo * MemoryInfo::IMPL::info = nullptr; 261 | bool MemoryInfo::IMPL::observing = false; 262 | } 263 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/MemoryInfo.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_MEMORY_INFO_HPP 26 | #define SB_MEMORY_INFO_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace SB 34 | { 35 | class MemoryInfo 36 | { 37 | public: 38 | 39 | static void startObserving(); 40 | static MemoryInfo current(); 41 | 42 | MemoryInfo( const MemoryInfo & o ); 43 | MemoryInfo( MemoryInfo && o ) noexcept; 44 | ~MemoryInfo(); 45 | 46 | MemoryInfo & operator =( MemoryInfo o ); 47 | 48 | uint64_t total() const; 49 | uint64_t wired() const; 50 | uint64_t active() const; 51 | uint64_t inactive() const; 52 | uint64_t free() const; 53 | uint64_t purgeable() const; 54 | uint64_t speculative() const; 55 | uint64_t used() const; 56 | double percentUsed() const; 57 | 58 | friend void swap( MemoryInfo & o1, MemoryInfo & o2 ); 59 | 60 | private: 61 | 62 | MemoryInfo( uint64_t total, uint64_t wired, uint64_t active, uint64_t inactive, uint64_t free, uint64_t purgeable, uint64_t speculative ); 63 | 64 | class IMPL; 65 | std::unique_ptr< IMPL > impl; 66 | }; 67 | } 68 | 69 | #endif /* SB_MEMORY_INFO_HPP */ 70 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/NetworkInfo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/NetworkInfo.hpp" 26 | #include "SB/UpdateQueue.hpp" 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace SB 35 | { 36 | class NetworkInfo::IMPL 37 | { 38 | public: 39 | 40 | IMPL( const std::string & name, const std::string & address ); 41 | IMPL( const IMPL & o ); 42 | ~IMPL(); 43 | 44 | std::string _name; 45 | std::string _address; 46 | 47 | static void init(); 48 | static void observe(); 49 | static NetworkInfo getNetworkInfo(); 50 | 51 | static std::recursive_mutex * rmtx; 52 | static NetworkInfo * info; 53 | static bool observing; 54 | }; 55 | 56 | void NetworkInfo::startObserving() 57 | { 58 | NetworkInfo::IMPL::init(); 59 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 60 | 61 | if( IMPL::observing ) 62 | { 63 | return; 64 | } 65 | 66 | IMPL::observing = true; 67 | 68 | SB::UpdateQueue::shared().registerUpdate( [] { IMPL::observe(); } ); 69 | } 70 | 71 | NetworkInfo NetworkInfo::current() 72 | { 73 | NetworkInfo::IMPL::init(); 74 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 75 | 76 | return *( IMPL::info ); 77 | } 78 | 79 | NetworkInfo::NetworkInfo( const std::string & name, const std::string & address ): 80 | impl( std::make_unique< IMPL >( name, address ) ) 81 | {} 82 | 83 | NetworkInfo::NetworkInfo( const NetworkInfo & o ): 84 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 85 | {} 86 | 87 | NetworkInfo::NetworkInfo( NetworkInfo && o ) noexcept: 88 | impl( std::move( o.impl ) ) 89 | {} 90 | 91 | NetworkInfo::~NetworkInfo() 92 | {} 93 | 94 | NetworkInfo & NetworkInfo::operator =( NetworkInfo o ) 95 | { 96 | swap( *( this ), o ); 97 | 98 | return *( this ); 99 | } 100 | 101 | std::string NetworkInfo::name() const 102 | { 103 | return this->impl->_name; 104 | } 105 | 106 | std::string NetworkInfo::address() const 107 | { 108 | return this->impl->_address; 109 | } 110 | 111 | void swap( NetworkInfo & o1, NetworkInfo & o2 ) 112 | { 113 | using std::swap; 114 | 115 | swap( o1.impl, o2.impl ); 116 | } 117 | 118 | NetworkInfo::IMPL::IMPL( const std::string & name, const std::string & address ): 119 | _name( name ), 120 | _address( address ) 121 | {} 122 | 123 | NetworkInfo::IMPL::IMPL( const IMPL & o ): 124 | _name( o._name ), 125 | _address( o._address ) 126 | {} 127 | 128 | NetworkInfo::IMPL::~IMPL() 129 | {} 130 | 131 | void NetworkInfo::IMPL::init() 132 | { 133 | static std::once_flag once; 134 | 135 | std::call_once 136 | ( 137 | once, 138 | [] 139 | { 140 | rmtx = new std::recursive_mutex(); 141 | info = new NetworkInfo( "", "" ); 142 | } 143 | ); 144 | } 145 | 146 | void NetworkInfo::IMPL::observe() 147 | { 148 | NetworkInfo current = IMPL::getNetworkInfo(); 149 | 150 | { 151 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 152 | 153 | delete IMPL::info; 154 | 155 | IMPL::info = new NetworkInfo( current ); 156 | } 157 | } 158 | 159 | NetworkInfo NetworkInfo::IMPL::getNetworkInfo() 160 | { 161 | struct ifaddrs * interfaces = nullptr; 162 | 163 | if( getifaddrs( &interfaces ) != 0 ) 164 | { 165 | return { "", "" }; 166 | } 167 | 168 | struct ifaddrs * interface = interfaces; 169 | 170 | while( interface != nullptr ) 171 | { 172 | if( interface->ifa_addr->sa_family == AF_INET ) 173 | { 174 | std::string name = interface->ifa_name; 175 | struct sockaddr_in * in = reinterpret_cast< struct sockaddr_in * >( interface->ifa_addr ); 176 | std::string address = inet_ntoa( in->sin_addr ); 177 | 178 | if( name != "lo0" ) 179 | { 180 | freeifaddrs( interfaces ); 181 | 182 | return { name, address }; 183 | } 184 | } 185 | 186 | interface = interface->ifa_next; 187 | } 188 | 189 | freeifaddrs( interfaces ); 190 | 191 | return { "", "" }; 192 | } 193 | 194 | std::recursive_mutex * NetworkInfo::IMPL::rmtx = nullptr; 195 | NetworkInfo * NetworkInfo::IMPL::info = nullptr; 196 | bool NetworkInfo::IMPL::observing = false; 197 | } 198 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/NetworkInfo.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_NETWORK_INFO_HPP 26 | #define SB_NETWORK_INFO_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | class NetworkInfo 35 | { 36 | public: 37 | 38 | static void startObserving(); 39 | static NetworkInfo current(); 40 | 41 | NetworkInfo( const NetworkInfo & o ); 42 | NetworkInfo( NetworkInfo && o ) noexcept; 43 | ~NetworkInfo(); 44 | 45 | NetworkInfo & operator =( NetworkInfo o ); 46 | 47 | std::string name() const; 48 | std::string address() const; 49 | 50 | friend void swap( NetworkInfo & o1, NetworkInfo & o2 ); 51 | 52 | private: 53 | 54 | NetworkInfo( const std::string & name, const std::string & address ); 55 | 56 | class IMPL; 57 | std::unique_ptr< IMPL > impl; 58 | }; 59 | } 60 | 61 | #endif /* SB_NETWORK_INFO_HPP */ 62 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/TemperatureInfo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Instruments/TemperatureInfo.hpp" 26 | #include "SB/Helpers/Vector.hpp" 27 | #include "SB/Helpers/String.hpp" 28 | #include "SB/UpdateQueue.hpp" 29 | #include "SB/Instruments/Internal/IOHID.hpp" 30 | #include "SB/Instruments/Internal/SMC.hpp" 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | namespace SB 38 | { 39 | class TemperatureInfo::IMPL 40 | { 41 | public: 42 | 43 | IMPL( double temperature ); 44 | IMPL( const IMPL & o ); 45 | ~IMPL(); 46 | 47 | double _temperature; 48 | 49 | static void init(); 50 | static void observe(); 51 | static TemperatureInfo getTemperatureInfo(); 52 | static std::vector< double > readHIDSensors( double & tcal ); 53 | static std::vector< double > readSMCSensors(); 54 | 55 | static std::recursive_mutex * rmtx; 56 | static TemperatureInfo * info; 57 | static bool observing; 58 | static IOHIDEventSystemClientRef hidClient; 59 | static io_connect_t smcConnection; 60 | static std::vector< uint32_t > * smcKeys; 61 | static std::map< uint32_t, SMCKeyInfoData > * smcCache; 62 | 63 | }; 64 | 65 | void TemperatureInfo::startObserving() 66 | { 67 | TemperatureInfo::IMPL::init(); 68 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 69 | 70 | if( IMPL::observing ) 71 | { 72 | return; 73 | } 74 | 75 | IMPL::observing = true; 76 | 77 | SB::UpdateQueue::shared().registerUpdate( [] { IMPL::observe(); } ); 78 | } 79 | 80 | TemperatureInfo TemperatureInfo::current() 81 | { 82 | TemperatureInfo::IMPL::init(); 83 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 84 | 85 | return *( IMPL::info ); 86 | } 87 | 88 | TemperatureInfo::TemperatureInfo( double temperature ): 89 | impl( std::make_unique< IMPL >( temperature ) ) 90 | {} 91 | 92 | TemperatureInfo::TemperatureInfo( const TemperatureInfo & o ): 93 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 94 | {} 95 | 96 | TemperatureInfo::TemperatureInfo( TemperatureInfo && o ) noexcept: 97 | impl( std::move( o.impl ) ) 98 | {} 99 | 100 | TemperatureInfo::~TemperatureInfo() 101 | {} 102 | 103 | TemperatureInfo & TemperatureInfo::operator =( TemperatureInfo o ) 104 | { 105 | swap( *( this ), o ); 106 | 107 | return *( this ); 108 | } 109 | 110 | double TemperatureInfo::temperature() const 111 | { 112 | return this->impl->_temperature; 113 | } 114 | 115 | void swap( TemperatureInfo & o1, TemperatureInfo & o2 ) 116 | { 117 | using std::swap; 118 | 119 | swap( o1.impl, o2.impl ); 120 | } 121 | 122 | TemperatureInfo::IMPL::IMPL( double temperature ): 123 | _temperature( temperature ) 124 | {} 125 | 126 | TemperatureInfo::IMPL::IMPL( const IMPL & o ): 127 | _temperature( o._temperature ) 128 | {} 129 | 130 | TemperatureInfo::IMPL::~IMPL() 131 | {} 132 | 133 | void TemperatureInfo::IMPL::init() 134 | { 135 | static std::once_flag once; 136 | 137 | std::call_once 138 | ( 139 | once, 140 | [] 141 | { 142 | IMPL::rmtx = new std::recursive_mutex(); 143 | IMPL::info = new TemperatureInfo( 0 ); 144 | IMPL::hidClient = IOHIDEventSystemClientCreate( kCFAllocatorDefault ); 145 | IMPL::smcKeys = new std::vector< uint32_t >(); 146 | IMPL::smcCache = new std::map< uint32_t, SMCKeyInfoData >(); 147 | 148 | { 149 | io_service_t smc = IOServiceGetMatchingService( kIOMasterPortDefault, IOServiceMatching( "AppleSMC" ) ); 150 | 151 | if( smc != IO_OBJECT_NULL ) 152 | { 153 | io_connect_t connection = IO_OBJECT_NULL; 154 | kern_return_t result = IOServiceOpen( smc, mach_task_self(), 0, &connection ); 155 | 156 | if( result == kIOReturnSuccess && connection != IO_OBJECT_NULL ) 157 | { 158 | IMPL::smcConnection = connection; 159 | } 160 | } 161 | } 162 | } 163 | ); 164 | } 165 | 166 | void TemperatureInfo::IMPL::observe() 167 | { 168 | TemperatureInfo current = IMPL::getTemperatureInfo(); 169 | 170 | { 171 | std::lock_guard< std::recursive_mutex > l( *( IMPL::rmtx ) ); 172 | 173 | delete IMPL::info; 174 | 175 | IMPL::info = new TemperatureInfo( current ); 176 | } 177 | } 178 | 179 | TemperatureInfo TemperatureInfo::IMPL::getTemperatureInfo() 180 | { 181 | double tcal = 0; 182 | double hid = Vector::reduce< double, double >( IMPL::readHIDSensors( tcal ), 0.0, []( double a, double b ) { return ( a > b ) ? a : b; } ); 183 | double smc = Vector::reduce< double, double > 184 | ( 185 | IMPL::readSMCSensors(), 186 | 0.0, 187 | [ & ]( double a, double b ) 188 | { 189 | if( static_cast< int64_t >( tcal * 100 ) == static_cast< int64_t >( b * 100 ) ) 190 | { 191 | return a; 192 | } 193 | 194 | return ( a > b ) ? a : b; 195 | } 196 | ); 197 | 198 | return ( hid > smc ) ? hid : smc; 199 | } 200 | 201 | std::vector< double > TemperatureInfo::IMPL::readHIDSensors( double & tcal ) 202 | { 203 | std::vector< double > sensors; 204 | std::map< std::string, double > values = IOHID::read 205 | ( 206 | IMPL::hidClient, 207 | static_cast< int64_t >( IOHIDPage::IOHIDPageAppleVendor ), 208 | static_cast< int64_t >( IOHIDUsageAppleVendor::IOHIDUsageAppleVendorTemperatureSensor ), 209 | static_cast< int64_t >( IOHIDEvent::IOHIDEventTypeTemperature ), 210 | static_cast< int64_t >( IOHIDEventField::IOHIDEventFieldTemperatureLevel ) 211 | ); 212 | 213 | tcal = 0; 214 | 215 | for( const auto & p: values ) 216 | { 217 | if( String::hasSuffix( p.first, "tcal" ) ) 218 | { 219 | tcal = p.second; 220 | } 221 | else 222 | { 223 | sensors.push_back( p.second ); 224 | } 225 | } 226 | 227 | return sensors; 228 | } 229 | 230 | std::vector< double > TemperatureInfo::IMPL::readSMCSensors() 231 | { 232 | if( IMPL::smcConnection == IO_OBJECT_NULL ) 233 | { 234 | return {}; 235 | } 236 | 237 | if( IMPL::smcKeys->size() == 0 ) 238 | { 239 | uint32_t count = SMC::readSMCKeyCount( IMPL::smcConnection, *( IMPL::smcCache ) ); 240 | 241 | for( uint32_t i = 0; i < count; i++ ) 242 | { 243 | uint32_t key = 0; 244 | 245 | if( SMC::readSMCKey( IMPL::smcConnection, key, i ) == false ) 246 | { 247 | continue; 248 | } 249 | 250 | SMCKeyInfoData keyInfo; 251 | uint8_t data[ 32 ]; 252 | uint32_t size = sizeof( data ); 253 | 254 | if( SMC::readSMCKey( IMPL::smcConnection, key, data, size, keyInfo, *( IMPL::smcCache ) ) == false ) 255 | { 256 | continue; 257 | } 258 | 259 | std::string name = String::fourCC( key ); 260 | std::string type = String::fourCC( keyInfo.dataType ); 261 | 262 | if( name.length() == 0 || name[ 0 ] != 'T' ) 263 | { 264 | continue; 265 | } 266 | 267 | if( type != "ioft" && type != "flt " ) 268 | { 269 | continue; 270 | } 271 | 272 | if( key != 0 ) 273 | { 274 | IMPL::smcKeys->push_back( key ); 275 | } 276 | } 277 | } 278 | 279 | std::vector< double > sensors; 280 | 281 | for( auto key: *( IMPL::smcKeys ) ) 282 | { 283 | SMCKeyInfoData keyInfo; 284 | uint8_t data[ 32 ]; 285 | uint32_t size = sizeof( data ); 286 | 287 | if( SMC::readSMCKey( IMPL::smcConnection, key, data, size, keyInfo, *( IMPL::smcCache ) ) == false ) 288 | { 289 | continue; 290 | } 291 | 292 | std::string type = String::fourCC( keyInfo.dataType ); 293 | 294 | double value = 0; 295 | 296 | if( type == "ioft" ) 297 | { 298 | value = SMC::readIOFloat( data, size ); 299 | } 300 | else if( type == "flt " ) 301 | { 302 | value = SMC::readFloat32( data, size ); 303 | } 304 | 305 | if( value > 0 && value < 120 ) 306 | { 307 | sensors.push_back( value ); 308 | } 309 | else 310 | { 311 | continue; 312 | } 313 | } 314 | 315 | return sensors; 316 | } 317 | 318 | std::recursive_mutex * TemperatureInfo::IMPL::rmtx = nullptr; 319 | TemperatureInfo * TemperatureInfo::IMPL::info = nullptr; 320 | bool TemperatureInfo::IMPL::observing = false; 321 | IOHIDEventSystemClientRef TemperatureInfo::IMPL::hidClient = nullptr; 322 | io_connect_t TemperatureInfo::IMPL::smcConnection = 0; 323 | std::vector< uint32_t > * TemperatureInfo::IMPL::smcKeys = nullptr; 324 | std::map< uint32_t, SMCKeyInfoData > * TemperatureInfo::IMPL::smcCache = nullptr; 325 | } 326 | -------------------------------------------------------------------------------- /statusbar/SB/Instruments/TemperatureInfo.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_TEMPERATURE_INFO_HPP 26 | #define SB_TEMPERATURE_INFO_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace SB 34 | { 35 | class TemperatureInfo 36 | { 37 | public: 38 | 39 | static void startObserving(); 40 | static TemperatureInfo current(); 41 | 42 | TemperatureInfo( const TemperatureInfo & o ); 43 | TemperatureInfo( TemperatureInfo && o ) noexcept; 44 | ~TemperatureInfo(); 45 | 46 | TemperatureInfo & operator =( TemperatureInfo o ); 47 | 48 | double temperature() const; 49 | 50 | friend void swap( TemperatureInfo & o1, TemperatureInfo & o2 ); 51 | 52 | private: 53 | 54 | TemperatureInfo( double temperature ); 55 | 56 | class IMPL; 57 | std::unique_ptr< IMPL > impl; 58 | }; 59 | } 60 | 61 | #endif /* SB_TEMPERATURE_INFO_HPP */ 62 | -------------------------------------------------------------------------------- /statusbar/SB/Options.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/Options.hpp" 26 | 27 | namespace SB 28 | { 29 | class Options::IMPL 30 | { 31 | public: 32 | 33 | IMPL( int argc, const char ** argv ); 34 | IMPL( const IMPL & o ); 35 | ~IMPL(); 36 | 37 | bool _debug; 38 | bool _help; 39 | bool _cpu; 40 | bool _gpu; 41 | bool _memory; 42 | bool _temperature; 43 | bool _battery; 44 | bool _network; 45 | bool _date; 46 | bool _time; 47 | Color _cpuColor; 48 | Color _gpuColor; 49 | Color _memoryColor; 50 | Color _temperatureColor; 51 | Color _batteryColor; 52 | Color _networkColor; 53 | Color _dateColor; 54 | Color _timeColor; 55 | }; 56 | 57 | Options::Options( int argc, const char ** argv ): 58 | impl( std::make_unique< IMPL >( argc, argv ) ) 59 | {} 60 | 61 | Options::Options( const Options & o ): 62 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 63 | {} 64 | 65 | Options::Options( Options && o ) noexcept: 66 | impl( std::move( o.impl ) ) 67 | {} 68 | 69 | Options::~Options() 70 | {} 71 | 72 | Options & Options::operator =( Options o ) 73 | { 74 | swap( *( this ), o ); 75 | 76 | return *( this ); 77 | } 78 | 79 | bool Options::debug() const 80 | { 81 | return this->impl->_debug; 82 | } 83 | 84 | bool Options::help() const 85 | { 86 | return this->impl->_help; 87 | } 88 | 89 | bool Options::cpu() const 90 | { 91 | return this->impl->_cpu; 92 | } 93 | 94 | bool Options::gpu() const 95 | { 96 | return this->impl->_gpu; 97 | } 98 | 99 | bool Options::memory() const 100 | { 101 | return this->impl->_memory; 102 | } 103 | 104 | bool Options::temperature() const 105 | { 106 | return this->impl->_temperature; 107 | } 108 | 109 | bool Options::battery() const 110 | { 111 | return this->impl->_battery; 112 | } 113 | 114 | bool Options::network() const 115 | { 116 | return this->impl->_network; 117 | } 118 | 119 | bool Options::date() const 120 | { 121 | return this->impl->_date; 122 | } 123 | 124 | bool Options::time() const 125 | { 126 | return this->impl->_time; 127 | } 128 | 129 | Color Options::cpuColor() const 130 | { 131 | return this->impl->_cpuColor; 132 | } 133 | 134 | Color Options::gpuColor() const 135 | { 136 | return this->impl->_gpuColor; 137 | } 138 | 139 | Color Options::memoryColor() const 140 | { 141 | return this->impl->_memoryColor; 142 | } 143 | 144 | Color Options::temperatureColor() const 145 | { 146 | return this->impl->_temperatureColor; 147 | } 148 | 149 | Color Options::batteryColor() const 150 | { 151 | return this->impl->_batteryColor; 152 | } 153 | 154 | Color Options::networkColor() const 155 | { 156 | return this->impl->_networkColor; 157 | } 158 | 159 | Color Options::dateColor() const 160 | { 161 | return this->impl->_dateColor; 162 | } 163 | 164 | Color Options::timeColor() const 165 | { 166 | return this->impl->_timeColor; 167 | } 168 | 169 | void swap( Options & o1, Options & o2 ) 170 | { 171 | using std::swap; 172 | 173 | swap( o1.impl, o2.impl ); 174 | } 175 | 176 | Options::IMPL::IMPL( int argc, const char ** argv ): 177 | _debug( false ), 178 | _help( false ), 179 | _cpu( false ), 180 | _gpu( false ), 181 | _memory( false ), 182 | _temperature( false ), 183 | _battery( false ), 184 | _network( false ), 185 | _date( false ), 186 | _time( false ), 187 | _cpuColor( Color::cyan() ), 188 | _gpuColor( Color::blue() ), 189 | _memoryColor( Color::magenta() ), 190 | _temperatureColor( Color::red() ), 191 | _batteryColor( Color::yellow() ), 192 | _networkColor( Color::green() ), 193 | _dateColor( Color::cyan() ), 194 | _timeColor( Color::magenta() ) 195 | { 196 | for( int i = 0; i < argc; i++ ) 197 | { 198 | std::string option = argv[ i ]; 199 | 200 | if( option == "--debug" ) { this->_debug = true; } 201 | if( option == "--help" ) { this->_help = true; } 202 | if( option == "--cpu" ) { this->_cpu = true; } 203 | if( option == "--gpu" ) { this->_gpu = true; } 204 | if( option == "--memory" ) { this->_memory = true; } 205 | if( option == "--temperature" ) { this->_temperature = true; } 206 | if( option == "--battery" ) { this->_battery = true; } 207 | if( option == "--network" ) { this->_network = true; } 208 | if( option == "--date" ) { this->_date = true; } 209 | if( option == "--time" ) { this->_time = true; } 210 | 211 | if( i < argc - 1 && option == "--cpu-color" ) { this->_cpuColor = Color::color( argv[ ++i ] ); } 212 | if( i < argc - 1 && option == "--gpu-color" ) { this->_gpuColor = Color::color( argv[ ++i ] ); } 213 | if( i < argc - 1 && option == "--memory-color" ) { this->_memoryColor = Color::color( argv[ ++i ] ); } 214 | if( i < argc - 1 && option == "--temperature-color" ) { this->_temperatureColor = Color::color( argv[ ++i ] ); } 215 | if( i < argc - 1 && option == "--battery-color" ) { this->_batteryColor = Color::color( argv[ ++i ] ); } 216 | if( i < argc - 1 && option == "--network-color" ) { this->_networkColor = Color::color( argv[ ++i ] ); } 217 | if( i < argc - 1 && option == "--date-color" ) { this->_dateColor = Color::color( argv[ ++i ] ); } 218 | if( i < argc - 1 && option == "--time-color" ) { this->_timeColor = Color::color( argv[ ++i ] ); } 219 | } 220 | 221 | if 222 | ( 223 | this->_cpu == false 224 | && this->_gpu == false 225 | && this->_memory == false 226 | && this->_temperature == false 227 | && this->_battery == false 228 | && this->_network == false 229 | && this->_date == false 230 | && this->_time == false 231 | ) 232 | { 233 | this->_cpu = true; 234 | this->_gpu = true; 235 | this->_memory = true; 236 | this->_temperature = true; 237 | this->_battery = true; 238 | this->_network = true; 239 | this->_date = true; 240 | this->_time = true; 241 | } 242 | 243 | for( int i = 0; i < argc; i++ ) 244 | { 245 | std::string option = argv[ i ]; 246 | 247 | if( option == "--no-cpu" ) { this->_cpu = false; } 248 | if( option == "--no-gpu" ) { this->_gpu = false; } 249 | if( option == "--no-memory" ) { this->_memory = false; } 250 | if( option == "--no-temperature" ) { this->_temperature = false; } 251 | if( option == "--no-battery" ) { this->_battery = false; } 252 | if( option == "--no-network" ) { this->_network = false; } 253 | if( option == "--no-date" ) { this->_date = false; } 254 | if( option == "--no-time" ) { this->_time = false; } 255 | } 256 | } 257 | 258 | Options::IMPL::IMPL( const IMPL & o ): 259 | _debug( o._debug ), 260 | _help( o._help ), 261 | _cpu( o._cpu ), 262 | _gpu( o._gpu ), 263 | _memory( o._memory ), 264 | _temperature( o._temperature ), 265 | _battery( o._battery ), 266 | _network( o._network ), 267 | _date( o._date ), 268 | _time( o._time ), 269 | _cpuColor( o._cpuColor ), 270 | _gpuColor( o._gpuColor ), 271 | _memoryColor( o._memoryColor ), 272 | _temperatureColor( o._temperatureColor ), 273 | _batteryColor( o._batteryColor ), 274 | _networkColor( o._networkColor ), 275 | _dateColor( o._dateColor ), 276 | _timeColor( o._timeColor ) 277 | {} 278 | 279 | Options::IMPL::~IMPL() 280 | {} 281 | } 282 | -------------------------------------------------------------------------------- /statusbar/SB/Options.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_OPTIONS_HPP 26 | #define SB_OPTIONS_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include "SB/UI/Color.hpp" 32 | 33 | namespace SB 34 | { 35 | class Options 36 | { 37 | public: 38 | 39 | Options( int argc, const char ** argv ); 40 | Options( const Options & o ); 41 | Options( Options && o ) noexcept; 42 | ~Options(); 43 | 44 | Options & operator =( Options o ); 45 | 46 | bool debug() const; 47 | bool help() const; 48 | bool cpu() const; 49 | bool gpu() const; 50 | bool memory() const; 51 | bool temperature() const; 52 | bool battery() const; 53 | bool network() const; 54 | bool date() const; 55 | bool time() const; 56 | 57 | Color cpuColor() const; 58 | Color gpuColor() const; 59 | Color memoryColor() const; 60 | Color temperatureColor() const; 61 | Color batteryColor() const; 62 | Color networkColor() const; 63 | Color dateColor() const; 64 | Color timeColor() const; 65 | 66 | friend void swap( Options & o1, Options & o2 ); 67 | 68 | private: 69 | 70 | class IMPL; 71 | std::unique_ptr< IMPL > impl; 72 | }; 73 | } 74 | 75 | #endif /* SB_OPTIONS_HPP */ 76 | -------------------------------------------------------------------------------- /statusbar/SB/SleepManager.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SleepManager.hpp" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace SB 40 | { 41 | class SleepManager::IMPL 42 | { 43 | public: 44 | 45 | IMPL(); 46 | IMPL( const IMPL & o ); 47 | ~IMPL(); 48 | 49 | void run(); 50 | 51 | static void sleepCallback( void * connection, io_service_t service, natural_t messageType, void * context ); 52 | void sleepCallback( Event e ); 53 | 54 | std::vector< std::pair< UUID, std::function< void( Event ) > > > _callbacks; 55 | CFRunLoopRef _rl; 56 | std::recursive_mutex _rmtx; 57 | io_connect_t _rootPort; 58 | }; 59 | 60 | SleepManager & SleepManager::shared() 61 | { 62 | static SleepManager * instance = nullptr; 63 | static std::once_flag once; 64 | 65 | std::call_once 66 | ( 67 | once, 68 | [ & ] 69 | { 70 | instance = new SleepManager(); 71 | } 72 | ); 73 | 74 | return *( instance ); 75 | } 76 | 77 | SleepManager::SleepManager(): 78 | impl( std::make_unique< IMPL >() ) 79 | {} 80 | 81 | SleepManager::~SleepManager() 82 | {} 83 | 84 | UUID SleepManager::subscribe( const std::function< void( Event ) > & callback ) 85 | { 86 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 87 | UUID uuid; 88 | 89 | this->impl->_callbacks.push_back( { uuid, callback } ); 90 | 91 | return uuid; 92 | } 93 | 94 | void SleepManager::unsubscribe( const UUID & uuid ) 95 | { 96 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 97 | 98 | this->impl->_callbacks.erase 99 | ( 100 | std::remove_if 101 | ( 102 | this->impl->_callbacks.begin(), 103 | this->impl->_callbacks.end(), 104 | [ & ]( const auto & p ) 105 | { 106 | return p.first == uuid; 107 | } 108 | ), 109 | this->impl->_callbacks.end() 110 | ); 111 | } 112 | 113 | SleepManager::IMPL::IMPL(): 114 | _rl( nullptr ) 115 | { 116 | this->run(); 117 | } 118 | 119 | SleepManager::IMPL::IMPL( const IMPL & o ): 120 | _callbacks( o._callbacks ), 121 | _rl( nullptr ) 122 | { 123 | this->run(); 124 | } 125 | 126 | SleepManager::IMPL::~IMPL() 127 | { 128 | if( this->_rl != nullptr ) 129 | { 130 | CFRunLoopStop( this->_rl ); 131 | } 132 | } 133 | 134 | void SleepManager::IMPL::run() 135 | { 136 | std::thread 137 | ( 138 | [ & ] 139 | { 140 | IONotificationPortRef notifyPort; 141 | io_object_t notifier; 142 | io_connect_t rootPort = IORegisterForSystemPower( this, ¬ifyPort, IMPL::sleepCallback, ¬ifier ); 143 | 144 | if( rootPort == MACH_PORT_NULL ) 145 | { 146 | return; 147 | } 148 | 149 | CFRunLoopRef rl = CFRunLoopGetCurrent(); 150 | 151 | { 152 | std::lock_guard< std::recursive_mutex > l( this->_rmtx ); 153 | 154 | this->_rl = rl; 155 | this->_rootPort = rootPort; 156 | } 157 | 158 | CFRunLoopAddSource( rl, IONotificationPortGetRunLoopSource( notifyPort ), kCFRunLoopCommonModes ); 159 | CFRunLoopRun(); 160 | CFRunLoopRemoveSource( rl, IONotificationPortGetRunLoopSource( notifyPort ), kCFRunLoopCommonModes ); 161 | IODeregisterForSystemPower( ¬ifier ); 162 | IOServiceClose( rootPort ); 163 | IONotificationPortDestroy( notifyPort ); 164 | } 165 | ) 166 | .detach(); 167 | } 168 | 169 | void SleepManager::IMPL::sleepCallback( void * context, io_service_t service, natural_t messageType, void * messageArgument ) 170 | { 171 | ( void )service; 172 | 173 | IMPL * o = static_cast< IMPL * >( context ); 174 | 175 | if( messageType == kIOMessageCanSystemSleep || messageType == kIOMessageSystemWillSleep ) 176 | { 177 | IOAllowPowerChange( o->_rootPort, reinterpret_cast< long >( messageArgument ) ); 178 | } 179 | 180 | switch( messageType ) 181 | { 182 | case kIOMessageCanSystemSleep: o->sleepCallback( Event::CanSleep ); break; 183 | case kIOMessageSystemWillSleep: o->sleepCallback( Event::WillSleep ); break; 184 | case kIOMessageSystemWillPowerOn: o->sleepCallback( Event::WillPowerOn ); break; 185 | case kIOMessageSystemHasPoweredOn: o->sleepCallback( Event::DidPowerOn ); break; 186 | default: break; 187 | } 188 | } 189 | 190 | void SleepManager::IMPL::sleepCallback( Event e ) 191 | { 192 | std::lock_guard< std::recursive_mutex > l( this->_rmtx ); 193 | 194 | for( const auto & p: this->_callbacks ) 195 | { 196 | p.second( e ); 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /statusbar/SB/SleepManager.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_SLEEP_MANAGER_HPP 26 | #define SB_SLEEP_MANAGER_HPP 27 | 28 | #include 29 | #include 30 | #include "SB/UUID.hpp" 31 | 32 | namespace SB 33 | { 34 | class SleepManager 35 | { 36 | public: 37 | 38 | enum class Event 39 | { 40 | CanSleep, 41 | WillSleep, 42 | WillPowerOn, 43 | DidPowerOn 44 | }; 45 | 46 | static SleepManager & shared(); 47 | 48 | SleepManager( const SleepManager & o ) = delete; 49 | SleepManager & operator =( const SleepManager & o ) = delete; 50 | 51 | UUID subscribe( const std::function< void( Event ) > & callback ); 52 | void unsubscribe( const UUID & uuid ); 53 | 54 | private: 55 | 56 | SleepManager(); 57 | ~SleepManager(); 58 | 59 | class IMPL; 60 | std::unique_ptr< IMPL > impl; 61 | }; 62 | } 63 | 64 | #endif /* SB_SLEEP_MANAGER_HPP */ 65 | -------------------------------------------------------------------------------- /statusbar/SB/UI/Color.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/UI/Color.hpp" 26 | #include 27 | #include 28 | 29 | namespace SB 30 | { 31 | class Color::IMPL 32 | { 33 | public: 34 | 35 | IMPL( short value ); 36 | IMPL( const IMPL & o ); 37 | ~IMPL(); 38 | 39 | short _value; 40 | }; 41 | 42 | Color Color::color( const std::string & name ) 43 | { 44 | if( name == "black" ) { return Color::black(); } 45 | if( name == "red" ) { return Color::red(); } 46 | if( name == "green" ) { return Color::green(); } 47 | if( name == "yellow" ) { return Color::yellow(); } 48 | if( name == "blue" ) { return Color::blue(); } 49 | if( name == "magenta" ) { return Color::magenta(); } 50 | if( name == "cyan" ) { return Color::cyan(); } 51 | if( name == "white" ) { return Color::white(); } 52 | 53 | return Color::clear(); 54 | } 55 | 56 | Color Color::clear() 57 | { 58 | return Color( -1 ); 59 | } 60 | 61 | Color Color::black() 62 | { 63 | return Color( COLOR_BLACK ); 64 | } 65 | 66 | Color Color::red() 67 | { 68 | return Color( COLOR_RED ); 69 | } 70 | 71 | Color Color::green() 72 | { 73 | return Color( COLOR_GREEN ); 74 | } 75 | 76 | Color Color::yellow() 77 | { 78 | return Color( COLOR_YELLOW ); 79 | } 80 | 81 | Color Color::blue() 82 | { 83 | return Color( COLOR_BLUE ); 84 | } 85 | 86 | Color Color::magenta() 87 | { 88 | return Color( COLOR_MAGENTA ); 89 | } 90 | 91 | Color Color::cyan() 92 | { 93 | return Color( COLOR_CYAN ); 94 | } 95 | 96 | Color Color::white() 97 | { 98 | return Color( COLOR_WHITE ); 99 | } 100 | 101 | Color::Color( short value ): 102 | impl( std::make_unique< IMPL >( value ) ) 103 | {} 104 | 105 | Color::Color( const Color & o ): 106 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 107 | {} 108 | 109 | Color::Color( Color && o ) noexcept: 110 | impl( std::move( o.impl ) ) 111 | {} 112 | 113 | Color::~Color() 114 | {} 115 | 116 | Color & Color::operator =( Color o ) 117 | { 118 | swap( *( this ), o ); 119 | 120 | return *( this ); 121 | } 122 | 123 | bool Color::operator ==( const Color & o ) const 124 | { 125 | return this->value() == o.value(); 126 | } 127 | 128 | bool Color::operator !=( const Color & o ) const 129 | { 130 | return !operator ==( o ); 131 | } 132 | 133 | short Color::value() const 134 | { 135 | return this->impl->_value; 136 | } 137 | 138 | void swap( Color & o1, Color & o2 ) 139 | { 140 | using std::swap; 141 | 142 | swap( o1.impl, o2.impl ); 143 | } 144 | 145 | Color::IMPL::IMPL( short value ): 146 | _value( value ) 147 | {} 148 | 149 | Color::IMPL::IMPL( const IMPL & o ): 150 | _value( o._value ) 151 | {} 152 | 153 | Color::IMPL::~IMPL() 154 | {} 155 | } 156 | -------------------------------------------------------------------------------- /statusbar/SB/UI/Color.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_COLOR_HPP 26 | #define SB_COLOR_HPP 27 | 28 | #include 29 | #include 30 | 31 | namespace SB 32 | { 33 | class Color 34 | { 35 | public: 36 | 37 | static Color color( const std::string & name ); 38 | 39 | static Color clear(); 40 | static Color black(); 41 | static Color red(); 42 | static Color green(); 43 | static Color yellow(); 44 | static Color blue(); 45 | static Color magenta(); 46 | static Color cyan(); 47 | static Color white(); 48 | 49 | Color( const Color & o ); 50 | Color( Color && o ) noexcept; 51 | ~Color(); 52 | 53 | Color & operator =( Color o ); 54 | 55 | bool operator ==( const Color & o ) const; 56 | bool operator !=( const Color & o ) const; 57 | 58 | short value() const; 59 | 60 | friend void swap( Color & o1, Color & o2 ); 61 | 62 | private: 63 | 64 | explicit Color( short value ); 65 | 66 | class IMPL; 67 | std::unique_ptr< IMPL > impl; 68 | }; 69 | } 70 | 71 | #endif /* SB_COLOR_HPP */ 72 | -------------------------------------------------------------------------------- /statusbar/SB/UI/ColorPair.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/UI/ColorPair.hpp" 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace SB 32 | { 33 | class ColorPair::IMPL 34 | { 35 | public: 36 | 37 | IMPL(); 38 | IMPL( const IMPL & o ); 39 | ~IMPL(); 40 | 41 | std::vector< std::tuple< short, Color, Color > > _pairs; 42 | }; 43 | 44 | short ColorPair::pairForColors( const Color & foreground, const Color & background ) 45 | { 46 | ColorPair & pairs = ColorPair::shared(); 47 | 48 | for( const auto & p: pairs.impl->_pairs ) 49 | { 50 | if( std::get< 1 >( p ) == foreground && std::get< 2 >( p ) == background ) 51 | { 52 | return std::get< 0 >( p ); 53 | } 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | ColorPair & ColorPair::shared() 60 | { 61 | static ColorPair * instance( nullptr ); 62 | static std::once_flag once; 63 | 64 | std::call_once( once, [ & ]{ instance = new ColorPair(); } ); 65 | 66 | return *( instance ); 67 | } 68 | 69 | ColorPair::ColorPair(): 70 | impl( std::make_unique< IMPL >() ) 71 | {} 72 | 73 | ColorPair::ColorPair( const ColorPair & o ): 74 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 75 | {} 76 | 77 | ColorPair::ColorPair( ColorPair && o ) noexcept: 78 | impl( std::move( o.impl ) ) 79 | {} 80 | 81 | ColorPair::~ColorPair() 82 | {} 83 | 84 | ColorPair & ColorPair::operator =( ColorPair o ) 85 | { 86 | swap( *( this ), o ); 87 | 88 | return *( this ); 89 | } 90 | 91 | void swap( ColorPair & o1, ColorPair & o2 ) 92 | { 93 | using std::swap; 94 | 95 | swap( o1.impl, o2.impl ); 96 | } 97 | 98 | ColorPair::IMPL::IMPL() 99 | { 100 | short i = 1; 101 | std::vector< Color > colors = 102 | { 103 | Color::clear(), 104 | Color::black(), 105 | Color::red(), 106 | Color::green(), 107 | Color::yellow(), 108 | Color::blue(), 109 | Color::magenta(), 110 | Color::cyan(), 111 | Color::white() 112 | }; 113 | 114 | for( const auto & c1: std::vector< Color >( colors ) ) 115 | { 116 | for( const auto & c2: std::vector< Color >( colors ) ) 117 | { 118 | ::init_pair( i, c1.value(), c2.value() ); 119 | this->_pairs.push_back( { i, c1, c2 } ); 120 | 121 | i++; 122 | } 123 | } 124 | } 125 | 126 | ColorPair::IMPL::IMPL( const IMPL & o ): 127 | _pairs( o._pairs ) 128 | {} 129 | 130 | ColorPair::IMPL::~IMPL() 131 | {} 132 | } 133 | -------------------------------------------------------------------------------- /statusbar/SB/UI/ColorPair.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_COLOR_PAIR_HPP 26 | #define SB_COLOR_PAIR_HPP 27 | 28 | #include "SB/UI/Color.hpp" 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | class ColorPair 35 | { 36 | public: 37 | 38 | static short pairForColors( const Color & foreground, const Color & background ); 39 | 40 | private: 41 | 42 | static ColorPair & shared(); 43 | 44 | ColorPair(); 45 | ColorPair( const ColorPair & o ); 46 | ColorPair( ColorPair && o ) noexcept; 47 | ~ColorPair(); 48 | 49 | ColorPair & operator =( ColorPair o ); 50 | 51 | friend void swap( ColorPair & o1, ColorPair & o2 ); 52 | 53 | class IMPL; 54 | std::unique_ptr< IMPL > impl; 55 | }; 56 | } 57 | 58 | #endif /* SB_COLOR_PAIR_HPP */ 59 | -------------------------------------------------------------------------------- /statusbar/SB/UI/Screen.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/UI/Screen.hpp" 26 | #include "SB/UI/ColorPair.hpp" 27 | #include "SB/SleepManager.hpp" 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace SB 40 | { 41 | class Screen::IMPL 42 | { 43 | public: 44 | 45 | IMPL(); 46 | ~IMPL(); 47 | 48 | std::vector< std::function< void() > > _onResize; 49 | std::vector< std::function< void( int ) > > _onKeyPress; 50 | std::vector< std::function< void() > > _onUpdate; 51 | 52 | std::size_t _width; 53 | std::size_t _height; 54 | bool _colors; 55 | bool _running; 56 | bool _sleeping; 57 | UUID _sleepRegistration; 58 | std::recursive_mutex _rmtx; 59 | }; 60 | 61 | Screen & Screen::shared() 62 | { 63 | static Screen * screen( nullptr ); 64 | static std::once_flag once; 65 | 66 | std::call_once( once, [ & ]{ screen = new Screen(); } ); 67 | 68 | return *( screen ); 69 | } 70 | 71 | Screen::Screen(): 72 | impl( std::make_unique< IMPL >() ) 73 | { 74 | struct winsize s; 75 | 76 | ::initscr(); 77 | 78 | if( ::has_colors() ) 79 | { 80 | this->impl->_colors = true; 81 | 82 | ::start_color(); 83 | ::use_default_colors(); 84 | } 85 | 86 | this->clear(); 87 | ::noecho(); 88 | ::cbreak(); 89 | ::keypad( stdscr, true ); 90 | this->refresh(); 91 | 92 | ::ioctl( STDOUT_FILENO, TIOCGWINSZ, &s ); 93 | 94 | this->impl->_width = s.ws_col; 95 | this->impl->_height = s.ws_row; 96 | } 97 | 98 | std::size_t Screen::width() const 99 | { 100 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 101 | 102 | return this->impl->_width; 103 | } 104 | 105 | std::size_t Screen::height() const 106 | { 107 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 108 | 109 | return this->impl->_height; 110 | } 111 | 112 | bool Screen::supportsColors() const 113 | { 114 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 115 | 116 | return this->impl->_colors; 117 | } 118 | 119 | void Screen::disableColors() const 120 | { 121 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 122 | 123 | this->impl->_colors = false; 124 | } 125 | 126 | bool Screen::isRunning() const 127 | { 128 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 129 | 130 | return this->impl->_running; 131 | } 132 | 133 | void Screen::clear() const 134 | { 135 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 136 | 137 | ::clear(); 138 | } 139 | 140 | void Screen::refresh() const 141 | { 142 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 143 | 144 | ::refresh(); 145 | } 146 | 147 | void Screen::print( const std::string & s ) 148 | { 149 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 150 | 151 | ::printw( s.c_str() ); 152 | } 153 | 154 | void Screen::print( const Color & foreground, const std::string & s ) 155 | { 156 | this->print( foreground, Color::clear(), s ); 157 | } 158 | 159 | void Screen::print( const Color & foreground, const Color & background, const std::string & s ) 160 | { 161 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 162 | 163 | if( this->supportsColors() ) 164 | { 165 | ::attrset( static_cast< int >( COLOR_PAIR( ColorPair::pairForColors( foreground, background ) ) ) ); 166 | } 167 | 168 | ::printw( s.c_str() ); 169 | 170 | if( this->supportsColors() ) 171 | { 172 | ::attrset( static_cast< int >( COLOR_PAIR( ColorPair::pairForColors( Color::clear(), Color::clear() ) ) ) ); 173 | } 174 | } 175 | 176 | void Screen::start( unsigned int refreshInterval ) 177 | { 178 | { 179 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 180 | 181 | if( this->impl->_running ) 182 | { 183 | return; 184 | } 185 | 186 | this->impl->_running = true; 187 | } 188 | 189 | ::curs_set( 0 ); 190 | 191 | while( this->impl->_running ) 192 | { 193 | struct winsize s; 194 | std::vector< std::function< void() > > onResize; 195 | std::vector< std::function< void( int ) > > onKeyPress; 196 | std::vector< std::function< void() > > onUpdate; 197 | int key( 0 ); 198 | 199 | ::ioctl( STDOUT_FILENO, TIOCGWINSZ, &s ); 200 | 201 | { 202 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 203 | 204 | onKeyPress = this->impl->_onKeyPress; 205 | onUpdate = this->impl->_onUpdate; 206 | 207 | if( s.ws_col != this->impl->_width || s.ws_row != this->impl->_height ) 208 | { 209 | this->impl->_width = s.ws_col; 210 | this->impl->_height = s.ws_row; 211 | 212 | onResize = this->impl->_onResize; 213 | } 214 | 215 | { 216 | static struct pollfd p; 217 | 218 | memset( &p, 0, sizeof( p ) ); 219 | 220 | p.fd = 0; 221 | p.events = POLLIN; 222 | p.revents = 0; 223 | 224 | if( poll( &p, 1, 0 ) > 0 ) 225 | { 226 | key = getc( stdin ); 227 | onKeyPress = this->impl->_onKeyPress; 228 | } 229 | } 230 | } 231 | 232 | for( const auto & f: onResize ) 233 | { 234 | f(); 235 | } 236 | 237 | for( const auto & f: onKeyPress ) 238 | { 239 | f( key ); 240 | } 241 | 242 | for( const auto & f: onUpdate ) 243 | { 244 | f(); 245 | } 246 | 247 | this->refresh(); 248 | 249 | if( this->impl->_sleeping ) 250 | { 251 | std::this_thread::sleep_for( std::chrono::seconds( 5 ) ); 252 | } 253 | else 254 | { 255 | std::this_thread::sleep_for( std::chrono::milliseconds( refreshInterval ) ); 256 | } 257 | } 258 | 259 | this->clear(); 260 | this->refresh(); 261 | 262 | ::curs_set( 1 ); 263 | } 264 | 265 | void Screen::stop() 266 | { 267 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 268 | 269 | this->impl->_running = false; 270 | } 271 | 272 | void Screen::onResize( const std::function< void() > & f ) 273 | { 274 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 275 | 276 | this->impl->_onResize.push_back( f ); 277 | } 278 | 279 | void Screen::onKeyPress( const std::function< void( int key ) > & f ) 280 | { 281 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 282 | 283 | this->impl->_onKeyPress.push_back( f ); 284 | } 285 | 286 | void Screen::onUpdate( const std::function< void() > & f ) 287 | { 288 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 289 | 290 | this->impl->_onUpdate.push_back( f ); 291 | } 292 | 293 | Screen::IMPL::IMPL(): 294 | _width( 0 ), 295 | _height( 0 ), 296 | _colors( false ), 297 | _running( false ), 298 | _sleeping( false ) 299 | { 300 | this->_sleepRegistration = SleepManager::shared().subscribe 301 | ( 302 | [ & ]( SleepManager::Event e ) 303 | { 304 | std::lock_guard< std::recursive_mutex > l( this->_rmtx ); 305 | 306 | if( e == SleepManager::Event::WillSleep ) 307 | { 308 | this->_sleeping = true; 309 | } 310 | else if( e == SleepManager::Event::DidPowerOn ) 311 | { 312 | this->_sleeping = false; 313 | } 314 | } 315 | ); 316 | } 317 | 318 | Screen::IMPL::~IMPL() 319 | { 320 | SleepManager::shared().unsubscribe( this->_sleepRegistration ); 321 | 322 | ::clrtoeol(); 323 | ::refresh(); 324 | ::endwin(); 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /statusbar/SB/UI/Screen.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_SCREEN_HPP 26 | #define SB_SCREEN_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "SB/UI/Color.hpp" 34 | 35 | namespace SB 36 | { 37 | class Screen 38 | { 39 | public: 40 | 41 | static Screen & shared(); 42 | 43 | Screen( const Screen & o ) = delete; 44 | Screen( Screen && o ) noexcept = delete; 45 | Screen & operator =( Screen o ) = delete; 46 | 47 | std::size_t width() const; 48 | std::size_t height() const; 49 | 50 | bool supportsColors() const; 51 | void disableColors() const; 52 | bool isRunning() const; 53 | void clear() const; 54 | void refresh() const; 55 | 56 | void print( const std::string & s ); 57 | void print( const Color & foreground, const std::string & s ); 58 | void print( const Color & foreground, const Color & background, const std::string & s ); 59 | 60 | void start( unsigned int refreshInterval ); 61 | void stop(); 62 | 63 | void onResize( const std::function< void() > & f ); 64 | void onKeyPress( const std::function< void( int key ) > & f ); 65 | void onUpdate( const std::function< void() > & f ); 66 | 67 | private: 68 | 69 | Screen(); 70 | 71 | class IMPL; 72 | 73 | std::unique_ptr< IMPL > impl; 74 | }; 75 | } 76 | 77 | #endif /* SB_SCREEN_HPP */ 78 | -------------------------------------------------------------------------------- /statusbar/SB/UI/Window.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/UI/Window.hpp" 26 | #include "SB/Helpers/Casts.hpp" 27 | #include "SB/UI/Screen.hpp" 28 | #include "SB/UI/ColorPair.hpp" 29 | #include 30 | 31 | namespace SB 32 | { 33 | class Window::IMPL 34 | { 35 | public: 36 | 37 | IMPL( size_t x, size_t y, size_t width, size_t height ); 38 | IMPL( const IMPL & o ); 39 | ~IMPL( void ); 40 | 41 | size_t _x; 42 | size_t _y; 43 | size_t _width; 44 | size_t _height; 45 | ::WINDOW * _win; 46 | }; 47 | 48 | Window::Window( size_t x, size_t y, size_t width, size_t height ): 49 | impl( std::make_unique< IMPL >( x, y, width, height ) ) 50 | {} 51 | 52 | Window::Window( const Window & o ): 53 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 54 | {} 55 | 56 | Window::Window( Window && o ) noexcept: 57 | impl( std::move( o.impl ) ) 58 | {} 59 | 60 | Window::~Window( void ) 61 | {} 62 | 63 | Window & Window::operator =( Window o ) 64 | { 65 | swap( *( this ), o ); 66 | 67 | return *( this ); 68 | } 69 | 70 | void Window::refresh( void ) 71 | { 72 | ::wrefresh( this->impl->_win ); 73 | } 74 | 75 | void Window::move( size_t x, size_t y ) 76 | { 77 | ::wmove( this->impl->_win, numeric_cast< int >( y ), numeric_cast< int >( x ) ); 78 | } 79 | 80 | void Window::print( const std::string & s ) 81 | { 82 | ::wprintw( this->impl->_win, s.c_str() ); 83 | } 84 | 85 | void Window::print( const char * format, ... ) 86 | { 87 | va_list ap; 88 | 89 | va_start( ap, format ); 90 | ::vw_printw( this->impl->_win, format, ap ); 91 | va_end( ap ); 92 | } 93 | 94 | void Window::print( const Color & foreground, const Color & background, const std::string & s ) 95 | { 96 | if( Screen::shared().supportsColors() ) 97 | { 98 | ::wattrset( this->impl->_win, static_cast< int >( COLOR_PAIR( ColorPair::pairForColors( foreground, background ) ) ) ); 99 | } 100 | 101 | ::wprintw( this->impl->_win, s.c_str() ); 102 | 103 | if( Screen::shared().supportsColors() ) 104 | { 105 | ::wattrset( this->impl->_win, static_cast< int >( COLOR_PAIR( ColorPair::pairForColors( Color::clear(), Color::clear() ) ) ) ); 106 | } 107 | } 108 | 109 | void Window::print( const Color & foreground, const Color & background, const char * format, ... ) 110 | { 111 | va_list ap; 112 | 113 | va_start( ap, format ); 114 | 115 | if( Screen::shared().supportsColors() ) 116 | { 117 | ::wattrset( this->impl->_win, static_cast< int >( COLOR_PAIR( ColorPair::pairForColors( foreground, background ) ) ) ); 118 | } 119 | 120 | ::vw_printw( this->impl->_win, format, ap ); 121 | 122 | if( Screen::shared().supportsColors() ) 123 | { 124 | ::wattrset( this->impl->_win, static_cast< int >( COLOR_PAIR( ColorPair::pairForColors( Color::clear(), Color::clear() ) ) ) ); 125 | } 126 | 127 | va_end( ap ); 128 | } 129 | 130 | void Window::box( void ) 131 | { 132 | ::box( this->impl->_win, 0, 0 ); 133 | } 134 | 135 | void Window::addHorizontalLine( size_t width ) 136 | { 137 | ::whline( this->impl->_win, 0, numeric_cast< int >( width ) ); 138 | } 139 | 140 | void Window::addVerticalLine( size_t height ) 141 | { 142 | ::wvline( this->impl->_win, 0, numeric_cast< int >( height ) ); 143 | } 144 | 145 | void swap( Window & o1, Window & o2 ) 146 | { 147 | using std::swap; 148 | 149 | swap( o1.impl, o2.impl ); 150 | } 151 | 152 | Window::IMPL::IMPL( size_t x, size_t y, size_t width, size_t height ): 153 | _x( x ), 154 | _y( y ), 155 | _width( width ), 156 | _height( height ), 157 | _win( ::newwin( numeric_cast< int >( height ), numeric_cast< int >( width ), numeric_cast< int >( y ), numeric_cast< int >( x ) ) ) 158 | {} 159 | 160 | Window::IMPL::IMPL( const IMPL & o ): 161 | _x( o._x ), 162 | _y( o._y ), 163 | _width( o._width ), 164 | _height( o._height ), 165 | _win( ::newwin( numeric_cast< int >( o._height ), numeric_cast< int >( o._width ), numeric_cast< int >( o._y ), numeric_cast< int >( o._x ) ) ) 166 | {} 167 | 168 | Window::IMPL::~IMPL( void ) 169 | { 170 | ::delwin( this->_win ); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /statusbar/SB/UI/Window.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_WINDOW_HPP 26 | #define SB_WINDOW_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "SB/UI/Color.hpp" 33 | 34 | namespace SB 35 | { 36 | class Window 37 | { 38 | public: 39 | 40 | Window( size_t x, size_t y, size_t width, size_t height ); 41 | Window( const Window & o ); 42 | Window( Window && o ) noexcept; 43 | ~Window( void ); 44 | 45 | Window & operator =( Window o ); 46 | 47 | void refresh( void ); 48 | void move( size_t x, size_t y ); 49 | void print( const std::string & s ); 50 | void print( const char * format, ... ); 51 | void print( const Color & foreground, const Color & background, const std::string & s ); 52 | void print( const Color & foreground, const Color & background, const char * format, ... ); 53 | void box( void ); 54 | void addHorizontalLine( size_t width ); 55 | void addVerticalLine( size_t height ); 56 | 57 | friend void swap( Window & o1, Window & o2 ); 58 | 59 | private: 60 | 61 | class IMPL; 62 | std::unique_ptr< IMPL > impl; 63 | }; 64 | } 65 | 66 | #endif /* SB_WINDOW_HPP */ 67 | -------------------------------------------------------------------------------- /statusbar/SB/UUID.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/UUID.hpp" 26 | #include "SB/Helpers/String.hpp" 27 | #include 28 | #include 29 | 30 | namespace SB 31 | { 32 | class UUID::IMPL 33 | { 34 | public: 35 | 36 | IMPL( void ); 37 | IMPL( const IMPL & o ); 38 | ~IMPL(); 39 | 40 | std::string _uuid; 41 | }; 42 | 43 | UUID::UUID( void ): 44 | impl( std::make_unique< IMPL >() ) 45 | {} 46 | 47 | UUID::UUID( const UUID & o ): 48 | impl( std::make_unique< IMPL >( *( o.impl ) ) ) 49 | {} 50 | 51 | UUID::UUID( UUID && o ) noexcept: 52 | impl( std::move( o.impl ) ) 53 | {} 54 | 55 | UUID::~UUID( void ) 56 | {} 57 | 58 | UUID & UUID::operator =( UUID o ) 59 | { 60 | swap( *( this ), o ); 61 | 62 | return *( this ); 63 | } 64 | 65 | bool UUID::operator ==( const UUID & o ) const 66 | { 67 | return this->impl->_uuid == o.impl->_uuid; 68 | } 69 | 70 | bool UUID::operator !=( const UUID & o ) const 71 | { 72 | return !operator ==( o ); 73 | } 74 | 75 | void swap( UUID & o1, UUID & o2 ) 76 | { 77 | using std::swap; 78 | 79 | swap( o1.impl, o2.impl ); 80 | } 81 | 82 | UUID::IMPL::IMPL( void ) 83 | { 84 | uuid_t uuid; 85 | char s[ 37 ]; 86 | 87 | uuid_generate_random( uuid ); 88 | memset( s, 0, sizeof( s ) ); 89 | uuid_unparse( uuid, s ); 90 | 91 | this->_uuid = String::toLower( std::string( s ) ); 92 | } 93 | 94 | UUID::IMPL::IMPL( const IMPL & o ): 95 | _uuid( o._uuid ) 96 | {} 97 | 98 | UUID::IMPL::~IMPL() 99 | {} 100 | } 101 | -------------------------------------------------------------------------------- /statusbar/SB/UUID.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_UUID_HPP 26 | #define SB_UUID_HPP 27 | 28 | #include 29 | #include 30 | 31 | namespace SB 32 | { 33 | class UUID 34 | { 35 | public: 36 | 37 | UUID( void ); 38 | UUID( const UUID & o ); 39 | UUID( UUID && o ) noexcept; 40 | ~UUID( void ); 41 | 42 | UUID & operator =( UUID o ); 43 | 44 | bool operator ==( const UUID & o ) const; 45 | bool operator !=( const UUID & o ) const; 46 | 47 | friend void swap( UUID & o1, UUID & o2 ); 48 | 49 | private: 50 | 51 | class IMPL; 52 | 53 | std::unique_ptr< IMPL > impl; 54 | }; 55 | } 56 | 57 | #endif /* SB_UUID_HPP */ 58 | -------------------------------------------------------------------------------- /statusbar/SB/UpdateQueue.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/UpdateQueue.hpp" 26 | #include "SB/SleepManager.hpp" 27 | #include 28 | #include 29 | #include 30 | 31 | namespace SB 32 | { 33 | class UpdateQueue::IMPL 34 | { 35 | public: 36 | 37 | IMPL(); 38 | ~IMPL(); 39 | 40 | void run(); 41 | 42 | std::vector< std::function< void() > > _functions; 43 | std::recursive_mutex _rmtx; 44 | bool _sleeping; 45 | UUID _sleepRegistration; 46 | }; 47 | 48 | UpdateQueue & UpdateQueue::shared() 49 | { 50 | static UpdateQueue * queue; 51 | static std::once_flag once; 52 | 53 | std::call_once 54 | ( 55 | once, 56 | [ & ] 57 | { 58 | queue = new UpdateQueue(); 59 | } 60 | ); 61 | 62 | return *( queue ); 63 | } 64 | 65 | UpdateQueue::UpdateQueue(): 66 | impl( std::make_unique< IMPL >() ) 67 | {} 68 | 69 | UpdateQueue::~UpdateQueue() 70 | {} 71 | 72 | void UpdateQueue::registerUpdate( const std::function< void() > & f ) 73 | { 74 | std::lock_guard< std::recursive_mutex > l( this->impl->_rmtx ); 75 | 76 | this->impl->_functions.push_back( f ); 77 | } 78 | 79 | UpdateQueue::IMPL::IMPL(): 80 | _sleeping( false ) 81 | { 82 | this->_sleepRegistration = SleepManager::shared().subscribe 83 | ( 84 | [ & ]( SleepManager::Event e ) 85 | { 86 | std::lock_guard< std::recursive_mutex > l( this->_rmtx ); 87 | 88 | if( e == SleepManager::Event::WillSleep ) 89 | { 90 | this->_sleeping = true; 91 | } 92 | else if( e == SleepManager::Event::DidPowerOn ) 93 | { 94 | this->_sleeping = false; 95 | } 96 | } 97 | ); 98 | 99 | this->run(); 100 | } 101 | 102 | UpdateQueue::IMPL::~IMPL() 103 | { 104 | SleepManager::shared().unsubscribe( this->_sleepRegistration ); 105 | } 106 | 107 | void UpdateQueue::IMPL::run() 108 | { 109 | std::thread 110 | ( 111 | [ this ] 112 | { 113 | while( true ) 114 | { 115 | if( this->_sleeping ) 116 | { 117 | std::this_thread::sleep_for( std::chrono::seconds( 5 ) ); 118 | 119 | continue; 120 | } 121 | 122 | std::vector< std::function< void() > > functions; 123 | 124 | { 125 | std::lock_guard< std::recursive_mutex > l( this->_rmtx ); 126 | 127 | functions = this->_functions; 128 | } 129 | 130 | for( const auto & f: functions ) 131 | { 132 | f(); 133 | } 134 | 135 | std::this_thread::sleep_for( std::chrono::seconds( 1 ) ); 136 | } 137 | } 138 | ) 139 | .detach(); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /statusbar/SB/UpdateQueue.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #ifndef SB_UPDATE_QUEUE_HPP 26 | #define SB_UPDATE_QUEUE_HPP 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace SB 33 | { 34 | class UpdateQueue 35 | { 36 | public: 37 | 38 | static UpdateQueue & shared(); 39 | 40 | UpdateQueue( const UpdateQueue & o ) = delete; 41 | UpdateQueue & operator =( UpdateQueue o ) = delete; 42 | 43 | void registerUpdate( const std::function< void() > & f ); 44 | 45 | private: 46 | 47 | UpdateQueue(); 48 | ~UpdateQueue(); 49 | 50 | class IMPL; 51 | std::unique_ptr< IMPL > impl; 52 | }; 53 | } 54 | 55 | #endif /* SB_UPDATE_QUEUE_HPP */ 56 | -------------------------------------------------------------------------------- /statusbar/main.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | #include "SB/UI/Screen.hpp" 26 | #include "SB/Instruments/CPULoad.hpp" 27 | #include "SB/Instruments/GPULoad.hpp" 28 | #include "SB/Instruments/BatteryInfo.hpp" 29 | #include "SB/Instruments/NetworkInfo.hpp" 30 | #include "SB/Options.hpp" 31 | #include "SB/Instruments/MemoryInfo.hpp" 32 | #include "SB/Instruments/TemperatureInfo.hpp" 33 | #include "SB/Helpers/String.hpp" 34 | #include "SB/UI/Window.hpp" 35 | #include 36 | #include 37 | #include 38 | 39 | void displayCPU( const SB::Color & color, SB::Window & window, const SB::CPULoad & cpu ); 40 | void displayGPU( const SB::Color & color, SB::Window & window, const SB::GPULoad & cpu ); 41 | void displayMemory( const SB::Color & color, SB::Window & window, const SB::MemoryInfo & memory ); 42 | void displayBattery( const SB::Color & color, SB::Window & window, const SB::BatteryInfo & battery ); 43 | void displayTemperature( const SB::Color & color, SB::Window & window, const SB::TemperatureInfo & temperature ); 44 | void displayNetwork( const SB::Color & color, SB::Window & window, const SB::NetworkInfo & network ); 45 | void displayDate( const SB::Color & color, SB::Window & window, time_t time ); 46 | void displayTime( const SB::Color & color, SB::Window & window, time_t time ); 47 | 48 | void showHelp(); 49 | 50 | int main( int argc, const char * argv[] ) 51 | { 52 | SB::Options options = { argc, argv }; 53 | 54 | if( options.help() ) 55 | { 56 | showHelp(); 57 | 58 | return 0; 59 | } 60 | 61 | if( options.cpu() ) { SB::CPULoad::startObserving(); } 62 | if( options.gpu() ) { SB::GPULoad::startObserving(); } 63 | if( options.memory() ) { SB::MemoryInfo::startObserving(); } 64 | if( options.battery() ) { SB::BatteryInfo::startObserving(); } 65 | if( options.network() ) { SB::NetworkInfo::startObserving(); } 66 | if( options.temperature() ) { SB::TemperatureInfo::startObserving(); } 67 | 68 | setlocale( LC_ALL, "" ); 69 | 70 | if( options.debug() ) 71 | { 72 | while( true ) 73 | { 74 | std::this_thread::sleep_for( std::chrono::seconds( 1 ) ); 75 | } 76 | } 77 | else 78 | { 79 | SB::Screen & screen = SB::Screen::shared(); 80 | 81 | screen.onKeyPress 82 | ( 83 | [ & ]( int key ) 84 | { 85 | if( key == 'q' ) 86 | { 87 | screen.stop(); 88 | } 89 | } 90 | ); 91 | 92 | screen.onUpdate 93 | ( 94 | [ & ] 95 | { 96 | SB::CPULoad cpu = SB::CPULoad::current(); 97 | SB::GPULoad gpu = SB::GPULoad::current(); 98 | SB::MemoryInfo memory = SB::MemoryInfo::current(); 99 | SB::BatteryInfo battery = SB::BatteryInfo::current(); 100 | SB::NetworkInfo network = SB::NetworkInfo::current(); 101 | SB::TemperatureInfo temperature = SB::TemperatureInfo::current(); 102 | 103 | std::size_t leftWidth = 29; 104 | 105 | if( options.date() == false && options.time() == false ) 106 | { 107 | leftWidth = 0; 108 | } 109 | else if( options.date() == false ) 110 | { 111 | leftWidth = 11; 112 | } 113 | else if( options.time() == false ) 114 | { 115 | leftWidth = 13; 116 | } 117 | 118 | SB::Window left( 0, 0, screen.width() - leftWidth, screen.height() ); 119 | SB::Window right( screen.width() - leftWidth, 0, leftWidth, screen.height() ); 120 | 121 | bool hasLeftData = false; 122 | bool hasRightData = false; 123 | 124 | if( options.cpu() ) 125 | { 126 | if( hasLeftData ) 127 | { 128 | left.print( " " ); 129 | } 130 | 131 | displayCPU( options.cpuColor(), left, cpu ); 132 | 133 | hasLeftData = true; 134 | } 135 | 136 | if( options.gpu() && gpu.percent() >= 0 ) 137 | { 138 | if( hasLeftData ) 139 | { 140 | left.print( " " ); 141 | } 142 | 143 | displayGPU( options.gpuColor(), left, gpu ); 144 | 145 | hasLeftData = true; 146 | } 147 | 148 | if( options.memory() && memory.total() > 0 ) 149 | { 150 | if( hasLeftData ) 151 | { 152 | left.print( " " ); 153 | } 154 | 155 | displayMemory( options.memoryColor(),left, memory ); 156 | 157 | hasLeftData = true; 158 | } 159 | 160 | if( options.battery() && battery.isAvailable() ) 161 | { 162 | if( hasLeftData ) 163 | { 164 | left.print( " " ); 165 | } 166 | 167 | displayBattery( options.batteryColor(), left, battery ); 168 | 169 | hasLeftData = true; 170 | } 171 | 172 | if( options.temperature() && temperature.temperature() > 0 ) 173 | { 174 | if( hasLeftData ) 175 | { 176 | left.print( " " ); 177 | } 178 | 179 | displayTemperature( options.temperatureColor(), left, temperature ); 180 | 181 | hasLeftData = true; 182 | } 183 | 184 | if( options.network() && network.name().empty() == false ) 185 | { 186 | if( hasLeftData ) 187 | { 188 | left.print( " " ); 189 | } 190 | 191 | displayNetwork( options.networkColor(), left, network ); 192 | 193 | hasLeftData = true; 194 | } 195 | 196 | if( options.date() ) 197 | { 198 | if( hasRightData ) 199 | { 200 | right.print( " " ); 201 | } 202 | 203 | displayDate( options.dateColor(), right, time( nullptr ) ); 204 | 205 | hasRightData = true; 206 | } 207 | 208 | if( options.time() ) 209 | { 210 | if( hasRightData ) 211 | { 212 | right.print( " " ); 213 | } 214 | 215 | displayTime( options.timeColor(), right, time( nullptr ) ); 216 | 217 | hasRightData = true; 218 | } 219 | 220 | left.refresh(); 221 | right.refresh(); 222 | } 223 | ); 224 | 225 | screen.start( 1000 ); 226 | } 227 | 228 | return 0; 229 | } 230 | 231 | void displayCPU( const SB::Color & color, SB::Window & window, const SB::CPULoad & cpu ) 232 | { 233 | window.print( color, SB::Color::clear(), "\uf2db CPU: %.0f%% ", cpu.total() ); 234 | 235 | for( int i = 0; i < 10; i++ ) 236 | { 237 | if( cpu.total() / 10 < i || cpu.total() < 5 ) 238 | { 239 | window.print( color, SB::Color::clear(), "\uf096 " ); 240 | } 241 | else 242 | { 243 | window.print( color, SB::Color::clear(), "\uf0c8 " ); 244 | } 245 | } 246 | 247 | window.print( color, SB::Color::clear(), " \uf007 %.0f%% \uf013 %.0f%%", cpu.user(), cpu.system() ); 248 | } 249 | 250 | void displayGPU( const SB::Color & color, SB::Window & window, const SB::GPULoad & gpu ) 251 | { 252 | window.print( color, SB::Color::clear(), "\ueb4c GPU: %.0f%% ", gpu.percent() ); 253 | 254 | for( int i = 0; i < 10; i++ ) 255 | { 256 | if( gpu.percent() / 10 < i || gpu.percent() < 5 ) 257 | { 258 | window.print( color, SB::Color::clear(), "\uf096 " ); 259 | } 260 | else 261 | { 262 | window.print( color, SB::Color::clear(), "\uf0c8 " ); 263 | } 264 | } 265 | } 266 | 267 | void displayMemory( const SB::Color & color, SB::Window & window, const SB::MemoryInfo & memory ) 268 | { 269 | window.print( color, SB::Color::clear(), "\uf1c0 Memory %.0f%% : ", memory.percentUsed() ); 270 | 271 | for( int i = 0; i < 10; i++ ) 272 | { 273 | if( memory.percentUsed() / 10 < i || memory.percentUsed() < 5 ) 274 | { 275 | window.print( color, SB::Color::clear(), "\uf096 " ); 276 | } 277 | else 278 | { 279 | window.print( color, SB::Color::clear(), "\uf0c8 " ); 280 | } 281 | } 282 | 283 | window.print 284 | ( 285 | color, 286 | SB::Color::clear(), 287 | " %s / %s", 288 | SB::String::bytesToHumanReadable( memory.used() ).c_str(), 289 | SB::String::bytesToHumanReadable( memory.total() ).c_str() 290 | ); 291 | } 292 | 293 | void displayBattery( const SB::Color & color, SB::Window & window, const SB::BatteryInfo & battery ) 294 | { 295 | int64_t capacity = battery.capacity(); 296 | const char * icon; 297 | 298 | if( capacity >= 80 ) { icon = "\uf240"; } 299 | else if( capacity >= 60 ) { icon = "\uf241"; } 300 | else if( capacity >= 40 ) { icon = "\uf242"; } 301 | else if( capacity >= 20 ) { icon = "\uf243"; } 302 | else { icon = "\uf244"; } 303 | 304 | window.print( color, SB::Color::clear(), "%s Battery: %lli%%", icon, capacity ); 305 | 306 | if( battery.isCharging() ) 307 | { 308 | window.print( color, SB::Color::clear(), " \uf0e7" ); 309 | } 310 | } 311 | 312 | void displayTemperature( const SB::Color & color, SB::Window & window, const SB::TemperatureInfo & temperature ) 313 | { 314 | window.print( color, SB::Color::clear(), " \uf2c7 Temperature: %.0f°", temperature.temperature() ); 315 | } 316 | 317 | void displayNetwork( const SB::Color & color, SB::Window & window, const SB::NetworkInfo & network ) 318 | { 319 | window.print( color, SB::Color::clear(), " \uead0 Network: %s (%s)", network.address().c_str(), network.name().c_str() ); 320 | } 321 | 322 | void displayDate( const SB::Color & color, SB::Window & window, time_t time ) 323 | { 324 | struct tm * local = localtime( &time ); 325 | 326 | char buf[ 1024 ]; 327 | 328 | memset( buf, 0, sizeof( buf ) ); 329 | strftime( buf, sizeof( buf ), "%d.%m.%Y", local ); 330 | 331 | window.print( color, SB::Color::clear(), "\uf073 %s ", buf ); 332 | } 333 | 334 | void displayTime( const SB::Color & color, SB::Window & window, time_t time ) 335 | { 336 | struct tm * local = localtime( &time ); 337 | 338 | char buf[ 1024 ]; 339 | 340 | memset( buf, 0, sizeof( buf ) ); 341 | strftime( buf, sizeof( buf ), "%H:%M:%S", local ); 342 | 343 | window.print( color, SB::Color::clear(), "\uf017 %s ", buf ); 344 | } 345 | 346 | void showHelp() 347 | { 348 | std::cout << "Usage: statusbar [OPTIONS]" 349 | << std::endl 350 | << std::endl 351 | << "Options:" 352 | << std::endl 353 | << std::endl 354 | << " --help Show this help dialog" << std::endl 355 | << " --cpu Display CPU load" << std::endl 356 | << " --gpu Display GPU load" << std::endl 357 | << " --memory Display memory usage" << std::endl 358 | << " --temperature Display temperature" << std::endl 359 | << " --battery Display battery charge" << std::endl 360 | << " --network Display network address" << std::endl 361 | << " --date Display current date" << std::endl 362 | << " --time Display current time" << std::endl 363 | << " --no-cpu Don't display CPU load" << std::endl 364 | << " --no-gpu Don't display GPU load" << std::endl 365 | << " --no-memory Don't display memory usage" << std::endl 366 | << " --no-temperature Don't display temperature" << std::endl 367 | << " --no-battery Don't display battery charge" << std::endl 368 | << " --no-network Don't display network address" << std::endl 369 | << " --no-date Don't display current date" << std::endl 370 | << " --no-time Don't display current time" << std::endl 371 | << " --cpu-color Color for CPU load" << std::endl 372 | << " --gpu-color Color for GPU load" << std::endl 373 | << " --memory-color Color for memory usage" << std::endl 374 | << " --temperature-color Color for temperature" << std::endl 375 | << " --battery-color Color for battery charge" << std::endl 376 | << " --network-color Color for network address" << std::endl 377 | << " --date-color Color for current date" << std::endl 378 | << " --time-color Color for current time" << std::endl 379 | << std::endl 380 | << "Available Colors: red, yellow, green, cyan, blue, magenta, black, white, clear" 381 | << std::endl; 382 | } 383 | --------------------------------------------------------------------------------