xenocara/xserver/Xext/cup.c

343 lines
9.5 KiB
C

/*
Copyright 1997, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
#define NEED_REPLIES
#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "dixstruct.h"
#include "extnsionst.h"
#include "colormapst.h"
#include "scrnintstr.h"
#include "servermd.h"
#include "swapreq.h"
#define _XCUP_SERVER_
#include <X11/extensions/Xcupstr.h>
#include <X11/Xfuncproto.h>
#include "../os/osdep.h"
#include "modinit.h"
static int ProcDispatch(ClientPtr client);
static int SProcDispatch(ClientPtr client);
static void ResetProc(ExtensionEntry* extEntry);
#if defined(WIN32) || defined(TESTWIN32)
#define HAVE_SPECIAL_DESKTOP_COLORS
#endif
static xColorItem citems[] = {
#ifndef HAVE_SPECIAL_DESKTOP_COLORS
#define CUP_BLACK_PIXEL 0
#define CUP_WHITE_PIXEL 1
/* pix red green blue */
{ 0, 0, 0, 0, 0, 0 },
{ 1, 0xffff, 0xffff, 0xffff, 0, 0 }
#else
#ifndef WIN32
/*
This approximates the MS-Windows desktop colormap for testing
purposes but has black and white pixels in the typical Unix
locations, which should be switched if necessary if your system
has blackPixel and whitePixel swapped. No entries are provided
for colormap entries 254 and 255 because AllocColor/FindColor
will reuse entries zero and one.
*/
{ 0, 0, 0, 0, 0, 0 },
{ 1, 0xffff, 0xffff, 0xffff, 0, 0 },
{ 2, 0x8000, 0, 0, 0, 0 },
{ 3, 0, 0x8000, 0, 0, 0 },
{ 4, 0x8000, 0x8000, 0, 0, 0 },
{ 5, 0, 0, 0x8000, 0, 0 },
{ 6, 0x8000, 0, 0x8000, 0, 0 },
{ 7, 0, 0x8000, 0x8000, 0, 0 },
{ 8, 0xc000, 0xc000, 0xc000, 0, 0 },
{ 9, 0xc000, 0xdc00, 0xc000, 0, 0 },
{ 246, 0xa000, 0xa000, 0xa000, 0, 0 },
{ 247, 0x8000, 0x8000, 0x8000, 0, 0 },
{ 248, 0xffff, 0, 0, 0, 0 },
{ 249, 0, 0xffff, 0, 0, 0 },
{ 250, 0xffff, 0xffff, 0, 0, 0 },
{ 251, 0, 0, 0xffff, 0, 0 },
{ 252, 0xffff, 0, 0xffff, 0, 0 },
{ 253, 0, 0xffff, 0xffff, 0, 0 }
#else
/*
this is the MS-Windows desktop, adjusted for X's 16-bit color
specifications.
*/
{ 0, 0, 0, 0, 0, 0 },
{ 1, 0x8000, 0, 0, 0, 0 },
{ 2, 0, 0x8000, 0, 0, 0 },
{ 3, 0x8000, 0x8000, 0, 0, 0 },
{ 4, 0, 0, 0x8000, 0, 0 },
{ 5, 0x8000, 0, 0x8000, 0, 0 },
{ 6, 0, 0x8000, 0x8000, 0, 0 },
{ 7, 0xc000, 0xc000, 0xc000, 0, 0 },
{ 8, 0xc000, 0xdc00, 0xc000, 0, 0 },
{ 9, 0xa600, 0xca00, 0xf000, 0, 0 },
{ 246, 0xff00, 0xfb00, 0xf000, 0, 0 },
{ 247, 0xa000, 0xa000, 0xa400, 0, 0 },
{ 248, 0x8000, 0x8000, 0x8000, 0, 0 },
{ 249, 0xff00, 0, 0, 0, 0 },
{ 250, 0, 0xff00, 0, 0, 0 },
{ 251, 0xff00, 0xff00, 0, 0, 0 },
{ 252, 0, 0, 0xff00, 0, 0 },
{ 253, 0xff00, 0, 0xff00, 0, 0 },
{ 254, 0, 0xff00, 0xff00, 0, 0 },
{ 255, 0xff00, 0xff00, 0xff00, 0, 0 }
#endif
#endif
};
#define NUM_DESKTOP_COLORS (sizeof citems / sizeof citems[0])
void
XcupExtensionInit (INITARGS)
{
(void) AddExtension (XCUPNAME,
0,
XcupNumberErrors,
ProcDispatch,
SProcDispatch,
ResetProc,
StandardMinorOpcode);
/* PC servers initialize the desktop colors (citems) here! */
}
/*ARGSUSED*/
static
void ResetProc(
ExtensionEntry* extEntry)
{
}
static
int ProcQueryVersion(
register ClientPtr client)
{
/* REQUEST (xXcupQueryVersionReq); */
xXcupQueryVersionReply rep;
register int n;
REQUEST_SIZE_MATCH (xXcupQueryVersionReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequence_number = client->sequence;
rep.server_major_version = XCUP_MAJOR_VERSION;
rep.server_minor_version = XCUP_MINOR_VERSION;
if (client->swapped) {
swaps (&rep.sequence_number, n);
swapl (&rep.length, n);
swaps (&rep.server_major_version, n);
swaps (&rep.server_minor_version, n);
}
WriteToClient (client, sizeof (xXcupQueryVersionReply), (char *)&rep);
return client->noClientException;
}
static
int ProcGetReservedColormapEntries(
register ClientPtr client)
{
REQUEST (xXcupGetReservedColormapEntriesReq);
xXcupGetReservedColormapEntriesReply rep;
xColorItem* cptr;
register int n;
REQUEST_SIZE_MATCH (xXcupGetReservedColormapEntriesReq);
if (stuff->screen >= screenInfo.numScreens)
return BadValue;
#ifndef HAVE_SPECIAL_DESKTOP_COLORS
citems[CUP_BLACK_PIXEL].pixel =
screenInfo.screens[stuff->screen]->blackPixel;
citems[CUP_WHITE_PIXEL].pixel =
screenInfo.screens[stuff->screen]->whitePixel;
#endif
rep.type = X_Reply;
rep.sequence_number = client->sequence;
rep.length = NUM_DESKTOP_COLORS * 3;
if (client->swapped) {
swaps (&rep.sequence_number, n);
swapl (&rep.length, n);
}
WriteToClient (client, sizeof (xXcupGetReservedColormapEntriesReply), (char *)&rep);
for (n = 0, cptr = citems; n < NUM_DESKTOP_COLORS; n++, cptr++) {
if (client->swapped) SwapColorItem (cptr);
WriteToClient (client, SIZEOF(xColorItem), (char *)cptr);
}
return client->noClientException;
}
static
int ProcStoreColors(
register ClientPtr client)
{
REQUEST (xXcupStoreColorsReq);
ColormapPtr pcmp;
int rc;
REQUEST_AT_LEAST_SIZE (xXcupStoreColorsReq);
rc = dixLookupResource((pointer *)&pcmp, stuff->cmap, RT_COLORMAP,
client, DixAddAccess);
if (rc == Success) {
int ncolors, n;
xXcupStoreColorsReply rep;
xColorItem* cptr;
if (!(pcmp->class & DynamicClass))
return BadMatch;
ncolors = (client->req_len << 2) - SIZEOF (xXcupStoreColorsReq);
if (ncolors % SIZEOF(xColorItem))
return BadLength;
ncolors /= SIZEOF (xColorItem);
for (n = 0, cptr = (xColorItem*) &stuff[1]; n < ncolors; n++) {
Pixel pixel = cptr->pixel;
if (AllocColor (pcmp,
&cptr->red, &cptr->green, &cptr->blue,
&pixel, client->index) == Success) {
cptr->pixel = pixel;
cptr->flags = 0x08;
} else
cptr->flags = 0;
cptr = (xColorItem*) (((char*)cptr) + SIZEOF(xColorItem));
}
rep.type = X_Reply;
rep.sequence_number = client->sequence;
rep.length = ncolors * 3;
if (client->swapped) {
swaps (&rep.sequence_number, n);
swapl (&rep.length, n);
}
WriteToClient (client, sizeof (xXcupGetReservedColormapEntriesReply), (char *)&rep);
for (n = 0, cptr = (xColorItem*) &stuff[1]; n < ncolors; n++) {
if (client->swapped) SwapColorItem (cptr);
WriteToClient (client, SIZEOF(xColorItem), (char *)cptr);
cptr = (xColorItem*) (((char*)cptr) + SIZEOF(xColorItem));
}
return client->noClientException;
} else {
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
}
}
static
int ProcDispatch(
register ClientPtr client)
{
REQUEST (xReq);
switch (stuff->data)
{
case X_XcupQueryVersion:
return ProcQueryVersion (client);
case X_XcupGetReservedColormapEntries:
return ProcGetReservedColormapEntries (client);
case X_XcupStoreColors:
return ProcStoreColors (client);
default:
return BadRequest;
}
}
static
int SProcQueryVersion(
register ClientPtr client)
{
register int n;
REQUEST(xXcupQueryVersionReq);
swaps(&stuff->length, n);
return ProcQueryVersion(client);
}
static
int SProcGetReservedColormapEntries(
ClientPtr client)
{
register int n;
REQUEST (xXcupGetReservedColormapEntriesReq);
swaps (&stuff->length, n);
swapl (&stuff->screen, n);
REQUEST_AT_LEAST_SIZE (xXcupGetReservedColormapEntriesReq);
return ProcGetReservedColormapEntries (client);
}
static
int SProcXcupStoreColors(
ClientPtr client)
{
register int n;
int count;
xColorItem* pItem;
REQUEST (xXcupStoreColorsReq);
swaps (&stuff->length, n);
REQUEST_AT_LEAST_SIZE (xXcupStoreColorsReq);
swapl(&stuff->cmap, n);
pItem = (xColorItem*) &stuff[1];
for(count = LengthRestB(stuff)/sizeof(xColorItem); --count >= 0; )
SwapColorItem(pItem++);
return ProcStoreColors (client);
}
static
int SProcDispatch(
register ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_XcupQueryVersion:
return SProcQueryVersion (client);
case X_XcupGetReservedColormapEntries:
return SProcGetReservedColormapEntries (client);
case X_XcupStoreColors:
return SProcXcupStoreColors (client);
default:
return BadRequest;
}
}