/* * GraphLCD driver library * * g15daemon.c - pseudo device for the g15daemon meta driver * Output goes to the g15daemon which then displays it * * This file is released under the GNU General Public License. Refer * to the COPYING file distributed with this package. * * (c) 2005-2010 Andreas Regel * (c) 2011 Wolfgang Astleitner */ #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "config.h" #include "g15daemon.h" #define G15SERVER_PORT 15550 #define G15SERVER_ADDR "127.0.0.1" #define G15_WIDTH 160 #define G15_HEIGHT 43 static int g15_send(int sock, const char *buf, int len) { int total = 0; int retval = 0; int bytesleft = len; while (total < len) { retval = send(sock, buf+total, bytesleft, 0); if (retval == -1) { break; } bytesleft -= retval; total += retval; } return retval==-1?-1:0; } static int g15_recv(int sock, char *buf, int len) { int total = 0; int retval = 0; int bytesleft = len; while (total < len) { retval = recv(sock, buf+total, bytesleft, 0); if (retval < 1) { break; } total += retval; bytesleft -= retval; } return total; } static int open_g15_daemon() { int g15screen_fd; struct sockaddr_in serv_addr; char buffer[256]; g15screen_fd = socket(AF_INET, SOCK_STREAM, 0); if (g15screen_fd < 0) return -1; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; inet_aton (G15SERVER_ADDR, &serv_addr.sin_addr); serv_addr.sin_port = htons(G15SERVER_PORT); if (connect(g15screen_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) return -1; memset(buffer,0,256); if (g15_recv(g15screen_fd, buffer, 16)<0) return -1; /* here we check that we're really talking to the g15daemon */ if (strcmp(buffer,"G15 daemon HELLO") != 0) return -1; /* we want to use a pixelbuffer */ g15_send(g15screen_fd,"GBUF",4); return g15screen_fd; } namespace GLCD { cDriverG15daemon::cDriverG15daemon(cDriverConfig * config) : config(config), offbuff(0), sockfd(-1) { oldConfig = new cDriverConfig(*config); } cDriverG15daemon::~cDriverG15daemon() { delete oldConfig; } int cDriverG15daemon::Init() { // default values width = config->width; if (width !=G15_WIDTH) width = G15_WIDTH; height = config->height; if (height !=G15_HEIGHT) height = G15_HEIGHT; for (unsigned int i = 0; i < config->options.size(); i++) { if (config->options[i].name == "") { } } screensize = 6880; if ((sockfd = open_g15_daemon())<0) return -1; // reserve memory to draw into offbuff = new char[6880]; *oldConfig = *config; // clear display Refresh(true); syslog(LOG_INFO, "%s: g15daemon initialized.\n", config->name.c_str()); return 0; } int cDriverG15daemon::DeInit() { if (offbuff); delete[] offbuff; if (-1 != sockfd) close(sockfd); return 0; } int cDriverG15daemon::CheckSetup() { if (config->device != oldConfig->device || config->port != oldConfig->port || config->width != oldConfig->width || config->height != oldConfig->height) { DeInit(); Init(); return 0; } if (config->upsideDown != oldConfig->upsideDown || config->invert != oldConfig->invert) { oldConfig->upsideDown = config->upsideDown; oldConfig->invert = config->invert; return 1; } return 0; } void cDriverG15daemon::SetPixel(int x, int y, uint32_t data) { if (x >= width || y >= height) return; if (config->upsideDown) { x = width - 1 - x; y = height - 1 - y; } offbuff[x + (width * y)] = ( (data == GLCD::cColor::White) ? 1 : 0 ); } void cDriverG15daemon::Clear() { memset(offbuff, 0, screensize); } #if 0 void cDriverG15daemon::Set8Pixels(int x, int y, unsigned char data) { int n; x &= 0xFFF8; for (n = 0; n < 8; ++n) { if (data & (0x80 >> n)) // if bit is set SetPixel(x + n, y, GLCD::cColor::White); } } #endif void cDriverG15daemon::Refresh(bool refreshAll) { g15_send(sockfd, offbuff, screensize); } } // end of namespace