Compare commits
54 Commits
0.3.0
...
expression
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7023e1fa92 | ||
|
|
a51103964b | ||
|
|
f6a2ba7420 | ||
|
|
bad10ed0f2 | ||
|
|
cee33835a7 | ||
|
|
0cd6727d45 | ||
|
|
22aeaf8ffa | ||
|
|
a389c785f7 | ||
|
|
44dbbe7b72 | ||
|
|
3a3017b46f | ||
|
|
8b998c636f | ||
|
|
f389caffbc | ||
|
|
b5aa30d599 | ||
|
|
29d33ce93a | ||
|
|
27ffb9c65a | ||
|
|
4f40132742 | ||
|
|
1a5fab5f5a | ||
|
|
cf239da94c | ||
|
|
890d40f6c6 | ||
|
|
c927b075a7 | ||
|
|
7691323989 | ||
|
|
d90d7e4b70 | ||
|
|
79d80fee46 | ||
|
|
034f353aa9 | ||
|
|
db04032b46 | ||
|
|
d7043d471d | ||
|
|
c614783e87 | ||
|
|
06cee3eef1 | ||
|
|
8a98e2703f | ||
|
|
b1a8fb4a3b | ||
|
|
2b1c74ac30 | ||
|
|
baa5fdff85 | ||
|
|
d139a3d89a | ||
|
|
4291fa71b2 | ||
|
|
ea80320531 | ||
|
|
88819a795b | ||
|
|
3002d2256e | ||
|
|
1205a1639d | ||
|
|
122bbcd823 | ||
|
|
5c42cad5e7 | ||
|
|
7781063407 | ||
|
|
e56884ecd9 | ||
|
|
dd1f4408c9 | ||
|
|
f3dbaf43ec | ||
|
|
87ae4cd280 | ||
|
|
a073f5cde2 | ||
|
|
9fcf6939d0 | ||
|
|
71e087cfd0 | ||
|
|
6a16e66cbd | ||
|
|
4351613e72 | ||
|
|
2253833105 | ||
|
|
87e6dcbb9c | ||
|
|
d92489348d | ||
|
|
2b27302166 |
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
*.[om]
|
||||
*.rp355p
|
||||
cscope.*
|
||||
tags
|
||||
gdigi
|
||||
*.orig
|
||||
*.swp
|
||||
images/gdigi_icon.h
|
||||
core
|
||||
3
AUTHORS
3
AUTHORS
@@ -2,10 +2,11 @@ Tomasz Moń <desowin@gmail.com>
|
||||
Stephen Rigler <riglersc@gmail.com>
|
||||
Jaco Kroon <jaco@kroon.co.za>
|
||||
Rafael Moreno <laocanfei@yahoo.com>
|
||||
Andrew O. Shadoura <bugzilla@tut.by>
|
||||
Andrew Shadura <bugzilla@tut.by>
|
||||
Andreas Karajannis <aakara13@googlemail.com>
|
||||
Miklos Aubert <miklos.aubert@gmail.com>
|
||||
Jonathan A. Tice <jonandtice@gmail.com>
|
||||
John Hammen <jhammen@gmail.com>
|
||||
Ahmed Toulan <thelinuxer@gmail.com>
|
||||
Tim LaBerge <tlaberge@visi.com>
|
||||
Mauro Carvalho Chehab <maurochehab@gmail.com>
|
||||
|
||||
7
Makefile
7
Makefile
@@ -3,7 +3,7 @@ EXTRA_CFLAGS ?=
|
||||
EXTRA_LDFLAGS ?=
|
||||
CFLAGS := $(shell pkg-config --cflags glib-2.0 gio-2.0 gtk+-3.0 libxml-2.0) -Wall -g -ansi -std=c99 $(EXTRA_CFLAGS)
|
||||
LDFLAGS = $(EXTRA_LDFLAGS) -Wl,--as-needed
|
||||
LDADD := $(shell pkg-config --libs glib-2.0 gio-2.0 gtk+-3.0 gthread-2.0 alsa libxml-2.0) -lexpat
|
||||
LDADD := $(shell pkg-config --libs glib-2.0 gio-2.0 gtk+-3.0 gthread-2.0 alsa libxml-2.0) -lexpat -lm
|
||||
OBJECTS = gdigi.o gui.o effects.o preset.o gtkknob.o preset_xml.o
|
||||
DEPFILES = $(foreach m,$(OBJECTS:.o=),.$(m).m)
|
||||
|
||||
@@ -19,16 +19,21 @@ all: gdigi
|
||||
gdigi: $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) -o $@ $+ $(LDADD)
|
||||
|
||||
images/gdigi_icon.h: images/icon.png
|
||||
gdk-pixbuf-csource --raw --name=gdigi_icon $< > $@
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
|
||||
distclean : clean
|
||||
rm -f .*.m
|
||||
rm -r images/gdigi_icon.h
|
||||
rm -f gdigi
|
||||
|
||||
install: gdigi
|
||||
install gdigi $(DESTDIR)/usr/bin
|
||||
install gdigi.desktop $(DESTDIR)/usr/share/applications/
|
||||
install images/gdigi.png $(DESTDIR)/usr/share/icons/
|
||||
|
||||
NODEP_TARGETS := clean distclean
|
||||
depinc := 1
|
||||
|
||||
13
effects.h
13
effects.h
@@ -27,7 +27,8 @@ typedef enum {
|
||||
VALUE_TYPE_LABEL = 1 << 3, /**< use value labels (overrides any other option) */
|
||||
VALUE_TYPE_EXTRA = 1 << 4, /**< use extra values */
|
||||
VALUE_TYPE_DECIMAL= 1 << 5, /**< display decimal places */
|
||||
VALUE_TYPE_NONE = 1 << 6, /**< no value displayed */
|
||||
VALUE_TYPE_POSID = 1 << 6, /**< Packed Position/ID: (pos << 16) | id */
|
||||
VALUE_TYPE_NONE = 1 << 7, /**< no value displayed */
|
||||
} ValueType;
|
||||
|
||||
typedef struct _EffectValues {
|
||||
@@ -105,7 +106,7 @@ enum product_id {
|
||||
RP255 = 8,
|
||||
RP355 = 9,
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
gchar *name;
|
||||
unsigned char family_id;
|
||||
@@ -116,12 +117,16 @@ typedef struct {
|
||||
gint n_banks;
|
||||
} Device;
|
||||
|
||||
ModifierGroup *modifier_linkable_list();
|
||||
void modifier_group_free(ModifierGroup *modifier_group);
|
||||
gchar *get_position(guint position);
|
||||
void update_modifier_linkable_list(GString* msg);
|
||||
extern ModifierGroup *ModifierLinkableList;
|
||||
EffectGroup *get_modifier_group(void);
|
||||
guint get_modifier_amt(void);
|
||||
void get_values_info(EffectValues *values,
|
||||
gdouble *min, gdouble *max, gboolean *custom);
|
||||
gboolean get_device_info(unsigned char device_id, unsigned char family_id,
|
||||
unsigned char product_id,
|
||||
Device **device);
|
||||
|
||||
|
||||
#endif /* GDIGI_EFFECTS_H */
|
||||
|
||||
415
gdigi.c
415
gdigi.c
@@ -21,6 +21,7 @@
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <alloca.h>
|
||||
#include "gdigi.h"
|
||||
#include "gdigi_xml.h"
|
||||
#include "gui.h"
|
||||
|
||||
static unsigned char device_id = 0x7F;
|
||||
@@ -35,6 +36,173 @@ static GQueue *message_queue = NULL;
|
||||
static GMutex *message_queue_mutex = NULL;
|
||||
static GCond *message_queue_cond = NULL;
|
||||
|
||||
static guint DebugFlags;
|
||||
|
||||
gboolean
|
||||
debug_flag_is_set (debug_flags_t flags)
|
||||
{
|
||||
if (DebugFlags & flags) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean set_debug_flags (const gchar *option_name, const gchar *value,
|
||||
gpointer data, GError **error)
|
||||
{
|
||||
if (strchr(value, 'd')) {
|
||||
DebugFlags |= DEBUG_MSG2DEV;
|
||||
}
|
||||
if (strchr(value, 'h')) {
|
||||
DebugFlags |= DEBUG_MSG2HOST;
|
||||
}
|
||||
if (strchr(value, 'm')) {
|
||||
DebugFlags |= DEBUG_MSG2DEV|DEBUG_MSG2HOST|DEBUG_GROUP;
|
||||
}
|
||||
if (strchr(value, 's')) {
|
||||
DebugFlags |= DEBUG_STARTUP;
|
||||
}
|
||||
if (strchr(value, 'H')) {
|
||||
DebugFlags |= DEBUG_HEX;
|
||||
}
|
||||
if (strchr(value, 'g')) {
|
||||
DebugFlags |= DEBUG_GROUP;
|
||||
}
|
||||
if (strchr(value, 'x')) {
|
||||
DebugFlags |= DEBUG_XML;
|
||||
}
|
||||
if (strchr(value, 'v')) {
|
||||
DebugFlags |= DEBUG_VERBOSE;
|
||||
}
|
||||
if (strchr(value, 'a')) {
|
||||
DebugFlags = -1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
debug_msg (debug_flags_t flags, char *fmt, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
if (flags & DebugFlags) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, 1024, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format a value according to the xml setting.
|
||||
* Returns an allocated buffer that must be freed by the caller.
|
||||
*/
|
||||
GString *
|
||||
format_value (XmlSettings *xml, guint value)
|
||||
{
|
||||
GString *buf = g_string_sized_new(1);
|
||||
EffectValues *values = NULL;
|
||||
ValueType vtype;
|
||||
gchar *suffix = "";
|
||||
gdouble step = 1.0;
|
||||
gint offset = 0;
|
||||
gboolean decimal = FALSE;
|
||||
|
||||
values = xml->values;
|
||||
vtype = values->type;
|
||||
while ((vtype & VALUE_TYPE_EXTRA) && value_is_extra(values, value)) {
|
||||
values = values->extra;
|
||||
vtype = values->type;
|
||||
}
|
||||
vtype &= ~VALUE_TYPE_EXTRA;
|
||||
|
||||
if (vtype & VALUE_TYPE_OFFSET) {
|
||||
offset = values->offset;
|
||||
vtype &= ~VALUE_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
if (vtype & VALUE_TYPE_STEP) {
|
||||
step = values->step;
|
||||
vtype &= ~VALUE_TYPE_STEP;
|
||||
}
|
||||
|
||||
if (vtype & VALUE_TYPE_SUFFIX) {
|
||||
suffix = values->suffix;
|
||||
vtype &= ~VALUE_TYPE_SUFFIX;
|
||||
}
|
||||
|
||||
if (vtype & VALUE_TYPE_DECIMAL) {
|
||||
decimal = TRUE;
|
||||
vtype &= ~VALUE_TYPE_DECIMAL;
|
||||
}
|
||||
|
||||
switch (vtype) {
|
||||
case VALUE_TYPE_LABEL:
|
||||
{
|
||||
char *textp = map_xml_value(xml, values, value);
|
||||
if (!textp) {
|
||||
g_warning("%s: Unable to map %s value %d for id %d position %d",
|
||||
__FUNCTION__, xml->label, value, xml->id, xml->position);
|
||||
textp = "";
|
||||
}
|
||||
g_string_printf(buf, "%s", textp);
|
||||
break;
|
||||
}
|
||||
case VALUE_TYPE_PLAIN:
|
||||
{
|
||||
if (decimal) {
|
||||
double dvalue = ((gint)value + offset) * step;
|
||||
g_string_printf(buf, "%0.2f%s", dvalue, suffix);
|
||||
} else {
|
||||
gint ivalue = ((gint)value + offset) * step;
|
||||
g_string_printf(buf, "%d%s", ivalue, suffix);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VALUE_TYPE_NONE:
|
||||
g_string_printf(buf, "%s", "");
|
||||
break;
|
||||
|
||||
case VALUE_TYPE_POSID:
|
||||
g_string_printf(buf, "%d", value);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning("Unhandled value type %d", vtype);
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
GString *
|
||||
format_ipv (guint id, guint pos, guint val)
|
||||
{
|
||||
GString *buf = g_string_sized_new(1);
|
||||
GString *vec_buf = g_string_sized_new(1);
|
||||
XmlSettings *xml = get_xml_settings(id, pos);
|
||||
GString *val_buf;
|
||||
|
||||
if (!xml) {
|
||||
g_warning("Failed to find xml settings for position %d id %d.",
|
||||
id, pos);
|
||||
g_string_printf(buf, "%s", "error");
|
||||
return buf;
|
||||
}
|
||||
val_buf = format_value(xml, val);
|
||||
|
||||
g_string_printf(vec_buf, "(%d, %d, %d)", pos, id, val);
|
||||
g_string_printf(buf, "%-16s %s: %s: %s",
|
||||
vec_buf->str,
|
||||
get_position(pos), xml->label, val_buf->str);
|
||||
g_string_free(vec_buf, TRUE);
|
||||
g_string_free(val_buf, TRUE);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an error quark for gdigi if necessary.
|
||||
*
|
||||
@@ -218,33 +386,57 @@ MessageID get_message_id(GString *msg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define HEX_WIDTH 26
|
||||
|
||||
static gboolean modifier_linkable_list_request_pending = FALSE;
|
||||
|
||||
void push_message(GString *msg)
|
||||
{
|
||||
if (((unsigned char)msg->str[0] == 0xF0) && ((unsigned char)msg->str[msg->len-1] == 0xF7))
|
||||
g_message("Pushing correct message!");
|
||||
else
|
||||
MessageID msgid = get_message_id(msg);
|
||||
if (((unsigned char)msg->str[0] == 0xF0) &&
|
||||
((unsigned char)msg->str[msg->len-1] == 0xF7)) {
|
||||
debug_msg(DEBUG_VERBOSE, "Pushing correct message!");
|
||||
} else {
|
||||
g_warning("Pushing incorrect message!");
|
||||
}
|
||||
|
||||
int x;
|
||||
for (x = 0; x<msg->len; x++)
|
||||
printf("%02x ", (unsigned char)msg->str[x]);
|
||||
printf("\n");
|
||||
if (debug_flag_is_set(DEBUG_HEX)) {
|
||||
for (x = 0; x<msg->len; x++) {
|
||||
if (x && (x % HEX_WIDTH) == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("%02x ", (unsigned char)msg->str[x]);
|
||||
}
|
||||
if (x % HEX_WIDTH) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
debug_msg(DEBUG_VERBOSE, "Received %s", get_message_name(msgid));
|
||||
|
||||
switch (get_message_id(msg)) {
|
||||
SettingParam *param;
|
||||
switch (msgid) {
|
||||
case ACK:
|
||||
g_message("Received ACK");
|
||||
g_string_free(msg, TRUE);
|
||||
return;
|
||||
|
||||
case NACK:
|
||||
g_message("Received NACK");
|
||||
g_warning("Received NACK!");
|
||||
g_string_free(msg, TRUE);
|
||||
return;
|
||||
|
||||
case RECEIVE_PARAMETER_VALUE:
|
||||
{
|
||||
unpack_message(msg);
|
||||
SettingParam *param = setting_param_new_from_data(&msg->str[8], NULL);
|
||||
g_message("Received parameter change ID: %d Position: %d Value: %d", param->id, param->position, param->value);
|
||||
param = setting_param_new_from_data(&msg->str[8], NULL);
|
||||
if (debug_flag_is_set(DEBUG_MSG2HOST)) {
|
||||
GString *ipv = format_ipv(param->id,
|
||||
param->position,
|
||||
param->value);
|
||||
debug_msg(DEBUG_MSG2HOST, "RECEIVE_PARAMETER_VALUE\n%s",
|
||||
ipv->str);
|
||||
g_string_free(ipv, TRUE);
|
||||
}
|
||||
|
||||
GDK_THREADS_ENTER();
|
||||
apply_setting_param_to_gui(param);
|
||||
@@ -253,32 +445,127 @@ void push_message(GString *msg)
|
||||
setting_param_free(param);
|
||||
g_string_free(msg, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
case RECEIVE_DEVICE_NOTIFICATION:
|
||||
unpack_message(msg);
|
||||
unsigned char *str = (unsigned char*)msg->str;
|
||||
switch (str[8]) {
|
||||
case NOTIFY_PRESET_MOVED:
|
||||
if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) {
|
||||
g_message("Loaded preset %d from bank %d", str[10], str[9]);
|
||||
case NOTIFY_PRESET_MOVED:
|
||||
if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) {
|
||||
|
||||
GDK_THREADS_ENTER();
|
||||
g_timeout_add(0, apply_current_preset_to_gui, NULL);
|
||||
GDK_THREADS_LEAVE();
|
||||
} else {
|
||||
g_message("%d %d moved to %d %d", str[9], str[10], str[11], str[12]);
|
||||
GDK_THREADS_ENTER();
|
||||
g_timeout_add(0, apply_current_preset_to_gui, NULL);
|
||||
GDK_THREADS_LEAVE();
|
||||
debug_msg(DEBUG_MSG2HOST,
|
||||
"RECEIVE_DEVICE_NOTIFICATION: Loaded preset "
|
||||
"%d from bank %d",
|
||||
str[10], str[9]);
|
||||
} else {
|
||||
debug_msg(DEBUG_MSG2HOST,
|
||||
"RECEIVE_DEVICE_NOTIFICATION: %d %d moved to "
|
||||
"%d %d",
|
||||
str[9], str[10],
|
||||
str[11], str[12]);
|
||||
}
|
||||
break;
|
||||
|
||||
case NOTIFY_MODIFIER_GROUP_CHANGED:
|
||||
{
|
||||
int i;
|
||||
if (debug_flag_is_set(DEBUG_HEX)) {
|
||||
printf("\n");
|
||||
for (i = 0; i < msg->len; i++) {
|
||||
printf(" %02x", (unsigned char) str[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_message("Received unhandled device notification 0x%x", str[11]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
debug_msg(DEBUG_MSG2HOST,
|
||||
"NOTIFY_MODIFIER_GROUP_CHANGED: Modifier group "
|
||||
"id %d changed",
|
||||
(str[9] << 8) | (str[10]));
|
||||
|
||||
if (!modifier_linkable_list_request_pending) {
|
||||
send_message(REQUEST_MODIFIER_LINKABLE_LIST, "\x00\x01", 2);
|
||||
modifier_linkable_list_request_pending = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
g_warning("Received unhandled device notification 0x%x",
|
||||
str[11]);
|
||||
}
|
||||
g_string_free(msg, TRUE);
|
||||
return;
|
||||
case RECEIVE_GLOBAL_PARAMETERS:
|
||||
unpack_message(msg);
|
||||
gint tot, n, x;
|
||||
tot = (unsigned char)msg->str[9];
|
||||
if (debug_flag_is_set(DEBUG_HEX)) {
|
||||
for (n = 0; n < msg->len; n++) {
|
||||
printf("%02x ",(unsigned char) msg->str[n]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
n = 0;
|
||||
x = 10;
|
||||
do {
|
||||
param = setting_param_new_from_data(&msg->str[x], &x);
|
||||
debug_msg(DEBUG_MSG2HOST,
|
||||
"RECEIVE_GLOBAL_PARAMETERS ID: %5d "
|
||||
"Position: %2.1d Value: %6.1d: %s",
|
||||
param->id,
|
||||
param->position, param->value, "XXX");
|
||||
|
||||
GDK_THREADS_ENTER();
|
||||
apply_setting_param_to_gui(param);
|
||||
GDK_THREADS_LEAVE();
|
||||
|
||||
setting_param_free(param);
|
||||
} while ( (x < msg->len) && n < tot);
|
||||
|
||||
g_string_free(msg, TRUE);
|
||||
return;
|
||||
|
||||
|
||||
case RECEIVE_MODIFIER_LINKABLE_LIST:
|
||||
|
||||
modifier_linkable_list_request_pending = FALSE;
|
||||
unpack_message(msg);
|
||||
tot = (unsigned char)msg->str[9];
|
||||
|
||||
if (debug_flag_is_set(DEBUG_HEX)) {
|
||||
for (n = 0; n < msg->len; n++) {
|
||||
printf("%02x ",(unsigned char) msg->str[n]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
update_modifier_linkable_list(msg);
|
||||
|
||||
g_string_free(msg, TRUE);
|
||||
|
||||
GDK_THREADS_ENTER();
|
||||
|
||||
create_modifier_group(EXP_POSITION, EXP_ASSIGN1);
|
||||
create_modifier_group(LFO1_POSITION, LFO_TYPE);
|
||||
create_modifier_group(LFO2_POSITION, LFO_TYPE);
|
||||
|
||||
GDK_THREADS_LEAVE();
|
||||
|
||||
return;
|
||||
|
||||
|
||||
default:
|
||||
g_mutex_lock(message_queue_mutex);
|
||||
g_queue_push_tail(message_queue, msg);
|
||||
g_cond_signal(message_queue_cond);
|
||||
g_mutex_unlock(message_queue_mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +588,8 @@ gpointer read_data_thread(gboolean *stop)
|
||||
unsigned short revents;
|
||||
|
||||
/* SysEx messages can't contain bytes with 8th bit set.
|
||||
memset our buffer to 0xFF, so if for some reason we'll get out of reply bounds, we'll catch it */
|
||||
memset our buffer to 0xFF, so if for some reason we'll
|
||||
get out of reply bounds, we'll catch it */
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
|
||||
err = poll(pfds, npfds, 200);
|
||||
@@ -400,6 +688,9 @@ void send_message(gint procedure, gchar *data, gint len)
|
||||
g_string_append_printf(msg, "%c\xF7",
|
||||
calculate_checksum(&msg->str[1], msg->len - 1));
|
||||
|
||||
debug_msg(DEBUG_VERBOSE, "Sending %s len %d",
|
||||
get_message_name(procedure), len);
|
||||
|
||||
send_data(msg->str, msg->len);
|
||||
|
||||
g_string_free(msg, TRUE);
|
||||
@@ -620,12 +911,30 @@ SectionID get_genetx_section_id(gint version, gint type)
|
||||
}
|
||||
}
|
||||
|
||||
g_message("This version of gdigi don't know what to do with this "
|
||||
g_warning("This version of gdigi don't know what to do with this "
|
||||
"GeNetX version (%d) and type (%d)", version, type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \param id Parameter ID
|
||||
* \param position Parameter position
|
||||
* \param value Parameter value
|
||||
*
|
||||
* Forms SysEx message to request parameter then sends it to device.
|
||||
**/
|
||||
void get_option(guint id, guint position)
|
||||
{
|
||||
GString *msg = g_string_sized_new(9);
|
||||
debug_msg(DEBUG_MSG2DEV, "REQUEST_PARAMETER_VALUE: id %d position %d",
|
||||
id, position);
|
||||
g_string_append_printf(msg, "%c%c%c",
|
||||
((id & 0xFF00) >> 8), (id & 0xFF),
|
||||
position);
|
||||
send_message(REQUEST_PARAMETER_VALUE, msg->str, msg->len);
|
||||
g_string_free(msg, TRUE);
|
||||
}
|
||||
/**
|
||||
* \param id Parameter ID
|
||||
* \param position Parameter position
|
||||
@@ -640,6 +949,11 @@ void set_option(guint id, guint position, guint value)
|
||||
((id & 0xFF00) >> 8), (id & 0xFF),
|
||||
position);
|
||||
append_value(msg, value);
|
||||
if (debug_flag_is_set(DEBUG_MSG2DEV)) {
|
||||
GString *ipv = format_ipv(id, position, value);
|
||||
debug_msg(DEBUG_MSG2DEV, "RECEIVE_PARAMETER_VALUE\n%s", ipv->str);
|
||||
g_string_free(ipv, TRUE);
|
||||
}
|
||||
send_message(RECEIVE_PARAMETER_VALUE, msg->str, msg->len);
|
||||
g_string_free(msg, TRUE);
|
||||
}
|
||||
@@ -846,11 +1160,12 @@ GList *get_message_list(MessageID id)
|
||||
g_error("get_message_list() doesn't support followning id: %d", id);
|
||||
g_string_free(data, TRUE);
|
||||
g_list_free(list);
|
||||
g_assert(!"BUG");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (amt) {
|
||||
g_message("%d messages left", amt);
|
||||
debug_msg(DEBUG_VERBOSE, "%d messages left", amt);
|
||||
data = g_queue_pop_nth(message_queue, x);
|
||||
if (data == NULL) {
|
||||
g_cond_wait(message_queue_cond, message_queue_mutex);
|
||||
@@ -1058,9 +1373,11 @@ static gboolean request_who_am_i(unsigned char *device_id, unsigned char *family
|
||||
*device_id = data->str[8];
|
||||
*family_id = data->str[9];
|
||||
*product_id = data->str[10];
|
||||
g_message("I am device id %d family %d product id %d.",
|
||||
*device_id, *family_id, *product_id);
|
||||
g_string_free(data, TRUE);
|
||||
debug_msg(DEBUG_STARTUP, "Found device id %d family %d product id %d.",
|
||||
*device_id,
|
||||
*family_id,
|
||||
*product_id);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -1107,6 +1424,25 @@ static void request_device_configuration()
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{"device", 'd', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &device_port, "MIDI device port to use", NULL},
|
||||
{"debug-flags <flags>", 'D', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, set_debug_flags,
|
||||
"<flags> any of a, d, g, h, m, s, x, v:\n"
|
||||
" "
|
||||
"a: Everything.\n"
|
||||
" "
|
||||
"d: Messages to the device.\n"
|
||||
" "
|
||||
"g: Group messages.\n"
|
||||
" "
|
||||
"h: Dump message contents in hex.\n"
|
||||
" "
|
||||
"m: All messages.\n"
|
||||
" "
|
||||
"s: Startup.\n"
|
||||
" "
|
||||
"x: Debug xml parsing/writing.\n"
|
||||
" "
|
||||
"v: Additional verbosity.\n" ,
|
||||
NULL},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -1132,6 +1468,7 @@ static gint get_digitech_devices(GList **devices)
|
||||
number++;
|
||||
*devices = g_list_append(*devices, GINT_TO_POINTER(card_num));
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
|
||||
return number;
|
||||
@@ -1151,7 +1488,7 @@ int main(int argc, char *argv[]) {
|
||||
g_option_context_add_group(context, gtk_get_option_group(TRUE));
|
||||
|
||||
if (!g_option_context_parse(context, &argc, &argv, &error)) {
|
||||
g_message("option parsing failed: %s\n", error->message);
|
||||
g_warning("option parsing failed: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
g_option_context_free(context);
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -1159,12 +1496,12 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (device_port == NULL) {
|
||||
/* port not given explicitly in commandline - search for devices */
|
||||
GList *devices = NULL;
|
||||
GList *device = NULL;
|
||||
int num_devices = 0;
|
||||
int chosen_device = 0;
|
||||
GList *devices = NULL;
|
||||
GList *device = NULL;
|
||||
int num_devices = 0;
|
||||
int chosen_device = 0;
|
||||
if ((num_devices = get_digitech_devices(&devices)) <= 0) {
|
||||
g_message("Couldn't find any DigiTech devices!");
|
||||
g_warning("Couldn't find DigiTech devices!");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (num_devices > 1) {
|
||||
@@ -1178,9 +1515,9 @@ int main(int argc, char *argv[]) {
|
||||
device_port = g_strdup_printf("hw:%d,0,0",
|
||||
GPOINTER_TO_INT(device->data));
|
||||
g_list_free(devices);
|
||||
g_message("Found device %s", device_port);
|
||||
debug_msg(DEBUG_STARTUP, "Found device %s.", device_port);
|
||||
} else {
|
||||
g_message("Using device %s", device_port);
|
||||
debug_msg(DEBUG_STARTUP, "Using device %s.", device_port);
|
||||
}
|
||||
|
||||
g_option_context_free(context);
|
||||
@@ -1208,14 +1545,14 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (device != NULL) {
|
||||
/* enable GUI mode */
|
||||
set_option(GUI_MODE_ON_OFF, USB_POSITION, 1);
|
||||
set_option(GUI_MODE_ON_OFF, GLOBAL_POSITION, 1);
|
||||
|
||||
gui_create(device);
|
||||
gtk_main();
|
||||
gui_free();
|
||||
|
||||
/* disable GUI mode */
|
||||
set_option(GUI_MODE_ON_OFF, USB_POSITION, 0);
|
||||
set_option(GUI_MODE_ON_OFF, GLOBAL_POSITION, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1229,8 +1566,8 @@ int main(int argc, char *argv[]) {
|
||||
g_mutex_free(message_queue_mutex);
|
||||
}
|
||||
|
||||
if (message_queue != NULL) {
|
||||
g_message("%d unread messages in queue",
|
||||
if (message_queue != NULL && g_queue_get_length(message_queue)) {
|
||||
g_warning("%d unread messages in queue",
|
||||
g_queue_get_length(message_queue));
|
||||
g_queue_foreach(message_queue, (GFunc) message_free_func, NULL);
|
||||
g_queue_free(message_queue);
|
||||
|
||||
@@ -4,4 +4,5 @@ Type=Application
|
||||
Name=gdigi
|
||||
Exec=gdigi
|
||||
Categories=GNOME;Audio;AudioVideo;
|
||||
Icon=gdigi
|
||||
|
||||
|
||||
42
gdigi.h
42
gdigi.h
@@ -22,6 +22,19 @@
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
typedef enum {
|
||||
DEBUG_MSG2DEV = (1 << 0), // Device bound messages.
|
||||
DEBUG_MSG2HOST = (1 << 1), // Host bound messages.
|
||||
DEBUG_STARTUP = (1 << 2),
|
||||
DEBUG_GROUP = (1 << 3), // Modifier group
|
||||
DEBUG_HEX = (1 << 4), // Dump message contents in hex.
|
||||
DEBUG_XML = (1 << 5),
|
||||
DEBUG_VERBOSE = (1 << 6),
|
||||
} debug_flags_t;
|
||||
|
||||
void debug_msg (debug_flags_t, char *fmt, ...);
|
||||
gboolean debug_flag_is_set (debug_flags_t flag);
|
||||
|
||||
#define GNX_CHANNEL_POSITION 7
|
||||
#define GNX_CHANNEL_AMP 260
|
||||
#define GNX_WARP 261
|
||||
@@ -315,7 +328,7 @@ enum {
|
||||
|
||||
#define AMP_TYPE 2496
|
||||
#define AMP_ON_OFF 265
|
||||
#define AMP_POSITION 8
|
||||
#define AMP_A_POSITION 8
|
||||
#define AMP_B_POSITION 10
|
||||
|
||||
#define AMP_LOOP_ON_OFF 3649
|
||||
@@ -427,7 +440,6 @@ enum {
|
||||
#define EQ_TREB_FREQ 3211
|
||||
#define EQ_ENABLE 3212
|
||||
|
||||
|
||||
#define EQ_LOW_FREQ 3213
|
||||
#define EQ_MID_FREQ_XXX 3214
|
||||
#define EQ_HIGH_FREQ 3215
|
||||
@@ -518,7 +530,6 @@ enum {
|
||||
};
|
||||
|
||||
#define MOD_TYPE 768
|
||||
#define MOD_POSITION 768
|
||||
#define MOD_PRE_POST 1798
|
||||
|
||||
#define CHORUSFX_TYPE 768
|
||||
@@ -731,7 +742,7 @@ enum {
|
||||
IPS_SCALE_LYDIAN = 4,
|
||||
IPS_SCALE_HMINOR = 5,
|
||||
};
|
||||
|
||||
|
||||
#define OCTAVER_OCTAVE1 1746
|
||||
#define OCTAVER_OCTAVE2 1747
|
||||
#define OCTAVER_DRY_LEVEL 1748
|
||||
@@ -842,7 +853,7 @@ enum {
|
||||
#define EXP_POSITION 19
|
||||
|
||||
#define EXP_VOLUME_PRE_FX 854594
|
||||
#define EXP_VOLUME_POST_FX 1116738
|
||||
#define EXP_VOLUME_POST_FX 1116738
|
||||
|
||||
#define EXP_MIN 8195
|
||||
#define EXP_MAX 8196
|
||||
@@ -855,7 +866,7 @@ enum {
|
||||
|
||||
#define LFO_WAVEFORM_TRI 0
|
||||
#define LFO_WAVEFORM_SINE 1
|
||||
#define LFO_WAVEFORM_SQUARE 2
|
||||
#define LFO_WAVEFORM_SQUARE 2
|
||||
|
||||
#define LFO1_POSITION 22
|
||||
#define LFO2_POSITION 23
|
||||
@@ -864,7 +875,7 @@ enum {
|
||||
#define LFO_ASSIGN_NONE 0
|
||||
#define LFO_ASSIGN_PICKUP_ON 131137
|
||||
#define LFO_ASSIGN_COMP_ON 262337
|
||||
#define LFO_ASSIGN_SUSTAN 262352
|
||||
#define LFO_ASSIGN_SUSTAN 262352
|
||||
|
||||
#define VSWITCH_ASSIGN 8384
|
||||
#define VSWITCH_MIN 8385
|
||||
@@ -881,12 +892,14 @@ enum {
|
||||
#define LIBRARY_EFFECTS 8705
|
||||
#define EFFECTS_LEVEL 8706
|
||||
|
||||
#define LIBRARY_POSITION 25
|
||||
#define LIB_POSITION 26
|
||||
#define LIB_POSITION_A 26
|
||||
#define LIB_POSITION_B 25
|
||||
|
||||
#define TONE_LIB_TYPE 8704
|
||||
#define FX_LIB_TYPE 8705
|
||||
#define FX_LIB_LEVEL 8706
|
||||
#define FX_LIB_LEVEL 8706 // This influences pitch shift mix, delay level,
|
||||
// and reverb level, in proportion, as
|
||||
// specified by FX_LIB_LEVEL_MAX1,2,3.
|
||||
#define FX_LIB_LEVEL_MAX1 8708
|
||||
#define FX_LIB_LEVEL_MAX2 8710
|
||||
#define FX_LIB_LEVEL_MAX3 8712
|
||||
@@ -963,12 +976,17 @@ enum {
|
||||
EFFECTS_LIB_CUSTOM = 1856
|
||||
};
|
||||
|
||||
#define USB_POSITION 0
|
||||
#define GLOBAL_POSITION 0
|
||||
|
||||
#define TUNING_REFERENCE 12288
|
||||
#define USB_AUDIO_PLAYBACK_MIX 12297
|
||||
#define USB_AUDIO_LEVEL 12307
|
||||
|
||||
#define GUI_MODE_ON_OFF 12298
|
||||
|
||||
#define EXP_PEDAL_LEVEL 12300
|
||||
#define STOMP_MODE 12370
|
||||
|
||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||
|
||||
typedef enum {
|
||||
@@ -1114,6 +1132,7 @@ void setting_genetx_free(SettingGenetx *genetx);
|
||||
void setting_param_free(SettingParam *param);
|
||||
SectionID get_genetx_section_id(gint version, gint type);
|
||||
void set_option(guint id, guint position, guint value);
|
||||
void get_option(guint id, guint position);
|
||||
void send_object(SectionID section, guint bank, guint index,
|
||||
gchar *name, GString *data);
|
||||
void send_preset_parameters(GList *params);
|
||||
@@ -1123,5 +1142,6 @@ void set_preset_level(int level);
|
||||
GStrv query_preset_names(gchar bank);
|
||||
void message_list_free(GList *list);
|
||||
GList *get_current_preset();
|
||||
GString *format_ipv(guint id, guint pos, guint val);
|
||||
|
||||
#endif /* GDIGI_H */
|
||||
|
||||
@@ -33,7 +33,8 @@ typedef struct {
|
||||
guint xml_labels_amt;
|
||||
} XmlSettings;
|
||||
|
||||
// XmlSettings *get_xml_settings(guint id, guint position);
|
||||
// gchar *get_xml_label(guint id, guint position, gint type);
|
||||
XmlSettings *get_xml_settings(guint id, guint position);
|
||||
gboolean value_is_extra(EffectValues *val, int value);
|
||||
gchar * map_xml_value(XmlSettings *xml, EffectValues *values, gint value);
|
||||
|
||||
#endif /* GDIGI_XML_H */
|
||||
|
||||
38
gtkknob.c
38
gtkknob.c
@@ -18,7 +18,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
@@ -153,6 +154,7 @@ gtk_knob_init (GtkKnob *knob) {
|
||||
gtk_widget_set_has_window(GTK_WIDGET(knob), FALSE);
|
||||
gtk_widget_set_hexpand(GTK_WIDGET(knob), FALSE);
|
||||
gtk_widget_set_vexpand(GTK_WIDGET(knob), FALSE);
|
||||
gtk_widget_add_events(GTK_WIDGET(knob), GDK_SCROLL_MASK);
|
||||
}
|
||||
|
||||
|
||||
@@ -367,7 +369,7 @@ gtk_knob_get_preferred_width(GtkWidget *widget,
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_KNOB (widget));
|
||||
|
||||
*minimum_width = *natural_width = GTK_KNOB(widget)->width;
|
||||
*minimum_width = *natural_width = GTK_KNOB(widget)->width;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -378,7 +380,7 @@ gtk_knob_get_preferred_height(GtkWidget *widget,
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_KNOB (widget));
|
||||
|
||||
*minimum_height = *natural_height = GTK_KNOB(widget)->height;
|
||||
*minimum_height = *natural_height = GTK_KNOB(widget)->height;
|
||||
}
|
||||
|
||||
|
||||
@@ -624,7 +626,7 @@ static gint gtk_knob_key_press(GtkWidget *widget, GdkEventKey *event)
|
||||
static gint
|
||||
gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
|
||||
GtkKnob *knob;
|
||||
GdkModifierType mods;
|
||||
GdkWindow *window;
|
||||
gint x, y;
|
||||
|
||||
g_return_val_if_fail (widget != NULL, FALSE);
|
||||
@@ -636,10 +638,6 @@ gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
|
||||
x = event->x;
|
||||
y = event->y;
|
||||
|
||||
if (event->is_hint || (event->window != gtk_widget_get_window(widget))) {
|
||||
gdk_window_get_pointer(gtk_widget_get_window(widget), &x, &y, &mods);
|
||||
}
|
||||
|
||||
switch (knob->state) {
|
||||
|
||||
case STATE_PRESSED:
|
||||
@@ -647,14 +645,22 @@ gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
|
||||
/* fall through */
|
||||
|
||||
case STATE_DRAGGING:
|
||||
if (mods & GDK_BUTTON1_MASK) {
|
||||
gtk_knob_update_mouse (knob, x, y, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (mods & GDK_BUTTON3_MASK) {
|
||||
gtk_knob_update_mouse (knob, x, y, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
window = gtk_widget_get_window(widget);
|
||||
if (event->is_hint || (event->window != window)) {
|
||||
GdkModifierType mods;
|
||||
GdkDeviceManager *device_manager = gdk_display_get_device_manager(gdk_window_get_display(window));
|
||||
GdkDevice *pointer = gdk_device_manager_get_client_pointer(device_manager);
|
||||
|
||||
gdk_window_get_device_position(window, pointer, &x, &y, &mods);
|
||||
if (mods & GDK_BUTTON1_MASK) {
|
||||
gtk_knob_update_mouse (knob, x, y, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (mods & GDK_BUTTON3_MASK) {
|
||||
gtk_knob_update_mouse (knob, x, y, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA.
|
||||
*****************************************************************************/
|
||||
#ifndef __GTK_KNOB_H__
|
||||
#define __GTK_KNOB_H__
|
||||
@@ -50,7 +51,7 @@ typedef enum
|
||||
gint height; /* derived from image height. */
|
||||
gint frame_width; /* derived from pixbuf (width / height) or provided override for rectangular frames */
|
||||
};
|
||||
|
||||
|
||||
struct _GtkKnob {
|
||||
GtkWidget widget;
|
||||
|
||||
@@ -68,7 +69,7 @@ typedef enum
|
||||
/* knob animation */
|
||||
GtkKnobAnim *anim;
|
||||
gint width, height;
|
||||
|
||||
|
||||
/* Old values from adjustment stored so we know when something changes */
|
||||
gdouble old_value;
|
||||
gdouble old_lower;
|
||||
|
||||
409
gui.c
409
gui.c
@@ -23,6 +23,73 @@
|
||||
#include "effects.h"
|
||||
#include "preset.h"
|
||||
#include "gtkknob.h"
|
||||
#include "images/gdigi_icon.h"
|
||||
#include "gdigi_xml.h"
|
||||
|
||||
|
||||
static gchar* MessageID_names[] = {
|
||||
[REQUEST_WHO_AM_I] = "REQUEST_WHO_AM_I",
|
||||
[RECEIVE_WHO_AM_I] = "RECEIVE_WHO_AM_I",
|
||||
|
||||
[REQUEST_DEVICE_CONFIGURATION] = "REQUEST_DEVICE_CONFIGURATION",
|
||||
[RECEIVE_DEVICE_CONFIGURATION] = "RECEIVE_DEVICE_CONFIGURATION",
|
||||
|
||||
[REQUEST_GLOBAL_PARAMETERS] = "REQUEST_GLOBAL_PARAMETERS",
|
||||
[RECEIVE_GLOBAL_PARAMETERS] = "RECEIVE_GLOBAL_PARAMETERS",
|
||||
|
||||
[REQUEST_BULK_DUMP] = "REQUEST_BULK_DUMP",
|
||||
[RECEIVE_BULK_DUMP_START] = "RECEIVE_BULK_DUMP_START",
|
||||
[RECEIVE_BULK_DUMP_END] = "RECEIVE_BULK_DUMP_END",
|
||||
|
||||
[REQUEST_PRESET_NAMES] = "REQUEST_PRESET_NAMES",
|
||||
[RECEIVE_PRESET_NAMES] = "RECEIVE_PRESET_NAMES",
|
||||
|
||||
[REQUEST_PRESET_NAME] = "REQUEST_PRESET_NAME",
|
||||
[RECEIVE_PRESET_NAME] = "RECEIVE_PRESET_NAME",
|
||||
|
||||
[REQUEST_PRESET] = "REQUEST_PRESET",
|
||||
[RECEIVE_PRESET_START] = "RECEIVE_PRESET_START",
|
||||
[RECEIVE_PRESET_END] = "RECEIVE_PRESET_END",
|
||||
[RECEIVE_PRESET_PARAMETERS] = "RECEIVE_PRESET_PARAMETERS",
|
||||
|
||||
[LOAD_EDIT_BUFFER_PRESET] = "LOAD_EDIT_BUFFER_PRESET",
|
||||
|
||||
[MOVE_PRESET] = "MOVE_PRESET",
|
||||
|
||||
[REQUEST_MODIFIER_LINKABLE_LIST] = "REQUEST_MODIFIER_LINKABLE_LIST",
|
||||
[RECEIVE_MODIFIER_LINKABLE_LIST] = "RECEIVE_MODIFIER_LINKABLE_LIST",
|
||||
|
||||
[REQUEST_PARAMETER_VALUE] = "REQUEST_PARAMETER_VALUE",
|
||||
[RECEIVE_PARAMETER_VALUE] = "RECEIVE_PARAMETER_VALUE",
|
||||
|
||||
/* version 1 and later */
|
||||
[REQUEST_OBJECT_NAMES] = "REQUEST_OBJECT_NAMES",
|
||||
[RECEIVE_OBJECT_NAMES] = "RECEIVE_OBJECT_NAMES",
|
||||
[REQUEST_OBJECT_NAME] = "REQUEST_OBJECT_NAME",
|
||||
[RECEIVE_OBJECT_NAME] = "RECEIVE_OBJECT_NAME",
|
||||
[REQUEST_OBJECT] = "REQUEST_OBJECT",
|
||||
[RECEIVE_OBJECT] = "RECEIVE_OBJECT",
|
||||
[MOVE_OBJECT] = "MOVE_OBJECT",
|
||||
[DELETE_OBJECT] = "DELETE_OBJECT",
|
||||
[REQUEST_TABLE] = "REQUEST_TABLE",
|
||||
[RECEIVE_TABLE] = "RECEIVE_TABLE",
|
||||
|
||||
[RECEIVE_DEVICE_NOTIFICATION] = "RECEIVE_DEVICE_NOTIFICATION",
|
||||
|
||||
[ACK] = "ACK",
|
||||
[NACK] = "NACK",
|
||||
};
|
||||
|
||||
const gchar*
|
||||
get_message_name(MessageID msgid)
|
||||
{
|
||||
if (MessageID_names[msgid]) {
|
||||
return MessageID_names[msgid];
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GObject *widget;
|
||||
@@ -54,7 +121,7 @@ void show_error_message(GtkWidget *parent, gchar *message)
|
||||
GTK_BUTTONS_OK,
|
||||
"%s", message);
|
||||
|
||||
gtk_dialog_run(GTK_DIALOG(msg));
|
||||
(void)gtk_dialog_run(GTK_DIALOG(msg));
|
||||
gtk_widget_destroy(msg);
|
||||
}
|
||||
|
||||
@@ -184,7 +251,7 @@ static gboolean custom_value_output_cb(GtkSpinButton *spin, EffectValues *values
|
||||
if (values->type & VALUE_TYPE_EXTRA) {
|
||||
values = values->extra;
|
||||
} else {
|
||||
g_message("custom_value_output_cb called with out of bounds value");
|
||||
g_warning("custom_value_output_cb called with out of bounds value");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -306,8 +373,9 @@ static void apply_widget_setting(WidgetTreeElem *el, SettingParam *param)
|
||||
else if (GTK_IS_ADJUSTMENT(el->widget))
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(el->widget), (gdouble)param->value);
|
||||
} else { /* combo box */
|
||||
if (el->value == param->value)
|
||||
if (el->value == param->value) {
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(el->widget), el->x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,6 +443,56 @@ gboolean apply_current_preset_to_gui(gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the data associated with the dynamically allocated settings
|
||||
* for the EXP_POSITION.
|
||||
*/
|
||||
void modifier_settings_exp_free(EffectSettings *settings)
|
||||
{
|
||||
guint i;
|
||||
guint id = settings->id;
|
||||
guint pos = settings->position;
|
||||
gpointer key;
|
||||
GList *link, *next, *orig_list;
|
||||
WidgetTreeElem *el;
|
||||
GObject *widget;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
||||
id = settings[i].id;
|
||||
pos = settings[i].position;
|
||||
key = GINT_TO_POINTER(pos <<16| id);
|
||||
orig_list = g_tree_lookup(widget_tree, key);
|
||||
if (!orig_list) {
|
||||
continue;
|
||||
}
|
||||
|
||||
link = g_list_first(orig_list);
|
||||
while (link != NULL) {
|
||||
next = link->next;
|
||||
|
||||
el = link->data;
|
||||
if (el) {
|
||||
|
||||
widget = el->widget;
|
||||
if (g_object_get_data(G_OBJECT(widget), "exp")) {
|
||||
g_slice_free(WidgetTreeElem, el);
|
||||
link->data = NULL;
|
||||
}
|
||||
}
|
||||
link = next;
|
||||
}
|
||||
|
||||
/* Remove all the list elements from which we freed data. */
|
||||
orig_list = g_list_remove_all(orig_list, NULL);
|
||||
|
||||
/* The list should be empty at this point. */
|
||||
g_assert(!orig_list);
|
||||
|
||||
/* Removed them all, so remove the key from the tree.*/
|
||||
g_tree_steal(widget_tree, key);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \param settings effect parameters
|
||||
* \param amt amount of effect parameters
|
||||
@@ -424,6 +542,12 @@ GtkWidget *create_grid(EffectSettings *settings, gint amt, GHashTable *widget_ta
|
||||
|
||||
widget_tree_add(G_OBJECT(adj), settings[x].id,
|
||||
settings[x].position, -1, -1);
|
||||
|
||||
if (settings[x].position == EXP_POSITION) {
|
||||
/* Tag the adj so we can free it when we free the modifier group. */
|
||||
g_object_set_data(G_OBJECT(adj), "exp", GINT_TO_POINTER(1));
|
||||
}
|
||||
|
||||
gtk_grid_attach(GTK_GRID(grid), label, 0, x, 1, 1);
|
||||
gtk_grid_attach(GTK_GRID(grid), knob, 1, x, 1, 1);
|
||||
gtk_grid_attach(GTK_GRID(grid), widget, 2, x, 1, 1);
|
||||
@@ -474,8 +598,9 @@ void effect_settings_group_free(EffectSettingsGroup *group)
|
||||
{
|
||||
if (group->child != NULL) {
|
||||
/* destroy widget without parent */
|
||||
if (gtk_widget_get_parent(group->child) == NULL)
|
||||
if (gtk_widget_get_parent(group->child) == NULL) {
|
||||
gtk_widget_destroy(group->child);
|
||||
}
|
||||
|
||||
g_object_unref(group->child);
|
||||
}
|
||||
@@ -496,32 +621,40 @@ void combo_box_changed_cb(GtkComboBox *widget, gpointer data)
|
||||
EffectSettingsGroup *settings = NULL;
|
||||
gchar *name = NULL;
|
||||
gint x;
|
||||
|
||||
g_object_get(G_OBJECT(widget), "active", &x, NULL);
|
||||
|
||||
vbox = g_object_get_data(G_OBJECT(widget), "vbox");
|
||||
|
||||
if (x != -1) {
|
||||
GtkWidget *new_child = NULL;
|
||||
|
||||
name = g_strdup_printf("SettingsGroup%d", x);
|
||||
settings = g_object_get_data(G_OBJECT(widget), name);
|
||||
g_free(name);
|
||||
|
||||
if (settings != NULL && allow_send)
|
||||
set_option(settings->id, settings->position, settings->type);
|
||||
|
||||
child = g_object_get_data(G_OBJECT(widget), "active_child");
|
||||
if (child == settings->child) {
|
||||
return;
|
||||
if (settings != NULL)
|
||||
{
|
||||
if (allow_send)
|
||||
set_option(settings->id, settings->position, settings->type);
|
||||
|
||||
if (child == settings->child) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (child != NULL) {
|
||||
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(gtk_widget_get_parent(vbox))), child);
|
||||
}
|
||||
|
||||
if (settings->child != NULL) {
|
||||
if (settings != NULL && settings->child != NULL) {
|
||||
gtk_container_add(GTK_CONTAINER(gtk_widget_get_parent(gtk_widget_get_parent(vbox))), settings->child);
|
||||
gtk_widget_show_all(gtk_widget_get_parent(gtk_widget_get_parent(vbox)));
|
||||
new_child = settings->child;
|
||||
}
|
||||
g_object_set_data(G_OBJECT(widget), "active_child", settings->child);
|
||||
|
||||
g_object_set_data(G_OBJECT(widget), "active_child", new_child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +679,7 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p
|
||||
gint x;
|
||||
gint cmbox_no = -1;
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
|
||||
widget_table = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
|
||||
@@ -558,15 +691,22 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p
|
||||
g_signal_connect(G_OBJECT(combo_box), "changed", G_CALLBACK(combo_box_changed_cb), group);
|
||||
g_object_set_data(G_OBJECT(combo_box), "vbox", vbox);
|
||||
}
|
||||
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo_box),
|
||||
NULL, group[x].label);
|
||||
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), group[x].label);
|
||||
cmbox_no++;
|
||||
|
||||
if ((group[x].settings != NULL) && (group[x].settings_amt > 0)) {
|
||||
widget = create_grid(group[x].settings, group[x].settings_amt, widget_table);
|
||||
/*
|
||||
* Create a grid for each combo box entry to contain per
|
||||
* combo box entry settings.
|
||||
*/
|
||||
widget = create_grid(group[x].settings,
|
||||
group[x].settings_amt,
|
||||
widget_table);
|
||||
g_object_ref_sink(widget);
|
||||
} else
|
||||
} else {
|
||||
widget = NULL;
|
||||
}
|
||||
|
||||
settings = g_slice_new(EffectSettingsGroup);
|
||||
settings->id = id;
|
||||
@@ -577,11 +717,15 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p
|
||||
widget_tree_add(G_OBJECT(combo_box), id, position, group[x].type, x);
|
||||
|
||||
name = g_strdup_printf("SettingsGroup%d", cmbox_no);
|
||||
g_object_set_data_full(G_OBJECT(combo_box), name, settings, ((GDestroyNotify)effect_settings_group_free));
|
||||
g_object_set_data_full(G_OBJECT(combo_box),
|
||||
name, settings,
|
||||
((GDestroyNotify)effect_settings_group_free));
|
||||
g_free(name);
|
||||
} else {
|
||||
if ((group[x].settings != NULL) && (group[x].settings_amt > 0)) {
|
||||
widget = create_grid(group[x].settings, group[x].settings_amt, widget_table);
|
||||
widget = create_grid(group[x].settings,
|
||||
group[x].settings_amt,
|
||||
widget_table);
|
||||
gtk_box_pack_end(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
|
||||
}
|
||||
}
|
||||
@@ -592,6 +736,157 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p
|
||||
return vbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the vbox for an effect dependent on the modifier list.
|
||||
*
|
||||
* \param vbox The vbox for the effect.
|
||||
* \param combo_box The combo box to repopulate.
|
||||
* \param id The id of the effect.
|
||||
* \param position The position of the effect.
|
||||
*/
|
||||
static void update_modifier_vbox(GtkWidget *vbox, GObject *combo_box, gint id, gint position)
|
||||
{
|
||||
gint x;
|
||||
EffectSettingsGroup *settings = NULL;
|
||||
EffectGroup *group = get_modifier_group();
|
||||
guint amt = get_modifier_amt();
|
||||
GtkWidget *child = NULL;
|
||||
GHashTable *widget_table;
|
||||
|
||||
widget_table = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
|
||||
for (x = 0; x<amt; x++) {
|
||||
gchar *name;
|
||||
g_assert(group[x].label);
|
||||
|
||||
settings = g_slice_new(EffectSettingsGroup);
|
||||
settings->id = id;
|
||||
settings->type = group[x].type;
|
||||
settings->position = position;
|
||||
|
||||
if (position == EXP_POSITION) {
|
||||
child = g_object_steal_data(G_OBJECT(combo_box), "active_child");
|
||||
child = create_grid(group[x].settings, group[x].settings_amt,
|
||||
widget_table);
|
||||
g_object_ref_sink(child);
|
||||
settings->child = child;
|
||||
} else {
|
||||
/* LFO has one settings group.*/
|
||||
settings->child = NULL;
|
||||
}
|
||||
|
||||
name = g_strdup_printf("SettingsGroup%d", x);
|
||||
g_object_set_data(G_OBJECT(combo_box), name, settings);
|
||||
g_free(name);
|
||||
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), group[x].label);
|
||||
widget_tree_add(combo_box, id, position, group[x].type, x);
|
||||
}
|
||||
|
||||
g_hash_table_destroy(widget_table);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void clean_modifier_combo_box(GObject *combo_box, GList *list)
|
||||
{
|
||||
EffectSettingsGroup *settings = NULL;
|
||||
WidgetTreeElem *el;
|
||||
gchar *name;
|
||||
GList *link, *next, *stale_link;
|
||||
|
||||
link = g_list_first(list);
|
||||
|
||||
while (link != NULL) {
|
||||
next = link->next;
|
||||
el = link->data;
|
||||
stale_link = NULL;
|
||||
|
||||
/* We need to clean the data associated with a combo box.
|
||||
* This may include the per-entry settings widgets.
|
||||
*/
|
||||
if (el->value != -1) {
|
||||
/* This is a combo box entry. Remove the associated data. */
|
||||
stale_link = link;
|
||||
link = g_list_remove_link(list, link);
|
||||
|
||||
name = g_strdup_printf("SettingsGroup%d", el->x);
|
||||
settings = g_object_steal_data(G_OBJECT(combo_box), name);
|
||||
if (settings && settings->child) {
|
||||
gtk_widget_destroy(settings->child);
|
||||
}
|
||||
|
||||
g_slice_free(EffectSettingsGroup, settings);
|
||||
g_free(name);
|
||||
g_slice_free(WidgetTreeElem, el);
|
||||
}
|
||||
|
||||
if (stale_link) {
|
||||
g_list_free_1(stale_link);
|
||||
}
|
||||
|
||||
link = next;
|
||||
}
|
||||
gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(combo_box));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a linkable effect, update the combo box for the linkable parameters.
|
||||
*
|
||||
* @param[in] pos Position
|
||||
* @param[in] id Id
|
||||
*/
|
||||
void
|
||||
create_modifier_group (guint pos, guint id)
|
||||
{
|
||||
|
||||
GtkWidget *vbox;
|
||||
gpointer key;
|
||||
WidgetTreeElem *el;
|
||||
GList *list;
|
||||
GObject *modifier_combo_box;
|
||||
|
||||
debug_msg(DEBUG_GROUP, "Building modifier group for position %d id %d \"%s\"",
|
||||
pos, id, get_xml_settings(id, pos)->label);
|
||||
|
||||
key = GINT_TO_POINTER((pos << 16) | id);
|
||||
list = g_tree_lookup(widget_tree, key);
|
||||
|
||||
/*
|
||||
* The list will be destroyed and recreated, but we don't want to
|
||||
* handle the teardown ourselves. So steal it from the tree.
|
||||
*/
|
||||
g_tree_steal(widget_tree, key);
|
||||
if (!list) {
|
||||
return;
|
||||
}
|
||||
|
||||
el = g_list_nth_data(list, 0);
|
||||
if (!el) {
|
||||
g_warning("No effect settings group for position %d id %d!\n",
|
||||
pos, id);
|
||||
return;
|
||||
}
|
||||
|
||||
modifier_combo_box = el->widget;
|
||||
g_assert(modifier_combo_box != NULL);
|
||||
|
||||
vbox = g_object_get_data(modifier_combo_box, "vbox");
|
||||
g_assert(vbox != NULL);
|
||||
|
||||
clean_modifier_combo_box(modifier_combo_box, list);
|
||||
|
||||
update_modifier_vbox(vbox, modifier_combo_box, id, pos);
|
||||
|
||||
get_option(id, pos);
|
||||
|
||||
if (pos == EXP_POSITION) {
|
||||
get_option(EXP_MIN, EXP_POSITION);
|
||||
get_option(EXP_MAX, EXP_POSITION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \param widgets Effect descriptions
|
||||
* \param amt amount of effect descriptions
|
||||
@@ -613,13 +908,14 @@ GtkWidget *create_vbox(Effect *widgets, gint amt, gchar *label)
|
||||
|
||||
frame = gtk_frame_new(label);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
|
||||
grid = gtk_grid_new();
|
||||
gtk_grid_set_column_spacing(GTK_GRID(grid), 2);
|
||||
|
||||
for (x = 0; x<amt; x++) {
|
||||
if ((widgets[x].id != -1) && (widgets[x].position != -1)) {
|
||||
|
||||
widget = create_on_off_button(&widgets[x]);
|
||||
gtk_grid_attach(GTK_GRID(grid), widget, 0, x, 1, 1);
|
||||
|
||||
@@ -629,21 +925,29 @@ GtkWidget *create_vbox(Effect *widgets, gint amt, gchar *label)
|
||||
y = 0;
|
||||
|
||||
} else if (widgets[x].label) {
|
||||
|
||||
widget = gtk_label_new(widgets[x].label);
|
||||
gtk_grid_attach(GTK_GRID(grid), widget, 0, x, 1, 1);
|
||||
y = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Default to 1 */
|
||||
if (x == 0)
|
||||
y = 1;
|
||||
}
|
||||
|
||||
container = create_widget_container(widgets[x].group, widgets[x].group_amt, widgets[x].type, widgets[x].position);
|
||||
container = create_widget_container(widgets[x].group,
|
||||
widgets[x].group_amt,
|
||||
widgets[x].type,
|
||||
widgets[x].position);
|
||||
|
||||
gtk_grid_attach(GTK_GRID(grid), container, 1-y, x+y, 1, 1);
|
||||
}
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(vbox), grid, FALSE, FALSE, 2);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -844,15 +1148,22 @@ static void action_show_about_dialog_cb(GtkAction *action)
|
||||
"Stephen Rigler <riglersc@gmail.com>",
|
||||
"Jaco Kroon <jaco@kroon.co.za>",
|
||||
"Rafael Moreno <laocanfei@yahoo.com>",
|
||||
"Andrew O. Shadoura <bugzilla@tut.by>",
|
||||
"Andrew Shadura <bugzilla@tut.by>",
|
||||
"Andreas Karajannis <aakara13@googlemail.com>",
|
||||
"Miklos Aubert <miklos.aubert@gmail.com>",
|
||||
"Jonathan A. Tice <jonandtice@gmail.com>",
|
||||
"John Hammen <jhammen@gmail.com>",
|
||||
"Ahmed Toulan <thelinuxer@gmail.com>",
|
||||
"Tim LaBerge <tlaberge@visi.com>",
|
||||
"Mauro Carvalho Chehab <maurochehab@gmail.com>",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const gchar * const artists[] = {
|
||||
"Islam Alwazery <wazery@ubuntu.com>",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const gchar copyright[] = "Copyright \xc2\xa9 2009 Tomasz Moń";
|
||||
static const gchar website[] = "http://desowin.org/gdigi/";
|
||||
static const gchar version[] = "0.3.0";
|
||||
@@ -861,6 +1172,7 @@ static void action_show_about_dialog_cb(GtkAction *action)
|
||||
|
||||
gtk_show_about_dialog(GTK_WINDOW(window),
|
||||
"authors", authors,
|
||||
"artists", artists,
|
||||
"copyright", copyright,
|
||||
"website", website,
|
||||
"license-type", GTK_LICENSE_GPL_3_0,
|
||||
@@ -891,7 +1203,7 @@ SupportedFileTypes file_types[] = {
|
||||
|
||||
static guint n_file_types = G_N_ELEMENTS(file_types);
|
||||
|
||||
gchar *
|
||||
gchar *
|
||||
get_preset_filename (int prod_id)
|
||||
{
|
||||
return file_types[prod_id].name;
|
||||
@@ -928,7 +1240,7 @@ static void action_open_preset_cb(GtkAction *action)
|
||||
for (x=0; x<n_file_types; x++) {
|
||||
GtkFileFilter *current_filter = gtk_file_filter_new();
|
||||
if (file_types[x].name == NULL) {
|
||||
g_message("Skipping NULL array entry");
|
||||
g_warning("Skipping NULL array entry");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -938,7 +1250,6 @@ static void action_open_preset_cb(GtkAction *action)
|
||||
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), current_filter);
|
||||
if (x == product_id) {
|
||||
|
||||
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), current_filter);
|
||||
}
|
||||
|
||||
@@ -1008,10 +1319,9 @@ static void action_open_preset_cb(GtkAction *action)
|
||||
section = get_genetx_section_id(genetx->version,
|
||||
genetx->type);
|
||||
bank = 0x04;
|
||||
index = genetx->channel;
|
||||
|
||||
if (i == 0) {
|
||||
index = genetx->channel;
|
||||
} else {
|
||||
if (i != 0) {
|
||||
if (genetx->channel == GENETX_CHANNEL1) {
|
||||
index = GENETX_CHANNEL1_CUSTOM;
|
||||
} else if (genetx->channel == GENETX_CHANNEL2) {
|
||||
@@ -1061,15 +1371,10 @@ static void action_save_preset_cb(GtkAction *action)
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
GError *error = NULL;
|
||||
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
|
||||
|
||||
|
||||
if (error) {
|
||||
show_error_message(window, error->message);
|
||||
g_error_free(error);
|
||||
error = NULL;
|
||||
if (filename == NULL) {
|
||||
show_error_message(window, "No file name");
|
||||
} else {
|
||||
gchar real_filename[256];
|
||||
GList *list = get_current_preset();
|
||||
@@ -1082,8 +1387,8 @@ static void action_save_preset_cb(GtkAction *action)
|
||||
write_preset_to_xml(preset, real_filename);
|
||||
|
||||
preset_free(preset);
|
||||
g_free(filename);
|
||||
}
|
||||
g_free(filename);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
@@ -1190,7 +1495,7 @@ static void add_menubar(GtkWidget *window, GtkWidget *vbox)
|
||||
gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ui));
|
||||
|
||||
if (!gtk_ui_manager_add_ui_from_string(ui, menu_info, -1, &error)) {
|
||||
g_message("building menus failed: %s", error->message);
|
||||
g_warning("building menus failed: %s", error->message);
|
||||
g_error_free(error);
|
||||
error = NULL;
|
||||
}
|
||||
@@ -1233,18 +1538,23 @@ void gui_create(Device *device)
|
||||
GtkWidget *widget;
|
||||
GtkWidget *notebook;
|
||||
GtkWidget *sw; /* scrolled window to carry preset treeview */
|
||||
GdkPixbuf *icon;
|
||||
|
||||
gint x;
|
||||
gint i;
|
||||
|
||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(window), "gdigi");
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
icon = gdk_pixbuf_new_from_inline(-1, gdigi_icon, FALSE, NULL);
|
||||
gtk_window_set_icon(GTK_WINDOW(window), icon);
|
||||
|
||||
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||
|
||||
add_menubar(window, vbox);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add(GTK_CONTAINER(vbox), hbox);
|
||||
|
||||
sw = gtk_scrolled_window_new(NULL, NULL);
|
||||
@@ -1268,14 +1578,14 @@ void gui_create(Device *device)
|
||||
|
||||
for (i = 0; i<device->n_pages; i++) {
|
||||
GtkWidget *label = NULL;
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
label = gtk_label_new(device->pages[i].name);
|
||||
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
|
||||
|
||||
for (x = 0; x<device->pages[i].n_effects; x++) {
|
||||
if ((x % ((device->pages[i].n_effects+1)/device->pages[i].n_rows)) == 0) {
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 2);
|
||||
}
|
||||
widget = create_vbox(device->pages[i].effects[x].effect, device->pages[i].effects[x].amt, device->pages[i].effects[x].label);
|
||||
@@ -1287,6 +1597,10 @@ void gui_create(Device *device)
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), NULL);
|
||||
|
||||
/* Get the initial values for the linkable parameters and the globals. */
|
||||
send_message(REQUEST_MODIFIER_LINKABLE_LIST, "\x00\x01", 2);
|
||||
send_message(REQUEST_GLOBAL_PARAMETERS, "\x00\x01", 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1306,7 +1620,7 @@ void gui_free()
|
||||
*
|
||||
* Displays dialogbox stating that device is unsupported.
|
||||
*
|
||||
* \return TRUE if user selects "compability mode", otherwise FALSE.
|
||||
* \return TRUE if user selects "compatibility mode", otherwise FALSE.
|
||||
**/
|
||||
gboolean unsupported_device_dialog(Device **device)
|
||||
{
|
||||
@@ -1329,7 +1643,7 @@ gboolean unsupported_device_dialog(Device **device)
|
||||
|
||||
label = gtk_label_new("Your device appears to be unsupported by gdigi.\n"
|
||||
"As some of the settings may be common between different devices,\n"
|
||||
"you can now select compability mode with one of the supported devices.\n"
|
||||
"you can now select compatibility mode with one of the supported devices.\n"
|
||||
"Please take a look at gdigi's HACKING file.");
|
||||
gtk_container_add(GTK_CONTAINER(vbox), label);
|
||||
|
||||
@@ -1345,7 +1659,8 @@ gboolean unsupported_device_dialog(Device **device)
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
gint number = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_box));
|
||||
if (number != -1 && number <n_supported_devices) {
|
||||
g_message("Starting %s compability mode", supported_devices[number]->name);
|
||||
g_message("Starting %s compatibility mode",
|
||||
supported_devices[number]->name);
|
||||
*device = supported_devices[number];
|
||||
gtk_widget_destroy(dialog);
|
||||
return TRUE;
|
||||
@@ -1365,7 +1680,6 @@ gboolean unsupported_device_dialog(Device **device)
|
||||
**/
|
||||
gint select_device_dialog (GList *devices)
|
||||
{
|
||||
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *label;
|
||||
GtkWidget *combo_box;
|
||||
@@ -1385,13 +1699,14 @@ gint select_device_dialog (GList *devices)
|
||||
|
||||
combo_box = gtk_combo_box_text_new();
|
||||
device = g_list_first(devices);
|
||||
do {
|
||||
while (device != NULL) {
|
||||
char *name;
|
||||
|
||||
snd_card_get_longname(GPOINTER_TO_INT(device->data), &name);
|
||||
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo_box), NULL, name);
|
||||
|
||||
} while ((device = g_list_next(device)));
|
||||
device = g_list_next(device);
|
||||
};
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(vbox), combo_box);
|
||||
|
||||
|
||||
3
gui.h
3
gui.h
@@ -29,5 +29,8 @@ void gui_create(Device *device);
|
||||
void gui_free();
|
||||
gboolean unsupported_device_dialog(Device **device);
|
||||
gint select_device_dialog (GList *devices);
|
||||
const gchar* get_message_name(MessageID msgid);
|
||||
void create_modifier_group (guint pos, guint id);
|
||||
void modifier_settings_exp_free(EffectSettings *settings);
|
||||
|
||||
#endif /* GDIGI_GUI_H */
|
||||
|
||||
BIN
images/gdigi.png
Normal file
BIN
images/gdigi.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
images/icon.png
Normal file
BIN
images/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
33
preset.c
33
preset.c
@@ -69,7 +69,7 @@ static void XMLCALL start(void *data, const char *el, const char **attr) {
|
||||
if (g_strcmp0(el, "Params") == 0) {
|
||||
ad->section = SECTION_PARAMS;
|
||||
if (ad->preset->params != NULL)
|
||||
g_message("Params aleady exists!");
|
||||
g_warning("Params aleady exists!");
|
||||
} else if (g_strcmp0(el, "Param") == 0) {
|
||||
SettingParam *param = setting_param_new();
|
||||
ad->preset->params = g_list_prepend(ad->preset->params, param);
|
||||
@@ -84,7 +84,7 @@ static void XMLCALL start(void *data, const char *el, const char **attr) {
|
||||
} else if (g_strcmp0(el, "Genetx") == 0) {
|
||||
ad->section = SECTION_GENETX;
|
||||
if (ad->preset->genetxs != NULL)
|
||||
g_message("Genetx already exists!");
|
||||
g_warning("Genetx already exists!");
|
||||
} else if (g_strcmp0(el, "GenetxModel") == 0) {
|
||||
SettingGenetx *genetx = setting_genetx_new();
|
||||
ad->preset->genetxs = g_list_prepend(ad->preset->genetxs, genetx);
|
||||
@@ -160,7 +160,7 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
|
||||
} else if (g_strcmp0(value, "Version2") == 0) {
|
||||
genetx->version = GENETX_VERSION_2;
|
||||
} else {
|
||||
g_message("Unknown GeNetX version: %s", value);
|
||||
g_warning("Unknown GeNetX version: %s", value);
|
||||
}
|
||||
break;
|
||||
case PARSER_TYPE_GENETX_TYPE:
|
||||
@@ -169,7 +169,7 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
|
||||
} else if (g_strcmp0(value, "Cabinet") == 0) {
|
||||
genetx->type = GENETX_TYPE_CABINET;
|
||||
} else {
|
||||
g_message("Unknown GeNetX type: %s", value);
|
||||
g_warning("Unknown GeNetX type: %s", value);
|
||||
}
|
||||
break;
|
||||
case PARSER_TYPE_GENETX_CHANNEL:
|
||||
@@ -178,7 +178,7 @@ static void XMLCALL text_cb(void *data, const char* text, int len)
|
||||
} else if (g_strcmp0(value, "Channel2") == 0) {
|
||||
genetx->channel = GENETX_CHANNEL2;
|
||||
} else {
|
||||
g_message("Unknown GeNetX channel: %s", value);
|
||||
g_warning("Unknown GeNetX channel: %s", value);
|
||||
}
|
||||
break;
|
||||
case PARSER_TYPE_GENETX_NAME:
|
||||
@@ -219,7 +219,7 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
||||
gchar *contents;
|
||||
|
||||
if (g_file_get_contents(filename, &contents, NULL, &err) == FALSE) {
|
||||
g_message("Failed to get %s contents: %s", filename, err->message);
|
||||
g_warning("Failed to get %s contents: %s", filename, err->message);
|
||||
*error = g_error_copy(err);
|
||||
g_error_free(err);
|
||||
return NULL;
|
||||
@@ -308,12 +308,16 @@ Preset *create_preset_from_data(GList *list)
|
||||
modified = (unsigned char)data->str[11+strlen(name)];
|
||||
|
||||
if ((bank == PRESETS_EDIT_BUFFER) && (number == 0)) {
|
||||
g_message("Received current edit buffer");
|
||||
debug_msg(DEBUG_MSG2HOST,
|
||||
"RECEIVE_PRESET_START: current edit buffer");
|
||||
} else {
|
||||
g_message("Received preset %d from bank %d", number, bank);
|
||||
debug_msg(DEBUG_MSG2HOST,
|
||||
"RECEIVE_PRESET_START: preset %d from bank %d",
|
||||
number, bank);
|
||||
}
|
||||
|
||||
g_message("Modified flag: %d Name: %s", modified, name);
|
||||
debug_msg(DEBUG_MSG2HOST, "Name: %s, %sodified",
|
||||
name, modified ? "M" : "Not m");
|
||||
preset->name = name;
|
||||
break;
|
||||
case RECEIVE_PRESET_PARAMETERS:
|
||||
@@ -326,15 +330,20 @@ Preset *create_preset_from_data(GList *list)
|
||||
SettingParam *param = setting_param_new_from_data(&data->str[x], &x);
|
||||
n++;
|
||||
preset->params = g_list_prepend(preset->params, param);
|
||||
g_message("%d ID %d Position %d Value %d", n, param->id, param->position, param->value);
|
||||
if (debug_flag_is_set(DEBUG_MSG2HOST)) {
|
||||
GString *ipv = format_ipv(param->id, param->position, param->value);
|
||||
debug_msg(DEBUG_MSG2HOST, "%3d %s", n, ipv->str);
|
||||
g_string_free(ipv, TRUE);
|
||||
}
|
||||
} while ((x < data->len) && n<total);
|
||||
g_message("TOTAL %d", total);
|
||||
debug_msg(DEBUG_MSG2HOST, "TOTAL %d", total);
|
||||
preset->params = g_list_sort(preset->params, params_cmp);
|
||||
break;
|
||||
case RECEIVE_PRESET_END:
|
||||
break;
|
||||
default:
|
||||
g_message("Unhandled message in preset messages list");
|
||||
g_warning("Unhandled message 0x%x in preset messages list",
|
||||
get_message_id(data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
49
preset_xml.c
49
preset_xml.c
@@ -30,6 +30,7 @@
|
||||
extern XmlSettings xml_settings[];
|
||||
extern guint n_xml_settings;
|
||||
extern EffectValues values_on_off;
|
||||
|
||||
/**
|
||||
* \param id modifier ID
|
||||
* \param position modifier position
|
||||
@@ -52,16 +53,18 @@ XmlSettings *get_xml_settings (guint id, guint position)
|
||||
}
|
||||
|
||||
gchar *
|
||||
map_xml_value(XmlSettings *xml, gint value)
|
||||
map_xml_value (XmlSettings *xml, EffectValues *values, gint value)
|
||||
{
|
||||
switch (xml->values->type) {
|
||||
switch (values->type) {
|
||||
case VALUE_TYPE_LABEL:
|
||||
if ((xml->values == &values_on_off) && (value > 1)) {
|
||||
g_message("Skipping modifier->label %s\n", xml->label);
|
||||
if ((values == &values_on_off) && (value > 1)) {
|
||||
g_warning("Skipping modifier->label %s\n", xml->label);
|
||||
return NULL;
|
||||
}
|
||||
if (value > xml->values->max || value < xml->values->min) {
|
||||
g_message("%s value %d out of range %0.1f %0.1f", xml->label, value, xml->values->min, xml->values->max);
|
||||
|
||||
if (value > values->max || value < values->min) {
|
||||
g_warning("%s value %d out of range %0.1f %0.1f",
|
||||
xml->label, value, xml->values->min, xml->values->max);
|
||||
}
|
||||
{
|
||||
XmlLabel *labels = xml->xml_labels;
|
||||
@@ -83,10 +86,9 @@ map_xml_value(XmlSettings *xml, gint value)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
gboolean value_is_extra (EffectValues *val, SettingParam *param)
|
||||
gboolean value_is_extra (EffectValues *val, int value)
|
||||
{
|
||||
if ((param->value < val->min) || (param->value > val->max)) {
|
||||
if ((value < val->min) || (value > val->max)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -111,7 +113,7 @@ write_preset_to_xml(Preset *preset, gchar *filename)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Start the document with the xml default for the version,
|
||||
* encoding and the default for the standalone declaration.
|
||||
*/
|
||||
@@ -130,7 +132,7 @@ write_preset_to_xml(Preset *preset, gchar *filename)
|
||||
rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "SchemaVersion",
|
||||
BAD_CAST "1.2");
|
||||
|
||||
|
||||
|
||||
rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xmlns",
|
||||
BAD_CAST "http://www.digitech.com/xml/preset");
|
||||
|
||||
@@ -142,9 +144,9 @@ write_preset_to_xml(Preset *preset, gchar *filename)
|
||||
while (iter_params) {
|
||||
XmlSettings *xml;
|
||||
SettingParam *param = (SettingParam *) iter_params->data;
|
||||
|
||||
|
||||
if (param->id == last_id && param->position == last_position) {
|
||||
g_message("Skipping duplicate parameter id %d position %d",
|
||||
g_warning("Skipping duplicate parameter id %d position %d",
|
||||
last_id, last_position);
|
||||
iter_params = iter_params->next;
|
||||
continue;
|
||||
@@ -177,7 +179,7 @@ write_preset_to_xml(Preset *preset, gchar *filename)
|
||||
BAD_CAST xml->label);
|
||||
values = xml->values;
|
||||
type = values->type;
|
||||
while ((type & VALUE_TYPE_EXTRA) && value_is_extra(values, param)) {
|
||||
while ((type & VALUE_TYPE_EXTRA) && value_is_extra(values, param->value)) {
|
||||
values = values->extra;
|
||||
type = values->type;
|
||||
}
|
||||
@@ -206,10 +208,11 @@ write_preset_to_xml(Preset *preset, gchar *filename)
|
||||
switch (type) {
|
||||
case VALUE_TYPE_LABEL:
|
||||
{
|
||||
char *textp = map_xml_value(xml, param->value);
|
||||
char *textp = map_xml_value(xml, values, param->value);
|
||||
if (!textp) {
|
||||
g_message("Unable to map %s value %d for id %d position %d",
|
||||
xml->label, param->value, param->id, param->position);
|
||||
g_warning("Unable to map %s value %d for id %d position %d",
|
||||
xml->label, param->value, param->id,
|
||||
param->position);
|
||||
textp = "";
|
||||
}
|
||||
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Text",
|
||||
@@ -223,7 +226,7 @@ write_preset_to_xml(Preset *preset, gchar *filename)
|
||||
double value = (param->value + offset) * step;
|
||||
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Text",
|
||||
"%0.2f%s", value, suffix);
|
||||
} else {
|
||||
} else {
|
||||
gint value = (param->value + offset) * step;
|
||||
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Text",
|
||||
"%d%s", value, suffix);
|
||||
@@ -237,20 +240,16 @@ write_preset_to_xml(Preset *preset, gchar *filename)
|
||||
break;
|
||||
|
||||
default:
|
||||
g_message("Unhandled value type %d", type);
|
||||
g_warning("Unhandled value type %d", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rc = xmlTextWriterEndElement(writer);
|
||||
|
||||
iter_params = iter_params->next;
|
||||
}
|
||||
|
||||
/* Here we could close the elements ORDER and EXAMPLE using the
|
||||
* function xmlTextWriterEndElement, but since we do not want to
|
||||
* write any other elements, we simply call xmlTextWriterEndDocument,
|
||||
* which will do all the work. */
|
||||
|
||||
rc = xmlTextWriterEndDocument(writer);
|
||||
if (rc < 0) {
|
||||
printf("testXmlwriterFilename: Error at xmlTextWriterEndDocument\n");
|
||||
|
||||
Reference in New Issue
Block a user