789d64e19a
Casting return to (void) was used to tell lint that you intended to ignore the return value, so it didn't warn you about it. Casting the third argument to (char *) was used as the most generic pointer type in the days before compilers supported C89 (void *) (except for a couple places it's used for byte-sized pointer math). Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: Keith Packard <keithp@keithp.com> Tested-by: Daniel Stone <daniel@fooishbar.org>
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), &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), &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, &rep);
|
|
return Success;
|
|
}
|
|
|
|
if (!(num = DGAGetModes(stuff->screen))) {
|
|
WriteToClient(client, sz_xXDGAQueryModesReply, &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, &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, (&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, &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, &rep);
|
|
WriteToClient(client, sz_xXDGAModeInfo, (&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), &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), &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), &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), &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), &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), &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), &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), &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);
|
|
}
|
|
}
|