コード例 #1
0
/** send data packet to arduino */
NftResult ad_txPacket(struct priv *p,
                      unsigned char opcode,
                      unsigned char *data, unsigned char size)
{

        /* send opcode */
        if(write(p->fd, &opcode, 1) == -1)
        {
                NFT_LOG_PERROR("write()");
                return NFT_FAILURE;
        }


        /* send datasize */
        if(write(p->fd, &size, 1) == -1)
        {
                NFT_LOG_PERROR("write()");
                return NFT_FAILURE;
        }


        /* send data */
        if(write(p->fd, data, (size_t) size) == -1)
        {
                NFT_LOG_PERROR("write()");
                return NFT_FAILURE;
        }

        return NFT_SUCCESS;
}
コード例 #2
0
/**
 *  show yes/no dialog and wat for answer
 */
gboolean ui_log_dialog_yesno(
        char *title,
        char *message,
        ...)
{
        if(!message)
                NFT_LOG_NULL(false);

        /* allocate mem to build message */
        char *tmp;
        if(!(tmp = alloca(MAX_MSG_SIZE)))
        {
                NFT_LOG_PERROR("alloca");
                return false;
        }

        /* build message */
        va_list ap;
        va_start(ap, message);

        /* print log-string */
        if(vsnprintf((char *) tmp, MAX_MSG_SIZE, message, ap) < 0)
        {
                NFT_LOG_PERROR("vsnprintf");
                return false;
        }

        va_end(ap);


        /* Create the widgets */
        GtkWidget *dialog, *label, *content_area;
        dialog = gtk_dialog_new_with_buttons(title,
                                             NULL,
                                             0,
                                             GTK_STOCK_NO,
                                             GTK_RESPONSE_REJECT,
                                             GTK_STOCK_YES,
                                             GTK_RESPONSE_ACCEPT, NULL);
        content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
        label = gtk_label_new(tmp);

        /* Add the label, and show everything we've added to the dialog. */
        gtk_container_add(GTK_CONTAINER(content_area), label);
        gtk_widget_show_all(dialog);

        /* wait for answer */
        gboolean result = false;
        if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
                result = true;

        gtk_widget_destroy(dialog);

        return result;
}
コード例 #3
0
/**
 * initialize this plugin
 */
static NftResult _init(void **privdata, LedHardware * hw)
{
        /** create niftylino descriptor */
        Niftylino *n;
        if(!(n = calloc(1, sizeof(Niftylino))))
        {
                NFT_LOG_PERROR("calloc");
                return NFT_FAILURE;
        }

        /* save Niftylino descriptor as private-data */
        *privdata = n;

        /* initialize default usb timeout */
        n->usb_timeout = 2500;

        /* save our hardware descriptor for later */
        n->hw = hw;

        /* initialize usb subsystem */
        usb_init();

        /* enable debugging */
        int level = 0;
        if(nft_log_level_is_noisier_than(nft_log_level_get(), L_VERBOSE))
                level = 3;
        else if(nft_log_level_is_noisier_than(nft_log_level_get(), L_INFO))
                level = 2;
        else if(nft_log_level_is_noisier_than(nft_log_level_get(), L_ERROR))
                level = 1;

        usb_set_debug(level);

        return NFT_SUCCESS;
}
コード例 #4
0
ファイル: artnet.c プロジェクト: niftylight/niftyled-plugins
/**
 * called upon plugin load
 */
static NftResult _init(void **privdata, LedHardware * h)
{
        NFT_LOG(L_INFO, "Initializing plugin...");


        /* allocate private structure */
        struct priv *p;
        if(!(p = calloc(1, sizeof(struct priv))))
        {
                NFT_LOG_PERROR("calloc");
                return NFT_FAILURE;
        }


        /* register our config-structure */
        *privdata = p;

        /* save our hardware descriptor */
        p->hw = h;





        // ~ /* register dynamic property for artnet address */
        // ~ if(!led_hardware_plugin_prop_register(h, "address",
        // LED_HW_CUSTOM_PROP_STRING))
        // ~ return NFT_FAILURE;
        // ~ /* register dynamic property for artnet port / universe */
        // ~ if(!led_hardware_plugin_prop_register(h, "port",
        // LED_HW_CUSTOM_PROP_INT))
        // ~ return NFT_FAILURE;

        return NFT_SUCCESS;
}
コード例 #5
0
/**
 * sample current time
 */
NftResult led_fps_sample()
{

        if(gettimeofday(&_last, NULL) != 0)
        {
                NFT_LOG_PERROR("gettimeofday");
                return NFT_FAILURE;
        }

        return NFT_SUCCESS;
}
コード例 #6
0
/**
 * show alert/error message
 *
 * @param message printable text that will be presented to the user
 */
void ui_log_alert_show(
        char *message,
        ...)
{
        /* just hide when message is NULL */
        if(!message)
        {
                gtk_widget_set_visible(GTK_WIDGET(UI("alert_dialog")), FALSE);
                return;
        }

        /* allocate mem to build message */
        char *tmp;
        if(!(tmp = alloca(MAX_MSG_SIZE)))
        {
                NFT_LOG_PERROR("alloca");
                return;
        }

        /* build message */
        va_list ap;
        va_start(ap, message);

        /* print log-string */
        if(vsnprintf((char *) tmp, MAX_MSG_SIZE, message, ap) < 0)
        {
                NFT_LOG_PERROR("vsnprintf");
                return;
        }

        va_end(ap);

        /* putout message through niftyled log mechanism also */
        NFT_LOG(L_ERROR, "%s", tmp);

        /* set message */
        gtk_label_set_text(GTK_LABEL(UI("alert_label")), tmp);

        /* show dialog */
        gtk_widget_set_visible(GTK_WIDGET(UI("alert_dialog")), TRUE);
}
コード例 #7
0
ファイル: node.c プロジェクト: niftylight/niftyprefs
/**
 * create preferences minimal buffer from NftPrefsNode - compared to
 * nft_prefs_node_to_buffer, this doesn't include any encapsulation or headers.
 * Just the bare information contained in the node. This should be used to
 * export single nodes, e.g. for copying them to a clipboard 
 *
 * @param p NftPrefs context  
 * @param n NftPrefsNode
 * @result string holding xml representation of object (use free() to deallocate)
 * @note s. @ref nft_prefs_node_to_file for description
 */
