improvements
This commit is contained in:
parent
bdc7ff9d08
commit
2c2744db26
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
100
desktop/server.c
100
desktop/server.c
@ -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,52 +6,55 @@
|
|||||||
|
|
||||||
#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) {
|
||||||
|
s->next_command = command;
|
||||||
libwebsocket_callback_on_writable(context, s->wsi);
|
libwebsocket_callback_on_writable(context, s->wsi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int callback_http(struct libwebsocket_context *this,
|
static int callback_http(struct libwebsocket_context *this,
|
||||||
struct libwebsocket *wsi,
|
struct libwebsocket *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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void server_init() {
|
||||||
static struct libwebsocket_protocols protocols[] = {
|
static struct libwebsocket_protocols protocols[] = {
|
||||||
{ "http-only", callback_http, 0, 0 },
|
{ "http-only", callback_http, 0, 0 },
|
||||||
{ "signaling-protocol", callback_signaling, sizeof(struct per_session_data), 0 },
|
{ "signaling-protocol", callback_signaling, sizeof(server_session_t), 0 },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void server_init() {
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
/**
|
|
||||||
* Based on https://gist.github.com/EmilHernvall/953968
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VECTOR_H__
|
#ifndef VECTOR_H__
|
||||||
#define VECTOR_H__
|
#define VECTOR_H__
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user