#include <stdarg.h>
#include <assert.h>
#include <poll.h>
+#include <unistd.h> /* gethostname() */
+#include <limits.h> /* HOST_NAME_MAX */
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
xcb_connection_t *conn;
key_handler_t *keys;
vlc_thread_t thread;
+
+ xcb_window_t root;
+ xcb_atom_t wm_state;
+ xcb_atom_t wm_state_above;
+ /*xcb_atom_t wmstate_fullscreen;*/
};
static inline
XA_STRING, 8, strlen (value), value);
}
+static inline
+void set_hostname_prop (xcb_connection_t *conn, xcb_window_t window)
+{
+ char hostname[HOST_NAME_MAX];
+
+ if (gethostname (hostname, sizeof (hostname)) == 0)
+ {
+ hostname[sizeof (hostname) - 1] = '\0';
+ set_ascii_prop (conn, window, XA_WM_CLIENT_MACHINE, hostname);
+ }
+}
+
+static
+xcb_atom_t get_atom (xcb_connection_t *conn, xcb_intern_atom_cookie_t ck)
+{
+ xcb_intern_atom_reply_t *reply;
+ xcb_atom_t atom;
+
+ reply = xcb_intern_atom_reply (conn, ck, NULL);
+ if (reply == NULL)
+ return 0;
+
+ atom = reply->atom;
+ free (reply);
+ return atom;
+}
+
/**
* Create an X11 window.
*/
goto error;
}
+ /* ICCCM
+ * No cut&paste nor drag&drop, only Window Manager communication. */
/* Plain ASCII localization of VLC for ICCCM window name */
set_ascii_prop (conn, window, XA_WM_NAME,
- pgettext ("ASCII VLC media player", "VLC media player"));
+ vlc_pgettext ("ASCII VLC media player", "VLC media player"));
set_ascii_prop (conn, window, XA_WM_ICON_NAME,
- pgettext ("ASCII VLC", "VLC"));
+ vlc_pgettext ("ASCII VLC", "VLC"));
+ xcb_change_property (conn, XCB_PROP_MODE_REPLACE, window, XA_WM_CLASS,
+ XA_STRING, 8, 8, "vlc\0Vlc");
+ set_hostname_prop (conn, window);
wnd->handle.xid = window;
wnd->p_sys = p_sys;
p_sys->conn = conn;
p_sys->keys = CreateKeyHandler (obj, conn);
+ p_sys->root = scr->root;
+
+ /* Cache any EWMH atom we may need later */
+ xcb_intern_atom_cookie_t wm_state_ck, wm_state_above_ck;
+ wm_state_ck = xcb_intern_atom (conn, 0, 13, "_NET_WM_STATE");
+ wm_state_above_ck = xcb_intern_atom (conn, 0, 18, "_NET_WM_STATE_ABOVE");
+
+ p_sys->wm_state = get_atom (conn, wm_state_ck);
+ p_sys->wm_state_above = get_atom (conn, wm_state_above_ck);
+
+ /* Create the event thread. It will dequeue all events, so any checked
+ * request from this thread must be completed at this point. */
if ((p_sys->keys != NULL)
&& vlc_clone (&p_sys->thread, Thread, wnd, VLC_THREAD_PRIORITY_LOW))
DestroyKeyHandler (p_sys->keys);
break;
}
+ case VOUT_SET_STAY_ON_TOP:
+ { /* From EWMH "_WM_STATE" */
+ xcb_client_message_event_t ev = {
+ .response_type = 0x80 | XCB_CLIENT_MESSAGE,
+ .format = 32,
+ .window = wnd->handle.xid,
+ .type = p_sys->wm_state,
+ };
+ bool on = va_arg (ap, int);
+
+ ev.data.data32[0] = on;
+ ev.data.data32[1] = p_sys->wm_state_above;
+ ev.data.data32[1] = 289;
+ ev.data.data32[3] = 1;
+
+ /* From ICCCM "Changing Window State" */
+ xcb_send_event (p_sys->conn, 0, p_sys->root,
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
+ (const char *)&ev);
+ xcb_flush (p_sys->conn);
+ return VLC_SUCCESS;
+ }
+
default:
msg_Err (wnd, "request %d not implemented", cmd);
return VLC_EGENERIC;