Last active
December 14, 2017 16:02
-
-
Save hzeller/9ece7d7150c6d28ed1825eee85b5d243 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- | |
Compile in rpi-rgb-led-matrix directory. | |
make # compile library | |
g++ -Wall -O3 -g -Iinclude simple-udp.cc -o simple-udp -Llib -lrgbmatrix -lrt -lm -lpthread | |
*/ | |
#include "led-matrix.h" | |
#include <arpa/inet.h> | |
#include <signal.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/ioctl.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
const int kListenPort = 9999; // The UDP port we listen on. | |
using namespace rgb_matrix; | |
volatile bool interrupt_received = false; | |
static void InterruptHandler(int signo) { | |
interrupt_received = true; | |
} | |
static FrameCanvas *FillFramebuffer(RGBMatrix *matrix, FrameCanvas *canvas, | |
const char *buffer) { | |
const int width = matrix->width(); | |
const int height = matrix->height(); | |
for (int y = 0; y < height; ++y) { | |
for (int x = 0; x < width; ++x) { | |
int r = *buffer++; | |
int g = *buffer++; | |
int b = *buffer++; | |
canvas->SetPixel(x, y, r, g, b); | |
} | |
} | |
return matrix->SwapOnVSync(canvas); | |
} | |
static int usage(const char *progname) { | |
fprintf(stderr, "usage: %s [options]\n", progname); | |
fprintf(stderr, "Options:\n"); | |
rgb_matrix::PrintMatrixFlags(stderr); | |
return 1; | |
} | |
int main(int argc, char *argv[]) { | |
RGBMatrix::Options matrix_options; | |
rgb_matrix::RuntimeOptions runtime_opt; | |
if (!rgb_matrix::ParseOptionsFromFlags(&argc, &argv, | |
&matrix_options, &runtime_opt)) { | |
return usage(argv[0]); | |
} | |
int port = kListenPort; | |
RGBMatrix *matrix = rgb_matrix::CreateMatrixFromOptions(matrix_options, | |
runtime_opt); | |
FrameCanvas *swap_buffer = matrix->CreateFrameCanvas(); | |
const int framebuffer_size = matrix->width() * matrix->height() * 3; | |
char *const packet_buffer = new char[framebuffer_size]; | |
struct sigaction sa; | |
sa.sa_handler = InterruptHandler; | |
sa.sa_flags = SA_RESETHAND | SA_NODEFER; | |
sigaction(SIGTERM, &sa, NULL); | |
sigaction(SIGINT, &sa, NULL); | |
int s; | |
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { | |
perror("creating UDP socket"); | |
exit(1); | |
} | |
struct sockaddr_in addr; | |
memset(&addr, 0, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
addr.sin_port = htons(port); | |
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { | |
perror("bind"); | |
exit(1); | |
} | |
matrix->Clear(); | |
while (!interrupt_received) { | |
const ssize_t buffer_bytes = recvfrom(s, packet_buffer, framebuffer_size, | |
0, NULL, 0); | |
if (interrupt_received) | |
break; | |
if (buffer_bytes < 1) | |
continue; | |
swap_buffer = FillFramebuffer(matrix, swap_buffer, packet_buffer); | |
} | |
delete matrix; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment