I've been fiddling with the framebuffer device and have discovered an
inconsistency in using it on different architectures. The test program
that follows opens the framebuffer device, mmap's it, sets a palette
entry, and clears the screen.
Linux/x86 (Red Hat 6.0, kernel 2.2.13) and Linux/m68k (Mac IIci, Debian
2.1, kernel 2.2.6) act as expected: the background turns red, the
foreground is erased, the program exits and a new prompt is displayed.
With Linux/Sparc (Red Hat 6.1, kernel 2.2.12-42) the foreground is never
erased. In fact, is seems I can't write _anything_ to the mmap'd buffer.
Any suggestions?
- Greg
--- cut ---
/*
* fbtest.c
*
* build: gcc fbtest.c -o fbtest
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
int init(void);
void clear(void);
int setrgb(int, int, int, int);
unsigned char *vmem;
int fd = -1;
int buffer_size;
static u_int16_t red[256], blue[256], green[256], transp[256];
static struct fb_cmap pal;
int init(void)
{
struct fb_var_screeninfo info;
if ((fd = open("/dev/fb0", O_RDWR)) == -1)
{
fprintf(stderr, "cannot open framebuffer device (%s)\n",
strerror(errno));
return -1;
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &info))
{
fprintf(stderr, "ioctl failed on framebuffer device (%s)\n",
strerror(errno));
close(fd);
return -1;
}
/* we're only going to try 8-bit pixels: */
if (info.bits_per_pixel == 8)
buffer_size = info.xres * info.yres;
else
{
fprintf(stderr, "we don't do % bits per pixel mode\n",
info.bits_per_pixel);
close(fd);
return -1;
}
if ((vmem = mmap(NULL, buffer_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0)) == MAP_FAILED)
{
fprintf(stderr, "cannot mmap() framebuffer device (%s)\n",
strerror(errno));
close(fd);
return -1;
}
pal.start = 0;
pal.len = 256;
pal.red = red;
pal.green = green;
pal.blue = blue;
pal.transp = transp;
if (ioctl(fd, FBIOGETCMAP, &pal))
{
fprintf(stderr, "couldn't get cmap\n");
close(fd);
return -1;
}
return 0;
}
void clear(void)
{
memset(vmem, 0, buffer_size);
}
int setrgb(int n, int r, int g, int b)
{
pal.red[n] = r << 8;
pal.green[n] = g << 8;
pal.blue[n] = b << 8;
pal.transp[n] = 0;
return ioctl(fd, FBIOPUTCMAP, &pal);
}
int main(int argc, char **argv)
{
if (!init())
{
setrgb(0, 255, 0, 0);
clear();
}
return 0;
}
--- cut ---
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/