commands over unix socket
authornotaz <notasas@gmail.com>
Sun, 13 Jul 2014 18:39:59 +0000 (21:39 +0300)
committernotaz <notasas@gmail.com>
Sun, 13 Jul 2014 18:39:59 +0000 (21:39 +0300)
Makefile
custom.c [new file with mode: 0644]
main.c
readme.txt

index fe05688..7bae7b7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,11 +7,14 @@ LDLIBS += -lpthread -lrt
 
 OBJS = main.o fonts.o
 
-all: liveinfo
+all: liveinfo custom
 
 liveinfo: $(OBJS)
        $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
 
+custom: custom.c
+       $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
+
 clean:
        $(RM) liveinfo $(OBJS)
 
diff --git a/custom.c b/custom.c
new file mode 100644 (file)
index 0000000..728e831
--- /dev/null
+++ b/custom.c
@@ -0,0 +1,48 @@
+/*
+ * This file is licensed under the Creative Commons Zero License,
+ * version 1.0, available at
+ * http://creativecommons.org/publicdomain/zero/1.0/legalcode
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+/*
+ * example usage:
+ * ./custom "fps: 60"
+ */
+int main(int argc, char *argv[])
+{
+  static const char socket_name[] = "\0liveinfo";
+  struct sockaddr_un sun;
+  int sock;
+  int ret;
+
+  if (argv[1] == NULL) {
+    fprintf(stderr, "usage:\n%s \"label: value\"\n", argv[0]);
+    return 1;
+  }
+
+  sock = socket(PF_UNIX, SOCK_DGRAM, 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 = sendto(sock, argv[1], strlen(argv[1]), 0,
+    (struct sockaddr *)&sun, sizeof(sun));
+  if (ret < 0) {
+    perror("sendto");
+    return 1;
+  }
+
+  close(sock);
+  return 0;
+}
diff --git a/main.c b/main.c
index 75799b4..010f63c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -42,6 +42,7 @@ 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 IS_START(buf, str) \
   !strncmp(buf, str, sizeof(str) - 1)
 
@@ -218,6 +219,70 @@ static void handle_usr1(int num)
   pthread_cond_signal(&g_cond);
 }
 
+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;
+}
+
 #define s_printf(x, y, fmt, ...) \
   basic_text_out16(g_screen, WIDTH, x, y, fmt, ##__VA_ARGS__);
 
@@ -678,10 +743,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,11 +759,11 @@ 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;
   }
 
   fd = open(fbname, O_RDWR);
@@ -729,12 +794,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 +835,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 +863,9 @@ int main(int argc, char *argv[])
       is_hidden = 0;
     }
 
+    if (check_layer(fd) != 0)
+      break;
+
     collect_stats();
 
     y += Y_STEP;
@@ -823,18 +906,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);
index fbcacbd..acc9149 100644 (file)
@@ -44,6 +44,39 @@ Fields
  T:   23.2C  battery temperature
 
 
+Controlling live info
+---------------------
+
+It's possible to hide Live info by sending it USR1 signal and show it
+again by sending the same signal. This can be done by simply running
+"killall -USR1 liveinfo" command. This command can also be bound to
+xfce keyboard shortcuts or similar.
+Sending the TERM signal ("killall liveinfo") causes it to cleanly exit
+(sending it KILL / -9 signal will leave the layer enabled and visible,
+so is not recommended).
+
+
+Showing custom fields and alternative control
+---------------------------------------------
+
+There is a tool called 'custom' included inside of .pnd, it can be used
+to also send commands and display custom fields. The code is included
+inside the .pnd and can be integrated in other programs, it's simple
+communication over local/unix sockets.
+
+Any command containing a semicolon ":" is interpreted as a field to
+display on screen. For example, running
+./custom "fps: 60"
+will show that string on screen. There is no removal command, the
+string will time out by itself.
+
+Other understood commands are:
+  quit   - self explanatory
+  hide
+  show
+  poke   - if hidden, show up; if visible, exit
+
+
 License
 -------