taler-mdb

GNU Taler Extensions and Integrations
Log | Files | Refs | Submodules | README | LICENSE

taler-mdb-display.c (7788B)


      1 /*
      2  This file is part of TALER
      3  Copyright (C) 2024 Taler Systems SA
      4 
      5  TALER is free software; you can redistribute it and/or modify it under the
      6  terms of the GNU General Public License as published by the Free Software
      7  Foundation; either version 3, or (at your option) any later version.
      8 
      9  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10  WARRANTY; without even the implied warranty of MERCHANTABILITY or
     11 FITNESS FOR
     12  A PARTICULAR PURPOSE.  See the GNU General Public License for more
     13 details.
     14 
     15  You should have received a copy of the GNU General Public License
     16 along with
     17  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file taler-mdb-display.c
     21  * @brief turn on the display back light on or off
     22  * @author Boss Marco
     23  * @author Christian Grothoff
     24  */
     25 #include "config.h"
     26 #include <stdio.h>
     27 #include <stdlib.h>
     28 #include <string.h>
     29 #include <unistd.h>
     30 #include <errno.h>
     31 #include <gnunet/gnunet_util_lib.h>
     32 #include <sys/mman.h>
     33 #include <sys/ioctl.h>
     34 #include <fcntl.h>
     35 /* for adafruit pitft display */
     36 #include <linux/fb.h>
     37 #include "taler_mdb_util.h"
     38 
     39 /**
     40  * Handle for the Framebuffer device
     41  */
     42 struct Display
     43 {
     44   /**
     45    * File descriptor for the screen
     46    */
     47   int devicefd;
     48 
     49   /**
     50    * File descriptor to set backlight information
     51    */
     52   int backlightfd;
     53 
     54   /**
     55    * The display memory to set the pixel information
     56    */
     57   uint16_t *memory;
     58 
     59   /**
     60    * Original screen information
     61    */
     62   struct fb_var_screeninfo orig_vinfo;
     63 
     64   /**
     65    * Variable screen information (color depth ...)
     66    */
     67   struct fb_var_screeninfo var_info;
     68 
     69   /**
     70    * Fixed screen informtaion
     71    */
     72   struct fb_fix_screeninfo fix_info;
     73 };
     74 
     75 
     76 /**
     77  * Name of the framebuffer device (i.e. /dev/fb1).
     78  */
     79 static char *framebuffer_device_filename;
     80 
     81 /**
     82  * Name of the backlight file of @e framebuffer_device_filename (i.e. /sys/class/backlight/soc:backlight/brightness).
     83  */
     84 static char *framebuffer_backlight_filename;
     85 
     86 /**
     87  * Global option '-i' to invert backlight on/off values
     88  */
     89 static int backlight_invert;
     90 
     91 /**
     92  * Standard backlight on value
     93  */
     94 static char backlight_on = '1';
     95 
     96 /**
     97  * Standard backlight off value
     98  */
     99 static char backlight_off = '0';
    100 
    101 /**
    102  * Handle for the framebuffer device
    103  */
    104 static struct Display qrDisplay;
    105 
    106 
    107 static void
    108 shutdown_task (void *cls)
    109 {
    110   (void) cls;
    111   if (NULL != qrDisplay.memory)
    112     memset (qrDisplay.memory,
    113             0xFF,
    114             qrDisplay.var_info.xres * qrDisplay.var_info.yres
    115             * sizeof (uint16_t));
    116   if (NULL != qrDisplay.memory)
    117   {
    118     /* free the display data  */
    119     munmap (qrDisplay.memory,
    120             qrDisplay.fix_info.smem_len);
    121     qrDisplay.memory = NULL;
    122     /* close device */
    123     GNUNET_break (0 == close (qrDisplay.devicefd));
    124     qrDisplay.devicefd = -1;
    125     if (0 < qrDisplay.backlightfd)
    126       GNUNET_break (0 == close (qrDisplay.backlightfd));
    127     qrDisplay.backlightfd = -1;
    128   }
    129 }
    130 
    131 
    132 /**
    133  * @brief Start the application
    134  *
    135  * @param cls closure
    136  * @param args arguments left
    137  * @param cfgfile config file name
    138  * @param cfg handle for the configuration file
    139  */
    140 static void
    141 run (void *cls,
    142      char *const *args,
    143      const char *cfgfile,
    144      const struct GNUNET_CONFIGURATION_Handle *cfg)
    145 {
    146   (void) cls;
    147   (void) cfgfile;
    148 
    149   if (GNUNET_OK !=
    150       GNUNET_CONFIGURATION_get_value_filename (cfg,
    151                                                "taler-mdb",
    152                                                "FRAMEBUFFER_DEVICE",
    153                                                &framebuffer_device_filename))
    154   {
    155     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    156                                "taler-mdb",
    157                                "FRAMEBUFFER_DEVICE");
    158     framebuffer_device_filename = GNUNET_strdup ("/dev/fb1");
    159   }
    160   if (GNUNET_OK !=
    161       GNUNET_CONFIGURATION_get_value_filename (cfg,
    162                                                "taler-mdb",
    163                                                "FRAMEBUFFER_BACKLIGHT",
    164                                                &framebuffer_backlight_filename))
    165   {
    166     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    167                                "taler-mdb",
    168                                "FRAMEBUFFER_BACKLIGHT");
    169     framebuffer_backlight_filename = GNUNET_strdup (
    170       "/sys/class/backlight/soc:backlight/brightness");
    171   }
    172   /* open the framebuffer device */
    173   qrDisplay.devicefd = open (framebuffer_device_filename,
    174                              O_RDWR);
    175   if (0 < qrDisplay.devicefd)
    176   {
    177     /* read information about the screen */
    178     ioctl (qrDisplay.devicefd,
    179            FBIOGET_VSCREENINFO,
    180            &qrDisplay.var_info);
    181 
    182     /* store current screeninfo for reset */
    183     qrDisplay.orig_vinfo = qrDisplay.var_info;
    184 
    185     if (16 != qrDisplay.var_info.bits_per_pixel)
    186     {
    187       /* Change variable info to 16 bit per pixel */
    188       qrDisplay.var_info.bits_per_pixel = 16;
    189       if (0 > ioctl (qrDisplay.devicefd,
    190                      FBIOPUT_VSCREENINFO,
    191                      &qrDisplay.var_info))
    192       {
    193         GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
    194                              "ioctl(FBIOPUT_VSCREENINFO)");
    195         return;
    196       }
    197     }
    198 
    199     /* Get fixed screen information */
    200     if (0 > ioctl (qrDisplay.devicefd,
    201                    FBIOGET_FSCREENINFO,
    202                    &qrDisplay.fix_info))
    203     {
    204       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
    205                            "ioctl(FBIOGET_FSCREENINFO)");
    206       return;
    207     }
    208 
    209     /* get pointer onto frame buffer */
    210     qrDisplay.memory =  mmap (NULL,
    211                               qrDisplay.fix_info.smem_len,
    212                               PROT_READ | PROT_WRITE, MAP_SHARED,
    213                               qrDisplay.devicefd,
    214                               0);
    215 
    216     /* open backlight file to turn display backlight on and off */
    217     if (0 > qrDisplay.devicefd)
    218     {
    219       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
    220                            "mmap");
    221       return;
    222     }
    223 
    224     memset (qrDisplay.memory,
    225             0xFF,
    226             qrDisplay.var_info.xres * qrDisplay.var_info.yres
    227             * sizeof (uint16_t));
    228 
    229     qrDisplay.backlightfd = open (
    230       framebuffer_backlight_filename, O_WRONLY);
    231     if (0 > qrDisplay.backlightfd)
    232     {
    233       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
    234                                 "open",
    235                                 framebuffer_backlight_filename);
    236     }
    237     else
    238     {
    239       if (backlight_invert)
    240       {
    241         backlight_on = '0';
    242         backlight_off = '1';
    243       }
    244       (void) ! write (qrDisplay.backlightfd,
    245                       &backlight_off,
    246                       1);
    247     }
    248   }
    249   else
    250   {
    251     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
    252                               "open",
    253                               framebuffer_device_filename);
    254   }
    255   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
    256                                  NULL);
    257 
    258   if (0 < qrDisplay.backlightfd)
    259     (void) ! write (qrDisplay.backlightfd,
    260                     &backlight_on,
    261                     1);
    262 }
    263 
    264 
    265 int
    266 main (int argc,
    267       char*const*argv)
    268 {
    269   enum GNUNET_GenericReturnValue ret;
    270   struct GNUNET_GETOPT_CommandLineOption options[] = {
    271     GNUNET_GETOPT_option_flag ('i',
    272                                "backlight-invert",
    273                                "toggle on vs. off",
    274                                &backlight_invert),
    275     GNUNET_GETOPT_OPTION_END
    276   };
    277 
    278   ret = GNUNET_PROGRAM_run (TALER_MDB_project_data (),
    279                             argc,
    280                             argv,
    281                             "taler-mdb-display",
    282                             "Turn frame buffer display on or off\n",
    283                             options,
    284                             &run,
    285                             NULL);
    286   if (GNUNET_OK != ret)
    287     return 1;
    288   return 0;
    289 }