From: notaz Date: Sat, 12 Jul 2014 17:53:45 +0000 (+0300) Subject: 0.1 release X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pandora_liveinfo.git;a=commitdiff_plain;h=063ae4be6676b3b6c48183e3753238b05547b124 0.1 release --- 063ae4be6676b3b6c48183e3753238b05547b124 diff --git a/COPYING b/COPYING new file mode 100644 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 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 index 0000000..2994023 --- /dev/null +++ b/fonts.c @@ -0,0 +1,314 @@ +#include +#include + +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 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 index 0000000..8394186 Binary files /dev/null and b/liveinfo.png differ diff --git a/liveinfo.pxml b/liveinfo.pxml new file mode 100644 index 0000000..5ea3c02 --- /dev/null +++ b/liveinfo.pxml @@ -0,0 +1,48 @@ + + + + + Live system info + + + + + + + Live system info + + Live system info + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/main.c b/main.c new file mode 100644 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 index 0000000..ca1344e Binary files /dev/null and b/preview.jpg differ diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..fbcacbd --- /dev/null +++ b/readme.txt @@ -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 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 index 0000000..f6be786 --- /dev/null +++ b/update_pnd.sh @@ -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