u8g.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. // Module for U8glib
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "lmem.h"
  5. #include "u8g.h"
  6. #include "u8g_glue.h"
  7. #include "u8g_config.h"
  8. // helper function: retrieve and check userdata argument
  9. static lu8g_userdata_t *get_lud( lua_State *L )
  10. {
  11. lu8g_userdata_t *lud = (lu8g_userdata_t *)luaL_checkudata(L, 1, "u8g.display");
  12. luaL_argcheck(L, lud, 1, "u8g.display expected");
  13. return lud;
  14. }
  15. // helper function: retrieve given number of integer arguments
  16. static void lu8g_get_int_args( lua_State *L, uint8_t stack, uint8_t num, u8g_uint_t *args)
  17. {
  18. while (num-- > 0)
  19. {
  20. *args++ = luaL_checkinteger( L, stack++ );
  21. }
  22. }
  23. // Lua: u8g.begin( self )
  24. static int lu8g_begin( lua_State *L )
  25. {
  26. lu8g_userdata_t *lud;
  27. if ((lud = get_lud( L )) == NULL)
  28. return 0;
  29. u8g_Begin( LU8G );
  30. return 0;
  31. }
  32. // Lua: u8g.setFont( self, font )
  33. static int lu8g_setFont( lua_State *L )
  34. {
  35. lu8g_userdata_t *lud;
  36. if ((lud = get_lud( L )) == NULL)
  37. return 0;
  38. u8g_fntpgm_uint8_t *font = (u8g_fntpgm_uint8_t *)lua_touserdata( L, 2 );
  39. if (font != NULL)
  40. u8g_SetFont( LU8G, font );
  41. else
  42. luaL_argerror(L, 2, "font data expected");
  43. return 0;
  44. }
  45. // Lua: u8g.setFontRefHeightAll( self )
  46. static int lu8g_setFontRefHeightAll( lua_State *L )
  47. {
  48. lu8g_userdata_t *lud;
  49. if ((lud = get_lud( L )) == NULL)
  50. return 0;
  51. u8g_SetFontRefHeightAll( LU8G );
  52. return 0;
  53. }
  54. // Lua: u8g.setFontRefHeightExtendedText( self )
  55. static int lu8g_setFontRefHeightExtendedText( lua_State *L )
  56. {
  57. lu8g_userdata_t *lud;
  58. if ((lud = get_lud( L )) == NULL)
  59. return 0;
  60. u8g_SetFontRefHeightExtendedText( LU8G );
  61. return 0;
  62. }
  63. // Lua: u8g.setFontRefHeightText( self )
  64. static int lu8g_setFontRefHeightText( lua_State *L )
  65. {
  66. lu8g_userdata_t *lud;
  67. if ((lud = get_lud( L )) == NULL)
  68. return 0;
  69. u8g_SetFontRefHeightText( LU8G );
  70. return 0;
  71. }
  72. // Lua: u8g.setDefaultBackgroundColor( self )
  73. static int lu8g_setDefaultBackgroundColor( lua_State *L )
  74. {
  75. lu8g_userdata_t *lud;
  76. if ((lud = get_lud( L )) == NULL)
  77. return 0;
  78. u8g_SetDefaultBackgroundColor( LU8G );
  79. return 0;
  80. }
  81. // Lua: u8g.setDefaultForegroundColor( self )
  82. static int lu8g_setDefaultForegroundColor( lua_State *L )
  83. {
  84. lu8g_userdata_t *lud;
  85. if ((lud = get_lud( L )) == NULL)
  86. return 0;
  87. u8g_SetDefaultForegroundColor( LU8G );
  88. return 0;
  89. }
  90. // Lua: u8g.setFontPosBaseline( self )
  91. static int lu8g_setFontPosBaseline( lua_State *L )
  92. {
  93. lu8g_userdata_t *lud;
  94. if ((lud = get_lud( L )) == NULL)
  95. return 0;
  96. u8g_SetFontPosBaseline( LU8G );
  97. return 0;
  98. }
  99. // Lua: u8g.setFontPosBottom( self )
  100. static int lu8g_setFontPosBottom( lua_State *L )
  101. {
  102. lu8g_userdata_t *lud;
  103. if ((lud = get_lud( L )) == NULL)
  104. return 0;
  105. u8g_SetFontPosBottom( LU8G );
  106. return 0;
  107. }
  108. // Lua: u8g.setFontPosCenter( self )
  109. static int lu8g_setFontPosCenter( lua_State *L )
  110. {
  111. lu8g_userdata_t *lud;
  112. if ((lud = get_lud( L )) == NULL)
  113. return 0;
  114. u8g_SetFontPosCenter( LU8G );
  115. return 0;
  116. }
  117. // Lua: u8g.setFontPosTop( self )
  118. static int lu8g_setFontPosTop( lua_State *L )
  119. {
  120. lu8g_userdata_t *lud;
  121. if ((lud = get_lud( L )) == NULL)
  122. return 0;
  123. u8g_SetFontPosTop( LU8G );
  124. return 0;
  125. }
  126. // Lua: int = u8g.getFontAscent( self )
  127. static int lu8g_getFontAscent( lua_State *L )
  128. {
  129. lu8g_userdata_t *lud;
  130. if ((lud = get_lud( L )) == NULL)
  131. return 0;
  132. lua_pushinteger( L, u8g_GetFontAscent( LU8G ) );
  133. return 1;
  134. }
  135. // Lua: int = u8g.getFontDescent( self )
  136. static int lu8g_getFontDescent( lua_State *L )
  137. {
  138. lu8g_userdata_t *lud;
  139. if ((lud = get_lud( L )) == NULL)
  140. return 0;
  141. lua_pushinteger( L, u8g_GetFontDescent( LU8G ) );
  142. return 1;
  143. }
  144. // Lua: int = u8g.getFontLineSpacing( self )
  145. static int lu8g_getFontLineSpacing( lua_State *L )
  146. {
  147. lu8g_userdata_t *lud;
  148. if ((lud = get_lud( L )) == NULL)
  149. return 0;
  150. lua_pushinteger( L, u8g_GetFontLineSpacing( LU8G ) );
  151. return 1;
  152. }
  153. // Lua: int = u8g.getMode( self )
  154. static int lu8g_getMode( lua_State *L )
  155. {
  156. lu8g_userdata_t *lud;
  157. if ((lud = get_lud( L )) == NULL)
  158. return 0;
  159. lua_pushinteger( L, u8g_GetMode( LU8G ) );
  160. return 1;
  161. }
  162. // Lua: u8g.setContrast( self, constrast )
  163. static int lu8g_setContrast( lua_State *L )
  164. {
  165. lu8g_userdata_t *lud;
  166. if ((lud = get_lud( L )) == NULL)
  167. return 0;
  168. u8g_SetContrast( LU8G, luaL_checkinteger( L, 2 ) );
  169. return 0;
  170. }
  171. // Lua: u8g.setColorIndex( self, color )
  172. static int lu8g_setColorIndex( lua_State *L )
  173. {
  174. lu8g_userdata_t *lud;
  175. if ((lud = get_lud( L )) == NULL)
  176. return 0;
  177. u8g_SetColorIndex( LU8G, luaL_checkinteger( L, 2 ) );
  178. return 0;
  179. }
  180. // Lua: int = u8g.getColorIndex( self )
  181. static int lu8g_getColorIndex( lua_State *L )
  182. {
  183. lu8g_userdata_t *lud;
  184. if ((lud = get_lud( L )) == NULL)
  185. return 0;
  186. lua_pushinteger( L, u8g_GetColorIndex( LU8G ) );
  187. return 1;
  188. }
  189. static int lu8g_generic_drawStr( lua_State *L, uint8_t rot )
  190. {
  191. lu8g_userdata_t *lud;
  192. if ((lud = get_lud( L )) == NULL)
  193. return 0;
  194. u8g_uint_t args[2];
  195. lu8g_get_int_args( L, 2, 2, args );
  196. const char *s = luaL_checkstring( L, (1+2) + 1 );
  197. if (s == NULL)
  198. return 0;
  199. switch (rot)
  200. {
  201. case 1:
  202. lua_pushinteger( L, u8g_DrawStr90( LU8G, args[0], args[1], s ) );
  203. break;
  204. case 2:
  205. lua_pushinteger( L, u8g_DrawStr180( LU8G, args[0], args[1], s ) );
  206. break;
  207. case 3:
  208. lua_pushinteger( L, u8g_DrawStr270( LU8G, args[0], args[1], s ) );
  209. break;
  210. default:
  211. lua_pushinteger( L, u8g_DrawStr( LU8G, args[0], args[1], s ) );
  212. break;
  213. }
  214. return 1;
  215. }
  216. // Lua: pix_len = u8g.drawStr( self, x, y, string )
  217. static int lu8g_drawStr( lua_State *L )
  218. {
  219. return lu8g_generic_drawStr( L, 0 );
  220. }
  221. // Lua: pix_len = u8g.drawStr90( self, x, y, string )
  222. static int lu8g_drawStr90( lua_State *L )
  223. {
  224. return lu8g_generic_drawStr( L, 1 );
  225. }
  226. // Lua: pix_len = u8g.drawStr180( self, x, y, string )
  227. static int lu8g_drawStr180( lua_State *L )
  228. {
  229. return lu8g_generic_drawStr( L, 2 );
  230. }
  231. // Lua: pix_len = u8g.drawStr270( self, x, y, string )
  232. static int lu8g_drawStr270( lua_State *L )
  233. {
  234. return lu8g_generic_drawStr( L, 3 );
  235. }
  236. // Lua: u8g.drawLine( self, x1, y1, x2, y2 )
  237. static int lu8g_drawLine( lua_State *L )
  238. {
  239. lu8g_userdata_t *lud;
  240. if ((lud = get_lud( L )) == NULL)
  241. return 0;
  242. u8g_uint_t args[4];
  243. lu8g_get_int_args( L, 2, 4, args );
  244. u8g_DrawLine( LU8G, args[0], args[1], args[2], args[3] );
  245. return 0;
  246. }
  247. // Lua: u8g.drawTriangle( self, x0, y0, x1, y1, x2, y2 )
  248. static int lu8g_drawTriangle( lua_State *L )
  249. {
  250. lu8g_userdata_t *lud;
  251. if ((lud = get_lud( L )) == NULL)
  252. return 0;
  253. u8g_uint_t args[6];
  254. lu8g_get_int_args( L, 2, 6, args );
  255. u8g_DrawTriangle( LU8G, args[0], args[1], args[2], args[3], args[4], args[5] );
  256. return 0;
  257. }
  258. // Lua: u8g.drawBox( self, x, y, width, height )
  259. static int lu8g_drawBox( lua_State *L )
  260. {
  261. lu8g_userdata_t *lud;
  262. if ((lud = get_lud( L )) == NULL)
  263. return 0;
  264. u8g_uint_t args[4];
  265. lu8g_get_int_args( L, 2, 4, args );
  266. u8g_DrawBox( LU8G, args[0], args[1], args[2], args[3] );
  267. return 0;
  268. }
  269. // Lua: u8g.drawRBox( self, x, y, width, height, radius )
  270. static int lu8g_drawRBox( lua_State *L )
  271. {
  272. lu8g_userdata_t *lud;
  273. if ((lud = get_lud( L )) == NULL)
  274. return 0;
  275. u8g_uint_t args[5];
  276. lu8g_get_int_args( L, 2, 5, args );
  277. u8g_DrawRBox( LU8G, args[0], args[1], args[2], args[3], args[4] );
  278. return 0;
  279. }
  280. // Lua: u8g.drawFrame( self, x, y, width, height )
  281. static int lu8g_drawFrame( lua_State *L )
  282. {
  283. lu8g_userdata_t *lud;
  284. if ((lud = get_lud( L )) == NULL)
  285. return 0;
  286. u8g_uint_t args[4];
  287. lu8g_get_int_args( L, 2, 4, args );
  288. u8g_DrawFrame( LU8G, args[0], args[1], args[2], args[3] );
  289. return 0;
  290. }
  291. // Lua: u8g.drawRFrame( self, x, y, width, height, radius )
  292. static int lu8g_drawRFrame( lua_State *L )
  293. {
  294. lu8g_userdata_t *lud;
  295. if ((lud = get_lud( L )) == NULL)
  296. return 0;
  297. u8g_uint_t args[5];
  298. lu8g_get_int_args( L, 2, 5, args );
  299. u8g_DrawRFrame( LU8G, args[0], args[1], args[2], args[3], args[4] );
  300. return 0;
  301. }
  302. // Lua: u8g.drawDisc( self, x0, y0, rad, opt = U8G_DRAW_ALL )
  303. static int lu8g_drawDisc( lua_State *L )
  304. {
  305. lu8g_userdata_t *lud;
  306. if ((lud = get_lud( L )) == NULL)
  307. return 0;
  308. u8g_uint_t args[3];
  309. lu8g_get_int_args( L, 2, 3, args );
  310. u8g_uint_t opt = luaL_optinteger( L, (1+3) + 1, U8G_DRAW_ALL );
  311. u8g_DrawDisc( LU8G, args[0], args[1], args[2], opt );
  312. return 0;
  313. }
  314. // Lua: u8g.drawCircle( self, x0, y0, rad, opt = U8G_DRAW_ALL )
  315. static int lu8g_drawCircle( lua_State *L )
  316. {
  317. lu8g_userdata_t *lud;
  318. if ((lud = get_lud( L )) == NULL)
  319. return 0;
  320. u8g_uint_t args[3];
  321. lu8g_get_int_args( L, 2, 3, args );
  322. u8g_uint_t opt = luaL_optinteger( L, (1+3) + 1, U8G_DRAW_ALL );
  323. u8g_DrawCircle( LU8G, args[0], args[1], args[2], opt );
  324. return 0;
  325. }
  326. // Lua: u8g.drawEllipse( self, x0, y0, rx, ry, opt = U8G_DRAW_ALL )
  327. static int lu8g_drawEllipse( lua_State *L )
  328. {
  329. lu8g_userdata_t *lud;
  330. if ((lud = get_lud( L )) == NULL)
  331. return 0;
  332. u8g_uint_t args[4];
  333. lu8g_get_int_args( L, 2, 4, args );
  334. u8g_uint_t opt = luaL_optinteger( L, (1+4) + 1, U8G_DRAW_ALL );
  335. u8g_DrawEllipse( LU8G, args[0], args[1], args[2], args[3], opt );
  336. return 0;
  337. }
  338. // Lua: u8g.drawFilledEllipse( self, x0, y0, rx, ry, opt = U8G_DRAW_ALL )
  339. static int lu8g_drawFilledEllipse( lua_State *L )
  340. {
  341. lu8g_userdata_t *lud;
  342. if ((lud = get_lud( L )) == NULL)
  343. return 0;
  344. u8g_uint_t args[4];
  345. lu8g_get_int_args( L, 2, 4, args );
  346. u8g_uint_t opt = luaL_optinteger( L, (1+4) + 1, U8G_DRAW_ALL );
  347. u8g_DrawFilledEllipse( LU8G, args[0], args[1], args[2], args[3], opt );
  348. return 0;
  349. }
  350. // Lua: u8g.drawPixel( self, x, y )
  351. static int lu8g_drawPixel( lua_State *L )
  352. {
  353. lu8g_userdata_t *lud;
  354. if ((lud = get_lud( L )) == NULL)
  355. return 0;
  356. u8g_uint_t args[2];
  357. lu8g_get_int_args( L, 2, 2, args );
  358. u8g_DrawPixel( LU8G, args[0], args[1] );
  359. return 0;
  360. }
  361. // Lua: u8g.drawHLine( self, x, y, width )
  362. static int lu8g_drawHLine( lua_State *L )
  363. {
  364. lu8g_userdata_t *lud;
  365. if ((lud = get_lud( L )) == NULL)
  366. return 0;
  367. u8g_uint_t args[3];
  368. lu8g_get_int_args( L, 2, 3, args );
  369. u8g_DrawHLine( LU8G, args[0], args[1], args[2] );
  370. return 0;
  371. }
  372. // Lua: u8g.drawVLine( self, x, y, width )
  373. static int lu8g_drawVLine( lua_State *L )
  374. {
  375. lu8g_userdata_t *lud;
  376. if ((lud = get_lud( L )) == NULL)
  377. return 0;
  378. u8g_uint_t args[3];
  379. lu8g_get_int_args( L, 2, 3, args );
  380. u8g_DrawVLine( LU8G, args[0], args[1], args[2] );
  381. return 0;
  382. }
  383. // Lua: u8g.drawXBM( self, x, y, width, height, data )
  384. static int lu8g_drawXBM( lua_State *L )
  385. {
  386. lu8g_userdata_t *lud;
  387. if ((lud = get_lud( L )) == NULL)
  388. return 0;
  389. u8g_uint_t args[4];
  390. lu8g_get_int_args( L, 2, 4, args );
  391. const char *xbm_data = luaL_checkstring( L, (1+4) + 1 );
  392. if (xbm_data == NULL)
  393. return 0;
  394. u8g_DrawXBM( LU8G, args[0], args[1], args[2], args[3], (const uint8_t *)xbm_data );
  395. return 0;
  396. }
  397. // Lua: u8g.drawBitmap( self, x, y, count, height, data )
  398. static int lu8g_drawBitmap( lua_State *L )
  399. {
  400. lu8g_userdata_t *lud;
  401. if ((lud = get_lud( L )) == NULL)
  402. return 0;
  403. u8g_uint_t args[4];
  404. lu8g_get_int_args( L, 2, 4, args );
  405. const char *bm_data = luaL_checkstring( L, (1+4) + 1 );
  406. if (bm_data == NULL)
  407. return 0;
  408. u8g_DrawBitmap( LU8G, args[0], args[1], args[2], args[3], (const uint8_t *)bm_data );
  409. return 0;
  410. }
  411. // Lua: u8g.setScale2x2( self )
  412. static int lu8g_setScale2x2( lua_State *L )
  413. {
  414. lu8g_userdata_t *lud;
  415. if ((lud = get_lud( L )) == NULL)
  416. return 0;
  417. u8g_SetScale2x2( LU8G );
  418. return 0;
  419. }
  420. // Lua: u8g.undoScale( self )
  421. static int lu8g_undoScale( lua_State *L )
  422. {
  423. lu8g_userdata_t *lud;
  424. if ((lud = get_lud( L )) == NULL)
  425. return 0;
  426. u8g_UndoScale( LU8G );
  427. return 0;
  428. }
  429. // Lua: u8g.firstPage( self )
  430. static int lu8g_firstPage( lua_State *L )
  431. {
  432. lu8g_userdata_t *lud;
  433. if ((lud = get_lud( L )) == NULL)
  434. return 0;
  435. u8g_FirstPage( LU8G );
  436. return 0;
  437. }
  438. // Lua: bool = u8g.nextPage( self )
  439. static int lu8g_nextPage( lua_State *L )
  440. {
  441. lu8g_userdata_t *lud;
  442. if ((lud = get_lud( L )) == NULL)
  443. return 0;
  444. lua_pushboolean( L, u8g_NextPage( LU8G ) );
  445. return 1;
  446. }
  447. // Lua: u8g.sleepOn( self )
  448. static int lu8g_sleepOn( lua_State *L )
  449. {
  450. lu8g_userdata_t *lud;
  451. if ((lud = get_lud( L )) == NULL)
  452. return 0;
  453. u8g_SleepOn( LU8G );
  454. return 0;
  455. }
  456. // Lua: u8g.sleepOff( self )
  457. static int lu8g_sleepOff( lua_State *L )
  458. {
  459. lu8g_userdata_t *lud;
  460. if ((lud = get_lud( L )) == NULL)
  461. return 0;
  462. u8g_SleepOff( LU8G );
  463. return 0;
  464. }
  465. // Lua: u8g.setRot90( self )
  466. static int lu8g_setRot90( lua_State *L )
  467. {
  468. lu8g_userdata_t *lud;
  469. if ((lud = get_lud( L )) == NULL)
  470. return 0;
  471. u8g_SetRot90( LU8G );
  472. return 0;
  473. }
  474. // Lua: u8g.setRot180( self )
  475. static int lu8g_setRot180( lua_State *L )
  476. {
  477. lu8g_userdata_t *lud;
  478. if ((lud = get_lud( L )) == NULL)
  479. return 0;
  480. u8g_SetRot180( LU8G );
  481. return 0;
  482. }
  483. // Lua: u8g.setRot270( self )
  484. static int lu8g_setRot270( lua_State *L )
  485. {
  486. lu8g_userdata_t *lud;
  487. if ((lud = get_lud( L )) == NULL)
  488. return 0;
  489. u8g_SetRot270( LU8G );
  490. return 0;
  491. }
  492. // Lua: u8g.undoRotation( self )
  493. static int lu8g_undoRotation( lua_State *L )
  494. {
  495. lu8g_userdata_t *lud;
  496. if ((lud = get_lud( L )) == NULL)
  497. return 0;
  498. u8g_UndoRotation( LU8G );
  499. return 0;
  500. }
  501. // Lua: width = u8g.getWidth( self )
  502. static int lu8g_getWidth( lua_State *L )
  503. {
  504. lu8g_userdata_t *lud;
  505. if ((lud = get_lud( L )) == NULL)
  506. return 0;
  507. lua_pushinteger( L, u8g_GetWidth( LU8G ) );
  508. return 1;
  509. }
  510. // Lua: height = u8g.getHeight( self )
  511. static int lu8g_getHeight( lua_State *L )
  512. {
  513. lu8g_userdata_t *lud;
  514. if ((lud = get_lud( L )) == NULL)
  515. return 0;
  516. lua_pushinteger( L, u8g_GetHeight( LU8G ) );
  517. return 1;
  518. }
  519. // Lua: width = u8g.getStrWidth( self, string )
  520. static int lu8g_getStrWidth( lua_State *L )
  521. {
  522. lu8g_userdata_t *lud;
  523. if ((lud = get_lud( L )) == NULL)
  524. return 0;
  525. const char *s = luaL_checkstring( L, 2 );
  526. if (s == NULL)
  527. return 0;
  528. lua_pushinteger( L, u8g_GetStrWidth( LU8G, s ) );
  529. return 1;
  530. }
  531. // Lua: u8g.setFontLineSpacingFactor( self, factor )
  532. static int lu8g_setFontLineSpacingFactor( lua_State *L )
  533. {
  534. lu8g_userdata_t *lud;
  535. if ((lud = get_lud( L )) == NULL)
  536. return 0;
  537. u8g_uint_t factor = luaL_checkinteger( L, 2 );
  538. u8g_SetFontLineSpacingFactor( LU8G, factor );
  539. return 0;
  540. }
  541. // device destructor
  542. static int lu8g_close_display( lua_State *L )
  543. {
  544. lu8g_userdata_t *lud;
  545. if ((lud = get_lud( L )) == NULL)
  546. return 0;
  547. if (lud->cb_ref != LUA_NOREF) {
  548. // this is the fb_rle device
  549. u8g_dev_t *fb_dev = LU8G->dev;
  550. u8g_pb_t *fb_dev_pb = (u8g_pb_t *)(fb_dev->dev_mem);
  551. uint8_t *fb_dev_buf = fb_dev_pb->buf;
  552. luaM_free( L, fb_dev_buf );
  553. luaM_free( L, fb_dev_pb );
  554. luaM_free( L, fb_dev );
  555. luaL_unref( L, lud->cb_ref, LUA_REGISTRYINDEX );
  556. }
  557. return 0;
  558. }
  559. // ***************************************************************************
  560. // Device constructors
  561. //
  562. //
  563. // I2C based devices will use this function template to implement the Lua binding.
  564. #undef U8G_DISPLAY_TABLE_ENTRY
  565. #define U8G_DISPLAY_TABLE_ENTRY(device) \
  566. static int lu8g_ ## device( lua_State *L ) \
  567. { \
  568. unsigned addr = luaL_checkinteger( L, 1 ); \
  569. unsigned del = luaL_optinteger( L, 2, 0 ); \
  570. \
  571. if (addr == 0) \
  572. return luaL_error( L, "i2c address required" ); \
  573. \
  574. lu8g_userdata_t *lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) ); \
  575. lud->cb_ref = LUA_NOREF; \
  576. \
  577. lud->i2c_addr = (uint8_t)addr; \
  578. lud->use_delay = del > 0 ? 1 : 0; \
  579. \
  580. u8g_InitI2C( LU8G, &u8g_dev_ ## device, U8G_I2C_OPT_NONE); \
  581. \
  582. /* set its metatable */ \
  583. luaL_getmetatable(L, "u8g.display"); \
  584. lua_setmetatable(L, -2); \
  585. \
  586. return 1; \
  587. }
  588. //
  589. // Unroll the display table and insert binding functions for I2C based displays.
  590. U8G_DISPLAY_TABLE_I2C
  591. //
  592. //
  593. //
  594. // SPI based devices will use this function template to implement the Lua binding.
  595. #undef U8G_DISPLAY_TABLE_ENTRY
  596. #define U8G_DISPLAY_TABLE_ENTRY(device) \
  597. static int lu8g_ ## device( lua_State *L ) \
  598. { \
  599. unsigned cs = luaL_checkinteger( L, 1 ); \
  600. if (cs == 0) \
  601. return luaL_error( L, "CS pin required" ); \
  602. unsigned dc = luaL_checkinteger( L, 2 ); \
  603. if (dc == 0) \
  604. return luaL_error( L, "D/C pin required" ); \
  605. unsigned res = luaL_optinteger( L, 3, U8G_PIN_NONE ); \
  606. unsigned del = luaL_optinteger( L, 4, 0 ); \
  607. \
  608. lu8g_userdata_t *lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) ); \
  609. lud->cb_ref = LUA_NOREF; \
  610. \
  611. lud->use_delay = del > 0 ? 1 : 0; \
  612. \
  613. u8g_InitHWSPI( LU8G, &u8g_dev_ ## device, cs, dc, res ); \
  614. \
  615. /* set its metatable */ \
  616. luaL_getmetatable(L, "u8g.display"); \
  617. lua_setmetatable(L, -2); \
  618. \
  619. return 1; \
  620. }
  621. //
  622. // Unroll the display table and insert binding functions for SPI based displays.
  623. U8G_DISPLAY_TABLE_SPI
  624. //
  625. //
  626. //
  627. // This display forwards the framebuffer contents as run-length encoded chunks to a Lua callback
  628. static int lu8g_fb_rle( lua_State *L ) {
  629. lu8g_userdata_t *lud;
  630. if ((lua_type( L, 1 ) != LUA_TFUNCTION) &&
  631. (lua_type( L, 1 ) != LUA_TLIGHTFUNCTION)) {
  632. luaL_typerror( L, 1, "function" );
  633. }
  634. int width = luaL_checkint( L, 2 );
  635. int height = luaL_checkint( L, 3 );
  636. luaL_argcheck( L, (width > 0) && (width < 256) && ((width % 8) == 0), 2, "invalid width" );
  637. luaL_argcheck( L, (height > 0) && (height < 256) && ((height % 8) == 0), 3, "invalid height" );
  638. // construct display device structures manually because width and height are configurable
  639. uint8_t *fb_dev_buf = (uint8_t *)luaM_malloc( L, width );
  640. u8g_pb_t *fb_dev_pb = (u8g_pb_t *)luaM_malloc( L, sizeof( u8g_pb_t ) );
  641. fb_dev_pb->p.page_height = 8;
  642. fb_dev_pb->p.total_height = height;
  643. fb_dev_pb->p.page_y0 = 0;
  644. fb_dev_pb->p.page_y1 = 0;
  645. fb_dev_pb->p.page = 0;
  646. fb_dev_pb->width = width;
  647. fb_dev_pb->buf = fb_dev_buf;
  648. u8g_dev_t *fb_dev = (u8g_dev_t *)luaM_malloc( L, sizeof( u8g_dev_t ) );
  649. fb_dev->dev_fn = u8g_dev_gen_fb_fn;
  650. fb_dev->dev_mem = fb_dev_pb;
  651. fb_dev->com_fn = u8g_com_esp8266_fbrle_fn;
  652. lud = (lu8g_userdata_t *) lua_newuserdata( L, sizeof( lu8g_userdata_t ) );
  653. lua_pushvalue( L, 1 ); // copy argument (func) to the top of stack
  654. lud->cb_ref = luaL_ref( L, LUA_REGISTRYINDEX );
  655. /* set metatable for userdata */
  656. luaL_getmetatable(L, "u8g.display");
  657. lua_setmetatable(L, -2);
  658. u8g_Init8BitFixedPort( LU8G, fb_dev, width, height, 0, 0, 0);
  659. return 1;
  660. }
  661. //
  662. // ***************************************************************************
  663. // Module function map
  664. static const LUA_REG_TYPE lu8g_display_map[] = {
  665. { LSTRKEY( "begin" ), LFUNCVAL( lu8g_begin ) },
  666. { LSTRKEY( "drawBitmap" ), LFUNCVAL( lu8g_drawBitmap ) },
  667. { LSTRKEY( "drawBox" ), LFUNCVAL( lu8g_drawBox ) },
  668. { LSTRKEY( "drawCircle" ), LFUNCVAL( lu8g_drawCircle ) },
  669. { LSTRKEY( "drawDisc" ), LFUNCVAL( lu8g_drawDisc ) },
  670. { LSTRKEY( "drawEllipse" ), LFUNCVAL( lu8g_drawEllipse ) },
  671. { LSTRKEY( "drawFilledEllipse" ), LFUNCVAL( lu8g_drawFilledEllipse ) },
  672. { LSTRKEY( "drawFrame" ), LFUNCVAL( lu8g_drawFrame ) },
  673. { LSTRKEY( "drawHLine" ), LFUNCVAL( lu8g_drawHLine ) },
  674. { LSTRKEY( "drawLine" ), LFUNCVAL( lu8g_drawLine ) },
  675. { LSTRKEY( "drawPixel" ), LFUNCVAL( lu8g_drawPixel ) },
  676. { LSTRKEY( "drawRBox" ), LFUNCVAL( lu8g_drawRBox ) },
  677. { LSTRKEY( "drawRFrame" ), LFUNCVAL( lu8g_drawRFrame ) },
  678. { LSTRKEY( "drawStr" ), LFUNCVAL( lu8g_drawStr ) },
  679. { LSTRKEY( "drawStr90" ), LFUNCVAL( lu8g_drawStr90 ) },
  680. { LSTRKEY( "drawStr180" ), LFUNCVAL( lu8g_drawStr180 ) },
  681. { LSTRKEY( "drawStr270" ), LFUNCVAL( lu8g_drawStr270 ) },
  682. { LSTRKEY( "drawTriangle" ), LFUNCVAL( lu8g_drawTriangle ) },
  683. { LSTRKEY( "drawVLine" ), LFUNCVAL( lu8g_drawVLine ) },
  684. { LSTRKEY( "drawXBM" ), LFUNCVAL( lu8g_drawXBM ) },
  685. { LSTRKEY( "firstPage" ), LFUNCVAL( lu8g_firstPage ) },
  686. { LSTRKEY( "getColorIndex" ), LFUNCVAL( lu8g_getColorIndex ) },
  687. { LSTRKEY( "getFontAscent" ), LFUNCVAL( lu8g_getFontAscent ) },
  688. { LSTRKEY( "getFontDescent" ), LFUNCVAL( lu8g_getFontDescent ) },
  689. { LSTRKEY( "getFontLineSpacing" ), LFUNCVAL( lu8g_getFontLineSpacing ) },
  690. { LSTRKEY( "getHeight" ), LFUNCVAL( lu8g_getHeight ) },
  691. { LSTRKEY( "getMode" ), LFUNCVAL( lu8g_getMode ) },
  692. { LSTRKEY( "getStrWidth" ), LFUNCVAL( lu8g_getStrWidth ) },
  693. { LSTRKEY( "getWidth" ), LFUNCVAL( lu8g_getWidth ) },
  694. { LSTRKEY( "nextPage" ), LFUNCVAL( lu8g_nextPage ) },
  695. { LSTRKEY( "setContrast" ), LFUNCVAL( lu8g_setContrast ) },
  696. { LSTRKEY( "setColorIndex" ), LFUNCVAL( lu8g_setColorIndex ) },
  697. { LSTRKEY( "setDefaultBackgroundColor" ), LFUNCVAL( lu8g_setDefaultBackgroundColor ) },
  698. { LSTRKEY( "setDefaultForegroundColor" ), LFUNCVAL( lu8g_setDefaultForegroundColor ) },
  699. { LSTRKEY( "setFont" ), LFUNCVAL( lu8g_setFont ) },
  700. { LSTRKEY( "setFontLineSpacingFactor" ), LFUNCVAL( lu8g_setFontLineSpacingFactor ) },
  701. { LSTRKEY( "setFontPosBaseline" ), LFUNCVAL( lu8g_setFontPosBaseline ) },
  702. { LSTRKEY( "setFontPosBottom" ), LFUNCVAL( lu8g_setFontPosBottom ) },
  703. { LSTRKEY( "setFontPosCenter" ), LFUNCVAL( lu8g_setFontPosCenter ) },
  704. { LSTRKEY( "setFontPosTop" ), LFUNCVAL( lu8g_setFontPosTop ) },
  705. { LSTRKEY( "setFontRefHeightAll" ), LFUNCVAL( lu8g_setFontRefHeightAll ) },
  706. { LSTRKEY( "setFontRefHeightExtendedText" ), LFUNCVAL( lu8g_setFontRefHeightExtendedText ) },
  707. { LSTRKEY( "setFontRefHeightText" ), LFUNCVAL( lu8g_setFontRefHeightText ) },
  708. { LSTRKEY( "setRot90" ), LFUNCVAL( lu8g_setRot90 ) },
  709. { LSTRKEY( "setRot180" ), LFUNCVAL( lu8g_setRot180 ) },
  710. { LSTRKEY( "setRot270" ), LFUNCVAL( lu8g_setRot270 ) },
  711. { LSTRKEY( "setScale2x2" ), LFUNCVAL( lu8g_setScale2x2 ) },
  712. { LSTRKEY( "sleepOff" ), LFUNCVAL( lu8g_sleepOff ) },
  713. { LSTRKEY( "sleepOn" ), LFUNCVAL( lu8g_sleepOn ) },
  714. { LSTRKEY( "undoRotation" ), LFUNCVAL( lu8g_undoRotation ) },
  715. { LSTRKEY( "undoScale" ), LFUNCVAL( lu8g_undoScale ) },
  716. { LSTRKEY( "__gc" ), LFUNCVAL( lu8g_close_display ) },
  717. { LSTRKEY( "__index" ), LROVAL( lu8g_display_map ) },
  718. { LNILKEY, LNILVAL }
  719. };
  720. #undef U8G_DISPLAY_TABLE_ENTRY
  721. #undef U8G_FONT_TABLE_ENTRY
  722. static const LUA_REG_TYPE lu8g_map[] = {
  723. #define U8G_DISPLAY_TABLE_ENTRY(device) \
  724. { LSTRKEY( #device ), LFUNCVAL ( lu8g_ ##device ) },
  725. U8G_DISPLAY_TABLE_I2C
  726. U8G_DISPLAY_TABLE_SPI
  727. // Register fonts
  728. #define U8G_FONT_TABLE_ENTRY(font) \
  729. { LSTRKEY( #font ), LUDATA( (void *)(u8g_ ## font) ) },
  730. U8G_FONT_TABLE
  731. //
  732. { LSTRKEY( "fb_rle" ), LFUNCVAL( lu8g_fb_rle ) },
  733. // Options for circle/ ellipse drawing
  734. { LSTRKEY( "DRAW_UPPER_RIGHT" ), LNUMVAL( U8G_DRAW_UPPER_RIGHT ) },
  735. { LSTRKEY( "DRAW_UPPER_LEFT" ), LNUMVAL( U8G_DRAW_UPPER_LEFT ) },
  736. { LSTRKEY( "DRAW_LOWER_RIGHT" ), LNUMVAL( U8G_DRAW_LOWER_RIGHT ) },
  737. { LSTRKEY( "DRAW_LOWER_LEFT" ), LNUMVAL( U8G_DRAW_LOWER_LEFT ) },
  738. { LSTRKEY( "DRAW_ALL" ), LNUMVAL( U8G_DRAW_ALL ) },
  739. // Display modes
  740. { LSTRKEY( "MODE_BW" ), LNUMVAL( U8G_MODE_BW ) },
  741. { LSTRKEY( "MODE_GRAY2BIT" ), LNUMVAL( U8G_MODE_GRAY2BIT ) },
  742. { LSTRKEY( "__metatable" ), LROVAL( lu8g_map ) },
  743. { LNILKEY, LNILVAL }
  744. };
  745. int luaopen_u8g( lua_State *L ) {
  746. luaL_rometatable(L, "u8g.display", (void *)lu8g_display_map); // create metatable
  747. return 0;
  748. }
  749. NODEMCU_MODULE(U8G, "u8g", lu8g_map, luaopen_u8g);