X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=main.c;h=4a8b952d150aaa56ea9d0e36552bb966aad3fc99;hb=refs%2Fheads%2Fmaster;hp=75799b475fb0968e9ce8c1bb65fc7ceb787a7b08;hpb=15f42220856460f67c375c1e64de4ffc4bdf6f47;p=pandora_liveinfo.git diff --git a/main.c b/main.c index 75799b4..4a8b952 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -32,16 +33,21 @@ #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 struct { + int x, y, w, h; +} g_layer; +static unsigned int g_mem_size; static unsigned int g_old_mem; static int g_flip_id; static int g_exit, g_hide; static pthread_cond_t g_cond; +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define PAGE_ALIGN(x) (((x) + 0xfff) & ~0xfff) #define IS_START(buf, str) \ !strncmp(buf, str, sizeof(str) - 1) @@ -77,8 +83,9 @@ static int setup_layer(int fd) } g_old_mem = mi.size; - if (mi.size < MEM_SIZE) { - mi.size = MEM_SIZE; + g_mem_size = PAGE_ALIGN(g_layer.w * g_layer.h * 2 * 2); + if (mi.size < g_mem_size) { + mi.size = g_mem_size; ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi); if (ret < 0) { perror("ioctl SETUP_MEM"); @@ -86,10 +93,13 @@ static int setup_layer(int fd) } } - pi.pos_x = SCREEN_WIDTH - WIDTH; - pi.pos_y = 0; - pi.out_width = WIDTH; - pi.out_height = HEIGHT; + printf("layer: %d %d %d %d\n", + g_layer.x, g_layer.y, g_layer.w, g_layer.h); + + pi.pos_x = g_layer.x; + pi.pos_y = g_layer.y; + pi.out_width = g_layer.w; + pi.out_height = g_layer.h; ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi); if (ret < 0) { perror("ioctl OMAPFB_SETUP_PLANE (e1)"); @@ -102,9 +112,9 @@ static int setup_layer(int fd) return 1; } - g_vi.xres = g_vi.xres_virtual = WIDTH; - g_vi.yres = HEIGHT; - g_vi.yres_virtual = HEIGHT * 2; + g_vi.xres = g_vi.xres_virtual = g_layer.w; + g_vi.yres = g_layer.h; + g_vi.yres_virtual = g_layer.h * 2; g_vi.bits_per_pixel = 16; ret = ioctl(fd, FBIOPUT_VSCREENINFO, &g_vi); @@ -130,14 +140,14 @@ static int setup_layer(int fd) return 1; } - g_screen_base = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, + g_screen_base = mmap(NULL, g_mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (g_screen_base == MAP_FAILED) { perror("mmap"); g_screen = g_screen_base = NULL; return 1; } - clear_bytes(g_screen_base, MEM_SIZE); + clear_bytes(g_screen_base, g_mem_size); g_screen = g_screen_base; g_flip_id = 0; @@ -170,7 +180,7 @@ static void remove_layer(int fd) int ret; if (g_screen_base != NULL) { - munmap(g_screen_base, MEM_SIZE); + munmap(g_screen_base, g_mem_size); g_screen = g_screen_base = NULL; } @@ -200,10 +210,10 @@ out:; static void flip_fb(int fd) { - g_vi.yoffset = g_flip_id * HEIGHT; + g_vi.yoffset = g_flip_id * g_layer.h; ioctl(fd, FBIOPAN_DISPLAY, &g_vi); g_flip_id ^= 1; - g_screen = g_screen_base + g_flip_id * WIDTH * HEIGHT; + g_screen = g_screen_base + g_flip_id * g_layer.w * g_layer.h; } static void handle_term(int num) @@ -218,8 +228,129 @@ static void handle_usr1(int num) pthread_cond_signal(&g_cond); } -#define s_printf(x, y, fmt, ...) \ - basic_text_out16(g_screen, WIDTH, x, y, fmt, ##__VA_ARGS__); +static struct { + char text[16]; + int idle; +} user_msgs[16]; + +static int handle_socket(int sock) +{ + char buf[256], *p; + int i, ret; + + ret = recv(sock, buf, sizeof(buf) - 1, 0); + if (ret < 0) { + perror("recv"); + return ret; + } + if (ret == 0) + return 0; + + buf[ret] = 0; + p = strchr(buf, ':'); + if (p != NULL) { + for (i = 0; i < ARRAY_SIZE(user_msgs); i++) { + if (user_msgs[i].text[0] == 0) + break; + if (!strncmp(user_msgs[i].text, buf, p - buf + 1)) + break; + } + if (i == ARRAY_SIZE(user_msgs)) { + printf("out of user_msg slots\n"); + return 0; + } + memcpy(user_msgs[i].text, buf, sizeof(user_msgs[i].text) - 1); + user_msgs[i].text[sizeof(user_msgs[i].text) - 1] = 0; + user_msgs[i].idle = 0; + } + else if (!strcmp(buf, "poke")) { + // if hidden, show up + // if visible, exit + if (g_hide) { + g_hide = 0; + return 1; + } + g_exit = 1; + return 1; + } + else if (!strcmp(buf, "hide")) { + g_hide = 1; + return 1; + } + else if (!strcmp(buf, "show")) { + g_hide = 0; + return 1; + } + else if (!strcmp(buf, "quit")) { + g_exit = 1; + return 1; + } + else { + printf("unknown command: '%s'\n", buf); + } + + return 0; +} + +static void default_config(void) +{ + g_layer.x = SCREEN_WIDTH - WIDTH; + g_layer.y = 0; + g_layer.w = WIDTH; + g_layer.h = HEIGHT; +} + +static void handle_config(void) +{ + char buf[256], *p; + int x, y, v; + FILE *f; + + default_config(); + + f = fopen("config.cfg", "r"); + if (f == NULL) + return; + + while ((p = fgets(buf, sizeof(buf), f))) { + while (isspace(*p)) + p++; + if (*p == '#' || *p == ';' || *p == 0) + continue; + + if (sscanf(p, "position = %d %d", &x, &y) == 2) { + g_layer.x = x; + g_layer.y = y; + } + else { + printf("unhandled config entry: '%s'\n", p); + } + } + fclose(f); + + v = SCREEN_WIDTH - g_layer.x; + if (v <= 0) { + printf("bad x position in config: %d\n", g_layer.x); + default_config(); + return; + } + if (v < WIDTH) + g_layer.w = v; + + v = SCREEN_HEIGHT - g_layer.y; + if (v <= 0) { + printf("bad y position in config: %d\n", g_layer.y); + default_config(); + return; + } + if (v < HEIGHT) + g_layer.h = v; +} + +#define s_printf(x, y, fmt, ...) do { \ + if ((y) <= g_layer.h - 8) \ + basic_text_out16(g_screen, g_layer.w, x, y, fmt, ##__VA_ARGS__); \ +} while (0) static int read_int_file(const char *fn, int *val) { @@ -251,7 +382,10 @@ static void clear_bytes(void *mem, int bytes) static void clear(int h) { - clear_bytes(g_screen, WIDTH * h * 2); + if (h > g_layer.h) + h = g_layer.h; + + clear_bytes(g_screen, g_layer.w * h * 2); } struct proc_stat { @@ -678,10 +812,10 @@ int main(int argc, char *argv[]) int y = 0, y_max = 0; int fd = -1; int sock; - int ret; + int i, ret; // look for other instance - sock = socket(PF_UNIX, SOCK_STREAM, 0); + sock = socket(PF_UNIX, SOCK_DGRAM, 0); if (sock == -1) { perror("socket PF_UNIX"); return 1; @@ -694,13 +828,16 @@ int main(int argc, char *argv[]) ret = connect(sock, (struct sockaddr *)&sun, sizeof(sun)); if (ret == 0) { printf("other instance detected, sending poke command\n"); - ret = send(sock, "poke", 5, 0); - if (ret != 5) + ret = send(sock, "poke", 4, 0); + if (ret != 4) perror("send"); close(sock); - return ret == 5 ? 0 : 1; + return ret == 4 ? 0 : 1; } + // load the config + handle_config(); + fd = open(fbname, O_RDWR); if (fd == -1) { fprintf(stderr, "open %s: ", fbname); @@ -729,12 +866,14 @@ int main(int argc, char *argv[]) return 1; } +#if 0 ret = listen(sock, 1); if (ret != 0) { perror("listen"); close(sock); return 1; } +#endif pfd.fd = sock; pfd.events = POLLIN | POLLPRI; @@ -768,6 +907,19 @@ int main(int argc, char *argv[]) while (!g_exit) { + // anything on unix socket? + ret = poll(&pfd, 1, 0); + if (ret < 0) { + perror("poll"); + break; + } + if (ret > 0) { + ret = handle_socket(sock); + if (ret < 0) + break; + continue; + } + // handle hiding if (g_hide) { if (!is_hidden) { @@ -783,6 +935,9 @@ int main(int argc, char *argv[]) is_hidden = 0; } + if (check_layer(fd) != 0) + break; + collect_stats(); y += Y_STEP; @@ -823,18 +978,27 @@ int main(int argc, char *argv[]) get_bwatts (0, y += Y_STEP); get_btemp (0, y += Y_STEP); - flip_fb(fd); - - if (check_layer(fd) != 0) - break; + // print user messages + y += Y_STEP; + for (i = 0; i < ARRAY_SIZE(user_msgs); i++) { + if (user_msgs[i].text[0] == 0) + break; + user_msgs[i].idle++; + if (user_msgs[i].idle > 6) { + // drop old entry, shift others up + memmove(&user_msgs[i], &user_msgs[i + 1], + (ARRAY_SIZE(user_msgs) - i - 1) * sizeof(user_msgs[0])); + user_msgs[ARRAY_SIZE(user_msgs) - 1].text[0] = 0; + // reprocess + i--; + continue; + } - // anything on unix socket? - ret = poll(&pfd, 1, 0); - if (ret != 0) { - printf("poll returned %d\n", ret); - break; + s_printf(0, y += Y_STEP, user_msgs[i].text); } + flip_fb(fd); + do_sleep: ts.tv_sec++; pthread_cond_timedwait(&g_cond, &mutex, &ts);