Initial commit
[jamendo] / branches / nota-show-app / src / gtkservice.c
1 /***************************************************************************
2  *            gtkservice.c
3  *
4  *  Wed Nov 18 10:46:06 2009
5  *  Copyright  2009  Marcin Miklas, Bartlomiej Swiercz
6  *  <marcin.miklas@teleca.com>
7  *  <bartlomiej.swiercz@teleca.com>
8  ****************************************************************************/
9
10 #include <gtk/gtk.h>
11 #include <glib.h>
12 #include <string.h> // for strlen
13 #include <unistd.h>
14 #include "service.h"
15 #include "ts7200/ts7200_client.h"
16
17 GtkWidget* g_image = NULL;
18 GtkWidget* g_text_view = NULL;
19 GtkWidget* act_state[2] = { NULL, NULL };
20 GtkWidget* act_info[2] = { NULL, NULL };
21 volatile int run_check = 1;
22
23 void terminate()
24 {
25     run_check = 0;
26     gtk_main_quit();
27 }
28
29 void displayUI()
30 {
31     GtkWidget* mainWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
32     act_state[0] = gtk_check_button_new();
33     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( act_state[0] ), FALSE );
34     act_state[1] = gtk_check_button_new();
35     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( act_state[1] ), FALSE );
36     act_info[0]  = gtk_label_new( "Not connected" );
37     act_info[1]  = gtk_label_new( "Not connected" );
38
39     gtk_window_set_default_size(GTK_WINDOW(mainWindow), 700, 600);
40     gtk_window_set_title(GTK_WINDOW(mainWindow), "NoTA Service - operator's panel");
41     gtk_window_set_position(GTK_WINDOW(mainWindow), GTK_WIN_POS_CENTER_ALWAYS);
42     gtk_container_set_border_width( GTK_CONTAINER( mainWindow ), 5 );
43
44         gtk_signal_connect(GTK_OBJECT(mainWindow), "destroy", G_CALLBACK( terminate ), NULL);
45
46     GtkWidget *hbox_main = gtk_hbox_new( FALSE, 2 );
47         gtk_container_add( GTK_CONTAINER( mainWindow ), hbox_main );
48         GtkWidget *vbox = gtk_vbox_new(FALSE,2);
49         gtk_box_pack_start( GTK_BOX( hbox_main ), vbox, TRUE, TRUE, 0 );
50
51     GtkWidget *frame_r = gtk_frame_new( " System log monitor: " );
52         gtk_box_pack_start( GTK_BOX( hbox_main ), frame_r, TRUE, TRUE, 0 );
53
54         g_text_view = gtk_text_view_new();
55         gtk_text_view_set_editable(GTK_TEXT_VIEW(g_text_view),FALSE);
56         gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(g_text_view),FALSE);
57         
58         GtkWidget* swindow = gtk_scrolled_window_new (NULL, NULL);
59         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
60                                   GTK_POLICY_AUTOMATIC,
61                                   GTK_POLICY_AUTOMATIC);
62         gtk_container_add(GTK_CONTAINER(swindow), g_text_view);
63         gtk_container_add( GTK_CONTAINER( frame_r ), swindow );
64         
65         g_image = gtk_image_new();
66         GdkPixbuf* pixbuf = gtk_widget_render_icon( GTK_WIDGET(g_image), GTK_STOCK_MISSING_IMAGE,
67                                                 GTK_ICON_SIZE_DIALOG, NULL);
68         gtk_image_set_from_pixbuf(GTK_IMAGE(g_image),pixbuf);
69         gtk_box_pack_start(GTK_BOX(vbox),g_image,TRUE,TRUE,0);
70
71     GtkWidget *frame_l = gtk_frame_new( " Actuators: " );
72         gtk_box_pack_start( GTK_BOX( vbox ), frame_l, TRUE, TRUE, 0 );
73
74     GtkWidget *act_panel = gtk_table_new( 3, 3, FALSE );
75         gtk_container_add( GTK_CONTAINER( frame_l ), act_panel );
76     /* Row 1 - headings: */
77     gtk_table_attach( GTK_TABLE( act_panel ), gtk_label_new( "State:" ), 0, 1, 0, 1, 
78                       GTK_FILL, GTK_FILL, 1, 1); 
79     gtk_table_attach( GTK_TABLE( act_panel ), gtk_label_new( "Name:" ), 1, 2, 0, 1, 
80                       GTK_FILL | GTK_EXPAND, GTK_FILL, 1, 1); 
81     gtk_table_attach( GTK_TABLE( act_panel ), gtk_label_new( "Information:" ), 2, 3, 0, 1, 
82                       GTK_FILL | GTK_EXPAND, GTK_FILL, 1, 1); 
83     /* Row 2: */
84     gtk_table_attach( GTK_TABLE( act_panel ), act_state[0], 0, 1, 1, 2, 
85                       GTK_FILL, GTK_FILL, 1, 1); 
86     gtk_table_attach( GTK_TABLE( act_panel ), gtk_label_new( "Actuator TS7200-1" ), 1, 2, 1, 2, 
87                       GTK_FILL | GTK_EXPAND, GTK_FILL, 1, 1); 
88     gtk_table_attach( GTK_TABLE( act_panel ), act_info[0], 2, 3, 1, 2, 
89                       GTK_FILL | GTK_EXPAND, GTK_FILL, 1, 1); 
90     /* Row 3: */
91     gtk_table_attach( GTK_TABLE( act_panel ), act_state[1], 0, 1, 2, 3, 
92                       GTK_FILL, GTK_FILL, 1, 1); 
93     gtk_table_attach( GTK_TABLE( act_panel ), gtk_label_new( "Actuator TS7200-2" ), 1, 2, 2, 3, 
94                       GTK_FILL | GTK_EXPAND, GTK_FILL, 1, 1); 
95     gtk_table_attach( GTK_TABLE( act_panel ), act_info[1], 2, 3, 2, 3, 
96                       GTK_FILL | GTK_EXPAND, GTK_FILL, 1, 1); 
97
98         gtk_widget_show_all(mainWindow);
99 }
100
101 void gtklog(const char* str) {
102         if(!run_check) return;
103         
104         GtkTextBuffer* text_buffer;
105         GtkTextIter iter;
106
107         gdk_threads_enter();
108
109         text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(g_text_view));
110         gtk_text_buffer_insert_at_cursor(text_buffer,str,strlen(str));
111         gtk_text_buffer_get_end_iter(text_buffer,&iter);
112         gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(g_text_view),&iter,0,FALSE,0,0);
113
114         gdk_threads_leave();
115 }
116
117 guchar* last_img = NULL;
118 int last_img_size = 0;
119 struct {
120         int x,y,r;
121 } face = {0};
122
123 void put_image(guchar* img_buf,int size) {
124         if(!run_check) return;
125         
126         gdk_threads_enter();
127
128         GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
129         gdk_pixbuf_loader_write(loader,(guchar*)img_buf,size,NULL);
130         gdk_pixbuf_loader_close(loader,NULL);
131         GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
132         
133         gtk_image_set_from_pixbuf(GTK_IMAGE(g_image),pixbuf);
134         if(face.r) {
135                 /* sie nie wywala, ale rysuje nie tam gdzie trzeba.
136                 GdkGC* gc;
137                 gc=gdk_gc_new(g_image->window); 
138                 gdk_draw_arc(g_image->window, gc, TRUE, face.x-face.r, face.y-face.r,2*face.r, 2*face.r, 0, 360*64);
139                  */
140         }
141         g_object_unref(loader);
142
143         gdk_threads_leave();
144
145         if(last_img) {
146                 g_free(last_img);
147         }
148         last_img = g_memdup(img_buf,size);
149         last_img_size = size;
150 }
151
152 guchar* get_image(int* img_size) {
153         if(!run_check) return NULL;
154         
155         if(img_size)
156                 *img_size = last_img_size;
157         if(last_img) {
158                 return g_memdup(last_img,last_img_size);
159         }
160         else {
161                 return NULL;
162         }
163 }
164
165 void face_found(int x,int y,int r) {
166         if(!run_check) return;
167         
168         gchar* str = g_strdup_printf("Face detected (%d,%d,%d)!\n",x,y,r);
169         gtklog(str);
170         g_free(str);
171
172     int resp =  act_run_cmd( ACT1_SID, FACE_DETECTED );
173
174         face.x = x;
175         face.y = y;
176         face.r = r;
177 }
178
179 gpointer act_check( gpointer data )
180 {
181     unsigned int sid = *((unsigned int*) data);
182     int resp, i;
183     while( run_check )
184     {
185         for (i=0; i<2; ++i)
186         {
187             resp =  act_run_cmd( sid+i, PING );
188
189             gdk_threads_enter();
190             if (resp == CONNECTED )
191             {
192                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( act_state[i] ), TRUE );
193                 gtk_label_set_text( GTK_LABEL( act_info[i] ), "Connected" );
194             }
195             else
196             {
197                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( act_state[i] ), FALSE );
198                 gtk_label_set_text( GTK_LABEL( act_info[i] ), "Not connected" );
199             }
200             gdk_threads_leave();
201         }
202
203         sleep( 2 );
204     }
205     return NULL;
206 }
207
208 int main(int argc, char *argv[])
209 {
210         if (!g_thread_supported()) {
211                 g_thread_init(NULL);
212         }
213         gdk_threads_init();
214         gdk_threads_enter();
215         
216         gtk_init(&argc, &argv);
217
218         displayUI();
219
220         ServiceCallbacks* cb = g_new0(ServiceCallbacks,1);
221         cb->run_check = &run_check;
222         cb->log = &gtklog;
223         cb->put_image = &put_image;
224         cb->get_image = &get_image;
225         cb->face_found = &face_found;
226         
227         g_thread_create((GThreadFunc)service,cb,FALSE,NULL);
228
229     int sid = ACT1_SID;
230         g_thread_create( (GThreadFunc) act_check, &sid, FALSE, NULL);
231         
232         gtk_main();
233
234         gdk_threads_leave();
235         return 0;
236 }