Hi, First of all many many thanks for working on this. For a first version these patches look very good! Second sorry for being a bit late with this reply I started composing it a week ago, and then other stuff got in the way. In the mean time you've had some other replies so some of the things in here may repeat stuff said in other mails ... But I would like to first settle on a final agent protocol, which supports all features we want before merging any parts of this, as once merged we can no longer change the proto. So I've been discussing this a bit with Alon, and thinking about it, and in the end I think we need the following messages: 1) VD_AGENT_FILE_XFER_STATUS enum VDAgentFileXferResult { VD_AGENT_FILE_XFER_SUCCESS, VD_AGENT_FILE_XFER_DISK_FULL, VD_AGENT_FILE_XFER_CANCELLED }; typedef struct SPICE_ATTR_PACKED VDAgentFileXferStatusMessage{ uint32_t id; uint32_t result; } VDAgentFileXferStatusMessage; 2) VD_AGENT_FILE_XFER_START typedef struct SPICE_ATTR_PACKED VDAgentFileXferStartMessage{ uint32_t id; uint64_t file_size; uint8_t file_name[0]; } VDAgentFileXferStartMessage; 3) VD_AGENT_FILE_XFER_DATA typedef struct SPICE_ATTR_PACKED VDAgentFileXferDataMessage{ uint32_t id; uint64_t size; uint8_t data[0]; } VDAgentFileXferDataMessage; The id-field is there to allow multiple simultaneous file transfers, this is useful ie when a user drag and drops a dvd iso, and then while that is transferring also drags and drops a word file he wants to work on, without having to wait for the iso transfer to finish, before the word document gets send. Here are some examples to clarify how this would work at the protocol level: Steps of a single file file-transfer: 1) Client sends a VD_AGENT_FILE_XFER_START 2) Agent reserves diskspace and sends an VD_AGENT_FILE_XFER_STATUS with a VD_AGENT_FILE_XFER_SUCCESS result 3) Client sends VD_AGENT_FILE_XFER_DATA messages until it has send file-size bytes of data. Steps of a too large file-transfer: 1) Client sends a VD_AGENT_FILE_XFER_START 2) Agent fails to reserve diskspace and sends an VD_AGENT_FILE_XFER_STATUS with a VD_AGENT_FILE_XFER_DISK_FULL result 3) Client shows error dialog to the user Steps of a cancelled file-transfer 1) Client sends a VD_AGENT_FILE_XFER_START 2) Agent reserves diskspace and sends an VD_AGENT_FILE_XFER_STATUS with a VD_AGENT_FILE_XFER_SUCCESS result 3) Since this is a large file, which will take a while, the client shows a window with a progress bar and a cancel button 4) Client sends some VD_AGENT_FILE_XFER_DATA messages 5) user clicks cancel 6) Client sends a VD_AGENT_FILE_XFER_STATUS with a VD_AGENT_FILE_XFER_CANCELLED result, stops sending further data and closes the progress dialog 7) The agent frees the reserved diskspace upon reception of the VD_AGENT_FILE_XFER_CANCELLED result Steps of a multi file file-transfer 1) Client sends a VD_AGENT_FILE_XFER_START, id = 1 2) Agent reserves diskspace and sends an VD_AGENT_FILE_XFER_STATUS with a VD_AGENT_FILE_XFER_SUCCESS result, id = 1 3) Client sends some VD_AGENT_FILE_XFER_DATA messages with id = 1 4) Client sends a VD_AGENT_FILE_XFER_START, id = 2 5) Agent reserves diskspace for id = 2 and sends an VD_AGENT_FILE_XFER_STATUS with a VD_AGENT_FILE_XFER_SUCCESS result, id = 2 6) Client sends some VD_AGENT_FILE_XFER_DATA messages with id = 1 7) Client sends some VD_AGENT_FILE_XFER_DATA messages with id = 2 8) 6 and 7 repeat, sending some data for each transfer until id = 2 is finished. 9) Client sends VD_AGENT_FILE_XFER_DATA messages with id = 2 until it has finished too ### So about the spice-gtk implementation, both for copy and paste to keep working, as well as for multiple file transfers at the same time to work, the spice-gtk implementation cannot simply out the entire file in the agent msg queue in one go. So we need a mechanism to put some data in the agent msg queue, and then get called back when the queue is empty. I think the easiest way to do this is to: 1) add a callback ( + opaque context pointer) to the SpiceMsgOut struct, with the callback prototype matching that of a GIdle function 2) Have a new spice_msg_out_new_callback function to create SpiceMsgOut structs with the callback set, rather then with a regular msg 3) Have spice_msg_out_send call this callback rather then queuing the packet when encountering such a callback SpiceMsgOut; and 4) spice_msg_out_send_internal schedule calling the callback through g_idle_add 5) The file xfer code would then queue some agent messages with data, followed by a callback SpiceMsgOut, which will then caused the file xfer code to get called for more data when the agent queue is empty This way we can have multiple file transfers going at the same time, and keep copy and paste (and other agent messages) working while a file is being transferred. And as already mentioned, the function to add some file data to the agent message queue should use async gio code, to ensure to not freeze the client while waiting for disk io. I believe that at least for the Linux agent the agent code can simply use synchronous file-io. Regards, Hans _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel