ref: e3a3564affde308600a8bd534df38a0e9229efba
parent: f00064c3e10452efe86d9a646c54b074d6da54b0
author: telephil9 <[email protected]>
date: Sun Oct 25 05:09:10 EDT 2020
Major code refactoring Much needed code cleanup after what was a POC style initial version: - Stick to plan9 C coding standards - Split code in several files for readability - Expose constants as uppercase to match lua coding standards - Added a key module to expose known key constants
--- a/README.md
+++ b/README.md
@@ -1,21 +1,23 @@
# About
lua9 is a custom version of the [lua](http://lua.org) interpreter including bindings to plan9 libdraw.
-This relies on the [lua 5.4 port](https://github.com/staalmannen/lua) for plan9 by [staalmannen](https://github.com/staalmannen).
-Disclaimer: This is work in progress and is sure to contain bugs.
+__Disclaimer:__ This is work in progress and is sure to contain bugs.
# Installation
-First, install the lua 5.4 port for plan9.
+Make sure to have [git9](http://github.com/oridb/git9] installed first.
-Clone the sources using the [git9](https://github.com/oridb/git9) client:
+Install the [lua 5.4 port](https://github.com/staalmannen/lua) for plan9 by [staalmannen](https://github.com/staalmannen).
```sh
-% git/clone git://github.com/telephil9/lua9
+% git/clone git://github.com/staalmannen/lua
+% cd lua
+% mk install
```
-Install the lua9 interpreter:
+Install lua9:
```sh
+% git/clone git://github.com/telephil9/lua9
% cd lua9
% mk install
```
@@ -25,8 +27,10 @@
```sh
% ape/lua9 <script.lua>
```
-It is also possible to use a shebang script.
-# Credits
+You can also start your lua script with `#!/bin/ape/lua9`.
-- Philippe ([telephil9](https://github.com/telephil9/))
+# Documentation
+
+TODO
+
--- /dev/null
+++ b/display.c
@@ -1,0 +1,87 @@
+#include <draw.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include "ldraw.h"
+#include "utils.h"
+
+#define DISPLAY "Display"
+
+typedef struct LDisplay LDisplay;
+
+struct LDisplay
+{
+ Display *d;
+};
+
+void
+pushdisplay(lua_State *L, Display *d)
+{
+ LDisplay *l;
+
+ l = (LDisplay*)lua_newuserdata(L, sizeof(LDisplay));
+ luaL_getmetatable(L, DISPLAY);
+ lua_setmetatable(L, -2);
+ l->d = d;
+}
+
+Display*
+checkdisplay(lua_State *L, int index)
+{
+ LDisplay *l;
+
+ l = (LDisplay*)luaL_checkudata(L, index, DISPLAY);
+ luaL_argcheck(L, l != NULL, index, "Display expected");
+ return l->d;
+}
+
+static int
+display__gc(lua_State *L)
+{
+ /* we do not GC the display */
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+static int
+display__tostring(lua_State *L)
+{
+ void *p;
+
+ p = lua_touserdata(L, 1);
+ lua_pushfstring(L, "display: %p", p);
+ return 1;
+}
+
+static int
+display__index(lua_State *L)
+{
+ Display *d;
+ const char *s;
+
+ d = checkdisplay(L, 1);
+ s = luaL_checkstring(L, 2);
+ if(strncmp(s, "white", 5) == 0)
+ pushimage(L, d->white);
+ else if(strncmp(s, "black", 5) == 0)
+ pushimage(L, d->black);
+ else
+ return 0;
+ return 1;
+}
+
+static const struct luaL_Reg display_funcs[] = {
+ { "__gc", display__gc },
+ { "__tostring", display__tostring },
+ { "__index", display__index },
+ { NULL, NULL },
+};
+
+void
+registerdisplaymeta(lua_State *L)
+{
+ createmetatable(L, DISPLAY, display_funcs);
+}
+
--- /dev/null
+++ b/font.c
@@ -1,0 +1,94 @@
+#include <draw.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include "ldraw.h"
+#include "utils.h"
+
+#define FONT "Font"
+
+typedef struct LFont LFont;
+
+struct LFont
+{
+ Font *f;
+};
+
+void
+pushfont(lua_State *L, Font *f)
+{
+ LFont *l;
+
+ l = (LFont*)lua_newuserdata(L, sizeof(LFont));
+ luaL_getmetatable(L, FONT);
+ lua_setmetatable(L, -2);
+ l->f = f;
+}
+
+Font*
+checkfont(lua_State *L, int index)
+{
+ LFont *l;
+
+ l = (LFont*)luaL_checkudata(L, index, FONT);
+ luaL_argcheck(L, l != NULL, index, "Font expected");
+ return l->f;
+}
+
+static int
+font__gc(lua_State *L)
+{
+ /* TODO */
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+static int
+font__tostring(lua_State *L)
+{
+ void *p;
+
+ p = lua_touserdata(L, 1);
+ lua_pushfstring(L, "font: %p", p);
+ return 1;
+}
+
+static int
+font__index(lua_State *L)
+{
+ Font *f;
+ const char *s;
+
+ f = checkfont(L, 1);
+ s = luaL_checkstring(L, 2);
+ if(strncmp(s, "name", 4) == 0)
+ lua_pushstring(L, f->name);
+ else if(strncmp(s, "height", 6) == 0)
+ lua_pushinteger(L, f->height);
+ else if(strncmp(s, "ascent", 6) == 0)
+ lua_pushinteger(L, f->ascent);
+ else if(strncmp(s, "width", 5) == 0)
+ lua_pushinteger(L, f->width);
+ else if(strncmp(s, "nsub", 4) == 0)
+ lua_pushinteger(L, f->nsub);
+ else if(strncmp(s, "age", 3) == 0)
+ lua_pushinteger(L, f->age);
+ else
+ return 0;
+ return 1;
+}
+
+static const struct luaL_Reg font_funcs[] = {
+ { "__gc", font__gc },
+ { "__tostring", font__tostring },
+ { "__index", font__index },
+ { NULL, NULL },
+};
+
+void
+registerfontmeta(lua_State *L)
+{
+ createmetatable(L, FONT, font_funcs);
+}
--- /dev/null
+++ b/geometry.c
@@ -1,0 +1,91 @@
+#include <draw.h>
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+void
+pushrect(lua_State *L, Rectangle r)
+{
+ lua_newtable(L);
+ lua_newtable(L);
+ lua_pushinteger(L, r.min.x);
+ lua_setfield(L, -2, "x");
+ lua_pushinteger(L, r.min.y);
+ lua_setfield(L, -2, "y");
+ lua_setfield(L, -2, "min");
+ lua_newtable(L);
+ lua_pushinteger(L, r.max.x);
+ lua_setfield(L, -2, "x");
+ lua_pushinteger(L, r.max.y);
+ lua_setfield(L, -2, "y");
+ lua_setfield(L, -2, "max");
+}
+
+Rectangle
+checkrect(lua_State *L, int index)
+{
+ Rectangle r;
+
+ if(lua_istable(L, index) == 0)
+ luaL_argerror(L, index, "rectangle table expected");
+ lua_pushstring(L, "min");
+ lua_gettable(L, index);
+ lua_pushstring(L, "x");
+ lua_gettable(L, -2);
+ r.min.x = luaL_checkinteger(L, -1);
+ lua_pushstring(L, "y");
+ lua_gettable(L, -3);
+ r.min.y = luaL_checkinteger(L, -1);
+ lua_pop(L, 3); /* table | x | y */
+ lua_pushstring(L, "max");
+ lua_gettable(L, index);
+ lua_pushstring(L, "x");
+ lua_gettable(L, -2);
+ r.max.x = luaL_checkinteger(L, -1);
+ lua_pushstring(L, "y");
+ lua_gettable(L, -3);
+ r.max.y = luaL_checkinteger(L, -1);
+ lua_pop(L, 3);
+ return r;
+}
+
+void
+pushpoint(lua_State *L, Point p)
+{
+ lua_newtable(L);
+ lua_pushinteger(L, p.x);
+ lua_setfield(L, -2, "x");
+ lua_pushinteger(L, p.y);
+ lua_setfield(L, -2, "y");
+}
+
+Point
+getpoint(lua_State *L, int index)
+{
+ Point p;
+
+ lua_pushstring(L, "x");
+ lua_gettable(L, index);
+ p.x = luaL_checkinteger(L, -1);
+ lua_pushstring(L, "y");
+ lua_gettable(L, index);
+ p.y = luaL_checkinteger(L, -1);
+ lua_pop(L, 2);
+ return p;
+}
+
+Point
+checkpoint(lua_State *L, int index)
+{
+ if(lua_istable(L, index) == 0)
+ luaL_argerror(L, index, "point table expected");
+ return getpoint(L, index);
+}
+
+Point
+optpoint(lua_State *L, int index)
+{
+ if(lua_istable(L, index) == 0)
+ return ZP;
+ return getpoint(L, index);
+}
--- /dev/null
+++ b/image.c
@@ -1,0 +1,107 @@
+#include <draw.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include "ldraw.h"
+#include "utils.h"
+
+#define IMAGE "Image"
+
+typedef struct LImage LImage;
+
+struct LImage
+{
+ Image *i;
+};
+
+void pushimage(lua_State *L, Image *i)
+{
+ LImage *l;
+
+ l = (LImage*)lua_newuserdata(L, sizeof(LImage));
+ luaL_getmetatable(L, IMAGE);
+ lua_setmetatable(L, -2);
+ l->i = i;
+}
+
+Image*
+checkimage(lua_State *L, int index)
+{
+ LImage *l;
+
+ l = (LImage*)luaL_checkudata(L, index, IMAGE);
+ luaL_argcheck(L, l != NULL, index, "Image expected");
+ return l->i;
+}
+
+Image*
+optimage(lua_State *L, int index)
+{
+ if(lua_isnil(L, index))
+ return nil;
+ return checkimage(L, index);
+}
+
+static int
+image__gc(lua_State *L)
+{
+ Image *i;
+
+ i = checkimage(L, 1);
+ if(i == screen) {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+ /* TODO freeimage */
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+static int
+image__tostring(lua_State *L)
+{
+ void *p;
+ char buf[64];
+
+ p = lua_touserdata(L, 1);
+ lua_pushfstring(L, "image: %p", p);
+ return 1;
+}
+
+static int
+image__index(lua_State *L)
+{
+ Image *i;
+ const char *s;
+
+ i = checkimage(L, 1);
+ s = luaL_checkstring(L, 2);
+ if(!strncmp(s, "r", 1))
+ pushrect(L, i->r);
+ else if(!strncmp(s, "clipr", 5))
+ pushrect(L, i->clipr);
+ else if(!strncmp(s, "chan", 4))
+ lua_pushinteger(L, i->chan);
+ else if(!strncmp(s, "depth", 5))
+ lua_pushinteger(L, i->depth);
+ else if(!strncmp(s, "repl", 4))
+ lua_pushinteger(L, i->repl);
+ else
+ return 0;
+ return 1;
+}
+
+static const struct luaL_Reg image_funcs[] = {
+ { "__gc", image__gc },
+ { "__tostring", image__tostring },
+ { "__index", image__index },
+ { NULL, NULL },
+};
+
+void
+registerimagemeta(lua_State *L)
+{
+ createmetatable(L, IMAGE, image_funcs);
+}
--- /dev/null
+++ b/key.c
@@ -1,0 +1,50 @@
+#include <keyboard.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include "utils.h"
+
+static int
+lkeyeq(lua_State *L)
+{
+ int i;
+ const char *s;
+
+ i = luaL_checkinteger(L, 1);
+ s = luaL_checkstring(L, 2);
+ lua_pushboolean(L, i==*s);
+ return 1;
+}
+
+static const struct luaL_Reg libkey[] = {
+ { "eq", lkeyeq },
+ { NULL, NULL },
+};
+
+int
+openlibkey(lua_State *L)
+{
+ luaL_newlib(L, libkey);
+ pushglobal(L, "HOME", Khome);
+ pushglobal(L, "UP", Kup);
+ pushglobal(L, "DOWN", Kdown);
+ pushglobal(L, "PGUP", Kpgup);
+ pushglobal(L, "PRINT", Kprint);
+ pushglobal(L, "LEFT", Kleft);
+ pushglobal(L, "RIGHT", Kright);
+ pushglobal(L, "PGDOWN", Kpgdown);
+ pushglobal(L, "INS", Kins);
+ pushglobal(L, "END", Kend);
+ pushglobal(L, "SOH", Ksoh);
+ pushglobal(L, "STX", Kstx);
+ pushglobal(L, "ETX", Ketx);
+ pushglobal(L, "EOF", Keof);
+ pushglobal(L, "ENQ", Kenq);
+ pushglobal(L, "ACK", Kack);
+ pushglobal(L, "BS", Kbs);
+ pushglobal(L, "NACK", Knack);
+ pushglobal(L, "ETB", Ketb);
+ pushglobal(L, "DEL", Kdel);
+ pushglobal(L, "ESC", Kesc);
+ return 1;
+}
--- /dev/null
+++ b/ldraw.h
@@ -1,0 +1,32 @@
+#ifndef LDRAW_H__
+#define LDRAW_H__
+
+/* display */
+void registerdisplaymeta(lua_State *L);
+void pushdisplay(lua_State *L, Display *d);
+Display* checkdisplay(lua_State *L, int index);
+
+/* font */
+void registerfontmeta(lua_State *L);
+void pushfont(lua_State *L, Font *f);
+Font* checkfont(lua_State *L, int index);
+
+/* image */
+void registerimagemeta(lua_State *L);
+void pushimage(lua_State *L, Image *i);
+Image* checkimage(lua_State *L, int index);
+Image* optimage(lua_State *L, int index);
+
+/* geometry */
+void pushrect(lua_State *L, Rectangle r);
+Rectangle checkrect(lua_State *L, int index);
+void pushpoint(lua_State *L, Point p);
+Point checkpoint(lua_State *L, int index);
+Point getpoint(lua_State *L, int index);
+Point optpoint(lua_State *L, int index);
+
+/* libs */
+int openlibdraw(lua_State *L);
+int openlibkey(lua_State *L);
+
+#endif
--- a/lua9.c
+++ b/lua9.c
@@ -5,43 +5,15 @@
#include <draw.h>
#include <event.h>
#include <keyboard.h>
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include "ldraw.h"
+#include "utils.h"
-#define IMAGE_META "Image"
-#define DISPLAY_META "Display"
-#define FONT_META "Font"
-
-typedef struct ImagePtr ImagePtr;
-typedef struct DisplayPtr DisplayPtr;
-typedef struct FontPtr FontPtr;
-
-struct ImagePtr {
- Image *p;
-};
-
-struct DisplayPtr {
- Display *p;
-};
-
-struct FontPtr {
- Font *p;
-};
-
static lua_State *state;
static int ridx, tidx;
-static ImagePtr* to_image(lua_State *L, Image *img) {
- ImagePtr *i;
-
- i = (ImagePtr*)lua_newuserdata(L, sizeof(ImagePtr));
- luaL_getmetatable(L, IMAGE_META);
- lua_setmetatable(L, -2);
- i->p = img;
- return i;
-}
-
void eresized(int new) {
if(new && getwindow(display, Refnone) < 0){
fprintf(stderr, "cannot reattach to window: %r");
@@ -53,29 +25,9 @@
lua_pop(state, 2);
}
-static void create_globals(lua_State *L) {
- ImagePtr *i;
- DisplayPtr *d;
- FontPtr *f;
-
- i = (ImagePtr*)lua_newuserdatauv(L, sizeof(ImagePtr), 1);
- luaL_getmetatable(L, IMAGE_META);
- lua_setmetatable(L, -2);
- i->p = screen;
- lua_setglobal(L, "screen");
- d = (DisplayPtr*)lua_newuserdata(L, sizeof(DisplayPtr));
- luaL_getmetatable(L, DISPLAY_META);
- lua_setmetatable(L, -2);
- d->p = display;
- lua_setglobal(L, "display");
- f = (FontPtr*)lua_newuserdata(L, sizeof(FontPtr));
- luaL_getmetatable(L, FONT_META);
- lua_setmetatable(L, -2);
- f->p = font;
- lua_setglobal(L, "font");
-}
-
-static int l_initdraw(lua_State *L) {
+static int
+linitdraw(lua_State *L)
+{
const char *n;
char buf[256];
@@ -96,11 +48,18 @@
lua_error(L);
}
state = L;
- create_globals(L);
+ pushdisplay(L, display);
+ lua_setglobal(L, "display");
+ pushimage(L, screen);
+ lua_setglobal(L, "screen");
+ pushfont(L, font);
+ lua_setglobal(L, "font");
return 0;
}
-static int l_einit(lua_State *L) {
+static int
+leinit(lua_State *L)
+{
lua_Integer i;
i = luaL_checknumber(L, -1);
@@ -108,7 +67,9 @@
return 0;
}
-static int l_event(lua_State *L) {
+static int
+levent(lua_State *L)
+{
Event ev;
int e;
@@ -120,182 +81,97 @@
return 2;
}
-static Point l_getpoint(lua_State *L, int index)
+static int
+ldraw(lua_State *L)
{
- Point p;
-
- lua_pushstring(L, "x");
- lua_gettable(L, index);
- p.x = luaL_checkinteger(L, -1);
- lua_pushstring(L, "y");
- lua_gettable(L, index);
- p.y = luaL_checkinteger(L, -1);
- lua_pop(L, 2);
- return p;
-}
-
-static Point l_checkpoint(lua_State *L, int index)
-{
- if(lua_istable(L, index) == 0)
- luaL_argerror(L, index, "draw: point table expected");
- return l_getpoint(L, index);
-}
-
-static Point l_optpoint(lua_State *L, int index)
-{
- if(lua_istable(L, index) == 0)
- return ZP;
- return l_getpoint(L, index);
-}
-
-static Rectangle l_getrect(lua_State *L, int index)
-{
- Rectangle r;
- int t;
-
- lua_pushstring(L, "min");
- lua_gettable(L, index);
- lua_pushstring(L, "x");
- lua_gettable(L, -2);
- r.min.x = luaL_checkinteger(L, -1);
- lua_pushstring(L, "y");
- t = lua_gettable(L, -3);
- r.min.y = luaL_checkinteger(L, -1);
- lua_pop(L, 3); /* table | x | y */
- lua_pushstring(L, "max");
- lua_gettable(L, index);
- lua_pushstring(L, "x");
- lua_gettable(L, -2);
- r.max.x = luaL_checkinteger(L, -1);
- lua_pushstring(L, "y");
- lua_gettable(L, -3);
- r.max.y = luaL_checkinteger(L, -1);
- lua_pop(L, 3);
- return r;
-}
-
-static Rectangle l_checkrect(lua_State *L, int index)
-{
- if(lua_istable(L, index) == 0)
- luaL_argerror(L, index, "draw: rectangle table expected");
- return l_getrect(L, index);
-}
-
-static Image* l_checkimage(lua_State *L, int index)
-{
- ImagePtr *p;
-
- p = (ImagePtr*)luaL_checkudata(L, index, IMAGE_META);
- luaL_argcheck(L, p != NULL, index, "draw: Image expected");
- return p->p;
-}
-
-static Image* l_optimage(lua_State *L, int index)
-{
- if(lua_isnil(L, index))
- return nil;
- return l_checkimage(L, index);
-}
-
-static Font* l_checkfont(lua_State *L, int index)
-{
- FontPtr *p;
-
- p = (FontPtr*)luaL_checkudata(L, index, FONT_META);
- luaL_argcheck(L, p != NULL, index, "draw: Font expected");
- return p->p;
-}
-
-static Display* l_checkdisplay(lua_State *L, int index)
-{
- DisplayPtr *p;
-
- p = (DisplayPtr*)luaL_checkudata(L, index, DISPLAY_META);
- luaL_argcheck(L, p!=NULL, index, "draw: Display expected");
- return p->p;
-}
-
-static int l_draw(lua_State *L) {
Image *dst, *src, *mask;
Point p;
Rectangle r;
- dst = l_checkimage(L, 1);
- r = l_checkrect(L, 2);
- src = l_checkimage(L, 3);
- mask = l_optimage(L, 4);
- p = l_checkpoint(L, 5);
+ dst = checkimage(L, 1);
+ r = checkrect(L, 2);
+ src = checkimage(L, 3);
+ mask = optimage(L, 4);
+ p = checkpoint(L, 5);
draw(dst, r, src, mask, p);
return 0;
}
-static int l_line(lua_State *L) {
+static int
+lline(lua_State *L)
+{
Image *dst, *src;
Point p0, p1, sp;
int end0, end1, thick;
- dst = l_checkimage(L, 1);
- p0 = l_checkpoint(L, 2);
- p1 = l_checkpoint(L, 3);
+ dst = checkimage(L, 1);
+ p0 = checkpoint(L, 2);
+ p1 = checkpoint(L, 3);
end0 = luaL_checkinteger(L, 4);
end1 = luaL_checkinteger(L, 5);
thick = luaL_checkinteger(L, 6);
- src = l_checkimage(L, 7);
- sp = l_checkpoint(L, 8);
+ src = checkimage(L, 7);
+ sp = checkpoint(L, 8);
line(dst, p0, p1, end0, end1, thick, src, sp);
return 0;
}
-static int l_ellipse(lua_State *L)
+static int
+lellipse(lua_State *L)
{
Image *dst, *src;
Point c, sp;
int a, b, thick;
- dst = l_checkimage(L, 1);
- c = l_checkpoint(L, 2);
+ dst = checkimage(L, 1);
+ c = checkpoint(L, 2);
a = luaL_checkinteger(L, 3);
b = luaL_checkinteger(L, 4);
thick = luaL_checkinteger(L, 5);
- src = l_checkimage(L, 6);
- sp = l_checkpoint(L, 7);
+ src = checkimage(L, 6);
+ sp = checkpoint(L, 7);
ellipse(dst, c, a, b, thick, src, sp);
return 0;
}
-static int l_fillellipse(lua_State *L)
+static int
+lfillellipse(lua_State *L)
{
Image *dst, *src;
Point c, sp;
int a, b;
- dst = l_checkimage(L, 1);
- c = l_checkpoint(L, 2);
+ dst = checkimage(L, 1);
+ c = checkpoint(L, 2);
a = luaL_checkinteger(L, 3);
b = luaL_checkinteger(L, 4);
- src = l_checkimage(L, 5);
- sp = l_checkpoint(L, 6);
+ src = checkimage(L, 5);
+ sp = checkpoint(L, 6);
fillellipse(dst, c, a, b, src, sp);
return 0;
}
-static int l_string(lua_State *L) {
+static int
+lstring(lua_State *L)
+{
Image *dst, *src;
Font *f;
- Point p, sp;
+ Point p, sp, r;
const char *s;
- dst = l_checkimage(L, 1);
- p = l_checkpoint(L, 2);
- src = l_checkimage(L, 3);
- sp = l_optpoint(L, 4);
- f = l_checkfont(L, 5);
+ dst = checkimage(L, 1);
+ p = checkpoint(L, 2);
+ src = checkimage(L, 3);
+ sp = optpoint(L, 4);
+ f = checkfont(L, 5);
s = luaL_checkstring(L, 6);
- string(dst, p, src, sp, f, s);
- return 0;
+ r = string(dst, p, src, sp, f, s);
+ pushpoint(L, r);
+ return 1;
}
-static int l_allocimage(lua_State *L)
+static int
+lallocimage(lua_State *L)
{
Display *d;
Rectangle r;
@@ -303,207 +179,67 @@
int repl;
Image *i;
- d = l_checkdisplay(L, 1);
- r = l_checkrect(L, 2);
+ d = checkdisplay(L, 1);
+ r = checkrect(L, 2);
chan = (ulong)luaL_checkinteger(L, 3);
repl = luaL_checkinteger(L, 4);
col = (ulong)luaL_checkinteger(L, 5);
i = allocimage(d, r, chan, repl, col);
- to_image(L, i);
+ pushimage(L, i);
return 1;
}
-/* Image metatable */
-static int l_image_gc(lua_State *L) {
- ImagePtr *i;
+static const struct luaL_Reg libdraw [] = {
+ { "initdraw", linitdraw },
+ { "einit", leinit },
+ { "event", levent },
+ { "draw", ldraw },
+ { "line", lline },
+ { "ellipse", lellipse },
+ { "fillellipse", lfillellipse },
+ { "string", lstring },
+ { "allocimage", lallocimage },
+ { NULL, NULL }
+};
- i = (ImagePtr*)luaL_checkudata(L, 1, IMAGE_META);
- luaL_argcheck(L, i != NULL, 1, "draw: Image expected");
- if(i->p == screen) {
- lua_pushboolean(L, 0);
- return 1;
- }
- /* TODO freeimage */
- lua_pushboolean(L, 1);
- return 1;
-}
-
-static int l_image_tostring(lua_State *L) {
- void *p;
- char buf[64];
-
- p = lua_touserdata(L, 1);
- snprintf(buf, sizeof buf, "image: %p", p);
- lua_pushstring(L, buf);
- return 1;
-}
-
-static void l_pushrect(lua_State *L, Rectangle r)
+int
+openlibdraw(lua_State *L)
{
- lua_newtable(L);
- lua_newtable(L);
- lua_pushinteger(L, r.min.x);
- lua_setfield(L, -2, "x");
- lua_pushinteger(L, r.min.y);
- lua_setfield(L, -2, "y");
- lua_setfield(L, -2, "min");
- lua_newtable(L);
- lua_pushinteger(L, r.max.x);
- lua_setfield(L, -2, "x");
- lua_pushinteger(L, r.max.y);
- lua_setfield(L, -2, "y");
- lua_setfield(L, -2, "max");
-}
+ registerdisplaymeta(L);
+ registerimagemeta(L);
+ registerfontmeta(L);
+ luaL_newlib(L, libdraw);
+ pushglobal(L, "Emouse", Emouse);
+ pushglobal(L, "Ekeyboard", Ekeyboard);
+ pushglobal(L, "Endsquare", Endsquare);
+ pushglobal(L, "Enddisc", Enddisc);
+ pushglobal(L, "Endarrow", Endarrow);
+ pushglobal(L, "Endmask", Endmask);
-static int l_image_index(lua_State *L) {
- Image *i;
- const char *s;
-
- i = l_checkimage(L, 1);
- s = luaL_checkstring(L, 2);
- if(!strncmp(s, "r", 1)) {
- l_pushrect(L, i->r);
- } else if(!strncmp(s, "clipr", 5)) {
- l_pushrect(L, i->clipr);
- } else if(!strncmp(s, "chan", 4)) {
- lua_pushinteger(L, i->chan);
- } else if(!strncmp(s, "depth", 5)) {
- lua_pushinteger(L, i->depth);
- } else if(!strncmp(s, "repl", 4)) {
- lua_pushinteger(L, i->repl);
- } else {
- return 0;
- }
return 1;
}
-static const struct luaL_Reg image_funcs[] = {
- { "__gc", l_image_gc },
- { "__tostring", l_image_tostring },
- { "__index", l_image_index },
+static const luaL_Reg libs[] = {
+ { "draw", openlibdraw },
+ { "key", openlibkey },
{ NULL, NULL },
};
-static int l_display_gc(lua_State *L) {
- /* we do not GC the display */
- lua_pushboolean(L, 0);
- return 1;
-}
-
-static int l_display_tostring(lua_State *L) {
- void *p;
- char buf[64];
-
- p = lua_touserdata(L, 1);
- snprintf(buf, sizeof buf, "display: %p", p);
- lua_pushstring(L, buf);
- return 1;
-}
-
-static int l_display_index(lua_State *L) {
- DisplayPtr *d;
- const char *s;
-
- d = (DisplayPtr*)luaL_checkudata(L, 1, DISPLAY_META);
- luaL_argcheck(L, d != NULL, 1, "draw: Display expected");
- s = luaL_checkstring(L, 2);
- if(strncmp(s, "white", 5) == 0) {
- to_image(L, d->p->white);
- return 1;
- } else if(strncmp(s, "black", 5) == 0) {
- to_image(L, d->p->black);
- return 1;
- }
- return 0;
-}
-
-static const struct luaL_Reg display_funcs[] = {
- { "__gc", l_display_gc },
- { "__tostring", l_display_tostring },
- { "__index", l_display_index },
- { NULL, NULL },
-};
-
-static int l_font_gc(lua_State *L) {
- /* TODO */
- lua_pushboolean(L, 0);
- return 1;
-}
-
-static int l_font_tostring(lua_State *L) {
- void *p;
-
- p = lua_touserdata(L, 1);
- lua_pushfstring(L, "font: %p", p);
- return 1;
-}
-
-static const struct luaL_Reg font_funcs[] = {
- { "__gc", l_font_gc },
- { "__tostring", l_font_tostring },
-// { "__index", l_display_index },
- { NULL, NULL },
-};
-
-static void create_metatable(lua_State *L, const char *name, luaL_Reg *funcs) {
- luaL_newmetatable(L, name);
- luaL_setfuncs(L, funcs, 0);
- lua_pushliteral (L, "__metatable");
- lua_pushliteral (L, "draw: you're not allowed to get this metatable");
- lua_settable (L, -3);
-}
-
-static const struct luaL_Reg drawlib [] = {
- { "initdraw", l_initdraw },
- { "einit", l_einit },
- { "event", l_event },
- { "draw", l_draw },
- { "line", l_line },
- { "ellipse", l_ellipse },
- { "fillellipse", l_fillellipse },
- { "string", l_string },
- { "allocimage", l_allocimage },
- { NULL, NULL }
-};
-
-static void l_pushglobal(lua_State *L, const char *name, int value, int index)
-{
- lua_pushnumber(L, value);
- lua_setfield(L, index, name);
-}
-
-int luaopen_drawlib (lua_State *L) {
- create_metatable(L, IMAGE_META, image_funcs);
- create_metatable(L, DISPLAY_META, display_funcs);
- create_metatable(L, FONT_META, font_funcs);
- luaL_newlib(L, drawlib);
- lua_pushnumber(L, Emouse);
- lua_setfield(L, -2, "Emouse");
- lua_pushnumber(L, Ekeyboard);
- lua_setfield(L, -2, "Ekeyboard");
- l_pushglobal(L, "Endsquare", Endsquare, -2);
- l_pushglobal(L, "Enddisc", Enddisc, -2);
- l_pushglobal(L, "Endarrow", Endarrow, -2);
- l_pushglobal(L, "Endmask", Endmask, -2);
-
- return 1;
-}
-
-
int
main(int argc, char *argv[])
{
lua_State *L;
+ luaL_Reg *lib;
char *f = NULL;
int r;
L = luaL_newstate();
luaL_openlibs(L);
- luaL_requiref(L, "draw", luaopen_drawlib, 1);
- lua_pop(L, 1);
- if(argc > 1)
- f = argv[1];
- r = luaL_dofile(L, f);
+ for(lib = libs; lib->func; lib++){
+ luaL_requiref(L, lib->name, lib->func, 1);
+ lua_pop(L, 1);
+ }
+ r = luaL_dofile(L, argc > 1 ? argv[1] : NULL);
lua_close(L);
return f == LUA_OK;
}
--- a/mkfile
+++ b/mkfile
@@ -6,13 +6,17 @@
BIN=/$objtype/bin/ape
OFILES=\
- lua9.$O \
-
+ display.$O \
+ font.$O \
+ image.$O \
+ geometry.$O \
+ key.$O \
+ utils.$O \
+ lua9.$O
+
HFILES=\
- /sys/include/ape/lauxlib.h \
- /sys/include/ape/lua.h \
- /sys/include/ape/luaconf.h \
- /sys/include/ape/lualib.h
+ ldraw.h \
+ utils.h
</sys/src/cmd/mkone
--- a/sample.lua
+++ b/sample.lua
@@ -31,7 +31,7 @@
if e == draw.Emouse then
--print 'Mouse event'
elseif e == draw.Ekeyboard then
- if string.char(ev.kbdc) == 'q' then
+ if key.eq(ev.kbdc, 'q') or ev.kbdc == key.DEL then
os.exit()
end
end
--- /dev/null
+++ b/utils.c
@@ -1,0 +1,21 @@
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+/* push a global definition in the lib on the stack */
+void
+pushglobal(lua_State *L, const char *name, int value)
+{
+ lua_pushnumber(L, value);
+ lua_setfield(L, -2, name);
+}
+
+void
+createmetatable(lua_State *L, const char *name, luaL_Reg *funcs)
+{
+ luaL_newmetatable(L, name);
+ luaL_setfuncs(L, funcs, 0);
+ lua_pushliteral (L, "__metatable");
+ lua_pushliteral (L, "metatable access forbidden");
+ lua_settable (L, -3);
+}
--- /dev/null
+++ b/utils.h
@@ -1,0 +1,7 @@
+#ifndef UTILS_H__
+#define UTILS_H__
+
+void pushglobal(lua_State *L, const char *name, int value);
+void createmetatable(lua_State *L, const char *name, luaL_Reg *funcs);
+
+#endif