Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

widgets/external_ip: port to javaScripCore #27

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ bin_PROGRAMS = wkline
wkline_SOURCES = \
util/log.c \
src/wkline.c \
src/widgets/widgets.c \
src/widgets/desktops.c

wkline_LDADD = \
Expand Down
84 changes: 59 additions & 25 deletions src/widgets/external_ip.c
Original file line number Diff line number Diff line change
@@ -1,34 +1,68 @@
#include "widgets.h"
#include "util/curl.h"
#include "src/config.h"
#include "external_ip.h"

static int
widget_external_ip_send_update () {
char *external_ip = wkline_curl_request(wkline_widget_external_ip_address);

json_t *json_data_object = json_object();
char *json_payload;

json_object_set_new(json_data_object, "ip", json_string(external_ip));

json_payload = json_dumps(json_data_object, 0);

widget_data_t *widget_data = malloc(sizeof(widget_data_t) + 4096);
widget_data->widget = "external_ip";
widget_data->data = json_payload;
g_idle_add((GSourceFunc)update_widget, widget_data);

free(external_ip);

return 0;
/* externalIp.get_address method callback implementation */
static JSValueRef get_external_ip(JSContextRef context,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef *exception)
{
const char *address;
JSStringRef string;
address = wkline_curl_request(wkline_widget_external_ip_address);
string = JSStringCreateWithUTF8CString(address);
return JSValueMakeString(context, string);
}

void
*widget_external_ip () {
for (;;) {
widget_external_ip_send_update();
/* Class method declarations */
static const JSStaticFunction external_ip_staticfuncs[] =
{
{"get_address", get_external_ip, kJSPropertyAttributeReadOnly},
{NULL, NULL, 0}
};

static const JSClassDefinition notification_def =
{
0, // version
kJSClassAttributeNone, // attributes
"externalIp", // className
NULL, // parentClass
NULL, // staticValues
external_ip_staticfuncs,// staticFunctions
NULL, // initialize
NULL, // finalize
NULL, // hasProperty
NULL, // getProperty
NULL, // setProperty
NULL, // deleteProperty
NULL, // getPropertyNames
NULL, // callAsFunction
NULL, // callAsConstructor
NULL, // hasInstance
NULL // convertToType
};

sleep(600);
}
typedef struct wk_dimensions_t {
int w;
int h;
} wk_dimensions_t;

return 0;
/* Callback - JavaScript window object has been cleared */
void add_class_external_ip(WebKitWebView *web_view,
WebKitWebFrame *frame,
gpointer context,
gpointer window_object,
gpointer user_data)
{
/* Add classes to JavaScriptCore */
JSClassRef classDef = JSClassCreate(&notification_def);
JSObjectRef classObj = JSObjectMake(context, classDef, context);
JSObjectRef globalObj = JSContextGetGlobalObject(context);
JSStringRef str = JSStringCreateWithUTF8CString("externalIp");
JSObjectSetProperty(context, globalObj, str, classObj, kJSPropertyAttributeNone, NULL);
}
8 changes: 6 additions & 2 deletions src/widgets/external_ip.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
#include "util/curl.h"
#include "src/config.h"

void add_class_external_ip(WebKitWebView *web_view,
WebKitWebFrame *frame,
gpointer context,
gpointer window_object,
gpointer user_data);
199 changes: 156 additions & 43 deletions src/widgets/volume.c
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
#include "widgets.h"
#include "volume.h"
#include "src/config.h"

static int
widget_volume_send_update (snd_mixer_elem_t* elem) {
json_t *json_data_object = json_object();
char *json_payload;
long volume_min, volume_max, volume;
int muted;

snd_mixer_selem_get_playback_volume_range(elem, &volume_min, &volume_max);
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &volume);
snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT , &muted);
volume *= muted; /* if muted set volume to 0 */
typedef struct {
JSContextRef context;
JSObjectRef object;
} RefContextObject;

json_object_set_new(json_data_object, "percent", json_real(100 * (volume - volume_min) / (volume_max - volume_min)));

json_payload = json_dumps(json_data_object, 0);
struct volume_data{
snd_mixer_elem_t *elem;
snd_mixer_t *mixer;
RefContextObject *ref;
int running;
};

widget_data_t *widget_data = malloc(sizeof(widget_data_t) + 4096);
widget_data->widget = "volume";
widget_data->data = json_payload;
g_idle_add((GSourceFunc)update_widget, widget_data);
static void call_on_change(RefContextObject *ref) {
/* Get onChange property */
JSStringRef string_onchange;
string_onchange = JSStringCreateWithUTF8CString("onChange");
JSValueRef func = JSObjectGetProperty(ref->context, ref->object, string_onchange, NULL);
JSObjectRef function = JSValueToObject(ref->context, func, NULL);
JSStringRelease(string_onchange);

if (!JSObjectIsFunction(ref->context, function)) {
g_message("JSObject is not function or is not set");
return;
}

return 0;
JSValueRef result = JSObjectCallAsFunction(ref->context, // The execution context to use
function, // The JSObject to call as a function.
ref->object, // The object to use as "this," or NULL to use the global object as "this."
0, // An integer count of the number of arguments in arguments.
NULL, // A JSValue array of arguments to pass to the function. Pass NULL if argumentCount is 0.
NULL); // A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
}

void
*widget_volume () {
snd_mixer_t *mixer;
thread_wait_mixer_change(void *user_data){
struct volume_data *widget = user_data;
snd_mixer_selem_id_t *sid;
struct pollfd *pollfds = NULL;
int nfds = 0, n, err, wait_err;
unsigned short revents;

// open mixer
snd_mixer_open(&mixer, 0);
snd_mixer_attach(mixer, wkline_widget_volume_card);
snd_mixer_selem_register(mixer, NULL, NULL);
snd_mixer_load(mixer);

snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, wkline_widget_volume_selem);
snd_mixer_elem_t* elem = snd_mixer_find_selem(mixer, sid);

widget_volume_send_update(elem);

for (;;) {
while(1){
// Code mostly from the alsamixer main loop
n = 1 + snd_mixer_poll_descriptors_count(mixer);
n = 1 + snd_mixer_poll_descriptors_count(widget->mixer);
if (n != nfds) {
free(pollfds);
nfds = n;
pollfds = calloc(nfds, sizeof *pollfds);
pollfds[0].fd = fileno(stdin);
pollfds[0].events = POLLIN;
}
err = snd_mixer_poll_descriptors(mixer, &pollfds[1], nfds - 1);
err = snd_mixer_poll_descriptors(widget->mixer, &pollfds[1], nfds - 1);
if (err < 0) {
wklog("alsa: can't get poll descriptors: %i", err);
break;
}
wait_err = snd_mixer_wait(mixer, -1);
wait_err = snd_mixer_wait(widget->mixer, -1);
if (wait_err < 0) {
wklog("alsa: wait error");
}
Expand All @@ -79,7 +77,7 @@ void
break;
}
if (n > 0) {
err = snd_mixer_poll_descriptors_revents(mixer, &pollfds[1], nfds - 1, &revents);
err = snd_mixer_poll_descriptors_revents(widget->mixer, &pollfds[1], nfds - 1, &revents);
if (err < 0) {
wklog("alsa: fatal error: %i", err);
break;
Expand All @@ -89,14 +87,129 @@ void
break;
}
else if (revents & POLLIN) {
snd_mixer_handle_events(mixer);
snd_mixer_handle_events(widget->mixer);
}
}
if(widget->running)
call_on_change(widget->ref);
else{
free(pollfds);
snd_mixer_close(widget->mixer);
free(widget);
g_thread_exit(NULL);
}

}
}

/* Class initialize */
static void widget_init_cb(JSContextRef ctx,
JSObjectRef object)
{
struct volume_data *widget;
snd_mixer_selem_id_t *sid;

widget_volume_send_update(elem);
printf("Class Init\n");

widget = calloc(1, sizeof( *widget));
JSObjectSetPrivate(object,widget);

widget->ref = g_new(RefContextObject, 1);
widget->ref->context = ctx;
widget->ref->object = object;

// open mixer
snd_mixer_open(&widget->mixer, 0);
snd_mixer_attach(widget->mixer, wkline_widget_volume_card);
snd_mixer_selem_register(widget->mixer, NULL, NULL);
snd_mixer_load(widget->mixer);

snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, wkline_widget_volume_selem);
widget->elem = snd_mixer_find_selem(widget->mixer, sid);

widget->running = 1;
g_thread_new("widget", (GThreadFunc)thread_wait_mixer_change, widget);
}

