From 81505c8be20b89cd545dfc2fe6d3ed0c86524e89 Mon Sep 17 00:00:00 2001 From: inmarket Date: Tue, 30 Aug 2016 19:12:46 +1000 Subject: [PATCH] New uGFXnetESP8266 driver. A gdisp driver for the ESP8266. Not tested yet. --- drivers/multiple/uGFXnet/readme.txt | 2 +- drivers/multiple/uGFXnetESP8266/driver.mk | 2 + .../uGFXnetESP8266/gdisp_lld_config.h | 32 + .../gdisp_lld_uGFXnetESP8266.cpp | 622 ++++++++++++++++++ .../uGFXnetESP8266/ginput_lld_mouse_config.h | 41 ++ drivers/multiple/uGFXnetESP8266/readme.txt | 30 + .../multiple/uGFXnetESP8266/uGFXnetProtocol.h | 34 + 7 files changed, 762 insertions(+), 1 deletion(-) create mode 100644 drivers/multiple/uGFXnetESP8266/driver.mk create mode 100644 drivers/multiple/uGFXnetESP8266/gdisp_lld_config.h create mode 100644 drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp create mode 100644 drivers/multiple/uGFXnetESP8266/ginput_lld_mouse_config.h create mode 100644 drivers/multiple/uGFXnetESP8266/readme.txt create mode 100644 drivers/multiple/uGFXnetESP8266/uGFXnetProtocol.h diff --git a/drivers/multiple/uGFXnet/readme.txt b/drivers/multiple/uGFXnet/readme.txt index 67b37c12..0cb3ee07 100644 --- a/drivers/multiple/uGFXnet/readme.txt +++ b/drivers/multiple/uGFXnet/readme.txt @@ -19,7 +19,7 @@ and a touchscreen driver. 2. To your makefile add the following lines: include $(GFXLIB)/gfx.mk - include $(GFXLIB)/drivers/multiple/uGFXnet/gdisp_lld.mk + include $(GFXLIB)/drivers/multiple/uGFXnet/driver.mk 3. Make sure you have networking libraries included in your Makefile. diff --git a/drivers/multiple/uGFXnetESP8266/driver.mk b/drivers/multiple/uGFXnetESP8266/driver.mk new file mode 100644 index 00000000..ed322f52 --- /dev/null +++ b/drivers/multiple/uGFXnetESP8266/driver.mk @@ -0,0 +1,2 @@ +GFXINC += $(GFXLIB)/drivers/multiple/uGFXnetESP8266 +GFXSRC += $(GFXLIB)/drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp diff --git a/drivers/multiple/uGFXnetESP8266/gdisp_lld_config.h b/drivers/multiple/uGFXnetESP8266/gdisp_lld_config.h new file mode 100644 index 00000000..e181d91e --- /dev/null +++ b/drivers/multiple/uGFXnetESP8266/gdisp_lld_config.h @@ -0,0 +1,32 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +// Calling gdispGFlush() is optional for this driver but can be used by the +// application to force a display update. eg after streaming. + +#define GDISP_HARDWARE_FLUSH TRUE +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_FILLS TRUE +#define GDISP_HARDWARE_BITFILLS TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_SCROLL TRUE +#define GDISP_HARDWARE_CONTROL TRUE + +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp b/drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp new file mode 100644 index 00000000..7963acab --- /dev/null +++ b/drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp @@ -0,0 +1,622 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +// We need to include stdio.h below. Turn off GFILE_NEED_STDIO just for this file to prevent conflicts +#define GFILE_NEED_STDIO_MUST_BE_OFF + +#include "gfx.h" + +#if GFX_USE_GDISP + +#include + +#define GDISP_DRIVER_VMT GDISPVMT_uGFXnetESP8266 +#include "gdisp_lld_config.h" +#include "../../../src/gdisp/gdisp_driver.h" +#include "uGFXnetProtocol.h" + +#ifndef GDISP_SCREEN_WIDTH + #define GDISP_SCREEN_WIDTH 640 +#endif +#ifndef GDISP_SCREEN_HEIGHT + #define GDISP_SCREEN_HEIGHT 480 +#endif +#ifndef GDISP_GFXNET_PORT + #define GDISP_GFXNET_PORT GNETCODE_DEFAULT_PORT +#endif +#ifndef GDISP_DONT_WAIT_FOR_NET_DISPLAY + #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE +#endif + +static WiFiServer server(GDISP_GFXNET_PORT); +static GTimer poller; +static bool_t uGFXInitDone; + +#ifndef GDISP_GFXNET_WIFI_INIT_FUNCTION + #define GDISP_GFXNET_WIFI_INIT_FUNCTION uGFXnetArduinoWifiInit + #ifndef GDISP_GFXNET_WIFI_SSID + #error "uGFXnetArduino: GDISP_GFXNET_WIFI_SSID is not set. You must define the Wifi SSID" + #endif + #ifndef GDISP_GFXNET_WIFI_PASSWORD + #error "uGFXnetArduino: GDISP_GFXNET_WIFI_PASSWORD is not set. You must define the Wifi password" + #endif + + static void uGFXnetArduinoWifiInit(WifiServer *ws) { + WiFi.begin(GDISP_GFXNET_WIFI_SSID, GDISP_GFXNET_WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + gfxYield(); + + ws->begin(); + } +#else + extern "C" void GDISP_GFXNET_WIFI_INIT_FUNCTION(WifiServer *ws); +#endif + +#if GINPUT_NEED_MOUSE + // Include mouse support code + #define GMOUSE_DRIVER_VMT GMOUSEVMT_uGFXnet + #include "../../../src/ginput/ginput_driver_mouse.h" + + // Forward definitions + static bool_t NMouseInit(GMouse *m, unsigned driverinstance); + static bool_t NMouseRead(GMouse *m, GMouseReading *prd); + + const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{ + { + GDRIVER_TYPE_MOUSE, + GMOUSE_VFLG_NOPOLL|GMOUSE_VFLG_DYNAMICONLY, + // Extra flags for testing only + //GMOUSE_VFLG_TOUCH|GMOUSE_VFLG_SELFROTATION|GMOUSE_VFLG_DEFAULTFINGER + //GMOUSE_VFLG_CALIBRATE|GMOUSE_VFLG_CAL_EXTREMES|GMOUSE_VFLG_CAL_TEST|GMOUSE_VFLG_CAL_LOADFREE + //GMOUSE_VFLG_ONLY_DOWN|GMOUSE_VFLG_POORUPDOWN + sizeof(GMouse), + _gmouseInitDriver, _gmousePostInitDriver, _gmouseDeInitDriver + }, + 1, // z_max + 0, // z_min + 1, // z_touchon + 0, // z_touchoff + { // pen_jitter + 0, // calibrate + 0, // click + 0 // move + }, + { // finger_jitter + 0, // calibrate + 2, // click + 2 // move + }, + NMouseInit, // init + 0, // deinit + NMouseRead, // get + 0, // calsave + 0 // calload + }}; +#endif + +#if GNETCODE_VERSION != GNETCODE_VERSION_1_0 + #error "GDISP: uGFXnetESP8266 - This driver only support protocol V1.0" +#endif +#if GDISP_LLD_PIXELFORMAT != GNETCODE_PIXELFORMAT + #error "GDISP: uGFXnetESP8266 - The driver pixel format must match the protocol" +#endif + +#define GDISP_FLG_CONNECTED (GDISP_FLG_DRIVER<<0) +#define GDISP_FLG_HAVEDATA (GDISP_FLG_DRIVER<<1) + +#define CLIENTFD WifiClient * + +/*===========================================================================*/ +/* Driver local routines . */ +/*===========================================================================*/ + +typedef struct netPriv { + CLIENTFD netfd; // The current client + unsigned databytes; // How many bytes have been read + uint16_t data[2]; // Buffer for storing data read. + #if GINPUT_NEED_MOUSE + coord_t mousex, mousey; + uint16_t mousebuttons; + GMouse * mouse; + #endif +} netPriv; + +#if GDISP_GFXNET_UNSAFE_SOCKETS + static gfxMutex uGFXnetMutex; + #define MUTEX_INIT gfxMutexInit(&uGFXnetMutex) + #define MUTEX_ENTER gfxMutexEnter(&uGFXnetMutex) + #define MUTEX_EXIT gfxMutexExit(&uGFXnetMutex) +#else + #define MUTEX_INIT + #define MUTEX_ENTER + #define MUTEX_EXIT +#endif + +static void endcon(GDisplay *g) { + netPriv * priv; + + g->flags &= ~GDISP_FLG_CONNECTED; + priv = g->priv; + priv->netfd->stop(); + delete priv->netfd; + priv->netfd = 0; +} + +/** + * Send a whole packet of data. + * Len is specified in the number of uint16_t's we want to send as our protocol only talks uint16_t's. + * Note that contents of the packet are modified to ensure it will cross the wire in the correct format. + * If the connection closes before we send all the data - the call returns FALSE. + */ +static bool_t sendpkt(CLIENTFD fd, uint16_t *pkt, int len) { + // Convert each uint16_t to network order + #if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE + { + int i; + + for(i = 0; i < len; i++) + pkt[i] = ((pkt[i]>>8)|(pkt[i]<<8)); + } + #endif + + // Send it + len *= sizeof(uint16_t); + return fd->write((uint8_t *)pkt, len) == len; +} + +static void rxdata(GDisplay *g) { + netPriv * priv; + CLIENTFD fd; + int len; + + if ((g->flags & GDISP_FLG_HAVEDATA)) { + // The higher level is still processing the previous data. + // Give it a chance to run by coming back to this data. + return; + } + + priv = g->priv; + fd = priv->netfd; + + MUTEX_ENTER; + // Are we still connected? + if (!fd->connected()) { + MUTEX_EXIT; + endcon(g); + return; + } + + // Is there data available + if (!fd->available()) { + MUTEX_EXIT; + return; + } + + // Get the data + if ((len = fd->read(((uint8_t *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) { + // Socket closed or in error state + MUTEX_EXIT; + endcon(g); + return; + } + MUTEX_EXIT; + + // Do we have a full reply yet + priv->databytes += len; + if (priv->databytes < sizeof(priv->data)) + return; + priv->databytes = 0; + + // Convert network byte or to host byte order + #if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE + priv->data[0] = ((priv->data[0]>>8)|(priv->data[0]<<8)) + priv->data[1] = ((priv->data[1]>>8)|(priv->data[1]<<8)) + #endif + + // Process the data received + switch(priv->data[0]) { + #if GINPUT_NEED_MOUSE + case GNETCODE_MOUSE_X: priv->mousex = priv->data[1]; break; + case GNETCODE_MOUSE_Y: priv->mousey = priv->data[1]; break; + case GNETCODE_MOUSE_B: + priv->mousebuttons = priv->data[1]; + // Treat the button event as the sync signal + _gmouseWakeup(priv->mouse); + break; + #endif + case GNETCODE_CONTROL: + case GNETCODE_READ: + g->flags |= GDISP_FLG_HAVEDATA; + break; + case GNETCODE_KILL: + gfxHalt("GDISP: uGFXnet - Display sent KILL command"); + break; + + default: + // Just ignore unrecognised data + break; + } +} + +void uGFXnetClientPoller(void *param) { + GDisplay *g; + (void) param; + + // Is there a new server connection? + if (server.hasClient()) { + + // Look for a display that isn't connected + for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) { + // Ignore displays for other controllers + #ifdef GDISP_DRIVER_LIST + if (gvmt(g) != &GDISPVMT_uGFXnet) + continue; + #endif + if (!(g->flags & GDISP_FLG_CONNECTED)) { + netPriv * priv; + + // Reset the priv area + priv = g->priv; + priv->netfd = new WifiClient(server.available()); + priv->databytes = 0; + priv->mousebuttons = 0; + + // Send the initialisation data (2 words at a time) + priv->data[0] = GNETCODE_INIT; + priv->data[1] = GNETCODE_VERSION; + sendpkt(priv->netfd, priv->data, 2); + priv->data[0] = GDISP_SCREEN_WIDTH; + priv->data[1] = GDISP_SCREEN_HEIGHT; + sendpkt(priv->netfd, priv->data, 2); + priv->data[0] = GDISP_LLD_PIXELFORMAT; + priv->data[1] = 1; // We have a mouse + MUTEX_ENTER; + sendpkt(priv->netfd, priv->data, 2); + MUTEX_EXIT; + + // The display is now working + g->flags |= GDISP_FLG_CONNECTED; + + // Send a redraw all + #if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER + gdispGClear(g, gwinGetDefaultBgColor()); + gwinRedrawDisplay(g, FALSE); + #endif + break; + } + } + } + + // Look for a display that is connected so we can check if it has data + for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) { + // Ignore displays for other controllers + #ifdef GDISP_DRIVER_LIST + if (gvmt(g) != &GDISPVMT_uGFXnet) + continue; + #endif + if ((g->flags & GDISP_FLG_CONNECTED)) + rxdata(g); + } +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + netPriv * priv; + + // Initialise the receiver thread (if it hasn't been done already) + if (!uGFXInitDone) { + MUTEX_INIT; + // Init and Start the poller + GDISP_GFXNET_WIFI_INIT_FUNCTION(&server); + + // Initialise the poller + gtimerInit(&poller); + gtimerStart(&poller, uGFXnetClientPoller, 0, TRUE, 50); + uGFXInitDone = TRUE; + } + + // Create a private area for this window + if (!(priv = gfxAlloc(sizeof(netPriv)))) + gfxHalt("GDISP: uGFXnetESP8266 - Memory allocation failed"); + memset(priv, 0, sizeof(netPriv)); + g->priv = priv; + g->board = 0; // no board interface for this controller + + // Create the associated mouse + #if GINPUT_NEED_MOUSE + priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g); + #endif + + // Initialise the GDISP structure + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = 100; + g->g.Contrast = 50; + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + + return TRUE; +} + +#if GDISP_HARDWARE_FLUSH + LLDSPEC void gdisp_lld_flush(GDisplay *g) { + netPriv * priv; + uint16_t buf[1]; + + #if GDISP_DONT_WAIT_FOR_NET_DISPLAY + if (!(g->flags & GDISP_FLG_CONNECTED)) + return; + #else + while(!(g->flags & GDISP_FLG_CONNECTED)) + gfxSleepMilliseconds(200); + #endif + + priv = g->priv; + buf[0] = GNETCODE_FLUSH; + MUTEX_ENTER; + sendpkt(priv->netfd, buf, 1); + MUTEX_EXIT; + } +#endif + +#if GDISP_HARDWARE_DRAWPIXEL + LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + netPriv * priv; + uint16_t buf[4]; + + #if GDISP_DONT_WAIT_FOR_NET_DISPLAY + if (!(g->flags & GDISP_FLG_CONNECTED)) + return; + #else + while(!(g->flags & GDISP_FLG_CONNECTED)) + gfxSleepMilliseconds(200); + #endif + + priv = g->priv; + buf[0] = GNETCODE_PIXEL; + buf[1] = g->p.x; + buf[2] = g->p.y; + buf[3] = gdispColor2Native(g->p.color); + MUTEX_ENTER; + sendpkt(priv->netfd, buf, 4); + MUTEX_EXIT; + } +#endif + +/* ---- Optional Routines ---- */ + +#if GDISP_HARDWARE_FILLS + LLDSPEC void gdisp_lld_fill_area(GDisplay *g) { + netPriv * priv; + uint16_t buf[6]; + + #if GDISP_DONT_WAIT_FOR_NET_DISPLAY + if (!(g->flags & GDISP_FLG_CONNECTED)) + return; + #else + while(!(g->flags & GDISP_FLG_CONNECTED)) + gfxSleepMilliseconds(200); + #endif + + priv = g->priv; + buf[0] = GNETCODE_FILL; + buf[1] = g->p.x; + buf[2] = g->p.y; + buf[3] = g->p.cx; + buf[4] = g->p.cy; + buf[5] = gdispColor2Native(g->p.color); + MUTEX_ENTER; + sendpkt(priv->netfd, buf, 6); + MUTEX_EXIT; + } +#endif + +#if GDISP_HARDWARE_BITFILLS + LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { + netPriv * priv; + pixel_t * buffer; + uint16_t buf[5]; + coord_t x, y; + + #if GDISP_DONT_WAIT_FOR_NET_DISPLAY + if (!(g->flags & GDISP_FLG_CONNECTED)) + return; + #else + while(!(g->flags & GDISP_FLG_CONNECTED)) + gfxSleepMilliseconds(200); + #endif + + // Make everything relative to the start of the line + buffer = g->p.ptr; + buffer += g->p.x2*g->p.y1; + + priv = g->priv; + buf[0] = GNETCODE_BLIT; + buf[1] = g->p.x; + buf[2] = g->p.y; + buf[3] = g->p.cx; + buf[4] = g->p.cy; + MUTEX_ENTER; + sendpkt(priv->netfd, buf, 5); + + for(y = 0; y < g->p.cy; y++, buffer += g->p.x2 - g->p.cx) { + for(x = 0; x < g->p.cx; x++, buffer++) { + buf[0] = gdispColor2Native(buffer[0]); + sendpkt(priv->netfd, buf, 1); + } + } + MUTEX_EXIT; + } +#endif + +#if GDISP_HARDWARE_PIXELREAD + LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { + netPriv * priv; + uint16_t buf[3]; + color_t data; + + #if GDISP_DONT_WAIT_FOR_NET_DISPLAY + if (!(g->flags & GDISP_FLG_CONNECTED)) + return 0; + #else + while(!(g->flags & GDISP_FLG_CONNECTED)) + gfxSleepMilliseconds(200); + #endif + + priv = g->priv; + buf[0] = GNETCODE_READ; + buf[1] = g->p.x; + buf[2] = g->p.y; + MUTEX_ENTER; + sendpkt(priv->netfd, buf, 3); + MUTEX_EXIT; + + // Now wait for a reply + while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_READ) + gfxSleepMilliseconds(1); + + data = gdispNative2Color(priv->data[1]); + g->flags &= ~GDISP_FLG_HAVEDATA; + + return data; + } +#endif + +#if GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL + LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) { + netPriv * priv; + uint16_t buf[6]; + + #if GDISP_DONT_WAIT_FOR_NET_DISPLAY + if (!(g->flags & GDISP_FLG_CONNECTED)) + return; + #else + while(!(g->flags & GDISP_FLG_CONNECTED)) + gfxSleepMilliseconds(200); + #endif + + priv = g->priv; + buf[0] = GNETCODE_SCROLL; + buf[1] = g->p.x; + buf[2] = g->p.y; + buf[3] = g->p.cx; + buf[4] = g->p.cy; + buf[5] = g->p.y1; + MUTEX_ENTER; + sendpkt(priv->netfd, buf, 6); + MUTEX_EXIT; + } +#endif + +#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL + LLDSPEC void gdisp_lld_control(GDisplay *g) { + netPriv * priv; + uint16_t buf[3]; + bool_t allgood; + + #if GDISP_DONT_WAIT_FOR_NET_DISPLAY + if (!(g->flags & GDISP_FLG_CONNECTED)) + return; + #else + while(!(g->flags & GDISP_FLG_CONNECTED)) + gfxSleepMilliseconds(200); + #endif + + // Check if we might support the code + switch(g->p.x) { + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + break; + case GDISP_CONTROL_POWER: + if (g->g.Powermode == (powermode_t)g->p.ptr) + return; + break; + case GDISP_CONTROL_BACKLIGHT: + if (g->g.Backlight == (uint16_t)(int)g->p.ptr) + return; + if ((uint16_t)(int)g->p.ptr > 100) + g->p.ptr = (void *)100; + break; + default: + return; + } + + // Send the command + priv = g->priv; + buf[0] = GNETCODE_CONTROL; + buf[1] = g->p.x; + buf[2] = (uint16_t)(int)g->p.ptr; + MUTEX_ENTER; + sendpkt(priv->netfd, buf, 3); + MUTEX_EXIT; + + // Now wait for a reply + while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_CONTROL) + gfxSleepMilliseconds(1); + + // Extract the return status + allgood = priv->data[1] ? TRUE : FALSE; + g->flags &= ~GDISP_FLG_HAVEDATA; + + // Do nothing more if the operation failed + if (!allgood) return; + + // Update the local stuff + switch(g->p.x) { + case GDISP_CONTROL_ORIENTATION: + switch((orientation_t)g->p.ptr) { + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + break; + case GDISP_CONTROL_POWER: + g->g.Powermode = (powermode_t)g->p.ptr; + break; + case GDISP_CONTROL_BACKLIGHT: + g->g.Backlight = (uint16_t)(int)g->p.ptr; + break; + } + } +#endif + +#if GINPUT_NEED_MOUSE + static bool_t NMouseInit(GMouse *m, unsigned driverinstance) { + (void) m; + (void) driverinstance; + return TRUE; + } + static bool_t NMouseRead(GMouse *m, GMouseReading *pt) { + GDisplay * g; + netPriv * priv; + + g = m->display; + priv = g->priv; + + pt->x = priv->mousex; + pt->y = priv->mousey; + pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0; + pt->buttons = priv->mousebuttons; + return TRUE; + } +#endif /* GINPUT_NEED_MOUSE */ + +#endif /* GFX_USE_GDISP */ diff --git a/drivers/multiple/uGFXnetESP8266/ginput_lld_mouse_config.h b/drivers/multiple/uGFXnetESP8266/ginput_lld_mouse_config.h new file mode 100644 index 00000000..576df7ee --- /dev/null +++ b/drivers/multiple/uGFXnetESP8266/ginput_lld_mouse_config.h @@ -0,0 +1,41 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _LLD_GINPUT_MOUSE_CONFIG_H +#define _LLD_GINPUT_MOUSE_CONFIG_H + +// This driver supports being both a mouse or a touch device (we don't actually know which it really is) +// When operating in mouse mode a long left button click does not generate a context click. +// When operating in touch mode we allow sloppier clicks etc +#if 1 + #define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE + #define GINPUT_MOUSE_CLICK_TIME TIME_INFINITE // Long click != Context Click + #define GINPUT_MOUSE_NEED_CALIBRATION FALSE + #define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE + #define GINPUT_MOUSE_READ_CYCLES 1 + #define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1 + #define GINPUT_MOUSE_MAX_CLICK_JITTER 0 + #define GINPUT_MOUSE_MAX_MOVE_JITTER 0 +#else + #define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH + #define GINPUT_MOUSE_CLICK_TIME 700 // Long click = Context Click + #define GINPUT_MOUSE_NEED_CALIBRATION FALSE // Can be set to TRUE just for testing + #define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE + #define GINPUT_MOUSE_READ_CYCLES 1 + #define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 2 + #define GINPUT_MOUSE_MAX_CLICK_JITTER 2 + #define GINPUT_MOUSE_MAX_MOVE_JITTER 2 +#endif + +// This driver supports both an "interrupt" mode, and a polled mode +#define GINPUT_MOUSE_POLL_PERIOD TIME_INFINITE // Interrupt driven by the Window thread +//#define GINPUT_MOUSE_POLL_PERIOD 25 // Poll driven + +// This driver does not require rotation of co-ordinates for orientations other than 0. +#define GINPUT_MOUSE_NO_ROTATION TRUE + +#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */ diff --git a/drivers/multiple/uGFXnetESP8266/readme.txt b/drivers/multiple/uGFXnetESP8266/readme.txt new file mode 100644 index 00000000..d7ce2178 --- /dev/null +++ b/drivers/multiple/uGFXnetESP8266/readme.txt @@ -0,0 +1,30 @@ +To use this driver: + +This driver is special in that it implements both the gdisp low level driver +and a touchscreen driver. + +1. Add in your gfxconf.h: + a) #define GFX_USE_GDISP TRUE + b) Optionally #define GFX_USE_GINPUT TRUE + #define GINPUT_USE_MOUSE TRUE + c) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD + d) Optionally the following (with appropriate values): + #define GDISP_SCREEN_WIDTH 640 // Virtual display width + #define GDISP_SCREEN_HEIGHT 480 // Virtual display height + #define GDISP_GFXNET_WIFI_INIT_FUNCTION MyWifiStart // Optionally specify if you want to + // use your own wifi startup routine. + // Prototype... + // extern "C" void MyWifiStart(WifiServer *ws); + #define GDISP_GFXNET_WIFI_SSID "ssid" // Your wifi SSID. + // Not required if GDISP_GFXNET_WIFI_INIT_FUNCTION + // is specified. + #define GDISP_GFXNET_WIFI_PASSWORD "password" // Your wifi password. + // Not required if GDISP_GFXNET_WIFI_INIT_FUNCTION + // is specified. + #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE // Don't halt waiting for the first connection + $define GDISP_GFXNET_PORT 13001 // The TCP port the display sits on + + +2. To your makefile (or Library) add the following lines: + include $(GFXLIB)/gfx.mk + include $(GFXLIB)/drivers/multiple/uGFXnetESP8266/driver.mk diff --git a/drivers/multiple/uGFXnetESP8266/uGFXnetProtocol.h b/drivers/multiple/uGFXnetESP8266/uGFXnetProtocol.h new file mode 100644 index 00000000..521cca0f --- /dev/null +++ b/drivers/multiple/uGFXnetESP8266/uGFXnetProtocol.h @@ -0,0 +1,34 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#define GNETCODE_VERSION GNETCODE_VERSION_1_0 // The current protocol version + +// The list of possible protocol version numbers +#define GNETCODE_VERSION_1_0 0x0100 // V1.0 + +// The required pixel format +#define GNETCODE_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 + +// The default TCP/IP port +#define GNETCODE_DEFAULT_PORT 13001 + +/** + * All commands are sent in 16 bit blocks (2 bytes) in network order (BigEndian) + * Across all uGFXnet protocol versions, the stream will always start with GNETCODE_INIT (0xFFFF) and then the version number. + */ +#define GNETCODE_INIT 0xFFFF // Followed by version,width,height,pixelformat,hasmouse +#define GNETCODE_FLUSH 0x0000 // No following data +#define GNETCODE_PIXEL 0x0001 // Followed by x,y,color +#define GNETCODE_FILL 0x0002 // Followed by x,y,cx,cy,color +#define GNETCODE_BLIT 0x0003 // Followed by x,y,cx,cy,bits +#define GNETCODE_READ 0x0004 // Followed by x,y - Response is GNETCODE_READ,color +#define GNETCODE_SCROLL 0x0005 // Followed by x,y,cx,cy,lines +#define GNETCODE_CONTROL 0x0006 // Followed by what,data - Response is GNETCODE_CONTROL,0x0000 (fail) or GNETCODE_CONTROL,0x0001 (success) +#define GNETCODE_MOUSE_X 0x0007 // This is only ever received - never sent. Response is GNETCODE_MOUSE_X,x +#define GNETCODE_MOUSE_Y 0x0008 // This is only ever received - never sent. Response is GNETCODE_MOUSE_Y,y +#define GNETCODE_MOUSE_B 0x0009 // This is only ever received - never sent. Response is GNETCODE_MOUSE_B,buttons. This is also the sync signal for mouse updates. +#define GNETCODE_KILL 0xFFFE // This is only ever received - never sent. Response is GNETCODE_KILL,retcode