Import first implementations of individual controls

This commit is contained in:
Pierre Pronchery 2017-05-21 03:34:43 +02:00
parent 541ba6f8f2
commit d1093bd347
6 changed files with 704 additions and 0 deletions

247
src/controls/channels.c Normal file
View File

@ -0,0 +1,247 @@
/* $Id$ */
/* Copyright (c) 2017 Pierre Pronchery <khorben@defora.org> */
/* 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 <stdlib.h>
#include <System/object.h>
#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 */
}

142
src/controls/mute.c Normal file
View File

@ -0,0 +1,142 @@
/* $Id$ */
/* Copyright (c) 2017 Pierre Pronchery <khorben@defora.org> */
/* 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 <System/object.h>
/* 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 */
}

27
src/controls/project.conf Normal file
View File

@ -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

149
src/controls/radio.c Normal file
View File

@ -0,0 +1,149 @@
/* $Id$ */
/* Copyright (c) 2017 Pierre Pronchery <khorben@defora.org> */
/* 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 <System/object.h>
#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 */

138
src/controls/set.c Normal file
View File

@ -0,0 +1,138 @@
/* $Id$ */
/* Copyright (c) 2017 Pierre Pronchery <khorben@defora.org> */
/* 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 <System/object.h>
#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 */
}

View File

@ -1,3 +1,4 @@
subdirs=controls
targets=mixer
cppflags_force=-I../include
#cppflags=-D EMBEDDED