From 864fc3a22e3a1b57079e100f74159d41be9a4e12 Mon Sep 17 00:00:00 2001
From: Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
Date: Thu, 8 Oct 2020 12:45:54 +0200
Subject: [PATCH] Added logging message to files.

---
 README    |  5 ++++
 display.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 display.h |  1 +
 osd-clock |  2 +-
 osdd.c    | 10 +++++++
 5 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/README b/README
index c934518..de074fb 100644
--- a/README
+++ b/README
@@ -53,6 +53,11 @@ You can also add attributes to the message (written as command-line options):
 
   --to=stdout		Write message to stdout instead of display.
 
+  --log=mask		Write this message to log file. Bitmask.
+	Last bit:       Write to ~/.osdd_last in machine readable form.
+	Second bit:     Append to ~/.osdd_log in human readable form with RGB color.
+
+
 The default values of most of these attributes can be given by command-line
 options of the daemon, use `osdd --help' to get the full list.
 
diff --git a/display.c b/display.c
index 8a50abe..ae50e68 100644
--- a/display.c
+++ b/display.c
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
+#include <time.h>
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include <X11/extensions/shape.h>
@@ -377,10 +378,89 @@ static void osd_draw_line(struct osd_state *osd, int i)
   XftColorFree(osd->dpy, osd->visual, osd->cmap, &osd->mask_color);
 }
 
+static void repace_bad_char(char * in)
+{
+	for(;*in;in++)
+	{
+		if('a'<= *in&& *in<='z') continue;
+		if('A'<= *in&& *in<='Z') continue;
+		if('0'<= *in&& *in<='9') continue;
+		if(128 <= (unsigned char)*in) continue;
+		*in=' ';
+	}
+}
+
+static void osd_log_to_file(struct osd_state *osd)
+{
+#define MAXIMUM_FILE_MANE_LEN 1024
+	int need_log=0;
+	for(int i=0;i<osd->num_lines;i++) need_log|=osd->lines[i].log;
+	if(need_log&1)
+	{
+		char name[MAXIMUM_FILE_MANE_LEN];
+		snprintf(name,MAXIMUM_FILE_MANE_LEN,"%s/.osdd_last",getenv("HOME"));
+		FILE * f = fopen(name,"w");
+		if(f)
+		{
+			fprintf(f,"%lld\n",(long long)time(0));
+			for(int i=0;i<osd->num_lines;i++)
+			{
+				struct osd_line * line = osd->lines+i;
+				if(!(line->log & 1)) continue;
+				if(line->type!=OSD_TYPE_TEXT) continue;
+				// Allocate colors
+				XftColor outline_color;
+				XRenderColor mask_rc = { .red = 0xffff, .green = 0xffff, .blue = 0xffff, .alpha = 0xffff };
+				if (!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->fg_color, &osd->fg_color) ||
+						!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->outline_color, &outline_color) ||
+						!XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &mask_rc, &osd->mask_color))
+					die("Cannot allocate colors");
+				typeof(osd->fg_color.color) c = osd->fg_color.color;
+				//fprintf(stderr,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,osd->lines[i].u.text);
+				char text[1024];
+				snprintf(text,1000,osd->lines[i].u.text);
+				repace_bad_char(text);
+				fprintf(f,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,text);
+			}
+			fclose(f);
+		}
+	}
+	if(need_log&2)
+	{
+		char name[MAXIMUM_FILE_MANE_LEN];
+		snprintf(name,MAXIMUM_FILE_MANE_LEN,"%s/.osdd_log",getenv("HOME"));
+		FILE * f = fopen(name,"a");
+		if(f)
+		{
+			time_t t = time(NULL);
+			struct tm tm = *localtime(&t);
+			fprintf(f,"%04d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+			for(int i=0;i<osd->num_lines;i++)
+			{
+				struct osd_line * line = osd->lines+i;
+				if(!(line->log & 2)) continue;
+				// Allocate colors
+				XftColor outline_color;
+				XRenderColor mask_rc = { .red = 0xffff, .green = 0xffff, .blue = 0xffff, .alpha = 0xffff };
+				if (!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->fg_color, &osd->fg_color) ||
+						!XftColorAllocName(osd->dpy, osd->visual, osd->cmap, line->outline_color, &outline_color) ||
+						!XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &mask_rc, &osd->mask_color))
+					die("Cannot allocate colors");
+				typeof(osd->fg_color.color) c = osd->fg_color.color;
+				//fprintf(stderr,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,osd->lines[i].u.text);
+				fprintf(f," \x1b[38;2;%d;%d;%dm%s\e[0m",c.red/256,c.green/256,c.blue/256,osd->lines[i].u.text);
+			}
+			fprintf(f,"\n");
+			fclose(f);
+		}
+	}
+}
+
 void osd_show(struct osd_state *osd)
 {
   osd_hide(osd);
   osd_prepare(osd);
+  osd_log_to_file(osd);
 
   // Create our window
   XSetWindowAttributes win_attr = {
diff --git a/display.h b/display.h
index 953ef93..fb21c24 100644
--- a/display.h
+++ b/display.h
@@ -35,6 +35,7 @@ struct osd_line {
   int slider_unit;
   int slider_space;
   int slider_units;
+  int log;
 };
 
 struct osd_state *osd_new(Display *dpy);
diff --git a/osd-clock b/osd-clock
index dfc2454..4d6d818 100755
--- a/osd-clock
+++ b/osd-clock
@@ -1,2 +1,2 @@
 #!/bin/sh
-date '+%d-%m-%Y  %H:%M:%S' | osdc -
+date '+%Y-%m-%d  %H:%M:%S' | osdc --log=0 --min-duration=1 - 
diff --git a/osdd.c b/osdd.c
index 0da7712..b1119df 100644
--- a/osdd.c
+++ b/osdd.c
@@ -30,6 +30,7 @@ static char *default_outline_color = "black";
 static int default_outline_width = 2;
 static int default_duration = 1000;
 static int default_min_duration = 250;
+static int default_log = 255;
 static int debug_mode;
 static int test_mode;
 static double line_spacing = 0.2;
@@ -49,6 +50,7 @@ static const struct option long_opts[] = {
   { "outline-color",	required_argument,	NULL,	'o' },
   { "outline-width",	required_argument,	NULL,	'O' },
   { "line-spacing",	required_argument,	NULL,	's' },
+  { "log",		required_argument,	NULL,	'L' },
   { "test",		no_argument,		NULL,	OPT_TEST },	// Undocumented test mode
   { NULL,		0,			NULL,	0   },
 };
@@ -66,6 +68,7 @@ Options:\n\
 -o, --outline-color=<c>\tDefault outline color\n\
 -O, --outline-width=<n>\tDefault outline width (default=2)\n\
 -s, --line-spacing=<n>\tSet line spacing factor (decimal fraction, default=0.2)\n\
+-L, --log=<n>\t\tSet default log options (bitmask, default=255)\n\
 ");
   exit(1);
 }
@@ -101,6 +104,9 @@ parse_opts(int argc, char **argv)
       case 'O':
 	default_outline_width = atoi(optarg);
 	break;
+      case 'L':
+	default_log = atoi(optarg);
+	break;
       case OPT_TEST:
 	test_mode = 1;
 	debug_mode = 1;
@@ -130,6 +136,7 @@ display_msg(struct msg *msg)
   char *fg_color = default_color;
   char *outline_color = default_outline_color;
   int outline_width = default_outline_width;
+  int log = default_log;
 
   char *line = msg->text;
   while (*line)
@@ -172,6 +179,8 @@ display_msg(struct msg *msg)
 	msg->max_light = now + atoi(val);
       else if (!strcmp(key, "min-duration"))
 	msg->min_light = now + atoi(val);
+      else if (!strcmp(key, "log"))
+	log = atoi(val);
       else if (!strcmp(key, "color"))
 	fg_color = val;
       else if (!strcmp(key, "outline-color"))
@@ -183,6 +192,7 @@ display_msg(struct msg *msg)
 	  l->fg_color = fg_color;
 	  l->outline_color = outline_color;
 	  l->outline_width = outline_width;
+	  l->log = log;
 	}
 
       line = nl;
-- 
GitLab