1
/* aosd -- OSD with transparency, cairo, and pango.
3
* Copyright (C) 2006 Evan Martin <martine@danga.com>
5
* With further development by Giacomo Lozito <james@develia.org>
6
* - added real transparency with X Composite Extension
7
* - added mouse event handling on OSD window
8
* - added/changed some other stuff
17
#include <X11/Xatom.h>
19
#ifdef HAVE_XCOMPOSITE
20
#include <X11/extensions/Xrender.h>
21
#include <X11/extensions/Xcomposite.h>
24
#include "aosd-internal.h"
27
make_window(Aosd* aosd)
29
Display* dsp = aosd->display;
30
Window root_win = aosd->root_win;
32
if (aosd->win != None)
34
if (aosd->background.set)
36
XFreePixmap(dsp, aosd->background.pixmap);
37
aosd->background.set = 0;
40
if (aosd->colormap != None)
42
XFreeColormap(dsp, aosd->colormap);
43
aosd->colormap = None;
46
XDestroyWindow(dsp, aosd->win);
53
XSetWindowAttributes att;
55
att.backing_store = WhenMapped;
56
att.background_pixel = 0x0;
58
att.background_pixmap = None;
60
att.save_under = True;
61
att.event_mask = ExposureMask | StructureNotifyMask | ButtonPressMask;
62
att.override_redirect = True;
64
if (aosd->mode == TRANSPARENCY_COMPOSITE)
66
#ifdef HAVE_XCOMPOSITE
67
Visual* visual = NULL;
68
if (composite_check_ext_and_mgr(dsp, aosd->screen_num) &&
69
(visual = composite_find_argb_visual(dsp, aosd->screen_num)) != NULL)
71
aosd->visual = visual;
72
aosd->colormap = att.colormap =
73
XCreateColormap(dsp, root_win, visual, AllocNone);
74
aosd->win = XCreateWindow(dsp, root_win,
75
-1, -1, 1, 1, 0, 32, InputOutput, visual,
76
CWBackingStore | CWBackPixel | CWBackPixmap | CWBorderPixel |
77
CWColormap | CWEventMask | CWSaveUnder | CWOverrideRedirect,
83
aosd->mode = TRANSPARENCY_FAKE;
90
aosd->win = XCreateWindow(dsp, root_win,
91
-1, -1, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent,
92
CWBackingStore | CWBackPixel | CWBackPixmap | CWBorderPixel |
93
CWEventMask | CWSaveUnder | CWOverrideRedirect, &att);
96
set_window_properties(dsp, aosd->win);
97
if (aosd->width && aosd->height)
98
aosd_set_geometry(aosd, aosd->x, aosd->y, aosd->width, aosd->height);
102
take_snapshot(Aosd* aosd)
104
Display* dsp = aosd->display;
105
Window root_win = aosd->root_win, win = aosd->win;
106
int width = aosd->width, height = aosd->height;
107
int scr = aosd->screen_num;
111
/* create a pixmap to hold the screenshot */
112
pixmap = XCreatePixmap(dsp, win, width, height, DefaultDepth(dsp, scr));
114
/* then copy the screen into the pixmap */
115
gc = XCreateGC(dsp, pixmap, 0, NULL);
116
XSetSubwindowMode(dsp, gc, IncludeInferiors);
117
XCopyArea(dsp, root_win, pixmap, gc, aosd->x, aosd->y, width, height, 0, 0);
118
XSetSubwindowMode(dsp, gc, ClipByChildren);
125
set_window_properties(Display* dsp, Window win)
127
/* we're almost a _NET_WM_WINDOW_TYPE_SPLASH, but we don't want
128
* to be centered on the screen. instead, manually request the
129
* behavior we want. */
131
/* turn off window decorations.
132
* we could pull this in from a motif header, but it's easier to
133
* use this snippet i found on a mailing list. */
134
Atom mwm_hints = XInternAtom(dsp, "_MOTIF_WM_HINTS", False);
137
long flags, functions, decorations, input_mode;
139
mwm_hints_setting = { (1L<<1), 0L, 0L, 0L };
141
XChangeProperty(dsp, win, mwm_hints, mwm_hints, 32,
142
PropModeReplace, (unsigned char *)&mwm_hints_setting, 4);
144
/* always on top, not in taskbar or pager. */
145
Atom win_state = XInternAtom(dsp, "_NET_WM_STATE", False);
146
Atom win_state_setting[] =
148
XInternAtom(dsp, "_NET_WM_STATE_ABOVE", False),
149
XInternAtom(dsp, "_NET_WM_STATE_SKIP_TASKBAR", False),
150
XInternAtom(dsp, "_NET_WM_STATE_SKIP_PAGER", False)
152
XChangeProperty(dsp, win, win_state, XA_ATOM, 32,
153
PropModeReplace, (unsigned char*)&win_state_setting, 3);
156
#ifdef HAVE_XCOMPOSITE
158
composite_check_ext_and_mgr(Display* dsp, int scr)
160
int event_base, error_base;
161
Atom comp_manager_atom;
162
char comp_manager_hint[32];
164
if (!XCompositeQueryExtension(dsp, &event_base, &error_base))
167
snprintf(comp_manager_hint, 32, "_NET_WM_CM_S%d", scr);
168
comp_manager_atom = XInternAtom(dsp, comp_manager_hint, False);
170
return (XGetSelectionOwner(dsp, comp_manager_atom) != None);
174
composite_find_argb_visual(Display* dsp, int scr)
177
XVisualInfo template;
179
XRenderPictFormat* format;
180
Visual* visual = NULL;
182
template.screen = scr;
184
template.class = TrueColor;
186
xvi = XGetVisualInfo(dsp,
187
VisualScreenMask | VisualDepthMask | VisualClassMask,
193
for (i = 0; i < nvi; i++)
195
format = XRenderFindVisualFormat(dsp, xvi[i].visual);
196
if (format->type == PictTypeDirect &&
197
format->direct.alphaMask)
199
visual = xvi[i].visual;
209
/* vim: set ts=2 sw=2 et : */