improvements

This commit is contained in:
ch1p 2014-11-19 11:33:04 +03:00
parent bdc7ff9d08
commit 2c2744db26
7 changed files with 91 additions and 82 deletions

View File

@ -1,13 +1,13 @@
LIBS = gtk+-2.0 glib-2.0 cairo pango gdk-pixbuf-2.0 atk libwebsockets x11 LIBS=gtk+-2.0 glib-2.0 cairo pango gdk-pixbuf-2.0 atk libwebsockets x11
CC = gcc CC=gcc
CCFLAGS = -Wall -std=c99 -pthread `pkg-config --cflags --libs ${LIBS}` CCFLAGS=-Wall -std=c99 -pthread `pkg-config --cflags ${LIBS}`
LDFLAGS = -lm LDFLAGS=-lm -pthread `pkg-config --libs ${LIBS}`
BINARIES = vkpc BINARIES=vkpc
all : vkpc all : vkpc
vkpc : server.o grab.o vector.o main.o vkpc : server.o grab.o vector.o main.o
${CC} ${CCFLAGS} server.o grab.o vector.o main.o ${LDFLAGS} -o vkpc ${CC} ${LDFLAGS} server.o grab.o vector.o main.o -o vkpc
server.o : server.c server.o : server.c
${CC} ${CCFLAGS} -c server.c ${CC} ${CCFLAGS} -c server.c

View File

