We're compiling! Yaaaa<SEG FAULT>
This commit is contained in:
parent
5220d1e7e0
commit
f8bbfbb2d2
5 changed files with 132 additions and 160 deletions
1
_vimrc_local.vim
Normal file
1
_vimrc_local.vim
Normal file
|
@ -0,0 +1 @@
|
||||||
|
let g:ale_cpp_gcc_options = '-I /usr/local/include/node/node_api.h'
|
|
@ -2,7 +2,8 @@
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"target_name": "miccontrol",
|
"target_name": "miccontrol",
|
||||||
"sources": ["main.c"]
|
"sources": ["main.c"],
|
||||||
|
"libraries": ["/usr/lib/x86_64-linux-gnu/libpulse.so"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#keep this dir
|
|
281
main.c
281
main.c
|
@ -1,187 +1,158 @@
|
||||||
/*
|
|
||||||
* main.c
|
|
||||||
* Copyright (C) 2018 jshaver <john@jshaver.net>
|
|
||||||
*
|
|
||||||
* Distributed under terms of the MIT license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <node_api.h>
|
#include <node_api.h>
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "pulse/pulseaudio.h"
|
#include <pulse/pulseaudio.h>
|
||||||
|
|
||||||
struct CBData {
|
struct PACBData {
|
||||||
pa_context *context;
|
pa_context *context;
|
||||||
pa_mainloop *mainloop;
|
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) {
|
struct NapiCBData {
|
||||||
}
|
napi_value *cb;
|
||||||
|
napi_env *env;
|
||||||
|
napi_ref *cbRef;
|
||||||
|
};
|
||||||
|
|
||||||
void handleSourceList(pa_context *c, const pa_source_info *i, int eol, void *userdata) {
|
const char *NAME = "miccontrol";
|
||||||
printf("Callback called...\n");
|
|
||||||
printf("eol is %d\n", eol);
|
|
||||||
printf(i->description);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return;
|
void handleSourceList(struct pa_context *c, const pa_source_info *i, int eol, void *userdata);
|
||||||
}
|
void connectToPulseCB(pa_context *context, void *userdata);
|
||||||
|
napi_value connectToPulse(napi_env env, napi_callback_info info);
|
||||||
|
napi_value init(napi_env env, napi_value exports);
|
||||||
|
|
||||||
|
napi_value connectToPulse(napi_env env, napi_callback_info info) {
|
||||||
|
size_t argc = 1;
|
||||||
|
napi_value args[1];
|
||||||
|
struct PACBData *paCBData;
|
||||||
|
napi_status status;
|
||||||
|
struct NapiCBData *napiCBData = malloc(sizeof(*napiCBData));
|
||||||
|
|
||||||
|
|
||||||
|
status = napi_get_cb_info(env, info, &argc, args, NULL, (void**)&paCBData);
|
||||||
|
assert(status == napi_ok);
|
||||||
|
|
||||||
|
napiCBData->env = &env;
|
||||||
|
|
||||||
|
status = napi_create_reference(env, args[0], 1, napiCBData->cbRef);
|
||||||
|
assert(status == napi_ok);
|
||||||
|
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
pa_context_set_state_callback(paCBData->context, connectToPulseCB, napiCBData);
|
||||||
|
pa_context_connect(paCBData->context, NULL, 0, NULL);
|
||||||
|
|
||||||
|
pa_mainloop_run(paCBData->mainloop, &ret);
|
||||||
|
|
||||||
|
pa_context_unref(paCBData->context);
|
||||||
|
pa_mainloop_free(paCBData->mainloop);
|
||||||
|
//free(napiCBData);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void connectToPulseCB(pa_context *context, void *userdata) {
|
||||||
|
napi_status status;
|
||||||
|
napi_value argv[1];
|
||||||
|
struct NapiCBData *napiCBData = (struct NapiCBData*)userdata;
|
||||||
|
pa_context_state_t pa_state = pa_context_get_state(context);
|
||||||
|
napi_value errorString;
|
||||||
|
|
||||||
|
if(pa_state == PA_CONTEXT_READY) {
|
||||||
|
status = napi_get_undefined(*(napiCBData->env), &argv[0]);
|
||||||
|
} else if(pa_state == PA_CONTEXT_FAILED) {
|
||||||
|
|
||||||
|
status = napi_create_string_utf8(
|
||||||
|
*(napiCBData->env),
|
||||||
|
"Error connecting to Pulse Audio",
|
||||||
|
NAPI_AUTO_LENGTH,
|
||||||
|
&errorString);
|
||||||
|
assert(status == napi_ok);
|
||||||
|
status = napi_create_error(*(napiCBData->env), NULL, errorString, &argv[0]);
|
||||||
|
assert(status == napi_ok);
|
||||||
|
} else {
|
||||||
|
//eventually need to look into reconnecting on disconnections and handling
|
||||||
|
//connection failures.
|
||||||
|
}
|
||||||
|
napi_value global;
|
||||||
|
status = napi_get_global(*(napiCBData->env), &global);
|
||||||
|
assert(status == napi_ok);
|
||||||
|
napi_value result;
|
||||||
|
napi_value cb;
|
||||||
|
|
||||||
|
status = napi_get_reference_value(*(napiCBData->env), *(napiCBData->cbRef), &cb);
|
||||||
|
assert(status == napi_ok);
|
||||||
|
status = napi_call_function(*(napiCBData->env), global, cb, 1, argv, &result);
|
||||||
|
assert(status == napi_ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
//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 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) {
|
napi_value init(napi_env env, napi_value exports) {
|
||||||
static pa_mainloop *mainloop = pa_mainloop_new();
|
pa_mainloop *mainloop = pa_mainloop_new();
|
||||||
static pa_mainloop_api *mainloop_api = pa_mainloop_get_api(mainloop);
|
pa_mainloop_api *mainloop_api = pa_mainloop_get_api(mainloop);
|
||||||
static pa_context *context = pa_context_new(mainloop_api, NULL);
|
pa_context *context = pa_context_new(mainloop_api, NULL);
|
||||||
|
|
||||||
CBData *cbData;
|
struct PACBData *paCBData = malloc(sizeof(*paCBData));
|
||||||
|
|
||||||
cbData.context = context;
|
paCBData->context = context;
|
||||||
cbData.mainloop = mainloop;
|
paCBData->mainloop = mainloop;
|
||||||
|
|
||||||
napi_status status;
|
napi_status status;
|
||||||
napi_value fn;
|
napi_value fn;
|
||||||
|
|
||||||
status = napi_create_function(env, NULL, NAPI_AUTO_LENGTH, callConnectToPulse, cbData, &fn);
|
status = napi_create_function(
|
||||||
|
env,
|
||||||
|
"connectToPulse",
|
||||||
|
NAPI_AUTO_LENGTH,
|
||||||
|
connectToPulse,
|
||||||
|
paCBData,
|
||||||
|
&fn);
|
||||||
if(status != napi_ok) {
|
if(status != napi_ok) {
|
||||||
return nullptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = napi_set_named_property(env, exports, "connectToPulse", fn);
|
status = napi_set_named_property(env, exports, "connectToPulse", fn);
|
||||||
if(status != napi_ok) {
|
if(status != napi_ok) {
|
||||||
return nullptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = napi_create_function(env, NULL, NAPI_AUTO_LENGTH, getSources, cbData, &fn);
|
// status = napi_create_function(env, NULL, NAPI_AUTO_LENGTH, getSources, paCBData, &fn);
|
||||||
|
//
|
||||||
|
// if(status != napi_ok) {
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// status = napi_set_named_property(env, exports, "getSources", fn);
|
||||||
|
//
|
||||||
|
// if(status != napi_ok) {
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
|
||||||
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;
|
return exports;
|
||||||
}
|
}
|
||||||
|
|
||||||
NAPI_MODULE(NODE_GYP_MODULE_NAME, init);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
4
main.js
4
main.js
|
@ -1,4 +1,4 @@
|
||||||
const nativeCode = require('bindings')(miccontrol.node);=
|
const nativeCode = require('bindings')('miccontrol.node');
|
||||||
let connectionStarted = false;
|
let connectionStarted = false;
|
||||||
let connected = false;
|
let connected = false;
|
||||||
let queuedRequests = [];
|
let queuedRequests = [];
|
||||||
|
@ -48,7 +48,7 @@ module.exports = () => {
|
||||||
return aAddon.isSourceMuted(id);
|
return aAddon.isSourceMuted(id);
|
||||||
},
|
},
|
||||||
toggleMute: async () => {
|
toggleMute: async () => {
|
||||||
if(await aAddon.isSourceMuted)(id) {
|
if(await aAddon.isSourceMuted(id)) {
|
||||||
return aAddon.unmuteSource(id);
|
return aAddon.unmuteSource(id);
|
||||||
}
|
}
|
||||||
return aAddon.muteSource(id);
|
return aAddon.muteSource(id);
|
||||||
|
|
Loading…
Reference in a new issue