char *nft_prefs_node_to_buffer_minimal(NftPrefs *p, NftPrefsNode * n)
{
        if(!n)
                NFT_LOG_NULL(NULL);

        /* result pointer (xml dump) */
        char *dump = NULL;

        /* add prefs version to node */
        if(!(_updater_node_add_version(p, n)))
        {
                NFT_LOG(L_ERROR, "failed to add version to node \"%s\"",
                        nft_prefs_node_get_name(n));
                return NULL;
        }

        /* create buffer */
        xmlBufferPtr buf;
        if(!(buf = xmlBufferCreate()))
        {
                NFT_LOG(L_ERROR, "failed to xmlBufferCreate()");
                return NULL;
        }

        /* dump node */
        if(xmlNodeDump(buf, n->doc, n, 0, true) < 0)
        {
                NFT_LOG(L_ERROR, "xmlNodeDump() failed");
                goto _pntb_exit;
        }

        /* allocate buffer */
        size_t length = xmlBufferLength(buf);
        if(!(dump = malloc(length + 1)))
        {
                NFT_LOG_PERROR("malloc()");
                goto _pntb_exit;
        }

        /* copy buffer */
        strncpy(dump, (char *) xmlBufferContent(buf), length);
        dump[length] = '\0';

_pntb_exit:
        xmlBufferFree(buf);

        return dump;
}
コード例 #8
0
ファイル: magick.c プロジェクト: waebbl/ledcat
/**
 * initialize stream for ImageMagick
 */
NftResult im_open_stream(struct Ledcat *c)
{
#if HAVE_IMAGEMAGICK == 1
    /* open a stream (for ImageMagick)? */
    if(!c->raw)
    {
        /* open stream from file-descriptor */
        if(!(c->file = fdopen(c->fd, "r")))
        {
            NFT_LOG_PERROR("fdopen()");
            return FALSE;
        }
    }
#endif
    return TRUE;
}
コード例 #9
0
/**
 * read a complete raw pixel-frame
 */
int raw_read_frame(bool *running, char *buf, int fd, size_t size)
{

        ssize_t bytes_to_read, bytes_read = 0;
        
        for(bytes_to_read = size; 
            bytes_to_read > 0;  
            bytes_to_read -= bytes_read)
        {		
                /* read from stdin? */
                //~ if(fd == STDIN_FILENO)
                //~ {
                        //~ /* prepare stuff for select() */
                        //~ fd_set fds;
                        //~ struct timeval tv;
                        //~ FD_ZERO(&fds);
                        //~ FD_SET(fd, &fds);
                        //~ tv.tv_sec = 0;
                        //~ tv.tv_usec = 500;
                        
                        //~ /* wait for incoming data */
                        //~ while(*running && (select(1, &fds, NULL, NULL, &tv) == 0));
                //~ }
                                                
                /* break loop if we're not running anymore */
                if(!*running)
                        break;

                /* read data into buffer */
                if((bytes_read = read(fd, buf, bytes_to_read)) < 0)
                {
                        NFT_LOG_PERROR("read()");
                        return 0;
                }

                /* end of file? */
                if(fd != STDIN_FILENO && bytes_read == 0)
                	break;
                                
                buf += bytes_read;
        }

        return bytes_read;
}
コード例 #10
0
/**
 * called upon plugin load
 *
 * You should:
 * - do any non-hardware initialization/checking here 
 * - register plugin properties
 * - fill in "privdata" if you want to use a private pointer that's passed to
 *   the plugin in subsequent calls.
 *
 * @param privdata space for a private pointer.  
 * @param h LedHardware descriptor belonging to this plugin
 * @result NFT_SUCCESS or NFT_FAILURE upon error
 */
static NftResult _init(void **privdata, LedHardware * h)
{
        NFT_LOG(L_DEBUG, "Initializing LDP8806 plugin...");


        /* allocate private structure */
        struct priv *p;
        if(!(p = calloc(1, sizeof(struct priv))))
        {
                NFT_LOG_PERROR("calloc");
                return NFT_FAILURE;
        }


        /* register our config-structure */
        *privdata = p;

        /* save our hardware descriptor */
        p->hw = h;


        /* defaults */
        p->ledcount = 0;
        p->spiMode = SPI_MODE_0;
        p->spiBPW = 8;
        p->spiDelay = 0;
        p->spiSpeed = 500000;

        /* 
         * register some dynamic properties for this plugin - those will be
         * set/read in the _get/set_handler() from this plugin
         */
        if(!led_hardware_plugin_prop_register
           (h, "spi_speed", LED_HW_CUSTOM_PROP_INT))
                return NFT_FAILURE;
        if(!led_hardware_plugin_prop_register
           (h, "spi_delay", LED_HW_CUSTOM_PROP_INT))
                return NFT_FAILURE;


        return NFT_SUCCESS;
}
コード例 #11
0
/** send/receive SPI data */
NftResult spiTxData(int fd, uint8_t * tx, uint32_t len)
{
        /* SPI transfer descriptor */
        struct spi_ioc_transfer tr;

        /* zero initialize */
        memset(&tr, 0, sizeof(struct spi_ioc_transfer));

        tr.tx_buf = (unsigned long) tx;
        tr.len = len;
        tr.cs_change = false;

        if(ioctl(fd, SPI_IOC_MESSAGE(1), &tr) < 1)
        {
                NFT_LOG_PERROR("Failed to send SPI message:");
                return NFT_FAILURE;
        }

        return NFT_SUCCESS;
}
コード例 #12
0
/**
 * delay until next frame is due
 */
NftResult led_fps_delay(int fps)
{
        /* get current-time */
        struct timeval current;
        if(gettimeofday(&current, NULL) != 0)
        {
                NFT_LOG_PERROR("gettimeofday");
                return NFT_FAILURE;
        }

        /* calc delay from fps */
        long fps_sec = (1 / fps);
        long fps_usec = (1000000 / fps);

        /* delay if frame isn't due yet */
        if(((_last.tv_sec + fps_sec) >= current.tv_sec) &&
           ((_last.tv_usec + fps_usec) > current.tv_usec))
        {
                /* calc time to delay */
                unsigned long _usec =
                        (_last.tv_usec + fps_usec) - current.tv_usec;
                unsigned long _sec =
                        (_last.tv_sec + fps_sec) - current.tv_sec;
                usleep(_usec + (_sec * 1000000));

                /* calculate current fps */
                _current_fps = 1000000 /
                        ((current.tv_usec - _last.tv_usec +
                          (current.tv_sec - _last.tv_sec) * 1000000) +
                         (_usec + (_sec * 1000000)));
        }
        else
        {
                /* calculate current fps */
                _current_fps =
                        1000000 / (current.tv_usec - _last.tv_usec +
                                   (current.tv_sec - _last.tv_sec) * 1000000);
        }

        return NFT_SUCCESS;
}
コード例 #13
0
ファイル: prefs.c プロジェクト: niftylight/niftyprefs
/**
 * initialize libniftyprefs - call this once before doing any other API call
 *
 * @result new NftPrefs descriptor or NULL upon failure
 */
