Fix show existing automation for audio tracks (part of #3193)
[ArdourMidi.git] / gtk2_ardour / imageframe_socket_handler.cc
blobdc9188db1b74ed1c1d1ee6f5c483fd99ce831110
1 /*
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.
20 #include <iostream>
21 #include <iomanip>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <unistd.h>
26 #include <arpa/inet.h>
27 #include <cstdio>
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"
44 #include "i18n.h"
46 #include "ardour/session.h"
47 #include "ardour/session_utils.h"
49 #include <unistd.h>
51 using namespace std;
52 using namespace ardourvis ;
53 using namespace ARDOUR;
54 using namespace PBD;
56 ImageFrameSocketHandler* ImageFrameSocketHandler::_instance = 0 ;
58 /**
59 * Constructs a new ImageFrameSocketHandler to handle communication between Ardour and the Image Compositor
61 * @param ed the PublicEditor
63 ImageFrameSocketHandler::ImageFrameSocketHandler(PublicEditor& ed) : thePublicEditor(ed), theArdourToCompositorSocket(-1)
68 /**
69 * Descructor
70 * this will shutdown the socket if open
72 ImageFrameSocketHandler::~ImageFrameSocketHandler()
74 close_connection() ;
78 /**
79 * Returns the instance of the ImageFrameSocketHandler
80 * the instance should first be created with createInstance
82 * @return the instance of the ImageFrameSocketHandler
84 ImageFrameSocketHandler*
85 ImageFrameSocketHandler::get_instance()
87 return(_instance) ;
90 /**
91 * Create an new instance of the ImageFrameSocketHandler, if one does not already exist
93 * @param ed the Ardour PublicEditor
95 ImageFrameSocketHandler*
96 ImageFrameSocketHandler::create_instance(PublicEditor& ed)
98 if(_instance)
100 return(_instance) ;
102 else
104 _instance = new ImageFrameSocketHandler(ed) ;
105 return(_instance) ;
110 * call back to handle doing the processing work
111 * This method is added to the gdk main loop and called when there is data
112 * upon the socket.
115 void
116 ImageFrameSocketHandler::image_socket_callback(void *arg, int32_t fd, GdkInputCondition cond)
118 char buf[ardourvis::MAX_MSG_SIZE + 1] ;
119 memset(buf, 0, (ardourvis::MAX_MSG_SIZE + 1)) ;
120 buf[ardourvis::MAX_MSG_SIZE] = '\0' ;
122 int retcode = ::recv(fd, buf, MAX_MSG_SIZE, 0) ;
123 if (retcode == 0)
125 //end-of-file, other end closed or shutdown?
126 ARDOUR_UI::instance()->popup_error(_("Image Compositor Socket has been shutdown/closed"));
128 // assume socket has been shutdown, tell, someone interested,
129 // and remove the socket from the event loop
130 ImageFrameSocketHandler* ifsh = ImageFrameSocketHandler::get_instance() ;
131 gdk_input_remove(ifsh->theGdkInputTag) ;
132 ifsh->close_connection() ;
133 ifsh->CompositorSocketShutdown() ; /* EMIT_SIGNAL */
135 if(retcode > 0)
137 //std::cout << "Received Msg [" << buf << "]\n" ;
138 ImageFrameSocketHandler* ifsh = ImageFrameSocketHandler::get_instance() ;
140 std::string mType = ifsh->get_message_part(0,2,buf) ;
142 if(mType == ardourvis::INSERT_ITEM)
144 ifsh->handle_insert_message(buf) ;
146 else if (mType == ardourvis::REMOVE_ITEM)
148 ifsh->handle_remove_message(buf) ;
150 else if (mType == ardourvis::RENAME_ITEM)
152 ifsh->handle_rename_message(buf) ;
154 else if (mType == ardourvis::ITEM_UPDATE)
156 ifsh->handle_item_update_message(buf) ;
158 else if (mType == ardourvis::REQUEST_DATA)
160 ifsh->handle_request_data(buf) ;
162 else if (mType == ardourvis::ITEM_SELECTED)
164 ifsh->handle_item_selected(buf) ;
166 else if(mType == ardourvis::SESSION_ACTION)
168 ifsh->handle_session_action(buf) ;
170 else
172 std::string errMsg = "Unknown Message type : " ;
173 errMsg.append(mType) ;
174 ifsh->send_return_failure(errMsg) ;
180 * Attempt to connect to the image compositor on the specified host and port
182 * @param hostIp the ip address of the image compositor host
183 * @param port the oprt number to attemp the connection on
184 * @return true if the connection was a succees
185 * false otherwise
187 bool
188 ImageFrameSocketHandler::connect(const char * hostIp, int32_t port)
190 if (is_connected())
192 //already connected...
193 return(true) ;
196 theArdourToCompositorSocket = socket(AF_INET, SOCK_STREAM, 0) ;
197 if(theArdourToCompositorSocket == -1)
199 return(false) ;
202 int on = 1 ;
203 setsockopt(theArdourToCompositorSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) ;
205 sockaddr_in m_addr ;
206 m_addr.sin_family = AF_INET ;
207 m_addr.sin_port = htons(port) ;
208 m_addr.sin_addr.s_addr = inet_addr(hostIp) ;
210 int status = ::connect(theArdourToCompositorSocket, (sockaddr *) &m_addr, sizeof(m_addr)) ;
212 if(status == -1)
214 theArdourToCompositorSocket = -1 ;
215 return(false) ;
218 return(true) ;
222 * Closes the connection to th Image Compositor
225 void
226 ImageFrameSocketHandler::close_connection()
228 if(is_connected())
230 ::close(theArdourToCompositorSocket) ;
231 theArdourToCompositorSocket = -1 ;
236 * Returns true if this ImagFrameSocketHandler is currently connected to rthe image compositor
238 * @return true if connected to the image compositor
240 bool
241 ImageFrameSocketHandler::is_connected()
243 return(theArdourToCompositorSocket == -1 ? false : true) ;
247 * Sets the tag used to describe this input within gtk
248 * this is returned when gdk_input_add is called and is required to remove the input
250 * @param tag the gdk input tag of this input
252 void
253 ImageFrameSocketHandler::set_gdk_input_tag(int tag)
255 theGdkInputTag = tag ;
259 * Returns the gdk input tag of this input
261 * @return the gdk input tag of this input
262 * @see setGdkInputTag
265 ImageFrameSocketHandler::get_gdk_input_tag()
267 return(theGdkInputTag) ;
271 * Returns the socket file descriptor
273 * @return the Sockt file descriptor
276 ImageFrameSocketHandler::get_socket_descriptor()
278 return(theArdourToCompositorSocket) ;
284 //---------------------------------------------------------------------------------------//
285 // Handle Sending messages to the Image Compositor
287 //----------------------------
288 // ImageFrameTimeAxis Messages
291 * Sends a message stating that the named image frame time axis has been removed
293 * @param track_id the unique id of the removed image frame time axis
294 * @param src the identity of the object that initiated the change
296 void
297 ImageFrameSocketHandler::send_imageframe_time_axis_removed(const string & track_id, void* src)
299 if(this == src || src == 0)
301 // ie the change originated from us, then dont send any message back
302 return ;
305 // create a message buffer
306 std::ostringstream msgBuffer ;
307 msgBuffer << std::setfill('0') ;
309 // add the msg type
310 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_TIME_AXIS ;
312 // add the id length, and the id
313 msgBuffer << std::setw(3) << track_id.length() ;
314 msgBuffer << track_id ;
316 send_message(msgBuffer.str()) ;
318 // XXX should do something with the return
319 std::string retmsg ;
320 read_message(retmsg) ;
324 * Sends a message indicating that an ImageFrameTimeAxis has been renamed
326 * @param new_id the new name, or Id, of the track
327 * @param old_id the old name, or Id, of the track
328 * @param src the identity of the object that initiated the change
329 * @param time_axis the time axis that has changed
331 void
332 ImageFrameSocketHandler::send_imageframe_time_axis_renamed(const string & new_id, const string & old_id, void* src, ImageFrameTimeAxis* time_axis)
334 // ENSURE_GUI_THREAD(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_renamed, new_id, old_id, src, time_axis);
336 if(this == src || src == 0)
338 // ie the change originated from us, then dont send any message back
339 return ;
342 // create a message buffer
343 std::ostringstream msgBuffer ;
344 msgBuffer << std::setfill('0') ;
346 // add the msg type
347 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_TIME_AXIS ;
349 // add the old id and length
350 msgBuffer << std::setw(3) << old_id.length() ;
351 msgBuffer << old_id ;
353 // add the new id and length
354 msgBuffer << std::setw(3) << new_id.length() ;
355 msgBuffer << new_id ;
357 send_message(msgBuffer.str()) ;
359 // XXX should do something with the return
360 std::string retmsg ;
361 read_message(retmsg) ;
364 //------------------------
365 // MarkerTimeAxis Messages
368 * Sends a message stating that the named marker time axis has been removed
370 * @param track_id the unique id of the removed image frame time axis
371 * @param src the identity of the object that initiated the change
373 void
374 ImageFrameSocketHandler::send_marker_time_axis_removed(const string & track_id, void* src)
376 if(this == src || src == 0)
378 // ie the change originated from us, then dont send any message back
379 return ;
382 // create a message buffer
383 std::ostringstream msgBuffer ;
384 msgBuffer << std::setfill('0') ;
386 // add the msg type
387 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_TIME_AXIS ;
389 // add the id length, and the id
390 msgBuffer << std::setw(3) << track_id.length() ;
391 msgBuffer << track_id ;
393 send_message(msgBuffer.str()) ;
395 // XXX should do something with the return
396 std::string retmsg ;
397 read_message(retmsg) ;
401 * Sends a message indicating that an MarkerTimeAxis has been renamed
403 * @param new_id the new name, or Id, of the track
404 * @param old_id the old name, or Id, of the track
405 * @param src the identity of the object that initiated the change
406 * @param time_axis the time axis that has changed
408 void
409 ImageFrameSocketHandler::send_marker_time_axis_renamed(const string & new_id, const string & old_id, void* src, MarkerTimeAxis* time_axis)
411 // ENSURE_GUI_THREAD (*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed, new_id, old_id, src, time_axis)
413 if(this == src || src == 0)
415 // ie the change originated from us, then dont send any message back
416 return ;
419 // ctreate a message buffer
420 std::ostringstream msgBuffer ;
421 msgBuffer << std::setfill('0') ;
423 // add the msg type
424 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_TIME_AXIS ;
426 // add the old id and length
427 msgBuffer << std::setw(3) << old_id.length() ;
428 msgBuffer << old_id ;
430 // add the new id and length
431 msgBuffer << std::setw(3) << new_id.length() ;
432 msgBuffer << new_id ;
434 send_message(msgBuffer.str()) ;
436 // XXX should do something with the return
437 std::string retmsg ;
438 read_message(retmsg) ;
441 //---------------------------------
442 // ImageFrameTimeAxisGroup Messages
445 * Sends a message stating that the group has been removed
447 * @param group_id the unique id of the removed image frame time axis
448 * @param src the identity of the object that initiated the change
449 * @param group the group that has changed
451 void
452 ImageFrameSocketHandler::send_imageframe_time_axis_group_removed(const string & group_id, void* src, ImageFrameTimeAxisGroup* group)
454 if(this == src || src == 0)
456 // ie the change originated from us, then dont send any message back
457 return ;
460 // create a message buffer
461 std::ostringstream msgBuffer ;
462 msgBuffer << std::setfill('0') ;
464 // add the msg type
465 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_GROUP ;
467 // add the id length, and the id of the parent image time axis
468 std::string track_id = group->get_view().trackview().name() ;
469 msgBuffer << std::setw(3) << track_id.length() ;
470 msgBuffer << track_id ;
472 // add the group id and length
473 msgBuffer << std::setw(3) << group_id.length() ;
474 msgBuffer << group_id ;
476 send_message(msgBuffer.str()) ;
478 // XXX should do something with the return
479 std::string retmsg ;
480 read_message(retmsg) ;
484 * Send a message indicating that an ImageFrameTimeAxisGroup has been renamed
486 * @param new_id the new name, or Id, of the group
487 * @param old_id the old name, or Id, of the group
488 * @param src the identity of the object that initiated the change
489 * @param group the group that has changed
491 void
492 ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed(const string & new_id, const string & old_id, void* src, ImageFrameTimeAxisGroup* group)
494 // ENSURE_GUI_THREAD (*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed, new_id, old_id, src, group)
496 if(this == src || src == 0)
498 // ie the change originated from us, then dont send any message back
499 return ;
502 // ctreate a message buffer
503 std::ostringstream msgBuffer ;
504 msgBuffer << std::setfill('0') ;
506 // add the msg type
507 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_GROUP ;
509 // add the track this group is upon
510 std::string track_id = group->get_view().trackview().name() ;
511 msgBuffer << std::setw(3) << track_id.length() << track_id ;
513 // add the old id and length
514 msgBuffer << std::setw(3) << old_id.length() ;
515 msgBuffer << old_id ;
517 // add the new id and length
518 msgBuffer << std::setw(3) << new_id.length() ;
519 msgBuffer << new_id ;
521 send_message(msgBuffer.str()) ;
523 // XXX should do something with the return
524 std::string retmsg ;
525 read_message(retmsg) ;
529 //---------------------------------
530 // ImageFrameView Messages
533 * Send an Image Frame View Item position changed message
535 * @param pos the new position value
536 * @param src the identity of the object that initiated the change
537 * @param item the time axis item whos position has changed
539 void
540 ImageFrameSocketHandler::send_imageframe_view_position_change(nframes_t pos, void* src, ImageFrameView* item)
542 // ENSURE_GUI_THREAD (*this, &ImageFrameSocketHandler::send_imageframe_view_position_change, pos, src, item)
544 if(this == src || src == 0)
546 return ;
549 // create a message buffer
550 std::ostringstream msgBuffer ;
551 msgBuffer << std::setfill('0') ;
553 // add the msg type
554 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::POSITION_CHANGE ;
556 // add the item description
557 this->compose_imageframe_item_desc(item, msgBuffer) ;
559 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
561 send_message(msgBuffer.str()) ;
563 // XXX should do something with the return
564 std::string retmsg ;
565 read_message(retmsg) ;
569 * Send a Image Frame View item duration changed message
571 * @param dur the the new duration value
572 * @param src the identity of the object that initiated the change
573 * @param item the item which has had a duration change
575 void
576 ImageFrameSocketHandler::send_imageframe_view_duration_change(nframes_t dur, void* src, ImageFrameView* item)
578 // ENSURE_GUI_THREAD (*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change, dur, src, item)
580 if(this == src || src == 0)
582 return ;
585 // create a message buffer
586 std::ostringstream msgBuffer ;
587 msgBuffer << std::setfill('0') ;
589 // add the msg type
590 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::DURATION_CHANGE ;
592 this->compose_imageframe_item_desc(item, msgBuffer) ;
594 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
596 send_message(msgBuffer.str()) ;
598 // XXX should do something with the return
599 std::string retmsg ;
600 read_message(retmsg) ;
604 * Send a message indicating that an ImageFrameView has been renamed
606 * @param item the ImageFrameView which has been renamed
607 * @param src the identity of the object that initiated the change
608 * @param item the renamed item
610 void
611 ImageFrameSocketHandler::send_imageframe_view_renamed(const string & new_id, const string & old_id, void* src, ImageFrameView* item)
613 if(this == src || src == 0)
615 // ie the change originated from us, then dont send any message back
616 return ;
619 // ctreate a message buffer
620 std::ostringstream msgBuffer ;
621 msgBuffer << std::setfill('0') ;
623 // add the msg type
624 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_ITEM ;
626 this->compose_imageframe_item_desc(item, msgBuffer) ;
628 // add the old id and length
629 msgBuffer << std::setw(3) << old_id.length() ;
630 msgBuffer << old_id ;
632 send_message(msgBuffer.str()) ;
634 // XXX should do something with the return
635 std::string retmsg ;
636 read_message(retmsg) ;
640 * Send a message indicating that an ImageFrameView item has been removed message
642 * @param item_id the id of the item that was removed
643 * @param item the removed item
645 void
646 ImageFrameSocketHandler::send_imageframe_view_removed(const string & item_id, void* src, ImageFrameView* item)
648 if(this == src || src == 0)
650 // ie the change originated from us, then dont send any message back
651 return ;
654 // create a message buffer
655 std::ostringstream msgBuffer ;
656 msgBuffer << std::setfill('0') ;
658 // add the msg type
659 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_ITEM ;
661 // add the id length, and the id
662 ImageFrameTimeAxisGroup* parentGroup = item->get_time_axis_group() ;
663 std::string group_id = parentGroup->get_group_name() ;
664 std::string track_id = parentGroup->get_view().trackview().name() ;
665 msgBuffer << std::setw(3) << track_id.length() << track_id ;
666 msgBuffer << std::setw(3) << group_id.length() << group_id ;
667 msgBuffer << std::setw(3) << item_id.length() << item_id ;
669 send_message(msgBuffer.str()) ;
671 // XXX should do something with the return
672 std::string retmsg ;
673 read_message(retmsg) ;
679 //---------------------------------
680 // MarkerView Messages
683 * Send a Marker View Item position changed message
685 * @param pos the new position value
686 * @param src the identity of the object that initiated the change
687 * @param item the time axis item whos position has changed
689 void
690 ImageFrameSocketHandler::send_marker_view_position_change(nframes_t pos, void* src, MarkerView* item)
692 if(this == src || src == 0)
694 return ;
697 // create a message buffer
698 std::ostringstream msgBuffer ;
699 msgBuffer << std::setfill('0') ;
701 // add the msg type
702 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::POSITION_CHANGE ;
704 // add the item description
705 this->compose_marker_item_desc(item, msgBuffer) ;
707 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
709 send_message(msgBuffer.str()) ;
711 // XXX should do something with the return
712 std::string retmsg ;
713 read_message(retmsg) ;
717 * Send a Marker View item duration changed message
719 * @param dur the new duration value
720 * @param src the identity of the object that initiated the change
721 * @param item the time axis item whos position has changed
723 void
724 ImageFrameSocketHandler::send_marker_view_duration_change(nframes_t dur, void* src, MarkerView* item)
726 if(this == src || src == 0)
728 return ;
731 // create a message buffer
732 std::ostringstream msgBuffer ;
733 msgBuffer << std::setfill('0') ;
735 // add the msg type
736 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::DURATION_CHANGE ;
738 this->compose_marker_item_desc(item, msgBuffer) ;
740 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
742 send_message(msgBuffer.str()) ;
744 // XXX should do something with the return
745 std::string retmsg ;
746 read_message(retmsg) ;
751 * Send a message indicating that a MarkerView has been renamed
753 * @param new_id the new_id of the object
754 * @param old_id the old_id of the object
755 * @param src the identity of the object that initiated the change
756 * @param item the MarkerView which has been renamed
758 void
759 ImageFrameSocketHandler::send_marker_view_renamed(const string & new_id, const string & old_id, void* src, MarkerView* item)
761 if(this == src || src == 0)
763 // ie the change originated from us, then dont send any message back
764 return ;
767 // ctreate a message buffer
768 std::ostringstream msgBuffer ;
769 msgBuffer << std::setfill('0') ;
771 // add the msg type
772 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_ITEM ;
774 this->compose_marker_item_desc(item, msgBuffer) ;
776 // add the old id and length
777 msgBuffer << std::setw(3) << old_id.length() ;
778 msgBuffer << old_id ;
780 send_message(msgBuffer.str()) ;
782 // XXX should do something with the return
783 std::string retmsg ;
784 read_message(retmsg) ;
788 * Send a message indicating that a MarkerView item has been removed message
790 * @param item_id the id of the item that was removed
791 * @param src the identity of the object that initiated the change
792 * @param item the MarkerView which has been removed
794 void
795 ImageFrameSocketHandler::send_marker_view_removed(const string & item_id, void* src, MarkerView* item)
797 if(this == src || src == 0)
799 // ie the change originated from us, then dont send any message back
800 return ;
803 // create a message buffer
804 std::ostringstream msgBuffer ;
805 msgBuffer << std::setfill('0') ;
807 // add the msg type
808 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_ITEM ;
810 // add the id length, and the id
811 std::string track_id = item->get_time_axis_view().name() ;
812 msgBuffer << std::setw(3) << track_id.length() << track_id ;
813 msgBuffer << std::setw(3) << item_id.length() << item_id ;
815 send_message(msgBuffer.str()) ;
817 // XXX should do something with the return
818 std::string retmsg ;
819 read_message(retmsg) ;
832 //---------------------------------------------------------------------------------------//
833 //---------------------------------------------------------------------------------------//
834 //---------------------------------------------------------------------------------------//
835 // Message breakdown ie avoid a big if...then...else
839 * Handle insert item requests
841 * @param msg the received message
843 void
844 ImageFrameSocketHandler::handle_insert_message(const char* msg)
846 // handle the insert item message
847 // determine the object type to insert based upon characters 2-3
849 std::string oType = get_message_part(2,2,msg) ;
851 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
853 this->handle_insert_imageframe_time_axis(msg) ;
855 else if (oType == ardourvis::MARKER_TIME_AXIS)
857 this->handle_insert_marker_time_axis(msg) ;
859 else if (oType == ardourvis::IMAGEFRAME_GROUP)
861 this->handle_insert_imageframe_group(msg) ;
863 else if (oType == ardourvis::IMAGEFRAME_ITEM)
865 this->handle_insert_imageframe_view(msg) ;
867 else if (oType == ardourvis::MARKER_ITEM)
869 this->handle_insert_marker_view(msg) ;
871 else
873 std::string errMsg = "Unknown Object type during insert: " ;
874 errMsg.append(oType) ;
875 send_return_failure(errMsg) ;
880 * Handle remove item requests
882 * @param msg the received message
884 void
885 ImageFrameSocketHandler::handle_remove_message(const char* msg)
887 // handle the removal of an item message
888 // determine the object type to remove based upon characters 2-3
890 std::string oType = get_message_part(2,2,msg) ;
892 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
894 this->handle_remove_imageframe_time_axis(msg) ;
896 else if (oType == ardourvis::MARKER_TIME_AXIS)
898 this->handle_remove_marker_time_axis(msg) ;
900 else if (oType == ardourvis::IMAGEFRAME_ITEM)
902 this->handle_remove_imageframe_view(msg) ;
904 else if (oType == ardourvis::MARKER_ITEM)
906 this->handle_remove_marker_view(msg) ;
908 else
910 std::string errMsg = "Unknown Object type during Remove: " ;
911 errMsg.append(oType) ;
912 send_return_failure(errMsg) ;
917 * Handle rename item requests
919 * @param msg the received message
921 void
922 ImageFrameSocketHandler::handle_rename_message(const char* msg)
924 // handle the renaming of an item message
925 // determine the object type to rename based upon characters 2-3
927 std::string oType = get_message_part(2,2,msg) ;
929 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
931 this->handle_rename_imageframe_time_axis(msg) ;
933 else if (oType == ardourvis::MARKER_TIME_AXIS)
935 this->handle_rename_marker_time_axis(msg) ;
937 else if (oType == ardourvis::IMAGEFRAME_ITEM)
939 this->handle_rename_imageframe_view(msg) ;
941 else if (oType == ardourvis::MARKER_ITEM)
943 this->handle_rename_marker_view(msg) ;
945 else
947 std::string errMsg = "Unknown Object type during Rename: " ;
948 errMsg.append(oType) ;
949 send_return_failure(errMsg) ;
954 * Handle a request for session information
956 * @param msg the received message
958 void
959 ImageFrameSocketHandler::handle_request_data(const char* msg)
961 // determine the request type
962 std::string reqType = get_message_part(2,2,msg) ;
964 if(reqType == ardourvis::SESSION_NAME)
966 handle_session_name_request(msg) ;
971 * Handle the update of a particular item
973 * @param msg the received message
975 void
976 ImageFrameSocketHandler::handle_item_update_message(const char* msg)
978 // determin the object that requires updating, characters 2-3
979 std::string oType = get_message_part(2,2,msg) ;
981 // What needs updating? chars 4-5
982 std::string attr = get_message_part(4,2,msg) ;
984 if(oType == ardourvis::IMAGEFRAME_ITEM)
986 if(attr == ardourvis::POSITION_CHANGE)
988 handle_imageframe_view_position_update(msg) ;
990 else if(attr == ardourvis::DURATION_CHANGE)
992 handle_imageframe_view_duration_update(msg) ;
994 else if(attr == ardourvis::POSITION_LOCK_CHANGE)
996 handle_imageframe_position_lock_update(msg) ;
998 else if(attr == ardourvis::MAX_DURATION_CHANGE)
1000 handle_imageframe_view_max_duration_update(msg) ;
1002 else if(attr == ardourvis::MAX_DURATION_ENABLE_CHANGE)
1004 handle_imageframe_view_max_duration_enable_update(msg) ;
1006 else if(attr == ardourvis::MIN_DURATION_CHANGE)
1008 handle_imageframe_view_min_duration_update(msg) ;
1010 else if(attr == ardourvis::MIN_DURATION_ENABLE_CHANGE)
1012 handle_imageframe_view_min_duration_enable_update(msg) ;
1014 else
1016 std::string errMsg = "Unknown Attribute during Item Update: " ;
1017 errMsg.append(oType) ;
1018 send_return_failure(errMsg) ;
1021 else if(oType == ardourvis::MARKER_ITEM)
1023 if(attr == ardourvis::POSITION_CHANGE)
1025 handle_marker_view_position_update(msg) ;
1027 else if(attr == ardourvis::DURATION_CHANGE)
1029 handle_marker_view_duration_update(msg) ;
1031 else
1033 std::string errMsg = "Unknown Attribute during Item Update: " ;
1034 errMsg.append(oType) ;
1035 send_return_failure(errMsg) ;
1038 else
1040 std::string errMsg = "Unknown Object type during Item Update: " ;
1041 errMsg.append(oType) ;
1042 send_return_failure(errMsg) ;
1047 * Handle the selection of an Item
1049 * @param msg the received message
1051 void
1052 ImageFrameSocketHandler::handle_item_selected(const char* msg)
1054 // determine the object that requires updating, characters 2-3
1055 std::string oType = get_message_part(2,2,msg) ;
1057 if(oType == std::string(ardourvis::IMAGEFRAME_ITEM))
1059 int position = 4 ; // message type chars
1061 std::string track_id ;
1062 std::string scene_id ;
1063 std::string item_id ;
1064 int track_id_size ;
1065 int scene_id_size ;
1066 int item_id_size ;
1068 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1070 // get the named time axis
1071 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1073 if(!ifta)
1075 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1077 else
1079 // get the parent scene
1080 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1081 if(!iftag)
1083 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1085 else
1087 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1088 if(!ifv)
1090 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1092 else
1094 ifv->set_selected(true) ;
1095 ifta->get_view()->set_selected_imageframe_view(iftag, ifv) ;
1097 thePublicEditor.scroll_timeaxis_to_imageframe_item(ifv) ;
1098 send_return_success() ;
1106 * Handle s session action message
1108 * @param msg the received message
1110 void
1111 ImageFrameSocketHandler::handle_session_action(const char* msg)
1113 std::string actionType = get_message_part(2,2,msg) ;
1115 if(actionType == ardourvis::OPEN_SESSION)
1117 this->handle_open_session(msg) ;
1129 //---------------------------------------------------------------------------------------//
1130 // handlers for specific insert procedures
1133 * Handle the insertion of a new ImaegFrameTimeAxis
1135 * @param msg the received message
1137 void
1138 ImageFrameSocketHandler::handle_insert_imageframe_time_axis(const char* msg)
1140 int position = 4 ; // message type chars
1142 // get the ImageFrameTrack name size
1143 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1144 position += ardourvis::TEXT_SIZE_CHARS ;
1146 // get the image frame track name
1147 std::string track_name = get_message_part(position, track_name_size, msg) ;
1148 position += track_name_size ;
1150 // check we dont already have an time axis with that name
1151 TimeAxisView* tav = thePublicEditor.get_named_time_axis(track_name) ;
1152 if(tav)
1154 std::string errmsg("Track already exists: ") ;
1155 errmsg.append(track_name) ;
1156 send_return_failure(errmsg) ;
1158 else
1160 thePublicEditor.add_imageframe_time_axis(track_name, this) ;
1161 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1163 if(new_tav)
1165 ImageFrameTimeAxis* ifta = (ImageFrameTimeAxis*)new_tav ;
1166 ifta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_removed)) ;
1167 ifta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_renamed), ifta)) ;
1169 send_return_success() ;
1171 else
1173 std::string msg("Addition Failed: ") ;
1174 msg.append(track_name) ;
1175 send_return_failure(msg) ;
1182 * Handle the insertion of a new MarkerTimeAxis
1184 * @param msg the received message
1186 void
1187 ImageFrameSocketHandler::handle_insert_marker_time_axis(const char* msg)
1189 int position = 4 ; // message type chars
1191 // get the ImageFrameTrack name size
1192 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1193 position += ardourvis::TEXT_SIZE_CHARS ;
1195 // get the image frame track name
1196 std::string track_name = get_message_part(position, track_name_size, msg) ;
1197 position += track_name_size ;
1199 // get the size of the name of the associated track
1200 int assoc_track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1201 position += ardourvis::TEXT_SIZE_CHARS ;
1203 // get the name of the track we associate the marker track with
1204 std::string assoc_track_name = get_message_part(position, assoc_track_name_size, msg) ;
1205 position += assoc_track_name_size ;
1207 // check that we dont already have a time axis with that name
1208 TimeAxisView* checkTav = thePublicEditor.get_named_time_axis(track_name) ;
1209 if(checkTav)
1211 std::string errmsg("Track already exists: ") ;
1212 errmsg.append(track_name) ;
1213 send_return_failure(errmsg) ;
1215 else
1217 // check the associated time axis exists
1218 TimeAxisView* assoc_tav = thePublicEditor.get_named_time_axis(assoc_track_name) ;
1219 if(assoc_tav)
1221 thePublicEditor.add_imageframe_marker_time_axis(track_name, assoc_tav, this) ;
1222 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1224 bool added = false ;
1226 if(new_tav)
1228 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(new_tav) ;
1229 if(mta)
1231 added = true ;
1232 mta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_removed)) ;
1233 mta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed), mta)) ;
1237 if(added)
1239 std::string msg("Addition Failed: ") ;
1240 msg.append(track_name) ;
1241 send_return_failure(msg) ;
1244 else
1246 std::string errmsg("No associated Track Found: ") ;
1247 errmsg.append(track_name) ;
1248 send_return_failure(errmsg) ;
1254 * Handle the insertion of a time axis group (a scene)
1256 * @param msg the received message
1258 void
1259 ImageFrameSocketHandler::handle_insert_imageframe_group(const char* msg)
1261 int position = 4 ; // message type chars
1263 // get the ImageFrameTrack name size
1264 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1265 position += ardourvis::TEXT_SIZE_CHARS ;
1267 // get the image frame track name
1268 std::string track_name = get_message_part(position, track_name_size, msg) ;
1269 position += track_name_size ;
1271 // get the scene id size
1272 int scene_id_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1273 position += ardourvis::TEXT_SIZE_CHARS ;
1275 // get the scene id
1276 std::string scene_id = get_message_part(position, scene_id_size, msg) ;
1277 position += scene_id_size ;
1280 // get the named ImageFrameTrack
1281 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_name)) ;
1283 // check we got a valid ImageFrameTimeAxis
1284 if(!ifta)
1286 send_return_failure(std::string("No Image Frame Time Axis Found: ").append(track_name)) ;
1287 return ;
1290 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->add_imageframe_group(scene_id, this) ;
1291 if(!iftag)
1293 send_return_failure(std::string("Image Frame Group insert failed")) ;
1295 else
1297 iftag->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed), iftag)) ;
1298 iftag->GroupRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_removed), iftag)) ;
1299 send_return_success() ;
1305 * Handle the insertion of a new ImageFrameItem
1307 * @param msg the received message
1309 void
1310 ImageFrameSocketHandler::handle_insert_imageframe_view(const char* msg)
1312 int position = 4 ; // message type chars
1314 // get the ImageFrameTrack name size
1315 int track_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
1316 position += 3 ;
1318 // get the ImageFrameTrack Name
1319 std::string imageframe_track_name = get_message_part(position,track_name_size,msg) ;
1320 position += track_name_size ;
1322 // get the scene name size
1323 int scene_size = atoi(get_message_part(position,3,msg).c_str()) ;
1324 position += 3 ;
1326 // get the scene Name
1327 std::string scene_name = get_message_part(position,scene_size,msg) ;
1328 position += scene_size ;
1330 // get the image frame_id size
1331 int image_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1332 position += 3 ;
1334 // get the image frame_id
1335 std::string image_id = get_message_part(position,image_id_size,msg) ;
1336 position += image_id_size ;
1338 // get the start frame value
1339 nframes_t start = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1340 position += 10 ;
1342 // get the duration value
1343 nframes_t duration = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1344 position += 10 ;
1346 //get the named time axis view we about to add an image to
1347 TimeAxisView* tav = thePublicEditor.get_named_time_axis(imageframe_track_name) ;
1348 ImageFrameTimeAxis* ifta = 0 ;
1350 if(tav)
1352 ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1355 if(!ifta)
1357 std::string errmsg("No Parent Image Track Found: ") ;
1358 errmsg.append(imageframe_track_name) ;
1359 send_return_failure(errmsg) ;
1361 // dont really like all these returns mid-way
1362 // but this is goinf to get awfully if..then nested if not
1363 return ;
1366 // check the parent group exists
1367 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_name) ;
1368 if(!iftag)
1370 std::string errmsg("No Image Frame Group Found: ") ;
1371 errmsg.append(scene_name) ;
1372 send_return_failure(errmsg) ;
1373 return ;
1376 // ok, so we have the parent group and track, now we need dome image data
1380 // request the image data from the image compositor
1383 // ctreate a message buffer
1384 std::ostringstream reqBuffer ;
1385 reqBuffer << std::setfill('0') ;
1387 // add the msg type
1388 reqBuffer << REQUEST_DATA << IMAGE_RGB_DATA ;
1390 // add the image track and size
1391 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << track_name_size ;
1392 reqBuffer << imageframe_track_name ;
1394 // add the scene id and size
1395 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << scene_size ;
1396 reqBuffer << scene_name ;
1398 // add the image id and size
1399 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << image_id_size ;
1400 reqBuffer << image_id ;
1402 // add the preferred image height
1403 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << ifta->get_image_display_height() ;
1405 // send the request message
1406 send_message(reqBuffer.str()) ;
1409 // read the reply, the inital image data message
1410 // this gives us the image dimensions and the expected size of the image data
1411 // msg type(4) + image width(3) + height(3) + num channels(3) + size of the image data (32)
1412 std::string init_image_data_msg ;
1413 read_message(init_image_data_msg) ;
1414 int init_msg_pos = 4 ;
1416 int imgWidth = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1417 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1418 int imgHeight = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1419 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1420 int imgChannels = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1421 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1422 int imgSize = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_DATA_MESSAGE_SIZE_CHARS).c_str()) ;
1424 // send a success msg
1425 // we need to do this to keep things moving
1426 send_return_success() ;
1428 // create our image rgb buffer, this holds the image data we receive
1429 unsigned char* rgb_img_buf = new unsigned char[imgSize] ;
1431 int retcode = ::recv(theArdourToCompositorSocket, rgb_img_buf, imgSize, MSG_WAITALL) ;
1433 if(retcode != imgSize)
1435 delete [] rgb_img_buf ;
1436 send_return_failure("Could not create new Image Frame View : image data sizes did not match") ;
1438 else
1440 ImageFrameView* ifv = iftag->add_imageframe_item(image_id, start, duration, rgb_img_buf, (uint32_t)imgWidth, (uint32_t)imgHeight, (uint32_t)imgChannels, this) ;
1441 if(ifv)
1443 ifv->PositionChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_position_change), ifv)) ;
1444 ifv->DurationChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change), ifv)) ;
1445 ifv->ItemRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_removed), ifv)) ;
1447 send_return_success() ;
1449 else
1451 //addition failed. assume duplicate item_id
1452 send_return_failure("Could not create new Image Frame View") ;
1460 * Handle the insertion of a new MarkerItem
1462 * @param msg the received message
1464 void
1465 ImageFrameSocketHandler::handle_insert_marker_view(const char* msg)
1469 //---------------------------------------------------------------------------------------//
1470 // handlers for specific removal procedures
1474 * Handle the removal of an ImageTimeAxis
1476 * @param msg the received message
1478 void
1479 ImageFrameSocketHandler::handle_remove_imageframe_time_axis(const char* msg)
1483 * Handle the removal of an MarkerTimeAxis
1485 * @param msg the received message
1487 void
1488 ImageFrameSocketHandler::handle_remove_marker_time_axis(const char* msg)
1492 * Handle the removal of an ImageFrameTimeAxisGroup
1494 * @param msg the received message
1496 void
1497 ImageFrameSocketHandler::handle_remove_imageframe_time_axis_group(const char* msg)
1501 * Handle the removal of an ImageFrameItem
1503 * @param msg the received message
1505 void
1506 ImageFrameSocketHandler::handle_remove_imageframe_view(const char* msg)
1510 * Handle the removal of an MarkerItem
1512 * @param msg the received message
1514 void
1515 ImageFrameSocketHandler::handle_remove_marker_view(const char* msg)
1522 //---------------------------------------------------------------------------------------//
1523 // handlers for the specific rename procedures
1526 * Handle the renaming of an ImageTimeAxis
1528 * @param msg the received message
1530 void
1531 ImageFrameSocketHandler::handle_rename_imageframe_time_axis(const char* msg)
1533 // msg [MVIT][oldSize][oldId][newSize][newId]
1535 int position = 4 ; // message type chars
1537 // get the old Id size
1538 int old_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1539 position += 3 ;
1541 // get the old id
1542 std::string old_id = get_message_part(position,old_id_size,msg) ;
1543 position += old_id_size ;
1545 //get the new Id size
1546 int new_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1547 position += 3 ;
1549 // get the new Id
1550 std::string new_id = get_message_part(position,new_id_size,msg) ;
1551 position += new_id_size ;
1553 // get the Named time axis
1554 TimeAxisView* tav = thePublicEditor.get_named_time_axis(old_id) ;
1555 if(dynamic_cast<ImageFrameTimeAxis*>(tav))
1557 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1558 ifta->set_time_axis_name(new_id, this) ;
1559 send_return_success() ;
1561 else
1563 std::string msg = "No Image Track Found: " ;
1564 msg.append(old_id) ;
1565 send_return_failure(msg) ;
1570 * Handle the renaming of an MarkerTimeAxis
1572 * @param msg the received message
1574 void
1575 ImageFrameSocketHandler::handle_rename_marker_time_axis(const char* msg)
1579 * Handle the renaming of an ImageFrameItem
1581 * @param msg the received message
1583 void
1584 ImageFrameSocketHandler::handle_rename_imageframe_time_axis_group(const char* msg)
1588 * Handle the renaming of an ImageFrameItem
1590 * @param msg the received message
1592 void
1593 ImageFrameSocketHandler::handle_rename_imageframe_view(const char* msg)
1597 * Handle the renaming of an Marker
1599 * @param msg the received message
1601 void
1602 ImageFrameSocketHandler::handle_rename_marker_view(const char* msg)
1608 //---------------------------------------------------------------------------------------//
1609 // handlers for data request
1612 * Handle a request for the sessnio naem fo the current session
1613 * We return a failure state if no session is open
1615 * @param msg the received message
1617 void
1618 ImageFrameSocketHandler::handle_session_name_request(const char* msg)
1620 ARDOUR::Session* currentSession = thePublicEditor.session() ;
1622 if(currentSession == 0)
1624 // no current session, return failure
1625 std::string msg("No Current Session") ;
1626 send_return_failure(msg) ;
1628 else
1630 std::string sessionName = currentSession->name() ;
1631 std::string sessionPath = currentSession->path() ;
1633 if(sessionPath[sessionPath.length() -1] != '/')
1635 sessionPath.append("/") ;
1638 sessionPath.append(sessionName) ;
1640 std::ostringstream msgBuf ;
1641 msgBuf << ardourvis::RETURN_DATA << ardourvis::SESSION_NAME ;
1642 msgBuf << std::setfill('0') ;
1643 msgBuf << std::setw(ardourvis::TEXT_SIZE_CHARS) << sessionPath.length() ;
1644 msgBuf << sessionPath ;
1645 send_message(msgBuf.str()) ;
1653 //---------------------------------------------------------------------------------------//
1654 // handlers for specific item update changes
1657 * Handle ImageFrameView positional changes
1659 * @param msg the received message
1661 void
1662 ImageFrameSocketHandler::handle_imageframe_view_position_update(const char* msg)
1664 int position = 6 ; // message type chars
1666 std::string track_id ;
1667 std::string scene_id ;
1668 std::string item_id ;
1669 int track_id_size ;
1670 int scene_id_size ;
1671 int item_id_size ;
1673 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1675 nframes_t start_frame = strtoul(get_message_part(position, ardourvis::TIME_VALUE_CHARS, msg).c_str(), 0, 10) ;
1676 position += ardourvis::TIME_VALUE_CHARS ;
1678 // get the named time axis
1679 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1681 if(!ifta)
1683 send_return_failure(std::string("No parent Image Track found: ").append(track_id)) ;
1684 return ;
1687 // get the parent scene
1688 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1689 if(!iftag)
1691 send_return_failure(std::string("No parent Scene found: ").append(scene_id)) ;
1692 return ;
1695 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1697 if(!ifv)
1699 send_return_failure(std::string("No Image Frame Item found: ").append(item_id)) ;
1700 return ;
1704 ifv->set_position(start_frame, this) ;
1705 send_return_success() ;
1709 * Handle ImageFrameView Duration changes
1711 * @param msg the received message
1713 void
1714 ImageFrameSocketHandler::handle_imageframe_view_duration_update(const char* msg)
1716 int position = 6 ; // message type chars
1718 std::string track_id ;
1719 std::string scene_id ;
1720 std::string item_id ;
1721 int track_id_size ;
1722 int scene_id_size ;
1723 int item_id_size ;
1725 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1727 nframes_t duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1728 position += ardourvis::TIME_VALUE_CHARS ;
1730 // get the named time axis
1731 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1733 if(!ifta)
1735 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1736 return ;
1739 // get the parent scene
1740 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1741 if(!iftag)
1743 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1744 return ;
1747 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1749 if(!ifv)
1751 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1752 return ;
1755 ifv->set_duration(duration, this) ;
1756 send_return_success() ;
1760 * Handle ImageFrameView Position Lock Constraint changes
1762 * @param msg the received message
1764 void
1765 ImageFrameSocketHandler::handle_imageframe_position_lock_update(const char* msg)
1767 int position = 6 ; // message type chars
1769 std::string track_id ;
1770 std::string group_id ;
1771 std::string item_id ;
1772 int track_id_size ;
1773 int group_id_size ;
1774 int item_id_size ;
1776 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1778 std::string pos_lock = get_message_part(position,1,msg) ;
1779 bool pos_lock_active = false ;
1781 if(pos_lock == "0")
1783 pos_lock_active = false ;
1785 else if(pos_lock == "1")
1787 pos_lock_active = true ;
1789 else
1791 send_return_failure(std::string("Unknown Value used during Position Loack: ").append(pos_lock)) ;
1792 return ;
1795 position += 1 ;
1797 int errcode ;
1798 std::string errmsg ;
1799 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1800 if(ifv)
1802 ifv->set_position_locked(pos_lock_active, this) ;
1803 send_return_success() ;
1805 else
1807 send_return_failure(errmsg) ;
1812 * Handle ImageFrameView Maximum Duration changes
1814 * @param msg the received message
1816 void
1817 ImageFrameSocketHandler::handle_imageframe_view_max_duration_update(const char* msg)
1819 int position = 6 ; // message type chars
1821 std::string track_id ;
1822 std::string group_id ;
1823 std::string item_id ;
1824 int track_id_size ;
1825 int group_id_size ;
1826 int item_id_size ;
1828 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1830 nframes_t max_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1831 position += ardourvis::TIME_VALUE_CHARS ;
1833 int errcode ;
1834 std::string errmsg ;
1835 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1836 if(ifv)
1838 ifv->set_max_duration(max_duration, this) ;
1839 send_return_success() ;
1841 else
1843 send_return_failure(errmsg) ;
1848 * Handle image frame max duration enable constraint changes
1850 * @param msg the received message
1852 void
1853 ImageFrameSocketHandler::handle_imageframe_view_max_duration_enable_update(const char* msg)
1855 int position = 6 ; // message type chars
1857 std::string track_id ;
1858 std::string group_id ;
1859 std::string item_id ;
1860 int track_id_size ;
1861 int group_id_size ;
1862 int item_id_size ;
1864 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1866 std::string active = get_message_part(position,1,msg) ;
1867 bool max_duration_active = false ;
1869 if(active == "0")
1871 max_duration_active = false ;
1873 else if(active == "1")
1875 max_duration_active = true ;
1877 else
1879 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1880 return ;
1883 position += 1 ;
1885 int errcode ;
1886 std::string errmsg ;
1887 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1888 if(ifv)
1890 ifv->set_max_duration_active(max_duration_active, this) ;
1891 send_return_success() ;
1893 else
1895 send_return_failure(errmsg) ;
1900 * Handle ImageFrameView Minimum Duration changes
1902 * @param msg the received message
1904 void
1905 ImageFrameSocketHandler::handle_imageframe_view_min_duration_update(const char* msg)
1907 int position = 6 ; // message type chars
1909 std::string track_id ;
1910 std::string group_id ;
1911 std::string item_id ;
1912 int track_id_size ;
1913 int group_id_size ;
1914 int item_id_size ;
1916 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1918 nframes_t min_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1919 position += ardourvis::TIME_VALUE_CHARS ;
1921 int errcode ;
1922 std::string errmsg ;
1923 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1924 if(ifv)
1926 ifv->set_min_duration(min_duration, this) ;
1927 send_return_success() ;
1929 else
1931 send_return_failure(errmsg) ;
1936 * Handle image frame min duration enable constraint changes
1938 * @param msg the received message
1940 void
1941 ImageFrameSocketHandler::handle_imageframe_view_min_duration_enable_update(const char* msg)
1943 int position = 6 ; // message type chars
1945 std::string track_id ;
1946 std::string group_id ;
1947 std::string item_id ;
1948 int track_id_size ;
1949 int group_id_size ;
1950 int item_id_size ;
1952 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1954 std::string active = get_message_part(position,1,msg) ;
1955 bool min_duration_active = false ;
1957 if(active == "0")
1959 min_duration_active = false ;
1961 else if(active == "1")
1963 min_duration_active = true ;
1965 else
1967 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1968 return ;
1971 position += 1 ;
1973 int errcode ;
1974 std::string errmsg ;
1975 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1976 if(ifv)
1978 ifv->set_min_duration_active(min_duration_active, this) ;
1979 send_return_success() ;
1981 else
1983 send_return_failure(errmsg) ;
1988 * Handle MarkerView position changes
1990 * @param msg the received message
1992 void
1993 ImageFrameSocketHandler::handle_marker_view_position_update(const char* msg)
1997 * Handle MarkerView duration changes
1999 * @param msg the received message
2001 void
2002 ImageFrameSocketHandler::handle_marker_view_duration_update(const char* msg)
2006 * Handle MarkerView Position Lock Constraint changes
2008 * @param msg the received message
2010 void
2011 ImageFrameSocketHandler::handle_marker_view_position_lock_update(const char* msg)
2016 * Handle MarkerView maximum duration changes
2018 * @param msg the received message
2020 void
2021 ImageFrameSocketHandler::handle_marker_view_max_duration_update(const char* msg)
2025 * Handle MarkerView minimum duration changes
2027 * @param msg the received message
2029 void
2030 ImageFrameSocketHandler::handle_marker_view_min_duration_update(const char* msg)
2037 //---------------------------------------------------------------------------------------//
2038 // handlers for Session Actions
2041 * Handle the opening of a named audio session
2043 * @param msg the received message
2045 void
2046 ImageFrameSocketHandler::handle_open_session(const char* msg)
2048 // msg [SAOS][sessionSize][sessionPath]
2050 int position = 4 ; // message type chars
2052 // get the session name size
2053 int session_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
2054 position += 3 ;
2056 // get the session name
2057 std::string session_name = get_message_part(position,session_name_size,msg) ;
2058 position += session_name_size ;
2061 // open the session
2062 std::string path, name ;
2063 bool isnew;
2065 if (ARDOUR::find_session(session_name, path, name, isnew) == 0) {
2066 if (ARDOUR_UI::instance()->load_session (path, name) == 0) {
2067 send_return_success() ;
2068 } else {
2069 std::string retMsg = "Failed to load Session" ;
2070 send_return_failure(retMsg) ;
2072 } else {
2073 std::string retMsg = "Failed to find Session" ;
2074 send_return_failure(retMsg) ;
2080 * Handle the closing of a named audio session
2082 * @param msg the received message
2084 void
2085 ImageFrameSocketHandler::handle_closed_session(const char* msg)
2088 //---------------------------------------------------------------------------------------//
2089 // handlers for the shutdown of the Image Compositor
2092 * Handle the shutdown message from the image compositor
2094 * @param msg the received message
2096 void
2097 ImageFrameSocketHandler::handle_shutdown(const char* msg)
2099 CompositorSocketShutdown() ; /* EMIT_SIGNAL */
2111 //---------------------------------------------------------------------------------------//
2112 // convenince methods to break up messages
2115 * Returns part of the received message as a std::string
2117 * @param start the start character
2118 * @param num_chars the number of characters to read
2119 * @param the message to break apart
2120 * @return the sub string of the message
2122 std::string
2123 ImageFrameSocketHandler::get_message_part(int start, int32_t num_chars, const char* msg)
2125 char buf[num_chars + 1] ;
2126 strncpy(buf,msg+start,num_chars) ;
2127 buf[num_chars] = '\0' ;
2128 std::string s(buf) ;
2130 return(s) ;
2136 * break up am image item description message
2137 * we break the mesage up into the parent Image Track id and size,
2138 * the parent group id and size, and the image id and size
2140 * @param track_id
2141 * @param track_id_size
2142 * @param scene_id
2143 * @param scene_id_size
2144 * @param item_id
2145 * @param item_id_size
2147 void
2148 ImageFrameSocketHandler::decompose_imageframe_item_desc(const char* msg, int& position, std::string& track_id,
2149 int& track_id_size, std::string& scene_id, int& scene_id_size, std::string& item_id, int& item_id_size)
2151 // get the track Id size
2152 track_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2153 position += ardourvis::TEXT_SIZE_CHARS ;
2155 // get the track id
2156 track_id = get_message_part(position,track_id_size,msg) ;
2157 position += track_id_size ;
2159 // get the track Id size
2160 scene_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2161 position += ardourvis::TEXT_SIZE_CHARS ;
2163 // get the scene id
2164 scene_id = get_message_part(position,scene_id_size,msg) ;
2165 position += scene_id_size ;
2167 // get the item id size
2168 item_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2169 position += ardourvis::TEXT_SIZE_CHARS ;
2171 // get the item id
2172 item_id = get_message_part(position,item_id_size,msg) ;
2173 position += item_id_size ;
2177 * Compose a description of the specified image frame view
2178 * The description consists of the parent track name size and name,
2179 * the parent group name size and name, and the item name size and name
2181 * @param ifv the item to string_compose a description of
2182 * @param buffer the buffer to write the description
2184 void
2185 ImageFrameSocketHandler::compose_imageframe_item_desc(ImageFrameView* ifv, std::ostringstream& buffer)
2187 buffer << std::setw(3) << ifv->get_time_axis_group()->get_view().trackview().name().length() ;
2188 buffer << ifv->get_time_axis_group()->get_view().trackview().name() ;
2190 // add the parent scene
2191 buffer << std::setw(3) << ifv->get_time_axis_group()->get_group_name().length() ;
2192 buffer << ifv->get_time_axis_group()->get_group_name() ;
2194 // add the ImageFrameItem id length and Id
2195 buffer << setw(3) << ifv->get_item_name().length() ;
2196 buffer << ifv->get_item_name() ;
2200 * Compose a description of the specified marker view
2201 * The description consists of the parent track name size and name,
2202 * and the item name size and name
2204 * @param mv the item to string_compose a description of
2205 * @param buffer the buffer to write the description
2207 void
2208 ImageFrameSocketHandler::compose_marker_item_desc(MarkerView* mv, std::ostringstream& buffer)
2210 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(&mv->get_time_axis_view()) ;
2212 if(!mta)
2214 return ;
2217 buffer << std::setw(3) << mta->name().length() ;
2218 buffer << mta->name() ;
2220 buffer << std::setw(3) << mv->get_item_name().length() ;
2221 buffer << mv->get_item_name() ;
2226 * Returns the ImageFrameView from the specified description
2227 * The errcode parameter is used to indicate the item which caused
2228 * an error on failure of this method
2229 * 0 = success
2230 * 1 = the track item was not found
2231 * 2 = the group item was not found
2232 * 3 = the imageframe item was not found
2234 * @paran track_id the track on which the item is placed
2235 * @param group_id the group in which the item is a member
2236 * @param item_id the id of the item
2237 * @param int32_t reference used for error codes on failure
2238 * @param errmsg populated with a description of the error on failure
2239 * @return the described item on success, 0 otherwise
2241 ImageFrameView*
2242 ImageFrameSocketHandler::get_imageframe_view_from_desc(const string & track_id, const string & group_id, const string & item_id, int& errcode, std::string& errmsg)
2244 ImageFrameView* item = 0 ;
2246 // get the named time axis
2247 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
2249 if(!ifta)
2251 errcode = 1 ;
2252 errmsg = std::string("Image Frame Time Axis Not Found: ").append(track_id) ;
2254 else
2256 // get the parent scene
2257 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(group_id) ;
2258 if(!iftag)
2260 errcode = 2 ;
2261 errmsg = std::string("Image Frame Group Not Found: ").append(group_id) ;
2263 else
2265 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
2266 if(!ifv)
2268 errcode = 3 ;
2269 errmsg = std::string("Image Frame Item Not Found: ").append(item_id) ;
2271 else
2273 // yay!!
2274 item = ifv ;
2275 errcode = 0 ;
2280 return(item) ;
2283 //---------------------------------------------------------------------------------------//
2284 // Convenince Message Send Methods
2286 #ifndef MSG_NOSIGNAL
2287 #define MSG_NOSIGNAL 0
2288 #endif
2291 * Sends a message throught the socket
2293 * @param msg the message to send
2294 * @return the return value of the socket call
2297 ImageFrameSocketHandler::send_message(const string & msg)
2299 //std::cout << "Sending Message [" << msg << "]\n" ;
2300 int retcode = ::send(theArdourToCompositorSocket, msg.c_str(), msg.length(), MSG_NOSIGNAL) ;
2302 return(retcode) ;
2306 * Reads a message from the Socket
2308 * @param msg a string to populate with the received message
2309 * @return the return value from the socket call
2312 ImageFrameSocketHandler::read_message(std::string& msg)
2314 char buf[ardourvis::MAX_MSG_SIZE + 1] ;
2315 memset(buf, 0, (ardourvis::MAX_MSG_SIZE + 1)) ;
2317 msg = "" ;
2318 int retcode = ::recv(theArdourToCompositorSocket, buf, ardourvis::MAX_MSG_SIZE, 0) ;
2320 msg = buf ;
2321 //std::cout << "Received Message [" << msg << "]\n" ;
2323 return(retcode) ;
2328 * Convenience method to string_compose and send a success messasge back to the Image Compositor
2331 void
2332 ImageFrameSocketHandler::send_return_success()
2334 send_message(ardourvis::RETURN_TRUE) ;
2338 * Convenience method to string_compose and send a failure messasge back to the Image Compositor
2340 * @param msg the failure message
2342 void
2343 ImageFrameSocketHandler::send_return_failure(const std::string& msg)
2345 std::ostringstream buf ;
2346 buf << std::setfill('0') ;
2347 buf << ardourvis::RETURN_FALSE ;
2348 buf << std::setw(3) << msg.length(); ;
2349 buf << msg ;
2351 send_message(buf.str()) ;