/** * capture image */ static NftResult _capture(LedFrame *frame, LedFrameCord x, LedFrameCord y) { if(!frame) NFT_LOG_NULL(NFT_FAILURE); /* get screen-portion from X server */ XImage *image = NULL; if(!(image = XGetImage(_c.display, RootWindow(_c.display, _c.screen), x, y, led_frame_get_width(frame), led_frame_get_height(frame), AllPlanes, ZPixmap))) { NFT_LOG(L_ERROR, "XGetImage() failed"); return NFT_FAILURE; } /* copy framebuffer */ memcpy(led_frame_get_buffer(frame), image->data, led_frame_get_buffersize(frame)); /* destroy images */ XDestroyImage(image); return NFT_SUCCESS; }
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; }