1#include <ctype.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/mman.h>
5#include <fcntl.h>
6#include <string.h>
7#include <termios.h>
8#include <unistd.h>
9#include <errno.h>
10#include <linux/fb.h>
11
12
13int rotatefb_main(int argc, char *argv[])
14{
15    int c;
16    char *fbdev = "/dev/graphics/fb0";
17    int rotation = 0;
18    int fd;
19    int res;
20    struct fb_var_screeninfo fbinfo;
21
22    do {
23        c = getopt(argc, argv, "d:");
24        if (c == EOF)
25            break;
26        switch (c) {
27        case 'd':
28            fbdev = optarg;
29            break;
30        case '?':
31            fprintf(stderr, "%s: invalid option -%c\n",
32                argv[0], optopt);
33            exit(1);
34        }
35    } while (1);
36
37    if(optind + 1 != argc) {
38        fprintf(stderr, "%s: specify rotation\n", argv[0]);
39        exit(1);
40    }
41    rotation = atoi(argv[optind]);
42
43    fd = open(fbdev, O_RDWR);
44    if(fd < 0) {
45        fprintf(stderr, "cannot open %s\n", fbdev);
46        return 1;
47    }
48
49    res = ioctl(fd, FBIOGET_VSCREENINFO, &fbinfo);
50    if(res < 0) {
51        fprintf(stderr, "failed to get fbinfo: %s\n", strerror(errno));
52        return 1;
53    }
54    if((fbinfo.rotate ^ rotation) & 1) {
55        unsigned int xres = fbinfo.yres;
56        fbinfo.yres = fbinfo.xres;
57        fbinfo.xres = xres;
58        fbinfo.xres_virtual = fbinfo.xres;
59        fbinfo.yres_virtual = fbinfo.yres * 2;
60        if(fbinfo.yoffset == xres)
61            fbinfo.yoffset = fbinfo.yres;
62    }
63    fbinfo.rotate = rotation;
64    res = ioctl(fd, FBIOPUT_VSCREENINFO, &fbinfo);
65    if(res < 0) {
66        fprintf(stderr, "failed to set fbinfo: %s\n", strerror(errno));
67        return 1;
68    }
69
70    return 0;
71}
72