/* * main.c * Copyright (C) 2018 jshaver * * Distributed under terms of the MIT license. */ #include #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; }