2 * GraphLCD driver library
4 * framebuffer.h - framebuffer device
5 * Output goes to a framebuffer device
7 * This file is released under the GNU General Public License. Refer
8 * to the COPYING file distributed with this package.
10 * (c) 2004 Stephan Skrodzki
18 #include <sys/ioctl.h>
22 #include "framebuffer.h"
28 cDriverFramebuffer::cDriverFramebuffer(cDriverConfig * config)
33 oldConfig = new cDriverConfig(*config);
36 cDriverFramebuffer::~cDriverFramebuffer()
41 int cDriverFramebuffer::Init()
44 width = config->width;
47 height = config->height;
52 for (unsigned int i = 0; i < config->options.size(); i++)
54 if (config->options[i].name == "Zoom")
56 int z = atoi(config->options[i].value.c_str());
60 syslog(LOG_ERR, "%s error: zoom %d not supported, using default (%d)!\n",
61 config->name.c_str(), z, zoom);
65 // Open the file for reading and writing
66 fbfd = open("/dev/fb0", O_RDWR);
69 syslog(LOG_ERR, "%s: cannot open framebuffer device.\n", config->name.c_str());
72 syslog(LOG_INFO, "%s: The framebuffer device was opened successfully.\n", config->name.c_str());
74 // Get fixed screen information
75 if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))
77 syslog(LOG_ERR, "%s: Error reading fixed information.\n", config->name.c_str());
81 // Get variable screen information
82 if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
84 syslog(LOG_ERR, "%s: Error reading variable information.\n", config->name.c_str());
88 // Figure out the size of the screen in bytes
89 screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
91 syslog(LOG_INFO, "%s: V01: xres: %d, yres %d, vyres: %d, bpp: %d, linelenght: %d\n", config->name.c_str(),vinfo.xres,vinfo.yres,vinfo.yres_virtual,vinfo.bits_per_pixel,finfo.line_length);
93 // reserve another memory to draw into
94 offbuff = new char[screensize];
97 syslog(LOG_ERR, "%s: failed to alloc memory for framebuffer device.\n", config->name.c_str());
101 // Map the device to memory
102 fbp = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
103 if (fbp == MAP_FAILED)
105 syslog(LOG_ERR, "%s: failed to map framebuffer device to memory.\n", config->name.c_str());
108 syslog(LOG_INFO, "%s: The framebuffer device was mapped to memory successfully.\n", config->name.c_str());
110 *oldConfig = *config;
115 syslog(LOG_INFO, "%s: Framebuffer initialized.\n", config->name.c_str());
119 int cDriverFramebuffer::DeInit()
123 munmap(fbp, screensize);
129 int cDriverFramebuffer::CheckSetup()
131 if (config->device != oldConfig->device ||
132 config->port != oldConfig->port ||
133 config->width != oldConfig->width ||
134 config->height != oldConfig->height)
141 if (config->upsideDown != oldConfig->upsideDown ||
142 config->invert != oldConfig->invert)
144 oldConfig->upsideDown = config->upsideDown;
145 oldConfig->invert = config->invert;
151 void cDriverFramebuffer::SetPixel(int x, int y)
156 if (x >= width || y >= height)
159 if (config->upsideDown)
165 // Figure out where in memory to put the pixel
166 location = (x*(1+zoom)+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
167 (y*(1+zoom)+vinfo.yoffset) * finfo.line_length;
169 if (vinfo.bits_per_pixel <= 8)
178 if (vinfo.bits_per_pixel <= 8)
180 *(offbuff + location) = outcol;
183 *(offbuff + location + 1) = outcol;
184 *(offbuff + location + finfo.line_length) = outcol;
185 *(offbuff + location + finfo.line_length + 1) = outcol;
188 else if (vinfo.bits_per_pixel <= 16)
190 *(offbuff + location) = outcol;
191 *(offbuff + location + 1) = outcol;
194 *(offbuff + location + 2) = outcol;
195 *(offbuff + location + 3) = outcol;
196 *(offbuff + location + finfo.line_length) = outcol;
197 *(offbuff + location + finfo.line_length + 1) = outcol;
198 *(offbuff + location + finfo.line_length + 2) = outcol;
199 *(offbuff + location + finfo.line_length + 3) = outcol;
204 *(offbuff + location) = outcol;
205 *(offbuff + location + 1) = outcol;
206 *(offbuff + location + 2) = outcol;
207 *(offbuff + location + 3) = 0; /* should be transparency */
210 *(offbuff + location + 4) = outcol;
211 *(offbuff + location + 5) = outcol;
212 *(offbuff + location + 6) = outcol;
213 *(offbuff + location + 7) = 0;
214 *(offbuff + location + finfo.line_length) = outcol;
215 *(offbuff + location + finfo.line_length + 1) = outcol;
216 *(offbuff + location + finfo.line_length + 2) = outcol;
217 *(offbuff + location + finfo.line_length + 3) = 0;
218 *(offbuff + location + finfo.line_length + 4) = outcol;
219 *(offbuff + location + finfo.line_length + 5) = outcol;
220 *(offbuff + location + finfo.line_length + 6) = outcol;
221 *(offbuff + location + finfo.line_length + 7) = 0;
226 void cDriverFramebuffer::Clear()
228 memset(offbuff, 0, screensize);
231 void cDriverFramebuffer::Set8Pixels(int x, int y, unsigned char data)
237 for (n = 0; n < 8; ++n)
239 if (data & (0x80 >> n)) // if bit is set
244 void cDriverFramebuffer::Refresh(bool refreshAll)
246 memcpy(fbp, offbuff, screensize);
249 } // end of namespace