NftPrefs *nft_prefs_init(unsigned int version)
{

        /* 
         * this initializes the library and check potential ABI mismatches
         * between the version it was compiled for and the actual shared
         * library used.
         */
        if(!NFT_PREFS_CHECK_VERSION)
                return NULL;

        xmlSetBufferAllocationScheme(XML_BUFFER_ALLOC_DOUBLEIT);

        /* register error-logging function */
        xmlSetGenericErrorFunc(NULL, _xml_error_handler);

        /* needed for indented output */
        xmlKeepBlanksDefault(0);

        /* allocate new NftPrefs context */
        NftPrefs *p;
        if(!(p = calloc(1, sizeof(NftPrefs))))
        {
                NFT_LOG_PERROR("calloc");
                return NULL;
        }

        /* save version */
        p->version = version;

        /* allocate array to store classes that will be registered */
        if(!_class_init_array(&p->classes))
        {
                NFT_LOG(L_ERROR, "Failed to init class array");
                free(p);
                return NULL;
        }

        return p;
}
コード例 #14
0
/**
 * called upon plugin load
 *
 * You should:
 * - do any non-hardware initialization/checking here 
 * - register plugin properties
 * - fill in "privdata" if you want to use a private pointer that's passed to
 *   the plugin in subsequent calls.
 *
 * @param privdata space for a private pointer.  
 * @param h LedHardware descriptor belonging to this plugin
 * @result NFT_SUCCESS or NFT_FAILURE upon error
 */
static NftResult _init(void **privdata, LedHardware * h)
{
        NFT_LOG(L_DEBUG, "Initializing arduino-max72xx plugin...");


        /* allocate private structure */
        struct priv *p;
        if(!(p = calloc(1, sizeof(struct priv))))
        {
                NFT_LOG_PERROR("calloc");
                return NFT_FAILURE;
        }


        /* register our config-structure */
        *privdata = p;

        /* save our hardware descriptor */
        p->hw = h;


        /* defaults */
        p->ledcount = 0;
        p->threshold = 128;

        /* 
         * register some dynamic properties for this plugin - those will be
         * set/read in the _get/set_handler() from this plugin
         */
        if(!led_hardware_plugin_prop_register
           (h, "threshold", LED_HW_CUSTOM_PROP_INT))
                return NFT_FAILURE;
        if(!led_hardware_plugin_prop_register
           (h, "scan_limit", LED_HW_CUSTOM_PROP_INT))
                return NFT_FAILURE;

        return NFT_SUCCESS;
}
コード例 #15
0
/**
 * initialize hardware
 */
static NftResult _hw_init(void *privdata, const char *id)
{
        NFT_LOG(L_DEBUG, "Initializing arduino-max72xx hardware");

        struct priv *p = privdata;

        /* ... do checks ... */

        /* pixelformat supported? */
        LedPixelFormat *format =
                led_chain_get_format(led_hardware_get_chain(p->hw));
        if(led_pixel_format_get_bytes_per_pixel(format) != 1)
        {
                NFT_LOG(L_ERROR,
                        "This hardware only supports 1 bpp formats (e.g. \"Y u8\")");
                return NFT_FAILURE;
        }

        if(led_pixel_format_get_n_components(format) != 1)
        {
                NFT_LOG(L_ERROR,
                        "This hardware only supports 1 component per pixel (e.g. \"Y u8\")");
                return NFT_FAILURE;
        }

        const char *fmtstring =
                led_pixel_format_to_string(led_chain_get_format
                                           (led_hardware_get_chain(p->hw)));
        NFT_LOG(L_DEBUG, "Using \"%s\" as pixel-format", fmtstring);

        /* 
         * check if id = "*" in this case we should try to automagically find our device,
         * we'll just use a default in this case 
         */
        if(strcmp(id, "*") == 0)
        {
                strncpy(p->id, "/dev/ttyUSB0", sizeof(p->id));
        }
        else
        {
                /* copy our id (and/or change it) */
                strncpy(p->id, id, sizeof(p->id));
        }

        /* open serial port */
        if((p->fd = open(p->id, O_RDWR | O_NOCTTY)) == -1)
        {
                NFT_LOG(L_ERROR, "Failed to open port \"%s\"", p->id);
                NFT_LOG_PERROR("open()");
                return NFT_FAILURE;
        }

        /* save current port settings */
        tcgetattr(p->fd, &p->oldtio);

        /* space for new tio structure */
        struct termios newtio;
        memset(&newtio, 0, sizeof(struct termios));

        /* set new port settings */
        newtio.c_cflag = B115200 | CS8 | CSTOPB | CLOCAL | CREAD;
        newtio.c_iflag = IGNPAR | IGNBRK;
        newtio.c_oflag = 0;
        newtio.c_lflag = 0;
        newtio.c_cc[VMIN] = 1;
        newtio.c_cc[VTIME] = 5;
        tcflush(p->fd, TCIFLUSH);
        tcsetattr(p->fd, TCSANOW, &newtio);


        return NFT_SUCCESS;
}
コード例 #16
0
ファイル: node.c プロジェクト: niftylight/niftyprefs
/**
 * create preferences file from NftPrefsNode and child nodes
 *
 * This will create the same output as nft_prefs_node_to_file() would but
 * without all encapsulation/headers/footers/... of the underlying prefs mechanism.
 * e.g. for XML this omits the "<?xml version="1.0" encoding="UTF-8"?>" header.
 * This is used when one only needs an "incomplete" snippet of a configuration.
 * e.g. for copy/paste or to use the XInclude feature of XML
 * 
 * @param p NftPrefs context
 * @param n NftPrefsNode
 * @param filename full path of file to be written
 * @param overwrite if a file called "filename" already exists, it 
 * will be overwritten if this is "true", otherwise NFT_FAILURE will be returned
 * @result NFT_SUCCESS or NFT_FAILURE
 */
