[Spice-devel] [PATCH spice] spicec-x11: Put locks around xlib calls which wait for a reply
Arnon Gilboa
agilboa at redhat.com
Tue Oct 12 01:15:02 PDT 2010
Ack, although this important but boring patch got just a brief review;)
I guess that using a dedicated thread will clean all these locks.
Hans de Goede wrote:
> Since libX11-1.3.4 the multi-threading handling code of libX11 has been
> changed, see:
> http://cgit.freedesktop.org/xorg/lib/libX11/commit/?id=933aee1d5c53b0cc7d608011a29188b594c8d70b
>
> This causes several issues. One of them is the display inside the
> client not getting updated when there are no XEvents being generated,
> this is caused by the following part of the referenced commit message:
>
> Caveats:
> - If one thread is waiting for events and another thread tries to read a reply,
> both will hang until an event arrives. Previously, if this happened it might
> work sometimes, but otherwise would trigger either an assertion failure or
> a permanent hang.
>
> We were depending on the otherwise behavior and apparently were lucky.
> This can be seen by starting F14 in runlevel 3 and then doing startx
> and not touching the mouse / keyb afterwards. Once you move the mouse
> (generate an event you see the UI contents being updated but not before.
>
> Another thing both I and Alon (iirc) have seen are hangs where 2
> threads are stuck in XSync waiting for a reply simultaneously. This might
> be related to libxcb version, according to the libX11 commit a libxcb
> newer then 1.6 was needed, and my system had 1.5 at the time I saw this
> after updating to libxcb 1.7 I can no longer reproduce.
>
> This patch tackles both problems (and is needed for the 1st one
> indepently of the 2nd one possibly being fixed) by adding XLockDisplay
> calls around all libX11 calls which wait for a reply or an event.
> ---
> client/x11/platform.cpp | 180 ++++++++++++++++++++++++++++++++++++++-----
> client/x11/red_drawable.cpp | 7 +-
> client/x11/red_window.cpp | 158 ++++++++++++++++++++++++++++++++-----
> client/x11/x_icon.cpp | 13 +++
> 4 files changed, 314 insertions(+), 44 deletions(-)
>
> diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp
> index ccae877..9751a30 100644
> --- a/client/x11/platform.cpp
> +++ b/client/x11/platform.cpp
> @@ -65,7 +65,7 @@
> #define BOOL bool
> #include "named_pipe.h"
>
> -//#define X_DEBUG_SYNC(display) XSync(display, False)
> +//#define X_DEBUG_SYNC(display) do { XLockDisplay(display); XSync(display, False); XUnlockDisplay(display); } while(0)
> #define X_DEBUG_SYNC(display)
> #ifdef HAVE_XRANDR12
> #define USE_XRANDR_1_2
> @@ -175,10 +175,16 @@ static Platform::ClipboardListener* clipboard_listener = &default_clipboard_list
>
> static const char *atom_name(Atom atom)
> {
> + const char *name;
> +
> if (atom == None)
> return "None";
>
> - return XGetAtomName(x_display, atom);
> + XLockDisplay(x_display);
> + name = XGetAtomName(x_display, atom);
> + XUnlockDisplay(x_display);
> +
> + return name;
> }
>
> static uint32_t get_clipboard_type(Atom target) {
> @@ -265,6 +271,7 @@ XEventHandler::XEventHandler(Display& x_display, XContext& win_proc_context)
>
> void XEventHandler::on_event()
> {
> + XLockDisplay(x_display);
> while (XPending(&_x_display)) {
> XPointer proc_pointer;
> XEvent event;
> @@ -281,8 +288,11 @@ void XEventHandler::on_event()
> if (XFindContext(&_x_display, event.xany.window, _win_proc_context, &proc_pointer)) {
> THROW("no window proc");
> }
> + XUnlockDisplay(x_display);
> ((XPlatform::win_proc_t)proc_pointer)(event);
> + XLockDisplay(x_display);
> }
> + XUnlockDisplay(x_display);
> }
>
> Display* XPlatform::get_display()
> @@ -315,6 +325,12 @@ XImage *XPlatform::create_x_shm_image(RedDrawable::Format format,
> XImage *image;
> XShmSegmentInfo *shminfo;
>
> + /* We need to lock the display early, and force any pending requests to
> + be processed, to make sure that any errors reported by
> + handle_x_errors_stop() are actually ours */
> + XLockDisplay(XPlatform::get_display());
> + XSync(XPlatform::get_display(), False);
> +
> shminfo = new XShmSegmentInfo;
> shminfo->shmid = -1;
> shminfo->shmaddr = NULL;
> @@ -375,6 +391,8 @@ XImage *XPlatform::create_x_shm_image(RedDrawable::Format format,
> the segment if the client crashes. */
> shmctl(shminfo->shmid, IPC_RMID, 0);
>
> + XUnlockDisplay(XPlatform::get_display());
> +
> image->data = (char *)shminfo->shmaddr;
>
> *shminfo_out = shminfo;
> @@ -390,6 +408,7 @@ err2:
> }
>
> err1:
> + XUnlockDisplay(XPlatform::get_display());
> delete shminfo;
> return NULL;
> }
> @@ -422,6 +441,7 @@ XImage *XPlatform::create_x_image(RedDrawable::Format format,
> THROW("Out of memory");
> }
>
> + XLockDisplay(XPlatform::get_display());
> if (format == RedDrawable::A1) {
> image = XCreateImage(XPlatform::get_display(),
> NULL, 1, XYBitmap,
> @@ -431,6 +451,7 @@ XImage *XPlatform::create_x_image(RedDrawable::Format format,
> visual, depth, ZPixmap,
> 0, (char *)data, width, height, 32, stride);
> }
> + XUnlockDisplay(XPlatform::get_display());
>
> return image;
> }
> @@ -440,6 +461,7 @@ void XPlatform::free_x_image(XImage *image,
> XShmSegmentInfo *shminfo)
> {
> if (shminfo) {
> + XLockDisplay(XPlatform::get_display());
> XShmDetach(XPlatform::get_display(), shminfo);
> }
> if (image) {
> @@ -448,6 +470,7 @@ void XPlatform::free_x_image(XImage *image,
> if (shminfo) {
> XSync(XPlatform::get_display(), False);
> shmdt(shminfo->shmaddr);
> + XUnlockDisplay(XPlatform::get_display());
> delete shminfo;
> }
> }
> @@ -477,14 +500,21 @@ XIC XPlatform::get_input_context()
>
> void XPlatform::set_win_proc(Window win, win_proc_t proc)
> {
> - if (XSaveContext(x_display, win, win_proc_context, (XPointer)proc)) {
> + int res;
> +
> + XLockDisplay(x_display);
> + res = XSaveContext(x_display, win, win_proc_context, (XPointer)proc);
> + XUnlockDisplay(x_display);
> + if (res) {
> THROW("set win proc failed");
> }
> }
>
> void XPlatform::cleare_win_proc(Window win)
> {
> + XLockDisplay(x_display);
> XDeleteContext(x_display, win, win_proc_context);
> + XUnlockDisplay(x_display);
> }
>
> void Platform::send_quit_request()
> @@ -651,12 +681,15 @@ static void show_scren_info()
> int maxWidth;
> int maxHeight;
>
> + XLockDisplay(x_display);
> AutoScreenRes res(XRRGetScreenResources(x_display, root_window));
> + XUnlockDisplay(x_display);
>
> if (!res.valid()) {
> throw Exception(fmt("%s: get screen resources failed") % __FUNCTION__);
> }
>
> + XLockDisplay(x_display);
> XRRGetScreenSizeRange(x_display, root_window, &minWidth, &minHeight,
> &maxWidth, &maxHeight);
> printf("screen: min %dx%d max %dx%d\n", minWidth, minHeight,
> @@ -706,6 +739,7 @@ static void show_scren_info()
> crtc_info->x, crtc_info->y,
> crtc_info->width, crtc_info->height, crtc_info->mode);
> }
> + XUnlockDisplay(x_display);
> }
>
> #endif
> @@ -767,7 +801,10 @@ XScreen::XScreen(Display* display, int screen)
> int root = RootWindow(display, screen);
>
> XWindowAttributes attrib;
> +
> + XLockDisplay(display);
> XGetWindowAttributes(display, root, &attrib);
> + XUnlockDisplay(display);
>
> _position.x = attrib.x;
> _position.y = attrib.y;
> @@ -837,6 +874,8 @@ static void intern_clipboard_atoms()
> int i;
> static bool interned = false;
> if (interned) return;
> +
> + XLockDisplay(x_display);
> clipboard_prop = XInternAtom(x_display, "CLIPBOARD", False);
> incr_atom = XInternAtom(x_display, "INCR", False);
> multiple_atom = XInternAtom(x_display, "MULTIPLE", False);
> @@ -844,6 +883,8 @@ static void intern_clipboard_atoms()
> for(i = 0; i < utf8_atom_count; i++)
> utf8_atoms[i] = XInternAtom(x_display, utf8_atom_names[i], False);
>
> + XUnlockDisplay(x_display);
> +
> interned = true;
> }
>
> @@ -856,7 +897,10 @@ DynamicScreen::DynamicScreen(Display* display, int screen, int& next_mon_id)
> {
> X_DEBUG_SYNC(display);
> //FIXME: replace RootWindow() in other refs as well?
> + XLockDisplay(display);
> platform_win = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 1, 1, 0, 0, 0);
> + XUnlockDisplay(display);
> +
> LOG_INFO("platform_win: %u", (unsigned int)platform_win);
> intern_clipboard_atoms();
> XSelectInput(display, platform_win, StructureNotifyMask);
> @@ -907,7 +951,10 @@ void DynamicScreen::do_set_mode(int width, int height)
> int num_sizes;
>
> X_DEBUG_SYNC(get_display());
> +
> + XLockDisplay(get_display());
> XRRScreenSize* sizes = XRRSizes(get_display(), get_screen(), &num_sizes);
> + XUnlockDisplay(get_display());
>
> typedef std::set<SizeInfo, SizeCompare> SizesSet;
> SizesSet sizes_set;
> @@ -932,7 +979,10 @@ void DynamicScreen::do_restore()
> }
> int num_sizes;
>
> + XLockDisplay(get_display());
> XRRScreenSize* sizes = XRRSizes(get_display(), get_screen(), &num_sizes);
> + XUnlockDisplay(get_display());
> +
> for (int i = 0; i < num_sizes; i++) {
> if (sizes[i].width == _saved_width && sizes[i].height == _saved_height) {
> set_screen_size(i);
> @@ -949,7 +999,11 @@ bool DynamicScreen::set_screen_size(int size_index)
> Window root_window = RootWindow(get_display(), get_screen());
> XRRScreenConfiguration* config;
>
> - if (!(config = XRRGetScreenInfo(get_display(), root_window))) {
> + XLockDisplay(get_display());
> + config = XRRGetScreenInfo(get_display(), root_window);
> + XUnlockDisplay(get_display());
> +
> + if (!config) {
> LOG_WARN("get screen info failed");
> return false;
> }
> @@ -965,7 +1019,11 @@ bool DynamicScreen::set_screen_size(int size_index)
> X_DEBUG_SYNC(get_display());
>
> int num_sizes;
> +
> + XLockDisplay(get_display());
> XRRScreenSize* sizes = XRRSizes(get_display(), get_screen(), &num_sizes);
> + XUnlockDisplay(get_display());
> +
> if (num_sizes <= size_index) {
> THROW("invalid sizes size");
> }
> @@ -1091,10 +1149,13 @@ MultyMonScreen::MultyMonScreen(Display* display, int screen, int& next_mon_id)
> {
> X_DEBUG_SYNC(get_display());
> Window root_window = RootWindow(display, screen);
> +
> + XLockDisplay(display);
> XRRGetScreenSizeRange(display, root_window, &_min_width, &_min_height,
> &_max_width, &_max_height);
> -
> AutoScreenRes res(XRRGetScreenResources(display, root_window));
> + XUnlockDisplay(display);
> +
> if (!res.valid()) {
> THROW("get screen resources failed");
> }
> @@ -1102,6 +1163,7 @@ MultyMonScreen::MultyMonScreen(Display* display, int screen, int& next_mon_id)
> #ifdef SHOW_SCREEN_INFO
> show_scren_info();
> #endif
> + XLockDisplay(display);
> try {
> for (int i = 0; i < res->ncrtc; i++) {
> AutoCrtcInfo crtc_info(XRRGetCrtcInfo(display, res.get(), res->crtcs[i]));
> @@ -1126,12 +1188,17 @@ MultyMonScreen::MultyMonScreen(Display* display, int screen, int& next_mon_id)
>
> _monitors.push_back(new XMonitor(*this, next_mon_id++, res->crtcs[i]));
> }
> + XUnlockDisplay(display);
> } catch (...) {
> + XUnlockDisplay(display);
> monitors_cleanup();
> throw;
> }
>
> + XLockDisplay(display);
> platform_win = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 1, 1, 0, 0, 0);
> + XUnlockDisplay(display);
> +
> LOG_INFO("platform_win: %u", (unsigned int)platform_win);
> intern_clipboard_atoms();
> XSelectInput(display, platform_win, StructureNotifyMask);
> @@ -1851,13 +1918,18 @@ void XMonitor::update_position()
> Display* display = _container.get_display();
> X_DEBUG_SYNC(display);
> Window root_window = RootWindow(display, _container.get_screen());
> +
> + XLockDisplay(display);
> AutoScreenRes res(XRRGetScreenResources(display, root_window));
> + XUnlockDisplay(display);
>
> if (!res.valid()) {
> THROW("get screen resources failed");
> }
>
> + XLockDisplay(display);
> AutoCrtcInfo crtc_info(XRRGetCrtcInfo(display, res.get(), _crtc));
> + XUnlockDisplay(display);
>
> ASSERT(crtc_info->noutput);
>
> @@ -1887,7 +1959,9 @@ void XMonitor::update_position()
> //todo: set valid subpixel order in case all outputs share the same type
> _subpixel_order = RED_SUBPIXEL_ORDER_UNKNOWN;
> } else {
> + XLockDisplay(display);
> AutoOutputInfo output_info(XRRGetOutputInfo(display, res.get(), crtc_info->outputs[0]));
> + XUnlockDisplay(display);
>
> switch (output_info->subpixel_order) {
> case SubPixelUnknown:
> @@ -1924,8 +1998,10 @@ void XMonitor::update_position()
> bool XMonitor::finde_mode_in_outputs(RRMode mode, int start_index, XRRScreenResources* res)
> {
> int i, j;
> + bool retval = true;
>
> X_DEBUG_SYNC(_container.get_display());
> + XLockDisplay(_container.get_display());
> for (i = start_index; i < _noutput; i++) {
> AutoOutputInfo output_info(XRRGetOutputInfo(_container.get_display(), res, _outputs[i]));
> for (j = 0; j < output_info->nmode; j++) {
> @@ -1934,11 +2010,13 @@ bool XMonitor::finde_mode_in_outputs(RRMode mode, int start_index, XRRScreenReso
> }
> }
> if (j == output_info->nmode) {
> - return false;
> + retval = false;
> + break;
> }
> }
> + XUnlockDisplay(_container.get_display());
> X_DEBUG_SYNC(_container.get_display());
> - return true;
> + return retval;
> }
>
> bool XMonitor::finde_mode_in_clones(RRMode mode, XRRScreenResources* res)
> @@ -1975,7 +2053,11 @@ XRRModeInfo* XMonitor::find_mode(int width, int height, XRRScreenResources* res)
> typedef std::set<ModeInfo, ModeCompare> ModesSet;
> ModesSet modes_set;
> X_DEBUG_SYNC(_container.get_display());
> +
> + XLockDisplay(_container.get_display());
> AutoOutputInfo output_info(XRRGetOutputInfo(_container.get_display(), res, _outputs[0]));
> + XUnlockDisplay(_container.get_display());
> +
> for (int i = 0; i < output_info->nmode; i++) {
> XRRModeInfo* mode_inf = find_mod(res, output_info->modes[i]);
> if (mode_inf->width >= width && mode_inf->height >= height) {
> @@ -2010,7 +2092,11 @@ void XMonitor::do_set_mode(int width, int height)
> Display* display = _container.get_display();
> X_DEBUG_SYNC(display);
> Window root_window = RootWindow(display, _container.get_screen());
> +
> + XLockDisplay(display);
> AutoScreenRes res(XRRGetScreenResources(display, root_window));
> + XUnlockDisplay(display);
> +
> if (!res.valid()) {
> THROW("get screen resource failed");
> }
> @@ -2041,7 +2127,11 @@ void XMonitor::disable()
> Display* display = _container.get_display();
> X_DEBUG_SYNC(display);
> Window root_window = RootWindow(display, _container.get_screen());
> +
> + XLockDisplay(display);
> AutoScreenRes res(XRRGetScreenResources(display, root_window));
> + XUnlockDisplay(display);
> +
> if (!res.valid()) {
> THROW("get screen resources failed");
> }
> @@ -2061,7 +2151,11 @@ void XMonitor::enable()
> Display* display = _container.get_display();
> X_DEBUG_SYNC(display);
> Window root_window = RootWindow(display, _container.get_screen());
> +
> + XLockDisplay(display);
> AutoScreenRes res(XRRGetScreenResources(display, root_window));
> + XUnlockDisplay(display);
> +
> if (!res.valid()) {
> THROW("get screen resources failed");
> }
> @@ -2343,7 +2437,7 @@ static int get_selection(XEvent &event, Atom type, Atom prop, int format,
> {
> Bool del = incr ? True: False;
> Atom type_ret;
> - int format_ret, ret_val = -1;
> + int res, format_ret, ret_val = -1;
> unsigned long len, remain;
> unsigned char *data = NULL;
>
> @@ -2366,9 +2460,15 @@ static int get_selection(XEvent &event, Atom type, Atom prop, int format,
> }
> }
>
> - if (XGetWindowProperty(x_display, platform_win, prop, 0,
> - LONG_MAX, del, type, &type_ret, &format_ret, &len,
> - &remain, &data) != Success) {
> + /* Warning we are running with the clipboard_lock held!! That is ok, as
> + there is no code holding XLockDisplay which calls code taking
> + the clipboard_lock!! */
> + XLockDisplay(x_display);
> + res = XGetWindowProperty(x_display, platform_win, prop, 0,
> + LONG_MAX, del, type, &type_ret, &format_ret, &len,
> + &remain, &data);
> + XUnlockDisplay(x_display);
> + if (res != Success) {
> LOG_WARN("XGetWindowProperty failed");
> goto exit;
> }
> @@ -2686,17 +2786,25 @@ static void root_win_proc(XEvent& event)
>
> static void process_monitor_configure_events(Window root)
> {
> - XSync(x_display, False);
> XEvent event;
>
> + XLockDisplay(x_display);
> + XSync(x_display, False);
> +
> while (XCheckTypedWindowEvent(x_display, root, ConfigureNotify, &event)) {
> + XUnlockDisplay(x_display);
> root_win_proc(event);
> + XLockDisplay(x_display);
> }
>
> while (XCheckTypedWindowEvent(x_display, root, xrandr_event_base + RRScreenChangeNotify,
> &event)) {
> + XUnlockDisplay(x_display);
> root_win_proc(event);
> + XLockDisplay(x_display);
> }
> +
> + XUnlockDisplay(x_display);
> }
>
> static void cleanup(void)
> @@ -2779,7 +2887,7 @@ static void init_xfixes()
> XFixesQueryVersion(x_display, &major, &minor) && major >= 1;
> }
>
> -unsigned int get_modifier_mask(KeySym modifier)
> +static unsigned int get_modifier_mask(KeySym modifier)
> {
> int mask = 0;
> int i;
> @@ -3028,7 +3136,9 @@ uint32_t Platform::get_keyboard_lock_modifiers()
> XKeyboardState keyboard_state;
> uint32_t modifiers = 0;
>
> + XLockDisplay(x_display);
> XGetKeyboardControl(x_display, &keyboard_state);
> + XUnlockDisplay(x_display);
>
> if (keyboard_state.led_mask & 0x01) {
> modifiers |= CAPS_LOCK_MODIFIER;
> @@ -3088,7 +3198,7 @@ void Platform::set_keyboard_lock_modifiers(uint32_t modifiers)
> }
> }
>
> -uint32_t key_bit(char* keymap, int key, uint32_t bit)
> +static uint32_t key_bit(char* keymap, int key, uint32_t bit)
> {
> KeyCode key_code = XKeysymToKeycode(x_display, key);
> return (((keymap[key_code >> 3] >> (key_code & 7)) & 1) ? bit : 0);
> @@ -3097,14 +3207,19 @@ uint32_t key_bit(char* keymap, int key, uint32_t bit)
> uint32_t Platform::get_keyboard_modifiers()
> {
> char keymap[32];
> + uint32_t mods;
>
> + XLockDisplay(x_display);
> XQueryKeymap(x_display, keymap);
> - return key_bit(keymap, XK_Shift_L, L_SHIFT_MODIFIER) |
> + mods = key_bit(keymap, XK_Shift_L, L_SHIFT_MODIFIER) |
> key_bit(keymap, XK_Shift_R, R_SHIFT_MODIFIER) |
> key_bit(keymap, XK_Control_L, L_CTRL_MODIFIER) |
> key_bit(keymap, XK_Control_R, R_CTRL_MODIFIER) |
> key_bit(keymap, XK_Alt_L, L_ALT_MODIFIER) |
> key_bit(keymap, XK_Alt_R, R_ALT_MODIFIER);
> + XUnlockDisplay(x_display);
> +
> + return mods;
> }
>
> void Platform::reset_cursor_pos()
> @@ -3258,7 +3373,9 @@ XLocalCursor::XLocalCursor(CursorData* cursor_data)
> case SPICE_CURSOR_TYPE_COLOR8:
> default:
> LOG_WARN("unsupported cursor type %d", header.type);
> + XLockDisplay(x_display);
> _handle = XCreateFontCursor(x_display, XC_arrow);
> + XUnlockDisplay(x_display);
> delete[] cur_data;
> return;
> }
> @@ -3284,22 +3401,25 @@ XLocalCursor::XLocalCursor(CursorData* cursor_data)
> }
>
> Window root_window = RootWindow(x_display, DefaultScreen(x_display));
> - Pixmap pixmap = XCreatePixmap(x_display, root_window, header.width, header.height, 32);
> -
> XGCValues gc_vals;
> gc_vals.function = GXcopy;
> gc_vals.foreground = ~0;
> gc_vals.background = 0;
> gc_vals.plane_mask = AllPlanes;
>
> + XLockDisplay(x_display);
> + Pixmap pixmap = XCreatePixmap(x_display, root_window, header.width, header.height, 32);
> GC gc = XCreateGC(x_display, pixmap, GCFunction | GCForeground | GCBackground | GCPlaneMask,
> &gc_vals);
> +
> XPutImage(x_display, pixmap, gc, &image, 0, 0, 0, 0, header.width, header.height);
> XFreeGC(x_display, gc);
>
> XRenderPictFormat *xformat = XRenderFindStandardFormat(x_display, PictStandardARGB32);
> Picture picture = XRenderCreatePicture(x_display, pixmap, xformat, 0, NULL);
> _handle = XRenderCreateCursor(x_display, picture, header.hot_spot_x, header.hot_spot_y);
> + XUnlockDisplay(x_display);
> +
> XRenderFreePicture(x_display, picture);
> XFreePixmap(x_display, pixmap);
> delete[] cur_data;
> @@ -3323,7 +3443,12 @@ LocalCursor* Platform::create_inactive_cursor()
>
> class XDefaultCursor: public XBaseLocalCursor {
> public:
> - XDefaultCursor() { _handle = XCreateFontCursor(x_display, XC_top_left_arrow);}
> + XDefaultCursor()
> + {
> + XLockDisplay(x_display);
> + _handle = XCreateFontCursor(x_display, XC_top_left_arrow);
> + XUnlockDisplay(x_display);
> + }
> };
>
> LocalCursor* Platform::create_default_cursor()
> @@ -3440,13 +3565,17 @@ bool Platform::on_clipboard_notify(uint32_t type, const uint8_t* data, int32_t s
>
> bool Platform::on_clipboard_request(uint32_t type)
> {
> + Window owner;
> Lock lock(clipboard_lock);
> Atom target = get_clipboard_target(type);
>
> if (target == None)
> return false;
>
> - if (XGetSelectionOwner(x_display, clipboard_prop) == None) {
> + XLockDisplay(x_display);
> + owner = XGetSelectionOwner(x_display, clipboard_prop);
> + XUnlockDisplay(x_display);
> + if (owner == None) {
> LOG_INFO("No owner for the selection");
> return false;
> }
> @@ -3464,8 +3593,12 @@ bool Platform::on_clipboard_request(uint32_t type)
> void Platform::on_clipboard_release()
> {
> XEvent event;
> + Window owner;
>
> - if (XGetSelectionOwner(x_display, clipboard_prop) != platform_win) {
> + XLockDisplay(x_display);
> + owner = XGetSelectionOwner(x_display, clipboard_prop);
> + XUnlockDisplay(x_display);
> + if (owner != platform_win) {
> LOG_INFO("Platform::on_clipboard_release() called while not selection owner");
> return;
> }
> @@ -3477,11 +3610,16 @@ void Platform::on_clipboard_release()
> /* Make sure we process the XFixesSetSelectionOwnerNotify event caused
> by this, so we don't end up changing the clipboard owner to none, after
> it has already been re-owned because this event is still pending. */
> + XLockDisplay(x_display);
> XSync(x_display, False);
> while (XCheckTypedEvent(x_display,
> XFixesSelectionNotify + xfixes_event_base,
> - &event))
> + &event)) {
> + XUnlockDisplay(x_display);
> root_win_proc(event);
> + XLockDisplay(x_display);
> + }
> + XUnlockDisplay(x_display);
>
> /* Note no need to do a set_clipboard_owner(owner_none) here, as that is
> already done by processing the XFixesSetSelectionOwnerNotify event. */
> diff --git a/client/x11/red_drawable.cpp b/client/x11/red_drawable.cpp
> index 327028b..e7151ed 100644
> --- a/client/x11/red_drawable.cpp
> +++ b/client/x11/red_drawable.cpp
> @@ -216,7 +216,6 @@ static inline void copy_to_drawable_from_pixmap(const RedDrawable_p* dest,
> dest->source.x_drawable.gc, source->pixmap.x_image,
> src_x, src_y, area.left + offset.x, area.top + offset.y,
> area.right - area.left, area.bottom - area.top, false);
> - XSync(XPlatform::get_display(), 0);
> } else {
> XPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable,
> dest->source.x_drawable.gc, source->pixmap.x_image, src_x,
> @@ -242,7 +241,6 @@ static inline void copy_to_drawable_from_pixmap(const RedDrawable_p* dest,
> dest->source.x_drawable.gc, image,
> 0, 0, area.left + offset.x, area.top + offset.y,
> area.right - area.left, area.bottom - area.top, false);
> - XSync(XPlatform::get_display(), 0);
> } else {
> XPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable,
> dest->source.x_drawable.gc, image,
> @@ -252,6 +250,7 @@ static inline void copy_to_drawable_from_pixmap(const RedDrawable_p* dest,
>
> free_temp_image(image, shminfo, pixman_image);
> }
> + XFlush(XPlatform::get_display());
> }
>
> static inline void copy_to_x_drawable(const RedDrawable_p* dest,
> @@ -628,6 +627,7 @@ static inline void fill_drawable(RedDrawable_p* dest, const SpiceRect& area, rgb
> Drawable drawable = dest->source.x_drawable.drawable;
> GC gc = dest->source.x_drawable.gc;
>
> + XLockDisplay(XPlatform::get_display());
> Colormap color_map = DefaultColormap(XPlatform::get_display(),
> DefaultScreen(XPlatform::get_display()));
> XColor x_color;
> @@ -639,6 +639,7 @@ static inline void fill_drawable(RedDrawable_p* dest, const SpiceRect& area, rgb
> if (!XAllocColor(XPlatform::get_display(), color_map, &x_color)) {
> LOG_WARN("color map failed");
> }
> + XUnlockDisplay(XPlatform::get_display());
>
> XGCValues gc_vals;
> gc_vals.foreground = x_color.pixel;
> @@ -724,6 +725,7 @@ static inline void frame_drawable(RedDrawable_p* dest, const SpiceRect& area, rg
> Drawable drawable = dest->source.x_drawable.drawable;
> GC gc = dest->source.x_drawable.gc;
>
> + XLockDisplay(XPlatform::get_display());
> Colormap color_map = DefaultColormap(XPlatform::get_display(),
> DefaultScreen(XPlatform::get_display()));
> XColor x_color;
> @@ -735,6 +737,7 @@ static inline void frame_drawable(RedDrawable_p* dest, const SpiceRect& area, rg
> if (!XAllocColor(XPlatform::get_display(), color_map, &x_color)) {
> LOG_WARN("color map failed");
> }
> + XUnlockDisplay(XPlatform::get_display());
>
> XGCValues gc_vals;
> gc_vals.foreground = x_color.pixel;
> diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp
> index 5a0886a..e7b6815 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;
> }
> diff --git a/client/x11/x_icon.cpp b/client/x11/x_icon.cpp
> index e59a030..937eecc 100644
> --- a/client/x11/x_icon.cpp
> +++ b/client/x11/x_icon.cpp
> @@ -61,13 +61,19 @@ void XIcon::get_pixmaps(int screen, Pixmap& out_pixmap, Pixmap& out_mask)
> Pixmap mask = None;
> GC gc = NULL;
> try {
> + XLockDisplay(x_display);
> pixmap = XCreatePixmap(x_display, root_window, _raw_icon->width, _raw_icon->height, 24);
> + XUnlockDisplay(x_display);
> if (pixmap == None) {
> THROW("create pixmap failed");
> }
>
> XWindowAttributes attr;
> +
> + XLockDisplay(x_display);
> XGetWindowAttributes(x_display, root_window, &attr);
> + XUnlockDisplay(x_display);
> +
> XImage image;
> memset(&image, 0, sizeof(image));
> image.width = _raw_icon->width;
> @@ -94,14 +100,18 @@ void XIcon::get_pixmaps(int screen, Pixmap& out_pixmap, Pixmap& out_mask)
> gc_vals.foreground = ~0;
> gc_vals.background = 0;
> gc_vals.plane_mask = AllPlanes;
> +
> + XLockDisplay(x_display);
> gc = XCreateGC(x_display, pixmap, GCFunction | GCForeground | GCBackground | GCPlaneMask,
> &gc_vals);
> XPutImage(x_display, pixmap, gc, &image, 0, 0, 0, 0, image.width, image.height);
> + // HDG: why ?? XFlush should suffice
> XSync(x_display, False);
> XFreeGC(x_display, gc);
> gc = NULL;
>
> mask = XCreatePixmap(x_display, root_window, _raw_icon->width, _raw_icon->height, 1);
> + XUnlockDisplay(x_display);
> if (mask == None) {
> THROW("create mask failed");
> }
> @@ -121,10 +131,13 @@ void XIcon::get_pixmaps(int screen, Pixmap& out_pixmap, Pixmap& out_mask)
> THROW("init image failed");
> }
>
> + XLockDisplay(x_display);
> gc = XCreateGC(x_display, mask, GCFunction | GCForeground | GCBackground | GCPlaneMask,
> &gc_vals);
> XPutImage(x_display, mask, gc, &image, 0, 0, 0, 0, image.width, image.height);
> + // HDG: why ?? XFlush should suffice
> XSync(x_display, False);
> + XUnlockDisplay(x_display);
> XFreeGC(x_display, gc);
> } catch (...) {
> if (gc) {
>
More information about the Spice-devel
mailing list