1030 lines
27 KiB
C
1030 lines
27 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 "protocol-versions.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "modinit.h"
|
|
|
|
#define DGA_PROTOCOL_OLD_SUPPORT 1
|
|
|
|
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)
|
|
|
|
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 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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|