gtk: More sample width fixes.
[sigrok:sigrok.git] / gtk / main.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <sigrok.h>
21 #include <gtk/gtk.h>
22
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <sys/stat.h>
26
27 #include "sigrok-gtk.h"
28
29 GtkWidget *sigview;
30
31 static const char *colours[8] = {
32         "black", "brown", "red", "orange",
33         "gold", "darkgreen", "blue", "magenta",
34 };
35
36 static void
37 datafeed_in(struct sr_device *device, struct sr_datafeed_packet *packet)
38 {
39         static int probelist[65] = { 0 };
40         static int unitsize = 0;
41         struct sr_probe *probe;
42         struct sr_datafeed_header *header;
43         struct sr_datafeed_logic *logic = NULL;
44         int num_enabled_probes, sample_size, i;
45         uint64_t filter_out_len;
46         char *filter_out;
47         GArray *data;
48
49         switch (packet->type) {
50         case SR_DF_HEADER:
51                 g_message("cli: Received SR_DF_HEADER");
52                 header = packet->payload;
53                 num_enabled_probes = 0;
54                 gtk_list_store_clear(siglist);
55                 for (i = 0; i < header->num_logic_probes; i++) {
56                         probe = g_slist_nth_data(device->probes, i);
57                         if (probe->enabled) {
58                                 GtkTreeIter iter;
59                                 probelist[num_enabled_probes++] = probe->index;
60                                 gtk_list_store_append(siglist, &iter);
61                                 gtk_list_store_set(siglist, &iter,
62                                                 0, probe->name,
63                                                 1, colours[(num_enabled_probes - 1) & 7],
64                                                 2, num_enabled_probes - 1,
65                                                 -1);
66                         }
67                 }
68                 /* How many bytes we need to store num_enabled_probes bits */
69                 unitsize = (num_enabled_probes + 7) / 8;
70                 data = g_array_new(FALSE, FALSE, unitsize);
71                 g_object_set_data(G_OBJECT(siglist), "sampledata", data);
72
73                 break;
74         case SR_DF_END:
75                 sigview_zoom(sigview, 1, 0);
76                 g_message("cli: Received SR_DF_END");
77                 sr_session_halt();
78                 break;
79         case SR_DF_TRIGGER:
80                 g_message("cli: received SR_DF_TRIGGER at %"PRIu64" ms",
81                                 packet->timeoffset / 1000000);
82                 break;
83         case SR_DF_LOGIC:
84                 logic = packet->payload;
85                 sample_size = logic->unitsize;
86                 g_message("cli: received SR_DF_LOGIC at %f ms duration %f ms, %"PRIu64" bytes",
87                                 packet->timeoffset / 1000000.0, packet->duration / 1000000.0,
88                                 logic->length);
89                 break;
90         case SR_DF_ANALOG:
91                 break;
92         }
93
94         if (!logic)
95                 return;
96
97         if (sr_filter_probes(sample_size, unitsize, probelist,
98                                    logic->data, logic->length,
99                                    &filter_out, &filter_out_len) != SR_OK)
100                 return;
101
102         data = g_object_get_data(G_OBJECT(siglist), "sampledata");
103         g_return_if_fail(data != NULL);
104
105         g_array_append_vals(data, filter_out, filter_out_len/unitsize);
106 }
107
108 void load_input_file(GtkWindow *parent, const gchar *file)
109 {
110         if (sr_session_load(file) == SR_OK) {
111                 /* sigrok session file */
112                 sr_session_datafeed_callback_add(datafeed_in);
113                 sr_session_start();
114                 sr_session_run();
115                 sr_session_stop();
116         }
117
118         /* Create a new session and programatically emit changed signal from
119          * the device selection combo box to reselect the device. 
120          */
121         sr_session_new();
122         sr_session_datafeed_callback_add(datafeed_in);
123         g_signal_emit_by_name(g_object_get_data(G_OBJECT(parent), "devcombo"), 
124                         "changed");
125 }
126
127 int main(int argc, char **argv)
128 {
129         GtkWindow *window;
130         GtkWidget *vbox, *vpaned, *log;
131         gtk_init(&argc, &argv);
132         icons_register();
133         sr_init();
134         sr_session_new();
135         sr_session_datafeed_callback_add(datafeed_in);
136
137         window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
138         gtk_window_set_icon_name(window, "sigrok-logo");
139         gtk_window_set_title(window, "Sigrok-GTK");
140         gtk_window_set_default_size(window, 600, 400);
141
142         g_signal_connect(window, "destroy", gtk_main_quit, NULL);
143
144         vbox = gtk_vbox_new(FALSE, 0);
145         vpaned = gtk_vpaned_new();
146
147         gtk_box_pack_start(GTK_BOX(vbox), toolbar_init(window), FALSE, FALSE, 0);
148         gtk_box_pack_start(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0);
149         log = log_init();
150         gtk_widget_set_no_show_all(log, TRUE);
151         g_object_set_data(G_OBJECT(window), "logview", log);
152         gtk_paned_add2(GTK_PANED(vpaned), log);
153         sigview = sigview_init();
154         g_object_set_data(G_OBJECT(window), "sigview", sigview);
155         gtk_paned_pack1(GTK_PANED(vpaned), sigview, TRUE, FALSE);
156
157         gtk_container_add(GTK_CONTAINER(window), vbox);
158         gtk_widget_show_all(GTK_WIDGET(window));
159
160         sr_set_loglevel(1);
161
162         gtk_main();
163
164         sr_session_destroy();
165         gtk_exit(0);
166
167         return 0;
168 }
169