From 49567866c314ea7267fc8cec961f80a60840bdc6 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 13 Oct 2015 02:17:00 +0200 Subject: renamed files to prepare merge of code dirs --- server/Makefile | 10 +-- server/dolmetschctl.c | 4 +- server/midi.c | 237 -------------------------------------------------- server/midi.h | 55 ------------ server/midi_server.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++ server/midi_server.h | 55 ++++++++++++ server/osc.c | 164 ---------------------------------- server/osc.h | 50 ----------- server/osc_server.c | 164 ++++++++++++++++++++++++++++++++++ server/osc_server.h | 50 +++++++++++ 10 files changed, 513 insertions(+), 513 deletions(-) delete mode 100644 server/midi.c delete mode 100644 server/midi.h create mode 100644 server/midi_server.c create mode 100644 server/midi_server.h delete mode 100644 server/osc.c delete mode 100644 server/osc.h create mode 100644 server/osc_server.c create mode 100644 server/osc_server.h (limited to 'server') diff --git a/server/Makefile b/server/Makefile index ff1bd06..2fb8c2d 100644 --- a/server/Makefile +++ b/server/Makefile @@ -26,11 +26,11 @@ endif EXECUTABLE := dolmetschctl -C_OBJS := osc.o \ - midi.o \ - slist.o \ +C_OBJS := slist.o \ + osc_server.o \ + midi_server.o \ mixer.o \ - dolmetschctl.o + dolmetschctl.o C_SRCS := $(C_OBJS:%.o=%.c) @@ -91,4 +91,4 @@ remove-bin: remove-etc: purge: remove - rm -rf $(DESTDIR)$(ETCDIR)/$(EXECUTABLE)/ \ No newline at end of file + rm -rf $(DESTDIR)$(ETCDIR)/$(EXECUTABLE)/ diff --git a/server/dolmetschctl.c b/server/dolmetschctl.c index 5bb9965..3b20cb6 100644 --- a/server/dolmetschctl.c +++ b/server/dolmetschctl.c @@ -31,8 +31,8 @@ #include #include "mixer.h" -#include "midi.h" -#include "osc.h" +#include "midi_server.h" +#include "osc_server.h" void print_version() diff --git a/server/midi.c b/server/midi.c deleted file mode 100644 index 6ef5775..0000000 --- a/server/midi.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * dolmetschctl - * - * - * Copyright (C) 2015 Christian Pointner - * - * This file is part of dolmetschctl. - * - * dolmetschctl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * dolmetschctl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with dolmetschctl. If not, see . - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "midi.h" - -#define NOTE_EN 0x00 -#define NOTE_DE 0x01 -u_int8_t done_data_en[] = { 0xB0, NOTE_EN, 0x01, 0xB0, NOTE_DE, 0x00 }; -u_int8_t done_data_de[] = { 0xB0, NOTE_EN, 0x00, 0xB0, NOTE_DE, 0x01 }; - -int midi_init(midi_t* m, const char* device) -{ - assert(m != NULL); - - m->input_ = NULL; - m->output_ = NULL; - memset(m->buf_, 0, sizeof(m->buf_)); - m->read_idx_ = 0; - - slist_init(&(m->done_data_), free); - - if(device) { - int ret = snd_rawmidi_open(&(m->input_), &(m->output_), device, SND_RAWMIDI_NONBLOCK); - if(ret < 0) { - error(0, 0, "MIDI: cannot open port '%s': %s", device, snd_strerror(ret)); - return ret; - } - } - - return 0; -} - -int midi_get_poll_fd_count(midi_t* m) -{ - assert(m); - - if(!m->input_ || !m->output_) - return 0; - - m->in_pfds_cnt_ = snd_rawmidi_poll_descriptors_count(m->input_); - assert(m->in_pfds_cnt_ > 0); - m->out_pfds_cnt_ = snd_rawmidi_poll_descriptors_count(m->output_); - assert(m->out_pfds_cnt_ > 0); - - return (m->in_pfds_cnt_ + m->out_pfds_cnt_); -} - -int midi_get_poll_fds(midi_t* m, struct pollfd *pfds, int npfds) -{ - assert(m); - - if(!m->input_ || !m->output_) - return 0; - - snd_rawmidi_poll_descriptors(m->input_, pfds, m->in_pfds_cnt_); - snd_rawmidi_poll_descriptors(m->output_, &(pfds[m->in_pfds_cnt_]), npfds - m->in_pfds_cnt_); - - int pending_data = 0; - if(m->done_data_.first_) { - midi_done_data_t* d = (midi_done_data_t*)(m->done_data_.first_->data_); - if(d->active_) - pending_data = 1; - } - if(!pending_data) { - int i; - for(i = m->in_pfds_cnt_; i < npfds; ++i) - pfds[i].events = 0; - } - return (m->in_pfds_cnt_ + m->out_pfds_cnt_); -} - -void midi_lang_switch_done(void* data) -{ - assert(data); - midi_done_data_t* d = data; - d->active_ = 1; -} - -static int midi_enqueue_lang_switch(midi_t* m, mixer_t* x, const char* lang, const u_int8_t* buf, int len) -{ - midi_done_data_t* done_data = malloc(sizeof(midi_done_data_t)); - assert(done_data); - done_data->self_ = m; - done_data->active_ = 0; - done_data->buf_ = buf; - done_data->len_ = len; - done_data->write_idx_ = 0; - assert(slist_add(&(m->done_data_), done_data)); - - return mixer_switch_lang(x, lang, &midi_lang_switch_done, done_data); -} - -static int midi_handle_note_on(midi_t* m, mixer_t* x) -{ - int ret = 0; - switch(m->buf_[1]) { - case NOTE_EN: ret = midi_enqueue_lang_switch(m, x, "en", done_data_en, sizeof(done_data_en)); break; - case NOTE_DE: ret = midi_enqueue_lang_switch(m, x, "de", done_data_de, sizeof(done_data_de)); break; - default: printf("ignoring unknown note\n"); break; - } - return ret; -} - -static int midi_handle_note_off(midi_t* m, mixer_t* x) -{ - return 0; -} - -static int midi_handle_message(midi_t* m, mixer_t* x) -{ - /* int i; */ - /* printf("MIDI: "); */ - /* for (i = 0; i < sizeof(m->buf_); ++i) */ - /* printf("%02X%c", m->buf_[i], (i >= (sizeof(m->buf_)-1)) ? '\n' : ' '); */ - - int ret = 0; - switch(m->buf_[0]) { - case 0x90: ret = midi_handle_note_on(m, x); break; - case 0x80: ret = midi_handle_note_off(m, x); break; - default: printf("ignoring unknown midi command\n"); break; - } - - return ret; -} - -static int midi_handle_in_revents(midi_t* m, struct pollfd *pfds, int npfds, mixer_t* x) -{ - int err; - unsigned short revents; - if((err = snd_rawmidi_poll_descriptors_revents(m->input_, pfds, npfds, &revents)) < 0) { - error(0, 0, "MIDI: cannot get poll events: %s", snd_strerror(errno)); - return -1; - } - if(pfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { - error(0, 0, "MIDI: got POLLERR, POLLHUP or POLLNVAL"); - return -1; - } - if(!(revents & POLLIN)) - return 0; - - int ret = snd_rawmidi_read(m->input_, &(m->buf_[m->read_idx_]), sizeof(m->buf_) - m->read_idx_); - if(ret == -EAGAIN) - return 0; - if(ret < 0) { - error(0, 0, "MIDI: cannot read from midi port: %s", snd_strerror(ret)); - return -1; - } - m->read_idx_ += ret; - if(m->read_idx_ >= sizeof(m->buf_)) { - ret = midi_handle_message(m, x); - memset(m->buf_, 0, sizeof(m->buf_)); - m->read_idx_ = 0; - return ret; - } - - return ret; -} - -static int midi_handle_out_revents(midi_t* m, struct pollfd *pfds, int npfds) -{ - int err; - unsigned short revents; - if((err = snd_rawmidi_poll_descriptors_revents(m->output_, pfds, npfds, &revents)) < 0) { - error(0, 0, "MIDI: cannot get poll events: %s", snd_strerror(errno)); - return -1; - } - if(pfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { - error(0, 0, "MIDI: got POLLERR, POLLHUP or POLLNVAL"); - return -1; - } - if(!(revents & POLLOUT)) - return 0; - - assert(m->done_data_.first_); - midi_done_data_t* done_data = (midi_done_data_t*)(m->done_data_.first_->data_); - assert(done_data); - assert(done_data->active_); - assert(done_data->buf_); - - int ret = snd_rawmidi_write(m->output_, &(done_data->buf_[done_data->write_idx_]), done_data->len_ - done_data->write_idx_); - if(ret == -EAGAIN) - return 0; - if(ret < 0) { - error(0, 0, "MIDI: cannot write to port: %s", snd_strerror(ret)); - return -1; - } - done_data->write_idx_ += ret; - if(done_data->write_idx_ >= done_data->len_) { - if((err = snd_rawmidi_drain(m->output_)) < 0) { - error(0, 0, "MIDI: cannot drain output: %s", snd_strerror(err)); - return -1; - } - slist_remove(&(m->done_data_), done_data); - } - - return 0; -} - -int midi_handle_revents(midi_t* m, struct pollfd *pfds, int npfds, mixer_t* x) -{ - assert(m); - - if(!m->input_ || !m->output_) - return 0; - - int ret = midi_handle_in_revents(m, pfds, m->in_pfds_cnt_, x); - if(ret) - return ret; - - return midi_handle_out_revents(m, &(pfds[m->in_pfds_cnt_]), m->out_pfds_cnt_); -} diff --git a/server/midi.h b/server/midi.h deleted file mode 100644 index 537c356..0000000 --- a/server/midi.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * dolmetschctl - * - * - * Copyright (C) 2015 Christian Pointner - * - * This file is part of dolmetschctl. - * - * dolmetschctl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * dolmetschctl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with dolmetschctl. If not, see . - */ - -#ifndef DOLMETSCHCTL_midi_h_INCLUDED -#define DOLMETSCHCTL_midi_h_INCLUDED - -#include -#include - -#include "slist.h" -#include "mixer.h" - -typedef struct { - snd_rawmidi_t* input_; - int in_pfds_cnt_; - snd_rawmidi_t* output_; - int out_pfds_cnt_; - u_int8_t buf_[3]; - int read_idx_; - slist_t done_data_; -} midi_t; - -typedef struct { - midi_t* self_; - int active_; - const u_int8_t* buf_; - int len_; - int write_idx_; -} midi_done_data_t; - -int midi_init(midi_t* m, const char* device); -int midi_get_poll_fd_count(midi_t* m); -int midi_get_poll_fds(midi_t* m, struct pollfd *pfds, int npfds); -int midi_handle_revents(midi_t* m, struct pollfd *pfds, int npfds, mixer_t* x); - -#endif diff --git a/server/midi_server.c b/server/midi_server.c new file mode 100644 index 0000000..dbbf222 --- /dev/null +++ b/server/midi_server.c @@ -0,0 +1,237 @@ +/* + * dolmetschctl + * + * + * Copyright (C) 2015 Christian Pointner + * + * This file is part of dolmetschctl. + * + * dolmetschctl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * dolmetschctl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dolmetschctl. If not, see . + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "midi_server.h" + +#define NOTE_EN 0x00 +#define NOTE_DE 0x01 +u_int8_t done_data_en[] = { 0xB0, NOTE_EN, 0x01, 0xB0, NOTE_DE, 0x00 }; +u_int8_t done_data_de[] = { 0xB0, NOTE_EN, 0x00, 0xB0, NOTE_DE, 0x01 }; + +int midi_init(midi_t* m, const char* device) +{ + assert(m != NULL); + + m->input_ = NULL; + m->output_ = NULL; + memset(m->buf_, 0, sizeof(m->buf_)); + m->read_idx_ = 0; + + slist_init(&(m->done_data_), free); + + if(device) { + int ret = snd_rawmidi_open(&(m->input_), &(m->output_), device, SND_RAWMIDI_NONBLOCK); + if(ret < 0) { + error(0, 0, "MIDI: cannot open port '%s': %s", device, snd_strerror(ret)); + return ret; + } + } + + return 0; +} + +int midi_get_poll_fd_count(midi_t* m) +{ + assert(m); + + if(!m->input_ || !m->output_) + return 0; + + m->in_pfds_cnt_ = snd_rawmidi_poll_descriptors_count(m->input_); + assert(m->in_pfds_cnt_ > 0); + m->out_pfds_cnt_ = snd_rawmidi_poll_descriptors_count(m->output_); + assert(m->out_pfds_cnt_ > 0); + + return (m->in_pfds_cnt_ + m->out_pfds_cnt_); +} + +int midi_get_poll_fds(midi_t* m, struct pollfd *pfds, int npfds) +{ + assert(m); + + if(!m->input_ || !m->output_) + return 0; + + snd_rawmidi_poll_descriptors(m->input_, pfds, m->in_pfds_cnt_); + snd_rawmidi_poll_descriptors(m->output_, &(pfds[m->in_pfds_cnt_]), npfds - m->in_pfds_cnt_); + + int pending_data = 0; + if(m->done_data_.first_) { + midi_done_data_t* d = (midi_done_data_t*)(m->done_data_.first_->data_); + if(d->active_) + pending_data = 1; + } + if(!pending_data) { + int i; + for(i = m->in_pfds_cnt_; i < npfds; ++i) + pfds[i].events = 0; + } + return (m->in_pfds_cnt_ + m->out_pfds_cnt_); +} + +void midi_lang_switch_done(void* data) +{ + assert(data); + midi_done_data_t* d = data; + d->active_ = 1; +} + +static int midi_enqueue_lang_switch(midi_t* m, mixer_t* x, const char* lang, const u_int8_t* buf, int len) +{ + midi_done_data_t* done_data = malloc(sizeof(midi_done_data_t)); + assert(done_data); + done_data->self_ = m; + done_data->active_ = 0; + done_data->buf_ = buf; + done_data->len_ = len; + done_data->write_idx_ = 0; + assert(slist_add(&(m->done_data_), done_data)); + + return mixer_switch_lang(x, lang, &midi_lang_switch_done, done_data); +} + +static int midi_handle_note_on(midi_t* m, mixer_t* x) +{ + int ret = 0; + switch(m->buf_[1]) { + case NOTE_EN: ret = midi_enqueue_lang_switch(m, x, "en", done_data_en, sizeof(done_data_en)); break; + case NOTE_DE: ret = midi_enqueue_lang_switch(m, x, "de", done_data_de, sizeof(done_data_de)); break; + default: printf("ignoring unknown note\n"); break; + } + return ret; +} + +static int midi_handle_note_off(midi_t* m, mixer_t* x) +{ + return 0; +} + +static int midi_handle_message(midi_t* m, mixer_t* x) +{ + /* int i; */ + /* printf("MIDI: "); */ + /* for (i = 0; i < sizeof(m->buf_); ++i) */ + /* printf("%02X%c", m->buf_[i], (i >= (sizeof(m->buf_)-1)) ? '\n' : ' '); */ + + int ret = 0; + switch(m->buf_[0]) { + case 0x90: ret = midi_handle_note_on(m, x); break; + case 0x80: ret = midi_handle_note_off(m, x); break; + default: printf("ignoring unknown midi command\n"); break; + } + + return ret; +} + +static int midi_handle_in_revents(midi_t* m, struct pollfd *pfds, int npfds, mixer_t* x) +{ + int err; + unsigned short revents; + if((err = snd_rawmidi_poll_descriptors_revents(m->input_, pfds, npfds, &revents)) < 0) { + error(0, 0, "MIDI: cannot get poll events: %s", snd_strerror(errno)); + return -1; + } + if(pfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { + error(0, 0, "MIDI: got POLLERR, POLLHUP or POLLNVAL"); + return -1; + } + if(!(revents & POLLIN)) + return 0; + + int ret = snd_rawmidi_read(m->input_, &(m->buf_[m->read_idx_]), sizeof(m->buf_) - m->read_idx_); + if(ret == -EAGAIN) + return 0; + if(ret < 0) { + error(0, 0, "MIDI: cannot read from midi port: %s", snd_strerror(ret)); + return -1; + } + m->read_idx_ += ret; + if(m->read_idx_ >= sizeof(m->buf_)) { + ret = midi_handle_message(m, x); + memset(m->buf_, 0, sizeof(m->buf_)); + m->read_idx_ = 0; + return ret; + } + + return ret; +} + +static int midi_handle_out_revents(midi_t* m, struct pollfd *pfds, int npfds) +{ + int err; + unsigned short revents; + if((err = snd_rawmidi_poll_descriptors_revents(m->output_, pfds, npfds, &revents)) < 0) { + error(0, 0, "MIDI: cannot get poll events: %s", snd_strerror(errno)); + return -1; + } + if(pfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { + error(0, 0, "MIDI: got POLLERR, POLLHUP or POLLNVAL"); + return -1; + } + if(!(revents & POLLOUT)) + return 0; + + assert(m->done_data_.first_); + midi_done_data_t* done_data = (midi_done_data_t*)(m->done_data_.first_->data_); + assert(done_data); + assert(done_data->active_); + assert(done_data->buf_); + + int ret = snd_rawmidi_write(m->output_, &(done_data->buf_[done_data->write_idx_]), done_data->len_ - done_data->write_idx_); + if(ret == -EAGAIN) + return 0; + if(ret < 0) { + error(0, 0, "MIDI: cannot write to port: %s", snd_strerror(ret)); + return -1; + } + done_data->write_idx_ += ret; + if(done_data->write_idx_ >= done_data->len_) { + if((err = snd_rawmidi_drain(m->output_)) < 0) { + error(0, 0, "MIDI: cannot drain output: %s", snd_strerror(err)); + return -1; + } + slist_remove(&(m->done_data_), done_data); + } + + return 0; +} + +int midi_handle_revents(midi_t* m, struct pollfd *pfds, int npfds, mixer_t* x) +{ + assert(m); + + if(!m->input_ || !m->output_) + return 0; + + int ret = midi_handle_in_revents(m, pfds, m->in_pfds_cnt_, x); + if(ret) + return ret; + + return midi_handle_out_revents(m, &(pfds[m->in_pfds_cnt_]), m->out_pfds_cnt_); +} diff --git a/server/midi_server.h b/server/midi_server.h new file mode 100644 index 0000000..537c356 --- /dev/null +++ b/server/midi_server.h @@ -0,0 +1,55 @@ +/* + * dolmetschctl + * + * + * Copyright (C) 2015 Christian Pointner + * + * This file is part of dolmetschctl. + * + * dolmetschctl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * dolmetschctl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dolmetschctl. If not, see . + */ + +#ifndef DOLMETSCHCTL_midi_h_INCLUDED +#define DOLMETSCHCTL_midi_h_INCLUDED + +#include +#include + +#include "slist.h" +#include "mixer.h" + +typedef struct { + snd_rawmidi_t* input_; + int in_pfds_cnt_; + snd_rawmidi_t* output_; + int out_pfds_cnt_; + u_int8_t buf_[3]; + int read_idx_; + slist_t done_data_; +} midi_t; + +typedef struct { + midi_t* self_; + int active_; + const u_int8_t* buf_; + int len_; + int write_idx_; +} midi_done_data_t; + +int midi_init(midi_t* m, const char* device); +int midi_get_poll_fd_count(midi_t* m); +int midi_get_poll_fds(midi_t* m, struct pollfd *pfds, int npfds); +int midi_handle_revents(midi_t* m, struct pollfd *pfds, int npfds, mixer_t* x); + +#endif diff --git a/server/osc.c b/server/osc.c deleted file mode 100644 index 1011ad8..0000000 --- a/server/osc.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * dolmetschctl - * - * - * Copyright (C) 2015 Christian Pointner - * - * This file is part of dolmetschctl. - * - * dolmetschctl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * dolmetschctl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with dolmetschctl. If not, see . - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "osc.h" - - -static void print_error(int num, const char *msg, const char *path) -{ - error(0, 0, "liblo server error %d in path %s: %s", num, path, msg); -} - -static int lang_handler(const char *path, const char *types, lo_arg ** argv, - int argc, lo_message msg, void *user_data) -{ - if(argc != 1 || !lo_is_string_type((lo_type)types[0])) - return 1; - - lo_address from = lo_message_get_source(msg); - const char* host = lo_address_get_hostname(from); - const char* port = lo_address_get_port(from); - assert(host && port); - - osc_t* o = (osc_t*)user_data; - assert(o); - osc_done_data_t* done_data = malloc(sizeof(osc_done_data_t)); - assert(done_data); - - done_data->self_ = o; - done_data->state_ = 0; - assert((done_data->lang_ = strdup(&(argv[0]->s)))); - done_data->addr_ = lo_address_new(host, port); - assert(done_data->addr_); - done_data->msg_ = lo_message_new(); - assert(done_data->msg_); - assert(!lo_message_add(done_data->msg_, "s", done_data->lang_)); - - assert(slist_add(&(o->done_data_), done_data)); - - return 0; -} - -void free_osc_done_data(void* ptr) -{ - osc_done_data_t* done_data = (osc_done_data_t*)ptr; - - lo_message_free(done_data->msg_); - lo_address_free(done_data->addr_); - free(done_data->lang_); - free(done_data); -} - -void osc_lang_switch_done(void* data) -{ - assert(data); - osc_done_data_t* d = data; - - lo_send_message_from(d->addr_, d->self_->server_, "/lang/ack", d->msg_); - slist_remove(&(d->self_->done_data_), d); -} - -int osc_init(osc_t* o, const char* port) -{ - assert(o != NULL); - - o->server_ = NULL; - slist_init(&(o->done_data_), free_osc_done_data); - - if(!port) - return 0; - - o->server_ = lo_server_new(port, print_error); - if(!o->server_) - return -1; - - if(!lo_server_add_method(o->server_, "/lang/switch", "s", lang_handler, (void*)o)) - return -1; - - return 0; -} - - -int osc_get_poll_fd_count(osc_t* o) -{ - assert(o); - - if(!o->server_) - return 0; - - return 1; -} - -int osc_get_poll_fds(osc_t* o, struct pollfd *pfds, int npfds) -{ - assert(o); - - if(!o->server_) - return 0; - - pfds[0].fd = lo_server_get_socket_fd(o->server_); - pfds[0].events = POLLIN; - pfds[0].revents = 0; - - return 0; -} - -int osc_handle_revents(osc_t* o, struct pollfd *pfds, int npfds, mixer_t* x) -{ - assert(o); - - if(!o->server_) - return 0; - - if(pfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { - error(0, 0, "OSC: got POLLERR, POLLHUP or POLLNVAL"); - return -1; - } - if(!(pfds[0].revents & POLLIN)) - return 0; - - lo_server_recv_noblock(o->server_, 0); - - int ret = 0; - slist_element_t* tmp; - for(tmp = o->done_data_.first_; tmp; tmp = tmp->next_) { - osc_done_data_t* d = (osc_done_data_t*)(tmp->data_); - if(d->state_ == 0) { - ret = mixer_switch_lang(x, d->lang_, &osc_lang_switch_done, d); - if(ret) - break; - - d->state_ = 1; - } - } - - - return ret; -} diff --git a/server/osc.h b/server/osc.h deleted file mode 100644 index 40210b3..0000000 --- a/server/osc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * dolmetschctl - * - * - * Copyright (C) 2015 Christian Pointner - * - * This file is part of dolmetschctl. - * - * dolmetschctl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * dolmetschctl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with dolmetschctl. If not, see . - */ - -#ifndef DOLMETSCHCTL_osc_h_INCLUDED -#define DOLMETSCHCTL_osc_h_INCLUDED - -#include "lo/lo.h" -#include - -#include "slist.h" -#include "mixer.h" - -typedef struct { - lo_server server_; - slist_t done_data_; -} osc_t; - -typedef struct { - osc_t* self_; - int state_; - char* lang_; - lo_address addr_; - lo_message msg_; -} osc_done_data_t; - -int osc_init(osc_t* o, const char* port); -int osc_get_poll_fd_count(osc_t* o); -int osc_get_poll_fds(osc_t* o, struct pollfd *pfds, int npfds); -int osc_handle_revents(osc_t* o, struct pollfd *pfds, int npfds, mixer_t* x); - -#endif diff --git a/server/osc_server.c b/server/osc_server.c new file mode 100644 index 0000000..223a192 --- /dev/null +++ b/server/osc_server.c @@ -0,0 +1,164 @@ +/* + * dolmetschctl + * + * + * Copyright (C) 2015 Christian Pointner + * + * This file is part of dolmetschctl. + * + * dolmetschctl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * dolmetschctl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dolmetschctl. If not, see . + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "osc_server.h" + + +static void print_error(int num, const char *msg, const char *path) +{ + error(0, 0, "liblo server error %d in path %s: %s", num, path, msg); +} + +static int lang_handler(const char *path, const char *types, lo_arg ** argv, + int argc, lo_message msg, void *user_data) +{ + if(argc != 1 || !lo_is_string_type((lo_type)types[0])) + return 1; + + lo_address from = lo_message_get_source(msg); + const char* host = lo_address_get_hostname(from); + const char* port = lo_address_get_port(from); + assert(host && port); + + osc_t* o = (osc_t*)user_data; + assert(o); + osc_done_data_t* done_data = malloc(sizeof(osc_done_data_t)); + assert(done_data); + + done_data->self_ = o; + done_data->state_ = 0; + assert((done_data->lang_ = strdup(&(argv[0]->s)))); + done_data->addr_ = lo_address_new(host, port); + assert(done_data->addr_); + done_data->msg_ = lo_message_new(); + assert(done_data->msg_); + assert(!lo_message_add(done_data->msg_, "s", done_data->lang_)); + + assert(slist_add(&(o->done_data_), done_data)); + + return 0; +} + +void free_osc_done_data(void* ptr) +{ + osc_done_data_t* done_data = (osc_done_data_t*)ptr; + + lo_message_free(done_data->msg_); + lo_address_free(done_data->addr_); + free(done_data->lang_); + free(done_data); +} + +void osc_lang_switch_done(void* data) +{ + assert(data); + osc_done_data_t* d = data; + + lo_send_message_from(d->addr_, d->self_->server_, "/lang/ack", d->msg_); + slist_remove(&(d->self_->done_data_), d); +} + +int osc_init(osc_t* o, const char* port) +{ + assert(o != NULL); + + o->server_ = NULL; + slist_init(&(o->done_data_), free_osc_done_data); + + if(!port) + return 0; + + o->server_ = lo_server_new(port, print_error); + if(!o->server_) + return -1; + + if(!lo_server_add_method(o->server_, "/lang/switch", "s", lang_handler, (void*)o)) + return -1; + + return 0; +} + + +int osc_get_poll_fd_count(osc_t* o) +{ + assert(o); + + if(!o->server_) + return 0; + + return 1; +} + +int osc_get_poll_fds(osc_t* o, struct pollfd *pfds, int npfds) +{ + assert(o); + + if(!o->server_) + return 0; + + pfds[0].fd = lo_server_get_socket_fd(o->server_); + pfds[0].events = POLLIN; + pfds[0].revents = 0; + + return 0; +} + +int osc_handle_revents(osc_t* o, struct pollfd *pfds, int npfds, mixer_t* x) +{ + assert(o); + + if(!o->server_) + return 0; + + if(pfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { + error(0, 0, "OSC: got POLLERR, POLLHUP or POLLNVAL"); + return -1; + } + if(!(pfds[0].revents & POLLIN)) + return 0; + + lo_server_recv_noblock(o->server_, 0); + + int ret = 0; + slist_element_t* tmp; + for(tmp = o->done_data_.first_; tmp; tmp = tmp->next_) { + osc_done_data_t* d = (osc_done_data_t*)(tmp->data_); + if(d->state_ == 0) { + ret = mixer_switch_lang(x, d->lang_, &osc_lang_switch_done, d); + if(ret) + break; + + d->state_ = 1; + } + } + + + return ret; +} diff --git a/server/osc_server.h b/server/osc_server.h new file mode 100644 index 0000000..40210b3 --- /dev/null +++ b/server/osc_server.h @@ -0,0 +1,50 @@ +/* + * dolmetschctl + * + * + * Copyright (C) 2015 Christian Pointner + * + * This file is part of dolmetschctl. + * + * dolmetschctl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * dolmetschctl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dolmetschctl. If not, see . + */ + +#ifndef DOLMETSCHCTL_osc_h_INCLUDED +#define DOLMETSCHCTL_osc_h_INCLUDED + +#include "lo/lo.h" +#include + +#include "slist.h" +#include "mixer.h" + +typedef struct { + lo_server server_; + slist_t done_data_; +} osc_t; + +typedef struct { + osc_t* self_; + int state_; + char* lang_; + lo_address addr_; + lo_message msg_; +} osc_done_data_t; + +int osc_init(osc_t* o, const char* port); +int osc_get_poll_fd_count(osc_t* o); +int osc_get_poll_fds(osc_t* o, struct pollfd *pfds, int npfds); +int osc_handle_revents(osc_t* o, struct pollfd *pfds, int npfds, mixer_t* x); + +#endif -- cgit v1.2.3