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.
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
27 #include <arpa/inet.h>
30 #include <sigc++/bind.h>
32 #include <gtkmm2ext/gtk_ui.h>
34 #include "imageframe_socket_handler.h"
35 #include "imageframe_time_axis.h"
36 #include "imageframe_time_axis_view.h"
37 #include "imageframe_time_axis_group.h"
38 #include "imageframe_view.h"
39 #include "marker_time_axis.h"
40 #include "marker_time_axis_view.h"
41 #include "ardour_ui.h"
42 #include "public_editor.h"
43 #include "gui_thread.h"
47 #include <ardour/session.h>
52 using namespace ardourvis ;
55 ImageFrameSocketHandler* ImageFrameSocketHandler::_instance = 0 ;
58 * Constructs a new ImageFrameSocketHandler to handle communication between Ardour and the Image Compositor
60 * @param ed the PublicEditor
62 ImageFrameSocketHandler::ImageFrameSocketHandler(PublicEditor& ed) : thePublicEditor(ed), theArdourToCompositorSocket(-1)
69 * this will shutdown the socket if open
71 ImageFrameSocketHandler::~ImageFrameSocketHandler()
78 * Returns the instance of the ImageFrameSocketHandler
79 * the instance should first be created with createInstance
81 * @return the instance of the ImageFrameSocketHandler
83 ImageFrameSocketHandler*
84 ImageFrameSocketHandler::get_instance()
90 * Create an new instance of the ImageFrameSocketHandler, if one does not already exist
92 * @param ed the Ardour PublicEditor
94 ImageFrameSocketHandler*
95 ImageFrameSocketHandler::create_instance(PublicEditor& ed)
103 _instance = new ImageFrameSocketHandler(ed) ;
109 * call back to handle doing the processing work
110 * This method is added to the gdk main loop and called when there is data
115 ImageFrameSocketHandler::image_socket_callback(void *arg, int32_t fd, GdkInputCondition cond)
117 char buf[ardourvis::MAX_MSG_SIZE + 1] ;
118 memset(buf, 0, (ardourvis::MAX_MSG_SIZE + 1)) ;
119 buf[ardourvis::MAX_MSG_SIZE] = '\0' ;
121 int retcode = ::recv(fd, buf, MAX_MSG_SIZE, 0) ;
124 //end-of-file, other end closed or shutdown?
125 ARDOUR_UI::instance()->popup_error(_("Image Compositor Socket has been shutdown/closed"));
127 // assume socket has been shutdown, tell, someone interested,
128 // and remove the socket from the event loop
129 ImageFrameSocketHandler* ifsh = ImageFrameSocketHandler::get_instance() ;
130 gdk_input_remove(ifsh->theGdkInputTag) ;
131 ifsh->close_connection() ;
132 ifsh->CompositorSocketShutdown() ; /* EMIT_SIGNAL */
136 //std::cout << "Received Msg [" << buf << "]\n" ;
137 ImageFrameSocketHandler* ifsh = ImageFrameSocketHandler::get_instance() ;
139 std::string mType = ifsh->get_message_part(0,2,buf) ;
141 if(mType == ardourvis::INSERT_ITEM)
143 ifsh->handle_insert_message(buf) ;
145 else if (mType == ardourvis::REMOVE_ITEM)
147 ifsh->handle_remove_message(buf) ;
149 else if (mType == ardourvis::RENAME_ITEM)
151 ifsh->handle_rename_message(buf) ;
153 else if (mType == ardourvis::ITEM_UPDATE)
155 ifsh->handle_item_update_message(buf) ;
157 else if (mType == ardourvis::REQUEST_DATA)
159 ifsh->handle_request_data(buf) ;
161 else if (mType == ardourvis::ITEM_SELECTED)
163 ifsh->handle_item_selected(buf) ;
165 else if(mType == ardourvis::SESSION_ACTION)
167 ifsh->handle_session_action(buf) ;
171 std::string errMsg = "Unknown Message type : " ;
172 errMsg.append(mType) ;
173 ifsh->send_return_failure(errMsg) ;
179 * Attempt to connect to the image compositor on the specified host and port
181 * @param hostIp the ip address of the image compositor host
182 * @param port the oprt number to attemp the connection on
183 * @return true if the connection was a succees
187 ImageFrameSocketHandler::connect(std::string hostIp, int32_t port)
191 //already connected...
195 theArdourToCompositorSocket = socket(AF_INET, SOCK_STREAM, 0) ;
196 if(theArdourToCompositorSocket == -1)
202 setsockopt(theArdourToCompositorSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) ;
205 m_addr.sin_family = AF_INET ;
206 m_addr.sin_port = htons(port) ;
207 m_addr.sin_addr.s_addr = inet_addr(hostIp.c_str()) ;
209 int status = ::connect(theArdourToCompositorSocket, (sockaddr *) &m_addr, sizeof(m_addr)) ;
213 theArdourToCompositorSocket = -1 ;
221 * Closes the connection to th Image Compositor
225 ImageFrameSocketHandler::close_connection()
229 ::close(theArdourToCompositorSocket) ;
230 theArdourToCompositorSocket = -1 ;
235 * Returns true if this ImagFrameSocketHandler is currently connected to rthe image compositor
237 * @return true if connected to the image compositor
240 ImageFrameSocketHandler::is_connected()
242 return(theArdourToCompositorSocket == -1 ? false : true) ;
246 * Sets the tag used to describe this input within gtk
247 * this is returned when gdk_input_add is called and is required to remove the input
249 * @param tag the gdk input tag of this input
252 ImageFrameSocketHandler::set_gdk_input_tag(int tag)
254 theGdkInputTag = tag ;
258 * Returns the gdk input tag of this input
260 * @return the gdk input tag of this input
261 * @see setGdkInputTag
264 ImageFrameSocketHandler::get_gdk_input_tag()
266 return(theGdkInputTag) ;
270 * Returns the socket file descriptor
272 * @return the Sockt file descriptor
275 ImageFrameSocketHandler::get_socket_descriptor()
277 return(theArdourToCompositorSocket) ;
283 //---------------------------------------------------------------------------------------//
284 // Handle Sending messages to the Image Compositor
286 //----------------------------
287 // ImageFrameTimeAxis Messages
290 * Sends a message stating that the named image frame time axis has been removed
292 * @param track_id the unique id of the removed image frame time axis
293 * @param src the identity of the object that initiated the change
296 ImageFrameSocketHandler::send_imageframe_time_axis_removed(std::string track_id, void* src)
298 if(this == src || src == 0)
300 // ie the change originated from us, then dont send any message back
304 // create a message buffer
305 std::ostringstream msgBuffer ;
306 msgBuffer << std::setfill('0') ;
309 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_TIME_AXIS ;
311 // add the id length, and the id
312 msgBuffer << std::setw(3) << track_id.length() ;
313 msgBuffer << track_id ;
315 send_message(msgBuffer.str()) ;
317 // XXX should do something with the return
319 read_message(retmsg) ;
323 * Sends a message indicating that an ImageFrameTimeAxis has been renamed
325 * @param new_id the new name, or Id, of the track
326 * @param old_id the old name, or Id, of the track
327 * @param src the identity of the object that initiated the change
328 * @param time_axis the time axis that has changed
331 ImageFrameSocketHandler::send_imageframe_time_axis_renamed(std::string new_id, std::string old_id, void* src, ImageFrameTimeAxis* time_axis)
333 // ENSURE_GUI_THREAD(SigC::bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_renamed), new_id, old_id, src, time_axis));
335 if(this == src || src == 0)
337 // ie the change originated from us, then dont send any message back
341 // create a message buffer
342 std::ostringstream msgBuffer ;
343 msgBuffer << std::setfill('0') ;
346 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_TIME_AXIS ;
348 // add the old id and length
349 msgBuffer << std::setw(3) << old_id.length() ;
350 msgBuffer << old_id ;
352 // add the new id and length
353 msgBuffer << std::setw(3) << new_id.length() ;
354 msgBuffer << new_id ;
356 send_message(msgBuffer.str()) ;
358 // XXX should do something with the return
360 read_message(retmsg) ;
363 //------------------------
364 // MarkerTimeAxis Messages
367 * Sends a message stating that the named marker time axis has been removed
369 * @param track_id the unique id of the removed image frame time axis
370 * @param src the identity of the object that initiated the change
373 ImageFrameSocketHandler::send_marker_time_axis_removed(std::string track_id, void* src)
375 if(this == src || src == 0)
377 // ie the change originated from us, then dont send any message back
381 // create a message buffer
382 std::ostringstream msgBuffer ;
383 msgBuffer << std::setfill('0') ;
386 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_TIME_AXIS ;
388 // add the id length, and the id
389 msgBuffer << std::setw(3) << track_id.length() ;
390 msgBuffer << track_id ;
392 send_message(msgBuffer.str()) ;
394 // XXX should do something with the return
396 read_message(retmsg) ;
400 * Sends a message indicating that an MarkerTimeAxis has been renamed
402 * @param new_id the new name, or Id, of the track
403 * @param old_id the old name, or Id, of the track
404 * @param src the identity of the object that initiated the change
405 * @param time_axis the time axis that has changed
408 ImageFrameSocketHandler::send_marker_time_axis_renamed(std::string new_id, std::string old_id, void* src, MarkerTimeAxis* time_axis)
410 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed), new_id, old_id, src, time_axis));
412 if(this == src || src == 0)
414 // ie the change originated from us, then dont send any message back
418 // ctreate a message buffer
419 std::ostringstream msgBuffer ;
420 msgBuffer << std::setfill('0') ;
423 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_TIME_AXIS ;
425 // add the old id and length
426 msgBuffer << std::setw(3) << old_id.length() ;
427 msgBuffer << old_id ;
429 // add the new id and length
430 msgBuffer << std::setw(3) << new_id.length() ;
431 msgBuffer << new_id ;
433 send_message(msgBuffer.str()) ;
435 // XXX should do something with the return
437 read_message(retmsg) ;
440 //---------------------------------
441 // ImageFrameTimeAxisGroup Messages
444 * Sends a message stating that the group has been removed
446 * @param group_id the unique id of the removed image frame time axis
447 * @param src the identity of the object that initiated the change
448 * @param group the group that has changed
451 ImageFrameSocketHandler::send_imageframe_time_axis_group_removed(std::string group_id, void* src, ImageFrameTimeAxisGroup* group)
453 if(this == src || src == 0)
455 // ie the change originated from us, then dont send any message back
459 // create a message buffer
460 std::ostringstream msgBuffer ;
461 msgBuffer << std::setfill('0') ;
464 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_GROUP ;
466 // add the id length, and the id of the parent image time axis
467 std::string track_id = group->get_view().trackview().name() ;
468 msgBuffer << std::setw(3) << track_id.length() ;
469 msgBuffer << track_id ;
471 // add the group id and length
472 msgBuffer << std::setw(3) << group_id.length() ;
473 msgBuffer << group_id ;
475 send_message(msgBuffer.str()) ;
477 // XXX should do something with the return
479 read_message(retmsg) ;
483 * Send a message indicating that an ImageFrameTimeAxisGroup has been renamed
485 * @param new_id the new name, or Id, of the group
486 * @param old_id the old name, or Id, of the group
487 * @param src the identity of the object that initiated the change
488 * @param group the group that has changed
491 ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed(std::string new_id, std::string old_id, void* src, ImageFrameTimeAxisGroup* group)
493 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed), new_id, old_id, src, group));
495 if(this == src || src == 0)
497 // ie the change originated from us, then dont send any message back
501 // ctreate a message buffer
502 std::ostringstream msgBuffer ;
503 msgBuffer << std::setfill('0') ;
506 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_GROUP ;
508 // add the track this group is upon
509 std::string track_id = group->get_view().trackview().name() ;
510 msgBuffer << std::setw(3) << track_id.length() << track_id ;
512 // add the old id and length
513 msgBuffer << std::setw(3) << old_id.length() ;
514 msgBuffer << old_id ;
516 // add the new id and length
517 msgBuffer << std::setw(3) << new_id.length() ;
518 msgBuffer << new_id ;
520 send_message(msgBuffer.str()) ;
522 // XXX should do something with the return
524 read_message(retmsg) ;
528 //---------------------------------
529 // ImageFrameView Messages
532 * Send an Image Frame View Item position changed message
534 * @param pos the new position value
535 * @param src the identity of the object that initiated the change
536 * @param item the time axis item whos position has changed
539 ImageFrameSocketHandler::send_imageframe_view_position_change(jack_nframes_t pos, void* src, ImageFrameView* item)
541 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_position_change), pos, src, item));
543 if(this == src || src == 0)
548 // create a message buffer
549 std::ostringstream msgBuffer ;
550 msgBuffer << std::setfill('0') ;
553 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::POSITION_CHANGE ;
555 // add the item description
556 this->compose_imageframe_item_desc(item, msgBuffer) ;
558 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
560 send_message(msgBuffer.str()) ;
562 // XXX should do something with the return
564 read_message(retmsg) ;
568 * Send a Image Frame View item duration changed message
570 * @param dur the the new duration value
571 * @param src the identity of the object that initiated the change
572 * @param item the item which has had a duration change
575 ImageFrameSocketHandler::send_imageframe_view_duration_change(jack_nframes_t dur, void* src, ImageFrameView* item)
577 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change), dur, src, item));
579 if(this == src || src == 0)
584 // create a message buffer
585 std::ostringstream msgBuffer ;
586 msgBuffer << std::setfill('0') ;
589 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::DURATION_CHANGE ;
591 this->compose_imageframe_item_desc(item, msgBuffer) ;
593 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
595 send_message(msgBuffer.str()) ;
597 // XXX should do something with the return
599 read_message(retmsg) ;
603 * Send a message indicating that an ImageFrameView has been renamed
605 * @param item the ImageFrameView which has been renamed
606 * @param src the identity of the object that initiated the change
607 * @param item the renamed item
610 ImageFrameSocketHandler::send_imageframe_view_renamed(std::string new_id, std::string old_id, void* src, ImageFrameView* item)
612 if(this == src || src == 0)
614 // ie the change originated from us, then dont send any message back
618 // ctreate a message buffer
619 std::ostringstream msgBuffer ;
620 msgBuffer << std::setfill('0') ;
623 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_ITEM ;
625 this->compose_imageframe_item_desc(item, msgBuffer) ;
627 // add the old id and length
628 msgBuffer << std::setw(3) << old_id.length() ;
629 msgBuffer << old_id ;
631 send_message(msgBuffer.str()) ;
633 // XXX should do something with the return
635 read_message(retmsg) ;
639 * Send a message indicating that an ImageFrameView item has been removed message
641 * @param item_id the id of the item that was removed
642 * @param item the removed item
645 ImageFrameSocketHandler::send_imageframe_view_removed(std::string item_id, void* src, ImageFrameView* item)
647 if(this == src || src == 0)
649 // ie the change originated from us, then dont send any message back
653 // create a message buffer
654 std::ostringstream msgBuffer ;
655 msgBuffer << std::setfill('0') ;
658 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_ITEM ;
660 // add the id length, and the id
661 ImageFrameTimeAxisGroup* parentGroup = item->get_time_axis_group() ;
662 std::string group_id = parentGroup->get_group_name() ;
663 std::string track_id = parentGroup->get_view().trackview().name() ;
664 msgBuffer << std::setw(3) << track_id.length() << track_id ;
665 msgBuffer << std::setw(3) << group_id.length() << group_id ;
666 msgBuffer << std::setw(3) << item_id.length() << item_id ;
668 send_message(msgBuffer.str()) ;
670 // XXX should do something with the return
672 read_message(retmsg) ;
678 //---------------------------------
679 // MarkerView Messages
682 * Send a Marker View Item position changed message
684 * @param pos the new position value
685 * @param src the identity of the object that initiated the change
686 * @param item the time axis item whos position has changed
689 ImageFrameSocketHandler::send_marker_view_position_change(jack_nframes_t pos, void* src, MarkerView* item)
691 if(this == src || src == 0)
696 // create a message buffer
697 std::ostringstream msgBuffer ;
698 msgBuffer << std::setfill('0') ;
701 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::POSITION_CHANGE ;
703 // add the item description
704 this->compose_marker_item_desc(item, msgBuffer) ;
706 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
708 send_message(msgBuffer.str()) ;
710 // XXX should do something with the return
712 read_message(retmsg) ;
716 * Send a Marker View item duration changed message
718 * @param dur the new duration value
719 * @param src the identity of the object that initiated the change
720 * @param item the time axis item whos position has changed
723 ImageFrameSocketHandler::send_marker_view_duration_change(jack_nframes_t dur, void* src, MarkerView* item)
725 if(this == src || src == 0)
730 // create a message buffer
731 std::ostringstream msgBuffer ;
732 msgBuffer << std::setfill('0') ;
735 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::DURATION_CHANGE ;
737 this->compose_marker_item_desc(item, msgBuffer) ;
739 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
741 send_message(msgBuffer.str()) ;
743 // XXX should do something with the return
745 read_message(retmsg) ;
750 * Send a message indicating that a MarkerView has been renamed
752 * @param new_id the new_id of the object
753 * @param old_id the old_id of the object
754 * @param src the identity of the object that initiated the change
755 * @param item the MarkerView which has been renamed
758 ImageFrameSocketHandler::send_marker_view_renamed(std::string new_id, std::string old_id, void* src, MarkerView* item)
760 if(this == src || src == 0)
762 // ie the change originated from us, then dont send any message back
766 // ctreate a message buffer
767 std::ostringstream msgBuffer ;
768 msgBuffer << std::setfill('0') ;
771 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_ITEM ;
773 this->compose_marker_item_desc(item, msgBuffer) ;
775 // add the old id and length
776 msgBuffer << std::setw(3) << old_id.length() ;
777 msgBuffer << old_id ;
779 send_message(msgBuffer.str()) ;
781 // XXX should do something with the return
783 read_message(retmsg) ;
787 * Send a message indicating that a MarkerView item has been removed message
789 * @param item_id the id of the item that was removed
790 * @param src the identity of the object that initiated the change
791 * @param item the MarkerView which has been removed
794 ImageFrameSocketHandler::send_marker_view_removed(std::string item_id, void* src, MarkerView* item)
796 if(this == src || src == 0)
798 // ie the change originated from us, then dont send any message back
802 // create a message buffer
803 std::ostringstream msgBuffer ;
804 msgBuffer << std::setfill('0') ;
807 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_ITEM ;
809 // add the id length, and the id
810 std::string track_id = item->get_time_axis_view().name() ;
811 msgBuffer << std::setw(3) << track_id.length() << track_id ;
812 msgBuffer << std::setw(3) << item_id.length() << item_id ;
814 send_message(msgBuffer.str()) ;
816 // XXX should do something with the return
818 read_message(retmsg) ;
831 //---------------------------------------------------------------------------------------//
832 //---------------------------------------------------------------------------------------//
833 //---------------------------------------------------------------------------------------//
834 // Message breakdown ie avoid a big if...then...else
838 * Handle insert item requests
840 * @param msg the received message
843 ImageFrameSocketHandler::handle_insert_message(const char* msg)
845 // handle the insert item message
846 // determine the object type to insert based upon characters 2-3
848 std::string oType = get_message_part(2,2,msg) ;
850 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
852 this->handle_insert_imageframe_time_axis(msg) ;
854 else if (oType == ardourvis::MARKER_TIME_AXIS)
856 this->handle_insert_marker_time_axis(msg) ;
858 else if (oType == ardourvis::IMAGEFRAME_GROUP)
860 this->handle_insert_imageframe_group(msg) ;
862 else if (oType == ardourvis::IMAGEFRAME_ITEM)
864 this->handle_insert_imageframe_view(msg) ;
866 else if (oType == ardourvis::MARKER_ITEM)
868 this->handle_insert_marker_view(msg) ;
872 std::string errMsg = "Unknown Object type during insert: " ;
873 errMsg.append(oType) ;
874 send_return_failure(errMsg) ;
879 * Handle remove item requests
881 * @param msg the received message
884 ImageFrameSocketHandler::handle_remove_message(const char* msg)
886 // handle the removal of an item message
887 // determine the object type to remove based upon characters 2-3
889 std::string oType = get_message_part(2,2,msg) ;
891 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
893 this->handle_remove_imageframe_time_axis(msg) ;
895 else if (oType == ardourvis::MARKER_TIME_AXIS)
897 this->handle_remove_marker_time_axis(msg) ;
899 else if (oType == ardourvis::IMAGEFRAME_ITEM)
901 this->handle_remove_imageframe_view(msg) ;
903 else if (oType == ardourvis::MARKER_ITEM)
905 this->handle_remove_marker_view(msg) ;
909 std::string errMsg = "Unknown Object type during Remove: " ;
910 errMsg.append(oType) ;
911 send_return_failure(errMsg) ;
916 * Handle rename item requests
918 * @param msg the received message
921 ImageFrameSocketHandler::handle_rename_message(const char* msg)
923 // handle the renaming of an item message
924 // determine the object type to rename based upon characters 2-3
926 std::string oType = get_message_part(2,2,msg) ;
928 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
930 this->handle_rename_imageframe_time_axis(msg) ;
932 else if (oType == ardourvis::MARKER_TIME_AXIS)
934 this->handle_rename_marker_time_axis(msg) ;
936 else if (oType == ardourvis::IMAGEFRAME_ITEM)
938 this->handle_rename_imageframe_view(msg) ;
940 else if (oType == ardourvis::MARKER_ITEM)
942 this->handle_rename_marker_view(msg) ;
946 std::string errMsg = "Unknown Object type during Rename: " ;
947 errMsg.append(oType) ;
948 send_return_failure(errMsg) ;
953 * Handle a request for session information
955 * @param msg the received message
958 ImageFrameSocketHandler::handle_request_data(const char* msg)
960 // determine the request type
961 std::string reqType = get_message_part(2,2,msg) ;
963 if(reqType == ardourvis::SESSION_NAME)
965 handle_session_name_request(msg) ;
970 * Handle the update of a particular item
972 * @param msg the received message
975 ImageFrameSocketHandler::handle_item_update_message(const char* msg)
977 // determin the object that requires updating, characters 2-3
978 std::string oType = get_message_part(2,2,msg) ;
980 // What needs updating? chars 4-5
981 std::string attr = get_message_part(4,2,msg) ;
983 if(oType == ardourvis::IMAGEFRAME_ITEM)
985 if(attr == ardourvis::POSITION_CHANGE)
987 handle_imageframe_view_position_update(msg) ;
989 else if(attr == ardourvis::DURATION_CHANGE)
991 handle_imageframe_view_duration_update(msg) ;
993 else if(attr == ardourvis::POSITION_LOCK_CHANGE)
995 handle_imageframe_position_lock_update(msg) ;
997 else if(attr == ardourvis::MAX_DURATION_CHANGE)
999 handle_imageframe_view_max_duration_update(msg) ;
1001 else if(attr == ardourvis::MAX_DURATION_ENABLE_CHANGE)
1003 handle_imageframe_view_max_duration_enable_update(msg) ;
1005 else if(attr == ardourvis::MIN_DURATION_CHANGE)
1007 handle_imageframe_view_min_duration_update(msg) ;
1009 else if(attr == ardourvis::MIN_DURATION_ENABLE_CHANGE)
1011 handle_imageframe_view_min_duration_enable_update(msg) ;
1015 std::string errMsg = "Unknown Attribute during Item Update: " ;
1016 errMsg.append(oType) ;
1017 send_return_failure(errMsg) ;
1020 else if(oType == ardourvis::MARKER_ITEM)
1022 if(attr == ardourvis::POSITION_CHANGE)
1024 handle_marker_view_position_update(msg) ;
1026 else if(attr == ardourvis::DURATION_CHANGE)
1028 handle_marker_view_duration_update(msg) ;
1032 std::string errMsg = "Unknown Attribute during Item Update: " ;
1033 errMsg.append(oType) ;
1034 send_return_failure(errMsg) ;
1039 std::string errMsg = "Unknown Object type during Item Update: " ;
1040 errMsg.append(oType) ;
1041 send_return_failure(errMsg) ;
1046 * Handle the selection of an Item
1048 * @param msg the received message
1051 ImageFrameSocketHandler::handle_item_selected(const char* msg)
1053 // determine the object that requires updating, characters 2-3
1054 std::string oType = get_message_part(2,2,msg) ;
1056 if(oType == std::string(ardourvis::IMAGEFRAME_ITEM))
1058 int position = 4 ; // message type chars
1060 std::string track_id ;
1061 std::string scene_id ;
1062 std::string item_id ;
1067 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1069 // get the named time axis
1070 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1074 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1078 // get the parent scene
1079 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1082 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1086 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1089 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1093 ifv->set_selected(true, this) ;
1094 ifta->get_view()->set_selected_imageframe_view(iftag, ifv) ;
1096 thePublicEditor.scroll_timeaxis_to_imageframe_item(ifv) ;
1097 send_return_success() ;
1105 * Handle s session action message
1107 * @param msg the received message
1110 ImageFrameSocketHandler::handle_session_action(const char* msg)
1112 std::string actionType = get_message_part(2,2,msg) ;
1114 if(actionType == ardourvis::OPEN_SESSION)
1116 this->handle_open_session(msg) ;
1128 //---------------------------------------------------------------------------------------//
1129 // handlers for specific insert procedures
1132 * Handle the insertion of a new ImaegFrameTimeAxis
1134 * @param msg the received message
1137 ImageFrameSocketHandler::handle_insert_imageframe_time_axis(const char* msg)
1139 int position = 4 ; // message type chars
1141 // get the ImageFrameTrack name size
1142 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1143 position += ardourvis::TEXT_SIZE_CHARS ;
1145 // get the image frame track name
1146 std::string track_name = get_message_part(position, track_name_size, msg) ;
1147 position += track_name_size ;
1149 // check we dont already have an time axis with that name
1150 TimeAxisView* tav = thePublicEditor.get_named_time_axis(track_name) ;
1153 std::string errmsg("Track already exists: ") ;
1154 errmsg.append(track_name) ;
1155 send_return_failure(errmsg) ;
1159 thePublicEditor.add_imageframe_time_axis(track_name, this) ;
1160 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1164 ImageFrameTimeAxis* ifta = (ImageFrameTimeAxis*)new_tav ;
1165 ifta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_removed)) ;
1166 ifta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_renamed), ifta)) ;
1168 send_return_success() ;
1172 std::string msg("Addition Failed: ") ;
1173 msg.append(track_name) ;
1174 send_return_failure(msg) ;
1181 * Handle the insertion of a new MarkerTimeAxis
1183 * @param msg the received message
1186 ImageFrameSocketHandler::handle_insert_marker_time_axis(const char* msg)
1188 int position = 4 ; // message type chars
1190 // get the ImageFrameTrack name size
1191 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1192 position += ardourvis::TEXT_SIZE_CHARS ;
1194 // get the image frame track name
1195 std::string track_name = get_message_part(position, track_name_size, msg) ;
1196 position += track_name_size ;
1198 // get the size of the name of the associated track
1199 int assoc_track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1200 position += ardourvis::TEXT_SIZE_CHARS ;
1202 // get the name of the track we associate the marker track with
1203 std::string assoc_track_name = get_message_part(position, assoc_track_name_size, msg) ;
1204 position += assoc_track_name_size ;
1206 // check that we dont already have a time axis with that name
1207 TimeAxisView* checkTav = thePublicEditor.get_named_time_axis(track_name) ;
1210 std::string errmsg("Track already exists: ") ;
1211 errmsg.append(track_name) ;
1212 send_return_failure(errmsg) ;
1216 // check the associated time axis exists
1217 TimeAxisView* assoc_tav = thePublicEditor.get_named_time_axis(assoc_track_name) ;
1220 thePublicEditor.add_imageframe_marker_time_axis(track_name, assoc_tav, this) ;
1221 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1223 bool added = false ;
1227 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(new_tav) ;
1231 mta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_removed)) ;
1232 mta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed), mta)) ;
1238 std::string msg("Addition Failed: ") ;
1239 msg.append(track_name) ;
1240 send_return_failure(msg) ;
1245 std::string errmsg("No associated Track Found: ") ;
1246 errmsg.append(track_name) ;
1247 send_return_failure(errmsg) ;
1253 * Handle the insertion of a time axis group (a scene)
1255 * @param msg the received message
1258 ImageFrameSocketHandler::handle_insert_imageframe_group(const char* msg)
1260 int position = 4 ; // message type chars
1262 // get the ImageFrameTrack name size
1263 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1264 position += ardourvis::TEXT_SIZE_CHARS ;
1266 // get the image frame track name
1267 std::string track_name = get_message_part(position, track_name_size, msg) ;
1268 position += track_name_size ;
1270 // get the scene id size
1271 int scene_id_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1272 position += ardourvis::TEXT_SIZE_CHARS ;
1275 std::string scene_id = get_message_part(position, scene_id_size, msg) ;
1276 position += scene_id_size ;
1279 // get the named ImageFrameTrack
1280 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_name)) ;
1282 // check we got a valid ImageFrameTimeAxis
1285 send_return_failure(std::string("No Image Frame Time Axis Found: ").append(track_name)) ;
1289 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->add_imageframe_group(scene_id, this) ;
1292 send_return_failure(std::string("Image Frame Group insert failed")) ;
1296 iftag->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed), iftag)) ;
1297 iftag->GroupRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_removed), iftag)) ;
1298 send_return_success() ;
1304 * Handle the insertion of a new ImageFrameItem
1306 * @param msg the received message
1309 ImageFrameSocketHandler::handle_insert_imageframe_view(const char* msg)
1311 int position = 4 ; // message type chars
1313 // get the ImageFrameTrack name size
1314 int track_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
1317 // get the ImageFrameTrack Name
1318 std::string imageframe_track_name = get_message_part(position,track_name_size,msg) ;
1319 position += track_name_size ;
1321 // get the scene name size
1322 int scene_size = atoi(get_message_part(position,3,msg).c_str()) ;
1325 // get the scene Name
1326 std::string scene_name = get_message_part(position,scene_size,msg) ;
1327 position += scene_size ;
1329 // get the image frame_id size
1330 int image_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1333 // get the image frame_id
1334 std::string image_id = get_message_part(position,image_id_size,msg) ;
1335 position += image_id_size ;
1337 // get the start frame value
1338 jack_nframes_t start = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1341 // get the duration value
1342 jack_nframes_t duration = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1345 //get the named time axis view we about to add an image to
1346 TimeAxisView* tav = thePublicEditor.get_named_time_axis(imageframe_track_name) ;
1347 ImageFrameTimeAxis* ifta = 0 ;
1351 ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1356 std::string errmsg("No Parent Image Track Found: ") ;
1357 errmsg.append(imageframe_track_name) ;
1358 send_return_failure(errmsg) ;
1360 // dont really like all these returns mid-way
1361 // but this is goinf to get awfully if..then nested if not
1365 // check the parent group exists
1366 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_name) ;
1369 std::string errmsg("No Image Frame Group Found: ") ;
1370 errmsg.append(scene_name) ;
1371 send_return_failure(errmsg) ;
1375 // ok, so we have the parent group and track, now we need dome image data
1379 // request the image data from the image compositor
1382 // ctreate a message buffer
1383 std::ostringstream reqBuffer ;
1384 reqBuffer << std::setfill('0') ;
1387 reqBuffer << REQUEST_DATA << IMAGE_RGB_DATA ;
1389 // add the image track and size
1390 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << track_name_size ;
1391 reqBuffer << imageframe_track_name ;
1393 // add the scene id and size
1394 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << scene_size ;
1395 reqBuffer << scene_name ;
1397 // add the image id and size
1398 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << image_id_size ;
1399 reqBuffer << image_id ;
1401 // add the preferred image height
1402 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << ifta->get_image_display_height() ;
1404 // send the request message
1405 send_message(reqBuffer.str()) ;
1408 // read the reply, the inital image data message
1409 // this gives us the image dimensions and the expected size of the image data
1410 // msg type(4) + image width(3) + height(3) + num channels(3) + size of the image data (32)
1411 std::string init_image_data_msg ;
1412 read_message(init_image_data_msg) ;
1413 int init_msg_pos = 4 ;
1415 int imgWidth = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1416 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1417 int imgHeight = 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 imgChannels = 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 imgSize = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_DATA_MESSAGE_SIZE_CHARS).c_str()) ;
1423 // send a success msg
1424 // we need to do this to keep things moving
1425 send_return_success() ;
1427 // create our image rgb buffer, this holds the image data we receive
1428 unsigned char* rgb_img_buf = new unsigned char[imgSize] ;
1430 int retcode = ::recv(theArdourToCompositorSocket, rgb_img_buf, imgSize, MSG_WAITALL) ;
1432 if(retcode != imgSize)
1434 delete [] rgb_img_buf ;
1435 send_return_failure("Could not create new Image Frame View : image data sizes did not match") ;
1439 ImageFrameView* ifv = iftag->add_imageframe_item(image_id, start, duration, rgb_img_buf, (uint32_t)imgWidth, (uint32_t)imgHeight, (uint32_t)imgChannels, this) ;
1442 ifv->PositionChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_position_change), ifv)) ;
1443 ifv->DurationChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change), ifv)) ;
1444 ifv->ItemRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_removed), ifv)) ;
1446 send_return_success() ;
1450 //addition failed. assume duplicate item_id
1451 send_return_failure("Could not create new Image Frame View") ;
1459 * Handle the insertion of a new MarkerItem
1461 * @param msg the received message
1464 ImageFrameSocketHandler::handle_insert_marker_view(const char* msg)
1468 //---------------------------------------------------------------------------------------//
1469 // handlers for specific removal procedures
1473 * Handle the removal of an ImageTimeAxis
1475 * @param msg the received message
1478 ImageFrameSocketHandler::handle_remove_imageframe_time_axis(const char* msg)
1482 * Handle the removal of an MarkerTimeAxis
1484 * @param msg the received message
1487 ImageFrameSocketHandler::handle_remove_marker_time_axis(const char* msg)
1491 * Handle the removal of an ImageFrameTimeAxisGroup
1493 * @param msg the received message
1496 ImageFrameSocketHandler::handle_remove_imageframe_time_axis_group(const char* msg)
1500 * Handle the removal of an ImageFrameItem
1502 * @param msg the received message
1505 ImageFrameSocketHandler::handle_remove_imageframe_view(const char* msg)
1509 * Handle the removal of an MarkerItem
1511 * @param msg the received message
1514 ImageFrameSocketHandler::handle_remove_marker_view(const char* msg)
1521 //---------------------------------------------------------------------------------------//
1522 // handlers for the specific rename procedures
1525 * Handle the renaming of an ImageTimeAxis
1527 * @param msg the received message
1530 ImageFrameSocketHandler::handle_rename_imageframe_time_axis(const char* msg)
1532 // msg [MVIT][oldSize][oldId][newSize][newId]
1534 int position = 4 ; // message type chars
1536 // get the old Id size
1537 int old_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1541 std::string old_id = get_message_part(position,old_id_size,msg) ;
1542 position += old_id_size ;
1544 //get the new Id size
1545 int new_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1549 std::string new_id = get_message_part(position,new_id_size,msg) ;
1550 position += new_id_size ;
1552 // get the Named time axis
1553 TimeAxisView* tav = thePublicEditor.get_named_time_axis(old_id) ;
1554 if(dynamic_cast<ImageFrameTimeAxis*>(tav))
1556 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1557 ifta->set_time_axis_name(new_id, this) ;
1558 send_return_success() ;
1562 std::string msg = "No Image Track Found: " ;
1563 msg.append(old_id) ;
1564 send_return_failure(msg) ;
1569 * Handle the renaming of an MarkerTimeAxis
1571 * @param msg the received message
1574 ImageFrameSocketHandler::handle_rename_marker_time_axis(const char* msg)
1578 * Handle the renaming of an ImageFrameItem
1580 * @param msg the received message
1583 ImageFrameSocketHandler::handle_rename_imageframe_time_axis_group(const char* msg)
1587 * Handle the renaming of an ImageFrameItem
1589 * @param msg the received message
1592 ImageFrameSocketHandler::handle_rename_imageframe_view(const char* msg)
1596 * Handle the renaming of an Marker
1598 * @param msg the received message
1601 ImageFrameSocketHandler::handle_rename_marker_view(const char* msg)
1607 //---------------------------------------------------------------------------------------//
1608 // handlers for data request
1611 * Handle a request for the sessnio naem fo the current session
1612 * We return a failure state if no session is open
1614 * @param msg the received message
1617 ImageFrameSocketHandler::handle_session_name_request(const char* msg)
1619 ARDOUR::Session* currentSession = thePublicEditor.current_session() ;
1621 if(currentSession == 0)
1623 // no current session, return failure
1624 std::string msg("No Current Session") ;
1625 send_return_failure(msg) ;
1629 std::string sessionName = currentSession->name() ;
1630 std::string sessionPath = currentSession->path() ;
1632 if(sessionPath[sessionPath.length() -1] != '/')
1634 sessionPath.append("/") ;
1637 sessionPath.append(sessionName) ;
1639 std::ostringstream msgBuf ;
1640 msgBuf << ardourvis::RETURN_DATA << ardourvis::SESSION_NAME ;
1641 msgBuf << std::setfill('0') ;
1642 msgBuf << std::setw(ardourvis::TEXT_SIZE_CHARS) << sessionPath.length() ;
1643 msgBuf << sessionPath ;
1644 send_message(msgBuf.str()) ;
1652 //---------------------------------------------------------------------------------------//
1653 // handlers for specific item update changes
1656 * Handle ImageFrameView positional changes
1658 * @param msg the received message
1661 ImageFrameSocketHandler::handle_imageframe_view_position_update(const char* msg)
1663 int position = 6 ; // message type chars
1665 std::string track_id ;
1666 std::string scene_id ;
1667 std::string item_id ;
1672 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1674 jack_nframes_t start_frame = strtoul(get_message_part(position, ardourvis::TIME_VALUE_CHARS, msg).c_str(), 0, 10) ;
1675 position += ardourvis::TIME_VALUE_CHARS ;
1677 // get the named time axis
1678 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1682 send_return_failure(std::string("No parent Image Track found: ").append(track_id)) ;
1686 // get the parent scene
1687 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1690 send_return_failure(std::string("No parent Scene found: ").append(scene_id)) ;
1694 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1698 send_return_failure(std::string("No Image Frame Item found: ").append(item_id)) ;
1703 ifv->set_position(start_frame, this) ;
1704 send_return_success() ;
1708 * Handle ImageFrameView Duration changes
1710 * @param msg the received message
1713 ImageFrameSocketHandler::handle_imageframe_view_duration_update(const char* msg)
1715 int position = 6 ; // message type chars
1717 std::string track_id ;
1718 std::string scene_id ;
1719 std::string item_id ;
1724 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1726 jack_nframes_t duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1727 position += ardourvis::TIME_VALUE_CHARS ;
1729 // get the named time axis
1730 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1734 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1738 // get the parent scene
1739 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1742 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1746 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1750 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1754 ifv->set_duration(duration, this) ;
1755 send_return_success() ;
1759 * Handle ImageFrameView Position Lock Constraint changes
1761 * @param msg the received message
1764 ImageFrameSocketHandler::handle_imageframe_position_lock_update(const char* msg)
1766 int position = 6 ; // message type chars
1768 std::string track_id ;
1769 std::string group_id ;
1770 std::string item_id ;
1775 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1777 std::string pos_lock = get_message_part(position,1,msg) ;
1778 bool pos_lock_active = false ;
1782 pos_lock_active = false ;
1784 else if(pos_lock == "1")
1786 pos_lock_active = true ;
1790 send_return_failure(std::string("Unknown Value used during Position Loack: ").append(pos_lock)) ;
1797 std::string errmsg ;
1798 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1801 ifv->set_position_locked(pos_lock_active, this) ;
1802 send_return_success() ;
1806 send_return_failure(errmsg) ;
1811 * Handle ImageFrameView Maximum Duration changes
1813 * @param msg the received message
1816 ImageFrameSocketHandler::handle_imageframe_view_max_duration_update(const char* msg)
1818 int position = 6 ; // message type chars
1820 std::string track_id ;
1821 std::string group_id ;
1822 std::string item_id ;
1827 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1829 jack_nframes_t max_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1830 position += ardourvis::TIME_VALUE_CHARS ;
1833 std::string errmsg ;
1834 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1837 ifv->set_max_duration(max_duration, this) ;
1838 send_return_success() ;
1842 send_return_failure(errmsg) ;
1847 * Handle image frame max duration enable constraint changes
1849 * @param msg the received message
1852 ImageFrameSocketHandler::handle_imageframe_view_max_duration_enable_update(const char* msg)
1854 int position = 6 ; // message type chars
1856 std::string track_id ;
1857 std::string group_id ;
1858 std::string item_id ;
1863 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1865 std::string active = get_message_part(position,1,msg) ;
1866 bool max_duration_active = false ;
1870 max_duration_active = false ;
1872 else if(active == "1")
1874 max_duration_active = true ;
1878 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1885 std::string errmsg ;
1886 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1889 ifv->set_max_duration_active(max_duration_active, this) ;
1890 send_return_success() ;
1894 send_return_failure(errmsg) ;
1899 * Handle ImageFrameView Minimum Duration changes
1901 * @param msg the received message
1904 ImageFrameSocketHandler::handle_imageframe_view_min_duration_update(const char* msg)
1906 int position = 6 ; // message type chars
1908 std::string track_id ;
1909 std::string group_id ;
1910 std::string item_id ;
1915 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1917 jack_nframes_t min_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1918 position += ardourvis::TIME_VALUE_CHARS ;
1921 std::string errmsg ;
1922 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1925 ifv->set_min_duration(min_duration, this) ;
1926 send_return_success() ;
1930 send_return_failure(errmsg) ;
1935 * Handle image frame min duration enable constraint changes
1937 * @param msg the received message
1940 ImageFrameSocketHandler::handle_imageframe_view_min_duration_enable_update(const char* msg)
1942 int position = 6 ; // message type chars
1944 std::string track_id ;
1945 std::string group_id ;
1946 std::string item_id ;
1951 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1953 std::string active = get_message_part(position,1,msg) ;
1954 bool min_duration_active = false ;
1958 min_duration_active = false ;
1960 else if(active == "1")
1962 min_duration_active = true ;
1966 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1973 std::string errmsg ;
1974 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1977 ifv->set_min_duration_active(min_duration_active, this) ;
1978 send_return_success() ;
1982 send_return_failure(errmsg) ;
1987 * Handle MarkerView position changes
1989 * @param msg the received message
1992 ImageFrameSocketHandler::handle_marker_view_position_update(const char* msg)
1996 * Handle MarkerView duration changes
1998 * @param msg the received message
2001 ImageFrameSocketHandler::handle_marker_view_duration_update(const char* msg)
2005 * Handle MarkerView Position Lock Constraint changes
2007 * @param msg the received message
2010 ImageFrameSocketHandler::handle_marker_view_position_lock_update(const char* msg)
2015 * Handle MarkerView maximum duration changes
2017 * @param msg the received message
2020 ImageFrameSocketHandler::handle_marker_view_max_duration_update(const char* msg)
2024 * Handle MarkerView minimum duration changes
2026 * @param msg the received message
2029 ImageFrameSocketHandler::handle_marker_view_min_duration_update(const char* msg)
2036 //---------------------------------------------------------------------------------------//
2037 // handlers for Session Actions
2040 * Handle the opening of a named audio session
2042 * @param msg the received message
2045 ImageFrameSocketHandler::handle_open_session(const char* msg)
2047 // msg [SAOS][sessionSize][sessionPath]
2049 int position = 4 ; // message type chars
2051 // get the session name size
2052 int session_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
2055 // get the session name
2056 std::string session_name = get_message_part(position,session_name_size,msg) ;
2057 position += session_name_size ;
2061 std::string path, name ;
2064 if (ARDOUR::Session::find_session(session_name, path, name, isnew) == 0) {
2065 if (ARDOUR_UI::instance()->load_session (path, name) == 0) {
2066 send_return_success() ;
2068 std::string retMsg = "Failed to load Session" ;
2069 send_return_failure(retMsg) ;
2072 std::string retMsg = "Failed to find Session" ;
2073 send_return_failure(retMsg) ;
2079 * Handle the closing of a named audio session
2081 * @param msg the received message
2084 ImageFrameSocketHandler::handle_closed_session(const char* msg)
2087 //---------------------------------------------------------------------------------------//
2088 // handlers for the shutdown of the Image Compositor
2091 * Handle the shutdown message from the image compositor
2093 * @param msg the received message
2096 ImageFrameSocketHandler::handle_shutdown(const char* msg)
2098 CompositorSocketShutdown() ; /* EMIT_SIGNAL */
2110 //---------------------------------------------------------------------------------------//
2111 // convenince methods to break up messages
2114 * Returns part of the received message as a std::string
2116 * @param start the start character
2117 * @param num_chars the number of characters to read
2118 * @param the message to break apart
2119 * @return the sub string of the message
2122 ImageFrameSocketHandler::get_message_part(int start, int32_t num_chars, const char* msg)
2124 char buf[num_chars + 1] ;
2125 strncpy(buf,msg+start,num_chars) ;
2126 buf[num_chars] = '\0' ;
2127 std::string s(buf) ;
2135 * break up am image item description message
2136 * we break the mesage up into the parent Image Track id and size,
2137 * the parent group id and size, and the image id and size
2140 * @param track_id_size
2142 * @param scene_id_size
2144 * @param item_id_size
2147 ImageFrameSocketHandler::decompose_imageframe_item_desc(const char* msg, int& position, std::string& track_id,
2148 int& track_id_size, std::string& scene_id, int& scene_id_size, std::string& item_id, int& item_id_size)
2150 // get the track Id size
2151 track_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2152 position += ardourvis::TEXT_SIZE_CHARS ;
2155 track_id = get_message_part(position,track_id_size,msg) ;
2156 position += track_id_size ;
2158 // get the track Id size
2159 scene_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2160 position += ardourvis::TEXT_SIZE_CHARS ;
2163 scene_id = get_message_part(position,scene_id_size,msg) ;
2164 position += scene_id_size ;
2166 // get the item id size
2167 item_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2168 position += ardourvis::TEXT_SIZE_CHARS ;
2171 item_id = get_message_part(position,item_id_size,msg) ;
2172 position += item_id_size ;
2176 * Compose a description of the specified image frame view
2177 * The description consists of the parent track name size and name,
2178 * the parent group name size and name, and the item name size and name
2180 * @param ifv the item to string_compose a description of
2181 * @param buffer the buffer to write the description
2184 ImageFrameSocketHandler::compose_imageframe_item_desc(ImageFrameView* ifv, std::ostringstream& buffer)
2186 buffer << std::setw(3) << ifv->get_time_axis_group()->get_view().trackview().name().length() ;
2187 buffer << ifv->get_time_axis_group()->get_view().trackview().name() ;
2189 // add the parent scene
2190 buffer << std::setw(3) << ifv->get_time_axis_group()->get_group_name().length() ;
2191 buffer << ifv->get_time_axis_group()->get_group_name() ;
2193 // add the ImageFrameItem id length and Id
2194 buffer << setw(3) << ifv->get_item_name().length() ;
2195 buffer << ifv->get_item_name() ;
2199 * Compose a description of the specified marker view
2200 * The description consists of the parent track name size and name,
2201 * and the item name size and name
2203 * @param mv the item to string_compose a description of
2204 * @param buffer the buffer to write the description
2207 ImageFrameSocketHandler::compose_marker_item_desc(MarkerView* mv, std::ostringstream& buffer)
2209 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(&mv->get_time_axis_view()) ;
2216 buffer << std::setw(3) << mta->name().length() ;
2217 buffer << mta->name() ;
2219 buffer << std::setw(3) << mv->get_item_name().length() ;
2220 buffer << mv->get_item_name() ;
2225 * Returns the ImageFrameView from the specified description
2226 * The errcode parameter is used to indicate the item which caused
2227 * an error on failure of this method
2229 * 1 = the track item was not found
2230 * 2 = the group item was not found
2231 * 3 = the imageframe item was not found
2233 * @paran track_id the track on which the item is placed
2234 * @param group_id the group in which the item is a member
2235 * @param item_id the id of the item
2236 * @param int32_t reference used for error codes on failure
2237 * @param errmsg populated with a description of the error on failure
2238 * @return the described item on success, 0 otherwise
2241 ImageFrameSocketHandler::get_imageframe_view_from_desc(const std::string& track_id, const std::string& group_id, const std::string& item_id, int& errcode, std::string& errmsg)
2243 ImageFrameView* item = 0 ;
2245 // get the named time axis
2246 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
2251 errmsg = std::string("Image Frame Time Axis Not Found: ").append(track_id) ;
2255 // get the parent scene
2256 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(group_id) ;
2260 errmsg = std::string("Image Frame Group Not Found: ").append(group_id) ;
2264 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
2268 errmsg = std::string("Image Frame Item Not Found: ").append(item_id) ;
2282 //---------------------------------------------------------------------------------------//
2283 // Convenince Message Send Methods
2285 #ifndef MSG_NOSIGNAL
2286 #define MSG_NOSIGNAL 0
2290 * Sends a message throught the socket
2292 * @param msg the message to send
2293 * @return the return value of the socket call
2296 ImageFrameSocketHandler::send_message(const std::string& msg)
2298 //std::cout << "Sending Message [" << msg << "]\n" ;
2299 int retcode = ::send(theArdourToCompositorSocket, msg.c_str(), msg.length(), MSG_NOSIGNAL) ;
2305 * Reads a message from the Socket
2307 * @param msg a string to populate with the received message
2308 * @return the return value from the socket call
2311 ImageFrameSocketHandler::read_message(std::string& msg)
2313 char buf[ardourvis::MAX_MSG_SIZE + 1] ;
2314 memset(buf, 0, (ardourvis::MAX_MSG_SIZE + 1)) ;
2317 int retcode = ::recv(theArdourToCompositorSocket, buf, ardourvis::MAX_MSG_SIZE, 0) ;
2320 //std::cout << "Received Message [" << msg << "]\n" ;
2327 * Convenience method to string_compose and send a success messasge back to the Image Compositor
2331 ImageFrameSocketHandler::send_return_success()
2333 send_message(ardourvis::RETURN_TRUE) ;
2337 * Convenience method to string_compose and send a failure messasge back to the Image Compositor
2339 * @param msg the failure message
2342 ImageFrameSocketHandler::send_return_failure(const std::string& msg)
2344 std::ostringstream buf ;
2345 buf << std::setfill('0') ;
2346 buf << ardourvis::RETURN_FALSE ;
2347 buf << std::setw(3) << msg.length(); ;
2350 send_message(buf.str()) ;