NftResult nft_prefs_node_to_file_minimal(NftPrefs *p, NftPrefsNode * n, const char *filename,
                                       bool overwrite)
{
        if(!n || !filename)
                NFT_LOG_NULL(NFT_FAILURE);

        /* file already existing? */
        struct stat sts;
        if(stat(filename, &sts) == -1)
        {
                /* continue if stat error was caused because file doesn't exist 
                 */
                if(errno != ENOENT)
                {
                        NFT_LOG(L_ERROR, "Failed to access \"%s\" - %s",
                                filename, strerror(errno));
                        return NFT_FAILURE;
                }
        }
        /* stat succeeded, file exists */
        else if(strcmp("-", filename) != 0)
        {
                /* remove old file? */
                if(!overwrite)
                        return NFT_FAILURE;

                /* delete existing file */
                if(unlink(filename) == -1)
                {
                        NFT_LOG(L_ERROR,
                                "Failed to remove old version of \"%s\" - %s",
                                filename, strerror(errno));
                        return NFT_FAILURE;
                }
        }

        /* overall result */
        NftResult r = NFT_FAILURE;

        /* add prefs version to node */
        if(!(_updater_node_add_version(p, n)))
        {
                NFT_LOG(L_ERROR, "failed to add version to node \"%s\"",
                        nft_prefs_node_get_name(n));
                return r;
        }

        /* create buffer */
        xmlBufferPtr buf;
        if(!(buf = xmlBufferCreate()))
        {
                NFT_LOG(L_ERROR, "failed to xmlBufferCreate()");
                return r;
        }

        /* dump node */
        if(xmlNodeDump(buf, n->doc, n, 0, true) < 0)
        {
                NFT_LOG(L_ERROR, "xmlNodeDump() failed");
                goto _pntf_exit;
        }

        /* stdout? */
        int fd;
        if(strcmp("-", filename) == 0)
        {
                fd = STDOUT_FILENO;
        }
        /* open file */
        else
        {
#ifdef WIN32
                if((fd = open(filename,
                              O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1)
#else
                if((fd = open(filename,
                              O_CREAT | O_WRONLY,
                              S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP)) == -1)
#endif
                {
                        NFT_LOG_PERROR("open");
                        goto _pntf_exit;
                }
        }

        /* write to file */
        ssize_t length = xmlBufferLength(buf);
        if(write(fd, (char *) xmlBufferContent(buf), length) != length)
        {
                NFT_LOG_PERROR("write");
                goto _pntf_exit;
        }

        if(fd != STDOUT_FILENO)
                close(fd);

        r = NFT_SUCCESS;

_pntf_exit:
        xmlBufferFree(buf);

        return r;
}
コード例 #17
0
ファイル: node.c プロジェクト: niftylight/niftyprefs
/**
 * create preferences buffer with all format specific encapsulation from a 
 * NftPrefsNode. This is used when one needs a complete configuration.
 *
 * @param p NftPrefs context
 * @param n NftPrefsNode
 * @result string holding xml representation of object or NULL upon error
 * @note use free() to deallocate; s. @ref nft_prefs_node_to_file for description
 */
char *nft_prefs_node_to_buffer(NftPrefs *p, NftPrefsNode * n)
{
        if(!n)
                NFT_LOG_NULL(NULL);

        /* add prefs version to node */
        if(!(_updater_node_add_version(p, n)))
        {
                NFT_LOG(L_ERROR, "failed to add version to node \"%s\"",
                        nft_prefs_node_get_name(n));
                return NULL;
        }

        /* create copy of node */
        NftPrefsNode *copy;
        if(!(copy = xmlCopyNode(n, 1)))
                return NULL;

        /* create temp xmlDoc */
        xmlDoc *d = NULL;
        if(!(d = xmlNewDoc(BAD_CAST "1.0")))
        {
                NFT_LOG(L_ERROR, "Failed to create new XML doc");
                xmlFreeNode(copy);
                return NULL;
        }

        /* set node as root element of temporary doc */
        xmlDocSetRootElement(d, copy);

        /* overall result */
        char *r = NULL;
        xmlChar *dump = NULL;
        int length = 0;

        /* dump document to buffer */
        xmlDocDumpFormatMemoryEnc(d, &dump, &length, "UTF-8", 1);
        if(!dump || length <= 0)
        {
                NFT_LOG(L_ERROR, "Failed to dump XML file");
                goto _pntbwh_exit;
        }

        if(!(r = malloc(length + 1)))
        {
                NFT_LOG_PERROR("malloc");
                goto _pntbwh_exit;
        }

        memcpy(r, dump, length);
        r[length] = '\0';

_pntbwh_exit:
        /* free node */
        if(copy)
        {
                /* unlink node from document again */
                xmlUnlinkNode(copy);
                xmlFreeNode(copy);
        }

        /* free xml buffer */
        if(dump)
                xmlFree(dump);

        /* free temporary xmlDoc */
        if(d)
        {
                xmlFreeDoc(d);
        }

        return r;
}
コード例 #18
0
int main(int argc, char *argv[])
{
        /** return value of main() */
        int res = 1;
        /* current configuration */
        LedPrefs *prefs = NULL;
	/* current setup */
	LedSetup *setup = NULL;
        /** framebuffer for captured image */
        LedFrame *frame = NULL;



        /* check binary version compatibility */
        NFT_LED_CHECK_VERSION


        /* set default loglevel to INFO */
	nft_log_level_set(L_INFO);


	/* initialize exit handlers */
	int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT };
	unsigned int i;
	for(i=0; i<sizeof(signals)/sizeof(int); i++)
	{
		if(signal(signals[i], _exit_signal_handler) == SIG_ERR)
		{
			NFT_LOG_PERROR("signal()");
			goto _m_exit;
		}
	}



        /* default fps */
        _c.fps = 25;

        /* default mechanism */
        _c.method = METHOD_MIN+1;

        /* default config-filename */
        if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcap.xml"))
                goto _m_exit;

        /* parse cmdline-arguments */
        if(!_parse_args(argc, argv))
                goto _m_exit;


	/* print welcome msg */
	NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcap_version_long());
	NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get()));



	/* initialize preferences context */
    	if(!(prefs = led_prefs_init()))
    		return -1;

	/* parse prefs-file */
    	LedPrefsNode *pnode;
    	if(!(pnode = led_prefs_node_from_file(_c.prefsfile)))
    	{
		NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"",
		        		_c.prefsfile);
		goto _m_exit;
	}

        /* create setup from prefs-node */
    	if(!(setup = led_prefs_setup_from_node(prefs, pnode)))
    	{
		NFT_LOG(L_ERROR, "No valid setup found in preferences file.");
		led_prefs_node_free(pnode);
		goto _m_exit;
	}

    	/* free preferences node */
    	led_prefs_node_free(pnode);




        /* determine width of input-frames */
        LedFrameCord width, height;
        if((width = led_setup_get_width(setup)) > _c.width)
        {
                NFT_LOG(L_WARNING, "LED-Setup width (%d) > our width (%d). Using setup-value",
                        width,_c.width);
                /* use dimensions of mapped chain */
                _c.width = width;
        }

        /* determine height of input-frames */
        if((height = led_setup_get_height(setup)) > _c.height)
        {
                NFT_LOG(L_WARNING, "LED-Setup height (%d) > our height (%d). Using setup-value.",
                        height, _c.height);
                /* use dimensions of mapped chain */
                _c.height = height;
        }


        if(_c.width < 0)
        {
                NFT_LOG(L_ERROR, "width (%d) < 0", _c.width);
                goto _m_exit;
        }

        if(_c.height < 0)
        {
                NFT_LOG(L_ERROR, "height (%d) < 0", _c.height);
                goto _m_exit;
        }

        /* sanitize x-offset @todo check for maximum */
        if(_c.x < 0)
        {
                NFT_LOG(L_ERROR, "Invalid x coordinate: %d, using 0", _c.x);
                _c.x = 0;
        }

        /* sanitize y-offset @todo check for maximum */
        if(_c.y < 0)
        {
                NFT_LOG(L_ERROR, "Invalid y coordinate: %d, using 0", _c.y);
                _c.y = 0;
        }


        /* initialize capture mechanism (only imlib for now) */
        if(!capture_init(_c.method))
                goto _m_exit;

        /* allocate framebuffer */
        NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)",
	        _c.width, _c.height, capture_format());
        if(!(frame = led_frame_new(_c.width, _c.height, led_pixel_format_from_string(capture_format()))))
                goto _m_exit;

        /* respect endianess */
        led_frame_set_big_endian(frame, capture_is_big_endian());

        /* get first hardware */
        LedHardware *hw;
        if(!(hw = led_setup_get_hardware(setup)))
                goto _m_exit;

        /* initialize pixel->led mapping */
        if(!led_hardware_list_refresh_mapping(hw))
                goto _m_exit;

        /* precalc memory offsets for actual mapping */
        if(!led_chain_map_from_frame(led_hardware_get_chain(hw), frame))
                goto _m_exit;

        /* set saved gain to all registered hardware instances */
        if(!led_hardware_list_refresh_gain(hw))
                goto _m_exit;


	/* print some debug-info */
        led_frame_print(frame, L_VERBOSE);
        led_hardware_print(hw, L_VERBOSE);


        /* initially sample time for frametiming */
        if(!led_fps_sample())
                goto _m_exit;


        /* output some useful info */
        NFT_LOG(L_INFO, "Capturing %dx%d pixels at position x/y: %d/%d", _c.width, _c.height, _c.x, _c.y);

        /* loop until _c.running is set to FALSE */
        _c.running = TRUE;
        while(_c.running)
        {
                /* capture frame */
                if(!(capture_frame(frame, _c.x, _c.y)))
                        break;

                /* print frame for debugging */
                //led_frame_buffer_print(frame);

                /* map from frame */
                LedHardware *h;
                for(h = hw; h; h = led_hardware_list_get_next(h))
                {
                        if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame))
                        {
                                NFT_LOG(L_ERROR, "Error while mapping frame");
                                break;
                        }
                }


                /* send frame to hardware(s) */
                led_hardware_list_send(hw);

                /* delay in respect to fps */
                if(!led_fps_delay(_c.fps))
                        break;

                /* show frame */
                led_hardware_list_show(hw);

                /* save time when frame is displayed */
                if(!led_fps_sample())
                        break;
        }



        /* mark success */
        res = 0;