/* Class finalize */
static void widget_destroy_cb(JSObjectRef object)
{
struct volume_data *widget = JSObjectGetPrivate(object);
widget->running = 0;
}

static JSValueRef get_volume(JSContextRef context,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef *exception)
{
struct volume_data *widget = JSObjectGetPrivate(thisObject);
long volume_min, volume_max, volume;
int muted;
if (argumentCount == 0) {
snd_mixer_selem_get_playback_volume_range(widget->elem, &volume_min, &volume_max);
snd_mixer_selem_get_playback_volume(widget->elem, SND_MIXER_SCHN_FRONT_LEFT, &volume);
snd_mixer_selem_get_playback_switch(widget->elem, SND_MIXER_SCHN_FRONT_LEFT , &muted);
volume *= muted; /* if muted set volume to 0 */
printf("get_volume: %d\n", 100 * (volume - volume_min) / (volume_max - volume_min));
return JSValueMakeNumber(context, 100 * (volume - volume_min) / (volume_max - volume_min));
}
return JSValueMakeUndefined(context);
}

/* Class constructor */
static JSObjectRef widget_constructor_cb(JSContextRef context,
JSObjectRef constructor,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef *exception)
{
return constructor;
}

/* Class method declarations */
static const JSStaticFunction widget_staticfuncs[] =
{
{"get_volume", get_volume, kJSPropertyAttributeReadOnly},
{NULL, NULL, 0}
};

