1 | #include <unistd.h>
|
2 | #include <stdio.h>
|
3 | #include <stdlib.h>
|
4 | #include <string.h>
|
5 | #include <fcntl.h>
|
6 | #include <linux/fb.h>
|
7 | #include <sys/mman.h>
|
8 |
|
9 | // 'global' variables to store screen info
|
10 | char *fbp = 0;
|
11 | struct fb_var_screeninfo vinfo;
|
12 | struct fb_fix_screeninfo finfo;
|
13 |
|
14 | // helper function to 'plot' a pixel in given color
|
15 | //
|
16 | // x, y sind Pixelkoordinaten, (0,0) ist links oben
|
17 | // color ist Farbe als unsigned long: 0x00rrggbb für RGB
|
18 | //
|
19 | void put_pixel(long x, long y, long c)
|
20 | {
|
21 | unsigned long pix_offset;
|
22 |
|
23 | pix_offset = 3 * x + y * finfo.line_length;
|
24 | *((char*)(fbp + pix_offset )) = (unsigned char)(c & 0x000000ff);
|
25 | *((char*)(fbp + pix_offset+1)) = (unsigned char)((c >> 8) & 0x000000ff);
|
26 | *((char*)(fbp + pix_offset+2)) = (unsigned char)((c >> 16) & 0x000000ff);
|
27 | return;
|
28 | }
|
29 |
|
30 | // helper function for drawing - no more need to go mess with the main function when just want to change what to draw...
|
31 | void draw(void)
|
32 | {
|
33 | long x, y, c;
|
34 | unsigned char r, g, b;
|
35 |
|
36 | for (y = 0; y < vinfo.yres; y++)
|
37 | {
|
38 | for (x = 0; x < vinfo.xres; x++)
|
39 | {
|
40 | r = 0;
|
41 | g = 0;
|
42 | b = 0;
|
43 | // oberes Bildviertel: Balken, links schwarz,
|
44 | // nach rechts überblenden zu rot
|
45 | if ((y >= 0) && (y < vinfo.yres/4))
|
46 | {
|
47 | r = (unsigned char)((255*x)/vinfo.xres);
|
48 | }
|
49 | // zweites Bildviertel: Balken, links schwarz,
|
50 | // nach rechts überblenden zu grün
|
51 | if ((y >= vinfo.yres/4) && (y < vinfo.yres/2))
|
52 | {
|
53 | g = (unsigned char)((255*x)/vinfo.xres);
|
54 | }
|
55 | // drittes Bildviertel: Balken, links schwarz,
|
56 | // nach rechts überblenden zu blau
|
57 | if ((y >= vinfo.yres/2) && (y < vinfo.yres*3/4))
|
58 | {
|
59 | b = (unsigned char)((255*x)/vinfo.xres);
|
60 | }
|
61 | // unteres Bildviertel: Balken, links schwarz,
|
62 | // nach rechts überblenden zu weiß
|
63 | if ((y >= vinfo.yres*3/4) && (y <= vinfo.yres))
|
64 | {
|
65 | r = (unsigned char)((255*x)/vinfo.xres);
|
66 | g = (unsigned char)((255*x)/vinfo.xres);
|
67 | b = (unsigned char)((255*x)/vinfo.xres);
|
68 | }
|
69 | c = (int)(((r << 16) & 0x00ff0000) | ((g << 8) & 0x0000ff00) | (b & 0x000000ff));
|
70 | put_pixel(x, y, c);
|
71 | }
|
72 | }
|
73 | return;
|
74 | }
|
75 |
|
76 | // application entry point
|
77 | int main(int argc, char* argv[])
|
78 | {
|
79 | int fbfd = 0;
|
80 | struct fb_var_screeninfo orig_vinfo;
|
81 | long int screensize = 0;
|
82 | long int x;
|
83 |
|
84 | fbfd = open("/dev/fb0", O_RDWR); // Open the file for reading and writing
|
85 | if (!fbfd)
|
86 | {
|
87 | // printf("Error: cannot open framebuffer device.\n");
|
88 | return(1);
|
89 | }
|
90 | // printf("The framebuffer device was opened successfully.\n");
|
91 |
|
92 | if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) // Get variable screen information
|
93 | {
|
94 | // printf("Error reading variable information.\n");
|
95 | }
|
96 | // printf("Original %dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
|
97 |
|
98 | memcpy(&orig_vinfo, &vinfo, sizeof(struct fb_var_screeninfo)); // Store for reset (copy vinfo to vinfo_orig)
|
99 |
|
100 | vinfo.bits_per_pixel = 24; // Change variable info
|
101 | if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo))
|
102 | {
|
103 | // printf("Error setting variable information.\n");
|
104 | }
|
105 |
|
106 | if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) // Get fixed screen information
|
107 | {
|
108 | // printf("Error reading fixed information.\n");
|
109 | }
|
110 |
|
111 | screensize = 3 * vinfo.xres * vinfo.yres; // map fb to user mem
|
112 | fbp = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
|
113 |
|
114 | if ((int)fbp == -1)
|
115 | {
|
116 | // printf("Failed to mmap.\n");
|
117 | }
|
118 | else
|
119 | {
|
120 | // draw...
|
121 | draw();
|
122 | for (x = 0; x < 200000000; x++); // delay, danach Programm beenden
|
123 | }
|
124 |
|
125 | munmap(fbp, screensize); // cleanup
|
126 | if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &orig_vinfo))
|
127 | {
|
128 | // printf("Error re-setting variable information.\n");
|
129 | }
|
130 | close(fbfd);
|
131 |
|
132 | return 0;
|
133 | }
|