_m_exit:
        /* deinitialize capture mechanism */
        capture_deinit();

	/* free frame */
        led_frame_destroy(frame);

	/* destroy config */
        led_setup_destroy(setup);

	/* destroy config */
        led_prefs_deinit(prefs);


        return res;
}
コード例 #19
0
/**
 * Object-to-Config function.
 * Creates a config-node (and subnodes) from a LedHardware model
 * @param c the current preferences context
 * @param n a freshly created prefs node that this function should fill with properties of obj
 * @param obj object of this class where preferences should be generated from
 * @result NFT_SUCCESS if everything went fine, NFT_FAILURE otherwise
 * @note you shouldn't call this function directly
 * It's used by nft_prefs_obj_to_node() etc.
 */
static NftResult _prefs_from_hardware(NftPrefs * p, NftPrefsNode * n,
                                      void *obj, void *userptr)
{
        if(!p || !n || !obj)
                NFT_LOG_NULL(NFT_FAILURE);

        /* hardware "object" */
        LedHardware *h = obj;



        /* name of hardware */
        if(!nft_prefs_node_prop_string_set(n, LED_HARDWARE_PROP_NAME,
                                           (char *) led_hardware_get_name(h)))
                return NFT_FAILURE;


        /* plugin family of hardware */
        if(!nft_prefs_node_prop_string_set(n, LED_HARDWARE_PROP_PLUGIN,
                                           (char
                                            *) led_hardware_plugin_get_family
                                           (h)))
                return NFT_FAILURE;


        /* id of hardware */
        if(!nft_prefs_node_prop_string_set(n, LED_HARDWARE_PROP_ID,
                                           (char *) led_hardware_get_id(h)))
                return NFT_FAILURE;


        /* LED stride */
        if(!nft_prefs_node_prop_int_set(n, LED_HARDWARE_PROP_STRIDE,
                                        led_hardware_get_stride(h)))
                return NFT_FAILURE;

        /* handle custom plugin properties */
        int i, a = led_hardware_plugin_prop_get_count(h);
        for(i = 0; i < a; i++)
        {
                LedPluginCustomProp *prop;
                if(!(prop = led_hardware_plugin_prop_get_nth(h, i)))
                {
                        NFT_LOG(L_ERROR,
                                "Could not get property %d (but %d registered). This is a bug!",
                                i, a);
                        break;
                }

                /* create new node for property */
                NftPrefsNode *pnode;
                if(!
                   (pnode = nft_prefs_node_alloc(LED_HARDWARE_PROPERTY_NAME)))
                {
                        NFT_LOG(L_ERROR, "Failed to create new node.");
                        return NFT_FAILURE;
                }

                /* name of property */
                if(!nft_prefs_node_prop_string_set
                   (pnode, LED_HARDWARE_PROPERTY_PROP_NAME,
                    (char *) led_hardware_plugin_prop_get_name(prop)))
                        return NFT_FAILURE;

                /* handle various types of properties */
                switch (led_hardware_plugin_prop_get_type(prop))
                {
                        case LED_HW_CUSTOM_PROP_STRING:
                        {
                                /* save type */
                                if(!nft_prefs_node_prop_string_set
                                   (pnode, LED_HARDWARE_PROPERTY_PROP_TYPE,
                                    "string"))
                                        return NFT_FAILURE;

                                /* get string */
                                char *string;
                                if(!led_hardware_plugin_prop_get_string(h,
                                                                        led_hardware_plugin_prop_get_name
                                                                        (prop),
                                                                        &string))
                                        return NFT_FAILURE;

                                /* save value */
                                if(!nft_prefs_node_prop_string_set
                                   (pnode, LED_HARDWARE_PROPERTY_PROP_VALUE,
                                    string))
                                        return NFT_FAILURE;

                                break;
                        }

                        case LED_HW_CUSTOM_PROP_INT:
                        {
                                /* save type */
                                if(!nft_prefs_node_prop_string_set
                                   (pnode, LED_HARDWARE_PROPERTY_PROP_TYPE,
                                    "int"))
                                        return NFT_FAILURE;

                                /* get integer */
                                int integer;
                                if(!led_hardware_plugin_prop_get_int(h,
                                                                     led_hardware_plugin_prop_get_name
                                                                     (prop),
                                                                     &integer))
                                        return NFT_FAILURE;

                                /* convert to string */
                                char *string;
                                if(!(string = alloca(64)))
                                {
                                        NFT_LOG_PERROR("alloca");
                                        return NFT_FAILURE;
                                }
                                snprintf(string, 64, "%d", integer);

                                /* save value */
                                if(!nft_prefs_node_prop_string_set
                                   (pnode, LED_HARDWARE_PROPERTY_PROP_VALUE,
                                    string))
                                        return NFT_FAILURE;
                                break;
                        }

                        case LED_HW_CUSTOM_PROP_FLOAT:
                        {
                                /* save type */
                                if(!nft_prefs_node_prop_string_set
                                   (pnode, LED_HARDWARE_PROPERTY_PROP_TYPE,
                                    "float"))
                                        return NFT_FAILURE;

                                /* get float */
                                float fp;
                                if(!led_hardware_plugin_prop_get_float(h,
                                                                       led_hardware_plugin_prop_get_name
                                                                       (prop),
                                                                       &fp))
                                        return NFT_FAILURE;

                                /* convert to string */
                                char *string;
                                if(!(string = alloca(64)))
                                {
                                        NFT_LOG_PERROR("alloca");
                                        return NFT_FAILURE;
                                }
                                snprintf(string, 64, "%f", fp);

                                /* save value */
                                if(!nft_prefs_node_prop_string_set
                                   (pnode, LED_HARDWARE_PROPERTY_PROP_VALUE,
                                    string))
                                        return NFT_FAILURE;

                                break;
                        }

                                /* unsupported type */
                        default:
                        {
                                NFT_LOG(L_WARNING,
                                        "Property \"%s\" is of unsupported type. Ignoring",
                                        led_hardware_plugin_prop_get_name
                                        (prop));
                                continue;
                        }
                }

                /* add node as child of this node */
                nft_prefs_node_add_child(n, pnode);

        }

        /* chain of this hardware */
        LedChain *c;
        if((c = led_hardware_get_chain(h)))
        {
                /* generate prefs node from chain */
                NftPrefsNode *node;
                if(!(node = led_prefs_chain_to_node(p, c)))
                        return NFT_FAILURE;

                /* add node as child of this node */
                nft_prefs_node_add_child(n, node);
        }

        /* tiles of this hardware */
        LedTile *t;
        for(t = led_hardware_get_tile(h); t; t = led_tile_list_get_next(t))
        {
                NftPrefsNode *node;
                if(!(node = led_prefs_tile_to_node(p, t)))
                        return NFT_FAILURE;

                /* add node as child of this node */
                nft_prefs_node_add_child(n, node);
        }


        /* all OK */
        return NFT_SUCCESS;
}
コード例 #20
0
int main(int argc, char *argv[])
{
        /* current configuration */
        LedPrefs *p = NULL;
    	/** current setup */
    	LedSetup *s = NULL;
        /** list of LED hardware adapters */
        LedHardware *hw = NULL;
        /* input pixel-frame buffer */
        LedFrame *frame = NULL;
        /** width of map */
        LedFrameCord width;
        /** height of map */
        LedFrameCord height;



        /* check libniftyled binary version compatibility */
        NFT_LED_CHECK_VERSION

        /* set default loglevel to INFO */
        nft_log_level_set(L_INFO);

        /* initialize exit handlers */
#if WIN32
        int signals[] = { SIGINT, SIGABRT };
#else
        int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT };
