commit 1fb1de725b9c2bd8ad03949eb5d5b222231c7c47
parent ded603095a464b4a6ca7f7fb9d8dfa20d90a063a
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 4 Aug 2024 21:34:02 +0200
rename qr-show command
Diffstat:
4 files changed, 457 insertions(+), 450 deletions(-)
diff --git a/debian/taler-mdb.install b/debian/taler-mdb.install
@@ -1,7 +1,7 @@
debian/etc/* etc/
usr/bin/taler-mdb
usr/bin/taler-mdb-display
-usr/bin/qr-show
+usr/bin/taler-mdb-qr-show
usr/bin/taler-mdb-ads.sh
usr/bin/taler-mdb-show.sh
usr/bin/taler-mdb-network-check.sh
diff --git a/src/Makefile.am b/src/Makefile.am
@@ -4,7 +4,7 @@ bin_PROGRAMS = \
taler-mdb-display
if HAVE_QR
-bin_PROGRAMS += qr-show
+bin_PROGRAMS += taler-mdb-qr-show
endif
if USE_COVERAGE
@@ -28,8 +28,8 @@ taler_mdb_LDADD = \
$(XLIB)
-qr_show_SOURCES = \
- qr-show.c
+taler_mdb_qr_show_SOURCES = \
+ taler-mdb-qr-show.c
qr_show_LDADD = \
-lgnunetutil \
@QR_LIBS@ \
diff --git a/src/qr-show.c b/src/qr-show.c
@@ -1,446 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2019 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER 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 General Public License for more
-details.
-
- You should have received a copy of the GNU General Public License
-along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
-* @file qr-show.c
-* @brief shows a QR code on the display for a defined amount of time
-* @author Boss Marco
-* @author Christian Grothoff
-*/
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#if HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-#if HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-#include <netinet/ip.h> /* superset of previous */
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <termios.h>
-#include <nfc/nfc.h>
-#include <microhttpd.h>
-#include <gnunet/gnunet_util_lib.h>
-#include <qrencode.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-/* for adafruit pitft display */
-#include <linux/fb.h>
-
-/**
- * Disable i18n support.
- */
-#define _(s) (s)
-
-/**
- * Handle for the Framebuffer device
- */
-struct Display
-{
- /**
- * File descriptor for the screen
- */
- int devicefd;
-
- /**
- * File descriptor to set backlight information
- */
- int backlightfd;
-
- /**
- * The display memory to set the pixel information
- */
- uint16_t *memory;
-
- /**
- * Original screen information
- */
- struct fb_var_screeninfo orig_vinfo;
-
- /**
- * Variable screen information (color depth ...)
- */
- struct fb_var_screeninfo var_info;
-
- /**
- * Fixed screen informtaion
- */
- struct fb_fix_screeninfo fix_info;
-};
-
-
-/**
- * Next program to launch.
- */
-static char *const *arg_next;
-
-static struct GNUNET_TIME_Relative delay;
-
-/**
- * Reference to the delay task
- */
-static struct GNUNET_SCHEDULER_Task *delay_task;
-
-/**
- * Name of the framebuffer device (i.e. /dev/fb1).
- */
-static char *framebuffer_device_filename;
-
-/**
- * Name of the backlight file of @e framebuffer_device_filename (i.e. /sys/class/backlight/soc:backlight/brightness).
- */
-static char *framebuffer_backlight_filename;
-
-/**
- * Global option '-i' to invert backlight on/off values
- */
-static int backlight_invert;
-
-/**
- * Standard backlight on value
- */
-static char backlight_on = '1';
-
-/**
- * Standard backlight off value
- */
-static char backlight_off = '0';
-
-/**
- * Handle for the framebuffer device
- */
-static struct Display qrDisplay;
-
-
-/**
- * @brief Create the QR code to pay and display it on screen
- *
- * @param uri what text to show in the QR code
- */
-static void
-show_qrcode (const char *uri)
-{
- QRinput *qri;
- QRcode *qrc;
- unsigned int size;
- size_t xOff;
- size_t yOff;
-
- if (0 > qrDisplay.devicefd)
- return; /* no display, no dice */
- qri = QRinput_new2 (0, QR_ECLEVEL_L);
- if (NULL == qri)
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
- "QRinput_new2");
- return;
- }
- /* first try encoding as uppercase-only alpha-numerical
- QR code (much smaller encoding); if that fails, also
- try using binary encoding (in case nick contains
- special characters). */
- if ( (0 !=
- QRinput_append (qri,
- QR_MODE_AN,
- strlen (uri),
- (unsigned char *) uri)) &&
- (0 !=
- QRinput_append (qri,
- QR_MODE_8,
- strlen (uri),
- (unsigned char *) uri)))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
- "QRinput_append");
- return;
- }
- qrc = QRcode_encodeInput (qri);
- if (NULL == qrc)
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
- "QRcode_encodeInput");
- QRinput_free (qri);
- return;
- }
-
- /* +8 for 4-pixels border */
- size = GNUNET_MIN (qrDisplay.var_info.xres,
- qrDisplay.var_info.yres);
- unsigned int nwidth = qrc->width + 8; /* 4 pixel border */
- xOff = 4 * size / nwidth;
- yOff = 4 * size / nwidth;
- if (qrDisplay.var_info.xres < qrDisplay.var_info.yres)
- yOff += (qrDisplay.var_info.yres - qrDisplay.var_info.xres) / 2;
- else
- xOff += (qrDisplay.var_info.xres - qrDisplay.var_info.yres) / 2;
- for (unsigned int x = 0; x < qrDisplay.var_info.xres - 2 * xOff; x++)
- for (unsigned int y = 0; y < qrDisplay.var_info.yres - 2 * yOff; y++)
- {
- unsigned int xoff = x * nwidth / size;
- unsigned int yoff = y * nwidth / size;
- unsigned int off = xoff + yoff * qrc->width;
- if ( (xoff >= (unsigned) qrc->width) ||
- (yoff >= (unsigned) qrc->width) )
- continue;
- qrDisplay.memory[(y + yOff) * qrDisplay.var_info.xres + (x + xOff)] =
- (0 == (qrc->data[off] & 1)) ? 0xFFFF : 0x0000;
- }
-
- QRcode_free (qrc);
- QRinput_free (qri);
-
- if (0 < qrDisplay.backlightfd)
- (void) ! write (qrDisplay.backlightfd,
- &backlight_on,
- 1);
-}
-
-
-static void
-stop_task (void *cls)
-{
- (void) cls;
- delay_task = NULL;
- GNUNET_SCHEDULER_shutdown ();
-}
-
-
-static void
-shutdown_task (void *cls)
-{
- (void) cls;
- if (NULL != delay_task)
- {
- GNUNET_SCHEDULER_cancel (delay_task);
- delay_task = NULL;
- }
- if (NULL != qrDisplay.memory)
- memset (qrDisplay.memory,
- 0xFF,
- qrDisplay.var_info.xres * qrDisplay.var_info.yres
- * sizeof (uint16_t));
- if (0 < qrDisplay.backlightfd)
- (void) ! write (qrDisplay.backlightfd,
- &backlight_off,
- 1);
- if (NULL != qrDisplay.memory)
- {
- /* free the display data */
- munmap (qrDisplay.memory,
- qrDisplay.fix_info.smem_len);
- qrDisplay.memory = NULL;
- /* reset original state */
- if (0 > ioctl (qrDisplay.devicefd,
- FBIOPUT_VSCREENINFO,
- &qrDisplay.orig_vinfo))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "failed to reset original display state\n");
- }
- /* close device */
- GNUNET_break (0 == close (qrDisplay.devicefd));
- qrDisplay.devicefd = -1;
- if (0 < qrDisplay.backlightfd)
- GNUNET_break (0 == close (qrDisplay.backlightfd));
- qrDisplay.backlightfd = -1;
- }
-}
-
-
-/**
- * @brief Start the application
- *
- * @param cls closure
- * @param args arguments left
- * @param cfgfile config file name
- * @param cfg handle for the configuration file
- */
-static void
-run (void *cls,
- char *const *args,
- const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- (void) cls;
- (void) cfgfile;
-
- if (NULL == args[0])
- return;
- arg_next = args + 1;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- "taler-mdb",
- "FRAMEBUFFER_DEVICE",
- &framebuffer_device_filename))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "taler-mdb",
- "FRAMEBUFFER_DEVICE");
- framebuffer_device_filename = GNUNET_strdup ("/dev/fb1");
- }
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- "taler-mdb",
- "FRAMEBUFFER_BACKLIGHT",
- &framebuffer_backlight_filename))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "taler-mdb",
- "FRAMEBUFFER_BACKLIGHT");
- framebuffer_backlight_filename = GNUNET_strdup (
- "/sys/class/backlight/soc:backlight/brightness");
- }
- /* open the framebuffer device */
- qrDisplay.devicefd = open (framebuffer_device_filename,
- O_RDWR);
- if (0 < qrDisplay.devicefd)
- {
- /* read information about the screen */
- ioctl (qrDisplay.devicefd,
- FBIOGET_VSCREENINFO,
- &qrDisplay.var_info);
-
- /* store current screeninfo for reset */
- qrDisplay.orig_vinfo = qrDisplay.var_info;
-
- if (16 != qrDisplay.var_info.bits_per_pixel)
- {
- /* Change variable info to 16 bit per pixel */
- qrDisplay.var_info.bits_per_pixel = 16;
- if (0 > ioctl (qrDisplay.devicefd,
- FBIOPUT_VSCREENINFO,
- &qrDisplay.var_info))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
- "ioctl(FBIOPUT_VSCREENINFO)");
- return;
- }
- }
-
- /* Get fixed screen information */
- if (0 > ioctl (qrDisplay.devicefd,
- FBIOGET_FSCREENINFO,
- &qrDisplay.fix_info))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
- "ioctl(FBIOGET_FSCREENINFO)");
- return;
- }
-
- /* get pointer onto frame buffer */
- qrDisplay.memory = mmap (NULL,
- qrDisplay.fix_info.smem_len,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- qrDisplay.devicefd,
- 0);
-
- /* open backlight file to turn display backlight on and off */
- if (0 > qrDisplay.devicefd)
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
- "mmap");
- return;
- }
-
- memset (qrDisplay.memory,
- 0xFF,
- qrDisplay.var_info.xres * qrDisplay.var_info.yres
- * sizeof (uint16_t));
-
- qrDisplay.backlightfd = open (
- framebuffer_backlight_filename, O_WRONLY);
- if (0 > qrDisplay.backlightfd)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "open",
- framebuffer_backlight_filename);
- }
- else
- {
- if (backlight_invert)
- {
- backlight_on = '0';
- backlight_off = '1';
- }
- (void) ! write (qrDisplay.backlightfd,
- &backlight_off,
- 1);
- }
- }
- else
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "open",
- framebuffer_device_filename);
- }
- GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
- NULL);
- show_qrcode (args[0]);
- delay_task = GNUNET_SCHEDULER_add_delayed (delay,
- &stop_task,
- NULL);
-}
-
-
-int
-main (int argc,
- char*const*argv)
-{
- int ret;
- /* the available command line options */
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_option_relative_time ('d',
- "delay",
- "DELAY",
- "how long should we display the text before continuing",
- &delay),
- GNUNET_GETOPT_option_flag ('i',
- "backlight-invert",
- "invert the backlight on/off values (standard on = 1)",
- &backlight_invert),
- GNUNET_GETOPT_OPTION_END
- };
-
- ret = GNUNET_PROGRAM_run (argc,
- argv,
- "qr-show",
- "This is an application to show a QR code for a defined period of time before starting another program.\n",
- options,
- &run,
- NULL);
- if (GNUNET_OK != ret)
- return 1;
- if ( (NULL == arg_next) ||
- (NULL == arg_next[0]) )
- return 0;
- execvp (arg_next[0],
- arg_next);
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "execvp",
- arg_next[0]);
- return 1;
-}
diff --git a/src/taler-mdb-qr-show.c b/src/taler-mdb-qr-show.c
@@ -0,0 +1,453 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER 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 General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+* @file taler-mdb-qr-show.c
+* @brief shows a QR code on the display for a defined amount of time
+* @author Boss Marco
+* @author Christian Grothoff
+*/
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP_H
+#include <netinet/ip.h> /* superset of previous */
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <termios.h>
+#include <nfc/nfc.h>
+#include <microhttpd.h>
+#include <gnunet/gnunet_util_lib.h>
+#include <qrencode.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+/* for adafruit pitft display */
+#include <linux/fb.h>
+
+/**
+ * Disable i18n support.
+ */
+#define _(s) (s)
+
+/**
+ * Handle for the Framebuffer device
+ */
+struct Display
+{
+ /**
+ * File descriptor for the screen
+ */
+ int devicefd;
+
+ /**
+ * File descriptor to set backlight information
+ */
+ int backlightfd;
+
+ /**
+ * The display memory to set the pixel information
+ */
+ uint16_t *memory;
+
+ /**
+ * Original screen information
+ */
+ struct fb_var_screeninfo orig_vinfo;
+
+ /**
+ * Variable screen information (color depth ...)
+ */
+ struct fb_var_screeninfo var_info;
+
+ /**
+ * Fixed screen informtaion
+ */
+ struct fb_fix_screeninfo fix_info;
+};
+
+
+/**
+ * Next program to launch.
+ */
+static char *const *arg_next;
+
+static struct GNUNET_TIME_Relative delay;
+
+/**
+ * Reference to the delay task
+ */
+static struct GNUNET_SCHEDULER_Task *delay_task;
+
+/**
+ * Name of the framebuffer device (i.e. /dev/fb1).
+ */
+static char *framebuffer_device_filename;
+
+/**
+ * Name of the backlight file of @e framebuffer_device_filename (i.e. /sys/class/backlight/soc:backlight/brightness).
+ */
+static char *framebuffer_backlight_filename;
+
+/**
+ * Global option '-i' to invert backlight on/off values
+ */
+static int backlight_invert;
+
+/**
+ * Standard backlight on value
+ */
+static char backlight_on = '1';
+
+/**
+ * Standard backlight off value
+ */
+static char backlight_off = '0';
+
+/**
+ * Handle for the framebuffer device
+ */
+static struct Display qrDisplay;
+
+
+/**
+ * @brief Create the QR code to pay and display it on screen
+ *
+ * @param uri what text to show in the QR code
+ */
+static void
+show_qrcode (const char *uri)
+{
+ QRinput *qri;
+ QRcode *qrc;
+ unsigned int size;
+ size_t xOff;
+ size_t yOff;
+
+ if (0 > qrDisplay.devicefd)
+ return; /* no display, no dice */
+ qri = QRinput_new2 (0, QR_ECLEVEL_L);
+ if (NULL == qri)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "QRinput_new2");
+ return;
+ }
+ /* first try encoding as uppercase-only alpha-numerical
+ QR code (much smaller encoding); if that fails, also
+ try using binary encoding (in case nick contains
+ special characters). */
+ if ( (0 !=
+ QRinput_append (qri,
+ QR_MODE_AN,
+ strlen (uri),
+ (unsigned char *) uri)) &&
+ (0 !=
+ QRinput_append (qri,
+ QR_MODE_8,
+ strlen (uri),
+ (unsigned char *) uri)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "QRinput_append");
+ return;
+ }
+ qrc = QRcode_encodeInput (qri);
+ if (NULL == qrc)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "QRcode_encodeInput");
+ QRinput_free (qri);
+ return;
+ }
+
+ /* +8 for 4-pixels border */
+ size = GNUNET_MIN (qrDisplay.var_info.xres,
+ qrDisplay.var_info.yres);
+ unsigned int nwidth = qrc->width + 8; /* 4 pixel border */
+ xOff = 4 * size / nwidth;
+ yOff = 4 * size / nwidth;
+ if (qrDisplay.var_info.xres < qrDisplay.var_info.yres)
+ yOff += (qrDisplay.var_info.yres - qrDisplay.var_info.xres) / 2;
+ else
+ xOff += (qrDisplay.var_info.xres - qrDisplay.var_info.yres) / 2;
+ for (unsigned int x = 0; x < qrDisplay.var_info.xres - 2 * xOff; x++)
+ for (unsigned int y = 0; y < qrDisplay.var_info.yres - 2 * yOff; y++)
+ {
+ unsigned int xoff = x * nwidth / size;
+ unsigned int yoff = y * nwidth / size;
+ unsigned int off = xoff + yoff * qrc->width;
+ if ( (xoff >= (unsigned) qrc->width) ||
+ (yoff >= (unsigned) qrc->width) )
+ continue;
+ qrDisplay.memory[(y + yOff) * qrDisplay.var_info.xres + (x + xOff)] =
+ (0 == (qrc->data[off] & 1)) ? 0xFFFF : 0x0000;
+ }
+
+ QRcode_free (qrc);
+ QRinput_free (qri);
+
+ if (0 < qrDisplay.backlightfd)
+ (void) ! write (qrDisplay.backlightfd,
+ &backlight_on,
+ 1);
+}
+
+
+static void
+stop_task (void *cls)
+{
+ (void) cls;
+ delay_task = NULL;
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+static void
+shutdown_task (void *cls)
+{
+ (void) cls;
+ if (NULL != delay_task)
+ {
+ GNUNET_SCHEDULER_cancel (delay_task);
+ delay_task = NULL;
+ }
+ if (NULL != qrDisplay.memory)
+ memset (qrDisplay.memory,
+ 0xFF,
+ qrDisplay.var_info.xres
+ * qrDisplay.var_info.yres
+ * sizeof (uint16_t));
+ if (0 < qrDisplay.backlightfd)
+ (void) ! write (qrDisplay.backlightfd,
+ &backlight_off,
+ 1);
+ if (NULL != qrDisplay.memory)
+ {
+ /* free the display data */
+ munmap (qrDisplay.memory,
+ qrDisplay.fix_info.smem_len);
+ qrDisplay.memory = NULL;
+ /* reset original state */
+ if (0 > ioctl (qrDisplay.devicefd,
+ FBIOPUT_VSCREENINFO,
+ &qrDisplay.orig_vinfo))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "failed to reset original display state\n");
+ }
+ /* close device */
+ GNUNET_break (0 == close (qrDisplay.devicefd));
+ qrDisplay.devicefd = -1;
+ if (0 < qrDisplay.backlightfd)
+ GNUNET_break (0 == close (qrDisplay.backlightfd));
+ qrDisplay.backlightfd = -1;
+ }
+}
+
+
+/**
+ * @brief Start the application
+ *
+ * @param cls closure
+ * @param args arguments left
+ * @param cfgfile config file name
+ * @param cfg handle for the configuration file
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ (void) cls;
+ (void) cfgfile;
+
+ if (NULL == args[0])
+ return;
+ arg_next = args + 1;
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (
+ cfg,
+ "taler-mdb",
+ "FRAMEBUFFER_DEVICE",
+ &framebuffer_device_filename))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler-mdb",
+ "FRAMEBUFFER_DEVICE");
+ framebuffer_device_filename = GNUNET_strdup ("/dev/fb1");
+ }
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (
+ cfg,
+ "taler-mdb",
+ "FRAMEBUFFER_BACKLIGHT",
+ &framebuffer_backlight_filename))
+ {
+ GNUNET_log_config_missing (
+ GNUNET_ERROR_TYPE_ERROR,
+ "taler-mdb",
+ "FRAMEBUFFER_BACKLIGHT");
+ framebuffer_backlight_filename = GNUNET_strdup (
+ "/sys/class/backlight/soc:backlight/brightness");
+ }
+ /* open the framebuffer device */
+ qrDisplay.devicefd = open (framebuffer_device_filename,
+ O_RDWR);
+ if (0 < qrDisplay.devicefd)
+ {
+ /* read information about the screen */
+ ioctl (qrDisplay.devicefd,
+ FBIOGET_VSCREENINFO,
+ &qrDisplay.var_info);
+
+ /* store current screeninfo for reset */
+ qrDisplay.orig_vinfo = qrDisplay.var_info;
+
+ if (16 != qrDisplay.var_info.bits_per_pixel)
+ {
+ /* Change variable info to 16 bit per pixel */
+ qrDisplay.var_info.bits_per_pixel = 16;
+ if (0 > ioctl (qrDisplay.devicefd,
+ FBIOPUT_VSCREENINFO,
+ &qrDisplay.var_info))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "ioctl(FBIOPUT_VSCREENINFO)");
+ return;
+ }
+ }
+
+ /* Get fixed screen information */
+ if (0 > ioctl (qrDisplay.devicefd,
+ FBIOGET_FSCREENINFO,
+ &qrDisplay.fix_info))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "ioctl(FBIOGET_FSCREENINFO)");
+ return;
+ }
+
+ /* get pointer onto frame buffer */
+ qrDisplay.memory
+ = mmap (NULL,
+ qrDisplay.fix_info.smem_len,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ qrDisplay.devicefd,
+ 0);
+
+ /* open backlight file to turn display backlight on and off */
+ if (0 > qrDisplay.devicefd)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "mmap");
+ return;
+ }
+
+ memset (qrDisplay.memory,
+ 0xFF,
+ qrDisplay.var_info.xres * qrDisplay.var_info.yres
+ * sizeof (uint16_t));
+
+ qrDisplay.backlightfd = open (
+ framebuffer_backlight_filename, O_WRONLY);
+ if (0 > qrDisplay.backlightfd)
+ {
+ GNUNET_log_strerror_file (
+ GNUNET_ERROR_TYPE_WARNING,
+ "open",
+ framebuffer_backlight_filename);
+ }
+ else
+ {
+ if (backlight_invert)
+ {
+ backlight_on = '0';
+ backlight_off = '1';
+ }
+ (void) ! write (qrDisplay.backlightfd,
+ &backlight_off,
+ 1);
+ }
+ }
+ else
+ {
+ GNUNET_log_strerror_file (
+ GNUNET_ERROR_TYPE_WARNING,
+ "open",
+ framebuffer_device_filename);
+ }
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+ NULL);
+ show_qrcode (args[0]);
+ delay_task = GNUNET_SCHEDULER_add_delayed (delay,
+ &stop_task,
+ NULL);
+}
+
+
+int
+main (int argc,
+ char*const*argv)
+{
+ int ret;
+ /* the available command line options */
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_relative_time ('d',
+ "delay",
+ "DELAY",
+ "how long should we display the QR code before exiting",
+ &delay),
+ GNUNET_GETOPT_option_flag ('i',
+ "backlight-invert",
+ "invert the backlight on/off values (standard on = 1)",
+ &backlight_invert),
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ ret = GNUNET_PROGRAM_run (argc,
+ argv,
+ "taler-mdb-qr-show",
+ "This is an application to show a QR code for a defined period of time before starting another program.\n",
+ options,
+ &run,
+ NULL);
+ if (GNUNET_OK != ret)
+ return 1;
+ if ( (NULL == arg_next) ||
+ (NULL == arg_next[0]) )
+ return 0;
+ execvp (arg_next[0],
+ arg_next);
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "execvp",
+ arg_next[0]);
+ return 1;
+}