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