#include #include #include #include #include "entity.h" /* The way an raw-io tag can look in the xml. * */ static void rendio_raw_io_do (ENode * node, int source, char *function) { enode_call_ignore_return (node, function, ""); } static int rendio_raw_io_ready_callback (gint source, EIOCond cond, ENode * node) { gchar *oncanread; gchar *oncanwrite; gchar *onerror; EDEBUG ( ("raw-io-renderer", "in rendio_raw_io_ready_callback, cond = %i", cond)); if (cond & EIO_READ) { oncanread = enode_attrib_str (node, "oncanread", NULL); rendio_raw_io_do (node, source, oncanread); } if (cond & EIO_WRITE) { oncanwrite = enode_attrib_str (node, "oncanwrite", NULL); rendio_raw_io_do (node, source, oncanwrite); } if (cond & EIO_ERROR) { onerror = enode_attrib_str (node, "onerror", NULL); rendio_raw_io_do (node, source, onerror); } return FALSE; } static EIOCond rendio_raw_io_get_condition (ENode * node) { EIOCond cond = EIO_READ; char *oncanread; char *oncanwrite; char *onerror; oncanread = enode_attrib_str (node, "oncanread", NULL); oncanwrite = enode_attrib_str (node, "oncanwrite", NULL); onerror = enode_attrib_str (node, "onerror", NULL); if (oncanread && strlen (oncanread)) { cond |= EIO_READ; } if (oncanwrite && strlen (oncanwrite)) { cond |= EIO_WRITE; } if (onerror && strlen (onerror)) { cond |= EIO_READ; } EDEBUG (("raw-io-renderer", "cond = %i, read = %i", cond, EIO_READ)); return cond; } static int rendio_raw_io_fd_attr_set (ENode * node, EBuf * attr, EBuf * value) { EIOCond cond; int source; gpointer tag; gpointer old_tag; old_tag = enode_get_kv (node, "rendio-raw-io-tag"); source = erend_get_integer (value); if (source < 0) { /* need to delete the old tag and callback connection. */ EDEBUG (("raw-io-renderer", "going to delete old tag")); if (old_tag) { entity_mainloop->io_remove (old_tag); } return TRUE; /* Source of <0 means disconnect completely. */ } if (old_tag) { /* need to delete the old tag and callback connection. */ entity_mainloop->io_remove (old_tag); } cond = rendio_raw_io_get_condition (node); /* No blocking io is alowed... */ fcntl (source, F_SETFL, O_NONBLOCK); EDEBUG (("raw-io-renderer", "source = %i, cond = %i", source, cond)); tag = entity_mainloop->io_add (source, cond, (void *) rendio_raw_io_ready_callback, node); enode_set_kv (node, "rendio-raw-io-tag", tag); return TRUE; } static void rendio_raw_io_render (ENode * node) { enode_attribs_sync (node); enode_set_kv (node, "rendio-raw-io-tag", NULL); } static void rendio_raw_io_destroy (ENode * node) { gpointer tag; tag = enode_get_kv (node, "rendio-raw-io-tag"); if (tag) entity_mainloop->io_remove (tag); } static void rendio_raw_io_parent (ENode * parent_node, ENode * child_node) { /* Short curcuit the node so that you can stick the timer node anywhere */ parent_node->entity_data = child_node->entity_data; } void raw_io_renderer_register (void) { Element *element; ElementAttr *e_attr; element = g_new0 (Element, 1); element->render_func = rendio_raw_io_render; element->destroy_func = rendio_raw_io_destroy; element->parent_func = rendio_raw_io_parent; element->tag = "raw-io"; element->description = "Event driven IO watcher. Feed it a file descriptor, and it'll call you when data arrives, or is ready to be sent."; element_register (element); e_attr = g_new0 (ElementAttr, 1); e_attr->attribute = "fd"; e_attr->description = "Sepcify the file descripter to watch"; e_attr->value_desc = "integer"; e_attr->possible_values = "-1,*"; e_attr->set_attr_func = rendio_raw_io_fd_attr_set; element_register_attrib (element, e_attr); e_attr = g_new0 (ElementAttr, 1); e_attr->attribute = "oncanread"; e_attr->description = "Function to call when the fd is ready for reading."; e_attr->value_desc = "function"; e_attr->set_attr_func = NULL; element_register_attrib (element, e_attr); e_attr = g_new0 (ElementAttr, 1); e_attr->attribute = "oncanwrite"; e_attr->description = "Function to call when the fd is ready for writing."; e_attr->value_desc = "function"; e_attr->set_attr_func = NULL; element_register_attrib (element, e_attr); e_attr = g_new0 (ElementAttr, 1); e_attr->attribute = "onerror"; e_attr->description = "Function to call when an exception occurs on the fd."; e_attr->value_desc = "function"; e_attr->set_attr_func = NULL; element_register_attrib (element, e_attr); }