mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
Wrap the whole miPointerScreenFuncRec, instead of only Set/MoveCursor
We were clobbering entries in mi's global miSpritePointerFuncs struct,
which cannot work correctly with multiple primary screens. Instead,
assign a pointer to our own wrapper struct to PointPriv->spriteFuncs.
Fixes crashes with multiple primary screens.
Fixes: 1fe8ca7597 ("Keep track of how many SW cursors are visible on
each screen")
Reported-by: Mario Kleiner <mario.kleiner.de@gmail.com>
This commit is contained in:
committed by
Michel Dänzer
parent
7e18aea984
commit
b915e8e6fb
@@ -37,6 +37,7 @@
|
||||
#include "inputstr.h"
|
||||
#include "list.h"
|
||||
#include "micmap.h"
|
||||
#include "mipointrst.h"
|
||||
#include "xf86cmap.h"
|
||||
#include "xf86Priv.h"
|
||||
#include "radeon.h"
|
||||
@@ -2750,8 +2751,8 @@ static void drmmode_sprite_do_set_cursor(struct radeon_device_priv *device_priv,
|
||||
info->sprites_visible += device_priv->sprite_visible - sprite_visible;
|
||||
}
|
||||
|
||||
void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
|
||||
CursorPtr pCursor, int x, int y)
|
||||
static void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
|
||||
CursorPtr pCursor, int x, int y)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
@@ -2762,11 +2763,11 @@ void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
|
||||
device_priv->cursor = pCursor;
|
||||
drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
|
||||
|
||||
info->SetCursor(pDev, pScreen, pCursor, x, y);
|
||||
info->SpriteFuncs->SetCursor(pDev, pScreen, pCursor, x, y);
|
||||
}
|
||||
|
||||
void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
|
||||
int y)
|
||||
static void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
|
||||
int x, int y)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
@@ -2776,9 +2777,57 @@ void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
|
||||
|
||||
drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
|
||||
|
||||
info->MoveCursor(pDev, pScreen, x, y);
|
||||
info->SpriteFuncs->MoveCursor(pDev, pScreen, x, y);
|
||||
}
|
||||
|
||||
static Bool drmmode_sprite_realize_realize_cursor(DeviceIntPtr pDev,
|
||||
ScreenPtr pScreen,
|
||||
CursorPtr pCursor)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
|
||||
return info->SpriteFuncs->RealizeCursor(pDev, pScreen, pCursor);
|
||||
}
|
||||
|
||||
static Bool drmmode_sprite_realize_unrealize_cursor(DeviceIntPtr pDev,
|
||||
ScreenPtr pScreen,
|
||||
CursorPtr pCursor)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
|
||||
return info->SpriteFuncs->UnrealizeCursor(pDev, pScreen, pCursor);
|
||||
}
|
||||
|
||||
static Bool drmmode_sprite_device_cursor_initialize(DeviceIntPtr pDev,
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
|
||||
return info->SpriteFuncs->DeviceCursorInitialize(pDev, pScreen);
|
||||
}
|
||||
|
||||
static void drmmode_sprite_device_cursor_cleanup(DeviceIntPtr pDev,
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
||||
RADEONInfoPtr info = RADEONPTR(scrn);
|
||||
|
||||
info->SpriteFuncs->DeviceCursorCleanup(pDev, pScreen);
|
||||
}
|
||||
|
||||
miPointerSpriteFuncRec drmmode_sprite_funcs = {
|
||||
.RealizeCursor = drmmode_sprite_realize_realize_cursor,
|
||||
.UnrealizeCursor = drmmode_sprite_realize_unrealize_cursor,
|
||||
.SetCursor = drmmode_sprite_set_cursor,
|
||||
.MoveCursor = drmmode_sprite_move_cursor,
|
||||
.DeviceCursorInitialize = drmmode_sprite_device_cursor_initialize,
|
||||
.DeviceCursorCleanup = drmmode_sprite_device_cursor_cleanup,
|
||||
};
|
||||
|
||||
|
||||
void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo)
|
||||
{
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||
|
||||
@@ -206,10 +206,6 @@ extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
|
||||
extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
|
||||
extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
|
||||
extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
|
||||
extern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
|
||||
CursorPtr pCursor, int x, int y);
|
||||
extern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
|
||||
int y);
|
||||
extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
|
||||
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
|
||||
extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
|
||||
@@ -249,5 +245,8 @@ Bool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type,
|
||||
uint64_t *ust, uint32_t *result_seq);
|
||||
|
||||
|
||||
miPointerSpriteFuncRec drmmode_sprite_funcs;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -557,9 +557,7 @@ typedef struct {
|
||||
CreateScreenResourcesProcPtr CreateScreenResources;
|
||||
CreateWindowProcPtr CreateWindow;
|
||||
WindowExposuresProcPtr WindowExposures;
|
||||
void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen,
|
||||
CursorPtr pCursor, int x, int y);
|
||||
void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
|
||||
miPointerSpriteFuncPtr SpriteFuncs;
|
||||
|
||||
/* Number of SW cursors currently visible on this screen */
|
||||
int sprites_visible;
|
||||
|
||||
@@ -2017,12 +2017,8 @@ static Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (PointPriv->spriteFuncs->SetCursor != drmmode_sprite_set_cursor) {
|
||||
info->SetCursor = PointPriv->spriteFuncs->SetCursor;
|
||||
info->MoveCursor = PointPriv->spriteFuncs->MoveCursor;
|
||||
PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor;
|
||||
PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor;
|
||||
}
|
||||
info->SpriteFuncs = PointPriv->spriteFuncs;
|
||||
PointPriv->spriteFuncs = &drmmode_sprite_funcs;
|
||||
}
|
||||
|
||||
if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
|
||||
@@ -2186,10 +2182,8 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen)
|
||||
miPointerScreenPtr PointPriv =
|
||||
dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
|
||||
|
||||
if (PointPriv->spriteFuncs->SetCursor == drmmode_sprite_set_cursor) {
|
||||
PointPriv->spriteFuncs->SetCursor = info->SetCursor;
|
||||
PointPriv->spriteFuncs->MoveCursor = info->MoveCursor;
|
||||
}
|
||||
if (PointPriv->spriteFuncs == &drmmode_sprite_funcs)
|
||||
PointPriv->spriteFuncs = info->SpriteFuncs;
|
||||
}
|
||||
|
||||
pScreen->BlockHandler = info->BlockHandler;
|
||||
|
||||
Reference in New Issue
Block a user