#endif
        unsigned int i;
        for(i=0; i<sizeof(signals)/sizeof(int); i++)
        {
            if(signal(signals[i], _exit_signal_handler) == SIG_ERR)
            {
                NFT_LOG_PERROR("signal()");
                return -1;
            }
        }



        /* default result of main() function */
        int res = -1;

        /* default fps */
        _c.fps = 25;

        /* default endianess */
        _c.is_big_endian = FALSE;

#if HAVE_IMAGEMAGICK == 1
        /* default handle-input-as-raw */
        _c.raw = FALSE;
#endif

        /* default looping */
        _c.do_loop = FALSE;

        /* set "running" flag */
        _c.running = TRUE;

        /* default pixel-format */
        strncpy(_c.pixelformat, "RGB u8", sizeof(_c.pixelformat));

        /* default prefs-filename */
        if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcat.xml"))
                return -1;


	/* parse commandline arguments */
	if(!_parse_args(argc, argv))
		return -1;



	/* print welcome msg */
	NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcat_version_long());
	NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get()));


#if HAVE_IMAGEMAGICK == 1
        /* initialize imagemagick */
        if(!_c.raw)
        {
                if(!im_init(&_c))
                {
                        NFT_LOG(L_ERROR, "Failed to initialize ImageMagick");
                        return -1;
                }
        }
