This repository has been archived by the owner on Dec 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 25
/
overscan.c
128 lines (115 loc) · 3.43 KB
/
overscan.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
121
122
123
124
125
126
127
128
/****************************************************************
* overscan.c version 1.0.1 -- get/set overscan values on the fly
* to use this standalone you will need to create the mailbox
* device first. sudo mknod /dev/mailbox c 100 0
* if used with the set_overscan.sh script this is not necessary
****************************************************************
* returns 0 if successful, positive integer if failure
* 1 == unable to open device, 2 == ioctl error
*
****************************************************************
* complete rewrite from scratch of version 0.7
* and add some semblance of error checking.
***************************************************************/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define GET_OVERSCAN 0x0004000a
#define TST_OVERSCAN 0x0004400a
#define SET_OVERSCAN 0x0004800a
#define END_TAG 0x00000000
/*
* send property message to mailbox using ioctl
*/
static int mailbox_property(int file_desc, void *buf)
{
int return_value = ioctl(file_desc, _IOWR(100, 0, char *), buf);
/* ioctl error of some kind */
if (return_value < 0) {
close(file_desc);
exit(2);
}
return return_value;
}
/*
* Get the current values for overscan
*/
static unsigned get_overscan(int file_desc, unsigned coord[4])
{
int i=0;
unsigned property[32];
property[i++] = 0;
property[i++] = 0x00000000;
property[i++] = GET_OVERSCAN;
property[i++] = 0x00000010;
property[i++] = 0x00000000;
property[i++] = 0x00000000;
property[i++] = 0x00000000;
property[i++] = 0x00000000;
property[i++] = 0x00000000;
property[i++] = END_TAG;
property[0] = i*sizeof *property;
mailbox_property(file_desc, property);
coord[0] = property[5]; /* top */
coord[1] = property[6]; /* bottom */
coord[2] = property[7]; /* left */
coord[3] = property[8]; /* right */
return 0;
}
/*
* Set overscan values. No checking that the values are sane or
* successful. If you want to check they've been set you could
* do a get after the set.
*/
static unsigned set_overscan(int file_desc, unsigned coord[4])
{
int i=0;
unsigned property[32];
property[i++] = 0;
property[i++] = 0x00000000;
property[i++] = SET_OVERSCAN;
property[i++] = 0x00000010;
property[i++] = 0x00000010;
property[i++] = coord[0]; /* top */
property[i++] = coord[1]; /* bottom */
property[i++] = coord[2]; /* left */
property[i++] = coord[3]; /* right */
property[i++] = END_TAG;
property[0] = i*sizeof *property;
mailbox_property(file_desc, property);
coord[0] = property[5]; /* top */
coord[1] = property[6]; /* bottom */
coord[2] = property[7]; /* left */
coord[3] = property[8]; /* right */
return 0;
}
/*
* Start of program
*/
int main(int argc, char *argv[])
{
int file_desc;
unsigned coord[4];
file_desc = open("/dev/vcio", 0);
if (file_desc == -1)
exit(1);
/* order of coords on the command line/return order
* top, bottom, left, right and they are all or nothing
* you can't set just one value.
*/
if (argc == 5) {
for (int i=0; i<4; i++)
if (argc > 1+i)
coord[i] = strtoul(argv[1+i], 0, 0);
set_overscan(file_desc, coord);
} else {
get_overscan(file_desc, coord);
printf("%d %d %d %d\n", coord[0], coord[1], coord[2], coord[3]);
}
close(file_desc);
return 0;
}