2 #include <X11/Xft/Xft.h>
13 int get_max_len(char *body
, XftFont
*font
, int max_text_width
)
15 int body_len
= strlen(body
);
17 XftTextExtentsUtf8(display
, font
, (FcChar8
*)body
, body_len
, &info
);
19 if (info
.width
< max_text_width
)
22 int eol
= max_text_width
/ font
->max_advance_width
;
25 while (info
.width
< max_text_width
)
28 XftTextExtentsUtf8(display
, font
, (FcChar8
*)body
, eol
, &info
);
35 while (body
[eol
] != ' ' && eol
)
47 event
.type
= ButtonPress
;
48 XSendEvent(display
, window
, 0, 0, &event
);
52 int main(int argc
, char *argv
[])
56 fprintf(stderr
, "Usage: herbe body\n");
60 signal(SIGALRM
, expire
);
63 display
= XOpenDisplay(NULL
);
67 fprintf(stderr
, "Cannot open display\n");
71 int screen
= DefaultScreen(display
);
72 Visual
*visual
= DefaultVisual(display
, screen
);
73 Colormap colormap
= DefaultColormap(display
, screen
);
75 int screen_width
= DisplayWidth(display
, screen
);
76 int screen_height
= DisplayHeight(display
, screen
);
80 XSetWindowAttributes attributes
;
81 attributes
.override_redirect
= True
;
82 XftColorAllocName(display
, visual
, colormap
, background_color
, &color
);
83 attributes
.background_pixel
= color
.pixel
;
84 XftColorAllocName(display
, visual
, colormap
, border_color
, &color
);
85 attributes
.border_pixel
= color
.pixel
;
87 XftFont
*font
= XftFontOpenName(display
, screen
, font_pattern
);
90 int max_text_width
= width
- 2 * padding
;
91 // TODO replace hard-coded size 100
92 char words
[100][max_text_width
/ font
->max_advance_width
+ 2];
94 for (int i
= 1; i
< argc
; i
++)
98 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
))
100 strncpy(words
[num_of_lines
], body
, eol
);
101 words
[num_of_lines
][eol
] = '\0';
105 unsigned int x
= pos_x
;
106 unsigned int y
= pos_y
;
107 unsigned int text_height
= font
->ascent
- font
->descent
;
108 unsigned int height
= (num_of_lines
- 1) * line_spacing
+ num_of_lines
* text_height
+ 2 * padding
;
110 if (corner
== TOP_RIGHT
|| corner
== BOTTOM_RIGHT
)
111 x
= screen_width
- width
- border_size
* 2 - pos_x
;
113 if (corner
== BOTTOM_LEFT
|| corner
== BOTTOM_RIGHT
)
114 y
= screen_height
- height
- border_size
* 2 - pos_y
;
116 window
= XCreateWindow(display
, RootWindow(display
, screen
), x
, y
, width
, height
, border_size
, DefaultDepth(display
, screen
), CopyFromParent
, visual
,
117 CWOverrideRedirect
| CWBackPixel
| CWBorderPixel
, &attributes
);
119 XftDraw
*draw
= XftDrawCreate(display
, window
, visual
, colormap
);
120 XftColorAllocName(display
, visual
, colormap
, font_color
, &color
);
122 XSelectInput(display
, window
, ExposureMask
| ButtonPress
);
124 XMapWindow(display
, window
);
130 XNextEvent(display
, &event
);
132 if (event
.type
== Expose
)
134 XClearWindow(display
, window
);
135 for (int i
= 0; i
< num_of_lines
; i
++)
136 XftDrawStringUtf8(draw
, &color
, font
, padding
, line_spacing
* i
+ text_height
* (i
+ 1) + padding
, (FcChar8
*)words
[i
], strlen(words
[i
]));
138 if (event
.type
== ButtonPress
)
142 XftDrawDestroy(draw
);
143 XftColorFree(display
, visual
, colormap
, &color
);
144 XftFontClose(display
, font
);
146 XCloseDisplay(display
);