void RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, int *y) { rrScrPriv (pScreen); int i; /* intentional dead space -> let it float */ if (pScrPriv->discontiguous) return; /* if we're moving inside a crtc, we're fine */ for (i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; int left, right, top, bottom; if (!crtc->mode) continue; crtc_bounds(crtc, &left, &right, &top, &bottom); if ((*x >= left) && (*x <= right) && (*y >= top) && (*y <= bottom)) return; } /* if we're trying to escape, clamp to the CRTC we're coming from */ for (i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; int nx, ny; int left, right, top, bottom; if (!crtc->mode) continue; crtc_bounds(crtc, &left, &right, &top, &bottom); miPointerGetPosition(pDev, &nx, &ny); if ((nx >= left) && (nx <= right) && (ny >= top) && (ny <= bottom)) { if ((*x <= left) || (*x >= right)) { int dx = *x - nx; if (dx > 0) *x = right; else if (dx < 0) *x = left; } if ((*y <= top) || (*y >= bottom)) { int dy = *y - ny; if (dy > 0) *y = bottom; else if (dy < 0) *y = top; } return; } } }
static void chipsRandRInit (ScreenPtr pScreen) { rrScrPriv(pScreen); pScrPriv->rrSetConfig = chipsRandRSetConfig; }
/* * Poll the driver for changed information */ Bool RRGetInfo (ScreenPtr pScreen) { rrScrPriv (pScreen); Rotation rotations; int i; for (i = 0; i < pScrPriv->numOutputs; i++) pScrPriv->outputs[i]->changed = FALSE; for (i = 0; i < pScrPriv->numCrtcs; i++) pScrPriv->crtcs[i]->changed = FALSE; rotations = 0; pScrPriv->changed = FALSE; pScrPriv->configChanged = FALSE; if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) return FALSE; #if RANDR_10_INTERFACE if (pScrPriv->nSizes) RRScanOldConfig (pScreen, rotations); #endif RRTellChanged (pScreen); return TRUE; }
static void RRClientCallback (CallbackListPtr *list, pointer closure, pointer data) { NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; ClientPtr pClient = clientinfo->client; rrClientPriv(pClient); RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); int i; pRRClient->major_version = 0; pRRClient->minor_version = 0; for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; rrScrPriv(pScreen); if (pScrPriv) { pTimes[i].setTime = pScrPriv->lastSetTime; pTimes[i].configTime = pScrPriv->lastConfigTime; } } }
void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); xRROutputChangeNotifyEvent oe; RRCrtcPtr crtc = output->crtc; RRModePtr mode = crtc ? crtc->mode : 0; oe.type = RRNotify + RREventBase; oe.subCode = RRNotify_OutputChange; oe.timestamp = pScrPriv->lastSetTime.milliseconds; oe.configTimestamp = pScrPriv->lastConfigTime.milliseconds; oe.window = pWin->drawable.id; oe.output = output->id; if (crtc) { oe.crtc = crtc->id; oe.mode = mode ? mode->mode.id : None; oe.rotation = crtc->rotation; } else { oe.crtc = None; oe.mode = None; oe.rotation = RR_Rotate_0; } oe.connection = output->connection; oe.subpixelOrder = output->subpixelOrder; WriteEventsToClient(client, 1, (xEvent *) &oe); }
static void RRComputeContiguity (ScreenPtr pScreen) { rrScrPriv(pScreen); Bool discontiguous = TRUE; int i, n = pScrPriv->numCrtcs; int *reachable = calloc(n, sizeof(int)); if (!reachable) goto out; /* Find first enabled CRTC and start search for reachable CRTCs from it */ for (i = 0; i < n; ++i) { if (pScrPriv->crtcs[i]->mode) { mark_crtcs(pScrPriv, reachable, i); break; } } /* Check that all enabled CRTCs were marked as reachable */ for (i = 0; i < n; ++i) if (pScrPriv->crtcs[i]->mode && !reachable[i]) goto out; discontiguous = FALSE; out: free(reachable); pScrPriv->discontiguous = discontiguous; }
/* * Something changed; send events and adjust pointer position */ void RRTellChanged (ScreenPtr pScreen) { rrScrPriv (pScreen); int i; if (pScrPriv->changed) { UpdateCurrentTime (); if (pScrPriv->configChanged) { pScrPriv->lastConfigTime = currentTime; pScrPriv->configChanged = FALSE; } pScrPriv->changed = FALSE; WalkTree (pScreen, TellChanged, (pointer) pScreen); for (i = 0; i < pScrPriv->numOutputs; i++) pScrPriv->outputs[i]->changed = FALSE; for (i = 0; i < pScrPriv->numCrtcs; i++) pScrPriv->crtcs[i]->changed = FALSE; if (pScrPriv->layoutChanged) { pScrPriv->layoutChanged = FALSE; RRPointerScreenConfigured (pScreen); RRSendConfigNotify (pScreen); } } }
void RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) { ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv (pScreen); xRRCrtcChangeNotifyEvent ce; RRModePtr mode = crtc->mode; ce.type = RRNotify + RREventBase; ce.subCode = RRNotify_CrtcChange; ce.timestamp = pScrPriv->lastSetTime.milliseconds; ce.window = pWin->drawable.id; ce.crtc = crtc->id; ce.rotation = crtc->rotation; if (mode) { ce.mode = mode->mode.id; ce.x = crtc->x; ce.y = crtc->y; ce.width = mode->mode.width; ce.height = mode->mode.height; } else { ce.mode = None; ce.x = 0; ce.y = 0; ce.width = 0; ce.height = 0; } WriteEventsToClient (client, 1, (xEvent *) &ce); }
/* * Poll the driver for changed information */ Bool RRGetInfo(ScreenPtr pScreen, Bool force_query) { rrScrPriv(pScreen); Rotation rotations; int i; /* Return immediately if we don't need to re-query and we already have the * information. */ if (!force_query) { if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0) return TRUE; } for (i = 0; i < pScrPriv->numOutputs; i++) pScrPriv->outputs[i]->changed = FALSE; for (i = 0; i < pScrPriv->numCrtcs; i++) pScrPriv->crtcs[i]->changed = FALSE; rotations = 0; pScrPriv->changed = FALSE; pScrPriv->configChanged = FALSE; if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) return FALSE; #if RANDR_10_INTERFACE if (pScrPriv->nSizes) RRScanOldConfig(pScreen, rotations); #endif RRTellChanged(pScreen); return TRUE; }
static int RRCrtcDestroyResource (pointer value, XID pid) { RRCrtcPtr crtc = (RRCrtcPtr) value; ScreenPtr pScreen = crtc->pScreen; if (pScreen) { rrScrPriv(pScreen); int i; for (i = 0; i < pScrPriv->numCrtcs; i++) { if (pScrPriv->crtcs[i] == crtc) { memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr)); --pScrPriv->numCrtcs; break; } } } free(crtc->gammaRed); if (crtc->mode) RRModeDestroy (crtc->mode); free(crtc); return 1; }
void RRPointerMoved(ScreenPtr pScreen, int x, int y) { rrScrPriv(pScreen); RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc; int c; /* Check last known CRTC */ if (pointerCrtc && RRCrtcContainsPosition(pointerCrtc, x, y)) return; /* Check all CRTCs */ for (c = 0; c < pScrPriv->numCrtcs; c++) { RRCrtcPtr crtc = pScrPriv->crtcs[c]; if (RRCrtcContainsPosition(crtc, x, y)) { /* Remember containing CRTC */ pScrPriv->pointerCrtc = crtc; return; } } /* None contain pointer, find nearest */ ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n"); RRPointerToNearestCrtc(inputInfo.pointer, pScreen, x, y, pointerCrtc); }
RRScreenSizePtr RRRegisterSize (ScreenPtr pScreen, short width, short height, short mmWidth, short mmHeight) { rrScrPriv (pScreen); int i; RRScreenSize tmp; RRScreenSizePtr pNew; if (!pScrPriv) return 0; tmp.id = 0; tmp.width = width; tmp.height= height; tmp.mmWidth = mmWidth; tmp.mmHeight = mmHeight; tmp.pRates = 0; tmp.nRates = 0; for (i = 0; i < pScrPriv->nSizes; i++) if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) return &pScrPriv->pSizes[i]; pNew = xrealloc (pScrPriv->pSizes, (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); if (!pNew) return 0; pNew[pScrPriv->nSizes++] = tmp; pScrPriv->pSizes = pNew; return &pNew[pScrPriv->nSizes-1]; }
void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); RRCrtcPtr crtc = output->crtc; RRModePtr mode = crtc ? crtc->mode : NULL; xRROutputChangeNotifyEvent oe = { .type = RRNotify + RREventBase, .subCode = RRNotify_OutputChange, .timestamp = pScrPriv->lastSetTime.milliseconds, .configTimestamp = pScrPriv->lastConfigTime.milliseconds, .window = pWin->drawable.id, .output = output->id, .crtc = crtc ? crtc->id : None, .mode = mode ? mode->mode.id : None, .rotation = crtc ? crtc->rotation : RR_Rotate_0, .connection = output->connection, .subpixelOrder = output->subpixelOrder }; WriteEventsToClient(client, 1, (xEvent *) &oe); } /* * Destroy a Output at shutdown */ void RROutputDestroy(RROutputPtr output) { FreeResource(output->id, 0); }
void RRSetCurrentConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize) { rrScrPriv(pScreen); if (!pScrPriv) return; pScrPriv->size = pSize - pScrPriv->pSizes; pScrPriv->rotation = rotation; pScrPriv->rate = rate; }
/* * Notify the output of some change */ void RROutputChanged(RROutputPtr output, Bool configChanged) { ScreenPtr pScreen = output->pScreen; output->changed = TRUE; if (pScreen) { rrScrPriv(pScreen); pScrPriv->changed = TRUE; if (configChanged) pScrPriv->configChanged = TRUE; } }
/* * Find the CRTC nearest the specified position, ignoring 'skip' */ static void RRPointerToNearestCrtc(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) { rrScrPriv(pScreen); int c; RRCrtcPtr nearest = NULL; int best = 0; int best_dx = 0, best_dy = 0; for (c = 0; c < pScrPriv->numCrtcs; c++) { RRCrtcPtr crtc = pScrPriv->crtcs[c]; RRModePtr mode = crtc->mode; int dx, dy; int dist; int scan_width, scan_height; if (!mode) continue; if (crtc == skip) continue; RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height); if (x < crtc->x) dx = crtc->x - x; else if (x > crtc->x + scan_width - 1) dx = crtc->x + (scan_width - 1) - x; else dx = 0; if (y < crtc->y) dy = crtc->y - y; else if (y > crtc->y + scan_height - 1) dy = crtc->y + (scan_height - 1) - y; else dy = 0; dist = dx * dx + dy * dy; if (!nearest || dist < best) { nearest = crtc; best_dx = dx; best_dy = dy; best = dist; } } if (best_dx || best_dy) (*pScreen->SetCursorPosition) (pDev, pScreen, x + best_dx, y + best_dy, TRUE); pScrPriv->pointerCrtc = nearest; }
static RRModePtr RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) { ScreenPtr pScreen = output->pScreen; rrScrPriv(pScreen); xRRModeInfo modeInfo; char name[100]; RRModePtr mode; int i; RRModePtr *modes; memset (&modeInfo, '\0', sizeof (modeInfo)); sprintf (name, "%dx%d", size->width, size->height); modeInfo.width = size->width; modeInfo.height = size->height; modeInfo.hTotal = size->width; modeInfo.vTotal = size->height; modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height * (CARD32) refresh); modeInfo.nameLength = strlen (name); mode = RRModeGet (&modeInfo, name); if (!mode) return NULL; for (i = 0; i < output->numModes; i++) if (output->modes[i] == mode) { RRModeDestroy (mode); return mode; } if (output->numModes) modes = xrealloc (output->modes, (output->numModes + 1) * sizeof (RRModePtr)); else modes = xalloc (sizeof (RRModePtr)); if (!modes) { RRModeDestroy (mode); FreeResource (mode->mode.id, 0); return NULL; } modes[output->numModes++] = mode; output->modes = modes; output->changed = TRUE; pScrPriv->changed = TRUE; pScrPriv->configChanged = TRUE; return mode; }
static Bool RRCrtcPendingProperties (RRCrtcPtr crtc) { ScreenPtr pScreen = crtc->pScreen; rrScrPriv(pScreen); int o; for (o = 0; o < pScrPriv->numOutputs; o++) { RROutputPtr output = pScrPriv->outputs[o]; if (output->crtc == crtc && output->pendingProperties) return TRUE; } return FALSE; }
/* * Notify the CRTC of some change */ void RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged) { ScreenPtr pScreen = crtc->pScreen; crtc->changed = TRUE; if (pScreen) { rrScrPriv(pScreen); pScrPriv->changed = TRUE; /* * Send ConfigureNotify on any layout change */ if (layoutChanged) pScrPriv->layoutChanged = TRUE; } }
static int TellChanged (WindowPtr pWin, pointer value) { RREventPtr *pHead, pRREvent; ClientPtr client; ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); int i; dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, RREventType, serverClient, DixReadAccess); if (!pHead) return WT_WALKCHILDREN; for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { client = pRREvent->client; if (client == serverClient || client->clientGone) continue; if (pRREvent->mask & RRScreenChangeNotifyMask) RRDeliverScreenEvent (client, pWin, pScreen); if (pRREvent->mask & RRCrtcChangeNotifyMask) { for (i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; if (crtc->changed) RRDeliverCrtcEvent (client, pWin, crtc); } } if (pRREvent->mask & RROutputChangeNotifyMask) { for (i = 0; i < pScrPriv->numOutputs; i++) { RROutputPtr output = pScrPriv->outputs[i]; if (output->changed) RRDeliverOutputEvent (client, pWin, output); } } } return WT_WALKCHILDREN; }
/* * Request current gamma back from the DDX (if possible). * This includes gamma size. */ Bool RRCrtcGammaGet(RRCrtcPtr crtc) { Bool ret = TRUE; #if RANDR_12_INTERFACE ScreenPtr pScreen = crtc->pScreen; #endif #if RANDR_12_INTERFACE if (pScreen) { rrScrPriv(pScreen); if (pScrPriv->rrCrtcGetGamma) ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc); } #endif return ret; }
static Bool RRCloseScreen (int i, ScreenPtr pScreen) { rrScrPriv(pScreen); int j; unwrap (pScrPriv, pScreen, CloseScreen); for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) RRCrtcDestroy (pScrPriv->crtcs[j]); for (j = pScrPriv->numOutputs - 1; j >= 0; j--) RROutputDestroy (pScrPriv->outputs[j]); xfree (pScrPriv->crtcs); xfree (pScrPriv->outputs); xfree (pScrPriv); RRNScreens -= 1; /* ok, one fewer screen with RandR running */ return (*pScreen->CloseScreen) (i, pScreen); }
static int RROutputDestroyResource(void *value, XID pid) { RROutputPtr output = (RROutputPtr) value; ScreenPtr pScreen = output->pScreen; int m; if (pScreen) { rrScrPriv(pScreen); int i; if (pScrPriv->primaryOutput == output) pScrPriv->primaryOutput = NULL; for (i = 0; i < pScrPriv->numOutputs; i++) { if (pScrPriv->outputs[i] == output) { memmove(pScrPriv->outputs + i, pScrPriv->outputs + i + 1, (pScrPriv->numOutputs - (i + 1)) * sizeof(RROutputPtr)); --pScrPriv->numOutputs; break; } } RRResourcesChanged(pScreen); } if (output->modes) { for (m = 0; m < output->numModes; m++) RRModeDestroy(output->modes[m]); free(output->modes); } for (m = 0; m < output->numUserModes; m++) RRModeDestroy(output->userModes[m]); free(output->userModes); free(output->crtcs); free(output->clones); RRDeleteAllOutputProperties(output); free(output); return 1; }
Bool RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue) { Bool ret = TRUE; #if RANDR_12_INTERFACE ScreenPtr pScreen = crtc->pScreen; #endif memcpy(crtc->gammaRed, red, crtc->gammaSize * sizeof(CARD16)); memcpy(crtc->gammaGreen, green, crtc->gammaSize * sizeof(CARD16)); memcpy(crtc->gammaBlue, blue, crtc->gammaSize * sizeof(CARD16)); #if RANDR_12_INTERFACE if (pScreen) { rrScrPriv(pScreen); if (pScrPriv->rrCrtcSetGamma) ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc); } #endif return ret; }
/* * Register the range of sizes for the screen */ void RRScreenSetSizeRange(ScreenPtr pScreen, CARD16 minWidth, CARD16 minHeight, CARD16 maxWidth, CARD16 maxHeight) { rrScrPriv(pScreen); if (!pScrPriv) return; if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight && pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight) { return; } pScrPriv->minWidth = minWidth; pScrPriv->minHeight = minHeight; pScrPriv->maxWidth = maxWidth; pScrPriv->maxHeight = maxHeight; pScrPriv->changed = TRUE; pScrPriv->configChanged = TRUE; }
/* * Return the first output which is connected to an active CRTC * Used in emulating 1.0 behaviour */ RROutputPtr RRFirstOutput (ScreenPtr pScreen) { rrScrPriv(pScreen); RROutputPtr output; int i, j; if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) return pScrPriv->primaryOutput; for (i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; for (j = 0; j < pScrPriv->numOutputs; j++) { output = pScrPriv->outputs[j]; if (output->crtc == crtc) return output; } } return NULL; }
Bool RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate) { rrScrPriv(pScreen); int i; RRScreenRatePtr pNew, pRate; if (!pScrPriv) return FALSE; for (i = 0; i < pSize->nRates; i++) if (pSize->pRates[i].rate == rate) return TRUE; pNew = realloc(pSize->pRates, (pSize->nRates + 1) * sizeof(RRScreenRate)); if (!pNew) return FALSE; pRate = &pNew[pSize->nRates++]; pRate->rate = rate; pSize->pRates = pNew; return TRUE; }
int RROutputAddUserMode(RROutputPtr output, RRModePtr mode) { int m; ScreenPtr pScreen = output->pScreen; rrScrPriv(pScreen); RRModePtr *newModes; /* Check to see if this mode is already listed for this output */ for (m = 0; m < output->numModes + output->numUserModes; m++) { RRModePtr e = (m < output->numModes ? output->modes[m] : output->userModes[m - output->numModes]); if (mode == e) return Success; } /* Check with the DDX to see if this mode is OK */ if (pScrPriv->rrOutputValidateMode) if (!pScrPriv->rrOutputValidateMode(pScreen, output, mode)) return BadMatch; if (output->userModes) newModes = realloc(output->userModes, (output->numUserModes + 1) * sizeof(RRModePtr)); else newModes = malloc(sizeof(RRModePtr)); if (!newModes) return BadAlloc; output->userModes = newModes; output->userModes[output->numUserModes++] = mode; ++mode->refcnt; RROutputChanged(output, TRUE); RRTellChanged(pScreen); return Success; }
/* * Request that the Crtc be reconfigured */ Bool RRCrtcSet (RRCrtcPtr crtc, RRModePtr mode, int x, int y, Rotation rotation, int numOutputs, RROutputPtr *outputs) { ScreenPtr pScreen = crtc->pScreen; Bool ret = FALSE; rrScrPriv(pScreen); /* See if nothing changed */ if (crtc->mode == mode && crtc->x == x && crtc->y == y && crtc->rotation == rotation && crtc->numOutputs == numOutputs && !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && !RRCrtcPendingProperties (crtc) && !RRCrtcPendingTransform (crtc)) { ret = TRUE; } else { #if RANDR_12_INTERFACE if (pScrPriv->rrCrtcSet) { ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, rotation, numOutputs, outputs); } else #endif { #if RANDR_10_INTERFACE if (pScrPriv->rrSetConfig) { RRScreenSize size; RRScreenRate rate; if (!mode) { RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL); ret = TRUE; } else { size.width = mode->mode.width; size.height = mode->mode.height; if (outputs[0]->mmWidth && outputs[0]->mmHeight) { size.mmWidth = outputs[0]->mmWidth; size.mmHeight = outputs[0]->mmHeight; } else { size.mmWidth = pScreen->mmWidth; size.mmHeight = pScreen->mmHeight; } size.nRates = 1; rate.rate = RRVerticalRefresh (&mode->mode); size.pRates = &rate; ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size); /* * Old 1.0 interface tied screen size to mode size */ if (ret) { RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs); RRScreenSizeNotify (pScreen); } } } #endif } if (ret) { int o; RRTellChanged (pScreen); for (o = 0; o < numOutputs; o++) RRPostPendingProperties (outputs[o]); } } return ret; }
RRModePtr * RRModesForScreen (ScreenPtr pScreen, int *num_ret) { rrScrPriv(pScreen); int o, c, m; RRModePtr *screen_modes; int num_screen_modes = 0; screen_modes = xalloc ((num_modes ? num_modes : 1) * sizeof (RRModePtr)); if (!screen_modes) return NULL; /* * Add modes from all outputs */ for (o = 0; o < pScrPriv->numOutputs; o++) { RROutputPtr output = pScrPriv->outputs[o]; int m, n; for (m = 0; m < output->numModes + output->numUserModes; m++) { RRModePtr mode = (m < output->numModes ? output->modes[m] : output->userModes[m-output->numModes]); for (n = 0; n < num_screen_modes; n++) if (screen_modes[n] == mode) break; if (n == num_screen_modes) screen_modes[num_screen_modes++] = mode; } } /* * Add modes from all crtcs. The goal is to * make sure all available and active modes * are visible to the client */ for (c = 0; c < pScrPriv->numCrtcs; c++) { RRCrtcPtr crtc = pScrPriv->crtcs[c]; RRModePtr mode = crtc->mode; int n; if (!mode) continue; for (n = 0; n < num_screen_modes; n++) if (screen_modes[n] == mode) break; if (n == num_screen_modes) screen_modes[num_screen_modes++] = mode; } /* * Add all user modes for this screen */ for (m = 0; m < num_modes; m++) { RRModePtr mode = modes[m]; int n; if (mode->userScreen != pScreen) continue; for (n = 0; n < num_screen_modes; n++) if (screen_modes[n] == mode) break; if (n == num_screen_modes) screen_modes[num_screen_modes++] = mode; } *num_ret = num_screen_modes; return screen_modes; }