Commit 6ba17a54 authored by Hanspeter Portner's avatar Hanspeter Portner

redesign sherlock#atom_inspector.

* show turtle instead of atom object genlist
* fix detection of maximal amount of events
parent bfbbc743
......@@ -59,13 +59,19 @@ target_link_libraries(sherlock_ui
set_target_properties(sherlock_ui PROPERTIES PREFIX "")
install(TARGETS sherlock_ui DESTINATION ${DEST})
find_package(FLEX)
flex_target(encoder encoder.l ${PROJECT_BINARY_DIR}/encoder.c
COMPILE_FLAGS "--header-file=${PROJECT_BINARY_DIR}/encoder.h --prefix=enc")
add_library(sherlock_eo MODULE
sherlock_eo.c
atom_inspector_eo.c
midi_inspector_eo.c
osc_inspector_eo.c)
osc_inspector_eo.c
${FLEX_encoder_OUTPUTS})
target_link_libraries(sherlock_eo
${ELM_LDFLAGS})
${ELM_LDFLAGS}
${SRATOM_LDFLAGS})
set_target_properties(sherlock_eo PROPERTIES PREFIX "")
install(TARGETS sherlock_eo DESTINATION ${DEST})
......
......@@ -16,24 +16,25 @@
*/
#include <inttypes.h>
#include <stdio.h>
#include <sherlock.h>
#include <common.h>
#include <Elementary.h>
#include <sratom/sratom.h>
#define COUNT_MAX 2048 // maximal amount of events shown
#define STRING_BUF_SIZE 2048
#define STRING_MAX 256
#define STRING_OFF (STRING_MAX - 4)
// Disable deprecation warnings for Blank and Resource
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#define NS_RDF (const uint8_t*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define NS_XSD (const uint8_t*)"http://www.w3.org/2001/XMLSchema#"
#define NS_OSC (const uint8_t*)"http://open-music-kontrollers.ch/lv2/osc#"
#define NS_XPRESS (const uint8_t*)"http://open-music-kontrollers.ch/lv2/xpress#"
#define NS_SPOD (const uint8_t*)"http://open-music-kontrollers.ch/lv2/synthpod#"
typedef struct _UI UI;
......@@ -44,20 +45,7 @@ struct _UI {
LV2_URID_Map *map;
LV2_URID_Unmap *unmap;
struct {
LV2_URID midi_MidiEvent;
LV2_URID event_transfer;
LV2_URID time_position;
LV2_URID time_barBeat;
LV2_URID time_bar;
LV2_URID time_beat;
LV2_URID time_beatUnit;
LV2_URID time_beatsPerBar;
LV2_URID time_beatsPerMinute;
LV2_URID time_frame;
LV2_URID time_framesPerSecond;
LV2_URID time_speed;
} uris;
LV2_Atom_Forge forge;
......@@ -71,37 +59,65 @@ struct _UI {
Evas_Object *autoblock;
Evas_Object *popup;
Elm_Genlist_Item_Class *itc_sherlock;
Elm_Genlist_Item_Class *itc_list;
Elm_Genlist_Item_Class *itc_group;
Elm_Genlist_Item_Class *itc_seq;
Elm_Genlist_Item_Class *itc_prop;
Elm_Genlist_Item_Class *itc_vec;
Elm_Genlist_Item_Class *itc_atom;
char string_buf [STRING_BUF_SIZE];
char *logo_path;
Eina_Hash *urids;
Sratom *sratom;
const char *base_uri;
char *chunk;
};
static inline int
_is_expandable(UI *ui, const uint32_t type)
#define CODE_PRE "<style=shadow,bottom>"
#define CODE_POST "</style>"
#define URI(VAL,TYP) ("<color=#bbb font=Mono><b>"VAL"</b></color> <color=#fff font=Default>"TYP"</color>")
static void
_encoder_begin(void *data)
{
return lv2_atom_forge_is_object_type(&ui->forge, type)
|| (type == ui->forge.Tuple)
|| (type == ui->forge.Vector)
|| (type == ui->forge.Sequence);
UI *ui = data;
ui->chunk = strdup("");
}
#define CODE_PRE "<style=shadow,bottom>"
#define CODE_POST "</style>"
static void
_encoder_append(const char *str, void *data)
{
UI *ui = data;
#define HIL_PRE(VAL) ("<color=#bbb font=Mono><b>"VAL"</b></color> <color=#b00 font=Mono>")
#define HIL_POST ("</color>")
size_t size = 0;
size += ui->chunk ? strlen(ui->chunk) : 0;
size += str ? strlen(str) + 1 : 0;
#define URI(VAL,TYP) ("<color=#bbb font=Mono><b>"VAL"</b></color> <color=#fff font=Default>"TYP"</color>")
#define HIL(VAL,TYP) ("<color=#bbb font=Mono><b>"VAL"</b></color> <color=#b00 font=Mono>"TYP"</color>")
if(size)
ui->chunk = realloc(ui->chunk, size);
if(ui->chunk && str)
strcat(ui->chunk, str);
}
static void
_encoder_end(void *data)
{
UI *ui = data;
elm_entry_entry_set(ui->info, ui->chunk);
free(ui->chunk);
}
static moony_encoder_t enc = {
.begin = _encoder_begin,
.append = _encoder_append,
.end = _encoder_end,
.data = NULL
};
moony_encoder_t *encoder = &enc;
static void
_hash_del(void *data)
......@@ -135,359 +151,6 @@ _hash_get(UI *ui, LV2_URID urid)
return uri;
}
static char *
_atom_stringify(UI *ui, char *ptr, char *end, int newline, const LV2_Atom *atom)
{
//FIXME check for buffer overflows!!!
sprintf(ptr, CODE_PRE);
ptr += strlen(ptr);
const char *type = _hash_get(ui, atom->type);
sprintf(ptr, URI("type ", "%s (%"PRIu32")"), type, atom->type);
ptr += strlen(ptr);
if(lv2_atom_forge_is_object_type(&ui->forge, atom->type))
{
const LV2_Atom_Object *atom_object = (const LV2_Atom_Object *)atom;
const char *id = atom_object->body.id
? _hash_get(ui, atom_object->body.id)
: NULL;
const char *otype = _hash_get(ui, atom_object->body.otype);
if(id)
{
sprintf(ptr, URI("</br>id ", "%s (%"PRIu32")"), id, atom_object->body.id);
ptr += strlen(ptr);
if(newline)
sprintf(ptr, "</br>");
else
sprintf(ptr, "</tab>");
}
else // !id
{
sprintf(ptr, "</br>");
ptr += strlen(ptr);
if(newline)
sprintf(ptr, "</br>");
}
ptr += strlen(ptr);
sprintf(ptr, URI("otype ", "%s (%"PRIu32")"), otype, atom_object->body.otype);
}
else if(atom->type == ui->forge.Tuple)
{
const LV2_Atom_Tuple *atom_tuple = (const LV2_Atom_Tuple *)atom;
// do nothing
sprintf(ptr, "</br>");
}
else if(atom->type == ui->forge.Vector)
{
const LV2_Atom_Vector *atom_vector = (const LV2_Atom_Vector *)atom;
const char *ctype = _hash_get(ui, atom_vector->body.child_type);
sprintf(ptr, URI("</br>ctype ", "%s (%"PRIu32")"), ctype, atom_vector->body.child_type);
ptr += strlen(ptr);
if(newline)
sprintf(ptr, "</br>");
else
sprintf(ptr, "</tab>");
ptr += strlen(ptr);
sprintf(ptr, URI("csize ", "%"PRIu32), atom_vector->body.child_size);
}
else if(atom->type == ui->forge.Sequence)
{
const LV2_Atom_Sequence *atom_seq = (const LV2_Atom_Sequence *)atom;
// do nothing
sprintf(ptr, "</br>");
}
else if(atom->type == ui->forge.Int)
{
const LV2_Atom_Int *atom_int = (const LV2_Atom_Int *)atom;
sprintf(ptr, HIL("</br>value ", "%"PRIi32), atom_int->body);
}
else if(atom->type == ui->forge.Long)
{
const LV2_Atom_Long *atom_long = (const LV2_Atom_Long *)atom;
sprintf(ptr, HIL("</br>value ", "%"PRIi64), atom_long->body);
}
else if(atom->type == ui->forge.Float)
{
const LV2_Atom_Float *atom_float = (const LV2_Atom_Float *)atom;
sprintf(ptr, HIL("</br>value ", "%f"), atom_float->body);
}
else if(atom->type == ui->forge.Double)
{
const LV2_Atom_Double *atom_double = (const LV2_Atom_Double *)atom;
sprintf(ptr, HIL("</br>value ", "%lf"), atom_double->body);
}
else if(atom->type == ui->forge.Bool)
{
const LV2_Atom_Int *atom_int = (const LV2_Atom_Int *)atom;
sprintf(ptr, HIL("</br>value ", "%s"), atom_int->body ? "true" : "false");
}
else if(atom->type == ui->forge.URID)
{
const LV2_Atom_URID *atom_urid = (const LV2_Atom_URID *)atom;
const char *uri = _hash_get(ui, atom_urid->body);
sprintf(ptr, HIL("</br>value ", "%"PRIu32" (%s)"), atom_urid->body, uri);
}
else if(atom->type == ui->forge.String)
{
char *str = LV2_ATOM_CONTENTS(LV2_Atom_String, atom);
if(atom->size == 0)
str = "";
// truncate
char tmp[4] = {'\0'};
if(atom->size > STRING_MAX)
{
memcpy(tmp, &str[STRING_OFF], 4);
strcpy(&str[STRING_OFF], "...");
}
sprintf(ptr, HIL("</br>value ", "%s"), str);
// restore
if(atom->size > STRING_MAX)
memcpy(&str[STRING_OFF], tmp, 4);
}
else if(atom->type == ui->forge.Path)
{
char *str = LV2_ATOM_CONTENTS(LV2_Atom_String, atom);
if(atom->size == 0)
str = "";
// truncate
char tmp[4] = {'\0'};
if(atom->size > STRING_MAX)
{
memcpy(tmp, &str[STRING_OFF], 4);
strcpy(&str[STRING_OFF], "...");
}
sprintf(ptr, HIL("</br>value ", "%s"), str);
// restore
if(atom->size > STRING_MAX)
memcpy(&str[STRING_OFF], tmp, 4);
}
else if(atom->type == ui->forge.Literal)
{
const LV2_Atom_Literal *atom_lit = (const LV2_Atom_Literal *)atom;
char *str = LV2_ATOM_CONTENTS(LV2_Atom_Literal, atom);
if(atom->size == sizeof(LV2_Atom_Literal_Body))
str = "";
const char *datatype = _hash_get(ui, atom_lit->body.datatype);
const char *lang = _hash_get(ui, atom_lit->body.lang);
// truncate
char tmp[4] = {'\0'};
if(atom->size > STRING_MAX)
{
memcpy(tmp, &str[STRING_OFF], 4);
strcpy(&str[STRING_OFF], "...");
}
sprintf(ptr, HIL("</br>value ", "%s"), str);
ptr += strlen(ptr);
// restore
if(atom->size > STRING_MAX)
memcpy(&str[STRING_OFF], tmp, 4);
if(newline)
sprintf(ptr, "</br>");
else
sprintf(ptr, "</tab>");
ptr += strlen(ptr);
sprintf(ptr, URI("datatype", "%s (%"PRIu32")"), datatype, atom_lit->body.datatype);
ptr += strlen(ptr);
sprintf(ptr, URI("</tab>lang ", "%s (%"PRIu32")"), lang, atom_lit->body.lang);
}
else if(atom->type == ui->forge.URI)
{
char *str = LV2_ATOM_CONTENTS(LV2_Atom_String, atom);
if(atom->size == 0)
str = "";
LV2_URID urid = ui->map->map(ui->map->handle, str); //TODO add hashing
// truncate
char tmp[4] = {'\0'};
if(atom->size > STRING_MAX)
{
memcpy(tmp, &str[STRING_OFF], 4);
strcpy(&str[STRING_OFF], "...");
}
sprintf(ptr, HIL("</br>value ", "%s (%"PRIu32")"), str, urid);
// restore
if(atom->size > STRING_MAX)
memcpy(&str[STRING_OFF], tmp, 4);
}
else if(atom->type == ui->uris.midi_MidiEvent)
{
const uint8_t *midi = LV2_ATOM_BODY_CONST(atom);
sprintf(ptr, HIL_PRE("</br>value "));
ptr += strlen(ptr);
char *barrier = ptr + STRING_OFF;
for(unsigned i=0; (i<atom->size) && (ptr<barrier); i++, ptr += 3)
sprintf(ptr, "%02X ", midi[i]);
if(ptr >= barrier) // there would be more to print
{
ptr = barrier;
sprintf(ptr, "...");
ptr += 4;
}
sprintf(ptr, HIL_POST);
}
else if(atom->type == ui->forge.Chunk)
{
const uint8_t *chunk = LV2_ATOM_BODY_CONST(atom);
sprintf(ptr, HIL_PRE("</br>value "));
ptr += strlen(ptr);
char *barrier = ptr + STRING_OFF;
for(unsigned i=0; (i<atom->size) && (ptr<barrier); i++, ptr += 3)
sprintf(ptr, "%02"PRIX8" ", chunk[i]);
if(ptr >= barrier) // there would be more to print
{
ptr = barrier;
sprintf(ptr, "...");
ptr += 4;
}
sprintf(ptr, HIL_POST);
}
if( newline
&& !lv2_atom_forge_is_object_type(&ui->forge, atom->type)
&& !(atom->type == ui->forge.Literal)
&& !(atom->type == ui->forge.Vector) )
{
ptr += strlen(ptr);
sprintf(ptr, "</br>");
}
ptr += strlen(ptr);
sprintf(ptr, CODE_POST);
return ptr + strlen(ptr);
}
static char *
_atom_item_label_get(void *data, Evas_Object *obj, const char *part)
{
UI *ui = evas_object_data_get(obj, "ui");
const LV2_Atom *atom = data;
if(!ui)
return NULL;
if(!strcmp(part, "elm.text"))
{
char *buf = ui->string_buf;
char *ptr = buf;
char *end = buf + STRING_BUF_SIZE;
ptr = _atom_stringify(ui, ptr, end, 1, atom);
return ptr
? strdup(buf)
: NULL;
}
return NULL;
}
static char *
_prop_item_label_get(void *data, Evas_Object *obj, const char *part)
{
UI *ui = evas_object_data_get(obj, "ui");
const LV2_Atom_Property_Body *prop = data;
if(!ui)
return NULL;
if(!strcmp(part, "elm.text"))
{
char *buf = ui->string_buf;
char *ptr = buf;
char *end = buf + STRING_BUF_SIZE;
const char *key = _hash_get(ui, prop->key);
const char *context = _hash_get(ui, prop->context);
sprintf(ptr, URI("key ", "%s (%"PRIu32")"), key, prop->key);
ptr += strlen(ptr);
if(context)
{
sprintf(ptr, URI("</tab>context ", "%s (%"PRIu32")"), context, prop->context);
ptr += strlen(ptr);
}
sprintf(ptr, "</br>");
ptr += strlen(ptr);
ptr = _atom_stringify(ui, ptr, end, 0, &prop->value);
return ptr
? strdup(buf)
: NULL;
}
return NULL;
}
static char *
_seq_item_label_get(void *data, Evas_Object *obj, const char *part)
{
UI *ui = evas_object_data_get(obj, "ui");
const LV2_Atom_Event *ev = data;
const LV2_Atom *atom = &ev->body;
if(!ui)
return NULL;
if(!strcmp(part, "elm.text"))
{
char *buf = ui->string_buf;
char *ptr = buf;
char *end = buf + STRING_BUF_SIZE;
ptr = _atom_stringify(ui, ptr, end, 1, atom);
return ptr
? strdup(buf)
: NULL;
}
return NULL;
}
static char *
_list_item_label_get(void *data, Evas_Object *obj, const char *part)
{
......@@ -519,10 +182,11 @@ _list_item_label_get(void *data, Evas_Object *obj, const char *part)
}
static Evas_Object *
_group_item_content_get(void *data, Evas_Object *obj, const char *part)
_seq_item_content_get(void *data, Evas_Object *obj, const char *part)
{
UI *ui = evas_object_data_get(obj, "ui");
const position_t *pos = data;
const LV2_Atom_Event *ev = data;
const LV2_Atom *atom = &ev->body;
if(!ui)
return NULL;
......@@ -531,7 +195,7 @@ _group_item_content_get(void *data, Evas_Object *obj, const char *part)
{
char *buf = ui->string_buf;
sprintf(buf, "<color=#000 font=Mono>0x%"PRIx64"</color>", pos->offset);
sprintf(buf, "<color=#bb0 font=Mono>%04"PRIi64"</color>", ev->time.frames);
Evas_Object *label = elm_label_add(obj);
if(label)
......@@ -546,63 +210,6 @@ _group_item_content_get(void *data, Evas_Object *obj, const char *part)
{
char *buf = ui->string_buf;
sprintf(buf, "<color=#0bb font=Mono>%"PRIu32"</color>", pos->nsamples);
Evas_Object *label = elm_label_add(obj);
if(label)
{
elm_object_part_text_set(label, "default", buf);
evas_object_show(label);
}
return label;
}
return NULL;
}
static Evas_Object *
_atom_item_content_get(void *data, Evas_Object *obj, const char *part)
{
UI *ui = evas_object_data_get(obj, "ui");
const LV2_Atom *atom = data;
if(!ui)
return NULL;
if(!strcmp(part, "elm.swallow.end"))
{
char *buf = ui->string_buf;
sprintf(buf, "<color=#0bb font=Mono>%4"PRIu32"</color>", atom->size);
Evas_Object *label = elm_label_add(obj);
if(label)
{
elm_object_part_text_set(label, "default", buf);
evas_object_show(label);
}
return label;
}
return NULL;
}
static Evas_Object *
_prop_item_content_get(void *data, Evas_Object *obj, const char *part)
{
UI *ui = evas_object_data_get(obj, "ui");
const LV2_Atom_Property_Body *prop = data;
const LV2_Atom *atom = &prop->value;
if(!ui)
return NULL;
if(!strcmp(part, "elm.swallow.end"))
{
char *buf = ui->string_buf;
sprintf(buf, "<color=#0bb font=Mono>%4"PRIu32"</color>", atom->size);
Evas_Object *label = elm_label_add(obj);
......@@ -619,11 +226,10 @@ _prop_item_content_get(void *data, Evas_Object *obj, const char *part)
}
static Evas_Object *
_seq_item_content_get(void *data, Evas_Object *obj, const char *part)
_group_item_content_get(void *data, Evas_Object *obj, const char *part)
{
UI *ui = evas_object_data_get(obj, "ui");
const LV2_Atom_Event *ev = data;
const LV2_Atom *atom = &ev->body;
const position_t *pos = data;
if(!ui)
return NULL;
......@@ -632,7 +238,7 @@ _seq_item_content_get(void *data, Evas_Object *obj, const char *part)
{
char *buf = ui->string_buf;
sprintf(buf, "<color=#bb0 font=Mono>%04"PRIi64"</color>", ev->time.frames);
sprintf(buf, "<color=#000 font=Mono>0x%"PRIx64"</color>", pos->offset);
Evas_Object *label = elm_label_add(obj);
if(label)
......@@ -647,7 +253,7 @@ _seq_item_content_get(void *data, Evas_Object *obj, const char *part)
{
char *buf = ui->string_buf;
sprintf(buf, "<color=#0bb font=Mono>%4"PRIu32"</color>", atom->size);
sprintf(buf, "<color=#0bb font=Mono>%"PRIu32"</color>", pos->nsamples);
Evas_Object *label = elm_label_add(obj);
if(label)
......@@ -668,131 +274,58 @@ _del(void *data, Evas_Object *obj)
free(data);
}
static void
_item_expand_request(void *data, Evas_Object *obj, void *event_info)
{
Elm_Object_Item *itm = event_info;
UI *ui = data;
elm_genlist_item_expanded_set(itm, EINA_TRUE);
}
static void
_item_contract_request(void *data, Evas_Object *obj, void *event_info)
// copyied and adapted from libsratom
static inline char *
_sratom_to_turtle(Sratom* sratom,
LV2_URID_Unmap* unmap,
const char* base_uri,
const SerdNode* subject,
const SerdNode* predicate,
uint32_t type,
uint32_t size,
const void* body)
{
Elm_Object_Item *itm = event_info;
UI *ui = data;
elm_genlist_item_expanded_set(itm, EINA_FALSE);
}
static void
_atom_expand(UI *ui, const LV2_Atom *atom, Evas_Object *obj, Elm_Object_Item *itm)
{
if(lv2_atom_forge_is_object_type(&ui->forge, atom->type))
{
const LV2_Atom_Object *atom_object = (const LV2_Atom_Object *)atom;
LV2_ATOM_OBJECT_FOREACH(atom_object, prop)
{
Elm_Object_Item *itm2 = elm_genlist_item_append(ui->info, ui->itc_prop,
prop, itm, ELM_GENLIST_ITEM_TREE, NULL, NULL);
elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT);
elm_genlist_item_expanded_set(itm2, EINA_TRUE);
}
}
else if(atom->type == ui->forge.Tuple)
{
const LV2_Atom_Tuple *atom_tuple = (const LV2_Atom_Tuple *)atom;
for(LV2_Atom *iter = lv2_atom_tuple_begin(atom_tuple);
!lv2_atom_tuple_is_end(LV2_ATOM_BODY(atom_tuple), atom_tuple->atom.size, iter);
iter = lv2_atom_tuple_next(iter))
{
Elm_Object_Item *itm2 = elm_genlist_item_append(ui->info, ui->itc_atom,
iter, itm, ELM_GENLIST_ITEM_TREE, NULL, NULL);
elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT);
elm_genlist_item_expanded_set(itm2, EINA_TRUE);
}
}
else if(atom->type == ui->forge.Vector)
{
const LV2_Atom_Vector *atom_vector = (const LV2_Atom_Vector *)atom;
int num = (atom_vector->atom.size - sizeof(LV2_Atom_Vector_Body))
/ atom_vector->body.child_size;
const uint8_t *body = LV2_ATOM_CONTENTS_CONST(LV2_Atom_Vector, atom_vector);
for(int i=0; i<num; i++)
{
LV2_Atom *child = malloc(sizeof(LV2_Atom) + atom_vector->body.child_size);
if(child)
{
child->size = atom_vector->body.child_size;
child->type = atom_vector->body.child_type;
memcpy(LV2_ATOM_BODY(child), body + i*child->size, child->size);
Elm_Object_Item *itm2 = elm_genlist_item_append(ui->info, ui->itc_vec,
child, itm, ELM_GENLIST_ITEM_TREE, NULL, NULL);
elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT);
elm_genlist_item_expanded_set(itm2, EINA_TRUE);
}
}
}
else if(atom->type == ui->forge.Sequence)
{
const LV2_Atom_Sequence *atom_seq = (const LV2_Atom_Sequence *)atom;
LV2_ATOM_SEQUENCE_FOREACH(atom_seq, ev)
{
const LV2_Atom *child = &ev->body;
Elm_Object_Item *itm2 = elm_genlist_item_append(ui->info, ui->itc_seq,
ev, itm, ELM_GENLIST_ITEM_TREE, NULL, NULL);
elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT);
elm_genlist_item_expanded_set(itm2, EINA_TRUE);
}