2 #include <X11/Xft/Xft.h>
10 #include <semaphore.h>
18 int exit_code
= EXIT_SUCCESS
;
20 static void die(const char *format
, ...)
24 vfprintf(stderr
, format
, ap
);
25 fprintf(stderr
, "\n");
30 int get_max_len(char *body
, XftFont
*font
, int max_text_width
)
32 int eol
= strlen(body
);
34 XftTextExtentsUtf8(display
, font
, (FcChar8
*)body
, eol
, &info
);
36 if (info
.width
> max_text_width
)
38 eol
= max_text_width
/ font
->max_advance_width
;
41 while (info
.width
< max_text_width
)
44 XftTextExtentsUtf8(display
, font
, (FcChar8
*)body
, eol
, &info
);
50 for (int i
= 0; i
< eol
; i
++)
57 if (info
.width
< max_text_width
)
62 while (body
[eol
] != ' ' && eol
)
74 event
.type
= ButtonPress
;
75 event
.xbutton
.button
= DISMISS_BUTTON
;
76 XSendEvent(display
, window
, 0, 0, &event
);
82 exit_code
= EXIT_ACTION
;
86 int main(int argc
, char *argv
[])
91 die("Usage: %s body", argv
[0]);
94 signal(SIGALRM
, expire
);
95 signal(SIGTERM
, expire
);
96 signal(SIGINT
, expire
);
97 signal(SIGUSR1
, SIG_IGN
);
98 signal(SIGUSR2
, SIG_IGN
);
100 display
= XOpenDisplay(0);
103 die("Cannot open display");
105 int screen
= DefaultScreen(display
);
106 Visual
*visual
= DefaultVisual(display
, screen
);
107 Colormap colormap
= DefaultColormap(display
, screen
);
109 int screen_width
= DisplayWidth(display
, screen
);
110 int screen_height
= DisplayHeight(display
, screen
);
114 XSetWindowAttributes attributes
;
115 attributes
.override_redirect
= True
;
116 XftColorAllocName(display
, visual
, colormap
, background_color
, &color
);
117 attributes
.background_pixel
= color
.pixel
;
118 XftColorAllocName(display
, visual
, colormap
, border_color
, &color
);
119 attributes
.border_pixel
= color
.pixel
;
121 XftFont
*font
= XftFontOpenName(display
, screen
, font_pattern
);
123 int num_of_lines
= 0;
124 int max_text_width
= width
- 2 * padding
;
126 char **words
= malloc(words_size
* sizeof(char *));
128 die("malloc failed");
130 for (int i
= 1; i
< argc
; i
++)
132 char *body
= argv
[i
];
134 for (unsigned int eol
= get_max_len(body
, font
, max_text_width
); eol
<= strlen(body
) && eol
; body
+= eol
, num_of_lines
++, eol
= get_max_len(body
, font
, max_text_width
))
136 if (words_size
<= num_of_lines
)
138 words
= realloc(words
, (words_size
+= 5) * sizeof(char *));
140 die("malloc failed");
142 words
[num_of_lines
] = malloc((eol
+ 1) * sizeof(char));
143 if (!words
[num_of_lines
])
144 die("malloc failed");
145 strncpy(words
[num_of_lines
], body
, eol
);
146 words
[num_of_lines
][eol
] = '\0';
150 unsigned int x
= pos_x
;
151 unsigned int y
= pos_y
;
152 unsigned int text_height
= font
->ascent
- font
->descent
;
153 unsigned int height
= (num_of_lines
- 1) * line_spacing
+ num_of_lines
* text_height
+ 2 * padding
;
155 if (corner
== TOP_RIGHT
|| corner
== BOTTOM_RIGHT
)
156 x
= screen_width
- width
- border_size
* 2 - pos_x
;
158 if (corner
== BOTTOM_LEFT
|| corner
== BOTTOM_RIGHT
)
159 y
= screen_height
- height
- border_size
* 2 - pos_y
;
161 window
= XCreateWindow(display
, RootWindow(display
, screen
), x
, y
, width
, height
, border_size
, DefaultDepth(display
, screen
), CopyFromParent
, visual
,
162 CWOverrideRedirect
| CWBackPixel
| CWBorderPixel
, &attributes
);
164 XftDraw
*draw
= XftDrawCreate(display
, window
, visual
, colormap
);
165 XftColorAllocName(display
, visual
, colormap
, font_color
, &color
);
167 XSelectInput(display
, window
, ExposureMask
| ButtonPress
);
169 XMapWindow(display
, window
);
171 sem_t
*mutex
= sem_open("/herbe", O_CREAT
, 0644, 1);
174 signal(SIGUSR1
, expire
);
175 signal(SIGUSR2
, action
);
183 XNextEvent(display
, &event
);
185 if (event
.type
== Expose
)
187 XClearWindow(display
, window
);
188 for (int i
= 0; i
< num_of_lines
; i
++)
189 XftDrawStringUtf8(draw
, &color
, font
, padding
, line_spacing
* i
+ text_height
* (i
+ 1) + padding
, (FcChar8
*)words
[i
], strlen(words
[i
]));
191 if (event
.type
== ButtonPress
)
193 if (event
.xbutton
.button
== DISMISS_BUTTON
)
195 else if (event
.xbutton
.button
== ACTION_BUTTON
)
197 exit_code
= EXIT_ACTION
;
206 for (int i
= 0; i
< num_of_lines
; i
++)
210 XftDrawDestroy(draw
);
211 XftColorFree(display
, visual
, colormap
, &color
);
212 XftFontClose(display
, font
);
213 XCloseDisplay(display
);