11b5d61b8Smrg/*
21b5d61b8Smrg * Copyright © 2014 Jon Turney
31b5d61b8Smrg *
41b5d61b8Smrg * Permission is hereby granted, free of charge, to any person obtaining a
51b5d61b8Smrg * copy of this software and associated documentation files (the "Software"),
61b5d61b8Smrg * to deal in the Software without restriction, including without limitation
71b5d61b8Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81b5d61b8Smrg * and/or sell copies of the Software, and to permit persons to whom the
91b5d61b8Smrg * Software is furnished to do so, subject to the following conditions:
101b5d61b8Smrg *
111b5d61b8Smrg * The above copyright notice and this permission notice (including the next
121b5d61b8Smrg * paragraph) shall be included in all copies or substantial portions of the
131b5d61b8Smrg * Software.
141b5d61b8Smrg *
151b5d61b8Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161b5d61b8Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171b5d61b8Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181b5d61b8Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191b5d61b8Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201b5d61b8Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
211b5d61b8Smrg * IN THE SOFTWARE.
221b5d61b8Smrg */
231b5d61b8Smrg
241b5d61b8Smrg#ifdef HAVE_DIX_CONFIG_H
251b5d61b8Smrg#include <dix-config.h>
261b5d61b8Smrg#endif
271b5d61b8Smrg
281b5d61b8Smrg#include <X11/X.h>
291b5d61b8Smrg#include <X11/Xproto.h>
301b5d61b8Smrg#include <X11/extensions/windowsdristr.h>
311b5d61b8Smrg
321b5d61b8Smrg#include "dixstruct.h"
331b5d61b8Smrg#include "extnsionst.h"
341b5d61b8Smrg#include "scrnintstr.h"
351b5d61b8Smrg#include "swaprep.h"
361b5d61b8Smrg#include "protocol-versions.h"
371b5d61b8Smrg#include "windowsdri.h"
381b5d61b8Smrg#include "glx/dri_helpers.h"
391b5d61b8Smrg
401b5d61b8Smrgstatic int WindowsDRIErrorBase = 0;
411b5d61b8Smrgstatic unsigned char WindowsDRIReqCode = 0;
421b5d61b8Smrgstatic int WindowsDRIEventBase = 0;
431b5d61b8Smrg
441b5d61b8Smrgstatic void
451b5d61b8SmrgWindowsDRIResetProc(ExtensionEntry* extEntry)
461b5d61b8Smrg{
471b5d61b8Smrg}
481b5d61b8Smrg
491b5d61b8Smrgstatic int
501b5d61b8SmrgProcWindowsDRIQueryVersion(ClientPtr client)
511b5d61b8Smrg{
521b5d61b8Smrg    xWindowsDRIQueryVersionReply rep;
531b5d61b8Smrg
541b5d61b8Smrg    REQUEST_SIZE_MATCH(xWindowsDRIQueryVersionReq);
551b5d61b8Smrg    rep.type = X_Reply;
561b5d61b8Smrg    rep.length = 0;
571b5d61b8Smrg    rep.sequenceNumber = client->sequence;
581b5d61b8Smrg    rep.majorVersion = SERVER_WINDOWSDRI_MAJOR_VERSION;
591b5d61b8Smrg    rep.minorVersion = SERVER_WINDOWSDRI_MINOR_VERSION;
601b5d61b8Smrg    rep.patchVersion = SERVER_WINDOWSDRI_PATCH_VERSION;
611b5d61b8Smrg    if (client->swapped) {
621b5d61b8Smrg        swaps(&rep.sequenceNumber);
631b5d61b8Smrg        swapl(&rep.length);
641b5d61b8Smrg        swaps(&rep.majorVersion);
651b5d61b8Smrg        swaps(&rep.minorVersion);
661b5d61b8Smrg        swapl(&rep.patchVersion);
671b5d61b8Smrg    }
681b5d61b8Smrg    WriteToClient(client, sizeof(xWindowsDRIQueryVersionReply), &rep);
691b5d61b8Smrg    return Success;
701b5d61b8Smrg}
711b5d61b8Smrg
721b5d61b8Smrgstatic int
731b5d61b8SmrgProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)
741b5d61b8Smrg{
751b5d61b8Smrg    xWindowsDRIQueryDirectRenderingCapableReply rep;
761b5d61b8Smrg
771b5d61b8Smrg    REQUEST(xWindowsDRIQueryDirectRenderingCapableReq);
781b5d61b8Smrg    REQUEST_SIZE_MATCH(xWindowsDRIQueryDirectRenderingCapableReq);
791b5d61b8Smrg    rep.type = X_Reply;
801b5d61b8Smrg    rep.length = 0;
811b5d61b8Smrg    rep.sequenceNumber = client->sequence;
821b5d61b8Smrg
831b5d61b8Smrg    if (!client->local)
841b5d61b8Smrg        rep.isCapable = 0;
851b5d61b8Smrg    else
861b5d61b8Smrg        rep.isCapable = glxWinGetScreenAiglxIsActive(screenInfo.screens[stuff->screen]);
871b5d61b8Smrg
881b5d61b8Smrg    if (client->swapped) {
891b5d61b8Smrg        swaps(&rep.sequenceNumber);
901b5d61b8Smrg        swapl(&rep.length);
911b5d61b8Smrg    }
921b5d61b8Smrg
931b5d61b8Smrg    WriteToClient(client,
941b5d61b8Smrg                  sizeof(xWindowsDRIQueryDirectRenderingCapableReply),
951b5d61b8Smrg                  &rep);
961b5d61b8Smrg    return Success;
971b5d61b8Smrg}
981b5d61b8Smrg
991b5d61b8Smrgstatic int
1001b5d61b8SmrgProcWindowsDRIQueryDrawable(ClientPtr client)
1011b5d61b8Smrg{
1021b5d61b8Smrg    xWindowsDRIQueryDrawableReply rep;
1031b5d61b8Smrg    int rc;
1041b5d61b8Smrg
1051b5d61b8Smrg    REQUEST(xWindowsDRIQueryDrawableReq);
1061b5d61b8Smrg    REQUEST_SIZE_MATCH(xWindowsDRIQueryDrawableReq);
1071b5d61b8Smrg    rep.type = X_Reply;
1081b5d61b8Smrg    rep.length = 0;
1091b5d61b8Smrg    rep.sequenceNumber = client->sequence;
1101b5d61b8Smrg
1111b5d61b8Smrg    rc = glxWinQueryDrawable(client, stuff->drawable, &(rep.drawable_type), &(rep.handle));
1121b5d61b8Smrg
1131b5d61b8Smrg    if (rc)
1141b5d61b8Smrg        return rc;
1151b5d61b8Smrg
1161b5d61b8Smrg    if (client->swapped) {
1171b5d61b8Smrg        swaps(&rep.sequenceNumber);
1181b5d61b8Smrg        swapl(&rep.length);
1191b5d61b8Smrg        swapl(&rep.handle);
1201b5d61b8Smrg        swapl(&rep.drawable_type);
1211b5d61b8Smrg    }
1221b5d61b8Smrg
1231b5d61b8Smrg    WriteToClient(client, sizeof(xWindowsDRIQueryDrawableReply), &rep);
1241b5d61b8Smrg    return Success;
1251b5d61b8Smrg}
1261b5d61b8Smrg
1271b5d61b8Smrgstatic int
1281b5d61b8SmrgProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)
1291b5d61b8Smrg{
1301b5d61b8Smrg    xWindowsDRIFBConfigToPixelFormatReply rep;
1311b5d61b8Smrg
1321b5d61b8Smrg    REQUEST(xWindowsDRIFBConfigToPixelFormatReq);
1331b5d61b8Smrg    REQUEST_SIZE_MATCH(xWindowsDRIFBConfigToPixelFormatReq);
1341b5d61b8Smrg    rep.type = X_Reply;
1351b5d61b8Smrg    rep.length = 0;
1361b5d61b8Smrg    rep.sequenceNumber = client->sequence;
1371b5d61b8Smrg
1381b5d61b8Smrg    rep.pixelFormatIndex = glxWinFBConfigIDToPixelFormatIndex(stuff->screen, stuff->fbConfigID);
1391b5d61b8Smrg
1401b5d61b8Smrg    if (client->swapped) {
1411b5d61b8Smrg        swaps(&rep.sequenceNumber);
1421b5d61b8Smrg        swapl(&rep.length);
1431b5d61b8Smrg        swapl(&rep.pixelFormatIndex);
1441b5d61b8Smrg    }
1451b5d61b8Smrg
1461b5d61b8Smrg    WriteToClient(client, sizeof(xWindowsDRIFBConfigToPixelFormatReply), &rep);
1471b5d61b8Smrg    return Success;
1481b5d61b8Smrg}
1491b5d61b8Smrg
1501b5d61b8Smrg/* dispatch */
1511b5d61b8Smrg
1521b5d61b8Smrgstatic int
1531b5d61b8SmrgProcWindowsDRIDispatch(ClientPtr client)
1541b5d61b8Smrg{
1551b5d61b8Smrg    REQUEST(xReq);
1561b5d61b8Smrg
1571b5d61b8Smrg    switch (stuff->data) {
1581b5d61b8Smrg    case X_WindowsDRIQueryVersion:
1591b5d61b8Smrg        return ProcWindowsDRIQueryVersion(client);
1601b5d61b8Smrg
1611b5d61b8Smrg    case X_WindowsDRIQueryDirectRenderingCapable:
1621b5d61b8Smrg        return ProcWindowsDRIQueryDirectRenderingCapable(client);
1631b5d61b8Smrg    }
1641b5d61b8Smrg
1651b5d61b8Smrg    if (!client->local)
1661b5d61b8Smrg        return WindowsDRIErrorBase + WindowsDRIClientNotLocal;
1671b5d61b8Smrg
1681b5d61b8Smrg    switch (stuff->data) {
1691b5d61b8Smrg    case X_WindowsDRIQueryDrawable:
1701b5d61b8Smrg        return ProcWindowsDRIQueryDrawable(client);
1711b5d61b8Smrg
1721b5d61b8Smrg    case X_WindowsDRIFBConfigToPixelFormat:
1731b5d61b8Smrg        return ProcWindowsDRIFBConfigToPixelFormat(client);
1741b5d61b8Smrg
1751b5d61b8Smrg    default:
1761b5d61b8Smrg        return BadRequest;
1771b5d61b8Smrg    }
1781b5d61b8Smrg}
1791b5d61b8Smrg
1801b5d61b8Smrgstatic void
1811b5d61b8SmrgSNotifyEvent(xWindowsDRINotifyEvent *from,
1821b5d61b8Smrg             xWindowsDRINotifyEvent *to)
1831b5d61b8Smrg{
1841b5d61b8Smrg    to->type = from->type;
1851b5d61b8Smrg    to->kind = from->kind;
1861b5d61b8Smrg    cpswaps(from->sequenceNumber, to->sequenceNumber);
1871b5d61b8Smrg    cpswapl(from->time, to->time);
1881b5d61b8Smrg}
1891b5d61b8Smrg
1901b5d61b8Smrgstatic int
1911b5d61b8SmrgSProcWindowsDRIQueryVersion(ClientPtr client)
1921b5d61b8Smrg{
1931b5d61b8Smrg    REQUEST(xWindowsDRIQueryVersionReq);
1941b5d61b8Smrg    swaps(&stuff->length);
1951b5d61b8Smrg    return ProcWindowsDRIQueryVersion(client);
1961b5d61b8Smrg}
1971b5d61b8Smrg
1981b5d61b8Smrgstatic int
1991b5d61b8SmrgSProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)
2001b5d61b8Smrg{
2011b5d61b8Smrg    REQUEST(xWindowsDRIQueryDirectRenderingCapableReq);
2021b5d61b8Smrg    swaps(&stuff->length);
2031b5d61b8Smrg    swapl(&stuff->screen);
2041b5d61b8Smrg    return ProcWindowsDRIQueryDirectRenderingCapable(client);
2051b5d61b8Smrg}
2061b5d61b8Smrg
2071b5d61b8Smrgstatic int
2081b5d61b8SmrgSProcWindowsDRIQueryDrawable(ClientPtr client)
2091b5d61b8Smrg{
2101b5d61b8Smrg    REQUEST(xWindowsDRIQueryDrawableReq);
2111b5d61b8Smrg    swaps(&stuff->length);
2121b5d61b8Smrg    swapl(&stuff->screen);
2131b5d61b8Smrg    swapl(&stuff->drawable);
2141b5d61b8Smrg    return ProcWindowsDRIQueryDrawable(client);
2151b5d61b8Smrg}
2161b5d61b8Smrg
2171b5d61b8Smrgstatic int
2181b5d61b8SmrgSProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)
2191b5d61b8Smrg{
2201b5d61b8Smrg    REQUEST(xWindowsDRIFBConfigToPixelFormatReq);
2211b5d61b8Smrg    swaps(&stuff->length);
2221b5d61b8Smrg    swapl(&stuff->screen);
2231b5d61b8Smrg    swapl(&stuff->fbConfigID);
2241b5d61b8Smrg    return ProcWindowsDRIFBConfigToPixelFormat(client);
2251b5d61b8Smrg}
2261b5d61b8Smrg
2271b5d61b8Smrgstatic int
2281b5d61b8SmrgSProcWindowsDRIDispatch(ClientPtr client)
2291b5d61b8Smrg{
2301b5d61b8Smrg    REQUEST(xReq);
2311b5d61b8Smrg
2321b5d61b8Smrg    switch (stuff->data) {
2331b5d61b8Smrg    case X_WindowsDRIQueryVersion:
2341b5d61b8Smrg        return SProcWindowsDRIQueryVersion(client);
2351b5d61b8Smrg
2361b5d61b8Smrg    case X_WindowsDRIQueryDirectRenderingCapable:
2371b5d61b8Smrg        return SProcWindowsDRIQueryDirectRenderingCapable(client);
2381b5d61b8Smrg    }
2391b5d61b8Smrg
2401b5d61b8Smrg    if (!client->local)
2411b5d61b8Smrg        return WindowsDRIErrorBase + WindowsDRIClientNotLocal;
2421b5d61b8Smrg
2431b5d61b8Smrg    switch (stuff->data) {
2441b5d61b8Smrg    case X_WindowsDRIQueryDrawable:
2451b5d61b8Smrg        return SProcWindowsDRIQueryDrawable(client);
2461b5d61b8Smrg
2471b5d61b8Smrg    case X_WindowsDRIFBConfigToPixelFormat:
2481b5d61b8Smrg        return SProcWindowsDRIFBConfigToPixelFormat(client);
2491b5d61b8Smrg
2501b5d61b8Smrg    default:
2511b5d61b8Smrg        return BadRequest;
2521b5d61b8Smrg    }
2531b5d61b8Smrg}
2541b5d61b8Smrg
2551b5d61b8Smrgvoid
2561b5d61b8SmrgWindowsDRIExtensionInit(void)
2571b5d61b8Smrg{
2581b5d61b8Smrg    ExtensionEntry* extEntry;
2591b5d61b8Smrg
2601b5d61b8Smrg    if ((extEntry = AddExtension(WINDOWSDRINAME,
2611b5d61b8Smrg                                 WindowsDRINumberEvents,
2621b5d61b8Smrg                                 WindowsDRINumberErrors,
2631b5d61b8Smrg                                 ProcWindowsDRIDispatch,
2641b5d61b8Smrg                                 SProcWindowsDRIDispatch,
2651b5d61b8Smrg                                 WindowsDRIResetProc,
2661b5d61b8Smrg                                 StandardMinorOpcode))) {
2671b5d61b8Smrg        size_t i;
2681b5d61b8Smrg        WindowsDRIReqCode = (unsigned char)extEntry->base;
2691b5d61b8Smrg        WindowsDRIErrorBase = extEntry->errorBase;
2701b5d61b8Smrg        WindowsDRIEventBase = extEntry->eventBase;
2711b5d61b8Smrg        for (i = 0; i < WindowsDRINumberEvents; i++)
2721b5d61b8Smrg            EventSwapVector[WindowsDRIEventBase + i] = (EventSwapPtr)SNotifyEvent;
2731b5d61b8Smrg    }
2741b5d61b8Smrg}
275