-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
126 lines (106 loc) · 2.93 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xft/Xft.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#define LENGTH(X) (sizeof X / sizeof X[0])
typedef struct {
char *label;
char **command;
int size;
} Command;
#include "config.h"
Display *display;
Window w;
XEvent event;
XftDraw *xftdraw;
XRenderColor xrcolor;
XftColor xftcolor;
XftFont *xftfont = NULL;
XGlyphInfo extents;
int cmds_x[LENGTH(commands)] = { 0 };
int cmds_w[LENGTH(commands)] = { 0 };
int y;
int h;
XButtonEvent e;
char *status = NULL;
void handler(int _d)
{
wait(NULL);
}
void update_status(void)
{
XTextProperty prop;
if (status != NULL)
XFree(status);
status = NULL;
if (XGetWMName(display, DefaultRootWindow(display), &prop))
status = (char*) prop.value;
}
void render(void)
{
XClearWindow(display, w);
xftdraw = XftDrawCreate(display, w, DefaultVisual(display, 0), DefaultColormap(display, 0));
if (status != NULL)
XftDrawStringUtf8(xftdraw, &xftcolor, xftfont, PADDING, y, status, strlen(status));
for (int i = 0; i < LENGTH(commands); i++)
XftDrawStringUtf8(xftdraw, &xftcolor, xftfont, cmds_x[i], y + PADDING * 2 + h, commands[i].label, commands[i].size);
XftDrawDestroy(xftdraw);
}
int main()
{
signal(SIGCHLD, handler);
display = XOpenDisplay(0);
w = XCreateSimpleWindow(display, DefaultRootWindow(display), X, Y, WIDTH, HEIGHT, 0, 0, BACKGROUND);
XStoreName(display, w, "Window Waiting TO Be Usefull");
XSelectInput(display, w, ExposureMask | ButtonPressMask);
XSelectInput(display, DefaultRootWindow(display), PropertyChangeMask);
XMapWindow(display, w);
xftfont = XftFontOpenName(display, 0, font);
if (!xftfont)
return 1;
xrcolor.red = FG_RED;
xrcolor.green = FG_GREEN;
xrcolor.blue = FG_BLUE;
xrcolor.alpha = 0xffff;
XftColorAllocValue(display, DefaultVisual(display, 0), DefaultColormap(display, 0), &xrcolor, &xftcolor);
XftTextExtentsUtf8(display, xftfont, commands[0].label, commands[0].size, &extents);
cmds_x[0] = PADDING + extents.x;
cmds_w[0] = extents.width - extents.x;
y = PADDING + extents.y;
h = extents.height;
for (int i = 1; i < LENGTH(commands); i++) {
XftTextExtentsUtf8(display, xftfont, commands[i].label, commands[i].size, &extents);
cmds_x[i] = PADDING + extents.x + cmds_x[i - 1] + cmds_w[i - 1];
cmds_w[i] = extents.width - extents.x;
}
update_status();
for (;;) {
XNextEvent(display, &event);
switch (event.type) {
case PropertyNotify:
update_status();
case Expose:
render();
break;
case ButtonPress:
e = event.xbutton;
if (e.y > PADDING * 3 + h && e.y < PADDING * 4 + h * 2) {
for (int i = 0; i < LENGTH(commands); i++) {
if (e.x >= cmds_x[i] && e.x <= cmds_w[i] + cmds_x[i]) {
if (fork() == 0) {
execvp(commands[i].command[0], commands[i].command);
exit(1);
}
break;
}
}
}
break;
}
}
XFlush(display);
XftColorFree(display, DefaultVisual(display,0), DefaultColormap(display,0), &xftcolor);
return 0;
}