13
#define MAX_SUPPORTED_XEMBED_VERSION 1
15
#define XEMBED_MAPPED (1 << 0)
18
#define XEMBED_EMBEDDED_NOTIFY 0
19
#define XEMBED_WINDOW_ACTIVATE 1
20
#define XEMBED_WINDOW_DEACTIVATE 2
21
#define XEMBED_REQUEST_FOCUS 3
22
#define XEMBED_FOCUS_IN 4
23
#define XEMBED_FOCUS_OUT 5
24
#define XEMBED_FOCUS_NEXT 6
25
#define XEMBED_FOCUS_PREV 7
26
/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
27
#define XEMBED_MODALITY_ON 10
28
#define XEMBED_MODALITY_OFF 11
29
#define XEMBED_REGISTER_ACCELERATOR 12
30
#define XEMBED_UNREGISTER_ACCELERATOR 13
31
#define XEMBED_ACTIVATE_ACCELERATOR 14
34
static int trapped_error_code = 0;
35
static int (*old_error_handler) (Display *d, XErrorEvent *e);
39
/* static void tray_map_window (Display* dpy, Window win); */
42
error_handler(Display *display,
45
trapped_error_code = error->error_code;
52
trapped_error_code = 0;
53
old_error_handler = XSetErrorHandler(error_handler);
59
XSetErrorHandler(old_error_handler);
60
return trapped_error_code;
64
tray_init(Display* dpy, tray_win_t* tray)
66
static char *atom_names[] = {
69
"_NET_SYSTEM_TRAY_OPCODE",
70
"_NET_SYSTEM_TRAY_ORIENTATION",
71
"_NET_SYSTEM_TRAY_VISUAL"
74
atom_names[0] = strdup("_NET_SYSTEM_TRAY_S0");
75
atom_names[0][17] += iScreen;
77
XInternAtoms (dpy, atom_names, 5, False, Atoms);
78
memset(&tray->visual, 0, sizeof(XVisualInfo));
84
tray_find_dock(Display *dpy, Window win)
90
Dock = XGetSelectionOwner(dpy, Atoms[ATOM_SELECTION]);
93
XSelectInput(dpy, RootWindow(dpy, DefaultScreen(dpy)),
100
tray_send_opcode(dpy, Dock, SYSTEM_TRAY_REQUEST_DOCK, win, 0, 0);
107
XVisualInfo* tray_get_visual(Display* dpy, tray_win_t* tray)
110
Dock = XGetSelectionOwner(dpy, Atoms[ATOM_SELECTION]);
115
unsigned long nitems, bytes_remaining;
116
unsigned char *data = 0;
117
int result = XGetWindowProperty(dpy, Dock, Atoms[ATOM_VISUAL], 0, 1,
118
False, XA_VISUALID, &actual_type,
119
&actual_format, &nitems, &bytes_remaining, &data);
121
if (result == Success && data && actual_type == XA_VISUALID && actual_format == 32 &&
122
nitems == 1 && bytes_remaining == 0)
123
vid = *(VisualID*)data;
129
uint mask = VisualIDMask;
130
XVisualInfo *vi, rvi;
133
vi = XGetVisualInfo(dpy, mask, &rvi, &count);
135
tray->visual = vi[0];
138
if (tray->visual.depth != 32)
139
memset(&tray->visual, 0, sizeof(XVisualInfo));
142
return tray->visual.visual ? &tray->visual : 0;
147
tray_handle_client_message(Display *dpy, Window win, XEvent *an_event)
149
if (an_event->xclient.message_type == Atoms[ATOM_XEMBED]) {
150
switch (an_event->xclient.data.l[1]) {
151
case XEMBED_EMBEDDED_NOTIFY:
152
case XEMBED_WINDOW_ACTIVATE:
153
tray_map_window (dpy, win);
158
if (an_event->xclient.message_type == Atoms[ATOM_MANAGER] && Dock == None) {
159
if (an_event->xclient.data.l[1] == Atoms[ATOM_SYSTEM_TRAY])
160
tray_find_dock(dpy, win);
165
void tray_send_opcode(Display* dpy, Window w,
166
long message, long data1, long data2, long data3)
170
memset(&ev, 0, sizeof(ev));
171
ev.xclient.type = ClientMessage;
172
ev.xclient.window = w;
173
ev.xclient.message_type = Atoms[ATOM_SYSTEM_TRAY_OPCODE];
174
ev.xclient.format = 32;
175
ev.xclient.data.l[0] = CurrentTime;
176
ev.xclient.data.l[1] = message;
177
ev.xclient.data.l[2] = data1;
178
ev.xclient.data.l[3] = data2;
179
ev.xclient.data.l[4] = data3;
182
XSendEvent(dpy, w, False, NoEventMask, &ev);
184
if (untrap_errors()) {
185
fprintf(stderr, "Tray.c : X error %i on opcode send\n",
186
trapped_error_code );
190
Window tray_get_dock(Display* dpy)
192
Window dock = XGetSelectionOwner(dpy, Atoms[ATOM_SELECTION]);