#endif

    	/* initialize preferences context */
    	if(!(p = led_prefs_init()))
    		return -1;

	/* parse prefs-file */
    	LedPrefsNode *pnode;
    	if(!(pnode = led_prefs_node_from_file(_c.prefsfile)))
    	{
		NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"",
		        		_c.prefsfile);
		goto m_deinit;
	}

        /* create setup from prefs-node */
    	if(!(s = led_prefs_setup_from_node(p, pnode)))
    	{
		NFT_LOG(L_ERROR, "No valid setup found in preferences file.");
		led_prefs_node_free(pnode);
		goto m_deinit;
	}

    	/* free preferences node */
    	led_prefs_node_free(pnode);

        /* determine width of input-frames */
        if(!_c.width)
                /* width of mapped chain */
                width = led_setup_get_width(s);
        else
                /* use value from cmdline arguments */
                width = _c.width;


        /* determine height of input-frames */
        if(!_c.height)
                /* height of mapped chain */
                height = led_setup_get_height(s);
        else
                height = _c.height;


        /* validate dimensions */
        if(width <= 0 || height <= 0)
        {
                NFT_LOG(L_ERROR, "Dimensions %dx%d not possible in this universe. Exiting.", width, height);
                goto m_deinit;
        }


	/* allocate frame (where our pixelbuffer resides) */
	NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)",
	        width, height, _c.pixelformat);
        LedPixelFormat *format = led_pixel_format_from_string(_c.pixelformat);
	if(!(frame = led_frame_new(width, height, format)))
		goto m_deinit;


        /* get first toplevel hardware */
        if(!(hw = led_setup_get_hardware(s)))
                goto m_deinit;

        /* initialize hardware */
	/*if(!(led_hardware_init(hw, ledcount, (LedGreyscaleFormat) format)))
	{
		NFT_LOG(L_ERROR, "failed to initialize hardware.");
                goto m_deinit;
	}*/

        /* initialize pixel->led mapping */
        if(!led_hardware_list_refresh_mapping(hw))
                goto m_deinit;

        /* precalc memory offsets for actual mapping */
        LedHardware *ch;
        for(ch = hw; ch; ch = led_hardware_list_get_next(ch))
        {
                if(!led_chain_map_from_frame(led_hardware_get_chain(ch), frame))
                        goto m_deinit;
        }

        /* set correct gain to hardware */
        if(!led_hardware_list_refresh_gain(hw))
                goto m_deinit;

#if HAVE_IMAGEMAGICK == 1
        /* determine format that ImageMagick should provide */
        if(!_c.raw)
        {
                if(!(im_format(&_c, format)))
                {
                        NFT_LOG(L_ERROR, "Failed to determine valid ImageMagick format");
                        goto m_deinit;
                }
        }
#endif

	/* do we have at least one filename? */
	if(!_c.files[0])
	{
		NFT_LOG(L_ERROR, "No input file(s) given");
		goto m_deinit;
	}


        /* initially sample time for frame-timing */
        if(!led_fps_sample())
                goto m_deinit;


#if ! WIN32
        /* initialize alarm-signal handler for periodical fps output */
        {
                struct sigaction sa;
                struct itimerval timer;

                memset(&sa, 0, sizeof(sa));
                sa.sa_handler = &_alarm_signal_handler;
                sigaction(SIGALRM, &sa, NULL);
                timer.it_value.tv_sec = 1;
                timer.it_value.tv_usec = 0;
                timer.it_interval.tv_sec = 1;
                timer.it_interval.tv_usec = 0;
                setitimer(ITIMER_REAL, &timer, NULL);
        }
#endif

        /* get data-buffer of frame to write our pixels to */
        char *buf;
        if(!(buf = led_frame_get_buffer(frame)))
        {
                NFT_LOG(L_ERROR, "Frame has NULL buffer");
                goto m_deinit;
        }


	/* walk all files (supplied as commandline arguments) and output them */
	int filecount;
	for(filecount = 0; _c.files[filecount]; filecount++)
	{

		NFT_LOG(L_VERBOSE, "Getting pixels from \"%s\"", _c.files[filecount]);

		/* open file */
		if(_c.files[filecount][0] == '-' && strlen(_c.files[filecount]) == 1)
		{
			_c.fd = STDIN_FILENO;
		}
		else
		{
			if((_c.fd = open(_c.files[filecount], O_RDONLY)) < 0)
			{
				NFT_LOG(L_ERROR, "Failed to open \"%s\": %s",
				        _c.files[filecount], strerror(errno));
				continue;
			}
		}

#if HAVE_IMAGEMAGICK == 1
                /** initialize stream for ImageMagick */
                if(!_c.raw)
                {
                        if(!(im_open_stream(&_c)))
                                continue;
                }
#endif



		/* output file frame-by-frame */
		while(_c.running)
		{

#if HAVE_IMAGEMAGICK == 1
                        /* use imagemagick to load file if we're not in "raw-mode" */
                        if(!_c.raw)
                        {
                                /* load frame to buffer using ImageMagick */
                                if(!im_read_frame(&_c, width, height, buf))
                                        break;

                        }
                        else
                        {
#endif
                                /* read raw frame */
                                if(raw_read_frame(&_c.running, buf, _c.fd,
                                               led_pixel_format_get_buffer_size(
                                                        led_frame_get_format(frame),
                                                        led_frame_get_width(frame)*led_frame_get_height(frame))) == 0)
                                        continue;

#if HAVE_IMAGEMAGICK == 1
                        }
#endif

                        /* set endianess (flag will be changed when conversion occurs) */
                        led_frame_set_big_endian(frame, _c.is_big_endian);

			/* print frame for debugging */
			//nft_frame_buffer_print(frame);

			/* fill chain of every hardware from frame */
                        LedHardware *h;
                        for(h = hw; h; h = led_hardware_list_get_next(h))
                        {
                                if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame))
                                {
                                        NFT_LOG(L_ERROR, "Error while mapping frame");
                                        break;
                                }
                        }

			/* send frame to hardware(s) */
			NFT_LOG(L_DEBUG, "Sending frame");
                        led_hardware_list_send(hw);

			/* delay in respect to fps */
			if(!led_fps_delay(_c.fps))
				break;

			/* latch hardware */
			NFT_LOG(L_DEBUG, "Showing frame");
                        led_hardware_list_show(hw);


			/* save time when frame is displayed */
			if(!led_fps_sample())
				break;


			/* clear frame */
			//nft_frame_clear_buffer(frame);

		}


