xserver-multidpi/hw/xfree86/dixmods/extmod/xf86dga2.c

1066 lines
26 KiB
C

/*
* Copyright (c) 1995 Jon Tombs
* Copyright (c) 1995, 1996, 1999 XFree86 Inc
* Copyright (c) 1999 - The XFree86 Project Inc.
*
* Written by Mark Vojkovich
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "dixstruct.h"
#include "dixevents.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "colormapst.h"
#include "cursorstr.h"
#include "scrnintstr.h"
#include "servermd.h"
#include <X11/extensions/xf86dgaproto.h>
#include "swaprep.h"
#include "dgaproc.h"
#include "xf86dgaext.h"
#include "protocol-versions.h"
#include <string.h>
#include "modinit.h"
#define DGA_PROTOCOL_OLD_SUPPORT 1
static DISPATCH_PROC(ProcXDGADispatch);
static DISPATCH_PROC(SProcXDGADispatch);
static DISPATCH_PROC(ProcXDGAQueryVersion);
static DISPATCH_PROC(ProcXDGAQueryModes);
static DISPATCH_PROC(ProcXDGASetMode);
static DISPATCH_PROC(ProcXDGAOpenFramebuffer);
static DISPATCH_PROC(ProcXDGACloseFramebuffer);
static DISPATCH_PROC(ProcXDGASetViewport);
static DISPATCH_PROC(ProcXDGAInstallColormap);
static DISPATCH_PROC(ProcXDGASelectInput);
static DISPATCH_PROC(ProcXDGAFillRectangle);
static DISPATCH_PROC(ProcXDGACopyArea);
static DISPATCH_PROC(ProcXDGACopyTransparentArea);
static DISPATCH_PROC(ProcXDGAGetViewportStatus);
static DISPATCH_PROC(ProcXDGASync);
static DISPATCH_PROC(ProcXDGASetClientVersion);
static DISPATCH_PROC(ProcXDGAChangePixmapMode);
static DISPATCH_PROC(ProcXDGACreateColormap);
static void XDGAResetProc(ExtensionEntry *extEntry);
static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
unsigned char DGAReqCode = 0;
int DGAErrorBase;
int DGAEventBase;
static DevPrivateKeyRec DGAScreenPrivateKeyRec;
#define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec)
#define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized)
static DevPrivateKeyRec DGAClientPrivateKeyRec;
#define DGAClientPrivateKey (&DGAClientPrivateKeyRec)
static int DGACallbackRefCount = 0;
/* This holds the client's version information */
typedef struct {
int major;
int minor;
} DGAPrivRec, *DGAPrivPtr;
#define DGA_GETCLIENT(idx) ((ClientPtr) \
dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
#define DGA_SETCLIENT(idx,p) \
dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
#define DGA_GETPRIV(c) ((DGAPrivPtr) \
dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
#define DGA_SETPRIV(c,p) \
dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
void
XFree86DGAExtensionInit(INITARGS)
{
ExtensionEntry* extEntry;
if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0))
return;
if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
return;
if ((extEntry = AddExtension(XF86DGANAME,
XF86DGANumberEvents,
XF86DGANumberErrors,
ProcXDGADispatch,
SProcXDGADispatch,
XDGAResetProc,
StandardMinorOpcode))) {
int i;
DGAReqCode = (unsigned char)extEntry->base;
DGAErrorBase = extEntry->errorBase;
DGAEventBase = extEntry->eventBase;
for (i = KeyPress; i <= MotionNotify; i++)
SetCriticalEvent (DGAEventBase + i);
}
}
static void
XDGAResetProc (ExtensionEntry *extEntry)
{
DeleteCallback (&ClientStateCallback, DGAClientStateChange, NULL);
DGACallbackRefCount = 0;
}
static int
ProcXDGAQueryVersion(ClientPtr client)
{
xXDGAQueryVersionReply rep;
REQUEST_SIZE_MATCH(xXDGAQueryVersionReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.majorVersion = SERVER_XDGA_MAJOR_VERSION;
rep.minorVersion = SERVER_XDGA_MINOR_VERSION;
WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *)&rep);
return Success;
}
static int
ProcXDGAOpenFramebuffer(ClientPtr client)
{
REQUEST(xXDGAOpenFramebufferReq);
xXDGAOpenFramebufferReply rep;
char *deviceName;
int nameSize;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if (!DGAAvailable(stuff->screen))
return DGAErrorBase + XF86DGANoDirectVideoMode;
REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
if(!DGAOpenFramebuffer(stuff->screen, &deviceName,
(unsigned char**)(&rep.mem1),
(int*)&rep.size, (int*)&rep.offset, (int*)&rep.extra))
{
return BadAlloc;
}
nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
rep.length = bytes_to_int32(nameSize);
WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *)&rep);
if(rep.length)
WriteToClient(client, nameSize, deviceName);
return Success;
}
static int
ProcXDGACloseFramebuffer(ClientPtr client)
{
REQUEST(xXDGACloseFramebufferReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if (!DGAAvailable(stuff->screen))
return DGAErrorBase + XF86DGANoDirectVideoMode;
REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
DGACloseFramebuffer(stuff->screen);
return Success;
}
static int
ProcXDGAQueryModes(ClientPtr client)
{
int i, num, size;
REQUEST(xXDGAQueryModesReq);
xXDGAQueryModesReply rep;
xXDGAModeInfo info;
XDGAModePtr mode;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
REQUEST_SIZE_MATCH(xXDGAQueryModesReq);
rep.type = X_Reply;
rep.length = 0;
rep.number = 0;
rep.sequenceNumber = client->sequence;
if (!DGAAvailable(stuff->screen)) {
rep.number = 0;
rep.length = 0;
WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
return Success;
}
if(!(num = DGAGetModes(stuff->screen))) {
WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
return Success;
}
if(!(mode = (XDGAModePtr)malloc(num * sizeof(XDGAModeRec))))
return BadAlloc;
for(i = 0; i < num; i++)
DGAGetModeInfo(stuff->screen, mode + i, i + 1);
size = num * sz_xXDGAModeInfo;
for(i = 0; i < num; i++)
size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
rep.number = num;
rep.length = bytes_to_int32(size);
WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
for(i = 0; i < num; i++) {
size = strlen(mode[i].name) + 1;
info.byte_order = mode[i].byteOrder;
info.depth = mode[i].depth;
info.num = mode[i].num;
info.bpp = mode[i].bitsPerPixel;
info.name_size = (size + 3) & ~3L;
info.vsync_num = mode[i].VSync_num;
info.vsync_den = mode[i].VSync_den;
info.flags = mode[i].flags;
info.image_width = mode[i].imageWidth;
info.image_height = mode[i].imageHeight;
info.pixmap_width = mode[i].pixmapWidth;
info.pixmap_height = mode[i].pixmapHeight;
info.bytes_per_scanline = mode[i].bytesPerScanline;
info.red_mask = mode[i].red_mask;
info.green_mask = mode[i].green_mask;
info.blue_mask = mode[i].blue_mask;
info.visual_class = mode[i].visualClass;
info.viewport_width = mode[i].viewportWidth;
info.viewport_height = mode[i].viewportHeight;
info.viewport_xstep = mode[i].xViewportStep;
info.viewport_ystep = mode[i].yViewportStep;
info.viewport_xmax = mode[i].maxViewportX;
info.viewport_ymax = mode[i].maxViewportY;
info.viewport_flags = mode[i].viewportFlags;
info.reserved1 = mode[i].reserved1;
info.reserved2 = mode[i].reserved2;
WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
WriteToClient(client, size, mode[i].name);
}
free(mode);
return Success;
}
static void
DGAClientStateChange (
CallbackListPtr* pcbl,
pointer nulldata,
pointer calldata
){
NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
ClientPtr client = NULL;
int i;
for(i = 0; i < screenInfo.numScreens; i++) {
if(DGA_GETCLIENT(i) == pci->client) {
client = pci->client;
break;
}
}
if(client &&
((client->clientState == ClientStateGone) ||
(client->clientState == ClientStateRetained))) {
XDGAModeRec mode;
PixmapPtr pPix;
DGA_SETCLIENT(i, NULL);
DGASelectInput(i, NULL, 0);
DGASetMode(i, 0, &mode, &pPix);
if(--DGACallbackRefCount == 0)
DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
}
}
static int
ProcXDGASetMode(ClientPtr client)
{
REQUEST(xXDGASetModeReq);
xXDGASetModeReply rep;
XDGAModeRec mode;
xXDGAModeInfo info;
PixmapPtr pPix;
ClientPtr owner;
int size;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
owner = DGA_GETCLIENT(stuff->screen);
REQUEST_SIZE_MATCH(xXDGASetModeReq);
rep.type = X_Reply;
rep.length = 0;
rep.offset = 0;
rep.flags = 0;
rep.sequenceNumber = client->sequence;
if (!DGAAvailable(stuff->screen))
return DGAErrorBase + XF86DGANoDirectVideoMode;
if(owner && owner != client)
return DGAErrorBase + XF86DGANoDirectVideoMode;
if(!stuff->mode) {
if(owner) {
if(--DGACallbackRefCount == 0)
DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
}
DGA_SETCLIENT(stuff->screen, NULL);
DGASelectInput(stuff->screen, NULL, 0);
DGASetMode(stuff->screen, 0, &mode, &pPix);
WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
return Success;
}
if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
return BadValue;
if(!owner) {
if(DGACallbackRefCount++ == 0)
AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
}
DGA_SETCLIENT(stuff->screen, client);
if(pPix) {
if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
pPix->drawable.id = (int)stuff->pid;
rep.flags = DGA_PIXMAP_AVAILABLE;
}
}
size = strlen(mode.name) + 1;
info.byte_order = mode.byteOrder;
info.depth = mode.depth;
info.num = mode.num;
info.bpp = mode.bitsPerPixel;
info.name_size = (size + 3) & ~3L;
info.vsync_num = mode.VSync_num;
info.vsync_den = mode.VSync_den;
info.flags = mode.flags;
info.image_width = mode.imageWidth;
info.image_height = mode.imageHeight;
info.pixmap_width = mode.pixmapWidth;
info.pixmap_height = mode.pixmapHeight;
info.bytes_per_scanline = mode.bytesPerScanline;
info.red_mask = mode.red_mask;
info.green_mask = mode.green_mask;
info.blue_mask = mode.blue_mask;
info.visual_class = mode.visualClass;
info.viewport_width = mode.viewportWidth;
info.viewport_height = mode.viewportHeight;
info.viewport_xstep = mode.xViewportStep;
info.viewport_ystep = mode.yViewportStep;
info.viewport_xmax = mode.maxViewportX;
info.viewport_ymax = mode.maxViewportY;
info.viewport_flags = mode.viewportFlags;
info.reserved1 = mode.reserved1;
info.reserved2 = mode.reserved2;
rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size);
WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
WriteToClient(client, size, mode.name);
return Success;
}
static int
ProcXDGASetViewport(ClientPtr client)
{
REQUEST(xXDGASetViewportReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASetViewportReq);
DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
return Success;
}
static int
ProcXDGAInstallColormap(ClientPtr client)
{
ColormapPtr cmap;
int rc;
REQUEST(xXDGAInstallColormapReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
rc = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, RT_COLORMAP,
client, DixInstallAccess);
if (rc != Success)
return rc;
DGAInstallCmap(cmap);
return Success;
}
static int
ProcXDGASelectInput(ClientPtr client)
{
REQUEST(xXDGASelectInputReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASelectInputReq);
if(DGA_GETCLIENT(stuff->screen) == client)
DGASelectInput(stuff->screen, client, stuff->mask);
return Success;
}
static int
ProcXDGAFillRectangle(ClientPtr client)
{
REQUEST(xXDGAFillRectangleReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
if(Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
stuff->width, stuff->height, stuff->color))
return BadMatch;
return Success;
}
static int
ProcXDGACopyArea(ClientPtr client)
{
REQUEST(xXDGACopyAreaReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
if(Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy,
stuff->width, stuff->height, stuff->dstx, stuff->dsty))
return BadMatch;
return Success;
}
static int
ProcXDGACopyTransparentArea(ClientPtr client)
{
REQUEST(xXDGACopyTransparentAreaReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
if(Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy,
stuff->width, stuff->height, stuff->dstx, stuff->dsty, stuff->key))
return BadMatch;
return Success;
}
static int
ProcXDGAGetViewportStatus(ClientPtr client)
{
REQUEST(xXDGAGetViewportStatusReq);
xXDGAGetViewportStatusReply rep;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.status = DGAGetViewportStatus(stuff->screen);
WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *)&rep);
return Success;
}
static int
ProcXDGASync(ClientPtr client)
{
REQUEST(xXDGASyncReq);
xXDGASyncReply rep;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASyncReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
DGASync(stuff->screen);
WriteToClient(client, sizeof(xXDGASyncReply), (char *)&rep);
return Success;
}
static int
ProcXDGASetClientVersion(ClientPtr client)
{
REQUEST(xXDGASetClientVersionReq);
DGAPrivPtr pPriv;
REQUEST_SIZE_MATCH(xXDGASetClientVersionReq);
if ((pPriv = DGA_GETPRIV(client)) == NULL) {
pPriv = malloc(sizeof(DGAPrivRec));
/* XXX Need to look into freeing this */
if (!pPriv)
return BadAlloc;
DGA_SETPRIV(client, pPriv);
}
pPriv->major = stuff->major;
pPriv->minor = stuff->minor;
return Success;
}
static int
ProcXDGAChangePixmapMode(ClientPtr client)
{
REQUEST(xXDGAChangePixmapModeReq);
xXDGAChangePixmapModeReply rep;
int x, y;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
x = stuff->x;
y = stuff->y;
if(!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
return BadMatch;
rep.x = x;
rep.y = y;
WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *)&rep);
return Success;
}
static int
ProcXDGACreateColormap(ClientPtr client)
{
REQUEST(xXDGACreateColormapReq);
int result;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
if(!stuff->mode)
return BadValue;
result = DGACreateColormap(stuff->screen, client, stuff->id,
stuff->mode, stuff->alloc);
if(result != Success)
return result;
return Success;
}
/*
*
* Support for the old DGA protocol, used to live in xf86dga.c
*
*/
#ifdef DGA_PROTOCOL_OLD_SUPPORT
static DISPATCH_PROC(ProcXF86DGADirectVideo);
static DISPATCH_PROC(ProcXF86DGAGetVidPage);
static DISPATCH_PROC(ProcXF86DGAGetVideoLL);
static DISPATCH_PROC(ProcXF86DGAGetViewPortSize);
static DISPATCH_PROC(ProcXF86DGASetVidPage);
static DISPATCH_PROC(ProcXF86DGASetViewPort);
static DISPATCH_PROC(ProcXF86DGAInstallColormap);
static DISPATCH_PROC(ProcXF86DGAQueryDirectVideo);
static DISPATCH_PROC(ProcXF86DGAViewPortChanged);
static int
ProcXF86DGAGetVideoLL(ClientPtr client)
{
REQUEST(xXF86DGAGetVideoLLReq);
xXF86DGAGetVideoLLReply rep;
XDGAModeRec mode;
int num, offset, flags;
char *name;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
if(!DGAAvailable(stuff->screen))
return (DGAErrorBase + XF86DGANoDirectVideoMode);
if(!(num = DGAGetOldDGAMode(stuff->screen)))
return (DGAErrorBase + XF86DGANoDirectVideoMode);
/* get the parameters for the mode that best matches */
DGAGetModeInfo(stuff->screen, &mode, num);
if(!DGAOpenFramebuffer(stuff->screen, &name,
(unsigned char**)(&rep.offset),
(int*)(&rep.bank_size), &offset, &flags))
return BadAlloc;
rep.offset += mode.offset;
rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3);
rep.ram_size = rep.bank_size >> 10;
WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *)&rep);
return Success;
}
static int
ProcXF86DGADirectVideo(ClientPtr client)
{
int num;
PixmapPtr pix;
XDGAModeRec mode;
ClientPtr owner;
REQUEST(xXF86DGADirectVideoReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
if (!DGAAvailable(stuff->screen))
return DGAErrorBase + XF86DGANoDirectVideoMode;
owner = DGA_GETCLIENT(stuff->screen);
if (owner && owner != client)
return DGAErrorBase + XF86DGANoDirectVideoMode;
if (stuff->enable & XF86DGADirectGraphics) {
if(!(num = DGAGetOldDGAMode(stuff->screen)))
return (DGAErrorBase + XF86DGANoDirectVideoMode);
} else
num = 0;
if(Success != DGASetMode(stuff->screen, num, &mode, &pix))
return (DGAErrorBase + XF86DGAScreenNotActive);
DGASetInputMode (stuff->screen,
(stuff->enable & XF86DGADirectKeyb) != 0,
(stuff->enable & XF86DGADirectMouse) != 0);
/* We need to track the client and attach the teardown callback */
if (stuff->enable &
(XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
if (!owner) {
if (DGACallbackRefCount++ == 0)
AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
}
DGA_SETCLIENT(stuff->screen, client);
} else {
if (owner) {
if (--DGACallbackRefCount == 0)
DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
}
DGA_SETCLIENT(stuff->screen, NULL);
}
return Success;
}
static int
ProcXF86DGAGetViewPortSize(ClientPtr client)
{
int num;
XDGAModeRec mode;
REQUEST(xXF86DGAGetViewPortSizeReq);
xXF86DGAGetViewPortSizeReply rep;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
if (!DGAAvailable(stuff->screen))
return (DGAErrorBase + XF86DGANoDirectVideoMode);
if(!(num = DGAGetOldDGAMode(stuff->screen)))
return (DGAErrorBase + XF86DGANoDirectVideoMode);
DGAGetModeInfo(stuff->screen, &mode, num);
rep.width = mode.viewportWidth;
rep.height = mode.viewportHeight;
WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *)&rep);
return Success;
}
static int
ProcXF86DGASetViewPort(ClientPtr client)
{
REQUEST(xXF86DGASetViewPortReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
if (!DGAAvailable(stuff->screen))
return (DGAErrorBase + XF86DGANoDirectVideoMode);
if (!DGAActive(stuff->screen))
return DGAErrorBase + XF86DGADirectNotActivated;
if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE)
!= Success)
return DGAErrorBase + XF86DGADirectNotActivated;
return Success;
}
static int
ProcXF86DGAGetVidPage(ClientPtr client)
{
REQUEST(xXF86DGAGetVidPageReq);
xXF86DGAGetVidPageReply rep;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.vpage = 0; /* silently fail */
WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *)&rep);
return Success;
}
static int
ProcXF86DGASetVidPage(ClientPtr client)
{
REQUEST(xXF86DGASetVidPageReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq);
/* silently fail */
return Success;
}
static int
ProcXF86DGAInstallColormap(ClientPtr client)
{
ColormapPtr pcmp;
int rc;
REQUEST(xXF86DGAInstallColormapReq);
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
if (!DGAActive(stuff->screen))
return (DGAErrorBase + XF86DGADirectNotActivated);
rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP,
client, DixInstallAccess);
if (rc == Success) {
DGAInstallCmap(pcmp);
return Success;
} else {
return rc;
}
}
static int
ProcXF86DGAQueryDirectVideo(ClientPtr client)
{
REQUEST(xXF86DGAQueryDirectVideoReq);
xXF86DGAQueryDirectVideoReply rep;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.flags = 0;
if (DGAAvailable(stuff->screen))
rep.flags = XF86DGADirectPresent;
WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *)&rep);
return Success;
}
static int
ProcXF86DGAViewPortChanged(ClientPtr client)
{
REQUEST(xXF86DGAViewPortChangedReq);
xXF86DGAViewPortChangedReply rep;
if (stuff->screen > screenInfo.numScreens)
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
if (!DGAActive(stuff->screen))
return (DGAErrorBase + XF86DGADirectNotActivated);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.result = 1;
WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *)&rep);
return Success;
}
#endif /* DGA_PROTOCOL_OLD_SUPPORT */
static int
SProcXDGADispatch (ClientPtr client)
{
return DGAErrorBase + XF86DGAClientNotLocal;
}
#if 0
#define DGA_REQ_DEBUG
#endif
#ifdef DGA_REQ_DEBUG
static char *dgaMinor[] = {
"QueryVersion",
"GetVideoLL",
"DirectVideo",
"GetViewPortSize",
"SetViewPort",
"GetVidPage",
"SetVidPage",
"InstallColormap",
"QueryDirectVideo",
"ViewPortChanged",
"10",
"11",
"QueryModes",
"SetMode",
"SetViewport",
"InstallColormap",
"SelectInput",
"FillRectangle",
"CopyArea",
"CopyTransparentArea",
"GetViewportStatus",
"Sync",
"OpenFramebuffer",
"CloseFramebuffer",
"SetClientVersion",
"ChangePixmapMode",
"CreateColormap",
};
#endif
static int
ProcXDGADispatch (ClientPtr client)
{
REQUEST(xReq);
if (!LocalClient(client))
return DGAErrorBase + XF86DGAClientNotLocal;
#ifdef DGA_REQ_DEBUG
if (stuff->data <= X_XDGACreateColormap)
fprintf (stderr, " DGA %s\n", dgaMinor[stuff->data]);
#endif
switch (stuff->data){
/*
* DGA2 Protocol
*/
case X_XDGAQueryVersion:
return ProcXDGAQueryVersion(client);
case X_XDGAQueryModes:
return ProcXDGAQueryModes(client);
case X_XDGASetMode:
return ProcXDGASetMode(client);
case X_XDGAOpenFramebuffer:
return ProcXDGAOpenFramebuffer(client);
case X_XDGACloseFramebuffer:
return ProcXDGACloseFramebuffer(client);
case X_XDGASetViewport:
return ProcXDGASetViewport(client);
case X_XDGAInstallColormap:
return ProcXDGAInstallColormap(client);
case X_XDGASelectInput:
return ProcXDGASelectInput(client);
case X_XDGAFillRectangle:
return ProcXDGAFillRectangle(client);
case X_XDGACopyArea:
return ProcXDGACopyArea(client);
case X_XDGACopyTransparentArea:
return ProcXDGACopyTransparentArea(client);
case X_XDGAGetViewportStatus:
return ProcXDGAGetViewportStatus(client);
case X_XDGASync:
return ProcXDGASync(client);
case X_XDGASetClientVersion:
return ProcXDGASetClientVersion(client);
case X_XDGAChangePixmapMode:
return ProcXDGAChangePixmapMode(client);
case X_XDGACreateColormap:
return ProcXDGACreateColormap(client);
/*
* Old DGA Protocol
*/
#ifdef DGA_PROTOCOL_OLD_SUPPORT
case X_XF86DGAGetVideoLL:
return ProcXF86DGAGetVideoLL(client);
case X_XF86DGADirectVideo:
return ProcXF86DGADirectVideo(client);
case X_XF86DGAGetViewPortSize:
return ProcXF86DGAGetViewPortSize(client);
case X_XF86DGASetViewPort:
return ProcXF86DGASetViewPort(client);
case X_XF86DGAGetVidPage:
return ProcXF86DGAGetVidPage(client);
case X_XF86DGASetVidPage:
return ProcXF86DGASetVidPage(client);
case X_XF86DGAInstallColormap:
return ProcXF86DGAInstallColormap(client);
case X_XF86DGAQueryDirectVideo:
return ProcXF86DGAQueryDirectVideo(client);
case X_XF86DGAViewPortChanged:
return ProcXF86DGAViewPortChanged(client);
#endif /* DGA_PROTOCOL_OLD_SUPPORT */
default:
return BadRequest;
}
}
void
XFree86DGARegister(INITARGS)
{
XDGAEventBase = &DGAEventBase;
}