diff options
author | Michel Dänzer <daenzer@vmware.com> | 2010-03-10 13:16:00 +0100 |
---|---|---|
committer | Michel Dänzer <daenzer@vmware.com> | 2010-03-10 13:16:00 +0100 |
commit | 21c91b410a2a2cbf8eb677e59e3322f86320f2b0 (patch) | |
tree | 4b22540f20e7821662e5cc05621152009a2c1f46 | |
parent | a8f3b3f88acc1f0193fa740e76e9d815f07f32ab (diff) |
st/xorg: Work around cursor reference counting bugs in older X servers.
Could result in use of freed memory and consequently random crashes, e.g. on
screen resize.
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_crtc.c | 14 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_driver.c | 5 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_tracker.h | 1 |
3 files changed, 20 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index daa9f8b820..5b78d57d64 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -276,7 +276,21 @@ err_bo_destroy: static void crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); modesettingPtr ms = modesettingPTR(crtc->scrn); + + /* Older X servers have cursor reference counting bugs leading to use of + * freed memory and consequently random crashes. Should be fixed as of + * xserver 1.8, but this workaround shouldn't hurt anyway. + */ + if (config->cursor) + config->cursor->refcnt++; + + if (ms->cursor) + FreeCursor(ms->cursor, None); + + ms->cursor = config->cursor; + if (ms->screen) crtc_load_cursor_argb_ga3d(crtc, image); #ifdef HAVE_LIBKMS diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 372fa3d9d1..2aedbb0978 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -949,6 +949,11 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen) drv_leave_vt(scrnIndex, 0); } + if (ms->cursor) { + FreeCursor(ms->cursor, None); + ms->cursor = NULL; + } + if (cust && cust->winsys_screen_close) cust->winsys_screen_close(cust); diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index 9de1df76aa..570368108c 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -98,6 +98,7 @@ typedef struct _modesettingRec Bool noAccel; Bool SWCursor; + CursorPtr cursor; Bool swapThrottling; Bool dirtyThrottling; CloseScreenProcPtr CloseScreen; |