static int ProcDRI2GetBuffers(ClientPtr client) { REQUEST(xDRI2GetBuffersReq); DrawablePtr pDrawable; DRI2BufferPtr *buffers; int status, width, height, count; unsigned int *attachments; REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, &pDrawable, &status)) return status; if (DRI2ThrottleClient(client, pDrawable)) return Success; attachments = (unsigned int *) &stuff[1]; buffers = DRI2GetBuffers(pDrawable, &width, &height, attachments, stuff->count, &count); return send_buffers_reply(client, pDrawable, buffers, count, width, height); }
static void DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, CARD32 sbc) { DrawablePtr pDrawable = data; xDRI2BufferSwapComplete2 event = { .type = DRI2EventBase + DRI2_BufferSwapComplete, .event_type = type, .drawable = pDrawable->id, .ust_hi = (CARD64) ust >> 32, .ust_lo = ust & 0xffffffff, .msc_hi = (CARD64) msc >> 32, .msc_lo = msc & 0xffffffff, .sbc = sbc }; WriteEventsToClient(client, 1, (xEvent *) &event); } static int ProcDRI2SwapBuffers(ClientPtr client) { REQUEST(xDRI2SwapBuffersReq); xDRI2SwapBuffersReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; DrawablePtr pDrawable; CARD64 target_msc, divisor, remainder, swap_target; int status; REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, &pDrawable, &status)) return status; /* * Ensures an out of control client can't exhaust our swap queue, and * also orders swaps. */ if (DRI2ThrottleClient(client, pDrawable)) return Success; target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi); divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi); remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder, &swap_target, DRI2SwapEvent, pDrawable); if (status != Success) return BadDrawable; load_swap_reply(&rep, swap_target); WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep); return Success; } static void load_msc_reply(xDRI2MSCReply * rep, CARD64 ust, CARD64 msc, CARD64 sbc) { rep->ust_hi = ust >> 32; rep->ust_lo = ust & 0xffffffff; rep->msc_hi = msc >> 32; rep->msc_lo = msc & 0xffffffff; rep->sbc_hi = sbc >> 32; rep->sbc_lo = sbc & 0xffffffff; }
static int send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, DRI2BufferPtr * buffers, int count, int width, int height) { xDRI2GetBuffersReply rep; int skip = 0; int i; if (buffers == NULL) return BadAlloc; if (pDrawable->type == DRAWABLE_WINDOW) { for (i = 0; i < count; i++) { /* Do not send the real front buffer of a window to the client. */ if (buffers[i]->attachment == DRI2BufferFrontLeft) { skip++; continue; } } } rep = (xDRI2GetBuffersReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = (count - skip) * sizeof(xDRI2Buffer) / 4, .width = width, .height = height, .count = count - skip }; WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); for (i = 0; i < count; i++) { xDRI2Buffer buffer; /* Do not send the real front buffer of a window to the client. */ if ((pDrawable->type == DRAWABLE_WINDOW) && (buffers[i]->attachment == DRI2BufferFrontLeft)) { continue; } buffer.attachment = buffers[i]->attachment; buffer.name = buffers[i]->name; buffer.pitch = buffers[i]->pitch; buffer.cpp = buffers[i]->cpp; buffer.flags = buffers[i]->flags; WriteToClient(client, sizeof(xDRI2Buffer), &buffer); } return Success; } static int ProcDRI2GetBuffers(ClientPtr client) { REQUEST(xDRI2GetBuffersReq); DrawablePtr pDrawable; DRI2BufferPtr *buffers; int status, width, height, count; unsigned int *attachments; REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, &pDrawable, &status)) return status; if (DRI2ThrottleClient(client, pDrawable)) return Success; attachments = (unsigned int *) &stuff[1]; buffers = DRI2GetBuffers(pDrawable, &width, &height, attachments, stuff->count, &count); return send_buffers_reply(client, pDrawable, buffers, count, width, height); }