diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b89af70..81479cb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,9 @@ message(STATUS "ENABLE_WS2812BPWM = " ${ENABLE_WS2812BPWM}) option(ENABLE_X11 "Enable the X11 grabber" OFF) message(STATUS "ENABLE_X11 = " ${ENABLE_X11}) +option(ENABLE_QT5 "Enable QT5" OFF) +message(STATUS "ENABLE_QT5 = " ${ENABLE_QT5}) + if(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF) message(FATAL_ERROR "V4L2 grabber requires PROTOBUF. Disable V4L2 or enable PROTOBUF") endif(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF) @@ -53,6 +56,10 @@ if(ENABLE_OSX AND ENABLE_DISPMANX) message(FATAL_ERROR "dispmanx grabber and osx grabber cannot be used at the same time") endif(ENABLE_OSX AND ENABLE_DISPMANX) +#if(ENABLE_QT5) +# TODO vs ENABLE_QT4? +#endif(ENABLE_QT5) + # Createt the configuration file # configure a header file to pass some of the CMake settings # to the source code @@ -61,8 +68,14 @@ include_directories("${PROJECT_BINARY_DIR}") # Add project specific cmake modules (find, etc) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +if(ENABLE_QT5) +ADD_DEFINITIONS ( -DENABLE_QT5 ) +#find_package(Qt5Widgets) +else(ENABLE_QT5) # Add specific cmake modules to find qt4 (default version finds first available QT which might not be qt4) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt4) +endif(ENABLE_QT5) # Define the global output path of binaries SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) @@ -85,15 +98,27 @@ set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++11 -Wall") +if(ENABLE_QT5) +#find_package(Qt5Core REQUIRED) +find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") +# set(CMAKE_CXX_FLAGS "-fPIC") +else(ENABLE_QT5) # Configure the use of QT4 find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED QUIET) +endif(ENABLE_QT5) #add libusb and pthreads find_package(libusb-1.0 REQUIRED) find_package(Threads REQUIRED) - +if(ENABLE_QT5) +#include(${QT_USE_FILE}) +add_definitions(${QT_DEFINITIONS}) +else(ENABLE_QT5) include(${QT_USE_FILE}) add_definitions(${QT_DEFINITIONS}) +endif(ENABLE_QT5) + # TODO[TvdZ]: This linking directory should only be added if we are cross compiling if(NOT APPLE) link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf) diff --git a/dependencies/LightberryHDUSBAPA1021.1.zip b/dependencies/LightberryHDUSBAPA1021.1.zip new file mode 100644 index 00000000..af1527ae Binary files /dev/null and b/dependencies/LightberryHDUSBAPA1021.1.zip differ diff --git a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino new file mode 100644 index 00000000..603599c9 --- /dev/null +++ b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino @@ -0,0 +1,274 @@ +// Arduino "bridge" code between host computer and WS2801-based digital +// RGB LED pixels (e.g. Adafruit product ID #322). Intended for use +// with USB-native boards such as Teensy or Adafruit 32u4 Breakout; +// works on normal serial Arduinos, but throughput is severely limited. +// LED data is streamed, not buffered, making this suitable for larger +// installations (e.g. video wall, etc.) than could otherwise be held +// in the Arduino's limited RAM. + +// Some effort is put into avoiding buffer underruns (where the output +// side becomes starved of data). The WS2801 latch protocol, being +// delay-based, could be inadvertently triggered if the USB bus or CPU +// is swamped with other tasks. This code buffers incoming serial data +// and introduces intentional pauses if there's a threat of the buffer +// draining prematurely. The cost of this complexity is somewhat +// reduced throughput, the gain is that most visual glitches are +// avoided (though ultimately a function of the load on the USB bus and +// host CPU, and out of our control). + +// LED data and clock lines are connected to the Arduino's SPI output. +// On traditional Arduino boards, SPI data out is digital pin 11 and +// clock is digital pin 13. On both Teensy and the 32u4 Breakout, +// data out is pin B2, clock is B1. LEDs should be externally +// powered -- trying to run any more than just a few off the Arduino's +// 5V line is generally a Bad Idea. LED ground should also be +// connected to Arduino ground. + +// -------------------------------------------------------------------- +// This file is part of Adalight. + +// Adalight is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. + +// Adalight is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with Adalight. If not, see +// . +// -------------------------------------------------------------------- + +#include + +// LED pin for Adafruit 32u4 Breakout Board: +//#define LED_DDR DDRE +//#define LED_PORT PORTE +//#define LED_PIN _BV(PORTE6) +// LED pin for Teensy: +//#define LED_DDR DDRD +//#define LED_PORT PORTD +//#define LED_PIN _BV(PORTD6) +// LED pin for Arduino: +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN _BV(PORTB5) + +// A 'magic word' (along with LED count & checksum) precedes each block +// of LED data; this assists the microcontroller in syncing up with the +// host-side software and properly issuing the latch (host I/O is +// likely buffered, making usleep() unreliable for latch). You may see +// an initial glitchy frame or two until the two come into alignment. +// The magic word can be whatever sequence you like, but each character +// should be unique, and frequent pixel values like 0 and 255 are +// avoided -- fewer false positives. The host software will need to +// generate a compatible header: immediately following the magic word +// are three bytes: a 16-bit count of the number of LEDs (high byte +// first) followed by a simple checksum value (high byte XOR low byte +// XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B, +// where 0 = off and 255 = max brightness. + +static const uint8_t magic[] = {'A', 'd', 'a'}; +#define MAGICSIZE sizeof(magic) +#define HEADERSIZE (MAGICSIZE + 3) + +#define MODE_HEADER 0 +#define MODE_HOLD 1 +#define MODE_DATA 2 + +#define DATA_LED A5 +#define SPI_LED A3 + +// If no serial data is received for a while, the LEDs are shut off +// automatically. This avoids the annoying "stuck pixel" look when +// quitting LED display programs on the host computer. +static const unsigned long serialTimeout = 15000; // 15 seconds + +void setup() +{ + // Dirty trick: the circular buffer for serial data is 256 bytes, + // and the "in" and "out" indices are unsigned 8-bit types -- this + // much simplifies the cases where in/out need to "wrap around" the + // beginning/end of the buffer. Otherwise there'd be a ton of bit- + // masking and/or conditional code every time one of these indices + // needs to change, slowing things down tremendously. + uint8_t + buffer[256], + indexIn = 0, + indexOut = 0, + mode = MODE_HEADER, + hi, lo, chk, i, spiFlag; + int16_t + bytesBuffered = 0, + hold = 0, + c; + int32_t + bytesRemaining; + unsigned long + startTime, + lastByteTime, + lastAckTime, + t; + bool + data_in_led = false, + spi_out_led = false; + + LED_DDR |= LED_PIN; // Enable output for LED + LED_PORT &= ~LED_PIN; // LED off + pinMode(DATA_LED, OUTPUT); //data in led + pinMode(SPI_LED, OUTPUT); //data out led + + Serial.begin(115200); // Teensy/32u4 disregards baud rate; is OK! + + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + SPI.setClockDivider(SPI_CLOCK_DIV8); // 2Mhz + + // Issue test pattern to LEDs on startup. This helps verify that + // wiring between the Arduino and LEDs is correct. Not knowing the + // actual number of LEDs connected, this sets all of them (well, up + // to the first 25,000, so as not to be TOO time consuming) to red, + // green, blue, then off. Once you're confident everything is working + // end-to-end, it's OK to comment this out and reprogram the Arduino. + uint8_t testcolor[] = { 0, 0, 0, 255, 0, 0 }; + for (char n = 3; n >= 0; n--) { + for (int i = 0; i < 4; i++) { //Start Frame + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + } + for (c = 0; c < 25000; c++) { + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte + for (i = 0; i < 3; i++) { + for (SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); ); //BGR + } + } + for (int i = 0; i < 4; i++) { //Stop Frame + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + } + + delay(1); // One millisecond pause = latch + } + digitalWrite(SPI_LED, spi_out_led = !spi_out_led); + + Serial.print("Ada\n"); // Send ACK string to host + + startTime = micros(); + lastByteTime = lastAckTime = millis(); + + // loop() is avoided as even that small bit of function overhead + // has a measurable impact on this code's overall throughput. + + for (;;) { + digitalWrite(DATA_LED, LOW); + digitalWrite(SPI_LED, LOW); + // Implementation is a simple finite-state machine. + // Regardless of mode, check for serial input each time: + t = millis(); + if ((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) { + buffer[indexIn++] = c; + bytesBuffered++; + lastByteTime = lastAckTime = t; // Reset timeout counters + } else { + // No data received. If this persists, send an ACK packet + // to host once every second to alert it to our presence. + if ((t - lastAckTime) > 1000) { + Serial.print("Ada\n"); // Send ACK string to host + lastAckTime = t; // Reset counter + } + // If no data received for an extended time, turn off all LEDs. + if ((t - lastByteTime) > serialTimeout) { + for (i = 0; i < 4; i++) { //Start Frame + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + } + for (c = 0; c < 25000; c++) { + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness Byte + for (i = 0; i < 3; i++) { + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); //BGR + } + } + for (i = 0; i < 4; i++) { //Stop Frame + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + } + delay(1); // One millisecond pause = latch + lastByteTime = t; // Reset counter + } + } + + switch (mode) { + + case MODE_HEADER: + + // In header-seeking mode. Is there enough data to check? + if (bytesBuffered >= HEADERSIZE) { + // Indeed. Check for a 'magic word' match. + for (i = 0; (i < MAGICSIZE) && (buffer[indexOut++] == magic[i++]);); + if (i == MAGICSIZE) { + // Magic word matches. Now how about the checksum? + hi = buffer[indexOut++]; + lo = buffer[indexOut++]; + chk = buffer[indexOut++]; + if (chk == (hi ^ lo ^ 0x55)) { + // Checksum looks valid. Get 16-bit LED count, add 1 + // (# LEDs is always > 0) and multiply by 3 for R,G,B. + bytesRemaining = 4L * (256L * (long)hi + (long)lo) + 4L + (256L * (long)hi + (long)lo + 15) / 16; + bytesBuffered -= 3; + spiFlag = 0; // No data out yet + mode = MODE_HOLD; // Proceed to latch wait mode + digitalWrite(DATA_LED, data_in_led = !data_in_led); + } else { + // Checksum didn't match; search resumes after magic word. + indexOut -= 3; // Rewind + } + } // else no header match. Resume at first mismatched byte. + bytesBuffered -= i; + } + break; + + case MODE_HOLD: + + // Ostensibly "waiting for the latch from the prior frame + // to complete" mode, but may also revert to this mode when + // underrun prevention necessitates a delay. + + if ((micros() - startTime) < hold) break; // Still holding; keep buffering + + // Latch/delay complete. Advance to data-issuing mode... + LED_PORT &= ~LED_PIN; // LED off + mode = MODE_DATA; // ...and fall through (no break): + + case MODE_DATA: + digitalWrite(SPI_LED, spi_out_led = !spi_out_led); + while (spiFlag && !(SPSR & _BV(SPIF))); // Wait for prior byte + if (bytesRemaining > 0) { + if (bytesBuffered > 0) { + SPDR = buffer[indexOut++]; // Issue next byte + bytesBuffered--; + bytesRemaining--; + spiFlag = 1; + } + // If serial buffer is threatening to underrun, start + // introducing progressively longer pauses to allow more + // data to arrive (up to a point). + if ((bytesBuffered < 32) && (bytesRemaining > bytesBuffered)) { + startTime = micros(); + hold = 100 + (32 - bytesBuffered) * 10; + mode = MODE_HOLD; + } + } else { + // End of data -- issue latch: + startTime = micros(); + hold = 1000; // Latch duration = 1000 uS + LED_PORT |= LED_PIN; // LED on + mode = MODE_HEADER; // Begin next header search + } + } // end switch + } // end for(;;) +} + +void loop() +{ + // Not used. See note in setup() function. +} diff --git a/deploy/hyperion_imx6.tar.gz.REMOVED.git-id b/deploy/hyperion_imx6.tar.gz.REMOVED.git-id index 294f2909..99536c87 100644 --- a/deploy/hyperion_imx6.tar.gz.REMOVED.git-id +++ b/deploy/hyperion_imx6.tar.gz.REMOVED.git-id @@ -1 +1 @@ -3785db40d7232275fbc00b20e627280e0e057f99 \ No newline at end of file +471d676fb66aa53e3b10d887a1d9e6d3b4afea90 \ No newline at end of file diff --git a/deploy/hyperion_rpi.tar.gz.REMOVED.git-id b/deploy/hyperion_rpi.tar.gz.REMOVED.git-id index 0f6903ba..44bbdc58 100644 --- a/deploy/hyperion_rpi.tar.gz.REMOVED.git-id +++ b/deploy/hyperion_rpi.tar.gz.REMOVED.git-id @@ -1 +1 @@ -0769228a95e4a0d4b2ed6649f21ddf70b43773d6 \ No newline at end of file +5c164e4ff52076a530461cdf6966943d52cd39df \ No newline at end of file diff --git a/deploy/hyperion_wetek.tar.gz.REMOVED.git-id b/deploy/hyperion_wetek.tar.gz.REMOVED.git-id index 4a4621a7..668065d1 100644 --- a/deploy/hyperion_wetek.tar.gz.REMOVED.git-id +++ b/deploy/hyperion_wetek.tar.gz.REMOVED.git-id @@ -1 +1 @@ -7e53ee35b7258e7d58d96514701a50014a98da31 \ No newline at end of file +d2bf44cca4e7753b53acc2ebbdb933ba8f74f93f \ No newline at end of file diff --git a/deploy/hyperion_x32.tar.gz.REMOVED.git-id b/deploy/hyperion_x32.tar.gz.REMOVED.git-id index 24239241..89355ddf 100644 --- a/deploy/hyperion_x32.tar.gz.REMOVED.git-id +++ b/deploy/hyperion_x32.tar.gz.REMOVED.git-id @@ -1 +1 @@ -36d03bb18626fa0faea8aabf6426e571eab4f719 \ No newline at end of file +7936b39302bec31b18f11a321ba6904c12b5c3ec \ No newline at end of file diff --git a/deploy/hyperion_x64.tar.gz.REMOVED.git-id b/deploy/hyperion_x64.tar.gz.REMOVED.git-id index f6368736..38e3e0b0 100644 --- a/deploy/hyperion_x64.tar.gz.REMOVED.git-id +++ b/deploy/hyperion_x64.tar.gz.REMOVED.git-id @@ -1 +1 @@ -6f86ceeb6650e527d179cf7153e0beada3b73889 \ No newline at end of file +774c67bd8e4e46d2ebf9c223a38fdfd93cae1100 \ No newline at end of file diff --git a/effects/x-mas.json b/effects/x-mas.json new file mode 100644 index 00000000..72892a52 --- /dev/null +++ b/effects/x-mas.json @@ -0,0 +1,8 @@ +{ + "name" : "X-Mas", + "script" : "x-mas.py", + "args" : + { + "sleepTime" : 0.75 + } +} diff --git a/effects/x-mas.py b/effects/x-mas.py new file mode 100644 index 00000000..697d6f71 --- /dev/null +++ b/effects/x-mas.py @@ -0,0 +1,28 @@ +import hyperion +import time +import colorsys + +# Get the parameters +sleepTime = float(hyperion.args.get('sleepTime', 1.0)) + +# Initialize the led data +ledDataOdd = bytearray() +for i in range(hyperion.ledCount): + if i%2 == 0: + ledDataOdd += bytearray((int(255), int(0), int(0))) + else: + ledDataOdd += bytearray((int(255), int(255), int(255))) + +ledDataEven = bytearray() +for i in range(hyperion.ledCount): + if i%2 == 0: + ledDataEven += bytearray((int(255), int(255), int(255))) + else: + ledDataEven += bytearray((int(255), int(0), int(0))) + +# Start the write data loop +while not hyperion.abort(): + hyperion.setColor(ledDataOdd) + time.sleep(sleepTime) + hyperion.setColor(ledDataEven) + time.sleep(sleepTime) \ No newline at end of file diff --git a/include/blackborder/BlackBorderDetector.h b/include/blackborder/BlackBorderDetector.h index c5ee91e7..14cf051c 100644 --- a/include/blackborder/BlackBorderDetector.h +++ b/include/blackborder/BlackBorderDetector.h @@ -61,49 +61,45 @@ namespace hyperion template BlackBorder process(const Image & image) { - // only test the topleft third of the image - int width = image.width() /3; + + // test center and 1/3, 2/3 of width/heigth + int width = image.width() / 3; int height = image.height() / 3; - int maxSize = std::max(width, height); + int width2 = width * 2; + int height2 = height * 2; + int xCenter = image.width() / 2; + int yCenter = image.height() / 2; + int firstNonBlackXPixelIndex = -1; int firstNonBlackYPixelIndex = -1; - // find some pixel of the image - for (int i = 0; i < maxSize; ++i) + // find first X pixel of the image + for (int x = 0; x < width; ++x) { - int x = std::min(i, width); - int y = std::min(i, height); - - const Pixel_T & color = image(x, y); - if (!isBlack(color)) + const Pixel_T & color1 = image(x, yCenter); + const Pixel_T & color2 = image(x, height); + const Pixel_T & color3 = image(x, height2); + if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3)) { firstNonBlackXPixelIndex = x; + break; + } + } + + // find first Y pixel of the image + for (int y = 0; y < height; ++y) + { + const Pixel_T & color1 = image(xCenter, y); + const Pixel_T & color2 = image(width, y); + const Pixel_T & color3 = image(width2, y); + if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3)) + { firstNonBlackYPixelIndex = y; break; } } - // expand image to the left - for(; firstNonBlackXPixelIndex > 0; --firstNonBlackXPixelIndex) - { - const Pixel_T & color = image(firstNonBlackXPixelIndex-1, firstNonBlackYPixelIndex); - if (isBlack(color)) - { - break; - } - } - - // expand image to the top - for(; firstNonBlackYPixelIndex > 0; --firstNonBlackYPixelIndex) - { - const Pixel_T & color = image(firstNonBlackXPixelIndex, firstNonBlackYPixelIndex-1); - if (isBlack(color)) - { - break; - } - } - // Construct result BlackBorder detectedBorder; detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1; diff --git a/include/blackborder/BlackBorderProcessor.h b/include/blackborder/BlackBorderProcessor.h index 4d0c4fca..14be0585 100644 --- a/include/blackborder/BlackBorderProcessor.h +++ b/include/blackborder/BlackBorderProcessor.h @@ -94,5 +94,7 @@ namespace hyperion /// The number of frame the previous detected border matched the incomming border unsigned _consistentCnt; + /// The number of frame the previous detected border NOT matched the incomming border + unsigned _inconsistentCnt; }; } // end namespace hyperion diff --git a/libsrc/blackborder/BlackBorderProcessor.cpp b/libsrc/blackborder/BlackBorderProcessor.cpp index ee78efb9..2312da31 100644 --- a/libsrc/blackborder/BlackBorderProcessor.cpp +++ b/libsrc/blackborder/BlackBorderProcessor.cpp @@ -14,7 +14,8 @@ BlackBorderProcessor::BlackBorderProcessor(const unsigned unknownFrameCnt, _detector(blackborderThreshold), _currentBorder({true, -1, -1}), _previousDetectedBorder({true, -1, -1}), - _consistentCnt(0) + _consistentCnt(0), + _inconsistentCnt(0) { // empty } @@ -30,11 +31,13 @@ bool BlackBorderProcessor::updateBorder(const BlackBorder & newDetectedBorder) if (newDetectedBorder == _previousDetectedBorder) { ++_consistentCnt; + _inconsistentCnt = 0; } else { _previousDetectedBorder = newDetectedBorder; _consistentCnt = 0; + ++_inconsistentCnt; } // check if there is a change @@ -64,14 +67,18 @@ bool BlackBorderProcessor::updateBorder(const BlackBorder & newDetectedBorder) } else { - // apply smaller borders immediately - if (newDetectedBorder.verticalSize < _currentBorder.verticalSize) + bool stable = (_consistentCnt >= 10) || (_inconsistentCnt >=30 ); + //more then 10 consistent seems like a new size not only a short flicker + //more then 30 inconsistent seems like the image is changing a lot and we need to set smaller border + + // apply smaller borders (almost) immediately -> avoid switching for "abnormal" frames + if ( (newDetectedBorder.verticalSize < _currentBorder.verticalSize) && (stable) ) { _currentBorder.verticalSize = newDetectedBorder.verticalSize; borderChanged = true; } - if (newDetectedBorder.horizontalSize < _currentBorder.horizontalSize) + if ( (newDetectedBorder.horizontalSize < _currentBorder.horizontalSize) && (stable) ) { _currentBorder.horizontalSize = newDetectedBorder.horizontalSize; borderChanged = true; @@ -80,4 +87,4 @@ bool BlackBorderProcessor::updateBorder(const BlackBorder & newDetectedBorder) } return borderChanged; -} +} \ No newline at end of file diff --git a/libsrc/boblightserver/BoblightClientConnection.cpp b/libsrc/boblightserver/BoblightClientConnection.cpp index f78d6784..a8e5a810 100644 --- a/libsrc/boblightserver/BoblightClientConnection.cpp +++ b/libsrc/boblightserver/BoblightClientConnection.cpp @@ -59,13 +59,16 @@ void BoblightClientConnection::readData() while(bytes > 0) { // create message string (strip the newline) +#ifdef ENABLE_QT5 + QString message = QString::fromLatin1(_receiveBuffer.data(), bytes-1); +#else QString message = QString::fromAscii(_receiveBuffer.data(), bytes-1); - +#endif // remove message data from buffer _receiveBuffer = _receiveBuffer.mid(bytes); - // handle message - handleMessage(message); + // handle trimmed message + handleMessage(message.trimmed()); // drop messages if the buffer is too full if (_receiveBuffer.size() > 100*1024) @@ -132,9 +135,15 @@ void BoblightClientConnection::handleMessage(const QString & message) { if (messageParts[3] == "rgb" && messageParts.size() == 7) { + // replace decimal comma with decimal point + messageParts[4].replace(',', '.'); + messageParts[5].replace(',', '.'); + messageParts[6].replace(',', '.'); + bool rc1, rc2, rc3; uint8_t red = qMax(0, qMin(255, int(255 * messageParts[4].toFloat(&rc1)))); + // check for correct locale should not be needed anymore - please check! if (!rc1) { // maybe a locale issue. switch to a locale with a comma instead of a dot as decimal seperator (or vice versa) diff --git a/libsrc/boblightserver/CMakeLists.txt b/libsrc/boblightserver/CMakeLists.txt index 1bb30cdb..33be4d17 100644 --- a/libsrc/boblightserver/CMakeLists.txt +++ b/libsrc/boblightserver/CMakeLists.txt @@ -17,7 +17,11 @@ set(BoblightServer_SOURCES ${CURRENT_SOURCE_DIR}/BoblightClientConnection.cpp ) +if(ENABLE_QT5) +qt5_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS}) +else(ENABLE_QT5) qt4_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS}) +endif(ENABLE_QT5) add_library(boblightserver ${BoblightServer_HEADERS} @@ -26,6 +30,10 @@ add_library(boblightserver ${BoblightServer_HEADERS_MOC} ) +if(ENABLE_QT5) +qt5_use_modules(boblightserver Widgets) +endif(ENABLE_QT5) + target_link_libraries(boblightserver hyperion hyperion-utils diff --git a/libsrc/effectengine/CMakeLists.txt b/libsrc/effectengine/CMakeLists.txt index c7c77236..619b691d 100644 --- a/libsrc/effectengine/CMakeLists.txt +++ b/libsrc/effectengine/CMakeLists.txt @@ -27,9 +27,13 @@ SET(EffectEngineSOURCES set(EffectEngine_RESOURCES ${CURRENT_SOURCE_DIR}/EffectEngine.qrc) +if(ENABLE_QT5) +QT5_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS}) +qt5_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress") +else(ENABLE_QT5) QT4_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS}) - qt4_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress") +endif(ENABLE_QT5) add_library(effectengine ${EffectEngineHEADERS} @@ -39,6 +43,10 @@ add_library(effectengine ${EffectEngineSOURCES} ) +if(ENABLE_QT5) +qt5_use_modules(effectengine Widgets) +endif(ENABLE_QT5) + target_link_libraries(effectengine hyperion jsoncpp diff --git a/libsrc/effectengine/EffectEngine.cpp b/libsrc/effectengine/EffectEngine.cpp index f7057e21..b9379fad 100644 --- a/libsrc/effectengine/EffectEngine.cpp +++ b/libsrc/effectengine/EffectEngine.cpp @@ -75,7 +75,11 @@ const std::list &EffectEngine::getEffects() const bool EffectEngine::loadEffectDefinition(const std::string &path, const std::string &effectConfigFile, EffectDefinition & effectDefinition) { +#ifdef ENABLE_QT5 + std::string fileName = path + QDir::separator().toLatin1() + effectConfigFile; +#else std::string fileName = path + QDir::separator().toAscii() + effectConfigFile; +#endif std::ifstream file(fileName.c_str()); if (!file.is_open()) @@ -110,7 +114,11 @@ bool EffectEngine::loadEffectDefinition(const std::string &path, const std::stri // setup the definition effectDefinition.name = config["name"].asString(); +#ifdef ENABLE_QT5 + effectDefinition.script = path + QDir::separator().toLatin1() + config["script"].asString(); +#else effectDefinition.script = path + QDir::separator().toAscii() + config["script"].asString(); +#endif effectDefinition.args = config["args"]; // return succes diff --git a/libsrc/grabber/amlogic/CMakeLists.txt b/libsrc/grabber/amlogic/CMakeLists.txt index 447a873d..be6cb97d 100644 --- a/libsrc/grabber/amlogic/CMakeLists.txt +++ b/libsrc/grabber/amlogic/CMakeLists.txt @@ -15,7 +15,11 @@ SET(AmlogicSOURCES ${CURRENT_SOURCE_DIR}/AmlogicGrabber.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS}) +endif(ENABLE_QT5) add_library(amlogic-grabber ${AmlogicHEADERS} diff --git a/libsrc/grabber/dispmanx/CMakeLists.txt b/libsrc/grabber/dispmanx/CMakeLists.txt index 20714dba..d4d64b72 100644 --- a/libsrc/grabber/dispmanx/CMakeLists.txt +++ b/libsrc/grabber/dispmanx/CMakeLists.txt @@ -21,7 +21,11 @@ SET(DispmanxGrabberSOURCES ${CURRENT_SOURCE_DIR}/DispmanxFrameGrabber.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS}) +endif(ENABLE_QT5) add_library(dispmanx-grabber ${DispmanxGrabberHEADERS} diff --git a/libsrc/grabber/framebuffer/CMakeLists.txt b/libsrc/grabber/framebuffer/CMakeLists.txt index 9a6a12be..dc585f42 100644 --- a/libsrc/grabber/framebuffer/CMakeLists.txt +++ b/libsrc/grabber/framebuffer/CMakeLists.txt @@ -21,7 +21,11 @@ SET(FramebufferGrabberSOURCES ${CURRENT_SOURCE_DIR}/FramebufferFrameGrabber.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS}) +endif(ENABLE_QT5) add_library(framebuffer-grabber ${FramebufferGrabberHEADERS} diff --git a/libsrc/grabber/osx/CMakeLists.txt b/libsrc/grabber/osx/CMakeLists.txt index 05c67b3b..03868eeb 100644 --- a/libsrc/grabber/osx/CMakeLists.txt +++ b/libsrc/grabber/osx/CMakeLists.txt @@ -16,7 +16,11 @@ SET(OsxGrabberSOURCES ${CURRENT_SOURCE_DIR}/OsxFrameGrabber.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS}) +endif(ENABLE_QT5) add_library(osx-grabber ${OsxGrabberHEADERS} diff --git a/libsrc/grabber/v4l2/CMakeLists.txt b/libsrc/grabber/v4l2/CMakeLists.txt index 5c7844e0..71de7806 100644 --- a/libsrc/grabber/v4l2/CMakeLists.txt +++ b/libsrc/grabber/v4l2/CMakeLists.txt @@ -16,7 +16,11 @@ SET(V4L2_SOURCES ${CURRENT_SOURCE_DIR}/V4L2Wrapper.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS}) +endif(ENABLE_QT5) add_library(v4l2-grabber ${V4L2_HEADERS} @@ -25,6 +29,10 @@ add_library(v4l2-grabber ${V4L2_HEADERS_MOC} ) +if(ENABLE_QT5) +qt5_use_modules(v4l2-grabber Widgets) +endif(ENABLE_QT5) + target_link_libraries(v4l2-grabber hyperion ${QT_LIBRARIES} diff --git a/libsrc/grabber/x11/CMakeLists.txt b/libsrc/grabber/x11/CMakeLists.txt index 869fb4bf..4d8ead6d 100644 --- a/libsrc/grabber/x11/CMakeLists.txt +++ b/libsrc/grabber/x11/CMakeLists.txt @@ -22,7 +22,11 @@ SET(X11_SOURCES ${CURRENT_SOURCE_DIR}/X11Grabber.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS}) +endif(ENABLE_QT5) add_library(x11-grabber ${X11_HEADERS} diff --git a/libsrc/hyperion/CMakeLists.txt b/libsrc/hyperion/CMakeLists.txt index 8f6a227d..1434f105 100644 --- a/libsrc/hyperion/CMakeLists.txt +++ b/libsrc/hyperion/CMakeLists.txt @@ -36,9 +36,13 @@ set(Hyperion_RESOURCES ${CURRENT_SOURCE_DIR}/resource.qrc ) +if(ENABLE_QT5) +QT5_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS}) +QT5_ADD_RESOURCES(Hyperion_RESOURCES_RCC ${Hyperion_RESOURCES} OPTIONS "-no-compress") +else(ENABLE_QT5) QT4_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS}) - QT4_ADD_RESOURCES(Hyperion_RESOURCES_RCC ${Hyperion_RESOURCES} OPTIONS "-no-compress") +endif(ENABLE_QT5) add_library(hyperion ${Hyperion_HEADERS} @@ -48,6 +52,10 @@ add_library(hyperion ${Hyperion_RESOURCES_RCC} ) +if(ENABLE_QT5) +qt5_use_modules(hyperion Widgets) +endif(ENABLE_QT5) + target_link_libraries(hyperion blackborder hyperion-utils diff --git a/libsrc/jsonserver/CMakeLists.txt b/libsrc/jsonserver/CMakeLists.txt index 208c1ed9..d03ed1ea 100644 --- a/libsrc/jsonserver/CMakeLists.txt +++ b/libsrc/jsonserver/CMakeLists.txt @@ -20,10 +20,13 @@ set(JsonServer_SOURCES set(JsonServer_RESOURCES ${CURRENT_SOURCE_DIR}/JsonSchemas.qrc ) - +if(ENABLE_QT5) +qt5_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS}) +qt5_add_resources(JsonServer_RESOURCES_RCC ${JsonServer_RESOURCES} OPTIONS "-no-compress") +else(ENABLE_QT5) qt4_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS}) - qt4_add_resources(JsonServer_RESOURCES_RCC ${JsonServer_RESOURCES} OPTIONS "-no-compress") +endif(ENABLE_QT5) add_library(jsonserver ${JsonServer_HEADERS} @@ -34,6 +37,10 @@ add_library(jsonserver ${JsonServer_RESOURCES_RCC} ) +if(ENABLE_QT5) +qt5_use_modules(jsonserver Widgets Network) +endif(ENABLE_QT5) + target_link_libraries(jsonserver hyperion hyperion-utils diff --git a/libsrc/leddevice/CMakeLists.txt b/libsrc/leddevice/CMakeLists.txt index d6d4682c..96098ed3 100755 --- a/libsrc/leddevice/CMakeLists.txt +++ b/libsrc/leddevice/CMakeLists.txt @@ -20,6 +20,8 @@ SET(Leddevice_QT_HEADERS ${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.h ${CURRENT_SOURCE_DIR}/LedHIDDevice.h ${CURRENT_SOURCE_DIR}/LedDeviceRawHID.h + ${CURRENT_SOURCE_DIR}/LedDeviceTest.h + ${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h ) SET(Leddevice_HEADERS @@ -32,6 +34,7 @@ SET(Leddevice_HEADERS ${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.h ${CURRENT_SOURCE_DIR}/LedDeviceSedu.h ${CURRENT_SOURCE_DIR}/LedDeviceTest.h + ${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h ${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h ${CURRENT_SOURCE_DIR}/LedDeviceTpm2.h ${CURRENT_SOURCE_DIR}/LedDeviceAtmo.h @@ -53,6 +56,7 @@ SET(Leddevice_SOURCES ${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.cpp ${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp ${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.cpp ${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.cpp ${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.cpp ${CURRENT_SOURCE_DIR}/LedDeviceTpm2.cpp @@ -102,8 +106,12 @@ if(ENABLE_TINKERFORGE) ) endif(ENABLE_TINKERFORGE) - +if(ENABLE_QT5) +QT5_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS}) +endif(ENABLE_QT5) + add_library(leddevice ${Leddevice_HEADERS} @@ -112,9 +120,13 @@ add_library(leddevice ${Leddevice_SOURCES} ) +if(ENABLE_QT5) +qt5_use_modules(leddevice Widgets Network) +endif(ENABLE_QT5) + target_link_libraries(leddevice hyperion-utils - serialport + serialport ${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev ${CMAKE_THREAD_LIBS_INIT} ${QT_LIBRARIES} diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.cpp b/libsrc/leddevice/LedDeviceAdalightApa102.cpp index 07732080..9cbd3603 100644 --- a/libsrc/leddevice/LedDeviceAdalightApa102.cpp +++ b/libsrc/leddevice/LedDeviceAdalightApa102.cpp @@ -3,7 +3,6 @@ #include #include #include -#include // Linux includes #include @@ -13,30 +12,38 @@ #include "LedDeviceAdalightApa102.h" LedDeviceAdalightApa102::LedDeviceAdalightApa102(const std::string& outputDevice, const unsigned baudrate, int delayAfterConnect_ms) : - LedDeviceAdalight(outputDevice, baudrate, delayAfterConnect_ms), + LedRs232Device(outputDevice, baudrate, delayAfterConnect_ms), _ledBuffer(0), _timer() { + // setup the timer + _timer.setSingleShot(false); + _timer.setInterval(5000); + connect(&_timer, SIGNAL(timeout()), this, SLOT(rewriteLeds())); + + // start the timer + _timer.start(); } //comparing to ws2801 adalight, the following changes were needed: // 1- differnt data frame (4 bytes instead of 3) // 2 - in order to accomodate point 1 above, number of leds sent to adalight is increased by 1/3rd int LedDeviceAdalightApa102::write(const std::vector & ledValues) { + ledCount = ledValues.size(); const unsigned int startFrameSize = 4; - const unsigned int endFrameSize = std::max(((ledValues.size() + 15) / 16), 4); - const unsigned int mLedCount = (ledValues.size() * 4) + startFrameSize + endFrameSize; - if(_ledBuffer.size() != mLedCount){ - _ledBuffer.resize(mLedCount, 0xFF); + const unsigned int endFrameSize = std::max(((ledCount + 15) / 16), 4); + const unsigned int mLedCount = (ledCount * 4) + startFrameSize + endFrameSize; + if(_ledBuffer.size() != mLedCount+6){ + _ledBuffer.resize(mLedCount+6, 0x00); _ledBuffer[0] = 'A'; _ledBuffer[1] = 'd'; _ledBuffer[2] = 'a'; - _ledBuffer[3] = (((unsigned int)(ledValues.size() * 1.33) - 1) >> 8) & 0xFF; // LED count high byte - _ledBuffer[4] = ((unsigned int)(ledValues.size() * 1.33) - 1) & 0xFF; // LED count low byte + _ledBuffer[3] = (((unsigned int)(ledValues.size())) >> 8) & 0xFF; // LED count high byte + _ledBuffer[4] = ((unsigned int)(ledValues.size())) & 0xFF; // LED count low byte _ledBuffer[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum } - - for (unsigned iLed=1; iLed<=ledValues.size(); iLed++) { + + for (unsigned iLed=1; iLed<=ledCount; iLed++) { const ColorRgb& rgb = ledValues[iLed-1]; _ledBuffer[iLed*4+6] = 0xFF; _ledBuffer[iLed*4+1+6] = rgb.red; @@ -51,4 +58,25 @@ int LedDeviceAdalightApa102::write(const std::vector & ledValues) return writeBytes(_ledBuffer.size(), _ledBuffer.data()); } +int LedDeviceAdalightApa102::switchOff() +{ + for (unsigned iLed=1; iLed<=ledCount; iLed++) { + _ledBuffer[iLed*4+6] = 0xFF; + _ledBuffer[iLed*4+1+6] = 0x00; + _ledBuffer[iLed*4+2+6] = 0x00; + _ledBuffer[iLed*4+3+6] = 0x00; + } + + // restart the timer + _timer.start(); + + // write data + return writeBytes(_ledBuffer.size(), _ledBuffer.data()); + +} + +void LedDeviceAdalightApa102::rewriteLeds() +{ + writeBytes(_ledBuffer.size(), _ledBuffer.data()); +} diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.h b/libsrc/leddevice/LedDeviceAdalightApa102.h index a0a7c89c..eef37662 100644 --- a/libsrc/leddevice/LedDeviceAdalightApa102.h +++ b/libsrc/leddevice/LedDeviceAdalightApa102.h @@ -7,12 +7,12 @@ #include // hyperion incluse -#include "LedDeviceAdalight.h" +#include "LedRs232Device.h" /// /// Implementation of the LedDevice interface for writing to an Adalight led device for APA102. /// -class LedDeviceAdalightApa102 : public LedDeviceAdalight +class LedDeviceAdalightApa102 : public LedRs232Device { Q_OBJECT @@ -32,13 +32,17 @@ public: /// @return Zero on succes else negative /// virtual int write(const std::vector & ledValues); + virtual int switchOff(); - +private slots: + /// Write the last data to the leds again + void rewriteLeds(); + private: /// The buffer containing the packed RGB values std::vector _ledBuffer; - + unsigned int ledCount; /// Timer object which makes sure that led data is written at a minimum rate /// The Adalight device will switch off when it does not receive data at least /// every 15 seconds diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 85f665a5..b0fd064f 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -30,6 +30,7 @@ #include "LedDevicePiBlaster.h" #include "LedDeviceSedu.h" #include "LedDeviceTest.h" +#include "LedDeviceFadeCandy.h" #include "LedDeviceHyperionUsbasp.h" #include "LedDevicePhilipsHue.h" #include "LedDeviceTpm2.h" @@ -243,6 +244,12 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) const std::string output = deviceConfig["output"].asString(); device = new LedDeviceTest(output); } + else if (type == "fadecandy") + { + const std::string host = deviceConfig.get("output", "127.0.0.1").asString(); + const uint16_t port = deviceConfig.get("port", 7890).asInt(); + device = new LedDeviceFadeCandy(host,port); + } else if (type == "tpm2") { const std::string output = deviceConfig["output"].asString(); diff --git a/libsrc/leddevice/LedDeviceFadeCandy.cpp b/libsrc/leddevice/LedDeviceFadeCandy.cpp new file mode 100755 index 00000000..e8c178d1 --- /dev/null +++ b/libsrc/leddevice/LedDeviceFadeCandy.cpp @@ -0,0 +1,93 @@ +#include "LedDeviceFadeCandy.h" + +static const unsigned MAX_NUM_LEDS = 512; +static const unsigned OPC_BROADCAST = 0; // OPC broadcast channel +static const unsigned OPC_SET_PIXELS = 0; // OPC command codes +static const unsigned OPC_HEADER_SIZE = 4; // OPC header size + + +LedDeviceFadeCandy::LedDeviceFadeCandy(const std::string& host, const uint16_t port) : + _host(host), _port(port) +{ + _opc_data.resize( OPC_HEADER_SIZE ); + _opc_data[0] = OPC_BROADCAST; + _opc_data[1] = OPC_SET_PIXELS; + _opc_data[2] = 0; + _opc_data[3] = 0; +} + + +LedDeviceFadeCandy::~LedDeviceFadeCandy() +{ + _client.close(); +} + + +bool LedDeviceFadeCandy::isConnected() +{ + return _client.state() == QAbstractSocket::ConnectedState; +} + + +bool LedDeviceFadeCandy::tryConnect() +{ + if ( _client.state() == QAbstractSocket::UnconnectedState ) { + qDebug("connecting to %s %i",_host.c_str(),_port); + + _client.connectToHost( _host.c_str(), _port); + if ( _client.waitForConnected(1000) ) + qDebug("connected"); + } + + return isConnected(); +} + + +int LedDeviceFadeCandy::write( const std::vector & ledValues ) +{ + ssize_t nrLedValues = ledValues.size(); + ssize_t led_data_size = nrLedValues * 3; // 3 color bytes + ssize_t opc_data_size = led_data_size + OPC_HEADER_SIZE; + + if (nrLedValues > MAX_NUM_LEDS) + { + std::cerr << "Invalid attempt to write led values. Not more than " << MAX_NUM_LEDS << " leds are allowed." << std::endl; + return -1; + } + + if ( opc_data_size != _opc_data.size() ) + _opc_data.resize( opc_data_size ); + + _opc_data[2] = led_data_size >> 8; + _opc_data[3] = led_data_size & 0xff; + + uint idx = OPC_HEADER_SIZE; + for (const ColorRgb& color : ledValues) + { + _opc_data[idx ] = unsigned( color.red ); + _opc_data[idx+1] = unsigned( color.green ); + _opc_data[idx+2] = unsigned( color.blue ); + idx += 3; + } + + return ( transferData()<0 ? -1 : 0 ); +} + + +int LedDeviceFadeCandy::transferData() +{ + if ( isConnected() || tryConnect() ) + return _client.write( _opc_data, _opc_data.size() ); + + return -2; +} + + +int LedDeviceFadeCandy::switchOff() +{ + for ( int idx=OPC_HEADER_SIZE; idx < _opc_data.size(); idx++ ) + _opc_data[idx] = 0; + + return ( transferData()<0 ? -1 : 0 ); +} + diff --git a/libsrc/leddevice/LedDeviceFadeCandy.h b/libsrc/leddevice/LedDeviceFadeCandy.h new file mode 100755 index 00000000..0b894e88 --- /dev/null +++ b/libsrc/leddevice/LedDeviceFadeCandy.h @@ -0,0 +1,70 @@ +#pragma once + +// STL/Qt includes +#include +#include +#include + +// Leddevice includes +#include + +/// +/// Implementation of the LedDevice interface for sending to +/// fadecandy/opc-server via network by using the 'open pixel control' protocol. +/// +class LedDeviceFadeCandy : public QObject, public LedDevice +{ + Q_OBJECT + +public: + /// + /// Constructs the LedDevice for fadecandy/opc server + /// + /// @param host The ip address/host name of fadecandy/opc server + /// @param port The port to use (fadecandy default is 7890) + /// + LedDeviceFadeCandy(const std::string& host, const uint16_t port); + + /// + /// Destructor of the LedDevice; closes the tcp client + /// + virtual ~LedDeviceFadeCandy(); + + /// + /// Writes the led color values to the led-device + /// + /// @param ledValues The color-value per led + /// @return Zero on succes else negative + /// + virtual int write(const std::vector & ledValues); + + /// Switch the leds off + virtual int switchOff(); + + +private: + QTcpSocket _client; + const std::string _host; + const uint16_t _port; + QByteArray _opc_data; + + /// try to establish connection to opc server, if not connected yet + /// + /// @return true if connection is established + /// + bool tryConnect(); + + /// return the conenction state + /// + /// @return True if connection established + /// + bool isConnected(); + + + /// transfer current opc_data buffer to opc server + /// + /// @return amount of transfered bytes. -1 error while transfering, -2 error while connecting + /// + int transferData(); + +}; diff --git a/libsrc/leddevice/LedDevicePhilipsHue.cpp b/libsrc/leddevice/LedDevicePhilipsHue.cpp index dc95d421..b1d138e9 100755 --- a/libsrc/leddevice/LedDevicePhilipsHue.cpp +++ b/libsrc/leddevice/LedDevicePhilipsHue.cpp @@ -5,7 +5,7 @@ #include // qt includes -#include +#include #include #include @@ -200,22 +200,30 @@ int LedDevicePhilipsHue::write(const std::vector & ledValues) { // Next light id. idx++; } +#ifdef ENABLE_QT5 + +#else timer.start(); +#endif return 0; } int LedDevicePhilipsHue::switchOff() { +#ifdef ENABLE_QT5 + +#else timer.stop(); // If light states have been saved before, ... if (areStatesSaved()) { // ... restore them. restoreStates(); } +#endif return 0; } -void LedDevicePhilipsHue::put(QString route, QString content) { - QString url = QString("http://%1/api/%2/%3").arg(host).arg(username).arg(route); +void LedDevicePhilipsHue::put(QString route, QString content) { + QString url = QString("http://%1/api/%2/%3").arg(host).arg(username).arg(route); // Perfrom request QNetworkRequest request(url); QNetworkReply* reply = manager->put(request, content.toAscii()); @@ -226,8 +234,8 @@ void LedDevicePhilipsHue::put(QString route, QString content) { loop.exec(); } -QByteArray LedDevicePhilipsHue::get(QString route) { - QString url = QString("http://%1/api/%2/%3").arg(host).arg(username).arg(route); +QByteArray LedDevicePhilipsHue::get(QString route) { + QString url = QString("http://%1/api/%2/%3").arg(host).arg(username).arg(route); // Perfrom request QNetworkRequest request(url); QNetworkReply* reply = manager->get(request); @@ -236,8 +244,8 @@ QByteArray LedDevicePhilipsHue::get(QString route) { loop.connect(reply, SIGNAL(finished()), SLOT(quit())); // Go into the loop until the request is finished. loop.exec(); - // Read all data of the response. - return reply->readAll(); + // Read all data of the response. + return reply->readAll(); } QString LedDevicePhilipsHue::getStateRoute(unsigned int lightId) { diff --git a/libsrc/leddevice/LedDevicePhilipsHue.h b/libsrc/leddevice/LedDevicePhilipsHue.h index 2d6f9056..61047062 100755 --- a/libsrc/leddevice/LedDevicePhilipsHue.h +++ b/libsrc/leddevice/LedDevicePhilipsHue.h @@ -8,7 +8,6 @@ #include #include #include - // Leddevice includes #include @@ -165,7 +164,7 @@ private: /// User name for the API ("newdeveloper") QString username; /// QNetworkAccessManager object for sending requests. - QNetworkAccessManager* manager; + QNetworkAccessManager* manager; /// Use timer to reset lights when we got into "GRABBINGMODE_OFF". QTimer timer; /// diff --git a/libsrc/protoserver/CMakeLists.txt b/libsrc/protoserver/CMakeLists.txt index 6a9b6d1e..769cc807 100644 --- a/libsrc/protoserver/CMakeLists.txt +++ b/libsrc/protoserver/CMakeLists.txt @@ -34,7 +34,11 @@ protobuf_generate_cpp(ProtoServer_PROTO_SRCS ProtoServer_PROTO_HDRS ${ProtoServer_PROTOS} ) +if(ENABLE_QT5) +qt5_wrap_cpp(ProtoServer_HEADERS_MOC ${ProtoServer_QT_HEADERS}) +else(ENABLE_QT5) qt4_wrap_cpp(ProtoServer_HEADERS_MOC ${ProtoServer_QT_HEADERS}) +endif(ENABLE_QT5) add_library(protoserver ${ProtoServer_HEADERS} @@ -45,6 +49,9 @@ add_library(protoserver ${ProtoServer_PROTO_SRCS} ${ProtoServer_PROTO_HDRS} ) +if(ENABLE_QT5) +qt5_use_modules(protoserver Widgets) +endif(ENABLE_QT5) target_link_libraries(protoserver hyperion diff --git a/libsrc/xbmcvideochecker/CMakeLists.txt b/libsrc/xbmcvideochecker/CMakeLists.txt index 77ee2f34..f6e71b00 100644 --- a/libsrc/xbmcvideochecker/CMakeLists.txt +++ b/libsrc/xbmcvideochecker/CMakeLists.txt @@ -15,7 +15,11 @@ SET(XBMCVideoChecker_SOURCES ${CURRENT_SOURCE_DIR}/XBMCVideoChecker.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(XBMCVideoChecker_HEADERS_MOC ${XBMCVideoChecker_QT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(XBMCVideoChecker_HEADERS_MOC ${XBMCVideoChecker_QT_HEADERS}) +endif(ENABLE_QT5) add_library(xbmcvideochecker ${XBMCVideoChecker_HEADERS} @@ -24,6 +28,10 @@ add_library(xbmcvideochecker ${XBMCVideoChecker_SOURCES} ) +if(ENABLE_QT5) +qt5_use_modules(xbmcvideochecker Widgets) +endif(ENABLE_QT5) + target_link_libraries(xbmcvideochecker hyperion ${QT_LIBRARIES}) diff --git a/src/hyperion-aml/CMakeLists.txt b/src/hyperion-aml/CMakeLists.txt index d6f88a90..5d45222a 100644 --- a/src/hyperion-aml/CMakeLists.txt +++ b/src/hyperion-aml/CMakeLists.txt @@ -23,7 +23,11 @@ set(Hyperion_AML_SOURCES hyperion-aml.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(Hyperion_AML_HEADERS_MOC ${Hyperion_AML_QT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(Hyperion_AML_HEADERS_MOC ${Hyperion_AML_QT_HEADERS}) +endif(ENABLE_QT5) add_executable(hyperion-amlogic ${Hyperion_AML_HEADERS} diff --git a/src/hyperion-remote/CMakeLists.txt b/src/hyperion-remote/CMakeLists.txt index c934be21..b8c73a59 100644 --- a/src/hyperion-remote/CMakeLists.txt +++ b/src/hyperion-remote/CMakeLists.txt @@ -3,7 +3,13 @@ cmake_minimum_required(VERSION 2.8) project(hyperion-remote) # find Qt4 +if(ENABLE_QT5) +find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED) +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") +# set(CMAKE_CXX_FLAGS "-fPIC") +else(ENABLE_QT5) find_package(Qt4 REQUIRED QtCore QtGui QtNetwork) +endif(ENABLE_QT5) # The following I do not undrstand completely... # libQtCore.so uses some hardcoded library path inside which are incorrect after copying the file RPi file system @@ -25,6 +31,10 @@ add_executable(hyperion-remote ${hyperion-remote_HEADERS} ${hyperion-remote_SOURCES}) +if(ENABLE_QT5) +qt5_use_modules(hyperion-remote Widgets Network) +endif(ENABLE_QT5) + target_link_libraries(hyperion-remote jsoncpp getoptPlusPlus diff --git a/src/hyperion-remote/hyperion-remote.cpp b/src/hyperion-remote/hyperion-remote.cpp index da9d4b00..3636721f 100644 --- a/src/hyperion-remote/hyperion-remote.cpp +++ b/src/hyperion-remote/hyperion-remote.cpp @@ -43,8 +43,13 @@ int main(int argc, char * argv[]) // create the option parser and initialize all parameters OptionsParser optionParser("Simple application to send a command to hyperion using the Json interface"); ParameterSet & parameters = optionParser.getParameters(); +#ifdef ENABLE_QT5 + StringParameter & argAddress = parameters.add ('a', "address" , QString("Set the address of the hyperion server [default: %1]").arg(defaultServerAddress).toLatin1().constData()); + IntParameter & argPriority = parameters.add ('p', "priority" , QString("Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]").arg(defaultPriority).toLatin1().constData()); +#else StringParameter & argAddress = parameters.add ('a', "address" , QString("Set the address of the hyperion server [default: %1]").arg(defaultServerAddress).toAscii().constData()); IntParameter & argPriority = parameters.add ('p', "priority" , QString("Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]").arg(defaultPriority).toAscii().constData()); +#endif IntParameter & argDuration = parameters.add ('d', "duration" , "Specify how long the leds should be switched on in millseconds [default: infinity]"); ColorParameter & argColor = parameters.add ('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name. The color may be repeated multiple time like: RRGGBBRRGGBB)"); ImageParameter & argImage = parameters.add ('i', "image" , "Set the leds to the colors according to the given image file"); diff --git a/src/hyperion-v4l2/CMakeLists.txt b/src/hyperion-v4l2/CMakeLists.txt index 6607c04f..ef051e2d 100644 --- a/src/hyperion-v4l2/CMakeLists.txt +++ b/src/hyperion-v4l2/CMakeLists.txt @@ -3,7 +3,14 @@ cmake_minimum_required(VERSION 2.8) project(hyperion-v4l2) # find Qt4 +if(ENABLE_QT5) +find_package(Qt5Widgets REQUIRED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") +# set(CMAKE_CXX_FLAGS "-fPIC") +else(ENABLE_QT5) find_package(Qt4 REQUIRED QtCore QtGui QtNetwork) +endif(ENABLE_QT5) + include_directories( ${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/protoserver @@ -24,8 +31,11 @@ set(Hyperion_V4L2_SOURCES hyperion-v4l2.cpp ScreenshotHandler.cpp ) - +if(ENABLE_QT5) +QT5_WRAP_CPP(Hyperion_V4L2_MOC_SOURCES ${Hyperion_V4L2_QT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(Hyperion_V4L2_MOC_SOURCES ${Hyperion_V4L2_QT_HEADERS}) +endif(ENABLE_QT5) add_executable(hyperion-v4l2 ${Hyperion_V4L2_HEADERS} diff --git a/src/hyperion-x11/CMakeLists.txt b/src/hyperion-x11/CMakeLists.txt index 89912f66..626781f9 100644 --- a/src/hyperion-x11/CMakeLists.txt +++ b/src/hyperion-x11/CMakeLists.txt @@ -4,8 +4,12 @@ cmake_minimum_required(VERSION 2.8) # Set the project name project(hyperion-x11) +if(ENABLE_QT5) +find_package(Qt5Widgets REQUIRED) +else(ENABLE_QT5) # find Qt4 find_package(Qt4 REQUIRED QtCore QtGui QtNetwork) +endif(ENABLE_QT5) # Find X11 find_package(X11 REQUIRED) @@ -28,7 +32,11 @@ set(Hyperion_X11_SOURCES X11Wrapper.cpp ) +if(ENABLE_QT5) +QT5_WRAP_CPP(Hyperion_X11_HEADERS_MOC ${Hyperion_X11_QT_HEADERS}) +else(ENABLE_QT5) QT4_WRAP_CPP(Hyperion_X11_HEADERS_MOC ${Hyperion_X11_QT_HEADERS}) +endif(ENABLE_QT5) add_executable(hyperion-x11 ${Hyperion_X11_HEADERS} @@ -46,7 +54,11 @@ target_link_libraries(hyperion-x11 pthread ) +if(ENABLE_QT5) +qt5_use_modules(hyperion-x11 Widgets Core Gui Network) +else(ENABLE_QT5) qt4_use_modules(hyperion-x11 Core Gui Network) +endif(ENABLE_QT5) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bf40cebb..76cbb5dc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -53,10 +53,19 @@ add_executable(test_qtscreenshot TestQtScreenshot.cpp) target_link_libraries(test_qtscreenshot ${QT_LIBRARIES}) +if(ENABLE_QT5) +qt5_use_modules(test_qregexp Widgets) +qt5_use_modules(test_qtscreenshot Widgets) +endif(ENABLE_QT5) + if(ENABLE_X11) # Find X11 find_package(X11 REQUIRED) add_executable(test_x11performance TestX11Performance.cpp) target_link_libraries(test_x11performance ${X11_LIBRARIES} ${QT_LIBRARIES}) +if(ENABLE_QT5) +qt5_use_modules(test_x11performance Widgets) +endif(ENABLE_QT5) + endif(ENABLE_X11)