OSDN Git Service

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