00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <tools/firestation/fuse_transfer_widget.h>
00024 #include <tools/firestation/colormap_viewer_widget.h>
00025
00026 #include <fvutils/net/fuse_client.h>
00027 #include <fvutils/net/fuse_message.h>
00028 #include <fvutils/net/fuse_lut_content.h>
00029 #include <fvutils/net/fuse_lutlist_content.h>
00030
00031 #include <models/color/lookuptable.h>
00032
00033 #include <netinet/in.h>
00034 #include <cstring>
00035
00036 using namespace fawkes;
00037 using namespace firevision;
00038
00039
00040
00041
00042
00043
00044
00045
00046 FuseTransferWidget::FuseTransferWidget()
00047 {
00048 m_local_colormap_viewer = new ColormapViewerWidget();
00049 m_remote_colormap_viewer = new ColormapViewerWidget();
00050
00051 m_local_lut_list = Gtk::ListStore::create(m_lut_record);
00052 m_remote_lut_list = Gtk::ListStore::create(m_lut_record);
00053
00054 m_signal_update_local_lut_list.connect( sigc::mem_fun( *this, &FuseTransferWidget::update_local_lut_list) );
00055 m_signal_update_remote_lut_list.connect( sigc::mem_fun( *this, &FuseTransferWidget::update_remote_lut_list) );
00056 m_signal_get_lut_list.connect( sigc::mem_fun( *this, &FuseTransferWidget::get_lut_list) );
00057 m_signal_delete_client.connect( sigc::mem_fun( *this, &FuseTransferWidget::delete_clients) );
00058 m_signal_update_remote_lut.connect( sigc::mem_fun( *this, &FuseTransferWidget::update_remote_lut) );
00059
00060 m_new_clients.clear();
00061 m_delete_clients.clear();
00062
00063 m_cur_client.active = false;
00064
00065 m_btn_upload = 0;
00066 m_btn_download = 0;
00067 m_img_local = 0;
00068 m_img_remote = 0;
00069 m_trv_local_lut_list = 0;
00070 m_trv_remote_lut_list = 0;
00071 }
00072
00073
00074 FuseTransferWidget::~FuseTransferWidget()
00075 {
00076 delete m_local_colormap_viewer;
00077 delete m_remote_colormap_viewer;
00078
00079 FuseClient* c;
00080 m_new_clients.lock();
00081 while (m_new_clients.size() != 0)
00082 {
00083 c = m_new_clients.front().client;
00084 m_new_clients.pop();
00085 c->disconnect();
00086 c->cancel();
00087 c->join();
00088 delete c;
00089 }
00090 m_new_clients.unlock();
00091
00092 if (m_cur_client.active)
00093 {
00094 m_cur_client.active = false;
00095 m_delete_clients.push_locked(m_cur_client.client);
00096 delete_clients();
00097 }
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 void
00107 FuseTransferWidget::add_fountain_service( const char* name,
00108 const char* host_name,
00109 uint16_t port )
00110 {
00111 ClientData data;
00112 data.client = 0;
00113 data.service_name = std::string(name);
00114 data.host_name = std::string(host_name);
00115 data.port = port;
00116 data.active = false;
00117
00118 m_new_clients.push_locked(data);
00119 m_signal_get_lut_list();
00120 }
00121
00122
00123
00124
00125
00126 void
00127 FuseTransferWidget::remove_fountain_service(const char* name)
00128 {
00129 Gtk::TreeModel::Children children = m_remote_lut_list->children();
00130 Gtk::TreeModel::Children::iterator iter = children.begin();
00131 while( iter != children.end() )
00132 {
00133 Gtk::TreeModel::Row row = *iter;
00134 if (row[m_lut_record.service_name] == Glib::ustring(name))
00135 {
00136 iter = m_local_lut_list->erase(iter);
00137 m_local_lut_list->row_deleted( m_local_lut_list->get_path(iter) );
00138 }
00139 else
00140 {
00141 ++iter;
00142 }
00143 }
00144 }
00145
00146
00147
00148
00149
00150 void
00151 FuseTransferWidget::set_current_colormap(YuvColormap* colormap)
00152 {
00153 m_current_colormap = colormap;
00154
00155
00156 Gtk::TreeModel::Children children = m_local_lut_list->children();
00157 Gtk::TreeModel::Children::iterator iter = children.begin();
00158 while ( iter != children.end() )
00159 {
00160 Gtk::TreeModel::Row row = *iter;
00161 if (row[m_lut_record.filename] == "Current")
00162 {
00163 iter = m_local_lut_list->erase(iter);
00164 m_local_lut_list->row_deleted( m_local_lut_list->get_path(iter) );
00165 }
00166 else
00167 {
00168 ++iter;
00169 }
00170 }
00171
00172 Gtk::TreeModel::Row row = *m_local_lut_list->prepend();
00173 row[m_lut_record.filename] = "Current";
00174 row[m_lut_record.width] = colormap->width();
00175 row[m_lut_record.height] = colormap->height();
00176 row[m_lut_record.depth] = colormap->depth();
00177 }
00178
00179 void
00180 FuseTransferWidget::update_local_lut_list()
00181 {
00182 if (m_trv_local_lut_list)
00183 { m_trv_local_lut_list->queue_draw(); }
00184 }
00185
00186 void
00187 FuseTransferWidget::update_remote_lut_list()
00188 {
00189 if (m_trv_remote_lut_list)
00190 { m_trv_remote_lut_list->queue_draw(); }
00191 }
00192
00193
00194
00195
00196 void
00197 FuseTransferWidget::set_upload_btn(Gtk::Button* btn)
00198 {
00199 m_btn_upload = btn;
00200 m_btn_upload->signal_clicked().connect( sigc::mem_fun( *this, &FuseTransferWidget::upload_lut) );
00201 }
00202
00203
00204
00205
00206 void
00207 FuseTransferWidget::set_download_btn(Gtk::Button* btn)
00208 {
00209 m_btn_download = btn;
00210 }
00211
00212
00213
00214
00215 void
00216 FuseTransferWidget::set_local_img(Gtk::Image* img)
00217 {
00218 m_img_local = img;
00219 m_local_colormap_viewer->set_colormap_img(m_img_local);
00220 }
00221
00222
00223
00224
00225 void
00226 FuseTransferWidget::set_local_layer_selector(Gtk::Scale* scl)
00227 {
00228 m_local_colormap_viewer->set_layer_selector(scl);
00229 }
00230
00231
00232
00233
00234 void
00235 FuseTransferWidget::set_remote_img(Gtk::Image* img)
00236 {
00237 m_img_remote = img;
00238 m_remote_colormap_viewer->set_colormap_img(m_img_remote);
00239 }
00240
00241
00242
00243
00244 void
00245 FuseTransferWidget::set_remote_layer_selector(Gtk::Scale* scl)
00246 {
00247 m_remote_colormap_viewer->set_layer_selector(scl);
00248 }
00249
00250
00251
00252
00253 void
00254 FuseTransferWidget::set_local_lut_list_trv(Gtk::TreeView* trv)
00255 {
00256 m_trv_local_lut_list = trv;
00257 m_trv_local_lut_list->set_model(m_local_lut_list);
00258 m_trv_local_lut_list->append_column("Filename", m_lut_record.filename);
00259 m_trv_local_lut_list->append_column("Width", m_lut_record.width);
00260 m_trv_local_lut_list->append_column("Height", m_lut_record.height);
00261 m_trv_local_lut_list->append_column("Depth", m_lut_record.depth);
00262
00263
00264 m_trv_local_lut_list->signal_cursor_changed().connect( sigc::mem_fun( *this, &FuseTransferWidget::local_lut_selected) );
00265 }
00266
00267
00268
00269
00270 void
00271 FuseTransferWidget::set_remote_lut_list_trv(Gtk::TreeView* trv)
00272 {
00273 m_trv_remote_lut_list = trv;
00274 m_trv_remote_lut_list->set_model(m_remote_lut_list);
00275 m_trv_remote_lut_list->append_column("Host", m_lut_record.host_name);
00276
00277 m_trv_remote_lut_list->append_column("ID", m_lut_record.lut_id);
00278 m_trv_remote_lut_list->append_column("Width", m_lut_record.width);
00279 m_trv_remote_lut_list->append_column("Height", m_lut_record.height);
00280 m_trv_remote_lut_list->append_column("Depth", m_lut_record.depth);
00281 m_trv_remote_lut_list->append_column("BPC", m_lut_record.bytes_per_cell);
00282
00283 m_trv_remote_lut_list->signal_cursor_changed().connect( sigc::mem_fun( *this, &FuseTransferWidget::remote_lut_selected) );
00284 }
00285
00286 void
00287 FuseTransferWidget::get_lut_list()
00288 {
00289 if (m_cur_client.active)
00290
00291 { return; }
00292
00293 m_new_clients.lock();
00294 if (m_new_clients.size() == 0)
00295 {
00296 m_new_clients.unlock();
00297 return;
00298 }
00299
00300 m_cur_client = m_new_clients.front();
00301 m_cur_client.active = true;
00302 m_new_clients.pop();
00303 m_new_clients.unlock();
00304
00305 try
00306 {
00307 m_cur_client.client = new FuseClient( m_cur_client.host_name.c_str(),
00308 m_cur_client.port, this );
00309 m_cur_client.client->connect();
00310 m_cur_client.client->start();
00311 m_cur_client.client->enqueue(FUSE_MT_GET_LUT_LIST);
00312 }
00313 catch (Exception& e)
00314 {
00315 e.print_trace();
00316 m_cur_client.client->cancel();
00317 m_cur_client.client->join();
00318 delete m_cur_client.client;
00319 m_cur_client.active = false;
00320 }
00321 }
00322
00323 void
00324 FuseTransferWidget::delete_clients()
00325 {
00326 FuseClient* c;
00327
00328 m_delete_clients.lock();
00329 while (m_delete_clients.size() != 0)
00330 {
00331 c = m_delete_clients.front();
00332 m_delete_clients.pop();
00333
00334 c->disconnect();
00335 c->cancel();
00336 c->join();
00337 delete c;
00338 }
00339 m_delete_clients.unlock();
00340 }
00341
00342 void
00343 FuseTransferWidget::update_local_lut()
00344 {
00345 if ( !m_img_local )
00346 { return; }
00347
00348 m_local_colormap_viewer->draw();
00349 }
00350
00351 void
00352 FuseTransferWidget::update_remote_lut()
00353 {
00354 if ( !m_img_remote )
00355 { return; }
00356
00357 m_remote_colormap_viewer->draw();
00358 }
00359
00360 void
00361 FuseTransferWidget::upload_lut()
00362 {
00363 if ( !m_local_colormap )
00364 { return; }
00365
00366
00367 Glib::RefPtr<Gtk::TreeSelection> selection = m_trv_remote_lut_list->get_selection();
00368
00369 if ( 1 != selection->count_selected_rows() )
00370 {
00371 printf("No remote lut selected\n");
00372 return;
00373 }
00374
00375 Gtk::TreeModel::iterator i = selection->get_selected();
00376 Glib::ustring hostname = (*i)[m_lut_record.host_name];
00377 unsigned int port = (*i)[m_lut_record.port];
00378 Glib::ustring lut_id = (*i)[m_lut_record.lut_id];
00379
00380 printf("sending lut to %s:%d id %s\n", hostname.c_str(), port, lut_id.c_str());
00381
00382 FuseLutContent* lut_content = new FuseLutContent( lut_id.c_str(),
00383 m_local_colormap->get_buffer(),
00384 m_local_colormap->width(),
00385 m_local_colormap->height(),
00386 m_local_colormap->depth(),
00387 1 );
00388
00389
00390 FuseClient* client = new FuseClient(hostname.c_str(), port, this);
00391
00392 try
00393 {
00394 client->connect();
00395 client->start();
00396
00397
00398 client->enqueue( new FuseNetworkMessage(FUSE_MT_SET_LUT, lut_content) );
00399
00400
00401 m_delete_clients.push_locked(client);
00402 }
00403 catch (Exception& e)
00404 {
00405 e.print_trace();
00406 client->cancel();
00407 client->join();
00408 delete client;
00409 }
00410 }
00411
00412 void
00413 FuseTransferWidget::local_lut_selected()
00414 {
00415 Glib::RefPtr<Gtk::TreeSelection> selection = m_trv_local_lut_list->get_selection();
00416 if (selection->count_selected_rows() != 1)
00417 { return; }
00418
00419 Gtk::TreeModel::iterator it = selection->get_selected();
00420 Glib::ustring filename = (*it)[m_lut_record.filename];
00421
00422 if (filename == "Current")
00423 {
00424 m_local_colormap = m_current_colormap;
00425 }
00426 else
00427 {
00428
00429 }
00430
00431 m_local_colormap_viewer->set_colormap(m_local_colormap);
00432 update_local_lut();
00433 }
00434
00435 void
00436 FuseTransferWidget::remote_lut_selected()
00437 {
00438 Glib::RefPtr<Gtk::TreeSelection> selection = m_trv_remote_lut_list->get_selection();
00439 if (selection->count_selected_rows() != 1)
00440 { return; }
00441
00442 Gtk::TreeModel::iterator it = selection->get_selected();
00443 Glib::ustring host_name = (*it)[m_lut_record.host_name];
00444 unsigned int port = (*it)[m_lut_record.port];
00445 Glib::ustring lut_id = (*it)[m_lut_record.lut_id];
00446
00447 FuseClient* c = new FuseClient(host_name.c_str(), port, this);
00448 try
00449 {
00450 c->connect();
00451 c->start();
00452
00453 FUSE_lutdesc_message_t* lut_desc = (FUSE_lutdesc_message_t*) malloc( sizeof(FUSE_lutdesc_message_t));
00454 memset(lut_desc, 0, sizeof(FUSE_lutdesc_message_t));
00455 strncpy(lut_desc->lut_id, lut_id.c_str(), LUT_ID_MAX_LENGTH);
00456 c->enqueue(FUSE_MT_GET_LUT, lut_desc, sizeof(FUSE_lutdesc_message_t));
00457
00458 m_delete_clients.push_locked(c);
00459 }
00460 catch (Exception& e)
00461 {
00462 e.print_trace();
00463 c->cancel();
00464 c->join();
00465 delete c;
00466 }
00467 }
00468
00469 void
00470 FuseTransferWidget::fuse_invalid_server_version(uint32_t local_version,
00471 uint32_t remote_version) throw()
00472 {
00473 printf("Invalid versions: local: %u remote: %u\n", local_version, remote_version);
00474 }
00475
00476 void
00477 FuseTransferWidget::fuse_connection_established () throw()
00478 {
00479 }
00480
00481 void
00482 FuseTransferWidget::fuse_connection_died() throw()
00483 {
00484 if (m_cur_client.active)
00485 {
00486 m_delete_clients.push_locked(m_cur_client.client);
00487 m_cur_client.active = false;
00488 }
00489
00490 m_signal_delete_client();
00491 }
00492
00493 void
00494 FuseTransferWidget::fuse_inbound_received (FuseNetworkMessage *m) throw()
00495 {
00496 switch ( m->type() )
00497 {
00498 case FUSE_MT_LUT_LIST:
00499 try
00500 {
00501 FuseLutListContent* content = m->msgc<FuseLutListContent>();
00502 if ( content->has_next() )
00503 {
00504 while ( content->has_next() )
00505 {
00506
00507 FUSE_lutinfo_t* lut_info = content->next();
00508 char lut_id[LUT_ID_MAX_LENGTH + 1];
00509 lut_id[LUT_ID_MAX_LENGTH] = '\0';
00510 strncpy(lut_id, lut_info->lut_id, LUT_ID_MAX_LENGTH);
00511
00512 Gtk::TreeModel::Children children = m_remote_lut_list->children();
00513 Gtk::TreeModel::Children::iterator iter = children.begin();
00514 while ( iter != children.end() )
00515 {
00516 Gtk::TreeModel::Row row = *iter;
00517 if ( row[m_lut_record.lut_id] == Glib::ustring(lut_id) )
00518 { iter = m_remote_lut_list->erase(iter); }
00519 else
00520 { ++iter; }
00521 }
00522
00523 Gtk::TreeModel::Row row = *m_remote_lut_list->append();
00524 row[m_lut_record.service_name] = Glib::ustring(m_cur_client.service_name);
00525 row[m_lut_record.host_name] = Glib::ustring(m_cur_client.host_name);
00526 row[m_lut_record.port] = m_cur_client.port;
00527 row[m_lut_record.lut_id] = Glib::ustring(lut_id);
00528 row[m_lut_record.width] = ntohl(lut_info->width);
00529 row[m_lut_record.height] = ntohl(lut_info->height);
00530 row[m_lut_record.depth] = ntohl(lut_info->depth);
00531 row[m_lut_record.bytes_per_cell] = ntohl(lut_info->bytes_per_cell);
00532 }
00533 }
00534 delete content;
00535 }
00536 catch (Exception& e)
00537 {
00538 e.print_trace();
00539 }
00540
00541 m_delete_clients.push_locked(m_cur_client.client);
00542 m_cur_client.active = false;
00543
00544 m_signal_update_remote_lut_list();
00545 m_signal_get_lut_list();
00546 m_signal_delete_client();
00547
00548 break;
00549
00550 case FUSE_MT_LUT:
00551 try
00552 {
00553 FuseLutContent* lut_content = m->msgc<FuseLutContent>();
00554
00555 if (m_remote_colormap)
00556 { delete m_remote_colormap; }
00557
00558 if ( lut_content->width() != 256 ||
00559 lut_content->height() != 256 )
00560 {
00561 m_signal_delete_client();
00562 break;
00563 }
00564
00565 m_remote_colormap = new YuvColormap( lut_content->depth() );
00566 m_remote_colormap->set( lut_content->buffer() );
00567
00568 delete lut_content;
00569 }
00570 catch (Exception& e)
00571 {
00572 e.print_trace();
00573 }
00574 m_remote_colormap_viewer->set_colormap(m_remote_colormap);
00575 m_signal_update_remote_lut();
00576 m_signal_delete_client();
00577
00578 break;
00579
00580 case FUSE_MT_SET_LUT_FAILED:
00581 printf("LUT upload failed\n");
00582
00583 case FUSE_MT_SET_LUT_SUCCEEDED:
00584 printf("LUT upload succeeded\n");
00585 m_signal_delete_client();
00586 break;
00587
00588 default:
00589 printf("Unhandled message type\n");
00590 }
00591 }