@ -2,7 +2,10 @@
#define GRAB_H__ #define GRAB_H__
enum HotkeyEvent { enum HotkeyEvent {
HK_PREV, HK_NEXT, HK_PAUSE, HK_PLAY, HK_PREV,
HK_NEXT,
HK_PAUSE,
HK_PLAY,
HOTKEYS_COUNT HOTKEYS_COUNT
}; };
struct Hotkey { struct Hotkey {

View File

@ -3,11 +3,13 @@
#define APP_NAME "VK Player Controller" #define APP_NAME "VK Player Controller"
#define APP_ABOUT "Use media buttons to switch between tracks." #define APP_ABOUT "Use media buttons to switch between tracks."
#define APP_VERSION "0.1" #define APP_VERSION "0.2"
#define APP_AUTHOR "Eugene Z. <ch1p@ch1p.com>" #define APP_AUTHOR "Eugene Z <me@ch1p.com>"
#define APP_URL "http://ch1p.com/vkpc/" #define APP_URL "https://ch1p.com/vkpc/?linux"
#define SERVER_PORT 52178 #define SERVER_PORT 52178
#define SERVER_HOST "localhost" #define SERVER_HOST "localhost"
// #define DEBUG 1
#endif #endif

View File

@ -11,12 +11,9 @@
static GtkStatusIcon *tray_icon; static GtkStatusIcon *tray_icon;
static GtkWidget *menu; static GtkWidget *menu;
enum server_last_cmd_enum server_last_cmd = NONE;
static pthread_t grab_thread; static pthread_t grab_thread;
static pthread_t server_thread; static pthread_t server_thread;
pthread_mutex_t server_last_cmd_mutex;
void tray_icon_on_click(GtkStatusIcon *status_icon, gpointer user_data) { void tray_icon_on_click(GtkStatusIcon *status_icon, gpointer user_data) {
// left-click // left-click
} }
@ -47,7 +44,6 @@ void menu_about(GtkWidget *widget, gpointer data) {
} }
void menu_quit(GtkWidget *widget, gpointer data) { void menu_quit(GtkWidget *widget, gpointer data) {
// quit app
exit(0); exit(0);
} }
@ -84,28 +80,30 @@ void create_menu() {
} }
void handle_hotkeys(enum HotkeyEvent e) { void handle_hotkeys(enum HotkeyEvent e) {
pthread_mutex_lock(&server_last_cmd_mutex); printf("[handle_hotkeys] e: %d\n", e);
pthread_mutex_lock(&server_command_mutex);
switch (e) { switch (e) {
case HK_PLAY: case HK_PLAY:
server_last_cmd = PLAY; server_command = PLAY;
break; break;
case HK_PAUSE: case HK_PAUSE:
server_last_cmd = PAUSE; server_command = PAUSE;
break; break;
case HK_NEXT: case HK_NEXT:
server_last_cmd = NEXT; server_command = NEXT;
break; break;
case HK_PREV: case HK_PREV:
server_last_cmd = PREV; server_command = PREV;
break; break;
default: default:
break; break;
} }
pthread_mutex_unlock(&server_last_cmd_mutex); pthread_mutex_unlock(&server_command_mutex);
} }
void start_grab() { void start_grab() {
@ -125,7 +123,7 @@ void start_server() {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
pthread_mutex_init(&server_last_cmd_mutex, NULL); pthread_mutex_init(&server_command_mutex, NULL);
start_grab(); start_grab();
start_server(); start_server();

View File

@ -1,7 +1,3 @@
/**
* TODO: logging level
*/
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -10,50 +6,53 @@
#include "server.h" #include "server.h"
#include "vector.h" #include "vector.h"
#include "info.h"
#define SERVER_PORT 52178 enum {
#define SERVER_HOST "localhost" LWS_LOG_ERR = 1,
LWS_LOG_WARN = 2,
LWS_LOG_NOTICE = 4,
LWS_LOG_INFO = 8,
LWS_LOG_DEBUG = 16,
LWS_LOG_PARSER = 32,
LWS_LOG_HEADER = 64,
LWS_LOG_EXTENSION = 128,
LWS_LOG_CLIENT = 256,
LWS_LOG_LATENCY = 512
};
static struct libwebsocket_context *context; static struct libwebsocket_context *context;
static char *server_last_cmd_values[] = { static const char *server_commands[] = {
"none", "play", "pause", "next", "prev" "none", "play", "pause", "next", "prev"
}; };
struct per_session_data { server_command_t server_command;
bool established; pthread_mutex_t server_command_mutex;
char *next_command;
};
struct session {
struct per_session_data *pss;
struct libwebsocket *wsi;
};
vector *sessions; vector *sessions;
static void add_session(struct libwebsocket *wsi, struct per_session_data *pss) { static void add_session(server_session_t *pss) {
struct session *s = malloc(sizeof(struct session)); vector_add(sessions, pss);
s->wsi = wsi;
s->pss = pss;
vector_add(sessions, s);
} }
static void delete_session(struct libwebsocket *wsi) { static void delete_session(struct libwebsocket *wsi) {
for (int i = 0; i < vector_count(sessions); i++) { int count = vector_count(sessions);
struct session *s = vector_get(sessions, i); for (int i = 0; i < count; i++) {
server_session_t *s = vector_get(sessions, i);
if (s != NULL && s->wsi == wsi) { if (s != NULL && s->wsi == wsi) {
printf("(delete_session) found, i=%d\n", i);
free(s);
vector_delete(sessions, i); vector_delete(sessions, i);
break; break;
} }
} }
} }
static void send_command_to_all(char *command) { static void send_command(server_command_t command) {
printf("Got command: %s\n", command); int count = vector_count(sessions);
for (int i = 0; i < vector_count(sessions); i++) { for (int i = 0; i < count; i++) {
struct session *s = (struct session *)vector_get(sessions, i); server_session_t *s = vector_get(sessions, i);
s->pss->next_command = command; if (s != NULL) {
libwebsocket_callback_on_writable(context, s->wsi); s->next_command = command;
libwebsocket_callback_on_writable(context, s->wsi);
}
} }
} }
@ -64,13 +63,13 @@ static int callback_http(struct libwebsocket_context *this,
void *in, void *in,
size_t len) size_t len)
{ {
static const char *response = "vkpc, world!";
switch (reason) { switch (reason) {
case LWS_CALLBACK_HTTP: ; case LWS_CALLBACK_HTTP: ;
libwebsocket_callback_on_writable(context, wsi); libwebsocket_callback_on_writable(context, wsi);
break; break;
case LWS_CALLBACK_HTTP_WRITEABLE: ; case LWS_CALLBACK_HTTP_WRITEABLE: ;
char *response = "vkpc, world!";
libwebsocket_write(wsi, (unsigned char *)response, strlen(response), LWS_WRITE_HTTP); libwebsocket_write(wsi, (unsigned char *)response, strlen(response), LWS_WRITE_HTTP);
return -1; return -1;
@ -87,26 +86,28 @@ static int callback_signaling(struct libwebsocket_context *this,
void *in, void *in,
size_t len) size_t len)
{ {
struct per_session_data *pss = (struct per_session_data *)user; server_session_t *pss = (server_session_t *)user;
switch (reason) { switch (reason) {
case LWS_CALLBACK_ESTABLISHED: case LWS_CALLBACK_ESTABLISHED:
lwsl_info("Connection established"); lwsl_info("Connection established");
pss->established = true; pss->next_command = NONE;
pss->next_command = NULL; pss->wsi = wsi;
add_session(wsi, pss); add_session(pss);
libwebsocket_callback_on_writable(context, wsi); libwebsocket_callback_on_writable(context, wsi);
break; break;
case LWS_CALLBACK_SERVER_WRITEABLE: case LWS_CALLBACK_SERVER_WRITEABLE:
if (pss->next_command != NULL) { if (pss->next_command != NONE) {
int length = strlen(pss->next_command); const char *command = server_commands[pss->next_command];
int length = strlen(command);
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + length + LWS_SEND_BUFFER_POST_PADDING]; unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + length + LWS_SEND_BUFFER_POST_PADDING];
unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING]; unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
strcpy((char *)p, pss->next_command); strcpy((char *)p, command);
int m = libwebsocket_write(wsi, p, length, LWS_WRITE_TEXT); int m = libwebsocket_write(wsi, p, length, LWS_WRITE_TEXT);
if (m < length) { if (m < length) {
@ -114,7 +115,7 @@ static int callback_signaling(struct libwebsocket_context *this,
return -1; return -1;
} }
pss->next_command = NULL; pss->next_command = NONE;
} }
break; break;
@ -135,13 +136,13 @@ static int callback_signaling(struct libwebsocket_context *this,
return 0; return 0;
} }
static struct libwebsocket_protocols protocols[] = {
{ "http-only", callback_http, 0, 0 },
{ "signaling-protocol", callback_signaling, sizeof(struct per_session_data), 0 },
{ NULL, NULL, 0 }
};
void server_init() { void server_init() {
static struct libwebsocket_protocols protocols[] = {
{ "http-only", callback_http, 0, 0 },
{ "signaling-protocol", callback_signaling, sizeof(server_session_t), 0 },
{ NULL, NULL, 0 }
};
sessions = vector_create(); sessions = vector_create();
struct lws_context_creation_info info; struct lws_context_creation_info info;
@ -157,22 +158,25 @@ void server_init() {
info.uid = -1; info.uid = -1;
info.options = 0; info.options = 0;
#ifdef DEBUG
lws_set_log_level(LWS_LOG_ERR | LWS_LOG_WARN | LWS_LOG_NOTICE | LWS_LOG_INFO | LWS_LOG_DEBUG | LWS_LOG_HEADER, NULL);
#else
lws_set_log_level(0, NULL);
#endif
context = libwebsocket_create_context(&info); context = libwebsocket_create_context(&info);
if (context == NULL) { if (context == NULL) {
fprintf(stderr, "libwebsocket init failed\n"); fprintf(stderr, "libwebsocket init failed\n");
return; return;
} }
enum server_last_cmd_enum last_cmd = NONE;
while (1) { while (1) {
pthread_mutex_lock(&server_last_cmd_mutex); pthread_mutex_lock(&server_command_mutex);
last_cmd = server_last_cmd; if (server_command != NONE) {
server_last_cmd = NONE; send_command(server_command);
pthread_mutex_unlock(&server_last_cmd_mutex); server_command = NONE;
if (last_cmd != NONE) {
send_command_to_all(server_last_cmd_values[last_cmd]);
} }
pthread_mutex_unlock(&server_command_mutex);
libwebsocket_service(context, 50); libwebsocket_service(context, 50);
} }

View File

@ -3,11 +3,17 @@
#ifndef SERVER_H__ #ifndef SERVER_H__
#define SERVER_H__ #define SERVER_H__
enum server_last_cmd_enum { typedef enum {
NONE = 0, PLAY, PAUSE, NEXT, PREV NONE = 0, PLAY, PAUSE, NEXT, PREV
}; } server_command_t;
extern enum server_last_cmd_enum server_last_cmd;
extern pthread_mutex_t server_last_cmd_mutex; typedef struct {
server_command_t next_command;
struct libwebsocket *wsi;
} server_session_t;
extern server_command_t server_command;
extern pthread_mutex_t server_command_mutex;
void server_init(); void server_init();

View File

@ -1,7 +1,3 @@
/**
* Based on https://gist.github.com/EmilHernvall/953968
*/
#ifndef VECTOR_H__ #ifndef VECTOR_H__
#define VECTOR_H__ #define VECTOR_H__