node-pulseaudio-control/main.c

188 lines
4.2 KiB
C

/*
* main.c
* Copyright (C) 2018 jshaver <john@jshaver.net>
*
* Distributed under terms of the MIT license.
*/
#include <node_api.h>
#include "stdio.h"
#include "pulse/pulseaudio.h"
struct CBData {
pa_context *context;
pa_mainloop *mainloop;
}
namespace miccontrol {
const char *NAME = "miccontrol";
void querySources(pa_context *c, void *userdata);
void handleSourceList(struct pa_context *c, const pa_source_info *i, int eol, void *userdata);
napi_value connectToPulse(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
pa_context *context;
CBData *cbData;
napi_status status;
status = napi_get_cb_info(env, info, &argc, args, nullptr, cbData);
assert(status == napi_ok);
napi_value *cb;
status = napi_create_reference(env, args[0], 1, cb);
assert(status == napi_ok);
int ret = 1;
pa_context_set_state_callback(cbData->context, connectToPulseCB, cb);
pa_context_connect(cbData->context, NULL, 0, NULL);
pa_mainloop_run(mainloop, &ret);
pa_context_unref(context);
pa_mainloop_free(mainloop);
return ret;
}
void connect_cb(pa_context *context, void *userdata) {
napi_status status;
napi_value argv[1];
pa_context_state pa_state = pa_context_get_state(context);
if(pa_state == PA_CONTEXT_READY) {
napi_get_undefined(env,
} else if(pa_state == PA_CONTEXT_FAILED) {
} else {
//eventually need to look into reconnecting on disconnections and handling
//connection failures.
}
}
napi_value getSources() {
pa_operation *getSourceOp = NULL;
getSourceOp = pa_context_get_source_info_list(context, handleSourceList, NULL);
if(!getSourceOp) {
} else {
pa_operation_state_t state = pa_operation_get_state(getSourceOp);
switch(state) {
case PA_OPERATION_RUNNING:
break;
case PA_OPERATION_DONE:
break;
case PA_OPERATION_CANCELLED:
}
}
}
};
void querySources(pa_context *c, void *userdata) {
}
void handleSourceList(pa_context *c, const pa_source_info *i, int eol, void *userdata) {
printf("Callback called...\n");
printf("eol is %d\n", eol);
printf(i->description);
printf("\n");
return;
}
}
napi_value init(napi_env env, napi_value exports) {
static pa_mainloop *mainloop = pa_mainloop_new();
static pa_mainloop_api *mainloop_api = pa_mainloop_get_api(mainloop);
static pa_context *context = pa_context_new(mainloop_api, NULL);
CBData *cbData;
cbData.context = context;
cbData.mainloop = mainloop;
napi_status status;
napi_value fn;
status = napi_create_function(env, NULL, NAPI_AUTO_LENGTH, callConnectToPulse, cbData, &fn);
if(status != napi_ok) {
return nullptr;
}
status = napi_set_named_property(env, exports, "connectToPulse", fn);
if(status != napi_ok) {
return nullptr;
}
status = napi_create_function(env, NULL, NAPI_AUTO_LENGTH, getSources, cbData, &fn);
if(status != napi_ok) {
return nullptr;
}
status = napi_set_named_property(env, exports, "getSources", fn);
if(status != napi_ok) {
return nullptr;
}
if(status != napi_ok) {
return nullptr;
}
return exports;
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, init);
napi_value addStatusListener(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value* args;
CBData *cbData;
napi_status status;
status = napi_get_cb_info(env, info, &argc, args, nullptr, &cbData);
assert(status == napi_ok);
if(argc !== 1) {
return nullptr;
}
napi_value emitter = args[0];
status = napi_create_reference(env, args[0], 1, cbData.emitter);
assert(status == napi_ok);
return napi_ok;
}
void emitToJS(napi_env env, napi_value fn, const char* event, napi_value data) {
napi_value emitArgs[2];
napi_status status;
status = napi_create_string_utf8(env, event, NAPI_AUTO_LENGTH, emitArgs);
assert(status == napi_ok);
napi_value global;
status = napi_get_global(env, &global);
assert(status == napi_ok);
napi_value result;
emitArgs[1] = data;
status = napi_call_function(env, global, fn, 2, emitArgs, result);
assert(status == napi_ok);
return;
}