static const JSClassDefinition notification_def =
{
0, // version
kJSClassAttributeNone, // attributes
"Volume", // className
NULL, // parentClass
NULL, // staticValues
widget_staticfuncs, // staticFunctions
widget_init_cb, // initialize
widget_destroy_cb, // finalize
NULL, // hasProperty
NULL, // getProperty
NULL, // setProperty
NULL, // deleteProperty
NULL, // getPropertyNames
NULL, // callAsFunction
widget_constructor_cb, // callAsConstructor
NULL, // hasInstance
NULL // convertToType
};

free(pollfds);
snd_mixer_close(mixer);
return 0;
/* Callback - JavaScript window object has been cleared */
void add_class_volume(WebKitWebView *web_view,
WebKitWebFrame *frame,
gpointer context,
gpointer window_object,
gpointer user_data)
{
/* Add classes to JavaScriptCore */
JSClassRef classDef = JSClassCreate(&notification_def);
JSObjectRef classObj = JSObjectMake(context, classDef, NULL);
JSObjectRef globalObj = JSContextGetGlobalObject(context);
JSStringRef str = JSStringCreateWithUTF8CString("Volume");
JSObjectSetProperty(context, globalObj, str, classObj, kJSPropertyAttributeNone, NULL);
}
6 changes: 5 additions & 1 deletion src/widgets/volume.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#include <webkit/webkit.h>
#include <alsa/asoundlib.h>

#include "src/config.h"
void add_class_volume(WebKitWebView *web_view,
WebKitWebFrame *frame,
gpointer context,
gpointer window_object,
gpointer user_data);
14 changes: 14 additions & 0 deletions src/widgets/widgets.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "widgets.h"
#include "external_ip.h"
#include "volume.h"

/* Callback - JavaScript window object has been cleared */
void
window_object_cleared_cb(WebKitWebView *web_view,
WebKitWebFrame *frame,
gpointer context,
gpointer window_object,
gpointer user_data){
add_class_volume(web_view,frame,context,window_object,user_data);
add_class_external_ip(web_view,frame,context,window_object,user_data);
}
Loading