rrprovider.c revision 35c4bbdf
135c4bbdfSmrg/* 235c4bbdfSmrg * Copyright © 2012 Red Hat Inc. 335c4bbdfSmrg * 435c4bbdfSmrg * Permission to use, copy, modify, distribute, and sell this software and its 535c4bbdfSmrg * documentation for any purpose is hereby granted without fee, provided that 635c4bbdfSmrg * the above copyright notice appear in all copies and that both that copyright 735c4bbdfSmrg * notice and this permission notice appear in supporting documentation, and 835c4bbdfSmrg * that the name of the copyright holders not be used in advertising or 935c4bbdfSmrg * publicity pertaining to distribution of the software without specific, 1035c4bbdfSmrg * written prior permission. The copyright holders make no representations 1135c4bbdfSmrg * about the suitability of this software for any purpose. It is provided "as 1235c4bbdfSmrg * is" without express or implied warranty. 1335c4bbdfSmrg * 1435c4bbdfSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1535c4bbdfSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1635c4bbdfSmrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1735c4bbdfSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1835c4bbdfSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1935c4bbdfSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2035c4bbdfSmrg * OF THIS SOFTWARE. 2135c4bbdfSmrg * 2235c4bbdfSmrg * Authors: Dave Airlie 2335c4bbdfSmrg */ 2435c4bbdfSmrg 2535c4bbdfSmrg#include "randrstr.h" 2635c4bbdfSmrg#include "swaprep.h" 2735c4bbdfSmrg 2835c4bbdfSmrgRESTYPE RRProviderType; 2935c4bbdfSmrg 3035c4bbdfSmrg/* 3135c4bbdfSmrg * Initialize provider type error value 3235c4bbdfSmrg */ 3335c4bbdfSmrgvoid 3435c4bbdfSmrgRRProviderInitErrorValue(void) 3535c4bbdfSmrg{ 3635c4bbdfSmrg SetResourceTypeErrorValue(RRProviderType, RRErrorBase + BadRRProvider); 3735c4bbdfSmrg} 3835c4bbdfSmrg 3935c4bbdfSmrg#define ADD_PROVIDER(_pScreen) do { \ 4035c4bbdfSmrg pScrPriv = rrGetScrPriv((_pScreen)); \ 4135c4bbdfSmrg if (pScrPriv->provider) { \ 4235c4bbdfSmrg providers[count_providers] = pScrPriv->provider->id; \ 4335c4bbdfSmrg if (client->swapped) \ 4435c4bbdfSmrg swapl(&providers[count_providers]); \ 4535c4bbdfSmrg count_providers++; \ 4635c4bbdfSmrg } \ 4735c4bbdfSmrg } while(0) 4835c4bbdfSmrg 4935c4bbdfSmrgint 5035c4bbdfSmrgProcRRGetProviders (ClientPtr client) 5135c4bbdfSmrg{ 5235c4bbdfSmrg REQUEST(xRRGetProvidersReq); 5335c4bbdfSmrg xRRGetProvidersReply rep; 5435c4bbdfSmrg WindowPtr pWin; 5535c4bbdfSmrg ScreenPtr pScreen; 5635c4bbdfSmrg rrScrPrivPtr pScrPriv; 5735c4bbdfSmrg int rc; 5835c4bbdfSmrg CARD8 *extra; 5935c4bbdfSmrg unsigned int extraLen; 6035c4bbdfSmrg RRProvider *providers; 6135c4bbdfSmrg int total_providers = 0, count_providers = 0; 6235c4bbdfSmrg ScreenPtr iter; 6335c4bbdfSmrg 6435c4bbdfSmrg REQUEST_SIZE_MATCH(xRRGetProvidersReq); 6535c4bbdfSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 6635c4bbdfSmrg if (rc != Success) 6735c4bbdfSmrg return rc; 6835c4bbdfSmrg 6935c4bbdfSmrg pScreen = pWin->drawable.pScreen; 7035c4bbdfSmrg 7135c4bbdfSmrg pScrPriv = rrGetScrPriv(pScreen); 7235c4bbdfSmrg 7335c4bbdfSmrg if (pScrPriv->provider) 7435c4bbdfSmrg total_providers++; 7535c4bbdfSmrg xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { 7635c4bbdfSmrg pScrPriv = rrGetScrPriv(iter); 7735c4bbdfSmrg total_providers += pScrPriv->provider ? 1 : 0; 7835c4bbdfSmrg } 7935c4bbdfSmrg xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { 8035c4bbdfSmrg pScrPriv = rrGetScrPriv(iter); 8135c4bbdfSmrg total_providers += pScrPriv->provider ? 1 : 0; 8235c4bbdfSmrg } 8335c4bbdfSmrg xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { 8435c4bbdfSmrg pScrPriv = rrGetScrPriv(iter); 8535c4bbdfSmrg total_providers += pScrPriv->provider ? 1 : 0; 8635c4bbdfSmrg } 8735c4bbdfSmrg 8835c4bbdfSmrg pScrPriv = rrGetScrPriv(pScreen); 8935c4bbdfSmrg 9035c4bbdfSmrg if (!pScrPriv) 9135c4bbdfSmrg { 9235c4bbdfSmrg rep = (xRRGetProvidersReply) { 9335c4bbdfSmrg .type = X_Reply, 9435c4bbdfSmrg .sequenceNumber = client->sequence, 9535c4bbdfSmrg .length = 0, 9635c4bbdfSmrg .timestamp = currentTime.milliseconds, 9735c4bbdfSmrg .nProviders = 0 9835c4bbdfSmrg }; 9935c4bbdfSmrg extra = NULL; 10035c4bbdfSmrg extraLen = 0; 10135c4bbdfSmrg } else { 10235c4bbdfSmrg rep = (xRRGetProvidersReply) { 10335c4bbdfSmrg .type = X_Reply, 10435c4bbdfSmrg .sequenceNumber = client->sequence, 10535c4bbdfSmrg .timestamp = pScrPriv->lastSetTime.milliseconds, 10635c4bbdfSmrg .nProviders = total_providers, 10735c4bbdfSmrg .length = total_providers 10835c4bbdfSmrg }; 10935c4bbdfSmrg extraLen = rep.length << 2; 11035c4bbdfSmrg if (extraLen) { 11135c4bbdfSmrg extra = malloc(extraLen); 11235c4bbdfSmrg if (!extra) 11335c4bbdfSmrg return BadAlloc; 11435c4bbdfSmrg } else 11535c4bbdfSmrg extra = NULL; 11635c4bbdfSmrg 11735c4bbdfSmrg providers = (RRProvider *)extra; 11835c4bbdfSmrg ADD_PROVIDER(pScreen); 11935c4bbdfSmrg xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { 12035c4bbdfSmrg ADD_PROVIDER(iter); 12135c4bbdfSmrg } 12235c4bbdfSmrg xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) { 12335c4bbdfSmrg ADD_PROVIDER(iter); 12435c4bbdfSmrg } 12535c4bbdfSmrg xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) { 12635c4bbdfSmrg ADD_PROVIDER(iter); 12735c4bbdfSmrg } 12835c4bbdfSmrg } 12935c4bbdfSmrg 13035c4bbdfSmrg if (client->swapped) { 13135c4bbdfSmrg swaps(&rep.sequenceNumber); 13235c4bbdfSmrg swapl(&rep.length); 13335c4bbdfSmrg swapl(&rep.timestamp); 13435c4bbdfSmrg swaps(&rep.nProviders); 13535c4bbdfSmrg } 13635c4bbdfSmrg WriteToClient(client, sizeof(xRRGetProvidersReply), (char *)&rep); 13735c4bbdfSmrg if (extraLen) 13835c4bbdfSmrg { 13935c4bbdfSmrg WriteToClient (client, extraLen, (char *) extra); 14035c4bbdfSmrg free(extra); 14135c4bbdfSmrg } 14235c4bbdfSmrg return Success; 14335c4bbdfSmrg} 14435c4bbdfSmrg 14535c4bbdfSmrgint 14635c4bbdfSmrgProcRRGetProviderInfo (ClientPtr client) 14735c4bbdfSmrg{ 14835c4bbdfSmrg REQUEST(xRRGetProviderInfoReq); 14935c4bbdfSmrg xRRGetProviderInfoReply rep; 15035c4bbdfSmrg rrScrPrivPtr pScrPriv, pScrProvPriv; 15135c4bbdfSmrg RRProviderPtr provider; 15235c4bbdfSmrg ScreenPtr pScreen; 15335c4bbdfSmrg CARD8 *extra; 15435c4bbdfSmrg unsigned int extraLen = 0; 15535c4bbdfSmrg RRCrtc *crtcs; 15635c4bbdfSmrg RROutput *outputs; 15735c4bbdfSmrg int i; 15835c4bbdfSmrg char *name; 15935c4bbdfSmrg ScreenPtr provscreen; 16035c4bbdfSmrg RRProvider *providers; 16135c4bbdfSmrg uint32_t *prov_cap; 16235c4bbdfSmrg 16335c4bbdfSmrg REQUEST_SIZE_MATCH(xRRGetProviderInfoReq); 16435c4bbdfSmrg VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); 16535c4bbdfSmrg 16635c4bbdfSmrg pScreen = provider->pScreen; 16735c4bbdfSmrg pScrPriv = rrGetScrPriv(pScreen); 16835c4bbdfSmrg 16935c4bbdfSmrg rep = (xRRGetProviderInfoReply) { 17035c4bbdfSmrg .type = X_Reply, 17135c4bbdfSmrg .status = RRSetConfigSuccess, 17235c4bbdfSmrg .sequenceNumber = client->sequence, 17335c4bbdfSmrg .length = 0, 17435c4bbdfSmrg .capabilities = provider->capabilities, 17535c4bbdfSmrg .nameLength = provider->nameLength, 17635c4bbdfSmrg .timestamp = pScrPriv->lastSetTime.milliseconds, 17735c4bbdfSmrg .nCrtcs = pScrPriv->numCrtcs, 17835c4bbdfSmrg .nOutputs = pScrPriv->numOutputs, 17935c4bbdfSmrg .nAssociatedProviders = 0 18035c4bbdfSmrg }; 18135c4bbdfSmrg 18235c4bbdfSmrg /* count associated providers */ 18335c4bbdfSmrg if (provider->offload_sink) 18435c4bbdfSmrg rep.nAssociatedProviders++; 18535c4bbdfSmrg if (provider->output_source) 18635c4bbdfSmrg rep.nAssociatedProviders++; 18735c4bbdfSmrg xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) 18835c4bbdfSmrg rep.nAssociatedProviders++; 18935c4bbdfSmrg xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) 19035c4bbdfSmrg rep.nAssociatedProviders++; 19135c4bbdfSmrg 19235c4bbdfSmrg rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs + 19335c4bbdfSmrg (rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength)); 19435c4bbdfSmrg 19535c4bbdfSmrg extraLen = rep.length << 2; 19635c4bbdfSmrg if (extraLen) { 19735c4bbdfSmrg extra = malloc(extraLen); 19835c4bbdfSmrg if (!extra) 19935c4bbdfSmrg return BadAlloc; 20035c4bbdfSmrg } 20135c4bbdfSmrg else 20235c4bbdfSmrg extra = NULL; 20335c4bbdfSmrg 20435c4bbdfSmrg crtcs = (RRCrtc *)extra; 20535c4bbdfSmrg outputs = (RROutput *)(crtcs + rep.nCrtcs); 20635c4bbdfSmrg providers = (RRProvider *)(outputs + rep.nOutputs); 20735c4bbdfSmrg prov_cap = (unsigned int *)(providers + rep.nAssociatedProviders); 20835c4bbdfSmrg name = (char *)(prov_cap + rep.nAssociatedProviders); 20935c4bbdfSmrg 21035c4bbdfSmrg for (i = 0; i < pScrPriv->numCrtcs; i++) { 21135c4bbdfSmrg crtcs[i] = pScrPriv->crtcs[i]->id; 21235c4bbdfSmrg if (client->swapped) 21335c4bbdfSmrg swapl(&crtcs[i]); 21435c4bbdfSmrg } 21535c4bbdfSmrg 21635c4bbdfSmrg for (i = 0; i < pScrPriv->numOutputs; i++) { 21735c4bbdfSmrg outputs[i] = pScrPriv->outputs[i]->id; 21835c4bbdfSmrg if (client->swapped) 21935c4bbdfSmrg swapl(&outputs[i]); 22035c4bbdfSmrg } 22135c4bbdfSmrg 22235c4bbdfSmrg i = 0; 22335c4bbdfSmrg if (provider->offload_sink) { 22435c4bbdfSmrg providers[i] = provider->offload_sink->id; 22535c4bbdfSmrg if (client->swapped) 22635c4bbdfSmrg swapl(&providers[i]); 22735c4bbdfSmrg prov_cap[i] = RR_Capability_SinkOffload; 22835c4bbdfSmrg if (client->swapped) 22935c4bbdfSmrg swapl(&prov_cap[i]); 23035c4bbdfSmrg i++; 23135c4bbdfSmrg } 23235c4bbdfSmrg if (provider->output_source) { 23335c4bbdfSmrg providers[i] = provider->output_source->id; 23435c4bbdfSmrg if (client->swapped) 23535c4bbdfSmrg swapl(&providers[i]); 23635c4bbdfSmrg prov_cap[i] = RR_Capability_SourceOutput; 23735c4bbdfSmrg swapl(&prov_cap[i]); 23835c4bbdfSmrg i++; 23935c4bbdfSmrg } 24035c4bbdfSmrg xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) { 24135c4bbdfSmrg pScrProvPriv = rrGetScrPriv(provscreen); 24235c4bbdfSmrg providers[i] = pScrProvPriv->provider->id; 24335c4bbdfSmrg if (client->swapped) 24435c4bbdfSmrg swapl(&providers[i]); 24535c4bbdfSmrg prov_cap[i] = RR_Capability_SinkOutput; 24635c4bbdfSmrg if (client->swapped) 24735c4bbdfSmrg swapl(&prov_cap[i]); 24835c4bbdfSmrg i++; 24935c4bbdfSmrg } 25035c4bbdfSmrg xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) { 25135c4bbdfSmrg pScrProvPriv = rrGetScrPriv(provscreen); 25235c4bbdfSmrg providers[i] = pScrProvPriv->provider->id; 25335c4bbdfSmrg if (client->swapped) 25435c4bbdfSmrg swapl(&providers[i]); 25535c4bbdfSmrg prov_cap[i] = RR_Capability_SourceOffload; 25635c4bbdfSmrg if (client->swapped) 25735c4bbdfSmrg swapl(&prov_cap[i]); 25835c4bbdfSmrg i++; 25935c4bbdfSmrg } 26035c4bbdfSmrg 26135c4bbdfSmrg 26235c4bbdfSmrg memcpy(name, provider->name, rep.nameLength); 26335c4bbdfSmrg if (client->swapped) { 26435c4bbdfSmrg swaps(&rep.sequenceNumber); 26535c4bbdfSmrg swapl(&rep.length); 26635c4bbdfSmrg swapl(&rep.capabilities); 26735c4bbdfSmrg swaps(&rep.nCrtcs); 26835c4bbdfSmrg swaps(&rep.nOutputs); 26935c4bbdfSmrg swaps(&rep.nameLength); 27035c4bbdfSmrg } 27135c4bbdfSmrg WriteToClient(client, sizeof(xRRGetProviderInfoReply), (char *)&rep); 27235c4bbdfSmrg if (extraLen) 27335c4bbdfSmrg { 27435c4bbdfSmrg WriteToClient (client, extraLen, (char *) extra); 27535c4bbdfSmrg free(extra); 27635c4bbdfSmrg } 27735c4bbdfSmrg return Success; 27835c4bbdfSmrg} 27935c4bbdfSmrg 28035c4bbdfSmrgint 28135c4bbdfSmrgProcRRSetProviderOutputSource(ClientPtr client) 28235c4bbdfSmrg{ 28335c4bbdfSmrg REQUEST(xRRSetProviderOutputSourceReq); 28435c4bbdfSmrg rrScrPrivPtr pScrPriv; 28535c4bbdfSmrg RRProviderPtr provider, source_provider = NULL; 28635c4bbdfSmrg ScreenPtr pScreen; 28735c4bbdfSmrg 28835c4bbdfSmrg REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq); 28935c4bbdfSmrg 29035c4bbdfSmrg VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); 29135c4bbdfSmrg 29235c4bbdfSmrg if (!(provider->capabilities & RR_Capability_SinkOutput)) 29335c4bbdfSmrg return BadValue; 29435c4bbdfSmrg 29535c4bbdfSmrg if (stuff->source_provider) { 29635c4bbdfSmrg VERIFY_RR_PROVIDER(stuff->source_provider, source_provider, DixReadAccess); 29735c4bbdfSmrg 29835c4bbdfSmrg if (!(source_provider->capabilities & RR_Capability_SourceOutput)) 29935c4bbdfSmrg return BadValue; 30035c4bbdfSmrg } 30135c4bbdfSmrg 30235c4bbdfSmrg pScreen = provider->pScreen; 30335c4bbdfSmrg pScrPriv = rrGetScrPriv(pScreen); 30435c4bbdfSmrg 30535c4bbdfSmrg pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider); 30635c4bbdfSmrg 30735c4bbdfSmrg provider->changed = TRUE; 30835c4bbdfSmrg RRSetChanged(pScreen); 30935c4bbdfSmrg 31035c4bbdfSmrg RRTellChanged (pScreen); 31135c4bbdfSmrg 31235c4bbdfSmrg return Success; 31335c4bbdfSmrg} 31435c4bbdfSmrg 31535c4bbdfSmrgint 31635c4bbdfSmrgProcRRSetProviderOffloadSink(ClientPtr client) 31735c4bbdfSmrg{ 31835c4bbdfSmrg REQUEST(xRRSetProviderOffloadSinkReq); 31935c4bbdfSmrg rrScrPrivPtr pScrPriv; 32035c4bbdfSmrg RRProviderPtr provider, sink_provider = NULL; 32135c4bbdfSmrg ScreenPtr pScreen; 32235c4bbdfSmrg 32335c4bbdfSmrg REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq); 32435c4bbdfSmrg 32535c4bbdfSmrg VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); 32635c4bbdfSmrg if (!(provider->capabilities & RR_Capability_SourceOffload)) 32735c4bbdfSmrg return BadValue; 32835c4bbdfSmrg if (!provider->pScreen->isGPU) 32935c4bbdfSmrg return BadValue; 33035c4bbdfSmrg 33135c4bbdfSmrg if (stuff->sink_provider) { 33235c4bbdfSmrg VERIFY_RR_PROVIDER(stuff->sink_provider, sink_provider, DixReadAccess); 33335c4bbdfSmrg if (!(sink_provider->capabilities & RR_Capability_SinkOffload)) 33435c4bbdfSmrg return BadValue; 33535c4bbdfSmrg } 33635c4bbdfSmrg pScreen = provider->pScreen; 33735c4bbdfSmrg pScrPriv = rrGetScrPriv(pScreen); 33835c4bbdfSmrg 33935c4bbdfSmrg pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider); 34035c4bbdfSmrg 34135c4bbdfSmrg provider->changed = TRUE; 34235c4bbdfSmrg RRSetChanged(pScreen); 34335c4bbdfSmrg 34435c4bbdfSmrg RRTellChanged (pScreen); 34535c4bbdfSmrg 34635c4bbdfSmrg return Success; 34735c4bbdfSmrg} 34835c4bbdfSmrg 34935c4bbdfSmrgRRProviderPtr 35035c4bbdfSmrgRRProviderCreate(ScreenPtr pScreen, const char *name, 35135c4bbdfSmrg int nameLength) 35235c4bbdfSmrg{ 35335c4bbdfSmrg RRProviderPtr provider; 35435c4bbdfSmrg rrScrPrivPtr pScrPriv; 35535c4bbdfSmrg 35635c4bbdfSmrg pScrPriv = rrGetScrPriv(pScreen); 35735c4bbdfSmrg 35835c4bbdfSmrg provider = calloc(1, sizeof(RRProviderRec) + nameLength + 1); 35935c4bbdfSmrg if (!provider) 36035c4bbdfSmrg return NULL; 36135c4bbdfSmrg 36235c4bbdfSmrg provider->id = FakeClientID(0); 36335c4bbdfSmrg provider->pScreen = pScreen; 36435c4bbdfSmrg provider->name = (char *) (provider + 1); 36535c4bbdfSmrg provider->nameLength = nameLength; 36635c4bbdfSmrg memcpy(provider->name, name, nameLength); 36735c4bbdfSmrg provider->name[nameLength] = '\0'; 36835c4bbdfSmrg provider->changed = FALSE; 36935c4bbdfSmrg 37035c4bbdfSmrg if (!AddResource (provider->id, RRProviderType, (void *) provider)) 37135c4bbdfSmrg return NULL; 37235c4bbdfSmrg pScrPriv->provider = provider; 37335c4bbdfSmrg return provider; 37435c4bbdfSmrg} 37535c4bbdfSmrg 37635c4bbdfSmrg/* 37735c4bbdfSmrg * Destroy a provider at shutdown 37835c4bbdfSmrg */ 37935c4bbdfSmrgvoid 38035c4bbdfSmrgRRProviderDestroy (RRProviderPtr provider) 38135c4bbdfSmrg{ 38235c4bbdfSmrg FreeResource (provider->id, 0); 38335c4bbdfSmrg} 38435c4bbdfSmrg 38535c4bbdfSmrgvoid 38635c4bbdfSmrgRRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities) 38735c4bbdfSmrg{ 38835c4bbdfSmrg provider->capabilities = capabilities; 38935c4bbdfSmrg} 39035c4bbdfSmrg 39135c4bbdfSmrgstatic int 39235c4bbdfSmrgRRProviderDestroyResource (void *value, XID pid) 39335c4bbdfSmrg{ 39435c4bbdfSmrg RRProviderPtr provider = (RRProviderPtr)value; 39535c4bbdfSmrg ScreenPtr pScreen = provider->pScreen; 39635c4bbdfSmrg 39735c4bbdfSmrg if (pScreen) 39835c4bbdfSmrg { 39935c4bbdfSmrg rrScrPriv(pScreen); 40035c4bbdfSmrg 40135c4bbdfSmrg if (pScrPriv->rrProviderDestroy) 40235c4bbdfSmrg (*pScrPriv->rrProviderDestroy)(pScreen, provider); 40335c4bbdfSmrg pScrPriv->provider = NULL; 40435c4bbdfSmrg } 40535c4bbdfSmrg free(provider); 40635c4bbdfSmrg return 1; 40735c4bbdfSmrg} 40835c4bbdfSmrg 40935c4bbdfSmrgBool 41035c4bbdfSmrgRRProviderInit(void) 41135c4bbdfSmrg{ 41235c4bbdfSmrg RRProviderType = CreateNewResourceType(RRProviderDestroyResource, "Provider"); 41335c4bbdfSmrg if (!RRProviderType) 41435c4bbdfSmrg return FALSE; 41535c4bbdfSmrg 41635c4bbdfSmrg return TRUE; 41735c4bbdfSmrg} 41835c4bbdfSmrg 41935c4bbdfSmrgextern _X_EXPORT Bool 42035c4bbdfSmrgRRProviderLookup(XID id, RRProviderPtr *provider_p) 42135c4bbdfSmrg{ 42235c4bbdfSmrg int rc = dixLookupResourceByType((void **)provider_p, id, 42335c4bbdfSmrg RRProviderType, NullClient, DixReadAccess); 42435c4bbdfSmrg if (rc == Success) 42535c4bbdfSmrg return TRUE; 42635c4bbdfSmrg return FALSE; 42735c4bbdfSmrg} 42835c4bbdfSmrg 42935c4bbdfSmrgvoid 43035c4bbdfSmrgRRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider) 43135c4bbdfSmrg{ 43235c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 43335c4bbdfSmrg 43435c4bbdfSmrg rrScrPriv(pScreen); 43535c4bbdfSmrg 43635c4bbdfSmrg xRRProviderChangeNotifyEvent pe = { 43735c4bbdfSmrg .type = RRNotify + RREventBase, 43835c4bbdfSmrg .subCode = RRNotify_ProviderChange, 43935c4bbdfSmrg .timestamp = pScrPriv->lastSetTime.milliseconds, 44035c4bbdfSmrg .window = pWin->drawable.id, 44135c4bbdfSmrg .provider = provider->id 44235c4bbdfSmrg }; 44335c4bbdfSmrg 44435c4bbdfSmrg WriteEventsToClient(client, 1, (xEvent *) &pe); 44535c4bbdfSmrg} 446