diff options
-rw-r--r-- | protocols/purple/purple.c | 90 |
1 files changed, 67 insertions, 23 deletions
diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c index f0fc736e..383ed55f 100644 --- a/protocols/purple/purple.c +++ b/protocols/purple/purple.c @@ -664,58 +664,102 @@ static PurpleNotifyUiOps bee_notify_uiops = prplcb_notify_email, }; -static void prplcb_xfer( PurpleXfer *xfer ) +struct prpl_xfer_data { - fprintf( stderr, "ft bla: 0x%p\n", xfer ); + PurpleXfer *xfer; + file_transfer_t *ft; + gint ready_timer; +}; + +/* Glorious hack: We seem to have to remind at least some libpurple plugins + that we're ready because this info may get lost if we give it too early. + So just do it ten times a second. :-/ */ +static gboolean prplcb_xfer_write_request_cb( gpointer data, gint fd, b_input_condition cond ) +{ + purple_xfer_ui_ready( data ); + return TRUE; +} + +static gboolean prpl_xfer_write_request( struct file_transfer *ft ) +{ + struct prpl_xfer_data *px = ft->data; + px->ready_timer = b_timeout_add( 100, prplcb_xfer_write_request_cb, px->xfer ); + return TRUE; +} + +static gssize prplcb_xfer_write( PurpleXfer *xfer, const guchar *buffer, gssize size ) +{ + struct prpl_xfer_data *px = xfer->ui_data; + gboolean st; + + b_event_remove( px->ready_timer ); + px->ready_timer = 0; + + st = px->ft->write( px->ft, (char*) buffer, size ); + + if( st && xfer->bytes_remaining == size ) + imcb_file_finished( px->ft ); + + return st ? size : 0; } static void prpl_xfer_accept( struct file_transfer *ft ) { - purple_xfer_request_accepted( ft->data, NULL ); - purple_xfer_ui_ready( ft->data ); + struct prpl_xfer_data *px = ft->data; + purple_xfer_request_accepted( px->xfer, NULL ); + prpl_xfer_write_request( ft ); } -static void prpl_xfer_reject( struct file_transfer *ft ) +static void prpl_xfer_canceled( struct file_transfer *ft, char *reason ) { - purple_xfer_request_denied( ft->data ); + struct prpl_xfer_data *px = ft->data; + purple_xfer_request_denied( px->xfer ); } static gboolean prplcb_xfer_new_cb( gpointer data, gint fd, b_input_condition cond ) { PurpleXfer *xfer = data; struct im_connection *ic = purple_ic_by_pa( xfer->account ); - file_transfer_t *ft; + struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 ); + PurpleBuddy *buddy; + const char *who; + + buddy = purple_find_buddy( xfer->account, xfer->who ); + who = buddy ? purple_buddy_get_name( buddy ) : xfer->who; - ft = imcb_file_send_start( ic, xfer->who, xfer->filename, xfer->size ); - ft->data = xfer; - xfer->ui_data = ft; + /* TODO(wilmer): After spreading some more const goodness in BitlBee, + remove the evil cast below. */ + px->ft = imcb_file_send_start( ic, (char*) who, xfer->filename, xfer->size ); + px->ft->data = px; + px->xfer = data; + px->xfer->ui_data = px; - ft->accept = prpl_xfer_accept; + px->ft->accept = prpl_xfer_accept; + px->ft->canceled = prpl_xfer_canceled; + px->ft->write_request = prpl_xfer_write_request; return FALSE; } static void prplcb_xfer_new( PurpleXfer *xfer ) { + /* This should suppress the stupid file dialog. */ purple_xfer_set_local_filename( xfer, "/tmp/wtf123" ); - fprintf( stderr, "ft_new bla: 0x%p\n", xfer ); - + /* Sadly the xfer struct is still empty ATM so come back after + the caller is done. */ b_timeout_add( 0, prplcb_xfer_new_cb, xfer ); } static PurpleXferUiOps bee_xfer_uiops = { prplcb_xfer_new, - prplcb_xfer, - prplcb_xfer, - prplcb_xfer, - prplcb_xfer, - prplcb_xfer, - prplcb_xfer, - prplcb_xfer, - prplcb_xfer, - prplcb_xfer, + NULL, + NULL, + NULL, + NULL, + NULL, + prplcb_xfer_write, }; static void purple_ui_init() @@ -726,7 +770,7 @@ static void purple_ui_init() purple_request_set_ui_ops( &bee_request_uiops ); purple_notify_set_ui_ops( &bee_notify_uiops ); purple_xfers_set_ui_ops( &bee_xfer_uiops ); - purple_debug_set_ui_ops( &bee_debug_uiops ); + //purple_debug_set_ui_ops( &bee_debug_uiops ); } void purple_initmodule() |