uGFXnet ported to newmouse driver (and tidied up)
This commit is contained in:
parent
d4a40cb507
commit
ac6e26f1a0
1 changed files with 193 additions and 178 deletions
|
@ -10,7 +10,7 @@
|
|||
#if GFX_USE_GDISP
|
||||
|
||||
#define GDISP_DRIVER_VMT GDISPVMT_uGFXnet
|
||||
#include "drivers/multiple/uGFXnet/gdisp_lld_config.h"
|
||||
#include "gdisp_lld_config.h"
|
||||
#include "src/gdisp/driver.h"
|
||||
#include "uGFXnetProtocol.h"
|
||||
|
||||
|
@ -33,6 +33,48 @@
|
|||
#define GDISP_GFXNET_BROKEN_LWIP_ACCEPT FALSE
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
// Include mouse support code
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_uGFXnet
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Forward definitions
|
||||
static bool_t NMouseInit(GMouse *m, unsigned driverinstance);
|
||||
static void 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: uGFXnet - This driver only support protocol V1.0"
|
||||
#endif
|
||||
|
@ -98,14 +140,8 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<0)
|
||||
#define GDISP_FLG_CONNECTED (GDISP_FLG_DRIVER<<1)
|
||||
#define GDISP_FLG_HAVEDATA (GDISP_FLG_DRIVER<<2)
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
/* Include mouse support code */
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
#endif
|
||||
#define GDISP_FLG_CONNECTED (GDISP_FLG_DRIVER<<0)
|
||||
#define GDISP_FLG_HAVEDATA (GDISP_FLG_DRIVER<<1)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local routines . */
|
||||
|
@ -118,15 +154,12 @@ typedef struct netPriv {
|
|||
#if GINPUT_NEED_MOUSE
|
||||
coord_t mousex, mousey;
|
||||
uint16_t mousebuttons;
|
||||
GMouse * mouse;
|
||||
#endif
|
||||
} netPriv;
|
||||
|
||||
static gfxThreadHandle hThread;
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
static GDisplay * mouseDisplay;
|
||||
#endif
|
||||
|
||||
#if GDISP_GFXNET_UNSAFE_SOCKETS
|
||||
static gfxMutex uGFXnetMutex;
|
||||
#define MUTEX_INIT gfxMutexInit(&uGFXnetMutex)
|
||||
|
@ -156,15 +189,134 @@ static bool_t sendpkt(SOCKET_TYPE netfd, uint16_t *pkt, int len) {
|
|||
return send(netfd, (const char *)pkt, len, 0) == len;
|
||||
}
|
||||
|
||||
static bool_t newconnection(SOCKET_TYPE clientfd) {
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
|
||||
// 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))
|
||||
break;
|
||||
}
|
||||
|
||||
// Was anything found?
|
||||
if (!g)
|
||||
return FALSE;
|
||||
|
||||
// Reset the priv area
|
||||
priv = g->priv;
|
||||
priv->netfd = clientfd;
|
||||
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
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t rxdata(SOCKET_TYPE fd) {
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
int len;
|
||||
|
||||
// Look for a display that is connected and the socket descriptor matches
|
||||
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
|
||||
priv = g->priv;
|
||||
if ((g->flags & GDISP_FLG_CONNECTED) && priv->netfd == fd)
|
||||
break;
|
||||
}
|
||||
if (!g)
|
||||
gfxHalt("GDISP: uGFXnet - Got data from unrecognized connection");
|
||||
|
||||
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.
|
||||
gfxSleepMilliseconds(1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* handle data from a client */
|
||||
MUTEX_ENTER;
|
||||
if ((len = recv(fd, ((char *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) {
|
||||
// Socket closed or in error state
|
||||
MUTEX_EXIT;
|
||||
g->flags &= ~GDISP_FLG_CONNECTED;
|
||||
return FALSE;
|
||||
}
|
||||
MUTEX_EXIT;
|
||||
|
||||
// Do we have a full reply yet
|
||||
priv->databytes += len;
|
||||
if (priv->databytes < sizeof(priv->data))
|
||||
return TRUE;
|
||||
priv->databytes = 0;
|
||||
|
||||
// Convert network byte or to host byte order
|
||||
priv->data[0] = ntohs(priv->data[0]);
|
||||
priv->data[1] = ntohs(priv->data[1]);
|
||||
|
||||
// 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;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static DECLARE_THREAD_STACK(waNetThread, 512);
|
||||
static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
||||
SOCKET_TYPE listenfd, fdmax, i, clientfd;
|
||||
socklen_t len;
|
||||
int leni;
|
||||
fd_set master, read_fds;
|
||||
struct sockaddr_in addr;
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
(void)param;
|
||||
|
||||
// Start the sockets layer
|
||||
|
@ -197,25 +349,13 @@ static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
|||
fdmax = listenfd; /* so far, it's this one*/
|
||||
|
||||
#if GDISP_GFXNET_BROKEN_LWIP_ACCEPT
|
||||
{
|
||||
#warning "Using GDISP_GFXNET_BROKEN_LWIP_ACCEPT limits the number of displays and the use of GFXNET. Avoid if possible!"
|
||||
len = sizeof(addr);
|
||||
if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
|
||||
gfxHalt("GDISP: uGFXnet - Accept failed");
|
||||
//printf("New connection from %s on socket %d\n", inet_ntoa(addr.sin_addr), clientfd);
|
||||
|
||||
// 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))
|
||||
break;
|
||||
}
|
||||
|
||||
// Was anything found?
|
||||
if (!g) {
|
||||
if (!newconnection(clientfd)) {
|
||||
// No Just close the connection
|
||||
closesocket(clientfd);
|
||||
gfxHalt("GDISP: uGFXnet - Can't find display for connection");
|
||||
|
@ -225,33 +365,6 @@ static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
|||
// Save the descriptor
|
||||
FD_SET(clientfd, &master);
|
||||
if (clientfd > fdmax) fdmax = clientfd;
|
||||
priv = g->priv;
|
||||
memset(priv, 0, sizeof(netPriv));
|
||||
priv->netfd = clientfd;
|
||||
//printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1);
|
||||
|
||||
// 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] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0;
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
/* loop */
|
||||
|
@ -268,132 +381,33 @@ static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
|||
|
||||
// Handle new connections
|
||||
if(i == listenfd) {
|
||||
|
||||
// Accept the connection
|
||||
len = sizeof(addr);
|
||||
if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
|
||||
gfxHalt("GDISP: uGFXnet - Accept failed");
|
||||
//printf("New connection from %s on socket %d\n", inet_ntoa(addr.sin_addr), clientfd);
|
||||
|
||||
// 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))
|
||||
break;
|
||||
}
|
||||
// Can we handle it?
|
||||
if (!newconnection(clientfd)) {
|
||||
|
||||
// Was anything found?
|
||||
if (!g) {
|
||||
// No Just close the connection
|
||||
// No - Just close the connection
|
||||
closesocket(clientfd);
|
||||
//printf(New connection from %s on socket %d rejected as all displays are already connected\n", inet_ntoa(addr.sin_addr), clientfd);
|
||||
|
||||
//printf("Rejected connection as all displays are already connected\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Save the descriptor
|
||||
FD_SET(clientfd, &master);
|
||||
if (clientfd > fdmax) fdmax = clientfd;
|
||||
priv = g->priv;
|
||||
memset(priv, 0, sizeof(netPriv));
|
||||
priv->netfd = clientfd;
|
||||
//printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1);
|
||||
|
||||
// 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] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0;
|
||||
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
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle data from a client
|
||||
|
||||
// Look for a display that is connected and the socket descriptor matches
|
||||
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
|
||||
priv = g->priv;
|
||||
if ((g->flags & GDISP_FLG_CONNECTED) && priv->netfd == i)
|
||||
break;
|
||||
}
|
||||
if (!g)
|
||||
gfxHalt("GDISP: uGFXnet - Got data from unrecognized connection");
|
||||
|
||||
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.
|
||||
gfxSleepMilliseconds(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* handle data from a client */
|
||||
MUTEX_ENTER;
|
||||
if ((leni = recv(i, ((char *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) {
|
||||
// Socket closed or in error state
|
||||
MUTEX_EXIT;
|
||||
g->flags &= ~GDISP_FLG_CONNECTED;
|
||||
memset(priv, 0, sizeof(netPriv));
|
||||
if (!rxdata(i)) {
|
||||
closesocket(i);
|
||||
FD_CLR(i, &master);
|
||||
continue;
|
||||
}
|
||||
MUTEX_EXIT;
|
||||
|
||||
// Do we have a full reply yet
|
||||
priv->databytes += leni;
|
||||
if (priv->databytes < sizeof(priv->data))
|
||||
continue;
|
||||
priv->databytes = 0;
|
||||
|
||||
// Convert network byte or to host byte order
|
||||
priv->data[0] = ntohs(priv->data[0]);
|
||||
priv->data[1] = ntohs(priv->data[1]);
|
||||
|
||||
// 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
|
||||
#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
|
||||
ginputMouseWakeup();
|
||||
#endif
|
||||
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;
|
||||
FD_CLR(clientfd, &master);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,14 +428,6 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
|||
gfxThreadClose(hThread);
|
||||
}
|
||||
|
||||
// Only turn on mouse on the first window for now
|
||||
#if GINPUT_NEED_MOUSE
|
||||
if (!g->controllerdisplay) {
|
||||
mouseDisplay = g;
|
||||
g->flags |= GDISP_FLG_HASMOUSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create a private area for this window
|
||||
if (!(priv = gfxAlloc(sizeof(netPriv))))
|
||||
gfxHalt("GDISP: uGFXnet - Memory allocation failed");
|
||||
|
@ -429,6 +435,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
|||
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;
|
||||
|
@ -694,17 +705,21 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
|||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
void ginput_lld_mouse_init(void) {}
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
static bool_t NMouseInit(GMouse *m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
(void) driverinstance;
|
||||
return TRUE;
|
||||
}
|
||||
static void NMouseRead(GMouse *m, GMouseReading *pt) {
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
|
||||
g = mouseDisplay;
|
||||
g = m->display;
|
||||
priv = g->priv;
|
||||
|
||||
pt->x = priv->mousex;
|
||||
pt->y = priv->mousey;
|
||||
pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
|
||||
pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0;
|
||||
pt->buttons = priv->mousebuttons;
|
||||
}
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
|
Loading…
Add table
Reference in a new issue