├── .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 | [](https://github.com/macmade/statusbar/actions/workflows/ci-mac.yaml)
5 | [](https://github.com/macmade/statusbar/issues)
6 | 
7 | 
8 | [](https://twitter.com/macmade)
9 | [](https://github.com/sponsors/macmade)
10 |
11 | ### About
12 |
13 | Statusbar for your terminal:
14 |
15 | 
16 | 
17 | 
18 | 
19 | 
20 | 
21 | 
22 | 
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