Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.bin/backlight/backlight.c
34677 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2020 Emmanuel Vadot <[email protected]>
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <sys/types.h>
29
#include <sys/ioctl.h>
30
#include <stdbool.h>
31
#include <sys/capsicum.h>
32
#include <sys/backlight.h>
33
34
#include <err.h>
35
#include <errno.h>
36
#include <fcntl.h>
37
#include <limits.h>
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include <unistd.h>
42
#include <capsicum_helpers.h>
43
44
#define BACKLIGHT_QUERY 0x0001
45
#define BACKLIGHT_SET_BRIGHTNESS 0x0002
46
#define BACKLIGHT_INCR 0x0004
47
#define BACKLIGHT_DECR 0x0008
48
#define BACKLIGHT_INFO 0x0010
49
50
static char device_name[PATH_MAX] = "/dev/backlight/backlight0";
51
52
static void
53
set_device_name(const char *name)
54
{
55
56
if (name[0] == '/')
57
strlcpy(device_name, name, sizeof(device_name));
58
else
59
snprintf(device_name, sizeof(device_name), "/dev/backlight/%s", name);
60
}
61
62
static void
63
usage(void)
64
{
65
fprintf(stderr, "Usage:\n");
66
fprintf(stderr, "\tbacklight [-q] [-f device]\n");
67
fprintf(stderr, "\tbacklight [-q] [-f device] -i\n");
68
fprintf(stderr, "\tbacklight [-f device] value\n");
69
fprintf(stderr, "\tbacklight [-f device] incr|+ value\n");
70
fprintf(stderr, "\tbacklight [-f device] decr|- value\n");
71
exit(1);
72
}
73
74
static const char *
75
backlight_type_to_string(enum backlight_info_type type)
76
{
77
switch (type) {
78
case BACKLIGHT_TYPE_PANEL:
79
return ("Panel");
80
case BACKLIGHT_TYPE_KEYBOARD:
81
return ("Keyboard");
82
}
83
84
return ("Unknown");
85
}
86
87
int
88
main(int argc, char *argv[])
89
{
90
struct backlight_props props;
91
struct backlight_info info;
92
int fd;
93
int action, ch;
94
cap_rights_t right_ioctl;
95
const unsigned long backlight_ioctls[] = {
96
BACKLIGHTGETSTATUS,
97
BACKLIGHTUPDATESTATUS,
98
BACKLIGHTGETINFO};
99
long percent = -1;
100
const char *percent_error;
101
uint32_t i;
102
bool quiet = false;
103
104
action = BACKLIGHT_QUERY;
105
fd = -1;
106
107
while ((ch = getopt(argc, argv, "f:qhi")) != -1) {
108
switch (ch) {
109
case 'q':
110
quiet = true;
111
break;
112
case 'f':
113
set_device_name(optarg);
114
break;
115
case 'i':
116
action = BACKLIGHT_INFO;
117
break;
118
case 'h':
119
usage();
120
break;
121
}
122
}
123
124
argc -= optind;
125
argv += optind;
126
if (argc != 0) {
127
if (strcmp("incr", argv[0]) == 0 ||
128
strcmp("+", argv[0]) == 0) {
129
action = BACKLIGHT_INCR;
130
argc -= 1;
131
argv += 1;
132
}
133
else if (strcmp("decr", argv[0]) == 0 ||
134
strcmp("-", argv[0]) == 0) {
135
action = BACKLIGHT_DECR;
136
argc -= 1;
137
argv += 1;
138
} else
139
action = BACKLIGHT_SET_BRIGHTNESS;
140
141
if (argc == 1) {
142
/* ignore a trailing % for user friendlyness */
143
if (strlen(argv[0]) > 0 &&
144
argv[0][strlen(argv[0]) - 1] == '%')
145
argv[0][strlen(argv[0]) - 1] = '\0';
146
percent = strtonum(argv[0], 0, 100, &percent_error);
147
if (percent_error)
148
errx(1, "Cannot parse brightness level %s: %s",
149
argv[0],
150
percent_error);
151
}
152
}
153
154
if ((fd = open(device_name, O_RDWR)) == -1)
155
errx(1, "cannot open %s: %s",
156
device_name, strerror(errno));
157
158
if (caph_limit_stdio() < 0)
159
errx(1, "can't limit stdio rights");
160
caph_cache_catpages();
161
cap_rights_init(&right_ioctl, CAP_IOCTL);
162
if (caph_rights_limit(fd, &right_ioctl) < 0)
163
errx(1, "cap_right_limit() failed");
164
if (caph_ioctls_limit(fd, backlight_ioctls, nitems(backlight_ioctls)) < 0)
165
errx(1, "caph_ioctls_limit() failed");
166
if (caph_enter() < 0)
167
errx(1, "failed to enter capability mode");
168
169
switch (action) {
170
case BACKLIGHT_QUERY:
171
if (ioctl(fd, BACKLIGHTGETSTATUS, &props) == -1)
172
errx(1, "Cannot query the backlight device");
173
if (quiet)
174
printf("%u\n", props.brightness);
175
else {
176
printf("brightness: %d\n", props.brightness);
177
if (props.nlevels != 0) {
178
printf("levels:");
179
for (i = 0; i < props.nlevels; i++)
180
printf(" %d", props.levels[i]);
181
printf("\n");
182
}
183
}
184
break;
185
case BACKLIGHT_SET_BRIGHTNESS:
186
if (percent == -1)
187
usage();
188
props.brightness = percent;
189
if (ioctl(fd, BACKLIGHTUPDATESTATUS, &props) == -1)
190
errx(1, "Cannot update the backlight device");
191
break;
192
case BACKLIGHT_INCR:
193
case BACKLIGHT_DECR:
194
if (percent == 0)
195
/* Avoid any ioctl if we don't have anything to do */
196
break;
197
if (ioctl(fd, BACKLIGHTGETSTATUS, &props) == -1)
198
errx(1, "Cannot query the backlight device");
199
percent = percent == -1 ? 10 : percent;
200
percent = action == BACKLIGHT_INCR ? percent : -percent;
201
props.brightness += percent;
202
if ((int)props.brightness < 0)
203
props.brightness = 0;
204
if (props.brightness > 100)
205
props.brightness = 100;
206
if (ioctl(fd, BACKLIGHTUPDATESTATUS, &props) == -1)
207
errx(1, "Cannot update the backlight device");
208
break;
209
case BACKLIGHT_INFO:
210
if (ioctl(fd, BACKLIGHTGETINFO, &info) == -1)
211
errx(1, "Cannot query the backlight device");
212
if (quiet == false) {
213
printf("Backlight name: %s\n", info.name);
214
printf("Backlight hardware type: %s\n", backlight_type_to_string(info.type));
215
} else {
216
printf("%s\n", info.name);
217
printf("%s\n", backlight_type_to_string(info.type));
218
}
219
break;
220
}
221
222
close(fd);
223
return (0);
224
}
225
226