µGFX library fork

gdisp_lld_uGFXnet.c 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. /*
  2. * This file is subject to the terms of the GFX License. If a copy of
  3. * the license was not distributed with this file, you can obtain one at:
  4. *
  5. * http://ugfx.org/license.html
  6. */
  7. // We need to include stdio.h below. Turn off GFILE_NEED_STDIO just for this file to prevent conflicts
  8. #define GFILE_NEED_STDIO_MUST_BE_OFF
  9. #include "gfx.h"
  10. #if GFX_USE_GDISP
  11. #define GDISP_DRIVER_VMT GDISPVMT_uGFXnet
  12. #include "gdisp_lld_config.h"
  13. #include "../../../src/gdisp/gdisp_driver.h"
  14. #include "uGFXnetProtocol.h"
  15. #ifndef GDISP_SCREEN_WIDTH
  16. #define GDISP_SCREEN_WIDTH 640
  17. #endif
  18. #ifndef GDISP_SCREEN_HEIGHT
  19. #define GDISP_SCREEN_HEIGHT 480
  20. #endif
  21. #ifndef GDISP_GFXNET_PORT
  22. #define GDISP_GFXNET_PORT GNETCODE_DEFAULT_PORT
  23. #endif
  24. #ifndef GDISP_DONT_WAIT_FOR_NET_DISPLAY
  25. #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE
  26. #endif
  27. #ifndef GDISP_GFXNET_UNSAFE_SOCKETS
  28. #define GDISP_GFXNET_UNSAFE_SOCKETS FALSE
  29. #endif
  30. #ifndef GDISP_GFXNET_BROKEN_LWIP_ACCEPT
  31. #define GDISP_GFXNET_BROKEN_LWIP_ACCEPT FALSE
  32. #endif
  33. #if GINPUT_NEED_MOUSE
  34. // Include mouse support code
  35. #define GMOUSE_DRIVER_VMT GMOUSEVMT_uGFXnet
  36. #include "../../../src/ginput/ginput_driver_mouse.h"
  37. // Forward definitions
  38. static bool_t NMouseInit(GMouse *m, unsigned driverinstance);
  39. static bool_t NMouseRead(GMouse *m, GMouseReading *prd);
  40. const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
  41. {
  42. GDRIVER_TYPE_MOUSE,
  43. GMOUSE_VFLG_NOPOLL|GMOUSE_VFLG_DYNAMICONLY,
  44. // Extra flags for testing only
  45. //GMOUSE_VFLG_TOUCH|GMOUSE_VFLG_SELFROTATION|GMOUSE_VFLG_DEFAULTFINGER
  46. //GMOUSE_VFLG_CALIBRATE|GMOUSE_VFLG_CAL_EXTREMES|GMOUSE_VFLG_CAL_TEST|GMOUSE_VFLG_CAL_LOADFREE
  47. //GMOUSE_VFLG_ONLY_DOWN|GMOUSE_VFLG_POORUPDOWN
  48. sizeof(GMouse),
  49. _gmouseInitDriver, _gmousePostInitDriver, _gmouseDeInitDriver
  50. },
  51. 1, // z_max
  52. 0, // z_min
  53. 1, // z_touchon
  54. 0, // z_touchoff
  55. { // pen_jitter
  56. 0, // calibrate
  57. 0, // click
  58. 0 // move
  59. },
  60. { // finger_jitter
  61. 0, // calibrate
  62. 2, // click
  63. 2 // move
  64. },
  65. NMouseInit, // init
  66. 0, // deinit
  67. NMouseRead, // get
  68. 0, // calsave
  69. 0 // calload
  70. }};
  71. #endif
  72. #if GNETCODE_VERSION != GNETCODE_VERSION_1_0
  73. #error "GDISP: uGFXnet - This driver only support protocol V1.0"
  74. #endif
  75. #if GDISP_LLD_PIXELFORMAT != GNETCODE_PIXELFORMAT
  76. #error "GDISP: uGFXnet - The driver pixel format must match the protocol"
  77. #endif
  78. #include <stdio.h>
  79. #include <string.h>
  80. #include <stdlib.h>
  81. #if defined(WIN32) || GFX_USE_OS_WIN32
  82. #include <winsock.h>
  83. #define SOCKET_TYPE SOCKET
  84. #define socklen_t int
  85. static void StopSockets(void) {
  86. WSACleanup();
  87. }
  88. static void StartSockets(void) {
  89. WSADATA wsaData;
  90. if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
  91. gfxHalt("GDISP: uGFXnet - WSAStartup failed");
  92. atexit(StopSockets);
  93. }
  94. #elif GFX_USE_OS_LINUX || GFX_USE_OS_OSX
  95. #include <sys/types.h>
  96. #include <sys/socket.h>
  97. #include <netinet/in.h>
  98. #include <arpa/inet.h>
  99. #include <netdb.h>
  100. #define closesocket(fd) close(fd)
  101. #define ioctlsocket(fd,cmd,arg) ioctl(fd,cmd,arg)
  102. #define StartSockets()
  103. #define SOCKET_TYPE int
  104. #else
  105. #include <lwip/sockets.h>
  106. #if GDISP_GFXNET_CUSTOM_LWIP_STARTUP
  107. extern void Start_LWIP(void); // Where the application does the lwip stack setup
  108. #define StartSockets() Start_LWIP();
  109. #else
  110. #include "lwipthread.h"
  111. #define StartSockets() gfxThreadClose(gfxThreadCreate(wa_lwip_thread, LWIP_THREAD_STACK_SIZE, NORMAL_PRIORITY, lwip_thread, 0))
  112. #endif
  113. #if !LWIP_SOCKET
  114. #error "GDISP: uGFXnet - LWIP_SOCKETS must be defined in your lwipopts.h file"
  115. #endif
  116. #if !LWIP_COMPAT_SOCKETS
  117. #error "GDISP: uGFXnet - LWIP_COMPAT_SOCKETS must be defined in your lwipopts.h file"
  118. #endif
  119. #define SOCKET_TYPE int
  120. // Mutex protection is required for LWIP
  121. #if !GDISP_GFXNET_UNSAFE_SOCKETS
  122. #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT
  123. #warning "GDISP: uGFXnet - LWIP sockets are not thread-safe. GDISP_GFXNET_UNSAFE_SOCKETS has been turned on for you."
  124. #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO
  125. COMPILER_WARNING("GDISP: uGFXnet - LWIP sockets are not thread-safe. GDISP_GFXNET_UNSAFE_SOCKETS has been turned on for you.")
  126. #endif
  127. #undef GDISP_GFXNET_UNSAFE_SOCKETS
  128. #define GDISP_GFXNET_UNSAFE_SOCKETS TRUE
  129. #endif
  130. #endif
  131. #define GDISP_FLG_CONNECTED (GDISP_FLG_DRIVER<<0)
  132. #define GDISP_FLG_HAVEDATA (GDISP_FLG_DRIVER<<1)
  133. /*===========================================================================*/
  134. /* Driver local routines . */
  135. /*===========================================================================*/
  136. typedef struct netPriv {
  137. SOCKET_TYPE netfd; // The current socket
  138. unsigned databytes; // How many bytes have been read
  139. uint16_t data[2]; // Buffer for storing data read.
  140. #if GINPUT_NEED_MOUSE
  141. coord_t mousex, mousey;
  142. uint16_t mousebuttons;
  143. GMouse * mouse;
  144. #endif
  145. } netPriv;
  146. static gfxThreadHandle hThread;
  147. #if GDISP_GFXNET_UNSAFE_SOCKETS
  148. static gfxMutex uGFXnetMutex;
  149. #define MUTEX_INIT gfxMutexInit(&uGFXnetMutex)
  150. #define MUTEX_ENTER gfxMutexEnter(&uGFXnetMutex)
  151. #define MUTEX_EXIT gfxMutexExit(&uGFXnetMutex)
  152. #else
  153. #define MUTEX_INIT
  154. #define MUTEX_ENTER
  155. #define MUTEX_EXIT
  156. #endif
  157. /**
  158. * Send a whole packet of data.
  159. * Len is specified in the number of uint16_t's we want to send as our protocol only talks uint16_t's.
  160. * Note that contents of the packet are modified to ensure it will cross the wire in the correct format.
  161. * If the connection closes before we send all the data - the call returns FALSE.
  162. */
  163. static bool_t sendpkt(SOCKET_TYPE netfd, uint16_t *pkt, int len) {
  164. int i;
  165. // Convert each uint16_t to network order
  166. for(i = 0; i < len; i++)
  167. pkt[i] = htons(pkt[i]);
  168. // Send it
  169. len *= sizeof(uint16_t);
  170. return send(netfd, (const char *)pkt, len, 0) == len;
  171. }
  172. static bool_t newconnection(SOCKET_TYPE clientfd) {
  173. GDisplay * g;
  174. netPriv * priv;
  175. // Look for a display that isn't connected
  176. for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
  177. // Ignore displays for other controllers
  178. #ifdef GDISP_DRIVER_LIST
  179. if (gvmt(g) != &GDISPVMT_uGFXnet)
  180. continue;
  181. #endif
  182. if (!(g->flags & GDISP_FLG_CONNECTED))
  183. break;
  184. }
  185. // Was anything found?
  186. if (!g)
  187. return FALSE;
  188. // Reset the priv area
  189. priv = g->priv;
  190. priv->netfd = clientfd;
  191. priv->databytes = 0;
  192. priv->mousebuttons = 0;
  193. // Send the initialisation data (2 words at a time)
  194. priv->data[0] = GNETCODE_INIT;
  195. priv->data[1] = GNETCODE_VERSION;
  196. sendpkt(priv->netfd, priv->data, 2);
  197. priv->data[0] = GDISP_SCREEN_WIDTH;
  198. priv->data[1] = GDISP_SCREEN_HEIGHT;
  199. sendpkt(priv->netfd, priv->data, 2);
  200. priv->data[0] = GDISP_LLD_PIXELFORMAT;
  201. priv->data[1] = 1; // We have a mouse
  202. MUTEX_ENTER;
  203. sendpkt(priv->netfd, priv->data, 2);
  204. MUTEX_EXIT;
  205. // The display is now working
  206. g->flags |= GDISP_FLG_CONNECTED;
  207. // Send a redraw all
  208. #if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
  209. gdispGClear(g, gwinGetDefaultBgColor());
  210. gwinRedrawDisplay(g, FALSE);
  211. #endif
  212. return TRUE;
  213. }
  214. static bool_t rxdata(SOCKET_TYPE fd) {
  215. GDisplay * g;
  216. netPriv * priv;
  217. int len;
  218. // Look for a display that is connected and the socket descriptor matches
  219. for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
  220. // Ignore displays for other controllers
  221. #ifdef GDISP_DRIVER_LIST
  222. if (gvmt(g) != &GDISPVMT_uGFXnet)
  223. continue;
  224. #endif
  225. priv = g->priv;
  226. if ((g->flags & GDISP_FLG_CONNECTED) && priv->netfd == fd)
  227. break;
  228. }
  229. if (!g)
  230. gfxHalt("GDISP: uGFXnet - Got data from unrecognized connection");
  231. if ((g->flags & GDISP_FLG_HAVEDATA)) {
  232. // The higher level is still processing the previous data.
  233. // Give it a chance to run by coming back to this data.
  234. gfxSleepMilliseconds(1);
  235. return TRUE;
  236. }
  237. /* handle data from a client */
  238. MUTEX_ENTER;
  239. if ((len = recv(fd, ((char *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) {
  240. // Socket closed or in error state
  241. MUTEX_EXIT;
  242. g->flags &= ~GDISP_FLG_CONNECTED;
  243. return FALSE;
  244. }
  245. MUTEX_EXIT;
  246. // Do we have a full reply yet
  247. priv->databytes += len;
  248. if (priv->databytes < sizeof(priv->data))
  249. return TRUE;
  250. priv->databytes = 0;
  251. // Convert network byte or to host byte order
  252. priv->data[0] = ntohs(priv->data[0]);
  253. priv->data[1] = ntohs(priv->data[1]);
  254. // Process the data received
  255. switch(priv->data[0]) {
  256. #if GINPUT_NEED_MOUSE
  257. case GNETCODE_MOUSE_X: priv->mousex = priv->data[1]; break;
  258. case GNETCODE_MOUSE_Y: priv->mousey = priv->data[1]; break;
  259. case GNETCODE_MOUSE_B:
  260. priv->mousebuttons = priv->data[1];
  261. // Treat the button event as the sync signal
  262. _gmouseWakeup(priv->mouse);
  263. break;
  264. #endif
  265. case GNETCODE_CONTROL:
  266. case GNETCODE_READ:
  267. g->flags |= GDISP_FLG_HAVEDATA;
  268. break;
  269. case GNETCODE_KILL:
  270. gfxHalt("GDISP: uGFXnet - Display sent KILL command");
  271. break;
  272. default:
  273. // Just ignore unrecognised data
  274. break;
  275. }
  276. return TRUE;
  277. }
  278. static DECLARE_THREAD_STACK(waNetThread, 512);
  279. static DECLARE_THREAD_FUNCTION(NetThread, param) {
  280. SOCKET_TYPE listenfd, fdmax, i, clientfd;
  281. socklen_t len;
  282. fd_set master, read_fds;
  283. struct sockaddr_in addr;
  284. (void)param;
  285. // Start the sockets layer
  286. StartSockets();
  287. gfxSleepMilliseconds(100); // Make sure the thread has time to start.
  288. /* clear the master and temp sets */
  289. FD_ZERO(&master);
  290. FD_ZERO(&read_fds);
  291. if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == (SOCKET_TYPE)-1)
  292. gfxHalt("GDISP: uGFXnet - Socket failed");
  293. memset(&addr, 0, sizeof(addr));
  294. addr.sin_family = AF_INET;
  295. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  296. addr.sin_port = htons(GDISP_GFXNET_PORT);
  297. if (bind(listenfd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
  298. gfxHalt("GDISP: uGFXnet - Bind failed");
  299. if (listen(listenfd, 10) == -1)
  300. gfxHalt("GDISP: uGFXnet - Listen failed");
  301. /* add the listener to the master set */
  302. FD_SET(listenfd, &master);
  303. /* keep track of the biggest file descriptor */
  304. fdmax = listenfd; /* so far, it's this one*/
  305. #if GDISP_GFXNET_BROKEN_LWIP_ACCEPT
  306. #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT
  307. #warning "Using GDISP_GFXNET_BROKEN_LWIP_ACCEPT limits the number of displays and the use of GFXNET. Avoid if possible!"
  308. #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO
  309. COMPILER_WARNING("Using GDISP_GFXNET_BROKEN_LWIP_ACCEPT limits the number of displays and the use of GFXNET. Avoid if possible!")
  310. #endif
  311. len = sizeof(addr);
  312. if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
  313. gfxHalt("GDISP: uGFXnet - Accept failed");
  314. //printf("New connection from %s on socket %d\n", inet_ntoa(addr.sin_addr), clientfd);
  315. if (!newconnection(clientfd)) {
  316. // No Just close the connection
  317. closesocket(clientfd);
  318. gfxHalt("GDISP: uGFXnet - Can't find display for connection");
  319. return 0;
  320. }
  321. // Save the descriptor
  322. FD_SET(clientfd, &master);
  323. if (clientfd > fdmax) fdmax = clientfd;
  324. #endif
  325. /* loop */
  326. for(;;) {
  327. /* copy it */
  328. read_fds = master;
  329. if (select(fdmax+1, &read_fds, 0, 0, 0) == -1)
  330. gfxHalt("GDISP: uGFXnet - Select failed");
  331. // Run through the existing connections looking for data to be read
  332. for(i = 0; i <= fdmax; i++) {
  333. if(!FD_ISSET(i, &read_fds))
  334. continue;
  335. // Handle new connections
  336. if(i == listenfd) {
  337. // Accept the connection
  338. len = sizeof(addr);
  339. if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
  340. gfxHalt("GDISP: uGFXnet - Accept failed");
  341. //printf("New connection from %s on socket %d\n", inet_ntoa(addr.sin_addr), clientfd);
  342. // Can we handle it?
  343. if (!newconnection(clientfd)) {
  344. // No - Just close the connection
  345. closesocket(clientfd);
  346. //printf("Rejected connection as all displays are already connected\n");
  347. continue;
  348. }
  349. // Save the descriptor
  350. FD_SET(clientfd, &master);
  351. if (clientfd > fdmax) fdmax = clientfd;
  352. continue;
  353. }
  354. // Handle data from a client
  355. if (!rxdata(i)) {
  356. closesocket(i);
  357. FD_CLR(clientfd, &master);
  358. }
  359. }
  360. }
  361. return 0;
  362. }
  363. /*===========================================================================*/
  364. /* Driver exported functions. */
  365. /*===========================================================================*/
  366. LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
  367. netPriv * priv;
  368. // Initialise the receiver thread (if it hasn't been done already)
  369. if (!hThread) {
  370. MUTEX_INIT;
  371. hThread = gfxThreadCreate(waNetThread, sizeof(waNetThread), HIGH_PRIORITY, NetThread, 0);
  372. gfxThreadClose(hThread);
  373. }
  374. // Create a private area for this window
  375. if (!(priv = gfxAlloc(sizeof(netPriv))))
  376. gfxHalt("GDISP: uGFXnet - Memory allocation failed");
  377. memset(priv, 0, sizeof(netPriv));
  378. g->priv = priv;
  379. g->board = 0; // no board interface for this controller
  380. // Create the associated mouse
  381. #if GINPUT_NEED_MOUSE
  382. priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g);
  383. #endif
  384. // Initialise the GDISP structure
  385. g->g.Orientation = GDISP_ROTATE_0;
  386. g->g.Powermode = powerOn;
  387. g->g.Backlight = 100;
  388. g->g.Contrast = 50;
  389. g->g.Width = GDISP_SCREEN_WIDTH;
  390. g->g.Height = GDISP_SCREEN_HEIGHT;
  391. return TRUE;
  392. }
  393. #if GDISP_HARDWARE_FLUSH
  394. LLDSPEC void gdisp_lld_flush(GDisplay *g) {
  395. netPriv * priv;
  396. uint16_t buf[1];
  397. #if GDISP_DONT_WAIT_FOR_NET_DISPLAY
  398. if (!(g->flags & GDISP_FLG_CONNECTED))
  399. return;
  400. #else
  401. while(!(g->flags & GDISP_FLG_CONNECTED))
  402. gfxSleepMilliseconds(200);
  403. #endif
  404. priv = g->priv;
  405. buf[0] = GNETCODE_FLUSH;
  406. MUTEX_ENTER;
  407. sendpkt(priv->netfd, buf, 1);
  408. MUTEX_EXIT;
  409. }
  410. #endif
  411. #if GDISP_HARDWARE_DRAWPIXEL
  412. LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
  413. netPriv * priv;
  414. uint16_t buf[4];
  415. #if GDISP_DONT_WAIT_FOR_NET_DISPLAY
  416. if (!(g->flags & GDISP_FLG_CONNECTED))
  417. return;
  418. #else
  419. while(!(g->flags & GDISP_FLG_CONNECTED))
  420. gfxSleepMilliseconds(200);
  421. #endif
  422. priv = g->priv;
  423. buf[0] = GNETCODE_PIXEL;
  424. buf[1] = g->p.x;
  425. buf[2] = g->p.y;
  426. buf[3] = gdispColor2Native(g->p.color);
  427. MUTEX_ENTER;
  428. sendpkt(priv->netfd, buf, 4);
  429. MUTEX_EXIT;
  430. }
  431. #endif
  432. /* ---- Optional Routines ---- */
  433. #if GDISP_HARDWARE_FILLS
  434. LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
  435. netPriv * priv;
  436. uint16_t buf[6];
  437. #if GDISP_DONT_WAIT_FOR_NET_DISPLAY
  438. if (!(g->flags & GDISP_FLG_CONNECTED))
  439. return;
  440. #else
  441. while(!(g->flags & GDISP_FLG_CONNECTED))
  442. gfxSleepMilliseconds(200);
  443. #endif
  444. priv = g->priv;
  445. buf[0] = GNETCODE_FILL;
  446. buf[1] = g->p.x;
  447. buf[2] = g->p.y;
  448. buf[3] = g->p.cx;
  449. buf[4] = g->p.cy;
  450. buf[5] = gdispColor2Native(g->p.color);
  451. MUTEX_ENTER;
  452. sendpkt(priv->netfd, buf, 6);
  453. MUTEX_EXIT;
  454. }
  455. #endif
  456. #if GDISP_HARDWARE_BITFILLS
  457. LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
  458. netPriv * priv;
  459. pixel_t * buffer;
  460. uint16_t buf[5];
  461. coord_t x, y;
  462. #if GDISP_DONT_WAIT_FOR_NET_DISPLAY
  463. if (!(g->flags & GDISP_FLG_CONNECTED))
  464. return;
  465. #else
  466. while(!(g->flags & GDISP_FLG_CONNECTED))
  467. gfxSleepMilliseconds(200);
  468. #endif
  469. // Make everything relative to the start of the line
  470. buffer = g->p.ptr;
  471. buffer += g->p.x2*g->p.y1;
  472. priv = g->priv;
  473. buf[0] = GNETCODE_BLIT;
  474. buf[1] = g->p.x;
  475. buf[2] = g->p.y;
  476. buf[3] = g->p.cx;
  477. buf[4] = g->p.cy;
  478. MUTEX_ENTER;
  479. sendpkt(priv->netfd, buf, 5);
  480. for(y = 0; y < g->p.cy; y++, buffer += g->p.x2 - g->p.cx) {
  481. for(x = 0; x < g->p.cx; x++, buffer++) {
  482. buf[0] = gdispColor2Native(buffer[0]);
  483. sendpkt(priv->netfd, buf, 1);
  484. }
  485. }
  486. MUTEX_EXIT;
  487. }
  488. #endif
  489. #if GDISP_HARDWARE_PIXELREAD
  490. LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
  491. netPriv * priv;
  492. uint16_t buf[3];
  493. color_t data;
  494. #if GDISP_DONT_WAIT_FOR_NET_DISPLAY
  495. if (!(g->flags & GDISP_FLG_CONNECTED))
  496. return 0;
  497. #else
  498. while(!(g->flags & GDISP_FLG_CONNECTED))
  499. gfxSleepMilliseconds(200);
  500. #endif
  501. priv = g->priv;
  502. buf[0] = GNETCODE_READ;
  503. buf[1] = g->p.x;
  504. buf[2] = g->p.y;
  505. MUTEX_ENTER;
  506. sendpkt(priv->netfd, buf, 3);
  507. MUTEX_EXIT;
  508. // Now wait for a reply
  509. while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_READ)
  510. gfxSleepMilliseconds(1);
  511. data = gdispNative2Color(priv->data[1]);
  512. g->flags &= ~GDISP_FLG_HAVEDATA;
  513. return data;
  514. }
  515. #endif
  516. #if GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL
  517. LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) {
  518. netPriv * priv;
  519. uint16_t buf[6];
  520. #if GDISP_DONT_WAIT_FOR_NET_DISPLAY
  521. if (!(g->flags & GDISP_FLG_CONNECTED))
  522. return;
  523. #else
  524. while(!(g->flags & GDISP_FLG_CONNECTED))
  525. gfxSleepMilliseconds(200);
  526. #endif
  527. priv = g->priv;
  528. buf[0] = GNETCODE_SCROLL;
  529. buf[1] = g->p.x;
  530. buf[2] = g->p.y;
  531. buf[3] = g->p.cx;
  532. buf[4] = g->p.cy;
  533. buf[5] = g->p.y1;
  534. MUTEX_ENTER;
  535. sendpkt(priv->netfd, buf, 6);
  536. MUTEX_EXIT;
  537. }
  538. #endif
  539. #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
  540. LLDSPEC void gdisp_lld_control(GDisplay *g) {
  541. netPriv * priv;
  542. uint16_t buf[3];
  543. bool_t allgood;
  544. #if GDISP_DONT_WAIT_FOR_NET_DISPLAY
  545. if (!(g->flags & GDISP_FLG_CONNECTED))
  546. return;
  547. #else
  548. while(!(g->flags & GDISP_FLG_CONNECTED))
  549. gfxSleepMilliseconds(200);
  550. #endif
  551. // Check if we might support the code
  552. switch(g->p.x) {
  553. case GDISP_CONTROL_ORIENTATION:
  554. if (g->g.Orientation == (orientation_t)g->p.ptr)
  555. return;
  556. break;
  557. case GDISP_CONTROL_POWER:
  558. if (g->g.Powermode == (powermode_t)g->p.ptr)
  559. return;
  560. break;
  561. case GDISP_CONTROL_BACKLIGHT:
  562. if (g->g.Backlight == (uint16_t)(int)g->p.ptr)
  563. return;
  564. if ((uint16_t)(int)g->p.ptr > 100)
  565. g->p.ptr = (void *)100;
  566. break;
  567. default:
  568. return;
  569. }
  570. // Send the command
  571. priv = g->priv;
  572. buf[0] = GNETCODE_CONTROL;
  573. buf[1] = g->p.x;
  574. buf[2] = (uint16_t)(int)g->p.ptr;
  575. MUTEX_ENTER;
  576. sendpkt(priv->netfd, buf, 3);
  577. MUTEX_EXIT;
  578. // Now wait for a reply
  579. while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_CONTROL)
  580. gfxSleepMilliseconds(1);
  581. // Extract the return status
  582. allgood = priv->data[1] ? TRUE : FALSE;
  583. g->flags &= ~GDISP_FLG_HAVEDATA;
  584. // Do nothing more if the operation failed
  585. if (!allgood) return;
  586. // Update the local stuff
  587. switch(g->p.x) {
  588. case GDISP_CONTROL_ORIENTATION:
  589. switch((orientation_t)g->p.ptr) {
  590. case GDISP_ROTATE_0:
  591. case GDISP_ROTATE_180:
  592. g->g.Width = GDISP_SCREEN_WIDTH;
  593. g->g.Height = GDISP_SCREEN_HEIGHT;
  594. break;
  595. case GDISP_ROTATE_90:
  596. case GDISP_ROTATE_270:
  597. g->g.Height = GDISP_SCREEN_WIDTH;
  598. g->g.Width = GDISP_SCREEN_HEIGHT;
  599. break;
  600. default:
  601. return;
  602. }
  603. g->g.Orientation = (orientation_t)g->p.ptr;
  604. break;
  605. case GDISP_CONTROL_POWER:
  606. g->g.Powermode = (powermode_t)g->p.ptr;
  607. break;
  608. case GDISP_CONTROL_BACKLIGHT:
  609. g->g.Backlight = (uint16_t)(int)g->p.ptr;
  610. break;
  611. }
  612. }
  613. #endif
  614. #if GINPUT_NEED_MOUSE
  615. static bool_t NMouseInit(GMouse *m, unsigned driverinstance) {
  616. (void) m;
  617. (void) driverinstance;
  618. return TRUE;
  619. }
  620. static bool_t NMouseRead(GMouse *m, GMouseReading *pt) {
  621. GDisplay * g;
  622. netPriv * priv;
  623. g = m->display;
  624. priv = g->priv;
  625. pt->x = priv->mousex;
  626. pt->y = priv->mousey;
  627. pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0;
  628. pt->buttons = priv->mousebuttons;
  629. return TRUE;
  630. }
  631. #endif /* GINPUT_NEED_MOUSE */
  632. #endif /* GFX_USE_GDISP */