#if HAVE_IMAGEMAGICK == 1
		if(!_c.raw)
                	im_close_stream(&_c);
#else
                close(_c.fd);
#endif

                /* loop endlessly? */
                if((_c.running) && (!_c.files[filecount+1]) && _c.do_loop)
                {
                        /* start over by resetting the for-loop */
                        filecount = -1;
                }
	}

        /* all ok */
        res = 0;

m_deinit:
    	/* free setup */
    	led_setup_destroy(s);

	/* free frame */
	led_frame_destroy(frame);

        /* destroy config */
        led_prefs_deinit(p);

#if HAVE_IMAGEMAGICK == 1
        /* deinitialize ImageMagick */
        im_deinit(&_c);
#endif

        return res;
}
コード例 #21
0
/**
 * initialize hardware
 */
static NftResult _spi_init(void *privdata, const char *id)
{
        NFT_LOG(L_DEBUG, "Initializing LDP8806 hardware");

        struct priv *p = privdata;


        /* pixelformat supported? */
        LedPixelFormat *format =
                led_chain_get_format(led_hardware_get_chain(p->hw));
        const char *fmtstring = led_pixel_format_to_string(format);

        int bytes_per_pixel = led_pixel_format_get_bytes_per_pixel(format);
        int components_per_pixel = led_pixel_format_get_n_components(format);
        int bytes_per_component = bytes_per_pixel / components_per_pixel;

        if(bytes_per_component != 1)
        {
                NFT_LOG(L_ERROR,
                        "We need a format with 8 bits per pixel-component. Format %s has %d bytes-per-pixel and %d components-per-pixel.",
                        fmtstring, bytes_per_pixel, components_per_pixel);
                return NFT_FAILURE;
        }


        NFT_LOG(L_DEBUG, "Using \"%s\" as pixel-format", fmtstring);


        /* 
         * check if id = "*" in this case we should try to automagically find our device,
         * we'll just use a default in this case 
         * @todo cycle through all devices 
         */
        if(strcmp(id, "*") == 0)
        {
                strncpy(p->id, "/dev/spidev0.0", sizeof(p->id));
        }
        else
        {
                /* copy our id (and/or change it) */
                strncpy(p->id, id, sizeof(p->id));
        }

        /* open SPI port */
        if((p->fd = open(p->id, O_RDWR)) == -1)
        {
                NFT_LOG(L_ERROR, "Failed to open port \"%s\"", p->id);
                NFT_LOG_PERROR("open()");
                return NFT_FAILURE;
        }


        /* Set SPI parameters */
        if(ioctl(p->fd, SPI_IOC_WR_MODE, &p->spiMode) < 0)
                return NFT_FAILURE;

        if(ioctl(p->fd, SPI_IOC_RD_MODE, &p->spiMode) < 0)
                return NFT_FAILURE;

        if(ioctl(p->fd, SPI_IOC_WR_BITS_PER_WORD, &p->spiBPW) < 0)
                return NFT_FAILURE;

        if(ioctl(p->fd, SPI_IOC_RD_BITS_PER_WORD, &p->spiBPW) < 0)
                return NFT_FAILURE;

        if(ioctl(p->fd, SPI_IOC_WR_MAX_SPEED_HZ, &p->spiSpeed) < 0)
                return NFT_FAILURE;

        if(ioctl(p->fd, SPI_IOC_RD_MAX_SPEED_HZ, &p->spiSpeed) < 0)
                return NFT_FAILURE;

        NFT_LOG(L_DEBUG,
                "SPI \"%d\" initialized (mode: %d, bits-per-word: %d, speed-hz: %d)",
                p->spiMode, p->spiBPW, p->spiSpeed);

        return NFT_SUCCESS;
}
コード例 #22
0
/**
 * allocate a fresh slot from array so the pointer to the slot element can be
 * received with nft_array_get_slot() 
 * 
 * @param a NftArray descriptor
 * @param s pointer where new free slot will be written to 
 * @result NFT_SUCCESS or NFT_FAILURE 
 * @note Use nft_array_free_slot() if you don't need the slot anymore
 */
NftResult nft_array_slot_alloc(NftArray * a, NftArraySlot * s)
{
        if(!a)
                NFT_LOG_NULL(NFT_FAILURE);


        /* enough space left? */
        if(a->arraysize <= a->elementcount)
        {
                /* increase element descriptor array by NFT_ARRAY_INC elements */
                if(!(a->elements = realloc(a->elements,
                                           /* total elements new array can hold 
                                            */
                                           (a->arraysize +
                                            NFT_ARRAY_DEFAULT_INC) *
                                           /* size of one element descriptor */
                                           (sizeof(NftElement)))))
                {
                        NFT_LOG_PERROR("realloc()");
                        return NFT_FAILURE;
                }

                /* increase element buffer by NFT_ARRAY_INC elements */
                if(!(a->buffer = realloc(a->buffer,
                                         (a->arraysize +
                                          NFT_ARRAY_DEFAULT_INC) *
                                         a->elementsize)))
                {
                        NFT_LOG_PERROR("realloc()");
                        return NFT_FAILURE;
                }

                /* clear new memory */
                memset(&a->elements[a->arraysize],
                       0, NFT_ARRAY_DEFAULT_INC * sizeof(NftElement));
                memset(&a->buffer[a->elementsize * a->arraysize],
                       0, NFT_ARRAY_DEFAULT_INC * a->elementsize);

                /* remember new arraysize */
                a->arraysize += NFT_ARRAY_DEFAULT_INC;
        }


        /* find free slot in list */
        NftArraySlot i;
        for(i = 0; i < a->arraysize; i++)
        {
                if(!a->elements[i].occupied)
                {
                        /* set element as occupied */
                        a->elements[i].occupied = TRUE;

                        /* another element allocated... */
                        a->elementcount++;

                        /* save slot */
                        *s = i;

                        return NFT_SUCCESS;
                }
        }

        /* huh? */
        NFT_LOG(L_ERROR,
                "No free slot found in array \"%s\" but buffer was not increased. Something went wrong! Expect fancy stuff.",
                nft_array_get_name(a));

        return NFT_FAILURE;
}