static void RRMonitorGetCrtcGeometry(RRCrtcPtr crtc, RRMonitorGeometryPtr geometry) { ScreenPtr screen = crtc->pScreen; rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); BoxRec panned_area; /* Check to see if crtc is panned and return the full area when applicable. */ if (pScrPriv && pScrPriv->rrGetPanning && pScrPriv->rrGetPanning(screen, crtc, &panned_area, NULL, NULL) && (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) { geometry->box = panned_area; } else { int width, height; RRCrtcGetScanoutSize(crtc, &width, &height); geometry->box.x1 = crtc->x; geometry->box.y1 = crtc->y; geometry->box.x2 = geometry->box.x1 + width; geometry->box.y2 = geometry->box.y1 + height; } if (crtc->numOutputs && crtc->outputs[0]->mmWidth && crtc->outputs[0]->mmHeight) { RROutputPtr output = crtc->outputs[0]; geometry->mmWidth = output->mmWidth; geometry->mmHeight = output->mmHeight; } else { geometry->mmWidth = floor ((geometry->box.x2 - geometry->box.x1) / DEFAULT_PIXELS_PER_MM + 0.5); geometry->mmHeight = floor ((geometry->box.y2 - geometry->box.y1) / DEFAULT_PIXELS_PER_MM + 0.5); } }
/* * 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 Bool RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y) { RRModePtr mode = crtc->mode; int scan_width, scan_height; if (!mode) return FALSE; RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height); if (crtc->x <= x && x < crtc->x + scan_width && crtc->y <= y && y < crtc->y + scan_height) return TRUE; return FALSE; }
int ProcRRGetCrtcInfo (ClientPtr client) { REQUEST(xRRGetCrtcInfoReq); xRRGetCrtcInfoReply rep; RRCrtcPtr crtc; CARD8 *extra; unsigned long extraLen; ScreenPtr pScreen; rrScrPrivPtr pScrPriv; RRModePtr mode; RROutput *outputs; RROutput *possible; int i, j, k, n; int width, height; BoxRec panned_area; REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); /* All crtcs must be associated with screens before client * requests are processed */ pScreen = crtc->pScreen; pScrPriv = rrGetScrPriv(pScreen); mode = crtc->mode; rep.type = X_Reply; rep.status = RRSetConfigSuccess; rep.sequenceNumber = client->sequence; rep.length = 0; rep.timestamp = pScrPriv->lastSetTime.milliseconds; if (pScrPriv->rrGetPanning && pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) && (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) { rep.x = panned_area.x1; rep.y = panned_area.y1; rep.width = panned_area.x2 - panned_area.x1; rep.height = panned_area.y2 - panned_area.y1; } else { RRCrtcGetScanoutSize (crtc, &width, &height); rep.x = crtc->x; rep.y = crtc->y; rep.width = width; rep.height = height; } rep.mode = mode ? mode->mode.id : 0; rep.rotation = crtc->rotation; rep.rotations = crtc->rotations; rep.nOutput = crtc->numOutputs; k = 0; for (i = 0; i < pScrPriv->numOutputs; i++) for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) if (pScrPriv->outputs[i]->crtcs[j] == crtc) k++; rep.nPossibleOutput = k; rep.length = rep.nOutput + rep.nPossibleOutput; extraLen = rep.length << 2; if (extraLen) { extra = malloc(extraLen); if (!extra) return BadAlloc; } else extra = NULL; outputs = (RROutput *) extra; possible = (RROutput *) (outputs + rep.nOutput); for (i = 0; i < crtc->numOutputs; i++) { outputs[i] = crtc->outputs[i]->id; if (client->swapped) swapl (&outputs[i], n); } k = 0; for (i = 0; i < pScrPriv->numOutputs; i++) for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) if (pScrPriv->outputs[i]->crtcs[j] == crtc) { possible[k] = pScrPriv->outputs[i]->id; if (client->swapped) swapl (&possible[k], n); k++; } if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); swapl(&rep.timestamp, n); swaps(&rep.x, n); swaps(&rep.y, n); swaps(&rep.width, n); swaps(&rep.height, n); swapl(&rep.mode, n); swaps(&rep.rotation, n); swaps(&rep.rotations, n); swaps(&rep.nOutput, n); swaps(&rep.nPossibleOutput, n); } WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep); if (extraLen) { WriteToClient (client, extraLen, (char *) extra); free(extra); } return Success; }