Index: roard/clients.c
===================================================================
--- roard/clients.c	(revision 4684)
+++ roard/clients.c	(revision 4686)
@@ -29,9 +29,9 @@
 #ifndef ROAR_WITHOUT_DCOMP_EMUL_ESD
 #ifdef ROAR_HAVE_H_ESD
- {ROAR_PROTO_ESOUND, NULL, emul_esd_check_client},
+ {ROAR_PROTO_ESOUND, NULL, emul_esd_check_client, NULL, NULL},
 #endif
 #endif
 #ifndef ROAR_WITHOUT_DCOMP_EMUL_RPLAY
- {ROAR_PROTO_RPLAY, NULL, emul_rplay_check_client},
+ {ROAR_PROTO_RPLAY, NULL, emul_rplay_check_client, NULL, NULL},
 #endif
  {-1, NULL}
@@ -344,5 +344,5 @@
  struct roar_client * c;
  struct timeval tv;
- fd_set r, e;
+ fd_set r, w, e;
  int i, j;
  int ret;
@@ -358,4 +358,5 @@
 
  FD_ZERO(&r);
+ FD_ZERO(&w);
  FD_ZERO(&e);
 
@@ -374,4 +375,8 @@
    FD_SET(fh, &r);
    FD_SET(fh, &e);
+
+   if ( g_clients[i]->outbuf != NULL ) {
+    FD_SET(fh, &w);
+   }
 
    if ( fh > max_fh )
@@ -408,5 +413,5 @@
   return 0;
 
- if ( (ret = select(max_fh + 1, &r, NULL, &e, &tv)) < 1 ) {
+ if ( (ret = select(max_fh + 1, &r, &w, &e, &tv)) < 1 ) {
   return ret < 0 ? ret : have;
  }
@@ -429,4 +434,7 @@
     }
    }
+   if ( FD_ISSET(fh, &w) ) {
+    clients_flush(i);
+   }
 
    if ( FD_ISSET(fh, &e) ) {
@@ -458,4 +466,5 @@
  if ( have_streamless ) {
    FD_ZERO(&r);
+   FD_ZERO(&w);
 
    tv.tv_sec  = 0;
@@ -476,9 +485,13 @@
     FD_SET(fh, &r);
 
+    if ( g_clients[i]->outbuf != NULL ) {
+     FD_SET(fh, &w);
+    }
+
     if ( fh > max_fh )
      max_fh = fh;
    }
 
-   if ( (ret = select(max_fh + 1, &r, NULL, NULL, &tv)) < 0 ) {
+   if ( (ret = select(max_fh + 1, &r, &w, NULL, &tv)) < 0 ) {
     return ret;
    }
@@ -487,4 +500,7 @@
     if ( FD_ISSET(streamless[i].fh, &r) ) {
      clients_check(streamless[i].id);
+    }
+    if ( FD_ISSET(streamless[i].fh, &w) ) {
+     clients_flush(streamless[i].id);
     }
    }
@@ -602,4 +618,65 @@
 }
 
+int clients_flush      (int id) {
+ struct roar_vio_calls         vio;
+ struct roar_client_server   * cs;
+ struct roar_client          * c;
+ struct roard_proto          * p = NULL;
+ size_t i;
+ size_t len;
+ ssize_t ret;
+ void * buf;
+
+ _CHECK_CID(id);
+
+ c = ROAR_CLIENT(cs = g_clients[id]);
+
+ for (i = 0; g_proto[i].proto != -1; i++) {
+  if ( g_proto[i].proto == c->proto ) {
+   p = &(g_proto[i]);
+   break;
+  }
+ }
+
+ if ( p == NULL )
+  return -1;
+
+ roar_vio_open_fh_socket(&vio, clients_get_fh(id));
+
+ if ( p->flush_client != NULL ) {
+  return p->flush_client(id, &vio);
+ }
+
+ if ( roar_buffer_get_len(cs->outbuf, &len) == -1 )
+  return -1;
+
+ if ( roar_buffer_get_data(cs->outbuf, &buf) == -1 )
+  return -1;
+
+ ret = roar_vio_write(&vio, buf, len);
+
+ if ( ret < 1 ) {
+  clients_delete(id);
+  return -1;
+ }
+
+ if ( ret == len ) {
+  roar_buffer_next(&(cs->outbuf));
+ } else {
+  if ( roar_buffer_set_offset(cs->outbuf, ret) == -1 ) {
+   clients_delete(id);
+   return -1;
+  }
+ }
+
+ if ( cs->outbuf == NULL ) {
+  if ( p->flushed_client != NULL ) {
+   return p->flushed_client(id, &vio);
+  }
+ }
+
+ return 0;
+}
+
 int clients_send_mon  (struct roar_audio_info * sa, uint32_t pos) {
  int i;
@@ -674,4 +751,19 @@
 
  return -1;
+}
+
+int clients_add_output (int id, struct roar_buffer * buf) {
+ struct roar_client_server   * cs;
+
+ _CHECK_CID(id);
+ cs = g_clients[id];
+
+ if ( cs->outbuf == NULL ) {
+  cs->outbuf = buf;
+ } else {
+  return roar_buffer_add(cs->outbuf, buf);
+ }
+
+ return 0;
 }
 
Index: roard/include/client.h
===================================================================
--- roard/include/client.h	(revision 4684)
+++ roard/include/client.h	(revision 4686)
@@ -77,4 +77,6 @@
  int (*new_client)(int client, struct roar_vio_calls * vio, struct roard_listen * lsock);
  int (*check_client)(int client, struct roar_vio_calls * vio);
+ int (*flush_client)(int client, struct roar_vio_calls * vio);
+ int (*flushed_client)(int client, struct roar_vio_calls * vio);
 };
 
@@ -104,6 +106,9 @@
 int clients_check_all  (void);
 int clients_check      (int id);
+int clients_flush      (int id);
 int clients_send_mon   (struct roar_audio_info * sa, uint32_t pos);
 int clients_send_filter(struct roar_audio_info * sa, uint32_t pos);
+
+int clients_add_output (int id, struct roar_buffer * buf);
 
 // proto support
