Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cada964d61 | ||
|
|
4bb78a5fe7 | ||
|
|
a2a4842fd9 | ||
|
|
079547c20f | ||
|
|
e3447292c4 | ||
|
|
9f4bd66217 | ||
|
|
85be87a636 | ||
|
|
d61e6c3046 | ||
|
|
196a7c2aa5 | ||
|
|
f1aa3665ed | ||
|
|
478f580e76 | ||
|
|
dfec60e7b4 | ||
|
|
e7de6b2bb5 | ||
|
|
17ff7063ec | ||
|
|
f1bca1eabb | ||
|
|
ba71876ebf | ||
|
|
8591b0feb7 | ||
|
|
f94ed1c93b | ||
|
|
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 | ||
|
|
eadaf198ba | ||
|
|
97547476e4 | ||
|
|
35e42dc653 | ||
|
|
ce296d2698 | ||
|
|
a073f5cde2 | ||
|
|
9fcf6939d0 | ||
|
|
71e087cfd0 | ||
|
|
6a16e66cbd | ||
|
|
4351613e72 | ||
|
|
2253833105 | ||
|
|
87e6dcbb9c | ||
|
|
d92489348d | ||
|
|
2b27302166 | ||
|
|
fd0369dc7c | ||
|
|
2c921df204 | ||
|
|
ee2fcd181e | ||
|
|
2eb4e97810 | ||
|
|
907a3d0ed9 | ||
|
|
5dc5f0652f | ||
|
|
5a44076e4f |
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
|
||||||
11
AUTHORS
11
AUTHORS
@@ -1 +1,12 @@
|
|||||||
Tomasz Moń <desowin@gmail.com>
|
Tomasz Moń <desowin@gmail.com>
|
||||||
|
Stephen Rigler <riglersc@gmail.com>
|
||||||
|
Jaco Kroon <jaco@kroon.co.za>
|
||||||
|
Rafael Moreno <laocanfei@yahoo.com>
|
||||||
|
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>
|
||||||
|
|||||||
58
HACKING
58
HACKING
@@ -10,36 +10,50 @@ There seems to be three possible ways to figure that out.
|
|||||||
(all numbers here are hex)
|
(all numbers here are hex)
|
||||||
04 F0 00 00 04 10 00 5E 04 02 41 00 04 30 09 00 07 00 34 F7
|
04 F0 00 00 04 10 00 5E 04 02 41 00 04 30 09 00 07 00 34 F7
|
||||||
|
|
||||||
To get SysEx command out of it, remove every 4th byte, so we have:
|
MIDI data is transferred over USB using 32-bit USB-MIDI Event Packets.
|
||||||
|
Byte 0 is Cable Number (high nibble) and Code Index Number (low nibble).
|
||||||
|
Bytes 1, 2 and 3 are data.
|
||||||
|
Every bulk transfer on USB MIDI endpoint contains atleast one such packet
|
||||||
|
(those are sent one after each other).
|
||||||
|
In case of Digitech devices, the Cable Number seems to be 0 (correct me,
|
||||||
|
if I'm wrong).
|
||||||
|
There are three different Code Index Numbers that are being used in this
|
||||||
|
particular case:
|
||||||
|
0x4 - SysEx starts or continues (Byte 1, 2 and 3 from this packet are
|
||||||
|
part of our MIDI message)
|
||||||
|
0x5 - SysEx ends with following single byte (we just need to take Byte 1
|
||||||
|
from this packet)
|
||||||
|
0x6 - SysEx ends with following two bytes (we just need to take Byte 1 and 2
|
||||||
|
from this packet)
|
||||||
|
0x7 - SysEx ends with following three bytes (we need to take Byte 1, 2 and 3
|
||||||
|
from this packet)
|
||||||
|
|
||||||
|
Unused bytes in USB-MIDI packets are supposed to be 0.
|
||||||
|
|
||||||
|
To get SysEx command out of it, apply above rules, so we have:
|
||||||
F0 00 00 10 00 5E 02 41 00 30 09 00 00 34 F7
|
F0 00 00 10 00 5E 02 41 00 30 09 00 00 34 F7
|
||||||
|
|
||||||
SysEx message format seems to be formed like this:
|
SysEx message format seems to be formed like this:
|
||||||
magic bytes - F0 00 00 10 00 5E 02 41
|
SysEx start byte - F0
|
||||||
status byte - in this example 00
|
Manufacturer ID - 00 00 10
|
||||||
|
Device ID - 00
|
||||||
|
Family ID - 5E (RP)
|
||||||
|
Product ID - 02 (RP250)
|
||||||
|
Procedure - 41 (see MessageID in gdigi.h)
|
||||||
|
|
||||||
|
As MIDI messages must not contain bytes with MSB bit set, Digitech
|
||||||
|
devices use packing system.
|
||||||
|
First byte contains MSB bits from following 7 bytes (this scheme
|
||||||
|
continues as many times as needed) (see pack_data() and unpack_message() in
|
||||||
|
gdigi.c for details).
|
||||||
|
|
||||||
|
Assuming message has been unpacked, the meaning of next bytes:
|
||||||
ID - in this example 30 09
|
ID - in this example 30 09
|
||||||
Position - in this example 00
|
Position - in this example 00
|
||||||
Value - in this example 00 (can be more bytes long, see below)
|
Value - in this example 00 (can be more bytes long, see below)
|
||||||
Checksum - to calculate it, XOR all bytes, and then XOR it with 07
|
Checksum - to calculate it, XOR all bytes (of packed message)
|
||||||
Every message ends with F7
|
Every message ends with F7
|
||||||
|
|
||||||
Status byte bits explained:
|
|
||||||
7th - ???
|
|
||||||
6th - if active add 80 to ID
|
|
||||||
5th - ???
|
|
||||||
4th - is active when value will start with length
|
|
||||||
In such case value can be something like:
|
|
||||||
01 12 or 02 12 34 or 03 12 34 56
|
|
||||||
and proper values are:
|
|
||||||
01 - 12
|
|
||||||
02 - 1234
|
|
||||||
03 - 123456
|
|
||||||
3rd - when 4th bit is also active, and first value byte is 01
|
|
||||||
then add 80 to value
|
|
||||||
2nd - when 4th bit is also active, and first value byte is 02
|
|
||||||
then add 80 to value
|
|
||||||
1st - when 4th bit is also active, and first value byte is 03
|
|
||||||
then add 80 to value
|
|
||||||
|
|
||||||
So for above example:
|
So for above example:
|
||||||
ID = 3009 (hex) = 12297 (decimal)
|
ID = 3009 (hex) = 12297 (decimal)
|
||||||
Position = 0
|
Position = 0
|
||||||
|
|||||||
14
Makefile
14
Makefile
@@ -1,10 +1,10 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
EXTRA_CFLAGS ?=
|
EXTRA_CFLAGS ?=
|
||||||
EXTRA_LDFLAGS ?=
|
EXTRA_LDFLAGS ?=
|
||||||
CFLAGS := $(shell pkg-config --cflags glib-2.0 gio-2.0 gtk+-2.0) -Wall -g -ansi -std=c99 $(EXTRA_CFLAGS)
|
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
|
LDFLAGS = $(EXTRA_LDFLAGS) -Wl,--as-needed
|
||||||
LDADD := $(shell pkg-config --libs glib-2.0 gio-2.0 gtk+-2.0 gthread-2.0 alsa) -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
|
OBJECTS = gdigi.o gui.o effects.o preset.o gtkknob.o preset_xml.o
|
||||||
DEPFILES = $(foreach m,$(OBJECTS:.o=),.$(m).m)
|
DEPFILES = $(foreach m,$(OBJECTS:.o=),.$(m).m)
|
||||||
|
|
||||||
.PHONY : clean distclean all
|
.PHONY : clean distclean all
|
||||||
@@ -19,19 +19,21 @@ all: gdigi
|
|||||||
gdigi: $(OBJECTS)
|
gdigi: $(OBJECTS)
|
||||||
$(CC) $(LDFLAGS) -o $@ $+ $(LDADD)
|
$(CC) $(LDFLAGS) -o $@ $+ $(LDADD)
|
||||||
|
|
||||||
knob.h: knob.png
|
images/gdigi_icon.h: images/icon.png
|
||||||
gdk-pixbuf-csource --name=knob_pixbuf knob.png > $@
|
gdk-pixbuf-csource --raw --name=gdigi_icon $< > $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
rm -f knob.h
|
|
||||||
|
|
||||||
distclean : clean
|
distclean : clean
|
||||||
rm -f .*.m
|
rm -f .*.m
|
||||||
|
rm -f images/gdigi_icon.h
|
||||||
rm -f gdigi
|
rm -f gdigi
|
||||||
|
|
||||||
install: gdigi
|
install: gdigi
|
||||||
install gdigi $(DESTDIR)/usr/bin
|
install gdigi $(DESTDIR)/usr/bin
|
||||||
|
install -m 0644 gdigi.desktop $(DESTDIR)/usr/share/applications/
|
||||||
|
install -m 0644 images/gdigi.png $(DESTDIR)/usr/share/icons/
|
||||||
|
|
||||||
NODEP_TARGETS := clean distclean
|
NODEP_TARGETS := clean distclean
|
||||||
depinc := 1
|
depinc := 1
|
||||||
|
|||||||
2
README
2
README
@@ -1,4 +1,4 @@
|
|||||||
Requirments: alsa, gtk+, glib, expat
|
Requirments: alsa, gtk+, glib, expat, libxml-2
|
||||||
|
|
||||||
Getting started guide:
|
Getting started guide:
|
||||||
-to compile: make
|
-to compile: make
|
||||||
|
|||||||
1
TODO
1
TODO
@@ -2,5 +2,4 @@
|
|||||||
-handling presets (saving, exporting to xml patches)
|
-handling presets (saving, exporting to xml patches)
|
||||||
-buildsystem (install knob.png to share dir, don't use inline knob pixbuf)
|
-buildsystem (install knob.png to share dir, don't use inline knob pixbuf)
|
||||||
-various fixes to MIDI IN messages handling
|
-various fixes to MIDI IN messages handling
|
||||||
-guess device port when user doesn't explicitly provide it (don't use hardcoded "hw:1,0,0")
|
|
||||||
-optimizations
|
-optimizations
|
||||||
|
|||||||
24
effects.h
24
effects.h
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
enum {
|
typedef enum {
|
||||||
VALUE_TYPE_PLAIN = 0, /**< value displayed directly */
|
VALUE_TYPE_PLAIN = 0, /**< value displayed directly */
|
||||||
VALUE_TYPE_SUFFIX = 1 << 0, /**< use suffix for displaying */
|
VALUE_TYPE_SUFFIX = 1 << 0, /**< use suffix for displaying */
|
||||||
VALUE_TYPE_OFFSET = 1 << 1, /**< use value offset */
|
VALUE_TYPE_OFFSET = 1 << 1, /**< use value offset */
|
||||||
@@ -27,6 +27,8 @@ enum {
|
|||||||
VALUE_TYPE_LABEL = 1 << 3, /**< use value labels (overrides any other option) */
|
VALUE_TYPE_LABEL = 1 << 3, /**< use value labels (overrides any other option) */
|
||||||
VALUE_TYPE_EXTRA = 1 << 4, /**< use extra values */
|
VALUE_TYPE_EXTRA = 1 << 4, /**< use extra values */
|
||||||
VALUE_TYPE_DECIMAL= 1 << 5, /**< display decimal places */
|
VALUE_TYPE_DECIMAL= 1 << 5, /**< display decimal places */
|
||||||
|
VALUE_TYPE_POSID = 1 << 6, /**< Packed Position/ID: (pos << 16) | id */
|
||||||
|
VALUE_TYPE_NONE = 1 << 7, /**< no value displayed */
|
||||||
} ValueType;
|
} ValueType;
|
||||||
|
|
||||||
typedef struct _EffectValues {
|
typedef struct _EffectValues {
|
||||||
@@ -93,6 +95,18 @@ typedef struct {
|
|||||||
PresetBank bank;
|
PresetBank bank;
|
||||||
} Banks;
|
} Banks;
|
||||||
|
|
||||||
|
enum product_id {
|
||||||
|
RP150 = 1,
|
||||||
|
RP250 = 2,
|
||||||
|
GNX4 = 3,
|
||||||
|
GNX3000 = 4,
|
||||||
|
RP500 = 5,
|
||||||
|
RP1000 = 6,
|
||||||
|
RP155 = 7,
|
||||||
|
RP255 = 8,
|
||||||
|
RP355 = 9,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gchar *name;
|
gchar *name;
|
||||||
unsigned char family_id;
|
unsigned char family_id;
|
||||||
@@ -103,12 +117,16 @@ typedef struct {
|
|||||||
gint n_banks;
|
gint n_banks;
|
||||||
} Device;
|
} Device;
|
||||||
|
|
||||||
ModifierGroup *modifier_linkable_list();
|
gchar *get_position(guint position);
|
||||||
void modifier_group_free(ModifierGroup *modifier_group);
|
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,
|
void get_values_info(EffectValues *values,
|
||||||
gdouble *min, gdouble *max, gboolean *custom);
|
gdouble *min, gdouble *max, gboolean *custom);
|
||||||
gboolean get_device_info(unsigned char device_id, unsigned char family_id,
|
gboolean get_device_info(unsigned char device_id, unsigned char family_id,
|
||||||
unsigned char product_id,
|
unsigned char product_id,
|
||||||
Device **device);
|
Device **device);
|
||||||
|
|
||||||
|
|
||||||
#endif /* GDIGI_EFFECTS_H */
|
#endif /* GDIGI_EFFECTS_H */
|
||||||
|
|||||||
458
gdigi.c
458
gdigi.c
@@ -21,20 +21,188 @@
|
|||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
#include "gdigi.h"
|
#include "gdigi.h"
|
||||||
|
#include "gdigi_xml.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
|
||||||
static unsigned char device_id = 0x7F;
|
static unsigned char device_id = 0x7F;
|
||||||
static unsigned char family_id = 0x7F;
|
static unsigned char family_id = 0x7F;
|
||||||
static unsigned char product_id = 0x7F;
|
unsigned char product_id = 0x7F;
|
||||||
|
|
||||||
static snd_rawmidi_t *output = NULL;
|
static snd_rawmidi_t *output = NULL;
|
||||||
static snd_rawmidi_t *input = NULL;
|
static snd_rawmidi_t *input = NULL;
|
||||||
static char *device_port = "hw:1,0,0";
|
static char *device_port = NULL;
|
||||||
|
|
||||||
static GQueue *message_queue = NULL;
|
static GQueue *message_queue = NULL;
|
||||||
static GMutex *message_queue_mutex = NULL;
|
static GMutex *message_queue_mutex = NULL;
|
||||||
static GCond *message_queue_cond = 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.",
|
||||||
|
pos, id);
|
||||||
|
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.
|
* Registers an error quark for gdigi if necessary.
|
||||||
*
|
*
|
||||||
@@ -122,13 +290,11 @@ GString *pack_data(gchar *data, gint len)
|
|||||||
gint i;
|
gint i;
|
||||||
gint new_len;
|
gint new_len;
|
||||||
unsigned char status;
|
unsigned char status;
|
||||||
gint offset;
|
|
||||||
gint status_byte;
|
gint status_byte;
|
||||||
|
|
||||||
new_len = len + (len/7);
|
new_len = len + (len/7);
|
||||||
packed = g_string_sized_new(new_len);
|
packed = g_string_sized_new(new_len);
|
||||||
status = 0;
|
status = 0;
|
||||||
offset = -1;
|
|
||||||
status_byte = 0;
|
status_byte = 0;
|
||||||
|
|
||||||
for (i=0; i<len; i++) {
|
for (i=0; i<len; i++) {
|
||||||
@@ -220,33 +386,57 @@ MessageID get_message_id(GString *msg)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HEX_WIDTH 26
|
||||||
|
|
||||||
|
static gboolean modifier_linkable_list_request_pending = FALSE;
|
||||||
|
|
||||||
void push_message(GString *msg)
|
void push_message(GString *msg)
|
||||||
{
|
{
|
||||||
if (((unsigned char)msg->str[0] == 0xF0) && ((unsigned char)msg->str[msg->len-1] == 0xF7))
|
MessageID msgid = get_message_id(msg);
|
||||||
g_message("Pushing correct message!");
|
if (((unsigned char)msg->str[0] == 0xF0) &&
|
||||||
else
|
((unsigned char)msg->str[msg->len-1] == 0xF7)) {
|
||||||
|
debug_msg(DEBUG_VERBOSE, "Pushing correct message!");
|
||||||
|
} else {
|
||||||
g_warning("Pushing incorrect message!");
|
g_warning("Pushing incorrect message!");
|
||||||
|
}
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
for (x = 0; x<msg->len; x++)
|
if (debug_flag_is_set(DEBUG_HEX)) {
|
||||||
printf("%02x ", (unsigned char)msg->str[x]);
|
for (x = 0; x<msg->len; x++) {
|
||||||
printf("\n");
|
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:
|
case ACK:
|
||||||
g_message("Received ACK");
|
|
||||||
g_string_free(msg, TRUE);
|
g_string_free(msg, TRUE);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case NACK:
|
case NACK:
|
||||||
g_message("Received NACK");
|
g_warning("Received NACK!");
|
||||||
g_string_free(msg, TRUE);
|
g_string_free(msg, TRUE);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RECEIVE_PARAMETER_VALUE:
|
case RECEIVE_PARAMETER_VALUE:
|
||||||
|
{
|
||||||
unpack_message(msg);
|
unpack_message(msg);
|
||||||
SettingParam *param = setting_param_new_from_data(&msg->str[8], NULL);
|
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);
|
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();
|
GDK_THREADS_ENTER();
|
||||||
apply_setting_param_to_gui(param);
|
apply_setting_param_to_gui(param);
|
||||||
@@ -255,30 +445,127 @@ void push_message(GString *msg)
|
|||||||
setting_param_free(param);
|
setting_param_free(param);
|
||||||
g_string_free(msg, TRUE);
|
g_string_free(msg, TRUE);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case RECEIVE_DEVICE_NOTIFICATION:
|
case RECEIVE_DEVICE_NOTIFICATION:
|
||||||
unpack_message(msg);
|
unpack_message(msg);
|
||||||
unsigned char *str = (unsigned char*)msg->str;
|
unsigned char *str = (unsigned char*)msg->str;
|
||||||
switch (str[8]) {
|
switch (str[8]) {
|
||||||
case NOTIFY_PRESET_MOVED:
|
case NOTIFY_PRESET_MOVED:
|
||||||
if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) {
|
if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) {
|
||||||
g_message("Loaded preset %d from bank %d", str[10], str[9]);
|
|
||||||
|
|
||||||
GDK_THREADS_ENTER();
|
GDK_THREADS_ENTER();
|
||||||
g_timeout_add(0, apply_current_preset_to_gui, NULL);
|
g_timeout_add(0, apply_current_preset_to_gui, NULL);
|
||||||
GDK_THREADS_LEAVE();
|
GDK_THREADS_LEAVE();
|
||||||
} else
|
debug_msg(DEBUG_MSG2HOST,
|
||||||
g_message("%d %d moved to %d %d", str[9], str[10], str[11], str[12]);
|
"RECEIVE_DEVICE_NOTIFICATION: Loaded preset "
|
||||||
default:
|
"%d from bank %d",
|
||||||
g_message("Received unhandled device notification");
|
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]);
|
||||||
|
}
|
||||||
|
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);
|
g_string_free(msg, TRUE);
|
||||||
return;
|
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:
|
default:
|
||||||
g_mutex_lock(message_queue_mutex);
|
g_mutex_lock(message_queue_mutex);
|
||||||
g_queue_push_tail(message_queue, msg);
|
g_queue_push_tail(message_queue, msg);
|
||||||
g_cond_signal(message_queue_cond);
|
g_cond_signal(message_queue_cond);
|
||||||
g_mutex_unlock(message_queue_mutex);
|
g_mutex_unlock(message_queue_mutex);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,8 +588,9 @@ gpointer read_data_thread(gboolean *stop)
|
|||||||
unsigned short revents;
|
unsigned short revents;
|
||||||
|
|
||||||
/* SysEx messages can't contain bytes with 8th bit set.
|
/* 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
|
||||||
memset(buf, sizeof(buf), 0xFF);
|
get out of reply bounds, we'll catch it */
|
||||||
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
|
||||||
err = poll(pfds, npfds, 200);
|
err = poll(pfds, npfds, 200);
|
||||||
if (err < 0 && errno == EINTR)
|
if (err < 0 && errno == EINTR)
|
||||||
@@ -400,6 +688,9 @@ void send_message(gint procedure, gchar *data, gint len)
|
|||||||
g_string_append_printf(msg, "%c\xF7",
|
g_string_append_printf(msg, "%c\xF7",
|
||||||
calculate_checksum(&msg->str[1], msg->len - 1));
|
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);
|
send_data(msg->str, msg->len);
|
||||||
|
|
||||||
g_string_free(msg, TRUE);
|
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);
|
"GeNetX version (%d) and type (%d)", version, type);
|
||||||
|
|
||||||
return -1;
|
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 id Parameter ID
|
||||||
* \param position Parameter position
|
* \param position Parameter position
|
||||||
@@ -640,6 +949,11 @@ void set_option(guint id, guint position, guint value)
|
|||||||
((id & 0xFF00) >> 8), (id & 0xFF),
|
((id & 0xFF00) >> 8), (id & 0xFF),
|
||||||
position);
|
position);
|
||||||
append_value(msg, value);
|
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);
|
send_message(RECEIVE_PARAMETER_VALUE, msg->str, msg->len);
|
||||||
g_string_free(msg, TRUE);
|
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_error("get_message_list() doesn't support followning id: %d", id);
|
||||||
g_string_free(data, TRUE);
|
g_string_free(data, TRUE);
|
||||||
g_list_free(list);
|
g_list_free(list);
|
||||||
|
g_assert(!"BUG");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (amt) {
|
while (amt) {
|
||||||
g_message("%d messages left", amt);
|
debug_msg(DEBUG_VERBOSE, "%d messages left", amt);
|
||||||
data = g_queue_pop_nth(message_queue, x);
|
data = g_queue_pop_nth(message_queue, x);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
g_cond_wait(message_queue_cond, message_queue_mutex);
|
g_cond_wait(message_queue_cond, message_queue_mutex);
|
||||||
@@ -1059,6 +1374,10 @@ static gboolean request_who_am_i(unsigned char *device_id, unsigned char *family
|
|||||||
*family_id = data->str[9];
|
*family_id = data->str[9];
|
||||||
*product_id = data->str[10];
|
*product_id = data->str[10];
|
||||||
g_string_free(data, TRUE);
|
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 TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -1105,11 +1424,56 @@ static void request_device_configuration()
|
|||||||
|
|
||||||
static GOptionEntry options[] = {
|
static GOptionEntry options[] = {
|
||||||
{"device", 'd', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &device_port, "MIDI device port to use", NULL},
|
{"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}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param[out] devices GList containing numbers (packed into pointers)
|
||||||
|
* of connected DigiTech devices
|
||||||
|
*
|
||||||
|
* Checks available soundcards for DigiTech devices.
|
||||||
|
*
|
||||||
|
* \return the number of connected DigiTech devices.
|
||||||
|
**/
|
||||||
|
static gint get_digitech_devices(GList **devices)
|
||||||
|
{
|
||||||
|
gint card_num = -1;
|
||||||
|
gint number = 0;
|
||||||
|
|
||||||
|
while (!snd_card_next(&card_num) && (card_num > -1)) {
|
||||||
|
char* name;
|
||||||
|
snd_card_get_longname(card_num, &name);
|
||||||
|
if (strspn(name,"DigiTech") > 0) {
|
||||||
|
number++;
|
||||||
|
*devices = g_list_append(*devices, GINT_TO_POINTER(card_num));
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
@@ -1124,12 +1488,38 @@ int main(int argc, char *argv[]) {
|
|||||||
g_option_context_add_group(context, gtk_get_option_group(TRUE));
|
g_option_context_add_group(context, gtk_get_option_group(TRUE));
|
||||||
|
|
||||||
if (!g_option_context_parse(context, &argc, &argv, &error)) {
|
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_error_free(error);
|
||||||
g_option_context_free(context);
|
g_option_context_free(context);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
if ((num_devices = get_digitech_devices(&devices)) <= 0) {
|
||||||
|
g_warning("Couldn't find DigiTech devices!");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (num_devices > 1) {
|
||||||
|
chosen_device = select_device_dialog(devices);
|
||||||
|
if (chosen_device < 0) {
|
||||||
|
show_error_message(NULL, "No device chosen");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
device = g_list_nth(devices, chosen_device);
|
||||||
|
device_port = g_strdup_printf("hw:%d,0,0",
|
||||||
|
GPOINTER_TO_INT(device->data));
|
||||||
|
g_list_free(devices);
|
||||||
|
debug_msg(DEBUG_STARTUP, "Found device %s.", device_port);
|
||||||
|
} else {
|
||||||
|
debug_msg(DEBUG_STARTUP, "Using device %s.", device_port);
|
||||||
|
}
|
||||||
|
|
||||||
g_option_context_free(context);
|
g_option_context_free(context);
|
||||||
|
|
||||||
if (open_device() == TRUE) {
|
if (open_device() == TRUE) {
|
||||||
@@ -1155,14 +1545,14 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if (device != NULL) {
|
if (device != NULL) {
|
||||||
/* enable GUI mode */
|
/* enable GUI mode */
|
||||||
set_option(GUI_MODE_ON_OFF, USB_POSITION, 1);
|
set_option(GUI_MODE_ON_OFF, GLOBAL_POSITION, 1);
|
||||||
|
|
||||||
gui_create(device);
|
gui_create(device);
|
||||||
gtk_main();
|
gtk_main();
|
||||||
gui_free();
|
gui_free();
|
||||||
|
|
||||||
/* disable GUI mode */
|
/* disable GUI mode */
|
||||||
set_option(GUI_MODE_ON_OFF, USB_POSITION, 0);
|
set_option(GUI_MODE_ON_OFF, GLOBAL_POSITION, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1176,8 +1566,8 @@ int main(int argc, char *argv[]) {
|
|||||||
g_mutex_free(message_queue_mutex);
|
g_mutex_free(message_queue_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message_queue != NULL) {
|
if (message_queue != NULL && g_queue_get_length(message_queue)) {
|
||||||
g_message("%d unread messages in queue",
|
g_warning("%d unread messages in queue",
|
||||||
g_queue_get_length(message_queue));
|
g_queue_get_length(message_queue));
|
||||||
g_queue_foreach(message_queue, (GFunc) message_free_func, NULL);
|
g_queue_foreach(message_queue, (GFunc) message_free_func, NULL);
|
||||||
g_queue_free(message_queue);
|
g_queue_free(message_queue);
|
||||||
|
|||||||
@@ -3,4 +3,7 @@ Version=1.0
|
|||||||
Type=Application
|
Type=Application
|
||||||
Name=gdigi
|
Name=gdigi
|
||||||
Exec=gdigi
|
Exec=gdigi
|
||||||
|
Categories=GTK;Audio;AudioVideo;
|
||||||
|
Icon=gdigi
|
||||||
|
X-Desktop-File-Install-Version=0.20
|
||||||
|
|
||||||
|
|||||||
267
gdigi.h
267
gdigi.h
@@ -22,6 +22,19 @@
|
|||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#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_POSITION 7
|
||||||
#define GNX_CHANNEL_AMP 260
|
#define GNX_CHANNEL_AMP 260
|
||||||
#define GNX_WARP 261
|
#define GNX_WARP 261
|
||||||
@@ -29,6 +42,8 @@
|
|||||||
#define GNX_CABINET_WARP 263
|
#define GNX_CABINET_WARP 263
|
||||||
#define GNX_CHANNEL_FS_MODE 264
|
#define GNX_CHANNEL_FS_MODE 264
|
||||||
|
|
||||||
|
unsigned char product_id;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GNX3K_WAH_TYPE_CRY = 129,
|
GNX3K_WAH_TYPE_CRY = 129,
|
||||||
GNX3K_WAH_TYPE_BOUTIQUE = 130,
|
GNX3K_WAH_TYPE_BOUTIQUE = 130,
|
||||||
@@ -48,6 +63,9 @@ enum {
|
|||||||
#define WAH_ON_OFF 129
|
#define WAH_ON_OFF 129
|
||||||
#define WAH_POSITION 3
|
#define WAH_POSITION 3
|
||||||
|
|
||||||
|
#define WAH_PEDAL_POSITION 132
|
||||||
|
#define WAH_VOLUME_BOOST 133
|
||||||
|
|
||||||
#define WAH_LEVEL 133
|
#define WAH_LEVEL 133
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -93,8 +111,8 @@ enum {
|
|||||||
#define COMP_OUTPUT 212
|
#define COMP_OUTPUT 212
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
PICKUP_TYPE_SC_HB = 65,
|
||||||
PICKUP_TYPE_HB_SC = 66,
|
PICKUP_TYPE_HB_SC = 66,
|
||||||
PICKUP_TYPE_SC_HB = 65
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PICKUP_TYPE 64
|
#define PICKUP_TYPE 64
|
||||||
@@ -227,9 +245,15 @@ enum {
|
|||||||
#define DIST_MP_TONE 2446
|
#define DIST_MP_TONE 2446
|
||||||
#define DIST_MP_VOLUME 2447
|
#define DIST_MP_VOLUME 2447
|
||||||
|
|
||||||
|
#define VOLUME_PRE_FX_POSITION 13
|
||||||
|
#define VOLUME_POST_FX_POSITION 17
|
||||||
|
|
||||||
#define PRESET_POSITION 18
|
#define PRESET_POSITION 18
|
||||||
#define PRESET_LEVEL 2626
|
#define PRESET_LEVEL 2626
|
||||||
|
|
||||||
|
#define STOMP_LOOP_ON_OFF 3329
|
||||||
|
#define STOMP_LOOP_POSITION 34
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AMP_TYPE_TWEED_CHAMP = 307,
|
AMP_TYPE_TWEED_CHAMP = 307,
|
||||||
AMP_TYPE_TWEED_DELUXE = 308,
|
AMP_TYPE_TWEED_DELUXE = 308,
|
||||||
@@ -239,7 +263,7 @@ enum {
|
|||||||
AMP_TYPE_BLACKFACE_DELUXE = 312,
|
AMP_TYPE_BLACKFACE_DELUXE = 312,
|
||||||
AMP_TYPE_PLEXI_JTM_45 = 313,
|
AMP_TYPE_PLEXI_JTM_45 = 313,
|
||||||
AMP_TYPE_SUPER_LEAD_PLEXI = 314,
|
AMP_TYPE_SUPER_LEAD_PLEXI = 314,
|
||||||
AMP_TYPE_PLEXI_JUMP_PANEL = 315,
|
AMP_TYPE_68_MARSHALL_JUMP = 315,
|
||||||
AMP_TYPE_MASTER_VOLUME = 316,
|
AMP_TYPE_MASTER_VOLUME = 316,
|
||||||
AMP_TYPE_JCM800 = 317,
|
AMP_TYPE_JCM800 = 317,
|
||||||
AMP_TYPE_JCM900 = 318,
|
AMP_TYPE_JCM900 = 318,
|
||||||
@@ -267,7 +291,7 @@ enum {
|
|||||||
AMP_TYPE_METAL = 332,
|
AMP_TYPE_METAL = 332,
|
||||||
AMP_TYPE_BRIGHT = 333,
|
AMP_TYPE_BRIGHT = 333,
|
||||||
AMP_TYPE_CHUNK = 334,
|
AMP_TYPE_CHUNK = 334,
|
||||||
AMP_TYPE_CLEAN = 335,
|
AMP_TYPE_DIGITECH_CLEAN = 335,
|
||||||
AMP_TYPE_HIGH_GAIN = 337,
|
AMP_TYPE_HIGH_GAIN = 337,
|
||||||
AMP_TYPE_BLUES = 338,
|
AMP_TYPE_BLUES = 338,
|
||||||
AMP_TYPE_FUZZ = 339,
|
AMP_TYPE_FUZZ = 339,
|
||||||
@@ -307,8 +331,8 @@ enum {
|
|||||||
|
|
||||||
#define AMP_TYPE 2496
|
#define AMP_TYPE 2496
|
||||||
#define AMP_ON_OFF 265
|
#define AMP_ON_OFF 265
|
||||||
#define AMP_POSITION 8
|
#define AMP_A_POSITION 8
|
||||||
#define CH2_AMP_POSITION 10
|
#define AMP_B_POSITION 10
|
||||||
|
|
||||||
#define AMP_LOOP_ON_OFF 3649
|
#define AMP_LOOP_ON_OFF 3649
|
||||||
#define AMP_LOOP_POSITION 33
|
#define AMP_LOOP_POSITION 33
|
||||||
@@ -316,11 +340,12 @@ enum {
|
|||||||
#define AMP_BYPASS_ON_OFF 12361
|
#define AMP_BYPASS_ON_OFF 12361
|
||||||
#define AMP_BYPASS_POSITION 0
|
#define AMP_BYPASS_POSITION 0
|
||||||
|
|
||||||
#define AMP_SELECT 256
|
#define AMP_CHANNEL 256
|
||||||
#define AMP_SELECT_POSITION 7
|
#define AMP_CHANNEL_POSITION 7
|
||||||
|
|
||||||
#define AMP_CHANNEL_A 0
|
#define AMP_CHANNEL_A 0
|
||||||
#define AMP_CHANNEL_B 1
|
#define AMP_CHANNEL_B 1
|
||||||
|
#define AMP_CHANNEL_WARP 2
|
||||||
|
|
||||||
#define AMP_GAIN 2497
|
#define AMP_GAIN 2497
|
||||||
#define AMP_LEVEL 2498
|
#define AMP_LEVEL 2498
|
||||||
@@ -339,7 +364,7 @@ enum {
|
|||||||
#define AMP_CAB_TYPE 2560
|
#define AMP_CAB_TYPE 2560
|
||||||
#define AMP_CAB_TUNING 2561
|
#define AMP_CAB_TUNING 2561
|
||||||
#define AMP_CAB_POSITION 9
|
#define AMP_CAB_POSITION 9
|
||||||
#define CH2_AMP_CAB_POSITION 11
|
#define AMP_CAB_B_POSITION 11
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AMP_CAB_DIRECT = 570,
|
AMP_CAB_DIRECT = 570,
|
||||||
@@ -406,23 +431,23 @@ enum {
|
|||||||
GNX_AMP_CAB_SVT_BASS8_10 = 595,
|
GNX_AMP_CAB_SVT_BASS8_10 = 595,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EQ_TYPE 3202
|
#define EQ_A_POSITION 24
|
||||||
#define EQ_ON_OFF 3212
|
#define EQ_B_POSITION 25
|
||||||
#define EQ_POSITION 24
|
|
||||||
#define EQ_POSITION_B 25
|
|
||||||
|
|
||||||
|
#define EQ_TYPE 3202
|
||||||
#define EQ_BASS 3203
|
#define EQ_BASS 3203
|
||||||
#define EQ_MID 3204
|
#define EQ_MID 3204
|
||||||
#define EQ_MID_HZ 3206
|
#define EQ_TREB 3205
|
||||||
#define EQ_TREBLE 3205
|
#define EQ_MID_FREQ 3206
|
||||||
#define EQ_PRESENCE 3207
|
#define EQ_PRESENCE 3207
|
||||||
#define EQ_TREBLE_HZ 3211
|
#define EQ_TREB_FREQ 3211
|
||||||
#define EQ_LOW_LEVEL 3203
|
#define EQ_ENABLE 3212
|
||||||
#define EQ_MID_LEVEL 3204
|
|
||||||
#define EQ_HIGH_LEVEL 3205
|
|
||||||
#define EQ_LOW_FREQ 3213
|
#define EQ_LOW_FREQ 3213
|
||||||
#define EQ_MID_FREQ 3214
|
#define EQ_MID_FREQ_RP500 3214
|
||||||
#define EQ_HIGH_FREQ 3215
|
#define EQ_HIGH_FREQ 3215
|
||||||
|
|
||||||
|
#define EQ_TREBLE_FREQ 3215
|
||||||
#define EQ_LOW_BANDWIDTH 3216
|
#define EQ_LOW_BANDWIDTH 3216
|
||||||
#define EQ_MID_BANDWIDTH 3217
|
#define EQ_MID_BANDWIDTH 3217
|
||||||
#define EQ_HIGH_BANDWIDTH 3218
|
#define EQ_HIGH_BANDWIDTH 3218
|
||||||
@@ -467,49 +492,53 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CHORUS_TYPE_CE = 0x37B,
|
CHORUS_TYPE_CE = 891,
|
||||||
CHORUS_TYPE_TC = 0x37C,
|
CHORUS_TYPE_TC = 892,
|
||||||
CHORUS_TYPE_DUAL = 0x379,
|
CHORUS_TYPE_DUAL = 889,
|
||||||
CHORUS_TYPE_GLISTEN = 0x392,
|
CHORUS_TYPE_GLISTEN = 914,
|
||||||
CHORUS_TYPE_MULTI = 0x37a,
|
CHORUS_TYPE_MULTI = 890,
|
||||||
CHORUS_TYPE_VOO_DOO = 0x396,
|
CHORUS_TYPE_VOO_DOO = 918,
|
||||||
CHORUS_TYPE_CLONE = 0x397,
|
CHORUS_TYPE_CLONE = 919,
|
||||||
CHORUS_TYPE_FLANGER = 0x37d,
|
CHORUS_TYPE_FLANGER = 893,
|
||||||
CHORUS_TYPE_TRIGGERED_FLANGER = 0x37e,
|
CHORUS_TYPE_TRIGGERED_FLANGER = 894,
|
||||||
CHORUS_TYPE_FLTFLANGER = 0x398,
|
CHORUS_TYPE_FLTFLANGER = 920,
|
||||||
CHORUS_TYPE_MXR_FLANGER = 0x37f,
|
CHORUS_TYPE_MXR_FLANGER = 895,
|
||||||
CHORUS_TYPE_EH_FLANGER = 0x380,
|
CHORUS_TYPE_EH_FLANGER = 896,
|
||||||
CHORUS_TYPE_AD_FLANGER = 0x393,
|
CHORUS_TYPE_AD_FLANGER = 915,
|
||||||
CHORUS_TYPE_PHASER = 0x381,
|
CHORUS_TYPE_PHASER = 897,
|
||||||
CHORUS_TYPE_TRIGGERED_PHASER = 0x382,
|
CHORUS_TYPE_TRIGGERED_PHASER = 898,
|
||||||
CHORUS_TYPE_MX_PHASER = 0x383,
|
CHORUS_TYPE_MX_PHASER = 899,
|
||||||
CHORUS_TYPE_EH_PHASER = 0x384,
|
CHORUS_TYPE_EH_PHASER = 900,
|
||||||
CHORUS_TYPE_VIBRATO = 0x360,
|
CHORUS_TYPE_VIBRATO = 864,
|
||||||
CHORUS_TYPE_ROTARY = 0x361,
|
CHORUS_TYPE_ROTARY = 865,
|
||||||
CHORUS_TYPE_VIBROPAN = 0x38f,
|
CHORUS_TYPE_VIBROPAN = 911,
|
||||||
CHORUS_TYPE_UNOVIBE = 0x390,
|
CHORUS_TYPE_UNOVIBE = 912,
|
||||||
CHORUS_TYPE_TREMOLO = 0x35e,
|
CHORUS_TYPE_TREMOLO = 862,
|
||||||
CHORUS_TYPE_SCATTER_TREM = 0x394,
|
CHORUS_TYPE_SCATTER_TREM = 916,
|
||||||
CHORUS_TYPE_OPTO_TREMOLO = 0x388,
|
CHORUS_TYPE_OPTO_TREMOLO = 904,
|
||||||
CHORUS_TYPE_BIAS_TREMOLO = 0x389,
|
CHORUS_TYPE_BIAS_TREMOLO = 905,
|
||||||
CHORUS_TYPE_PANNER = 0x35f,
|
CHORUS_TYPE_PANNER = 863,
|
||||||
CHORUS_TYPE_ENVELOPE = 0x38a,
|
CHORUS_TYPE_ENVELOPE = 906,
|
||||||
CHORUS_TYPE_FX25 = 0x38e,
|
CHORUS_TYPE_FX25 = 910,
|
||||||
CHORUS_TYPE_AUTOYA = 0x38b,
|
CHORUS_TYPE_AUTOYA = 907,
|
||||||
CHORUS_TYPE_YAYA = 0x38c,
|
CHORUS_TYPE_YAYA = 908,
|
||||||
CHORUS_TYPE_SYNTH_TALK = 0x391,
|
CHORUS_TYPE_SYNTH_TALK = 913,
|
||||||
CHORUS_TYPE_STEP_FILTER = 0x38d,
|
CHORUS_TYPE_STEP_FILTER = 909,
|
||||||
CHORUS_TYPE_SAMPLE_HOLD = 0x395,
|
CHORUS_TYPE_SAMPLE_HOLD = 917,
|
||||||
CHORUS_TYPE_WHAMMY = 0x540,
|
CHORUS_TYPE_WHAMMY = 1344,
|
||||||
CHORUS_TYPE_PITCH_SHIFT = 0x543,
|
CHORUS_TYPE_PITCH_SHIFT = 1347,
|
||||||
CHORUS_TYPE_DETUNE = 0x542,
|
CHORUS_TYPE_DETUNE = 1346,
|
||||||
CHORUS_TYPE_IPS = 0x541,
|
CHORUS_TYPE_IPS = 1345, // Also known as Harmony
|
||||||
CHORUS_TYPE_OCTAVER = 0x385,
|
CHORUS_TYPE_OCTAVER = 901,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MOD_TYPE 768
|
||||||
|
#define MOD_PRE_POST 1798
|
||||||
|
|
||||||
#define CHORUSFX_TYPE 768
|
#define CHORUSFX_TYPE 768
|
||||||
#define CHORUSFX_ON_OFF 769
|
#define CHORUSFX_ON_OFF 769
|
||||||
#define CHORUSFX_PRE_POST 770
|
#define CHORUSFX_PRE_POST 770
|
||||||
|
|
||||||
#define CHORUSFX_POSITION 14
|
#define CHORUSFX_POSITION 14
|
||||||
#define CHORUSFX_PRE 1543
|
#define CHORUSFX_PRE 1543
|
||||||
#define CHORUSFX_POST 1544
|
#define CHORUSFX_POST 1544
|
||||||
@@ -521,6 +550,12 @@ enum {
|
|||||||
#define CHORUS_WIDTH 848
|
#define CHORUS_WIDTH 848
|
||||||
#define CHORUS_INTENSITY 849
|
#define CHORUS_INTENSITY 849
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CHORUS_WAVEFORM_TRI = 0,
|
||||||
|
CHORUS_WAVEFORM_SINE = 1,
|
||||||
|
CHORUS_WAVEFORM_SQUARE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
#define CHORUS_LEVEL 836
|
#define CHORUS_LEVEL 836
|
||||||
#define CHORUS_WAVE 840
|
#define CHORUS_WAVE 840
|
||||||
#define CHORUS_BALANCE 841
|
#define CHORUS_BALANCE 841
|
||||||
@@ -638,6 +673,25 @@ enum {
|
|||||||
#define WHAMMY_PEDAL 1795
|
#define WHAMMY_PEDAL 1795
|
||||||
#define WHAMMY_MIX 1796
|
#define WHAMMY_MIX 1796
|
||||||
|
|
||||||
|
enum whammy_amt {
|
||||||
|
WHAMMY_TYPE_OCT_UP = 0,
|
||||||
|
WHAMMY_TYPE_2OCT_UP = 1,
|
||||||
|
WHAMMY_TYPE_2ND_DN = 2,
|
||||||
|
WHAMMY_TYPE_RV2ND_DN = 3,
|
||||||
|
WHAMMY_TYPE_4TH_DN = 4,
|
||||||
|
WHAMMY_TYPE_OCT_DN = 5,
|
||||||
|
WHAMMY_TYPE_2OCT_DN = 6,
|
||||||
|
WHAMMY_TYPE_DIV_BMB = 7,
|
||||||
|
WHAMMY_TYPE_M3_GT_MA3 = 8,
|
||||||
|
WHAMMY_TYPE_2ND_MA3 = 9,
|
||||||
|
WHAMMY_TYPE_3RD_4TH = 10,
|
||||||
|
WHAMMY_TYPE_4TH_5TH = 11,
|
||||||
|
WHAMMY_TYPE_5TH_OCT = 12,
|
||||||
|
WHAMMY_TYPE_HOCT_UP = 13,
|
||||||
|
WHAMMY_TYPE_HOCT_DN = 14,
|
||||||
|
WHAMMY_TYPE_OCT_GT_D = 15,
|
||||||
|
};
|
||||||
|
|
||||||
#define PITCH_AMOUNT 1730
|
#define PITCH_AMOUNT 1730
|
||||||
#define PITCH_BALANCE 1733
|
#define PITCH_BALANCE 1733
|
||||||
#define PITCH_MIX 1745
|
#define PITCH_MIX 1745
|
||||||
@@ -651,6 +705,47 @@ enum {
|
|||||||
#define IPS_SCALE 2755
|
#define IPS_SCALE 2755
|
||||||
#define IPS_LEVEL 2757
|
#define IPS_LEVEL 2757
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IPS_KEY_E = 0,
|
||||||
|
IPS_KEY_F = 1,
|
||||||
|
IPS_KEY_Gb = 2,
|
||||||
|
IPS_KEY_G = 3,
|
||||||
|
IPS_KEY_Ab = 4,
|
||||||
|
IPS_KEY_A = 5,
|
||||||
|
IPS_KEY_Bb = 6,
|
||||||
|
IPS_KEY_B = 7,
|
||||||
|
IPS_KEY_C = 8,
|
||||||
|
IPS_KEY_Db = 9,
|
||||||
|
IPS_KEY_D = 10,
|
||||||
|
IPS_KEY_Eb = 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IPS_SHIFT_OCT_DN = 0,
|
||||||
|
IPS_SHIFT_7TH_DN = 1,
|
||||||
|
IPS_SHIFT_6TH_DN = 2,
|
||||||
|
IPS_SHIFT_5TH_DN = 3,
|
||||||
|
IPS_SHIFT_4TH_DN = 4,
|
||||||
|
IPS_SHIFT_3RD_DN = 5,
|
||||||
|
IPS_SHIFT_2ND_DN = 6,
|
||||||
|
IPS_SHIFT_2ND_UP = 7,
|
||||||
|
IPS_SHIFT_3RD_UP = 8,
|
||||||
|
IPS_SHIFT_4TH_UP = 9,
|
||||||
|
IPS_SHIFT_5TH_UP = 10,
|
||||||
|
IPS_SHIFT_6TH_UP = 11,
|
||||||
|
IPS_SHIFT_7TH_UP = 12,
|
||||||
|
IPS_SHIFT_OCT_UP = 13,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IPS_SCALE_MAJOR = 0,
|
||||||
|
IPS_SCALE_MINOR = 1,
|
||||||
|
IPS_SCALE_DORIAN = 2,
|
||||||
|
IPS_SCALE_MIXOLYDIAN = 3,
|
||||||
|
IPS_SCALE_LYDIAN = 4,
|
||||||
|
IPS_SCALE_HMINOR = 5,
|
||||||
|
};
|
||||||
|
|
||||||
#define OCTAVER_OCTAVE1 1746
|
#define OCTAVER_OCTAVE1 1746
|
||||||
#define OCTAVER_OCTAVE2 1747
|
#define OCTAVER_OCTAVE2 1747
|
||||||
#define OCTAVER_DRY_LEVEL 1748
|
#define OCTAVER_DRY_LEVEL 1748
|
||||||
@@ -757,19 +852,66 @@ enum {
|
|||||||
#define REVERB_LEVEL 1925
|
#define REVERB_LEVEL 1925
|
||||||
|
|
||||||
#define EXP_TYPE 8194
|
#define EXP_TYPE 8194
|
||||||
|
#define EXP_ASSIGN1 8194
|
||||||
#define EXP_POSITION 19
|
#define EXP_POSITION 19
|
||||||
|
|
||||||
|
#define EXP_VOLUME_PRE_FX 854594
|
||||||
|
#define EXP_VOLUME_POST_FX 1116738
|
||||||
|
|
||||||
#define EXP_MIN 8195
|
#define EXP_MIN 8195
|
||||||
#define EXP_MAX 8196
|
#define EXP_MAX 8196
|
||||||
|
|
||||||
#define LFO_TYPE 8258
|
#define LFO_TYPE 8258
|
||||||
|
#define LFO_MIN 8259
|
||||||
|
#define LFO_MAX 8260
|
||||||
|
#define LFO_SPEED 8262
|
||||||
|
#define LFO_WAVEFORM 8263
|
||||||
|
|
||||||
|
#define LFO_WAVEFORM_TRI 0
|
||||||
|
#define LFO_WAVEFORM_SINE 1
|
||||||
|
#define LFO_WAVEFORM_SQUARE 2
|
||||||
|
|
||||||
#define LFO1_POSITION 22
|
#define LFO1_POSITION 22
|
||||||
#define LFO2_POSITION 23
|
#define LFO2_POSITION 23
|
||||||
|
|
||||||
|
// The LFO and VSWITCH defines are temporary.
|
||||||
|
#define LFO_ASSIGN_NONE 0
|
||||||
|
#define LFO_ASSIGN_PICKUP_ON 131137
|
||||||
|
#define LFO_ASSIGN_COMP_ON 262337
|
||||||
|
#define LFO_ASSIGN_SUSTAN 262352
|
||||||
|
|
||||||
|
#define VSWITCH_ASSIGN 8384
|
||||||
|
#define VSWITCH_MIN 8385
|
||||||
|
#define VSWITCH_MAX 8386
|
||||||
|
#define VSWITCH_TYPE 8393
|
||||||
|
#define VSWITCH_ENABLE 8449
|
||||||
|
#define VSWITCH_ASSIGN_POSITION 21
|
||||||
|
|
||||||
|
#define VSWITCH_TYPE_TOGGLE 0
|
||||||
|
#define VSWITCH_PEDAL_ASSIGN_WAH 196740
|
||||||
|
#define VSWITCH_ASSIGN_WAH_ENABLE 196737
|
||||||
|
|
||||||
|
#define FOOTSWITCH_6_POSITION 28
|
||||||
|
#define FOOTSWITCH_7_POSITION 29
|
||||||
|
#define FOOTSWITCH_8_POSITION 30
|
||||||
|
#define FOOTSWITCH_9_POSITION 31
|
||||||
|
#define FOOTSWITCH_10_POSITION 32
|
||||||
|
|
||||||
#define LIBRARY_TONE 8704
|
#define LIBRARY_TONE 8704
|
||||||
#define LIBRARY_EFFECTS 8705
|
#define LIBRARY_EFFECTS 8705
|
||||||
#define EFFECTS_LEVEL 8706
|
#define EFFECTS_LEVEL 8706
|
||||||
|
|
||||||
#define LIBRARY_POSITION 25
|
#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 // 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
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TONE_LIB_OVERDRIVE = 1793,
|
TONE_LIB_OVERDRIVE = 1793,
|
||||||
@@ -843,12 +985,17 @@ enum {
|
|||||||
EFFECTS_LIB_CUSTOM = 1856
|
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_PLAYBACK_MIX 12297
|
||||||
#define USB_AUDIO_LEVEL 12307
|
#define USB_AUDIO_LEVEL 12307
|
||||||
|
|
||||||
#define GUI_MODE_ON_OFF 12298
|
#define GUI_MODE_ON_OFF 12298
|
||||||
|
|
||||||
|
#define EXP_PEDAL_LEVEL 12300
|
||||||
|
#define STOMP_MODE 12370
|
||||||
|
|
||||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -994,6 +1141,7 @@ void setting_genetx_free(SettingGenetx *genetx);
|
|||||||
void setting_param_free(SettingParam *param);
|
void setting_param_free(SettingParam *param);
|
||||||
SectionID get_genetx_section_id(gint version, gint type);
|
SectionID get_genetx_section_id(gint version, gint type);
|
||||||
void set_option(guint id, guint position, guint value);
|
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,
|
void send_object(SectionID section, guint bank, guint index,
|
||||||
gchar *name, GString *data);
|
gchar *name, GString *data);
|
||||||
void send_preset_parameters(GList *params);
|
void send_preset_parameters(GList *params);
|
||||||
@@ -1003,5 +1151,6 @@ void set_preset_level(int level);
|
|||||||
GStrv query_preset_names(gchar bank);
|
GStrv query_preset_names(gchar bank);
|
||||||
void message_list_free(GList *list);
|
void message_list_free(GList *list);
|
||||||
GList *get_current_preset();
|
GList *get_current_preset();
|
||||||
|
GString *format_ipv(guint id, guint pos, guint val);
|
||||||
|
|
||||||
#endif /* GDIGI_H */
|
#endif /* GDIGI_H */
|
||||||
|
|||||||
40
gdigi_xml.h
Normal file
40
gdigi_xml.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009 Tomasz Moń <desowin@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; under version 3 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GDIGI_XML_H
|
||||||
|
#define GDIGI_XML_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include "effects.h"
|
||||||
|
typedef struct {
|
||||||
|
guint type;
|
||||||
|
gchar *label;
|
||||||
|
} XmlLabel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint id;
|
||||||
|
guint position;
|
||||||
|
gchar *label;
|
||||||
|
EffectValues *values;
|
||||||
|
XmlLabel *xml_labels; /* 'type' id's have a label group. */
|
||||||
|
guint xml_labels_amt;
|
||||||
|
} XmlSettings;
|
||||||
|
|
||||||
|
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 */
|
||||||
444
gtkknob.c
444
gtkknob.c
@@ -4,7 +4,7 @@
|
|||||||
* Tony Garnock-Jones, with modifications from Sean Bolton,
|
* Tony Garnock-Jones, with modifications from Sean Bolton,
|
||||||
* copyright (C) 2004, William Weston copyright (C) 2007,
|
* copyright (C) 2004, William Weston copyright (C) 2007,
|
||||||
* Pete Shorthose copyright (C) 2007, and Tomasz Moń,
|
* Pete Shorthose copyright (C) 2007, and Tomasz Moń,
|
||||||
* copyright (C) 2009
|
* copyright (C) 2009-2011
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -18,14 +18,16 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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>
|
#include <math.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gdk/gdkkeysyms.h>
|
#include <gdk/gdkkeysyms.h>
|
||||||
|
#include <string.h>
|
||||||
#include "gtkknob.h"
|
#include "gtkknob.h"
|
||||||
|
#include "knob.h"
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
# define M_PI 3.14159265358979323846 /* pi */
|
# define M_PI 3.14159265358979323846 /* pi */
|
||||||
@@ -44,11 +46,15 @@
|
|||||||
|
|
||||||
static void gtk_knob_class_init(GtkKnobClass *klass);
|
static void gtk_knob_class_init(GtkKnobClass *klass);
|
||||||
static void gtk_knob_init(GtkKnob *knob);
|
static void gtk_knob_init(GtkKnob *knob);
|
||||||
static void gtk_knob_destroy(GtkObject *object);
|
static void gtk_knob_destroy(GtkWidget *object);
|
||||||
static void gtk_knob_realize(GtkWidget *widget);
|
static void gtk_knob_realize(GtkWidget *widget);
|
||||||
static void gtk_knob_size_request(GtkWidget *widget, GtkRequisition *requisition);
|
static void gtk_knob_unrealize(GtkWidget *widget);
|
||||||
|
static void gtk_knob_map(GtkWidget *widget);
|
||||||
|
static void gtk_knob_unmap(GtkWidget *widget);
|
||||||
|
static void gtk_knob_get_preferred_width(GtkWidget *widget, gint *minimum_width, gint *natural_width);
|
||||||
|
static void gtk_knob_get_preferred_height(GtkWidget *widget, gint *minimum_height, gint *natural_height);
|
||||||
static void gtk_knob_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
|
static void gtk_knob_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
|
||||||
static gint gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event);
|
static gboolean gtk_knob_draw(GtkWidget *widget, cairo_t *cr);
|
||||||
static gint gtk_knob_scroll(GtkWidget *widget, GdkEventScroll *event);
|
static gint gtk_knob_scroll(GtkWidget *widget, GdkEventScroll *event);
|
||||||
static gint gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event);
|
static gint gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event);
|
||||||
static gint gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event);
|
static gint gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event);
|
||||||
@@ -102,25 +108,27 @@ gtk_knob_get_type(void) {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void
|
static void
|
||||||
gtk_knob_class_init (GtkKnobClass *klass) {
|
gtk_knob_class_init (GtkKnobClass *klass) {
|
||||||
GtkObjectClass *object_class;
|
|
||||||
GtkWidgetClass *widget_class;
|
GtkWidgetClass *widget_class;
|
||||||
|
|
||||||
object_class = (GtkObjectClass*) klass;
|
|
||||||
widget_class = (GtkWidgetClass*) klass;
|
widget_class = (GtkWidgetClass*) klass;
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent(klass);
|
parent_class = g_type_class_peek_parent(klass);
|
||||||
|
|
||||||
object_class->destroy = gtk_knob_destroy;
|
widget_class->destroy = gtk_knob_destroy;
|
||||||
|
|
||||||
widget_class->realize = gtk_knob_realize;
|
widget_class->realize = gtk_knob_realize;
|
||||||
widget_class->expose_event = gtk_knob_expose;
|
widget_class->unrealize = gtk_knob_unrealize;
|
||||||
widget_class->size_request = gtk_knob_size_request;
|
widget_class->draw = gtk_knob_draw;
|
||||||
|
widget_class->get_preferred_width = gtk_knob_get_preferred_width;
|
||||||
|
widget_class->get_preferred_height = gtk_knob_get_preferred_height;
|
||||||
widget_class->size_allocate = gtk_knob_size_allocate;
|
widget_class->size_allocate = gtk_knob_size_allocate;
|
||||||
widget_class->scroll_event = gtk_knob_scroll;
|
widget_class->scroll_event = gtk_knob_scroll;
|
||||||
widget_class->button_press_event = gtk_knob_button_press;
|
widget_class->button_press_event = gtk_knob_button_press;
|
||||||
widget_class->button_release_event = gtk_knob_button_release;
|
widget_class->button_release_event = gtk_knob_button_release;
|
||||||
widget_class->key_press_event = gtk_knob_key_press;
|
widget_class->key_press_event = gtk_knob_key_press;
|
||||||
widget_class->motion_notify_event = gtk_knob_motion_notify;
|
widget_class->motion_notify_event = gtk_knob_motion_notify;
|
||||||
|
widget_class->map = gtk_knob_map;
|
||||||
|
widget_class->unmap = gtk_knob_unmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -131,19 +139,22 @@ gtk_knob_class_init (GtkKnobClass *klass) {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void
|
static void
|
||||||
gtk_knob_init (GtkKnob *knob) {
|
gtk_knob_init (GtkKnob *knob) {
|
||||||
knob->policy = GTK_UPDATE_CONTINUOUS;
|
knob->policy = GTK_KNOB_UPDATE_CONTINUOUS;
|
||||||
knob->state = STATE_IDLE;
|
knob->state = STATE_IDLE;
|
||||||
knob->saved_x = 0;
|
knob->saved_x = 0;
|
||||||
knob->saved_y = 0;
|
knob->saved_y = 0;
|
||||||
knob->timer = 0;
|
knob->timer = 0;
|
||||||
knob->anim = NULL;
|
knob->anim = NULL;
|
||||||
knob->mask = NULL;
|
|
||||||
knob->mask_gc = NULL;
|
|
||||||
knob->red_gc = NULL;
|
|
||||||
knob->old_value = 0.0;
|
knob->old_value = 0.0;
|
||||||
knob->old_lower = 0.0;
|
knob->old_lower = 0.0;
|
||||||
knob->old_upper = 0.0;
|
knob->old_upper = 0.0;
|
||||||
knob->adjustment = NULL;
|
knob->adjustment = NULL;
|
||||||
|
|
||||||
|
gtk_widget_set_can_focus(GTK_WIDGET(knob), TRUE);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -157,7 +168,6 @@ gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim) {
|
|||||||
GtkKnob *knob;
|
GtkKnob *knob;
|
||||||
|
|
||||||
g_return_val_if_fail (anim != NULL, NULL);
|
g_return_val_if_fail (anim != NULL, NULL);
|
||||||
g_return_val_if_fail (GDK_IS_PIXBUF (anim->pixbuf), NULL);
|
|
||||||
|
|
||||||
knob = g_object_new (gtk_knob_get_type (), NULL);
|
knob = g_object_new (gtk_knob_get_type (), NULL);
|
||||||
|
|
||||||
@@ -180,7 +190,7 @@ gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim) {
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void
|
static void
|
||||||
gtk_knob_destroy(GtkObject *object) {
|
gtk_knob_destroy(GtkWidget *object) {
|
||||||
GtkKnob *knob;
|
GtkKnob *knob;
|
||||||
|
|
||||||
g_return_if_fail (object != NULL);
|
g_return_if_fail (object != NULL);
|
||||||
@@ -196,22 +206,8 @@ gtk_knob_destroy(GtkObject *object) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (knob->mask) {
|
if (GTK_WIDGET_CLASS(parent_class)->destroy) {
|
||||||
g_object_unref (knob->mask);
|
(*GTK_WIDGET_CLASS (parent_class)->destroy) (object);
|
||||||
knob->mask = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (knob->mask_gc) {
|
|
||||||
g_object_unref (knob->mask_gc);
|
|
||||||
knob->mask_gc = NULL;
|
|
||||||
}
|
|
||||||
if (knob->red_gc) {
|
|
||||||
g_object_unref (knob->red_gc);
|
|
||||||
knob->red_gc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GTK_OBJECT_CLASS (parent_class)->destroy) {
|
|
||||||
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +233,7 @@ gtk_knob_get_adjustment(GtkKnob *knob) {
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void
|
void
|
||||||
gtk_knob_set_update_policy(GtkKnob *knob, GtkUpdateType policy) {
|
gtk_knob_set_update_policy(GtkKnob *knob, GtkKnobUpdateType policy) {
|
||||||
|
|
||||||
g_return_if_fail (knob != NULL);
|
g_return_if_fail (knob != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (knob));
|
g_return_if_fail (GTK_IS_KNOB (knob));
|
||||||
@@ -276,9 +272,9 @@ gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment) {
|
|||||||
G_CALLBACK(gtk_knob_adjustment_value_changed),
|
G_CALLBACK(gtk_knob_adjustment_value_changed),
|
||||||
knob);
|
knob);
|
||||||
|
|
||||||
knob->old_value = adjustment->value;
|
knob->old_value = gtk_adjustment_get_value(adjustment);
|
||||||
knob->old_lower = adjustment->lower;
|
knob->old_lower = gtk_adjustment_get_lower(adjustment);
|
||||||
knob->old_upper = adjustment->upper;
|
knob->old_upper = gtk_adjustment_get_upper(adjustment);
|
||||||
|
|
||||||
gtk_knob_update (knob);
|
gtk_knob_update (knob);
|
||||||
}
|
}
|
||||||
@@ -293,66 +289,98 @@ gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment) {
|
|||||||
static void
|
static void
|
||||||
gtk_knob_realize(GtkWidget *widget) {
|
gtk_knob_realize(GtkWidget *widget) {
|
||||||
GtkKnob *knob;
|
GtkKnob *knob;
|
||||||
|
GdkWindow *window;
|
||||||
GdkWindowAttr attributes;
|
GdkWindowAttr attributes;
|
||||||
|
GtkAllocation allocation;
|
||||||
|
|
||||||
gint attributes_mask;
|
gint attributes_mask;
|
||||||
GdkColor color = { 0, 0xffff, 0, 0 };
|
|
||||||
|
|
||||||
g_return_if_fail (widget != NULL);
|
g_return_if_fail (widget != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (widget));
|
g_return_if_fail (GTK_IS_KNOB (widget));
|
||||||
|
|
||||||
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
|
gtk_widget_set_realized(widget, TRUE);
|
||||||
knob = GTK_KNOB (widget);
|
knob = GTK_KNOB (widget);
|
||||||
|
|
||||||
attributes.x = widget->allocation.x;
|
|
||||||
attributes.y = widget->allocation.y;
|
|
||||||
attributes.width = widget->allocation.width;
|
|
||||||
attributes.height = widget->allocation.height;
|
|
||||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
|
||||||
attributes.window_type = GDK_WINDOW_CHILD;
|
attributes.window_type = GDK_WINDOW_CHILD;
|
||||||
|
attributes.x = allocation.x;
|
||||||
|
attributes.y = allocation.y;
|
||||||
|
attributes.width = allocation.width;
|
||||||
|
attributes.height = allocation.height;
|
||||||
|
attributes.wclass = GDK_INPUT_ONLY;;
|
||||||
attributes.event_mask =
|
attributes.event_mask =
|
||||||
gtk_widget_get_events (widget) |
|
gtk_widget_get_events (widget) |
|
||||||
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
|
GDK_BUTTON_PRESS_MASK |
|
||||||
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
|
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
|
||||||
GDK_POINTER_MOTION_HINT_MASK;
|
GDK_POINTER_MOTION_HINT_MASK;
|
||||||
attributes.visual = gtk_widget_get_visual (widget);
|
|
||||||
attributes.colormap = gtk_widget_get_colormap (widget);
|
|
||||||
|
|
||||||
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
|
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
||||||
|
|
||||||
widget->window = gdk_window_new (widget->parent->window,
|
window = gtk_widget_get_parent_window(widget);
|
||||||
&attributes, attributes_mask);
|
gtk_widget_set_window(widget, window);
|
||||||
|
g_object_ref(window);
|
||||||
|
|
||||||
widget->style = gtk_style_attach (widget->style, widget->window);
|
knob->event_window = gdk_window_new(window, &attributes, attributes_mask);
|
||||||
|
gdk_window_set_user_data(knob->event_window, knob);
|
||||||
gdk_window_set_user_data (widget->window, widget);
|
|
||||||
|
|
||||||
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
|
|
||||||
|
|
||||||
knob->mask_gc = gdk_gc_new (widget->window);
|
|
||||||
gdk_gc_copy (knob->mask_gc, widget->style->bg_gc[GTK_STATE_NORMAL]);
|
|
||||||
gdk_gc_set_clip_mask (knob->mask_gc, knob->mask);
|
|
||||||
|
|
||||||
knob->red_gc = gdk_gc_new (widget->window);
|
|
||||||
gdk_gc_copy (knob->red_gc, widget->style->bg_gc[GTK_STATE_NORMAL]);
|
|
||||||
gdk_colormap_alloc_color (attributes.colormap, &color, FALSE, TRUE);
|
|
||||||
gdk_gc_set_foreground (knob->red_gc, &color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* gtk_knob_size_request()
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
static void
|
static void
|
||||||
gtk_knob_size_request (GtkWidget *widget, GtkRequisition *requisition) {
|
gtk_knob_unrealize(GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkKnob *knob = GTK_KNOB(widget);
|
||||||
|
|
||||||
|
if (knob->event_window)
|
||||||
|
{
|
||||||
|
gdk_window_set_user_data(knob->event_window, NULL);
|
||||||
|
gdk_window_destroy(knob->event_window);
|
||||||
|
knob->event_window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_knob_map(GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkKnob *knob = GTK_KNOB(widget);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(parent_class)->map(widget);
|
||||||
|
|
||||||
|
if (knob->event_window)
|
||||||
|
gdk_window_show(knob->event_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_knob_unmap(GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkKnob *knob = GTK_KNOB(widget);
|
||||||
|
|
||||||
|
if (knob->event_window)
|
||||||
|
gdk_window_hide(knob->event_window);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(parent_class)->unmap(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_knob_get_preferred_width(GtkWidget *widget,
|
||||||
|
gint *minimum_width,
|
||||||
|
gint *natural_width)
|
||||||
|
{
|
||||||
g_return_if_fail (widget != NULL);
|
g_return_if_fail (widget != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (widget));
|
g_return_if_fail (GTK_IS_KNOB (widget));
|
||||||
|
|
||||||
requisition->width = GTK_KNOB (widget)->width;
|
*minimum_width = *natural_width = GTK_KNOB(widget)->width;
|
||||||
requisition->height = GTK_KNOB (widget)->height;
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_knob_get_preferred_height(GtkWidget *widget,
|
||||||
|
gint *minimum_height,
|
||||||
|
gint *natural_height)
|
||||||
|
{
|
||||||
|
g_return_if_fail (widget != NULL);
|
||||||
|
g_return_if_fail (GTK_IS_KNOB (widget));
|
||||||
|
|
||||||
|
*minimum_height = *natural_height = GTK_KNOB(widget)->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -369,11 +397,11 @@ gtk_knob_size_allocate (GtkWidget *widget, GtkAllocation *allocation) {
|
|||||||
g_return_if_fail (GTK_IS_KNOB (widget));
|
g_return_if_fail (GTK_IS_KNOB (widget));
|
||||||
g_return_if_fail (allocation != NULL);
|
g_return_if_fail (allocation != NULL);
|
||||||
|
|
||||||
widget->allocation = *allocation;
|
gtk_widget_set_allocation(widget, allocation);
|
||||||
knob = GTK_KNOB (widget);
|
knob = GTK_KNOB (widget);
|
||||||
|
|
||||||
if (GTK_WIDGET_REALIZED (widget)) {
|
if (gtk_widget_get_realized (widget)) {
|
||||||
gdk_window_move_resize (widget->window,
|
gdk_window_move_resize (knob->event_window,
|
||||||
allocation->x, allocation->y,
|
allocation->x, allocation->y,
|
||||||
allocation->width, allocation->height);
|
allocation->width, allocation->height);
|
||||||
}
|
}
|
||||||
@@ -382,39 +410,50 @@ gtk_knob_size_allocate (GtkWidget *widget, GtkAllocation *allocation) {
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* gtk_knob_expose()
|
* gtk_knob_draw()
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static gint
|
static gboolean
|
||||||
gtk_knob_expose(GtkWidget *widget, GdkEventExpose *event) {
|
gtk_knob_draw(GtkWidget *widget, cairo_t *cr) {
|
||||||
GtkKnob *knob;
|
GtkKnob *knob;
|
||||||
gfloat dx, dy;
|
gdouble dx, dy;
|
||||||
gint frames;
|
gint frames;
|
||||||
|
|
||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
g_return_val_if_fail (widget != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (widget), FALSE);
|
||||||
g_return_val_if_fail (event != NULL, FALSE);
|
g_return_val_if_fail (cr != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (GTK_KNOB (widget)->adjustment), FALSE);
|
||||||
|
|
||||||
if (event->count > 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
knob = GTK_KNOB (widget);
|
knob = GTK_KNOB (widget);
|
||||||
|
|
||||||
frames = ((knob->anim->width / knob->anim->frame_width) - 1);
|
frames = ((knob->anim->width / knob->anim->frame_width) - 1);
|
||||||
dx = knob->adjustment->value - knob->adjustment->lower; /* value, from 0 */
|
dx = gtk_adjustment_get_value(knob->adjustment) - gtk_adjustment_get_lower(knob->adjustment); /* value, from 0 */
|
||||||
dy = knob->adjustment->upper - knob->adjustment->lower; /* range */
|
dy = gtk_adjustment_get_upper(knob->adjustment) - gtk_adjustment_get_lower(knob->adjustment); /* range */
|
||||||
|
|
||||||
dx = (int)(frames * dx / dy) * knob->width; /* check this for height != width */
|
dx = (int)(frames * dx / dy) * knob->width; /* check this for height != width */
|
||||||
|
|
||||||
gdk_draw_pixbuf (widget->window, knob->mask_gc, knob->anim->pixbuf,
|
cairo_surface_t *surface =
|
||||||
dx, 0, 0, 0, knob->width, knob->height,
|
cairo_surface_create_for_rectangle(knob->anim->image,
|
||||||
GDK_RGB_DITHER_NONE, 0, 0);
|
dx, 0.0,
|
||||||
|
(double)knob->width,
|
||||||
|
(double)knob->height);
|
||||||
|
cairo_set_source_surface(cr, surface, 0, 0);
|
||||||
|
cairo_paint(cr);
|
||||||
|
cairo_surface_destroy(surface);
|
||||||
|
|
||||||
if (GTK_WIDGET_HAS_FOCUS(widget)) {
|
if (gtk_widget_has_focus(widget)) {
|
||||||
gtk_paint_focus (widget->style, widget->window, widget->state,
|
GtkStyleContext *context;
|
||||||
NULL, widget, NULL, 0, 0,
|
|
||||||
widget->allocation.width, widget->allocation.height);
|
context = gtk_widget_get_style_context(widget);
|
||||||
|
gtk_style_context_save(context);
|
||||||
|
gtk_style_context_set_state(context, gtk_widget_get_state_flags (widget));
|
||||||
|
cairo_save(cr);
|
||||||
|
gtk_render_focus(context, cr,
|
||||||
|
0, 0,
|
||||||
|
gtk_widget_get_allocated_width(widget),
|
||||||
|
gtk_widget_get_allocated_height(widget));
|
||||||
|
cairo_restore(cr);
|
||||||
|
gtk_style_context_restore(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -439,11 +478,15 @@ gtk_knob_scroll(GtkWidget *widget, GdkEventScroll *event) {
|
|||||||
|
|
||||||
switch (event->direction) {
|
switch (event->direction) {
|
||||||
case GDK_SCROLL_UP:
|
case GDK_SCROLL_UP:
|
||||||
knob->adjustment->value += knob->adjustment->step_increment;
|
gtk_adjustment_set_value(knob->adjustment,
|
||||||
|
gtk_adjustment_get_value(knob->adjustment) +
|
||||||
|
gtk_adjustment_get_step_increment(knob->adjustment));
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
break;
|
break;
|
||||||
case GDK_SCROLL_DOWN:
|
case GDK_SCROLL_DOWN:
|
||||||
knob->adjustment->value -= knob->adjustment->step_increment;
|
gtk_adjustment_set_value(knob->adjustment,
|
||||||
|
gtk_adjustment_get_value(knob->adjustment) -
|
||||||
|
gtk_adjustment_get_step_increment(knob->adjustment));
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -475,16 +518,17 @@ gtk_knob_button_press(GtkWidget *widget, GdkEventButton *event) {
|
|||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
if (!GTK_WIDGET_HAS_FOCUS(widget))
|
if (!gtk_widget_has_focus(widget))
|
||||||
gtk_widget_grab_focus(widget);
|
gtk_widget_grab_focus(widget);
|
||||||
knob->state = STATE_PRESSED;
|
knob->state = STATE_PRESSED;
|
||||||
knob->saved_x = event->x;
|
knob->saved_x = event->x;
|
||||||
knob->saved_y = event->y;
|
knob->saved_y = event->y;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
knob->adjustment->value = floor ((knob->adjustment->lower +
|
gtk_adjustment_set_value(knob->adjustment,
|
||||||
knob->adjustment->upper + 1.0)
|
floor ((gtk_adjustment_get_lower(knob->adjustment) +
|
||||||
* 0.5);
|
gtk_adjustment_get_upper(knob->adjustment) + 1.0)
|
||||||
|
* 0.5));
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -523,8 +567,8 @@ gtk_knob_button_release(GtkWidget *widget, GdkEventButton *event) {
|
|||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
if (knob->policy != GTK_UPDATE_CONTINUOUS
|
if (knob->policy != GTK_KNOB_UPDATE_CONTINUOUS
|
||||||
&& knob->old_value != knob->adjustment->value)
|
&& knob->old_value != gtk_adjustment_get_value(knob->adjustment))
|
||||||
{
|
{
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
}
|
}
|
||||||
@@ -550,20 +594,20 @@ static gint gtk_knob_key_press(GtkWidget *widget, GdkEventKey *event)
|
|||||||
|
|
||||||
switch (event->keyval) {
|
switch (event->keyval) {
|
||||||
|
|
||||||
case GDK_Up:
|
case GDK_KEY_Up:
|
||||||
if (GTK_WIDGET_HAS_FOCUS (widget))
|
if (gtk_widget_has_focus (widget))
|
||||||
{
|
{
|
||||||
gtk_adjustment_set_value (knob->adjustment,
|
gtk_adjustment_set_value (knob->adjustment,
|
||||||
knob->old_value + knob->adjustment->step_increment);
|
knob->old_value + gtk_adjustment_get_step_increment(knob->adjustment));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
case GDK_Down:
|
case GDK_KEY_Down:
|
||||||
if (GTK_WIDGET_HAS_FOCUS (widget))
|
if (gtk_widget_has_focus (widget))
|
||||||
{
|
{
|
||||||
gtk_adjustment_set_value (knob->adjustment,
|
gtk_adjustment_set_value (knob->adjustment,
|
||||||
knob->old_value - knob->adjustment->step_increment);
|
knob->old_value - gtk_adjustment_get_step_increment(knob->adjustment));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -582,7 +626,7 @@ static gint gtk_knob_key_press(GtkWidget *widget, GdkEventKey *event)
|
|||||||
static gint
|
static gint
|
||||||
gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
|
gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
|
||||||
GtkKnob *knob;
|
GtkKnob *knob;
|
||||||
GdkModifierType mods;
|
GdkWindow *window;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
|
||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
g_return_val_if_fail (widget != NULL, FALSE);
|
||||||
@@ -594,10 +638,6 @@ gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
|
|||||||
x = event->x;
|
x = event->x;
|
||||||
y = event->y;
|
y = event->y;
|
||||||
|
|
||||||
if (event->is_hint || (event->window != widget->window)) {
|
|
||||||
gdk_window_get_pointer (widget->window, &x, &y, &mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (knob->state) {
|
switch (knob->state) {
|
||||||
|
|
||||||
case STATE_PRESSED:
|
case STATE_PRESSED:
|
||||||
@@ -605,14 +645,22 @@ gtk_knob_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case STATE_DRAGGING:
|
case STATE_DRAGGING:
|
||||||
if (mods & GDK_BUTTON1_MASK) {
|
window = gtk_widget_get_window(widget);
|
||||||
gtk_knob_update_mouse (knob, x, y, TRUE);
|
if (event->is_hint || (event->window != window)) {
|
||||||
return TRUE;
|
GdkModifierType mods;
|
||||||
}
|
GdkDeviceManager *device_manager = gdk_display_get_device_manager(gdk_window_get_display(window));
|
||||||
else if (mods & GDK_BUTTON3_MASK) {
|
GdkDevice *pointer = gdk_device_manager_get_client_pointer(device_manager);
|
||||||
gtk_knob_update_mouse (knob, x, y, FALSE);
|
|
||||||
return TRUE;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,7 +680,7 @@ gtk_knob_timer(GtkKnob *knob) {
|
|||||||
g_return_val_if_fail (GTK_IS_KNOB (knob), FALSE);
|
g_return_val_if_fail (GTK_IS_KNOB (knob), FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment), FALSE);
|
g_return_val_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment), FALSE);
|
||||||
|
|
||||||
if (knob->policy == GTK_UPDATE_DELAYED) {
|
if (knob->policy == GTK_KNOB_UPDATE_DELAYED) {
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,13 +698,13 @@ static void
|
|||||||
gtk_knob_update_mouse_update(GtkKnob *knob) {
|
gtk_knob_update_mouse_update(GtkKnob *knob) {
|
||||||
g_return_if_fail(GTK_IS_ADJUSTMENT (knob->adjustment));
|
g_return_if_fail(GTK_IS_ADJUSTMENT (knob->adjustment));
|
||||||
|
|
||||||
if (knob->policy == GTK_UPDATE_CONTINUOUS) {
|
if (knob->policy == GTK_KNOB_UPDATE_CONTINUOUS) {
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (knob));
|
gtk_widget_queue_draw (GTK_WIDGET (knob));
|
||||||
|
|
||||||
if (knob->policy == GTK_UPDATE_DELAYED) {
|
if (knob->policy == GTK_KNOB_UPDATE_DELAYED) {
|
||||||
if (knob->timer) {
|
if (knob->timer) {
|
||||||
g_source_remove (knob->timer);
|
g_source_remove (knob->timer);
|
||||||
}
|
}
|
||||||
@@ -675,14 +723,14 @@ gtk_knob_update_mouse_update(GtkKnob *knob) {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void
|
static void
|
||||||
gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
|
gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
|
||||||
gfloat old_value, new_value, dv, dh;
|
gdouble old_value, new_value, dv, dh;
|
||||||
gfloat angle;
|
gdouble angle;
|
||||||
|
|
||||||
g_return_if_fail (knob != NULL);
|
g_return_if_fail (knob != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (knob));
|
g_return_if_fail (GTK_IS_KNOB (knob));
|
||||||
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
|
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
|
||||||
|
|
||||||
old_value = knob->adjustment->value;
|
old_value = gtk_adjustment_get_value(knob->adjustment);
|
||||||
|
|
||||||
angle = atan2f (-y + (knob->height >> 1), x - (knob->width >> 1));
|
angle = atan2f (-y + (knob->height >> 1), x - (knob->width >> 1));
|
||||||
|
|
||||||
@@ -699,17 +747,17 @@ gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
|
|||||||
dh *= angle * angle;
|
dh *= angle * angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_value = knob->adjustment->value +
|
new_value = gtk_adjustment_get_value(knob->adjustment) +
|
||||||
dv * (step ? knob->adjustment->step_increment : knob->adjustment->page_increment) +
|
dv * (step ? gtk_adjustment_get_step_increment(knob->adjustment) : gtk_adjustment_get_page_increment(knob->adjustment)) +
|
||||||
dh * (knob->adjustment->upper -
|
dh * (gtk_adjustment_get_upper(knob->adjustment) -
|
||||||
knob->adjustment->lower) * 0.005; /* 0.005 == (1 / 200) */
|
gtk_adjustment_get_lower(knob->adjustment)) * 0.005; /* 0.005 == (1 / 200) */
|
||||||
|
|
||||||
new_value = MAX (MIN (new_value, knob->adjustment->upper),
|
new_value = MAX (MIN (new_value, gtk_adjustment_get_upper(knob->adjustment)),
|
||||||
knob->adjustment->lower);
|
gtk_adjustment_get_lower(knob->adjustment));
|
||||||
|
|
||||||
knob->adjustment->value = new_value;
|
gtk_adjustment_set_value(knob->adjustment, new_value);
|
||||||
|
|
||||||
if (knob->adjustment->value != old_value) {
|
if (gtk_adjustment_get_value(knob->adjustment) != old_value) {
|
||||||
gtk_knob_update_mouse_update (knob);
|
gtk_knob_update_mouse_update (knob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -722,29 +770,29 @@ gtk_knob_update_mouse(GtkKnob *knob, gint x, gint y, gboolean step) {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void
|
static void
|
||||||
gtk_knob_update(GtkKnob *knob) {
|
gtk_knob_update(GtkKnob *knob) {
|
||||||
gfloat new_value;
|
gdouble new_value;
|
||||||
|
|
||||||
g_return_if_fail (knob != NULL);
|
g_return_if_fail (knob != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (knob));
|
g_return_if_fail (GTK_IS_KNOB (knob));
|
||||||
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
|
g_return_if_fail (GTK_IS_ADJUSTMENT (knob->adjustment));
|
||||||
|
|
||||||
if (knob->adjustment->step_increment == 1) {
|
if (gtk_adjustment_get_step_increment(knob->adjustment) == 1) {
|
||||||
new_value = floor (knob->adjustment->value + 0.5);
|
new_value = floor (gtk_adjustment_get_value(knob->adjustment) + 0.5);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
new_value = knob->adjustment->value;
|
new_value = gtk_adjustment_get_value(knob->adjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_value < knob->adjustment->lower) {
|
if (new_value < gtk_adjustment_get_lower(knob->adjustment)) {
|
||||||
new_value = knob->adjustment->lower;
|
new_value = gtk_adjustment_get_lower(knob->adjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_value > knob->adjustment->upper) {
|
if (new_value > gtk_adjustment_get_upper(knob->adjustment)) {
|
||||||
new_value = knob->adjustment->upper;
|
new_value = gtk_adjustment_get_upper(knob->adjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_value != knob->adjustment->value) {
|
if (new_value != gtk_adjustment_get_value(knob->adjustment)) {
|
||||||
knob->adjustment->value = new_value;
|
gtk_adjustment_set_value(knob->adjustment, new_value);
|
||||||
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
g_signal_emit_by_name (knob->adjustment, "value_changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,15 +814,15 @@ gtk_knob_adjustment_changed(GtkAdjustment *adjustment, gpointer data) {
|
|||||||
|
|
||||||
knob = GTK_KNOB (data);
|
knob = GTK_KNOB (data);
|
||||||
|
|
||||||
if ((knob->old_value != adjustment->value) ||
|
if ((knob->old_value != gtk_adjustment_get_value(adjustment)) ||
|
||||||
(knob->old_lower != adjustment->lower) ||
|
(knob->old_lower != gtk_adjustment_get_lower(adjustment)) ||
|
||||||
(knob->old_upper != adjustment->upper))
|
(knob->old_upper != gtk_adjustment_get_upper(adjustment)))
|
||||||
{
|
{
|
||||||
gtk_knob_update (knob);
|
gtk_knob_update (knob);
|
||||||
|
|
||||||
knob->old_value = adjustment->value;
|
knob->old_value = gtk_adjustment_get_value(adjustment);
|
||||||
knob->old_lower = adjustment->lower;
|
knob->old_lower = gtk_adjustment_get_lower(adjustment);
|
||||||
knob->old_upper = adjustment->upper;
|
knob->old_upper = gtk_adjustment_get_upper(adjustment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,9 +841,9 @@ gtk_knob_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data) {
|
|||||||
|
|
||||||
knob = GTK_KNOB (data);
|
knob = GTK_KNOB (data);
|
||||||
|
|
||||||
if (knob->old_value != adjustment->value) {
|
if (knob->old_value != gtk_adjustment_get_value(adjustment)) {
|
||||||
gtk_knob_update (knob);
|
gtk_knob_update (knob);
|
||||||
knob->old_value = adjustment->value;
|
knob->old_value = gtk_adjustment_get_value(adjustment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,29 +858,31 @@ gtk_knob_set_animation (GtkKnob *knob, GtkKnobAnim *anim) {
|
|||||||
g_return_if_fail (knob != NULL);
|
g_return_if_fail (knob != NULL);
|
||||||
g_return_if_fail (anim != NULL);
|
g_return_if_fail (anim != NULL);
|
||||||
g_return_if_fail (GTK_IS_KNOB (knob));
|
g_return_if_fail (GTK_IS_KNOB (knob));
|
||||||
g_return_if_fail (GDK_IS_PIXBUF (anim->pixbuf));
|
|
||||||
|
|
||||||
knob->anim = (GtkKnobAnim *)anim;
|
knob->anim = (GtkKnobAnim *)anim;
|
||||||
knob->width = anim->frame_width;
|
knob->width = anim->frame_width;
|
||||||
knob->height = anim->height;
|
knob->height = anim->height;
|
||||||
|
|
||||||
if (GTK_WIDGET_REALIZED (knob)) {
|
if (gtk_widget_get_realized (GTK_WIDGET(knob))) {
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (knob));
|
gtk_widget_queue_resize (GTK_WIDGET (knob));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads embedded knob image
|
||||||
|
**/
|
||||||
|
static cairo_status_t
|
||||||
|
get_knob_image(void *closure, unsigned char *data, unsigned int length)
|
||||||
|
{
|
||||||
|
int *offset = (int *)closure;
|
||||||
|
|
||||||
/*****************************************************************************
|
if ((*offset + length) > sizeof (knob_png))
|
||||||
*
|
return CAIRO_STATUS_READ_ERROR;
|
||||||
* gtk_knob_animation_new_from_file()
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
GtkKnobAnim *
|
|
||||||
gtk_knob_animation_new_from_file(gchar *filename) {
|
|
||||||
GtkKnobAnim *anim;
|
|
||||||
|
|
||||||
anim = gtk_knob_animation_new_from_file_full (filename, -1, -1, KNOB_SIZE);
|
memcpy (data, knob_png + *offset, length);
|
||||||
return anim;
|
*offset = *offset + length;
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@@ -841,68 +891,20 @@ gtk_knob_animation_new_from_file(gchar *filename) {
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
GtkKnobAnim *
|
GtkKnobAnim *
|
||||||
gtk_knob_animation_new_from_inline(const guint8 *pixbuf) {
|
gtk_knob_animation_new_from_inline() {
|
||||||
GtkKnobAnim *anim = g_new0 (GtkKnobAnim, 1);
|
GtkKnobAnim *anim = g_new0 (GtkKnobAnim, 1);
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
g_return_val_if_fail((pixbuf != NULL), NULL);
|
anim->image =
|
||||||
|
cairo_image_surface_create_from_png_stream(get_knob_image, &offset);
|
||||||
|
|
||||||
anim->pixbuf = gdk_pixbuf_new_from_inline(-1, pixbuf, FALSE, NULL);
|
anim->width = cairo_image_surface_get_width(anim->image);
|
||||||
if (anim->pixbuf == NULL) {
|
anim->height = cairo_image_surface_get_height(anim->image);
|
||||||
g_free(anim);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
anim->height = gdk_pixbuf_get_height (anim->pixbuf);
|
|
||||||
anim->width = gdk_pixbuf_get_width (anim->pixbuf);
|
|
||||||
anim->frame_width = anim->height;
|
anim->frame_width = anim->height;
|
||||||
|
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* gtk_knob_new_from_file_full()
|
|
||||||
*
|
|
||||||
* frame_width: overrides the frame width (to make rectangular frames)
|
|
||||||
* but doesn't affect the image size width and height cause optional
|
|
||||||
* scaling if not set to -1 when they are derived from the native
|
|
||||||
* image size.
|
|
||||||
*
|
|
||||||
* FIXME: account for any problems where (width % frame_width != 0)
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
GtkKnobAnim *
|
|
||||||
gtk_knob_animation_new_from_file_full(gchar *filename, gint frame_width,
|
|
||||||
gint width, gint height) {
|
|
||||||
GtkKnobAnim *anim = g_new0 (GtkKnobAnim, 1);
|
|
||||||
|
|
||||||
g_return_val_if_fail ((filename != NULL), NULL);
|
|
||||||
|
|
||||||
GError *gerror = NULL;
|
|
||||||
|
|
||||||
#if GTK_MINOR_VERSION < 10
|
|
||||||
if (!(anim->pixbuf = gdk_pixbuf_new_from_file (filename, &gerror))) {
|
|
||||||
g_error_free(gerror);
|
|
||||||
gerror = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else /* GTK_MINOR_VERSION >= 10 */
|
|
||||||
if (!(anim->pixbuf = gdk_pixbuf_new_from_file_at_size (filename, width,
|
|
||||||
height, &gerror))) {
|
|
||||||
g_error_free(gerror);
|
|
||||||
gerror = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif /* GTK_MINOR_VERSION < 10 */
|
|
||||||
else {
|
|
||||||
anim->height = gdk_pixbuf_get_height (anim->pixbuf);
|
|
||||||
anim->width = gdk_pixbuf_get_width (anim->pixbuf);
|
|
||||||
anim->frame_width = (frame_width != -1) ? frame_width : anim->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
return anim;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* gtk_knob_animation_free()
|
* gtk_knob_animation_free()
|
||||||
@@ -912,8 +914,8 @@ void
|
|||||||
gtk_knob_animation_free(GtkKnobAnim *anim) {
|
gtk_knob_animation_free(GtkKnobAnim *anim) {
|
||||||
g_return_if_fail (anim != NULL);
|
g_return_if_fail (anim != NULL);
|
||||||
|
|
||||||
if (anim->pixbuf)
|
if (anim->image)
|
||||||
g_object_unref (anim->pixbuf);
|
cairo_surface_destroy(anim->image);
|
||||||
|
|
||||||
g_free (anim);
|
g_free (anim);
|
||||||
}
|
}
|
||||||
|
|||||||
36
gtkknob.h
36
gtkknob.h
@@ -3,7 +3,7 @@
|
|||||||
* Most of this code comes from gAlan 0.2.0, copyright (C) 1999
|
* Most of this code comes from gAlan 0.2.0, copyright (C) 1999
|
||||||
* Tony Garnock-Jones, with modifications by Sean Bolton,
|
* Tony Garnock-Jones, with modifications by Sean Bolton,
|
||||||
* copyright (C) 2004, and minor modifications by William Weston,
|
* copyright (C) 2004, and minor modifications by William Weston,
|
||||||
* copyright (C) 2007, Tomasz Moń, copyright (C) 2009
|
* copyright (C) 2007, Tomasz Moń, copyright (C) 2009-2011
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -17,7 +17,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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__
|
#ifndef __GTK_KNOB_H__
|
||||||
#define __GTK_KNOB_H__
|
#define __GTK_KNOB_H__
|
||||||
@@ -36,17 +37,25 @@ typedef struct _GtkKnob GtkKnob;
|
|||||||
typedef struct _GtkKnobClass GtkKnobClass;
|
typedef struct _GtkKnobClass GtkKnobClass;
|
||||||
typedef struct _GtkKnobAnim GtkKnobAnim;
|
typedef struct _GtkKnobAnim GtkKnobAnim;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GTK_KNOB_UPDATE_CONTINUOUS,
|
||||||
|
GTK_KNOB_UPDATE_DISCONTINUOUS,
|
||||||
|
GTK_KNOB_UPDATE_DELAYED
|
||||||
|
} GtkKnobUpdateType;
|
||||||
|
|
||||||
/* better to make this an object and let widgets ref/deref it perhaps */
|
/* better to make this an object and let widgets ref/deref it perhaps */
|
||||||
struct _GtkKnobAnim {
|
struct _GtkKnobAnim {
|
||||||
GdkPixbuf *pixbuf;
|
cairo_surface_t *image;
|
||||||
gint width; /* derived from image width */
|
gint width; /* derived from image width */
|
||||||
gint height; /* derived from image height. */
|
gint height; /* derived from image height. */
|
||||||
gint frame_width; /* derived from pixbuf (width / height) or provided override for rectangular frames */
|
gint frame_width; /* derived from pixbuf (width / height) or provided override for rectangular frames */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkKnob {
|
struct _GtkKnob {
|
||||||
GtkWidget widget;
|
GtkWidget widget;
|
||||||
|
|
||||||
|
GdkWindow *event_window;
|
||||||
/* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
|
/* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
|
||||||
guint policy : 2;
|
guint policy : 2;
|
||||||
|
|
||||||
@@ -60,15 +69,11 @@ typedef struct _GtkKnobAnim GtkKnobAnim;
|
|||||||
/* knob animation */
|
/* knob animation */
|
||||||
GtkKnobAnim *anim;
|
GtkKnobAnim *anim;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
|
||||||
GdkBitmap *mask;
|
|
||||||
GdkGC *mask_gc;
|
|
||||||
GdkGC *red_gc;
|
|
||||||
|
|
||||||
/* Old values from adjustment stored so we know when something changes */
|
/* Old values from adjustment stored so we know when something changes */
|
||||||
gfloat old_value;
|
gdouble old_value;
|
||||||
gfloat old_lower;
|
gdouble old_lower;
|
||||||
gfloat old_upper;
|
gdouble old_upper;
|
||||||
|
|
||||||
/* The adjustment object that stores the data for this knob */
|
/* The adjustment object that stores the data for this knob */
|
||||||
GtkAdjustment *adjustment;
|
GtkAdjustment *adjustment;
|
||||||
@@ -82,16 +87,11 @@ typedef struct _GtkKnobAnim GtkKnobAnim;
|
|||||||
extern GtkWidget *gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim);
|
extern GtkWidget *gtk_knob_new(GtkAdjustment *adjustment, GtkKnobAnim *anim);
|
||||||
extern GType gtk_knob_get_type(void);
|
extern GType gtk_knob_get_type(void);
|
||||||
extern GtkAdjustment *gtk_knob_get_adjustment(GtkKnob *knob);
|
extern GtkAdjustment *gtk_knob_get_adjustment(GtkKnob *knob);
|
||||||
extern void gtk_knob_set_update_policy(GtkKnob *knob, GtkUpdateType policy);
|
extern void gtk_knob_set_update_policy(GtkKnob *knob, GtkKnobUpdateType policy);
|
||||||
extern void gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment);
|
extern void gtk_knob_set_adjustment(GtkKnob *knob, GtkAdjustment *adjustment);
|
||||||
|
|
||||||
GtkKnobAnim *gtk_knob_animation_new_from_inline(const guint8 *pixbuf);
|
GtkKnobAnim *gtk_knob_animation_new_from_inline();
|
||||||
GtkKnobAnim *gtk_knob_animation_new_from_file_full(gchar *filename,
|
|
||||||
gint frame_width,
|
|
||||||
gint width,
|
|
||||||
gint height);
|
|
||||||
|
|
||||||
GtkKnobAnim *gtk_knob_animation_new_from_file(gchar *filename);
|
|
||||||
void gtk_knob_set_animation (GtkKnob *knob, GtkKnobAnim *anim);
|
void gtk_knob_set_animation (GtkKnob *knob, GtkKnobAnim *anim);
|
||||||
void gtk_knob_animation_free(GtkKnobAnim *anim);
|
void gtk_knob_animation_free(GtkKnobAnim *anim);
|
||||||
|
|
||||||
|
|||||||
6
gui.h
6
gui.h
@@ -17,14 +17,20 @@
|
|||||||
#ifndef GDIGI_GUI_H
|
#ifndef GDIGI_GUI_H
|
||||||
#define GDIGI_GUI_H
|
#define GDIGI_GUI_H
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "effects.h"
|
#include "effects.h"
|
||||||
|
|
||||||
|
gchar * get_preset_filename(int prod_id);
|
||||||
void show_error_message(GtkWidget *parent, gchar *message);
|
void show_error_message(GtkWidget *parent, gchar *message);
|
||||||
void apply_setting_param_to_gui(SettingParam *param);
|
void apply_setting_param_to_gui(SettingParam *param);
|
||||||
gboolean apply_current_preset_to_gui(gpointer data);
|
gboolean apply_current_preset_to_gui(gpointer data);
|
||||||
void gui_create(Device *device);
|
void gui_create(Device *device);
|
||||||
void gui_free();
|
void gui_free();
|
||||||
gboolean unsupported_device_dialog(Device **device);
|
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 */
|
#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 |
50
preset.c
50
preset.c
@@ -69,7 +69,7 @@ static void XMLCALL start(void *data, const char *el, const char **attr) {
|
|||||||
if (g_strcmp0(el, "Params") == 0) {
|
if (g_strcmp0(el, "Params") == 0) {
|
||||||
ad->section = SECTION_PARAMS;
|
ad->section = SECTION_PARAMS;
|
||||||
if (ad->preset->params != NULL)
|
if (ad->preset->params != NULL)
|
||||||
g_message("Params aleady exists!");
|
g_warning("Params aleady exists!");
|
||||||
} else if (g_strcmp0(el, "Param") == 0) {
|
} else if (g_strcmp0(el, "Param") == 0) {
|
||||||
SettingParam *param = setting_param_new();
|
SettingParam *param = setting_param_new();
|
||||||
ad->preset->params = g_list_prepend(ad->preset->params, param);
|
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) {
|
} else if (g_strcmp0(el, "Genetx") == 0) {
|
||||||
ad->section = SECTION_GENETX;
|
ad->section = SECTION_GENETX;
|
||||||
if (ad->preset->genetxs != NULL)
|
if (ad->preset->genetxs != NULL)
|
||||||
g_message("Genetx already exists!");
|
g_warning("Genetx already exists!");
|
||||||
} else if (g_strcmp0(el, "GenetxModel") == 0) {
|
} else if (g_strcmp0(el, "GenetxModel") == 0) {
|
||||||
SettingGenetx *genetx = setting_genetx_new();
|
SettingGenetx *genetx = setting_genetx_new();
|
||||||
ad->preset->genetxs = g_list_prepend(ad->preset->genetxs, genetx);
|
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) {
|
} else if (g_strcmp0(value, "Version2") == 0) {
|
||||||
genetx->version = GENETX_VERSION_2;
|
genetx->version = GENETX_VERSION_2;
|
||||||
} else {
|
} else {
|
||||||
g_message("Unknown GeNetX version: %s", value);
|
g_warning("Unknown GeNetX version: %s", value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PARSER_TYPE_GENETX_TYPE:
|
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) {
|
} else if (g_strcmp0(value, "Cabinet") == 0) {
|
||||||
genetx->type = GENETX_TYPE_CABINET;
|
genetx->type = GENETX_TYPE_CABINET;
|
||||||
} else {
|
} else {
|
||||||
g_message("Unknown GeNetX type: %s", value);
|
g_warning("Unknown GeNetX type: %s", value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PARSER_TYPE_GENETX_CHANNEL:
|
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) {
|
} else if (g_strcmp0(value, "Channel2") == 0) {
|
||||||
genetx->channel = GENETX_CHANNEL2;
|
genetx->channel = GENETX_CHANNEL2;
|
||||||
} else {
|
} else {
|
||||||
g_message("Unknown GeNetX channel: %s", value);
|
g_warning("Unknown GeNetX channel: %s", value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PARSER_TYPE_GENETX_NAME:
|
case PARSER_TYPE_GENETX_NAME:
|
||||||
@@ -219,7 +219,7 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
|||||||
gchar *contents;
|
gchar *contents;
|
||||||
|
|
||||||
if (g_file_get_contents(filename, &contents, NULL, &err) == FALSE) {
|
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);
|
*error = g_error_copy(err);
|
||||||
g_error_free(err);
|
g_error_free(err);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -260,6 +260,21 @@ Preset *create_preset_from_xml_file(gchar *filename, GError **error)
|
|||||||
return preset;
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint params_cmp(gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
const SettingParam *param_a = a;
|
||||||
|
const SettingParam *param_b = b;
|
||||||
|
|
||||||
|
if (param_a->position != param_b->position) {
|
||||||
|
return (param_a->position > param_b->position) ? 1 : -1;
|
||||||
|
}
|
||||||
|
if (param_a->id != param_b->id) {
|
||||||
|
return (param_a->id > param_b->id) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param list list containing unpacked preset SysEx messages.
|
* \param list list containing unpacked preset SysEx messages.
|
||||||
*
|
*
|
||||||
@@ -293,12 +308,16 @@ Preset *create_preset_from_data(GList *list)
|
|||||||
modified = (unsigned char)data->str[11+strlen(name)];
|
modified = (unsigned char)data->str[11+strlen(name)];
|
||||||
|
|
||||||
if ((bank == PRESETS_EDIT_BUFFER) && (number == 0)) {
|
if ((bank == PRESETS_EDIT_BUFFER) && (number == 0)) {
|
||||||
g_message("Received current edit buffer");
|
debug_msg(DEBUG_MSG2HOST,
|
||||||
|
"RECEIVE_PRESET_START: current edit buffer");
|
||||||
} else {
|
} 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;
|
preset->name = name;
|
||||||
break;
|
break;
|
||||||
case RECEIVE_PRESET_PARAMETERS:
|
case RECEIVE_PRESET_PARAMETERS:
|
||||||
@@ -311,15 +330,20 @@ Preset *create_preset_from_data(GList *list)
|
|||||||
SettingParam *param = setting_param_new_from_data(&data->str[x], &x);
|
SettingParam *param = setting_param_new_from_data(&data->str[x], &x);
|
||||||
n++;
|
n++;
|
||||||
preset->params = g_list_prepend(preset->params, param);
|
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);
|
} while ((x < data->len) && n<total);
|
||||||
g_message("TOTAL %d", total);
|
debug_msg(DEBUG_MSG2HOST, "TOTAL %d", total);
|
||||||
preset->params = g_list_reverse(preset->params);
|
preset->params = g_list_sort(preset->params, params_cmp);
|
||||||
break;
|
break;
|
||||||
case RECEIVE_PRESET_END:
|
case RECEIVE_PRESET_END:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_message("Unhandled message in preset messages list");
|
g_warning("Unhandled message 0x%x in preset messages list",
|
||||||
|
get_message_id(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
preset.h
2
preset.h
@@ -28,5 +28,5 @@ typedef struct {
|
|||||||
Preset *create_preset_from_xml_file(gchar *filename, GError **error);
|
Preset *create_preset_from_xml_file(gchar *filename, GError **error);
|
||||||
Preset *create_preset_from_data(GList *list);
|
Preset *create_preset_from_data(GList *list);
|
||||||
void preset_free(Preset *preset);
|
void preset_free(Preset *preset);
|
||||||
|
void write_preset_to_xml(Preset *preset, gchar *filename);
|
||||||
#endif /* GDIGI_PRESET_H */
|
#endif /* GDIGI_PRESET_H */
|
||||||
|
|||||||
261
preset_xml.c
Normal file
261
preset_xml.c
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009 Tomasz Moń <desowin@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; under version 3 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <expat.h>
|
||||||
|
#include <libxml/encoding.h>
|
||||||
|
#include <libxml/xmlreader.h>
|
||||||
|
#include <libxml/xmlwriter.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "preset.h"
|
||||||
|
#include "gdigi.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "gdigi_xml.h"
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
// FIXME: Bring the xml settings into this module?
|
||||||
|
extern XmlSettings xml_settings[];
|
||||||
|
extern guint n_xml_settings;
|
||||||
|
extern EffectValues values_on_off;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param id modifier ID
|
||||||
|
* \param position modifier position
|
||||||
|
*
|
||||||
|
* Gets modifier info.
|
||||||
|
*
|
||||||
|
* \return Modifier which must not be freed, or NULL if no matching Modifier has been found.
|
||||||
|
*/
|
||||||
|
XmlSettings *get_xml_settings (guint id, guint position)
|
||||||
|
{
|
||||||
|
gint x;
|
||||||
|
|
||||||
|
for (x=0; x< n_xml_settings; x++) {
|
||||||
|
if ((xml_settings[x].id == id) && (xml_settings[x].position == position)) {
|
||||||
|
return xml_settings + x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
map_xml_value (XmlSettings *xml, EffectValues *values, gint value)
|
||||||
|
{
|
||||||
|
switch (values->type) {
|
||||||
|
case VALUE_TYPE_LABEL:
|
||||||
|
if ((values == &values_on_off) && (value > 1)) {
|
||||||
|
g_warning("Skipping modifier->label %s\n", xml->label);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
guint labels_amt = xml->xml_labels_amt;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
// Maybe this can be a computation: i = xml->values->min + val
|
||||||
|
for (i = 0; i < labels_amt; i++) {
|
||||||
|
if (labels[i].type == value) {
|
||||||
|
return (labels[i].label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean value_is_extra (EffectValues *val, int value)
|
||||||
|
{
|
||||||
|
if ((value < val->min) || (value > val->max)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GDIGI_ENCODING "utf-8"
|
||||||
|
void
|
||||||
|
write_preset_to_xml(Preset *preset, gchar *filename)
|
||||||
|
{
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
xmlTextWriterPtr writer;
|
||||||
|
GList *iter_params = preset->params;
|
||||||
|
guint last_id = 0;
|
||||||
|
guint last_position = 0;
|
||||||
|
|
||||||
|
printf("Creating a new xml doc\n");
|
||||||
|
/* Create a new XmlWriter for uri, with no compression. */
|
||||||
|
writer = xmlNewTextWriterFilename(filename, 0);
|
||||||
|
if (writer == NULL) {
|
||||||
|
printf("testXmlwriterFilename: Error creating the xml writer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the document with the xml default for the version,
|
||||||
|
* encoding and the default for the standalone declaration.
|
||||||
|
*/
|
||||||
|
rc = xmlTextWriterStartDocument(writer, NULL, GDIGI_ENCODING, NULL);
|
||||||
|
if (rc < 0) {
|
||||||
|
printf
|
||||||
|
("testXmlwriterFilename: Error at xmlTextWriterStartDocument\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = xmlTextWriterSetIndent(writer, 1);
|
||||||
|
rc = xmlTextWriterSetIndentString(writer, BAD_CAST " ");
|
||||||
|
/* Write the tag identifying type of prefix, schema version and ns. */
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST get_preset_filename(product_id));
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "SchemaVersion",
|
||||||
|
BAD_CAST "1.2");
|
||||||
|
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xmlns",
|
||||||
|
BAD_CAST "http://www.digitech.com/xml/preset");
|
||||||
|
|
||||||
|
/* Write the Name tag. */
|
||||||
|
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Name", BAD_CAST preset->name);
|
||||||
|
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST "Params");
|
||||||
|
|
||||||
|
while (iter_params) {
|
||||||
|
XmlSettings *xml;
|
||||||
|
SettingParam *param = (SettingParam *) iter_params->data;
|
||||||
|
|
||||||
|
if (param->id == last_id && param->position == last_position) {
|
||||||
|
g_warning("Skipping duplicate parameter id %d position %d",
|
||||||
|
last_id, last_position);
|
||||||
|
iter_params = iter_params->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST "Param");
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ID",
|
||||||
|
"%d", param->id);
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Position",
|
||||||
|
"%d", param->position);
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Value",
|
||||||
|
"%d", param->value);
|
||||||
|
|
||||||
|
last_id = param->id;
|
||||||
|
last_position = param->position;
|
||||||
|
xml = get_xml_settings(param->id, param->position);
|
||||||
|
if (!xml) {
|
||||||
|
printf("Failed to get xml settings for id %d position %d\n",
|
||||||
|
param->id, param->position);
|
||||||
|
} else {
|
||||||
|
ValueType type;
|
||||||
|
gchar *suffix = "";
|
||||||
|
gdouble step = 1.0;
|
||||||
|
gint offset = 0;
|
||||||
|
gboolean decimal = FALSE;
|
||||||
|
EffectValues *values = NULL;
|
||||||
|
|
||||||
|
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Name",
|
||||||
|
BAD_CAST xml->label);
|
||||||
|
values = xml->values;
|
||||||
|
type = values->type;
|
||||||
|
while ((type & VALUE_TYPE_EXTRA) && value_is_extra(values, param->value)) {
|
||||||
|
values = values->extra;
|
||||||
|
type = values->type;
|
||||||
|
}
|
||||||
|
type &= ~VALUE_TYPE_EXTRA;
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_OFFSET) {
|
||||||
|
offset = values->offset;
|
||||||
|
type &= ~VALUE_TYPE_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_STEP) {
|
||||||
|
step = values->step;
|
||||||
|
type &= ~VALUE_TYPE_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_SUFFIX) {
|
||||||
|
suffix = values->suffix;
|
||||||
|
type &= ~VALUE_TYPE_SUFFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & VALUE_TYPE_DECIMAL) {
|
||||||
|
decimal = TRUE;
|
||||||
|
type &= ~VALUE_TYPE_DECIMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case VALUE_TYPE_LABEL:
|
||||||
|
{
|
||||||
|
char *textp = map_xml_value(xml, values, param->value);
|
||||||
|
if (!textp) {
|
||||||
|
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",
|
||||||
|
BAD_CAST textp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case VALUE_TYPE_PLAIN:
|
||||||
|
{
|
||||||
|
if (decimal) {
|
||||||
|
double value = (param->value + offset) * step;
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Text",
|
||||||
|
"%0.2f%s", value, suffix);
|
||||||
|
} else {
|
||||||
|
gint value = (param->value + offset) * step;
|
||||||
|
rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Text",
|
||||||
|
"%d%s", value, suffix);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
case VALUE_TYPE_NONE:
|
||||||
|
rc = xmlTextWriterStartElement(writer, BAD_CAST "Text");
|
||||||
|
rc = xmlTextWriterEndElement(writer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_warning("Unhandled value type %d", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = xmlTextWriterEndElement(writer);
|
||||||
|
|
||||||
|
iter_params = iter_params->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = xmlTextWriterEndDocument(writer);
|
||||||
|
if (rc < 0) {
|
||||||
|
printf("testXmlwriterFilename: Error at xmlTextWriterEndDocument\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlFreeTextWriter(writer);
|
||||||
|
}
|
||||||
|
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||||
Reference in New Issue
Block a user