summaryrefslogtreecommitdiffstats
path: root/client/x11/red_window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client/x11/red_window.cpp')
-rw-r--r--client/x11/red_window.cpp158
1 files changed, 137 insertions, 21 deletions
diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp
index 5a0886ac..e7b68151 100644
--- a/client/x11/red_window.cpp
+++ b/client/x11/red_window.cpp
@@ -309,13 +309,17 @@ enum KbdKeyCode {
static void query_keyboard()
{
+ XLockDisplay(x_display);
XkbDescPtr kbd_desk = XkbGetKeyboard(x_display, XkbAllComponentsMask, XkbUseCoreKbd);
+ XUnlockDisplay(x_display);
if (!kbd_desk) {
LOG_WARN("get keyboard failed");
return;
}
+ XLockDisplay(x_display);
char* keycodes = XGetAtomName(x_display, kbd_desk->names->keycodes);
+ XUnlockDisplay(x_display);
if (keycodes) {
if (strstr(keycodes, "evdev")) {
@@ -642,7 +646,9 @@ static void init_key_table_0xfe()
static inline RedKey to_red_key_code(unsigned int keycode)
{
+ XLockDisplay(x_display);
KeySym sym = XKeycodeToKeysym(x_display, keycode, 0);
+ XUnlockDisplay(x_display);
RedKey red_key;
if (sym == NoSymbol) {
@@ -772,8 +778,12 @@ void RedWindow_p::win_proc(XEvent& event)
{
XPointer window_pointer;
RedWindow* red_window;
+ int res;
- if (XFindContext(x_display, event.xany.window, user_data_context, &window_pointer)) {
+ XLockDisplay(x_display);
+ res = XFindContext(x_display, event.xany.window, user_data_context, &window_pointer);
+ XUnlockDisplay(x_display);
+ if (res) {
THROW("no user data");
}
red_window = (RedWindow*)window_pointer;
@@ -795,7 +805,10 @@ void RedWindow_p::win_proc(XEvent& event)
case KeyRelease: {
RedKey key = to_red_key_code(event.xkey.keycode);
XEvent next_event;
- if (XCheckWindowEvent(x_display, red_window->_win, ~long(0), &next_event)) {
+ XLockDisplay(x_display);
+ Bool check = XCheckWindowEvent(x_display, red_window->_win, ~long(0), &next_event);
+ XUnlockDisplay(x_display);
+ if (check) {
XPutBackEvent(x_display, &next_event);
if ((next_event.type == KeyPress) &&
(event.xkey.keycode == next_event.xkey.keycode) &&
@@ -921,6 +934,8 @@ void RedWindow_p::win_proc(XEvent& event)
void RedWindow_p::sync(bool shadowed)
{
+ XEvent event;
+
if (shadowed) {
_ignore_foucs = true;
_ignore_pointer = true;
@@ -928,11 +943,16 @@ void RedWindow_p::sync(bool shadowed)
_shadow_pointer_state = _pointer_in_window;
_shadow_focus_event.xany.serial = 0;
}
+
+ XLockDisplay(x_display);
XSync(x_display, False);
- XEvent event;
while (XCheckWindowEvent(x_display, _win, ~long(0), &event)) {
+ XUnlockDisplay(x_display);
win_proc(event);
+ XLockDisplay(x_display);
}
+ XUnlockDisplay(x_display);
+
if (!shadowed) {
return;
}
@@ -954,11 +974,17 @@ void RedWindow_p::wait_for_reparent()
{
XEvent event;
for (int i = 0; i < 50; i++) {
- if (XCheckTypedWindowEvent(x_display, _win, ReparentNotify, &event)) {
+ XLockDisplay(x_display);
+ bool check = XCheckTypedWindowEvent(x_display, _win, ReparentNotify, &event);
+ XUnlockDisplay(x_display);
+ if (check) {
return;
}
usleep(20 * 1000);
+ // HDG: why?? this makes no sense
+ XLockDisplay(x_display);
XSync(x_display, False);
+ XUnlockDisplay(x_display);
}
DBG(0, "failed");
}
@@ -968,7 +994,9 @@ void RedWindow_p::wait_for_map()
bool wait_parent = _expect_parent;
while (!_visibale) {
XEvent event;
+ XLockDisplay(x_display);
XWindowEvent(x_display, _win, ~0, &event);
+ XUnlockDisplay(x_display);
switch (event.type) {
case ReparentNotify:
wait_parent = false;
@@ -993,7 +1021,9 @@ void RedWindow_p::wait_for_unmap()
bool wait_parent = _expect_parent;
while (_visibale) {
XEvent event;
+ XLockDisplay(x_display);
XWindowEvent(x_display, _win, ~0, &event);
+ XUnlockDisplay(x_display);
switch (event.type) {
case ReparentNotify:
wait_parent = false;
@@ -1015,7 +1045,9 @@ void RedWindow_p::wait_for_unmap()
void RedWindow_p::set_glx(int width, int height)
{
if (_glcont_copy) {
+ XLockDisplay(x_display);
XSync(x_display, False);
+ XUnlockDisplay(x_display);
glXMakeCurrent(x_display, _win, _glcont_copy);
//glDrawBuffer(GL_FRONT);
glMatrixMode(GL_PROJECTION);
@@ -1050,8 +1082,10 @@ Cursor RedWindow_p::create_invisible_cursor(Window window)
XColor color;
char data[1] = {0};
Window root_window = RootWindow(x_display, DefaultScreen(x_display));
+ XLockDisplay(x_display);
Pixmap blank = XCreateBitmapFromData(x_display, root_window, data, 1, 1);
Cursor cursor = XCreatePixmapCursor(x_display, blank, blank, &color, &color, 0, 0);
+ XUnlockDisplay(x_display);
XFreePixmap(x_display, blank);
return cursor;
}
@@ -1071,6 +1105,8 @@ RedWindow_p::RedWindow_p()
void RedWindow_p::destroy(RedWindow& red_window, PixelsSource_p& pix_source)
{
+ XEvent event;
+
if (_win == None) {
return;
}
@@ -1082,9 +1118,12 @@ void RedWindow_p::destroy(RedWindow& red_window, PixelsSource_p& pix_source)
XPlatform::cleare_win_proc(_win);
XSelectInput(x_display, _win, 0);
+
+ XLockDisplay(x_display);
XSync(x_display, False);
- XEvent event;
while (XCheckWindowEvent(x_display, _win, ~long(0), &event));
+ XUnlockDisplay(x_display);
+
Window window = _win;
_win = None;
XFreeCursor(x_display, _invisible_cursor);
@@ -1123,6 +1162,7 @@ void RedWindow_p::create(RedWindow& red_window, PixelsSource_p& pix_source, int
ButtonReleaseMask | PointerMotionMask | FocusChangeMask |
EnterWindowMask | LeaveWindowMask;
+ XLockDisplay(x_display);
_colormap = XCreateColormap(x_display, root_window, XPlatform::get_vinfo()[in_screen]->visual,
AllocNone);
win_attributes.colormap = _colormap;
@@ -1131,22 +1171,34 @@ void RedWindow_p::create(RedWindow& red_window, PixelsSource_p& pix_source, int
width, height, 0, XPlatform::get_vinfo()[in_screen]->depth,
InputOutput, XPlatform::get_vinfo()[in_screen]->visual, mask,
&win_attributes);
+ XUnlockDisplay(x_display);
if (!window) {
THROW("create X window failed");
}
try {
- if (XSaveContext(x_display, window, user_data_context, (XPointer)&red_window)) {
+ int res;
+
+ XLockDisplay(x_display);
+ res = XSaveContext(x_display, window, user_data_context, (XPointer)&red_window);
+ XUnlockDisplay(x_display);
+ if (res) {
THROW("set win usr data failed");
}
XSetWMProtocols(x_display, window, &wm_delete_window_atom, 1);
XGCValues gc_vals;
- if (!(gc = XCreateGC(x_display, window, 0, &gc_vals))) {
+
+ XLockDisplay(x_display);
+ gc = XCreateGC(x_display, window, 0, &gc_vals);
+ XUnlockDisplay(x_display);
+ if (!gc) {
THROW("create gc failed");
}
- if (!(cursor = create_invisible_cursor(window))) {
+
+ cursor = create_invisible_cursor(window);
+ if (!cursor) {
THROW("create invisible cursor failed");
}
@@ -1189,7 +1241,9 @@ void RedWindow_p::migrate(RedWindow& red_window, PixelsSource_p& pix_source, int
THROW("get attributes failed");
}
XTextProperty text_pro;
+ XLockDisplay(x_display);
bool valid_title = XGetWMName(x_display, _win, &text_pro) && text_pro.value;
+ XUnlockDisplay(x_display);
destroy(red_window, pix_source);
create(red_window, pix_source, _show_pos.x, _show_pos.y, attrib.width, attrib.height,
to_screen);
@@ -1213,6 +1267,7 @@ void RedWindow_p::move_to_current_desktop()
unsigned char *prop_return;
long desktop = ~long(0);
+ XLockDisplay(x_display);
if (XGetWindowProperty(x_display, root, wm_current_desktop, 0, 1, False, AnyPropertyType,
&actual_type_return, &actual_format_return, &nitems_return,
&bytes_after_return, &prop_return) == Success &&
@@ -1221,6 +1276,7 @@ void RedWindow_p::move_to_current_desktop()
} else {
DBG(0, "get current desktop failed");
}
+ XUnlockDisplay(x_display);
XEvent xevent;
xevent.type = ClientMessage;
@@ -1266,7 +1322,9 @@ void RedWindow::set_title(std::wstring& title)
wchar_t *name = const_cast<wchar_t *>(title.c_str());
int r;
if (_win) {
+ XLockDisplay(x_display);
r = XwcTextListToTextProperty(x_display, &name, 1, XStringStyle, &text_prop);
+ XUnlockDisplay(x_display);
if (r >= 0) {
XSetWMName(x_display, _win, &text_prop);
XFree(text_prop.value);
@@ -1323,15 +1381,19 @@ public:
AutoXErrorHandler()
{
ASSERT(old_error_handler == NULL);
+ XLockDisplay(x_display);
XSync(x_display, False);
x_error = Success;
old_error_handler = XSetErrorHandler(x_error_handler);
+ XUnlockDisplay(x_display);
}
~AutoXErrorHandler()
{
if (old_error_handler) {
+ XLockDisplay(x_display);
XSetErrorHandler(old_error_handler);
+ XUnlockDisplay(x_display);
old_error_handler = NULL;
}
}
@@ -1344,8 +1406,12 @@ static Window get_window_for_reposition(Window window)
Window parent;
Window* childrens;
unsigned int num_childrens;
+ int res;
- if (!XQueryTree(x_display, window, &root, &parent, &childrens, &num_childrens)) {
+ XLockDisplay(x_display);
+ res = XQueryTree(x_display, window, &root, &parent, &childrens, &num_childrens);
+ XUnlockDisplay(x_display);
+ if (!res) {
return None;
}
@@ -1464,7 +1530,9 @@ static bool get_prop_32(Window win, Atom prop, uint32_t &val)
unsigned long bytes_after_return;
unsigned long nitems_return;
unsigned char *prop_return;
+ bool retval = false;
+ XLockDisplay(x_display);
if (XGetWindowProperty(x_display, win, prop, 0, 1, False, AnyPropertyType,
&actual_type_return, &actual_format_return,
&nitems_return, &bytes_after_return, &prop_return) == Success &&
@@ -1472,9 +1540,11 @@ static bool get_prop_32(Window win, Atom prop, uint32_t &val)
actual_type_return != None &&
actual_format_return == 32) {
val = *(uint32_t *)prop_return;
- return true;
+ retval = true;
}
- return false;
+ XUnlockDisplay(x_display);
+
+ return retval;
}
void RedWindow::external_show()
@@ -1486,7 +1556,9 @@ void RedWindow::external_show()
raise();
activate();
+ XLockDisplay(x_display);
atom = XInternAtom(x_display, "_NET_ACTIVE_WINDOW", true);
+ XUnlockDisplay(x_display);
if (atom != None) {
Window root;
XEvent xev;
@@ -1595,14 +1667,21 @@ static bool __get_position(Window window, SpicePoint& pos)
Window parent;
Window* childrens;
unsigned int num_childrens;
+ int res;
- if (!XGetWindowAttributes(x_display, window, &attrib)) {
+ XLockDisplay(x_display);
+ res = XGetWindowAttributes(x_display, window, &attrib);
+ XUnlockDisplay(x_display);
+ if (!res) {
return false;
}
pos.x += attrib.x;
pos.y += attrib.y;
- if (!XQueryTree(x_display, window, &root, &parent, &childrens, &num_childrens)) {
+ XLockDisplay(x_display);
+ res = XQueryTree(x_display, window, &root, &parent, &childrens, &num_childrens);
+ XUnlockDisplay(x_display);
+ if (!res) {
return false;
}
@@ -1648,7 +1727,9 @@ void RedWindow::do_start_key_interception()
// LeaveNotify and EnterNotify.
ASSERT(_focused);
+ XLockDisplay(x_display);
XGrabKeyboard(x_display, _win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+ XUnlockDisplay(x_display);
sync(true);
_listener.on_start_key_interception();
_key_interception_on = true;
@@ -1656,7 +1737,9 @@ void RedWindow::do_start_key_interception()
void RedWindow::do_stop_key_interception()
{
+ XLockDisplay(x_display);
XUngrabKeyboard(x_display, CurrentTime);
+ XUnlockDisplay(x_display);
sync(true);
_key_interception_on = false;
_listener.on_stop_key_interception();
@@ -1715,18 +1798,24 @@ void RedWindow::hide_cursor()
void RedWindow::release_mouse()
{
+ XLockDisplay(x_display);
XUngrabPointer(x_display, CurrentTime);
+ XUnlockDisplay(x_display);
sync(true);
}
void RedWindow::cupture_mouse()
{
int grab_retries = MOUSE_GRAB_RETRIES;
+ XLockDisplay(x_display);
XSync(x_display, False);
+ XUnlockDisplay(x_display);
for (;; --grab_retries) {
+ XLockDisplay(x_display);
int result = XGrabPointer(x_display, _win, True, 0,
GrabModeAsync, GrabModeAsync,
_win, None, CurrentTime);
+ XUnlockDisplay(x_display);
if (result == GrabSuccess) {
break;
}
@@ -1748,7 +1837,9 @@ void RedWindow::set_mouse_position(int x, int y)
SpicePoint RedWindow::get_size()
{
XWindowAttributes attrib;
+ XLockDisplay(x_display);
XGetWindowAttributes(x_display, _win, &attrib);
+ XUnlockDisplay(x_display);
SpicePoint size;
size.x = attrib.width;
size.y = attrib.height;
@@ -1777,7 +1868,12 @@ static QRegion *get_visibale_region(Window window)
QRegion* region = new QRegion;
region_init(region);
XWindowAttributes attrib;
- if (!XGetWindowAttributes(x_display, window, &attrib)) {
+ int res;
+
+ XLockDisplay(x_display);
+ res = XGetWindowAttributes(x_display, window, &attrib);
+ XUnlockDisplay(x_display);
+ if (!res) {
return NULL;
}
@@ -1800,11 +1896,20 @@ static QRegion *get_visibale_region(Window window)
AutoXErrorHandler auto_error_handler;
for (;;) {
- FAIL_ON_BAD_WINDOW(!XQueryTree(x_display, window, &root, &parent, &childrens,
- &num_childrens),
+ int res;
+
+ XLockDisplay(x_display);
+ res = XQueryTree(x_display, window, &root, &parent, &childrens,
+ &num_childrens);
+ XUnlockDisplay(x_display);
+ FAIL_ON_BAD_WINDOW(!res,
"%s: query X tree failed", __FUNCTION__);
for (int i = num_childrens - 1; i >= 0 && childrens[i] != prev; i--) {
- FAIL_ON_BAD_WINDOW(!XGetWindowAttributes(x_display, childrens[i], &attrib),
+
+ XLockDisplay(x_display);
+ res = XGetWindowAttributes(x_display, childrens[i], &attrib);
+ XUnlockDisplay(x_display);
+ FAIL_ON_BAD_WINDOW(!res,
"%s: get win attributes failed", __FUNCTION__);
if (attrib.map_state == IsViewable) {
@@ -1821,7 +1926,10 @@ static QRegion *get_visibale_region(Window window)
XFree(childrens);
}
- FAIL_ON_BAD_WINDOW(!XGetWindowAttributes(x_display, window, &attrib),
+ XLockDisplay(x_display);
+ res = XGetWindowAttributes(x_display, window, &attrib);
+ XUnlockDisplay(x_display);
+ FAIL_ON_BAD_WINDOW(!res,
"%s: get win attributes failed", __FUNCTION__);
window_area_from_attributes(window_area, attrib);
region_offset(region, window_area.left, window_area.top);
@@ -1830,7 +1938,10 @@ static QRegion *get_visibale_region(Window window)
break;
}
- FAIL_ON_BAD_WINDOW(!XGetWindowAttributes(x_display, parent, &attrib),
+ XLockDisplay(x_display);
+ res = XGetWindowAttributes(x_display, parent, &attrib);
+ XUnlockDisplay(x_display);
+ FAIL_ON_BAD_WINDOW(!res,
"%s: get win attributes failed", __FUNCTION__);
window_area_from_attributes(window_area, attrib);
window_area.right -= window_area.left;
@@ -1907,10 +2018,13 @@ bool RedWindow::get_mouse_anchor_point(SpicePoint& pt)
#ifdef USE_OGL
RedGlContext RedWindow::create_context_gl()
{
+ RedGlContext *context = NULL;
if (XPlatform::get_fbconfig()[_screen]) {
- return glXCreateContext(x_display, XPlatform::get_vinfo()[_screen], NULL, GL_TRUE);
+ XLockDisplay(x_display);
+ context = glXCreateContext(x_display, XPlatform::get_vinfo()[_screen], NULL, GL_TRUE);
+ XUnlockDisplay(x_display);
}
- return NULL;
+ return context;
}
RedPbuffer RedWindow::create_pbuff(int width, int height)
@@ -1925,8 +2039,10 @@ RedPbuffer RedWindow::create_pbuff(int width, int height)
0, 0 };
fb_config = XPlatform::get_fbconfig();
+ XLockDisplay(XPlatform::get_display());
pbuff = glXCreatePbuffer(XPlatform::get_display(), fb_config[_screen][0],
pbuf_attr);
+ XUnlockDisplay(XPlatform::get_display());
return pbuff;
}