WIP
This commit is contained in:
parent
508d3e1a0d
commit
6c2cd300c4
10 changed files with 208 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
out/
|
out/
|
||||||
|
.sass-cache
|
||||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "lib/lgi"]
|
||||||
|
path = lib/lgi
|
||||||
|
url = https://github.com/lgi-devs/lgi
|
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
|
@ -7,7 +7,8 @@
|
||||||
"/usr/include/lua5.3",
|
"/usr/include/lua5.3",
|
||||||
"/usr/include/glib-2.0",
|
"/usr/include/glib-2.0",
|
||||||
"/usr/lib/glib-2.0/include",
|
"/usr/lib/glib-2.0/include",
|
||||||
"/usr/lib/x86_64-linux-gnu/glib-2.0/include"
|
"/usr/lib/x86_64-linux-gnu/glib-2.0/include",
|
||||||
|
"/usr/include/gobject-introspection-1.0"
|
||||||
],
|
],
|
||||||
"defines": [],
|
"defines": [],
|
||||||
"compilerPath": "/usr/bin/gcc",
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
|
@ -1,3 +1,10 @@
|
||||||
{
|
{
|
||||||
"C_Cpp.errorSquiggles": "Enabled"
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
|
"files.associations": {
|
||||||
|
"**/tasks/*.yml": "ansible",
|
||||||
|
"*.rockspec": "lua",
|
||||||
|
"*.ld": "lua",
|
||||||
|
"glib-mainloop.h": "c",
|
||||||
|
"lua.h": "c"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
58
Makefile
58
Makefile
|
@ -2,31 +2,47 @@ PROJECT = lgi_pulseaudio
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
BUILD_DIR = out
|
BUILD_DIR = out
|
||||||
|
|
||||||
LUA_VERSION ?= 5.3
|
LUA_VERSION ?= 5.1
|
||||||
LUA ?= $(shell command -v lua$(LUA_VERSION))
|
LUA ?= $(shell command -v lua$(LUA_VERSION))
|
||||||
LUA_BINDIR ?= /usr/bin
|
LUA_BINDIR ?= /usr/bin
|
||||||
# LUA_LIBDIR ?= /usr/lib
|
LUA_LIBDIR ?= /usr/lib/x86_64-linux-gnu/lua/$(LUA_VERSION)
|
||||||
LUA_INCDIR ?= /usr/include/lua$(LUA_VERSION)
|
LUA_INCDIR ?= /usr/include/lua$(LUA_VERSION)
|
||||||
|
|
||||||
INSTALL_BINDIR ?= $(PREFIX)/bin
|
ifdef LIBDIR
|
||||||
|
INSTALL_LIBDIR ?= $(LIBDIR)
|
||||||
|
else
|
||||||
INSTALL_LIBDIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)
|
INSTALL_LIBDIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef LUADIR
|
||||||
|
INSTALL_LUADIR ?= $(LUADIR)
|
||||||
|
else
|
||||||
INSTALL_LUADIR ?= $(PREFIX)/share/lua/$(LUA_VERSION)
|
INSTALL_LUADIR ?= $(PREFIX)/share/lua/$(LUA_VERSION)
|
||||||
INSTALL_CONFDIR ?= $(PREFIX)/etc
|
endif
|
||||||
|
|
||||||
|
ifdef DOCDIR
|
||||||
|
INSTALL_DOCDIR ?= $(DOCDIR)
|
||||||
|
else
|
||||||
|
INSTALL_DOCDIR ?= $(PREFIX)/share/doc/$(PROJECT)
|
||||||
|
endif
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
PKG_CONFIG ?= $(shell command -v pkg-config)
|
PKG_CONFIG ?= $(shell command -v pkg-config)
|
||||||
|
|
||||||
PKGS = glib-2.0 gobject-2.0 lua$(LUA_VERSION)
|
PKGS = libpulse-mainloop-glib glib-2.0 gobject-2.0 gobject-introspection-1.0 lua$(LUA_VERSION)
|
||||||
|
|
||||||
CFLAGS ?= -fPIC
|
CFLAGS ?= -fPIC
|
||||||
LIBFLAG ?= -shared
|
LIBFLAG ?= -shared
|
||||||
|
|
||||||
CCFLAGS ?= $(CFLAGS)
|
CCFLAGS ?= $(CFLAGS)
|
||||||
CCFLAGS += -Wall -g $(shell $(PKG_CONFIG) --cflags $(PKGS)) -I$(LUA_INCDIR)
|
CCFLAGS += -Wall -g -rdynamic $(shell $(PKG_CONFIG) --cflags $(PKGS)) -I$(LUA_INCDIR) -I"./"
|
||||||
|
|
||||||
LIBS = -L"$(LUA_LIBDIR)" -L$(shell dirname "$(shell $(CC) -print-libgcc-file-name)")
|
LIBS = -L$(shell dirname "$(shell $(CC) -print-libgcc-file-name)") -L"$(LUA_LIBDIR)" -L"./"
|
||||||
LIBS += $(shell $(PKG_CONFIG) --libs $(PKGS))
|
LIBS += $(shell $(PKG_CONFIG) --libs $(PKGS))
|
||||||
OBJS = $(shell find src -type f -iname '*.c' | sed 's/\(.*\)\.c$$/$(BUILD_DIR)\/\1\.so/')
|
OBJS = $(shell find src -type f -iname '*.c' | sed 's/\(.*\)\.c$$/$(BUILD_DIR)\/\1\.o/')
|
||||||
|
LGI_OBJS = $(shell find lib/lgi/lgi -type f -iname '*.c' | sed 's/\(.*\)\.c$$/\1\.o/')
|
||||||
|
|
||||||
|
TARGET = $(BUILD_DIR)/$(PROJECT).so
|
||||||
|
|
||||||
ifdef CI
|
ifdef CI
|
||||||
CHECK_ARGS ?= --formatter TAP
|
CHECK_ARGS ?= --formatter TAP
|
||||||
|
@ -37,14 +53,17 @@ endif
|
||||||
|
|
||||||
.PHONY: clean doc doc-content doc-styles install test check rock
|
.PHONY: clean doc doc-content doc-styles install test check rock
|
||||||
|
|
||||||
build: $(OBJS)
|
build: build-lgi $(TARGET)
|
||||||
|
|
||||||
|
build-lgi:
|
||||||
|
make -C lib/lgi
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.c
|
$(BUILD_DIR)/%.o: %.c
|
||||||
@mkdir -p $(shell dirname "$@")
|
@mkdir -p $(shell dirname "$@")
|
||||||
$(CC) -c $(CCFLAGS) $< -o $@
|
$(CC) -c $(CCFLAGS) $< -o $@
|
||||||
|
|
||||||
%.so: %.o
|
$(TARGET): $(OBJS)
|
||||||
$(CC) $(LIBFLAG) -o $@ $< $(LIBS)
|
$(CC) $(LIBFLAG) -o $@ $(OBJS) $(LGI_OBJS) $(LIBS)
|
||||||
|
|
||||||
doc-styles:
|
doc-styles:
|
||||||
@printf "\e[1;97mGenerate stylesheet\e[0m\n"
|
@printf "\e[1;97mGenerate stylesheet\e[0m\n"
|
||||||
|
@ -66,21 +85,24 @@ clean:
|
||||||
rm -r out/
|
rm -r out/
|
||||||
|
|
||||||
install: build doc
|
install: build doc
|
||||||
@printf "\e[1;97mInstall C libraries\e[0m\n"
|
@printf "\e[1;97mInstall C library\e[0m\n"
|
||||||
find $(BUILD_DIR)/src -type f -iname '*.so' | xargs install -vDm 644 -t $(INSTALL_LIBDIR)/$(PROJECT)
|
xargs install -vDm 644 -t $(INSTALL_LIBDIR)/$(PROJECT) $(TARGET)
|
||||||
|
|
||||||
@printf "\e[1;97mInstall Lua libraries\e[0m\n"
|
# @printf "\e[1;97mInstall Lua libraries\e[0m\n"
|
||||||
find src/ -type f -iname '*.lua' | xargs install -vDm 644 -t $(INSTALL_LUADIR)/$(PROJECT)
|
# find src/ -type f -iname '*.lua' | xargs install -vDm 644 -t $(INSTALL_LUADIR)/$(PROJECT)
|
||||||
|
|
||||||
@printf "\e[1;97mInstall documentation\e[0m\n"
|
@printf "\e[1;97mInstall documentation\e[0m\n"
|
||||||
install -vd $(PREFIX)/share/doc/$(PROJECT)
|
install -vd $(INSTALL_DOCDIR)
|
||||||
cp -vr $(BUILD_DIR)/doc/* $(PREFIX)/share/doc/$(PROJECT)
|
cp -vr $(BUILD_DIR)/doc/* $(INSTALL_DOCDIR)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
find src/ -iname '*.lua' | xargs luacheck $(CHECK_ARGS)
|
@echo "Nothing to do"
|
||||||
|
|
||||||
test:
|
test:
|
||||||
busted --config-file=.busted.lua --lua=$(LUA) $(TEST_ARGS)
|
busted --config-file=.busted.lua --lua=$(LUA) $(TEST_ARGS)
|
||||||
|
|
||||||
rock:
|
rock:
|
||||||
luarocks --local --lua-version $(LUA_VERSION) make rocks/lgi-pulseaudio-scm-1.rockspec
|
luarocks --local --lua-version $(LUA_VERSION) make rocks/lgi-pulseaudio-scm-1.rockspec
|
||||||
|
|
||||||
|
run: build
|
||||||
|
env LUA_CPATH="./out/?.so;${LUA_CPATH}" lua5.1 test.lua
|
||||||
|
|
1
lib/lgi
Submodule
1
lib/lgi
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 340a250ab0dfc157fe027f7a29eafda9b8572e5c
|
|
@ -33,6 +33,7 @@ build = {
|
||||||
INSTALL_LIBDIR="$(LIBDIR)",
|
INSTALL_LIBDIR="$(LIBDIR)",
|
||||||
INSTALL_LUADIR="$(LUADIR)",
|
INSTALL_LUADIR="$(LUADIR)",
|
||||||
INSTALL_CONFDIR="$(CONFDIR)",
|
INSTALL_CONFDIR="$(CONFDIR)",
|
||||||
|
INSTALL_DOCDIR="$(DOCDIR)",
|
||||||
},
|
},
|
||||||
copy_directories = {
|
copy_directories = {
|
||||||
"spec"
|
"spec"
|
||||||
|
|
143
src/lgi-pulseaudio/pulseaudio.c
Normal file
143
src/lgi-pulseaudio/pulseaudio.c
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/// libpulse bindings.
|
||||||
|
//
|
||||||
|
// @module pulseaudio
|
||||||
|
#include "lib/lgi/lgi/lgi.h"
|
||||||
|
|
||||||
|
#undef G_LOG_DOMAIN
|
||||||
|
#define G_LOG_DOMAIN "lgi-pulseaudio"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <glib-2.0/glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <pulse/glib-mainloop.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define LUA_MOD_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define LUA_MOD_EXPORT extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LUA_PULSEAUDIO "pulseaudio"
|
||||||
|
|
||||||
|
#if LUA_VERSION_NUM <= 501
|
||||||
|
// Shamelessly copied from Lua 5.3 source.
|
||||||
|
// TODO: Is there any official way to do this in 5.1?
|
||||||
|
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
|
||||||
|
luaL_checkstack(L, nup, "too many upvalues");
|
||||||
|
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||||
|
if (l->func == NULL) /* place holder? */
|
||||||
|
lua_pushboolean(L, 0);
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||||
|
lua_pushvalue(L, -nup);
|
||||||
|
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
|
||||||
|
}
|
||||||
|
lua_setfield(L, -(nup + 2), l->name);
|
||||||
|
}
|
||||||
|
lua_pop(L, nup); /* remove upvalues */
|
||||||
|
}
|
||||||
|
|
||||||
|
#define luaL_newlib(L,l) (luaL_register(L,LUA_PULSEAUDIO,l))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct pulseaudio {
|
||||||
|
pa_glib_mainloop* mainloop;
|
||||||
|
} pulseaudio;
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
pulseaudio_new(lua_State* L)
|
||||||
|
{
|
||||||
|
printf("get new stuff: %d\n", lua_gettop(L));
|
||||||
|
GMainContext* ctx = NULL;
|
||||||
|
|
||||||
|
if (lua_gettop(L) > 0) {
|
||||||
|
luaL_argcheck(L, lua_isuserdata(L, 1), 1, NULL);
|
||||||
|
printf("it's userdata\n");
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "type");
|
||||||
|
GITypeInfo* type_info = *(GITypeInfo **) luaL_checkudata(L, -1, LGI_GI_INFO);
|
||||||
|
luaL_argcheck(L, type_info != NULL && GI_IS_TYPE_INFO(type_info), 1, "paramter has no type info");
|
||||||
|
// TODO: Check if it's really a GMainContext
|
||||||
|
printf("type: %s\n", g_base_info_get_name(type_info));
|
||||||
|
// Pop the `type` field
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_pop(L, lgi_marshal_2c(L, type_info, NULL, GI_TRANSFER_NOTHING, (gpointer) ctx, 1, 0, NULL, NULL));
|
||||||
|
ctx = (GMainContext*) lua_touserdata(L, 1);
|
||||||
|
} else {
|
||||||
|
ctx = g_main_context_default();
|
||||||
|
|
||||||
|
if (ctx == NULL) {
|
||||||
|
lua_pushfstring(L, "Failed to accquire default GLib Main Context. Are we running in a Main Loop?");
|
||||||
|
lua_error(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("got some context\n");
|
||||||
|
|
||||||
|
pulseaudio* pa = lua_newuserdata (L, sizeof(pulseaudio));
|
||||||
|
if (!pa) {
|
||||||
|
return luaL_error(L, "failed to create pulseaudio userdata");
|
||||||
|
}
|
||||||
|
pa->mainloop = pa_glib_mainloop_new(ctx);
|
||||||
|
luaL_getmetatable(L, LUA_PULSEAUDIO);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Implement `__gc` meta method to free the inner `pa_glib_mainloop`
|
||||||
|
static const struct luaL_Reg pulseaudio_mt [] = {
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct luaL_Reg pulseaudio_lib [] = {
|
||||||
|
{"new", pulseaudio_new},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Shamelessly stolen from Lua 5.3 source code
|
||||||
|
// Uses Lua's `require`
|
||||||
|
static int dolibrary(lua_State *L, const char *name) {
|
||||||
|
int status;
|
||||||
|
int base;
|
||||||
|
|
||||||
|
base = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_getglobal(L, "require");
|
||||||
|
lua_pushstring(L, name);
|
||||||
|
status = lua_pcall(L, 1, 1, 0);
|
||||||
|
|
||||||
|
// Data for the `require` call is no longer needed
|
||||||
|
lua_insert(L, base);
|
||||||
|
lua_pop(L, 2);
|
||||||
|
|
||||||
|
if (status == 0) {
|
||||||
|
lua_setglobal(L, name);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
LUA_MOD_EXPORT int luaopen_lgi_pulseaudio(lua_State* L)
|
||||||
|
{
|
||||||
|
if (dolibrary(L, "lgi") != 0) {
|
||||||
|
lua_pushfstring(L, "failed to load library 'lgi'");
|
||||||
|
lua_error(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
luaL_newmetatable(L, LUA_PULSEAUDIO);
|
||||||
|
luaL_setfuncs(L, pulseaudio_mt, 0);
|
||||||
|
|
||||||
|
luaL_newlib(L, pulseaudio_lib);
|
||||||
|
return 1;
|
||||||
|
}
|
8
test.lua
Normal file
8
test.lua
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
local lgi = require("lgi")
|
||||||
|
local pulseaudio = require("lgi_pulseaudio")
|
||||||
|
|
||||||
|
local loop = lgi.GLib.MainLoop.new()
|
||||||
|
|
||||||
|
print(pulseaudio.new)
|
||||||
|
print(loop:get_context())
|
||||||
|
-- print(pulseaudio.new(loop:get_context()))
|
Loading…
Add table
Reference in a new issue