0.1 release
authornotaz <notasas@gmail.com>
Sat, 12 Jul 2014 17:53:45 +0000 (20:53 +0300)
committernotaz <notasas@gmail.com>
Sat, 12 Jul 2014 17:53:45 +0000 (20:53 +0300)
COPYING [new file with mode: 0644]
Makefile [new file with mode: 0644]
fonts.c [new file with mode: 0644]
fonts.h [new file with mode: 0644]
liveinfo.png [new file with mode: 0644]
liveinfo.pxml [new file with mode: 0644]
main.c [new file with mode: 0644]
preview.jpg [new file with mode: 0644]
readme.txt [new file with mode: 0644]
run.sh [new file with mode: 0755]
update_pnd.sh [new file with mode: 0755]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..d44538c
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,24 @@
+
+ Copyright (c) 2014, notaz
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+     * Neither the name of the organization nor the
+       names of its contributors may be used to endorse or promote products
+       derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..fe05688
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+CC = $(CROSS_COMPILE)gcc
+CFLAGS += -Wall -ggdb
+ifndef DEBUG
+CFLAGS += -O2
+endif
+LDLIBS += -lpthread -lrt
+
+OBJS = main.o fonts.o
+
+all: liveinfo
+
+liveinfo: $(OBJS)
+       $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
+
+clean:
+       $(RM) liveinfo $(OBJS)
+
+.PHONY: all clean
diff --git a/fonts.c b/fonts.c
new file mode 100644 (file)
index 0000000..2994023
--- /dev/null
+++ b/fonts.c
@@ -0,0 +1,314 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+unsigned char fontdata8x8[64*16] =
+{
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x3C,0x42,0x99,0xBD,0xBD,0x99,0x42,0x3C,0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C,
+       0xFE,0x82,0x8A,0xD2,0xA2,0x82,0xFE,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
+       0x80,0xC0,0xF0,0xFC,0xF0,0xC0,0x80,0x00,0x01,0x03,0x0F,0x3F,0x0F,0x03,0x01,0x00,
+       0x18,0x3C,0x7E,0x18,0x7E,0x3C,0x18,0x00,0xEE,0xEE,0xEE,0xCC,0x00,0xCC,0xCC,0x00,
+       0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
+       0x3C,0x66,0x7A,0x7A,0x7E,0x7E,0x3C,0x00,0x0E,0x3E,0x3A,0x22,0x26,0x6E,0xE4,0x40,
+       0x18,0x3C,0x7E,0x3C,0x3C,0x3C,0x3C,0x00,0x3C,0x3C,0x3C,0x3C,0x7E,0x3C,0x18,0x00,
+       0x08,0x7C,0x7E,0x7E,0x7C,0x08,0x00,0x00,0x10,0x3E,0x7E,0x7E,0x3E,0x10,0x00,0x00,
+       0x58,0x2A,0xDC,0xC8,0xDC,0x2A,0x58,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00,
+       0x00,0x10,0x10,0x38,0x38,0x7C,0xFE,0x00,0xFE,0x7C,0x38,0x38,0x10,0x10,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x18,0x00,0x18,0x18,0x00,
+       0x6C,0x6C,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,
+       0x10,0x38,0x60,0x38,0x0C,0x78,0x10,0x00,0x40,0xA4,0x48,0x10,0x24,0x4A,0x04,0x00,
+       0x18,0x34,0x18,0x3A,0x6C,0x66,0x3A,0x00,0x18,0x18,0x20,0x00,0x00,0x00,0x00,0x00,
+       0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x00,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x00,
+       0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00,
+       0x38,0x4C,0xC6,0xC6,0xC6,0x64,0x38,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00,
+       0x7C,0xC6,0x0E,0x3C,0x78,0xE0,0xFE,0x00,0x7E,0x0C,0x18,0x3C,0x06,0xC6,0x7C,0x00,
+       0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x00,0xFC,0xC0,0xFC,0x06,0x06,0xC6,0x7C,0x00,
+       0x3C,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00,0xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00,
+       0x78,0xC4,0xE4,0x78,0x86,0x86,0x7C,0x00,0x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
+       0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30,
+       0x1C,0x38,0x70,0xE0,0x70,0x38,0x1C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,
+       0x70,0x38,0x1C,0x0E,0x1C,0x38,0x70,0x00,0x7C,0xC6,0xC6,0x1C,0x18,0x00,0x18,0x00,
+       0x3C,0x42,0x99,0xA1,0xA5,0x99,0x42,0x3C,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00,
+       0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,
+       0xF8,0xCC,0xC6,0xC6,0xC6,0xCC,0xF8,0x00,0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xFE,0x00,
+       0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0x00,0x3E,0x60,0xC0,0xCE,0xC6,0x66,0x3E,0x00,
+       0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,
+       0x06,0x06,0x06,0x06,0xC6,0xC6,0x7C,0x00,0xC6,0xCC,0xD8,0xF0,0xF8,0xDC,0xCE,0x00,
+       0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,
+       0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
+       0xFC,0xC6,0xC6,0xC6,0xFC,0xC0,0xC0,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x7A,0x00,
+       0xFC,0xC6,0xC6,0xCE,0xF8,0xDC,0xCE,0x00,0x78,0xCC,0xC0,0x7C,0x06,0xC6,0x7C,0x00,
+       0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
+       0xC6,0xC6,0xC6,0xEE,0x7C,0x38,0x10,0x00,0xC6,0xC6,0xD6,0xFE,0xFE,0xEE,0xC6,0x00,
+       0xC6,0xEE,0x3C,0x38,0x7C,0xEE,0xC6,0x00,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00,
+       0xFE,0x0E,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,
+       0x60,0x60,0x30,0x18,0x0C,0x06,0x06,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,
+       0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
+       0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3C,0x00,
+       0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00,
+       0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x3C,0x00,
+       0x1C,0x30,0x78,0x30,0x30,0x30,0x30,0x00,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x3C,
+       0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x00,
+       0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x38,0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00,
+       0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0xEC,0xFE,0xFE,0xFE,0xD6,0xC6,0x00,
+       0x00,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,
+       0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x06,
+       0x00,0x7E,0x70,0x60,0x60,0x60,0x60,0x00,0x00,0x3C,0x60,0x3C,0x06,0x66,0x3C,0x00,
+       0x30,0x78,0x30,0x30,0x30,0x30,0x1C,0x00,0x00,0x66,0x66,0x66,0x66,0x6E,0x3E,0x00,
+       0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x7C,0x6C,0x00,
+       0x00,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C,
+       0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x0E,0x18,0x0C,0x38,0x0C,0x18,0x0E,0x00,
+       0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x70,0x18,0x30,0x1C,0x30,0x18,0x70,0x00,
+       0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x10,0x28,0x10,0x54,0xAA,0x44,0x00,0x00,
+};
+
+
+/* The font is generated from Xorg clR5x8.bdf */
+/*
+COMMENT  Copyright 1989 Dale Schumacher, dal@syntel.mn.org
+COMMENT                 399 Beacon Ave.
+COMMENT                 St. Paul, MN  55104-3527
+COMMENT
+COMMENT  Permission to use, copy, modify, and distribute this software and
+COMMENT  its documentation for any purpose and without fee is hereby
+COMMENT  granted, provided that the above copyright notice appear in all
+COMMENT  copies and that both that copyright notice and this permission
+COMMENT  notice appear in supporting documentation, and that the name of
+COMMENT  Dale Schumacher not be used in advertising or publicity pertaining to
+COMMENT  distribution of the software without specific, written prior
+COMMENT  permission.  Dale Schumacher makes no representations about the
+COMMENT  suitability of this software for any purpose.  It is provided "as
+COMMENT  is" without express or implied warranty.
+COMMENT
+*/
+unsigned char fontdata6x8[256][8] = {
+{ 0x7c>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0xff>>2, 0x7c>>2, },
+{ 0x00>>2, 0x00>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x40>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x4c>>2, 0x44>>2, 0x3c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x1c>>2, 0x04>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x48>>2, 0x50>>2, 0x60>>2, 0x50>>2, 0x48>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x6c>>2, 0x54>>2, 0x54>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x64>>2, 0x54>>2, 0x4c>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x0c>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x50>>2, 0x4c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x38>>2, 0x04>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x28>>2, 0x28>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x54>>2, 0x54>>2, 0x6c>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x7c>>2, 0x00>>2, },
+{ 0xe0>>2, 0x80>>2, 0xe0>>2, 0x8c>>2, 0xf0>>2, 0x10>>2, 0x10>>2, 0x0c>>2, },
+{ 0x00>>2, 0x10>>2, 0x38>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x7c>>2, 0x38>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x18>>2, 0xfc>>2, 0x18>>2, 0x10>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x20>>2, 0x60>>2, 0xfc>>2, 0x60>>2, 0x20>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x10>>2, 0x00>>2, },
+{ 0x28>>2, 0x28>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x28>>2, 0x7c>>2, 0x28>>2, 0x7c>>2, 0x28>>2, 0x00>>2, 0x00>>2, },
+{ 0x10>>2, 0x3c>>2, 0x50>>2, 0x38>>2, 0x14>>2, 0x78>>2, 0x10>>2, 0x00>>2, },
+{ 0x60>>2, 0x64>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x4c>>2, 0x0c>>2, 0x00>>2, },
+{ 0x38>>2, 0x40>>2, 0x40>>2, 0x20>>2, 0x54>>2, 0x48>>2, 0x34>>2, 0x00>>2, },
+{ 0x10>>2, 0x20>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x04>>2, 0x08>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x08>>2, 0x04>>2, 0x00>>2, },
+{ 0x40>>2, 0x20>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x20>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x54>>2, 0x38>>2, 0x54>>2, 0x10>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x20>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x7c>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x04>>2, 0x04>>2, 0x08>>2, 0x08>>2, 0x10>>2, 0x10>>2, 0x20>>2, 0x20>>2, },
+{ 0x38>>2, 0x44>>2, 0x4c>>2, 0x54>>2, 0x64>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x10>>2, 0x30>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x04>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x7c>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x04>>2, 0x18>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x18>>2, 0x18>>2, 0x28>>2, 0x28>>2, 0x7c>>2, 0x08>>2, 0x1c>>2, 0x00>>2, },
+{ 0x7c>>2, 0x40>>2, 0x78>>2, 0x04>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x18>>2, 0x20>>2, 0x40>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x7c>>2, 0x44>>2, 0x04>>2, 0x08>>2, 0x08>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, 0x08>>2, 0x30>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x20>>2, },
+{ 0x00>>2, 0x0c>>2, 0x30>>2, 0xc0>>2, 0x30>>2, 0x0c>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x00>>2, 0x7c>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0xc0>>2, 0x30>>2, 0x0c>>2, 0x30>>2, 0xc0>>2, 0x00>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x04>>2, 0x08>>2, 0x10>>2, 0x00>>2, 0x10>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x5c>>2, 0x5c>>2, 0x58>>2, 0x40>>2, 0x38>>2, 0x00>>2, },
+{ 0x10>>2, 0x28>>2, 0x44>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x70>>2, 0x48>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x48>>2, 0x70>>2, 0x00>>2, },
+{ 0x7c>>2, 0x40>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x7c>>2, 0x40>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x40>>2, 0x4c>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x7c>>2, 0x00>>2, },
+{ 0x1c>>2, 0x04>>2, 0x04>>2, 0x04>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x44>>2, 0x48>>2, 0x50>>2, 0x60>>2, 0x50>>2, 0x48>>2, 0x44>>2, 0x00>>2, },
+{ 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x44>>2, 0x6c>>2, 0x54>>2, 0x54>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x44>>2, 0x64>>2, 0x64>>2, 0x54>>2, 0x4c>>2, 0x4c>>2, 0x44>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x0c>>2, },
+{ 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x50>>2, 0x48>>2, 0x44>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x40>>2, 0x38>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x28>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x54>>2, 0x54>>2, 0x6c>>2, 0x44>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x7c>>2, 0x04>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x1c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x1c>>2, 0x00>>2, },
+{ 0x20>>2, 0x20>>2, 0x10>>2, 0x10>>2, 0x08>>2, 0x08>>2, 0x04>>2, 0x04>>2, },
+{ 0x70>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x70>>2, 0x00>>2, },
+{ 0x10>>2, 0x28>>2, 0x44>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0xfc>>2, 0x00>>2, },
+{ 0x10>>2, 0x08>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x4c>>2, 0x34>>2, 0x00>>2, },
+{ 0x40>>2, 0x40>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x3c>>2, 0x00>>2, },
+{ 0x04>>2, 0x04>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x7c>>2, 0x40>>2, 0x38>>2, 0x00>>2, },
+{ 0x1c>>2, 0x20>>2, 0x78>>2, 0x20>>2, 0x20>>2, 0x20>>2, 0x20>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, 0x38>>2, },
+{ 0x40>>2, 0x40>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x10>>2, 0x00>>2, 0x30>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x38>>2, 0x00>>2, },
+{ 0x08>>2, 0x00>>2, 0x38>>2, 0x08>>2, 0x08>>2, 0x08>>2, 0x08>>2, 0x70>>2, },
+{ 0x40>>2, 0x40>>2, 0x48>>2, 0x50>>2, 0x60>>2, 0x50>>2, 0x48>>2, 0x00>>2, },
+{ 0x30>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x68>>2, 0x54>>2, 0x54>>2, 0x54>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x58>>2, 0x64>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x40>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, },
+{ 0x00>>2, 0x00>>2, 0x58>>2, 0x60>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x38>>2, 0x04>>2, 0x78>>2, 0x00>>2, },
+{ 0x10>>2, 0x10>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x0c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x4c>>2, 0x34>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x6c>>2, 0x28>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x54>>2, 0x54>>2, 0x54>>2, 0x28>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, 0x38>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x7c>>2, 0x00>>2, },
+{ 0x04>>2, 0x08>>2, 0x08>>2, 0x10>>2, 0x08>>2, 0x08>>2, 0x04>>2, 0x00>>2, },
+{ 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x40>>2, 0x20>>2, 0x20>>2, 0x10>>2, 0x20>>2, 0x20>>2, 0x40>>2, 0x00>>2, },
+{ 0x20>>2, 0x54>>2, 0x08>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x28>>2, 0x28>>2, 0x44>>2, 0x7c>>2, 0x00>>2, },
+};
+
+/* note: may use 1 extra pixel on the right */
+void basic_text_out16_nf(void *fb, int w, int x, int y, const char *text)
+{
+       int i, l;
+       unsigned short *screen;
+       unsigned short val = 0xffff;
+
+       screen = (unsigned short *)fb + x + y * w;
+       for (i = 0; x + i * 8 < w; i++, screen += 8)
+       {
+               char c = text[i];
+               if (c == 0)
+                       break;
+               if (c == ' ')
+                       continue;
+
+               for (l = 0; l < 8; l++)
+               {
+                       unsigned char fd = fontdata8x8[c * 8 + l];
+                       unsigned short *s = screen + l * w;
+                       unsigned char fd1, fdp = 0;
+
+                       if (fd&0x80) s[0] = val;
+                       if (fd&0x40) s[1] = val;
+                       if (fd&0x20) s[2] = val;
+                       if (fd&0x10) s[3] = val;
+                       if (fd&0x08) s[4] = val;
+                       if (fd&0x04) s[5] = val;
+                       if (fd&0x02) s[6] = val;
+                       if (fd&0x01) s[7] = val;
+
+                       // draw "shadow" (RGB1555 compatible)
+                       if (l > 0)
+                               fdp = fontdata8x8[c * 8 + l - 1];
+
+                       for (fd1 = 0x80; fd1 != 0; fd1 >>= 1, s++)
+                               if (!(fd & (fd1 >> 1)) && ((fdp | fd) & fd1))
+                                       s[1] = (s[1] >> 1) & 0x39ef;
+               }
+       }
+}
+
+void basic_text_out_uyvy_nf(void *fb, int w, int x, int y, const char *text)
+{
+       int i, l;
+       unsigned short *screen;
+
+       screen = (unsigned short *)fb + x + y * w;
+       for (i = 0; x + i * 8 < w; i++, screen += 8)
+       {
+               char c = text[i];
+               if (c == 0)
+                       break;
+               if (c == ' ')
+                       continue;
+
+               for (l = 0; l < 8; l++)
+               {
+                       unsigned char fd = fontdata8x8[c * 8 + l];
+                       unsigned char *s = (void *)(screen + l * w);
+                       unsigned char fd1, fdp = 0;
+
+                       if (fd&0x80) s[0 * 2 + 1] = 235;
+                       if (fd&0x40) s[1 * 2 + 1] = 235;
+                       if (fd&0x20) s[2 * 2 + 1] = 235;
+                       if (fd&0x10) s[3 * 2 + 1] = 235;
+                       if (fd&0x08) s[4 * 2 + 1] = 235;
+                       if (fd&0x04) s[5 * 2 + 1] = 235;
+                       if (fd&0x02) s[6 * 2 + 1] = 235;
+                       if (fd&0x01) s[7 * 2 + 1] = 235;
+
+                       // draw "shadow"
+                       if (l > 0)
+                               fdp = fontdata8x8[c * 8 + l - 1];
+
+                       for (fd1 = 0x80; fd1 != 0; fd1 >>= 1, s += 2)
+                               if (!(fd & (fd1 >> 1)) && ((fdp | fd) & fd1))
+                                       s[1] /= 2;
+               }
+       }
+}
+
+void basic_text_out16(void *fb, int w, int x, int y, const char *texto, ...)
+{
+       va_list args;
+       char    buffer[256];
+
+       va_start(args, texto);
+       vsnprintf(buffer, sizeof(buffer), texto, args);
+       va_end(args);
+
+       basic_text_out16_nf(fb, w, x, y, buffer);
+}
diff --git a/fonts.h b/fonts.h
new file mode 100644 (file)
index 0000000..e565c93
--- /dev/null
+++ b/fonts.h
@@ -0,0 +1,7 @@
+
+extern unsigned char fontdata8x8[64*16];
+extern unsigned char fontdata6x8[256-32][8];
+
+void basic_text_out16_nf(void *fb, int w, int x, int y, const char *text);
+void basic_text_out16(void *fb, int w, int x, int y, const char *texto, ...);
+void basic_text_out_uyvy_nf(void *fb, int w, int x, int y, const char *text);
diff --git a/liveinfo.png b/liveinfo.png
new file mode 100644 (file)
index 0000000..8394186
Binary files /dev/null and b/liveinfo.png differ
diff --git a/liveinfo.pxml b/liveinfo.pxml
new file mode 100644 (file)
index 0000000..5ea3c02
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PXML xmlns="http://openpandora.org/namespaces/PXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PXML_schema.xsd">
+<package id="package.liveinfo.notaz">
+  <titles>
+    <title lang="en_US">Live system info</title>
+  </titles>
+  <version major="0" minor="1" release="0" build="0" type="release"/>
+  <author name="notaz" website="http://notaz.gp2x.de/"/>
+</package>
+<application id="liveinfo.notaz" appdata="liveinfo">
+  <titles>
+    <title lang="en_US">Live system info</title>
+  </titles>
+  <title lang="en_US">Live system info</title>
+
+  <descriptions>
+    <description lang="en_US">Shows CPU, memory, I/O, network and battery information on an always-visible layer, updated once a second. Uses system-reserved OMAP hardware layer, so should be visible in most programs that don't use tv-out (tv-out needs that same layer to send video to TV).
+
+When you want to exit Live info, just run this pnd again.
+
+See documentation for information about what each number means.</description>
+  </descriptions>
+
+  <exec command="run.sh"/>
+
+  <author name="notaz" website="http://notaz.gp2x.de/"/>
+
+  <version major="0" minor="1" release="0" build="0" type="release"/>
+
+  <icon src="liveinfo.png"/>
+
+  <info name="Live info readme" type="text/plain" src="readme.txt"/>
+
+  <previewpics>
+    <pic src="preview.jpg"/>
+  </previewpics>
+
+  <licenses>
+    <license name="BSD" url="http://opensource.org/licenses/BSD-3-Clause"/>
+  </licenses>
+
+  <categories>
+    <category name="System">
+    <subcategory name="Monitor"/>
+    </category>
+  </categories>
+</application>
+</PXML>
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..75082eb
--- /dev/null
+++ b/main.c
@@ -0,0 +1,798 @@
+/*
+ * pandora live info
+ * (C) notaz, 2014
+ *
+ * This work is licensed under the terms of 3-clause BSD license.
+ * See COPYING file in the top-level directory.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <signal.h>
+#include <poll.h>
+#include <linux/fb.h>
+#include <linux/omapfb.h>
+#include <stdint.h>
+#include "fonts.h"
+
+#define SCREEN_WIDTH 800
+#define SCREEN_HEIGHT 480
+#define WIDTH 80
+#define HEIGHT 480
+#define MEM_SIZE (((WIDTH * HEIGHT * 2 * 2) + 0xfff) & ~0xfff)
+#define Y_STEP 9
+
+static struct fb_var_screeninfo g_vi;
+static uint16_t *g_screen_base, *g_screen;
+static unsigned int g_old_mem;
+static int g_fd, g_exit;
+
+#define IS_START(buf, str) \
+  !strncmp(buf, str, sizeof(str) - 1)
+
+static int setup_layer(void)
+{
+  static const char fbname[] = "/dev/fb2";
+  struct omapfb_plane_info pi;
+  struct omapfb_mem_info mi;
+  struct omapfb_color_key key;
+  int ret;
+
+  g_fd = open(fbname, O_RDWR);
+  if (g_fd == -1) {
+    fprintf(stderr, "open %s: ", fbname);
+    perror(NULL);
+    return 1;
+  }
+
+  ret = ioctl(g_fd, OMAPFB_QUERY_PLANE, &pi);
+  if (ret < 0) {
+    perror("ioctl OMAPFB_QUERY_PLANE");
+    return 1;
+  }
+
+  ret = ioctl(g_fd, OMAPFB_QUERY_MEM, &mi);
+  if (ret < 0) {
+    perror("ioctl OMAPFB_QUERY_MEM");
+    return 1;
+  }
+
+  /* must disable when changing stuff */
+  if (pi.enabled) {
+    pi.enabled = 0;
+    ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi);
+    if (ret < 0) {
+      perror("ioctl OMAPFB_SETUP_PLANE (d)");
+      return 1;
+    }
+  }
+
+  g_old_mem = mi.size;
+  if (mi.size < MEM_SIZE) {
+    mi.size = MEM_SIZE;
+    ret = ioctl(g_fd, OMAPFB_SETUP_MEM, &mi);
+    if (ret < 0) {
+      perror("ioctl SETUP_MEM");
+      return 1;
+    }
+  }
+
+  pi.pos_x = SCREEN_WIDTH - WIDTH;
+  pi.pos_y = 0;
+  pi.out_width = WIDTH;
+  pi.out_height = HEIGHT;
+  ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi);
+  if (ret < 0) {
+    perror("ioctl OMAPFB_SETUP_PLANE (e1)");
+    return 1;
+  }
+
+  ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_vi);
+  if (ret < 0) {
+    perror("ioctl FBIOGET_VSCREENINFO");
+    return 1;
+  }
+
+  g_vi.xres = g_vi.xres_virtual = WIDTH;
+  g_vi.yres = HEIGHT;
+  g_vi.yres_virtual = HEIGHT * 2;
+  g_vi.bits_per_pixel = 16;
+
+  ret = ioctl(g_fd, FBIOPUT_VSCREENINFO, &g_vi);
+  if (ret < 0) {
+    perror("ioctl FBIOPUT_VSCREENINFO");
+    return 1;
+  }
+
+  pi.enabled = 1;
+  ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi);
+  if (ret < 0) {
+    perror("ioctl OMAPFB_SETUP_PLANE (e2)");
+    return 1;
+  }
+
+  memset(&key, 0, sizeof(key));
+  key.key_type = OMAPFB_COLOR_KEY_VID_SRC;
+  key.trans_key = 0x07e0;
+
+       ret = ioctl(g_fd, OMAPFB_SET_COLOR_KEY, &key);
+       if (ret < 0) {
+               perror("ioctl OMAPFB_SET_COLOR_KEY");
+    return 1;
+       }
+
+  return 0;
+}
+
+static int check_layer(void)
+{
+  struct omapfb_plane_info pi;
+  int ret;
+
+  ret = ioctl(g_fd, OMAPFB_QUERY_PLANE, &pi);
+  if (ret < 0) {
+    perror("ioctl OMAPFB_QUERY_PLANE");
+    return 1;
+  }
+
+  if (!pi.enabled) {
+    printf("something disabled the layer (tv-out?), quitting\n");
+    return 1;
+  }
+
+  return 0;
+}
+
+static void remove_layer(void)
+{
+  struct omapfb_plane_info pi;
+  struct omapfb_mem_info mi;
+  int ret;
+
+  memset(&pi, 0, sizeof(pi));
+  pi.enabled = 0;
+  ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi);
+  if (ret < 0)
+    perror("ioctl OMAPFB_SETUP_PLANE (c)");
+
+  ret = ioctl(g_fd, OMAPFB_QUERY_MEM, &mi);
+  if (ret < 0) {
+    perror("ioctl OMAPFB_QUERY_MEM");
+    goto out;
+  }
+
+  if (mi.size != g_old_mem) {
+    mi.size = g_old_mem;
+    ret = ioctl(g_fd, OMAPFB_SETUP_MEM, &mi);
+    if (ret < 0) {
+      perror("ioctl SETUP_MEM");
+      goto out;
+    }
+  }
+
+out:
+  close(g_fd);
+  g_fd = -1;
+}
+
+static void handle_signal(int num)
+{
+  g_exit = 1;
+}
+
+static void flip_fb(void)
+{
+  static int id;
+
+       g_vi.yoffset = id * HEIGHT;
+       ioctl(g_fd, FBIOPAN_DISPLAY, &g_vi);
+  id ^= 1;
+  g_screen = g_screen_base + id * WIDTH * HEIGHT;
+}
+
+#define s_printf(x, y, fmt, ...) \
+  basic_text_out16(g_screen, WIDTH, x, y, fmt, ##__VA_ARGS__);
+
+static int read_int_file(const char *fn, int *val)
+{
+  FILE *f;
+  int ret;
+
+  *val = 0;
+  f = fopen(fn, "r");
+  if (f == NULL)
+    return 1;
+  ret = fscanf(f, "%d", val);
+  fclose(f);
+  if (ret != 1)
+    return 1;
+
+  return 0;
+}
+
+static void clear(int h)
+{
+  int *p = (int *)g_screen;
+  int l = WIDTH * h / 2;
+
+  for (; l >= 4; l -= 4, p += 4)
+    p[0] = p[1] = p[2] = p[3] = 0x07e007e0;
+  for (; l >  0; l--, p++)
+    *p = 0x07e007e0;
+}
+
+struct proc_stat {
+  unsigned long idlesum;
+  unsigned long sys;
+  unsigned long irqs;
+  unsigned long ctxt;
+};
+
+static struct {
+  struct proc_stat last_st;
+  int cpu_usage;
+  int cpu_sys;
+  int irqs;
+  int ctxt;
+  int mem_free;
+  int mem_huge;
+  int mem_free_swap;
+} stats;
+
+static void collect_proc_stat(void)
+{
+  static long hz;
+  struct proc_stat st;
+  char buf[256];
+  unsigned long wait;
+  unsigned long iowait;
+  FILE *f;
+
+  if (hz == 0) {
+    hz = sysconf(_SC_CLK_TCK);
+    printf("hz: %ld\n", hz);
+  }
+
+  f = fopen("/proc/stat", "r");
+  if (f == NULL)
+    return;
+
+  if (fscanf(f, "cpu %*s %*s %lu %lu %lu",
+      &st.sys, &wait, &iowait) != 3)
+    goto out;
+  do {
+    if (fgets(buf, sizeof(buf), f) == NULL)
+      goto out;
+  } while (fscanf(f, "intr %lu", &st.irqs) != 1);
+  do {
+    if (fgets(buf, sizeof(buf), f) == NULL)
+      goto out;
+  } while (fscanf(f, "ctxt %lu", &st.ctxt) != 1);
+
+  st.idlesum = wait + iowait;
+
+  stats.cpu_usage = hz - (st.idlesum - stats.last_st.idlesum);
+  stats.cpu_sys = st.sys - stats.last_st.sys;
+  if (hz != 100) {
+    stats.cpu_usage = stats.cpu_usage * 100 / hz;
+    stats.cpu_sys = stats.cpu_sys * 100 / hz;
+  }
+  stats.irqs = st.irqs - stats.last_st.irqs;
+  stats.ctxt = st.ctxt - stats.last_st.ctxt;
+
+out:
+  stats.last_st = st;
+  fclose(f);
+}
+
+static void collect_mem_stat(void)
+{
+  static const char fn[] = "/proc/meminfo";
+  uint32_t total = 0, free = 0, buffers = 0, cached = 0;
+  uint32_t anonhuge = 0, hugetot = 0, hugefree = 0, hugepgsz = 0;
+  uint32_t free_swap = 0;
+  char buf[128];
+  FILE *f;
+
+  f = fopen(fn, "r");
+  if (f == NULL)
+    return;
+
+  while (fgets(buf, sizeof(buf), f)) {
+    if (total == 0 && sscanf(buf, "MemTotal: %u", &total) == 1)
+      continue;
+    if (free == 0 && sscanf(buf, "MemFree: %u", &free) == 1)
+      continue;
+    if (buffers == 0 && sscanf(buf, "Buffers: %u", &buffers) == 1)
+      continue;
+    if (cached == 0 && sscanf(buf, "Cached: %u", &cached) == 1)
+      continue;
+    if (free_swap == 0 && sscanf(buf, "SwapFree: %u", &free_swap) == 1)
+      continue;
+    if (anonhuge == 0 && sscanf(buf, "AnonHugePages: %u", &anonhuge) == 1)
+      continue;
+    if (hugetot == 0 && sscanf(buf, "HugePages_Total: %u", &hugetot) == 1)
+      continue;
+    if (hugefree == 0 && sscanf(buf, "HugePages_Free: %u", &hugefree) == 1)
+      continue;
+    if (hugepgsz == 0 && sscanf(buf, "Hugepagesize: %u", &hugepgsz) == 1)
+      continue;
+  }
+
+  fclose(f);
+
+  hugetot = (hugetot - hugefree) * hugepgsz;
+  free += buffers + cached;
+  stats.mem_free = free >> 10;
+  stats.mem_huge = hugetot >> 10;
+  stats.mem_free_swap = free_swap >> 10;
+}
+
+struct io_stat {
+  unsigned long sec_r;
+  unsigned long sec_w;
+};
+
+static struct {
+  struct io_stat last_st;
+  int read; // kB/s
+  int write;
+} io_stats;
+
+static void collect_io_stat(void)
+{
+  unsigned long sec_r, sec_w;
+  struct io_stat st = { 0, };
+  char buf[128];
+  FILE *f;
+  int i;
+
+  for (i = 0; i < 2; i++) {
+    snprintf(buf, sizeof(buf), "/sys/block/mmcblk%d/stat", i);
+    f = fopen(buf, "r");
+    if (f == NULL)
+      continue;
+
+    if (fscanf(f, "%*s %*s %lu %*s %*s %*s %lu",
+               &sec_r, &sec_w) == 2)
+    {
+      st.sec_r += sec_r;
+      st.sec_w += sec_w;
+    }
+    fclose(f);
+  }
+
+  io_stats.read = st.sec_r - io_stats.last_st.sec_r;
+  io_stats.write = st.sec_w - io_stats.last_st.sec_w;
+  // assuming 512 byte sectors..
+  io_stats.read >>= 1;
+  io_stats.write >>= 1;
+
+  io_stats.last_st = st;
+}
+
+struct net_stat {
+  unsigned long rx;
+  unsigned long tx;
+};
+
+static struct {
+  struct net_stat last_st;
+  int down; // kB/s
+  int up;
+  int have_wlan;
+  int link;
+  int level;
+} net_stats;
+
+static void collect_net_stat(void)
+{
+  struct net_stat st = { 0, };
+  unsigned long rx, tx;
+  int found = 0;
+  char buf[256];
+  FILE *f;
+
+  net_stats.down = net_stats.up =
+  net_stats.have_wlan = net_stats.link = net_stats.level = 0;
+
+  f = fopen("/proc/net/dev", "r");
+  if (f == NULL)
+    return;
+
+  while (!feof(f)) {
+    static const char fmt[] =
+      "%255s %lu %*s %*s %*s %*s %*s %*s %lu";
+    if (fscanf(f, fmt, buf, &rx, &tx) != 3)
+      continue;
+    if (IS_START(buf, "lo"))
+      continue;
+    st.rx += rx;
+    st.tx += tx;
+    found = 1;
+  }
+  fclose(f);
+
+  if (found) {
+    net_stats.down = st.rx - net_stats.last_st.rx;
+    net_stats.up = st.tx - net_stats.last_st.tx;
+  }
+  net_stats.last_st = st;
+
+  f = fopen("/proc/net/wireless", "r");
+  if (f == NULL)
+    return;
+
+  while (!feof(f)) {
+    int lnk, lvl;
+    if (fscanf(f, "%255s %*x %d. %d.", buf, &lnk, &lvl) != 3)
+      continue;
+    if (IS_START(buf, "lo"))
+      continue;
+    // first one should be enough
+    net_stats.have_wlan = 1;
+    net_stats.link = lnk;
+    net_stats.level = lvl;
+    break;
+  }
+  fclose(f);
+}
+
+static void collect_stats(void)
+{
+  collect_proc_stat();
+  collect_mem_stat();
+  collect_io_stat();
+  collect_net_stat();
+}
+
+static char cpu_reg_path[64];
+
+static void init_stats(void)
+{
+  char buf[64];
+  int found;
+  FILE *f;
+  int i;
+
+  // find the CPU regulator
+  for (i = found = 0; ; i++) {
+    snprintf(buf, sizeof(buf),
+      "/sys/class/regulator/regulator.%d/name", i);
+    f = fopen(buf, "r");
+    if (f == NULL)
+      break;
+    fgets(buf, sizeof(buf), f);
+    fclose(f);
+    if (IS_START(buf, "vdd_mpu")) {
+      found = 1;
+      break;
+    }
+  }
+
+  if (found)
+    snprintf(cpu_reg_path, sizeof(cpu_reg_path),
+      "/sys/class/regulator/regulator.%d/microvolts", i);
+
+  // do collect so differential stats get sane values
+  collect_stats();
+}
+
+static void get_time(int x, int y)
+{
+  struct timeval tv;
+  struct tm *t;
+  char buf[16];
+
+  gettimeofday(&tv, NULL);
+  t = localtime(&tv.tv_sec);
+  strftime(buf, sizeof(buf), "%T", t);
+  s_printf(x, y, " %s", buf);
+}
+
+static void get_cpu(int x, int y)
+{
+  s_printf(x, y, "CPU:%5d%%", stats.cpu_usage);
+}
+
+static void get_sys(int x, int y)
+{
+  s_printf(x, y, "SYS:%5d%%", stats.cpu_sys);
+}
+
+static void get_irq(int x, int y)
+{
+  s_printf(x, y, "IRQ:%5u", stats.irqs);
+}
+
+static void get_cs(int x, int y)
+{
+  s_printf(x, y, "CS:%6u", stats.ctxt);
+}
+
+static void get_cpuf(int x, int y)
+{
+  static const char fn[] =
+    "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq";
+  int f;
+
+  if (read_int_file(fn, &f))
+    return;
+  s_printf(x, y, "f:%7dM", f / 1000);
+}
+
+static void get_cpuv(int x, int y)
+{
+  int v = 0;
+
+  if (!cpu_reg_path[0] || read_int_file(cpu_reg_path, &v))
+    return;
+  s_printf(x, y, "V:%7.3fV", (float)v / 1000000.0f);
+}
+
+static void get_memfree(int x, int y)
+{
+  s_printf(x, y, "M:%7dM", stats.mem_free);
+}
+
+static void get_memhuge(int x, int y)
+{
+  s_printf(x, y, "H:%7dM", stats.mem_huge);
+}
+
+static void get_memswap(int x, int y)
+{
+  s_printf(x, y, "S:%7dM", stats.mem_free_swap);
+}
+
+#define PS_BASE "/sys/class/power_supply/bq27500-0/"
+
+static void get_bcap(int x, int y)
+{
+  static const char fnc[] = PS_BASE "capacity";
+  int c;
+
+  if (read_int_file(fnc, &c))
+    return;
+  s_printf(x, y, "C:%7d%%", c);
+}
+
+static void get_btime(int x, int y)
+{
+  static const char fne[] = PS_BASE "time_to_empty_now";
+  static const char fnf[] = PS_BASE "time_to_full_now";
+  int t = 0;
+
+  if (read_int_file(fne, &t) || t == 0) {
+    if (read_int_file(fnf, &t))
+      return;
+  }
+  s_printf(x, y, "t:%4d:%02d", t / 3600, t / 60 % 60);
+}
+
+static void get_bvolts(int x, int y)
+{
+  static const char fnv[] = PS_BASE "voltage_now";
+  int volt = 0;
+
+  if (read_int_file(fnv, &volt))
+    return;
+
+  s_printf(x, y, "V:%7.3fV", (float)volt / 1000000.0f);
+}
+
+static void get_bwatts(int x, int y)
+{
+  static const char fnc[] = PS_BASE "current_now";
+  static const char fnv[] = PS_BASE "voltage_now";
+  int w, cur = 0, volt = 0;
+
+  if (read_int_file(fnc, &cur))
+    return;
+  if (read_int_file(fnv, &volt))
+    return;
+
+  w = (cur / 1000) * (volt / 1000);
+  s_printf(x, y, "P:%7.3fW", (float)w / 1000000.0f);
+}
+
+static void get_btemp(int x, int y)
+{
+  static const char fnt[] = PS_BASE "temp";
+  int t;
+
+  if (read_int_file(fnt, &t))
+    return;
+  s_printf(x, y, "T:%7.1fC", (float)t / 10.0f);
+}
+
+static void get_ioread(int x, int y)
+{
+  s_printf(x, y, "R:%5.1fM/s", (float)io_stats.read / 1000.0f);
+}
+
+static void get_iowrite(int x, int y)
+{
+  s_printf(x, y, "W:%5.1fM/s", (float)io_stats.write / 1000.0f);
+}
+
+static void get_netdown(int x, int y)
+{
+  s_printf(x, y, "D:%5uK/s", net_stats.down / 1000);
+}
+
+static void get_netup(int x, int y)
+{
+  s_printf(x, y, "U:%5uK/s", net_stats.up / 1000);
+}
+
+static void get_netsgnl(int x, int y)
+{
+  s_printf(x, y, "S:%5ddBm", net_stats.level);
+}
+
+int main(int argc, char *argv[])
+{
+  static const char socket_name[] = "\0livestats";
+  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+  pthread_cond_t cond;
+  pthread_condattr_t condattr;
+  struct sockaddr_un sun;
+  struct timespec ts;
+  struct pollfd pfd;
+  int y = 0, y_max = 0;
+  int sock;
+  int ret;
+
+  // look for other instance
+  sock = socket(PF_UNIX, SOCK_STREAM, 0);
+  if (sock == -1) {
+    perror("socket PF_UNIX");
+    return 1;
+  }
+
+  memset(&sun, 0, sizeof(sun));
+  sun.sun_family = AF_UNIX;
+  memcpy(sun.sun_path, socket_name, sizeof(socket_name));
+
+  ret = connect(sock, (struct sockaddr *)&sun, sizeof(sun));
+  if (ret == 0) {
+    printf("other instance detected, sending quit command\n");
+    ret = send(sock, "quit", 4, 0);
+    if (ret != 4)
+      perror("send");
+    close(sock);
+    return 0;
+  }
+
+  // bind/listen for quit command
+  ret = bind(sock, (struct sockaddr *)&sun, sizeof(sun));
+  if (ret != 0) {
+    perror("bind");
+    close(sock);
+    return 1;
+  }
+
+  ret = listen(sock, 1);
+  if (ret != 0) {
+    perror("listen");
+    close(sock);
+    return 1;
+  }
+
+  pfd.fd = sock;
+  pfd.events = POLLIN | POLLPRI;
+  pfd.revents = 0;
+
+  // clean up on kill too
+  signal(SIGTERM, handle_signal);
+
+  ret  = pthread_condattr_init(&condattr);
+  ret |= pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
+  ret |= pthread_cond_init(&cond, &condattr);
+  pthread_condattr_destroy(&condattr);
+  if (ret != 0) {
+    fprintf(stderr, "cond init failed\n");
+    return 1;
+  }
+
+  ret = setup_layer();
+  if (ret)
+    return ret;
+
+  g_screen_base = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE,
+                  MAP_SHARED, g_fd, 0);
+  if (g_screen_base == MAP_FAILED) {
+    perror("mmap");
+    return 1;
+  }
+  g_screen = g_screen_base;
+  clear(HEIGHT);
+  flip_fb();
+  clear(HEIGHT);
+
+  pthread_mutex_lock(&mutex);
+  ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+  if (ret != 0) {
+    perror("clock_gettime CLOCK_MONOTONIC");
+    return 1;
+  }
+
+  nice(-1);
+  init_stats();
+
+  while (!g_exit) {
+    collect_stats();
+
+    y += Y_STEP;
+    if (y > y_max)
+      y_max = y;
+    clear(y_max);
+
+    y = 0;
+    get_time   (0, y += Y_STEP);
+    y += Y_STEP / 2;
+    get_cpu    (0, y += Y_STEP);
+    get_sys    (0, y += Y_STEP);
+    get_irq    (0, y += Y_STEP);
+    get_cs     (0, y += Y_STEP);
+    get_cpuf   (0, y += Y_STEP);
+    get_cpuv   (0, y += Y_STEP);
+    y += Y_STEP / 2;
+    s_printf(0, y += Y_STEP, "mem");
+    get_memfree(0, y += Y_STEP);
+    get_memswap(0, y += Y_STEP);
+    if (stats.mem_huge)
+      get_memhuge(0, y += Y_STEP);
+    y += Y_STEP / 2;
+    s_printf(0, y += Y_STEP, "i/o");
+    get_ioread (0, y += Y_STEP);
+    get_iowrite(0, y += Y_STEP);
+    y += Y_STEP / 2;
+    s_printf(0, y += Y_STEP, "net");
+    get_netdown(0, y += Y_STEP);
+    get_netup  (0, y += Y_STEP);
+    if (net_stats.have_wlan)
+      get_netsgnl(0, y += Y_STEP);
+    y += Y_STEP / 2;
+    s_printf(0, y += Y_STEP, "batt");
+    get_bcap   (0, y += Y_STEP);
+    get_btime  (0, y += Y_STEP);
+    get_bvolts (0, y += Y_STEP);
+    get_bwatts (0, y += Y_STEP);
+    get_btemp  (0, y += Y_STEP);
+
+    flip_fb();
+
+    if (check_layer() != 0)
+      break;
+    ret = poll(&pfd, 1, 0);
+    if (ret != 0) {
+      printf("poll returned %d\n", ret);
+      break;
+    }
+
+    ts.tv_sec++;
+    pthread_cond_timedwait(&cond, &mutex, &ts);
+  }
+
+  munmap(g_screen_base, MEM_SIZE);
+  remove_layer();
+  close(sock);
+
+  return 0;
+}
+
+// vim:expandtab:sw=2:ts=2
diff --git a/preview.jpg b/preview.jpg
new file mode 100644 (file)
index 0000000..ca1344e
Binary files /dev/null and b/preview.jpg differ
diff --git a/readme.txt b/readme.txt
new file mode 100644 (file)
index 0000000..fbcacbd
--- /dev/null
@@ -0,0 +1,50 @@
+Live info
+---------
+
+This is a tool that shows CPU, memory, I/O, network and battery
+information on an always-visible layer, updated once a second.
+Uses system-reserved OMAP hardware layer, so should be visible
+in most programs that don't use tv-out (tv-out needs that same
+layer to send video to TV).
+
+When you want to exit Live info, just run this pnd again.
+
+
+Fields
+------
+
+ 17:40:05    real time clock, hours:minutes:seconds
+
+ CPU:  100%  total CPU usage, in percent
+ SYS:    0%  CPU usage by the kernel only
+ IRQ:   29   CPU interrupts per second
+ CS:    30   CPU context switches per second
+ f:   1000M  CPU clock frequency, in MHz
+ V:  1.375V  CPU voltage
+
+ mem
+ M:    414M  free RAM, in megabytes
+ S:    125M  free swap space, in megabytes
+ H:      0M  memory used in huge pages, MB (only shown if nonzero)
+
+ i/o
+ R:  0.0M/s  current read throughput from SD cards, in megabytes/s
+ W:  0.0M/s  current write throughput to SD cards, in megabytes/s
+
+ net
+ D:    0K/s  download throughput, kilobytes/s
+ U:    0K/s  upload throughput, kilobytes/s
+ S:  -45dBm  wifi signal strength, in dBm
+
+ batt
+ C:     91%  estimated battery charge level (from monitoring chip)
+ t:  13:14   estimated time to empty/full, hours:minutes
+ V:  3.960V  current battery voltage
+ P: -1.140W  electric power going into battery, negative means discharge
+ T:   23.2C  battery temperature
+
+
+License
+-------
+
+3-clause BSD. Source code included in pnd itself.
diff --git a/run.sh b/run.sh
new file mode 100755 (executable)
index 0000000..e54a444
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+MSG="Reserved OMAP video layer requires root access, please enter the password."
+
+if test -f /etc/slackware-version; then
+
+  ktsuss -m "$MSG" ./liveinfo
+
+else
+
+  t=`which terminal`
+  if [ -z "$t" ]; then
+    zenity --error --text='terminal is missing.'
+    exit 1
+  fi
+
+  gksudo  -D "SGX driver installer" \
+         -m "$MSG" ./liveinfo
+
+fi
diff --git a/update_pnd.sh b/update_pnd.sh
new file mode 100755 (executable)
index 0000000..f6be786
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if test -z "$PND_MAKE"; then
+  PND_MAKE=$HOME/dev/pnd/src/pandora-libraries/testdata/scripts/pnd_make.sh
+fi
+
+rm -f *.o
+$PND_MAKE -p /tmp/liveinfo.pnd -d . -x liveinfo.pxml -i liveinfo.png -c