From d1093bd347c2efd81d66f7634b313aa3db53f34b Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 21 May 2017 03:34:43 +0200 Subject: [PATCH] Import first implementations of individual controls --- src/controls/channels.c | 247 ++++++++++++++++++++++++++++++++++++++ src/controls/mute.c | 142 ++++++++++++++++++++++ src/controls/project.conf | 27 +++++ src/controls/radio.c | 149 +++++++++++++++++++++++ src/controls/set.c | 138 +++++++++++++++++++++ src/project.conf | 1 + 6 files changed, 704 insertions(+) create mode 100644 src/controls/channels.c create mode 100644 src/controls/mute.c create mode 100644 src/controls/project.conf create mode 100644 src/controls/radio.c create mode 100644 src/controls/set.c diff --git a/src/controls/channels.c b/src/controls/channels.c new file mode 100644 index 0000000..aff69fb --- /dev/null +++ b/src/controls/channels.c @@ -0,0 +1,247 @@ +/* $Id$ */ +/* Copyright (c) 2017 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Mixer */ +/* All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + + +#include +#include +#include "Mixer/control.h" + + +/* MixerControlChannels */ +/* private */ +/* types */ +typedef struct _MixerControlChannel +{ + MixerControlPlugin * plugin; + + GtkWidget * widget; +} MixerControlChannel; + +struct _MixerControlPlugin +{ + GtkWidget * widget; + + /* channels */ + GtkWidget * hbox; + MixerControlChannel * channels; + size_t channels_cnt; + + GtkWidget * bind; + GtkWidget * mute; +}; + + +/* prototypes */ +/* control */ +static MixerControlPlugin * _channels_init(String const * type, + va_list properties); +static void _channels_destroy(MixerControlPlugin * channels); + +static GtkWidget * _channels_get_widget(MixerControlPlugin * channels); + +static int _channels_set(MixerControlPlugin * channels, + va_list properties); + +/* callbacks */ +static void _channels_on_changed(gpointer data); + + +/* public */ +/* variables */ +MixerControlDefinition control = +{ + NULL, + "Channels", + NULL, + _channels_init, + _channels_destroy, + _channels_get_widget, + _channels_set +}; + + +/* private */ +/* functions */ +/* channels_init */ +static MixerControlPlugin * _channels_init(String const * type, + va_list properties) +{ + MixerControlPlugin * channels; + (void) type; + + if((channels = object_new(sizeof(*channels))) == NULL) + return NULL; + channels->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + channels->channels = NULL; + channels->channels_cnt = 0; + channels->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); + gtk_box_pack_start(GTK_BOX(channels->widget), channels->hbox, TRUE, + TRUE, 0); + if(_channels_set(channels, properties) != 0) + { + _channels_destroy(channels); + return NULL; + } + channels->bind = gtk_toggle_button_new(); + /* FIXME really implement */ + gtk_box_pack_start(GTK_BOX(channels->widget), channels->bind, + FALSE, TRUE, 0); + channels->mute = gtk_toggle_button_new(); + /* FIXME really implement */ + gtk_box_pack_start(GTK_BOX(channels->widget), channels->mute, + FALSE, TRUE, 0); + return channels; +} + + +/* channels_destroy */ +static void _channels_destroy(MixerControlPlugin * channels) +{ + g_object_unref(channels->widget); + object_delete(channels); +} + + +/* accessors */ +/* channels_get_widget */ +static GtkWidget * _channels_get_widget(MixerControlPlugin * channels) +{ + return channels->widget; +} + + +/* channels_set */ +static void _set_bind(MixerControlPlugin * channels, gboolean bind); +static int _set_channels(MixerControlPlugin * channels, guint cnt, + gdouble value); +static void _set_mute(MixerControlPlugin * channels, gboolean mute); +static void _set_value(MixerControlPlugin * channels, gdouble value); + +static int _channels_set(MixerControlPlugin * channels, + va_list properties) +{ + String const * p; + gboolean b; + guint u; + gdouble value = 0.0; + + while((p = va_arg(properties, String const *)) != NULL) + { + if(string_compare(p, "value") == 0) + { + value = va_arg(properties, gdouble); + _set_value(channels, value); + } + else if(string_compare(p, "bind") == 0) + { + b = va_arg(properties, gboolean); + _set_bind(channels, b); + } + else if(string_compare(p, "channels") == 0) + { + u = va_arg(properties, unsigned int); + /* FIXME look for the initial value first */ + if(_set_channels(channels, u, value) != 0) + return -1; + } + else if(string_compare(p, "mute") == 0) + { + b = va_arg(properties, gboolean); + _set_mute(channels, b); + } + else + /* FIXME report the error */ + return -1; + } + return 0; +} + +static void _set_bind(MixerControlPlugin * channels, gboolean bind) +{ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(channels->bind), bind); +} + +static int _set_channels(MixerControlPlugin * channels, guint cnt, + gdouble value) +{ + size_t i; + MixerControlChannel * p; + + /* delete channels as required */ + if(channels->channels_cnt >= cnt) + { + for(i = cnt; i < channels->channels_cnt; i++) + g_object_unref(channels->channels[i].widget); + channels->channels_cnt = cnt; + return 0; + } + if((p = realloc(channels->channels, sizeof(*p) * cnt)) == NULL) + return -1; + channels->channels = p; + for(i = channels->channels_cnt; i < cnt; i++) + { + p = &channels->channels[i]; + p->plugin = channels; + p->widget = gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL, + 0.0, 100.0, 1.0); + gtk_range_set_inverted(GTK_RANGE(p->widget), TRUE); + gtk_range_set_value(GTK_RANGE(p->widget), value); + g_signal_connect_swapped(p->widget, "value-changed", G_CALLBACK( + _channels_on_changed), p); + gtk_box_pack_start(GTK_BOX(channels->hbox), p->widget, TRUE, + TRUE, 0); + } + channels->channels_cnt = cnt; + return 0; +} + +static void _set_mute(MixerControlPlugin * channels, gboolean mute) +{ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(channels->mute), mute); +} + +static void _set_value(MixerControlPlugin * channels, gdouble value) +{ + size_t i; + gdouble v; + + v = (value / 255.0) * 100.0; + for(i = 0; i < channels->channels_cnt; i++) + gtk_range_set_value(GTK_RANGE(channels->channels[i].widget), v); +} + + +/* callbacks */ +/* channels_on_changed */ +static void _channels_on_changed(gpointer data) +{ + MixerControlChannel * channel = data; + + /* FIXME implement */ +} diff --git a/src/controls/mute.c b/src/controls/mute.c new file mode 100644 index 0000000..2ad2756 --- /dev/null +++ b/src/controls/mute.c @@ -0,0 +1,142 @@ +/* $Id$ */ +/* Copyright (c) 2017 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Mixer */ +/* All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + + +#include "Mixer/control.h" +#include + + +/* MixerControlMute */ +/* private */ +/* types */ +struct _MixerControlPlugin +{ + GtkWidget * widget; + + GtkWidget * mute; +}; + + +/* prototypes */ +/* control */ +static MixerControlPlugin * _mute_init(String const * type, va_list properties); +static void _mute_destroy(MixerControlPlugin * mute); + +static GtkWidget * _mute_get_widget(MixerControlPlugin * mute); + +static int _mute_set(MixerControlPlugin * mute, va_list properties); + +/* callbacks */ +static void _mute_on_toggled(gpointer data); + + +/* public */ +/* variables */ +MixerControlDefinition control = +{ + NULL, + "Mute button", + NULL, + _mute_init, + _mute_destroy, + _mute_get_widget, + _mute_set +}; + + +/* private */ +/* functions */ +/* mute_init */ +static MixerControlPlugin * _mute_init(String const * type, va_list properties) +{ + MixerControlPlugin * mute; + (void) type; + + if((mute = object_new(sizeof(*mute))) == NULL) + return NULL; + mute->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + mute->mute = gtk_toggle_button_new(); + g_signal_connect(mute->mute, "toggled", G_CALLBACK(_mute_on_toggled), + mute); + gtk_box_pack_start(GTK_BOX(mute->widget), mute->mute, FALSE, TRUE, 0); + if(_mute_set(mute, properties) != 0) + { + _mute_destroy(mute); + return NULL; + } + return mute; +} + + +/* mute_destroy */ +static void _mute_destroy(MixerControlPlugin * mute) +{ + g_object_unref(mute->widget); + object_delete(mute); +} + + +/* accessors */ +/* mute_get_widget */ +static GtkWidget * _mute_get_widget(MixerControlPlugin * mute) +{ + return mute->widget; +} + + +/* mute_set */ +static int _mute_set(MixerControlPlugin * mute, va_list properties) +{ + String const * p; + gboolean value; + + while((p = va_arg(properties, String const *)) != NULL) + { + if(string_compare(p, "value") == 0) + { + value = va_arg(properties, gboolean); + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(mute->mute), value); + } + else + /* FIXME report the error */ + return -1; + } + return 0; +} + + +/* callbacks */ +/* mute_on_toggled */ +static void _mute_on_toggled(gpointer data) +{ + MixerControlPlugin * mute = data; + + /* FIXME implement */ +} diff --git a/src/controls/project.conf b/src/controls/project.conf new file mode 100644 index 0000000..66b8212 --- /dev/null +++ b/src/controls/project.conf @@ -0,0 +1,27 @@ +targets=channels,mute,radio,set +cppflags_force=-I../../include +cflags_force=`pkg-config --cflags libDesktop` +cflags=-W -Wall -g -O2 -fPIC -D_FORTIFY_SOURCE=2 -fstack-protector-all +ldflags_force=`pkg-config --libs libDesktop` +ldflags=-Wl,-z,relro -Wl,-z,now +dist=Makefile + +[channels] +type=plugin +sources=channels.c +install=$(LIBDIR)/Desktop/Mixer/controls + +[radio] +type=plugin +sources=radio.c +install=$(LIBDIR)/Desktop/Mixer/controls + +[mute] +type=plugin +sources=mute.c +install=$(LIBDIR)/Desktop/Mixer/controls + +[set] +type=plugin +sources=set.c +install=$(LIBDIR)/Desktop/Mixer/controls diff --git a/src/controls/radio.c b/src/controls/radio.c new file mode 100644 index 0000000..a2f23e9 --- /dev/null +++ b/src/controls/radio.c @@ -0,0 +1,149 @@ +/* $Id$ */ +/* Copyright (c) 2017 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Mixer */ +/* All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + + +#include +#include "Mixer/control.h" + + +/* MixerControlRadio */ +/* private */ +/* types */ +typedef struct _MixerControlRadio +{ + MixerControlPlugin * plugin; + + GtkWidget * widget; +} MixerControlRadio; + +struct _MixerControlPlugin +{ + GtkWidget * widget; + + MixerControlRadio * radio; + size_t radio_cnt; +}; + + +/* prototypes */ +/* control */ +static MixerControlPlugin * _radio_init(String const * type, + va_list properties); +static void _radio_destroy(MixerControlPlugin * radio); + +static GtkWidget * _radio_get_widget(MixerControlPlugin * radio); + +static int _radio_set(MixerControlPlugin * radio, + va_list properties); + +/* callbacks */ + + +/* public */ +/* variables */ +MixerControlDefinition control = +{ + NULL, + "Radio buttons", + NULL, + _radio_init, + _radio_destroy, + _radio_get_widget, + _radio_set +}; + + +/* private */ +/* functions */ +/* radio_init */ +static MixerControlPlugin * _radio_init(String const * type, va_list properties) +{ + MixerControlPlugin * radio; + (void) type; + + if((radio = object_new(sizeof(*radio))) == NULL) + return NULL; + radio->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + radio->radio = NULL; + radio->radio_cnt = 0; + if(_radio_set(radio, properties) != 0) + { + _radio_destroy(radio); + return NULL; + } + return radio; +} + + +/* radio_destroy */ +static void _radio_destroy(MixerControlPlugin * radio) +{ + g_object_unref(radio->widget); + object_delete(radio); +} + + +/* accessors */ +/* radio_get_widget */ +static GtkWidget * _radio_get_widget(MixerControlPlugin * radio) +{ + return radio->widget; +} + + +/* radio_set */ +static void _set_value(MixerControlPlugin * radio, guint value); + +static int _radio_set(MixerControlPlugin * radio, va_list properties) +{ + String const * p; + guint value; + + while((p = va_arg(properties, String const *)) != NULL) + { + if(string_compare(p, "value") == 0) + { + value = va_arg(properties, guint); + _set_value(radio, value); + } + else + /* FIXME report the error */ + return -1; + } + return 0; +} + +static void _set_value(MixerControlPlugin * radio, guint value) +{ + /* FIXME implement */ +} + + +/* callbacks */ +/* FIXME implement */ diff --git a/src/controls/set.c b/src/controls/set.c new file mode 100644 index 0000000..21ac745 --- /dev/null +++ b/src/controls/set.c @@ -0,0 +1,138 @@ +/* $Id$ */ +/* Copyright (c) 2017 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Mixer */ +/* All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + + +#include +#include "Mixer/control.h" + + +/* MixerControlSet */ +/* private */ +/* types */ +typedef struct _MixerControlSet +{ + GtkWidget * widget; +} MixerControlSet; + +struct _MixerControlPlugin +{ + GtkWidget * widget; + + MixerControlSet * sets; + size_t sets_cnt; +}; + + +/* prototypes */ +static MixerControlPlugin * _set_init(String const * type, va_list properties); +static void _set_destroy(MixerControlPlugin * set); + +static GtkWidget * _set_get_widget(MixerControlPlugin * set); + +static int _set_set(MixerControlPlugin * set, va_list properties); + + +/* public */ +/* variables */ +MixerControlDefinition control = +{ + NULL, + "Set of values", + NULL, + _set_init, + _set_destroy, + _set_get_widget, + _set_set +}; + + +/* private */ +/* functions */ +/* set_init */ +static MixerControlPlugin * _set_init(String const * type, va_list properties) +{ + MixerControlPlugin * set; + (void) type; + + if((set = object_new(sizeof(*set))) == NULL) + return NULL; + set->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + set->sets = NULL; + set->sets_cnt = 0; + if(_set_set(set, properties) != 0) + { + _set_destroy(set); + return NULL; + } + return set; +} + + +/* set_destroy */ +static void _set_destroy(MixerControlPlugin * set) +{ + g_object_unref(set->widget); + object_delete(set); +} + + +/* accessors */ +/* set_get_widget */ +static GtkWidget * _set_get_widget(MixerControlPlugin * set) +{ + return set->widget; +} + + +/* set_set */ +static void _set_value(MixerControlPlugin * set, guint value); + +static int _set_set(MixerControlPlugin * set, va_list properties) +{ + String const * p; + guint value; + + while((p = va_arg(properties, String const *)) != NULL) + { + if(string_compare(p, "value") == 0) + { + value = va_arg(properties, guint); + _set_value(set, value); + } + else + /* FIXME report the error */ + return -1; + } + return 0; +} + +static void _set_value(MixerControlPlugin * set, guint value) +{ + /* FIXME implement */ +} diff --git a/src/project.conf b/src/project.conf index bddf76f..917316d 100644 --- a/src/project.conf +++ b/src/project.conf @@ -1,3 +1,4 @@ +subdirs=controls targets=mixer cppflags_force=-I../include #cppflags=-D EMBEDDED