-
Notifications
You must be signed in to change notification settings - Fork 0
/
display.c
120 lines (103 loc) · 3.68 KB
/
display.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* PiTabDaemon - Display Brightness Management */
/* Copyright (c) 2017 by Stefan Vorkoetter
This file is part of PiTabDaemon.
PiTabDaemon is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PiTabDaemon is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PiTabDaemon. If not, see <http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include "display.h"
/* These levels were chosen to result in a doubling of LED current over a
range of about 4mA to 500mA, and then tweaking them until the brightness
changes appeared to be uniform. */
static const int LEVELS[] = { 0, 10, 14, 23, 42, 72, 115, 172, 212 };
static const int NUM_LEVELS = sizeof(LEVELS) / sizeof(int);
static const int DEFAULT_INDEX = 4;
static int nextLevelIndex, currentLevel, targetLevel, rememberLevel;
/* Initialize brightness as specified, or about 1/4 of maximum (about 3/4
perceptually) by default if specified index is 0 or out of range. */
void InitBrightness( int initialIndex )
{
nextLevelIndex = 0 < initialIndex && initialIndex < NUM_LEVELS
? initialIndex : DEFAULT_INDEX;
NextBrightness();
currentLevel = targetLevel - 1;
NudgeBrightness();
}
/* Set the target brightness to the next value in the table. */
void NextBrightness( void )
{
/* Set target brightness from table and compute index for next time. */
targetLevel = rememberLevel = LEVELS[nextLevelIndex];
nextLevelIndex = (nextLevelIndex + 1) % NUM_LEVELS;
}
/* Set the target brightness to the maximum brighness value in the table. */
void MaxBrightness( void )
{
targetLevel = rememberLevel = LEVELS[NUM_LEVELS-1];
nextLevelIndex = 0;
}
/* Return the current brightness index. */
int GetBrightnessIndex( void )
{
return( (nextLevelIndex + NUM_LEVELS - 1) % NUM_LEVELS );
}
/* Nudge the display brightness towards the target brightness by 5% of the
current brightness. */
void NudgeBrightness( void )
{
if( currentLevel != targetLevel ) {
if( currentLevel == 0 )
currentLevel = LEVELS[1];
else if( currentLevel < targetLevel ) {
if( currentLevel < 20 )
++currentLevel;
else
currentLevel = (currentLevel * 21) / 20;
if( currentLevel > targetLevel )
currentLevel = targetLevel;
}
else {
/* Darken faster than we brighten so that full-on to full-off
doesn't take so long. */
currentLevel = (currentLevel * 10) / 11;
if( currentLevel < targetLevel )
currentLevel = targetLevel;
}
FILE *fp = fopen("/sys/class/backlight/rpi_backlight/brightness","w");
if( fp != NULL ) {
fprintf(fp,"%d\n",currentLevel);
fclose(fp);
}
}
}
/* Temporarily dim the display (unless it's already off) to half the current
perceived brightness. */
void DimDisplay( void )
{
if( nextLevelIndex != 1 ) {
if( nextLevelIndex == 0 )
targetLevel = LEVELS[NUM_LEVELS/2];
else {
targetLevel = LEVELS[(nextLevelIndex-1)/2];
if( targetLevel < LEVELS[1] ) targetLevel = LEVELS[1];
}
}
}
/* Temporarily turn off the backlight. */
void DarkenDisplay( void )
{
targetLevel = LEVELS[0];
}
/* Restore the display to the level it was at before we dimmed it. */
void RestoreDisplay( void )
{
targetLevel = rememberLevel;
// TODO - when restoring to a level 0 display, nudge it up to level 1.
}