diff --git a/randr/Makefile.am b/randr/Makefile.am index 868786ecb..0a735574e 100644 --- a/randr/Makefile.am +++ b/randr/Makefile.am @@ -11,6 +11,8 @@ librandr_la_SOURCES = \ randr.c \ randrstr.h \ rrcrtc.c \ + rrdispatch.c \ rrmode.c \ rroutput.c \ - rrscreen.c + rrscreen.c \ + rrsdispatch.c diff --git a/randr/randr.c b/randr/randr.c index 2305b6094..63d471ce0 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -42,10 +42,8 @@ int RRGeneration; int RRNScreens; -static int ProcRRQueryVersion (ClientPtr pClient); static int ProcRRDispatch (ClientPtr pClient); static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); #define wrap(priv,real,mem,func) {\ priv->mem = real->mem; \ @@ -56,57 +54,13 @@ static int SProcRRQueryVersion (ClientPtr pClient); real->mem = priv->mem; \ } -#if 0 -static CARD8 RRReqCode; -static int RRErrBase; -#endif int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; - -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; +int RRErrorBase; +RESTYPE RRClientType, RREventType; /* resource types for event masks */ +int RRClientPrivateIndex; int rrPrivIndex = -1; -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - static void RRClientCallback (CallbackListPtr *list, pointer closure, @@ -289,7 +243,7 @@ RRFreeClient (pointer data, XID id) pRREvent = (RREventPtr) data; pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); if (pHead) { pPrev = 0; for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) @@ -315,7 +269,7 @@ RRFreeEvents (pointer data, XID id) pHead = (RREventPtr *) data; for (pCur = *pHead; pCur; pCur = pNext) { pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); + FreeResource (pCur->clientResource, RRClientType); xfree ((pointer) pCur); } xfree ((pointer) pHead); @@ -337,38 +291,26 @@ RRExtensionInit (void) if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) return; - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) + RRClientType = CreateNewResourceType(RRFreeClient); + if (!RRClientType) return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) + RREventType = CreateNewResourceType(RRFreeEvents); + if (!RREventType) return; extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, ProcRRDispatch, SProcRRDispatch, RRResetProc, StandardMinorOpcode); if (!extEntry) return; -#if 0 - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; -#endif + RRErrorBase = extEntry->errorBase; RREventBase = extEntry->eventBase; EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; + SRRScreenChangeNotifyEvent; EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) SRRNotifyEvent; return; } -static void -DeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) -{ -} - -static void -DeliverOutputEvent (ClientPtr client, WindowPtr pWin, RROutputPtr output) -{ -} static int TellChanged (WindowPtr pWin, pointer value) @@ -379,7 +321,7 @@ TellChanged (WindowPtr pWin, pointer value) rrScrPriv(pScreen); int i; - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); + pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, RREventType); if (!pHead) return WT_WALKCHILDREN; @@ -398,7 +340,7 @@ TellChanged (WindowPtr pWin, pointer value) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; if (crtc->changed) - DeliverCrtcEvent (client, pWin, crtc); + RRDeliverCrtcEvent (client, pWin, crtc); } } @@ -408,7 +350,7 @@ TellChanged (WindowPtr pWin, pointer value) { RROutputPtr output = pScrPriv->outputs[i]; if (output->changed) - DeliverOutputEvent (client, pWin, output); + RRDeliverOutputEvent (client, pWin, output); } } } @@ -438,7 +380,7 @@ RRTellChanged (ScreenPtr pScreen) * Return the first output which is connected to an active CRTC * Used in emulating 1.0 behaviour */ -static RROutputPtr +RROutputPtr RRFirstOutput (ScreenPtr pScreen) { rrScrPriv(pScreen); @@ -459,7 +401,6 @@ RRFirstOutput (ScreenPtr pScreen) } #ifdef RANDR_10_INTERFACE - static RRModePtr RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) { @@ -515,13 +456,31 @@ static void RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) { rrScrPriv(pScreen); - RROutputPtr output = RRFirstOutput (pScreen); + RROutputPtr output; RRCrtcPtr crtc; RRModePtr mode, newMode = NULL; int i; CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT; CARD16 maxWidth = 0, maxHeight = 0; + /* + * First time through, create a crtc and output and hook + * them together + */ + if (pScrPriv->numOutputs == 0 && + pScrPriv->numCrtcs == 0) + { + crtc = RRCrtcCreate (pScreen, NULL); + if (!crtc) + return; + output = RROutputCreate (pScreen, "default", 7, NULL); + if (!output) + return; + RROutputSetCrtcs (output, &crtc, 1); + RROutputSetConnection (output, RR_Connected); + } + + output = RRFirstOutput (pScreen); if (!output) return; crtc = output->crtc; @@ -601,7 +560,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) /* * Poll the driver for changed information */ -static Bool +Bool RRGetInfo (ScreenPtr pScreen) { rrScrPriv (pScreen); @@ -627,44 +586,6 @@ RRGetInfo (ScreenPtr pScreen) return TRUE; } -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - register int n; - REQUEST(xRRQueryVersionReq); - rrClientPriv(client); - - REQUEST_SIZE_MATCH(xRRQueryVersionReq); - pRRClient->major_version = stuff->majorVersion; - pRRClient->minor_version = stuff->minorVersion; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - /* - * Report the current version; the current - * spec says they're all compatible after 1.0 - */ - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - -typedef struct _RR10Data { - RRScreenSizePtr sizes; - int nsize; - int nrefresh; - int size; - CARD16 refresh; -} RR10DataRec, *RR10DataPtr; - CARD16 RRVerticalRefresh (xRRModeInfo *mode) { @@ -677,411 +598,6 @@ RRVerticalRefresh (xRRModeInfo *mode) return (CARD16) refresh; } -/* - * Convert 1.2 monitor data into 1.0 screen data - */ -static RR10DataPtr -RR10GetData (ScreenPtr pScreen, RROutputPtr output) -{ - RR10DataPtr data; - RRScreenSizePtr size; - int nmode = output->numModes; - int i, j, k; - RRScreenRatePtr refresh; - CARD16 vRefresh; - RRModePtr mode; - - /* Make sure there is plenty of space for any combination */ - data = malloc (sizeof (RR10DataRec) + - sizeof (RRScreenSize) * nmode + - sizeof (RRScreenRate) * nmode); - if (!data) - return NULL; - size = (RRScreenSizePtr) (data + 1); - refresh = (RRScreenRatePtr) (size + nmode); - data->sizes = size; - data->nsize = 0; - data->nrefresh = 0; - data->size = 0; - data->refresh = 0; - for (i = 0; i < output->numModes; i++) - { - mode = output->modes[i]; - for (j = 0; j < data->nsize; j++) - if (mode->mode.width == size[j].width && - mode->mode.height == size[j].height) - break; - if (j == data->nsize) - { - size[j].id = j; - size[j].width = mode->mode.width; - size[j].height = mode->mode.height; - size[j].mmWidth = mode->mode.mmWidth; - size[j].mmHeight = mode->mode.mmHeight; - size[j].nRates = 0; - size[j].pRates = &refresh[data->nrefresh]; - data->nsize++; - } - vRefresh = RRVerticalRefresh (&mode->mode); - for (k = 0; k < size[j].nRates; k++) - if (vRefresh == size[j].pRates[k].rate) - break; - if (k == size[j].nRates) - { - size[j].pRates[k].rate = vRefresh; - size[j].pRates[k].mode = mode; - size[j].nRates++; - data->nrefresh++; - } - if (mode == output->crtc->mode) - { - data->size = j; - data->refresh = vRefresh; - } - } - return data; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - unsigned long extraLen; - RROutputPtr output; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - - if (pScrPriv) - RRGetInfo (pScreen); - - output = RRFirstOutput (pScreen); - - if (!pScrPriv || !output) - { - rep.type = X_Reply; - rep.setOfRotations = RR_Rotate_0;; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; - rep.nSizes = 0; - rep.sizeID = 0; - rep.rotation = RR_Rotate_0; - rep.rate = 0; - rep.nrateEnts = 0; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - RR10DataPtr pData; - RRScreenSizePtr pSize; - - pData = RR10GetData (pScreen, output); - if (!pData) - return BadAlloc; - - rep.type = X_Reply; - rep.setOfRotations = output->crtc->rotations; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.rotation = output->crtc->rotation; - rep.nSizes = pData->nsize; - rep.nrateEnts = pData->nrefresh + pData->nsize; - rep.sizeID = pData->size; - rep.rate = pData->refresh; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - { - xfree (pData); - return BadAlloc; - } - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pData->nsize; i++) - { - pSize = &pData->sizes[i]; - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRates; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - *rates = pSize->pRates[j].rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - xfree (pData); - - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", - (unsigned long)(data8 - (CARD8 *) extra), extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -#if 0 - return RRSetConfigSuccess; -} -#endif - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - int i; - Rotation rotation; - int rate; - Bool has_rate; - RROutputPtr output; - RRModePtr mode; - RR10DataPtr pData = NULL; - RRScreenSizePtr pSize; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - output = RRFirstOutput (pScreen); - if (!output) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - pData = RR10GetData (pScreen, output); - if (!pData) - return BadAlloc; - - if (stuff->sizeID >= pData->nsize) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - xfree (pData); - return BadValue; - } - pSize = &pData->sizes[stuff->sizeID]; - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - xfree (pData); - return BadValue; - } - - if ((~output->crtc->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - xfree (pData); - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - if (pSize->pRates[i].rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - xfree (pData); - return BadValue; - } - mode = pSize->pRates[i].mode; - } - else - mode = pSize->pRates[0].mode; - - /* - * Make sure the requested set-time is not older than - * the last set-time - */ - if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) - { - rep.status = RRSetConfigInvalidTime; - goto sendReply; - } - - rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, - 1, &output); - -sendReply: - - if (pData) - xfree (pData); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - #if 0 int RRSetScreenConfig (ScreenPtr pScreen, @@ -1159,478 +675,6 @@ RRSetScreenConfig (ScreenPtr pScreen, } #endif -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask| - RRCrtcChangeNotifyMask| - RROutputChangeNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - pRREvent = NULL; - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - break; - } - - if (!pRREvent) - { - /* build the entry */ - pRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pRREvent) - return BadAlloc; - pRREvent->next = 0; - pRREvent->client = client; - pRREvent->window = pWin; - pRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pRREvent->next = *pHead; - *pHead = pRREvent; - } - /* - * Now see if the client needs an event - */ - if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - RRDeliverScreenEvent (client, pWin, pScreen); - } - } - } - else if (stuff->enable == 0) - { - /* delete the interest */ - if (pHead) { - RREventPtr pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - -/* - * Retrieve valid screen size range - */ -static int ProcRRGetScreenSizeRange (ClientPtr client) -{ - REQUEST(xRRGetScreenSizeRangeReq); - xRRGetScreenSizeRangeReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - rep.type = X_Reply; - rep.pad = 0; - rep.sequenceNumber = client->sequence; - rep.length = 0; - - if (pScrPriv) - { - RRGetInfo (pScreen); - rep.minWidth = pScrPriv->minWidth; - rep.minHeight = pScrPriv->minHeight; - rep.maxWidth = pScrPriv->maxWidth; - rep.maxHeight = pScrPriv->maxHeight; - } - else - { - rep.maxWidth = rep.minWidth = pScreen->width; - rep.maxHeight = rep.minHeight = pScreen->height; - } - if (client->swapped) - { - int n; - - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.minWidth, n); - swaps(&rep.minHeight, n); - swaps(&rep.maxWidth, n); - swaps(&rep.maxHeight, n); - } - WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); - return (client->noClientException); -} - -static int ProcRRSetScreenSize (ClientPtr client) -{ - REQUEST(xRRSetScreenSizeReq); - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRCrtcPtr crtc; - int i; - - REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) - { - client->errorValue = stuff->width; - return BadValue; - } - if (stuff->height < pScrPriv->minHeight || - pScrPriv->maxHeight < stuff->height) - { - client->errorValue = stuff->height; - return BadValue; - } - for (i = 0; i < pScrPriv->numCrtcs; i++) { - crtc = pScrPriv->crtcs[i]; - if (crtc->mode && - (crtc->x + crtc->mode->mode.width > stuff->width || - crtc->y + crtc->mode->mode.height > stuff->height)) - return BadMatch; - } - if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) - { - client->errorValue = 0; - return BadValue; - } - if (!RRScreenSizeSet (pScreen, - stuff->width, stuff->height, - stuff->widthInMillimeters, - stuff->heightInMillimeters)) - { - return BadMatch; - } - return Success; -} - -#if 0 -static int ProcRRGetMonitorInfo (ClientPtr client) -{ - REQUEST(xRRGetMonitorInfoReq); - xRRGetMonitorInfoReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRMonitorPtr pMonitor; - RRModePtr pMode; - int extraLen; - CARD8 *extra; - xRRMonitorInfo *monitor; - xRRMonitorMode *mode; - CARD8 *names; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.type = X_Reply; - rep.pad = 0; - rep.sequenceNumber = client->sequence; - rep.numMonitors = 0; - rep.numModes = 0; - rep.sizeNames = 0; - if (!pScrPriv) - { - extraLen = 0; - extra = NULL; - } - else - { - int i, m, b; - for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) - { - rep.numMonitors++; - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - rep.numModes++; - rep.sizeNames += (1 + pMode->mode.nameLength); - } - } - extraLen = (rep.numMonitors * sizeof (xRRMonitorInfo) + - rep.numModes * sizeof (xRRMonitorMode) + - rep.sizeNames + 3) & ~3; - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - monitor = (xRRMonitorInfo *) extra; - mode = (xRRMonitorMode *) (monitor + rep.numMonitors); - names = (CARD8 *) (mode + rep.numModes); - i = 0; - m = 0; - b = 0; - for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) - { - monitor[i].timestamp = pScrPriv->lastSetTime; - monitor[i].configTimestamp = pScrPriv->lastConfigTime; - monitor[i].x = pMonitor->x; - monitor[i].y = pMonitor->y; - monitor[i].rotation = pMonitor->rotation; - monitor[i].mode = pMonitor->pMode->id; - monitor[i].defaultMode = 0; /* XXX */ - monitor[i].rotations = pMonitor->rotations; - monitor[i].firstMode = m; - monitor[i].numModes = 0; - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - monitor[i].numModes++; - mode[m] = pMode->mode; - names[b] = pMode->mode.nameLength; - b++; - memcpy (names + b, (char *) (pMode + 1), - pMode->mode.nameLength); - b += pMode->mode.nameLength; - m++; - } - i++; - } - if ((char *) (names + ((b + 3) & ~3)) != (char *) extra + extraLen) - FatalError ("RRGetMonitorInfo length mismatch\n"); - } - rep.length = extraLen >> 2; - - WriteToClient(client, sizeof(xRRGetMonitorInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - - if (extra) - xfree (extra); - return (client->noClientException); -} - -static int ProcRRAddMonitorMode (ClientPtr client) -{ - return BadImplementation; -} - -static int ProcRRDeleteMonitorMode (ClientPtr client) -{ - return BadImplementation; -} - -static int ProcRRSetMonitorConfig (ClientPtr client) -{ - REQUEST(xRRSetMonitorConfigReq); - xRRSetMonitorConfigReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRMonitorPtr pMonitor; - RRModePtr pMode; - TimeStamp configTime; - TimeStamp time; - Rotation rotation; - - REQUEST_SIZE_MATCH(xRRSetScreenConfigReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) - { - if (pMonitor->id == stuff->monitorIndex) - break; - } - if (!pMonitor) - { - client->errorValue = stuff->monitorIndex; - return BadValue; - } - - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - if (pMode->id == stuff->modeIndex) - break; - } - if (!pMode) - { - client->errorValue = stuff->modeIndex; - return BadValue; - } - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - return BadValue; - } - - if ((~pMonitor->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - if (stuff->x + pMode->mode.width > pScreen->width) - { - client->errorValue = stufff - stuff->y + pMode->mode.height > pScreen - /* - * Make sure the requested set-time is not older than - * the last set-time - */ - if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) - { - rep.status = RRSetConfigInvalidTime; - goto sendReply; - } - - rep.status = RRMonitorSetMode (pScreen, pMonitor, - pMode, stuff->x, stuff->y, rotation, time); - - return client->noClientException; -} -#endif - -int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { - ProcRRQueryVersion, /* 0 */ -/* we skip 1 to make old clients fail pretty immediately */ - NULL, /* 1 ProcRandrOldGetScreenInfo */ -/* V1.0 apps share the same set screen config request id */ - ProcRRSetScreenConfig, /* 2 */ - NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ -/* 3 used to be ScreenChangeSelectInput; deprecated */ - ProcRRSelectInput, /* 4 */ - ProcRRGetScreenInfo, /* 5 */ -/* V1.2 additions */ -#if 0 - ProcRRGetScreenSizeRange, /* 6 */ - ProcRRSetScreenSize, /* 7 */ - ProcRRGetMonitorInfo, /* 8 */ - ProcRRAddMonitorMode, /* 9 */ - ProcRRDeleteMonitorMode, /* 10 */ - ProcRRSetMonitorConfig, /* 11 */ -#endif -}; - - static int ProcRRDispatch (ClientPtr client) { @@ -1640,82 +684,13 @@ ProcRRDispatch (ClientPtr client) return (*ProcRandrVector[stuff->data]) (client); } -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); -} - - static int SProcRRDispatch (ClientPtr client) { REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) return BadRequest; - } + return (*SProcRandrVector[stuff->data]) (client); } #if RANDR_12_INTERFACE @@ -1741,7 +716,6 @@ RRScreenSetSizeRange (ScreenPtr pScreen, #endif #ifdef RANDR_10_INTERFACE - static Bool RRScreenSizeMatches (RRScreenSizePtr a, RRScreenSizePtr b) diff --git a/randr/randrstr.h b/randr/randrstr.h index f323660d9..33461570f 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -59,8 +59,11 @@ typedef XID RRMode; typedef XID RROutput; typedef XID RRCrtc; -extern int RREventBase; +extern int RREventBase, RRErrorBase; +extern int (*ProcRandrVector[RRNumberRequests])(ClientPtr); +extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr); + /* * Modeline for a monitor. Name follows directly after this struct */ @@ -101,7 +104,7 @@ struct _rrOutput { int numCrtcs; RRCrtcPtr *crtcs; int numClones; - RROutputPtr *outputs; + RROutputPtr *clones; int numModes; RRModePtr *modes; Bool changed; @@ -210,6 +213,42 @@ extern int rrPrivIndex; #define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) #define SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (pointer) (p)) +/* + * each window has a list of clients requesting + * RRNotify events. Each client has a resource + * for each window it selects RRNotify input for, + * this resource is used to delete the RRNotifyRec + * entry from the per-window queue. + */ + +typedef struct _RREvent *RREventPtr; + +typedef struct _RREvent { + RREventPtr next; + ClientPtr client; + WindowPtr window; + XID clientResource; + int mask; +} RREventRec; + +typedef struct _RRTimes { + TimeStamp setTime; + TimeStamp configTime; +} RRTimesRec, *RRTimesPtr; + +typedef struct _RRClient { + int major_version; + int minor_version; +/* RRTimesRec times[0]; */ +} RRClientRec, *RRClientPtr; + +extern RESTYPE RRClientType, RREventType; /* resource types for event masks */ +extern int RRClientPrivateIndex; +extern RESTYPE RRCrtcType, RRModeType, RROutputType; + +#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) +#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) + /* Initialize the extension */ void RRExtensionInit (void); @@ -278,8 +317,17 @@ miRRCrtcSet (ScreenPtr pScreen, void RRTellChanged (ScreenPtr pScreen); +/* + * Poll the driver for changed information + */ +Bool +RRGetInfo (ScreenPtr pScreen); + Bool RRScreenInit(ScreenPtr pScreen); +RROutputPtr +RRFirstOutput (ScreenPtr pScreen); + Rotation RRGetRotation (ScreenPtr pScreen); @@ -338,13 +386,6 @@ RRCrtcPtr RRCrtcCreate (ScreenPtr pScreen, void *devPrivate); - -/* - * Use this value for any num parameter to indicate that - * the related data are unchanged - */ -#define RR_NUM_UNCHANGED -1 - /* * Notify the extension that the Crtc has been reconfigured, * the driver calls this whenever it has updated the mode @@ -358,6 +399,9 @@ RRCrtcNotify (RRCrtcPtr crtc, int numOutput, RROutputPtr *outputs); +void +RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc); + /* * Request that the Crtc be reconfigured */ @@ -382,6 +426,10 @@ RRCrtcDestroy (RRCrtcPtr crtc); Bool RRCrtcInit (void); +/* rrdispatch.c */ +Bool +RRClientKnowsRates (ClientPtr pClient); + /* rrmode.c */ /* * Find, and if necessary, create a mode @@ -438,6 +486,9 @@ Bool RROutputSetConnection (RROutputPtr output, CARD8 connection); +void +RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); + void RROutputDestroy (RROutputPtr output); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index cc5b24d50..d343c3a57 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -22,7 +22,7 @@ #include "randrstr.h" -static RESTYPE CrtcType; +RESTYPE RRCrtcType; /* * Create a CRTC @@ -144,6 +144,12 @@ RRCrtcNotify (RRCrtcPtr crtc, return TRUE; } +void +RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) +{ + +} + /* * Request that the Crtc be reconfigured */ @@ -216,6 +222,7 @@ RRCrtcDestroyResource (pointer value, XID pid) memmove (pScrPriv->crtcs, pScrPriv->crtcs + 1, (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr)); --pScrPriv->numCrtcs; + break; } } free (value); @@ -228,11 +235,11 @@ RRCrtcDestroyResource (pointer value, XID pid) Bool RRCrtcInit (void) { - CrtcType = CreateNewResourceType (RRCrtcDestroyResource); - if (!CrtcType) + RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource); + if (!RRCrtcType) return FALSE; #ifdef XResExtension - RegisterResourceName (CrtcType, "CRTC"); + RegisterResourceName (RRCrtcType, "CRTC"); #endif return TRUE; } diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c new file mode 100644 index 000000000..acf629832 --- /dev/null +++ b/randr/rrdispatch.c @@ -0,0 +1,1034 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "randrstr.h" + +Bool +RRClientKnowsRates (ClientPtr pClient) +{ + rrClientPriv(pClient); + + return (pRRClient->major_version > 1 || + (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); +} + +typedef struct _RR10Data { + RRScreenSizePtr sizes; + int nsize; + int nrefresh; + int size; + CARD16 refresh; +} RR10DataRec, *RR10DataPtr; + +/* + * Convert 1.2 monitor data into 1.0 screen data + */ +static RR10DataPtr +RR10GetData (ScreenPtr pScreen, RROutputPtr output) +{ + RR10DataPtr data; + RRScreenSizePtr size; + int nmode = output->numModes; + int i, j, k; + RRScreenRatePtr refresh; + CARD16 vRefresh; + RRModePtr mode; + + /* Make sure there is plenty of space for any combination */ + data = malloc (sizeof (RR10DataRec) + + sizeof (RRScreenSize) * nmode + + sizeof (RRScreenRate) * nmode); + if (!data) + return NULL; + size = (RRScreenSizePtr) (data + 1); + refresh = (RRScreenRatePtr) (size + nmode); + data->sizes = size; + data->nsize = 0; + data->nrefresh = 0; + data->size = 0; + data->refresh = 0; + for (i = 0; i < output->numModes; i++) + { + mode = output->modes[i]; + for (j = 0; j < data->nsize; j++) + if (mode->mode.width == size[j].width && + mode->mode.height == size[j].height) + break; + if (j == data->nsize) + { + size[j].id = j; + size[j].width = mode->mode.width; + size[j].height = mode->mode.height; + size[j].mmWidth = mode->mode.mmWidth; + size[j].mmHeight = mode->mode.mmHeight; + size[j].nRates = 0; + size[j].pRates = &refresh[data->nrefresh]; + data->nsize++; + } + vRefresh = RRVerticalRefresh (&mode->mode); + for (k = 0; k < size[j].nRates; k++) + if (vRefresh == size[j].pRates[k].rate) + break; + if (k == size[j].nRates) + { + size[j].pRates[k].rate = vRefresh; + size[j].pRates[k].mode = mode; + size[j].nRates++; + data->nrefresh++; + } + if (mode == output->crtc->mode) + { + data->size = j; + data->refresh = vRefresh; + } + } + return data; +} + +static int +ProcRRQueryVersion (ClientPtr client) +{ + xRRQueryVersionReply rep; + register int n; + REQUEST(xRRQueryVersionReq); + rrClientPriv(client); + + REQUEST_SIZE_MATCH(xRRQueryVersionReq); + pRRClient->major_version = stuff->majorVersion; + pRRClient->minor_version = stuff->minorVersion; + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + /* + * Report the current version; the current + * spec says they're all compatible after 1.0 + */ + rep.majorVersion = RANDR_MAJOR; + rep.minorVersion = RANDR_MINOR; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +static int +ProcRRGetScreenInfo (ClientPtr client) +{ + REQUEST(xRRGetScreenInfoReq); + xRRGetScreenInfoReply rep; + WindowPtr pWin; + int n; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + RRGetInfo (pScreen); + + output = RRFirstOutput (pScreen); + + if (!pScrPriv || !output) + { + rep.type = X_Reply; + rep.setOfRotations = RR_Rotate_0;; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nSizes = 0; + rep.sizeID = 0; + rep.rotation = RR_Rotate_0; + rep.rate = 0; + rep.nrateEnts = 0; + extra = 0; + extraLen = 0; + } + else + { + int i, j; + xScreenSizes *size; + CARD16 *rates; + CARD8 *data8; + Bool has_rate = RRClientKnowsRates (client); + RR10DataPtr pData; + RRScreenSizePtr pSize; + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + rep.type = X_Reply; + rep.setOfRotations = output->crtc->rotations; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.rotation = output->crtc->rotation; + rep.nSizes = pData->nsize; + rep.nrateEnts = pData->nrefresh + pData->nsize; + rep.sizeID = pData->size; + rep.rate = pData->refresh; + + extraLen = (rep.nSizes * sizeof (xScreenSizes) + + rep.nrateEnts * sizeof (CARD16)); + + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + { + xfree (pData); + return BadAlloc; + } + /* + * First comes the size information + */ + size = (xScreenSizes *) extra; + rates = (CARD16 *) (size + rep.nSizes); + for (i = 0; i < pData->nsize; i++) + { + pSize = &pData->sizes[i]; + size->widthInPixels = pSize->width; + size->heightInPixels = pSize->height; + size->widthInMillimeters = pSize->mmWidth; + size->heightInMillimeters = pSize->mmHeight; + if (client->swapped) + { + swaps (&size->widthInPixels, n); + swaps (&size->heightInPixels, n); + swaps (&size->widthInMillimeters, n); + swaps (&size->heightInMillimeters, n); + } + size++; + if (has_rate) + { + *rates = pSize->nRates; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + for (j = 0; j < pSize->nRates; j++) + { + *rates = pSize->pRates[j].rate; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + } + } + } + xfree (pData); + + data8 = (CARD8 *) rates; + + if (data8 - (CARD8 *) extra != extraLen) + FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", + (unsigned long)(data8 - (CARD8 *) extra), extraLen); + rep.length = (extraLen + 3) >> 2; + } + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.rotation, n); + swaps(&rep.nSizes, n); + swaps(&rep.sizeID, n); + swaps(&rep.rate, n); + swaps(&rep.nrateEnts, n); + } + WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return (client->noClientException); +} + +static int +ProcRRSetScreenConfig (ClientPtr client) +{ + REQUEST(xRRSetScreenConfigReq); + xRRSetScreenConfigReply rep; + DrawablePtr pDraw; + int n; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp configTime; + TimeStamp time; + int i; + Rotation rotation; + int rate; + Bool has_rate; + RROutputPtr output; + RRModePtr mode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; + + UpdateCurrentTime (); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + has_rate = TRUE; + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + has_rate = FALSE; + } + + SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, + SecurityWriteAccess); + + pScreen = pDraw->pScreen; + + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + output = RRFirstOutput (pScreen); + if (!output) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + if (stuff->sizeID >= pData->nsize) + { + /* + * Invalid size ID + */ + client->errorValue = stuff->sizeID; + xfree (pData); + return BadValue; + } + pSize = &pData->sizes[stuff->sizeID]; + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadValue; + } + + if ((~output->crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadMatch; + } + + /* + * Validate requested refresh + */ + if (has_rate) + rate = (int) stuff->rate; + else + rate = 0; + + if (rate) + { + for (i = 0; i < pSize->nRates; i++) + { + if (pSize->pRates[i].rate == rate) + break; + } + if (i == pSize->nRates) + { + /* + * Invalid rate + */ + client->errorValue = rate; + xfree (pData); + return BadValue; + } + mode = pSize->pRates[i].mode; + } + else + mode = pSize->pRates[0].mode; + + /* + * Make sure the requested set-time is not older than + * the last set-time + */ + if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) + { + rep.status = RRSetConfigInvalidTime; + goto sendReply; + } + + rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, + 1, &output); + +sendReply: + + if (pData) + xfree (pData); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + swapl(&rep.newConfigTimestamp, n); + swapl(&rep.root, n); + } + WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); + + return (client->noClientException); +} + +static int +ProcRRSelectInput (ClientPtr client) +{ + REQUEST(xRRSelectInputReq); + rrClientPriv(client); + RRTimesPtr pTimes; + WindowPtr pWin; + RREventPtr pRREvent, *pHead; + XID clientResource; + + REQUEST_SIZE_MATCH(xRRSelectInputReq); + pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); + if (!pWin) + return BadWindow; + pHead = (RREventPtr *)SecurityLookupIDByType(client, + pWin->drawable.id, RREventType, + SecurityWriteAccess); + + if (stuff->enable & (RRScreenChangeNotifyMask| + RRCrtcChangeNotifyMask| + RROutputChangeNotifyMask)) + { + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv (pScreen); + + pRREvent = NULL; + if (pHead) + { + /* check for existing entry. */ + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) + if (pRREvent->client == client) + break; + } + + if (!pRREvent) + { + /* build the entry */ + pRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); + if (!pRREvent) + return BadAlloc; + pRREvent->next = 0; + pRREvent->client = client; + pRREvent->window = pWin; + pRREvent->mask = stuff->enable; + /* + * add a resource that will be deleted when + * the client goes away + */ + clientResource = FakeClientID (client->index); + pRREvent->clientResource = clientResource; + if (!AddResource (clientResource, RRClientType, (pointer)pRREvent)) + return BadAlloc; + /* + * create a resource to contain a pointer to the list + * of clients selecting input. This must be indirect as + * the list may be arbitrarily rearranged which cannot be + * done through the resource database. + */ + if (!pHead) + { + pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); + if (!pHead || + !AddResource (pWin->drawable.id, RREventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; + } + pRREvent->next = *pHead; + *pHead = pRREvent; + } + /* + * Now see if the client needs an event + */ + if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) + { + pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; + if (CompareTimeStamps (pTimes->setTime, + pScrPriv->lastSetTime) != 0 || + CompareTimeStamps (pTimes->configTime, + pScrPriv->lastConfigTime) != 0) + { + RRDeliverScreenEvent (client, pWin, pScreen); + } + } + } + else if (stuff->enable == 0) + { + /* delete the interest */ + if (pHead) { + RREventPtr pNewRREvent = 0; + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { + if (pRREvent->client == client) + break; + pNewRREvent = pRREvent; + } + if (pRREvent) { + FreeResource (pRREvent->clientResource, RRClientType); + if (pNewRREvent) + pNewRREvent->next = pRREvent->next; + else + *pHead = pRREvent->next; + xfree (pRREvent); + } + } + } + else + { + client->errorValue = stuff->enable; + return BadValue; + } + return Success; +} + +/* + * Retrieve valid screen size range + */ +static int +ProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + xRRGetScreenSizeRangeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + rep.pad = 0; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + if (pScrPriv) + { + RRGetInfo (pScreen); + rep.minWidth = pScrPriv->minWidth; + rep.minHeight = pScrPriv->minHeight; + rep.maxWidth = pScrPriv->maxWidth; + rep.maxHeight = pScrPriv->maxHeight; + } + else + { + rep.maxWidth = rep.minWidth = pScreen->width; + rep.maxHeight = rep.minHeight = pScreen->height; + } + if (client->swapped) + { + int n; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.minWidth, n); + swaps(&rep.minHeight, n); + swaps(&rep.maxWidth, n); + swaps(&rep.maxHeight, n); + } + WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); + return (client->noClientException); +} + +static int ProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + int i; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) + { + client->errorValue = stuff->width; + return BadValue; + } + if (stuff->height < pScrPriv->minHeight || + pScrPriv->maxHeight < stuff->height) + { + client->errorValue = stuff->height; + return BadValue; + } + for (i = 0; i < pScrPriv->numCrtcs; i++) { + crtc = pScrPriv->crtcs[i]; + if (crtc->mode && + (crtc->x + crtc->mode->mode.width > stuff->width || + crtc->y + crtc->mode->mode.height > stuff->height)) + return BadMatch; + } + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + if (!RRScreenSizeSet (pScreen, + stuff->width, stuff->height, + stuff->widthInMillimeters, + stuff->heightInMillimeters)) + { + return BadMatch; + } + return Success; +} + +static int +ProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetOutputInfo (ClientPtr client) +{ + REQUEST(xRRGetOutputInfoReq);; + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRListOutputProperties (ClientPtr client) +{ + REQUEST(xRRListOutputPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRChangeOutputProperty (ClientPtr client) +{ + REQUEST(xRRChangeOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRChangeOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRDeleteOutputProperty (ClientPtr client) +{ + REQUEST(xRRDeleteOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetOutputProperty (ClientPtr client) +{ + REQUEST(xRRGetOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + + REQUEST_SIZE_MATCH(xRRCreateModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRSetCrtcConfig (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigReq); + xRRSetCrtcConfigReply rep; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + RRModePtr mode; + int numOutputs; + RROutputPtr *outputs = NULL; + RROutput *outputIds; + TimeStamp configTime; + TimeStamp time; + Rotation rotation; + int i, j; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2); + + crtc = LookupIDByType (stuff->crtc, RRCrtcType); + if (!crtc) + { + client->errorValue = stuff->crtc; + return RRErrorBase + BadCrtc; + } + if (stuff->mode == None) + { + mode = NULL; + if (numOutputs > 0) + return BadMatch; + } + else + { + mode = LookupIDByType (stuff->mode, RRModeType); + if (!mode) + { + client->errorValue = stuff->mode; + return RRErrorBase + BadMode; + } + if (numOutputs == 0) + return BadMatch; + } + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + + outputIds = (RROutput *) (stuff + 1); + for (i = 0; i < numOutputs; i++) + { + outputs[i] = LookupIDByType (outputIds[i], RROutputType); + if (!outputs[i]) + { + client->errorValue = outputIds[i]; + return RRErrorBase + BadOutput; + } + /* validate crtc for this output */ + for (j = 0; j < outputs[i]->numCrtcs; j++) + if (outputs[i]->crtcs[j] == crtc) + break; + if (j == outputs[j]->numCrtcs) + return BadMatch; + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes; j++) + if (outputs[i]->modes[j] == mode) + break; + if (j == outputs[j]->numModes) + return BadMatch; + } + + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + return BadValue; + } + + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + return BadMatch; + } + + if (stuff->x + mode->mode.width > pScreen->width) + { + client->errorValue = stuff->x; + return BadValue; + } + + if (stuff->y + mode->mode.height > pScreen->height) + { + client->errorValue = stuff->y; + return BadValue; + } + + /* + * Make sure the requested set-time is not older than + * the last set-time + */ + if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) + { + rep.status = RRSetConfigInvalidTime; + goto sendReply; + } + + rep.status = RRCrtcSet (crtc, mode, stuff->x, stuff->y, + rotation, numOutputs, outputs); + +sendReply: + if (outputs) + xfree (outputs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds; + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + } + WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); + + return client->noClientException; +} + +static int +ProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { + ProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 ProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + ProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + ProcRRSelectInput, /* 4 */ + ProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + ProcRRGetScreenSizeRange, /* 6 */ + ProcRRSetScreenSize, /* 7 */ + ProcRRGetScreenResources, /* 8 */ + ProcRRGetOutputInfo, /* 9 */ + ProcRRListOutputProperties, /* 10 */ + ProcRRChangeOutputProperty, /* 11 */ + ProcRRDeleteOutputProperty, /* 12 */ + ProcRRGetOutputProperty, /* 13 */ + ProcRRCreateMode, /* 14 */ + ProcRRDestroyMode, /* 15 */ + ProcRRAddOutputMode, /* 16 */ + ProcRRDeleteOutputMode, /* 17 */ + ProcRRGetCrtcInfo, /* 18 */ + ProcRRSetCrtcConfig, /* 19 */ + ProcRRGetCrtcGammaSize, /* 20 */ + ProcRRGetCrtcGamma, /* 21 */ + ProcRRSetCrtcGamma, /* 22 */ +}; + diff --git a/randr/rrmode.c b/randr/rrmode.c index 1eb53c388..3a9d55671 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -22,7 +22,7 @@ #include "randrstr.h" -static RESTYPE ModeType; +RESTYPE RRModeType; RRModePtr RRModeGet (ScreenPtr pScreen, @@ -50,7 +50,7 @@ RRModeGet (ScreenPtr pScreen, memcpy (mode->name, name, modeInfo->nameLength); mode->name[modeInfo->nameLength] = '\0'; mode->id = FakeClientID(0); - if (!AddResource (mode->id, ModeType, (pointer) mode)) + if (!AddResource (mode->id, RRModeType, (pointer) mode)) return NULL; ++mode->refcnt; pScrPriv->changed = TRUE; @@ -75,11 +75,11 @@ RRModeDestroyResource (pointer value, XID pid) Bool RRModeInit (void) { - ModeType = CreateNewResourceType (RRModeDestroyResource); - if (!ModeType) + RRModeType = CreateNewResourceType (RRModeDestroyResource); + if (!RRModeType) return FALSE; #ifdef XResExtension - RegisterResourceName (ModeType, "MODE"); + RegisterResourceName (RRModeType, "MODE"); #endif return TRUE; } diff --git a/randr/rroutput.c b/randr/rroutput.c index c7e7995fc..6b67f1997 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -22,7 +22,124 @@ #include "randrstr.h" -static RESTYPE OutputType; +RESTYPE RROutputType; + +/* + * Create an output + */ + +RROutputPtr +RROutputCreate (ScreenPtr pScreen, + char *name, + int nameLength, + void *devPrivate) +{ + rrScrPriv (pScreen); + RROutputPtr output; + RROutputPtr *outputs; + + output = xalloc (sizeof (RROutputRec) + nameLength + 1); + if (!output) + return NULL; + if (pScrPriv->numOutputs) + outputs = xrealloc (pScrPriv->outputs, + (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr)); + else + outputs = xalloc (sizeof (RROutputPtr)); + if (!outputs) + { + xfree (output); + return NULL; + } + output->id = FakeClientID (0); + output->pScreen = pScreen; + output->name = (char *) (output + 1); + output->nameLength = nameLength; + memcpy (output->name, name, nameLength); + output->connection = RR_UnknownConnection; + output->subpixelOrder = SubPixelUnknown; + output->crtc = NULL; + output->numCrtcs = 0; + output->crtcs = NULL; + output->numClones = 0; + output->clones = NULL; + output->numModes = 0; + output->modes = NULL; + output->changed = TRUE; + output->devPrivate = devPrivate; + pScrPriv->outputs[pScrPriv->numOutputs++] = output; + return output; +} + +/* + * Notify extension that output parameters have been changed + */ +Bool +RROutputSetClones (RROutputPtr output, + RROutputPtr *clones, + int numClones) +{ + RROutputPtr *newClones; + + newClones = xalloc (numClones * sizeof (RROutputPtr)); + if (!newClones) + return FALSE; + if (output->clones) + xfree (output->clones); + memcpy (newClones, clones, numClones * sizeof (RROutputPtr)); + output->clones = newClones; + output->numClones = numClones; + return TRUE; +} + +Bool +RROutputSetModes (RROutputPtr output, + RRModePtr *modes, + int numModes) +{ + RRModePtr *newModes; + + newModes = xalloc (numModes * sizeof (RRModePtr)); + if (!newModes) + return FALSE; + if (output->modes) + xfree (output->modes); + memcpy (newModes, modes, numModes * sizeof (RRModePtr)); + output->modes = newModes; + output->numModes = numModes; + return TRUE; +} + +Bool +RROutputSetCrtcs (RROutputPtr output, + RRCrtcPtr *crtcs, + int numCrtcs) +{ + RRCrtcPtr *newCrtcs; + + newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr)); + if (!newCrtcs) + return FALSE; + if (output->crtcs) + xfree (output->crtcs); + memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr)); + output->crtcs = newCrtcs; + output->numCrtcs = numCrtcs; + return TRUE; +} + +Bool +RROutputSetConnection (RROutputPtr output, + CARD8 connection) +{ + output->connection = connection; + return TRUE; +} + +void +RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) +{ +} /* * Destroy a Output at shutdown @@ -36,7 +153,28 @@ RROutputDestroy (RROutputPtr crtc) static int RROutputDestroyResource (pointer value, XID pid) { - free (value); + RROutputPtr output = (RROutputPtr) value; + ScreenPtr pScreen = output->pScreen; + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numOutputs; i++) + { + if (pScrPriv->outputs[i] == output) + { + memmove (pScrPriv->outputs, pScrPriv->outputs + 1, + (pScrPriv->numOutputs - (i - 1)) * sizeof (RROutputPtr)); + --pScrPriv->numOutputs; + break; + } + } + if (output->modes) + xfree (output->modes); + if (output->crtcs) + xfree (output->crtcs); + if (output->clones) + xfree (output->clones); + xfree (output); return 1; } @@ -46,11 +184,11 @@ RROutputDestroyResource (pointer value, XID pid) Bool RROutputInit (void) { - OutputType = CreateNewResourceType (RROutputDestroyResource); - if (!OutputType) + RROutputType = CreateNewResourceType (RROutputDestroyResource); + if (!RROutputType) return FALSE; #ifdef XResExtension - RegisterResourceName (OutputType, "OUTPUT"); + RegisterResourceName (RROutputType, "OUTPUT"); #endif return TRUE; } diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c new file mode 100644 index 000000000..bf81f8bdb --- /dev/null +++ b/randr/rrsdispatch.c @@ -0,0 +1,282 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "randrstr.h" + +static int +SProcRRQueryVersion (ClientPtr client) +{ + register int n; + REQUEST(xRRQueryVersionReq); + + swaps(&stuff->length, n); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenInfo (ClientPtr client) +{ + register int n; + REQUEST(xRRGetScreenInfoReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetScreenConfig (ClientPtr client) +{ + register int n; + REQUEST(xRRSetScreenConfigReq); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + swaps (&stuff->rate, n); + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + } + + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + swapl(&stuff->timestamp, n); + swaps(&stuff->sizeID, n); + swaps(&stuff->rotation, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSelectInput (ClientPtr client) +{ + register int n; + REQUEST(xRRSelectInputReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + + REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetOutputInfo (ClientPtr client) +{ + REQUEST(xRRGetOutputInfoReq);; + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRListOutputProperties (ClientPtr client) +{ + REQUEST(xRRListOutputPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRChangeOutputProperty (ClientPtr client) +{ + REQUEST(xRRChangeOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRChangeOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRDeleteOutputProperty (ClientPtr client) +{ + REQUEST(xRRDeleteOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetOutputProperty (ClientPtr client) +{ + REQUEST(xRRGetOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + + REQUEST_SIZE_MATCH(xRRCreateModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRSetCrtcConfig (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcConfigReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { + SProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 SProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + SProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 SProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + SProcRRSelectInput, /* 4 */ + SProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + SProcRRGetScreenSizeRange, /* 6 */ + SProcRRSetScreenSize, /* 7 */ + SProcRRGetScreenResources, /* 8 */ + SProcRRGetOutputInfo, /* 9 */ + SProcRRListOutputProperties,/* 10 */ + SProcRRChangeOutputProperty,/* 11 */ + SProcRRDeleteOutputProperty,/* 12 */ + SProcRRGetOutputProperty, /* 13 */ + SProcRRCreateMode, /* 14 */ + SProcRRDestroyMode, /* 15 */ + SProcRRAddOutputMode, /* 16 */ + SProcRRDeleteOutputMode, /* 17 */ + SProcRRGetCrtcInfo, /* 18 */ + SProcRRSetCrtcConfig, /* 19 */ + SProcRRGetCrtcGammaSize, /* 20 */ + SProcRRGetCrtcGamma, /* 21 */ + SProcRRSetCrtcGamma, /* 22 */ +}; +