diff options
author | Daniel Stone <daniel@fooishbar.org> | 2012-07-10 02:03:10 +0100 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2012-07-09 23:37:09 -0700 |
commit | 7a5880bc3b47e1f90a638f056ad4d40be6931977 (patch) | |
tree | 2f2c77600bef8671876d8ef8acf3777332dc4325 /hw/xfree86/common | |
parent | 6fb481d1251626456914d0012d6ca5a342bfdf71 (diff) |
Move DGA from extmod to built-in
Rather than leave DGA languishing in extmod, move it to be a built-in
extension. As it's quite specific to the Xorg DDX, just move it
sideways to the rest of the DGA code in hw/xfree86/common, and
initialise it from xf86ExtensionInit, rather than miinitext.
Signed-off-by: Daniel Stone <daniel@fooishbar.org>
Acked-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'hw/xfree86/common')
-rw-r--r-- | hw/xfree86/common/Makefile.am | 3 | ||||
-rw-r--r-- | hw/xfree86/common/dgaproc.h | 115 | ||||
-rw-r--r-- | hw/xfree86/common/xf86DGA.c | 1023 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Extensions.c | 14 |
4 files changed, 1154 insertions, 1 deletions
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 556b9ccc7..ea98449ca 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -20,6 +20,7 @@ endif if DGA DGASOURCES = xf86DGA.c +DGA_SDK = dgaproc.h endif if XORG_BUS_PLATFORM @@ -60,7 +61,7 @@ INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \ sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \ xf86PciInfo.h xf86Priv.h xf86Privstr.h \ xf86cmap.h xf86fbman.h xf86str.h xf86Xinput.h xisb.h \ - $(XVSDKINCS) $(XF86VMODE_SDK) xorgVersion.h \ + $(XVSDKINCS) $(XF86VMODE_SDK) $(DGA_SDK) xorgVersion.h \ xf86sbusBus.h xf86VGAarbiter.h xf86Optionstr.h xf86platformBus.h DISTCLEANFILES = xf86Build.h diff --git a/hw/xfree86/common/dgaproc.h b/hw/xfree86/common/dgaproc.h new file mode 100644 index 000000000..2c2fae097 --- /dev/null +++ b/hw/xfree86/common/dgaproc.h @@ -0,0 +1,115 @@ + +#ifndef __DGAPROC_H +#define __DGAPROC_H + +#include <X11/Xproto.h> +#include "pixmap.h" + +#define DGA_CONCURRENT_ACCESS 0x00000001 +#define DGA_FILL_RECT 0x00000002 +#define DGA_BLIT_RECT 0x00000004 +#define DGA_BLIT_RECT_TRANS 0x00000008 +#define DGA_PIXMAP_AVAILABLE 0x00000010 + +#define DGA_INTERLACED 0x00010000 +#define DGA_DOUBLESCAN 0x00020000 + +#define DGA_FLIP_IMMEDIATE 0x00000001 +#define DGA_FLIP_RETRACE 0x00000002 + +#define DGA_COMPLETED 0x00000000 +#define DGA_PENDING 0x00000001 + +#define DGA_NEED_ROOT 0x00000001 + +typedef struct { + int num; /* A unique identifier for the mode (num > 0) */ + char *name; /* name of mode given in the XF86Config */ + int VSync_num; + int VSync_den; + int flags; /* DGA_CONCURRENT_ACCESS, etc... */ + int imageWidth; /* linear accessible portion (pixels) */ + int imageHeight; + int pixmapWidth; /* Xlib accessible portion (pixels) */ + int pixmapHeight; /* both fields ignored if no concurrent access */ + int bytesPerScanline; + int byteOrder; /* MSBFirst, LSBFirst */ + int depth; + int bitsPerPixel; + unsigned long red_mask; + unsigned long green_mask; + unsigned long blue_mask; + short visualClass; + int viewportWidth; + int viewportHeight; + int xViewportStep; /* viewport position granularity */ + int yViewportStep; + int maxViewportX; /* max viewport origin */ + int maxViewportY; + int viewportFlags; /* types of page flipping possible */ + int offset; + int reserved1; + int reserved2; +} XDGAModeRec, *XDGAModePtr; + +/* DDX interface */ + +extern _X_EXPORT int + DGASetMode(int Index, int num, XDGAModePtr mode, PixmapPtr *pPix); + +extern _X_EXPORT void + DGASetInputMode(int Index, Bool keyboard, Bool mouse); + +extern _X_EXPORT void + DGASelectInput(int Index, ClientPtr client, long mask); + +extern _X_EXPORT Bool DGAAvailable(int Index); +extern _X_EXPORT Bool DGAScreenAvailable(ScreenPtr pScreen); +extern _X_EXPORT Bool DGAActive(int Index); +extern _X_EXPORT void DGAShutdown(void); +extern _X_EXPORT void DGAInstallCmap(ColormapPtr cmap); +extern _X_EXPORT int DGAGetViewportStatus(int Index); +extern _X_EXPORT int DGASync(int Index); + +extern _X_EXPORT int + DGAFillRect(int Index, int x, int y, int w, int h, unsigned long color); + +extern _X_EXPORT int + DGABlitRect(int Index, int srcx, int srcy, int w, int h, int dstx, int dsty); + +extern _X_EXPORT int + +DGABlitTransRect(int Index, + int srcx, int srcy, + int w, int h, int dstx, int dsty, unsigned long color); + +extern _X_EXPORT int + DGASetViewport(int Index, int x, int y, int mode); + +extern _X_EXPORT int DGAGetModes(int Index); +extern _X_EXPORT int DGAGetOldDGAMode(int Index); + +extern _X_EXPORT int DGAGetModeInfo(int Index, XDGAModePtr mode, int num); + +extern _X_EXPORT Bool DGAVTSwitch(void); +extern _X_EXPORT Bool DGAStealButtonEvent(DeviceIntPtr dev, int Index, + int button, int is_down); +extern _X_EXPORT Bool DGAStealMotionEvent(DeviceIntPtr dev, int Index, int dx, + int dy); +extern _X_EXPORT Bool DGAStealKeyEvent(DeviceIntPtr dev, int Index, + int key_code, int is_down); + +extern _X_EXPORT Bool DGAOpenFramebuffer(int Index, char **name, + unsigned char **mem, int *size, + int *offset, int *flags); +extern _X_EXPORT void DGACloseFramebuffer(int Index); +extern _X_EXPORT Bool DGAChangePixmapMode(int Index, int *x, int *y, int mode); +extern _X_EXPORT int DGACreateColormap(int Index, ClientPtr client, int id, + int mode, int alloc); + +extern _X_EXPORT unsigned char DGAReqCode; +extern _X_EXPORT int DGAErrorBase; +extern _X_EXPORT int DGAEventBase; +extern _X_EXPORT int *XDGAEventBase; + +#endif /* __DGAPROC_H */ diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c index ab172a836..00b90226b 100644 --- a/hw/xfree86/common/xf86DGA.c +++ b/hw/xfree86/common/xf86DGA.c @@ -1,4 +1,6 @@ /* + * Copyright (c) 1995 Jon Tombs + * Copyright (c) 1995, 1996, 1999 XFree86 Inc * Copyright (c) 1998-2002 by The XFree86 Project, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -27,10 +29,20 @@ * Written by Mark Vojkovich */ +/* + * This is quite literally just two files glued together: + * hw/xfree86/common/xf86DGA.c is the first part, and + * hw/xfree86/dixmods/extmod/xf86dga2.c is the second part. One day, if + * someone actually cares about DGA, it'd be nice to clean this up. But trust + * me, I am not that person. + */ + #ifdef HAVE_XORG_CONFIG_H #include <xorg-config.h> #endif +#include <X11/X.h> +#include <X11/Xproto.h> #include "xf86.h" #include "xf86str.h" #include "xf86Priv.h" @@ -48,9 +60,24 @@ #include "exevents.h" #include "eventstr.h" #include "eventconvert.h" +#include "xf86Extensions.h" #include "mi.h" +#include "misc.h" +#include "dixstruct.h" +#include "dixevents.h" +#include "extnsionst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "swaprep.h" +#include "dgaproc.h" +#include "protocol-versions.h" + +#include <string.h> + +#define DGA_PROTOCOL_OLD_SUPPORT 1 + static DevPrivateKeyRec DGAScreenKeyRec; #define DGAScreenKeyRegistered dixPrivateKeyRegistered(&DGAScreenKeyRec) @@ -1178,3 +1205,999 @@ DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) break; } } + +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(void) +{ + XDGAEventBase = &DGAEventBase; +} + +void +XFree86DGAExtensionInit(void) +{ + 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); + } +} diff --git a/hw/xfree86/common/xf86Extensions.c b/hw/xfree86/common/xf86Extensions.c index aed0635a2..7a84988d7 100644 --- a/hw/xfree86/common/xf86Extensions.c +++ b/hw/xfree86/common/xf86Extensions.c @@ -41,10 +41,23 @@ #include "xselinux.h" #endif +#ifdef XFreeXDGA +#include <X11/extensions/xf86dgaproto.h> +#endif + /* * DDX-specific extensions. */ static ExtensionModule extensionModules[] = { +#ifdef XFreeXDGA + { + XFree86DGAExtensionInit, + XF86DGANAME, + &noXFree86DGAExtension, + XFree86DGARegister, + NULL + }, +#endif }; static void @@ -52,6 +65,7 @@ load_extension_config(void) { XF86ConfModulePtr mod_con = xf86configptr->conf_modules; XF86LoadPtr modp; + int i; /* Only the best. */ if (!mod_con) |