Root/frame_buffer/fbutils.c

1/*
2 * fbutils.c
3 *
4 * Utility routines for framebuffer interaction
5 *
6 * Copyright 2002 Russell King and Doug Lowder
7 *
8 * This file is placed under the GPL. Please see the
9 * file COPYING for details.
10 *
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17#include <sys/fcntl.h>
18#include <sys/ioctl.h>
19#include <sys/mman.h>
20#include <sys/time.h>
21
22#include <linux/vt.h>
23#include <linux/kd.h>
24#include <linux/fb.h>
25
26#include "font.h"
27#include "fbutils.h"
28
29union multiptr {
30    unsigned char *p8;
31    unsigned short *p16;
32    unsigned long *p32;
33};
34
35static int con_fd, last_vt = -1;
36static struct fb_fix_screeninfo fix;
37static struct fb_var_screeninfo var;
38static unsigned char *fbuffer;
39static unsigned char **line_addr;
40static int fb_fd=0;
41static int bytes_per_pixel;
42static unsigned colormap [256];
43__u32 xres, yres;
44
45static char *defaultfbdevice = "/dev/fb0";
46static char *defaultconsoledevice = "/dev/tty";
47static char *fbdevice = NULL;
48static char *consoledevice = NULL;
49
50int open_framebuffer(void)
51{
52    struct vt_stat vts;
53    char vtname[128];
54    int fd, nr;
55    unsigned y, addr;
56
57    if ((fbdevice = getenv ("TSLIB_FBDEVICE")) == NULL)
58        fbdevice = defaultfbdevice;
59
60    if ((consoledevice = getenv ("TSLIB_CONSOLEDEVICE")) == NULL)
61        consoledevice = defaultconsoledevice;
62
63    if (strcmp (consoledevice, "none") != 0) {
64        sprintf (vtname,"%s%d", consoledevice, 1);
65            fd = open (vtname, O_WRONLY);
66            if (fd < 0) {
67                    perror("open consoledevice");
68                    return -1;
69            }
70
71        if (ioctl(fd, VT_OPENQRY, &nr) < 0) {
72                    perror("ioctl VT_OPENQRY");
73                    return -1;
74            }
75            close(fd);
76
77            sprintf(vtname, "%s%d", consoledevice, nr);
78
79            con_fd = open(vtname, O_RDWR | O_NDELAY);
80            if (con_fd < 0) {
81                    perror("open tty");
82                    return -1;
83            }
84
85            if (ioctl(con_fd, VT_GETSTATE, &vts) == 0)
86                    last_vt = vts.v_active;
87
88            if (ioctl(con_fd, VT_ACTIVATE, nr) < 0) {
89                    perror("VT_ACTIVATE");
90                    close(con_fd);
91                    return -1;
92            }
93
94            if (ioctl(con_fd, VT_WAITACTIVE, nr) < 0) {
95                    perror("VT_WAITACTIVE");
96                    close(con_fd);
97                    return -1;
98            }
99
100            if (ioctl(con_fd, KDSETMODE, KD_GRAPHICS) < 0) {
101                    perror("KDSETMODE");
102                    close(con_fd);
103                    return -1;
104            }
105
106    }
107
108    fb_fd = open(fbdevice, O_RDWR);
109    if (fb_fd == -1) {
110        perror("open fbdevice");
111        return -1;
112    }
113
114    if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fix) < 0) {
115        perror("ioctl FBIOGET_FSCREENINFO");
116        close(fb_fd);
117        return -1;
118    }
119
120    if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var) < 0) {
121        perror("ioctl FBIOGET_VSCREENINFO");
122        close(fb_fd);
123        return -1;
124    }
125    xres = var.xres;
126    yres = var.yres;
127
128    fbuffer = mmap(NULL, fix.smem_len, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fb_fd, 0);
129    if (fbuffer == (unsigned char *)-1) {
130        perror("mmap framebuffer");
131        close(fb_fd);
132        return -1;
133    }
134    memset(fbuffer,0,fix.smem_len);
135
136    bytes_per_pixel = (var.bits_per_pixel + 7) / 8;
137    line_addr = malloc (sizeof (__u32) * var.yres_virtual);
138    addr = 0;
139    for (y = 0; y < var.yres_virtual; y++, addr += fix.line_length)
140        line_addr [y] = fbuffer + addr;
141
142    return 0;
143}
144
145void close_framebuffer(void)
146{
147    munmap(fbuffer, fix.smem_len);
148    close(fb_fd);
149
150
151    if(strcmp(consoledevice,"none")!=0) {
152    
153            if (ioctl(con_fd, KDSETMODE, KD_TEXT) < 0)
154                    perror("KDSETMODE");
155
156            if (last_vt >= 0)
157                    if (ioctl(con_fd, VT_ACTIVATE, last_vt))
158                            perror("VT_ACTIVATE");
159
160            close(con_fd);
161    }
162
163        free (line_addr);
164}
165
166void put_cross(int x, int y, unsigned colidx)
167{
168    line (x - 10, y, x - 2, y, colidx);
169    line (x + 2, y, x + 10, y, colidx);
170    line (x, y - 10, x, y - 2, colidx);
171    line (x, y + 2, x, y + 10, colidx);
172
173#if 1
174    line (x - 6, y - 9, x - 9, y - 9, colidx + 1);
175    line (x - 9, y - 8, x - 9, y - 6, colidx + 1);
176    line (x - 9, y + 6, x - 9, y + 9, colidx + 1);
177    line (x - 8, y + 9, x - 6, y + 9, colidx + 1);
178    line (x + 6, y + 9, x + 9, y + 9, colidx + 1);
179    line (x + 9, y + 8, x + 9, y + 6, colidx + 1);
180    line (x + 9, y - 6, x + 9, y - 9, colidx + 1);
181    line (x + 8, y - 9, x + 6, y - 9, colidx + 1);
182#else
183    line (x - 7, y - 7, x - 4, y - 4, colidx + 1);
184    line (x - 7, y + 7, x - 4, y + 4, colidx + 1);
185    line (x + 4, y - 4, x + 7, y - 7, colidx + 1);
186    line (x + 4, y + 4, x + 7, y + 7, colidx + 1);
187#endif
188}
189
190void put_char(int x, int y, int c, int colidx)
191{
192    int i,j,bits;
193
194    for (i = 0; i < font_vga_8x8.height; i++) {
195        bits = font_vga_8x8.data [font_vga_8x8.height * c + i];
196        for (j = 0; j < font_vga_8x8.width; j++, bits <<= 1)
197            if (bits & 0x80)
198                pixel (x + j, y + i, colidx);
199    }
200}
201
202void put_string(int x, int y, char *s, unsigned colidx)
203{
204    int i;
205    for (i = 0; *s; i++, x += font_vga_8x8.width, s++)
206        put_char (x, y, *s, colidx);
207}
208
209void put_string_center(int x, int y, char *s, unsigned colidx)
210{
211    size_t sl = strlen (s);
212        put_string (x - (sl / 2) * font_vga_8x8.width,
213                    y - font_vga_8x8.height / 2, s, colidx);
214}
215
216void setcolor(unsigned colidx, unsigned value)
217{
218    unsigned res;
219    unsigned short red, green, blue;
220    struct fb_cmap cmap;
221
222#ifdef DEBUG
223    if (colidx > 255) {
224        fprintf (stderr, "WARNING: color index = %u, must be <256\n",
225             colidx);
226        return;
227    }
228#endif
229
230    switch (bytes_per_pixel) {
231    default:
232    case 1:
233        res = colidx;
234        red = (value >> 8) & 0xff00;
235        green = value & 0xff00;
236        blue = (value << 8) & 0xff00;
237        cmap.start = colidx;
238        cmap.len = 1;
239        cmap.red = &red;
240        cmap.green = &green;
241        cmap.blue = &blue;
242        cmap.transp = NULL;
243
244            if (ioctl (fb_fd, FBIOPUTCMAP, &cmap) < 0)
245                    perror("ioctl FBIOPUTCMAP");
246        break;
247    case 2:
248    case 4:
249        red = (value >> 16) & 0xff;
250        green = (value >> 8) & 0xff;
251        blue = value & 0xff;
252        res = ((red >> (8 - var.red.length)) << var.red.offset) |
253                      ((green >> (8 - var.green.length)) << var.green.offset) |
254                      ((blue >> (8 - var.blue.length)) << var.blue.offset);
255    }
256        colormap [colidx] = res;
257}
258
259static inline void __setpixel (union multiptr loc, unsigned xormode, unsigned color)
260{
261    switch(bytes_per_pixel) {
262    case 1:
263    default:
264        if (xormode)
265            *loc.p8 ^= color;
266        else
267            *loc.p8 = color;
268        break;
269    case 2:
270        if (xormode)
271            *loc.p16 ^= color;
272        else
273            *loc.p16 = color;
274        break;
275    case 4:
276        if (xormode)
277            *loc.p32 ^= color;
278        else
279            *loc.p32 = color;
280        break;
281    }
282}
283
284void pixel (int x, int y, unsigned colidx)
285{
286    unsigned xormode;
287    union multiptr loc;
288
289    if ((x < 0) || ((__u32)x >= var.xres_virtual) ||
290        (y < 0) || ((__u32)y >= var.yres_virtual))
291        return;
292
293    xormode = colidx & XORMODE;
294    colidx &= ~XORMODE;
295
296#ifdef DEBUG
297    if (colidx > 255) {
298        fprintf (stderr, "WARNING: color value = %u, must be <256\n",
299             colidx);
300        return;
301    }
302#endif
303
304    loc.p8 = line_addr [y] + x * bytes_per_pixel;
305    __setpixel (loc, xormode, colormap [colidx]);
306}
307
308void line (int x1, int y1, int x2, int y2, unsigned colidx)
309{
310    int tmp;
311    int dx = x2 - x1;
312    int dy = y2 - y1;
313
314    if (abs (dx) < abs (dy)) {
315        if (y1 > y2) {
316            tmp = x1; x1 = x2; x2 = tmp;
317            tmp = y1; y1 = y2; y2 = tmp;
318            dx = -dx; dy = -dy;
319        }
320        x1 <<= 16;
321        /* dy is apriori >0 */
322        dx = (dx << 16) / dy;
323        while (y1 <= y2) {
324            pixel (x1 >> 16, y1, colidx);
325            x1 += dx;
326            y1++;
327        }
328    } else {
329        if (x1 > x2) {
330            tmp = x1; x1 = x2; x2 = tmp;
331            tmp = y1; y1 = y2; y2 = tmp;
332            dx = -dx; dy = -dy;
333        }
334        y1 <<= 16;
335        dy = dx ? (dy << 16) / dx : 0;
336        while (x1 <= x2) {
337            pixel (x1, y1 >> 16, colidx);
338            y1 += dy;
339            x1++;
340        }
341    }
342}
343
344void rect (int x1, int y1, int x2, int y2, unsigned colidx)
345{
346    line (x1, y1, x2, y1, colidx);
347    line (x2, y1, x2, y2, colidx);
348    line (x2, y2, x1, y2, colidx);
349    line (x1, y2, x1, y1, colidx);
350}
351
352void fillrect (int x1, int y1, int x2, int y2, unsigned colidx)
353{
354    int tmp;
355    unsigned xormode;
356    union multiptr loc;
357
358    /* Clipping and sanity checking */
359    if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; }
360    if (y1 > y2) { tmp = y1; y1 = y2; y2 = tmp; }
361    if (x1 < 0) x1 = 0; if ((__u32)x1 >= xres) x1 = xres - 1;
362    if (x2 < 0) x2 = 0; if ((__u32)x2 >= xres) x2 = xres - 1;
363    if (y1 < 0) y1 = 0; if ((__u32)y1 >= yres) y1 = yres - 1;
364    if (y2 < 0) y2 = 0; if ((__u32)y2 >= yres) y2 = yres - 1;
365
366    if ((x1 > x2) || (y1 > y2))
367        return;
368
369    xormode = colidx & XORMODE;
370    colidx &= ~XORMODE;
371
372#ifdef DEBUG
373    if (colidx > 255) {
374        fprintf (stderr, "WARNING: color value = %u, must be <256\n",
375             colidx);
376        return;
377    }
378#endif
379
380    colidx = colormap [colidx];
381
382    for (; y1 <= y2; y1++) {
383        loc.p8 = line_addr [y1] + x1 * bytes_per_pixel;
384        for (tmp = x1; tmp <= x2; tmp++) {
385            __setpixel (loc, xormode, colidx);
386            loc.p8 += bytes_per_pixel;
387        }
388    }
389}
390
391/*****************************TEST FRAMEBUFFER*********************************/
392static int palette [] = \
393{
394    0x000000, 0xffffff, 0xff0000, 0x00ff00, 0x0000ff
395};
396#define NR_COLORS (sizeof (palette) / sizeof (palette [0]))
397
398int main()
399{
400    int i,j,k;
401
402    printf("Opening framebuffer...\n\n");
403
404    if (open_framebuffer()) {
405        close_framebuffer();
406        exit(1);
407        printf("Framebuffer could not be opened!!\n\n");
408    }
409    
410
411    for (i = 0; i < NR_COLORS; i++)
412        setcolor (i, palette [i]);
413
414    printf("Testing... Reslution:%dx%d \n\n",xres,yres);
415    
416        k=10;
417        while(k<=xres/5){
418        for (i = 0; i < xres; i++)
419            for (j = 0; j < yres; j++)
420                if(j<yres/2)
421                    pixel(i,j,(i/k)%5);
422                else
423                    pixel(i,j,(j/k)%5);
424            k+=10;
425        }
426
427     while(1)
428    {
429        put_string_center (xres / 2, yres *0.6,
430               "Universidad Nacional de Colombia", 1);
431        put_string_center (xres / 2, yres *0.6 + 80,
432               "2010-III - Plataforma SIE", 2);
433    }
434    close_framebuffer();
435    printf("Framebuffer closed...\n\n");
436}
437
438

Archive Download this file

Branches:
master



interactive