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

1030 lines
27 KiB
C
Raw Normal View History

2003-11-14 17:48:57 +01:00
/*
* Copyright (c) 1995 Jon Tombs
* Copyright (c) 1995, 1996, 1999 XFree86 Inc
* Copyright (c) 1999 - The XFree86 Project Inc.
*
* Written by Mark Vojkovich
*/
2003-11-14 17:48:57 +01:00
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
2003-11-14 17:48:57 +01:00
#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>
2003-11-14 17:48:57 +01:00
#include "swaprep.h"
#include "dgaproc.h"
#include "protocol-versions.h"
2003-11-14 17:48:57 +01:00
#include <string.h>
#include "modinit.h"
2003-11-14 17:48:57 +01:00
#define DGA_PROTOCOL_OLD_SUPPORT 1
static void XDGAResetProc(ExtensionEntry * extEntry);
2003-11-14 17:48:57 +01:00
static void DGAClientStateChange(CallbackListPtr *, pointer, pointer);
2003-11-14 17:48:57 +01:00
unsigned char DGAReqCode = 0;
int DGAErrorBase;
int DGAEventBase;
2003-11-14 17:48:57 +01:00
static DevPrivateKeyRec DGAScreenPrivateKeyRec;
#define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec)
#define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized)
static DevPrivateKeyRec DGAClientPrivateKeyRec;
#define DGAClientPrivateKey (&DGAClientPrivateKeyRec)
2003-11-14 17:48:57 +01:00
static int DGACallbackRefCount = 0;
/* This holds the client's version information */
typedef struct {
int major;
int minor;
2003-11-14 17:48:57 +01:00
} 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)
2003-11-14 17:48:57 +01:00
static void
XDGAResetProc(ExtensionEntry * extEntry)
2003-11-14 17:48:57 +01:00
{
DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
DGACallbackRefCount = 0;
2003-11-14 17:48:57 +01:00
}
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;
2003-11-14 17:48:57 +01:00
WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *) &rep);
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGAOpenFramebuffer(ClientPtr client)
{
REQUEST(xXDGAOpenFramebufferReq);
xXDGAOpenFramebufferReply rep;
char *deviceName;
int nameSize;
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (!DGAAvailable(stuff->screen))
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
}
nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
rep.length = bytes_to_int32(nameSize);
2003-11-14 17:48:57 +01:00
WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *) &rep);
if (rep.length)
WriteToClient(client, nameSize, deviceName);
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGACloseFramebuffer(ClientPtr client)
{
REQUEST(xXDGACloseFramebufferReq);
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (!DGAAvailable(stuff->screen))
2003-11-14 17:48:57 +01:00
return DGAErrorBase + XF86DGANoDirectVideoMode;
REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
DGACloseFramebuffer(stuff->screen);
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGAQueryModes(ClientPtr client)
{
int i, num, size;
2003-11-14 17:48:57 +01:00
REQUEST(xXDGAQueryModesReq);
xXDGAQueryModesReply rep;
xXDGAModeInfo info;
XDGAModePtr mode;
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
}
if (!(num = DGAGetModes(stuff->screen))) {
WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep);
return Success;
2003-11-14 17:48:57 +01:00
}
if (!(mode = (XDGAModePtr) malloc(num * sizeof(XDGAModeRec))))
return BadAlloc;
2003-11-14 17:48:57 +01:00
for (i = 0; i < num; i++)
DGAGetModeInfo(stuff->screen, mode + i, i + 1);
2003-11-14 17:48:57 +01:00
size = num * sz_xXDGAModeInfo;
for (i = 0; i < num; i++)
size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
2003-11-14 17:48:57 +01:00
rep.number = num;
rep.length = bytes_to_int32(size);
2003-11-14 17:48:57 +01:00
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);
2003-11-14 17:48:57 +01:00
}
free(mode);
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
static void
DGAClientStateChange(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
{
NewClientInfoRec *pci = (NewClientInfoRec *) calldata;
2003-11-14 17:48:57 +01:00
ClientPtr client = NULL;
int i;
for (i = 0; i < screenInfo.numScreens; i++) {
if (DGA_GETCLIENT(i) == pci->client) {
client = pci->client;
break;
}
2003-11-14 17:48:57 +01:00
}
if (client &&
((client->clientState == ClientStateGone) ||
(client->clientState == ClientStateRetained))) {
XDGAModeRec mode;
PixmapPtr pPix;
2003-11-14 17:48:57 +01:00
DGA_SETCLIENT(i, NULL);
DGASelectInput(i, NULL, 0);
DGASetMode(i, 0, &mode, &pPix);
2003-11-14 17:48:57 +01:00
if (--DGACallbackRefCount == 0)
DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
2003-11-14 17:48:57 +01:00
}
}
static int
ProcXDGASetMode(ClientPtr client)
{
REQUEST(xXDGASetModeReq);
xXDGASetModeReply rep;
XDGAModeRec mode;
xXDGAModeInfo info;
PixmapPtr pPix;
ClientPtr owner;
2003-11-14 17:48:57 +01:00
int size;
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
owner = DGA_GETCLIENT(stuff->screen);
2003-11-14 17:48:57 +01:00
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))
2003-11-14 17:48:57 +01:00
return DGAErrorBase + XF86DGANoDirectVideoMode;
if (owner && owner != client)
2003-11-14 17:48:57 +01:00
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;
}
2003-11-14 17:48:57 +01:00
if (Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
return BadValue;
2003-11-14 17:48:57 +01:00
if (!owner) {
if (DGACallbackRefCount++ == 0)
AddCallback(&ClientStateCallback, DGAClientStateChange, NULL);
2003-11-14 17:48:57 +01:00
}
DGA_SETCLIENT(stuff->screen, client);
2003-11-14 17:48:57 +01:00
if (pPix) {
if (AddResource(stuff->pid, RT_PIXMAP, (pointer) (pPix))) {
pPix->drawable.id = (int) stuff->pid;
rep.flags = DGA_PIXMAP_AVAILABLE;
}
2003-11-14 17:48:57 +01:00
}
size = strlen(mode.name) + 1;
2003-11-14 17:48:57 +01:00
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);
2003-11-14 17:48:57 +01:00
WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep);
WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info));
2003-11-14 17:48:57 +01:00
WriteToClient(client, size, mode.name);
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGASetViewport(ClientPtr client)
{
REQUEST(xXDGASetViewportReq);
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASetViewportReq);
DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGAInstallColormap(ClientPtr client)
{
ColormapPtr cmap;
int rc;
2003-11-14 17:48:57 +01:00
REQUEST(xXDGAInstallColormapReq);
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGASelectInput(ClientPtr client)
{
REQUEST(xXDGASelectInputReq);
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASelectInputReq);
if (DGA_GETCLIENT(stuff->screen) == client)
DGASelectInput(stuff->screen, client, stuff->mask);
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGAFillRectangle(ClientPtr client)
{
REQUEST(xXDGAFillRectangleReq);
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
if (Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
stuff->width, stuff->height, stuff->color))
return BadMatch;
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGACopyArea(ClientPtr client)
{
REQUEST(xXDGACopyAreaReq);
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGACopyTransparentArea(ClientPtr client)
{
REQUEST(xXDGACopyTransparentAreaReq);
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGAGetViewportStatus(ClientPtr client)
{
REQUEST(xXDGAGetViewportStatusReq);
xXDGAGetViewportStatusReply rep;
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGASync(ClientPtr client)
{
REQUEST(xXDGASyncReq);
xXDGASyncReply rep;
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
}
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);
2003-11-14 17:48:57 +01:00
}
pPriv->major = stuff->major;
pPriv->minor = stuff->minor;
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGAChangePixmapMode(ClientPtr client)
{
REQUEST(xXDGAChangePixmapModeReq);
xXDGAChangePixmapModeReply rep;
int x, y;
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
2003-11-14 17:48:57 +01:00
x = stuff->x;
y = stuff->y;
if (!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
return BadMatch;
2003-11-14 17:48:57 +01:00
rep.x = x;
rep.y = y;
WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *) &rep);
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
static int
ProcXDGACreateColormap(ClientPtr client)
{
REQUEST(xXDGACreateColormapReq);
int result;
if (stuff->screen >= screenInfo.numScreens)
2003-11-14 17:48:57 +01:00
return BadValue;
if (DGA_GETCLIENT(stuff->screen) != client)
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
return Success;
2003-11-14 17:48:57 +01:00
}
/*
*
* 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 */
2003-11-14 17:48:57 +01:00
static int
SProcXDGADispatch(ClientPtr client)
2003-11-14 17:48:57 +01:00
{
return DGAErrorBase + XF86DGAClientNotLocal;
2003-11-14 17:48:57 +01:00
}
#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)
2003-11-14 17:48:57 +01:00
{
REQUEST(xReq);
if (!LocalClient(client))
return DGAErrorBase + XF86DGAClientNotLocal;
2003-11-14 17:48:57 +01:00
#ifdef DGA_REQ_DEBUG
if (stuff->data <= X_XDGACreateColormap)
fprintf(stderr, " DGA %s\n", dgaMinor[stuff->data]);
2003-11-14 17:48:57 +01:00
#endif
switch (stuff->data) {
/*
* DGA2 Protocol
*/
2003-11-14 17:48:57 +01:00
case X_XDGAQueryVersion:
return ProcXDGAQueryVersion(client);
2003-11-14 17:48:57 +01:00
case X_XDGAQueryModes:
return ProcXDGAQueryModes(client);
2003-11-14 17:48:57 +01:00
case X_XDGASetMode:
return ProcXDGASetMode(client);
2003-11-14 17:48:57 +01:00
case X_XDGAOpenFramebuffer:
return ProcXDGAOpenFramebuffer(client);
2003-11-14 17:48:57 +01:00
case X_XDGACloseFramebuffer:
return ProcXDGACloseFramebuffer(client);
2003-11-14 17:48:57 +01:00
case X_XDGASetViewport:
return ProcXDGASetViewport(client);
2003-11-14 17:48:57 +01:00
case X_XDGAInstallColormap:
return ProcXDGAInstallColormap(client);
2003-11-14 17:48:57 +01:00
case X_XDGASelectInput:
return ProcXDGASelectInput(client);
2003-11-14 17:48:57 +01:00
case X_XDGAFillRectangle:
return ProcXDGAFillRectangle(client);
2003-11-14 17:48:57 +01:00
case X_XDGACopyArea:
return ProcXDGACopyArea(client);
2003-11-14 17:48:57 +01:00
case X_XDGACopyTransparentArea:
return ProcXDGACopyTransparentArea(client);
2003-11-14 17:48:57 +01:00
case X_XDGAGetViewportStatus:
return ProcXDGAGetViewportStatus(client);
2003-11-14 17:48:57 +01:00
case X_XDGASync:
return ProcXDGASync(client);
2003-11-14 17:48:57 +01:00
case X_XDGASetClientVersion:
return ProcXDGASetClientVersion(client);
2003-11-14 17:48:57 +01:00
case X_XDGAChangePixmapMode:
return ProcXDGAChangePixmapMode(client);
2003-11-14 17:48:57 +01:00
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 */
2003-11-14 17:48:57 +01:00
default:
return BadRequest;
2003-11-14 17:48:57 +01:00
}
}
void
XFree86DGARegister(INITARGS)
2003-11-14 17:48:57 +01:00
{
XDGAEventBase = &DGAEventBase;
2003-11-14 17:48:57 +01:00
}
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);
}
}