diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index f3400a1cd..f52a214b3 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -43,6 +43,7 @@ #include #include "dix/dix_priv.h" +#include "Xext/xacestr.h" #include "xf86.h" #include "xf86Priv.h" @@ -86,14 +87,10 @@ static Bool ms_pci_probe(DriverPtr driver, int entity_num, struct pci_device *device, intptr_t match_data); static Bool ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data); +static void ms_property_access(CallbackListPtr *pcbl, void* unused, void *calldata); -/* window wrapper functions used to get the notification when - * the window property changes */ static Atom vrr_atom; -static Bool property_vectors_wrapped; -static Bool restore_property_vector; -static int (*saved_change_property) (ClientPtr client); -static int (*saved_delete_property) (ClientPtr client); +static int activeScreens = 0; #ifdef XSERVER_LIBPCIACCESS static const struct pci_id_match ms_device_match[] = { @@ -918,110 +915,22 @@ ms_vrr_property_update(WindowPtr window, Bool variable_refresh) ms_present_set_screen_vrr(scrn, variable_refresh); } -/* Wrapper for xserver/dix/property.c:ProcChangeProperty */ -static int -ms_change_property(ClientPtr client) -{ - WindowPtr window = NULL; - int ret = 0; - - REQUEST(xChangePropertyReq); - - client->requestVector[X_ChangeProperty] = saved_change_property; - ret = saved_change_property(client); - - if (restore_property_vector) - return ret; - - client->requestVector[X_ChangeProperty] = ms_change_property; - - if (ret != Success) - return ret; - - ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess); - if (ret != Success) - return ret; - - // Checking for the VRR property change on the window - if (stuff->property == vrr_atom && - xf86ScreenToScrn(window->drawable.pScreen)->PreInit == PreInit && - stuff->format == 32 && stuff->nUnits == 1) { - uint32_t *value = (uint32_t *)(stuff + 1); - ms_vrr_property_update(window, *value != 0); - } - - return ret; -} - -/* Wrapper for xserver/dix/property.c:ProcDeleteProperty */ -static int -ms_delete_property(ClientPtr client) -{ - WindowPtr window; - int ret; - - REQUEST(xDeletePropertyReq); - - client->requestVector[X_DeleteProperty] = saved_delete_property; - ret = saved_delete_property(client); - - if (restore_property_vector) - return ret; - - client->requestVector[X_DeleteProperty] = ms_delete_property; - - if (ret != Success) - return ret; - - ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess); - if (ret != Success) - return ret; - - if (stuff->property == vrr_atom && - xf86ScreenToScrn(window->drawable.pScreen)->PreInit == PreInit) - ms_vrr_property_update(window, FALSE); - - return ret; -} - static void -ms_unwrap_property_requests(ScrnInfoPtr scrn) +ms_property_access(CallbackListPtr *pcbl, void* unused, void *calldata) { - int i; + XacePropertyAccessRec *rec = calldata; + PropertyPtr pProp = *(rec->ppProp); - if (!property_vectors_wrapped) + // our property ? window on screen handled by us ? + if (!(pProp->propertyName == vrr_atom) && + (xf86ScreenToScrn(rec->pWin->drawable.pScreen)->PreInit == PreInit)) return; - if (ProcVector[X_ChangeProperty] == ms_change_property) - ProcVector[X_ChangeProperty] = saved_change_property; - else - restore_property_vector = TRUE; + if (rec->access_mode & DixDestroyAccess) + ms_vrr_property_update(rec->pWin, FALSE); - if (ProcVector[X_DeleteProperty] == ms_delete_property) - ProcVector[X_DeleteProperty] = saved_delete_property; - else - restore_property_vector = TRUE; - - for (i = 0; i < currentMaxClients; i++) { - if (clients[i]->requestVector[X_ChangeProperty] == ms_change_property) { - clients[i]->requestVector[X_ChangeProperty] = saved_change_property; - } else { - restore_property_vector = TRUE; - } - - if (clients[i]->requestVector[X_DeleteProperty] == ms_delete_property) { - clients[i]->requestVector[X_DeleteProperty] = saved_delete_property; - } else { - restore_property_vector = TRUE; - } - } - - if (restore_property_vector) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "Couldn't unwrap some window property request vectors\n"); - } - - property_vectors_wrapped = FALSE; + if ((rec->access_mode & DixWriteAccess) && (pProp->format == 32) && (pProp->size == 1)) + ms_vrr_property_update(rec->pWin, (*(uint32_t *)(pProp->data)) != 0); } static void @@ -1043,7 +952,6 @@ FreeRec(ScrnInfoPtr pScrn) ms_ent = ms_ent_priv(pScrn); ms_ent->fd_ref--; if (!ms_ent->fd_ref) { - ms_unwrap_property_requests(pScrn); if (ms->pEnt->location.type == BUS_PCI) ret = drmClose(ms->fd); else @@ -2194,17 +2102,15 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) pScrn->vtSema = TRUE; if (ms->vrr_support) { - if (!property_vectors_wrapped) { - saved_change_property = ProcVector[X_ChangeProperty]; - ProcVector[X_ChangeProperty] = ms_change_property; - saved_delete_property = ProcVector[X_DeleteProperty]; - ProcVector[X_DeleteProperty] = ms_delete_property; - property_vectors_wrapped = TRUE; - } vrr_atom = MakeAtom("_VARIABLE_REFRESH", strlen("_VARIABLE_REFRESH"), TRUE); } + /* first one: register Xace hook for Window property updates */ + if (!activeScreens) + XaceRegisterCallback(XACE_PROPERTY_ACCESS, ms_property_access, NULL); + activeScreens++; + return TRUE; } @@ -2289,6 +2195,12 @@ CloseScreen(ScreenPtr pScreen) modesettingPtr ms = modesettingPTR(pScrn); modesettingEntPtr ms_ent = ms_ent_priv(pScrn); + activeScreens--; + if (activeScreens < 1) { + XaceDeleteCallback(XACE_PROPERTY_ACCESS, ms_property_access, NULL); + activeScreens = 0; + } + /* Clear mask of assigned crtc's in this generation */ ms_ent->assigned_crtcs = 0;