2 Copyright (C) 2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
26 #include <arpa/inet.h>
29 #include <sigc++/bind.h>
31 #include <gtkmm2ext/gtk_ui.h>
33 #include "imageframe_socket_handler.h"
34 #include "imageframe_time_axis.h"
35 #include "imageframe_time_axis_view.h"
36 #include "imageframe_time_axis_group.h"
37 #include "imageframe_view.h"
38 #include "marker_time_axis.h"
39 #include "marker_time_axis_view.h"
40 #include "ardour_ui.h"
41 #include "public_editor.h"
42 #include "gui_thread.h"
46 #include <ardour/session.h>
47 #include <ardour/session_utils.h>
52 using namespace ardourvis ;
54 using namespace ARDOUR;
57 ImageFrameSocketHandler* ImageFrameSocketHandler::_instance = 0 ;
60 * Constructs a new ImageFrameSocketHandler to handle communication between Ardour and the Image Compositor
62 * @param ed the PublicEditor
64 ImageFrameSocketHandler::ImageFrameSocketHandler(PublicEditor& ed) : thePublicEditor(ed), theArdourToCompositorSocket(-1)
71 * this will shutdown the socket if open
73 ImageFrameSocketHandler::~ImageFrameSocketHandler()
80 * Returns the instance of the ImageFrameSocketHandler
81 * the instance should first be created with createInstance
83 * @return the instance of the ImageFrameSocketHandler
85 ImageFrameSocketHandler*
86 ImageFrameSocketHandler::get_instance()
92 * Create an new instance of the ImageFrameSocketHandler, if one does not already exist
94 * @param ed the Ardour PublicEditor
96 ImageFrameSocketHandler*
97 ImageFrameSocketHandler::create_instance(PublicEditor& ed)
105 _instance = new ImageFrameSocketHandler(ed) ;
111 * call back to handle doing the processing work
112 * This method is added to the gdk main loop and called when there is data
117 ImageFrameSocketHandler::image_socket_callback(void *arg, int32_t fd, GdkInputCondition cond)
119 char buf[ardourvis::MAX_MSG_SIZE + 1] ;
120 memset(buf, 0, (ardourvis::MAX_MSG_SIZE + 1)) ;
121 buf[ardourvis::MAX_MSG_SIZE] = '\0' ;
123 int retcode = ::recv(fd, buf, MAX_MSG_SIZE, 0) ;
126 //end-of-file, other end closed or shutdown?
127 ARDOUR_UI::instance()->popup_error(_("Image Compositor Socket has been shutdown/closed"));
129 // assume socket has been shutdown, tell, someone interested,
130 // and remove the socket from the event loop
131 ImageFrameSocketHandler* ifsh = ImageFrameSocketHandler::get_instance() ;
132 gdk_input_remove(ifsh->theGdkInputTag) ;
133 ifsh->close_connection() ;
134 ifsh->CompositorSocketShutdown() ; /* EMIT_SIGNAL */
138 //std::cout << "Received Msg [" << buf << "]\n" ;
139 ImageFrameSocketHandler* ifsh = ImageFrameSocketHandler::get_instance() ;
141 std::string mType = ifsh->get_message_part(0,2,buf) ;
143 if(mType == ardourvis::INSERT_ITEM)
145 ifsh->handle_insert_message(buf) ;
147 else if (mType == ardourvis::REMOVE_ITEM)
149 ifsh->handle_remove_message(buf) ;
151 else if (mType == ardourvis::RENAME_ITEM)
153 ifsh->handle_rename_message(buf) ;
155 else if (mType == ardourvis::ITEM_UPDATE)
157 ifsh->handle_item_update_message(buf) ;
159 else if (mType == ardourvis::REQUEST_DATA)
161 ifsh->handle_request_data(buf) ;
163 else if (mType == ardourvis::ITEM_SELECTED)
165 ifsh->handle_item_selected(buf) ;
167 else if(mType == ardourvis::SESSION_ACTION)
169 ifsh->handle_session_action(buf) ;
173 std::string errMsg = "Unknown Message type : " ;
174 errMsg.append(mType) ;
175 ifsh->send_return_failure(errMsg) ;
181 * Attempt to connect to the image compositor on the specified host and port
183 * @param hostIp the ip address of the image compositor host
184 * @param port the oprt number to attemp the connection on
185 * @return true if the connection was a succees
189 ImageFrameSocketHandler::connect(const char * hostIp, int32_t port)
193 //already connected...
197 theArdourToCompositorSocket = socket(AF_INET, SOCK_STREAM, 0) ;
198 if(theArdourToCompositorSocket == -1)
204 setsockopt(theArdourToCompositorSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) ;
207 m_addr.sin_family = AF_INET ;
208 m_addr.sin_port = htons(port) ;
209 m_addr.sin_addr.s_addr = inet_addr(hostIp) ;
211 int status = ::connect(theArdourToCompositorSocket, (sockaddr *) &m_addr, sizeof(m_addr)) ;
215 theArdourToCompositorSocket = -1 ;
223 * Closes the connection to th Image Compositor
227 ImageFrameSocketHandler::close_connection()
231 ::close(theArdourToCompositorSocket) ;
232 theArdourToCompositorSocket = -1 ;
237 * Returns true if this ImagFrameSocketHandler is currently connected to rthe image compositor
239 * @return true if connected to the image compositor
242 ImageFrameSocketHandler::is_connected()
244 return(theArdourToCompositorSocket == -1 ? false : true) ;
248 * Sets the tag used to describe this input within gtk
249 * this is returned when gdk_input_add is called and is required to remove the input
251 * @param tag the gdk input tag of this input
254 ImageFrameSocketHandler::set_gdk_input_tag(int tag)
256 theGdkInputTag = tag ;
260 * Returns the gdk input tag of this input
262 * @return the gdk input tag of this input
263 * @see setGdkInputTag
266 ImageFrameSocketHandler::get_gdk_input_tag()
268 return(theGdkInputTag) ;
272 * Returns the socket file descriptor
274 * @return the Sockt file descriptor
277 ImageFrameSocketHandler::get_socket_descriptor()
279 return(theArdourToCompositorSocket) ;
285 //---------------------------------------------------------------------------------------//
286 // Handle Sending messages to the Image Compositor
288 //----------------------------
289 // ImageFrameTimeAxis Messages
292 * Sends a message stating that the named image frame time axis has been removed
294 * @param track_id the unique id of the removed image frame time axis
295 * @param src the identity of the object that initiated the change
298 ImageFrameSocketHandler::send_imageframe_time_axis_removed(const string & track_id, void* src)
300 if(this == src || src == 0)
302 // ie the change originated from us, then dont send any message back
306 // create a message buffer
307 std::ostringstream msgBuffer ;
308 msgBuffer << std::setfill('0') ;
311 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_TIME_AXIS ;
313 // add the id length, and the id
314 msgBuffer << std::setw(3) << track_id.length() ;
315 msgBuffer << track_id ;
317 send_message(msgBuffer.str()) ;
319 // XXX should do something with the return
321 read_message(retmsg) ;
325 * Sends a message indicating that an ImageFrameTimeAxis has been renamed
327 * @param new_id the new name, or Id, of the track
328 * @param old_id the old name, or Id, of the track
329 * @param src the identity of the object that initiated the change
330 * @param time_axis the time axis that has changed
333 ImageFrameSocketHandler::send_imageframe_time_axis_renamed(const string & new_id, const string & old_id, void* src, ImageFrameTimeAxis* time_axis)
335 // ENSURE_GUI_THREAD(SigC::bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_renamed), new_id, old_id, src, time_axis));
337 if(this == src || src == 0)
339 // ie the change originated from us, then dont send any message back
343 // create a message buffer
344 std::ostringstream msgBuffer ;
345 msgBuffer << std::setfill('0') ;
348 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_TIME_AXIS ;
350 // add the old id and length
351 msgBuffer << std::setw(3) << old_id.length() ;
352 msgBuffer << old_id ;
354 // add the new id and length
355 msgBuffer << std::setw(3) << new_id.length() ;
356 msgBuffer << new_id ;
358 send_message(msgBuffer.str()) ;
360 // XXX should do something with the return
362 read_message(retmsg) ;
365 //------------------------
366 // MarkerTimeAxis Messages
369 * Sends a message stating that the named marker time axis has been removed
371 * @param track_id the unique id of the removed image frame time axis
372 * @param src the identity of the object that initiated the change
375 ImageFrameSocketHandler::send_marker_time_axis_removed(const string & track_id, void* src)
377 if(this == src || src == 0)
379 // ie the change originated from us, then dont send any message back
383 // create a message buffer
384 std::ostringstream msgBuffer ;
385 msgBuffer << std::setfill('0') ;
388 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_TIME_AXIS ;
390 // add the id length, and the id
391 msgBuffer << std::setw(3) << track_id.length() ;
392 msgBuffer << track_id ;
394 send_message(msgBuffer.str()) ;
396 // XXX should do something with the return
398 read_message(retmsg) ;
402 * Sends a message indicating that an MarkerTimeAxis has been renamed
404 * @param new_id the new name, or Id, of the track
405 * @param old_id the old name, or Id, of the track
406 * @param src the identity of the object that initiated the change
407 * @param time_axis the time axis that has changed
410 ImageFrameSocketHandler::send_marker_time_axis_renamed(const string & new_id, const string & old_id, void* src, MarkerTimeAxis* time_axis)
412 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed), new_id, old_id, src, time_axis));
414 if(this == src || src == 0)
416 // ie the change originated from us, then dont send any message back
420 // ctreate a message buffer
421 std::ostringstream msgBuffer ;
422 msgBuffer << std::setfill('0') ;
425 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_TIME_AXIS ;
427 // add the old id and length
428 msgBuffer << std::setw(3) << old_id.length() ;
429 msgBuffer << old_id ;
431 // add the new id and length
432 msgBuffer << std::setw(3) << new_id.length() ;
433 msgBuffer << new_id ;
435 send_message(msgBuffer.str()) ;
437 // XXX should do something with the return
439 read_message(retmsg) ;
442 //---------------------------------
443 // ImageFrameTimeAxisGroup Messages
446 * Sends a message stating that the group has been removed
448 * @param group_id the unique id of the removed image frame time axis
449 * @param src the identity of the object that initiated the change
450 * @param group the group that has changed
453 ImageFrameSocketHandler::send_imageframe_time_axis_group_removed(const string & group_id, void* src, ImageFrameTimeAxisGroup* group)
455 if(this == src || src == 0)
457 // ie the change originated from us, then dont send any message back
461 // create a message buffer
462 std::ostringstream msgBuffer ;
463 msgBuffer << std::setfill('0') ;
466 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_GROUP ;
468 // add the id length, and the id of the parent image time axis
469 std::string track_id = group->get_view().trackview().name() ;
470 msgBuffer << std::setw(3) << track_id.length() ;
471 msgBuffer << track_id ;
473 // add the group id and length
474 msgBuffer << std::setw(3) << group_id.length() ;
475 msgBuffer << group_id ;
477 send_message(msgBuffer.str()) ;
479 // XXX should do something with the return
481 read_message(retmsg) ;
485 * Send a message indicating that an ImageFrameTimeAxisGroup has been renamed
487 * @param new_id the new name, or Id, of the group
488 * @param old_id the old name, or Id, of the group
489 * @param src the identity of the object that initiated the change
490 * @param group the group that has changed
493 ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed(const string & new_id, const string & old_id, void* src, ImageFrameTimeAxisGroup* group)
495 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed), new_id, old_id, src, group));
497 if(this == src || src == 0)
499 // ie the change originated from us, then dont send any message back
503 // ctreate a message buffer
504 std::ostringstream msgBuffer ;
505 msgBuffer << std::setfill('0') ;
508 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_GROUP ;
510 // add the track this group is upon
511 std::string track_id = group->get_view().trackview().name() ;
512 msgBuffer << std::setw(3) << track_id.length() << track_id ;
514 // add the old id and length
515 msgBuffer << std::setw(3) << old_id.length() ;
516 msgBuffer << old_id ;
518 // add the new id and length
519 msgBuffer << std::setw(3) << new_id.length() ;
520 msgBuffer << new_id ;
522 send_message(msgBuffer.str()) ;
524 // XXX should do something with the return
526 read_message(retmsg) ;
530 //---------------------------------
531 // ImageFrameView Messages
534 * Send an Image Frame View Item position changed message
536 * @param pos the new position value
537 * @param src the identity of the object that initiated the change
538 * @param item the time axis item whos position has changed
541 ImageFrameSocketHandler::send_imageframe_view_position_change(nframes_t pos, void* src, ImageFrameView* item)
543 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_position_change), pos, src, item));
545 if(this == src || src == 0)
550 // create a message buffer
551 std::ostringstream msgBuffer ;
552 msgBuffer << std::setfill('0') ;
555 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::POSITION_CHANGE ;
557 // add the item description
558 this->compose_imageframe_item_desc(item, msgBuffer) ;
560 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
562 send_message(msgBuffer.str()) ;
564 // XXX should do something with the return
566 read_message(retmsg) ;
570 * Send a Image Frame View item duration changed message
572 * @param dur the the new duration value
573 * @param src the identity of the object that initiated the change
574 * @param item the item which has had a duration change
577 ImageFrameSocketHandler::send_imageframe_view_duration_change(nframes_t dur, void* src, ImageFrameView* item)
579 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change), dur, src, item));
581 if(this == src || src == 0)
586 // create a message buffer
587 std::ostringstream msgBuffer ;
588 msgBuffer << std::setfill('0') ;
591 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::DURATION_CHANGE ;
593 this->compose_imageframe_item_desc(item, msgBuffer) ;
595 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
597 send_message(msgBuffer.str()) ;
599 // XXX should do something with the return
601 read_message(retmsg) ;
605 * Send a message indicating that an ImageFrameView has been renamed
607 * @param item the ImageFrameView which has been renamed
608 * @param src the identity of the object that initiated the change
609 * @param item the renamed item
612 ImageFrameSocketHandler::send_imageframe_view_renamed(const string & new_id, const string & old_id, void* src, ImageFrameView* item)
614 if(this == src || src == 0)
616 // ie the change originated from us, then dont send any message back
620 // ctreate a message buffer
621 std::ostringstream msgBuffer ;
622 msgBuffer << std::setfill('0') ;
625 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_ITEM ;
627 this->compose_imageframe_item_desc(item, msgBuffer) ;
629 // add the old id and length
630 msgBuffer << std::setw(3) << old_id.length() ;
631 msgBuffer << old_id ;
633 send_message(msgBuffer.str()) ;
635 // XXX should do something with the return
637 read_message(retmsg) ;
641 * Send a message indicating that an ImageFrameView item has been removed message
643 * @param item_id the id of the item that was removed
644 * @param item the removed item
647 ImageFrameSocketHandler::send_imageframe_view_removed(const string & item_id, void* src, ImageFrameView* item)
649 if(this == src || src == 0)
651 // ie the change originated from us, then dont send any message back
655 // create a message buffer
656 std::ostringstream msgBuffer ;
657 msgBuffer << std::setfill('0') ;
660 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_ITEM ;
662 // add the id length, and the id
663 ImageFrameTimeAxisGroup* parentGroup = item->get_time_axis_group() ;
664 std::string group_id = parentGroup->get_group_name() ;
665 std::string track_id = parentGroup->get_view().trackview().name() ;
666 msgBuffer << std::setw(3) << track_id.length() << track_id ;
667 msgBuffer << std::setw(3) << group_id.length() << group_id ;
668 msgBuffer << std::setw(3) << item_id.length() << item_id ;
670 send_message(msgBuffer.str()) ;
672 // XXX should do something with the return
674 read_message(retmsg) ;
680 //---------------------------------
681 // MarkerView Messages
684 * Send a Marker View Item position changed message
686 * @param pos the new position value
687 * @param src the identity of the object that initiated the change
688 * @param item the time axis item whos position has changed
691 ImageFrameSocketHandler::send_marker_view_position_change(nframes_t pos, void* src, MarkerView* item)
693 if(this == src || src == 0)
698 // create a message buffer
699 std::ostringstream msgBuffer ;
700 msgBuffer << std::setfill('0') ;
703 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::POSITION_CHANGE ;
705 // add the item description
706 this->compose_marker_item_desc(item, msgBuffer) ;
708 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
710 send_message(msgBuffer.str()) ;
712 // XXX should do something with the return
714 read_message(retmsg) ;
718 * Send a Marker View item duration changed message
720 * @param dur the new duration value
721 * @param src the identity of the object that initiated the change
722 * @param item the time axis item whos position has changed
725 ImageFrameSocketHandler::send_marker_view_duration_change(nframes_t dur, void* src, MarkerView* item)
727 if(this == src || src == 0)
732 // create a message buffer
733 std::ostringstream msgBuffer ;
734 msgBuffer << std::setfill('0') ;
737 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::DURATION_CHANGE ;
739 this->compose_marker_item_desc(item, msgBuffer) ;
741 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
743 send_message(msgBuffer.str()) ;
745 // XXX should do something with the return
747 read_message(retmsg) ;
752 * Send a message indicating that a MarkerView has been renamed
754 * @param new_id the new_id of the object
755 * @param old_id the old_id of the object
756 * @param src the identity of the object that initiated the change
757 * @param item the MarkerView which has been renamed
760 ImageFrameSocketHandler::send_marker_view_renamed(const string & new_id, const string & old_id, void* src, MarkerView* item)
762 if(this == src || src == 0)
764 // ie the change originated from us, then dont send any message back
768 // ctreate a message buffer
769 std::ostringstream msgBuffer ;
770 msgBuffer << std::setfill('0') ;
773 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_ITEM ;
775 this->compose_marker_item_desc(item, msgBuffer) ;
777 // add the old id and length
778 msgBuffer << std::setw(3) << old_id.length() ;
779 msgBuffer << old_id ;
781 send_message(msgBuffer.str()) ;
783 // XXX should do something with the return
785 read_message(retmsg) ;
789 * Send a message indicating that a MarkerView item has been removed message
791 * @param item_id the id of the item that was removed
792 * @param src the identity of the object that initiated the change
793 * @param item the MarkerView which has been removed
796 ImageFrameSocketHandler::send_marker_view_removed(const string & item_id, void* src, MarkerView* item)
798 if(this == src || src == 0)
800 // ie the change originated from us, then dont send any message back
804 // create a message buffer
805 std::ostringstream msgBuffer ;
806 msgBuffer << std::setfill('0') ;
809 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_ITEM ;
811 // add the id length, and the id
812 std::string track_id = item->get_time_axis_view().name() ;
813 msgBuffer << std::setw(3) << track_id.length() << track_id ;
814 msgBuffer << std::setw(3) << item_id.length() << item_id ;
816 send_message(msgBuffer.str()) ;
818 // XXX should do something with the return
820 read_message(retmsg) ;
833 //---------------------------------------------------------------------------------------//
834 //---------------------------------------------------------------------------------------//
835 //---------------------------------------------------------------------------------------//
836 // Message breakdown ie avoid a big if...then...else
840 * Handle insert item requests
842 * @param msg the received message
845 ImageFrameSocketHandler::handle_insert_message(const char* msg)
847 // handle the insert item message
848 // determine the object type to insert based upon characters 2-3
850 std::string oType = get_message_part(2,2,msg) ;
852 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
854 this->handle_insert_imageframe_time_axis(msg) ;
856 else if (oType == ardourvis::MARKER_TIME_AXIS)
858 this->handle_insert_marker_time_axis(msg) ;
860 else if (oType == ardourvis::IMAGEFRAME_GROUP)
862 this->handle_insert_imageframe_group(msg) ;
864 else if (oType == ardourvis::IMAGEFRAME_ITEM)
866 this->handle_insert_imageframe_view(msg) ;
868 else if (oType == ardourvis::MARKER_ITEM)
870 this->handle_insert_marker_view(msg) ;
874 std::string errMsg = "Unknown Object type during insert: " ;
875 errMsg.append(oType) ;
876 send_return_failure(errMsg) ;
881 * Handle remove item requests
883 * @param msg the received message
886 ImageFrameSocketHandler::handle_remove_message(const char* msg)
888 // handle the removal of an item message
889 // determine the object type to remove based upon characters 2-3
891 std::string oType = get_message_part(2,2,msg) ;
893 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
895 this->handle_remove_imageframe_time_axis(msg) ;
897 else if (oType == ardourvis::MARKER_TIME_AXIS)
899 this->handle_remove_marker_time_axis(msg) ;
901 else if (oType == ardourvis::IMAGEFRAME_ITEM)
903 this->handle_remove_imageframe_view(msg) ;
905 else if (oType == ardourvis::MARKER_ITEM)
907 this->handle_remove_marker_view(msg) ;
911 std::string errMsg = "Unknown Object type during Remove: " ;
912 errMsg.append(oType) ;
913 send_return_failure(errMsg) ;
918 * Handle rename item requests
920 * @param msg the received message
923 ImageFrameSocketHandler::handle_rename_message(const char* msg)
925 // handle the renaming of an item message
926 // determine the object type to rename based upon characters 2-3
928 std::string oType = get_message_part(2,2,msg) ;
930 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
932 this->handle_rename_imageframe_time_axis(msg) ;
934 else if (oType == ardourvis::MARKER_TIME_AXIS)
936 this->handle_rename_marker_time_axis(msg) ;
938 else if (oType == ardourvis::IMAGEFRAME_ITEM)
940 this->handle_rename_imageframe_view(msg) ;
942 else if (oType == ardourvis::MARKER_ITEM)
944 this->handle_rename_marker_view(msg) ;
948 std::string errMsg = "Unknown Object type during Rename: " ;
949 errMsg.append(oType) ;
950 send_return_failure(errMsg) ;
955 * Handle a request for session information
957 * @param msg the received message
960 ImageFrameSocketHandler::handle_request_data(const char* msg)
962 // determine the request type
963 std::string reqType = get_message_part(2,2,msg) ;
965 if(reqType == ardourvis::SESSION_NAME)
967 handle_session_name_request(msg) ;
972 * Handle the update of a particular item
974 * @param msg the received message
977 ImageFrameSocketHandler::handle_item_update_message(const char* msg)
979 // determin the object that requires updating, characters 2-3
980 std::string oType = get_message_part(2,2,msg) ;
982 // What needs updating? chars 4-5
983 std::string attr = get_message_part(4,2,msg) ;
985 if(oType == ardourvis::IMAGEFRAME_ITEM)
987 if(attr == ardourvis::POSITION_CHANGE)
989 handle_imageframe_view_position_update(msg) ;
991 else if(attr == ardourvis::DURATION_CHANGE)
993 handle_imageframe_view_duration_update(msg) ;
995 else if(attr == ardourvis::POSITION_LOCK_CHANGE)
997 handle_imageframe_position_lock_update(msg) ;
999 else if(attr == ardourvis::MAX_DURATION_CHANGE)
1001 handle_imageframe_view_max_duration_update(msg) ;
1003 else if(attr == ardourvis::MAX_DURATION_ENABLE_CHANGE)
1005 handle_imageframe_view_max_duration_enable_update(msg) ;
1007 else if(attr == ardourvis::MIN_DURATION_CHANGE)
1009 handle_imageframe_view_min_duration_update(msg) ;
1011 else if(attr == ardourvis::MIN_DURATION_ENABLE_CHANGE)
1013 handle_imageframe_view_min_duration_enable_update(msg) ;
1017 std::string errMsg = "Unknown Attribute during Item Update: " ;
1018 errMsg.append(oType) ;
1019 send_return_failure(errMsg) ;
1022 else if(oType == ardourvis::MARKER_ITEM)
1024 if(attr == ardourvis::POSITION_CHANGE)
1026 handle_marker_view_position_update(msg) ;
1028 else if(attr == ardourvis::DURATION_CHANGE)
1030 handle_marker_view_duration_update(msg) ;
1034 std::string errMsg = "Unknown Attribute during Item Update: " ;
1035 errMsg.append(oType) ;
1036 send_return_failure(errMsg) ;
1041 std::string errMsg = "Unknown Object type during Item Update: " ;
1042 errMsg.append(oType) ;
1043 send_return_failure(errMsg) ;
1048 * Handle the selection of an Item
1050 * @param msg the received message
1053 ImageFrameSocketHandler::handle_item_selected(const char* msg)
1055 // determine the object that requires updating, characters 2-3
1056 std::string oType = get_message_part(2,2,msg) ;
1058 if(oType == std::string(ardourvis::IMAGEFRAME_ITEM))
1060 int position = 4 ; // message type chars
1062 std::string track_id ;
1063 std::string scene_id ;
1064 std::string item_id ;
1069 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1071 // get the named time axis
1072 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1076 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1080 // get the parent scene
1081 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1084 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1088 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1091 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1095 ifv->set_selected(true) ;
1096 ifta->get_view()->set_selected_imageframe_view(iftag, ifv) ;
1098 thePublicEditor.scroll_timeaxis_to_imageframe_item(ifv) ;
1099 send_return_success() ;
1107 * Handle s session action message
1109 * @param msg the received message
1112 ImageFrameSocketHandler::handle_session_action(const char* msg)
1114 std::string actionType = get_message_part(2,2,msg) ;
1116 if(actionType == ardourvis::OPEN_SESSION)
1118 this->handle_open_session(msg) ;
1130 //---------------------------------------------------------------------------------------//
1131 // handlers for specific insert procedures
1134 * Handle the insertion of a new ImaegFrameTimeAxis
1136 * @param msg the received message
1139 ImageFrameSocketHandler::handle_insert_imageframe_time_axis(const char* msg)
1141 int position = 4 ; // message type chars
1143 // get the ImageFrameTrack name size
1144 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1145 position += ardourvis::TEXT_SIZE_CHARS ;
1147 // get the image frame track name
1148 std::string track_name = get_message_part(position, track_name_size, msg) ;
1149 position += track_name_size ;
1151 // check we dont already have an time axis with that name
1152 TimeAxisView* tav = thePublicEditor.get_named_time_axis(track_name) ;
1155 std::string errmsg("Track already exists: ") ;
1156 errmsg.append(track_name) ;
1157 send_return_failure(errmsg) ;
1161 thePublicEditor.add_imageframe_time_axis(track_name, this) ;
1162 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1166 ImageFrameTimeAxis* ifta = (ImageFrameTimeAxis*)new_tav ;
1167 ifta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_removed)) ;
1168 ifta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_renamed), ifta)) ;
1170 send_return_success() ;
1174 std::string msg("Addition Failed: ") ;
1175 msg.append(track_name) ;
1176 send_return_failure(msg) ;
1183 * Handle the insertion of a new MarkerTimeAxis
1185 * @param msg the received message
1188 ImageFrameSocketHandler::handle_insert_marker_time_axis(const char* msg)
1190 int position = 4 ; // message type chars
1192 // get the ImageFrameTrack name size
1193 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1194 position += ardourvis::TEXT_SIZE_CHARS ;
1196 // get the image frame track name
1197 std::string track_name = get_message_part(position, track_name_size, msg) ;
1198 position += track_name_size ;
1200 // get the size of the name of the associated track
1201 int assoc_track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1202 position += ardourvis::TEXT_SIZE_CHARS ;
1204 // get the name of the track we associate the marker track with
1205 std::string assoc_track_name = get_message_part(position, assoc_track_name_size, msg) ;
1206 position += assoc_track_name_size ;
1208 // check that we dont already have a time axis with that name
1209 TimeAxisView* checkTav = thePublicEditor.get_named_time_axis(track_name) ;
1212 std::string errmsg("Track already exists: ") ;
1213 errmsg.append(track_name) ;
1214 send_return_failure(errmsg) ;
1218 // check the associated time axis exists
1219 TimeAxisView* assoc_tav = thePublicEditor.get_named_time_axis(assoc_track_name) ;
1222 thePublicEditor.add_imageframe_marker_time_axis(track_name, assoc_tav, this) ;
1223 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1225 bool added = false ;
1229 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(new_tav) ;
1233 mta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_removed)) ;
1234 mta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed), mta)) ;
1240 std::string msg("Addition Failed: ") ;
1241 msg.append(track_name) ;
1242 send_return_failure(msg) ;
1247 std::string errmsg("No associated Track Found: ") ;
1248 errmsg.append(track_name) ;
1249 send_return_failure(errmsg) ;
1255 * Handle the insertion of a time axis group (a scene)
1257 * @param msg the received message
1260 ImageFrameSocketHandler::handle_insert_imageframe_group(const char* msg)
1262 int position = 4 ; // message type chars
1264 // get the ImageFrameTrack name size
1265 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1266 position += ardourvis::TEXT_SIZE_CHARS ;
1268 // get the image frame track name
1269 std::string track_name = get_message_part(position, track_name_size, msg) ;
1270 position += track_name_size ;
1272 // get the scene id size
1273 int scene_id_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1274 position += ardourvis::TEXT_SIZE_CHARS ;
1277 std::string scene_id = get_message_part(position, scene_id_size, msg) ;
1278 position += scene_id_size ;
1281 // get the named ImageFrameTrack
1282 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_name)) ;
1284 // check we got a valid ImageFrameTimeAxis
1287 send_return_failure(std::string("No Image Frame Time Axis Found: ").append(track_name)) ;
1291 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->add_imageframe_group(scene_id, this) ;
1294 send_return_failure(std::string("Image Frame Group insert failed")) ;
1298 iftag->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed), iftag)) ;
1299 iftag->GroupRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_removed), iftag)) ;
1300 send_return_success() ;
1306 * Handle the insertion of a new ImageFrameItem
1308 * @param msg the received message
1311 ImageFrameSocketHandler::handle_insert_imageframe_view(const char* msg)
1313 int position = 4 ; // message type chars
1315 // get the ImageFrameTrack name size
1316 int track_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
1319 // get the ImageFrameTrack Name
1320 std::string imageframe_track_name = get_message_part(position,track_name_size,msg) ;
1321 position += track_name_size ;
1323 // get the scene name size
1324 int scene_size = atoi(get_message_part(position,3,msg).c_str()) ;
1327 // get the scene Name
1328 std::string scene_name = get_message_part(position,scene_size,msg) ;
1329 position += scene_size ;
1331 // get the image frame_id size
1332 int image_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1335 // get the image frame_id
1336 std::string image_id = get_message_part(position,image_id_size,msg) ;
1337 position += image_id_size ;
1339 // get the start frame value
1340 nframes_t start = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1343 // get the duration value
1344 nframes_t duration = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1347 //get the named time axis view we about to add an image to
1348 TimeAxisView* tav = thePublicEditor.get_named_time_axis(imageframe_track_name) ;
1349 ImageFrameTimeAxis* ifta = 0 ;
1353 ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1358 std::string errmsg("No Parent Image Track Found: ") ;
1359 errmsg.append(imageframe_track_name) ;
1360 send_return_failure(errmsg) ;
1362 // dont really like all these returns mid-way
1363 // but this is goinf to get awfully if..then nested if not
1367 // check the parent group exists
1368 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_name) ;
1371 std::string errmsg("No Image Frame Group Found: ") ;
1372 errmsg.append(scene_name) ;
1373 send_return_failure(errmsg) ;
1377 // ok, so we have the parent group and track, now we need dome image data
1381 // request the image data from the image compositor
1384 // ctreate a message buffer
1385 std::ostringstream reqBuffer ;
1386 reqBuffer << std::setfill('0') ;
1389 reqBuffer << REQUEST_DATA << IMAGE_RGB_DATA ;
1391 // add the image track and size
1392 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << track_name_size ;
1393 reqBuffer << imageframe_track_name ;
1395 // add the scene id and size
1396 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << scene_size ;
1397 reqBuffer << scene_name ;
1399 // add the image id and size
1400 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << image_id_size ;
1401 reqBuffer << image_id ;
1403 // add the preferred image height
1404 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << ifta->get_image_display_height() ;
1406 // send the request message
1407 send_message(reqBuffer.str()) ;
1410 // read the reply, the inital image data message
1411 // this gives us the image dimensions and the expected size of the image data
1412 // msg type(4) + image width(3) + height(3) + num channels(3) + size of the image data (32)
1413 std::string init_image_data_msg ;
1414 read_message(init_image_data_msg) ;
1415 int init_msg_pos = 4 ;
1417 int imgWidth = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1418 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1419 int imgHeight = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1420 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1421 int imgChannels = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1422 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1423 int imgSize = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_DATA_MESSAGE_SIZE_CHARS).c_str()) ;
1425 // send a success msg
1426 // we need to do this to keep things moving
1427 send_return_success() ;
1429 // create our image rgb buffer, this holds the image data we receive
1430 unsigned char* rgb_img_buf = new unsigned char[imgSize] ;
1432 int retcode = ::recv(theArdourToCompositorSocket, rgb_img_buf, imgSize, MSG_WAITALL) ;
1434 if(retcode != imgSize)
1436 delete [] rgb_img_buf ;
1437 send_return_failure("Could not create new Image Frame View : image data sizes did not match") ;
1441 ImageFrameView* ifv = iftag->add_imageframe_item(image_id, start, duration, rgb_img_buf, (uint32_t)imgWidth, (uint32_t)imgHeight, (uint32_t)imgChannels, this) ;
1444 ifv->PositionChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_position_change), ifv)) ;
1445 ifv->DurationChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change), ifv)) ;
1446 ifv->ItemRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_removed), ifv)) ;
1448 send_return_success() ;
1452 //addition failed. assume duplicate item_id
1453 send_return_failure("Could not create new Image Frame View") ;
1461 * Handle the insertion of a new MarkerItem
1463 * @param msg the received message
1466 ImageFrameSocketHandler::handle_insert_marker_view(const char* msg)
1470 //---------------------------------------------------------------------------------------//
1471 // handlers for specific removal procedures
1475 * Handle the removal of an ImageTimeAxis
1477 * @param msg the received message
1480 ImageFrameSocketHandler::handle_remove_imageframe_time_axis(const char* msg)
1484 * Handle the removal of an MarkerTimeAxis
1486 * @param msg the received message
1489 ImageFrameSocketHandler::handle_remove_marker_time_axis(const char* msg)
1493 * Handle the removal of an ImageFrameTimeAxisGroup
1495 * @param msg the received message
1498 ImageFrameSocketHandler::handle_remove_imageframe_time_axis_group(const char* msg)
1502 * Handle the removal of an ImageFrameItem
1504 * @param msg the received message
1507 ImageFrameSocketHandler::handle_remove_imageframe_view(const char* msg)
1511 * Handle the removal of an MarkerItem
1513 * @param msg the received message
1516 ImageFrameSocketHandler::handle_remove_marker_view(const char* msg)
1523 //---------------------------------------------------------------------------------------//
1524 // handlers for the specific rename procedures
1527 * Handle the renaming of an ImageTimeAxis
1529 * @param msg the received message
1532 ImageFrameSocketHandler::handle_rename_imageframe_time_axis(const char* msg)
1534 // msg [MVIT][oldSize][oldId][newSize][newId]
1536 int position = 4 ; // message type chars
1538 // get the old Id size
1539 int old_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1543 std::string old_id = get_message_part(position,old_id_size,msg) ;
1544 position += old_id_size ;
1546 //get the new Id size
1547 int new_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1551 std::string new_id = get_message_part(position,new_id_size,msg) ;
1552 position += new_id_size ;
1554 // get the Named time axis
1555 TimeAxisView* tav = thePublicEditor.get_named_time_axis(old_id) ;
1556 if(dynamic_cast<ImageFrameTimeAxis*>(tav))
1558 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1559 ifta->set_time_axis_name(new_id, this) ;
1560 send_return_success() ;
1564 std::string msg = "No Image Track Found: " ;
1565 msg.append(old_id) ;
1566 send_return_failure(msg) ;
1571 * Handle the renaming of an MarkerTimeAxis
1573 * @param msg the received message
1576 ImageFrameSocketHandler::handle_rename_marker_time_axis(const char* msg)
1580 * Handle the renaming of an ImageFrameItem
1582 * @param msg the received message
1585 ImageFrameSocketHandler::handle_rename_imageframe_time_axis_group(const char* msg)
1589 * Handle the renaming of an ImageFrameItem
1591 * @param msg the received message
1594 ImageFrameSocketHandler::handle_rename_imageframe_view(const char* msg)
1598 * Handle the renaming of an Marker
1600 * @param msg the received message
1603 ImageFrameSocketHandler::handle_rename_marker_view(const char* msg)
1609 //---------------------------------------------------------------------------------------//
1610 // handlers for data request
1613 * Handle a request for the sessnio naem fo the current session
1614 * We return a failure state if no session is open
1616 * @param msg the received message
1619 ImageFrameSocketHandler::handle_session_name_request(const char* msg)
1621 ARDOUR::Session* currentSession = thePublicEditor.current_session() ;
1623 if(currentSession == 0)
1625 // no current session, return failure
1626 std::string msg("No Current Session") ;
1627 send_return_failure(msg) ;
1631 std::string sessionName = currentSession->name() ;
1632 std::string sessionPath = currentSession->path() ;
1634 if(sessionPath[sessionPath.length() -1] != '/')
1636 sessionPath.append("/") ;
1639 sessionPath.append(sessionName) ;
1641 std::ostringstream msgBuf ;
1642 msgBuf << ardourvis::RETURN_DATA << ardourvis::SESSION_NAME ;
1643 msgBuf << std::setfill('0') ;
1644 msgBuf << std::setw(ardourvis::TEXT_SIZE_CHARS) << sessionPath.length() ;
1645 msgBuf << sessionPath ;
1646 send_message(msgBuf.str()) ;
1654 //---------------------------------------------------------------------------------------//
1655 // handlers for specific item update changes
1658 * Handle ImageFrameView positional changes
1660 * @param msg the received message
1663 ImageFrameSocketHandler::handle_imageframe_view_position_update(const char* msg)
1665 int position = 6 ; // message type chars
1667 std::string track_id ;
1668 std::string scene_id ;
1669 std::string item_id ;
1674 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1676 nframes_t start_frame = strtoul(get_message_part(position, ardourvis::TIME_VALUE_CHARS, msg).c_str(), 0, 10) ;
1677 position += ardourvis::TIME_VALUE_CHARS ;
1679 // get the named time axis
1680 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1684 send_return_failure(std::string("No parent Image Track found: ").append(track_id)) ;
1688 // get the parent scene
1689 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1692 send_return_failure(std::string("No parent Scene found: ").append(scene_id)) ;
1696 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1700 send_return_failure(std::string("No Image Frame Item found: ").append(item_id)) ;
1705 ifv->set_position(start_frame, this) ;
1706 send_return_success() ;
1710 * Handle ImageFrameView Duration changes
1712 * @param msg the received message
1715 ImageFrameSocketHandler::handle_imageframe_view_duration_update(const char* msg)
1717 int position = 6 ; // message type chars
1719 std::string track_id ;
1720 std::string scene_id ;
1721 std::string item_id ;
1726 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1728 nframes_t duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1729 position += ardourvis::TIME_VALUE_CHARS ;
1731 // get the named time axis
1732 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1736 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1740 // get the parent scene
1741 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1744 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1748 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1752 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1756 ifv->set_duration(duration, this) ;
1757 send_return_success() ;
1761 * Handle ImageFrameView Position Lock Constraint changes
1763 * @param msg the received message
1766 ImageFrameSocketHandler::handle_imageframe_position_lock_update(const char* msg)
1768 int position = 6 ; // message type chars
1770 std::string track_id ;
1771 std::string group_id ;
1772 std::string item_id ;
1777 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1779 std::string pos_lock = get_message_part(position,1,msg) ;
1780 bool pos_lock_active = false ;
1784 pos_lock_active = false ;
1786 else if(pos_lock == "1")
1788 pos_lock_active = true ;
1792 send_return_failure(std::string("Unknown Value used during Position Loack: ").append(pos_lock)) ;
1799 std::string errmsg ;
1800 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1803 ifv->set_position_locked(pos_lock_active, this) ;
1804 send_return_success() ;
1808 send_return_failure(errmsg) ;
1813 * Handle ImageFrameView Maximum Duration changes
1815 * @param msg the received message
1818 ImageFrameSocketHandler::handle_imageframe_view_max_duration_update(const char* msg)
1820 int position = 6 ; // message type chars
1822 std::string track_id ;
1823 std::string group_id ;
1824 std::string item_id ;
1829 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1831 nframes_t max_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1832 position += ardourvis::TIME_VALUE_CHARS ;
1835 std::string errmsg ;
1836 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1839 ifv->set_max_duration(max_duration, this) ;
1840 send_return_success() ;
1844 send_return_failure(errmsg) ;
1849 * Handle image frame max duration enable constraint changes
1851 * @param msg the received message
1854 ImageFrameSocketHandler::handle_imageframe_view_max_duration_enable_update(const char* msg)
1856 int position = 6 ; // message type chars
1858 std::string track_id ;
1859 std::string group_id ;
1860 std::string item_id ;
1865 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1867 std::string active = get_message_part(position,1,msg) ;
1868 bool max_duration_active = false ;
1872 max_duration_active = false ;
1874 else if(active == "1")
1876 max_duration_active = true ;
1880 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1887 std::string errmsg ;
1888 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1891 ifv->set_max_duration_active(max_duration_active, this) ;
1892 send_return_success() ;
1896 send_return_failure(errmsg) ;
1901 * Handle ImageFrameView Minimum Duration changes
1903 * @param msg the received message
1906 ImageFrameSocketHandler::handle_imageframe_view_min_duration_update(const char* msg)
1908 int position = 6 ; // message type chars
1910 std::string track_id ;
1911 std::string group_id ;
1912 std::string item_id ;
1917 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1919 nframes_t min_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1920 position += ardourvis::TIME_VALUE_CHARS ;
1923 std::string errmsg ;
1924 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1927 ifv->set_min_duration(min_duration, this) ;
1928 send_return_success() ;
1932 send_return_failure(errmsg) ;
1937 * Handle image frame min duration enable constraint changes
1939 * @param msg the received message
1942 ImageFrameSocketHandler::handle_imageframe_view_min_duration_enable_update(const char* msg)
1944 int position = 6 ; // message type chars
1946 std::string track_id ;
1947 std::string group_id ;
1948 std::string item_id ;
1953 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1955 std::string active = get_message_part(position,1,msg) ;
1956 bool min_duration_active = false ;
1960 min_duration_active = false ;
1962 else if(active == "1")
1964 min_duration_active = true ;
1968 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1975 std::string errmsg ;
1976 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1979 ifv->set_min_duration_active(min_duration_active, this) ;
1980 send_return_success() ;
1984 send_return_failure(errmsg) ;
1989 * Handle MarkerView position changes
1991 * @param msg the received message
1994 ImageFrameSocketHandler::handle_marker_view_position_update(const char* msg)
1998 * Handle MarkerView duration changes
2000 * @param msg the received message
2003 ImageFrameSocketHandler::handle_marker_view_duration_update(const char* msg)
2007 * Handle MarkerView Position Lock Constraint changes
2009 * @param msg the received message
2012 ImageFrameSocketHandler::handle_marker_view_position_lock_update(const char* msg)
2017 * Handle MarkerView maximum duration changes
2019 * @param msg the received message
2022 ImageFrameSocketHandler::handle_marker_view_max_duration_update(const char* msg)
2026 * Handle MarkerView minimum duration changes
2028 * @param msg the received message
2031 ImageFrameSocketHandler::handle_marker_view_min_duration_update(const char* msg)
2038 //---------------------------------------------------------------------------------------//
2039 // handlers for Session Actions
2042 * Handle the opening of a named audio session
2044 * @param msg the received message
2047 ImageFrameSocketHandler::handle_open_session(const char* msg)
2049 // msg [SAOS][sessionSize][sessionPath]
2051 int position = 4 ; // message type chars
2053 // get the session name size
2054 int session_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
2057 // get the session name
2058 std::string session_name = get_message_part(position,session_name_size,msg) ;
2059 position += session_name_size ;
2063 std::string path, name ;
2066 if (ARDOUR::find_session(session_name, path, name, isnew) == 0) {
2067 if (ARDOUR_UI::instance()->load_session (path, name) == 0) {
2068 send_return_success() ;
2070 std::string retMsg = "Failed to load Session" ;
2071 send_return_failure(retMsg) ;
2074 std::string retMsg = "Failed to find Session" ;
2075 send_return_failure(retMsg) ;
2081 * Handle the closing of a named audio session
2083 * @param msg the received message
2086 ImageFrameSocketHandler::handle_closed_session(const char* msg)
2089 //---------------------------------------------------------------------------------------//
2090 // handlers for the shutdown of the Image Compositor
2093 * Handle the shutdown message from the image compositor
2095 * @param msg the received message
2098 ImageFrameSocketHandler::handle_shutdown(const char* msg)
2100 CompositorSocketShutdown() ; /* EMIT_SIGNAL */
2112 //---------------------------------------------------------------------------------------//
2113 // convenince methods to break up messages
2116 * Returns part of the received message as a std::string
2118 * @param start the start character
2119 * @param num_chars the number of characters to read
2120 * @param the message to break apart
2121 * @return the sub string of the message
2124 ImageFrameSocketHandler::get_message_part(int start, int32_t num_chars, const char* msg)
2126 char buf[num_chars + 1] ;
2127 strncpy(buf,msg+start,num_chars) ;
2128 buf[num_chars] = '\0' ;
2129 std::string s(buf) ;
2137 * break up am image item description message
2138 * we break the mesage up into the parent Image Track id and size,
2139 * the parent group id and size, and the image id and size
2142 * @param track_id_size
2144 * @param scene_id_size
2146 * @param item_id_size
2149 ImageFrameSocketHandler::decompose_imageframe_item_desc(const char* msg, int& position, std::string& track_id,
2150 int& track_id_size, std::string& scene_id, int& scene_id_size, std::string& item_id, int& item_id_size)
2152 // get the track Id size
2153 track_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2154 position += ardourvis::TEXT_SIZE_CHARS ;
2157 track_id = get_message_part(position,track_id_size,msg) ;
2158 position += track_id_size ;
2160 // get the track Id size
2161 scene_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2162 position += ardourvis::TEXT_SIZE_CHARS ;
2165 scene_id = get_message_part(position,scene_id_size,msg) ;
2166 position += scene_id_size ;
2168 // get the item id size
2169 item_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2170 position += ardourvis::TEXT_SIZE_CHARS ;
2173 item_id = get_message_part(position,item_id_size,msg) ;
2174 position += item_id_size ;
2178 * Compose a description of the specified image frame view
2179 * The description consists of the parent track name size and name,
2180 * the parent group name size and name, and the item name size and name
2182 * @param ifv the item to string_compose a description of
2183 * @param buffer the buffer to write the description
2186 ImageFrameSocketHandler::compose_imageframe_item_desc(ImageFrameView* ifv, std::ostringstream& buffer)
2188 buffer << std::setw(3) << ifv->get_time_axis_group()->get_view().trackview().name().length() ;
2189 buffer << ifv->get_time_axis_group()->get_view().trackview().name() ;
2191 // add the parent scene
2192 buffer << std::setw(3) << ifv->get_time_axis_group()->get_group_name().length() ;
2193 buffer << ifv->get_time_axis_group()->get_group_name() ;
2195 // add the ImageFrameItem id length and Id
2196 buffer << setw(3) << ifv->get_item_name().length() ;
2197 buffer << ifv->get_item_name() ;
2201 * Compose a description of the specified marker view
2202 * The description consists of the parent track name size and name,
2203 * and the item name size and name
2205 * @param mv the item to string_compose a description of
2206 * @param buffer the buffer to write the description
2209 ImageFrameSocketHandler::compose_marker_item_desc(MarkerView* mv, std::ostringstream& buffer)
2211 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(&mv->get_time_axis_view()) ;
2218 buffer << std::setw(3) << mta->name().length() ;
2219 buffer << mta->name() ;
2221 buffer << std::setw(3) << mv->get_item_name().length() ;
2222 buffer << mv->get_item_name() ;
2227 * Returns the ImageFrameView from the specified description
2228 * The errcode parameter is used to indicate the item which caused
2229 * an error on failure of this method
2231 * 1 = the track item was not found
2232 * 2 = the group item was not found
2233 * 3 = the imageframe item was not found
2235 * @paran track_id the track on which the item is placed
2236 * @param group_id the group in which the item is a member
2237 * @param item_id the id of the item
2238 * @param int32_t reference used for error codes on failure
2239 * @param errmsg populated with a description of the error on failure
2240 * @return the described item on success, 0 otherwise
2243 ImageFrameSocketHandler::get_imageframe_view_from_desc(const string & track_id, const string & group_id, const string & item_id, int& errcode, std::string& errmsg)
2245 ImageFrameView* item = 0 ;
2247 // get the named time axis
2248 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
2253 errmsg = std::string("Image Frame Time Axis Not Found: ").append(track_id) ;
2257 // get the parent scene
2258 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(group_id) ;
2262 errmsg = std::string("Image Frame Group Not Found: ").append(group_id) ;
2266 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
2270 errmsg = std::string("Image Frame Item Not Found: ").append(item_id) ;
2284 //---------------------------------------------------------------------------------------//
2285 // Convenince Message Send Methods
2287 #ifndef MSG_NOSIGNAL
2288 #define MSG_NOSIGNAL 0
2292 * Sends a message throught the socket
2294 * @param msg the message to send
2295 * @return the return value of the socket call
2298 ImageFrameSocketHandler::send_message(const string & msg)
2300 //std::cout << "Sending Message [" << msg << "]\n" ;
2301 int retcode = ::send(theArdourToCompositorSocket, msg.c_str(), msg.length(), MSG_NOSIGNAL) ;
2307 * Reads a message from the Socket
2309 * @param msg a string to populate with the received message
2310 * @return the return value from the socket call
2313 ImageFrameSocketHandler::read_message(std::string& msg)
2315 char buf[ardourvis::MAX_MSG_SIZE + 1] ;
2316 memset(buf, 0, (ardourvis::MAX_MSG_SIZE + 1)) ;
2319 int retcode = ::recv(theArdourToCompositorSocket, buf, ardourvis::MAX_MSG_SIZE, 0) ;
2322 //std::cout << "Received Message [" << msg << "]\n" ;
2329 * Convenience method to string_compose and send a success messasge back to the Image Compositor
2333 ImageFrameSocketHandler::send_return_success()
2335 send_message(ardourvis::RETURN_TRUE) ;
2339 * Convenience method to string_compose and send a failure messasge back to the Image Compositor
2341 * @param msg the failure message
2344 ImageFrameSocketHandler::send_return_failure(const std::string& msg)
2346 std::ostringstream buf ;
2347 buf << std::setfill('0') ;
2348 buf << ardourvis::RETURN_FALSE ;
2349 buf << std::setw(3) << msg.length(); ;
2352 send_message(buf.str()) ;