x11: don't cache X Atoms manually

XInternAtom() already caches lookups. Even if calling XInternAtom would
be always inefficient, it wouldn't matter much during normal playback.
This commit is contained in:
wm4 2014-05-16 23:17:09 +02:00
parent 7c2cf7cdf1
commit 9546274710
2 changed files with 45 additions and 108 deletions

View File

@ -132,6 +132,8 @@ static void vo_x11_selectinput_witherr(struct vo *vo, Display *display,
Window w, long event_mask); Window w, long event_mask);
static void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer); static void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer);
#define XA(x11, s) (XInternAtom((x11)->display, # s, False))
/* /*
* Sends the EWMH fullscreen state event. * Sends the EWMH fullscreen state event.
* *
@ -151,11 +153,11 @@ static void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action)
xev.xclient.type = ClientMessage; xev.xclient.type = ClientMessage;
xev.xclient.serial = 0; xev.xclient.serial = 0;
xev.xclient.send_event = True; xev.xclient.send_event = True;
xev.xclient.message_type = x11->XA_NET_WM_STATE; xev.xclient.message_type = XA(x11, _NET_WM_STATE);
xev.xclient.window = x11->window; xev.xclient.window = x11->window;
xev.xclient.format = 32; xev.xclient.format = 32;
xev.xclient.data.l[0] = action; xev.xclient.data.l[0] = action;
xev.xclient.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; xev.xclient.data.l[1] = XA(x11, _NET_WM_STATE_FULLSCREEN);
xev.xclient.data.l[2] = 0; xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0; xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0; xev.xclient.data.l[4] = 0;
@ -225,7 +227,7 @@ static int x11_errorhandler(Display *display, XErrorEvent *event)
static int net_wm_support_state_test(struct vo_x11_state *x11, Atom atom) static int net_wm_support_state_test(struct vo_x11_state *x11, Atom atom)
{ {
#define NET_WM_STATE_TEST(x) { \ #define NET_WM_STATE_TEST(x) { \
if (atom == x11->XA_NET_WM_STATE_##x) { \ if (atom == XA(x11, _NET_WM_STATE_##x)) { \
MP_VERBOSE(x11, "Detected wm supports " #x " state.\n" ); \ MP_VERBOSE(x11, "Detected wm supports " #x " state.\n" ); \
return vo_wm_##x; \ return vo_wm_##x; \
} \ } \
@ -264,16 +266,16 @@ static int vo_wm_detect(struct vo *vo)
return 0; return 0;
// -- supports layers // -- supports layers
if (x11_get_property(x11, win, x11->XA_WIN_PROTOCOLS, &args, &nitems)) { if (x11_get_property(x11, win, XA(x11, _WIN_PROTOCOLS), &args, &nitems)) {
MP_VERBOSE(x11, "Detected wm supports layers.\n"); MP_VERBOSE(x11, "Detected wm supports layers.\n");
for (i = 0; i < nitems; i++) { for (i = 0; i < nitems; i++) {
if (args[i] == x11->XA_WIN_LAYER) if (args[i] == XA(x11, _WIN_LAYER))
wm |= vo_wm_LAYER; wm |= vo_wm_LAYER;
} }
XFree(args); XFree(args);
} }
// --- netwm // --- netwm
if (x11_get_property(x11, win, x11->XA_NET_SUPPORTED, &args, &nitems)) { if (x11_get_property(x11, win, XA(x11, _NET_SUPPORTED), &args, &nitems)) {
MP_VERBOSE(x11, "Detected wm supports NetWM.\n"); MP_VERBOSE(x11, "Detected wm supports NetWM.\n");
if (vo->opts->x11_netwm) { if (vo->opts->x11_netwm) {
for (i = 0; i < nitems; i++) for (i = 0; i < nitems; i++)
@ -289,43 +291,6 @@ static int vo_wm_detect(struct vo *vo)
return wm; return wm;
} }
#define XA_INIT(x) x11->XA ## x = XInternAtom(x11->display, # x, False)
static void init_atoms(struct vo_x11_state *x11)
{
XA_INIT(_NET_SUPPORTED);
XA_INIT(_NET_WM_STATE);
XA_INIT(_NET_WM_STATE_FULLSCREEN);
XA_INIT(_NET_WM_STATE_ABOVE);
XA_INIT(_NET_WM_STATE_STAYS_ON_TOP);
XA_INIT(_NET_WM_STATE_BELOW);
XA_INIT(_NET_WM_PID);
XA_INIT(_NET_WM_NAME);
XA_INIT(_NET_WM_ICON_NAME);
XA_INIT(_NET_WM_ICON);
XA_INIT(_NET_WM_MOVERESIZE);
XA_INIT(_WIN_PROTOCOLS);
XA_INIT(_WIN_LAYER);
XA_INIT(_WIN_HINTS);
XA_INIT(WM_PROTOCOLS);
XA_INIT(WM_DELETE_WINDOW);
XA_INIT(UTF8_STRING);
XA_INIT(TARGETS);
XA_INIT(XdndAware);
XA_INIT(XdndEnter);
XA_INIT(XdndLeave);
XA_INIT(XdndPosition);
XA_INIT(XdndStatus);
XA_INIT(XdndActionCopy);
XA_INIT(XdndTypeList);
XA_INIT(XdndDrop);
XA_INIT(XdndSelection);
XA_INIT(XdndFinished);
char buf[50];
sprintf(buf, "_NET_WM_CM_S%d", x11->screen);
x11->XA_NET_WM_CM = XInternAtom(x11->display, buf, False);
x11->XA_uri_list = XInternAtom(x11->display, "text/uri-list", False);
}
static void vo_x11_update_screeninfo(struct vo *vo) static void vo_x11_update_screeninfo(struct vo *vo)
{ {
struct mp_vo_opts *opts = vo->opts; struct mp_vo_opts *opts = vo->opts;
@ -417,8 +382,6 @@ int vo_x11_init(struct vo *vo)
if (!x11->xim) if (!x11->xim)
MP_WARN(x11, "XOpenIM() failed. Unicode input will not work.\n"); MP_WARN(x11, "XOpenIM() failed. Unicode input will not work.\n");
init_atoms(vo->x11);
x11->ws_width = DisplayWidth(x11->display, x11->screen); x11->ws_width = DisplayWidth(x11->display, x11->screen);
x11->ws_height = DisplayHeight(x11->display, x11->screen); x11->ws_height = DisplayHeight(x11->display, x11->screen);
@ -565,7 +528,7 @@ static void vo_x11_classhint(struct vo *vo, Window window, const char *name)
wmClass.res_name = opts->winname ? opts->winname : (char *)name; wmClass.res_name = opts->winname ? opts->winname : (char *)name;
wmClass.res_class = "mpv"; wmClass.res_class = "mpv";
XSetClassHint(x11->display, window, &wmClass); XSetClassHint(x11->display, window, &wmClass);
XChangeProperty(x11->display, window, x11->XA_NET_WM_PID, XA_CARDINAL, XChangeProperty(x11->display, window, XA(x11, _NET_WM_PID), XA_CARDINAL,
32, PropModeReplace, (unsigned char *) &pid, 1); 32, PropModeReplace, (unsigned char *) &pid, 1);
} }
@ -617,7 +580,7 @@ static void vo_x11_dnd_init_window(struct vo *vo)
struct vo_x11_state *x11 = vo->x11; struct vo_x11_state *x11 = vo->x11;
Atom version = DND_VERSION; Atom version = DND_VERSION;
XChangeProperty(x11->display, x11->window, x11->XAXdndAware, XA_ATOM, XChangeProperty(x11->display, x11->window, XA(x11, XdndAware), XA_ATOM,
32, PropModeReplace, (unsigned char *)&version, 1); 32, PropModeReplace, (unsigned char *)&version, 1);
x11->dnd_property = XInternAtom(x11->display, "mpv_dnd_selection", False); x11->dnd_property = XInternAtom(x11->display, "mpv_dnd_selection", False);
@ -627,7 +590,7 @@ static void dnd_select_format(struct vo_x11_state *x11, Atom *args, int items)
{ {
for (int n = 0; n < items; n++) { for (int n = 0; n < items; n++) {
// There are other types; possibly not worth supporting. // There are other types; possibly not worth supporting.
if (args[n] == x11->XA_uri_list) if (args[n] == XA(x11, _uri_list))
x11->dnd_requested_format = args[n]; x11->dnd_requested_format = args[n];
} }
} }
@ -647,14 +610,15 @@ static void vo_x11_dnd_handle_message(struct vo *vo, XClientMessageEvent *ce)
if (!x11->window) if (!x11->window)
return; return;
if (ce->message_type == x11->XAXdndEnter) { if (ce->message_type == XA(x11, XdndEnter)) {
x11->dnd_requested_format = 0; x11->dnd_requested_format = 0;
Window src = ce->data.l[0]; Window src = ce->data.l[0];
if (ce->data.l[1] & 1) { if (ce->data.l[1] & 1) {
unsigned long nitems = 0; unsigned long nitems = 0;
Atom *args = NULL; Atom *args = NULL;
if (x11_get_property(x11, src, x11->XAXdndTypeList, &args, &nitems)) { if (x11_get_property(x11, src, XA(x11, XdndTypeList), &args, &nitems))
{
dnd_select_format(x11, args, nitems); dnd_select_format(x11, args, nitems);
XFree(args); XFree(args);
} }
@ -664,29 +628,29 @@ static void vo_x11_dnd_handle_message(struct vo *vo, XClientMessageEvent *ce)
args[n - 2] = ce->data.l[n]; args[n - 2] = ce->data.l[n];
dnd_select_format(x11, args, 3); dnd_select_format(x11, args, 3);
} }
} else if (ce->message_type == x11->XAXdndPosition) { } else if (ce->message_type == XA(x11, XdndPosition)) {
Window src = ce->data.l[0]; Window src = ce->data.l[0];
XEvent xev; XEvent xev;
xev.xclient.type = ClientMessage; xev.xclient.type = ClientMessage;
xev.xclient.serial = 0; xev.xclient.serial = 0;
xev.xclient.send_event = True; xev.xclient.send_event = True;
xev.xclient.message_type = x11->XAXdndStatus; xev.xclient.message_type = XA(x11, XdndStatus);
xev.xclient.window = src; xev.xclient.window = src;
xev.xclient.format = 32; xev.xclient.format = 32;
xev.xclient.data.l[0] = x11->window; xev.xclient.data.l[0] = x11->window;
xev.xclient.data.l[1] = x11->dnd_requested_format ? 1 : 0; xev.xclient.data.l[1] = x11->dnd_requested_format ? 1 : 0;
xev.xclient.data.l[2] = 0; xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0; xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = x11->XAXdndActionCopy; xev.xclient.data.l[4] = XA(x11, XdndActionCopy);
XSendEvent(x11->display, src, False, 0, &xev); XSendEvent(x11->display, src, False, 0, &xev);
} else if (ce->message_type == x11->XAXdndDrop) { } else if (ce->message_type == XA(x11, XdndDrop)) {
x11->dnd_src_window = ce->data.l[0]; x11->dnd_src_window = ce->data.l[0];
XConvertSelection(x11->display, x11->XAXdndSelection, XConvertSelection(x11->display, XA(x11, XdndSelection),
x11->dnd_requested_format, x11->dnd_property, x11->dnd_requested_format, x11->dnd_property,
x11->window, ce->data.l[2]); x11->window, ce->data.l[2]);
} else if (ce->message_type == x11->XAXdndLeave) { } else if (ce->message_type == XA(x11, XdndLeave)) {
dnd_reset(vo); dnd_reset(vo);
} }
} }
@ -700,7 +664,7 @@ static void vo_x11_dnd_handle_selection(struct vo *vo, XSelectionEvent *se)
bool success = false; bool success = false;
if (se->selection == x11->XAXdndSelection && if (se->selection == XA(x11, XdndSelection) &&
se->property == x11->dnd_property && se->property == x11->dnd_property &&
se->target == x11->dnd_requested_format) se->target == x11->dnd_requested_format)
{ {
@ -729,12 +693,12 @@ static void vo_x11_dnd_handle_selection(struct vo *vo, XSelectionEvent *se)
xev.xclient.type = ClientMessage; xev.xclient.type = ClientMessage;
xev.xclient.serial = 0; xev.xclient.serial = 0;
xev.xclient.send_event = True; xev.xclient.send_event = True;
xev.xclient.message_type = x11->XAXdndFinished; xev.xclient.message_type = XA(x11, XdndFinished);
xev.xclient.window = x11->dnd_src_window; xev.xclient.window = x11->dnd_src_window;
xev.xclient.format = 32; xev.xclient.format = 32;
xev.xclient.data.l[0] = x11->window; xev.xclient.data.l[0] = x11->window;
xev.xclient.data.l[1] = success ? 1 : 0; xev.xclient.data.l[1] = success ? 1 : 0;
xev.xclient.data.l[2] = success ? x11->XAXdndActionCopy : 0; xev.xclient.data.l[2] = success ? XA(x11, XdndActionCopy) : 0;
xev.xclient.data.l[3] = 0; xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0; xev.xclient.data.l[4] = 0;
@ -837,7 +801,7 @@ int vo_x11_check_events(struct vo *vo)
xev.xclient.type = ClientMessage; xev.xclient.type = ClientMessage;
xev.xclient.serial = 0; xev.xclient.serial = 0;
xev.xclient.send_event = True; xev.xclient.send_event = True;
xev.xclient.message_type = x11->XA_NET_WM_MOVERESIZE; xev.xclient.message_type = XA(x11, _NET_WM_MOVERESIZE);
xev.xclient.window = x11->window; xev.xclient.window = x11->window;
xev.xclient.format = 32; xev.xclient.format = 32;
xev.xclient.data.l[0] = Event.xmotion.x_root; xev.xclient.data.l[0] = Event.xmotion.x_root;
@ -884,8 +848,8 @@ int vo_x11_check_events(struct vo *vo)
mp_input_put_key(vo->input_ctx, MP_KEY_CLOSE_WIN); mp_input_put_key(vo->input_ctx, MP_KEY_CLOSE_WIN);
break; break;
case ClientMessage: case ClientMessage:
if (Event.xclient.message_type == x11->XAWM_PROTOCOLS && if (Event.xclient.message_type == XA(x11, WM_PROTOCOLS) &&
Event.xclient.data.l[0] == x11->XAWM_DELETE_WINDOW) Event.xclient.data.l[0] == XA(x11, WM_DELETE_WINDOW))
mp_input_put_key(vo->input_ctx, MP_KEY_CLOSE_WIN); mp_input_put_key(vo->input_ctx, MP_KEY_CLOSE_WIN);
vo_x11_dnd_handle_message(vo, &Event.xclient); vo_x11_dnd_handle_message(vo, &Event.xclient);
break; break;
@ -975,7 +939,7 @@ static int vo_x11_get_gnome_layer(struct vo_x11_state *x11, Window win)
unsigned long bytesafter; unsigned long bytesafter;
unsigned short *args = NULL; unsigned short *args = NULL;
if (XGetWindowProperty(x11->display, win, x11->XA_WIN_LAYER, 0, 16384, if (XGetWindowProperty(x11->display, win, XA(x11, _WIN_LAYER), 0, 16384,
False, AnyPropertyType, &type, &format, &nitems, False, AnyPropertyType, &type, &format, &nitems,
&bytesafter, &bytesafter,
(unsigned char **) &args) == Success (unsigned char **) &args) == Success
@ -992,7 +956,7 @@ static void vo_x11_set_property_utf8(struct vo *vo, Atom name, const char *t)
{ {
struct vo_x11_state *x11 = vo->x11; struct vo_x11_state *x11 = vo->x11;
XChangeProperty(x11->display, x11->window, name, x11->XAUTF8_STRING, 8, XChangeProperty(x11->display, x11->window, name, XA(x11, UTF8_STRING), 8,
PropModeReplace, t, strlen(t)); PropModeReplace, t, strlen(t));
} }
@ -1026,8 +990,8 @@ static void vo_x11_update_window_title(struct vo *vo)
const char *title = vo_get_window_title(vo); const char *title = vo_get_window_title(vo);
vo_x11_set_property_string(vo, XA_WM_NAME, title); vo_x11_set_property_string(vo, XA_WM_NAME, title);
vo_x11_set_property_string(vo, XA_WM_ICON_NAME, title); vo_x11_set_property_string(vo, XA_WM_ICON_NAME, title);
vo_x11_set_property_utf8(vo, x11->XA_NET_WM_NAME, title); vo_x11_set_property_utf8(vo, XA(x11, _NET_WM_NAME), title);
vo_x11_set_property_utf8(vo, x11->XA_NET_WM_ICON_NAME, title); vo_x11_set_property_utf8(vo, XA(x11, _NET_WM_ICON_NAME), title);
} }
#if HAVE_ZLIB #if HAVE_ZLIB
@ -1118,7 +1082,7 @@ static void vo_x11_set_wm_icon(struct vo_x11_state *x11)
*cur++ = s[0] | (s[1] << 8) | (s[2] << 16) | ((unsigned)s[3] << 24); *cur++ = s[0] | (s[1] << 8) | (s[2] << 16) | ((unsigned)s[3] << 24);
} }
XChangeProperty(x11->display, x11->window, x11->XA_NET_WM_ICON, XChangeProperty(x11->display, x11->window, XA(x11, _NET_WM_ICON),
XA_CARDINAL, 32, PropModeReplace, XA_CARDINAL, 32, PropModeReplace,
(unsigned char *)icon, icon_size); (unsigned char *)icon, icon_size);
talloc_free(icon); talloc_free(icon);
@ -1157,7 +1121,8 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y,
x11->window = x11->window =
XCreateWindow(x11->display, parent, x, y, w, h, 0, vis->depth, XCreateWindow(x11->display, parent, x, y, w, h, 0, vis->depth,
CopyFromParent, vis->visual, xswamask, &xswa); CopyFromParent, vis->visual, xswamask, &xswa);
XSetWMProtocols(x11->display, x11->window, &x11->XAWM_DELETE_WINDOW, 1); Atom protos[1] = {XA(x11, WM_DELETE_WINDOW)};
XSetWMProtocols(x11->display, x11->window, protos, 1);
x11->f_gc = XCreateGC(x11->display, x11->window, 0, 0); x11->f_gc = XCreateGC(x11->display, x11->window, 0, 0);
x11->vo_gc = XCreateGC(x11->display, x11->window, 0, NULL); x11->vo_gc = XCreateGC(x11->display, x11->window, 0, NULL);
XSetForeground(x11->display, x11->f_gc, 0); XSetForeground(x11->display, x11->f_gc, 0);
@ -1188,8 +1153,8 @@ static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h)
vo_x11_decoration(vo, 0); vo_x11_decoration(vo, 0);
if (vo->opts->fullscreen && (x11->wm_type & vo_wm_FULLSCREEN)) { if (vo->opts->fullscreen && (x11->wm_type & vo_wm_FULLSCREEN)) {
Atom state = x11->XA_NET_WM_STATE_FULLSCREEN; Atom state = XA(x11, _NET_WM_STATE_FULLSCREEN);
XChangeProperty(x11->display, x11->window, x11->XA_NET_WM_STATE, XA_ATOM, XChangeProperty(x11->display, x11->window, XA(x11, _NET_WM_STATE), XA_ATOM,
32, PropModeAppend, (unsigned char *)&state, 1); 32, PropModeAppend, (unsigned char *)&state, 1);
x11->fs = 1; x11->fs = 1;
// The "saved" positions are bogus, so reset them when leaving FS again. // The "saved" positions are bogus, so reset them when leaving FS again.
@ -1375,7 +1340,7 @@ static void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer)
xev.type = ClientMessage; xev.type = ClientMessage;
xev.display = x11->display; xev.display = x11->display;
xev.window = vo_window; xev.window = vo_window;
xev.message_type = x11->XA_WIN_LAYER; xev.message_type = XA(x11, _WIN_LAYER);
xev.format = 32; xev.format = 32;
// if not fullscreen, stay on default layer // if not fullscreen, stay on default layer
xev.data.l[0] = layer ? WIN_LAYER_ABOVE_DOCK : x11->orig_layer; xev.data.l[0] = layer ? WIN_LAYER_ABOVE_DOCK : x11->orig_layer;
@ -1390,22 +1355,22 @@ static void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer)
memset(&xev, 0, sizeof(xev)); memset(&xev, 0, sizeof(xev));
xev.type = ClientMessage; xev.type = ClientMessage;
xev.message_type = x11->XA_NET_WM_STATE; xev.message_type = XA(x11, _NET_WM_STATE);
xev.display = x11->display; xev.display = x11->display;
xev.window = vo_window; xev.window = vo_window;
xev.format = 32; xev.format = 32;
xev.data.l[0] = layer; xev.data.l[0] = layer;
if (x11->wm_type & vo_wm_STAYS_ON_TOP) { if (x11->wm_type & vo_wm_STAYS_ON_TOP) {
xev.data.l[1] = x11->XA_NET_WM_STATE_STAYS_ON_TOP; xev.data.l[1] = XA(x11, _NET_WM_STATE_STAYS_ON_TOP);
} else if (x11->wm_type & vo_wm_ABOVE) { } else if (x11->wm_type & vo_wm_ABOVE) {
xev.data.l[1] = x11->XA_NET_WM_STATE_ABOVE; xev.data.l[1] = XA(x11, _NET_WM_STATE_ABOVE);
} else if (x11->wm_type & vo_wm_FULLSCREEN) { } else if (x11->wm_type & vo_wm_FULLSCREEN) {
xev.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; xev.data.l[1] = XA(x11, _NET_WM_STATE_FULLSCREEN);
} else if (x11->wm_type & vo_wm_BELOW) { } else if (x11->wm_type & vo_wm_BELOW) {
// This is not fallback. We can safely assume that the situation // This is not fallback. We can safely assume that the situation
// where only NETWM_STATE_BELOW is supported doesn't exist. // where only NETWM_STATE_BELOW is supported doesn't exist.
xev.data.l[1] = x11->XA_NET_WM_STATE_BELOW; xev.data.l[1] = XA(x11, _NET_WM_STATE_BELOW);
} }
XSendEvent(x11->display, x11->rootwin, False, SubstructureRedirectMask, XSendEvent(x11->display, x11->rootwin, False, SubstructureRedirectMask,
@ -1736,5 +1701,8 @@ double vo_x11_vm_get_fps(struct vo *vo)
bool vo_x11_screen_is_composited(struct vo *vo) bool vo_x11_screen_is_composited(struct vo *vo)
{ {
struct vo_x11_state *x11 = vo->x11; struct vo_x11_state *x11 = vo->x11;
return XGetSelectionOwner(x11->display, x11->XA_NET_WM_CM) != None; char buf[50];
sprintf(buf, "_NET_WM_CM_S%d", x11->screen);
Atom _NET_WM_CM = XInternAtom(x11->display, buf, False);
return XGetSelectionOwner(x11->display, _NET_WM_CM) != None;
} }

View File

@ -111,37 +111,6 @@ struct vo_x11_state {
/* dragging the window */ /* dragging the window */
bool win_drag_button1_down; bool win_drag_button1_down;
Atom XA_NET_SUPPORTED;
Atom XA_NET_WM_STATE;
Atom XA_NET_WM_STATE_FULLSCREEN;
Atom XA_NET_WM_STATE_ABOVE;
Atom XA_NET_WM_STATE_STAYS_ON_TOP;
Atom XA_NET_WM_STATE_BELOW;
Atom XA_NET_WM_PID;
Atom XA_NET_WM_NAME;
Atom XA_NET_WM_ICON_NAME;
Atom XA_NET_WM_ICON;
Atom XA_NET_WM_MOVERESIZE;
Atom XA_WIN_PROTOCOLS;
Atom XA_WIN_LAYER;
Atom XA_WIN_HINTS;
Atom XAWM_PROTOCOLS;
Atom XAWM_DELETE_WINDOW;
Atom XAUTF8_STRING;
Atom XA_NET_WM_CM;
Atom XATARGETS;
Atom XAXdndAware;
Atom XAXdndEnter;
Atom XAXdndLeave;
Atom XAXdndPosition;
Atom XAXdndStatus;
Atom XAXdndActionCopy;
Atom XAXdndTypeList;
Atom XAXdndDrop;
Atom XAXdndSelection;
Atom XAXdndFinished;
Atom XA_uri_list;
}; };
int vo_x11_init(struct vo *vo); int vo_x11_init(struct vo *vo);