variable tab
This commit is contained in:
parent
506f2f3d59
commit
b4904e1bb5
@ -6,9 +6,7 @@
|
|||||||
#include "tcpsocket.h"
|
#include "tcpsocket.h"
|
||||||
#include "sockaddr.h"
|
#include "sockaddr.h"
|
||||||
|
|
||||||
int tdc_parse_data(int fd);
|
#include "tdc_store.h"
|
||||||
void tdc_flush_vars(void);
|
|
||||||
void tdc_send_hello(int fd);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STAT_DISCONNECTED = 0,
|
STAT_DISCONNECTED = 0,
|
||||||
|
6
gtdc.c
6
gtdc.c
@ -1,14 +1,18 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "tdc_store.h"
|
||||||
|
#include "variable_tab.h"
|
||||||
|
|
||||||
gint control_tab_init(GtkNotebook *notebook);
|
gint control_tab_init(GtkNotebook *notebook);
|
||||||
gint variable_tab_init(GtkNotebook *notebook);
|
|
||||||
gint graph_tab_init(GtkNotebook *notebook);
|
gint graph_tab_init(GtkNotebook *notebook);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
tdc_init();
|
||||||
|
|
||||||
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
gtk_window_set_title(GTK_WINDOW(window), " gTDC v0.1 ");
|
gtk_window_set_title(GTK_WINDOW(window), " gTDC v0.1 ");
|
||||||
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
|
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
|
||||||
|
279
tdc_store.c
Normal file
279
tdc_store.c
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "tdc_store.h"
|
||||||
|
#include "tdcproto.h"
|
||||||
|
|
||||||
|
#include "variable_tab.h"
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
static struct tdc_var * var_map[256];
|
||||||
|
static GByteArray *stream;
|
||||||
|
|
||||||
|
static void destroy_var(int id)
|
||||||
|
{
|
||||||
|
g_free(var_map[id]);
|
||||||
|
var_map[id] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_var(int id, uint32_t flags, char *name, int len)
|
||||||
|
{
|
||||||
|
id &= 0xFF;
|
||||||
|
|
||||||
|
if (var_map[id] != NULL)
|
||||||
|
destroy_var(id);
|
||||||
|
|
||||||
|
var_map[id] = g_malloc0(sizeof(struct tdc_var) + len + 1);
|
||||||
|
var_map[id]->id = id;
|
||||||
|
var_map[id]->flags = flags;
|
||||||
|
|
||||||
|
strncpy(var_map[id]->name, name, len);
|
||||||
|
var_map[id]->name[len] = '\0';
|
||||||
|
|
||||||
|
vartab_add_var(var_map[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_var(int id, uint8_t *data, int len)
|
||||||
|
{
|
||||||
|
memcpy(&(var_map[id & 0xFF]->data_uint8), data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static char * stream_print(void)
|
||||||
|
{
|
||||||
|
int pos = 0, i = 0, j;
|
||||||
|
char *buf = g_malloc(stream->len * 4 + 64);
|
||||||
|
|
||||||
|
while (pos < stream->len) {
|
||||||
|
i += sprintf(buf + i, "%04X: ", pos);
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (pos + j < stream->len)
|
||||||
|
i += sprintf(buf + i, "%02X", stream->data[pos + j]);
|
||||||
|
else
|
||||||
|
i += sprintf(buf + i, " ");
|
||||||
|
|
||||||
|
if (j % 2)
|
||||||
|
buf[i++] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (pos + j < stream->len) {
|
||||||
|
unsigned char val = stream->data[pos + j];
|
||||||
|
if (val >= 0x20 && val < 0x80)
|
||||||
|
buf[i++] = val;
|
||||||
|
else
|
||||||
|
buf[i++] = '.';
|
||||||
|
} else {
|
||||||
|
buf[i++] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 16;
|
||||||
|
buf[i++] = '\r';
|
||||||
|
buf[i++] = '\n';
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int parse_size_helper(int available,
|
||||||
|
int packet_size,
|
||||||
|
int expected_base_size,
|
||||||
|
int packet_data_size,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
/* not enough data in buffer */
|
||||||
|
if (available < expected_base_size) {
|
||||||
|
printf("received incomplete %s\n", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* retest, after we know that packet_data_size is valid */
|
||||||
|
if (available < (expected_base_size + packet_data_size)) {
|
||||||
|
printf("received incomplete %s\n", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* packet has wrong size */
|
||||||
|
if (packet_size != (expected_base_size + packet_data_size)) {
|
||||||
|
printf("received invalid %s\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("received %s\n", name);
|
||||||
|
return packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse(int fd)
|
||||||
|
{
|
||||||
|
int address = (stream->data[0] & TDC_ADDRMASK) >> 4;
|
||||||
|
|
||||||
|
int remove = 1;
|
||||||
|
|
||||||
|
switch (stream->data[0] & (TDC_REPLY | TDC_OPCODEMASK)) {
|
||||||
|
case TDC_HELLO: {
|
||||||
|
struct tdc_pkt_header *pkt = (struct tdc_pkt_header *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_HELLO");
|
||||||
|
/* do nothing, we'll never receive TDC_HELLOs */
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case (TDC_HELLO | TDC_REPLY): {
|
||||||
|
struct tdc_hello_reply *pkt = (struct tdc_hello_reply *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_HELLO REPLY");
|
||||||
|
if (remove <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
printf("ADDR%d: '%32s'\n", address, pkt->name);
|
||||||
|
|
||||||
|
struct tdc_pkt_header pkt2;
|
||||||
|
pkt2.cmd = (address << 4) | TDC_GETVARS;
|
||||||
|
pkt2.size = sizeof(pkt2);
|
||||||
|
write(fd, &pkt2, pkt2.size);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TDC_GETVARS: {
|
||||||
|
struct tdc_pkt_header *pkt = (struct tdc_pkt_header *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_GETVARS");
|
||||||
|
/* do nothing, we'll never receive TDC_GETVARSs */
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case (TDC_GETVARS | TDC_REPLY): {
|
||||||
|
struct tdc_getvars_reply *pkt = (struct tdc_getvars_reply *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt),
|
||||||
|
pkt->name_len, "TDC_GETVARS REPLY");
|
||||||
|
|
||||||
|
if (remove <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
create_var(pkt->id, pkt->flags, pkt->name, pkt->name_len);
|
||||||
|
printf("create_var(%d, 0x%x, '%s', %d)\n",
|
||||||
|
pkt->id, var_map[pkt->id]->flags, var_map[pkt->id]->name, pkt->name_len);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TDC_GETVALUE: {
|
||||||
|
struct tdc_getvalue_request *pkt = (struct tdc_getvalue_request *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_GETVALUE");
|
||||||
|
/* do nothing, we'll never receive TDC_GETVALUEs */
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case (TDC_GETVALUE | TDC_REPLY): {
|
||||||
|
struct tdc_getvalue_reply *pkt = (struct tdc_getvalue_reply *)stream->data;
|
||||||
|
|
||||||
|
/* check base packet */
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_GETVALUE REPLY");
|
||||||
|
if (remove <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (var_map[pkt->id & 0xFF] == NULL) {
|
||||||
|
printf("unknown variable %d\n", pkt->id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int varsize = (var_map[pkt->id & 0xFF]->flags & TDC_SIZEMASK);
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), varsize, "TDC_GETVALUE REPLY");
|
||||||
|
// TODO: adjust remove on error (valid reply with invalid data size)
|
||||||
|
|
||||||
|
update_var(pkt->id, pkt->data, varsize);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TDC_SETVALUE: {
|
||||||
|
struct tdc_setvalue_request *pkt = (struct tdc_setvalue_request *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_SETVALUE");
|
||||||
|
if (remove <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (var_map[pkt->id & 0xFF] == NULL) {
|
||||||
|
printf("unknown variable %d\n", pkt->id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int varsize = (var_map[pkt->id & 0xFF]->flags & TDC_SIZEMASK);
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), varsize, "TDC_GETVALUE REPLY");
|
||||||
|
// TODO: adjust remove on error (valid reply with invalid data size)
|
||||||
|
|
||||||
|
/* do nothing, we'll never receive TDC_SETVALUEs */
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case (TDC_SETVALUE | TDC_REPLY):
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TDC_REQVALUES: {
|
||||||
|
struct tdc_reqvalues_request *pkt = (struct tdc_reqvalues_request *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_REQVALUES");
|
||||||
|
/* do nothing, we'll never receive TDC_REQVALUESs */
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case (TDC_REQVALUES | TDC_REPLY): {
|
||||||
|
struct tdc_reqvalues_reply *pkt = (struct tdc_reqvalues_reply *)stream->data;
|
||||||
|
remove = parse_size_helper(stream->len, pkt->size, sizeof(*pkt), 0, "TDC_REQVALUES");
|
||||||
|
if (remove <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TODO: output pkt->timestamp, pkt->cnt
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TDC_TERMINAL:
|
||||||
|
case (TDC_TERMINAL | TDC_REPLY):
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove != 0)
|
||||||
|
g_byte_array_remove_range(stream, 0, (remove > 0) ? remove : -remove);
|
||||||
|
|
||||||
|
return remove;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tdc_parse_data(int fd)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
int len = read(fd, buf, sizeof(buf));
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
g_byte_array_append(stream, (guint8 *)buf, len);
|
||||||
|
|
||||||
|
while (stream->len >= 2) {
|
||||||
|
if (parse(fd) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdc_flush_vars(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(var_map); i++) {
|
||||||
|
if (var_map[i] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
destroy_var(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream->len)
|
||||||
|
g_byte_array_remove_range(stream, 0, stream->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdc_send_hello(int fd)
|
||||||
|
{
|
||||||
|
int addr;
|
||||||
|
for (addr = 1; addr < 8; addr++) {
|
||||||
|
struct tdc_pkt_header pkt;
|
||||||
|
pkt.cmd = (addr << 4) | TDC_HELLO;
|
||||||
|
pkt.size = sizeof(pkt);
|
||||||
|
|
||||||
|
write(fd, &pkt, pkt.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdc_init(void)
|
||||||
|
{
|
||||||
|
stream = g_byte_array_new();
|
||||||
|
}
|
25
tdc_store.h
Normal file
25
tdc_store.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef TDC_STORE_H_
|
||||||
|
#define TDC_STORE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct tdc_var {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t flags;
|
||||||
|
union {
|
||||||
|
uint8_t data_uint8;
|
||||||
|
uint16_t data_uint16;
|
||||||
|
uint32_t data_uint32;
|
||||||
|
uint64_t data_uint64;
|
||||||
|
float data_float;
|
||||||
|
double data_double;
|
||||||
|
};
|
||||||
|
char name[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
int tdc_parse_data(int fd);
|
||||||
|
void tdc_flush_vars(void);
|
||||||
|
void tdc_send_hello(int fd);
|
||||||
|
void tdc_init(void);
|
||||||
|
|
||||||
|
#endif /* TDC_STORE_H_ */
|
101
tdcproto.h
Normal file
101
tdcproto.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#ifndef TDCPROTO_H_
|
||||||
|
#define TDCPROTO_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0: this is a request (host -> board)
|
||||||
|
* 1: this is a reply (board -> host)
|
||||||
|
*/
|
||||||
|
#define TDC_DIR 0x80
|
||||||
|
#define TDC_REPLY TDC_DIR
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDC_DIR = 0: destination address
|
||||||
|
* TDC_DIR = 1: source address
|
||||||
|
*/
|
||||||
|
#define TDC_ADDRMASK 0x70
|
||||||
|
#define TDC_ADDR0 0x00 // host (dynamic!, sends to interface of last hello)
|
||||||
|
#define TDC_ADDR1 0x10 // flightcontrol
|
||||||
|
#define TDC_ADDR2 0x20 // missioncontrol
|
||||||
|
#define TDC_ADDR3 0x30 // videocontrol
|
||||||
|
#define TDC_ADDR4 0x40
|
||||||
|
#define TDC_ADDR5 0x50
|
||||||
|
#define TDC_ADDR6 0x60
|
||||||
|
#define TDC_ADDR7 0x70
|
||||||
|
|
||||||
|
#define TDC_OPCODEMASK 0x0F
|
||||||
|
#define TDC_HELLO 0x00 // sets the path/interface to the host, reply is a info string
|
||||||
|
#define TDC_GETVARS 0x01 // request variable names, many replies
|
||||||
|
#define TDC_GETVALUE 0x02 // get one value, one reply
|
||||||
|
#define TDC_SETVALUE 0x03 // set one value, no reply
|
||||||
|
#define TDC_REQVALUES 0x04 // registers a periodic update, timed replies
|
||||||
|
#define TDC_TERMINAL 0x05 // stdout data
|
||||||
|
|
||||||
|
#define TDC_USERDATA 0x0F // user-defined data e.g. between boards
|
||||||
|
|
||||||
|
struct tdc_pkt_header {
|
||||||
|
uint8_t cmd; // TDC_*
|
||||||
|
uint8_t size; // size including this header
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct tdc_hello_reply {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t size;
|
||||||
|
char name[32]; // name of device, version string
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct tdc_getvars_reply {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t id; // variable ID (max 256 vars / board)
|
||||||
|
uint32_t flags; // variable parameters (type, size, ro/rw)
|
||||||
|
uint8_t name_len; // size of variable name
|
||||||
|
char name[0]; // variable name, excluding '\0'
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct tdc_getvalue_request {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t id; // variable ID (max 256 vars / board)
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct tdc_getvalue_reply {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t id; // variable ID (max 256 vars / board)
|
||||||
|
uint8_t data[0]; // variable data 1-8 bytes
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct tdc_setvalue_request {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t id; // variable ID (max 256 vars / board)
|
||||||
|
uint8_t data[0]; // variable data 1-8 bytes
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct tdc_reqvalues_request {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t size;
|
||||||
|
uint16_t interval; // interval in ms
|
||||||
|
uint32_t varmap[8]; // bitmap of variables (32 * 8 = 256)
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct tdc_reqvalues_reply {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t size;
|
||||||
|
uint32_t timestamp; // internal jiffie count
|
||||||
|
uint8_t cnt; // number of variables
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define TDC_SIZEMASK 0x000F
|
||||||
|
|
||||||
|
#define TDC_TYPEMASK 0x00F0
|
||||||
|
#define TDC_UNSIGNED 0x0000
|
||||||
|
#define TDC_SIGNED 0x0010
|
||||||
|
#define TDC_FP 0x0020
|
||||||
|
#define TDC_FIXED 0x0040
|
||||||
|
|
||||||
|
#define TDC_READONLY 0x0100
|
||||||
|
|
||||||
|
#endif /* TDCPROTO_H_ */
|
115
variable_tab.c
115
variable_tab.c
@ -1,21 +1,48 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "tdc_store.h"
|
||||||
|
#include "tdcproto.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
COL_GRAPH = 0,
|
COL_ID = 0, /* UINT */
|
||||||
COL_VALUE,
|
COL_GRAPH, /* BOOLEAN */
|
||||||
COL_TYPE,
|
COL_VALUE, /* PTR?, with cell_data_func */
|
||||||
COL_NAME,
|
COL_VALUE_EDIT, /* BOOLEAN */
|
||||||
|
COL_TYPE, /* STRING */
|
||||||
|
COL_NAME, /* STRING */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static GtkListStore *list_store;
|
||||||
|
|
||||||
|
static void cell_graph_toggle(GtkCellRendererToggle *cell, gchar *path_string, gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkTreeIter it;
|
||||||
|
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(user_data), &it, path_string);
|
||||||
|
|
||||||
|
gboolean toggle;
|
||||||
|
|
||||||
|
gtk_tree_model_get(GTK_TREE_MODEL(user_data), &it,
|
||||||
|
COL_GRAPH, &toggle,
|
||||||
|
-1);
|
||||||
|
|
||||||
|
gtk_list_store_set(GTK_LIST_STORE(user_data), &it,
|
||||||
|
COL_GRAPH, !toggle,
|
||||||
|
-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cell_value_edited(GtkCellRendererText *cell, gchar *path_string, gchar *new_text, gpointer user_data)
|
||||||
|
{
|
||||||
|
printf("cell_value_edited\n");
|
||||||
|
}
|
||||||
|
|
||||||
gint variable_tab_init(GtkNotebook *notebook)
|
gint variable_tab_init(GtkNotebook *notebook)
|
||||||
{
|
{
|
||||||
/* graph, value, type, name */
|
list_store = gtk_list_store_new(6,
|
||||||
GtkListStore *list_store = gtk_list_store_new(1,
|
G_TYPE_UINT, G_TYPE_BOOLEAN,
|
||||||
G_TYPE_BOOLEAN, G_TYPE_STRING,
|
G_TYPE_STRING, G_TYPE_BOOLEAN,
|
||||||
G_TYPE_STRING, G_TYPE_STRING);
|
G_TYPE_STRING, G_TYPE_STRING);
|
||||||
|
|
||||||
GtkWidget *view = gtk_tree_view_new();
|
GtkWidget *view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
|
||||||
gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(list_store));
|
|
||||||
g_object_unref(list_store);
|
g_object_unref(list_store);
|
||||||
|
|
||||||
GtkTreeViewColumn *col;
|
GtkTreeViewColumn *col;
|
||||||
@ -25,15 +52,22 @@ gint variable_tab_init(GtkNotebook *notebook)
|
|||||||
gtk_tree_view_column_set_title(col, "Graph");
|
gtk_tree_view_column_set_title(col, "Graph");
|
||||||
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
||||||
renderer = gtk_cell_renderer_toggle_new();
|
renderer = gtk_cell_renderer_toggle_new();
|
||||||
|
g_object_set(renderer, "activatable", TRUE, NULL);
|
||||||
|
g_signal_connect(renderer, "toggled", (GCallback)cell_graph_toggle, list_store);
|
||||||
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, renderer, "active", COL_GRAPH);
|
gtk_tree_view_column_add_attribute(col, renderer, "active", COL_GRAPH);
|
||||||
|
|
||||||
|
|
||||||
col = gtk_tree_view_column_new();
|
col = gtk_tree_view_column_new();
|
||||||
gtk_tree_view_column_set_title(col, "Value");
|
gtk_tree_view_column_set_title(col, "Value");
|
||||||
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
||||||
renderer = gtk_cell_renderer_text_new();
|
renderer = gtk_cell_renderer_text_new();
|
||||||
|
// gtk_tree_view_column_set_cell_data_func(col, renderer, cell_value_func, NULL, NULL);
|
||||||
|
g_signal_connect(renderer, "edited", (GCallback)cell_value_edited, NULL);
|
||||||
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_VALUE);
|
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_VALUE);
|
||||||
|
gtk_tree_view_column_add_attribute(col, renderer, "editable", COL_VALUE_EDIT);
|
||||||
|
|
||||||
|
|
||||||
col = gtk_tree_view_column_new();
|
col = gtk_tree_view_column_new();
|
||||||
gtk_tree_view_column_set_title(col, "Type");
|
gtk_tree_view_column_set_title(col, "Type");
|
||||||
@ -42,6 +76,7 @@ gint variable_tab_init(GtkNotebook *notebook)
|
|||||||
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_TYPE);
|
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_TYPE);
|
||||||
|
|
||||||
|
|
||||||
col = gtk_tree_view_column_new();
|
col = gtk_tree_view_column_new();
|
||||||
gtk_tree_view_column_set_title(col, "Name");
|
gtk_tree_view_column_set_title(col, "Name");
|
||||||
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
||||||
@ -49,6 +84,64 @@ gint variable_tab_init(GtkNotebook *notebook)
|
|||||||
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_NAME);
|
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_NAME);
|
||||||
|
|
||||||
|
GtkWidget *scrollbar = gtk_scrolled_window_new(NULL, NULL);
|
||||||
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbar), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||||
|
gtk_container_add(GTK_CONTAINER(scrollbar), view);
|
||||||
|
|
||||||
GtkWidget *label = gtk_label_new(" Variables ");
|
GtkWidget *label = gtk_label_new(" Variables ");
|
||||||
return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), view, label);
|
return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrollbar, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vartab_add_var(struct tdc_var *var)
|
||||||
|
{
|
||||||
|
GtkTreeIter it;
|
||||||
|
gtk_list_store_append(list_store, &it);
|
||||||
|
|
||||||
|
char typestr[16];
|
||||||
|
|
||||||
|
int size = (var->flags & TDC_SIZEMASK);
|
||||||
|
|
||||||
|
switch (var->flags & TDC_TYPEMASK) {
|
||||||
|
case TDC_UNSIGNED:
|
||||||
|
snprintf(typestr, sizeof(typestr), "uint%d_t", size * 8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TDC_SIGNED:
|
||||||
|
snprintf(typestr, sizeof(typestr), "int%d_t", size * 8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TDC_FP:
|
||||||
|
if (size == sizeof(float))
|
||||||
|
snprintf(typestr, sizeof(typestr), "float");
|
||||||
|
|
||||||
|
else if (size == sizeof(double))
|
||||||
|
snprintf(typestr, sizeof(typestr), "double");
|
||||||
|
|
||||||
|
else
|
||||||
|
snprintf(typestr, sizeof(typestr), "float(%d)", size * 8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TDC_FIXED:
|
||||||
|
snprintf(typestr, sizeof(typestr), "fixed(%d)", size * 8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_list_store_set(list_store, &it,
|
||||||
|
COL_ID, var->id,
|
||||||
|
COL_GRAPH, FALSE,
|
||||||
|
COL_VALUE, "none",
|
||||||
|
COL_VALUE_EDIT, !(var->flags & TDC_READONLY),
|
||||||
|
COL_TYPE, typestr,
|
||||||
|
COL_NAME, var->name,
|
||||||
|
-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vartab_update_var(struct tdc_var *var)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void vartab_remove_var(struct tdc_var *var)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
13
variable_tab.h
Normal file
13
variable_tab.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef VARIABLE_TAB_H_
|
||||||
|
#define VARIABLE_TAB_H_
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "tdc_store.h"
|
||||||
|
|
||||||
|
gint variable_tab_init(GtkNotebook *notebook);
|
||||||
|
|
||||||
|
void vartab_add_var(struct tdc_var *var);
|
||||||
|
void vartab_update_var(struct tdc_var *var);
|
||||||
|
void vartab_remove_var(struct tdc_var *var);
|
||||||
|
|
||||||
|
#endif /* VARIABLE_TAB_H_ */
|
Loading…
Reference in New Issue
Block a user