23 #include "fuse_image_list_widget.h" 25 #include <fvutils/net/fuse_message.h> 26 #include <fvutils/net/fuse_imagelist_content.h> 28 #include <netinet/in.h> 46 FuseImageListWidget::FuseImageListWidget()
48 m_chk_compression = NULL;
49 m_chk_auto_update = NULL;
51 m_cur_client.active =
false;
53 m_new_clients.clear();
54 m_delete_clients.clear();
56 m_image_list = Gtk::TreeStore::create(m_image_record);
58 m_signal_get_image_list.connect( sigc::mem_fun( *
this, &FuseImageListWidget::get_image_list) );
59 m_signal_delete_clients.connect( sigc::mem_fun( *
this, &FuseImageListWidget::delete_clients) );
60 m_signal_update_image_l.connect( sigc::mem_fun( *
this, &FuseImageListWidget::update_image_list) );
62 #if GTK_VERSION_LT(3,0) 63 m_popup_menu = Gtk::manage(
new Gtk::Menu() );
64 Gtk::Menu::MenuList& menulist = m_popup_menu->items();
65 menulist.push_back( Gtk::Menu_Helpers::MenuElem(
"Update now", sigc::mem_fun( *
this, &FuseImageListWidget::update_image_list) ) );
66 menulist.push_back( Gtk::Menu_Helpers::SeparatorElem() );
67 menulist.push_back( Gtk::Menu_Helpers::MenuElem(
"Add host manually", sigc::mem_fun( *
this, &FuseImageListWidget::on_add_host_manually) ) );
70 set_image_list_trv(
this);
74 FuseImageListWidget::~FuseImageListWidget()
78 while (m_new_clients.size() != 0)
80 c = m_new_clients.front().client;
81 m_new_clients.pop_front();
87 m_new_clients.unlock();
89 if (m_cur_client.active)
91 m_cur_client.active =
false;
92 m_delete_clients.push_locked(m_cur_client.client);
103 FuseImageListWidget::add_fountain_service(
const char* name,
104 const char* host_name,
108 m_img_list_mutex.lock();
109 Gtk::TreeModel::Children children = m_image_list->children();
110 for ( Gtk::TreeModel::Children::iterator iter = children.begin();
111 iter != children.end(); ++iter )
113 Gtk::TreeModel::Row row = *iter;
114 if ( row[m_image_record.service_name] == Glib::ustring(name) )
116 m_img_list_mutex.unlock();
120 m_img_list_mutex.unlock();
123 m_new_clients.lock();
125 iter != m_new_clients.end(); ++iter )
127 if (name == iter->service_name)
129 m_new_clients.unlock();
133 m_new_clients.unlock();
137 data.service_name = std::string(name);
138 data.host_name = std::string(host_name);
142 m_new_clients.push_back_locked(data);
143 m_signal_get_image_list();
150 FuseImageListWidget::remove_fountain_service(
const char* name)
152 m_img_list_mutex.lock();
153 Gtk::TreeModel::Children children = m_image_list->children();
154 Gtk::TreeModel::Children::iterator iter = children.begin();
155 while ( iter != children.end() )
157 Gtk::TreeModel::Row row = *iter;
158 if ( row[m_image_record.service_name] == Glib::ustring(name) )
160 iter = m_image_list->erase(iter);
161 m_image_list->row_deleted( m_image_list->get_path(iter) );
168 m_img_list_mutex.unlock();
175 FuseImageListWidget::set_image_list_trv(Gtk::TreeView* trv)
177 m_img_list_mutex.lock();
178 m_trv_image_list = trv;
179 m_trv_image_list->set_model(m_image_list);
180 m_trv_image_list->append_column(
"asdf", m_image_record.display_text);
181 m_trv_image_list->set_headers_visible(
false);
182 m_trv_image_list->signal_event().connect( sigc::mem_fun(*
this, &FuseImageListWidget::on_image_event) );
183 m_trv_image_list->signal_cursor_changed().connect( sigc::mem_fun(*
this, &FuseImageListWidget::on_image_selected) );
184 m_img_list_mutex.unlock();
191 FuseImageListWidget::set_toggle_compression_chk(Gtk::CheckButton* chk)
193 m_chk_compression = chk;
194 m_chk_compression->signal_toggled().connect( sigc::mem_fun(*
this, &FuseImageListWidget::on_compression_toggled) );
201 FuseImageListWidget::set_auto_update_chk(Gtk::CheckButton* chk)
203 m_chk_auto_update = chk;
204 m_chk_auto_update->signal_toggled().connect( sigc::mem_fun(*
this, &FuseImageListWidget::on_auto_update_toggled) );
213 FuseImageListWidget::image_selected()
215 return m_signal_image_selected;
222 FuseImageListWidget::auto_update()
224 return m_auto_update;
232 FuseImageListWidget::set_auto_update(
bool active,
unsigned int interval_sec)
234 m_auto_update = active;
235 m_interval_sec = interval_sec;
239 #if GLIBMM_MAJOR_VERSION > 2 || ( GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION >= 14 ) 240 m_timeout_conn = Glib::signal_timeout().connect_seconds( sigc::mem_fun(*
this, &FuseImageListWidget::on_update_timeout),
243 m_timeout_conn = Glib::signal_timeout().connect(sigc::mem_fun(*
this, &FuseImageListWidget::on_update_timeout), m_interval_sec);
246 else m_timeout_conn.disconnect();
257 FuseImageListWidget::get_selected_image( std::string& host_name,
unsigned short& port,
258 std::string& image_id,
bool& compression )
260 if ( !m_trv_image_list )
263 m_img_list_mutex.lock();
264 Glib::RefPtr<Gtk::TreeSelection> selection = m_trv_image_list->get_selection();
266 if ( selection->count_selected_rows() != 1 )
268 m_img_list_mutex.unlock();
272 Gtk::TreeModel::iterator iter = selection->get_selected();
273 host_name = iter->get_value(m_image_record.host_name);
274 port = iter->get_value(m_image_record.port);
275 image_id = iter->get_value(m_image_record.image_id);
276 m_img_list_mutex.unlock();
278 if (m_chk_compression)
279 { compression = m_chk_compression->get_active(); }
281 { compression =
false; }
288 FuseImageListWidget::on_image_event(GdkEvent *event)
290 GdkEventButton btn =
event->button;
291 if (btn.type == GDK_BUTTON_PRESS && btn.button == 3) {
292 #if GTK_VERSION_LT(3,0) 293 m_popup_menu->popup(btn.button, btn.time);
301 FuseImageListWidget::on_image_selected()
303 m_img_list_mutex.lock();
304 Glib::RefPtr<Gtk::TreeSelection> selection = m_trv_image_list->get_selection();
306 Gtk::TreeModel::iterator iter = selection->get_selected();
307 Glib::ustring image_id;
308 image_id = (*iter)[m_image_record.image_id];
309 m_img_list_mutex.unlock();
311 if ((image_id != m_cur_image_id) && (image_id !=
"invalid"))
313 m_cur_image_id = image_id;
314 m_signal_image_selected();
319 FuseImageListWidget::on_auto_update_toggled()
321 set_auto_update( m_chk_auto_update->get_active() );
325 FuseImageListWidget::on_compression_toggled()
327 m_signal_image_selected();
331 FuseImageListWidget::get_image_list()
333 if (m_cur_client.active)
337 m_new_clients.lock();
338 if (m_new_clients.size() == 0)
342 #if GLIBMM_MAJOR_VERSION > 2 || ( GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION >= 14 ) 343 m_timeout_conn = Glib::signal_timeout().connect_seconds( sigc::mem_fun(*
this, &FuseImageListWidget::on_update_timeout),
346 m_timeout_conn = Glib::signal_timeout().connect(sigc::mem_fun(*
this, &FuseImageListWidget::on_update_timeout), m_interval_sec);
349 m_new_clients.unlock();
353 m_cur_client = m_new_clients.front();
354 m_cur_client.active =
true;
355 m_new_clients.pop_front();
356 m_new_clients.unlock();
360 m_cur_client.client =
new FuseClient( m_cur_client.host_name.c_str(),
361 m_cur_client.port, this );
362 m_cur_client.client->
connect();
363 m_cur_client.client->start();
364 m_cur_client.client->enqueue(FUSE_MT_GET_IMAGE_LIST);
369 m_cur_client.client->cancel();
370 m_cur_client.client->join();
371 delete m_cur_client.client;
372 m_cur_client.active =
false;
377 FuseImageListWidget::delete_clients()
381 m_delete_clients.lock();
382 while (m_delete_clients.size() != 0)
384 c = m_delete_clients.front();
385 m_delete_clients.pop();
392 m_delete_clients.unlock();
396 FuseImageListWidget::on_update_timeout()
398 m_signal_update_image_l();
399 return m_auto_update;
403 FuseImageListWidget::update_image_list()
405 m_timeout_conn.disconnect();
406 if (m_img_list_mutex.try_lock())
408 Gtk::TreeModel::Children children = m_image_list->children();
409 for ( Gtk::TreeModel::Children::iterator iter = children.begin();
410 iter != children.end(); ++iter )
412 if ( (*iter)[m_image_record.image_id] ==
"invalid" )
416 Glib::ustring service_name = (*iter)[m_image_record.service_name];
417 Glib::ustring host_name = (*iter)[m_image_record.host_name];
418 data.service_name = std::string( service_name.c_str() );
419 data.host_name = std::string( host_name.c_str() );
420 data.port = (*iter)[m_image_record.port];
423 m_new_clients.push_back_locked(data);
426 m_img_list_mutex.unlock();
429 m_signal_get_image_list();
433 FuseImageListWidget::fuse_invalid_server_version(uint32_t local_version,
434 uint32_t remote_version)
throw()
436 printf(
"Invalid versions: local: %u remote: %u\n", local_version, remote_version);
440 FuseImageListWidget::fuse_connection_established () throw()
445 FuseImageListWidget::fuse_connection_died() throw()
447 if (m_cur_client.active)
449 m_delete_clients.push_locked(m_cur_client.client);
450 m_cur_client.active =
false;
453 m_signal_delete_clients();
461 case FUSE_MT_IMAGE_LIST:
464 m_img_list_mutex.lock();
465 Gtk::TreeModel::Children children = m_image_list->children();
466 Gtk::TreeModel::Children::iterator iter = children.begin();
467 while ( iter != children.end() )
469 Gtk::TreeModel::Row row = *iter;
470 if ( row[m_image_record.service_name] == Glib::ustring(m_cur_client.service_name) )
472 iter = m_image_list->erase(iter);
485 Gtk::TreeModel::Row row = *m_image_list->append();
486 row[m_image_record.display_text] = Glib::ustring(m_cur_client.host_name);
487 row[m_image_record.service_name] = Glib::ustring(m_cur_client.service_name);
488 row[m_image_record.host_name] = Glib::ustring(m_cur_client.host_name);
489 row[m_image_record.port] = m_cur_client.port;
490 row[m_image_record.colorspace] = 0;
491 row[m_image_record.image_id] =
"invalid";
492 row[m_image_record.width] = 0;
493 row[m_image_record.height] = 0;
494 row[m_image_record.buffer_size] = 0;
496 Gtk::TreeModel::Path path = m_image_list->get_path(row);
501 char image_id[IMAGE_ID_MAX_LENGTH + 1];
502 image_id[IMAGE_ID_MAX_LENGTH] =
'\0';
503 strncpy(image_id, image_info->
image_id, IMAGE_ID_MAX_LENGTH);
505 Gtk::TreeModel::Row childrow = *m_image_list->append( row.children() );
506 childrow[m_image_record.display_text] = Glib::ustring(image_id);
507 childrow[m_image_record.service_name] = Glib::ustring(m_cur_client.service_name);
508 childrow[m_image_record.host_name] = Glib::ustring(m_cur_client.host_name);
509 childrow[m_image_record.port] = m_cur_client.port;
510 childrow[m_image_record.colorspace] = ntohl(image_info->
colorspace);
511 childrow[m_image_record.image_id] = Glib::ustring(image_id);
512 childrow[m_image_record.width] = ntohl(image_info->
width);
513 childrow[m_image_record.height] = ntohl(image_info->
height);
514 childrow[m_image_record.buffer_size] = ntohl(image_info->
buffer_size);
517 m_trv_image_list->expand_row(path,
false);
527 m_img_list_mutex.unlock();
529 m_delete_clients.push_locked(m_cur_client.client);
530 m_cur_client.active =
false;
532 m_signal_get_image_list();
533 m_signal_delete_clients();
539 printf(
"Unhandled message type\n");
544 FuseImageListWidget::on_add_host_manually()
546 Gtk::Dialog* add_host =
547 new Gtk::Dialog(
"Add host manually",
true);
548 add_host->add_button(Gtk::Stock::ADD, Gtk::RESPONSE_OK);
549 add_host->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
551 Gtk::Table* tab = Gtk::manage(
new Gtk::Table(2, 2,
false) );
552 Gtk::Label* hlab = Gtk::manage(
new Gtk::Label(
"Host:") );
553 Gtk::Label* plab = Gtk::manage(
new Gtk::Label(
"Port:") );
554 Gtk::Entry* hent = Gtk::manage(
new Gtk::Entry() );
555 Gtk::HBox* pbox = Gtk::manage(
new Gtk::HBox() );
557 #if GTK_VERSION_GE(3,0) 558 Glib::RefPtr<Gtk::Adjustment> prange = Gtk::Adjustment::create(2208, 1, 65535);
560 Gtk::Adjustment prange(2208, 1, 65535);
562 Gtk::SpinButton *pent = Gtk::manage(
new Gtk::SpinButton(prange) );
564 char * fawkes_ip = getenv(
"FAWKES_IP");
565 if (fawkes_ip) hent->set_text(std::string(fawkes_ip).append(
":2208"));
566 else hent->set_text(
"localhost:2208");
568 pbox->pack_start(*pent,
false,
false, 0);
569 tab->attach(*hlab, 1, 2, 1, 2);
570 tab->attach(*plab, 1, 2, 2, 3);
571 tab->attach(*hent, 2, 3, 1, 2);
572 tab->attach(*pbox, 2, 3, 2, 3);
574 add_host->get_vbox()->pack_start(*tab,
false,
true, 0);
575 add_host->get_vbox()->show_all_children(
true);
577 if (add_host->run() == Gtk::RESPONSE_OK) {
578 std::string name =
"fountain on ";
579 std::string host = hent->get_text();
580 unsigned short port = 2208;
582 Glib::ustring::size_type pos;
583 if ((pos = host.find(
':')) != Glib::ustring::npos)
585 Glib::ustring tmp_host =
"";
586 unsigned int tmp_port = 1234567;
587 std::istringstream is(host.replace(pos, 1,
" "));
591 if (tmp_port != 1234567 && tmp_host.size())
599 add_fountain_service(name.c_str(), host.c_str(), port);
void disconnect()
Disconnect.
Fawkes library namespace.
uint32_t width
width in pixels
uint32_t colorspace
color space
char image_id[IMAGE_ID_MAX_LENGTH]
image ID
Base class for exceptions in Fawkes.
bool has_next()
Check if another image info is available.
void cancel()
Cancel a thread.
void print_trace()
Prints trace to stderr.
uint32_t height
height in pixels
void join()
Join the thread.
uint32_t buffer_size
size of following image buffer in bytes
FUSE_imageinfo_t * next()
Get next image info.