Code:
// Declare includes.
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
// Declare defines.
#define FRAMEBUFFER "/dev/fb0"
#define PROGRAM_NAME_SIZE 50
#define SIZE_OF_MARK 4
// Declare stuctures.
struct _colour
{
int blue;
int green;
int red;
int transparency;
};
struct _info
{
int fbfd;
char *fbp;
long screensize;
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
};
// Declare global variables.
char program_name[PROGRAM_NAME_SIZE + 1] = {0};
// Declare function prototypes.
void framebuffer_writing (void);
void get_info (struct _info *info);
void mark_row (int x, int y, int length, struct _info *info, struct _colour *colour);
int main (int argc, char *argv[])
{
// Get program name for error reporting.
strcpy(program_name, basename(argv[0]));
// Check number of arguments.
if(argc != 1)
{
fprintf(stderr, "Usage: %s\n", program_name);
exit(EXIT_FAILURE);
}
// Run process.
framebuffer_writing();
// Exit cleanly.
exit(EXIT_SUCCESS);
}
void framebuffer_writing (void)
{
// Declare variables.
struct _info info = {0};
struct _colour red = {0x00, 0x00, 0x87, 0x00};
// Get the framebuffer file descriptor.
get_info(&info);
// Make gradient row.
for(int a = 0; a < 255; a++, red.transparency++)
mark_row(0 + (a * SIZE_OF_MARK), 300, 1, &info, &red);
// Used to show the transparency value was changed.
printf("Transparency = %d\n", red.transparency);
// Unmap the framebuffer.
munmap(info.fbp, info.screensize);
// Close framebuffer file descriptor.
close(info.fbfd);
}
void get_info (struct _info *info)
{
// Open the framebuffer for reading and writing.
if(((*info).fbfd = open(FRAMEBUFFER, O_RDWR)) == -1)
{
fprintf(stderr, "%s: %s error: open failed (%s) (%s)\n", program_name, __func__, strerror(errno), FRAMEBUFFER);
exit(EXIT_FAILURE);
}
// Get fixed screen information.
if(ioctl((*info).fbfd, FBIOGET_FSCREENINFO, &(*info).finfo) == -1)
{
fprintf(stderr, "%s: %s error: ioctl failed (%s) (Error reading fixed information)\n", program_name, __func__, strerror(errno));
exit(EXIT_FAILURE);
}
// Get variable screen information.
if(ioctl((*info).fbfd, FBIOGET_VSCREENINFO, &(*info).vinfo) == -1)
{
fprintf(stderr, "%s: %s error: ioctl failed (%s) (Error reading variable information)\n", program_name, __func__, strerror(errno));
exit(EXIT_FAILURE);
}
// Figure out the size of the screen in bytes.
(*info).screensize = (*info).vinfo.xres * (*info).vinfo.yres * (*info).vinfo.bits_per_pixel / 8;
// Map the device to memory.
if (((*info).fbp = (char *)mmap(0, (*info).screensize, PROT_READ | PROT_WRITE, MAP_SHARED, (*info).fbfd, 0)) == MAP_FAILED)
{
fprintf(stderr, "%s: %s error: mmap failed (%s)\n", program_name, __func__, strerror(errno));
exit(EXIT_FAILURE);
}
}
void mark_row (int x, int y, int length, struct _info *info, struct _colour *colour)
{
// Declare variables.
long location = {0};
// Fill in a box on the framebuffer.
for(int a = 0; a < SIZE_OF_MARK; a++)
for(int b = 0; b < (SIZE_OF_MARK * length); b++)
{
// Determine location of the pixel placement.
location = (b + x + (*info).vinfo.xoffset) * ((*info).vinfo.bits_per_pixel / 8) + (a + y + (*info).vinfo.yoffset) * (*info).finfo.line_length;
// Set each colour for the pixel in question.
*((*info).fbp + location) = (*colour).blue;
*((*info).fbp + location + 1) = (*colour).green;
*((*info).fbp + location + 2) = (*colour).red;
*((*info).fbp + location + 3) = (*colour).transparency;
}
}
Can someone please give a little insight into why the transparency might not be changing for me?