k4ever/display-daemon/ser.c

321 lines
6.6 KiB
C

#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <pthread.h> /* Posix 1003.1c threads */
#include <signal.h>
#include <unistd.h>
int fd;
int screensaver;
int brightness = 4;
char *fifo;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread1;
int
initport (int fd)
{
struct termios options;
// Get the current options for the port...
tcgetattr (fd, &options);
// Set the baud rates to 9600...
cfsetispeed (&options, B9600);
cfsetospeed (&options, B9600);
// Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// Set the new options for the port...
tcsetattr (fd, TCSANOW, &options);
return 1;
}
char display_init[] = { 0x1b, 0x40 };
char display_showtime[] = { 0x1F, 0x54 };
char display_cursor_off[] = { 0x1f, 0x43, 0x0 };
char display_cursor_on[] = { 0x1f, 0x43, 0x1 };
char display_on[] = { 0x1f, 0x45, 0x0 };
char display_off[] = { 0x1f, 0x45, 0xff };
char display_overwrite[] = { 0x1f, 0x01 };
char display_vscroll[] = { 0x1f, 0x02 };
char display_hscroll[] = { 0x1f, 0x03 };
char display_clear_screen[] = { 0x0c };
char display_time[] = {0x1f,0x55};
#define DWC(c) display_write(c,sizeof(c))
#define SEND_TEXT(t) display_write(t,strlen(t))
#define SEND_DISPLAY_INIT DWC(display_init)
#define SEND_CURSOR_OFF DWC(display_cursor_off)
#define SEND_CURSOR_ON DWC(display_cursor_on)
#define SEND_DEFINE_TIMER DWC(display_showtime)
#define SEND_SHOW_TIMER DWC(display_time)
#define SEND_MODE_OVERWRITE DWC(display_overwrite)
#define SEND_MODE_VSCROLL DWC(display_vscroll)
#define SEND_MODE_HSCROLL DWC(display_hscroll)
#define SEND_DISPLAY_OFF DWC(display_off)
#define SEND_DISPLAY_ON DWC(display_on)
#define SEND_CLEAR DWC(display_clear_screen);
#define TIME_BASE 200000
#define TB_TO_SECS(x) (x*1000000/TIME_BASE)
#define TIME_CLOCK TB_TO_SECS(25)
#define TIME_DIM TB_TO_SECS(90)
#define TIME_OFF TB_TO_SECS(320)
#define DEVICE "/dev/ttyUSB0"
#define PAUSEMSG "Hallo, bitte melde Dich am Barcodereader an, um das Kassensystem zu benutzen *** Angebot: Die Mate heute nur 0.75 *** "
#define LINELEN 20
void
display_write (const void *buf, size_t count)
{
pthread_mutex_lock (&mutex1);
write (fd, buf, count);
pthread_mutex_unlock (&mutex1);
}
void
display_putstring (char *s)
{
screensaver = 0;
SEND_TEXT(s);
}
void
showtime (void)
{
SEND_CURSOR_OFF;
char c[5] = { 0x1F, 0x54, 0x00, 0x00 };
time_t timer; // Define the timer
struct tm *tblock; // Define a structure for time block
timer = time (NULL);
tblock = localtime (&timer);
c[2] = tblock->tm_hour;
c[3] = tblock->tm_min;
display_write (&c, 4);
SEND_MODE_HSCROLL;
char *msg = "Freitagsrunde 4!";
display_write (msg, strlen (msg));
}
void
display_dim (short i)
{
// return;
if (i == brightness)
{
//printf ("display_dim: would not change brightness. abort.\n");
return;
}
if (i > 0 && i < 5)
{
int l = 0;
char *d;
if (brightness == 0)
{
SEND_CURSOR_OFF;
// turn display on again
SEND_DISPLAY_ON;
SEND_MODE_OVERWRITE;
char c[4] = { 0x1f, 0x58, 0x04, 0x00 };
l = 6;
//c[5]=i;
d = c;
}
else
{
//set brightness directly:
char c[4] = { 0x1f, 0x58, 0x01, 0x00 };
l = 3;
c[2] = i;
d = c;
//printf ("command mode: %x \n", c[2]);
}
display_write (d, l);
brightness = i;
}
else if (i == 0)
{
//turn off
SEND_DISPLAY_OFF;
brightness = i;
}
}
void *
rthread (void *args)
{
int pipe;
char pc = ' ';
char c = ' ';
while (1)
{
pipe = open ("/tmp/display", O_RDONLY);
int r;
while ((r = read (pipe, &c, 1)) > 0)
{
screensaver = 0;
if (pc == '\n')
{
display_write (&pc, 1);
}
if (c != '\n')
{
display_write (&c, 1);
}
pc = c;
display_dim (4);
}
close (pipe);
}
}
void
sighandler (int sig)
{
pthread_kill (thread1, 0);
SEND_DISPLAY_INIT;
SEND_MODE_OVERWRITE;
SEND_CURSOR_OFF;
SEND_DISPLAY_OFF;
close (fd);
if (fifo) {unlink(fifo);}
exit (0);
//signal(sig, sighandler);
}
int
main (int argc, char **argv)
{
char *devnode ;
//TODO: arg parser!
fifo=strdup("/tmp/display");
if (argc != 2)
{
devnode=strdup(DEVICE);
printf ("no device specified, using default %s\n",devnode);
}else{
devnode=strdup(argv[1]);
}
fd = open (devnode, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror (devnode);
return 1;
}
else
{
fcntl (fd, F_SETFL, 0);
}
initport (fd);
//init display, set, vertical scroll, cursor off
SEND_DISPLAY_INIT;
SEND_MODE_OVERWRITE;
SEND_CURSOR_OFF;
pthread_create (&thread1, NULL, rthread, NULL);
signal (SIGINT, sighandler);
if (mkfifo (fifo, S_IRWXU | S_IRWXG | S_IRWXO))
{
perror (fifo);
if (errno != EEXIST && errno != ESPIPE)
{
return (1);
}
}
//showtime();
display_putstring ("Display initialized ");
display_putstring (fifo);
sleep (3);
screensaver = 0;
while (1)
{
usleep(TIME_BASE);
//printf ("screensaver = %05d brightness: %d\n", screensaver, brightness);
if (screensaver < 10000)
{
screensaver++;
}
if (screensaver == TIME_CLOCK)
{
showtime ();
}
if (screensaver == TIME_OFF)
{
display_dim (0);
}
//show a scroll text while the screensaver is active...
if ((screensaver > (TIME_CLOCK+10)) && (screensaver < TIME_OFF)){
char *message = calloc(LINELEN+1,sizeof(char));
strncpy(message,PAUSEMSG+((screensaver-TIME_CLOCK-1)%strlen(PAUSEMSG)),LINELEN);
int l = strlen(message);
if (l<LINELEN){
message = strncat(message, PAUSEMSG , LINELEN-l);
}
SEND_TEXT("\x0b");
SEND_TEXT(message);
free(message);
}
//after some more seconds of inactivity dim display and finally turn off
if ((screensaver > TIME_DIM) && (brightness > 1))
{
//printf ("dimming\n");
display_dim (brightness - 1);
}
}
//you'll never get here
close (fd);
return 0;
}