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