summaryrefslogtreecommitdiff
path: root/glcddrivers/serdisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'glcddrivers/serdisp.c')
-rw-r--r--glcddrivers/serdisp.c280
1 files changed, 197 insertions, 83 deletions
diff --git a/glcddrivers/serdisp.c b/glcddrivers/serdisp.c
index 7521105..5676bb3 100644
--- a/glcddrivers/serdisp.c
+++ b/glcddrivers/serdisp.c
@@ -7,7 +7,7 @@
* This file is released under the GNU General Public License. Refer
* to the COPYING file distributed with this package.
*
- * (c) 2003-2010 Wolfgang Astleitner <mrwastl AT users.sourceforge.net>
+ * (c) 2003-2011 Wolfgang Astleitner <mrwastl AT users.sourceforge.net>
*/
#include <stdio.h>
@@ -19,6 +19,9 @@
#include "config.h"
#include "serdisp.h"
+// for memcpy
+#include <string.h>
+
#define SERDISP_VERSION(a,b) ((long)(((a) << 8) + (b)))
#define SERDISP_VERSION_GET_MAJOR(_c) ((int)( (_c) >> 8 ))
#define SERDISP_VERSION_GET_MINOR(_c) ((int)( (_c) & 0xFF ))
@@ -32,15 +35,25 @@
#define SD_COL_BLACK 0xFF000000
#define SD_COL_WHITE 0xFFFFFFFF
+// taken from serdisp_gpevents.h
+#define SDGPT_SIMPLETOUCH 0x10 /* simple touch screen event, type: SDGP_evpkt_simpletouch_t */
+
namespace GLCD
{
+static void wrapEventListener(void* dd, SDGP_event_t* recylce);
+
+static int simpleTouchX=0, simpleTouchY=0, simpleTouchT=0;
+static bool simpleTouchChanged=false;
+
+
cDriverSerDisp::cDriverSerDisp(cDriverConfig * config)
: config(config)
{
oldConfig = new cDriverConfig(*config);
dd = (void *) NULL;
+ simpleTouchChanged = false;
}
cDriverSerDisp::~cDriverSerDisp(void)
@@ -83,95 +96,57 @@ int cDriverSerDisp::Init(void)
fp_serdisp_getversioncode = (long int (*)()) dlsym(sdhnd, "serdisp_getversioncode");
if (dlerror()) { // no serdisp_getversioncode() -> version of serdisplib is < 1.95
- syslog(LOG_DEBUG, "%s: INFO: symbol serdisp_getversioncode unknown: autodetecting pre 1.95 serdisplib version (cDriver::Init)\n",
- config->name.c_str());
-
- fp_SDCONN_open = (void*(*)(const char*)) dlsym(sdhnd, "SDCONN_open");
- if (dlerror()) { // no SDCONN_open() -> version of serdisplib is < 1.93
- serdisp_version = SERDISP_VERSION(1,92);
- syslog(LOG_DEBUG, "%s: INFO: detected serdisplib version <= 1.92 (cDriver::Init)\n", config->name.c_str());
-
- fp_PP_open = (void*(*)(const char*))dlsym(sdhnd, "PP_open");
- if ( (errmsg = dlerror()) != NULL ) { // should not happen
- syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "PP_open", errmsg);
- return -1;
- }
- fp_PP_close = (void*(*)(void*))dlsym(sdhnd, "PP_close");
- if ( (errmsg = dlerror()) != NULL ) { // should not happen
- syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "PP_close", errmsg);
- return -1;
- }
- } else {
- serdisp_version = SERDISP_VERSION(1,94); // no serdisp_getversioncode, but SDCONN_open: 1.93 or 1.94
- syslog(LOG_DEBUG, "%s: INFO: detected serdisplib version 1.93 or 1.94 (cDriver::Init)\n", config->name.c_str());
-
- fp_serdisp_quit = (void (*)(void*)) dlsym(sdhnd, "serdisp_quit");
- if ( (errmsg = dlerror()) != NULL ) { // should not happen
- syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "serdisp_quit", errmsg);
- return -1;
- }
- }
+ syslog(LOG_ERR, "%s: error: serdisplib version >= 1.95 required\n", config->name.c_str());
+ return -1;
+ }
- fp_serdisp_setpixcol = (void (*)(void*, int, int, long int)) dlsym(sdhnd, "serdisp_setpixel");
- if ( (errmsg = dlerror()) != NULL ) { // should not happen
- syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "serdisp_setpixel", errmsg);
- return -1;
- }
- fg_colour = 1; /* set foreground to 'pixel on' */
+ serdisp_version = fp_serdisp_getversioncode();
+ syslog(LOG_DEBUG, "%s: INFO: detected serdisplib version %d.%d (cDriver::Init)\n",
+ config->name.c_str(), SERDISP_VERSION_GET_MAJOR(serdisp_version), SERDISP_VERSION_GET_MINOR(serdisp_version));
- } else { // serdisp version >= 1.95
- serdisp_version = fp_serdisp_getversioncode();
- syslog(LOG_DEBUG, "%s: INFO: detected serdisplib version %d.%d (cDriver::Init)\n",
- config->name.c_str(), SERDISP_VERSION_GET_MAJOR(serdisp_version), SERDISP_VERSION_GET_MINOR(serdisp_version));
+ fp_SDCONN_open = (void*(*)(const char*)) dlsym(sdhnd, "SDCONN_open");
+ if ( (errmsg = dlerror()) != NULL ) { // should not happen
+ syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
+ config->name.c_str(), "SDCONN_open", errmsg);
+ return -1;
+ }
+ fp_serdisp_quit = (void (*)(void*)) dlsym(sdhnd, "serdisp_quit");
+ if ( (errmsg = dlerror()) != NULL ) { // should not happen
+ syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
+ config->name.c_str(), "serdisp_quit", errmsg);
+ return -1;
+ }
+ fp_serdisp_setcolour = (void (*)(void*, int, int, long int)) dlsym(sdhnd, "serdisp_setcolour");
+ if ( (errmsg = dlerror()) != NULL ) { // should not happen
+ syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
+ config->name.c_str(), "serdisp_setcolour", errmsg);
+ return -1;
+ }
+ fg_colour = SD_COL_BLACK; /* set foreground colour to black */
+
+ if (serdisp_version >= SERDISP_VERSION(1,96) ) {
+ supports_options = 1;
- fp_SDCONN_open = (void*(*)(const char*)) dlsym(sdhnd, "SDCONN_open");
+ fp_serdisp_isoption = (int (*)(void*, const char*)) dlsym(sdhnd, "serdisp_isoption");
if ( (errmsg = dlerror()) != NULL ) { // should not happen
syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "SDCONN_open", errmsg);
+ config->name.c_str(), "serdisp_isoption", errmsg);
return -1;
}
- fp_serdisp_quit = (void (*)(void*)) dlsym(sdhnd, "serdisp_quit");
+ fp_serdisp_setoption = (void (*)(void*, const char*, long int)) dlsym(sdhnd, "serdisp_setoption");
if ( (errmsg = dlerror()) != NULL ) { // should not happen
syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "serdisp_quit", errmsg);
+ config->name.c_str(), "serdisp_setoption", errmsg);
return -1;
}
- fp_serdisp_setpixcol = (void (*)(void*, int, int, long int)) dlsym(sdhnd, "serdisp_setcolour");
+ fp_serdisp_getoption = (long int (*)(void*, const char*, int*)) dlsym(sdhnd, "serdisp_getoption");
if ( (errmsg = dlerror()) != NULL ) { // should not happen
syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "serdisp_setcolour", errmsg);
+ config->name.c_str(), "serdisp_getoption", errmsg);
return -1;
}
- fg_colour = SD_COL_BLACK; /* set foreground colour to black */
-
- if (serdisp_version >= SERDISP_VERSION(1,96) ) {
- supports_options = 1;
-
- fp_serdisp_isoption = (int (*)(void*, const char*)) dlsym(sdhnd, "serdisp_isoption");
- if ( (errmsg = dlerror()) != NULL ) { // should not happen
- syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "serdisp_isoption", errmsg);
- return -1;
- }
- fp_serdisp_setoption = (void (*)(void*, const char*, long int)) dlsym(sdhnd, "serdisp_setoption");
- if ( (errmsg = dlerror()) != NULL ) { // should not happen
- syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "serdisp_setoption", errmsg);
- return -1;
- }
- fp_serdisp_getoption = (long int (*)(void*, const char*, int*)) dlsym(sdhnd, "serdisp_getoption");
- if ( (errmsg = dlerror()) != NULL ) { // should not happen
- syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
- config->name.c_str(), "serdisp_getoption", errmsg);
- return -1;
- }
- } /* >= 1.96 */
- }
+ } /* >= 1.96 */
// load other symbols that will be required
fp_serdisp_init = (void*(*)(void*, const char*, const char*)) dlsym(sdhnd, "serdisp_init");
@@ -230,6 +205,22 @@ int cDriverSerDisp::Init(void)
return -1;
}
+ fp_serdisp_getcolours = (int (*)(void*)) dlsym(sdhnd, "serdisp_getcolours");
+ if ( (errmsg = dlerror()) != NULL ) { // should not happen
+ syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n",
+ config->name.c_str(), "serdisp_getcolours", errmsg);
+ return -1;
+ }
+
+ // don't care if the following functions are not available
+ fp_serdisp_getdepth = (int (*)(void*)) dlsym(sdhnd, "serdisp_getdepth");
+
+ fp_SDGPI_search = (uint8_t (*)(void*, const char*)) dlsym(sdhnd, "SDGPI_search");
+ fp_SDGPI_isenabled = (int (*)(void*, uint8_t)) dlsym(sdhnd, "SDGPI_isenabled");
+ fp_SDGPI_enable = (int (*)(void*, uint8_t, int)) dlsym(sdhnd, "SDGPI_enable");
+ fp_SDEVLP_add_listener = (int (*)(void*, uint8_t, fp_eventlistener_t)) dlsym(sdhnd, "SDEVLP_add_listener");
+
+
// done loading all required symbols
// setting up the display
@@ -341,7 +332,8 @@ int cDriverSerDisp::Init(void)
fp_serdisp_feature(dd, FEATURE_REVERSE, config->invert);
} else {
/* standard options */
- fp_serdisp_setoption(dd, "ROTATE", config->upsideDown);
+ if (config->upsideDown)
+ fp_serdisp_setoption(dd, "ROTATE", config->upsideDown);
fp_serdisp_setoption(dd, "CONTRAST", config->contrast);
fp_serdisp_setoption(dd, "BACKLIGHT", config->backlight);
fp_serdisp_setoption(dd, "INVERT", config->invert);
@@ -433,6 +425,7 @@ int cDriverSerDisp::CheckSetup()
update = true;
}
+#if 0
/* driver dependend options */
if ( supports_options ) {
for (unsigned int i = 0; i < config->options.size(); i++) {
@@ -447,7 +440,7 @@ int cDriverSerDisp::CheckSetup()
}
}
}
-
+#endif
if (update)
return 1;
@@ -462,7 +455,7 @@ void cDriverSerDisp::Clear(void)
int x,y;
for (y = 0; y < fp_serdisp_getheight(dd); y++)
for (x = 0; x < fp_serdisp_getwidth(dd); x++)
- fp_serdisp_setpixcol(dd, x, y, bg_colour); /* >= 1.95: serdisp_setcolour(), < 1.95: serdisp_setpixel() */
+ fp_serdisp_setcolour(dd, x, y, bg_colour);
}
}
@@ -475,13 +468,50 @@ void cDriverSerDisp::Set8Pixels(int x, int y, unsigned char data) {
for (i = 0; i < 8; i++) {
pixel = data & (1 << i);
- if (pixel)
- fp_serdisp_setpixcol(dd, start + i, y, fg_colour); /* >= 1.95: serdisp_setcolour(), < 1.95: serdisp_setpixel() */
- else if (!pixel && bg_colour != -1) /* if bg_colour is set: use it if pixel is not set */
- fp_serdisp_setpixcol(dd, start + i, y, bg_colour); /* >= 1.95: serdisp_setcolour(), < 1.95: serdisp_setpixel() */
+ if (pixel) {
+ SetPixel(start + i, y, fg_colour);
+ } else if (!pixel && bg_colour != -1) { /* if bg_colour is set: use it if pixel is not set */
+ SetPixel(start + i, y, bg_colour);
+ }
}
}
+void cDriverSerDisp::SetPixel(int x, int y, uint32_t data)
+{
+ fp_serdisp_setcolour(dd, x, y, data);
+}
+
+#if 0
+// temporarily overwrite SetScreen() until problem with 'to Clear() or not to Clear()' is solved
+void cDriverSerDisp::SetScreen(const unsigned char * data, int wid, int hgt, int lineSize)
+{
+ int x, y;
+
+ if (wid > width)
+ wid = width;
+ if (hgt > height)
+ hgt = height;
+
+ //Clear();
+ if (data)
+ {
+ for (y = 0; y < hgt; y++)
+ {
+ for (x = 0; x < (wid / 8); x++)
+ {
+ Set8Pixels(x * 8, y, data[y * lineSize + x]);
+ }
+ if (width % 8)
+ {
+ Set8Pixels((wid / 8) * 8, y, data[y * lineSize + wid / 8] & bitmaskl[wid % 8 - 1]);
+ }
+ }
+ } else {
+ Clear();
+ }
+}
+#endif
+
void cDriverSerDisp::Refresh(bool refreshAll)
{
if (CheckSetup() == 1)
@@ -494,9 +524,93 @@ void cDriverSerDisp::Refresh(bool refreshAll)
}
void cDriverSerDisp::SetBrightness(unsigned int percent)
-{
+{
if ( supports_options && (fp_serdisp_isoption(dd, "BRIGHTNESS") == 1) ) /* if == 1: option is existing AND r/w */
- fp_serdisp_setoption(dd, "BRIGHTNESS", (long)percent);
+ fp_serdisp_setoption(dd, "BRIGHTNESS", (long)percent);
+}
+
+GLCD::cColor cDriverSerDisp::GetBackgroundColor(void) {
+ if ( supports_options && fp_serdisp_isoption(dd, "SELFEMITTING") && (fp_serdisp_getoption(dd, "SELFEMITTING", 0)) ) {
+ return GLCD::cColor::Black;
+ }
+ return GLCD::cColor::White;
+}
+
+
+bool cDriverSerDisp::SetFeature (const std::string & Feature, int value)
+{
+ if (strcasecmp(Feature.c_str(), "TOUCHSCREEN") == 0 || strcasecmp(Feature.c_str(), "TOUCH") == 0) {
+ if (fp_SDGPI_search && fp_SDGPI_isenabled && fp_SDGPI_enable) {
+ uint8_t gpid = fp_SDGPI_search(dd, Feature.c_str());
+ if (gpid == 0xFF)
+ return false;
+
+ int ena = fp_SDGPI_isenabled(dd, gpid);
+ bool enable = (value == 1) ? true : false;
+ if (ena == enable) { // already enabled or disabled
+ return true;
+ } else {
+ bool rc = (fp_SDGPI_enable(dd, gpid, ((enable) ? 1 : 0)) >= 0) ? true : false;
+
+ if (enable && rc && fp_SDEVLP_add_listener) {
+ fp_SDEVLP_add_listener(dd, gpid, wrapEventListener);
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool cDriverSerDisp::GetDriverFeature (const std::string & Feature, int & value) {
+ if (dd) {
+ if (strcasecmp(Feature.c_str(), "depth") == 0) {
+ value = fp_serdisp_getdepth(dd);
+ return true;
+ } else if (strcasecmp(Feature.c_str(), "ismonochrome") == 0) {
+ value = (fp_serdisp_getdepth(dd) == 1) ? 1 : 0;
+ return true;
+ } else if (strcasecmp(Feature.c_str(), "isgreyscale") == 0 || strcasecmp(Feature.c_str(), "isgrayscale") == 0) {
+ value = (fp_serdisp_getdepth(dd) > 1 && fp_serdisp_getdepth(dd) < 8) ? 1 : 0;
+ return true;
+ } else if (strcasecmp(Feature.c_str(), "iscolour") == 0 || strcasecmp(Feature.c_str(), "iscolor") == 0) {
+ value = (fp_serdisp_getdepth(dd) >= 8) ? 1 : 0;
+ return true;
+ } else if (strcasecmp(Feature.c_str(), "touch") == 0 || strcasecmp(Feature.c_str(), "touchscreen") == 0) {
+ if (fp_SDGPI_search && fp_SDGPI_isenabled) {
+ uint8_t gpid = fp_SDGPI_search(dd, Feature.c_str());
+ value = (gpid != 0xFF && fp_SDGPI_isenabled(dd, gpid)) ? 1 : 0;
+ }
+ return true;
+ }
+ }
+ value = 0;
+ return false;
+}
+
+cGLCDEvent * cDriverSerDisp::GetEvent(void) {
+ if (GLCD::simpleTouchChanged == false)
+ return NULL;
+
+ cSimpleTouchEvent * ev = new cSimpleTouchEvent();
+
+ ev->x = simpleTouchX;
+ ev->y = simpleTouchY;
+ ev->touch = simpleTouchT;
+ simpleTouchChanged = false;
+ return ev;
+}
+
+static void wrapEventListener(void* dd, SDGP_event_t* event) {
+ if (!event) return;
+ if (event->type == SDGPT_SIMPLETOUCH) {
+ SDGP_evpkt_simpletouch_t simpletouch;
+ memcpy(&simpletouch, &event->data, sizeof(SDGP_evpkt_simpletouch_t));
+ simpleTouchChanged = true;
+ simpleTouchX = simpletouch.norm_x;
+ simpleTouchY = simpletouch.norm_y;
+ simpleTouchT = simpletouch.norm_touch;
+ }
}
} // end of namespace