Fix minor bug causing 'dismiss' not to work
[herbe.git] / herbe.c
diff --git a/herbe.c b/herbe.c
index 503e6f26356af9986dcd697c47777534e99b71eb..270b9e973133a43cf06c4ef6d049c55a410f9ff2 100644 (file)
--- a/herbe.c
+++ b/herbe.c
@@ -6,11 +6,16 @@
 #include <unistd.h>
 #include <string.h>
 #include <stdarg.h>
+#include <fcntl.h>
+#include <semaphore.h>
 
 #include "config.h"
 
+#define EXIT_ACTION 3
+
 Display *display;
 Window window;
+int exit_code = EXIT_SUCCESS;
 
 static void die(const char *format, ...)
 {
@@ -24,23 +29,33 @@ static void die(const char *format, ...)
 
 int get_max_len(char *body, XftFont *font, int max_text_width)
 {
-       int body_len = strlen(body);
+       int eol = strlen(body);
        XGlyphInfo info;
-       XftTextExtentsUtf8(display, font, (FcChar8 *)body, body_len, &info);
+       XftTextExtentsUtf8(display, font, (FcChar8 *)body, eol, &info);
 
-       if (info.width < max_text_width)
-               return body_len;
+       if (info.width > max_text_width)
+       {
+               eol = max_text_width / font->max_advance_width;
+               info.width = 0;
 
-       int eol = max_text_width / font->max_advance_width;
-       info.width = 0;
+               while (info.width < max_text_width)
+               {
+                       eol++;
+                       XftTextExtentsUtf8(display, font, (FcChar8 *)body, eol, &info);
+               }
 
-       while (info.width < max_text_width)
-       {
-               eol++;
-               XftTextExtentsUtf8(display, font, (FcChar8 *)body, eol, &info);
+               eol--;
        }
 
-       eol--;
+       for (int i = 0; i < eol; i++)
+               if (body[i] == '\n')
+               {
+                       body[i] = ' ';
+                       return ++i;
+               }
+
+       if (info.width < max_text_width)
+               return eol;
 
        int temp = eol;
 
@@ -57,17 +72,27 @@ void expire()
 {
        XEvent event;
        event.type = ButtonPress;
+       event.xbutton.button = DISMISS_BUTTON;
        XSendEvent(display, window, 0, 0, &event);
        XFlush(display);
 }
 
+void action()
+{
+       exit_code = EXIT_ACTION;
+       expire();
+}
+
 int main(int argc, char *argv[])
 {
        if (argc == 1)
                die("Usage: %s body", argv[0]);
 
        signal(SIGALRM, expire);
-       alarm(duration);
+       signal(SIGTERM, expire);
+       signal(SIGINT, expire);
+       signal(SIGUSR1, SIG_IGN);
+       signal(SIGUSR2, SIG_IGN);
 
        display = XOpenDisplay(0);
 
@@ -140,6 +165,15 @@ int main(int argc, char *argv[])
 
        XMapWindow(display, window);
 
+       sem_t *mutex = sem_open("/herbe", O_CREAT, 0644, 1);
+       sem_wait(mutex);
+
+       signal(SIGUSR1, expire);
+       signal(SIGUSR2, action);
+
+       if (duration != 0)
+               alarm(duration);
+
        while (1)
        {
                XEvent event;
@@ -152,9 +186,20 @@ int main(int argc, char *argv[])
                                XftDrawStringUtf8(draw, &color, font, padding, line_spacing * i + text_height * (i + 1) + padding, (FcChar8 *)words[i], strlen(words[i]));
                }
                if (event.type == ButtonPress)
-                       break;
+               {
+                       if (event.xbutton.button == DISMISS_BUTTON)
+                               break;
+                       else if (event.xbutton.button == ACTION_BUTTON)
+                       {
+                               exit_code = EXIT_ACTION;
+                               break;
+                       }
+               }
        }
 
+       sem_post(mutex);
+       sem_close(mutex);
+
        for (int i = 0; i < num_of_lines; i++)
                free(words[i]);
 
@@ -164,5 +209,5 @@ int main(int argc, char *argv[])
        XftFontClose(display, font);
        XCloseDisplay(display);
 
-       exit(EXIT_SUCCESS);
-}
\ No newline at end of file
+       exit(exit_code);
+}