remove global LV2 external GUI list, always call LV2 UI cleanup method when appropria...
[ardour2.git] / gtk2_ardour / imageframe_socket_handler.cc
blob9279a177eeb750d4b70ae51531f3e3d58d4d0af9
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>
48 #include <unistd.h>
50 using namespace std;
51 using namespace ardourvis ;
52 using namespace sigc;
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 read_result();
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
330 void
331 ImageFrameSocketHandler::send_imageframe_time_axis_renamed(const string & new_id, const 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
338 return ;
341 // create a message buffer
342 std::ostringstream msgBuffer ;
343 msgBuffer << std::setfill('0') ;
345 // add the msg type
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
359 read_result();
362 //------------------------
363 // MarkerTimeAxis Messages
366 * Sends a message stating that the named marker time axis has been removed
368 * @param track_id the unique id of the removed image frame time axis
369 * @param src the identity of the object that initiated the change
371 void
372 ImageFrameSocketHandler::send_marker_time_axis_removed(const string & track_id, void* src)
374 if(this == src || src == 0)
376 // ie the change originated from us, then dont send any message back
377 return ;
380 // create a message buffer
381 std::ostringstream msgBuffer ;
382 msgBuffer << std::setfill('0') ;
384 // add the msg type
385 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_TIME_AXIS ;
387 // add the id length, and the id
388 msgBuffer << std::setw(3) << track_id.length() ;
389 msgBuffer << track_id ;
391 send_message(msgBuffer.str()) ;
393 // XXX should do something with the return
394 read_result();
398 * Sends a message indicating that an MarkerTimeAxis has been renamed
400 * @param new_id the new name, or Id, of the track
401 * @param old_id the old name, or Id, of the track
402 * @param src the identity of the object that initiated the change
403 * @param time_axis the time axis that has changed
405 void
406 ImageFrameSocketHandler::send_marker_time_axis_renamed(const string & new_id, const string & old_id, void* src, MarkerTimeAxis* time_axis)
408 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed), new_id, old_id, src, time_axis));
410 if(this == src || src == 0)
412 // ie the change originated from us, then dont send any message back
413 return ;
416 // ctreate a message buffer
417 std::ostringstream msgBuffer ;
418 msgBuffer << std::setfill('0') ;
420 // add the msg type
421 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_TIME_AXIS ;
423 // add the old id and length
424 msgBuffer << std::setw(3) << old_id.length() ;
425 msgBuffer << old_id ;
427 // add the new id and length
428 msgBuffer << std::setw(3) << new_id.length() ;
429 msgBuffer << new_id ;
431 send_message(msgBuffer.str()) ;
433 // XXX should do something with the return
434 read_result();
437 //---------------------------------
438 // ImageFrameTimeAxisGroup Messages
441 * Sends a message stating that the group has been removed
443 * @param group_id the unique id of the removed image frame time axis
444 * @param src the identity of the object that initiated the change
445 * @param group the group that has changed
447 void
448 ImageFrameSocketHandler::send_imageframe_time_axis_group_removed(const string & group_id, void* src, ImageFrameTimeAxisGroup* group)
450 if(this == src || src == 0)
452 // ie the change originated from us, then dont send any message back
453 return ;
456 // create a message buffer
457 std::ostringstream msgBuffer ;
458 msgBuffer << std::setfill('0') ;
460 // add the msg type
461 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_GROUP ;
463 // add the id length, and the id of the parent image time axis
464 std::string track_id = group->get_view().trackview().name() ;
465 msgBuffer << std::setw(3) << track_id.length() ;
466 msgBuffer << track_id ;
468 // add the group id and length
469 msgBuffer << std::setw(3) << group_id.length() ;
470 msgBuffer << group_id ;
472 send_message(msgBuffer.str()) ;
474 // XXX should do something with the return
475 read_result();
479 * Send a message indicating that an ImageFrameTimeAxisGroup has been renamed
481 * @param new_id the new name, or Id, of the group
482 * @param old_id the old name, or Id, of the group
483 * @param src the identity of the object that initiated the change
484 * @param group the group that has changed
486 void
487 ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed(const string & new_id, const string & old_id, void* src, ImageFrameTimeAxisGroup* group)
489 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed), new_id, old_id, src, group));
491 if(this == src || src == 0)
493 // ie the change originated from us, then dont send any message back
494 return ;
497 // ctreate a message buffer
498 std::ostringstream msgBuffer ;
499 msgBuffer << std::setfill('0') ;
501 // add the msg type
502 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_GROUP ;
504 // add the track this group is upon
505 std::string track_id = group->get_view().trackview().name() ;
506 msgBuffer << std::setw(3) << track_id.length() << track_id ;
508 // add the old id and length
509 msgBuffer << std::setw(3) << old_id.length() ;
510 msgBuffer << old_id ;
512 // add the new id and length
513 msgBuffer << std::setw(3) << new_id.length() ;
514 msgBuffer << new_id ;
516 send_message(msgBuffer.str()) ;
518 // XXX should do something with the return
519 read_result();
523 //---------------------------------
524 // ImageFrameView Messages
527 * Send an Image Frame View Item position changed message
529 * @param pos the new position value
530 * @param src the identity of the object that initiated the change
531 * @param item the time axis item whos position has changed
533 void
534 ImageFrameSocketHandler::send_imageframe_view_position_change(nframes_t pos, void* src, ImageFrameView* item)
536 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_position_change), pos, src, item));
538 if(this == src || src == 0)
540 return ;
543 // create a message buffer
544 std::ostringstream msgBuffer ;
545 msgBuffer << std::setfill('0') ;
547 // add the msg type
548 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::POSITION_CHANGE ;
550 // add the item description
551 this->compose_imageframe_item_desc(item, msgBuffer) ;
553 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
555 send_message(msgBuffer.str()) ;
557 // XXX should do something with the return
558 read_result();
562 * Send a Image Frame View item duration changed message
564 * @param dur the the new duration value
565 * @param src the identity of the object that initiated the change
566 * @param item the item which has had a duration change
568 void
569 ImageFrameSocketHandler::send_imageframe_view_duration_change(nframes_t dur, void* src, ImageFrameView* item)
571 // ENSURE_GUI_THREAD(bind (mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change), dur, src, item));
573 if(this == src || src == 0)
575 return ;
578 // create a message buffer
579 std::ostringstream msgBuffer ;
580 msgBuffer << std::setfill('0') ;
582 // add the msg type
583 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::IMAGEFRAME_ITEM << ardourvis::DURATION_CHANGE ;
585 this->compose_imageframe_item_desc(item, msgBuffer) ;
587 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
589 send_message(msgBuffer.str()) ;
591 // XXX should do something with the return
592 read_result();
596 * Send a message indicating that an ImageFrameView has been renamed
598 * @param item the ImageFrameView which has been renamed
599 * @param src the identity of the object that initiated the change
600 * @param item the renamed item
602 void
603 ImageFrameSocketHandler::send_imageframe_view_renamed(const string & new_id, const string & old_id, void* src, ImageFrameView* item)
605 if(this == src || src == 0)
607 // ie the change originated from us, then dont send any message back
608 return ;
611 // ctreate a message buffer
612 std::ostringstream msgBuffer ;
613 msgBuffer << std::setfill('0') ;
615 // add the msg type
616 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::IMAGEFRAME_ITEM ;
618 this->compose_imageframe_item_desc(item, msgBuffer) ;
620 // add the old id and length
621 msgBuffer << std::setw(3) << old_id.length() ;
622 msgBuffer << old_id ;
624 send_message(msgBuffer.str()) ;
626 // XXX should do something with the return
627 read_result();
631 * Send a message indicating that an ImageFrameView item has been removed message
633 * @param item_id the id of the item that was removed
634 * @param item the removed item
636 void
637 ImageFrameSocketHandler::send_imageframe_view_removed(const string & item_id, void* src, ImageFrameView* item)
639 if(this == src || src == 0)
641 // ie the change originated from us, then dont send any message back
642 return ;
645 // create a message buffer
646 std::ostringstream msgBuffer ;
647 msgBuffer << std::setfill('0') ;
649 // add the msg type
650 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::IMAGEFRAME_ITEM ;
652 // add the id length, and the id
653 ImageFrameTimeAxisGroup* parentGroup = item->get_time_axis_group() ;
654 std::string group_id = parentGroup->get_group_name() ;
655 std::string track_id = parentGroup->get_view().trackview().name() ;
656 msgBuffer << std::setw(3) << track_id.length() << track_id ;
657 msgBuffer << std::setw(3) << group_id.length() << group_id ;
658 msgBuffer << std::setw(3) << item_id.length() << item_id ;
660 send_message(msgBuffer.str()) ;
662 // XXX should do something with the return
663 read_result();
669 //---------------------------------
670 // MarkerView Messages
673 * Send a Marker View Item position changed message
675 * @param pos the new position value
676 * @param src the identity of the object that initiated the change
677 * @param item the time axis item whos position has changed
679 void
680 ImageFrameSocketHandler::send_marker_view_position_change(nframes_t pos, void* src, MarkerView* item)
682 if(this == src || src == 0)
684 return ;
687 // create a message buffer
688 std::ostringstream msgBuffer ;
689 msgBuffer << std::setfill('0') ;
691 // add the msg type
692 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::POSITION_CHANGE ;
694 // add the item description
695 this->compose_marker_item_desc(item, msgBuffer) ;
697 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << pos ;
699 send_message(msgBuffer.str()) ;
701 // XXX should do something with the return
702 read_result();
706 * Send a Marker View item duration changed message
708 * @param dur the new duration value
709 * @param src the identity of the object that initiated the change
710 * @param item the time axis item whos position has changed
712 void
713 ImageFrameSocketHandler::send_marker_view_duration_change(nframes_t dur, void* src, MarkerView* item)
715 if(this == src || src == 0)
717 return ;
720 // create a message buffer
721 std::ostringstream msgBuffer ;
722 msgBuffer << std::setfill('0') ;
724 // add the msg type
725 msgBuffer << ardourvis::ITEM_UPDATE << ardourvis::MARKER_ITEM << ardourvis::DURATION_CHANGE ;
727 this->compose_marker_item_desc(item, msgBuffer) ;
729 msgBuffer << std::setw(ardourvis::TIME_VALUE_CHARS) << dur ;
731 send_message(msgBuffer.str()) ;
733 // XXX should do something with the return
734 read_result();
739 * Send a message indicating that a MarkerView has been renamed
741 * @param new_id the new_id of the object
742 * @param old_id the old_id of the object
743 * @param src the identity of the object that initiated the change
744 * @param item the MarkerView which has been renamed
746 void
747 ImageFrameSocketHandler::send_marker_view_renamed(const string & new_id, const string & old_id, void* src, MarkerView* item)
749 if(this == src || src == 0)
751 // ie the change originated from us, then dont send any message back
752 return ;
755 // ctreate a message buffer
756 std::ostringstream msgBuffer ;
757 msgBuffer << std::setfill('0') ;
759 // add the msg type
760 msgBuffer << ardourvis::RENAME_ITEM << ardourvis::MARKER_ITEM ;
762 this->compose_marker_item_desc(item, msgBuffer) ;
764 // add the old id and length
765 msgBuffer << std::setw(3) << old_id.length() ;
766 msgBuffer << old_id ;
768 send_message(msgBuffer.str()) ;
770 // XXX should do something with the return
771 read_result();
775 * Send a message indicating that a MarkerView item has been removed message
777 * @param item_id the id of the item that was removed
778 * @param src the identity of the object that initiated the change
779 * @param item the MarkerView which has been removed
781 void
782 ImageFrameSocketHandler::send_marker_view_removed(const string & item_id, void* src, MarkerView* item)
784 if(this == src || src == 0)
786 // ie the change originated from us, then dont send any message back
787 return ;
790 // create a message buffer
791 std::ostringstream msgBuffer ;
792 msgBuffer << std::setfill('0') ;
794 // add the msg type
795 msgBuffer << ardourvis::REMOVE_ITEM << ardourvis::MARKER_ITEM ;
797 // add the id length, and the id
798 std::string track_id = item->get_time_axis_view().name() ;
799 msgBuffer << std::setw(3) << track_id.length() << track_id ;
800 msgBuffer << std::setw(3) << item_id.length() << item_id ;
802 send_message(msgBuffer.str()) ;
804 // XXX should do something with the return
805 read_result();
818 //---------------------------------------------------------------------------------------//
819 //---------------------------------------------------------------------------------------//
820 //---------------------------------------------------------------------------------------//
821 // Message breakdown ie avoid a big if...then...else
825 * Handle insert item requests
827 * @param msg the received message
829 void
830 ImageFrameSocketHandler::handle_insert_message(const char* msg)
832 // handle the insert item message
833 // determine the object type to insert based upon characters 2-3
835 std::string oType = get_message_part(2,2,msg) ;
837 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
839 this->handle_insert_imageframe_time_axis(msg) ;
841 else if (oType == ardourvis::MARKER_TIME_AXIS)
843 this->handle_insert_marker_time_axis(msg) ;
845 else if (oType == ardourvis::IMAGEFRAME_GROUP)
847 this->handle_insert_imageframe_group(msg) ;
849 else if (oType == ardourvis::IMAGEFRAME_ITEM)
851 this->handle_insert_imageframe_view(msg) ;
853 else if (oType == ardourvis::MARKER_ITEM)
855 this->handle_insert_marker_view(msg) ;
857 else
859 std::string errMsg = "Unknown Object type during insert: " ;
860 errMsg.append(oType) ;
861 send_return_failure(errMsg) ;
866 * Handle remove item requests
868 * @param msg the received message
870 void
871 ImageFrameSocketHandler::handle_remove_message(const char* msg)
873 // handle the removal of an item message
874 // determine the object type to remove based upon characters 2-3
876 std::string oType = get_message_part(2,2,msg) ;
878 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
880 this->handle_remove_imageframe_time_axis(msg) ;
882 else if (oType == ardourvis::MARKER_TIME_AXIS)
884 this->handle_remove_marker_time_axis(msg) ;
886 else if (oType == ardourvis::IMAGEFRAME_ITEM)
888 this->handle_remove_imageframe_view(msg) ;
890 else if (oType == ardourvis::MARKER_ITEM)
892 this->handle_remove_marker_view(msg) ;
894 else
896 std::string errMsg = "Unknown Object type during Remove: " ;
897 errMsg.append(oType) ;
898 send_return_failure(errMsg) ;
903 * Handle rename item requests
905 * @param msg the received message
907 void
908 ImageFrameSocketHandler::handle_rename_message(const char* msg)
910 // handle the renaming of an item message
911 // determine the object type to rename based upon characters 2-3
913 std::string oType = get_message_part(2,2,msg) ;
915 if(oType == ardourvis::IMAGEFRAME_TIME_AXIS)
917 this->handle_rename_imageframe_time_axis(msg) ;
919 else if (oType == ardourvis::MARKER_TIME_AXIS)
921 this->handle_rename_marker_time_axis(msg) ;
923 else if (oType == ardourvis::IMAGEFRAME_ITEM)
925 this->handle_rename_imageframe_view(msg) ;
927 else if (oType == ardourvis::MARKER_ITEM)
929 this->handle_rename_marker_view(msg) ;
931 else
933 std::string errMsg = "Unknown Object type during Rename: " ;
934 errMsg.append(oType) ;
935 send_return_failure(errMsg) ;
940 * Handle a request for session information
942 * @param msg the received message
944 void
945 ImageFrameSocketHandler::handle_request_data(const char* msg)
947 // determine the request type
948 std::string reqType = get_message_part(2,2,msg) ;
950 if(reqType == ardourvis::SESSION_NAME)
952 handle_session_name_request(msg) ;
957 * Handle the update of a particular item
959 * @param msg the received message
961 void
962 ImageFrameSocketHandler::handle_item_update_message(const char* msg)
964 // determin the object that requires updating, characters 2-3
965 std::string oType = get_message_part(2,2,msg) ;
967 // What needs updating? chars 4-5
968 std::string attr = get_message_part(4,2,msg) ;
970 if(oType == ardourvis::IMAGEFRAME_ITEM)
972 if(attr == ardourvis::POSITION_CHANGE)
974 handle_imageframe_view_position_update(msg) ;
976 else if(attr == ardourvis::DURATION_CHANGE)
978 handle_imageframe_view_duration_update(msg) ;
980 else if(attr == ardourvis::POSITION_LOCK_CHANGE)
982 handle_imageframe_position_lock_update(msg) ;
984 else if(attr == ardourvis::MAX_DURATION_CHANGE)
986 handle_imageframe_view_max_duration_update(msg) ;
988 else if(attr == ardourvis::MAX_DURATION_ENABLE_CHANGE)
990 handle_imageframe_view_max_duration_enable_update(msg) ;
992 else if(attr == ardourvis::MIN_DURATION_CHANGE)
994 handle_imageframe_view_min_duration_update(msg) ;
996 else if(attr == ardourvis::MIN_DURATION_ENABLE_CHANGE)
998 handle_imageframe_view_min_duration_enable_update(msg) ;
1000 else
1002 std::string errMsg = "Unknown Attribute during Item Update: " ;
1003 errMsg.append(oType) ;
1004 send_return_failure(errMsg) ;
1007 else if(oType == ardourvis::MARKER_ITEM)
1009 if(attr == ardourvis::POSITION_CHANGE)
1011 handle_marker_view_position_update(msg) ;
1013 else if(attr == ardourvis::DURATION_CHANGE)
1015 handle_marker_view_duration_update(msg) ;
1017 else
1019 std::string errMsg = "Unknown Attribute during Item Update: " ;
1020 errMsg.append(oType) ;
1021 send_return_failure(errMsg) ;
1024 else
1026 std::string errMsg = "Unknown Object type during Item Update: " ;
1027 errMsg.append(oType) ;
1028 send_return_failure(errMsg) ;
1033 * Handle the selection of an Item
1035 * @param msg the received message
1037 void
1038 ImageFrameSocketHandler::handle_item_selected(const char* msg)
1040 // determine the object that requires updating, characters 2-3
1041 std::string oType = get_message_part(2,2,msg) ;
1043 if(oType == std::string(ardourvis::IMAGEFRAME_ITEM))
1045 int position = 4 ; // message type chars
1047 std::string track_id ;
1048 std::string scene_id ;
1049 std::string item_id ;
1050 int track_id_size ;
1051 int scene_id_size ;
1052 int item_id_size ;
1054 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1056 // get the named time axis
1057 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1059 if(!ifta)
1061 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1063 else
1065 // get the parent scene
1066 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1067 if(!iftag)
1069 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1071 else
1073 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1074 if(!ifv)
1076 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1078 else
1080 ifv->set_selected(true) ;
1081 ifta->get_view()->set_selected_imageframe_view(iftag, ifv) ;
1083 thePublicEditor.scroll_timeaxis_to_imageframe_item(ifv) ;
1084 send_return_success() ;
1092 * Handle s session action message
1094 * @param msg the received message
1096 void
1097 ImageFrameSocketHandler::handle_session_action(const char* msg)
1099 std::string actionType = get_message_part(2,2,msg) ;
1101 if(actionType == ardourvis::OPEN_SESSION)
1103 this->handle_open_session(msg) ;
1115 //---------------------------------------------------------------------------------------//
1116 // handlers for specific insert procedures
1119 * Handle the insertion of a new ImaegFrameTimeAxis
1121 * @param msg the received message
1123 void
1124 ImageFrameSocketHandler::handle_insert_imageframe_time_axis(const char* msg)
1126 int position = 4 ; // message type chars
1128 // get the ImageFrameTrack name size
1129 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1130 position += ardourvis::TEXT_SIZE_CHARS ;
1132 // get the image frame track name
1133 std::string track_name = get_message_part(position, track_name_size, msg) ;
1134 position += track_name_size ;
1136 // check we dont already have an time axis with that name
1137 TimeAxisView* tav = thePublicEditor.get_named_time_axis(track_name) ;
1138 if(tav)
1140 std::string errmsg("Track already exists: ") ;
1141 errmsg.append(track_name) ;
1142 send_return_failure(errmsg) ;
1144 else
1146 thePublicEditor.add_imageframe_time_axis(track_name, this) ;
1147 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1149 if(new_tav)
1151 ImageFrameTimeAxis* ifta = (ImageFrameTimeAxis*)new_tav ;
1152 ifta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_removed)) ;
1153 ifta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_renamed), ifta)) ;
1155 send_return_success() ;
1157 else
1159 std::string msg("Addition Failed: ") ;
1160 msg.append(track_name) ;
1161 send_return_failure(msg) ;
1168 * Handle the insertion of a new MarkerTimeAxis
1170 * @param msg the received message
1172 void
1173 ImageFrameSocketHandler::handle_insert_marker_time_axis(const char* msg)
1175 int position = 4 ; // message type chars
1177 // get the ImageFrameTrack name size
1178 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1179 position += ardourvis::TEXT_SIZE_CHARS ;
1181 // get the image frame track name
1182 std::string track_name = get_message_part(position, track_name_size, msg) ;
1183 position += track_name_size ;
1185 // get the size of the name of the associated track
1186 int assoc_track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1187 position += ardourvis::TEXT_SIZE_CHARS ;
1189 // get the name of the track we associate the marker track with
1190 std::string assoc_track_name = get_message_part(position, assoc_track_name_size, msg) ;
1191 position += assoc_track_name_size ;
1193 // check that we dont already have a time axis with that name
1194 TimeAxisView* checkTav = thePublicEditor.get_named_time_axis(track_name) ;
1195 if(checkTav)
1197 std::string errmsg("Track already exists: ") ;
1198 errmsg.append(track_name) ;
1199 send_return_failure(errmsg) ;
1201 else
1203 // check the associated time axis exists
1204 TimeAxisView* assoc_tav = thePublicEditor.get_named_time_axis(assoc_track_name) ;
1205 if(assoc_tav)
1207 thePublicEditor.add_imageframe_marker_time_axis(track_name, assoc_tav, this) ;
1208 TimeAxisView* new_tav = thePublicEditor.get_named_time_axis(track_name) ;
1210 bool added = false ;
1212 if(new_tav)
1214 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(new_tav) ;
1215 if(mta)
1217 added = true ;
1218 mta->VisualTimeAxisRemoved.connect(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_removed)) ;
1219 mta->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_marker_time_axis_renamed), mta)) ;
1223 if(added)
1225 std::string msg("Addition Failed: ") ;
1226 msg.append(track_name) ;
1227 send_return_failure(msg) ;
1230 else
1232 std::string errmsg("No associated Track Found: ") ;
1233 errmsg.append(track_name) ;
1234 send_return_failure(errmsg) ;
1240 * Handle the insertion of a time axis group (a scene)
1242 * @param msg the received message
1244 void
1245 ImageFrameSocketHandler::handle_insert_imageframe_group(const char* msg)
1247 int position = 4 ; // message type chars
1249 // get the ImageFrameTrack name size
1250 int track_name_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1251 position += ardourvis::TEXT_SIZE_CHARS ;
1253 // get the image frame track name
1254 std::string track_name = get_message_part(position, track_name_size, msg) ;
1255 position += track_name_size ;
1257 // get the scene id size
1258 int scene_id_size = atoi(get_message_part(position, ardourvis::TEXT_SIZE_CHARS, msg).c_str()) ;
1259 position += ardourvis::TEXT_SIZE_CHARS ;
1261 // get the scene id
1262 std::string scene_id = get_message_part(position, scene_id_size, msg) ;
1263 position += scene_id_size ;
1266 // get the named ImageFrameTrack
1267 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_name)) ;
1269 // check we got a valid ImageFrameTimeAxis
1270 if(!ifta)
1272 send_return_failure(std::string("No Image Frame Time Axis Found: ").append(track_name)) ;
1273 return ;
1276 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->add_imageframe_group(scene_id, this) ;
1277 if(!iftag)
1279 send_return_failure(std::string("Image Frame Group insert failed")) ;
1281 else
1283 iftag->NameChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_renamed), iftag)) ;
1284 iftag->GroupRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_time_axis_group_removed), iftag)) ;
1285 send_return_success() ;
1291 * Handle the insertion of a new ImageFrameItem
1293 * @param msg the received message
1295 void
1296 ImageFrameSocketHandler::handle_insert_imageframe_view(const char* msg)
1298 int position = 4 ; // message type chars
1300 // get the ImageFrameTrack name size
1301 int track_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
1302 position += 3 ;
1304 // get the ImageFrameTrack Name
1305 std::string imageframe_track_name = get_message_part(position,track_name_size,msg) ;
1306 position += track_name_size ;
1308 // get the scene name size
1309 int scene_size = atoi(get_message_part(position,3,msg).c_str()) ;
1310 position += 3 ;
1312 // get the scene Name
1313 std::string scene_name = get_message_part(position,scene_size,msg) ;
1314 position += scene_size ;
1316 // get the image frame_id size
1317 int image_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1318 position += 3 ;
1320 // get the image frame_id
1321 std::string image_id = get_message_part(position,image_id_size,msg) ;
1322 position += image_id_size ;
1324 // get the start frame value
1325 nframes_t start = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1326 position += 10 ;
1328 // get the duration value
1329 nframes_t duration = strtoul((get_message_part(position,10,msg).c_str()),0,10) ;
1330 position += 10 ;
1332 //get the named time axis view we about to add an image to
1333 TimeAxisView* tav = thePublicEditor.get_named_time_axis(imageframe_track_name) ;
1334 ImageFrameTimeAxis* ifta = 0 ;
1336 if(tav)
1338 ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1341 if(!ifta)
1343 std::string errmsg("No Parent Image Track Found: ") ;
1344 errmsg.append(imageframe_track_name) ;
1345 send_return_failure(errmsg) ;
1347 // dont really like all these returns mid-way
1348 // but this is goinf to get awfully if..then nested if not
1349 return ;
1352 // check the parent group exists
1353 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_name) ;
1354 if(!iftag)
1356 std::string errmsg("No Image Frame Group Found: ") ;
1357 errmsg.append(scene_name) ;
1358 send_return_failure(errmsg) ;
1359 return ;
1362 // ok, so we have the parent group and track, now we need dome image data
1366 // request the image data from the image compositor
1369 // ctreate a message buffer
1370 std::ostringstream reqBuffer ;
1371 reqBuffer << std::setfill('0') ;
1373 // add the msg type
1374 reqBuffer << REQUEST_DATA << IMAGE_RGB_DATA ;
1376 // add the image track and size
1377 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << track_name_size ;
1378 reqBuffer << imageframe_track_name ;
1380 // add the scene id and size
1381 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << scene_size ;
1382 reqBuffer << scene_name ;
1384 // add the image id and size
1385 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << image_id_size ;
1386 reqBuffer << image_id ;
1388 // add the preferred image height
1389 reqBuffer << std::setw(ardourvis::TEXT_SIZE_CHARS) << ifta->get_image_display_height() ;
1391 // send the request message
1392 send_message(reqBuffer.str()) ;
1395 // read the reply, the inital image data message
1396 // this gives us the image dimensions and the expected size of the image data
1397 // msg type(4) + image width(3) + height(3) + num channels(3) + size of the image data (32)
1398 std::string init_image_data_msg ;
1399 read_message(init_image_data_msg) ;
1400 int init_msg_pos = 4 ;
1402 int imgWidth = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1403 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1404 int imgHeight = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1405 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1406 int imgChannels = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_SIZE_CHARS).c_str()) ;
1407 init_msg_pos += ardourvis::IMAGE_SIZE_CHARS ;
1408 int imgSize = atoi(init_image_data_msg.substr(init_msg_pos, ardourvis::IMAGE_DATA_MESSAGE_SIZE_CHARS).c_str()) ;
1410 // send a success msg
1411 // we need to do this to keep things moving
1412 send_return_success() ;
1414 // create our image rgb buffer, this holds the image data we receive
1415 unsigned char* rgb_img_buf = new unsigned char[imgSize] ;
1417 int retcode = ::recv(theArdourToCompositorSocket, rgb_img_buf, imgSize, MSG_WAITALL) ;
1419 if(retcode != imgSize)
1421 delete [] rgb_img_buf ;
1422 send_return_failure("Could not create new Image Frame View : image data sizes did not match") ;
1424 else
1426 ImageFrameView* ifv = iftag->add_imageframe_item(image_id, start, duration, rgb_img_buf, (uint32_t)imgWidth, (uint32_t)imgHeight, (uint32_t)imgChannels, this) ;
1427 if(ifv)
1429 ifv->PositionChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_position_change), ifv)) ;
1430 ifv->DurationChanged.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_duration_change), ifv)) ;
1431 ifv->ItemRemoved.connect(sigc::bind(sigc::mem_fun(*this, &ImageFrameSocketHandler::send_imageframe_view_removed), ifv)) ;
1433 send_return_success() ;
1435 else
1437 //addition failed. assume duplicate item_id
1438 send_return_failure("Could not create new Image Frame View") ;
1446 * Handle the insertion of a new MarkerItem
1448 * @param msg the received message
1450 void
1451 ImageFrameSocketHandler::handle_insert_marker_view(const char* msg)
1455 //---------------------------------------------------------------------------------------//
1456 // handlers for specific removal procedures
1460 * Handle the removal of an ImageTimeAxis
1462 * @param msg the received message
1464 void
1465 ImageFrameSocketHandler::handle_remove_imageframe_time_axis(const char* msg)
1469 * Handle the removal of an MarkerTimeAxis
1471 * @param msg the received message
1473 void
1474 ImageFrameSocketHandler::handle_remove_marker_time_axis(const char* msg)
1478 * Handle the removal of an ImageFrameTimeAxisGroup
1480 * @param msg the received message
1482 void
1483 ImageFrameSocketHandler::handle_remove_imageframe_time_axis_group(const char* msg)
1487 * Handle the removal of an ImageFrameItem
1489 * @param msg the received message
1491 void
1492 ImageFrameSocketHandler::handle_remove_imageframe_view(const char* msg)
1496 * Handle the removal of an MarkerItem
1498 * @param msg the received message
1500 void
1501 ImageFrameSocketHandler::handle_remove_marker_view(const char* msg)
1508 //---------------------------------------------------------------------------------------//
1509 // handlers for the specific rename procedures
1512 * Handle the renaming of an ImageTimeAxis
1514 * @param msg the received message
1516 void
1517 ImageFrameSocketHandler::handle_rename_imageframe_time_axis(const char* msg)
1519 // msg [MVIT][oldSize][oldId][newSize][newId]
1521 int position = 4 ; // message type chars
1523 // get the old Id size
1524 int old_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1525 position += 3 ;
1527 // get the old id
1528 std::string old_id = get_message_part(position,old_id_size,msg) ;
1529 position += old_id_size ;
1531 //get the new Id size
1532 int new_id_size = atoi(get_message_part(position,3,msg).c_str()) ;
1533 position += 3 ;
1535 // get the new Id
1536 std::string new_id = get_message_part(position,new_id_size,msg) ;
1537 position += new_id_size ;
1539 // get the Named time axis
1540 TimeAxisView* tav = thePublicEditor.get_named_time_axis(old_id) ;
1541 if(dynamic_cast<ImageFrameTimeAxis*>(tav))
1543 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(tav) ;
1544 ifta->set_time_axis_name(new_id, this) ;
1545 send_return_success() ;
1547 else
1549 std::string msg = "No Image Track Found: " ;
1550 msg.append(old_id) ;
1551 send_return_failure(msg) ;
1556 * Handle the renaming of an MarkerTimeAxis
1558 * @param msg the received message
1560 void
1561 ImageFrameSocketHandler::handle_rename_marker_time_axis(const char* msg)
1565 * Handle the renaming of an ImageFrameItem
1567 * @param msg the received message
1569 void
1570 ImageFrameSocketHandler::handle_rename_imageframe_time_axis_group(const char* msg)
1574 * Handle the renaming of an ImageFrameItem
1576 * @param msg the received message
1578 void
1579 ImageFrameSocketHandler::handle_rename_imageframe_view(const char* msg)
1583 * Handle the renaming of an Marker
1585 * @param msg the received message
1587 void
1588 ImageFrameSocketHandler::handle_rename_marker_view(const char* msg)
1594 //---------------------------------------------------------------------------------------//
1595 // handlers for data request
1598 * Handle a request for the sessnio naem fo the current session
1599 * We return a failure state if no session is open
1601 * @param msg the received message
1603 void
1604 ImageFrameSocketHandler::handle_session_name_request(const char* msg)
1606 ARDOUR::Session* currentSession = thePublicEditor.current_session() ;
1608 if(currentSession == 0)
1610 // no current session, return failure
1611 std::string msg("No Current Session") ;
1612 send_return_failure(msg) ;
1614 else
1616 std::string sessionName = currentSession->name() ;
1617 std::string sessionPath = currentSession->path() ;
1619 if(sessionPath[sessionPath.length() -1] != '/')
1621 sessionPath.append("/") ;
1624 sessionPath.append(sessionName) ;
1626 std::ostringstream msgBuf ;
1627 msgBuf << ardourvis::RETURN_DATA << ardourvis::SESSION_NAME ;
1628 msgBuf << std::setfill('0') ;
1629 msgBuf << std::setw(ardourvis::TEXT_SIZE_CHARS) << sessionPath.length() ;
1630 msgBuf << sessionPath ;
1631 send_message(msgBuf.str()) ;
1639 //---------------------------------------------------------------------------------------//
1640 // handlers for specific item update changes
1643 * Handle ImageFrameView positional changes
1645 * @param msg the received message
1647 void
1648 ImageFrameSocketHandler::handle_imageframe_view_position_update(const char* msg)
1650 int position = 6 ; // message type chars
1652 std::string track_id ;
1653 std::string scene_id ;
1654 std::string item_id ;
1655 int track_id_size ;
1656 int scene_id_size ;
1657 int item_id_size ;
1659 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1661 nframes_t start_frame = strtoul(get_message_part(position, ardourvis::TIME_VALUE_CHARS, msg).c_str(), 0, 10) ;
1662 position += ardourvis::TIME_VALUE_CHARS ;
1664 // get the named time axis
1665 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1667 if(!ifta)
1669 send_return_failure(std::string("No parent Image Track found: ").append(track_id)) ;
1670 return ;
1673 // get the parent scene
1674 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1675 if(!iftag)
1677 send_return_failure(std::string("No parent Scene found: ").append(scene_id)) ;
1678 return ;
1681 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1683 if(!ifv)
1685 send_return_failure(std::string("No Image Frame Item found: ").append(item_id)) ;
1686 return ;
1690 ifv->set_position(start_frame, this) ;
1691 send_return_success() ;
1695 * Handle ImageFrameView Duration changes
1697 * @param msg the received message
1699 void
1700 ImageFrameSocketHandler::handle_imageframe_view_duration_update(const char* msg)
1702 int position = 6 ; // message type chars
1704 std::string track_id ;
1705 std::string scene_id ;
1706 std::string item_id ;
1707 int track_id_size ;
1708 int scene_id_size ;
1709 int item_id_size ;
1711 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, scene_id, scene_id_size, item_id, item_id_size) ;
1713 nframes_t duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1714 position += ardourvis::TIME_VALUE_CHARS ;
1716 // get the named time axis
1717 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
1719 if(!ifta)
1721 send_return_failure(std::string("No parent Image Track found : ").append(track_id)) ;
1722 return ;
1725 // get the parent scene
1726 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(scene_id) ;
1727 if(!iftag)
1729 send_return_failure(std::string("No parent Scene found : ").append(scene_id)) ;
1730 return ;
1733 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
1735 if(!ifv)
1737 send_return_failure(std::string("No Image Frame Item found : ").append(item_id)) ;
1738 return ;
1741 ifv->set_duration(duration, this) ;
1742 send_return_success() ;
1746 * Handle ImageFrameView Position Lock Constraint changes
1748 * @param msg the received message
1750 void
1751 ImageFrameSocketHandler::handle_imageframe_position_lock_update(const char* msg)
1753 int position = 6 ; // message type chars
1755 std::string track_id ;
1756 std::string group_id ;
1757 std::string item_id ;
1758 int track_id_size ;
1759 int group_id_size ;
1760 int item_id_size ;
1762 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1764 std::string pos_lock = get_message_part(position,1,msg) ;
1765 bool pos_lock_active = false ;
1767 if(pos_lock == "0")
1769 pos_lock_active = false ;
1771 else if(pos_lock == "1")
1773 pos_lock_active = true ;
1775 else
1777 send_return_failure(std::string("Unknown Value used during Position Loack: ").append(pos_lock)) ;
1778 return ;
1781 position += 1 ;
1783 int errcode ;
1784 std::string errmsg ;
1785 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1786 if(ifv)
1788 ifv->set_position_locked(pos_lock_active, this) ;
1789 send_return_success() ;
1791 else
1793 send_return_failure(errmsg) ;
1798 * Handle ImageFrameView Maximum Duration changes
1800 * @param msg the received message
1802 void
1803 ImageFrameSocketHandler::handle_imageframe_view_max_duration_update(const char* msg)
1805 int position = 6 ; // message type chars
1807 std::string track_id ;
1808 std::string group_id ;
1809 std::string item_id ;
1810 int track_id_size ;
1811 int group_id_size ;
1812 int item_id_size ;
1814 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1816 nframes_t max_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1817 position += ardourvis::TIME_VALUE_CHARS ;
1819 int errcode ;
1820 std::string errmsg ;
1821 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1822 if(ifv)
1824 ifv->set_max_duration(max_duration, this) ;
1825 send_return_success() ;
1827 else
1829 send_return_failure(errmsg) ;
1834 * Handle image frame max duration enable constraint changes
1836 * @param msg the received message
1838 void
1839 ImageFrameSocketHandler::handle_imageframe_view_max_duration_enable_update(const char* msg)
1841 int position = 6 ; // message type chars
1843 std::string track_id ;
1844 std::string group_id ;
1845 std::string item_id ;
1846 int track_id_size ;
1847 int group_id_size ;
1848 int item_id_size ;
1850 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1852 std::string active = get_message_part(position,1,msg) ;
1853 bool max_duration_active = false ;
1855 if(active == "0")
1857 max_duration_active = false ;
1859 else if(active == "1")
1861 max_duration_active = true ;
1863 else
1865 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1866 return ;
1869 position += 1 ;
1871 int errcode ;
1872 std::string errmsg ;
1873 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1874 if(ifv)
1876 ifv->set_max_duration_active(max_duration_active, this) ;
1877 send_return_success() ;
1879 else
1881 send_return_failure(errmsg) ;
1886 * Handle ImageFrameView Minimum Duration changes
1888 * @param msg the received message
1890 void
1891 ImageFrameSocketHandler::handle_imageframe_view_min_duration_update(const char* msg)
1893 int position = 6 ; // message type chars
1895 std::string track_id ;
1896 std::string group_id ;
1897 std::string item_id ;
1898 int track_id_size ;
1899 int group_id_size ;
1900 int item_id_size ;
1902 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1904 nframes_t min_duration = strtoul(get_message_part(position,ardourvis::TIME_VALUE_CHARS,msg).c_str(),0,10) ;
1905 position += ardourvis::TIME_VALUE_CHARS ;
1907 int errcode ;
1908 std::string errmsg ;
1909 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1910 if(ifv)
1912 ifv->set_min_duration(min_duration, this) ;
1913 send_return_success() ;
1915 else
1917 send_return_failure(errmsg) ;
1922 * Handle image frame min duration enable constraint changes
1924 * @param msg the received message
1926 void
1927 ImageFrameSocketHandler::handle_imageframe_view_min_duration_enable_update(const char* msg)
1929 int position = 6 ; // message type chars
1931 std::string track_id ;
1932 std::string group_id ;
1933 std::string item_id ;
1934 int track_id_size ;
1935 int group_id_size ;
1936 int item_id_size ;
1938 this->decompose_imageframe_item_desc(msg, position, track_id, track_id_size, group_id, group_id_size, item_id, item_id_size) ;
1940 std::string active = get_message_part(position,1,msg) ;
1941 bool min_duration_active = false ;
1943 if(active == "0")
1945 min_duration_active = false ;
1947 else if(active == "1")
1949 min_duration_active = true ;
1951 else
1953 send_return_failure(std::string("Unknown Value used during enable max duration: ").append(active)) ;
1954 return ;
1957 position += 1 ;
1959 int errcode ;
1960 std::string errmsg ;
1961 ImageFrameView* ifv = get_imageframe_view_from_desc(track_id, group_id, item_id, errcode, errmsg) ;
1962 if(ifv)
1964 ifv->set_min_duration_active(min_duration_active, this) ;
1965 send_return_success() ;
1967 else
1969 send_return_failure(errmsg) ;
1974 * Handle MarkerView position changes
1976 * @param msg the received message
1978 void
1979 ImageFrameSocketHandler::handle_marker_view_position_update(const char* msg)
1983 * Handle MarkerView duration changes
1985 * @param msg the received message
1987 void
1988 ImageFrameSocketHandler::handle_marker_view_duration_update(const char* msg)
1992 * Handle MarkerView Position Lock Constraint changes
1994 * @param msg the received message
1996 void
1997 ImageFrameSocketHandler::handle_marker_view_position_lock_update(const char* msg)
2002 * Handle MarkerView maximum duration changes
2004 * @param msg the received message
2006 void
2007 ImageFrameSocketHandler::handle_marker_view_max_duration_update(const char* msg)
2011 * Handle MarkerView minimum duration changes
2013 * @param msg the received message
2015 void
2016 ImageFrameSocketHandler::handle_marker_view_min_duration_update(const char* msg)
2023 //---------------------------------------------------------------------------------------//
2024 // handlers for Session Actions
2027 * Handle the opening of a named audio session
2029 * @param msg the received message
2031 void
2032 ImageFrameSocketHandler::handle_open_session(const char* msg)
2034 // msg [SAOS][sessionSize][sessionPath]
2036 int position = 4 ; // message type chars
2038 // get the session name size
2039 int session_name_size = atoi(get_message_part(position,3,msg).c_str()) ;
2040 position += 3 ;
2042 // get the session name
2043 std::string session_name = get_message_part(position,session_name_size,msg) ;
2044 position += session_name_size ;
2047 // open the session
2048 std::string path, name ;
2049 bool isnew;
2051 if (ARDOUR::Session::find_session(session_name, path, name, isnew) == 0) {
2052 if (ARDOUR_UI::instance()->load_session (path, name) == 0) {
2053 send_return_success() ;
2054 } else {
2055 std::string retMsg = "Failed to load Session" ;
2056 send_return_failure(retMsg) ;
2058 } else {
2059 std::string retMsg = "Failed to find Session" ;
2060 send_return_failure(retMsg) ;
2066 * Handle the closing of a named audio session
2068 * @param msg the received message
2070 void
2071 ImageFrameSocketHandler::handle_closed_session(const char* msg)
2074 //---------------------------------------------------------------------------------------//
2075 // handlers for the shutdown of the Image Compositor
2078 * Handle the shutdown message from the image compositor
2080 * @param msg the received message
2082 void
2083 ImageFrameSocketHandler::handle_shutdown(const char* msg)
2085 CompositorSocketShutdown() ; /* EMIT_SIGNAL */
2097 //---------------------------------------------------------------------------------------//
2098 // convenince methods to break up messages
2101 * Returns part of the received message as a std::string
2103 * @param start the start character
2104 * @param num_chars the number of characters to read
2105 * @param the message to break apart
2106 * @return the sub string of the message
2108 std::string
2109 ImageFrameSocketHandler::get_message_part(int start, int32_t num_chars, const char* msg)
2111 char buf[num_chars + 1] ;
2112 strncpy(buf,msg+start,num_chars) ;
2113 buf[num_chars] = '\0' ;
2114 std::string s(buf) ;
2116 return(s) ;
2122 * break up am image item description message
2123 * we break the mesage up into the parent Image Track id and size,
2124 * the parent group id and size, and the image id and size
2126 * @param track_id
2127 * @param track_id_size
2128 * @param scene_id
2129 * @param scene_id_size
2130 * @param item_id
2131 * @param item_id_size
2133 void
2134 ImageFrameSocketHandler::decompose_imageframe_item_desc(const char* msg, int& position, std::string& track_id,
2135 int& track_id_size, std::string& scene_id, int& scene_id_size, std::string& item_id, int& item_id_size)
2137 // get the track Id size
2138 track_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2139 position += ardourvis::TEXT_SIZE_CHARS ;
2141 // get the track id
2142 track_id = get_message_part(position,track_id_size,msg) ;
2143 position += track_id_size ;
2145 // get the track Id size
2146 scene_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2147 position += ardourvis::TEXT_SIZE_CHARS ;
2149 // get the scene id
2150 scene_id = get_message_part(position,scene_id_size,msg) ;
2151 position += scene_id_size ;
2153 // get the item id size
2154 item_id_size = atoi(get_message_part(position,ardourvis::TEXT_SIZE_CHARS,msg).c_str()) ;
2155 position += ardourvis::TEXT_SIZE_CHARS ;
2157 // get the item id
2158 item_id = get_message_part(position,item_id_size,msg) ;
2159 position += item_id_size ;
2163 * Compose a description of the specified image frame view
2164 * The description consists of the parent track name size and name,
2165 * the parent group name size and name, and the item name size and name
2167 * @param ifv the item to string_compose a description of
2168 * @param buffer the buffer to write the description
2170 void
2171 ImageFrameSocketHandler::compose_imageframe_item_desc(ImageFrameView* ifv, std::ostringstream& buffer)
2173 buffer << std::setw(3) << ifv->get_time_axis_group()->get_view().trackview().name().length() ;
2174 buffer << ifv->get_time_axis_group()->get_view().trackview().name() ;
2176 // add the parent scene
2177 buffer << std::setw(3) << ifv->get_time_axis_group()->get_group_name().length() ;
2178 buffer << ifv->get_time_axis_group()->get_group_name() ;
2180 // add the ImageFrameItem id length and Id
2181 buffer << setw(3) << ifv->get_item_name().length() ;
2182 buffer << ifv->get_item_name() ;
2186 * Compose a description of the specified marker view
2187 * The description consists of the parent track name size and name,
2188 * and the item name size and name
2190 * @param mv the item to string_compose a description of
2191 * @param buffer the buffer to write the description
2193 void
2194 ImageFrameSocketHandler::compose_marker_item_desc(MarkerView* mv, std::ostringstream& buffer)
2196 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(&mv->get_time_axis_view()) ;
2198 if(!mta)
2200 return ;
2203 buffer << std::setw(3) << mta->name().length() ;
2204 buffer << mta->name() ;
2206 buffer << std::setw(3) << mv->get_item_name().length() ;
2207 buffer << mv->get_item_name() ;
2212 * Returns the ImageFrameView from the specified description
2213 * The errcode parameter is used to indicate the item which caused
2214 * an error on failure of this method
2215 * 0 = success
2216 * 1 = the track item was not found
2217 * 2 = the group item was not found
2218 * 3 = the imageframe item was not found
2220 * @paran track_id the track on which the item is placed
2221 * @param group_id the group in which the item is a member
2222 * @param item_id the id of the item
2223 * @param int32_t reference used for error codes on failure
2224 * @param errmsg populated with a description of the error on failure
2225 * @return the described item on success, 0 otherwise
2227 ImageFrameView*
2228 ImageFrameSocketHandler::get_imageframe_view_from_desc(const string & track_id, const string & group_id, const string & item_id, int& errcode, std::string& errmsg)
2230 ImageFrameView* item = 0 ;
2232 // get the named time axis
2233 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(thePublicEditor.get_named_time_axis(track_id)) ;
2235 if(!ifta)
2237 errcode = 1 ;
2238 errmsg = std::string("Image Frame Time Axis Not Found: ").append(track_id) ;
2240 else
2242 // get the parent scene
2243 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_named_imageframe_group(group_id) ;
2244 if(!iftag)
2246 errcode = 2 ;
2247 errmsg = std::string("Image Frame Group Not Found: ").append(group_id) ;
2249 else
2251 ImageFrameView* ifv = iftag->get_named_imageframe_item(item_id) ;
2252 if(!ifv)
2254 errcode = 3 ;
2255 errmsg = std::string("Image Frame Item Not Found: ").append(item_id) ;
2257 else
2259 // yay!!
2260 item = ifv ;
2261 errcode = 0 ;
2266 return(item) ;
2269 //---------------------------------------------------------------------------------------//
2270 // Convenince Message Send Methods
2272 #ifndef MSG_NOSIGNAL
2273 #define MSG_NOSIGNAL 0
2274 #endif
2277 * Sends a message throught the socket
2279 * @param msg the message to send
2280 * @return the return value of the socket call
2283 ImageFrameSocketHandler::send_message(const string & msg)
2285 //std::cout << "Sending Message [" << msg << "]\n" ;
2286 int retcode = ::send(theArdourToCompositorSocket, msg.c_str(), msg.length(), MSG_NOSIGNAL) ;
2288 return(retcode) ;
2292 * Reads a message from the Socket
2294 * @param msg a string to populate with the received message
2295 * @return the return value from the socket call
2298 ImageFrameSocketHandler::read_message(std::string& msg)
2300 char buf[ardourvis::MAX_MSG_SIZE + 1] ;
2301 memset(buf, 0, (ardourvis::MAX_MSG_SIZE + 1)) ;
2303 msg = "" ;
2304 int retcode = ::recv(theArdourToCompositorSocket, buf, ardourvis::MAX_MSG_SIZE, 0) ;
2306 msg = buf ;
2307 //std::cout << "Received Message [" << msg << "]\n" ;
2309 return(retcode) ;
2313 * Reads a reply message ("RT0"/"RT1") from the Socket
2315 * @return true if "RT0" was received,, otherwise false
2317 bool
2318 ImageFrameSocketHandler::read_result()
2320 char buf[(ardourvis::RETURN_MSG_SIZE)+1] ;
2321 int retcode = ::recv(theArdourToCompositorSocket, buf, ardourvis::RETURN_MSG_SIZE, 0) ;
2322 buf[ardourvis::RETURN_MSG_SIZE]='\0';
2323 if (retcode > 0) {
2324 std::cout << "Received Result [" << buf << "]\n" ;
2325 if (retcode == ardourvis::RETURN_MSG_SIZE && buf == ardourvis::RETURN_TRUE) {
2326 return (true);
2329 return(false) ;
2333 * Convenience method to string_compose and send a success messasge back to the Image Compositor
2336 void
2337 ImageFrameSocketHandler::send_return_success()
2339 send_message(ardourvis::RETURN_TRUE) ;
2343 * Convenience method to string_compose and send a failure messasge back to the Image Compositor
2345 * @param msg the failure message
2347 void
2348 ImageFrameSocketHandler::send_return_failure(const std::string& msg)
2350 std::ostringstream buf ;
2351 buf << std::setfill('0') ;
2352 buf << ardourvis::RETURN_FALSE ;
2353 buf << std::setw(3) << msg.length(); ;
2354 buf << msg ;
2356 send_message(buf.str()) ;