New upstream version 3.5.99.27
This commit is contained in:
194
nx-X11/programs/Xserver/mi/Imakefile
Normal file
194
nx-X11/programs/Xserver/mi/Imakefile
Normal file
@@ -0,0 +1,194 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* nx-X11, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
NULL =
|
||||
|
||||
#include <Server.tmpl>
|
||||
|
||||
#if ! HasCbrt
|
||||
CBRT_SRC = cbrt.c
|
||||
CBRT_OBJ = cbrt.o
|
||||
#endif
|
||||
|
||||
#if HasFfs
|
||||
FFS_DEFINES = -DHAS_FFS
|
||||
#endif
|
||||
|
||||
MIINITEXTSRC = miinitext.c
|
||||
MIINITEXTOBJ = miinitext.o
|
||||
|
||||
SRCS = $(CBRT_SRC) \
|
||||
mivaltree.c \
|
||||
mipolyseg.c \
|
||||
mipolyrect.c \
|
||||
mipoly.c \
|
||||
mipolycon.c \
|
||||
mipolygen.c \
|
||||
mipolyutil.c \
|
||||
mifillrct.c \
|
||||
miwideline.c \
|
||||
mispans.c \
|
||||
miarc.c \
|
||||
mizerarc.c \
|
||||
mifillarc.c \
|
||||
miwindow.c \
|
||||
micursor.c \
|
||||
mipolytext.c \
|
||||
mibitblt.c \
|
||||
mipolypnt.c \
|
||||
mipushpxl.c \
|
||||
miglblt.c \
|
||||
mizerline.c \
|
||||
mizerclip.c \
|
||||
mifpolycon.c \
|
||||
midash.c \
|
||||
mibstore.c \
|
||||
$(MIINITEXTSRC) \
|
||||
mieq.c \
|
||||
mipointer.c \
|
||||
misprite.c \
|
||||
midispcur.c \
|
||||
miscrinit.c \
|
||||
migc.c \
|
||||
micmap.c \
|
||||
mioverlay.c \
|
||||
miexpose.c \
|
||||
$(NULL)
|
||||
|
||||
OBJS = $(CBRT_OBJ) \
|
||||
mivaltree.o \
|
||||
mipolyseg.o \
|
||||
mipolyrect.o \
|
||||
mipoly.o \
|
||||
mipolycon.o \
|
||||
mipolygen.o \
|
||||
mipolyutil.o \
|
||||
mifillrct.o \
|
||||
miwideline.o \
|
||||
mispans.o \
|
||||
miarc.o \
|
||||
mizerarc.o \
|
||||
mifillarc.o \
|
||||
miwindow.o \
|
||||
micursor.o \
|
||||
mipolytext.o \
|
||||
mibitblt.o \
|
||||
mipolypnt.o \
|
||||
mipushpxl.o \
|
||||
miglblt.o \
|
||||
mizerline.o \
|
||||
mizerclip.o \
|
||||
mifpolycon.o \
|
||||
midash.o \
|
||||
mibstore.o \
|
||||
$(MIINITEXTOBJ) \
|
||||
mieq.o \
|
||||
mipointer.o \
|
||||
misprite.o \
|
||||
midispcur.o \
|
||||
miscrinit.o \
|
||||
migc.o \
|
||||
micmap.o \
|
||||
mioverlay.o \
|
||||
miexpose.o \
|
||||
$(NULL)
|
||||
|
||||
#if defined(XorgVersion)
|
||||
/*
|
||||
* Make sure XINPUT, XF86VidTune, etc aren't defined for the miinitext.o
|
||||
* used by Xnest, Xvfb
|
||||
*/
|
||||
|
||||
#if NXLibraries
|
||||
|
||||
NX_DEFINES = -DNXAGENT_SERVER \
|
||||
$(NULL)
|
||||
|
||||
/*
|
||||
* To build the NX agent we need the XINPUT symbol
|
||||
* in order to build the XInputExtension, since we
|
||||
* don't use the XF86 module loader.
|
||||
*/
|
||||
EXT_DEFINES = ExtensionDefines \
|
||||
$(NULL)
|
||||
#else
|
||||
EXT_DEFINES = ExtensionDefines \
|
||||
-UXINPUT \
|
||||
$(NULL)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
INCLUDES = -I. \
|
||||
-I../include \
|
||||
-I../render \
|
||||
-I../xfixes \
|
||||
-I../damageext \
|
||||
-I../miext/damage \
|
||||
-I$(XINCLUDESRC) \
|
||||
-I$(EXTINCSRC) \
|
||||
-I$(SERVERSRC)/Xext \
|
||||
`pkg-config --cflags-only-I pixman-1` \
|
||||
$(NULL)
|
||||
|
||||
LINTLIBS = \
|
||||
../dix/llib-ldix.ln \
|
||||
../os/llib-los.ln \
|
||||
$(NULL)
|
||||
|
||||
DEFINES = $(FFS_DEFINES) $(NX_DEFINES)
|
||||
|
||||
NormalLibraryObjectRule()
|
||||
NormalLibraryTarget(mi,$(OBJS))
|
||||
LintLibraryTarget(mi,$(SRCS))
|
||||
NormalLintTarget($(SRCS))
|
||||
|
||||
#ifndef Win32Architecture
|
||||
NormalLibraryTarget(cbrt,cbrt.o)
|
||||
#endif
|
||||
|
||||
SpecialCObjectRule(miinitext,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
SpecialCObjectRule(miscrinit,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
|
||||
#ifdef ItsyCompilerBug
|
||||
SpecialCObjectRule(mipolycon,$(_NOOP_),-O0)
|
||||
#endif
|
||||
#if defined(OpenBSDArchitecture) && defined(Sparc64Architecture)
|
||||
SpecialCObjectRule(mizerclip,NullParameter,-O0)
|
||||
#endif
|
||||
|
||||
AllTarget($(EXTRAMIINITEXTOBJ))
|
||||
|
||||
DependTarget()
|
||||
|
||||
InstallDriverSDKNonExecFile(mi.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(mibstore.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(micmap.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(migc.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(miline.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(mipointer.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(mipointrst.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(mizerarc.h,$(DRIVERSDKINCLUDEDIR))
|
||||
InstallDriverSDKNonExecFile(micoord.h,$(DRIVERSDKINCLUDEDIR))
|
||||
46
nx-X11/programs/Xserver/mi/cbrt.c
Normal file
46
nx-X11/programs/Xserver/mi/cbrt.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
|
||||
Copyright 1990, 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.
|
||||
|
||||
*/
|
||||
|
||||
/* simple cbrt, in case your math library doesn't have a good one */
|
||||
|
||||
/*
|
||||
* Would normally include <math.h> for this, but for the sake of compiler
|
||||
* warnings, we don't want to get duplicate declarations for cbrt().
|
||||
*/
|
||||
|
||||
double pow(double, double);
|
||||
double cbrt(double);
|
||||
|
||||
double
|
||||
cbrt(double x)
|
||||
{
|
||||
if (x > 0.0)
|
||||
return pow(x, 1.0/3.0);
|
||||
else
|
||||
return -pow(-x, 1.0/3.0);
|
||||
}
|
||||
629
nx-X11/programs/Xserver/mi/mi.h
Normal file
629
nx-X11/programs/Xserver/mi/mi.h
Normal file
@@ -0,0 +1,629 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef MI_H
|
||||
#define MI_H
|
||||
#include <nx-X11/X.h>
|
||||
#include "region.h"
|
||||
#include "validate.h"
|
||||
#include "window.h"
|
||||
#include "gc.h"
|
||||
#include <X11/fonts/font.h>
|
||||
#include "input.h"
|
||||
#include "cursor.h"
|
||||
|
||||
#define MiBits CARD32
|
||||
|
||||
typedef struct _miDash *miDashPtr;
|
||||
#define EVEN_DASH 0
|
||||
#define ODD_DASH ~0
|
||||
|
||||
/* miarc.c */
|
||||
|
||||
extern void miPolyArc(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*narcs*/,
|
||||
xArc * /*parcs*/
|
||||
);
|
||||
|
||||
/* mibitblt.c */
|
||||
|
||||
extern RegionPtr miCopyArea(
|
||||
DrawablePtr /*pSrcDrawable*/,
|
||||
DrawablePtr /*pDstDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*xIn*/,
|
||||
int /*yIn*/,
|
||||
int /*widthSrc*/,
|
||||
int /*heightSrc*/,
|
||||
int /*xOut*/,
|
||||
int /*yOut*/
|
||||
);
|
||||
|
||||
extern void miOpqStipDrawable(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
RegionPtr /*prgnSrc*/,
|
||||
MiBits * /*pbits*/,
|
||||
int /*srcx*/,
|
||||
int /*w*/,
|
||||
int /*h*/,
|
||||
int /*dstx*/,
|
||||
int /*dsty*/
|
||||
);
|
||||
|
||||
extern RegionPtr miCopyPlane(
|
||||
DrawablePtr /*pSrcDrawable*/,
|
||||
DrawablePtr /*pDstDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*srcx*/,
|
||||
int /*srcy*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int /*dstx*/,
|
||||
int /*dsty*/,
|
||||
unsigned long /*bitPlane*/
|
||||
);
|
||||
|
||||
extern void miGetImage(
|
||||
DrawablePtr /*pDraw*/,
|
||||
int /*sx*/,
|
||||
int /*sy*/,
|
||||
int /*w*/,
|
||||
int /*h*/,
|
||||
unsigned int /*format*/,
|
||||
unsigned long /*planeMask*/,
|
||||
char * /*pdstLine*/
|
||||
);
|
||||
|
||||
extern void miPutImage(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*depth*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*w*/,
|
||||
int /*h*/,
|
||||
int /*leftPad*/,
|
||||
int /*format*/,
|
||||
char * /*pImage*/
|
||||
);
|
||||
|
||||
/* micursor.c */
|
||||
|
||||
extern void miRecolorCursor(
|
||||
ScreenPtr /*pScr*/,
|
||||
CursorPtr /*pCurs*/,
|
||||
Bool /*displayed*/
|
||||
);
|
||||
|
||||
/* midash.c */
|
||||
|
||||
extern miDashPtr miDashLine(
|
||||
int /*npt*/,
|
||||
DDXPointPtr /*ppt*/,
|
||||
unsigned int /*nDash*/,
|
||||
unsigned char * /*pDash*/,
|
||||
unsigned int /*offset*/,
|
||||
int * /*pnseg*/
|
||||
);
|
||||
|
||||
extern void miStepDash(
|
||||
int /*dist*/,
|
||||
int * /*pDashIndex*/,
|
||||
unsigned char * /*pDash*/,
|
||||
int /*numInDashList*/,
|
||||
int * /*pDashOffset*/
|
||||
);
|
||||
|
||||
/* mieq.c */
|
||||
|
||||
|
||||
#ifndef INPUT_H
|
||||
typedef struct _DeviceRec *DevicePtr;
|
||||
#endif
|
||||
|
||||
extern Bool mieqInit(
|
||||
DevicePtr /*pKbd*/,
|
||||
DevicePtr /*pPtr*/
|
||||
);
|
||||
|
||||
extern void mieqEnqueue(
|
||||
xEventPtr /*e*/
|
||||
);
|
||||
|
||||
extern void mieqSwitchScreen(
|
||||
ScreenPtr /*pScreen*/,
|
||||
Bool /*fromDIX*/
|
||||
);
|
||||
|
||||
extern void mieqProcessInputEvents(
|
||||
void
|
||||
);
|
||||
|
||||
/* miexpose.c */
|
||||
|
||||
extern RegionPtr miHandleExposures(
|
||||
DrawablePtr /*pSrcDrawable*/,
|
||||
DrawablePtr /*pDstDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*srcx*/,
|
||||
int /*srcy*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int /*dstx*/,
|
||||
int /*dsty*/,
|
||||
unsigned long /*plane*/
|
||||
);
|
||||
|
||||
extern void miSendGraphicsExpose(
|
||||
ClientPtr /*client*/,
|
||||
RegionPtr /*pRgn*/,
|
||||
XID /*drawable*/,
|
||||
int /*major*/,
|
||||
int /*minor*/
|
||||
);
|
||||
|
||||
extern void miSendExposures(
|
||||
WindowPtr /*pWin*/,
|
||||
RegionPtr /*pRgn*/,
|
||||
int /*dx*/,
|
||||
int /*dy*/
|
||||
);
|
||||
|
||||
extern void miWindowExposures(
|
||||
WindowPtr /*pWin*/,
|
||||
RegionPtr /*prgn*/,
|
||||
RegionPtr /*other_exposed*/
|
||||
);
|
||||
|
||||
extern void miPaintWindow(
|
||||
WindowPtr /*pWin*/,
|
||||
RegionPtr /*prgn*/,
|
||||
int /*what*/
|
||||
);
|
||||
|
||||
extern void miClearDrawable(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/
|
||||
);
|
||||
|
||||
/* mifillrct.c */
|
||||
|
||||
extern void miPolyFillRect(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*nrectFill*/,
|
||||
xRectangle * /*prectInit*/
|
||||
);
|
||||
|
||||
/* miglblt.c */
|
||||
|
||||
extern void miPolyGlyphBlt(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
unsigned int /*nglyph*/,
|
||||
CharInfoPtr * /*ppci*/,
|
||||
void * /*pglyphBase*/
|
||||
);
|
||||
|
||||
extern void miImageGlyphBlt(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
unsigned int /*nglyph*/,
|
||||
CharInfoPtr * /*ppci*/,
|
||||
void * /*pglyphBase*/
|
||||
);
|
||||
|
||||
/* mipoly.c */
|
||||
|
||||
extern void miFillPolygon(
|
||||
DrawablePtr /*dst*/,
|
||||
GCPtr /*pgc*/,
|
||||
int /*shape*/,
|
||||
int /*mode*/,
|
||||
int /*count*/,
|
||||
DDXPointPtr /*pPts*/
|
||||
);
|
||||
|
||||
/* mipolycon.c */
|
||||
|
||||
extern Bool miFillConvexPoly(
|
||||
DrawablePtr /*dst*/,
|
||||
GCPtr /*pgc*/,
|
||||
int /*count*/,
|
||||
DDXPointPtr /*ptsIn*/
|
||||
);
|
||||
|
||||
/* mipolygen.c */
|
||||
|
||||
extern Bool miFillGeneralPoly(
|
||||
DrawablePtr /*dst*/,
|
||||
GCPtr /*pgc*/,
|
||||
int /*count*/,
|
||||
DDXPointPtr /*ptsIn*/
|
||||
);
|
||||
|
||||
/* mipolypnt.c */
|
||||
|
||||
extern void miPolyPoint(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*mode*/,
|
||||
int /*npt*/,
|
||||
xPoint * /*pptInit*/
|
||||
);
|
||||
|
||||
/* mipolyrect.c */
|
||||
|
||||
extern void miPolyRectangle(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*nrects*/,
|
||||
xRectangle * /*pRects*/
|
||||
);
|
||||
|
||||
/* mipolyseg.c */
|
||||
|
||||
extern void miPolySegment(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*nseg*/,
|
||||
xSegment * /*pSegs*/
|
||||
);
|
||||
|
||||
/* mipolytext.c */
|
||||
|
||||
extern int miPolyText(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*count*/,
|
||||
char * /*chars*/,
|
||||
FontEncoding /*fontEncoding*/
|
||||
);
|
||||
|
||||
extern int miPolyText8(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*count*/,
|
||||
char * /*chars*/
|
||||
);
|
||||
|
||||
extern int miPolyText16(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*count*/,
|
||||
unsigned short * /*chars*/
|
||||
);
|
||||
|
||||
extern int miImageText(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*count*/,
|
||||
char * /*chars*/,
|
||||
FontEncoding /*fontEncoding*/
|
||||
);
|
||||
|
||||
extern void miImageText8(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*count*/,
|
||||
char * /*chars*/
|
||||
);
|
||||
|
||||
extern void miImageText16(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*count*/,
|
||||
unsigned short * /*chars*/
|
||||
);
|
||||
|
||||
/* mipushpxl.c */
|
||||
|
||||
extern void miPushPixels(
|
||||
GCPtr /*pGC*/,
|
||||
PixmapPtr /*pBitMap*/,
|
||||
DrawablePtr /*pDrawable*/,
|
||||
int /*dx*/,
|
||||
int /*dy*/,
|
||||
int /*xOrg*/,
|
||||
int /*yOrg*/
|
||||
);
|
||||
|
||||
/* see also region.h */
|
||||
|
||||
extern Bool RegionRectAlloc(
|
||||
RegionPtr /*pRgn*/,
|
||||
int /*n*/
|
||||
);
|
||||
|
||||
extern void RegionSetExtents(
|
||||
RegionPtr /*pReg*/
|
||||
);
|
||||
|
||||
extern int miFindMaxBand(
|
||||
RegionPtr /*prgn*/
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern Bool RegionIsValid(
|
||||
RegionPtr /*prgn*/
|
||||
);
|
||||
#endif
|
||||
|
||||
extern Bool RegionBroken(RegionPtr pReg);
|
||||
|
||||
/* miscrinit.c */
|
||||
|
||||
extern Bool miModifyPixmapHeader(
|
||||
PixmapPtr /*pPixmap*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int /*depth*/,
|
||||
int /*bitsPerPixel*/,
|
||||
int /*devKind*/,
|
||||
void * /*pPixData*/
|
||||
);
|
||||
|
||||
extern Bool miCloseScreen(
|
||||
ScreenPtr /*pScreen*/
|
||||
);
|
||||
|
||||
extern Bool miCreateScreenResources(
|
||||
ScreenPtr /*pScreen*/
|
||||
);
|
||||
|
||||
extern Bool miScreenDevPrivateInit(
|
||||
ScreenPtr /*pScreen*/,
|
||||
int /*width*/,
|
||||
void * /*pbits*/
|
||||
);
|
||||
|
||||
extern Bool miScreenInit(
|
||||
ScreenPtr /*pScreen*/,
|
||||
void * /*pbits*/,
|
||||
int /*xsize*/,
|
||||
int /*ysize*/,
|
||||
int /*dpix*/,
|
||||
int /*dpiy*/,
|
||||
int /*width*/,
|
||||
int /*rootDepth*/,
|
||||
int /*numDepths*/,
|
||||
DepthPtr /*depths*/,
|
||||
VisualID /*rootVisual*/,
|
||||
int /*numVisuals*/,
|
||||
VisualPtr /*visuals*/
|
||||
);
|
||||
|
||||
extern int miAllocateGCPrivateIndex(
|
||||
void
|
||||
);
|
||||
|
||||
extern PixmapPtr miGetScreenPixmap(
|
||||
ScreenPtr pScreen
|
||||
);
|
||||
|
||||
extern void miSetScreenPixmap(
|
||||
PixmapPtr pPix
|
||||
);
|
||||
|
||||
/* mivaltree.c */
|
||||
|
||||
extern int miShapedWindowIn(
|
||||
ScreenPtr /*pScreen*/,
|
||||
RegionPtr /*universe*/,
|
||||
RegionPtr /*bounding*/,
|
||||
BoxPtr /*rect*/,
|
||||
int /*x*/,
|
||||
int /*y*/
|
||||
);
|
||||
|
||||
typedef void
|
||||
(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion);
|
||||
|
||||
typedef RegionPtr
|
||||
(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow);
|
||||
|
||||
void
|
||||
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
|
||||
GetRedirectBorderClipProcPtr getBorderClip);
|
||||
|
||||
extern int miValidateTree(
|
||||
WindowPtr /*pParent*/,
|
||||
WindowPtr /*pChild*/,
|
||||
VTKind /*kind*/
|
||||
);
|
||||
|
||||
extern void miWideLine(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*mode*/,
|
||||
int /*npt*/,
|
||||
DDXPointPtr /*pPts*/
|
||||
);
|
||||
|
||||
extern void miWideDash(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*mode*/,
|
||||
int /*npt*/,
|
||||
DDXPointPtr /*pPts*/
|
||||
);
|
||||
|
||||
extern void miMiter(
|
||||
void
|
||||
);
|
||||
|
||||
extern void miNotMiter(
|
||||
void
|
||||
);
|
||||
|
||||
/* miwindow.c */
|
||||
|
||||
extern void miClearToBackground(
|
||||
WindowPtr /*pWin*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*w*/,
|
||||
int /*h*/,
|
||||
Bool /*generateExposures*/
|
||||
);
|
||||
|
||||
extern Bool miChangeSaveUnder(
|
||||
WindowPtr /*pWin*/,
|
||||
WindowPtr /*first*/
|
||||
);
|
||||
|
||||
extern void miPostChangeSaveUnder(
|
||||
WindowPtr /*pWin*/,
|
||||
WindowPtr /*pFirst*/
|
||||
);
|
||||
|
||||
extern void miMarkWindow(
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
|
||||
extern Bool miMarkOverlappedWindows(
|
||||
WindowPtr /*pWin*/,
|
||||
WindowPtr /*pFirst*/,
|
||||
WindowPtr * /*ppLayerWin*/
|
||||
);
|
||||
|
||||
extern void miHandleValidateExposures(
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
|
||||
extern void miMoveWindow(
|
||||
WindowPtr /*pWin*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
WindowPtr /*pNextSib*/,
|
||||
VTKind /*kind*/
|
||||
);
|
||||
|
||||
extern void miSlideAndSizeWindow(
|
||||
WindowPtr /*pWin*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
unsigned int /*w*/,
|
||||
unsigned int /*h*/,
|
||||
WindowPtr /*pSib*/
|
||||
);
|
||||
|
||||
extern WindowPtr miGetLayerWindow(
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
|
||||
extern void miSetShape(
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
|
||||
extern void miChangeBorderWidth(
|
||||
WindowPtr /*pWin*/,
|
||||
unsigned int /*width*/
|
||||
);
|
||||
|
||||
extern void miMarkUnrealizedWindow(
|
||||
WindowPtr /*pChild*/,
|
||||
WindowPtr /*pWin*/,
|
||||
Bool /*fromConfigure*/
|
||||
);
|
||||
|
||||
extern void miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth);
|
||||
|
||||
/* mizerarc.c */
|
||||
|
||||
extern void miZeroPolyArc(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*narcs*/,
|
||||
xArc * /*parcs*/
|
||||
);
|
||||
|
||||
/* mizerline.c */
|
||||
|
||||
extern void miZeroLine(
|
||||
DrawablePtr /*dst*/,
|
||||
GCPtr /*pgc*/,
|
||||
int /*mode*/,
|
||||
int /*nptInit*/,
|
||||
DDXPointRec * /*pptInit*/
|
||||
);
|
||||
|
||||
extern void miZeroDashLine(
|
||||
DrawablePtr /*dst*/,
|
||||
GCPtr /*pgc*/,
|
||||
int /*mode*/,
|
||||
int /*nptInit*/,
|
||||
DDXPointRec * /*pptInit*/
|
||||
);
|
||||
|
||||
extern void miPolyFillArc(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
int /*narcs*/,
|
||||
xArc * /*parcs*/
|
||||
);
|
||||
|
||||
#endif /* MI_H */
|
||||
3721
nx-X11/programs/Xserver/mi/miarc.c
Normal file
3721
nx-X11/programs/Xserver/mi/miarc.c
Normal file
File diff suppressed because it is too large
Load Diff
845
nx-X11/programs/Xserver/mi/mibitblt.c
Normal file
845
nx-X11/programs/Xserver/mi/mibitblt.c
Normal file
@@ -0,0 +1,845 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/* Author: Todd Newman (aided and abetted by Mr. Drewry) */
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "windowstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "mi.h"
|
||||
#include "regionstr.h"
|
||||
#include <nx-X11/Xmd.h>
|
||||
#include "servermd.h"
|
||||
|
||||
#ifndef HAS_FFS
|
||||
extern int ffs(int);
|
||||
#endif
|
||||
|
||||
/* MICOPYAREA -- public entry for the CopyArea request
|
||||
* For each rectangle in the source region
|
||||
* get the pixels with GetSpans
|
||||
* set them in the destination with SetSpans
|
||||
* We let SetSpans worry about clipping to the destination.
|
||||
*/
|
||||
RegionPtr
|
||||
miCopyArea(pSrcDrawable, pDstDrawable,
|
||||
pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut)
|
||||
register DrawablePtr pSrcDrawable;
|
||||
register DrawablePtr pDstDrawable;
|
||||
GCPtr pGC;
|
||||
int xIn, yIn;
|
||||
int widthSrc, heightSrc;
|
||||
int xOut, yOut;
|
||||
{
|
||||
DDXPointPtr ppt, pptFirst;
|
||||
unsigned int *pwidthFirst, *pwidth, *pbits;
|
||||
BoxRec srcBox, *prect;
|
||||
/* may be a new region, or just a copy */
|
||||
RegionPtr prgnSrcClip;
|
||||
/* non-0 if we've created a src clip */
|
||||
RegionPtr prgnExposed;
|
||||
int realSrcClip = 0;
|
||||
int srcx, srcy, dstx, dsty, i, j, y, width, height,
|
||||
xMin, xMax, yMin, yMax;
|
||||
unsigned int *ordering;
|
||||
int numRects;
|
||||
BoxPtr boxes;
|
||||
|
||||
srcx = xIn + pSrcDrawable->x;
|
||||
srcy = yIn + pSrcDrawable->y;
|
||||
|
||||
/* If the destination isn't realized, this is easy */
|
||||
if (pDstDrawable->type == DRAWABLE_WINDOW &&
|
||||
!((WindowPtr)pDstDrawable)->realized)
|
||||
return (RegionPtr)NULL;
|
||||
|
||||
/* clip the source */
|
||||
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
|
||||
{
|
||||
BoxRec box;
|
||||
|
||||
box.x1 = pSrcDrawable->x;
|
||||
box.y1 = pSrcDrawable->y;
|
||||
box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
|
||||
box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
|
||||
|
||||
prgnSrcClip = RegionCreate(&box, 1);
|
||||
realSrcClip = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pGC->subWindowMode == IncludeInferiors) {
|
||||
prgnSrcClip = NotClippedByChildren ((WindowPtr) pSrcDrawable);
|
||||
realSrcClip = 1;
|
||||
} else
|
||||
prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
|
||||
}
|
||||
|
||||
/* If the src drawable is a window, we need to translate the srcBox so
|
||||
* that we can compare it with the window's clip region later on. */
|
||||
srcBox.x1 = srcx;
|
||||
srcBox.y1 = srcy;
|
||||
srcBox.x2 = srcx + widthSrc;
|
||||
srcBox.y2 = srcy + heightSrc;
|
||||
|
||||
dstx = xOut;
|
||||
dsty = yOut;
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
dstx += pDstDrawable->x;
|
||||
dsty += pDstDrawable->y;
|
||||
}
|
||||
|
||||
pptFirst = ppt = (DDXPointPtr)
|
||||
malloc(heightSrc * sizeof(DDXPointRec));
|
||||
pwidthFirst = pwidth = (unsigned int *)
|
||||
malloc(heightSrc * sizeof(unsigned int));
|
||||
numRects = RegionNumRects(prgnSrcClip);
|
||||
boxes = RegionRects(prgnSrcClip);
|
||||
ordering = (unsigned int *)
|
||||
malloc(numRects * sizeof(unsigned int));
|
||||
if(!pptFirst || !pwidthFirst || !ordering)
|
||||
{
|
||||
if (ordering)
|
||||
free(ordering);
|
||||
if (pwidthFirst)
|
||||
free(pwidthFirst);
|
||||
if (pptFirst)
|
||||
free(pptFirst);
|
||||
return (RegionPtr)NULL;
|
||||
}
|
||||
|
||||
/* If not the same drawable then order of move doesn't matter.
|
||||
Following assumes that boxes are sorted from top
|
||||
to bottom and left to right.
|
||||
*/
|
||||
if ((pSrcDrawable != pDstDrawable) &&
|
||||
((pGC->subWindowMode != IncludeInferiors) ||
|
||||
(pSrcDrawable->type == DRAWABLE_PIXMAP) ||
|
||||
(pDstDrawable->type == DRAWABLE_PIXMAP)))
|
||||
for (i=0; i < numRects; i++)
|
||||
ordering[i] = i;
|
||||
else { /* within same drawable, must sequence moves carefully! */
|
||||
if (dsty <= srcBox.y1) { /* Scroll up or stationary vertical.
|
||||
Vertical order OK */
|
||||
if (dstx <= srcBox.x1) /* Scroll left or stationary horizontal.
|
||||
Horizontal order OK as well */
|
||||
for (i=0; i < numRects; i++)
|
||||
ordering[i] = i;
|
||||
else { /* scroll right. must reverse horizontal banding of rects. */
|
||||
for (i=0, j=1, xMax=0; i < numRects; j=i+1, xMax=i) {
|
||||
/* find extent of current horizontal band */
|
||||
y=boxes[i].y1; /* band has this y coordinate */
|
||||
while ((j < numRects) && (boxes[j].y1 == y))
|
||||
j++;
|
||||
/* reverse the horizontal band in the output ordering */
|
||||
for (j-- ; j >= xMax; j--, i++)
|
||||
ordering[i] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* Scroll down. Must reverse vertical banding. */
|
||||
if (dstx < srcBox.x1) { /* Scroll left. Horizontal order OK. */
|
||||
for (i=numRects-1, j=i-1, yMin=i, yMax=0;
|
||||
i >= 0;
|
||||
j=i-1, yMin=i) {
|
||||
/* find extent of current horizontal band */
|
||||
y=boxes[i].y1; /* band has this y coordinate */
|
||||
while ((j >= 0) && (boxes[j].y1 == y))
|
||||
j--;
|
||||
/* reverse the horizontal band in the output ordering */
|
||||
for (j++ ; j <= yMin; j++, i--, yMax++)
|
||||
ordering[yMax] = j;
|
||||
}
|
||||
}
|
||||
else /* Scroll right or horizontal stationary.
|
||||
Reverse horizontal order as well (if stationary, horizontal
|
||||
order can be swapped without penalty and this is faster
|
||||
to compute). */
|
||||
for (i=0, j=numRects-1; i < numRects; i++, j--)
|
||||
ordering[i] = j;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < numRects; i++)
|
||||
{
|
||||
prect = &boxes[ordering[i]];
|
||||
xMin = max(prect->x1, srcBox.x1);
|
||||
xMax = min(prect->x2, srcBox.x2);
|
||||
yMin = max(prect->y1, srcBox.y1);
|
||||
yMax = min(prect->y2, srcBox.y2);
|
||||
/* is there anything visible here? */
|
||||
if(xMax <= xMin || yMax <= yMin)
|
||||
continue;
|
||||
|
||||
ppt = pptFirst;
|
||||
pwidth = pwidthFirst;
|
||||
y = yMin;
|
||||
height = yMax - yMin;
|
||||
width = xMax - xMin;
|
||||
|
||||
for(j = 0; j < height; j++)
|
||||
{
|
||||
/* We must untranslate before calling GetSpans */
|
||||
ppt->x = xMin;
|
||||
ppt++->y = y++;
|
||||
*pwidth++ = width;
|
||||
}
|
||||
pbits = (unsigned int *)malloc(height * PixmapBytePad(width,
|
||||
pSrcDrawable->depth));
|
||||
if (pbits)
|
||||
{
|
||||
(*pSrcDrawable->pScreen->GetSpans)(pSrcDrawable, width, pptFirst,
|
||||
(int *)pwidthFirst, height, (char *)pbits);
|
||||
ppt = pptFirst;
|
||||
pwidth = pwidthFirst;
|
||||
xMin -= (srcx - dstx);
|
||||
y = yMin - (srcy - dsty);
|
||||
for(j = 0; j < height; j++)
|
||||
{
|
||||
ppt->x = xMin;
|
||||
ppt++->y = y++;
|
||||
*pwidth++ = width;
|
||||
}
|
||||
|
||||
(*pGC->ops->SetSpans)(pDstDrawable, pGC, (char *)pbits, pptFirst,
|
||||
(int *)pwidthFirst, height, TRUE);
|
||||
free(pbits);
|
||||
}
|
||||
}
|
||||
prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
|
||||
widthSrc, heightSrc, xOut, yOut, (unsigned long)0);
|
||||
if(realSrcClip)
|
||||
RegionDestroy(prgnSrcClip);
|
||||
|
||||
free(ordering);
|
||||
free(pwidthFirst);
|
||||
free(pptFirst);
|
||||
return prgnExposed;
|
||||
}
|
||||
|
||||
/* MIGETPLANE -- gets a bitmap representing one plane of pDraw
|
||||
* A helper used for CopyPlane and XY format GetImage
|
||||
* No clever strategy here, we grab a scanline at a time, pull out the
|
||||
* bits and then stuff them in a 1 bit deep map.
|
||||
*/
|
||||
/*
|
||||
* This should be replaced with something more general. mi shouldn't have to
|
||||
* care about such things as scanline padding et alia.
|
||||
*/
|
||||
static
|
||||
MiBits *
|
||||
miGetPlane(
|
||||
DrawablePtr pDraw,
|
||||
int planeNum, /* number of the bitPlane */
|
||||
int sx,
|
||||
int sy,
|
||||
int w,
|
||||
int h,
|
||||
MiBits *result)
|
||||
{
|
||||
int i, j, k, width, bitsPerPixel, widthInBytes;
|
||||
DDXPointRec pt = {0, 0};
|
||||
MiBits pixel;
|
||||
MiBits bit;
|
||||
unsigned char *pCharsOut = NULL;
|
||||
|
||||
#if BITMAP_SCANLINE_UNIT == 8
|
||||
#define OUT_TYPE unsigned char
|
||||
#endif
|
||||
#if BITMAP_SCANLINE_UNIT == 16
|
||||
#define OUT_TYPE CARD16
|
||||
#endif
|
||||
#if BITMAP_SCANLINE_UNIT == 32
|
||||
#define OUT_TYPE CARD32
|
||||
#endif
|
||||
#if BITMAP_SCANLINE_UNIT == 64
|
||||
#define OUT_TYPE CARD64
|
||||
#endif
|
||||
|
||||
OUT_TYPE *pOut;
|
||||
int delta = 0;
|
||||
|
||||
sx += pDraw->x;
|
||||
sy += pDraw->y;
|
||||
widthInBytes = BitmapBytePad(w);
|
||||
if(!result)
|
||||
result = (MiBits *)malloc(h * widthInBytes);
|
||||
if (!result)
|
||||
return (MiBits *)NULL;
|
||||
bitsPerPixel = pDraw->bitsPerPixel;
|
||||
bzero((char *)result, h * widthInBytes);
|
||||
pOut = (OUT_TYPE *) result;
|
||||
if(bitsPerPixel == 1)
|
||||
{
|
||||
pCharsOut = (unsigned char *) result;
|
||||
width = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = (widthInBytes / (BITMAP_SCANLINE_UNIT / 8)) -
|
||||
(w / BITMAP_SCANLINE_UNIT);
|
||||
width = 1;
|
||||
#if IMAGE_BYTE_ORDER == MSBFirst
|
||||
planeNum += (32 - bitsPerPixel);
|
||||
#endif
|
||||
}
|
||||
pt.y = sy;
|
||||
for (i = h; --i >= 0; pt.y++)
|
||||
{
|
||||
pt.x = sx;
|
||||
if(bitsPerPixel == 1)
|
||||
{
|
||||
(*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1,
|
||||
(char *)pCharsOut);
|
||||
pCharsOut += widthInBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 0;
|
||||
for(j = w; --j >= 0; pt.x++)
|
||||
{
|
||||
/* Fetch the next pixel */
|
||||
(*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1,
|
||||
(char *)&pixel);
|
||||
/*
|
||||
* Now get the bit and insert into a bitmap in XY format.
|
||||
*/
|
||||
bit = (pixel >> planeNum) & 1;
|
||||
#ifndef XFree86Server
|
||||
/* XXX assuming bit order == byte order */
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
bit <<= k;
|
||||
#else
|
||||
bit <<= ((BITMAP_SCANLINE_UNIT - 1) - k);
|
||||
#endif
|
||||
#else
|
||||
/* XXX assuming byte order == LSBFirst */
|
||||
if (screenInfo.bitmapBitOrder == LSBFirst)
|
||||
bit <<= k;
|
||||
else
|
||||
bit <<= ((screenInfo.bitmapScanlineUnit - 1) -
|
||||
(k % screenInfo.bitmapScanlineUnit)) +
|
||||
((k / screenInfo.bitmapScanlineUnit) *
|
||||
screenInfo.bitmapScanlineUnit);
|
||||
#endif
|
||||
*pOut |= (OUT_TYPE) bit;
|
||||
k++;
|
||||
if (k == BITMAP_SCANLINE_UNIT)
|
||||
{
|
||||
pOut++;
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
pOut += delta;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
|
||||
}
|
||||
|
||||
/* MIOPQSTIPDRAWABLE -- use pbits as an opaque stipple for pDraw.
|
||||
* Drawing through the clip mask we SetSpans() the bits into a
|
||||
* bitmap and stipple those bits onto the destination drawable by doing a
|
||||
* PolyFillRect over the whole drawable,
|
||||
* then we invert the bitmap by copying it onto itself with an alu of
|
||||
* GXinvert, invert the foreground/background colors of the gc, and draw
|
||||
* the background bits.
|
||||
* Note how the clipped out bits of the bitmap are always the background
|
||||
* color so that the stipple never causes FillRect to draw them.
|
||||
*/
|
||||
void
|
||||
miOpqStipDrawable(pDraw, pGC, prgnSrc, pbits, srcx, w, h, dstx, dsty)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
RegionPtr prgnSrc;
|
||||
MiBits *pbits;
|
||||
int srcx, w, h, dstx, dsty;
|
||||
{
|
||||
int oldfill, i;
|
||||
unsigned long oldfg;
|
||||
int *pwidth, *pwidthFirst;
|
||||
ChangeGCVal gcv[6];
|
||||
PixmapPtr pStipple, pPixmap;
|
||||
DDXPointRec oldOrg;
|
||||
GCPtr pGCT;
|
||||
DDXPointPtr ppt, pptFirst;
|
||||
xRectangle rect;
|
||||
RegionPtr prgnSrcClip;
|
||||
|
||||
pPixmap = (*pDraw->pScreen->CreatePixmap)
|
||||
(pDraw->pScreen, w + srcx, h, 1,
|
||||
CREATE_PIXMAP_USAGE_SCRATCH);
|
||||
if (!pPixmap)
|
||||
return;
|
||||
|
||||
/* Put the image into a 1 bit deep pixmap */
|
||||
pGCT = GetScratchGC(1, pDraw->pScreen);
|
||||
if (!pGCT)
|
||||
{
|
||||
(*pDraw->pScreen->DestroyPixmap)(pPixmap);
|
||||
return;
|
||||
}
|
||||
/* First set the whole pixmap to 0 */
|
||||
gcv[0].val = 0;
|
||||
dixChangeGC(NullClient, pGCT, GCBackground, NULL, gcv);
|
||||
ValidateGC((DrawablePtr)pPixmap, pGCT);
|
||||
miClearDrawable((DrawablePtr)pPixmap, pGCT);
|
||||
ppt = pptFirst = (DDXPointPtr)malloc(h * sizeof(DDXPointRec));
|
||||
pwidth = pwidthFirst = (int *)malloc(h * sizeof(int));
|
||||
if(!pptFirst || !pwidthFirst)
|
||||
{
|
||||
if (pwidthFirst) free(pwidthFirst);
|
||||
if (pptFirst) free(pptFirst);
|
||||
FreeScratchGC(pGCT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* we need a temporary region because ChangeClip must be assumed
|
||||
to destroy what it's sent. note that this means we don't
|
||||
have to free prgnSrcClip ourselves.
|
||||
*/
|
||||
prgnSrcClip = RegionCreate(NULL, 0);
|
||||
RegionCopy(prgnSrcClip, prgnSrc);
|
||||
RegionTranslate(prgnSrcClip, srcx, 0);
|
||||
(*pGCT->funcs->ChangeClip)(pGCT, CT_REGION, prgnSrcClip, 0);
|
||||
ValidateGC((DrawablePtr)pPixmap, pGCT);
|
||||
|
||||
/* Since we know pDraw is always a pixmap, we never need to think
|
||||
* about translation here */
|
||||
for(i = 0; i < h; i++)
|
||||
{
|
||||
ppt->x = 0;
|
||||
ppt++->y = i;
|
||||
*pwidth++ = w + srcx;
|
||||
}
|
||||
|
||||
(*pGCT->ops->SetSpans)((DrawablePtr)pPixmap, pGCT, (char *)pbits,
|
||||
pptFirst, pwidthFirst, h, TRUE);
|
||||
free(pwidthFirst);
|
||||
free(pptFirst);
|
||||
|
||||
|
||||
/* Save current values from the client GC */
|
||||
oldfill = pGC->fillStyle;
|
||||
pStipple = pGC->stipple;
|
||||
if(pStipple)
|
||||
pStipple->refcnt++;
|
||||
oldOrg = pGC->patOrg;
|
||||
|
||||
/* Set a new stipple in the drawable */
|
||||
gcv[0].val = FillStippled;
|
||||
gcv[1].ptr = pPixmap;
|
||||
gcv[2].val = dstx - srcx;
|
||||
gcv[3].val = dsty;
|
||||
|
||||
dixChangeGC(NullClient, pGC,
|
||||
GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin,
|
||||
NULL, gcv);
|
||||
ValidateGC(pDraw, pGC);
|
||||
|
||||
/* Fill the drawable with the stipple. This will draw the
|
||||
* foreground color whereever 1 bits are set, leaving everything
|
||||
* with 0 bits untouched. Note that the part outside the clip
|
||||
* region is all 0s. */
|
||||
rect.x = dstx;
|
||||
rect.y = dsty;
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
(*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
|
||||
|
||||
/* Invert the tiling pixmap. This sets 0s for 1s and 1s for 0s, only
|
||||
* within the clipping region, the part outside is still all 0s */
|
||||
gcv[0].val = GXinvert;
|
||||
dixChangeGC(NullClient, pGCT, GCFunction, NULL, gcv);
|
||||
ValidateGC((DrawablePtr)pPixmap, pGCT);
|
||||
(*pGCT->ops->CopyArea)((DrawablePtr)pPixmap, (DrawablePtr)pPixmap,
|
||||
pGCT, 0, 0, w + srcx, h, 0, 0);
|
||||
|
||||
/* Swap foreground and background colors on the GC for the drawable.
|
||||
* Now when we fill the drawable, we will fill in the "Background"
|
||||
* values */
|
||||
oldfg = pGC->fgPixel;
|
||||
gcv[0].val = pGC->bgPixel;
|
||||
gcv[1].val = oldfg;
|
||||
gcv[2].ptr = pPixmap;
|
||||
dixChangeGC(NullClient, pGC, GCForeground | GCBackground | GCStipple,
|
||||
NULL, gcv);
|
||||
ValidateGC(pDraw, pGC);
|
||||
/* PolyFillRect might have bashed the rectangle */
|
||||
rect.x = dstx;
|
||||
rect.y = dsty;
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
(*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
|
||||
|
||||
/* Now put things back */
|
||||
if(pStipple)
|
||||
pStipple->refcnt--;
|
||||
gcv[0].val = oldfg;
|
||||
gcv[1].val = pGC->fgPixel;
|
||||
gcv[2].val = oldfill;
|
||||
gcv[3].ptr = pStipple;
|
||||
gcv[4].val = oldOrg.x;
|
||||
gcv[5].val = oldOrg.y;
|
||||
dixChangeGC(NullClient, pGC,
|
||||
GCForeground | GCBackground | GCFillStyle | GCStipple |
|
||||
GCTileStipXOrigin | GCTileStipYOrigin, NULL, gcv);
|
||||
|
||||
ValidateGC(pDraw, pGC);
|
||||
/* put what we hope is a smaller clip region back in the scratch gc */
|
||||
(*pGCT->funcs->ChangeClip)(pGCT, CT_NONE, NULL, 0);
|
||||
FreeScratchGC(pGCT);
|
||||
(*pDraw->pScreen->DestroyPixmap)(pPixmap);
|
||||
|
||||
}
|
||||
|
||||
/* MICOPYPLANE -- public entry for the CopyPlane request.
|
||||
* strategy:
|
||||
* First build up a bitmap out of the bits requested
|
||||
* build a source clip
|
||||
* Use the bitmap we've built up as a Stipple for the destination
|
||||
*/
|
||||
RegionPtr
|
||||
miCopyPlane(pSrcDrawable, pDstDrawable,
|
||||
pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
|
||||
DrawablePtr pSrcDrawable;
|
||||
DrawablePtr pDstDrawable;
|
||||
GCPtr pGC;
|
||||
int srcx, srcy;
|
||||
int width, height;
|
||||
int dstx, dsty;
|
||||
unsigned long bitPlane;
|
||||
{
|
||||
MiBits *ptile;
|
||||
BoxRec box;
|
||||
RegionPtr prgnSrc, prgnExposed;
|
||||
|
||||
/* incorporate the source clip */
|
||||
|
||||
box.x1 = srcx + pSrcDrawable->x;
|
||||
box.y1 = srcy + pSrcDrawable->y;
|
||||
box.x2 = box.x1 + width;
|
||||
box.y2 = box.y1 + height;
|
||||
/* clip to visible drawable */
|
||||
if (box.x1 < pSrcDrawable->x)
|
||||
box.x1 = pSrcDrawable->x;
|
||||
if (box.y1 < pSrcDrawable->y)
|
||||
box.y1 = pSrcDrawable->y;
|
||||
if (box.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
|
||||
box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
|
||||
if (box.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
|
||||
box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
|
||||
if (box.x1 > box.x2)
|
||||
box.x2 = box.x1;
|
||||
if (box.y1 > box.y2)
|
||||
box.y2 = box.y1;
|
||||
prgnSrc = RegionCreate(&box, 1);
|
||||
|
||||
if (pSrcDrawable->type != DRAWABLE_PIXMAP) {
|
||||
/* clip to visible drawable */
|
||||
|
||||
if (pGC->subWindowMode == IncludeInferiors)
|
||||
{
|
||||
RegionPtr clipList = NotClippedByChildren ((WindowPtr) pSrcDrawable);
|
||||
RegionIntersect(prgnSrc, prgnSrc, clipList);
|
||||
RegionDestroy(clipList);
|
||||
} else
|
||||
RegionIntersect(prgnSrc, prgnSrc,
|
||||
&((WindowPtr)pSrcDrawable)->clipList);
|
||||
}
|
||||
|
||||
box = *RegionExtents(prgnSrc);
|
||||
RegionTranslate(prgnSrc, -box.x1, -box.y1);
|
||||
|
||||
if ((box.x2 > box.x1) && (box.y2 > box.y1))
|
||||
{
|
||||
/* minimize the size of the data extracted */
|
||||
/* note that we convert the plane mask bitPlane into a plane number */
|
||||
box.x1 -= pSrcDrawable->x;
|
||||
box.x2 -= pSrcDrawable->x;
|
||||
box.y1 -= pSrcDrawable->y;
|
||||
box.y2 -= pSrcDrawable->y;
|
||||
ptile = miGetPlane(pSrcDrawable, ffs(bitPlane) - 1,
|
||||
box.x1, box.y1,
|
||||
box.x2 - box.x1, box.y2 - box.y1,
|
||||
(MiBits *) NULL);
|
||||
if (ptile)
|
||||
{
|
||||
miOpqStipDrawable(pDstDrawable, pGC, prgnSrc, ptile, 0,
|
||||
box.x2 - box.x1, box.y2 - box.y1,
|
||||
dstx + box.x1 - srcx, dsty + box.y1 - srcy);
|
||||
free(ptile);
|
||||
}
|
||||
}
|
||||
prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
|
||||
width, height, dstx, dsty, bitPlane);
|
||||
RegionDestroy(prgnSrc);
|
||||
return prgnExposed;
|
||||
}
|
||||
|
||||
/* MIGETIMAGE -- public entry for the GetImage Request
|
||||
* We're getting the image into a memory buffer. While we have to use GetSpans
|
||||
* to read a line from the device (since we don't know what that looks like),
|
||||
* we can just write into the destination buffer
|
||||
*
|
||||
* two different strategies are used, depending on whether we're getting the
|
||||
* image in Z format or XY format
|
||||
* Z format:
|
||||
* Line at a time, GetSpans a line into the destination buffer, then if the
|
||||
* planemask is not all ones, we do a SetSpans into a temporary buffer (to get
|
||||
* bits turned off) and then another GetSpans to get stuff back (because
|
||||
* pixmaps are opaque, and we are passed in the memory to write into). This is
|
||||
* pretty ugly and slow but works. Life is hard.
|
||||
* XY format:
|
||||
* get the single plane specified in planemask
|
||||
*/
|
||||
void
|
||||
miGetImage(pDraw, sx, sy, w, h, format, planeMask, pDst)
|
||||
DrawablePtr pDraw;
|
||||
int sx, sy, w, h;
|
||||
unsigned int format;
|
||||
unsigned long planeMask;
|
||||
char * pDst;
|
||||
{
|
||||
unsigned char depth;
|
||||
int i, linelength, width, srcx, srcy;
|
||||
DDXPointRec pt = {0, 0};
|
||||
XID gcv[2];
|
||||
PixmapPtr pPixmap = (PixmapPtr)NULL;
|
||||
GCPtr pGC = NULL;
|
||||
|
||||
depth = pDraw->depth;
|
||||
if(format == ZPixmap)
|
||||
{
|
||||
if ( (((1<<depth)-1)&planeMask) != (1<<depth)-1 )
|
||||
{
|
||||
xPoint xpt;
|
||||
|
||||
pGC = GetScratchGC(depth, pDraw->pScreen);
|
||||
if (!pGC)
|
||||
return;
|
||||
pPixmap = (*pDraw->pScreen->CreatePixmap)
|
||||
(pDraw->pScreen, w, 1, depth,
|
||||
CREATE_PIXMAP_USAGE_SCRATCH);
|
||||
if (!pPixmap)
|
||||
{
|
||||
FreeScratchGC(pGC);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Clear the pixmap before doing anything else
|
||||
*/
|
||||
ValidateGC((DrawablePtr)pPixmap, pGC);
|
||||
xpt.x = xpt.y = 0;
|
||||
width = w;
|
||||
(*pGC->ops->FillSpans)((DrawablePtr)pPixmap, pGC, 1, &xpt, &width,
|
||||
TRUE);
|
||||
|
||||
/* alu is already GXCopy */
|
||||
gcv[0] = (XID)planeMask;
|
||||
DoChangeGC(pGC, GCPlaneMask, gcv, 0);
|
||||
ValidateGC((DrawablePtr)pPixmap, pGC);
|
||||
}
|
||||
|
||||
linelength = PixmapBytePad(w, depth);
|
||||
srcx = sx + pDraw->x;
|
||||
srcy = sy + pDraw->y;
|
||||
for(i = 0; i < h; i++)
|
||||
{
|
||||
pt.x = srcx;
|
||||
pt.y = srcy + i;
|
||||
width = w;
|
||||
(*pDraw->pScreen->GetSpans)(pDraw, w, &pt, &width, 1, pDst);
|
||||
if (pPixmap)
|
||||
{
|
||||
pt.x = 0;
|
||||
pt.y = 0;
|
||||
width = w;
|
||||
(*pGC->ops->SetSpans)((DrawablePtr)pPixmap, pGC, pDst,
|
||||
&pt, &width, 1, TRUE);
|
||||
(*pDraw->pScreen->GetSpans)((DrawablePtr)pPixmap, w, &pt,
|
||||
&width, 1, pDst);
|
||||
}
|
||||
pDst += linelength;
|
||||
}
|
||||
if (pPixmap)
|
||||
{
|
||||
(*pGC->pScreen->DestroyPixmap)(pPixmap);
|
||||
FreeScratchGC(pGC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) miGetPlane(pDraw, ffs(planeMask) - 1, sx, sy, w, h,
|
||||
(MiBits *)pDst);
|
||||
}
|
||||
}
|
||||
|
||||
/* MIPUTIMAGE -- public entry for the PutImage request
|
||||
* Here we benefit from knowing the format of the bits pointed to by pImage,
|
||||
* even if we don't know how pDraw represents them.
|
||||
* Three different strategies are used depending on the format
|
||||
* XYBitmap Format:
|
||||
* we just use the Opaque Stipple helper function to cover the destination
|
||||
* Note that this covers all the planes of the drawable with the
|
||||
* foreground color (masked with the GC planemask) where there are 1 bits
|
||||
* and the background color (masked with the GC planemask) where there are
|
||||
* 0 bits
|
||||
* XYPixmap format:
|
||||
* what we're called with is a series of XYBitmaps, but we only want
|
||||
* each XYPixmap to update 1 plane, instead of updating all of them.
|
||||
* we set the foreground color to be all 1s and the background to all 0s
|
||||
* then for each plane, we set the plane mask to only effect that one
|
||||
* plane and recursive call ourself with the format set to XYBitmap
|
||||
* (This clever idea courtesy of RGD.)
|
||||
* ZPixmap format:
|
||||
* This part is simple, just call SetSpans
|
||||
*/
|
||||
void
|
||||
miPutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int depth, x, y, w, h, leftPad;
|
||||
int format;
|
||||
char *pImage;
|
||||
{
|
||||
DDXPointPtr pptFirst, ppt;
|
||||
int *pwidthFirst, *pwidth;
|
||||
RegionPtr prgnSrc;
|
||||
BoxRec box;
|
||||
unsigned long oldFg, oldBg;
|
||||
XID gcv[3];
|
||||
unsigned long oldPlanemask;
|
||||
unsigned long i;
|
||||
long bytesPer;
|
||||
|
||||
if (!w || !h)
|
||||
return;
|
||||
switch(format)
|
||||
{
|
||||
case XYBitmap:
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = w;
|
||||
box.y2 = h;
|
||||
prgnSrc = RegionCreate(&box, 1);
|
||||
|
||||
miOpqStipDrawable(pDraw, pGC, prgnSrc, (MiBits *) pImage,
|
||||
leftPad, w, h, x, y);
|
||||
RegionDestroy(prgnSrc);
|
||||
break;
|
||||
|
||||
case XYPixmap:
|
||||
depth = pGC->depth;
|
||||
oldPlanemask = pGC->planemask;
|
||||
oldFg = pGC->fgPixel;
|
||||
oldBg = pGC->bgPixel;
|
||||
gcv[0] = (XID)~0;
|
||||
gcv[1] = (XID)0;
|
||||
DoChangeGC(pGC, GCForeground | GCBackground, gcv, 0);
|
||||
bytesPer = (long)h * BitmapBytePad(w + leftPad);
|
||||
|
||||
for (i = 1 << (depth-1); i != 0; i >>= 1, pImage += bytesPer)
|
||||
{
|
||||
if (i & oldPlanemask)
|
||||
{
|
||||
gcv[0] = (XID)i;
|
||||
DoChangeGC(pGC, GCPlaneMask, gcv, 0);
|
||||
ValidateGC(pDraw, pGC);
|
||||
(*pGC->ops->PutImage)(pDraw, pGC, 1, x, y, w, h, leftPad,
|
||||
XYBitmap, (char *)pImage);
|
||||
}
|
||||
}
|
||||
gcv[0] = (XID)oldPlanemask;
|
||||
gcv[1] = (XID)oldFg;
|
||||
gcv[2] = (XID)oldBg;
|
||||
DoChangeGC(pGC, GCPlaneMask | GCForeground | GCBackground, gcv, 0);
|
||||
ValidateGC(pDraw, pGC);
|
||||
break;
|
||||
|
||||
case ZPixmap:
|
||||
ppt = pptFirst = (DDXPointPtr)malloc(h * sizeof(DDXPointRec));
|
||||
pwidth = pwidthFirst = (int *)malloc(h * sizeof(int));
|
||||
if(!pptFirst || !pwidthFirst)
|
||||
{
|
||||
if (pwidthFirst)
|
||||
free(pwidthFirst);
|
||||
if (pptFirst)
|
||||
free(pptFirst);
|
||||
return;
|
||||
}
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
x += pDraw->x;
|
||||
y += pDraw->y;
|
||||
}
|
||||
|
||||
for(i = 0; i < h; i++)
|
||||
{
|
||||
ppt->x = x;
|
||||
ppt->y = y + i;
|
||||
ppt++;
|
||||
*pwidth++ = w;
|
||||
}
|
||||
|
||||
(*pGC->ops->SetSpans)(pDraw, pGC, (char *)pImage, pptFirst,
|
||||
pwidthFirst, h, TRUE);
|
||||
free(pwidthFirst);
|
||||
free(pptFirst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
3896
nx-X11/programs/Xserver/mi/mibstore.c
Normal file
3896
nx-X11/programs/Xserver/mi/mibstore.c
Normal file
File diff suppressed because it is too large
Load Diff
29
nx-X11/programs/Xserver/mi/mibstore.h
Normal file
29
nx-X11/programs/Xserver/mi/mibstore.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*-
|
||||
* mibstore.h --
|
||||
* Header file for users of the MI backing-store scheme.
|
||||
*
|
||||
* Copyright (c) 1987 by the Regents of the University of California
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies. The University of California
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*
|
||||
* "$Xorg: mibstore.h,v 1.3 2000/08/17 19:53:37 cpqbld Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _MIBSTORE_H
|
||||
#define _MIBSTORE_H
|
||||
|
||||
#include "screenint.h"
|
||||
|
||||
extern void miInitializeBackingStore(
|
||||
ScreenPtr /*pScreen*/
|
||||
);
|
||||
|
||||
#endif /* _MIBSTORE_H */
|
||||
91
nx-X11/programs/Xserver/mi/mibstorest.h
Normal file
91
nx-X11/programs/Xserver/mi/mibstorest.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* mibstorest.h
|
||||
*
|
||||
* internal structure definitions for mi backing store
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "mibstore.h"
|
||||
#include "regionstr.h"
|
||||
|
||||
/*
|
||||
* One of these structures is allocated per GC used with a backing-store
|
||||
* drawable.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures
|
||||
* set FALSE and the clientClip set to
|
||||
* clip output to the valid regions of the
|
||||
* backing pixmap. */
|
||||
int guarantee; /* GuaranteeNothing, etc. */
|
||||
unsigned long serialNumber; /* clientClip computed time */
|
||||
unsigned long stateChanges; /* changes in parent gc since last copy */
|
||||
GCOps *wrapOps; /* wrapped ops */
|
||||
GCFuncs *wrapFuncs; /* wrapped funcs */
|
||||
} miBSGCRec, *miBSGCPtr;
|
||||
|
||||
/*
|
||||
* one of these structures is allocated per Window with backing store
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
PixmapPtr pBackingPixmap; /* Pixmap for saved areas */
|
||||
short x; /* origin of pixmap relative to window */
|
||||
short y;
|
||||
RegionRec SavedRegion; /* Valid area in pBackingPixmap */
|
||||
char viewable; /* Tracks pWin->viewable so SavedRegion may
|
||||
* be initialized correctly when the window
|
||||
* is first mapped */
|
||||
char status; /* StatusNoPixmap, etc. */
|
||||
char backgroundState; /* background type */
|
||||
PixUnion background; /* background pattern */
|
||||
} miBSWindowRec, *miBSWindowPtr;
|
||||
|
||||
#define StatusNoPixmap 1 /* pixmap has not been created */
|
||||
#define StatusVirtual 2 /* pixmap is virtual, tiled with background */
|
||||
#define StatusVDirty 3 /* pixmap is virtual, visiblt has contents */
|
||||
#define StatusBadAlloc 4 /* pixmap create failed, do not try again */
|
||||
#define StatusContents 5 /* pixmap is created, has valid contents */
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* screen func wrappers
|
||||
*/
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
GetImageProcPtr GetImage;
|
||||
GetSpansProcPtr GetSpans;
|
||||
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
|
||||
CreateGCProcPtr CreateGC;
|
||||
DestroyWindowProcPtr DestroyWindow;
|
||||
} miBSScreenRec, *miBSScreenPtr;
|
||||
698
nx-X11/programs/Xserver/mi/micmap.c
Normal file
698
nx-X11/programs/Xserver/mi/micmap.c
Normal file
@@ -0,0 +1,698 @@
|
||||
/* $XConsortium: cfbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
|
||||
/************************************************************
|
||||
Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright no-
|
||||
tice appear in all copies and that both that copyright no-
|
||||
tice and this permission notice appear in supporting docu-
|
||||
mentation, and that the names of Sun or X Consortium
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific prior
|
||||
written permission. Sun and X Consortium make no
|
||||
representations about the suitability of this software for
|
||||
any purpose. It is provided "as is" without any express or
|
||||
implied warranty.
|
||||
|
||||
SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
|
||||
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
|
||||
ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* This is based on cfbcmap.c. The functions here are useful independently
|
||||
* of cfb, which is the reason for including them here. How "mi" these
|
||||
* are may be debatable.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xproto.h>
|
||||
#include "scrnintstr.h"
|
||||
#include "colormapst.h"
|
||||
#include "resource.h"
|
||||
#include "globals.h"
|
||||
#include "micmap.h"
|
||||
|
||||
ColormapPtr miInstalledMaps[MAXSCREENS];
|
||||
|
||||
static Bool miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
|
||||
int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
|
||||
unsigned long sizes, int bitsPerRGB, int preferredVis);
|
||||
|
||||
miInitVisualsProcPtr miInitVisualsProc = miDoInitVisuals;
|
||||
|
||||
int
|
||||
miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
|
||||
{
|
||||
if (miInstalledMaps[pScreen->myNum]) {
|
||||
*pmaps = miInstalledMaps[pScreen->myNum]->mid;
|
||||
return (1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
miInstallColormap(ColormapPtr pmap)
|
||||
{
|
||||
int index = pmap->pScreen->myNum;
|
||||
ColormapPtr oldpmap = miInstalledMaps[index];
|
||||
|
||||
if(pmap != oldpmap)
|
||||
{
|
||||
/* Uninstall pInstalledMap. No hardware changes required, just
|
||||
* notify all interested parties. */
|
||||
if(oldpmap != (ColormapPtr)None)
|
||||
WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
|
||||
/* Install pmap */
|
||||
miInstalledMaps[index] = pmap;
|
||||
WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
miUninstallColormap(ColormapPtr pmap)
|
||||
{
|
||||
int index = pmap->pScreen->myNum;
|
||||
ColormapPtr curpmap = miInstalledMaps[index];
|
||||
|
||||
if(pmap == curpmap)
|
||||
{
|
||||
if (pmap->mid != pmap->pScreen->defColormap)
|
||||
{
|
||||
curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
|
||||
RT_COLORMAP);
|
||||
(*pmap->pScreen->InstallColormap)(curpmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
miResolveColor(unsigned short *pred, unsigned short *pgreen,
|
||||
unsigned short *pblue, VisualPtr pVisual)
|
||||
{
|
||||
int shift = 16 - pVisual->bitsPerRGBValue;
|
||||
unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
|
||||
|
||||
if ((pVisual->class | DynamicClass) == GrayScale)
|
||||
{
|
||||
/* rescale to gray then rgb bits */
|
||||
*pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
|
||||
*pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* rescale to rgb bits */
|
||||
*pred = ((*pred >> shift) * 65535) / lim;
|
||||
*pgreen = ((*pgreen >> shift) * 65535) / lim;
|
||||
*pblue = ((*pblue >> shift) * 65535) / lim;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
miInitializeColormap(ColormapPtr pmap)
|
||||
{
|
||||
register unsigned i;
|
||||
register VisualPtr pVisual;
|
||||
unsigned lim, maxent, shift;
|
||||
|
||||
pVisual = pmap->pVisual;
|
||||
lim = (1 << pVisual->bitsPerRGBValue) - 1;
|
||||
shift = 16 - pVisual->bitsPerRGBValue;
|
||||
maxent = pVisual->ColormapEntries - 1;
|
||||
if (pVisual->class == TrueColor)
|
||||
{
|
||||
unsigned limr, limg, limb;
|
||||
|
||||
limr = pVisual->redMask >> pVisual->offsetRed;
|
||||
limg = pVisual->greenMask >> pVisual->offsetGreen;
|
||||
limb = pVisual->blueMask >> pVisual->offsetBlue;
|
||||
for(i = 0; i <= maxent; i++)
|
||||
{
|
||||
/* rescale to [0..65535] then rgb bits */
|
||||
pmap->red[i].co.local.red =
|
||||
((((i * 65535) / limr) >> shift) * 65535) / lim;
|
||||
pmap->green[i].co.local.green =
|
||||
((((i * 65535) / limg) >> shift) * 65535) / lim;
|
||||
pmap->blue[i].co.local.blue =
|
||||
((((i * 65535) / limb) >> shift) * 65535) / lim;
|
||||
}
|
||||
}
|
||||
else if (pVisual->class == StaticColor)
|
||||
{
|
||||
unsigned limr, limg, limb;
|
||||
|
||||
limr = pVisual->redMask >> pVisual->offsetRed;
|
||||
limg = pVisual->greenMask >> pVisual->offsetGreen;
|
||||
limb = pVisual->blueMask >> pVisual->offsetBlue;
|
||||
for(i = 0; i <= maxent; i++)
|
||||
{
|
||||
/* rescale to [0..65535] then rgb bits */
|
||||
pmap->red[i].co.local.red =
|
||||
((((((i & pVisual->redMask) >> pVisual->offsetRed)
|
||||
* 65535) / limr) >> shift) * 65535) / lim;
|
||||
pmap->red[i].co.local.green =
|
||||
((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
|
||||
* 65535) / limg) >> shift) * 65535) / lim;
|
||||
pmap->red[i].co.local.blue =
|
||||
((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
|
||||
* 65535) / limb) >> shift) * 65535) / lim;
|
||||
}
|
||||
}
|
||||
else if (pVisual->class == StaticGray)
|
||||
{
|
||||
for(i = 0; i <= maxent; i++)
|
||||
{
|
||||
/* rescale to [0..65535] then rgb bits */
|
||||
pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
|
||||
* 65535) / lim;
|
||||
pmap->red[i].co.local.green = pmap->red[i].co.local.red;
|
||||
pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* When simulating DirectColor on PseudoColor hardware, multiple
|
||||
entries of the colormap must be updated
|
||||
*/
|
||||
|
||||
#define AddElement(mask) { \
|
||||
pixel = red | green | blue; \
|
||||
for (i = 0; i < nresult; i++) \
|
||||
if (outdefs[i].pixel == pixel) \
|
||||
break; \
|
||||
if (i == nresult) \
|
||||
{ \
|
||||
nresult++; \
|
||||
outdefs[i].pixel = pixel; \
|
||||
outdefs[i].flags = 0; \
|
||||
} \
|
||||
outdefs[i].flags |= (mask); \
|
||||
outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
|
||||
outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
|
||||
outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
|
||||
}
|
||||
|
||||
int
|
||||
miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs,
|
||||
xColorItem *outdefs)
|
||||
{
|
||||
register int red, green, blue;
|
||||
int maxred, maxgreen, maxblue;
|
||||
int stepred, stepgreen, stepblue;
|
||||
VisualPtr pVisual;
|
||||
register int pixel;
|
||||
register int nresult;
|
||||
register int i;
|
||||
|
||||
pVisual = pmap->pVisual;
|
||||
|
||||
stepred = 1 << pVisual->offsetRed;
|
||||
stepgreen = 1 << pVisual->offsetGreen;
|
||||
stepblue = 1 << pVisual->offsetBlue;
|
||||
maxred = pVisual->redMask;
|
||||
maxgreen = pVisual->greenMask;
|
||||
maxblue = pVisual->blueMask;
|
||||
nresult = 0;
|
||||
for (;ndef--; indefs++)
|
||||
{
|
||||
if (indefs->flags & DoRed)
|
||||
{
|
||||
red = indefs->pixel & pVisual->redMask;
|
||||
for (green = 0; green <= maxgreen; green += stepgreen)
|
||||
{
|
||||
for (blue = 0; blue <= maxblue; blue += stepblue)
|
||||
{
|
||||
AddElement (DoRed)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (indefs->flags & DoGreen)
|
||||
{
|
||||
green = indefs->pixel & pVisual->greenMask;
|
||||
for (red = 0; red <= maxred; red += stepred)
|
||||
{
|
||||
for (blue = 0; blue <= maxblue; blue += stepblue)
|
||||
{
|
||||
AddElement (DoGreen)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (indefs->flags & DoBlue)
|
||||
{
|
||||
blue = indefs->pixel & pVisual->blueMask;
|
||||
for (red = 0; red <= maxred; red += stepred)
|
||||
{
|
||||
for (green = 0; green <= maxgreen; green += stepgreen)
|
||||
{
|
||||
AddElement (DoBlue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nresult;
|
||||
}
|
||||
|
||||
Bool
|
||||
miCreateDefColormap(ScreenPtr pScreen)
|
||||
{
|
||||
/*
|
||||
* In the following sources PC X server vendors may want to delete
|
||||
* "_not_tog" from "#ifdef WIN32_not_tog"
|
||||
*/
|
||||
#ifdef WIN32_not_tog
|
||||
/*
|
||||
* these are the MS-Windows desktop colors, adjusted for X's 16-bit
|
||||
* color specifications.
|
||||
*/
|
||||
static xColorItem citems[] = {
|
||||
{ 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 }
|
||||
};
|
||||
#define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0]
|
||||
int i;
|
||||
#else
|
||||
unsigned short zero = 0, ones = 0xFFFF;
|
||||
#endif
|
||||
Pixel wp, bp;
|
||||
VisualPtr pVisual;
|
||||
ColormapPtr cmap;
|
||||
int alloctype;
|
||||
|
||||
for (pVisual = pScreen->visuals;
|
||||
pVisual->vid != pScreen->rootVisual;
|
||||
pVisual++)
|
||||
;
|
||||
|
||||
if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass))
|
||||
alloctype = AllocNone;
|
||||
else
|
||||
alloctype = AllocAll;
|
||||
|
||||
if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
|
||||
alloctype, 0) != Success)
|
||||
return FALSE;
|
||||
|
||||
if (pScreen->rootDepth > 1) {
|
||||
wp = pScreen->whitePixel;
|
||||
bp = pScreen->blackPixel;
|
||||
#ifdef WIN32_not_tog
|
||||
for (i = 0; i < NUM_DESKTOP_COLORS; i++) {
|
||||
if (AllocColor (cmap,
|
||||
&citems[i].red, &citems[i].green, &citems[i].blue,
|
||||
&citems[i].pixel, 0) != Success)
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
|
||||
Success) ||
|
||||
(AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
|
||||
Success))
|
||||
return FALSE;
|
||||
pScreen->whitePixel = wp;
|
||||
pScreen->blackPixel = bp;
|
||||
#endif
|
||||
}
|
||||
|
||||
(*pScreen->InstallColormap)(cmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Default true color bitmasks, should be overridden by
|
||||
* driver
|
||||
*/
|
||||
|
||||
#define _RZ(d) ((d + 2) / 3)
|
||||
#define _RS(d) 0
|
||||
#define _RM(d) ((1 << _RZ(d)) - 1)
|
||||
#define _GZ(d) ((d - _RZ(d) + 1) / 2)
|
||||
#define _GS(d) _RZ(d)
|
||||
#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
|
||||
#define _BZ(d) (d - _RZ(d) - _GZ(d))
|
||||
#define _BS(d) (_RZ(d) + _GZ(d))
|
||||
#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
|
||||
#define _CE(d) (1 << _RZ(d))
|
||||
|
||||
typedef struct _miVisuals {
|
||||
struct _miVisuals *next;
|
||||
int depth;
|
||||
int bitsPerRGB;
|
||||
int visuals;
|
||||
int count;
|
||||
int preferredCVC;
|
||||
Pixel redMask, greenMask, blueMask;
|
||||
} miVisualsRec, *miVisualsPtr;
|
||||
|
||||
static int miVisualPriority[] = {
|
||||
PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray
|
||||
};
|
||||
|
||||
#define NUM_PRIORITY 6
|
||||
|
||||
static miVisualsPtr miVisuals;
|
||||
|
||||
void
|
||||
miClearVisualTypes()
|
||||
{
|
||||
miVisualsPtr v;
|
||||
|
||||
while ((v = miVisuals)) {
|
||||
miVisuals = v->next;
|
||||
free(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Bool
|
||||
miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
|
||||
int preferredCVC,
|
||||
Pixel redMask, Pixel greenMask, Pixel blueMask)
|
||||
{
|
||||
miVisualsPtr new, *prev, v;
|
||||
int count;
|
||||
|
||||
new = (miVisualsPtr) malloc (sizeof *new);
|
||||
if (!new)
|
||||
return FALSE;
|
||||
if (!redMask || !greenMask || !blueMask)
|
||||
{
|
||||
redMask = _RM(depth);
|
||||
greenMask = _GM(depth);
|
||||
blueMask = _BM(depth);
|
||||
}
|
||||
new->next = 0;
|
||||
new->depth = depth;
|
||||
new->visuals = visuals;
|
||||
new->bitsPerRGB = bitsPerRGB;
|
||||
new->preferredCVC = preferredCVC;
|
||||
new->redMask = redMask;
|
||||
new->greenMask = greenMask;
|
||||
new->blueMask = blueMask;
|
||||
count = (visuals >> 1) & 033333333333;
|
||||
count = visuals - count - ((count >> 1) & 033333333333);
|
||||
count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
|
||||
new->count = count;
|
||||
for (prev = &miVisuals; (v = *prev); prev = &v->next);
|
||||
*prev = new;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
|
||||
{
|
||||
return miSetVisualTypesAndMasks (depth, visuals, bitsPerRGB,
|
||||
preferredCVC, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
miGetDefaultVisualMask(int depth)
|
||||
{
|
||||
if (depth > MAX_PSEUDO_DEPTH)
|
||||
return LARGE_VISUALS;
|
||||
else if (depth >= MIN_TRUE_DEPTH)
|
||||
return ALL_VISUALS;
|
||||
else if (depth == 1)
|
||||
return StaticGrayMask;
|
||||
else
|
||||
return SMALL_VISUALS;
|
||||
}
|
||||
|
||||
static Bool
|
||||
miVisualTypesSet (int depth)
|
||||
{
|
||||
miVisualsPtr visuals;
|
||||
|
||||
for (visuals = miVisuals; visuals; visuals = visuals->next)
|
||||
if (visuals->depth == depth)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool
|
||||
miSetPixmapDepths (void)
|
||||
{
|
||||
int d, f;
|
||||
|
||||
/* Add any unlisted depths from the pixmap formats */
|
||||
for (f = 0; f < screenInfo.numPixmapFormats; f++)
|
||||
{
|
||||
d = screenInfo.formats[f].depth;
|
||||
if (!miVisualTypesSet (d))
|
||||
{
|
||||
if (!miSetVisualTypes (d, 0, 0, -1))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
|
||||
int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
|
||||
unsigned long sizes, int bitsPerRGB, int preferredVis)
|
||||
|
||||
{
|
||||
if (miInitVisualsProc)
|
||||
return miInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
|
||||
rootDepthp, defaultVisp, sizes, bitsPerRGB,
|
||||
preferredVis);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Distance to least significant one bit
|
||||
*/
|
||||
static int
|
||||
maskShift (Pixel p)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (!p) return 0;
|
||||
s = 0;
|
||||
while (!(p & 1))
|
||||
{
|
||||
s++;
|
||||
p >>= 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a list of formats for a screen, create a list
|
||||
* of visuals and depths for the screen which corespond to
|
||||
* the set which can be used with this version of cfb.
|
||||
*/
|
||||
|
||||
static Bool
|
||||
miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
|
||||
int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
|
||||
unsigned long sizes, int bitsPerRGB, int preferredVis)
|
||||
{
|
||||
int i, j = 0, k;
|
||||
VisualPtr visual;
|
||||
DepthPtr depth;
|
||||
VisualID *vid;
|
||||
int d, b;
|
||||
int f;
|
||||
int ndepth, nvisual;
|
||||
int nvtype;
|
||||
int vtype;
|
||||
miVisualsPtr visuals, nextVisuals;
|
||||
int *preferredCVCs, *prefp;
|
||||
int first_depth;
|
||||
|
||||
/* none specified, we'll guess from pixmap formats */
|
||||
if (!miVisuals)
|
||||
{
|
||||
for (f = 0; f < screenInfo.numPixmapFormats; f++)
|
||||
{
|
||||
d = screenInfo.formats[f].depth;
|
||||
b = screenInfo.formats[f].bitsPerPixel;
|
||||
if (sizes & (1 << (b - 1)))
|
||||
vtype = miGetDefaultVisualMask(d);
|
||||
else
|
||||
vtype = 0;
|
||||
if (!miSetVisualTypes (d, vtype, bitsPerRGB, -1))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
nvisual = 0;
|
||||
ndepth = 0;
|
||||
for (visuals = miVisuals; visuals; visuals = nextVisuals)
|
||||
{
|
||||
nextVisuals = visuals->next;
|
||||
ndepth++;
|
||||
nvisual += visuals->count;
|
||||
}
|
||||
depth = (DepthPtr) malloc (ndepth * sizeof (DepthRec));
|
||||
visual = (VisualPtr) malloc (nvisual * sizeof (VisualRec));
|
||||
preferredCVCs = (int *)malloc(ndepth * sizeof(int));
|
||||
if (!depth || !visual || !preferredCVCs)
|
||||
{
|
||||
free (depth);
|
||||
free (visual);
|
||||
free (preferredCVCs);
|
||||
return FALSE;
|
||||
}
|
||||
*depthp = depth;
|
||||
*visualp = visual;
|
||||
*ndepthp = ndepth;
|
||||
*nvisualp = nvisual;
|
||||
prefp = preferredCVCs;
|
||||
for (visuals = miVisuals; visuals; visuals = nextVisuals)
|
||||
{
|
||||
nextVisuals = visuals->next;
|
||||
d = visuals->depth;
|
||||
vtype = visuals->visuals;
|
||||
nvtype = visuals->count;
|
||||
*prefp = visuals->preferredCVC;
|
||||
prefp++;
|
||||
vid = NULL;
|
||||
if (nvtype)
|
||||
{
|
||||
vid = (VisualID *) malloc (nvtype * sizeof (VisualID));
|
||||
if (!vid) {
|
||||
free(preferredCVCs);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
depth->depth = d;
|
||||
depth->numVids = nvtype;
|
||||
depth->vids = vid;
|
||||
depth++;
|
||||
for (i = 0; i < NUM_PRIORITY; i++) {
|
||||
if (! (vtype & (1 << miVisualPriority[i])))
|
||||
continue;
|
||||
visual->class = miVisualPriority[i];
|
||||
visual->bitsPerRGBValue = visuals->bitsPerRGB;
|
||||
visual->ColormapEntries = 1 << d;
|
||||
visual->nplanes = d;
|
||||
visual->vid = *vid = FakeClientID (0);
|
||||
switch (visual->class) {
|
||||
case PseudoColor:
|
||||
case GrayScale:
|
||||
case StaticGray:
|
||||
visual->redMask = 0;
|
||||
visual->greenMask = 0;
|
||||
visual->blueMask = 0;
|
||||
visual->offsetRed = 0;
|
||||
visual->offsetGreen = 0;
|
||||
visual->offsetBlue = 0;
|
||||
break;
|
||||
case DirectColor:
|
||||
case TrueColor:
|
||||
visual->ColormapEntries = _CE(d);
|
||||
/* fall through */
|
||||
case StaticColor:
|
||||
visual->redMask = visuals->redMask;
|
||||
visual->greenMask = visuals->greenMask;
|
||||
visual->blueMask = visuals->blueMask;
|
||||
visual->offsetRed = maskShift (visuals->redMask);
|
||||
visual->offsetGreen = maskShift (visuals->greenMask);
|
||||
visual->offsetBlue = maskShift (visuals->blueMask);
|
||||
}
|
||||
vid++;
|
||||
visual++;
|
||||
}
|
||||
free (visuals);
|
||||
}
|
||||
miVisuals = NULL;
|
||||
visual = *visualp;
|
||||
depth = *depthp;
|
||||
|
||||
/*
|
||||
* if we did not supplyied by a preferred visual class
|
||||
* check if there is a preferred class in one of the depth
|
||||
* structures - if there is, we want to start looking for the
|
||||
* default visual/depth from that depth.
|
||||
*/
|
||||
first_depth = 0;
|
||||
if (preferredVis < 0 && defaultColorVisualClass < 0 ) {
|
||||
for (i = 0; i < ndepth; i++) {
|
||||
if (preferredCVCs[i] >= 0) {
|
||||
first_depth = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = first_depth; i < ndepth; i++)
|
||||
{
|
||||
int prefColorVisualClass = -1;
|
||||
|
||||
if (defaultColorVisualClass >= 0)
|
||||
prefColorVisualClass = defaultColorVisualClass;
|
||||
else if (preferredVis >= 0)
|
||||
prefColorVisualClass = preferredVis;
|
||||
else if (preferredCVCs[i] >= 0)
|
||||
prefColorVisualClass = preferredCVCs[i];
|
||||
|
||||
if (*rootDepthp && *rootDepthp != depth[i].depth)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < depth[i].numVids; j++)
|
||||
{
|
||||
for (k = 0; k < nvisual; k++)
|
||||
if (visual[k].vid == depth[i].vids[j])
|
||||
break;
|
||||
if (k == nvisual)
|
||||
continue;
|
||||
if (prefColorVisualClass < 0 ||
|
||||
visual[k].class == prefColorVisualClass)
|
||||
break;
|
||||
}
|
||||
if (j != depth[i].numVids)
|
||||
break;
|
||||
}
|
||||
if (i == ndepth) {
|
||||
i = 0;
|
||||
j = 0;
|
||||
}
|
||||
*rootDepthp = depth[i].depth;
|
||||
*defaultVisp = depth[i].vids[j];
|
||||
free(preferredCVCs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
miResetInitVisuals()
|
||||
{
|
||||
miInitVisualsProc = miDoInitVisuals;
|
||||
}
|
||||
|
||||
64
nx-X11/programs/Xserver/mi/micmap.h
Normal file
64
nx-X11/programs/Xserver/mi/micmap.h
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
#include "colormapst.h"
|
||||
|
||||
#ifndef _MICMAP_H_
|
||||
#define _MICMAP_H_
|
||||
|
||||
extern ColormapPtr miInstalledMaps[MAXSCREENS];
|
||||
|
||||
typedef Bool (* miInitVisualsProcPtr)(VisualPtr *, DepthPtr *, int *, int *,
|
||||
int *, VisualID *, unsigned long, int,
|
||||
int);
|
||||
|
||||
extern miInitVisualsProcPtr miInitVisualsProc;
|
||||
|
||||
int miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
|
||||
void miInstallColormap(ColormapPtr pmap);
|
||||
void miUninstallColormap(ColormapPtr pmap);
|
||||
|
||||
void miResolveColor(unsigned short *, unsigned short *, unsigned short *,
|
||||
VisualPtr);
|
||||
Bool miInitializeColormap(ColormapPtr);
|
||||
int miExpandDirectColors(ColormapPtr, int, xColorItem *, xColorItem *);
|
||||
Bool miCreateDefColormap(ScreenPtr);
|
||||
void miClearVisualTypes(void);
|
||||
Bool miSetVisualTypes(int, int, int, int);
|
||||
Bool miSetPixmapDepths(void);
|
||||
Bool miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
|
||||
int preferredCVC,
|
||||
Pixel redMask, Pixel greenMask, Pixel blueMask);
|
||||
int miGetDefaultVisualMask(int);
|
||||
Bool miInitVisuals(VisualPtr *, DepthPtr *, int *, int *, int *, VisualID *,
|
||||
unsigned long, int, int);
|
||||
void miResetInitVisuals(void);
|
||||
|
||||
void miHookInitVisuals(void (**old)(miInitVisualsProcPtr *),
|
||||
void (*new)(miInitVisualsProcPtr *));
|
||||
|
||||
|
||||
#define MAX_PSEUDO_DEPTH 10
|
||||
#define MIN_TRUE_DEPTH 6
|
||||
|
||||
#define StaticGrayMask (1 << StaticGray)
|
||||
#define GrayScaleMask (1 << GrayScale)
|
||||
#define StaticColorMask (1 << StaticColor)
|
||||
#define PseudoColorMask (1 << PseudoColor)
|
||||
#define TrueColorMask (1 << TrueColor)
|
||||
#define DirectColorMask (1 << DirectColor)
|
||||
|
||||
#define ALL_VISUALS (StaticGrayMask|\
|
||||
GrayScaleMask|\
|
||||
StaticColorMask|\
|
||||
PseudoColorMask|\
|
||||
TrueColorMask|\
|
||||
DirectColorMask)
|
||||
|
||||
#define LARGE_VISUALS (TrueColorMask|\
|
||||
DirectColorMask)
|
||||
|
||||
#define SMALL_VISUALS (StaticGrayMask|\
|
||||
GrayScaleMask|\
|
||||
StaticColorMask|\
|
||||
PseudoColorMask)
|
||||
|
||||
#endif /* _MICMAP_H_ */
|
||||
70
nx-X11/programs/Xserver/mi/micoord.h
Normal file
70
nx-X11/programs/Xserver/mi/micoord.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2000 The XFree86 Project, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* 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
|
||||
* XFREE86 PROJECT 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 XFree86 Project 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
|
||||
* XFree86 Project.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MICOORD_H_
|
||||
#define _MICOORD_H_ 1
|
||||
|
||||
#include "servermd.h"
|
||||
|
||||
/* Macros which handle a coordinate in a single register */
|
||||
|
||||
/*
|
||||
* Most compilers will convert divisions by 65536 into shifts, if signed
|
||||
* shifts exist. If your machine does arithmetic shifts and your compiler
|
||||
* can't get it right, add to this line.
|
||||
*/
|
||||
|
||||
/*
|
||||
* mips compiler - what a joke - it CSEs the 65536 constant into a reg
|
||||
* forcing as to use div instead of shift. Let's be explicit.
|
||||
*/
|
||||
|
||||
#if defined(mips) || \
|
||||
defined(sparc) || defined(__sparc64__) || \
|
||||
defined(__alpha) || defined(__alpha__) || \
|
||||
defined(__i386__) || defined(i386) || \
|
||||
defined(__ia64__) || defined(ia64) || \
|
||||
defined(__s390x__) || defined(__s390__) || \
|
||||
defined(__amd64__) || defined(amd64) || defined(__amd64)
|
||||
#define GetHighWord(x) (((int) (x)) >> 16)
|
||||
#else
|
||||
#define GetHighWord(x) (((int) (x)) / 65536)
|
||||
#endif
|
||||
|
||||
#if IMAGE_BYTE_ORDER == MSBFirst
|
||||
#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) (i))))
|
||||
#define coordToInt(x,y) (((x) << 16) | ((y) & 0xffff))
|
||||
#define intToX(i) (GetHighWord(i))
|
||||
#define intToY(i) ((int) ((short) i))
|
||||
#else
|
||||
#define intToCoord(i,x,y) (((x) = (int) ((short) (i))), ((y) = GetHighWord(i)))
|
||||
#define coordToInt(x,y) (((y) << 16) | ((x) & 0xffff))
|
||||
#define intToX(i) ((int) ((short) (i)))
|
||||
#define intToY(i) (GetHighWord(i))
|
||||
#endif
|
||||
|
||||
#endif /* _MICOORD_H_ */
|
||||
71
nx-X11/programs/Xserver/mi/micursor.c
Normal file
71
nx-X11/programs/Xserver/mi/micursor.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "scrnintstr.h"
|
||||
#include "cursor.h"
|
||||
#include "misc.h"
|
||||
#include "mi.h"
|
||||
|
||||
void
|
||||
miRecolorCursor( pScr, pCurs, displayed)
|
||||
ScreenPtr pScr;
|
||||
CursorPtr pCurs;
|
||||
Bool displayed;
|
||||
{
|
||||
/*
|
||||
* This is guaranteed to correct any color-dependent state which may have
|
||||
* been bound up in private state created by RealizeCursor
|
||||
*/
|
||||
pScr->UnrealizeCursor(pScr, pCurs);
|
||||
pScr->RealizeCursor(pScr, pCurs);
|
||||
if (displayed)
|
||||
pScr->DisplayCursor(pScr, pCurs);
|
||||
|
||||
}
|
||||
313
nx-X11/programs/Xserver/mi/midash.c
Normal file
313
nx-X11/programs/Xserver/mi/midash.c
Normal file
@@ -0,0 +1,313 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "regionstr.h"
|
||||
#include "mistruct.h"
|
||||
#include "mifpoly.h"
|
||||
|
||||
static miDashPtr CheckDashStorage(miDashPtr *ppseg, int nseg, int *pnsegMax);
|
||||
|
||||
/* return a list of DashRec. there will be an extra
|
||||
entry at the end holding the last point of the polyline.
|
||||
this means that the code that actually draws dashes can
|
||||
get a pair of points for every dash. only the point in the last
|
||||
dash record is useful; the other fields are not used.
|
||||
nseg is the number of segments, not the number of points.
|
||||
|
||||
example:
|
||||
|
||||
dash1.start
|
||||
dash2.start
|
||||
dash3.start
|
||||
last-point
|
||||
|
||||
defines a list of segments
|
||||
(dash1.pt, dash2.pt)
|
||||
(dash2.pt, dash3.pt)
|
||||
(dash3.pt, last-point)
|
||||
and nseg == 3.
|
||||
|
||||
NOTE:
|
||||
EVEN_DASH == ~ODD_DASH
|
||||
|
||||
NOTE ALSO:
|
||||
miDashLines may return 0 segments, going from pt[0] to pt[0] with one dash.
|
||||
*/
|
||||
|
||||
miDashPtr
|
||||
miDashLine(npt, ppt, nDash, pDash, offset, pnseg)
|
||||
int npt;
|
||||
DDXPointPtr ppt;
|
||||
unsigned int nDash;
|
||||
unsigned char *pDash;
|
||||
unsigned int offset;
|
||||
int *pnseg;
|
||||
{
|
||||
DDXPointRec pt1, pt2;
|
||||
int lenCur; /* npt used from this dash */
|
||||
int lenMax; /* npt in this dash */
|
||||
int iDash = 0; /* index of current dash */
|
||||
int which; /* EVEN_DASH or ODD_DASH */
|
||||
miDashPtr pseg; /* list of dash segments */
|
||||
miDashPtr psegBase; /* start of list */
|
||||
int nseg = 0; /* number of dashes so far */
|
||||
int nsegMax = 0; /* num segs we can fit in this list */
|
||||
|
||||
int x, y, len;
|
||||
int adx, ady, signdx, signdy;
|
||||
int du, dv, e1, e2, e, base_e = 0;
|
||||
|
||||
lenCur = offset;
|
||||
which = EVEN_DASH;
|
||||
while(lenCur >= pDash[iDash])
|
||||
{
|
||||
lenCur -= pDash[iDash];
|
||||
iDash++;
|
||||
if (iDash >= nDash)
|
||||
iDash = 0;
|
||||
which = ~which;
|
||||
}
|
||||
lenMax = pDash[iDash];
|
||||
|
||||
psegBase = (miDashPtr)NULL;
|
||||
pt2 = ppt[0]; /* just in case there is only one point */
|
||||
|
||||
while(--npt)
|
||||
{
|
||||
if (PtEqual(ppt[0], ppt[1]))
|
||||
{
|
||||
ppt++;
|
||||
continue; /* no duplicated points in polyline */
|
||||
}
|
||||
pt1 = *ppt++;
|
||||
pt2 = *ppt;
|
||||
|
||||
adx = pt2.x - pt1.x;
|
||||
ady = pt2.y - pt1.y;
|
||||
signdx = sign(adx);
|
||||
signdy = sign(ady);
|
||||
adx = abs(adx);
|
||||
ady = abs(ady);
|
||||
|
||||
if (adx > ady)
|
||||
{
|
||||
du = adx;
|
||||
dv = ady;
|
||||
len = adx;
|
||||
}
|
||||
else
|
||||
{
|
||||
du = ady;
|
||||
dv = adx;
|
||||
len = ady;
|
||||
}
|
||||
|
||||
e1 = dv * 2;
|
||||
e2 = e1 - 2*du;
|
||||
e = e1 - du;
|
||||
x = pt1.x;
|
||||
y = pt1.y;
|
||||
|
||||
nseg++;
|
||||
pseg = CheckDashStorage(&psegBase, nseg, &nsegMax);
|
||||
if (!pseg)
|
||||
return (miDashPtr)NULL;
|
||||
pseg->pt = pt1;
|
||||
pseg->e1 = e1;
|
||||
pseg->e2 = e2;
|
||||
base_e = pseg->e = e;
|
||||
pseg->which = which;
|
||||
pseg->newLine = 1;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
if (adx > ady)
|
||||
{
|
||||
/* X_AXIS */
|
||||
if (((signdx > 0) && (e < 0)) ||
|
||||
((signdx <=0) && (e <=0))
|
||||
)
|
||||
{
|
||||
e += e1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y += signdy;
|
||||
e += e2;
|
||||
}
|
||||
x += signdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Y_AXIS */
|
||||
if (((signdx > 0) && (e < 0)) ||
|
||||
((signdx <=0) && (e <=0))
|
||||
)
|
||||
{
|
||||
e +=e1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += signdx;
|
||||
e += e2;
|
||||
}
|
||||
y += signdy;
|
||||
}
|
||||
|
||||
lenCur++;
|
||||
if (lenCur >= lenMax && (len || npt <= 1))
|
||||
{
|
||||
nseg++;
|
||||
pseg = CheckDashStorage(&psegBase, nseg, &nsegMax);
|
||||
if (!pseg)
|
||||
return (miDashPtr)NULL;
|
||||
pseg->pt.x = x;
|
||||
pseg->pt.y = y;
|
||||
pseg->e1 = e1;
|
||||
pseg->e2 = e2;
|
||||
pseg->e = e;
|
||||
which = ~which;
|
||||
pseg->which = which;
|
||||
pseg->newLine = 0;
|
||||
|
||||
/* move on to next dash */
|
||||
iDash++;
|
||||
if (iDash >= nDash)
|
||||
iDash = 0;
|
||||
lenMax = pDash[iDash];
|
||||
lenCur = 0;
|
||||
}
|
||||
} /* while len-- */
|
||||
} /* while --npt */
|
||||
|
||||
if (lenCur == 0 && nseg != 0)
|
||||
{
|
||||
nseg--;
|
||||
which = ~which;
|
||||
}
|
||||
*pnseg = nseg;
|
||||
pseg = CheckDashStorage(&psegBase, nseg+1, &nsegMax);
|
||||
if (!pseg)
|
||||
return (miDashPtr)NULL;
|
||||
pseg->pt = pt2;
|
||||
pseg->e = base_e;
|
||||
pseg->which = which;
|
||||
pseg->newLine = 0;
|
||||
return psegBase;
|
||||
}
|
||||
|
||||
|
||||
#define NSEGDELTA 16
|
||||
|
||||
/* returns a pointer to the pseg[nseg-1], growing the storage as
|
||||
necessary. this interface seems unnecessarily cumbersome.
|
||||
|
||||
*/
|
||||
|
||||
static
|
||||
miDashPtr
|
||||
CheckDashStorage(
|
||||
miDashPtr *ppseg, /* base pointer */
|
||||
int nseg, /* number of segment we want to write to */
|
||||
int *pnsegMax) /* size (in segments) of list so far */
|
||||
{
|
||||
if (nseg > *pnsegMax)
|
||||
{
|
||||
miDashPtr newppseg;
|
||||
|
||||
*pnsegMax += NSEGDELTA;
|
||||
newppseg = (miDashPtr)realloc(*ppseg,
|
||||
(*pnsegMax)*sizeof(miDashRec));
|
||||
if (!newppseg)
|
||||
{
|
||||
free(*ppseg);
|
||||
return (miDashPtr)NULL;
|
||||
}
|
||||
*ppseg = newppseg;
|
||||
}
|
||||
return(*ppseg+(nseg-1));
|
||||
}
|
||||
|
||||
void
|
||||
miStepDash (dist, pDashIndex, pDash, numInDashList, pDashOffset)
|
||||
int dist; /* distance to step */
|
||||
int *pDashIndex; /* current dash */
|
||||
unsigned char *pDash; /* dash list */
|
||||
int numInDashList; /* total length of dash list */
|
||||
int *pDashOffset; /* offset into current dash */
|
||||
{
|
||||
int dashIndex, dashOffset;
|
||||
int totallen;
|
||||
int i;
|
||||
|
||||
dashIndex = *pDashIndex;
|
||||
dashOffset = *pDashOffset;
|
||||
if (dist < pDash[dashIndex] - dashOffset)
|
||||
{
|
||||
*pDashOffset = dashOffset + dist;
|
||||
return;
|
||||
}
|
||||
dist -= pDash[dashIndex] - dashOffset;
|
||||
if (++dashIndex == numInDashList)
|
||||
dashIndex = 0;
|
||||
totallen = 0;
|
||||
for (i = 0; i < numInDashList; i++)
|
||||
totallen += pDash[i];
|
||||
if (totallen <= dist)
|
||||
dist = dist % totallen;
|
||||
while (dist >= pDash[dashIndex])
|
||||
{
|
||||
dist -= pDash[dashIndex];
|
||||
if (++dashIndex == numInDashList)
|
||||
dashIndex = 0;
|
||||
}
|
||||
*pDashIndex = dashIndex;
|
||||
*pDashOffset = dist;
|
||||
}
|
||||
813
nx-X11/programs/Xserver/mi/midispcur.c
Normal file
813
nx-X11/programs/Xserver/mi/midispcur.c
Normal file
@@ -0,0 +1,813 @@
|
||||
/*
|
||||
* midispcur.c
|
||||
*
|
||||
* machine independent cursor display routines
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
# include <nx-X11/X.h>
|
||||
# include "misc.h"
|
||||
# include "input.h"
|
||||
# include "cursorstr.h"
|
||||
# include "windowstr.h"
|
||||
# include "regionstr.h"
|
||||
# include "dixstruct.h"
|
||||
# include "scrnintstr.h"
|
||||
# include "servermd.h"
|
||||
# include "mipointer.h"
|
||||
# include "misprite.h"
|
||||
# include "gcstruct.h"
|
||||
|
||||
#ifdef ARGB_CURSOR
|
||||
# include "picturestr.h"
|
||||
#endif
|
||||
|
||||
/* per-screen private data */
|
||||
|
||||
static int miDCScreenIndex;
|
||||
static unsigned long miDCGeneration = 0;
|
||||
|
||||
static Bool miDCCloseScreen(ScreenPtr pScreen);
|
||||
|
||||
typedef struct {
|
||||
GCPtr pSourceGC, pMaskGC;
|
||||
GCPtr pSaveGC, pRestoreGC;
|
||||
GCPtr pMoveGC;
|
||||
GCPtr pPixSourceGC, pPixMaskGC;
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
PixmapPtr pSave, pTemp;
|
||||
#ifdef ARGB_CURSOR
|
||||
PicturePtr pRootPicture;
|
||||
PicturePtr pTempPicture;
|
||||
#endif
|
||||
} miDCScreenRec, *miDCScreenPtr;
|
||||
|
||||
/* per-cursor per-screen private data */
|
||||
typedef struct {
|
||||
PixmapPtr sourceBits; /* source bits */
|
||||
PixmapPtr maskBits; /* mask bits */
|
||||
#ifdef ARGB_CURSOR
|
||||
PicturePtr pPicture;
|
||||
#endif
|
||||
} miDCCursorRec, *miDCCursorPtr;
|
||||
|
||||
/*
|
||||
* sprite/cursor method table
|
||||
*/
|
||||
|
||||
static Bool miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
static Bool miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
static Bool miDCPutUpCursor(ScreenPtr pScreen, CursorPtr pCursor,
|
||||
int x, int y, unsigned long source,
|
||||
unsigned long mask);
|
||||
static Bool miDCSaveUnderCursor(ScreenPtr pScreen, int x, int y,
|
||||
int w, int h);
|
||||
static Bool miDCRestoreUnderCursor(ScreenPtr pScreen, int x, int y,
|
||||
int w, int h);
|
||||
static Bool miDCMoveCursor(ScreenPtr pScreen, CursorPtr pCursor,
|
||||
int x, int y, int w, int h, int dx, int dy,
|
||||
unsigned long source, unsigned long mask);
|
||||
static Bool miDCChangeSave(ScreenPtr pScreen, int x, int y, int w, int h,
|
||||
int dx, int dy);
|
||||
|
||||
static miSpriteCursorFuncRec miDCFuncs = {
|
||||
miDCRealizeCursor,
|
||||
miDCUnrealizeCursor,
|
||||
miDCPutUpCursor,
|
||||
miDCSaveUnderCursor,
|
||||
miDCRestoreUnderCursor,
|
||||
miDCMoveCursor,
|
||||
miDCChangeSave,
|
||||
};
|
||||
|
||||
Bool
|
||||
miDCInitialize (pScreen, screenFuncs)
|
||||
ScreenPtr pScreen;
|
||||
miPointerScreenFuncPtr screenFuncs;
|
||||
{
|
||||
miDCScreenPtr pScreenPriv;
|
||||
|
||||
if (miDCGeneration != serverGeneration)
|
||||
{
|
||||
miDCScreenIndex = AllocateScreenPrivateIndex ();
|
||||
if (miDCScreenIndex < 0)
|
||||
return FALSE;
|
||||
miDCGeneration = serverGeneration;
|
||||
}
|
||||
pScreenPriv = (miDCScreenPtr) malloc (sizeof (miDCScreenRec));
|
||||
if (!pScreenPriv)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* initialize the entire private structure to zeros
|
||||
*/
|
||||
|
||||
pScreenPriv->pSourceGC =
|
||||
pScreenPriv->pMaskGC =
|
||||
pScreenPriv->pSaveGC =
|
||||
pScreenPriv->pRestoreGC =
|
||||
pScreenPriv->pMoveGC =
|
||||
pScreenPriv->pPixSourceGC =
|
||||
pScreenPriv->pPixMaskGC = NULL;
|
||||
#ifdef ARGB_CURSOR
|
||||
pScreenPriv->pRootPicture = NULL;
|
||||
pScreenPriv->pTempPicture = NULL;
|
||||
#endif
|
||||
|
||||
pScreenPriv->pSave = pScreenPriv->pTemp = NULL;
|
||||
|
||||
pScreenPriv->CloseScreen = pScreen->CloseScreen;
|
||||
pScreen->CloseScreen = miDCCloseScreen;
|
||||
|
||||
pScreen->devPrivates[miDCScreenIndex].ptr = (void *) pScreenPriv;
|
||||
|
||||
if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs))
|
||||
{
|
||||
free ((void *) pScreenPriv);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define tossGC(gc) (gc ? FreeGC (gc, (GContext) 0) : 0)
|
||||
#define tossPix(pix) (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
|
||||
#define tossPict(pict) (pict ? FreePicture (pict, 0) : 0)
|
||||
|
||||
static Bool
|
||||
miDCCloseScreen (pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
miDCScreenPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
|
||||
pScreen->CloseScreen = pScreenPriv->CloseScreen;
|
||||
tossGC (pScreenPriv->pSourceGC);
|
||||
tossGC (pScreenPriv->pMaskGC);
|
||||
tossGC (pScreenPriv->pSaveGC);
|
||||
tossGC (pScreenPriv->pRestoreGC);
|
||||
tossGC (pScreenPriv->pMoveGC);
|
||||
tossGC (pScreenPriv->pPixSourceGC);
|
||||
tossGC (pScreenPriv->pPixMaskGC);
|
||||
tossPix (pScreenPriv->pSave);
|
||||
tossPix (pScreenPriv->pTemp);
|
||||
#ifdef ARGB_CURSOR
|
||||
tossPict (pScreenPriv->pRootPicture);
|
||||
tossPict (pScreenPriv->pTempPicture);
|
||||
#endif
|
||||
free ((void *) pScreenPriv);
|
||||
return (*pScreen->CloseScreen) (pScreen);
|
||||
}
|
||||
|
||||
static Bool
|
||||
miDCRealizeCursor (pScreen, pCursor)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
{
|
||||
if (pCursor->bits->refcnt <= 1)
|
||||
pCursor->bits->devPriv[pScreen->myNum] = (void *)NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef ARGB_CURSOR
|
||||
#define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win))
|
||||
|
||||
static VisualPtr
|
||||
miDCGetWindowVisual (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
VisualID vid = wVisual (pWin);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pScreen->numVisuals; i++)
|
||||
if (pScreen->visuals[i].vid == vid)
|
||||
return &pScreen->visuals[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PicturePtr
|
||||
miDCMakePicture (PicturePtr *ppPicture, DrawablePtr pDraw, WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pDraw->pScreen;
|
||||
VisualPtr pVisual;
|
||||
PictFormatPtr pFormat;
|
||||
XID subwindow_mode = IncludeInferiors;
|
||||
PicturePtr pPicture;
|
||||
int error;
|
||||
|
||||
pVisual = miDCGetWindowVisual (pWin);
|
||||
if (!pVisual)
|
||||
return 0;
|
||||
pFormat = PictureMatchVisual (pScreen, pDraw->depth, pVisual);
|
||||
if (!pFormat)
|
||||
return 0;
|
||||
pPicture = CreatePicture (0, pDraw, pFormat,
|
||||
CPSubwindowMode, &subwindow_mode,
|
||||
serverClient, &error);
|
||||
*ppPicture = pPicture;
|
||||
return pPicture;
|
||||
}
|
||||
#endif
|
||||
|
||||
static miDCCursorPtr
|
||||
miDCRealize (
|
||||
ScreenPtr pScreen,
|
||||
CursorPtr pCursor)
|
||||
{
|
||||
miDCCursorPtr pPriv;
|
||||
GCPtr pGC;
|
||||
XID gcvals[3];
|
||||
|
||||
pPriv = (miDCCursorPtr) malloc (sizeof (miDCCursorRec));
|
||||
if (!pPriv)
|
||||
return (miDCCursorPtr)NULL;
|
||||
#ifdef ARGB_CURSOR
|
||||
if (pCursor->bits->argb)
|
||||
{
|
||||
PixmapPtr pPixmap;
|
||||
PictFormatPtr pFormat;
|
||||
int error;
|
||||
|
||||
pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
|
||||
if (!pFormat)
|
||||
{
|
||||
free ((void *) pPriv);
|
||||
return (miDCCursorPtr)NULL;
|
||||
}
|
||||
|
||||
pPriv->sourceBits = 0;
|
||||
pPriv->maskBits = 0;
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
|
||||
pCursor->bits->height, 32,
|
||||
CREATE_PIXMAP_USAGE_SCRATCH);
|
||||
if (!pPixmap)
|
||||
{
|
||||
free ((void *) pPriv);
|
||||
return (miDCCursorPtr)NULL;
|
||||
}
|
||||
pGC = GetScratchGC (32, pScreen);
|
||||
if (!pGC)
|
||||
{
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
free ((void *) pPriv);
|
||||
return (miDCCursorPtr)NULL;
|
||||
}
|
||||
ValidateGC (&pPixmap->drawable, pGC);
|
||||
(*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32,
|
||||
0, 0, pCursor->bits->width,
|
||||
pCursor->bits->height,
|
||||
0, ZPixmap, (char *) pCursor->bits->argb);
|
||||
FreeScratchGC (pGC);
|
||||
pPriv->pPicture = CreatePicture (0, &pPixmap->drawable,
|
||||
pFormat, 0, 0, serverClient, &error);
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
if (!pPriv->pPicture)
|
||||
{
|
||||
free ((void *) pPriv);
|
||||
return (miDCCursorPtr)NULL;
|
||||
}
|
||||
pCursor->bits->devPriv[pScreen->myNum] = (void *) pPriv;
|
||||
return pPriv;
|
||||
}
|
||||
pPriv->pPicture = 0;
|
||||
#endif
|
||||
pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0);
|
||||
if (!pPriv->sourceBits)
|
||||
{
|
||||
free ((void *) pPriv);
|
||||
return (miDCCursorPtr)NULL;
|
||||
}
|
||||
pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0);
|
||||
if (!pPriv->maskBits)
|
||||
{
|
||||
(*pScreen->DestroyPixmap) (pPriv->sourceBits);
|
||||
free ((void *) pPriv);
|
||||
return (miDCCursorPtr)NULL;
|
||||
}
|
||||
pCursor->bits->devPriv[pScreen->myNum] = (void *) pPriv;
|
||||
|
||||
/* create the two sets of bits, clipping as appropriate */
|
||||
|
||||
pGC = GetScratchGC (1, pScreen);
|
||||
if (!pGC)
|
||||
{
|
||||
(void) miDCUnrealizeCursor (pScreen, pCursor);
|
||||
return (miDCCursorPtr)NULL;
|
||||
}
|
||||
|
||||
ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
|
||||
(*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
|
||||
0, 0, pCursor->bits->width, pCursor->bits->height,
|
||||
0, XYPixmap, (char *)pCursor->bits->source);
|
||||
gcvals[0] = GXand;
|
||||
ChangeGC (pGC, GCFunction, gcvals);
|
||||
ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
|
||||
(*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
|
||||
0, 0, pCursor->bits->width, pCursor->bits->height,
|
||||
0, XYPixmap, (char *)pCursor->bits->mask);
|
||||
|
||||
/* mask bits -- pCursor->mask & ~pCursor->source */
|
||||
gcvals[0] = GXcopy;
|
||||
ChangeGC (pGC, GCFunction, gcvals);
|
||||
ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
|
||||
(*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
|
||||
0, 0, pCursor->bits->width, pCursor->bits->height,
|
||||
0, XYPixmap, (char *)pCursor->bits->mask);
|
||||
gcvals[0] = GXandInverted;
|
||||
ChangeGC (pGC, GCFunction, gcvals);
|
||||
ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
|
||||
(*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
|
||||
0, 0, pCursor->bits->width, pCursor->bits->height,
|
||||
0, XYPixmap, (char *)pCursor->bits->source);
|
||||
FreeScratchGC (pGC);
|
||||
return pPriv;
|
||||
}
|
||||
|
||||
static Bool
|
||||
miDCUnrealizeCursor (pScreen, pCursor)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
{
|
||||
miDCCursorPtr pPriv;
|
||||
|
||||
pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
|
||||
if (pPriv && (pCursor->bits->refcnt <= 1))
|
||||
{
|
||||
if (pPriv->sourceBits)
|
||||
(*pScreen->DestroyPixmap) (pPriv->sourceBits);
|
||||
if (pPriv->maskBits)
|
||||
(*pScreen->DestroyPixmap) (pPriv->maskBits);
|
||||
#ifdef ARGB_CURSOR
|
||||
if (pPriv->pPicture)
|
||||
FreePicture (pPriv->pPicture, 0);
|
||||
#endif
|
||||
free ((void *) pPriv);
|
||||
pCursor->bits->devPriv[pScreen->myNum] = (void *)NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
miDCPutBits (
|
||||
DrawablePtr pDrawable,
|
||||
miDCCursorPtr pPriv,
|
||||
GCPtr sourceGC,
|
||||
GCPtr maskGC,
|
||||
int x_org,
|
||||
int y_org,
|
||||
unsigned w,
|
||||
unsigned h,
|
||||
unsigned long source,
|
||||
unsigned long mask)
|
||||
{
|
||||
XID gcvals[1];
|
||||
int x, y;
|
||||
|
||||
if (sourceGC->fgPixel != source)
|
||||
{
|
||||
gcvals[0] = source;
|
||||
DoChangeGC (sourceGC, GCForeground, gcvals, 0);
|
||||
}
|
||||
if (sourceGC->serialNumber != pDrawable->serialNumber)
|
||||
ValidateGC (pDrawable, sourceGC);
|
||||
|
||||
if(sourceGC->miTranslate)
|
||||
{
|
||||
x = pDrawable->x + x_org;
|
||||
y = pDrawable->y + y_org;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x_org;
|
||||
y = y_org;
|
||||
}
|
||||
|
||||
(*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y);
|
||||
if (maskGC->fgPixel != mask)
|
||||
{
|
||||
gcvals[0] = mask;
|
||||
DoChangeGC (maskGC, GCForeground, gcvals, 0);
|
||||
}
|
||||
if (maskGC->serialNumber != pDrawable->serialNumber)
|
||||
ValidateGC (pDrawable, maskGC);
|
||||
|
||||
if(maskGC->miTranslate)
|
||||
{
|
||||
x = pDrawable->x + x_org;
|
||||
y = pDrawable->y + y_org;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x_org;
|
||||
y = y_org;
|
||||
}
|
||||
|
||||
(*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
|
||||
}
|
||||
|
||||
#define EnsureGC(gc,win) (gc || miDCMakeGC(&gc, win))
|
||||
|
||||
static GCPtr
|
||||
miDCMakeGC(
|
||||
GCPtr *ppGC,
|
||||
WindowPtr pWin)
|
||||
{
|
||||
GCPtr pGC;
|
||||
int status;
|
||||
XID gcvals[2];
|
||||
|
||||
gcvals[0] = IncludeInferiors;
|
||||
gcvals[1] = FALSE;
|
||||
pGC = CreateGC((DrawablePtr)pWin,
|
||||
GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
|
||||
if (pGC && pWin->drawable.pScreen->DrawGuarantee)
|
||||
(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
|
||||
*ppGC = pGC;
|
||||
return pGC;
|
||||
}
|
||||
|
||||
|
||||
static Bool
|
||||
miDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
int x, y;
|
||||
unsigned long source, mask;
|
||||
{
|
||||
miDCScreenPtr pScreenPriv;
|
||||
miDCCursorPtr pPriv;
|
||||
WindowPtr pWin;
|
||||
|
||||
pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
|
||||
if (!pPriv)
|
||||
{
|
||||
pPriv = miDCRealize(pScreen, pCursor);
|
||||
if (!pPriv)
|
||||
return FALSE;
|
||||
}
|
||||
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
|
||||
pWin = pScreen->root;
|
||||
#ifdef ARGB_CURSOR
|
||||
if (pPriv->pPicture)
|
||||
{
|
||||
if (!EnsurePicture(pScreenPriv->pRootPicture, &pWin->drawable, pWin))
|
||||
return FALSE;
|
||||
CompositePicture (PictOpOver,
|
||||
pPriv->pPicture,
|
||||
NULL,
|
||||
pScreenPriv->pRootPicture,
|
||||
0, 0, 0, 0,
|
||||
x, y,
|
||||
pCursor->bits->width,
|
||||
pCursor->bits->height);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (!EnsureGC(pScreenPriv->pSourceGC, pWin))
|
||||
return FALSE;
|
||||
if (!EnsureGC(pScreenPriv->pMaskGC, pWin))
|
||||
{
|
||||
FreeGC (pScreenPriv->pSourceGC, (GContext) 0);
|
||||
pScreenPriv->pSourceGC = 0;
|
||||
return FALSE;
|
||||
}
|
||||
miDCPutBits ((DrawablePtr)pWin, pPriv,
|
||||
pScreenPriv->pSourceGC, pScreenPriv->pMaskGC,
|
||||
x, y, pCursor->bits->width, pCursor->bits->height,
|
||||
source, mask);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
miDCSaveUnderCursor (pScreen, x, y, w, h)
|
||||
ScreenPtr pScreen;
|
||||
int x, y, w, h;
|
||||
{
|
||||
miDCScreenPtr pScreenPriv;
|
||||
PixmapPtr pSave;
|
||||
WindowPtr pWin;
|
||||
GCPtr pGC;
|
||||
|
||||
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
|
||||
pSave = pScreenPriv->pSave;
|
||||
pWin = pScreen->root;
|
||||
if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
|
||||
{
|
||||
if (pSave)
|
||||
(*pScreen->DestroyPixmap) (pSave);
|
||||
pScreenPriv->pSave = pSave =
|
||||
(*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0);
|
||||
if (!pSave)
|
||||
return FALSE;
|
||||
}
|
||||
if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
|
||||
return FALSE;
|
||||
pGC = pScreenPriv->pSaveGC;
|
||||
if (pSave->drawable.serialNumber != pGC->serialNumber)
|
||||
ValidateGC ((DrawablePtr) pSave, pGC);
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
|
||||
x, y, w, h, 0, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
miDCRestoreUnderCursor (pScreen, x, y, w, h)
|
||||
ScreenPtr pScreen;
|
||||
int x, y, w, h;
|
||||
{
|
||||
miDCScreenPtr pScreenPriv;
|
||||
PixmapPtr pSave;
|
||||
WindowPtr pWin;
|
||||
GCPtr pGC;
|
||||
|
||||
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
|
||||
pSave = pScreenPriv->pSave;
|
||||
pWin = pScreen->root;
|
||||
if (!pSave)
|
||||
return FALSE;
|
||||
if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
|
||||
return FALSE;
|
||||
pGC = pScreenPriv->pRestoreGC;
|
||||
if (pWin->drawable.serialNumber != pGC->serialNumber)
|
||||
ValidateGC ((DrawablePtr) pWin, pGC);
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
|
||||
0, 0, w, h, x, y);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
miDCChangeSave (pScreen, x, y, w, h, dx, dy)
|
||||
ScreenPtr pScreen;
|
||||
int x, y, w, h, dx, dy;
|
||||
{
|
||||
miDCScreenPtr pScreenPriv;
|
||||
PixmapPtr pSave;
|
||||
WindowPtr pWin;
|
||||
GCPtr pGC;
|
||||
int sourcex, sourcey, destx, desty, copyw, copyh;
|
||||
|
||||
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
|
||||
pSave = pScreenPriv->pSave;
|
||||
pWin = pScreen->root;
|
||||
/*
|
||||
* restore the bits which are about to get trashed
|
||||
*/
|
||||
if (!pSave)
|
||||
return FALSE;
|
||||
if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
|
||||
return FALSE;
|
||||
pGC = pScreenPriv->pRestoreGC;
|
||||
if (pWin->drawable.serialNumber != pGC->serialNumber)
|
||||
ValidateGC ((DrawablePtr) pWin, pGC);
|
||||
/*
|
||||
* copy the old bits to the screen.
|
||||
*/
|
||||
if (dy > 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
|
||||
0, h - dy, w, dy, x + dx, y + h);
|
||||
}
|
||||
else if (dy < 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
|
||||
0, 0, w, -dy, x + dx, y + dy);
|
||||
}
|
||||
if (dy >= 0)
|
||||
{
|
||||
desty = y + dy;
|
||||
sourcey = 0;
|
||||
copyh = h - dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
desty = y;
|
||||
sourcey = - dy;
|
||||
copyh = h + dy;
|
||||
}
|
||||
if (dx > 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
|
||||
w - dx, sourcey, dx, copyh, x + w, desty);
|
||||
}
|
||||
else if (dx < 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
|
||||
0, sourcey, -dx, copyh, x + dx, desty);
|
||||
}
|
||||
if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
|
||||
return FALSE;
|
||||
pGC = pScreenPriv->pSaveGC;
|
||||
if (pSave->drawable.serialNumber != pGC->serialNumber)
|
||||
ValidateGC ((DrawablePtr) pSave, pGC);
|
||||
/*
|
||||
* move the bits that are still valid within the pixmap
|
||||
*/
|
||||
if (dx >= 0)
|
||||
{
|
||||
sourcex = 0;
|
||||
destx = dx;
|
||||
copyw = w - dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
destx = 0;
|
||||
sourcex = - dx;
|
||||
copyw = w + dx;
|
||||
}
|
||||
if (dy >= 0)
|
||||
{
|
||||
sourcey = 0;
|
||||
desty = dy;
|
||||
copyh = h - dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
desty = 0;
|
||||
sourcey = -dy;
|
||||
copyh = h + dy;
|
||||
}
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC,
|
||||
sourcex, sourcey, copyw, copyh, destx, desty);
|
||||
/*
|
||||
* copy the new bits from the screen into the remaining areas of the
|
||||
* pixmap
|
||||
*/
|
||||
if (dy > 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
|
||||
x, y, w, dy, 0, 0);
|
||||
}
|
||||
else if (dy < 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
|
||||
x, y + h + dy, w, -dy, 0, h + dy);
|
||||
}
|
||||
if (dy >= 0)
|
||||
{
|
||||
desty = dy;
|
||||
sourcey = y + dy;
|
||||
copyh = h - dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
desty = 0;
|
||||
sourcey = y;
|
||||
copyh = h + dy;
|
||||
}
|
||||
if (dx > 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
|
||||
x, sourcey, dx, copyh, 0, desty);
|
||||
}
|
||||
else if (dx < 0)
|
||||
{
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
|
||||
x + w + dx, sourcey, -dx, copyh, w + dx, desty);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
int x, y, w, h, dx, dy;
|
||||
unsigned long source, mask;
|
||||
{
|
||||
miDCCursorPtr pPriv;
|
||||
miDCScreenPtr pScreenPriv;
|
||||
int status;
|
||||
WindowPtr pWin;
|
||||
GCPtr pGC;
|
||||
XID gcval = FALSE;
|
||||
PixmapPtr pTemp;
|
||||
|
||||
pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
|
||||
if (!pPriv)
|
||||
{
|
||||
pPriv = miDCRealize(pScreen, pCursor);
|
||||
if (!pPriv)
|
||||
return FALSE;
|
||||
}
|
||||
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
|
||||
pWin = pScreen->root;
|
||||
pTemp = pScreenPriv->pTemp;
|
||||
if (!pTemp ||
|
||||
pTemp->drawable.width != pScreenPriv->pSave->drawable.width ||
|
||||
pTemp->drawable.height != pScreenPriv->pSave->drawable.height)
|
||||
{
|
||||
if (pTemp)
|
||||
(*pScreen->DestroyPixmap) (pTemp);
|
||||
#ifdef ARGB_CURSOR
|
||||
if (pScreenPriv->pTempPicture)
|
||||
{
|
||||
FreePicture (pScreenPriv->pTempPicture, 0);
|
||||
pScreenPriv->pTempPicture = 0;
|
||||
}
|
||||
#endif
|
||||
pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap)
|
||||
(pScreen, w, h, pScreenPriv->pSave->drawable.depth, 0);
|
||||
if (!pTemp)
|
||||
return FALSE;
|
||||
}
|
||||
if (!pScreenPriv->pMoveGC)
|
||||
{
|
||||
pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp,
|
||||
GCGraphicsExposures, &gcval, &status);
|
||||
if (!pScreenPriv->pMoveGC)
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* copy the saved area to a temporary pixmap
|
||||
*/
|
||||
pGC = pScreenPriv->pMoveGC;
|
||||
if (pGC->serialNumber != pTemp->drawable.serialNumber)
|
||||
ValidateGC ((DrawablePtr) pTemp, pGC);
|
||||
(*pGC->ops->CopyArea)((DrawablePtr)pScreenPriv->pSave,
|
||||
(DrawablePtr)pTemp, pGC, 0, 0, w, h, 0, 0);
|
||||
|
||||
/*
|
||||
* draw the cursor in the temporary pixmap
|
||||
*/
|
||||
#ifdef ARGB_CURSOR
|
||||
if (pPriv->pPicture)
|
||||
{
|
||||
if (!EnsurePicture(pScreenPriv->pTempPicture, &pTemp->drawable, pWin))
|
||||
return FALSE;
|
||||
CompositePicture (PictOpOver,
|
||||
pPriv->pPicture,
|
||||
NULL,
|
||||
pScreenPriv->pTempPicture,
|
||||
0, 0, 0, 0,
|
||||
dx, dy,
|
||||
pCursor->bits->width,
|
||||
pCursor->bits->height);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (!pScreenPriv->pPixSourceGC)
|
||||
{
|
||||
pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
|
||||
GCGraphicsExposures, &gcval, &status);
|
||||
if (!pScreenPriv->pPixSourceGC)
|
||||
return FALSE;
|
||||
}
|
||||
if (!pScreenPriv->pPixMaskGC)
|
||||
{
|
||||
pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
|
||||
GCGraphicsExposures, &gcval, &status);
|
||||
if (!pScreenPriv->pPixMaskGC)
|
||||
return FALSE;
|
||||
}
|
||||
miDCPutBits ((DrawablePtr)pTemp, pPriv,
|
||||
pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC,
|
||||
dx, dy, pCursor->bits->width, pCursor->bits->height,
|
||||
source, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy the temporary pixmap onto the screen
|
||||
*/
|
||||
|
||||
if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
|
||||
return FALSE;
|
||||
pGC = pScreenPriv->pRestoreGC;
|
||||
if (pWin->drawable.serialNumber != pGC->serialNumber)
|
||||
ValidateGC ((DrawablePtr) pWin, pGC);
|
||||
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pTemp, (DrawablePtr) pWin,
|
||||
pGC,
|
||||
0, 0, w, h, x, y);
|
||||
return TRUE;
|
||||
}
|
||||
204
nx-X11/programs/Xserver/mi/mieq.c
Normal file
204
nx-X11/programs/Xserver/mi/mieq.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* $Xorg: mieq.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $
|
||||
*
|
||||
Copyright 1990, 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.
|
||||
*
|
||||
* Author: Keith Packard, MIT X Consortium
|
||||
*/
|
||||
|
||||
/*
|
||||
* mieq.c
|
||||
*
|
||||
* Machine independent event queue
|
||||
*
|
||||
*/
|
||||
|
||||
# include <nx-X11/X.h>
|
||||
# include <nx-X11/Xmd.h>
|
||||
# include <nx-X11/Xproto.h>
|
||||
# include "misc.h"
|
||||
# include "windowstr.h"
|
||||
# include "pixmapstr.h"
|
||||
# include "inputstr.h"
|
||||
# include "mi.h"
|
||||
# include "scrnintstr.h"
|
||||
|
||||
#ifdef DPMSExtension
|
||||
# include "dpmsproc.h"
|
||||
# define DPMS_SERVER
|
||||
# include <nx-X11/extensions/dpms.h>
|
||||
#endif
|
||||
|
||||
#define QUEUE_SIZE 256
|
||||
|
||||
typedef struct _Event {
|
||||
xEvent event;
|
||||
ScreenPtr pScreen;
|
||||
} EventRec, *EventPtr;
|
||||
|
||||
typedef struct _EventQueue {
|
||||
HWEventQueueType head, tail; /* long for SetInputCheck */
|
||||
CARD32 lastEventTime; /* to avoid time running backwards */
|
||||
Bool lastMotion;
|
||||
EventRec events[QUEUE_SIZE]; /* static allocation for signals */
|
||||
DevicePtr pKbd, pPtr; /* device pointer, to get funcs */
|
||||
ScreenPtr pEnqueueScreen; /* screen events are being delivered to */
|
||||
ScreenPtr pDequeueScreen; /* screen events are being dispatched to */
|
||||
} EventQueueRec, *EventQueuePtr;
|
||||
|
||||
static EventQueueRec miEventQueue;
|
||||
|
||||
Bool
|
||||
mieqInit (pKbd, pPtr)
|
||||
DevicePtr pKbd, pPtr;
|
||||
{
|
||||
miEventQueue.head = miEventQueue.tail = 0;
|
||||
miEventQueue.lastEventTime = GetTimeInMillis ();
|
||||
miEventQueue.pKbd = pKbd;
|
||||
miEventQueue.pPtr = pPtr;
|
||||
miEventQueue.lastMotion = FALSE;
|
||||
miEventQueue.pEnqueueScreen = screenInfo.screens[0];
|
||||
miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen;
|
||||
SetInputCheck (&miEventQueue.head, &miEventQueue.tail);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be reentrant with ProcessInputEvents. Assumption: mieqEnqueue
|
||||
* will never be interrupted. If this is called from both signal
|
||||
* handlers and regular code, make sure the signal is suspended when
|
||||
* called from regular code.
|
||||
*/
|
||||
|
||||
void
|
||||
mieqEnqueue (e)
|
||||
xEvent *e;
|
||||
{
|
||||
HWEventQueueType oldtail, newtail;
|
||||
Bool isMotion;
|
||||
|
||||
oldtail = miEventQueue.tail;
|
||||
isMotion = e->u.u.type == MotionNotify;
|
||||
if (isMotion && miEventQueue.lastMotion && oldtail != miEventQueue.head)
|
||||
{
|
||||
if (oldtail == 0)
|
||||
oldtail = QUEUE_SIZE;
|
||||
oldtail = oldtail - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
newtail = oldtail + 1;
|
||||
if (newtail == QUEUE_SIZE)
|
||||
newtail = 0;
|
||||
/* Toss events which come in late */
|
||||
if (newtail == miEventQueue.head)
|
||||
return;
|
||||
miEventQueue.tail = newtail;
|
||||
}
|
||||
miEventQueue.lastMotion = isMotion;
|
||||
miEventQueue.events[oldtail].event = *e;
|
||||
/*
|
||||
* Make sure that event times don't go backwards - this
|
||||
* is "unnecessary", but very useful
|
||||
*/
|
||||
if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime &&
|
||||
miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
|
||||
{
|
||||
miEventQueue.events[oldtail].event.u.keyButtonPointer.time =
|
||||
miEventQueue.lastEventTime;
|
||||
}
|
||||
miEventQueue.lastEventTime =
|
||||
miEventQueue.events[oldtail].event.u.keyButtonPointer.time;
|
||||
miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen;
|
||||
}
|
||||
|
||||
void
|
||||
mieqSwitchScreen (pScreen, fromDIX)
|
||||
ScreenPtr pScreen;
|
||||
Bool fromDIX;
|
||||
{
|
||||
miEventQueue.pEnqueueScreen = pScreen;
|
||||
if (fromDIX)
|
||||
miEventQueue.pDequeueScreen = pScreen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this from ProcessInputEvents()
|
||||
*/
|
||||
|
||||
void mieqProcessInputEvents ()
|
||||
{
|
||||
EventRec *e;
|
||||
int x, y;
|
||||
xEvent xe;
|
||||
|
||||
while (miEventQueue.head != miEventQueue.tail)
|
||||
{
|
||||
if (screenIsSaved == SCREEN_SAVER_ON)
|
||||
SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
|
||||
|
||||
#ifdef DPMSExtension
|
||||
else if (DPMSPowerLevel != DPMSModeOn)
|
||||
SetScreenSaverTimer();
|
||||
|
||||
if (DPMSPowerLevel != DPMSModeOn)
|
||||
DPMSSet(DPMSModeOn);
|
||||
#endif
|
||||
|
||||
e = &miEventQueue.events[miEventQueue.head];
|
||||
/*
|
||||
* Assumption - screen switching can only occur on motion events
|
||||
*/
|
||||
if (e->pScreen != miEventQueue.pDequeueScreen)
|
||||
{
|
||||
miEventQueue.pDequeueScreen = e->pScreen;
|
||||
x = e->event.u.keyButtonPointer.rootX;
|
||||
y = e->event.u.keyButtonPointer.rootY;
|
||||
if (miEventQueue.head == QUEUE_SIZE - 1)
|
||||
miEventQueue.head = 0;
|
||||
else
|
||||
++miEventQueue.head;
|
||||
NewCurrentScreen (miEventQueue.pDequeueScreen, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
xe = e->event;
|
||||
if (miEventQueue.head == QUEUE_SIZE - 1)
|
||||
miEventQueue.head = 0;
|
||||
else
|
||||
++miEventQueue.head;
|
||||
switch (xe.u.u.type)
|
||||
{
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
(*miEventQueue.pKbd->processInputProc)
|
||||
(&xe, (DeviceIntPtr)miEventQueue.pKbd, 1);
|
||||
break;
|
||||
default:
|
||||
(*miEventQueue.pPtr->processInputProc)
|
||||
(&xe, (DeviceIntPtr)miEventQueue.pPtr, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
905
nx-X11/programs/Xserver/mi/miexpose.c
Normal file
905
nx-X11/programs/Xserver/mi/miexpose.c
Normal file
@@ -0,0 +1,905 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/*****************************************************************
|
||||
|
||||
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software.
|
||||
|
||||
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
|
||||
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
|
||||
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
|
||||
shall not be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Software without prior written authorization from Digital
|
||||
Equipment Corporation.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xproto.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "regionstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "windowstr.h"
|
||||
#include "pixmap.h"
|
||||
#include "input.h"
|
||||
|
||||
#include "dixstruct.h"
|
||||
#include "mi.h"
|
||||
#include <nx-X11/Xmd.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef PANORAMIX
|
||||
#include "panoramiX.h"
|
||||
#include "panoramiXsrv.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
machine-independent graphics exposure code. any device that uses
|
||||
the region package can call this.
|
||||
*/
|
||||
|
||||
#ifndef RECTLIMIT
|
||||
#define RECTLIMIT 25 /* pick a number, any number > 8 */
|
||||
#endif
|
||||
|
||||
/* miHandleExposures
|
||||
generate a region for exposures for areas that were copied from obscured or
|
||||
non-existent areas to non-obscured areas of the destination. Paint the
|
||||
background for the region, if the destination is a window.
|
||||
|
||||
NOTE:
|
||||
this should generally be called, even if graphicsExposures is false,
|
||||
because this is where bits get recovered from backing store.
|
||||
|
||||
NOTE:
|
||||
added argument 'plane' is used to indicate how exposures from backing
|
||||
store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
|
||||
should be used, else a CopyPlane of the indicated plane will be used. The
|
||||
exposing is done by the backing store's GraphicsExpose function, of course.
|
||||
|
||||
*/
|
||||
|
||||
RegionPtr
|
||||
miHandleExposures(pSrcDrawable, pDstDrawable,
|
||||
pGC, srcx, srcy, width, height, dstx, dsty, plane)
|
||||
register DrawablePtr pSrcDrawable;
|
||||
register DrawablePtr pDstDrawable;
|
||||
GCPtr pGC;
|
||||
int srcx, srcy;
|
||||
int width, height;
|
||||
int dstx, dsty;
|
||||
unsigned long plane;
|
||||
{
|
||||
register ScreenPtr pscr;
|
||||
RegionPtr prgnSrcClip; /* drawable-relative source clip */
|
||||
RegionRec rgnSrcRec;
|
||||
RegionPtr prgnDstClip; /* drawable-relative dest clip */
|
||||
RegionRec rgnDstRec;
|
||||
BoxRec srcBox; /* unclipped source */
|
||||
RegionRec rgnExposed; /* exposed region, calculated source-
|
||||
relative, made dst relative to
|
||||
intersect with visible parts of
|
||||
dest and send events to client,
|
||||
and then screen relative to paint
|
||||
the window background
|
||||
*/
|
||||
WindowPtr pSrcWin;
|
||||
BoxRec expBox = { 0, };
|
||||
Bool extents;
|
||||
|
||||
/* This prevents warning about pscr not being used. */
|
||||
pGC->pScreen = pscr = pGC->pScreen;
|
||||
|
||||
/* avoid work if we can */
|
||||
if (!pGC->graphicsExposures &&
|
||||
(pDstDrawable->type == DRAWABLE_PIXMAP) &&
|
||||
((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
|
||||
(((WindowPtr)pSrcDrawable)->backStorage == NULL)))
|
||||
return NULL;
|
||||
|
||||
srcBox.x1 = srcx;
|
||||
srcBox.y1 = srcy;
|
||||
srcBox.x2 = srcx+width;
|
||||
srcBox.y2 = srcy+height;
|
||||
|
||||
if (pSrcDrawable->type != DRAWABLE_PIXMAP)
|
||||
{
|
||||
BoxRec TsrcBox;
|
||||
|
||||
TsrcBox.x1 = srcx + pSrcDrawable->x;
|
||||
TsrcBox.y1 = srcy + pSrcDrawable->y;
|
||||
TsrcBox.x2 = TsrcBox.x1 + width;
|
||||
TsrcBox.y2 = TsrcBox.y1 + height;
|
||||
pSrcWin = (WindowPtr) pSrcDrawable;
|
||||
if (pGC->subWindowMode == IncludeInferiors)
|
||||
{
|
||||
prgnSrcClip = NotClippedByChildren (pSrcWin);
|
||||
if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN)
|
||||
{
|
||||
RegionDestroy(prgnSrcClip);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN)
|
||||
return NULL;
|
||||
prgnSrcClip = &rgnSrcRec;
|
||||
RegionNull(prgnSrcClip);
|
||||
RegionCopy(prgnSrcClip, &pSrcWin->clipList);
|
||||
}
|
||||
RegionTranslate(prgnSrcClip,
|
||||
-pSrcDrawable->x, -pSrcDrawable->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
BoxRec box;
|
||||
|
||||
if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
|
||||
(srcBox.x2 <= pSrcDrawable->width) &&
|
||||
(srcBox.y2 <= pSrcDrawable->height))
|
||||
return NULL;
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pSrcDrawable->width;
|
||||
box.y2 = pSrcDrawable->height;
|
||||
prgnSrcClip = &rgnSrcRec;
|
||||
RegionInit(prgnSrcClip, &box, 1);
|
||||
pSrcWin = (WindowPtr)NULL;
|
||||
}
|
||||
|
||||
if (pDstDrawable == pSrcDrawable)
|
||||
{
|
||||
prgnDstClip = prgnSrcClip;
|
||||
}
|
||||
else if (pDstDrawable->type != DRAWABLE_PIXMAP)
|
||||
{
|
||||
if (pGC->subWindowMode == IncludeInferiors)
|
||||
{
|
||||
prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
|
||||
}
|
||||
else
|
||||
{
|
||||
prgnDstClip = &rgnDstRec;
|
||||
RegionNull(prgnDstClip);
|
||||
RegionCopy(prgnDstClip,
|
||||
&((WindowPtr)pDstDrawable)->clipList);
|
||||
}
|
||||
RegionTranslate(prgnDstClip,
|
||||
-pDstDrawable->x, -pDstDrawable->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
BoxRec box;
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pDstDrawable->width;
|
||||
box.y2 = pDstDrawable->height;
|
||||
prgnDstClip = &rgnDstRec;
|
||||
RegionInit(prgnDstClip, &box, 1);
|
||||
}
|
||||
|
||||
/* drawable-relative source region */
|
||||
RegionInit(&rgnExposed, &srcBox, 1);
|
||||
|
||||
/* now get the hidden parts of the source box*/
|
||||
RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip);
|
||||
|
||||
if (pSrcWin && pSrcWin->backStorage)
|
||||
{
|
||||
/*
|
||||
* Copy any areas from the source backing store. Modifies
|
||||
* rgnExposed.
|
||||
*/
|
||||
(* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
|
||||
pDstDrawable,
|
||||
pGC,
|
||||
&rgnExposed,
|
||||
srcx, srcy,
|
||||
dstx, dsty,
|
||||
plane);
|
||||
}
|
||||
|
||||
/* move them over the destination */
|
||||
RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy);
|
||||
|
||||
/* intersect with visible areas of dest */
|
||||
RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip);
|
||||
|
||||
/*
|
||||
* If we have LOTS of rectangles, we decide to take the extents
|
||||
* and force an exposure on that. This should require much less
|
||||
* work overall, on both client and server. This is cheating, but
|
||||
* isn't prohibited by the protocol ("spontaneous combustion" :-)
|
||||
* for windows.
|
||||
*/
|
||||
extents = pGC->graphicsExposures &&
|
||||
(RegionNumRects(&rgnExposed) > RECTLIMIT) &&
|
||||
(pDstDrawable->type != DRAWABLE_PIXMAP);
|
||||
#ifdef SHAPE
|
||||
if (pSrcWin)
|
||||
{
|
||||
RegionPtr region;
|
||||
if (!(region = wClipShape (pSrcWin)))
|
||||
region = wBoundingShape (pSrcWin);
|
||||
/*
|
||||
* If you try to CopyArea the extents of a shaped window, compacting the
|
||||
* exposed region will undo all our work!
|
||||
*/
|
||||
if (extents && pSrcWin && region &&
|
||||
(RegionContainsRect(region, &srcBox) != rgnIN))
|
||||
extents = FALSE;
|
||||
}
|
||||
#endif
|
||||
if (extents)
|
||||
{
|
||||
WindowPtr pWin = (WindowPtr)pDstDrawable;
|
||||
|
||||
expBox = *RegionExtents(&rgnExposed);
|
||||
RegionReset(&rgnExposed, &expBox);
|
||||
/* need to clear out new areas of backing store */
|
||||
if (pWin->backStorage)
|
||||
(void) (* pWin->drawable.pScreen->ClearBackingStore)(
|
||||
pWin,
|
||||
expBox.x1,
|
||||
expBox.y1,
|
||||
expBox.x2 - expBox.x1,
|
||||
expBox.y2 - expBox.y1,
|
||||
FALSE);
|
||||
}
|
||||
if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
|
||||
(((WindowPtr)pDstDrawable)->backgroundState != None))
|
||||
{
|
||||
WindowPtr pWin = (WindowPtr)pDstDrawable;
|
||||
|
||||
/* make the exposed area screen-relative */
|
||||
RegionTranslate(&rgnExposed,
|
||||
pDstDrawable->x, pDstDrawable->y);
|
||||
|
||||
if (extents)
|
||||
{
|
||||
/* PaintWindowBackground doesn't clip, so we have to */
|
||||
RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
|
||||
}
|
||||
(*pWin->drawable.pScreen->PaintWindowBackground)(
|
||||
(WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
|
||||
|
||||
if (extents)
|
||||
{
|
||||
RegionReset(&rgnExposed, &expBox);
|
||||
}
|
||||
else
|
||||
RegionTranslate(&rgnExposed,
|
||||
-pDstDrawable->x, -pDstDrawable->y);
|
||||
}
|
||||
if (prgnDstClip == &rgnDstRec)
|
||||
{
|
||||
RegionUninit(prgnDstClip);
|
||||
}
|
||||
else if (prgnDstClip != prgnSrcClip)
|
||||
{
|
||||
RegionDestroy(prgnDstClip);
|
||||
}
|
||||
|
||||
if (prgnSrcClip == &rgnSrcRec)
|
||||
{
|
||||
RegionUninit(prgnSrcClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
RegionDestroy(prgnSrcClip);
|
||||
}
|
||||
|
||||
if (pGC->graphicsExposures)
|
||||
{
|
||||
/* don't look */
|
||||
RegionPtr exposed = RegionCreate(NullBox, 0);
|
||||
*exposed = rgnExposed;
|
||||
return exposed;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegionUninit(&rgnExposed);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* send GraphicsExpose events, or a NoExpose event, based on the region */
|
||||
|
||||
void
|
||||
miSendGraphicsExpose (client, pRgn, drawable, major, minor)
|
||||
ClientPtr client;
|
||||
RegionPtr pRgn;
|
||||
XID drawable;
|
||||
int major;
|
||||
int minor;
|
||||
{
|
||||
if (pRgn && !RegionNil(pRgn))
|
||||
{
|
||||
xEvent *pEvent;
|
||||
register xEvent *pe;
|
||||
register BoxPtr pBox;
|
||||
register int i;
|
||||
int numRects;
|
||||
|
||||
numRects = RegionNumRects(pRgn);
|
||||
pBox = RegionRects(pRgn);
|
||||
if(!(pEvent = (xEvent *)calloc(numRects, sizeof(xEvent))))
|
||||
return;
|
||||
pe = pEvent;
|
||||
|
||||
for (i=1; i<=numRects; i++, pe++, pBox++)
|
||||
{
|
||||
pe->u.u.type = GraphicsExpose;
|
||||
pe->u.graphicsExposure.drawable = drawable;
|
||||
pe->u.graphicsExposure.x = pBox->x1;
|
||||
pe->u.graphicsExposure.y = pBox->y1;
|
||||
pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
|
||||
pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
|
||||
pe->u.graphicsExposure.count = numRects - i;
|
||||
pe->u.graphicsExposure.majorEvent = major;
|
||||
pe->u.graphicsExposure.minorEvent = minor;
|
||||
}
|
||||
TryClientEvents(client, pEvent, numRects,
|
||||
(Mask)0, NoEventMask, NullGrab);
|
||||
free(pEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
xEvent event = {0};
|
||||
event.u.u.type = NoExpose;
|
||||
event.u.noExposure.drawable = drawable;
|
||||
event.u.noExposure.majorEvent = major;
|
||||
event.u.noExposure.minorEvent = minor;
|
||||
TryClientEvents(client, &event, 1,
|
||||
(Mask)0, NoEventMask, NullGrab);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
miSendExposures(pWin, pRgn, dx, dy)
|
||||
WindowPtr pWin;
|
||||
RegionPtr pRgn;
|
||||
register int dx, dy;
|
||||
{
|
||||
register BoxPtr pBox;
|
||||
int numRects;
|
||||
register xEvent *pEvent, *pe;
|
||||
register int i;
|
||||
|
||||
pBox = RegionRects(pRgn);
|
||||
numRects = RegionNumRects(pRgn);
|
||||
if(!(pEvent = (xEvent *) calloc(numRects, sizeof(xEvent))))
|
||||
return;
|
||||
|
||||
for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
|
||||
{
|
||||
pe->u.u.type = Expose;
|
||||
pe->u.expose.window = pWin->drawable.id;
|
||||
pe->u.expose.x = pBox->x1 - dx;
|
||||
pe->u.expose.y = pBox->y1 - dy;
|
||||
pe->u.expose.width = pBox->x2 - pBox->x1;
|
||||
pe->u.expose.height = pBox->y2 - pBox->y1;
|
||||
pe->u.expose.count = i;
|
||||
}
|
||||
|
||||
#ifdef PANORAMIX
|
||||
if(!noPanoramiXExtension) {
|
||||
int scrnum = pWin->drawable.pScreen->myNum;
|
||||
int x = 0, y = 0;
|
||||
XID realWin = 0;
|
||||
|
||||
if(!pWin->parent) {
|
||||
x = panoramiXdataPtr[scrnum].x;
|
||||
y = panoramiXdataPtr[scrnum].y;
|
||||
pWin = screenInfo.screens[0]->root;
|
||||
realWin = pWin->drawable.id;
|
||||
} else if (scrnum) {
|
||||
PanoramiXRes *win;
|
||||
win = PanoramiXFindIDByScrnum(XRT_WINDOW,
|
||||
pWin->drawable.id, scrnum);
|
||||
if(!win) {
|
||||
free(pEvent);
|
||||
return;
|
||||
}
|
||||
realWin = win->info[0].id;
|
||||
pWin = LookupIDByType(realWin, RT_WINDOW);
|
||||
}
|
||||
if(x || y || scrnum)
|
||||
for (i = 0; i < numRects; i++) {
|
||||
pEvent[i].u.expose.window = realWin;
|
||||
pEvent[i].u.expose.x += x;
|
||||
pEvent[i].u.expose.y += y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
DeliverEvents(pWin, pEvent, numRects, NullWindow);
|
||||
|
||||
free(pEvent);
|
||||
}
|
||||
|
||||
void
|
||||
miWindowExposures(pWin, prgn, other_exposed)
|
||||
WindowPtr pWin;
|
||||
register RegionPtr prgn, other_exposed;
|
||||
{
|
||||
RegionPtr exposures = prgn;
|
||||
if (pWin->backStorage && prgn)
|
||||
/*
|
||||
* in some cases, backing store will cause a different
|
||||
* region to be exposed than needs to be repainted
|
||||
* (like when a window is mapped). RestoreAreas is
|
||||
* allowed to return a region other than prgn,
|
||||
* in which case this routine will free the resultant
|
||||
* region. If exposures is null, then no events will
|
||||
* be sent to the client; if prgn is empty
|
||||
* no areas will be repainted.
|
||||
*/
|
||||
exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
|
||||
if ((prgn && !RegionNil(prgn)) ||
|
||||
(exposures && !RegionNil(exposures)) || other_exposed)
|
||||
{
|
||||
RegionRec expRec;
|
||||
int clientInterested;
|
||||
|
||||
/*
|
||||
* Restore from backing-store FIRST.
|
||||
*/
|
||||
clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
|
||||
if (other_exposed)
|
||||
{
|
||||
if (exposures)
|
||||
{
|
||||
RegionUnion(other_exposed,
|
||||
exposures,
|
||||
other_exposed);
|
||||
if (exposures != prgn)
|
||||
RegionDestroy(exposures);
|
||||
}
|
||||
exposures = other_exposed;
|
||||
}
|
||||
if (clientInterested && exposures && (RegionNumRects(exposures) > RECTLIMIT))
|
||||
{
|
||||
/*
|
||||
* If we have LOTS of rectangles, we decide to take the extents
|
||||
* and force an exposure on that. This should require much less
|
||||
* work overall, on both client and server. This is cheating, but
|
||||
* isn't prohibited by the protocol ("spontaneous combustion" :-).
|
||||
*/
|
||||
BoxRec box;
|
||||
|
||||
box = *RegionExtents(exposures);
|
||||
if (exposures == prgn) {
|
||||
exposures = &expRec;
|
||||
RegionInit(exposures, &box, 1);
|
||||
RegionReset(prgn, &box);
|
||||
} else {
|
||||
RegionReset(exposures, &box);
|
||||
RegionUnion(prgn, prgn, exposures);
|
||||
}
|
||||
/* PaintWindowBackground doesn't clip, so we have to */
|
||||
RegionIntersect(prgn, prgn, &pWin->clipList);
|
||||
/* need to clear out new areas of backing store, too */
|
||||
if (pWin->backStorage)
|
||||
(void) (* pWin->drawable.pScreen->ClearBackingStore)(
|
||||
pWin,
|
||||
box.x1 - pWin->drawable.x,
|
||||
box.y1 - pWin->drawable.y,
|
||||
box.x2 - box.x1,
|
||||
box.y2 - box.y1,
|
||||
FALSE);
|
||||
}
|
||||
if (prgn && !RegionNil(prgn))
|
||||
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
|
||||
if (clientInterested && exposures && !RegionNil(exposures))
|
||||
miSendExposures(pWin, exposures,
|
||||
pWin->drawable.x, pWin->drawable.y);
|
||||
if (exposures == &expRec)
|
||||
{
|
||||
RegionUninit(exposures);
|
||||
}
|
||||
else if (exposures && exposures != prgn && exposures != other_exposed)
|
||||
RegionDestroy(exposures);
|
||||
if (prgn)
|
||||
RegionEmpty(prgn);
|
||||
}
|
||||
else if (exposures && exposures != prgn)
|
||||
RegionDestroy(exposures);
|
||||
}
|
||||
|
||||
/*
|
||||
this code is highly unlikely. it is not haile selassie.
|
||||
|
||||
there is some hair here. we can't just use the window's
|
||||
clip region as it is, because if we are painting the border,
|
||||
the border is not in the client area and so we will be excluded
|
||||
when we validate the GC, and if we are painting a parent-relative
|
||||
background, the area we want to paint is in some other window.
|
||||
since we trust the code calling us to tell us to paint only areas
|
||||
that are really ours, we will temporarily give the window a
|
||||
clipList the size of the whole screen and an origin at (0,0).
|
||||
this more or less assumes that ddX code will do translation
|
||||
based on the window's absolute position, and that ValidateGC will
|
||||
look at clipList, and that no other fields from the
|
||||
window will be used. it's not possible to just draw
|
||||
in the root because it may be a different depth.
|
||||
|
||||
to get the tile to align correctly we set the GC's tile origin to
|
||||
be the (x,y) of the window's upper left corner, after which we
|
||||
get the right bits when drawing into the root.
|
||||
|
||||
because the clip_mask is being set to None, we may call DoChangeGC with
|
||||
fPointer set true, thus we no longer need to install the background or
|
||||
border tile in the resource table.
|
||||
*/
|
||||
|
||||
static RESTYPE ResType = 0;
|
||||
static int numGCs = 0;
|
||||
static GCPtr screenContext[MAXSCREENS];
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
tossGC (
|
||||
void * value,
|
||||
XID id)
|
||||
{
|
||||
GCPtr pGC = (GCPtr)value;
|
||||
screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
|
||||
FreeGC (pGC, id);
|
||||
numGCs--;
|
||||
if (!numGCs)
|
||||
ResType = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
miPaintWindow(pWin, prgn, what)
|
||||
register WindowPtr pWin;
|
||||
RegionPtr prgn;
|
||||
int what;
|
||||
{
|
||||
int status;
|
||||
|
||||
Bool usingScratchGC = FALSE;
|
||||
WindowPtr pRoot;
|
||||
|
||||
#define FUNCTION 0
|
||||
#define FOREGROUND 1
|
||||
#define TILE 2
|
||||
#define FILLSTYLE 3
|
||||
#define ABSX 4
|
||||
#define ABSY 5
|
||||
#define CLIPMASK 6
|
||||
#define SUBWINDOW 7
|
||||
#define COUNT_BITS 8
|
||||
|
||||
ChangeGCVal gcval[7];
|
||||
ChangeGCVal newValues [COUNT_BITS] = {{ 0 }};
|
||||
|
||||
BITS32 gcmask, index, mask;
|
||||
RegionRec prgnWin = {0};
|
||||
DDXPointRec oldCorner = {0};
|
||||
BoxRec box = {0};
|
||||
WindowPtr pBgWin;
|
||||
GCPtr pGC;
|
||||
register int i;
|
||||
register BoxPtr pbox;
|
||||
register ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
register xRectangle *prect;
|
||||
int numRects;
|
||||
|
||||
gcmask = 0;
|
||||
|
||||
if (what == PW_BACKGROUND)
|
||||
{
|
||||
switch (pWin->backgroundState) {
|
||||
case None:
|
||||
return;
|
||||
case ParentRelative:
|
||||
(*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
|
||||
return;
|
||||
case BackgroundPixel:
|
||||
newValues[FOREGROUND].val = pWin->background.pixel;
|
||||
newValues[FILLSTYLE].val = FillSolid;
|
||||
gcmask |= GCForeground | GCFillStyle;
|
||||
break;
|
||||
case BackgroundPixmap:
|
||||
newValues[TILE].ptr = (void *)pWin->background.pixmap;
|
||||
newValues[FILLSTYLE].val = FillTiled;
|
||||
gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pWin->borderIsPixel)
|
||||
{
|
||||
newValues[FOREGROUND].val = pWin->border.pixel;
|
||||
newValues[FILLSTYLE].val = FillSolid;
|
||||
gcmask |= GCForeground | GCFillStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValues[TILE].ptr = (void *)pWin->border.pixmap;
|
||||
newValues[FILLSTYLE].val = FillTiled;
|
||||
gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
|
||||
}
|
||||
}
|
||||
|
||||
prect = (xRectangle *)calloc(RegionNumRects(prgn), sizeof(xRectangle));
|
||||
if (!prect)
|
||||
return;
|
||||
|
||||
newValues[FUNCTION].val = GXcopy;
|
||||
gcmask |= GCFunction | GCClipMask;
|
||||
|
||||
i = pScreen->myNum;
|
||||
pRoot = screenInfo.screens[i]->root;
|
||||
|
||||
pBgWin = pWin;
|
||||
if (what == PW_BORDER)
|
||||
{
|
||||
while (pBgWin->backgroundState == ParentRelative)
|
||||
pBgWin = pBgWin->parent;
|
||||
}
|
||||
|
||||
if ((pWin->drawable.depth != pRoot->drawable.depth) ||
|
||||
(pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
|
||||
{
|
||||
usingScratchGC = TRUE;
|
||||
pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
|
||||
if (!pGC)
|
||||
{
|
||||
free(prect);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* mash the clip list so we can paint the border by
|
||||
* mangling the window in place, pretending it
|
||||
* spans the entire screen
|
||||
*/
|
||||
if (what == PW_BORDER)
|
||||
{
|
||||
prgnWin = pWin->clipList;
|
||||
oldCorner.x = pWin->drawable.x;
|
||||
oldCorner.y = pWin->drawable.y;
|
||||
pWin->drawable.x = pWin->drawable.y = 0;
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
box.y2 = pScreen->height;
|
||||
RegionInit(&pWin->clipList, &box, 1);
|
||||
pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
newValues[ABSX].val = pBgWin->drawable.x;
|
||||
newValues[ABSY].val = pBgWin->drawable.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValues[ABSX].val = 0;
|
||||
newValues[ABSY].val = 0;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* draw the background to the root window
|
||||
*/
|
||||
if (screenContext[i] == (GCPtr)NULL)
|
||||
{
|
||||
if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
|
||||
{
|
||||
free(prect);
|
||||
return;
|
||||
}
|
||||
screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
|
||||
(XID *)NULL, &status);
|
||||
if (!screenContext[i])
|
||||
{
|
||||
free(prect);
|
||||
return;
|
||||
}
|
||||
numGCs++;
|
||||
if (!AddResource(FakeClientID(0), ResType,
|
||||
(void *)screenContext[i]))
|
||||
{
|
||||
free(prect);
|
||||
return;
|
||||
}
|
||||
}
|
||||
pGC = screenContext[i];
|
||||
newValues[SUBWINDOW].val = IncludeInferiors;
|
||||
newValues[ABSX].val = pBgWin->drawable.x;
|
||||
newValues[ABSY].val = pBgWin->drawable.y;
|
||||
gcmask |= GCSubwindowMode;
|
||||
pWin = pRoot;
|
||||
}
|
||||
|
||||
if (pWin->backStorage)
|
||||
(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
|
||||
|
||||
mask = gcmask;
|
||||
gcmask = 0;
|
||||
i = 0;
|
||||
while (mask) {
|
||||
index = lowbit (mask);
|
||||
mask &= ~index;
|
||||
switch (index) {
|
||||
case GCFunction:
|
||||
if (pGC->alu != newValues[FUNCTION].val) {
|
||||
gcmask |= index;
|
||||
gcval[i++].val = newValues[FUNCTION].val;
|
||||
}
|
||||
break;
|
||||
case GCTileStipXOrigin:
|
||||
if ( pGC->patOrg.x != newValues[ABSX].val) {
|
||||
gcmask |= index;
|
||||
gcval[i++].val = newValues[ABSX].val;
|
||||
}
|
||||
break;
|
||||
case GCTileStipYOrigin:
|
||||
if ( pGC->patOrg.y != newValues[ABSY].val) {
|
||||
gcmask |= index;
|
||||
gcval[i++].val = newValues[ABSY].val;
|
||||
}
|
||||
break;
|
||||
case GCClipMask:
|
||||
if ( pGC->clientClipType != CT_NONE) {
|
||||
gcmask |= index;
|
||||
gcval[i++].val = CT_NONE;
|
||||
}
|
||||
break;
|
||||
case GCSubwindowMode:
|
||||
if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
|
||||
gcmask |= index;
|
||||
gcval[i++].val = newValues[SUBWINDOW].val;
|
||||
}
|
||||
break;
|
||||
case GCTile:
|
||||
if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
|
||||
{
|
||||
gcmask |= index;
|
||||
gcval[i++].ptr = newValues[TILE].ptr;
|
||||
}
|
||||
break;
|
||||
case GCFillStyle:
|
||||
if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
|
||||
gcmask |= index;
|
||||
gcval[i++].val = newValues[FILLSTYLE].val;
|
||||
}
|
||||
break;
|
||||
case GCForeground:
|
||||
if ( pGC->fgPixel != newValues[FOREGROUND].val) {
|
||||
gcmask |= index;
|
||||
gcval[i++].val = newValues[FOREGROUND].val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gcmask)
|
||||
dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
|
||||
|
||||
if (pWin->drawable.serialNumber != pGC->serialNumber)
|
||||
ValidateGC((DrawablePtr)pWin, pGC);
|
||||
|
||||
numRects = RegionNumRects(prgn);
|
||||
pbox = RegionRects(prgn);
|
||||
for (i= numRects; --i >= 0; pbox++, prect++)
|
||||
{
|
||||
prect->x = pbox->x1 - pWin->drawable.x;
|
||||
prect->y = pbox->y1 - pWin->drawable.y;
|
||||
prect->width = pbox->x2 - pbox->x1;
|
||||
prect->height = pbox->y2 - pbox->y1;
|
||||
}
|
||||
prect -= numRects;
|
||||
(*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
|
||||
free(prect);
|
||||
|
||||
if (pWin->backStorage)
|
||||
(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
|
||||
|
||||
if (usingScratchGC)
|
||||
{
|
||||
if (what == PW_BORDER)
|
||||
{
|
||||
RegionUninit(&pWin->clipList);
|
||||
pWin->clipList = prgnWin;
|
||||
pWin->drawable.x = oldCorner.x;
|
||||
pWin->drawable.y = oldCorner.y;
|
||||
pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
FreeScratchGC(pGC);
|
||||
}
|
||||
}
|
||||
|
||||
/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
|
||||
* the GC. Useful when we have a scratch drawable and need to initialize
|
||||
* it. */
|
||||
void
|
||||
miClearDrawable(pDraw, pGC)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
{
|
||||
XID fg = pGC->fgPixel;
|
||||
XID bg = pGC->bgPixel;
|
||||
xRectangle rect = {0};
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = pDraw->width;
|
||||
rect.height = pDraw->height;
|
||||
DoChangeGC(pGC, GCForeground, &bg, 0);
|
||||
ValidateGC(pDraw, pGC);
|
||||
(*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
|
||||
DoChangeGC(pGC, GCForeground, &fg, 0);
|
||||
ValidateGC(pDraw, pGC);
|
||||
}
|
||||
815
nx-X11/programs/Xserver/mi/mifillarc.c
Normal file
815
nx-X11/programs/Xserver/mi/mifillarc.c
Normal file
@@ -0,0 +1,815 @@
|
||||
/************************************************************
|
||||
|
||||
Copyright 1989, 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.
|
||||
|
||||
Author: Bob Scheifler, MIT X Consortium
|
||||
|
||||
********************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
#include "regionstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "mifpoly.h"
|
||||
#include "mi.h"
|
||||
#include "mifillarc.h"
|
||||
|
||||
#define QUADRANT (90 * 64)
|
||||
#define HALFCIRCLE (180 * 64)
|
||||
#define QUADRANT3 (270 * 64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define Dsin(d) sin((double)d*(M_PI/11520.0))
|
||||
#define Dcos(d) cos((double)d*(M_PI/11520.0))
|
||||
|
||||
void
|
||||
miFillArcSetup(arc, info)
|
||||
register xArc *arc;
|
||||
register miFillArcRec *info;
|
||||
{
|
||||
info->y = arc->height >> 1;
|
||||
info->dy = arc->height & 1;
|
||||
info->yorg = arc->y + info->y;
|
||||
info->dx = arc->width & 1;
|
||||
info->xorg = arc->x + (arc->width >> 1) + info->dx;
|
||||
info->dx = 1 - info->dx;
|
||||
if (arc->width == arc->height)
|
||||
{
|
||||
/* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */
|
||||
/* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
|
||||
info->ym = 8;
|
||||
info->xm = 8;
|
||||
info->yk = info->y << 3;
|
||||
if (!info->dx)
|
||||
{
|
||||
info->xk = 0;
|
||||
info->e = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->y++;
|
||||
info->yk += 4;
|
||||
info->xk = -4;
|
||||
info->e = - (info->y << 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
|
||||
/* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
|
||||
info->ym = (arc->width * arc->width) << 3;
|
||||
info->xm = (arc->height * arc->height) << 3;
|
||||
info->yk = info->y * info->ym;
|
||||
if (!info->dy)
|
||||
info->yk -= info->ym >> 1;
|
||||
if (!info->dx)
|
||||
{
|
||||
info->xk = 0;
|
||||
info->e = - (info->xm >> 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->y++;
|
||||
info->yk += info->ym;
|
||||
info->xk = -(info->xm >> 1);
|
||||
info->e = info->xk - info->yk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
miFillArcDSetup(arc, info)
|
||||
register xArc *arc;
|
||||
register miFillArcDRec *info;
|
||||
{
|
||||
/* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
|
||||
/* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
|
||||
info->y = arc->height >> 1;
|
||||
info->dy = arc->height & 1;
|
||||
info->yorg = arc->y + info->y;
|
||||
info->dx = arc->width & 1;
|
||||
info->xorg = arc->x + (arc->width >> 1) + info->dx;
|
||||
info->dx = 1 - info->dx;
|
||||
info->ym = ((double)arc->width) * (arc->width * 8);
|
||||
info->xm = ((double)arc->height) * (arc->height * 8);
|
||||
info->yk = info->y * info->ym;
|
||||
if (!info->dy)
|
||||
info->yk -= info->ym / 2.0;
|
||||
if (!info->dx)
|
||||
{
|
||||
info->xk = 0;
|
||||
info->e = - (info->xm / 8.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->y++;
|
||||
info->yk += info->ym;
|
||||
info->xk = -info->xm / 2.0;
|
||||
info->e = info->xk - info->yk;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
miGetArcEdge(
|
||||
register xArc *arc,
|
||||
register miSliceEdgePtr edge,
|
||||
int k,
|
||||
Bool top,
|
||||
Bool left )
|
||||
{
|
||||
register int xady, y;
|
||||
|
||||
y = arc->height >> 1;
|
||||
if (!(arc->width & 1))
|
||||
y++;
|
||||
if (!top)
|
||||
{
|
||||
y = -y;
|
||||
if (arc->height & 1)
|
||||
y--;
|
||||
}
|
||||
xady = k + y * edge->dx;
|
||||
if (xady <= 0)
|
||||
edge->x = - ((-xady) / edge->dy + 1);
|
||||
else
|
||||
edge->x = (xady - 1) / edge->dy;
|
||||
edge->e = xady - edge->x * edge->dy;
|
||||
if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0)))
|
||||
edge->e = edge->dy - edge->e + 1;
|
||||
if (left)
|
||||
edge->x++;
|
||||
edge->x += arc->x + (arc->width >> 1);
|
||||
if (edge->dx > 0)
|
||||
{
|
||||
edge->deltax = 1;
|
||||
edge->stepx = edge->dx / edge->dy;
|
||||
edge->dx = edge->dx % edge->dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge->deltax = -1;
|
||||
edge->stepx = - ((-edge->dx) / edge->dy);
|
||||
edge->dx = (-edge->dx) % edge->dy;
|
||||
}
|
||||
if (!top)
|
||||
{
|
||||
edge->deltax = -edge->deltax;
|
||||
edge->stepx = -edge->stepx;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
miEllipseAngleToSlope (angle, width, height, dxp, dyp, d_dxp, d_dyp)
|
||||
int angle;
|
||||
int width;
|
||||
int height;
|
||||
int *dxp;
|
||||
int *dyp;
|
||||
double *d_dxp;
|
||||
double *d_dyp;
|
||||
{
|
||||
int dx, dy;
|
||||
double d_dx, d_dy, scale;
|
||||
Bool negative_dx, negative_dy;
|
||||
|
||||
switch (angle) {
|
||||
case 0:
|
||||
*dxp = -1;
|
||||
*dyp = 0;
|
||||
if (d_dxp) {
|
||||
*d_dxp = width / 2.0;
|
||||
*d_dyp = 0;
|
||||
}
|
||||
break;
|
||||
case QUADRANT:
|
||||
*dxp = 0;
|
||||
*dyp = 1;
|
||||
if (d_dxp) {
|
||||
*d_dxp = 0;
|
||||
*d_dyp = - height / 2.0;
|
||||
}
|
||||
break;
|
||||
case HALFCIRCLE:
|
||||
*dxp = 1;
|
||||
*dyp = 0;
|
||||
if (d_dxp) {
|
||||
*d_dxp = - width / 2.0;
|
||||
*d_dyp = 0;
|
||||
}
|
||||
break;
|
||||
case QUADRANT3:
|
||||
*dxp = 0;
|
||||
*dyp = -1;
|
||||
if (d_dxp) {
|
||||
*d_dxp = 0;
|
||||
*d_dyp = height / 2.0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
d_dx = Dcos(angle) * width;
|
||||
d_dy = Dsin(angle) * height;
|
||||
if (d_dxp) {
|
||||
*d_dxp = d_dx / 2.0;
|
||||
*d_dyp = - d_dy / 2.0;
|
||||
}
|
||||
negative_dx = FALSE;
|
||||
if (d_dx < 0.0)
|
||||
{
|
||||
d_dx = -d_dx;
|
||||
negative_dx = TRUE;
|
||||
}
|
||||
negative_dy = FALSE;
|
||||
if (d_dy < 0.0)
|
||||
{
|
||||
d_dy = -d_dy;
|
||||
negative_dy = TRUE;
|
||||
}
|
||||
scale = d_dx;
|
||||
if (d_dy > d_dx)
|
||||
scale = d_dy;
|
||||
dx = floor ((d_dx * 32768) / scale + 0.5);
|
||||
if (negative_dx)
|
||||
dx = -dx;
|
||||
*dxp = dx;
|
||||
dy = floor ((d_dy * 32768) / scale + 0.5);
|
||||
if (negative_dy)
|
||||
dy = -dy;
|
||||
*dyp = dy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
miGetPieEdge(
|
||||
register xArc *arc,
|
||||
register int angle,
|
||||
register miSliceEdgePtr edge,
|
||||
Bool top,
|
||||
Bool left )
|
||||
{
|
||||
register int k;
|
||||
int dx, dy;
|
||||
|
||||
miEllipseAngleToSlope (angle, arc->width, arc->height, &dx, &dy, 0, 0);
|
||||
|
||||
if (dy == 0)
|
||||
{
|
||||
edge->x = left ? -65536 : 65536;
|
||||
edge->stepx = 0;
|
||||
edge->e = 0;
|
||||
edge->dx = -1;
|
||||
return;
|
||||
}
|
||||
if (dx == 0)
|
||||
{
|
||||
edge->x = arc->x + (arc->width >> 1);
|
||||
if (left && (arc->width & 1))
|
||||
edge->x++;
|
||||
else if (!left && !(arc->width & 1))
|
||||
edge->x--;
|
||||
edge->stepx = 0;
|
||||
edge->e = 0;
|
||||
edge->dx = -1;
|
||||
return;
|
||||
}
|
||||
if (dy < 0) {
|
||||
dx = -dx;
|
||||
dy = -dy;
|
||||
}
|
||||
k = (arc->height & 1) ? dx : 0;
|
||||
if (arc->width & 1)
|
||||
k += dy;
|
||||
edge->dx = dx << 1;
|
||||
edge->dy = dy << 1;
|
||||
miGetArcEdge(arc, edge, k, top, left);
|
||||
}
|
||||
|
||||
void
|
||||
miFillArcSliceSetup(arc, slice, pGC)
|
||||
register xArc *arc;
|
||||
register miArcSliceRec *slice;
|
||||
GCPtr pGC;
|
||||
{
|
||||
register int angle1, angle2;
|
||||
|
||||
angle1 = arc->angle1;
|
||||
if (arc->angle2 < 0)
|
||||
{
|
||||
angle2 = angle1;
|
||||
angle1 += arc->angle2;
|
||||
}
|
||||
else
|
||||
angle2 = angle1 + arc->angle2;
|
||||
while (angle1 < 0)
|
||||
angle1 += FULLCIRCLE;
|
||||
while (angle1 >= FULLCIRCLE)
|
||||
angle1 -= FULLCIRCLE;
|
||||
while (angle2 < 0)
|
||||
angle2 += FULLCIRCLE;
|
||||
while (angle2 >= FULLCIRCLE)
|
||||
angle2 -= FULLCIRCLE;
|
||||
slice->min_top_y = 0;
|
||||
slice->max_top_y = arc->height >> 1;
|
||||
slice->min_bot_y = 1 - (arc->height & 1);
|
||||
slice->max_bot_y = slice->max_top_y - 1;
|
||||
slice->flip_top = FALSE;
|
||||
slice->flip_bot = FALSE;
|
||||
if (pGC->arcMode == ArcPieSlice)
|
||||
{
|
||||
slice->edge1_top = (angle1 < HALFCIRCLE);
|
||||
slice->edge2_top = (angle2 <= HALFCIRCLE);
|
||||
if ((angle2 == 0) || (angle1 == HALFCIRCLE))
|
||||
{
|
||||
if (angle2 ? slice->edge2_top : slice->edge1_top)
|
||||
slice->min_top_y = slice->min_bot_y;
|
||||
else
|
||||
slice->min_top_y = arc->height;
|
||||
slice->min_bot_y = 0;
|
||||
}
|
||||
else if ((angle1 == 0) || (angle2 == HALFCIRCLE))
|
||||
{
|
||||
slice->min_top_y = slice->min_bot_y;
|
||||
if (angle1 ? slice->edge1_top : slice->edge2_top)
|
||||
slice->min_bot_y = arc->height;
|
||||
else
|
||||
slice->min_bot_y = 0;
|
||||
}
|
||||
else if (slice->edge1_top == slice->edge2_top)
|
||||
{
|
||||
if (angle2 < angle1)
|
||||
{
|
||||
slice->flip_top = slice->edge1_top;
|
||||
slice->flip_bot = !slice->edge1_top;
|
||||
}
|
||||
else if (slice->edge1_top)
|
||||
{
|
||||
slice->min_top_y = 1;
|
||||
slice->min_bot_y = arc->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
slice->min_bot_y = 0;
|
||||
slice->min_top_y = arc->height;
|
||||
}
|
||||
}
|
||||
miGetPieEdge(arc, angle1, &slice->edge1,
|
||||
slice->edge1_top, !slice->edge1_top);
|
||||
miGetPieEdge(arc, angle2, &slice->edge2,
|
||||
slice->edge2_top, slice->edge2_top);
|
||||
}
|
||||
else
|
||||
{
|
||||
double w2, h2, x1, y1, x2, y2, dx, dy, scale;
|
||||
int signdx, signdy, y, k;
|
||||
Bool isInt1 = TRUE, isInt2 = TRUE;
|
||||
|
||||
w2 = (double)arc->width / 2.0;
|
||||
h2 = (double)arc->height / 2.0;
|
||||
if ((angle1 == 0) || (angle1 == HALFCIRCLE))
|
||||
{
|
||||
x1 = angle1 ? -w2 : w2;
|
||||
y1 = 0.0;
|
||||
}
|
||||
else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3))
|
||||
{
|
||||
x1 = 0.0;
|
||||
y1 = (angle1 == QUADRANT) ? h2 : -h2;
|
||||
}
|
||||
else
|
||||
{
|
||||
isInt1 = FALSE;
|
||||
x1 = Dcos(angle1) * w2;
|
||||
y1 = Dsin(angle1) * h2;
|
||||
}
|
||||
if ((angle2 == 0) || (angle2 == HALFCIRCLE))
|
||||
{
|
||||
x2 = angle2 ? -w2 : w2;
|
||||
y2 = 0.0;
|
||||
}
|
||||
else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3))
|
||||
{
|
||||
x2 = 0.0;
|
||||
y2 = (angle2 == QUADRANT) ? h2 : -h2;
|
||||
}
|
||||
else
|
||||
{
|
||||
isInt2 = FALSE;
|
||||
x2 = Dcos(angle2) * w2;
|
||||
y2 = Dsin(angle2) * h2;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
if (arc->height & 1)
|
||||
{
|
||||
y1 -= 0.5;
|
||||
y2 -= 0.5;
|
||||
}
|
||||
if (arc->width & 1)
|
||||
{
|
||||
x1 += 0.5;
|
||||
x2 += 0.5;
|
||||
}
|
||||
if (dy < 0.0)
|
||||
{
|
||||
dy = -dy;
|
||||
signdy = -1;
|
||||
}
|
||||
else
|
||||
signdy = 1;
|
||||
if (dx < 0.0)
|
||||
{
|
||||
dx = -dx;
|
||||
signdx = -1;
|
||||
}
|
||||
else
|
||||
signdx = 1;
|
||||
if (isInt1 && isInt2)
|
||||
{
|
||||
slice->edge1.dx = dx * 2;
|
||||
slice->edge1.dy = dy * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = (dx > dy) ? dx : dy;
|
||||
slice->edge1.dx = floor((dx * 32768) / scale + .5);
|
||||
slice->edge1.dy = floor((dy * 32768) / scale + .5);
|
||||
}
|
||||
if (!slice->edge1.dy)
|
||||
{
|
||||
if (signdx < 0)
|
||||
{
|
||||
y = floor(y1 + 1.0);
|
||||
if (y >= 0)
|
||||
{
|
||||
slice->min_top_y = y;
|
||||
slice->min_bot_y = arc->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
slice->max_bot_y = -y - (arc->height & 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
y = floor(y1);
|
||||
if (y >= 0)
|
||||
slice->max_top_y = y;
|
||||
else
|
||||
{
|
||||
slice->min_top_y = arc->height;
|
||||
slice->min_bot_y = -y - (arc->height & 1);
|
||||
}
|
||||
}
|
||||
slice->edge1_top = TRUE;
|
||||
slice->edge1.x = 65536;
|
||||
slice->edge1.stepx = 0;
|
||||
slice->edge1.e = 0;
|
||||
slice->edge1.dx = -1;
|
||||
slice->edge2 = slice->edge1;
|
||||
slice->edge2_top = FALSE;
|
||||
}
|
||||
else if (!slice->edge1.dx)
|
||||
{
|
||||
if (signdy < 0)
|
||||
x1 -= 1.0;
|
||||
slice->edge1.x = ceil(x1);
|
||||
slice->edge1_top = signdy < 0;
|
||||
slice->edge1.x += arc->x + (arc->width >> 1);
|
||||
slice->edge1.stepx = 0;
|
||||
slice->edge1.e = 0;
|
||||
slice->edge1.dx = -1;
|
||||
slice->edge2_top = !slice->edge1_top;
|
||||
slice->edge2 = slice->edge1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (signdx < 0)
|
||||
slice->edge1.dx = -slice->edge1.dx;
|
||||
if (signdy < 0)
|
||||
slice->edge1.dx = -slice->edge1.dx;
|
||||
k = ceil(((x1 + x2) * slice->edge1.dy - (y1 + y2) * slice->edge1.dx) / 2.0);
|
||||
slice->edge2.dx = slice->edge1.dx;
|
||||
slice->edge2.dy = slice->edge1.dy;
|
||||
slice->edge1_top = signdy < 0;
|
||||
slice->edge2_top = !slice->edge1_top;
|
||||
miGetArcEdge(arc, &slice->edge1, k,
|
||||
slice->edge1_top, !slice->edge1_top);
|
||||
miGetArcEdge(arc, &slice->edge2, k,
|
||||
slice->edge2_top, slice->edge2_top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ADDSPANS() \
|
||||
pts->x = xorg - x; \
|
||||
pts->y = yorg - y; \
|
||||
*wids = slw; \
|
||||
pts++; \
|
||||
wids++; \
|
||||
if (miFillArcLower(slw)) \
|
||||
{ \
|
||||
pts->x = xorg - x; \
|
||||
pts->y = yorg + y + dy; \
|
||||
pts++; \
|
||||
*wids++ = slw; \
|
||||
}
|
||||
|
||||
static void
|
||||
miFillEllipseI(
|
||||
DrawablePtr pDraw,
|
||||
GCPtr pGC,
|
||||
xArc *arc )
|
||||
{
|
||||
register int x, y, e;
|
||||
int yk, xk, ym, xm, dx, dy, xorg, yorg;
|
||||
int slw;
|
||||
miFillArcRec info;
|
||||
DDXPointPtr points;
|
||||
register DDXPointPtr pts;
|
||||
int *widths;
|
||||
register int *wids;
|
||||
|
||||
points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * arc->height);
|
||||
if (!points)
|
||||
return;
|
||||
widths = (int *)malloc(sizeof(int) * arc->height);
|
||||
if (!widths)
|
||||
{
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
miFillArcSetup(arc, &info);
|
||||
MIFILLARCSETUP();
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
xorg += pDraw->x;
|
||||
yorg += pDraw->y;
|
||||
}
|
||||
pts = points;
|
||||
wids = widths;
|
||||
while (y > 0)
|
||||
{
|
||||
MIFILLARCSTEP(slw);
|
||||
ADDSPANS();
|
||||
}
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
}
|
||||
|
||||
static void
|
||||
miFillEllipseD(
|
||||
DrawablePtr pDraw,
|
||||
GCPtr pGC,
|
||||
xArc *arc )
|
||||
{
|
||||
register int x, y;
|
||||
int xorg, yorg, dx, dy, slw;
|
||||
double e, yk, xk, ym, xm;
|
||||
miFillArcDRec info;
|
||||
DDXPointPtr points;
|
||||
register DDXPointPtr pts;
|
||||
int *widths;
|
||||
register int *wids;
|
||||
|
||||
points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * arc->height);
|
||||
if (!points)
|
||||
return;
|
||||
widths = (int *)malloc(sizeof(int) * arc->height);
|
||||
if (!widths)
|
||||
{
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
miFillArcDSetup(arc, &info);
|
||||
MIFILLARCSETUP();
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
xorg += pDraw->x;
|
||||
yorg += pDraw->y;
|
||||
}
|
||||
pts = points;
|
||||
wids = widths;
|
||||
while (y > 0)
|
||||
{
|
||||
MIFILLARCSTEP(slw);
|
||||
ADDSPANS();
|
||||
}
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
}
|
||||
|
||||
#define ADDSPAN(l,r) \
|
||||
if (r >= l) \
|
||||
{ \
|
||||
pts->x = l; \
|
||||
pts->y = ya; \
|
||||
pts++; \
|
||||
*wids++ = r - l + 1; \
|
||||
}
|
||||
|
||||
#define ADDSLICESPANS(flip) \
|
||||
if (!flip) \
|
||||
{ \
|
||||
ADDSPAN(xl, xr); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
xc = xorg - x; \
|
||||
ADDSPAN(xc, xr); \
|
||||
xc += slw - 1; \
|
||||
ADDSPAN(xl, xc); \
|
||||
}
|
||||
|
||||
static void
|
||||
miFillArcSliceI(
|
||||
DrawablePtr pDraw,
|
||||
GCPtr pGC,
|
||||
xArc *arc )
|
||||
{
|
||||
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
|
||||
register int x, y, e;
|
||||
miFillArcRec info;
|
||||
miArcSliceRec slice;
|
||||
int ya, xl, xr, xc;
|
||||
DDXPointPtr points;
|
||||
register DDXPointPtr pts;
|
||||
int *widths;
|
||||
register int *wids;
|
||||
|
||||
miFillArcSetup(arc, &info);
|
||||
miFillArcSliceSetup(arc, &slice, pGC);
|
||||
MIFILLARCSETUP();
|
||||
slw = arc->height;
|
||||
if (slice.flip_top || slice.flip_bot)
|
||||
slw += (arc->height >> 1) + 1;
|
||||
points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * slw);
|
||||
if (!points)
|
||||
return;
|
||||
widths = (int *)malloc(sizeof(int) * slw);
|
||||
if (!widths)
|
||||
{
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
xorg += pDraw->x;
|
||||
yorg += pDraw->y;
|
||||
slice.edge1.x += pDraw->x;
|
||||
slice.edge2.x += pDraw->x;
|
||||
}
|
||||
pts = points;
|
||||
wids = widths;
|
||||
while (y > 0)
|
||||
{
|
||||
MIFILLARCSTEP(slw);
|
||||
MIARCSLICESTEP(slice.edge1);
|
||||
MIARCSLICESTEP(slice.edge2);
|
||||
if (miFillSliceUpper(slice))
|
||||
{
|
||||
ya = yorg - y;
|
||||
MIARCSLICEUPPER(xl, xr, slice, slw);
|
||||
ADDSLICESPANS(slice.flip_top);
|
||||
}
|
||||
if (miFillSliceLower(slice))
|
||||
{
|
||||
ya = yorg + y + dy;
|
||||
MIARCSLICELOWER(xl, xr, slice, slw);
|
||||
ADDSLICESPANS(slice.flip_bot);
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
}
|
||||
|
||||
static void
|
||||
miFillArcSliceD(
|
||||
DrawablePtr pDraw,
|
||||
GCPtr pGC,
|
||||
xArc *arc )
|
||||
{
|
||||
register int x, y;
|
||||
int dx, dy, xorg, yorg, slw;
|
||||
double e, yk, xk, ym, xm;
|
||||
miFillArcDRec info;
|
||||
miArcSliceRec slice;
|
||||
int ya, xl, xr, xc;
|
||||
DDXPointPtr points;
|
||||
register DDXPointPtr pts;
|
||||
int *widths;
|
||||
register int *wids;
|
||||
|
||||
miFillArcDSetup(arc, &info);
|
||||
miFillArcSliceSetup(arc, &slice, pGC);
|
||||
MIFILLARCSETUP();
|
||||
slw = arc->height;
|
||||
if (slice.flip_top || slice.flip_bot)
|
||||
slw += (arc->height >> 1) + 1;
|
||||
points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * slw);
|
||||
if (!points)
|
||||
return;
|
||||
widths = (int *)malloc(sizeof(int) * slw);
|
||||
if (!widths)
|
||||
{
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
xorg += pDraw->x;
|
||||
yorg += pDraw->y;
|
||||
slice.edge1.x += pDraw->x;
|
||||
slice.edge2.x += pDraw->x;
|
||||
}
|
||||
pts = points;
|
||||
wids = widths;
|
||||
while (y > 0)
|
||||
{
|
||||
MIFILLARCSTEP(slw);
|
||||
MIARCSLICESTEP(slice.edge1);
|
||||
MIARCSLICESTEP(slice.edge2);
|
||||
if (miFillSliceUpper(slice))
|
||||
{
|
||||
ya = yorg - y;
|
||||
MIARCSLICEUPPER(xl, xr, slice, slw);
|
||||
ADDSLICESPANS(slice.flip_top);
|
||||
}
|
||||
if (miFillSliceLower(slice))
|
||||
{
|
||||
ya = yorg + y + dy;
|
||||
MIARCSLICELOWER(xl, xr, slice, slw);
|
||||
ADDSLICESPANS(slice.flip_bot);
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
}
|
||||
|
||||
/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
|
||||
* Since we don't have to worry about overlapping segments, we can just
|
||||
* fill each arc as it comes.
|
||||
*/
|
||||
void
|
||||
miPolyFillArc(pDraw, pGC, narcs, parcs)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int narcs;
|
||||
xArc *parcs;
|
||||
{
|
||||
register int i;
|
||||
register xArc *arc;
|
||||
|
||||
for(i = narcs, arc = parcs; --i >= 0; arc++)
|
||||
{
|
||||
if (miFillArcEmpty(arc))
|
||||
continue;;
|
||||
if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
|
||||
{
|
||||
if (miCanFillArc(arc))
|
||||
miFillEllipseI(pDraw, pGC, arc);
|
||||
else
|
||||
miFillEllipseD(pDraw, pGC, arc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (miCanFillArc(arc))
|
||||
miFillArcSliceI(pDraw, pGC, arc);
|
||||
else
|
||||
miFillArcSliceD(pDraw, pGC, arc);
|
||||
}
|
||||
}
|
||||
}
|
||||
214
nx-X11/programs/Xserver/mi/mifillarc.h
Normal file
214
nx-X11/programs/Xserver/mi/mifillarc.h
Normal file
@@ -0,0 +1,214 @@
|
||||
/************************************************************
|
||||
|
||||
Copyright 1989, 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.
|
||||
|
||||
********************************************************/
|
||||
|
||||
|
||||
#ifndef __MIFILLARC_H__
|
||||
#define __MIFILLARC_H__
|
||||
|
||||
#define FULLCIRCLE (360 * 64)
|
||||
|
||||
typedef struct _miFillArc {
|
||||
int xorg, yorg;
|
||||
int y;
|
||||
int dx, dy;
|
||||
int e;
|
||||
int ym, yk, xm, xk;
|
||||
} miFillArcRec;
|
||||
|
||||
/* could use 64-bit integers */
|
||||
typedef struct _miFillArcD {
|
||||
int xorg, yorg;
|
||||
int y;
|
||||
int dx, dy;
|
||||
double e;
|
||||
double ym, yk, xm, xk;
|
||||
} miFillArcDRec;
|
||||
|
||||
#define miFillArcEmpty(arc) (!(arc)->angle2 || \
|
||||
!(arc)->width || !(arc)->height || \
|
||||
(((arc)->width == 1) && ((arc)->height & 1)))
|
||||
|
||||
#define miCanFillArc(arc) (((arc)->width == (arc)->height) || \
|
||||
(((arc)->width <= 800) && ((arc)->height <= 800)))
|
||||
|
||||
#define MIFILLARCSETUP() \
|
||||
x = 0; \
|
||||
y = info.y; \
|
||||
e = info.e; \
|
||||
xk = info.xk; \
|
||||
xm = info.xm; \
|
||||
yk = info.yk; \
|
||||
ym = info.ym; \
|
||||
dx = info.dx; \
|
||||
dy = info.dy; \
|
||||
xorg = info.xorg; \
|
||||
yorg = info.yorg
|
||||
|
||||
#define MIFILLARCSTEP(slw) \
|
||||
e += yk; \
|
||||
while (e >= 0) \
|
||||
{ \
|
||||
x++; \
|
||||
xk -= xm; \
|
||||
e += xk; \
|
||||
} \
|
||||
y--; \
|
||||
yk -= ym; \
|
||||
slw = (x << 1) + dx; \
|
||||
if ((e == xk) && (slw > 1)) \
|
||||
slw--
|
||||
|
||||
#define MIFILLCIRCSTEP(slw) MIFILLARCSTEP(slw)
|
||||
#define MIFILLELLSTEP(slw) MIFILLARCSTEP(slw)
|
||||
|
||||
#define miFillArcLower(slw) (((y + dy) != 0) && ((slw > 1) || (e != xk)))
|
||||
|
||||
typedef struct _miSliceEdge {
|
||||
int x;
|
||||
int stepx;
|
||||
int deltax;
|
||||
int e;
|
||||
int dy;
|
||||
int dx;
|
||||
} miSliceEdgeRec, *miSliceEdgePtr;
|
||||
|
||||
typedef struct _miArcSlice {
|
||||
miSliceEdgeRec edge1, edge2;
|
||||
int min_top_y, max_top_y;
|
||||
int min_bot_y, max_bot_y;
|
||||
Bool edge1_top, edge2_top;
|
||||
Bool flip_top, flip_bot;
|
||||
} miArcSliceRec;
|
||||
|
||||
#define MIARCSLICESTEP(edge) \
|
||||
edge.x -= edge.stepx; \
|
||||
edge.e -= edge.dx; \
|
||||
if (edge.e <= 0) \
|
||||
{ \
|
||||
edge.x -= edge.deltax; \
|
||||
edge.e += edge.dy; \
|
||||
}
|
||||
|
||||
#define miFillSliceUpper(slice) \
|
||||
((y >= slice.min_top_y) && (y <= slice.max_top_y))
|
||||
|
||||
#define miFillSliceLower(slice) \
|
||||
((y >= slice.min_bot_y) && (y <= slice.max_bot_y))
|
||||
|
||||
#define MIARCSLICEUPPER(xl,xr,slice,slw) \
|
||||
xl = xorg - x; \
|
||||
xr = xl + slw - 1; \
|
||||
if (slice.edge1_top && (slice.edge1.x < xr)) \
|
||||
xr = slice.edge1.x; \
|
||||
if (slice.edge2_top && (slice.edge2.x > xl)) \
|
||||
xl = slice.edge2.x;
|
||||
|
||||
#define MIARCSLICELOWER(xl,xr,slice,slw) \
|
||||
xl = xorg - x; \
|
||||
xr = xl + slw - 1; \
|
||||
if (!slice.edge1_top && (slice.edge1.x > xl)) \
|
||||
xl = slice.edge1.x; \
|
||||
if (!slice.edge2_top && (slice.edge2.x < xr)) \
|
||||
xr = slice.edge2.x;
|
||||
|
||||
#define MIWIDEARCSETUP(x,y,dy,slw,e,xk,xm,yk,ym) \
|
||||
x = 0; \
|
||||
y = slw >> 1; \
|
||||
yk = y << 3; \
|
||||
xm = 8; \
|
||||
ym = 8; \
|
||||
if (dy) \
|
||||
{ \
|
||||
xk = 0; \
|
||||
if (slw & 1) \
|
||||
e = -1; \
|
||||
else \
|
||||
e = -(y << 2) - 2; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
y++; \
|
||||
yk += 4; \
|
||||
xk = -4; \
|
||||
if (slw & 1) \
|
||||
e = -(y << 2) - 3; \
|
||||
else \
|
||||
e = - (y << 3); \
|
||||
}
|
||||
|
||||
#define MIFILLINARCSTEP(slw) \
|
||||
ine += inyk; \
|
||||
while (ine >= 0) \
|
||||
{ \
|
||||
inx++; \
|
||||
inxk -= inxm; \
|
||||
ine += inxk; \
|
||||
} \
|
||||
iny--; \
|
||||
inyk -= inym; \
|
||||
slw = (inx << 1) + dx; \
|
||||
if ((ine == inxk) && (slw > 1)) \
|
||||
slw--
|
||||
|
||||
#define miFillInArcLower(slw) (((iny + dy) != 0) && \
|
||||
((slw > 1) || (ine != inxk)))
|
||||
|
||||
extern int miFreeArcCache(
|
||||
void * /*data*/,
|
||||
XID /*id*/
|
||||
);
|
||||
|
||||
extern struct finalSpan *realAllocSpan(
|
||||
void
|
||||
);
|
||||
|
||||
extern void miFillArcSetup(
|
||||
xArc * /*arc*/,
|
||||
miFillArcRec * /*info*/
|
||||
);
|
||||
|
||||
extern void miFillArcDSetup(
|
||||
xArc * /*arc*/,
|
||||
miFillArcDRec * /*info*/
|
||||
);
|
||||
|
||||
extern void miEllipseAngleToSlope(
|
||||
int /*angle*/,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
int * /*dxp*/,
|
||||
int * /*dyp*/,
|
||||
double * /*d_dxp*/,
|
||||
double * /*d_dyp*/
|
||||
);
|
||||
|
||||
extern void miFillArcSliceSetup(
|
||||
xArc * /*arc*/,
|
||||
miArcSliceRec * /*slice*/,
|
||||
GCPtr /*pGC*/
|
||||
);
|
||||
|
||||
#endif /* __MIFILLARC_H__ */
|
||||
142
nx-X11/programs/Xserver/mi/mifillrct.c
Normal file
142
nx-X11/programs/Xserver/mi/mifillrct.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
#include "gcstruct.h"
|
||||
#include "windowstr.h"
|
||||
#include "pixmap.h"
|
||||
#include "mi.h"
|
||||
#include "misc.h"
|
||||
|
||||
/* mi rectangles
|
||||
written by newman, with debts to all and sundry
|
||||
*/
|
||||
|
||||
/* MIPOLYFILLRECT -- public entry for PolyFillRect request
|
||||
* very straight forward: translate rectangles if necessary
|
||||
* then call FillSpans to fill each rectangle. We let FillSpans worry about
|
||||
* clipping to the destination
|
||||
*/
|
||||
void
|
||||
miPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
|
||||
DrawablePtr pDrawable;
|
||||
GCPtr pGC;
|
||||
int nrectFill; /* number of rectangles to fill */
|
||||
xRectangle *prectInit; /* Pointer to first rectangle to fill */
|
||||
{
|
||||
int i;
|
||||
register int height;
|
||||
register int width;
|
||||
register xRectangle *prect;
|
||||
int xorg;
|
||||
register int yorg;
|
||||
int maxheight;
|
||||
DDXPointPtr pptFirst;
|
||||
register DDXPointPtr ppt;
|
||||
int *pwFirst;
|
||||
register int *pw;
|
||||
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
xorg = pDrawable->x;
|
||||
yorg = pDrawable->y;
|
||||
prect = prectInit;
|
||||
maxheight = 0;
|
||||
for (i = 0; i<nrectFill; i++, prect++)
|
||||
{
|
||||
prect->x += xorg;
|
||||
prect->y += yorg;
|
||||
maxheight = max(maxheight, prect->height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prect = prectInit;
|
||||
maxheight = 0;
|
||||
for (i = 0; i<nrectFill; i++, prect++)
|
||||
maxheight = max(maxheight, prect->height);
|
||||
}
|
||||
|
||||
pptFirst = (DDXPointPtr) malloc(maxheight * sizeof(DDXPointRec));
|
||||
pwFirst = (int *) malloc(maxheight * sizeof(int));
|
||||
if(!pptFirst || !pwFirst)
|
||||
{
|
||||
if (pwFirst) free(pwFirst);
|
||||
if (pptFirst) free(pptFirst);
|
||||
return;
|
||||
}
|
||||
|
||||
prect = prectInit;
|
||||
while(nrectFill--)
|
||||
{
|
||||
ppt = pptFirst;
|
||||
pw = pwFirst;
|
||||
height = prect->height;
|
||||
width = prect->width;
|
||||
xorg = prect->x;
|
||||
yorg = prect->y;
|
||||
while(height--)
|
||||
{
|
||||
*pw++ = width;
|
||||
ppt->x = xorg;
|
||||
ppt->y = yorg;
|
||||
ppt++;
|
||||
yorg++;
|
||||
}
|
||||
(* pGC->ops->FillSpans)(pDrawable, pGC,
|
||||
prect->height, pptFirst, pwFirst,
|
||||
1);
|
||||
prect++;
|
||||
}
|
||||
free(pwFirst);
|
||||
free(pptFirst);
|
||||
}
|
||||
109
nx-X11/programs/Xserver/mi/mifpoly.h
Normal file
109
nx-X11/programs/Xserver/mi/mifpoly.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __MIFPOLY_H__
|
||||
#define __MIFPOLY_H__
|
||||
|
||||
#define EPSILON 0.000001
|
||||
#define ISEQUAL(a,b) (Fabs((a) - (b)) <= EPSILON)
|
||||
#define UNEQUAL(a,b) (Fabs((a) - (b)) > EPSILON)
|
||||
#define WITHINHALF(a, b) (((a) - (b) > 0.0) ? (a) - (b) < 0.5 : \
|
||||
(b) - (a) <= 0.5)
|
||||
#define ROUNDTOINT(x) ((int) (((x) > 0.0) ? ((x) + 0.5) : ((x) - 0.5)))
|
||||
#define ISZERO(x) (Fabs((x)) <= EPSILON)
|
||||
#define PTISEQUAL(a,b) (ISEQUAL(a.x,b.x) && ISEQUAL(a.y,b.y))
|
||||
#define PTUNEQUAL(a,b) (UNEQUAL(a.x,b.x) || UNEQUAL(a.y,b.y))
|
||||
#define PtEqual(a, b) (((a).x == (b).x) && ((a).y == (b).y))
|
||||
|
||||
#define NotEnd 0
|
||||
#define FirstEnd 1
|
||||
#define SecondEnd 2
|
||||
|
||||
#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - for 11o miter cutoff */
|
||||
#define D2SECANT 5.21671526231167 /* 1/2*sin(11/2) - max extension per width */
|
||||
|
||||
#ifdef NOINLINEICEIL
|
||||
#define ICEIL(x) ((int)ceil(x))
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
static __inline int ICEIL(double x)
|
||||
{
|
||||
int _cTmp = x;
|
||||
return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp+1;
|
||||
}
|
||||
#else
|
||||
#define ICEIL(x) ((((x) == (_cTmp = (x))) || ((x) < 0.0)) ? _cTmp : _cTmp+1)
|
||||
#define ICEILTEMPDECL static int _cTmp;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Point with sub-pixel positioning. In this case we use doubles, but
|
||||
* see mifpolycon.c for other suggestions
|
||||
*/
|
||||
typedef struct _SppPoint {
|
||||
double x, y;
|
||||
} SppPointRec, *SppPointPtr;
|
||||
|
||||
typedef struct _SppArc {
|
||||
double x, y, width, height;
|
||||
double angle1, angle2;
|
||||
} SppArcRec, *SppArcPtr;
|
||||
|
||||
/* mifpolycon.c */
|
||||
|
||||
extern void miFillSppPoly(
|
||||
DrawablePtr /*dst*/,
|
||||
GCPtr /*pgc*/,
|
||||
int /*count*/,
|
||||
SppPointPtr /*ptsIn*/,
|
||||
int /*xTrans*/,
|
||||
int /*yTrans*/,
|
||||
double /*xFtrans*/,
|
||||
double /*yFtrans*/
|
||||
);
|
||||
|
||||
#endif /* __MIFPOLY_H__ */
|
||||
282
nx-X11/programs/Xserver/mi/mifpolycon.c
Normal file
282
nx-X11/programs/Xserver/mi/mifpolycon.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <nx-X11/X.h>
|
||||
#include "gcstruct.h"
|
||||
#include "windowstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "mifpoly.h"
|
||||
|
||||
static int GetFPolyYBounds(register SppPointPtr pts, int n, double yFtrans,
|
||||
int *by, int *ty);
|
||||
|
||||
#ifdef ICEILTEMPDECL
|
||||
ICEILTEMPDECL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Written by Todd Newman; April. 1987.
|
||||
*
|
||||
* Fill a convex polygon. If the given polygon
|
||||
* is not convex, then the result is undefined.
|
||||
* The algorithm is to order the edges from smallest
|
||||
* y to largest by partitioning the array into a left
|
||||
* edge list and a right edge list. The algorithm used
|
||||
* to traverse each edge is digital differencing analyzer
|
||||
* line algorithm with y as the major axis. There's some funny linear
|
||||
* interpolation involved because of the subpixel postioning.
|
||||
*/
|
||||
void
|
||||
miFillSppPoly(dst, pgc, count, ptsIn, xTrans, yTrans, xFtrans, yFtrans)
|
||||
DrawablePtr dst;
|
||||
GCPtr pgc;
|
||||
int count; /* number of points */
|
||||
SppPointPtr ptsIn; /* the points */
|
||||
int xTrans, yTrans; /* Translate each point by this */
|
||||
double xFtrans, yFtrans; /* translate before conversion
|
||||
by this amount. This provides
|
||||
a mechanism to match rounding
|
||||
errors with any shape that must
|
||||
meet the polygon exactly.
|
||||
*/
|
||||
{
|
||||
double xl = 0.0, xr = 0.0, /* x vals of left and right edges */
|
||||
ml = 0.0, /* left edge slope */
|
||||
mr = 0.0, /* right edge slope */
|
||||
dy, /* delta y */
|
||||
i; /* loop counter */
|
||||
int y, /* current scanline */
|
||||
j,
|
||||
imin, /* index of vertex with smallest y */
|
||||
ymin, /* y-extents of polygon */
|
||||
ymax,
|
||||
*width,
|
||||
*FirstWidth, /* output buffer */
|
||||
*Marked; /* set if this vertex has been used */
|
||||
register int left, right, /* indices to first endpoints */
|
||||
nextleft,
|
||||
nextright; /* indices to second endpoints */
|
||||
DDXPointPtr ptsOut,
|
||||
FirstPoint; /* output buffer */
|
||||
|
||||
if (pgc->miTranslate)
|
||||
{
|
||||
xTrans += dst->x;
|
||||
yTrans += dst->y;
|
||||
}
|
||||
|
||||
imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);
|
||||
|
||||
y = ymax - ymin + 1;
|
||||
if ((count < 3) || (y <= 0))
|
||||
return;
|
||||
ptsOut = FirstPoint = (DDXPointPtr)malloc(sizeof(DDXPointRec) * y);
|
||||
width = FirstWidth = (int *) malloc(sizeof(int) * y);
|
||||
Marked = (int *) malloc(sizeof(int) * count);
|
||||
|
||||
if(!ptsOut || !width || !Marked)
|
||||
{
|
||||
if (Marked) free(Marked);
|
||||
if (width) free(width);
|
||||
if (ptsOut) free(ptsOut);
|
||||
return;
|
||||
}
|
||||
|
||||
for(j = 0; j < count; j++)
|
||||
Marked[j] = 0;
|
||||
nextleft = nextright = imin;
|
||||
Marked[imin] = -1;
|
||||
y = ICEIL(ptsIn[nextleft].y + yFtrans);
|
||||
|
||||
/*
|
||||
* loop through all edges of the polygon
|
||||
*/
|
||||
do
|
||||
{
|
||||
/* add a left edge if we need to */
|
||||
if ((y > (ptsIn[nextleft].y + yFtrans) ||
|
||||
ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) &&
|
||||
Marked[nextleft] != 1)
|
||||
{
|
||||
Marked[nextleft]++;
|
||||
left = nextleft++;
|
||||
|
||||
/* find the next edge, considering the end conditions */
|
||||
if (nextleft >= count)
|
||||
nextleft = 0;
|
||||
|
||||
/* now compute the starting point and slope */
|
||||
dy = ptsIn[nextleft].y - ptsIn[left].y;
|
||||
if (dy != 0.0)
|
||||
{
|
||||
ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy;
|
||||
dy = y - (ptsIn[left].y + yFtrans);
|
||||
xl = (ptsIn[left].x + xFtrans) + ml * max(dy, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* add a right edge if we need to */
|
||||
if ((y > ptsIn[nextright].y + yFtrans) ||
|
||||
(ISEQUAL(y, ptsIn[nextright].y + yFtrans)
|
||||
&& Marked[nextright] != 1))
|
||||
{
|
||||
Marked[nextright]++;
|
||||
right = nextright--;
|
||||
|
||||
/* find the next edge, considering the end conditions */
|
||||
if (nextright < 0)
|
||||
nextright = count - 1;
|
||||
|
||||
/* now compute the starting point and slope */
|
||||
dy = ptsIn[nextright].y - ptsIn[right].y;
|
||||
if (dy != 0.0)
|
||||
{
|
||||
mr = (ptsIn[nextright].x - ptsIn[right].x) / dy;
|
||||
dy = y - (ptsIn[right].y + yFtrans);
|
||||
xr = (ptsIn[right].x + xFtrans) + mr * max(dy, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* generate scans to fill while we still have
|
||||
* a right edge as well as a left edge.
|
||||
*/
|
||||
i = (min(ptsIn[nextleft].y, ptsIn[nextright].y) + yFtrans) - y;
|
||||
|
||||
if (i < EPSILON)
|
||||
{
|
||||
if(Marked[nextleft] && Marked[nextright])
|
||||
{
|
||||
/* Arrgh, we're trapped! (no more points)
|
||||
* Out, we've got to get out of here before this decadence saps
|
||||
* our will completely! */
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = (int) i;
|
||||
if(!j)
|
||||
j++;
|
||||
}
|
||||
while (j > 0)
|
||||
{
|
||||
int cxl, cxr;
|
||||
|
||||
ptsOut->y = (y) + yTrans;
|
||||
|
||||
cxl = ICEIL(xl);
|
||||
cxr = ICEIL(xr);
|
||||
/* reverse the edges if necessary */
|
||||
if (xl < xr)
|
||||
{
|
||||
*(width++) = cxr - cxl;
|
||||
(ptsOut++)->x = cxl + xTrans;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(width++) = cxl - cxr;
|
||||
(ptsOut++)->x = cxr + xTrans;
|
||||
}
|
||||
y++;
|
||||
|
||||
/* increment down the edges */
|
||||
xl += ml;
|
||||
xr += mr;
|
||||
j--;
|
||||
}
|
||||
} while (y <= ymax);
|
||||
|
||||
/* Finally, fill the spans we've collected */
|
||||
(*pgc->ops->FillSpans)(dst, pgc,
|
||||
ptsOut-FirstPoint, FirstPoint, FirstWidth, 1);
|
||||
free(Marked);
|
||||
free(FirstWidth);
|
||||
free(FirstPoint);
|
||||
}
|
||||
|
||||
|
||||
/* Find the index of the point with the smallest y.also return the
|
||||
* smallest and largest y */
|
||||
static
|
||||
int
|
||||
GetFPolyYBounds(
|
||||
register SppPointPtr pts,
|
||||
int n,
|
||||
double yFtrans,
|
||||
int *by,
|
||||
int *ty)
|
||||
{
|
||||
register SppPointPtr ptMin;
|
||||
double ymin, ymax;
|
||||
SppPointPtr ptsStart = pts;
|
||||
|
||||
ptMin = pts;
|
||||
ymin = ymax = (pts++)->y;
|
||||
|
||||
while (--n > 0) {
|
||||
if (pts->y < ymin)
|
||||
{
|
||||
ptMin = pts;
|
||||
ymin = pts->y;
|
||||
}
|
||||
if(pts->y > ymax)
|
||||
ymax = pts->y;
|
||||
|
||||
pts++;
|
||||
}
|
||||
|
||||
*by = ICEIL(ymin + yFtrans);
|
||||
*ty = ICEIL(ymax + yFtrans - 1);
|
||||
return(ptMin-ptsStart);
|
||||
}
|
||||
298
nx-X11/programs/Xserver/mi/migc.c
Normal file
298
nx-X11/programs/Xserver/mi/migc.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
|
||||
Copyright 1993, 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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "regionstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "windowstr.h"
|
||||
#include "migc.h"
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
miChangeGC(pGC, mask)
|
||||
GCPtr pGC;
|
||||
unsigned long mask;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
miDestroyGC(pGC)
|
||||
GCPtr pGC;
|
||||
{
|
||||
if (pGC->pRotatedPixmap)
|
||||
(*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap);
|
||||
if (pGC->freeCompClip)
|
||||
RegionDestroy(pGC->pCompositeClip);
|
||||
miDestroyGCOps(pGC->ops);
|
||||
}
|
||||
|
||||
/*
|
||||
* create a private op array for a gc
|
||||
*/
|
||||
|
||||
GCOpsPtr
|
||||
miCreateGCOps(prototype)
|
||||
GCOpsPtr prototype;
|
||||
{
|
||||
GCOpsPtr ret;
|
||||
|
||||
ret = malloc(sizeof(GCOps));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
*ret = *prototype;
|
||||
ret->devPrivate.val = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
miDestroyGCOps(ops)
|
||||
GCOpsPtr ops;
|
||||
{
|
||||
if (ops->devPrivate.val)
|
||||
free(ops);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
miDestroyClip(pGC)
|
||||
GCPtr pGC;
|
||||
{
|
||||
if (pGC->clientClipType == CT_NONE)
|
||||
return;
|
||||
else if (pGC->clientClipType == CT_PIXMAP)
|
||||
{
|
||||
(*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* we know we'll never have a list of rectangles, since ChangeClip
|
||||
* immediately turns them into a region
|
||||
*/
|
||||
RegionDestroy(pGC->clientClip);
|
||||
}
|
||||
pGC->clientClip = NULL;
|
||||
pGC->clientClipType = CT_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
miChangeClip(pGC, type, pvalue, nrects)
|
||||
GCPtr pGC;
|
||||
int type;
|
||||
void *pvalue;
|
||||
int nrects;
|
||||
{
|
||||
(*pGC->funcs->DestroyClip) (pGC);
|
||||
if (type == CT_PIXMAP)
|
||||
{
|
||||
/* convert the pixmap to a region */
|
||||
pGC->clientClip = (void *) BitmapToRegion(pGC->pScreen,
|
||||
(PixmapPtr) pvalue);
|
||||
(*pGC->pScreen->DestroyPixmap) (pvalue);
|
||||
}
|
||||
else if (type == CT_REGION)
|
||||
{
|
||||
/* stuff the region in the GC */
|
||||
pGC->clientClip = pvalue;
|
||||
}
|
||||
else if (type != CT_NONE)
|
||||
{
|
||||
pGC->clientClip = (void *) RegionFromRects(nrects,
|
||||
(xRectangle *) pvalue,
|
||||
type);
|
||||
free(pvalue);
|
||||
}
|
||||
pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION : CT_NONE;
|
||||
pGC->stateChanges |= GCClipMask;
|
||||
}
|
||||
|
||||
void
|
||||
miCopyClip(pgcDst, pgcSrc)
|
||||
GCPtr pgcDst, pgcSrc;
|
||||
{
|
||||
RegionPtr prgnNew;
|
||||
|
||||
switch (pgcSrc->clientClipType)
|
||||
{
|
||||
case CT_PIXMAP:
|
||||
((PixmapPtr) pgcSrc->clientClip)->refcnt++;
|
||||
/* Fall through !! */
|
||||
case CT_NONE:
|
||||
(*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType,
|
||||
pgcSrc->clientClip, 0);
|
||||
break;
|
||||
case CT_REGION:
|
||||
prgnNew = RegionCreate(NULL, 1);
|
||||
RegionCopy(prgnNew,
|
||||
(RegionPtr) (pgcSrc->clientClip));
|
||||
(*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (void *) prgnNew, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
miCopyGC(pGCSrc, changes, pGCDst)
|
||||
GCPtr pGCSrc;
|
||||
unsigned long changes;
|
||||
GCPtr pGCDst;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
miComputeCompositeClip(pGC, pDrawable)
|
||||
GCPtr pGC;
|
||||
DrawablePtr pDrawable;
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
|
||||
/* This prevents warnings about pScreen not being used. */
|
||||
pGC->pScreen = pScreen = pGC->pScreen;
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW)
|
||||
{
|
||||
WindowPtr pWin = (WindowPtr) pDrawable;
|
||||
RegionPtr pregWin;
|
||||
Bool freeTmpClip, freeCompClip;
|
||||
|
||||
if (pGC->subWindowMode == IncludeInferiors)
|
||||
{
|
||||
pregWin = NotClippedByChildren(pWin);
|
||||
freeTmpClip = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pregWin = &pWin->clipList;
|
||||
freeTmpClip = FALSE;
|
||||
}
|
||||
freeCompClip = pGC->freeCompClip;
|
||||
|
||||
/*
|
||||
* if there is no client clip, we can get by with just keeping the
|
||||
* pointer we got, and remembering whether or not should destroy (or
|
||||
* maybe re-use) it later. this way, we avoid unnecessary copying of
|
||||
* regions. (this wins especially if many clients clip by children
|
||||
* and have no client clip.)
|
||||
*/
|
||||
if (pGC->clientClipType == CT_NONE)
|
||||
{
|
||||
if (freeCompClip)
|
||||
RegionDestroy(pGC->pCompositeClip);
|
||||
pGC->pCompositeClip = pregWin;
|
||||
pGC->freeCompClip = freeTmpClip;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* we need one 'real' region to put into the composite clip. if
|
||||
* pregWin the current composite clip are real, we can get rid of
|
||||
* one. if pregWin is real and the current composite clip isn't,
|
||||
* use pregWin for the composite clip. if the current composite
|
||||
* clip is real and pregWin isn't, use the current composite
|
||||
* clip. if neither is real, create a new region.
|
||||
*/
|
||||
|
||||
RegionTranslate(pGC->clientClip,
|
||||
pDrawable->x + pGC->clipOrg.x,
|
||||
pDrawable->y + pGC->clipOrg.y);
|
||||
|
||||
if (freeCompClip)
|
||||
{
|
||||
RegionIntersect(pGC->pCompositeClip,
|
||||
pregWin, pGC->clientClip);
|
||||
if (freeTmpClip)
|
||||
RegionDestroy(pregWin);
|
||||
}
|
||||
else if (freeTmpClip)
|
||||
{
|
||||
RegionIntersect(pregWin, pregWin, pGC->clientClip);
|
||||
pGC->pCompositeClip = pregWin;
|
||||
}
|
||||
else
|
||||
{
|
||||
pGC->pCompositeClip = RegionCreate(NullBox, 0);
|
||||
RegionIntersect(pGC->pCompositeClip,
|
||||
pregWin, pGC->clientClip);
|
||||
}
|
||||
pGC->freeCompClip = TRUE;
|
||||
RegionTranslate(pGC->clientClip,
|
||||
-(pDrawable->x + pGC->clipOrg.x),
|
||||
-(pDrawable->y + pGC->clipOrg.y));
|
||||
}
|
||||
} /* end of composite clip for a window */
|
||||
else
|
||||
{
|
||||
BoxRec pixbounds;
|
||||
|
||||
/* XXX should we translate by drawable.x/y here ? */
|
||||
/* If you want pixmaps in offscreen memory, yes */
|
||||
pixbounds.x1 = pDrawable->x;
|
||||
pixbounds.y1 = pDrawable->y;
|
||||
pixbounds.x2 = pDrawable->x + pDrawable->width;
|
||||
pixbounds.y2 = pDrawable->y + pDrawable->height;
|
||||
|
||||
if (pGC->freeCompClip)
|
||||
{
|
||||
RegionReset(pGC->pCompositeClip, &pixbounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
pGC->freeCompClip = TRUE;
|
||||
pGC->pCompositeClip = RegionCreate(&pixbounds, 1);
|
||||
}
|
||||
|
||||
if (pGC->clientClipType == CT_REGION)
|
||||
{
|
||||
if(pDrawable->x || pDrawable->y) {
|
||||
RegionTranslate(pGC->clientClip,
|
||||
pDrawable->x + pGC->clipOrg.x,
|
||||
pDrawable->y + pGC->clipOrg.y);
|
||||
RegionIntersect(pGC->pCompositeClip,
|
||||
pGC->pCompositeClip, pGC->clientClip);
|
||||
RegionTranslate(pGC->clientClip,
|
||||
-(pDrawable->x + pGC->clipOrg.x),
|
||||
-(pDrawable->y + pGC->clipOrg.y));
|
||||
} else {
|
||||
RegionTranslate(pGC->pCompositeClip,
|
||||
-pGC->clipOrg.x, -pGC->clipOrg.y);
|
||||
RegionIntersect(pGC->pCompositeClip,
|
||||
pGC->pCompositeClip, pGC->clientClip);
|
||||
RegionTranslate(pGC->pCompositeClip,
|
||||
pGC->clipOrg.x, pGC->clipOrg.y);
|
||||
}
|
||||
}
|
||||
} /* end of composite clip for pixmap */
|
||||
} /* end miComputeCompositeClip */
|
||||
72
nx-X11/programs/Xserver/mi/migc.h
Normal file
72
nx-X11/programs/Xserver/mi/migc.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
|
||||
Copyright 1993, 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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
extern void miChangeGC(
|
||||
GCPtr /*pGC*/,
|
||||
unsigned long /*mask*/
|
||||
);
|
||||
|
||||
extern void miDestroyGC(
|
||||
GCPtr /*pGC*/
|
||||
);
|
||||
|
||||
extern GCOpsPtr miCreateGCOps(
|
||||
GCOpsPtr /*prototype*/
|
||||
);
|
||||
|
||||
extern void miDestroyGCOps(
|
||||
GCOpsPtr /*ops*/
|
||||
);
|
||||
|
||||
extern void miDestroyClip(
|
||||
GCPtr /*pGC*/
|
||||
);
|
||||
|
||||
extern void miChangeClip(
|
||||
GCPtr /*pGC*/,
|
||||
int /*type*/,
|
||||
void * /*pvalue*/,
|
||||
int /*nrects*/
|
||||
);
|
||||
|
||||
extern void miCopyClip(
|
||||
GCPtr /*pgcDst*/,
|
||||
GCPtr /*pgcSrc*/
|
||||
);
|
||||
|
||||
extern void miCopyGC(
|
||||
GCPtr /*pGCSrc*/,
|
||||
unsigned long /*changes*/,
|
||||
GCPtr /*pGCDst*/
|
||||
);
|
||||
|
||||
extern void miComputeCompositeClip(
|
||||
GCPtr /*pGC*/,
|
||||
DrawablePtr /*pDrawable*/
|
||||
);
|
||||
264
nx-X11/programs/Xserver/mi/miglblt.c
Normal file
264
nx-X11/programs/Xserver/mi/miglblt.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xmd.h>
|
||||
#include <nx-X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include <X11/fonts/fontstruct.h>
|
||||
#ifdef HAS_XFONT2
|
||||
# include <X11/fonts/libxfont2.h>
|
||||
#else
|
||||
# include <X11/fonts/fontutil.h>
|
||||
#endif /* HAS_XFONT2 */
|
||||
#include "dixfontstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "windowstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmap.h"
|
||||
#include "servermd.h"
|
||||
#include "mi.h"
|
||||
|
||||
/*
|
||||
machine-independent glyph blt.
|
||||
assumes that glyph bits in snf are written in bytes,
|
||||
have same bit order as the server's bitmap format,
|
||||
and are byte padded. this corresponds to the snf distributed
|
||||
with the sample server.
|
||||
|
||||
get a scratch GC.
|
||||
in the scratch GC set alu = GXcopy, fg = 1, bg = 0
|
||||
allocate a bitmap big enough to hold the largest glyph in the font
|
||||
validate the scratch gc with the bitmap
|
||||
for each glyph
|
||||
carefully put the bits of the glyph in a buffer,
|
||||
padded to the server pixmap scanline padding rules
|
||||
fake a call to PutImage from the buffer into the bitmap
|
||||
use the bitmap in a call to PushPixels
|
||||
*/
|
||||
|
||||
void
|
||||
miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
|
||||
DrawablePtr pDrawable;
|
||||
GC *pGC;
|
||||
int x, y;
|
||||
unsigned int nglyph;
|
||||
CharInfoPtr *ppci; /* array of character info */
|
||||
void *pglyphBase; /* start of array of glyphs */
|
||||
{
|
||||
int width, height;
|
||||
PixmapPtr pPixmap;
|
||||
int nbyLine; /* bytes per line of padded pixmap */
|
||||
FontPtr pfont;
|
||||
GCPtr pGCtmp;
|
||||
register int i;
|
||||
register int j;
|
||||
unsigned char *pbits; /* buffer for PutImage */
|
||||
register unsigned char *pb; /* temp pointer into buffer */
|
||||
register CharInfoPtr pci; /* currect char info */
|
||||
register unsigned char *pglyph; /* pointer bits in glyph */
|
||||
int gWidth, gHeight; /* width and height of glyph */
|
||||
register int nbyGlyphWidth; /* bytes per scanline of glyph */
|
||||
int nbyPadGlyph; /* server padded line of glyph */
|
||||
|
||||
XID gcvals[3];
|
||||
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
x += pDrawable->x;
|
||||
y += pDrawable->y;
|
||||
}
|
||||
|
||||
pfont = pGC->font;
|
||||
width = FONTMAXBOUNDS(pfont,rightSideBearing) -
|
||||
FONTMINBOUNDS(pfont,leftSideBearing);
|
||||
height = FONTMAXBOUNDS(pfont,ascent) +
|
||||
FONTMAXBOUNDS(pfont,descent);
|
||||
|
||||
pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen,
|
||||
width, height, 1,
|
||||
CREATE_PIXMAP_USAGE_SCRATCH);
|
||||
if (!pPixmap)
|
||||
return;
|
||||
|
||||
pGCtmp = GetScratchGC(1, pDrawable->pScreen);
|
||||
if (!pGCtmp)
|
||||
{
|
||||
(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
|
||||
return;
|
||||
}
|
||||
|
||||
gcvals[0] = GXcopy;
|
||||
gcvals[1] = 1;
|
||||
gcvals[2] = 0;
|
||||
|
||||
DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0);
|
||||
|
||||
nbyLine = BitmapBytePad(width);
|
||||
pbits = (unsigned char *)malloc(height*nbyLine);
|
||||
if (!pbits)
|
||||
{
|
||||
(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
|
||||
FreeScratchGC(pGCtmp);
|
||||
return;
|
||||
}
|
||||
while(nglyph--)
|
||||
{
|
||||
pci = *ppci++;
|
||||
pglyph = FONTGLYPHBITS(pglyphBase, pci);
|
||||
gWidth = GLYPHWIDTHPIXELS(pci);
|
||||
gHeight = GLYPHHEIGHTPIXELS(pci);
|
||||
if (gWidth && gHeight)
|
||||
{
|
||||
nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
|
||||
nbyPadGlyph = BitmapBytePad(gWidth);
|
||||
|
||||
if (nbyGlyphWidth == nbyPadGlyph
|
||||
#if GLYPHPADBYTES != 4
|
||||
&& (((int) pglyph) & 3) == 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
pb = pglyph;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph))
|
||||
for (j = 0; j < nbyGlyphWidth; j++)
|
||||
*pb++ = *pglyph++;
|
||||
pb = pbits;
|
||||
}
|
||||
|
||||
if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber))
|
||||
ValidateGC((DrawablePtr)pPixmap, pGCtmp);
|
||||
(*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp,
|
||||
pPixmap->drawable.depth,
|
||||
0, 0, gWidth, gHeight,
|
||||
0, XYBitmap, (char *)pb);
|
||||
|
||||
if ((pGC->serialNumber) != (pDrawable->serialNumber))
|
||||
ValidateGC(pDrawable, pGC);
|
||||
(*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable,
|
||||
gWidth, gHeight,
|
||||
x + pci->metrics.leftSideBearing,
|
||||
y - pci->metrics.ascent);
|
||||
}
|
||||
x += pci->metrics.characterWidth;
|
||||
}
|
||||
(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
|
||||
free(pbits);
|
||||
FreeScratchGC(pGCtmp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
|
||||
DrawablePtr pDrawable;
|
||||
GC *pGC;
|
||||
int x, y;
|
||||
unsigned int nglyph;
|
||||
CharInfoPtr *ppci; /* array of character info */
|
||||
void *pglyphBase; /* start of array of glyphs */
|
||||
{
|
||||
ExtentInfoRec info; /* used by xfont2_query_glyph_extents (libXfont2)
|
||||
resp. QueryGlyphExtents() (libXfont1) */
|
||||
XID gcvals[3];
|
||||
int oldAlu, oldFS;
|
||||
unsigned long oldFG;
|
||||
xRectangle backrect;
|
||||
|
||||
#ifdef HAS_XFONT2
|
||||
xfont2_query_glyph_extents(pGC->font, ppci, (unsigned long) nglyph, &info);
|
||||
#else
|
||||
QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
|
||||
#endif /* HAS_XFONT2 */
|
||||
|
||||
if (info.overallWidth >= 0)
|
||||
{
|
||||
backrect.x = x;
|
||||
backrect.width = info.overallWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
backrect.x = x + info.overallWidth;
|
||||
backrect.width = -info.overallWidth;
|
||||
}
|
||||
backrect.y = y - FONTASCENT(pGC->font);
|
||||
backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
||||
|
||||
oldAlu = pGC->alu;
|
||||
oldFG = pGC->fgPixel;
|
||||
oldFS = pGC->fillStyle;
|
||||
|
||||
/* fill in the background */
|
||||
gcvals[0] = GXcopy;
|
||||
gcvals[1] = pGC->bgPixel;
|
||||
gcvals[2] = FillSolid;
|
||||
DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
|
||||
ValidateGC(pDrawable, pGC);
|
||||
(*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect);
|
||||
|
||||
/* put down the glyphs */
|
||||
gcvals[0] = oldFG;
|
||||
DoChangeGC(pGC, GCForeground, gcvals, 0);
|
||||
ValidateGC(pDrawable, pGC);
|
||||
(*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
|
||||
pglyphBase);
|
||||
|
||||
/* put all the toys away when done playing */
|
||||
gcvals[0] = oldAlu;
|
||||
gcvals[1] = oldFG;
|
||||
gcvals[2] = oldFS;
|
||||
DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
|
||||
ValidateGC(pDrawable, pGC);
|
||||
|
||||
}
|
||||
481
nx-X11/programs/Xserver/mi/miinitext.c
Normal file
481
nx-X11/programs/Xserver/mi/miinitext.c
Normal file
@@ -0,0 +1,481 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XORG_CONFIG_H
|
||||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DMX_CONFIG_H
|
||||
#include <dmx-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XNEST_CONFIG_H
|
||||
#include <xnest-config.h>
|
||||
#undef DPMSExtension
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "extension.h"
|
||||
#include "micmap.h"
|
||||
|
||||
extern Bool noTestExtensions;
|
||||
|
||||
#ifdef BIGREQS
|
||||
extern Bool noBigReqExtension;
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
extern Bool noCompositeExtension;
|
||||
#endif
|
||||
#ifdef DAMAGE
|
||||
extern Bool noDamageExtension;
|
||||
#endif
|
||||
#ifdef DBE
|
||||
extern Bool noDbeExtension;
|
||||
#endif
|
||||
#ifdef DPMSExtension
|
||||
extern Bool noDPMSExtension;
|
||||
#endif
|
||||
#ifdef GLXEXT
|
||||
extern Bool noGlxExtension;
|
||||
#endif
|
||||
#ifdef SCREENSAVER
|
||||
extern Bool noScreenSaverExtension;
|
||||
#endif
|
||||
#ifdef MITSHM
|
||||
extern Bool noMITShmExtension;
|
||||
#endif
|
||||
#ifdef RANDR
|
||||
extern Bool noRRExtension;
|
||||
#endif
|
||||
#ifdef RENDER
|
||||
extern Bool noRenderExtension;
|
||||
#endif
|
||||
#ifdef SHAPE
|
||||
extern Bool noShapeExtension;
|
||||
#endif
|
||||
#ifdef XCSECURITY
|
||||
extern Bool noSecurityExtension;
|
||||
#endif
|
||||
#ifdef XSYNC
|
||||
extern Bool noSyncExtension;
|
||||
#endif
|
||||
#ifdef RES
|
||||
extern Bool noResExtension;
|
||||
#endif
|
||||
#ifdef XCMISC
|
||||
extern Bool noXCMiscExtension;
|
||||
#endif
|
||||
#ifdef XF86BIGFONT
|
||||
extern Bool noXFree86BigfontExtension;
|
||||
#endif
|
||||
#ifdef XF86DRI
|
||||
extern Bool noXFree86DRIExtension;
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
extern Bool noXFixesExtension;
|
||||
#endif
|
||||
#ifdef XKB
|
||||
/* |noXkbExtension| is defined in xc/programs/Xserver/xkb/xkbInit.c */
|
||||
extern Bool noXkbExtension;
|
||||
#endif
|
||||
#ifdef PANORAMIX
|
||||
extern Bool noPanoramiXExtension;
|
||||
#endif
|
||||
#ifdef XINPUT
|
||||
extern Bool noXInputExtension;
|
||||
#endif
|
||||
#ifdef XIDLE
|
||||
extern Bool noXIdleExtension;
|
||||
#endif
|
||||
#ifdef XV
|
||||
extern Bool noXvExtension;
|
||||
#endif
|
||||
|
||||
typedef void (*InitExtension)(void);
|
||||
|
||||
#ifdef MITSHM
|
||||
#define _XSHM_SERVER_
|
||||
#ifdef LEGACY_XEXT_PROTO
|
||||
#include <X11/extensions/shmstr.h>
|
||||
#else
|
||||
#include <X11/extensions/shmproto.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef XTEST
|
||||
#define _XTEST_SERVER_
|
||||
#include <nx-X11/extensions/xtestconst.h>
|
||||
#endif
|
||||
#ifdef XKB
|
||||
#include <nx-X11/extensions/XKB.h>
|
||||
#endif
|
||||
#ifdef XCSECURITY
|
||||
#define _SECURITY_SERVER
|
||||
#include <nx-X11/extensions/securstr.h>
|
||||
#endif
|
||||
#ifdef PANORAMIX
|
||||
#include <nx-X11/extensions/panoramiXproto.h>
|
||||
#endif
|
||||
#ifdef XF86BIGFONT
|
||||
#include <nx-X11/extensions/xf86bigfproto.h>
|
||||
#endif
|
||||
#ifdef RES
|
||||
#include <nx-X11/extensions/XResproto.h>
|
||||
#endif
|
||||
|
||||
/* FIXME: this whole block of externs should be from the appropriate headers */
|
||||
#ifdef SHAPE
|
||||
extern void ShapeExtensionInit(void);
|
||||
#endif
|
||||
#ifdef MITSHM
|
||||
extern void ShmExtensionInit(void);
|
||||
#endif
|
||||
#ifdef PANORAMIX
|
||||
extern void PanoramiXExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XINPUT
|
||||
extern void XInputExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XTEST
|
||||
extern void XTestExtensionInit(void);
|
||||
#endif
|
||||
#ifdef BIGREQS
|
||||
extern void BigReqExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XIDLE
|
||||
extern void XIdleExtensionInit(void);
|
||||
#endif
|
||||
#ifdef SCREENSAVER
|
||||
extern void ScreenSaverExtensionInit (void);
|
||||
#endif
|
||||
#ifdef XV
|
||||
extern void XvExtensionInit(void);
|
||||
extern void XvMCExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XSYNC
|
||||
extern void SyncExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XKB
|
||||
extern void XkbExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XCMISC
|
||||
extern void XCMiscExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XRECORD
|
||||
extern void RecordExtensionInit(void);
|
||||
#endif
|
||||
#ifdef DBE
|
||||
extern void DbeExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XCSECURITY
|
||||
extern void SecurityExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XF86BIGFONT
|
||||
extern void XFree86BigfontExtensionInit(void);
|
||||
#endif
|
||||
#ifdef GLXEXT
|
||||
/*
|
||||
typedef struct __GLXprovider __GLXprovider;
|
||||
extern __GLXprovider __glXMesaProvider;
|
||||
extern void GlxPushProvider(__GLXprovider *impl);
|
||||
*/
|
||||
#ifndef __DARWIN__
|
||||
extern void GlxExtensionInit(void);
|
||||
#else
|
||||
extern void DarwinGlxExtensionInit(void);
|
||||
extern void DarwinGlxWrapInitVisuals(miInitVisualsProcPtr *);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef XF86DRI
|
||||
extern void XFree86DRIExtensionInit(void);
|
||||
#endif
|
||||
#ifdef DPMSExtension
|
||||
extern void DPMSExtensionInit(void);
|
||||
#endif
|
||||
#ifdef RENDER
|
||||
extern void RenderExtensionInit(void);
|
||||
#endif
|
||||
#ifdef RANDR
|
||||
extern void RRExtensionInit(void);
|
||||
#endif
|
||||
#ifdef RES
|
||||
extern void ResExtensionInit(void);
|
||||
#endif
|
||||
#ifdef DMXEXT
|
||||
extern void DMXExtensionInit(void);
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
extern void XFixesExtensionInit(void);
|
||||
#endif
|
||||
#ifdef DAMAGE
|
||||
extern void DamageExtensionInit(void);
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
extern void CompositeExtensionInit(void);
|
||||
#endif
|
||||
|
||||
/* The following is only a small first step towards run-time
|
||||
* configurable extensions.
|
||||
*/
|
||||
typedef struct {
|
||||
char *name;
|
||||
Bool *disablePtr;
|
||||
} ExtensionToggle;
|
||||
|
||||
static ExtensionToggle ExtensionToggleList[] =
|
||||
{
|
||||
/* sort order is extension name string as shown in xdpyinfo */
|
||||
#ifdef BIGREQS
|
||||
{ "BIG-REQUESTS", &noBigReqExtension },
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
{ "Composite", &noCompositeExtension },
|
||||
#endif
|
||||
#ifdef DAMAGE
|
||||
{ "DAMAGE", &noDamageExtension },
|
||||
#endif
|
||||
#ifdef DBE
|
||||
{ "DOUBLE-BUFFER", &noDbeExtension },
|
||||
#endif
|
||||
#ifdef DPMSExtension
|
||||
{ "DPMS", &noDPMSExtension },
|
||||
#endif
|
||||
#ifdef GLXEXT
|
||||
{ "GLX", &noGlxExtension },
|
||||
#endif
|
||||
#ifdef SCREENSAVER
|
||||
{ "MIT-SCREEN-SAVER", &noScreenSaverExtension },
|
||||
#endif
|
||||
#ifdef MITSHM
|
||||
{ SHMNAME, &noMITShmExtension },
|
||||
#endif
|
||||
#ifdef RANDR
|
||||
{ "RANDR", &noRRExtension },
|
||||
#endif
|
||||
#ifdef RENDER
|
||||
{ "RENDER", &noRenderExtension },
|
||||
#endif
|
||||
#ifdef SHAPE
|
||||
{ "SHAPE", &noShapeExtension },
|
||||
#endif
|
||||
#ifdef XCSECURITY
|
||||
{ "SECURITY", &noSecurityExtension },
|
||||
#endif
|
||||
#ifdef XSYNC
|
||||
{ "SYNC", &noSyncExtension },
|
||||
#endif
|
||||
#ifdef RES
|
||||
{ "X-Resource", &noResExtension },
|
||||
#endif
|
||||
#ifdef XCMISC
|
||||
{ "XC-MISC", &noXCMiscExtension },
|
||||
#endif
|
||||
#ifdef XF86BIGFONT
|
||||
{ "XFree86-Bigfont", &noXFree86BigfontExtension },
|
||||
#endif
|
||||
#ifdef XF86DRI
|
||||
{ "XFree86-DRI", &noXFree86DRIExtension },
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
{ "XFIXES", &noXFixesExtension },
|
||||
#endif
|
||||
#ifdef PANORAMIX
|
||||
{ "XINERAMA", &noPanoramiXExtension },
|
||||
#endif
|
||||
#ifdef XINPUT
|
||||
{ "XInputExtension", &noXInputExtension },
|
||||
#endif
|
||||
#ifdef XKB
|
||||
{ "XKEYBOARD", &noXkbExtension },
|
||||
#endif
|
||||
{ "XTEST", &noTestExtensions },
|
||||
#ifdef XV
|
||||
{ "XVideo", &noXvExtension },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
Bool EnableDisableExtension(char *name, Bool enable)
|
||||
{
|
||||
ExtensionToggle *ext = &ExtensionToggleList[0];
|
||||
|
||||
for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++) {
|
||||
if (strcmp(name, ext->name) == 0) {
|
||||
*ext->disablePtr = !enable;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void EnableDisableExtensionError(char *name, Bool enable)
|
||||
{
|
||||
ExtensionToggle *ext = &ExtensionToggleList[0];
|
||||
|
||||
ErrorF("Extension \"%s\" is not recognized\n", name);
|
||||
ErrorF("Only the following extensions can be run-time %s:\n",
|
||||
enable ? "enabled" : "disabled");
|
||||
for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++)
|
||||
ErrorF(" %s\n", ext->name);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
InitExtensions(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef PANORAMIX
|
||||
# if !defined(PRINT_ONLY_SERVER) && !defined(NO_PANORAMIX)
|
||||
if (!noPanoramiXExtension) PanoramiXExtensionInit();
|
||||
# endif
|
||||
#endif
|
||||
#ifdef SHAPE
|
||||
if (!noShapeExtension) ShapeExtensionInit();
|
||||
#endif
|
||||
#ifdef MITSHM
|
||||
if (!noMITShmExtension) ShmExtensionInit();
|
||||
#endif
|
||||
#if defined(XINPUT) && !defined(NO_HW_ONLY_EXTS)
|
||||
if (!noXInputExtension) XInputExtensionInit();
|
||||
#endif
|
||||
#ifdef XTEST
|
||||
if (!noTestExtensions) XTestExtensionInit();
|
||||
#endif
|
||||
#ifdef BIGREQS
|
||||
if (!noBigReqExtension) BigReqExtensionInit();
|
||||
#endif
|
||||
#ifdef XIDLE
|
||||
if (!noXIdleExtension) XIdleExtensionInit();
|
||||
#endif
|
||||
#if defined(SCREENSAVER) && !defined(PRINT_ONLY_SERVER)
|
||||
if (!noScreenSaverExtension) ScreenSaverExtensionInit ();
|
||||
#endif
|
||||
#ifdef XV
|
||||
if (!noXvExtension) {
|
||||
XvExtensionInit();
|
||||
XvMCExtensionInit();
|
||||
}
|
||||
#endif
|
||||
#ifdef XSYNC
|
||||
if (!noSyncExtension) SyncExtensionInit();
|
||||
#endif
|
||||
#if defined(XKB) && !defined(PRINT_ONLY_SERVER) && !defined(NO_HW_ONLY_EXTS)
|
||||
if (!noXkbExtension) XkbExtensionInit();
|
||||
#endif
|
||||
#ifdef XCMISC
|
||||
if (!noXCMiscExtension) XCMiscExtensionInit();
|
||||
#endif
|
||||
#ifdef XRECORD
|
||||
if (!noTestExtensions) RecordExtensionInit();
|
||||
#endif
|
||||
#ifdef DBE
|
||||
if (!noDbeExtension) DbeExtensionInit();
|
||||
#endif
|
||||
#ifdef XCSECURITY
|
||||
if (!noSecurityExtension) SecurityExtensionInit();
|
||||
#endif
|
||||
#if defined(DPMSExtension) && !defined(NO_HW_ONLY_EXTS)
|
||||
if (!noDPMSExtension) DPMSExtensionInit();
|
||||
#endif
|
||||
#ifdef XF86BIGFONT
|
||||
if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
|
||||
#endif
|
||||
#if !defined(PRINT_ONLY_SERVER) && !defined(NO_HW_ONLY_EXTS)
|
||||
#ifdef XF86DRI
|
||||
if (!noXFree86DRIExtension) XFree86DRIExtensionInit();
|
||||
#endif
|
||||
#endif
|
||||
#ifdef GLXEXT
|
||||
/*
|
||||
GlxPushProvider(&__glXMesaProvider);
|
||||
*/
|
||||
#ifndef __DARWIN__
|
||||
if (!noGlxExtension) GlxExtensionInit();
|
||||
#else
|
||||
if (!noGlxExtension) DarwinGlxExtensionInit();
|
||||
#endif
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
/* must be before Render to layer DisplayCursor correctly */
|
||||
if (!noXFixesExtension) XFixesExtensionInit();
|
||||
#endif
|
||||
#ifdef RENDER
|
||||
if (!noRenderExtension) RenderExtensionInit();
|
||||
#endif
|
||||
#ifdef RANDR
|
||||
if (!noRRExtension) RRExtensionInit();
|
||||
#endif
|
||||
#ifdef RES
|
||||
if (!noResExtension) ResExtensionInit();
|
||||
#endif
|
||||
#ifdef DMXEXT
|
||||
DMXExtensionInit(); /* server-specific extension, cannot be disabled */
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
if (!noCompositeExtension) CompositeExtensionInit();
|
||||
#endif
|
||||
#ifdef DAMAGE
|
||||
if (!noDamageExtension) DamageExtensionInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
InitVisualWrap()
|
||||
{
|
||||
miResetInitVisuals();
|
||||
#ifdef GLXEXT
|
||||
#ifdef __DARWIN__
|
||||
DarwinGlxWrapInitVisuals(&miInitVisualsProc);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
172
nx-X11/programs/Xserver/mi/miline.h
Normal file
172
nx-X11/programs/Xserver/mi/miline.h
Normal file
@@ -0,0 +1,172 @@
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1994, 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MILINE_H
|
||||
|
||||
#include "screenint.h"
|
||||
|
||||
/*
|
||||
* Public definitions used for configuring basic pixelization aspects
|
||||
* of the sample implementation line-drawing routines provided in
|
||||
* {mfb,mi,cfb*} at run-time.
|
||||
*/
|
||||
|
||||
#define XDECREASING 4
|
||||
#define YDECREASING 2
|
||||
#define YMAJOR 1
|
||||
|
||||
#define OCTANT1 (1 << (YDECREASING))
|
||||
#define OCTANT2 (1 << (YDECREASING|YMAJOR))
|
||||
#define OCTANT3 (1 << (XDECREASING|YDECREASING|YMAJOR))
|
||||
#define OCTANT4 (1 << (XDECREASING|YDECREASING))
|
||||
#define OCTANT5 (1 << (XDECREASING))
|
||||
#define OCTANT6 (1 << (XDECREASING|YMAJOR))
|
||||
#define OCTANT7 (1 << (YMAJOR))
|
||||
#define OCTANT8 (1 << (0))
|
||||
|
||||
#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
|
||||
|
||||
#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
|
||||
|
||||
/*
|
||||
* Devices can configure the rendering of routines in mi, mfb, and cfb*
|
||||
* by specifying a thin line bias to be applied to a particular screen
|
||||
* using the following function. The bias parameter is an OR'ing of
|
||||
* the appropriate OCTANT constants defined above to indicate which
|
||||
* octants to bias a line to prefer an axial step when the Bresenham
|
||||
* error term is exactly zero. The octants are mapped as follows:
|
||||
*
|
||||
* \ | /
|
||||
* \ 3 | 2 /
|
||||
* \ | /
|
||||
* 4 \ | / 1
|
||||
* \|/
|
||||
* -----------
|
||||
* /|\
|
||||
* 5 / | \ 8
|
||||
* / | \
|
||||
* / 6 | 7 \
|
||||
* / | \
|
||||
*
|
||||
* For more information, see "Ambiguities in Incremental Line Rastering,"
|
||||
* Jack E. Bresenham, IEEE CG&A, May 1987.
|
||||
*/
|
||||
|
||||
extern void miSetZeroLineBias(
|
||||
ScreenPtr /* pScreen */,
|
||||
unsigned int /* bias */
|
||||
);
|
||||
|
||||
/*
|
||||
* Private definitions needed for drawing thin (zero width) lines
|
||||
* Used by the mi, mfb, and all cfb* components.
|
||||
*/
|
||||
|
||||
#define X_AXIS 0
|
||||
#define Y_AXIS 1
|
||||
|
||||
#define OUT_LEFT 0x08
|
||||
#define OUT_RIGHT 0x04
|
||||
#define OUT_ABOVE 0x02
|
||||
#define OUT_BELOW 0x01
|
||||
|
||||
#define OUTCODES(_result, _x, _y, _pbox) \
|
||||
if ( (_x) < (_pbox)->x1) (_result) |= OUT_LEFT; \
|
||||
else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \
|
||||
if ( (_y) < (_pbox)->y1) (_result) |= OUT_ABOVE; \
|
||||
else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW;
|
||||
|
||||
#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
|
||||
{\
|
||||
if (x < xmin) outcode |= OUT_LEFT;\
|
||||
if (x > xmax) outcode |= OUT_RIGHT;\
|
||||
if (y < ymin) outcode |= OUT_ABOVE;\
|
||||
if (y > ymax) outcode |= OUT_BELOW;\
|
||||
}
|
||||
|
||||
#define SWAPINT(i, j) \
|
||||
{ register int _t = i; i = j; j = _t; }
|
||||
|
||||
#define SWAPPT(i, j) \
|
||||
{ DDXPointRec _t; _t = i; i = j; j = _t; }
|
||||
|
||||
#define SWAPINT_PAIR(x1, y1, x2, y2)\
|
||||
{ int t = x1; x1 = x2; x2 = t;\
|
||||
t = y1; y1 = y2; y2 = t;\
|
||||
}
|
||||
|
||||
#define miGetZeroLineBias(_pScreen) \
|
||||
((miZeroLineScreenIndex < 0) ? \
|
||||
0 : ((_pScreen)->devPrivates[miZeroLineScreenIndex].uval))
|
||||
|
||||
#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
|
||||
(_octant) = 0; \
|
||||
(_sx) = (_SX); \
|
||||
if (((_adx) = (_x2) - (_x1)) < 0) { \
|
||||
(_adx) = -(_adx); \
|
||||
(_sx = -(_sx)); \
|
||||
(_octant) |= XDECREASING; \
|
||||
} \
|
||||
(_sy) = (_SY); \
|
||||
if (((_ady) = (_y2) - (_y1)) < 0) { \
|
||||
(_ady) = -(_ady); \
|
||||
(_sy = -(_sy)); \
|
||||
(_octant) |= YDECREASING; \
|
||||
}
|
||||
|
||||
#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR)
|
||||
|
||||
#define FIXUP_ERROR(_e, _octant, _bias) \
|
||||
(_e) -= (((_bias) >> (_octant)) & 1)
|
||||
|
||||
#define IsXMajorOctant(_octant) (!((_octant) & YMAJOR))
|
||||
#define IsYMajorOctant(_octant) ((_octant) & YMAJOR)
|
||||
#define IsXDecreasingOctant(_octant) ((_octant) & XDECREASING)
|
||||
#define IsYDecreasingOctant(_octant) ((_octant) & YDECREASING)
|
||||
|
||||
extern int miZeroLineScreenIndex;
|
||||
|
||||
extern int miZeroClipLine(
|
||||
int /*xmin*/,
|
||||
int /*ymin*/,
|
||||
int /*xmax*/,
|
||||
int /*ymax*/,
|
||||
int * /*new_x1*/,
|
||||
int * /*new_y1*/,
|
||||
int * /*new_x2*/,
|
||||
int * /*new_y2*/,
|
||||
unsigned int /*adx*/,
|
||||
unsigned int /*ady*/,
|
||||
int * /*pt1_clipped*/,
|
||||
int * /*pt2_clipped*/,
|
||||
int /*octant*/,
|
||||
unsigned int /*bias*/,
|
||||
int /*oc1*/,
|
||||
int /*oc2*/
|
||||
);
|
||||
|
||||
#endif /* MILINE_H */
|
||||
2077
nx-X11/programs/Xserver/mi/mioverlay.c
Normal file
2077
nx-X11/programs/Xserver/mi/mioverlay.c
Normal file
File diff suppressed because it is too large
Load Diff
32
nx-X11/programs/Xserver/mi/mioverlay.h
Normal file
32
nx-X11/programs/Xserver/mi/mioverlay.h
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef __MIOVERLAY_H
|
||||
#define __MIOVERLAY_H
|
||||
|
||||
typedef void (*miOverlayTransFunc)(ScreenPtr, int, BoxPtr);
|
||||
typedef Bool (*miOverlayInOverlayFunc)(WindowPtr);
|
||||
|
||||
Bool
|
||||
miInitOverlay(
|
||||
ScreenPtr pScreen,
|
||||
miOverlayInOverlayFunc inOverlay,
|
||||
miOverlayTransFunc trans
|
||||
);
|
||||
|
||||
Bool
|
||||
miOverlayGetPrivateClips(
|
||||
WindowPtr pWin,
|
||||
RegionPtr *borderClip,
|
||||
RegionPtr *clipList
|
||||
);
|
||||
|
||||
Bool miOverlayCollectUnderlayRegions(WindowPtr, RegionPtr*);
|
||||
void miOverlayComputeCompositeClip(GCPtr, WindowPtr);
|
||||
Bool miOverlayCopyUnderlay(ScreenPtr);
|
||||
void miOverlaySetTransFunction(ScreenPtr, miOverlayTransFunc);
|
||||
void miOverlaySetRootClip(ScreenPtr, Bool);
|
||||
|
||||
#endif /* __MIOVERLAY_H */
|
||||
545
nx-X11/programs/Xserver/mi/mipointer.c
Normal file
545
nx-X11/programs/Xserver/mi/mipointer.c
Normal file
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
* mipointer.c
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
# include <nx-X11/X.h>
|
||||
# include <nx-X11/Xmd.h>
|
||||
# include <nx-X11/Xproto.h>
|
||||
# include "misc.h"
|
||||
# include "windowstr.h"
|
||||
# include "pixmapstr.h"
|
||||
# include "mi.h"
|
||||
# include "scrnintstr.h"
|
||||
# include "mipointrst.h"
|
||||
# include "cursorstr.h"
|
||||
# include "dixstruct.h"
|
||||
# include <nx-X11/extensions/XI.h>
|
||||
|
||||
int miPointerScreenIndex;
|
||||
static unsigned long miPointerGeneration = 0;
|
||||
|
||||
#define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr))
|
||||
#define SetupScreen(s) miPointerScreenPtr pScreenPriv = GetScreenPrivate(s)
|
||||
|
||||
/*
|
||||
* until more than one pointer device exists.
|
||||
*/
|
||||
|
||||
static miPointerRec miPointer;
|
||||
|
||||
static Bool miPointerRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
static Bool miPointerUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
static Bool miPointerDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
static void miPointerConstrainCursor(ScreenPtr pScreen, BoxPtr pBox);
|
||||
static void miPointerPointerNonInterestBox(ScreenPtr pScreen, BoxPtr pBox);
|
||||
static void miPointerCursorLimits(ScreenPtr pScreen, CursorPtr pCursor,
|
||||
BoxPtr pHotBox, BoxPtr pTopLeftBox);
|
||||
static Bool miPointerSetCursorPosition(ScreenPtr pScreen, int x, int y,
|
||||
Bool generateEvent);
|
||||
static Bool miPointerCloseScreen(ScreenPtr pScreen);
|
||||
static void miPointerMove(ScreenPtr pScreen, int x, int y, unsigned long time);
|
||||
|
||||
Bool
|
||||
miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate)
|
||||
ScreenPtr pScreen;
|
||||
miPointerSpriteFuncPtr spriteFuncs;
|
||||
miPointerScreenFuncPtr screenFuncs;
|
||||
Bool waitForUpdate;
|
||||
{
|
||||
miPointerScreenPtr pScreenPriv;
|
||||
|
||||
if (miPointerGeneration != serverGeneration)
|
||||
{
|
||||
miPointerScreenIndex = AllocateScreenPrivateIndex();
|
||||
if (miPointerScreenIndex < 0)
|
||||
return FALSE;
|
||||
miPointerGeneration = serverGeneration;
|
||||
}
|
||||
pScreenPriv = (miPointerScreenPtr) malloc (sizeof (miPointerScreenRec));
|
||||
if (!pScreenPriv)
|
||||
return FALSE;
|
||||
pScreenPriv->spriteFuncs = spriteFuncs;
|
||||
pScreenPriv->screenFuncs = screenFuncs;
|
||||
/*
|
||||
* check for uninitialized methods
|
||||
*/
|
||||
if (!screenFuncs->EnqueueEvent)
|
||||
screenFuncs->EnqueueEvent = mieqEnqueue;
|
||||
if (!screenFuncs->NewEventScreen)
|
||||
screenFuncs->NewEventScreen = mieqSwitchScreen;
|
||||
pScreenPriv->waitForUpdate = waitForUpdate;
|
||||
pScreenPriv->showTransparent = FALSE;
|
||||
pScreenPriv->CloseScreen = pScreen->CloseScreen;
|
||||
pScreen->CloseScreen = miPointerCloseScreen;
|
||||
pScreen->devPrivates[miPointerScreenIndex].ptr = (void *) pScreenPriv;
|
||||
/*
|
||||
* set up screen cursor method table
|
||||
*/
|
||||
pScreen->ConstrainCursor = miPointerConstrainCursor;
|
||||
pScreen->CursorLimits = miPointerCursorLimits;
|
||||
pScreen->DisplayCursor = miPointerDisplayCursor;
|
||||
pScreen->RealizeCursor = miPointerRealizeCursor;
|
||||
pScreen->UnrealizeCursor = miPointerUnrealizeCursor;
|
||||
pScreen->SetCursorPosition = miPointerSetCursorPosition;
|
||||
pScreen->RecolorCursor = miRecolorCursor;
|
||||
pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox;
|
||||
/*
|
||||
* set up the pointer object
|
||||
*/
|
||||
miPointer.pScreen = NULL;
|
||||
miPointer.pSpriteScreen = NULL;
|
||||
miPointer.pCursor = NULL;
|
||||
miPointer.pSpriteCursor = NULL;
|
||||
miPointer.limits.x1 = 0;
|
||||
miPointer.limits.x2 = 32767;
|
||||
miPointer.limits.y1 = 0;
|
||||
miPointer.limits.y2 = 32767;
|
||||
miPointer.confined = FALSE;
|
||||
miPointer.x = 0;
|
||||
miPointer.y = 0;
|
||||
miPointer.history_start = miPointer.history_end = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
miPointerCloseScreen (pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
SetupScreen(pScreen);
|
||||
|
||||
if (pScreen == miPointer.pScreen)
|
||||
miPointer.pScreen = 0;
|
||||
if (pScreen == miPointer.pSpriteScreen)
|
||||
miPointer.pSpriteScreen = 0;
|
||||
pScreen->CloseScreen = pScreenPriv->CloseScreen;
|
||||
free ((void *) pScreenPriv);
|
||||
return (*pScreen->CloseScreen) (pScreen);
|
||||
}
|
||||
|
||||
/*
|
||||
* DIX/DDX interface routines
|
||||
*/
|
||||
|
||||
static Bool
|
||||
miPointerRealizeCursor (pScreen, pCursor)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
{
|
||||
SetupScreen(pScreen);
|
||||
|
||||
return (*pScreenPriv->spriteFuncs->RealizeCursor) (pScreen, pCursor);
|
||||
}
|
||||
|
||||
static Bool
|
||||
miPointerUnrealizeCursor (pScreen, pCursor)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
{
|
||||
SetupScreen(pScreen);
|
||||
|
||||
return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pScreen, pCursor);
|
||||
}
|
||||
|
||||
static Bool
|
||||
miPointerDisplayCursor (pScreen, pCursor)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
{
|
||||
miPointer.pCursor = pCursor;
|
||||
miPointer.pScreen = pScreen;
|
||||
miPointerUpdate ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
miPointerConstrainCursor (pScreen, pBox)
|
||||
ScreenPtr pScreen;
|
||||
BoxPtr pBox;
|
||||
{
|
||||
miPointer.limits = *pBox;
|
||||
miPointer.confined = PointerConfinedToScreen();
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
miPointerPointerNonInterestBox (pScreen, pBox)
|
||||
ScreenPtr pScreen;
|
||||
BoxPtr pBox;
|
||||
{
|
||||
/* until DIX uses this, this will remain a stub */
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
miPointerCursorLimits(pScreen, pCursor, pHotBox, pTopLeftBox)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
BoxPtr pHotBox;
|
||||
BoxPtr pTopLeftBox;
|
||||
{
|
||||
*pTopLeftBox = *pHotBox;
|
||||
}
|
||||
|
||||
static Bool GenerateEvent;
|
||||
|
||||
static Bool
|
||||
miPointerSetCursorPosition(pScreen, x, y, generateEvent)
|
||||
ScreenPtr pScreen;
|
||||
int x, y;
|
||||
Bool generateEvent;
|
||||
{
|
||||
SetupScreen (pScreen);
|
||||
|
||||
GenerateEvent = generateEvent;
|
||||
|
||||
if (pScreen->ConstrainCursorHarder)
|
||||
pScreen->ConstrainCursorHarder(pScreen, Absolute, &x, &y);
|
||||
|
||||
/* device dependent - must pend signal and call miPointerWarpCursor */
|
||||
(*pScreenPriv->screenFuncs->WarpCursor) (pScreen, x, y);
|
||||
if (!generateEvent)
|
||||
miPointerUpdate();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Once signals are ignored, the WarpCursor function can call this */
|
||||
|
||||
void
|
||||
miPointerWarpCursor (pScreen, x, y)
|
||||
ScreenPtr pScreen;
|
||||
int x, y;
|
||||
{
|
||||
SetupScreen (pScreen);
|
||||
|
||||
if (miPointer.pScreen != pScreen)
|
||||
(*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, TRUE);
|
||||
|
||||
if (GenerateEvent)
|
||||
{
|
||||
miPointerMove (pScreen, x, y, GetTimeInMillis());
|
||||
}
|
||||
else
|
||||
{
|
||||
/* everything from miPointerMove except the event and history */
|
||||
|
||||
if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
|
||||
{
|
||||
miPointer.devx = x;
|
||||
miPointer.devy = y;
|
||||
if(!miPointer.pCursor->bits->emptyMask)
|
||||
(*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
|
||||
}
|
||||
miPointer.x = x;
|
||||
miPointer.y = y;
|
||||
miPointer.pScreen = pScreen;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pointer/CursorDisplay interface routines
|
||||
*/
|
||||
|
||||
int
|
||||
miPointerGetMotionBufferSize ()
|
||||
{
|
||||
return MOTION_SIZE;
|
||||
}
|
||||
|
||||
int
|
||||
miPointerGetMotionEvents (pPtr, coords, start, stop, pScreen)
|
||||
DeviceIntPtr pPtr;
|
||||
xTimecoord *coords;
|
||||
unsigned long start, stop;
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
miHistoryPtr h;
|
||||
|
||||
for (i = miPointer.history_start; i != miPointer.history_end;)
|
||||
{
|
||||
h = &miPointer.history[i];
|
||||
if (h->event.time >= stop)
|
||||
break;
|
||||
if (h->event.time >= start)
|
||||
{
|
||||
*coords++ = h->event;
|
||||
count++;
|
||||
}
|
||||
if (++i == MOTION_SIZE) i = 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* miPointerUpdate
|
||||
*
|
||||
* Syncronize the sprite with the cursor - called from ProcessInputEvents
|
||||
*/
|
||||
|
||||
void
|
||||
miPointerUpdate ()
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
miPointerScreenPtr pScreenPriv;
|
||||
CursorPtr pCursor;
|
||||
int x, y, devx, devy;
|
||||
|
||||
pScreen = miPointer.pScreen;
|
||||
x = miPointer.x;
|
||||
y = miPointer.y;
|
||||
devx = miPointer.devx;
|
||||
devy = miPointer.devy;
|
||||
if (!pScreen)
|
||||
return;
|
||||
pScreenPriv = GetScreenPrivate (pScreen);
|
||||
/*
|
||||
* if the cursor has switched screens, disable the sprite
|
||||
* on the old screen
|
||||
*/
|
||||
if (pScreen != miPointer.pSpriteScreen)
|
||||
{
|
||||
if (miPointer.pSpriteScreen)
|
||||
{
|
||||
miPointerScreenPtr pOldPriv;
|
||||
|
||||
pOldPriv = GetScreenPrivate (miPointer.pSpriteScreen);
|
||||
if (miPointer.pCursor)
|
||||
{
|
||||
(*pOldPriv->spriteFuncs->SetCursor)
|
||||
(miPointer.pSpriteScreen, NullCursor, 0, 0);
|
||||
}
|
||||
(*pOldPriv->screenFuncs->CrossScreen) (miPointer.pSpriteScreen, FALSE);
|
||||
}
|
||||
(*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE);
|
||||
(*pScreenPriv->spriteFuncs->SetCursor)
|
||||
(pScreen, miPointer.pCursor, x, y);
|
||||
miPointer.devx = x;
|
||||
miPointer.devy = y;
|
||||
miPointer.pSpriteCursor = miPointer.pCursor;
|
||||
miPointer.pSpriteScreen = pScreen;
|
||||
}
|
||||
/*
|
||||
* if the cursor has changed, display the new one
|
||||
*/
|
||||
else if (miPointer.pCursor != miPointer.pSpriteCursor)
|
||||
{
|
||||
pCursor = miPointer.pCursor;
|
||||
if (pCursor->bits->emptyMask && !pScreenPriv->showTransparent)
|
||||
pCursor = NullCursor;
|
||||
(*pScreenPriv->spriteFuncs->SetCursor) (pScreen, pCursor, x, y);
|
||||
|
||||
miPointer.devx = x;
|
||||
miPointer.devy = y;
|
||||
miPointer.pSpriteCursor = miPointer.pCursor;
|
||||
}
|
||||
else if (x != devx || y != devy)
|
||||
{
|
||||
miPointer.devx = x;
|
||||
miPointer.devy = y;
|
||||
if(!miPointer.pCursor->bits->emptyMask)
|
||||
(*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* miPointerDeltaCursor. The void * has moved dx,dy from it's previous
|
||||
* position.
|
||||
*/
|
||||
|
||||
void
|
||||
miPointerDeltaCursor (dx, dy, time)
|
||||
int dx, dy;
|
||||
unsigned long time;
|
||||
{
|
||||
miPointerAbsoluteCursor (miPointer.x + dx, miPointer.y + dy, time);
|
||||
}
|
||||
|
||||
void
|
||||
miPointerSetNewScreen(int screen_no, int x, int y)
|
||||
{
|
||||
miPointerScreenPtr pScreenPriv;
|
||||
ScreenPtr pScreen;
|
||||
|
||||
pScreen = screenInfo.screens[screen_no];
|
||||
pScreenPriv = GetScreenPrivate (pScreen);
|
||||
(*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
|
||||
NewCurrentScreen (pScreen, x, y);
|
||||
miPointer.limits.x2 = pScreen->width;
|
||||
miPointer.limits.y2 = pScreen->height;
|
||||
}
|
||||
|
||||
ScreenPtr
|
||||
miPointerCurrentScreen ()
|
||||
{
|
||||
return (miPointer.pScreen);
|
||||
}
|
||||
|
||||
/*
|
||||
* miPointerAbsoluteCursor. The void * has moved to x,y
|
||||
*/
|
||||
|
||||
void
|
||||
miPointerAbsoluteCursor (x, y, time)
|
||||
int x, y;
|
||||
unsigned long time;
|
||||
{
|
||||
miPointerScreenPtr pScreenPriv;
|
||||
ScreenPtr pScreen;
|
||||
ScreenPtr newScreen;
|
||||
|
||||
pScreen = miPointer.pScreen;
|
||||
if (!pScreen)
|
||||
return; /* called before ready */
|
||||
if (x < 0 || x >= pScreen->width || y < 0 || y >= pScreen->height)
|
||||
{
|
||||
pScreenPriv = GetScreenPrivate (pScreen);
|
||||
if (!miPointer.confined)
|
||||
{
|
||||
newScreen = pScreen;
|
||||
(*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y);
|
||||
if (newScreen != pScreen)
|
||||
{
|
||||
pScreen = newScreen;
|
||||
(*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
|
||||
pScreenPriv = GetScreenPrivate (pScreen);
|
||||
/* Smash the confine to the new screen */
|
||||
miPointer.limits.x2 = pScreen->width;
|
||||
miPointer.limits.y2 = pScreen->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* constrain the hot-spot to the current
|
||||
* limits
|
||||
*/
|
||||
if (x < miPointer.limits.x1)
|
||||
x = miPointer.limits.x1;
|
||||
if (x >= miPointer.limits.x2)
|
||||
x = miPointer.limits.x2 - 1;
|
||||
if (y < miPointer.limits.y1)
|
||||
y = miPointer.limits.y1;
|
||||
if (y >= miPointer.limits.y2)
|
||||
y = miPointer.limits.y2 - 1;
|
||||
if (miPointer.x == x && miPointer.y == y && miPointer.pScreen == pScreen)
|
||||
return;
|
||||
miPointerMove (pScreen, x, y, time);
|
||||
}
|
||||
|
||||
void
|
||||
miPointerPosition (x, y)
|
||||
int *x, *y;
|
||||
{
|
||||
*x = miPointer.x;
|
||||
*y = miPointer.y;
|
||||
}
|
||||
|
||||
/*
|
||||
* miPointerMove. The void * has moved to x,y on current screen
|
||||
*/
|
||||
|
||||
static void
|
||||
miPointerMove (pScreen, x, y, time)
|
||||
ScreenPtr pScreen;
|
||||
int x, y;
|
||||
unsigned long time;
|
||||
{
|
||||
SetupScreen(pScreen);
|
||||
xEvent xE;
|
||||
miHistoryPtr history;
|
||||
int prev, end, start;
|
||||
|
||||
if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
|
||||
{
|
||||
miPointer.devx = x;
|
||||
miPointer.devy = y;
|
||||
if(!miPointer.pCursor->bits->emptyMask)
|
||||
(*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
|
||||
}
|
||||
miPointer.x = x;
|
||||
miPointer.y = y;
|
||||
miPointer.pScreen = pScreen;
|
||||
|
||||
xE.u.u.type = MotionNotify;
|
||||
xE.u.keyButtonPointer.rootX = x;
|
||||
xE.u.keyButtonPointer.rootY = y;
|
||||
xE.u.keyButtonPointer.time = time;
|
||||
(*pScreenPriv->screenFuncs->EnqueueEvent) (&xE);
|
||||
|
||||
end = miPointer.history_end;
|
||||
start = miPointer.history_start;
|
||||
prev = end - 1;
|
||||
if (end == 0)
|
||||
prev = MOTION_SIZE - 1;
|
||||
history = &miPointer.history[prev];
|
||||
if (end == start || history->event.time != time)
|
||||
{
|
||||
history = &miPointer.history[end];
|
||||
if (++end == MOTION_SIZE)
|
||||
end = 0;
|
||||
if (end == start)
|
||||
{
|
||||
start = end + 1;
|
||||
if (start == MOTION_SIZE)
|
||||
start = 0;
|
||||
miPointer.history_start = start;
|
||||
}
|
||||
miPointer.history_end = end;
|
||||
}
|
||||
history->event.x = x;
|
||||
history->event.y = y;
|
||||
history->event.time = time;
|
||||
history->pScreen = pScreen;
|
||||
}
|
||||
|
||||
void
|
||||
_miRegisterPointerDevice (pScreen, pDevice)
|
||||
ScreenPtr pScreen;
|
||||
DeviceIntPtr pDevice;
|
||||
{
|
||||
miPointer.pPointer = (DevicePtr)pDevice;
|
||||
}
|
||||
|
||||
/* obsolete: for binary compatibility */
|
||||
|
||||
#ifdef miRegisterPointerDevice
|
||||
#undef miRegisterPointerDevice
|
||||
void
|
||||
miRegisterPointerDevice (pScreen, pDevice)
|
||||
ScreenPtr pScreen;
|
||||
DevicePtr pDevice;
|
||||
{
|
||||
miPointer.pPointer = pDevice;
|
||||
}
|
||||
#endif /* miRegisterPointerDevice */
|
||||
160
nx-X11/programs/Xserver/mi/mipointer.h
Normal file
160
nx-X11/programs/Xserver/mi/mipointer.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* mipointer.h
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
#ifndef MIPOINTER_H
|
||||
#define MIPOINTER_H
|
||||
|
||||
#include "cursor.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef struct _miPointerSpriteFuncRec {
|
||||
Bool (*RealizeCursor)(
|
||||
ScreenPtr /* pScr */,
|
||||
CursorPtr /* pCurs */
|
||||
);
|
||||
Bool (*UnrealizeCursor)(
|
||||
ScreenPtr /* pScr */,
|
||||
CursorPtr /* pCurs */
|
||||
);
|
||||
void (*SetCursor)(
|
||||
ScreenPtr /* pScr */,
|
||||
CursorPtr /* pCurs */,
|
||||
int /* x */,
|
||||
int /* y */
|
||||
);
|
||||
void (*MoveCursor)(
|
||||
ScreenPtr /* pScr */,
|
||||
int /* x */,
|
||||
int /* y */
|
||||
);
|
||||
} miPointerSpriteFuncRec, *miPointerSpriteFuncPtr;
|
||||
|
||||
typedef struct _miPointerScreenFuncRec {
|
||||
Bool (*CursorOffScreen)(
|
||||
ScreenPtr* /* ppScr */,
|
||||
int* /* px */,
|
||||
int* /* py */
|
||||
);
|
||||
void (*CrossScreen)(
|
||||
ScreenPtr /* pScr */,
|
||||
int /* entering */
|
||||
);
|
||||
void (*WarpCursor)(
|
||||
ScreenPtr /* pScr */,
|
||||
int /* x */,
|
||||
int /* y */
|
||||
);
|
||||
void (*EnqueueEvent)(
|
||||
xEventPtr /* event */
|
||||
);
|
||||
void (*NewEventScreen)(
|
||||
ScreenPtr /* pScr */,
|
||||
Bool /* fromDIX */
|
||||
);
|
||||
} miPointerScreenFuncRec, *miPointerScreenFuncPtr;
|
||||
|
||||
extern Bool miDCInitialize(
|
||||
ScreenPtr /*pScreen*/,
|
||||
miPointerScreenFuncPtr /*screenFuncs*/
|
||||
);
|
||||
|
||||
extern Bool miPointerInitialize(
|
||||
ScreenPtr /*pScreen*/,
|
||||
miPointerSpriteFuncPtr /*spriteFuncs*/,
|
||||
miPointerScreenFuncPtr /*screenFuncs*/,
|
||||
Bool /*waitForUpdate*/
|
||||
);
|
||||
|
||||
extern void miPointerWarpCursor(
|
||||
ScreenPtr /*pScreen*/,
|
||||
int /*x*/,
|
||||
int /*y*/
|
||||
);
|
||||
|
||||
extern int miPointerGetMotionBufferSize(
|
||||
void
|
||||
);
|
||||
|
||||
extern int miPointerGetMotionEvents(
|
||||
DeviceIntPtr /*pPtr*/,
|
||||
xTimecoord * /*coords*/,
|
||||
unsigned long /*start*/,
|
||||
unsigned long /*stop*/,
|
||||
ScreenPtr /*pScreen*/
|
||||
);
|
||||
|
||||
extern void miPointerUpdate(
|
||||
void
|
||||
);
|
||||
|
||||
extern void miPointerDeltaCursor(
|
||||
int /*dx*/,
|
||||
int /*dy*/,
|
||||
unsigned long /*time*/
|
||||
);
|
||||
|
||||
extern void miPointerAbsoluteCursor(
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
unsigned long /*time*/
|
||||
);
|
||||
|
||||
extern void miPointerPosition(
|
||||
int * /*x*/,
|
||||
int * /*y*/
|
||||
);
|
||||
|
||||
#undef miRegisterPointerDevice
|
||||
extern void miRegisterPointerDevice(
|
||||
ScreenPtr /*pScreen*/,
|
||||
DevicePtr /*pDevice*/
|
||||
);
|
||||
|
||||
extern void miPointerSetNewScreen(
|
||||
int, /*screen_no*/
|
||||
int, /*x*/
|
||||
int /*y*/
|
||||
);
|
||||
extern ScreenPtr miPointerCurrentScreen(
|
||||
void
|
||||
);
|
||||
|
||||
#define miRegisterPointerDevice(pScreen,pDevice) \
|
||||
_miRegisterPointerDevice(pScreen,pDevice)
|
||||
|
||||
extern void _miRegisterPointerDevice(
|
||||
ScreenPtr /*pScreen*/,
|
||||
DeviceIntPtr /*pDevice*/
|
||||
);
|
||||
|
||||
extern int miPointerScreenIndex;
|
||||
|
||||
#endif /* MIPOINTER_H */
|
||||
62
nx-X11/programs/Xserver/mi/mipointrst.h
Normal file
62
nx-X11/programs/Xserver/mi/mipointrst.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* mipointrst.h
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
#include "mipointer.h"
|
||||
#include "scrnintstr.h"
|
||||
|
||||
#define MOTION_SIZE 256
|
||||
|
||||
typedef struct {
|
||||
xTimecoord event;
|
||||
ScreenPtr pScreen;
|
||||
} miHistoryRec, *miHistoryPtr;
|
||||
|
||||
typedef struct {
|
||||
ScreenPtr pScreen; /* current screen */
|
||||
ScreenPtr pSpriteScreen;/* screen containing current sprite */
|
||||
CursorPtr pCursor; /* current cursor */
|
||||
CursorPtr pSpriteCursor;/* cursor on screen */
|
||||
BoxRec limits; /* current constraints */
|
||||
Bool confined; /* pointer can't change screens */
|
||||
int x, y; /* hot spot location */
|
||||
int devx, devy; /* sprite position */
|
||||
DevicePtr pPointer; /* pointer device structure */
|
||||
miHistoryRec history[MOTION_SIZE];
|
||||
int history_start, history_end;
|
||||
} miPointerRec, *miPointerPtr;
|
||||
|
||||
typedef struct {
|
||||
miPointerSpriteFuncPtr spriteFuncs; /* sprite-specific methods */
|
||||
miPointerScreenFuncPtr screenFuncs; /* screen-specific methods */
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
Bool waitForUpdate; /* don't move cursor in SIGIO */
|
||||
Bool showTransparent; /* show empty cursors */
|
||||
} miPointerScreenRec, *miPointerScreenPtr;
|
||||
127
nx-X11/programs/Xserver/mi/mipoly.c
Normal file
127
nx-X11/programs/Xserver/mi/mipoly.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/*
|
||||
* mipoly.c
|
||||
*
|
||||
* Written by Brian Kelleher; June 1986
|
||||
*
|
||||
* Draw polygons. This routine translates the point by the
|
||||
* origin if pGC->miTranslate is non-zero, and calls
|
||||
* to the appropriate routine to actually scan convert the
|
||||
* polygon.
|
||||
*/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include "windowstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "mi.h"
|
||||
#include "regionstr.h"
|
||||
|
||||
|
||||
void
|
||||
miFillPolygon(dst, pgc, shape, mode, count, pPts)
|
||||
DrawablePtr dst;
|
||||
register GCPtr pgc;
|
||||
int shape, mode;
|
||||
register int count;
|
||||
DDXPointPtr pPts;
|
||||
{
|
||||
int i;
|
||||
register int xorg, yorg;
|
||||
register DDXPointPtr ppt;
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
ppt = pPts;
|
||||
if (pgc->miTranslate)
|
||||
{
|
||||
xorg = dst->x;
|
||||
yorg = dst->y;
|
||||
|
||||
if (mode == CoordModeOrigin)
|
||||
{
|
||||
for (i = 0; i<count; i++)
|
||||
{
|
||||
ppt->x += xorg;
|
||||
ppt++->y += yorg;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ppt->x += xorg;
|
||||
ppt++->y += yorg;
|
||||
for (i = 1; i<count; i++)
|
||||
{
|
||||
ppt->x += (ppt-1)->x;
|
||||
ppt->y += (ppt-1)->y;
|
||||
ppt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == CoordModePrevious)
|
||||
{
|
||||
ppt++;
|
||||
for (i = 1; i<count; i++)
|
||||
{
|
||||
ppt->x += (ppt-1)->x;
|
||||
ppt->y += (ppt-1)->y;
|
||||
ppt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shape == Convex)
|
||||
miFillConvexPoly(dst, pgc, count, pPts);
|
||||
else
|
||||
miFillGeneralPoly(dst, pgc, count, pPts);
|
||||
}
|
||||
215
nx-X11/programs/Xserver/mi/mipoly.h
Normal file
215
nx-X11/programs/Xserver/mi/mipoly.h
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* fill.h
|
||||
*
|
||||
* Created by Brian Kelleher; Oct 1985
|
||||
*
|
||||
* Include file for filled polygon routines.
|
||||
*
|
||||
* These are the data structures needed to scan
|
||||
* convert regions. Two different scan conversion
|
||||
* methods are available -- the even-odd method, and
|
||||
* the winding number method.
|
||||
* The even-odd rule states that a point is inside
|
||||
* the polygon if a ray drawn from that point in any
|
||||
* direction will pass through an odd number of
|
||||
* path segments.
|
||||
* By the winding number rule, a point is decided
|
||||
* to be inside the polygon if a ray drawn from that
|
||||
* point in any direction passes through a different
|
||||
* number of clockwise and counter-clockwise path
|
||||
* segments.
|
||||
*
|
||||
* These data structures are adapted somewhat from
|
||||
* the algorithm in (Foley/Van Dam) for scan converting
|
||||
* polygons.
|
||||
* The basic algorithm is to start at the top (smallest y)
|
||||
* of the polygon, stepping down to the bottom of
|
||||
* the polygon by incrementing the y coordinate. We
|
||||
* keep a list of edges which the current scanline crosses,
|
||||
* sorted by x. This list is called the Active Edge Table (AET)
|
||||
* As we change the y-coordinate, we update each entry in
|
||||
* in the active edge table to reflect the edges new xcoord.
|
||||
* This list must be sorted at each scanline in case
|
||||
* two edges intersect.
|
||||
* We also keep a data structure known as the Edge Table (ET),
|
||||
* which keeps track of all the edges which the current
|
||||
* scanline has not yet reached. The ET is basically a
|
||||
* list of ScanLineList structures containing a list of
|
||||
* edges which are entered at a given scanline. There is one
|
||||
* ScanLineList per scanline at which an edge is entered.
|
||||
* When we enter a new edge, we move it from the ET to the AET.
|
||||
*
|
||||
* From the AET, we can implement the even-odd rule as in
|
||||
* (Foley/Van Dam).
|
||||
* The winding number rule is a little trickier. We also
|
||||
* keep the EdgeTableEntries in the AET linked by the
|
||||
* nextWETE (winding EdgeTableEntry) link. This allows
|
||||
* the edges to be linked just as before for updating
|
||||
* purposes, but only uses the edges linked by the nextWETE
|
||||
* link as edges representing spans of the polygon to
|
||||
* drawn (as with the even-odd rule).
|
||||
*/
|
||||
|
||||
/*
|
||||
* for the winding number rule
|
||||
*/
|
||||
#define CLOCKWISE 1
|
||||
#define COUNTERCLOCKWISE -1
|
||||
|
||||
typedef struct _EdgeTableEntry {
|
||||
int ymax; /* ycoord at which we exit this edge. */
|
||||
BRESINFO bres; /* Bresenham info to run the edge */
|
||||
struct _EdgeTableEntry *next; /* next in the list */
|
||||
struct _EdgeTableEntry *back; /* for insertion sort */
|
||||
struct _EdgeTableEntry *nextWETE; /* for winding num rule */
|
||||
int ClockWise; /* flag for winding number rule */
|
||||
} EdgeTableEntry;
|
||||
|
||||
|
||||
typedef struct _ScanLineList{
|
||||
int scanline; /* the scanline represented */
|
||||
EdgeTableEntry *edgelist; /* header node */
|
||||
struct _ScanLineList *next; /* next in the list */
|
||||
} ScanLineList;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int ymax; /* ymax for the polygon */
|
||||
int ymin; /* ymin for the polygon */
|
||||
ScanLineList scanlines; /* header node */
|
||||
} EdgeTable;
|
||||
|
||||
|
||||
/*
|
||||
* Here is a struct to help with storage allocation
|
||||
* so we can allocate a big chunk at a time, and then take
|
||||
* pieces from this heap when we need to.
|
||||
*/
|
||||
#define SLLSPERBLOCK 25
|
||||
|
||||
typedef struct _ScanLineListBlock {
|
||||
ScanLineList SLLs[SLLSPERBLOCK];
|
||||
struct _ScanLineListBlock *next;
|
||||
} ScanLineListBlock;
|
||||
|
||||
/*
|
||||
* number of points to buffer before sending them off
|
||||
* to scanlines() : Must be an even number
|
||||
*/
|
||||
#define NUMPTSTOBUFFER 200
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* a few macros for the inner loops of the fill code where
|
||||
* performance considerations don't allow a procedure call.
|
||||
*
|
||||
* Evaluate the given edge at the given scanline.
|
||||
* If the edge has expired, then we leave it and fix up
|
||||
* the active edge table; otherwise, we increment the
|
||||
* x value to be ready for the next scanline.
|
||||
* The winding number rule is in effect, so we must notify
|
||||
* the caller when the edge has been removed so he
|
||||
* can reorder the Winding Active Edge Table.
|
||||
*/
|
||||
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
|
||||
if (pAET->ymax == y) { /* leaving this edge */ \
|
||||
pPrevAET->next = pAET->next; \
|
||||
pAET = pPrevAET->next; \
|
||||
fixWAET = 1; \
|
||||
if (pAET) \
|
||||
pAET->back = pPrevAET; \
|
||||
} \
|
||||
else { \
|
||||
BRESINCRPGONSTRUCT(pAET->bres); \
|
||||
pPrevAET = pAET; \
|
||||
pAET = pAET->next; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Evaluate the given edge at the given scanline.
|
||||
* If the edge has expired, then we leave it and fix up
|
||||
* the active edge table; otherwise, we increment the
|
||||
* x value to be ready for the next scanline.
|
||||
* The even-odd rule is in effect.
|
||||
*/
|
||||
#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
|
||||
if (pAET->ymax == y) { /* leaving this edge */ \
|
||||
pPrevAET->next = pAET->next; \
|
||||
pAET = pPrevAET->next; \
|
||||
if (pAET) \
|
||||
pAET->back = pPrevAET; \
|
||||
} \
|
||||
else { \
|
||||
BRESINCRPGONSTRUCT(pAET->bres); \
|
||||
pPrevAET = pAET; \
|
||||
pAET = pAET->next; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* mipolyutil.c */
|
||||
|
||||
extern Bool miInsertEdgeInET(
|
||||
EdgeTable * /*ET*/,
|
||||
EdgeTableEntry * /*ETE*/,
|
||||
int /*scanline*/,
|
||||
ScanLineListBlock ** /*SLLBlock*/,
|
||||
int * /*iSLLBlock*/
|
||||
);
|
||||
|
||||
extern Bool miCreateETandAET(
|
||||
int /*count*/,
|
||||
DDXPointPtr /*pts*/,
|
||||
EdgeTable * /*ET*/,
|
||||
EdgeTableEntry * /*AET*/,
|
||||
EdgeTableEntry * /*pETEs*/,
|
||||
ScanLineListBlock * /*pSLLBlock*/
|
||||
);
|
||||
|
||||
extern void miloadAET(
|
||||
EdgeTableEntry * /*AET*/,
|
||||
EdgeTableEntry * /*ETEs*/
|
||||
);
|
||||
|
||||
extern void micomputeWAET(
|
||||
EdgeTableEntry * /*AET*/
|
||||
);
|
||||
|
||||
extern int miInsertionSort(
|
||||
EdgeTableEntry * /*AET*/
|
||||
);
|
||||
|
||||
extern void miFreeStorage(
|
||||
ScanLineListBlock * /*pSLLBlock*/
|
||||
);
|
||||
246
nx-X11/programs/Xserver/mi/mipolycon.c
Normal file
246
nx-X11/programs/Xserver/mi/mipolycon.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "gcstruct.h"
|
||||
#include "pixmap.h"
|
||||
#include "mi.h"
|
||||
#include "miscanfill.h"
|
||||
|
||||
static int getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty);
|
||||
|
||||
/*
|
||||
* convexpoly.c
|
||||
*
|
||||
* Written by Brian Kelleher; Dec. 1985.
|
||||
*
|
||||
* Fill a convex polygon. If the given polygon
|
||||
* is not convex, then the result is undefined.
|
||||
* The algorithm is to order the edges from smallest
|
||||
* y to largest by partitioning the array into a left
|
||||
* edge list and a right edge list. The algorithm used
|
||||
* to traverse each edge is an extension of Bresenham's
|
||||
* line algorithm with y as the major axis.
|
||||
* For a derivation of the algorithm, see the author of
|
||||
* this code.
|
||||
*/
|
||||
Bool
|
||||
miFillConvexPoly(dst, pgc, count, ptsIn)
|
||||
DrawablePtr dst;
|
||||
GCPtr pgc;
|
||||
int count; /* number of points */
|
||||
DDXPointPtr ptsIn; /* the points */
|
||||
{
|
||||
register int xl = 0, xr = 0; /* x vals of left and right edges */
|
||||
register int dl = 0, dr = 0; /* decision variables */
|
||||
register int ml = 0, m1l = 0;/* left edge slope and slope+1 */
|
||||
int mr = 0, m1r = 0; /* right edge slope and slope+1 */
|
||||
int incr1l = 0, incr2l = 0; /* left edge error increments */
|
||||
int incr1r = 0, incr2r = 0; /* right edge error increments */
|
||||
int dy; /* delta y */
|
||||
int y; /* current scanline */
|
||||
int left, right; /* indices to first endpoints */
|
||||
int i; /* loop counter */
|
||||
int nextleft, nextright; /* indices to second endpoints */
|
||||
DDXPointPtr ptsOut, FirstPoint; /* output buffer */
|
||||
int *width, *FirstWidth; /* output buffer */
|
||||
int imin; /* index of smallest vertex (in y) */
|
||||
int ymin; /* y-extents of polygon */
|
||||
int ymax;
|
||||
|
||||
/*
|
||||
* find leftx, bottomy, rightx, topy, and the index
|
||||
* of bottomy. Also translate the points.
|
||||
*/
|
||||
imin = getPolyYBounds(ptsIn, count, &ymin, &ymax);
|
||||
|
||||
dy = ymax - ymin + 1;
|
||||
if ((count < 3) || (dy < 0))
|
||||
return(TRUE);
|
||||
ptsOut = FirstPoint = (DDXPointPtr )malloc(sizeof(DDXPointRec)*dy);
|
||||
width = FirstWidth = (int *)malloc(sizeof(int) * dy);
|
||||
if(!FirstPoint || !FirstWidth)
|
||||
{
|
||||
if (FirstWidth) free(FirstWidth);
|
||||
if (FirstPoint) free(FirstPoint);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
nextleft = nextright = imin;
|
||||
y = ptsIn[nextleft].y;
|
||||
|
||||
/*
|
||||
* loop through all edges of the polygon
|
||||
*/
|
||||
do {
|
||||
/*
|
||||
* add a left edge if we need to
|
||||
*/
|
||||
if (ptsIn[nextleft].y == y) {
|
||||
left = nextleft;
|
||||
|
||||
/*
|
||||
* find the next edge, considering the end
|
||||
* conditions of the array.
|
||||
*/
|
||||
nextleft++;
|
||||
if (nextleft >= count)
|
||||
nextleft = 0;
|
||||
|
||||
/*
|
||||
* now compute all of the random information
|
||||
* needed to run the iterative algorithm.
|
||||
*/
|
||||
BRESINITPGON(ptsIn[nextleft].y-ptsIn[left].y,
|
||||
ptsIn[left].x,ptsIn[nextleft].x,
|
||||
xl, dl, ml, m1l, incr1l, incr2l);
|
||||
}
|
||||
|
||||
/*
|
||||
* add a right edge if we need to
|
||||
*/
|
||||
if (ptsIn[nextright].y == y) {
|
||||
right = nextright;
|
||||
|
||||
/*
|
||||
* find the next edge, considering the end
|
||||
* conditions of the array.
|
||||
*/
|
||||
nextright--;
|
||||
if (nextright < 0)
|
||||
nextright = count-1;
|
||||
|
||||
/*
|
||||
* now compute all of the random information
|
||||
* needed to run the iterative algorithm.
|
||||
*/
|
||||
BRESINITPGON(ptsIn[nextright].y-ptsIn[right].y,
|
||||
ptsIn[right].x,ptsIn[nextright].x,
|
||||
xr, dr, mr, m1r, incr1r, incr2r);
|
||||
}
|
||||
|
||||
/*
|
||||
* generate scans to fill while we still have
|
||||
* a right edge as well as a left edge.
|
||||
*/
|
||||
i = min(ptsIn[nextleft].y, ptsIn[nextright].y) - y;
|
||||
/* in case we're called with non-convex polygon */
|
||||
if(i < 0)
|
||||
{
|
||||
free(FirstWidth);
|
||||
free(FirstPoint);
|
||||
return(TRUE);
|
||||
}
|
||||
while (i-- > 0)
|
||||
{
|
||||
ptsOut->y = y;
|
||||
|
||||
/*
|
||||
* reverse the edges if necessary
|
||||
*/
|
||||
if (xl < xr)
|
||||
{
|
||||
*(width++) = xr - xl;
|
||||
(ptsOut++)->x = xl;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(width++) = xl - xr;
|
||||
(ptsOut++)->x = xr;
|
||||
}
|
||||
y++;
|
||||
|
||||
/* increment down the edges */
|
||||
BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l);
|
||||
BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r);
|
||||
}
|
||||
} while (y != ymax);
|
||||
|
||||
/*
|
||||
* Finally, fill the <remaining> spans
|
||||
*/
|
||||
(*pgc->ops->FillSpans)(dst, pgc,
|
||||
ptsOut-FirstPoint,FirstPoint,FirstWidth,
|
||||
1);
|
||||
free(FirstWidth);
|
||||
free(FirstPoint);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find the index of the point with the smallest y.
|
||||
*/
|
||||
static int
|
||||
getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty)
|
||||
{
|
||||
register DDXPointPtr ptMin;
|
||||
int ymin, ymax;
|
||||
DDXPointPtr ptsStart = pts;
|
||||
|
||||
ptMin = pts;
|
||||
ymin = ymax = (pts++)->y;
|
||||
|
||||
while (--n > 0) {
|
||||
if (pts->y < ymin)
|
||||
{
|
||||
ptMin = pts;
|
||||
ymin = pts->y;
|
||||
}
|
||||
if(pts->y > ymax)
|
||||
ymax = pts->y;
|
||||
|
||||
pts++;
|
||||
}
|
||||
|
||||
*by = ymin;
|
||||
*ty = ymax;
|
||||
return(ptMin-ptsStart);
|
||||
}
|
||||
230
nx-X11/programs/Xserver/mi/mipolygen.c
Normal file
230
nx-X11/programs/Xserver/mi/mipolygen.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include "gcstruct.h"
|
||||
#include "miscanfill.h"
|
||||
#include "mipoly.h"
|
||||
#include "pixmap.h"
|
||||
#include "mi.h"
|
||||
|
||||
/*
|
||||
*
|
||||
* Written by Brian Kelleher; Oct. 1985
|
||||
*
|
||||
* Routine to fill a polygon. Two fill rules are
|
||||
* supported: frWINDING and frEVENODD.
|
||||
*
|
||||
* See fillpoly.h for a complete description of the algorithm.
|
||||
*/
|
||||
|
||||
Bool
|
||||
miFillGeneralPoly(dst, pgc, count, ptsIn)
|
||||
DrawablePtr dst;
|
||||
GCPtr pgc;
|
||||
int count; /* number of points */
|
||||
DDXPointPtr ptsIn; /* the points */
|
||||
{
|
||||
register EdgeTableEntry *pAET; /* the Active Edge Table */
|
||||
register int y; /* the current scanline */
|
||||
register int nPts = 0; /* number of pts in buffer */
|
||||
register EdgeTableEntry *pWETE; /* Winding Edge Table */
|
||||
register ScanLineList *pSLL; /* Current ScanLineList */
|
||||
register DDXPointPtr ptsOut; /* ptr to output buffers */
|
||||
int *width;
|
||||
DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
|
||||
int FirstWidth[NUMPTSTOBUFFER];
|
||||
EdgeTableEntry *pPrevAET; /* previous AET entry */
|
||||
EdgeTable ET; /* Edge Table header node */
|
||||
EdgeTableEntry AET; /* Active ET header node */
|
||||
EdgeTableEntry *pETEs; /* Edge Table Entries buff */
|
||||
ScanLineListBlock SLLBlock; /* header for ScanLineList */
|
||||
int fixWAET = 0;
|
||||
|
||||
if (count < 3)
|
||||
return(TRUE);
|
||||
|
||||
if(!(pETEs = (EdgeTableEntry *)
|
||||
malloc(sizeof(EdgeTableEntry) * count)))
|
||||
return(FALSE);
|
||||
ptsOut = FirstPoint;
|
||||
width = FirstWidth;
|
||||
if (!miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock))
|
||||
{
|
||||
free(pETEs);
|
||||
return(FALSE);
|
||||
}
|
||||
pSLL = ET.scanlines.next;
|
||||
|
||||
if (pgc->fillRule == EvenOddRule)
|
||||
{
|
||||
/*
|
||||
* for each scanline
|
||||
*/
|
||||
for (y = ET.ymin; y < ET.ymax; y++)
|
||||
{
|
||||
/*
|
||||
* Add a new edge to the active edge table when we
|
||||
* get to the next edge.
|
||||
*/
|
||||
if (pSLL && y == pSLL->scanline)
|
||||
{
|
||||
miloadAET(&AET, pSLL->edgelist);
|
||||
pSLL = pSLL->next;
|
||||
}
|
||||
pPrevAET = &AET;
|
||||
pAET = AET.next;
|
||||
|
||||
/*
|
||||
* for each active edge
|
||||
*/
|
||||
while (pAET)
|
||||
{
|
||||
ptsOut->x = pAET->bres.minor;
|
||||
ptsOut++->y = y;
|
||||
*width++ = pAET->next->bres.minor - pAET->bres.minor;
|
||||
nPts++;
|
||||
|
||||
/*
|
||||
* send out the buffer when its full
|
||||
*/
|
||||
if (nPts == NUMPTSTOBUFFER)
|
||||
{
|
||||
(*pgc->ops->FillSpans)(dst, pgc,
|
||||
nPts, FirstPoint, FirstWidth,
|
||||
1);
|
||||
ptsOut = FirstPoint;
|
||||
width = FirstWidth;
|
||||
nPts = 0;
|
||||
}
|
||||
EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
|
||||
EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
|
||||
}
|
||||
miInsertionSort(&AET);
|
||||
}
|
||||
}
|
||||
else /* default to WindingNumber */
|
||||
{
|
||||
/*
|
||||
* for each scanline
|
||||
*/
|
||||
for (y = ET.ymin; y < ET.ymax; y++)
|
||||
{
|
||||
/*
|
||||
* Add a new edge to the active edge table when we
|
||||
* get to the next edge.
|
||||
*/
|
||||
if (pSLL && y == pSLL->scanline)
|
||||
{
|
||||
miloadAET(&AET, pSLL->edgelist);
|
||||
micomputeWAET(&AET);
|
||||
pSLL = pSLL->next;
|
||||
}
|
||||
pPrevAET = &AET;
|
||||
pAET = AET.next;
|
||||
pWETE = pAET;
|
||||
|
||||
/*
|
||||
* for each active edge
|
||||
*/
|
||||
while (pAET)
|
||||
{
|
||||
/*
|
||||
* if the next edge in the active edge table is
|
||||
* also the next edge in the winding active edge
|
||||
* table.
|
||||
*/
|
||||
if (pWETE == pAET)
|
||||
{
|
||||
ptsOut->x = pAET->bres.minor;
|
||||
ptsOut++->y = y;
|
||||
*width++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
|
||||
nPts++;
|
||||
|
||||
/*
|
||||
* send out the buffer
|
||||
*/
|
||||
if (nPts == NUMPTSTOBUFFER)
|
||||
{
|
||||
(*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint,
|
||||
FirstWidth, 1);
|
||||
ptsOut = FirstPoint;
|
||||
width = FirstWidth;
|
||||
nPts = 0;
|
||||
}
|
||||
|
||||
pWETE = pWETE->nextWETE;
|
||||
while (pWETE != pAET)
|
||||
EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
|
||||
pWETE = pWETE->nextWETE;
|
||||
}
|
||||
EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
|
||||
}
|
||||
|
||||
/*
|
||||
* reevaluate the Winding active edge table if we
|
||||
* just had to resort it or if we just exited an edge.
|
||||
*/
|
||||
if (miInsertionSort(&AET) || fixWAET)
|
||||
{
|
||||
micomputeWAET(&AET);
|
||||
fixWAET = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get any spans that we missed by buffering
|
||||
*/
|
||||
(*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint, FirstWidth, 1);
|
||||
free(pETEs);
|
||||
miFreeStorage(SLLBlock.next);
|
||||
return(TRUE);
|
||||
}
|
||||
123
nx-X11/programs/Xserver/mi/mipolypnt.c
Normal file
123
nx-X11/programs/Xserver/mi/mipolypnt.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
#include "pixmapstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "windowstr.h"
|
||||
#include "mi.h"
|
||||
|
||||
void
|
||||
miPolyPoint(pDrawable, pGC, mode, npt, pptInit)
|
||||
DrawablePtr pDrawable;
|
||||
GCPtr pGC;
|
||||
int mode; /* Origin or Previous */
|
||||
int npt;
|
||||
xPoint *pptInit;
|
||||
{
|
||||
|
||||
int xorg;
|
||||
int yorg;
|
||||
int nptTmp;
|
||||
XID fsOld, fsNew;
|
||||
int *pwidthInit, *pwidth;
|
||||
int i;
|
||||
register xPoint *ppt;
|
||||
|
||||
/* make pointlist origin relative */
|
||||
if (mode == CoordModePrevious)
|
||||
{
|
||||
ppt = pptInit;
|
||||
nptTmp = npt;
|
||||
nptTmp--;
|
||||
while(nptTmp--)
|
||||
{
|
||||
ppt++;
|
||||
ppt->x += (ppt-1)->x;
|
||||
ppt->y += (ppt-1)->y;
|
||||
}
|
||||
}
|
||||
|
||||
if(pGC->miTranslate)
|
||||
{
|
||||
ppt = pptInit;
|
||||
nptTmp = npt;
|
||||
xorg = pDrawable->x;
|
||||
yorg = pDrawable->y;
|
||||
while(nptTmp--)
|
||||
{
|
||||
ppt->x += xorg;
|
||||
ppt++->y += yorg;
|
||||
}
|
||||
}
|
||||
|
||||
fsOld = pGC->fillStyle;
|
||||
fsNew = FillSolid;
|
||||
if(pGC->fillStyle != FillSolid)
|
||||
{
|
||||
DoChangeGC(pGC, GCFillStyle, &fsNew, 0);
|
||||
ValidateGC(pDrawable, pGC);
|
||||
}
|
||||
if(!(pwidthInit = (int *)malloc(npt * sizeof(int))))
|
||||
return;
|
||||
pwidth = pwidthInit;
|
||||
for(i = 0; i < npt; i++)
|
||||
*pwidth++ = 1;
|
||||
(*pGC->ops->FillSpans)(pDrawable, pGC, npt, pptInit, pwidthInit, FALSE);
|
||||
|
||||
if(fsOld != FillSolid)
|
||||
{
|
||||
DoChangeGC(pGC, GCFillStyle, &fsOld, 0);
|
||||
ValidateGC(pDrawable, pGC);
|
||||
}
|
||||
free(pwidthInit);
|
||||
}
|
||||
|
||||
191
nx-X11/programs/Xserver/mi/mipolyrect.c
Normal file
191
nx-X11/programs/Xserver/mi/mipolyrect.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
#include "regionstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmap.h"
|
||||
#include "mi.h"
|
||||
|
||||
void
|
||||
miPolyRectangle(pDraw, pGC, nrects, pRects)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int nrects;
|
||||
xRectangle *pRects;
|
||||
{
|
||||
int i;
|
||||
xRectangle *pR = pRects;
|
||||
DDXPointRec rect[5];
|
||||
int bound_tmp;
|
||||
|
||||
#define MINBOUND(dst,eqn) bound_tmp = eqn; \
|
||||
if (bound_tmp < -32768) \
|
||||
bound_tmp = -32768; \
|
||||
dst = bound_tmp;
|
||||
|
||||
#define MAXBOUND(dst,eqn) bound_tmp = eqn; \
|
||||
if (bound_tmp > 32767) \
|
||||
bound_tmp = 32767; \
|
||||
dst = bound_tmp;
|
||||
|
||||
#define MAXUBOUND(dst,eqn) bound_tmp = eqn; \
|
||||
if (bound_tmp > 65535) \
|
||||
bound_tmp = 65535; \
|
||||
dst = bound_tmp;
|
||||
|
||||
if (pGC->lineStyle == LineSolid && pGC->joinStyle == JoinMiter &&
|
||||
pGC->lineWidth != 0)
|
||||
{
|
||||
xRectangle *tmp, *t;
|
||||
int ntmp;
|
||||
int offset1, offset2, offset3;
|
||||
int x, y, width, height;
|
||||
|
||||
ntmp = (nrects << 2);
|
||||
offset2 = pGC->lineWidth;
|
||||
offset1 = offset2 >> 1;
|
||||
offset3 = offset2 - offset1;
|
||||
tmp = (xRectangle *) malloc(ntmp * sizeof (xRectangle));
|
||||
if (!tmp)
|
||||
return;
|
||||
t = tmp;
|
||||
for (i = 0; i < nrects; i++)
|
||||
{
|
||||
x = pR->x;
|
||||
y = pR->y;
|
||||
width = pR->width;
|
||||
height = pR->height;
|
||||
pR++;
|
||||
if (width == 0 && height == 0)
|
||||
{
|
||||
rect[0].x = x;
|
||||
rect[0].y = y;
|
||||
rect[1].x = x;
|
||||
rect[1].y = y;
|
||||
(*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2, rect);
|
||||
}
|
||||
else if (height < offset2 || width < offset1)
|
||||
{
|
||||
if (height == 0)
|
||||
{
|
||||
t->x = x;
|
||||
t->width = width;
|
||||
}
|
||||
else
|
||||
{
|
||||
MINBOUND (t->x, x - offset1)
|
||||
MAXUBOUND (t->width, width + offset2)
|
||||
}
|
||||
if (width == 0)
|
||||
{
|
||||
t->y = y;
|
||||
t->height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
MINBOUND (t->y, y - offset1)
|
||||
MAXUBOUND (t->height, height + offset2)
|
||||
}
|
||||
t++;
|
||||
}
|
||||
else
|
||||
{
|
||||
MINBOUND(t->x, x - offset1)
|
||||
MINBOUND(t->y, y - offset1)
|
||||
MAXUBOUND(t->width, width + offset2)
|
||||
t->height = offset2;
|
||||
t++;
|
||||
MINBOUND(t->x, x - offset1)
|
||||
MAXBOUND(t->y, y + offset3);
|
||||
t->width = offset2;
|
||||
t->height = height - offset2;
|
||||
t++;
|
||||
MAXBOUND(t->x, x + width - offset1);
|
||||
MAXBOUND(t->y, y + offset3)
|
||||
t->width = offset2;
|
||||
t->height = height - offset2;
|
||||
t++;
|
||||
MINBOUND(t->x, x - offset1)
|
||||
MAXBOUND(t->y, y + height - offset1)
|
||||
MAXUBOUND(t->width, width + offset2)
|
||||
t->height = offset2;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
(*pGC->ops->PolyFillRect) (pDraw, pGC, t - tmp, tmp);
|
||||
free ((void *) tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for (i=0; i<nrects; i++)
|
||||
{
|
||||
rect[0].x = pR->x;
|
||||
rect[0].y = pR->y;
|
||||
|
||||
MAXBOUND(rect[1].x, pR->x + (int) pR->width)
|
||||
rect[1].y = rect[0].y;
|
||||
|
||||
rect[2].x = rect[1].x;
|
||||
MAXBOUND(rect[2].y, pR->y + (int) pR->height);
|
||||
|
||||
rect[3].x = rect[0].x;
|
||||
rect[3].y = rect[2].y;
|
||||
|
||||
rect[4].x = rect[0].x;
|
||||
rect[4].y = rect[0].y;
|
||||
|
||||
(*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 5, rect);
|
||||
pR++;
|
||||
}
|
||||
}
|
||||
}
|
||||
83
nx-X11/programs/Xserver/mi/mipolyseg.c
Normal file
83
nx-X11/programs/Xserver/mi/mipolyseg.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
#include "regionstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmap.h"
|
||||
#include "mi.h"
|
||||
|
||||
/*****************************************************************
|
||||
* miPolySegment
|
||||
*
|
||||
* For each segment, draws a line between (x1, y1) and (x2, y2). The
|
||||
* lines are drawn in the order listed.
|
||||
*
|
||||
* Walks the segments, compressing them into format for PolyLines.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
|
||||
void
|
||||
miPolySegment(pDraw, pGC, nseg, pSegs)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int nseg;
|
||||
xSegment *pSegs;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<nseg; i++)
|
||||
{
|
||||
(*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2,(DDXPointPtr)pSegs);
|
||||
pSegs++;
|
||||
}
|
||||
}
|
||||
200
nx-X11/programs/Xserver/mi/mipolytext.c
Normal file
200
nx-X11/programs/Xserver/mi/mipolytext.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/*******************************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
************************************************************************/
|
||||
/*
|
||||
* mipolytext.c - text routines
|
||||
*
|
||||
* Author: haynes
|
||||
* Digital Equipment Corporation
|
||||
* Western Software Laboratory
|
||||
* Date: Thu Feb 5 1987
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xmd.h>
|
||||
#include <nx-X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "gcstruct.h"
|
||||
#include <X11/fonts/fontstruct.h>
|
||||
#include "dixfontstr.h"
|
||||
#include "mi.h"
|
||||
|
||||
int
|
||||
miPolyText(pDraw, pGC, x, y, count, chars, fontEncoding)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int x, y;
|
||||
int count;
|
||||
char *chars;
|
||||
FontEncoding fontEncoding;
|
||||
{
|
||||
unsigned long n, i;
|
||||
int w;
|
||||
CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
|
||||
|
||||
GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
|
||||
fontEncoding, &n, charinfo);
|
||||
w = 0;
|
||||
for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
|
||||
if (n != 0)
|
||||
(*pGC->ops->PolyGlyphBlt)(
|
||||
pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
|
||||
return x+w;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
miPolyText8(pDraw, pGC, x, y, count, chars)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int x, y;
|
||||
int count;
|
||||
char *chars;
|
||||
{
|
||||
unsigned long n, i;
|
||||
int w;
|
||||
CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
|
||||
|
||||
GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
|
||||
Linear8Bit, &n, charinfo);
|
||||
w = 0;
|
||||
for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
|
||||
if (n != 0)
|
||||
(*pGC->ops->PolyGlyphBlt)(
|
||||
pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
|
||||
return x+w;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
miPolyText16(pDraw, pGC, x, y, count, chars)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int x, y;
|
||||
int count;
|
||||
unsigned short *chars;
|
||||
{
|
||||
unsigned long n, i;
|
||||
int w;
|
||||
CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
|
||||
|
||||
GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
|
||||
(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
|
||||
&n, charinfo);
|
||||
w = 0;
|
||||
for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
|
||||
if (n != 0)
|
||||
(*pGC->ops->PolyGlyphBlt)(
|
||||
pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
|
||||
return x+w;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
miImageText(pDraw, pGC, x, y, count, chars, fontEncoding)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int x, y;
|
||||
int count;
|
||||
char *chars;
|
||||
FontEncoding fontEncoding;
|
||||
{
|
||||
unsigned long n, i;
|
||||
FontPtr font = pGC->font;
|
||||
int w;
|
||||
CharInfoPtr charinfo[255];
|
||||
|
||||
GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
|
||||
fontEncoding, &n, charinfo);
|
||||
w = 0;
|
||||
for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
|
||||
if (n !=0 )
|
||||
(*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
|
||||
return x+w;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
miImageText8(pDraw, pGC, x, y, count, chars)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int x, y;
|
||||
int count;
|
||||
char *chars;
|
||||
{
|
||||
unsigned long n;
|
||||
FontPtr font = pGC->font;
|
||||
CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
|
||||
|
||||
GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
|
||||
Linear8Bit, &n, charinfo);
|
||||
if (n !=0 )
|
||||
(*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
miImageText16(pDraw, pGC, x, y, count, chars)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int x, y;
|
||||
int count;
|
||||
unsigned short *chars;
|
||||
{
|
||||
unsigned long n;
|
||||
FontPtr font = pGC->font;
|
||||
CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
|
||||
|
||||
GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
|
||||
(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
|
||||
&n, charinfo);
|
||||
if (n !=0 )
|
||||
(*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
|
||||
}
|
||||
399
nx-X11/programs/Xserver/mi/mipolyutil.c
Normal file
399
nx-X11/programs/Xserver/mi/mipolyutil.c
Normal file
@@ -0,0 +1,399 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "regionstr.h"
|
||||
#include "gc.h"
|
||||
#include "miscanfill.h"
|
||||
#include "mipoly.h"
|
||||
#include "misc.h" /* MAXINT */
|
||||
|
||||
/*
|
||||
* fillUtils.c
|
||||
*
|
||||
* Written by Brian Kelleher; Oct. 1985
|
||||
*
|
||||
* This module contains all of the utility functions
|
||||
* needed to scan convert a polygon.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* InsertEdgeInET
|
||||
*
|
||||
* Insert the given edge into the edge table.
|
||||
* First we must find the correct bucket in the
|
||||
* Edge table, then find the right slot in the
|
||||
* bucket. Finally, we can insert it.
|
||||
*
|
||||
*/
|
||||
Bool
|
||||
miInsertEdgeInET(ET, ETE, scanline, SLLBlock, iSLLBlock)
|
||||
EdgeTable *ET;
|
||||
EdgeTableEntry *ETE;
|
||||
int scanline;
|
||||
ScanLineListBlock **SLLBlock;
|
||||
int *iSLLBlock;
|
||||
{
|
||||
register EdgeTableEntry *start, *prev;
|
||||
register ScanLineList *pSLL, *pPrevSLL;
|
||||
ScanLineListBlock *tmpSLLBlock;
|
||||
|
||||
/*
|
||||
* find the right bucket to put the edge into
|
||||
*/
|
||||
pPrevSLL = &ET->scanlines;
|
||||
pSLL = pPrevSLL->next;
|
||||
while (pSLL && (pSLL->scanline < scanline))
|
||||
{
|
||||
pPrevSLL = pSLL;
|
||||
pSLL = pSLL->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* reassign pSLL (pointer to ScanLineList) if necessary
|
||||
*/
|
||||
if ((!pSLL) || (pSLL->scanline > scanline))
|
||||
{
|
||||
if (*iSLLBlock > SLLSPERBLOCK-1)
|
||||
{
|
||||
tmpSLLBlock =
|
||||
(ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
|
||||
if (!tmpSLLBlock)
|
||||
return FALSE;
|
||||
(*SLLBlock)->next = tmpSLLBlock;
|
||||
tmpSLLBlock->next = (ScanLineListBlock *)NULL;
|
||||
*SLLBlock = tmpSLLBlock;
|
||||
*iSLLBlock = 0;
|
||||
}
|
||||
pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
|
||||
|
||||
pSLL->next = pPrevSLL->next;
|
||||
pSLL->edgelist = (EdgeTableEntry *)NULL;
|
||||
pPrevSLL->next = pSLL;
|
||||
}
|
||||
pSLL->scanline = scanline;
|
||||
|
||||
/*
|
||||
* now insert the edge in the right bucket
|
||||
*/
|
||||
prev = (EdgeTableEntry *)NULL;
|
||||
start = pSLL->edgelist;
|
||||
while (start && (start->bres.minor < ETE->bres.minor))
|
||||
{
|
||||
prev = start;
|
||||
start = start->next;
|
||||
}
|
||||
ETE->next = start;
|
||||
|
||||
if (prev)
|
||||
prev->next = ETE;
|
||||
else
|
||||
pSLL->edgelist = ETE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateEdgeTable
|
||||
*
|
||||
* This routine creates the edge table for
|
||||
* scan converting polygons.
|
||||
* The Edge Table (ET) looks like:
|
||||
*
|
||||
* EdgeTable
|
||||
* --------
|
||||
* | ymax | ScanLineLists
|
||||
* |scanline|-->------------>-------------->...
|
||||
* -------- |scanline| |scanline|
|
||||
* |edgelist| |edgelist|
|
||||
* --------- ---------
|
||||
* | |
|
||||
* | |
|
||||
* V V
|
||||
* list of ETEs list of ETEs
|
||||
*
|
||||
* where ETE is an EdgeTableEntry data structure,
|
||||
* and there is one ScanLineList per scanline at
|
||||
* which an edge is initially entered.
|
||||
*
|
||||
*/
|
||||
|
||||
Bool
|
||||
miCreateETandAET(count, pts, ET, AET, pETEs, pSLLBlock)
|
||||
register int count;
|
||||
register DDXPointPtr pts;
|
||||
EdgeTable *ET;
|
||||
EdgeTableEntry *AET;
|
||||
register EdgeTableEntry *pETEs;
|
||||
ScanLineListBlock *pSLLBlock;
|
||||
{
|
||||
register DDXPointPtr top, bottom;
|
||||
register DDXPointPtr PrevPt, CurrPt;
|
||||
int iSLLBlock = 0;
|
||||
|
||||
int dy;
|
||||
|
||||
if (count < 2) return TRUE;
|
||||
|
||||
/*
|
||||
* initialize the Active Edge Table
|
||||
*/
|
||||
AET->next = (EdgeTableEntry *)NULL;
|
||||
AET->back = (EdgeTableEntry *)NULL;
|
||||
AET->nextWETE = (EdgeTableEntry *)NULL;
|
||||
AET->bres.minor = MININT;
|
||||
|
||||
/*
|
||||
* initialize the Edge Table.
|
||||
*/
|
||||
ET->scanlines.next = (ScanLineList *)NULL;
|
||||
ET->ymax = MININT;
|
||||
ET->ymin = MAXINT;
|
||||
pSLLBlock->next = (ScanLineListBlock *)NULL;
|
||||
|
||||
PrevPt = &pts[count-1];
|
||||
|
||||
/*
|
||||
* for each vertex in the array of points.
|
||||
* In this loop we are dealing with two vertices at
|
||||
* a time -- these make up one edge of the polygon.
|
||||
*/
|
||||
while (count--)
|
||||
{
|
||||
CurrPt = pts++;
|
||||
|
||||
/*
|
||||
* find out which point is above and which is below.
|
||||
*/
|
||||
if (PrevPt->y > CurrPt->y)
|
||||
{
|
||||
bottom = PrevPt, top = CurrPt;
|
||||
pETEs->ClockWise = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bottom = CurrPt, top = PrevPt;
|
||||
pETEs->ClockWise = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* don't add horizontal edges to the Edge table.
|
||||
*/
|
||||
if (bottom->y != top->y)
|
||||
{
|
||||
pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */
|
||||
|
||||
/*
|
||||
* initialize integer edge algorithm
|
||||
*/
|
||||
dy = bottom->y - top->y;
|
||||
BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
|
||||
|
||||
if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
|
||||
{
|
||||
miFreeStorage(pSLLBlock->next);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ET->ymax = max(ET->ymax, PrevPt->y);
|
||||
ET->ymin = min(ET->ymin, PrevPt->y);
|
||||
pETEs++;
|
||||
}
|
||||
|
||||
PrevPt = CurrPt;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* loadAET
|
||||
*
|
||||
* This routine moves EdgeTableEntries from the
|
||||
* EdgeTable into the Active Edge Table,
|
||||
* leaving them sorted by smaller x coordinate.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
miloadAET(AET, ETEs)
|
||||
register EdgeTableEntry *AET, *ETEs;
|
||||
{
|
||||
register EdgeTableEntry *pPrevAET;
|
||||
register EdgeTableEntry *tmp;
|
||||
|
||||
pPrevAET = AET;
|
||||
AET = AET->next;
|
||||
while (ETEs)
|
||||
{
|
||||
while (AET && (AET->bres.minor < ETEs->bres.minor))
|
||||
{
|
||||
pPrevAET = AET;
|
||||
AET = AET->next;
|
||||
}
|
||||
tmp = ETEs->next;
|
||||
ETEs->next = AET;
|
||||
if (AET)
|
||||
AET->back = ETEs;
|
||||
ETEs->back = pPrevAET;
|
||||
pPrevAET->next = ETEs;
|
||||
pPrevAET = ETEs;
|
||||
|
||||
ETEs = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* computeWAET
|
||||
*
|
||||
* This routine links the AET by the
|
||||
* nextWETE (winding EdgeTableEntry) link for
|
||||
* use by the winding number rule. The final
|
||||
* Active Edge Table (AET) might look something
|
||||
* like:
|
||||
*
|
||||
* AET
|
||||
* ---------- --------- ---------
|
||||
* |ymax | |ymax | |ymax |
|
||||
* | ... | |... | |... |
|
||||
* |next |->|next |->|next |->...
|
||||
* |nextWETE| |nextWETE| |nextWETE|
|
||||
* --------- --------- ^--------
|
||||
* | | |
|
||||
* V-------------------> V---> ...
|
||||
*
|
||||
*/
|
||||
void
|
||||
micomputeWAET(AET)
|
||||
register EdgeTableEntry *AET;
|
||||
{
|
||||
register EdgeTableEntry *pWETE;
|
||||
register int inside = 1;
|
||||
register int isInside = 0;
|
||||
|
||||
AET->nextWETE = (EdgeTableEntry *)NULL;
|
||||
pWETE = AET;
|
||||
AET = AET->next;
|
||||
while (AET)
|
||||
{
|
||||
if (AET->ClockWise)
|
||||
isInside++;
|
||||
else
|
||||
isInside--;
|
||||
|
||||
if ((!inside && !isInside) ||
|
||||
( inside && isInside))
|
||||
{
|
||||
pWETE->nextWETE = AET;
|
||||
pWETE = AET;
|
||||
inside = !inside;
|
||||
}
|
||||
AET = AET->next;
|
||||
}
|
||||
pWETE->nextWETE = (EdgeTableEntry *)NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* InsertionSort
|
||||
*
|
||||
* Just a simple insertion sort using
|
||||
* pointers and back pointers to sort the Active
|
||||
* Edge Table.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
miInsertionSort(AET)
|
||||
register EdgeTableEntry *AET;
|
||||
{
|
||||
register EdgeTableEntry *pETEchase;
|
||||
register EdgeTableEntry *pETEinsert;
|
||||
register EdgeTableEntry *pETEchaseBackTMP;
|
||||
register int changed = 0;
|
||||
|
||||
AET = AET->next;
|
||||
while (AET)
|
||||
{
|
||||
pETEinsert = AET;
|
||||
pETEchase = AET;
|
||||
while (pETEchase->back->bres.minor > AET->bres.minor)
|
||||
pETEchase = pETEchase->back;
|
||||
|
||||
AET = AET->next;
|
||||
if (pETEchase != pETEinsert)
|
||||
{
|
||||
pETEchaseBackTMP = pETEchase->back;
|
||||
pETEinsert->back->next = AET;
|
||||
if (AET)
|
||||
AET->back = pETEinsert->back;
|
||||
pETEinsert->next = pETEchase;
|
||||
pETEchase->back->next = pETEinsert;
|
||||
pETEchase->back = pETEinsert;
|
||||
pETEinsert->back = pETEchaseBackTMP;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
return(changed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up our act.
|
||||
*/
|
||||
void
|
||||
miFreeStorage(pSLLBlock)
|
||||
register ScanLineListBlock *pSLLBlock;
|
||||
{
|
||||
register ScanLineListBlock *tmpSLLBlock;
|
||||
|
||||
while (pSLLBlock)
|
||||
{
|
||||
tmpSLLBlock = pSLLBlock->next;
|
||||
free(pSLLBlock);
|
||||
pSLLBlock = tmpSLLBlock;
|
||||
}
|
||||
}
|
||||
274
nx-X11/programs/Xserver/mi/mipushpxl.c
Normal file
274
nx-X11/programs/Xserver/mi/mipushpxl.c
Normal file
@@ -0,0 +1,274 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include "gcstruct.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "regionstr.h"
|
||||
#include "mi.h"
|
||||
#include "servermd.h"
|
||||
|
||||
#define NPT 128
|
||||
|
||||
/* These were stolen from mfb. They don't really belong here. */
|
||||
#define LONG2CHARSSAMEORDER(x) ((MiBits)(x))
|
||||
#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \
|
||||
| ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \
|
||||
| ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \
|
||||
| ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) )
|
||||
|
||||
|
||||
#define PGSZB 4
|
||||
#define PPW (PGSZB<<3) /* assuming 8 bits per byte */
|
||||
#define PGSZ PPW
|
||||
#define PLST (PPW-1)
|
||||
#define PIM PLST
|
||||
#define PWSH 5
|
||||
|
||||
/* miPushPixels -- squeegees the fill style of pGC through pBitMap
|
||||
* into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
|
||||
* be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
|
||||
* is set in the bitmap, the fill style is put onto the drawable using
|
||||
* the GC's logical function. The drawable is not changed where the bitmap
|
||||
* has a zero bit or outside the area covered by the stencil.
|
||||
|
||||
WARNING:
|
||||
this code works if the 1-bit deep pixmap format returned by GetSpans
|
||||
is the same as the format defined by the mfb code (i.e. 32-bit padding
|
||||
per scanline, scanline unit = 32 bits; later, this might mean
|
||||
bitsizeof(int) padding and sacnline unit == bitsizeof(int).)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* in order to have both (MSB_FIRST and LSB_FIRST) versions of this
|
||||
* in the server, we need to rename one of them
|
||||
*/
|
||||
void
|
||||
miPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
|
||||
GCPtr pGC;
|
||||
PixmapPtr pBitMap;
|
||||
DrawablePtr pDrawable;
|
||||
int dx, dy, xOrg, yOrg;
|
||||
{
|
||||
int h, dxDivPPW, ibEnd;
|
||||
MiBits *pwLineStart;
|
||||
register MiBits *pw, *pwEnd;
|
||||
register MiBits msk;
|
||||
register int ib, w;
|
||||
register int ipt; /* index into above arrays */
|
||||
Bool fInBox;
|
||||
DDXPointRec pt[NPT], ptThisLine;
|
||||
int width[NPT];
|
||||
#ifdef XFree86Server
|
||||
MiBits startmask;
|
||||
if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
|
||||
if (screenInfo.bitmapBitOrder == LSBFirst)
|
||||
startmask = (MiBits)(-1) ^
|
||||
LONG2CHARSSAMEORDER((MiBits)(-1) << 1);
|
||||
else
|
||||
startmask = (MiBits)(-1) ^
|
||||
LONG2CHARSSAMEORDER((MiBits)(-1) >> 1);
|
||||
else
|
||||
if (screenInfo.bitmapBitOrder == LSBFirst)
|
||||
startmask = (MiBits)(-1) ^
|
||||
LONG2CHARSDIFFORDER((MiBits)(-1) << 1);
|
||||
else
|
||||
startmask = (MiBits)(-1) ^
|
||||
LONG2CHARSDIFFORDER((MiBits)(-1) >> 1);
|
||||
#endif
|
||||
|
||||
pwLineStart = (MiBits *)malloc(BitmapBytePad(dx));
|
||||
if (!pwLineStart)
|
||||
return;
|
||||
ipt = 0;
|
||||
dxDivPPW = dx/PPW;
|
||||
|
||||
for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0;
|
||||
h < dy;
|
||||
h++, ptThisLine.y++)
|
||||
{
|
||||
|
||||
(*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx,
|
||||
&ptThisLine, &dx, 1, (char *)pwLineStart);
|
||||
|
||||
pw = pwLineStart;
|
||||
/* Process all words which are fully in the pixmap */
|
||||
|
||||
fInBox = FALSE;
|
||||
pwEnd = pwLineStart + dxDivPPW;
|
||||
while(pw < pwEnd)
|
||||
{
|
||||
w = *pw;
|
||||
#ifdef XFree86Server
|
||||
msk = startmask;
|
||||
#else
|
||||
msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
|
||||
#endif
|
||||
for(ib = 0; ib < PPW; ib++)
|
||||
{
|
||||
if(w & msk)
|
||||
{
|
||||
if(!fInBox)
|
||||
{
|
||||
pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
|
||||
pt[ipt].y = h + yOrg;
|
||||
/* start new box */
|
||||
fInBox = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fInBox)
|
||||
{
|
||||
width[ipt] = ((pw - pwLineStart) << PWSH) +
|
||||
ib + xOrg - pt[ipt].x;
|
||||
if (++ipt >= NPT)
|
||||
{
|
||||
(*pGC->ops->FillSpans)(pDrawable, pGC,
|
||||
NPT, pt, width, TRUE);
|
||||
ipt = 0;
|
||||
}
|
||||
/* end box */
|
||||
fInBox = FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef XFree86Server
|
||||
/* This is not quite right, but it'll do for now */
|
||||
if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
|
||||
if (screenInfo.bitmapBitOrder == LSBFirst)
|
||||
msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
|
||||
else
|
||||
msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
|
||||
else
|
||||
if (screenInfo.bitmapBitOrder == LSBFirst)
|
||||
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
|
||||
else
|
||||
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
|
||||
#else
|
||||
msk = SCRRIGHT(msk, 1);
|
||||
#endif
|
||||
}
|
||||
pw++;
|
||||
}
|
||||
ibEnd = dx & PIM;
|
||||
if(ibEnd)
|
||||
{
|
||||
/* Process final partial word on line */
|
||||
w = *pw;
|
||||
#ifdef XFree86Server
|
||||
msk = startmask;
|
||||
#else
|
||||
msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
|
||||
#endif
|
||||
for(ib = 0; ib < ibEnd; ib++)
|
||||
{
|
||||
if(w & msk)
|
||||
{
|
||||
if(!fInBox)
|
||||
{
|
||||
/* start new box */
|
||||
pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
|
||||
pt[ipt].y = h + yOrg;
|
||||
fInBox = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fInBox)
|
||||
{
|
||||
/* end box */
|
||||
width[ipt] = ((pw - pwLineStart) << PWSH) +
|
||||
ib + xOrg - pt[ipt].x;
|
||||
if (++ipt >= NPT)
|
||||
{
|
||||
(*pGC->ops->FillSpans)(pDrawable,
|
||||
pGC, NPT, pt, width, TRUE);
|
||||
ipt = 0;
|
||||
}
|
||||
fInBox = FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef XFree86Server
|
||||
/* This is not quite right, but it'll do for now */
|
||||
if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
|
||||
if (screenInfo.bitmapBitOrder == LSBFirst)
|
||||
msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
|
||||
else
|
||||
msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
|
||||
else
|
||||
if (screenInfo.bitmapBitOrder == LSBFirst)
|
||||
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
|
||||
else
|
||||
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
|
||||
#else
|
||||
msk = SCRRIGHT(msk, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* If scanline ended with last bit set, end the box */
|
||||
if(fInBox)
|
||||
{
|
||||
width[ipt] = dx + xOrg - pt[ipt].x;
|
||||
if (++ipt >= NPT)
|
||||
{
|
||||
(*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
|
||||
ipt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(pwLineStart);
|
||||
/* Flush any remaining spans */
|
||||
if (ipt)
|
||||
{
|
||||
(*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
|
||||
}
|
||||
}
|
||||
147
nx-X11/programs/Xserver/mi/miscanfill.h
Normal file
147
nx-X11/programs/Xserver/mi/miscanfill.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef SCANFILLINCLUDED
|
||||
#define SCANFILLINCLUDED
|
||||
/*
|
||||
* scanfill.h
|
||||
*
|
||||
* Written by Brian Kelleher; Jan 1985
|
||||
*
|
||||
* This file contains a few macros to help track
|
||||
* the edge of a filled object. The object is assumed
|
||||
* to be filled in scanline order, and thus the
|
||||
* algorithm used is an extension of Bresenham's line
|
||||
* drawing algorithm which assumes that y is always the
|
||||
* major axis.
|
||||
* Since these pieces of code are the same for any filled shape,
|
||||
* it is more convenient to gather the library in one
|
||||
* place, but since these pieces of code are also in
|
||||
* the inner loops of output primitives, procedure call
|
||||
* overhead is out of the question.
|
||||
* See the author for a derivation if needed.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* In scan converting polygons, we want to choose those pixels
|
||||
* which are inside the polygon. Thus, we add .5 to the starting
|
||||
* x coordinate for both left and right edges. Now we choose the
|
||||
* first pixel which is inside the pgon for the left edge and the
|
||||
* first pixel which is outside the pgon for the right edge.
|
||||
* Draw the left pixel, but not the right.
|
||||
*
|
||||
* How to add .5 to the starting x coordinate:
|
||||
* If the edge is moving to the right, then subtract dy from the
|
||||
* error term from the general form of the algorithm.
|
||||
* If the edge is moving to the left, then add dy to the error term.
|
||||
*
|
||||
* The reason for the difference between edges moving to the left
|
||||
* and edges moving to the right is simple: If an edge is moving
|
||||
* to the right, then we want the algorithm to flip immediately.
|
||||
* If it is moving to the left, then we don't want it to flip until
|
||||
* we traverse an entire pixel.
|
||||
*/
|
||||
#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
|
||||
int dx; /* local storage */ \
|
||||
\
|
||||
/* \
|
||||
* if the edge is horizontal, then it is ignored \
|
||||
* and assumed not to be processed. Otherwise, do this stuff. \
|
||||
*/ \
|
||||
if ((dy) != 0) { \
|
||||
xStart = (x1); \
|
||||
dx = (x2) - xStart; \
|
||||
if (dx < 0) { \
|
||||
m = dx / (dy); \
|
||||
m1 = m - 1; \
|
||||
incr1 = -2 * dx + 2 * (dy) * m1; \
|
||||
incr2 = -2 * dx + 2 * (dy) * m; \
|
||||
d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
|
||||
} else { \
|
||||
m = dx / (dy); \
|
||||
m1 = m + 1; \
|
||||
incr1 = 2 * dx - 2 * (dy) * m1; \
|
||||
incr2 = 2 * dx - 2 * (dy) * m; \
|
||||
d = -2 * m * (dy) + 2 * dx; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
|
||||
if (m1 > 0) { \
|
||||
if (d > 0) { \
|
||||
minval += m1; \
|
||||
d += incr1; \
|
||||
} \
|
||||
else { \
|
||||
minval += m; \
|
||||
d += incr2; \
|
||||
} \
|
||||
} else {\
|
||||
if (d >= 0) { \
|
||||
minval += m1; \
|
||||
d += incr1; \
|
||||
} \
|
||||
else { \
|
||||
minval += m; \
|
||||
d += incr2; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This structure contains all of the information needed
|
||||
* to run the bresenham algorithm.
|
||||
* The variables may be hardcoded into the declarations
|
||||
* instead of using this structure to make use of
|
||||
* register declarations.
|
||||
*/
|
||||
typedef struct {
|
||||
int minor; /* minor axis */
|
||||
int d; /* decision variable */
|
||||
int m, m1; /* slope and slope+1 */
|
||||
int incr1, incr2; /* error increments */
|
||||
} BRESINFO;
|
||||
|
||||
|
||||
#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
|
||||
BRESINITPGON(dmaj, min1, min2, bres.minor, bres.d, \
|
||||
bres.m, bres.m1, bres.incr1, bres.incr2)
|
||||
|
||||
#define BRESINCRPGONSTRUCT(bres) \
|
||||
BRESINCRPGON(bres.d, bres.minor, bres.m, bres.m1, bres.incr1, bres.incr2)
|
||||
|
||||
|
||||
#endif
|
||||
342
nx-X11/programs/Xserver/mi/miscrinit.c
Normal file
342
nx-X11/programs/Xserver/mi/miscrinit.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
|
||||
Copyright 1990, 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include "servermd.h"
|
||||
#include "misc.h"
|
||||
#include "mi.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "dix.h"
|
||||
#include "miline.h"
|
||||
#ifdef MITSHM
|
||||
#include "shmint.h"
|
||||
#endif
|
||||
|
||||
/* We use this structure to propogate some information from miScreenInit to
|
||||
* miCreateScreenResources. miScreenInit allocates the structure, fills it
|
||||
* in, and puts it into pScreen->devPrivate. miCreateScreenResources
|
||||
* extracts the info and frees the structure. We could've accomplished the
|
||||
* same thing by adding fields to the screen structure, but they would have
|
||||
* ended up being redundant, and would have exposed this mi implementation
|
||||
* detail to the whole server.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * pbits; /* pointer to framebuffer */
|
||||
int width; /* delta to add to a framebuffer addr to move one row down */
|
||||
} miScreenInitParmsRec, *miScreenInitParmsPtr;
|
||||
|
||||
|
||||
/* this plugs into pScreen->ModifyPixmapHeader */
|
||||
Bool
|
||||
miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind,
|
||||
pPixData)
|
||||
PixmapPtr pPixmap;
|
||||
int width;
|
||||
int height;
|
||||
int depth;
|
||||
int bitsPerPixel;
|
||||
int devKind;
|
||||
void *pPixData;
|
||||
{
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* If all arguments are specified, reinitialize everything (including
|
||||
* validated state).
|
||||
*/
|
||||
if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
|
||||
(devKind > 0) && pPixData) {
|
||||
pPixmap->drawable.depth = depth;
|
||||
pPixmap->drawable.bitsPerPixel = bitsPerPixel;
|
||||
pPixmap->drawable.id = 0;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
pPixmap->drawable.x = 0;
|
||||
pPixmap->drawable.y = 0;
|
||||
pPixmap->drawable.width = width;
|
||||
pPixmap->drawable.height = height;
|
||||
pPixmap->devKind = devKind;
|
||||
pPixmap->refcnt = 1;
|
||||
pPixmap->devPrivate.ptr = pPixData;
|
||||
} else {
|
||||
/*
|
||||
* Only modify specified fields, keeping all others intact.
|
||||
*/
|
||||
|
||||
if (width > 0)
|
||||
pPixmap->drawable.width = width;
|
||||
|
||||
if (height > 0)
|
||||
pPixmap->drawable.height = height;
|
||||
|
||||
if (depth > 0)
|
||||
pPixmap->drawable.depth = depth;
|
||||
|
||||
if (bitsPerPixel > 0)
|
||||
pPixmap->drawable.bitsPerPixel = bitsPerPixel;
|
||||
else if ((bitsPerPixel < 0) && (depth > 0))
|
||||
pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
|
||||
|
||||
/*
|
||||
* CAVEAT: Non-SI DDXen may use devKind and devPrivate fields for
|
||||
* other purposes.
|
||||
*/
|
||||
if (devKind > 0)
|
||||
pPixmap->devKind = devKind;
|
||||
else if ((devKind < 0) && ((width > 0) || (depth > 0)))
|
||||
pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
|
||||
pPixmap->drawable.depth);
|
||||
|
||||
if (pPixData)
|
||||
pPixmap->devPrivate.ptr = pPixData;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
Bool
|
||||
miCloseScreen (pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
|
||||
}
|
||||
|
||||
/* With the introduction of pixmap privates, the "screen pixmap" can no
|
||||
* longer be created in miScreenInit, since all the modules that could
|
||||
* possibly ask for pixmap private space have not been initialized at
|
||||
* that time. pScreen->CreateScreenResources is called after all
|
||||
* possible private-requesting modules have been inited; we create the
|
||||
* screen pixmap here.
|
||||
*/
|
||||
Bool
|
||||
miCreateScreenResources(pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
miScreenInitParmsPtr pScrInitParms;
|
||||
void * value;
|
||||
|
||||
pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
|
||||
|
||||
/* if width is non-zero, pScreen->devPrivate will be a pixmap
|
||||
* else it will just take the value pbits
|
||||
*/
|
||||
if (pScrInitParms->width)
|
||||
{
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
/* create a pixmap with no data, then redirect it to point to
|
||||
* the screen
|
||||
*/
|
||||
pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
|
||||
if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
|
||||
pScreen->height, pScreen->rootDepth,
|
||||
BitsPerPixel(pScreen->rootDepth),
|
||||
PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
|
||||
pScrInitParms->pbits))
|
||||
return FALSE;
|
||||
value = (void *)pPixmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = pScrInitParms->pbits;
|
||||
}
|
||||
free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
|
||||
pScreen->devPrivate = value; /* pPixmap or pbits */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
miScreenDevPrivateInit(pScreen, width, pbits)
|
||||
register ScreenPtr pScreen;
|
||||
int width;
|
||||
void * pbits;
|
||||
{
|
||||
miScreenInitParmsPtr pScrInitParms;
|
||||
|
||||
/* Stash pbits and width in a short-lived miScreenInitParmsRec attached
|
||||
* to the screen, until CreateScreenResources can put them in the
|
||||
* screen pixmap.
|
||||
*/
|
||||
pScrInitParms = (miScreenInitParmsPtr)malloc(sizeof(miScreenInitParmsRec));
|
||||
if (!pScrInitParms)
|
||||
return FALSE;
|
||||
pScrInitParms->pbits = pbits;
|
||||
pScrInitParms->width = width;
|
||||
pScreen->devPrivate = (void *)pScrInitParms;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
|
||||
rootDepth, numDepths, depths, rootVisual, numVisuals, visuals)
|
||||
register ScreenPtr pScreen;
|
||||
void * pbits; /* pointer to screen bits */
|
||||
int xsize, ysize; /* in pixels */
|
||||
int dpix, dpiy; /* dots per inch */
|
||||
int width; /* pixel width of frame buffer */
|
||||
int rootDepth; /* depth of root window */
|
||||
int numDepths; /* number of depths supported */
|
||||
DepthRec *depths; /* supported depths */
|
||||
VisualID rootVisual; /* root visual */
|
||||
int numVisuals; /* number of visuals supported */
|
||||
VisualRec *visuals; /* supported visuals */
|
||||
{
|
||||
pScreen->width = xsize;
|
||||
pScreen->height = ysize;
|
||||
pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
|
||||
pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
|
||||
pScreen->numDepths = numDepths;
|
||||
pScreen->rootDepth = rootDepth;
|
||||
pScreen->allowedDepths = depths;
|
||||
pScreen->rootVisual = rootVisual;
|
||||
/* defColormap */
|
||||
pScreen->minInstalledCmaps = 1;
|
||||
pScreen->maxInstalledCmaps = 1;
|
||||
pScreen->backingStoreSupport = NotUseful;
|
||||
pScreen->saveUnderSupport = NotUseful;
|
||||
/* whitePixel, blackPixel */
|
||||
pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
|
||||
pScreen->CreateScreenResources = miCreateScreenResources;
|
||||
pScreen->GetScreenPixmap = miGetScreenPixmap;
|
||||
pScreen->SetScreenPixmap = miSetScreenPixmap;
|
||||
pScreen->numVisuals = numVisuals;
|
||||
pScreen->visuals = visuals;
|
||||
if (width)
|
||||
{
|
||||
#ifdef MITSHM
|
||||
ShmRegisterFbFuncs(pScreen);
|
||||
#endif
|
||||
pScreen->CloseScreen = miCloseScreen;
|
||||
}
|
||||
/* else CloseScreen */
|
||||
/* QueryBestSize, SaveScreen, GetImage, GetSpans */
|
||||
pScreen->PointerNonInterestBox = (PointerNonInterestBoxProcPtr) 0;
|
||||
pScreen->SourceValidate = (SourceValidateProcPtr) 0;
|
||||
/* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
|
||||
/* RealizeWindow, UnrealizeWindow */
|
||||
pScreen->ValidateTree = miValidateTree;
|
||||
pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
|
||||
pScreen->WindowExposures = miWindowExposures;
|
||||
/* PaintWindowBackground, PaintWindowBorder, CopyWindow */
|
||||
pScreen->ClearToBackground = miClearToBackground;
|
||||
pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
|
||||
pScreen->RestackWindow = (RestackWindowProcPtr) 0;
|
||||
/* CreatePixmap, DestroyPixmap */
|
||||
/* RealizeFont, UnrealizeFont */
|
||||
/* CreateGC */
|
||||
/* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
|
||||
/* ListInstalledColormaps, StoreColors, ResolveColor */
|
||||
/* BitmapToRegion */
|
||||
pScreen->SendGraphicsExpose = miSendGraphicsExpose;
|
||||
pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
|
||||
pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
|
||||
pScreen->blockData = (void *)0;
|
||||
pScreen->wakeupData = (void *)0;
|
||||
pScreen->MarkWindow = miMarkWindow;
|
||||
pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
|
||||
pScreen->ChangeSaveUnder = miChangeSaveUnder;
|
||||
pScreen->PostChangeSaveUnder = miPostChangeSaveUnder;
|
||||
pScreen->MoveWindow = miMoveWindow;
|
||||
pScreen->ResizeWindow = miSlideAndSizeWindow;
|
||||
pScreen->GetLayerWindow = miGetLayerWindow;
|
||||
pScreen->HandleExposures = miHandleValidateExposures;
|
||||
pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
|
||||
pScreen->ChangeBorderWidth = miChangeBorderWidth;
|
||||
#ifdef SHAPE
|
||||
pScreen->SetShape = miSetShape;
|
||||
#endif
|
||||
pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
|
||||
|
||||
pScreen->SaveDoomedAreas = 0;
|
||||
pScreen->RestoreAreas = 0;
|
||||
pScreen->ExposeCopy = 0;
|
||||
pScreen->TranslateBackingStore = 0;
|
||||
pScreen->ClearBackingStore = 0;
|
||||
pScreen->DrawGuarantee = 0;
|
||||
|
||||
miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
|
||||
|
||||
return miScreenDevPrivateInit(pScreen, width, pbits);
|
||||
}
|
||||
|
||||
int
|
||||
miAllocateGCPrivateIndex()
|
||||
{
|
||||
static int privateIndex = -1;
|
||||
static unsigned long miGeneration = 0;
|
||||
|
||||
if (miGeneration != serverGeneration)
|
||||
{
|
||||
privateIndex = AllocateGCPrivateIndex();
|
||||
miGeneration = serverGeneration;
|
||||
}
|
||||
return privateIndex;
|
||||
}
|
||||
|
||||
int miZeroLineScreenIndex;
|
||||
unsigned int miZeroLineGeneration = 0;
|
||||
|
||||
void
|
||||
miSetZeroLineBias(pScreen, bias)
|
||||
ScreenPtr pScreen;
|
||||
unsigned int bias;
|
||||
{
|
||||
if (miZeroLineGeneration != serverGeneration)
|
||||
{
|
||||
miZeroLineScreenIndex = AllocateScreenPrivateIndex();
|
||||
miZeroLineGeneration = serverGeneration;
|
||||
}
|
||||
if (miZeroLineScreenIndex >= 0)
|
||||
pScreen->devPrivates[miZeroLineScreenIndex].uval = bias;
|
||||
}
|
||||
|
||||
PixmapPtr
|
||||
miGetScreenPixmap(pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
return (PixmapPtr)(pScreen->devPrivate);
|
||||
}
|
||||
|
||||
void
|
||||
miSetScreenPixmap(pPix)
|
||||
PixmapPtr pPix;
|
||||
{
|
||||
if (pPix)
|
||||
pPix->drawable.pScreen->devPrivate = (void *)pPix;
|
||||
}
|
||||
559
nx-X11/programs/Xserver/mi/mispans.c
Normal file
559
nx-X11/programs/Xserver/mi/mispans.c
Normal file
@@ -0,0 +1,559 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1989, 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.
|
||||
|
||||
|
||||
Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "mispans.h"
|
||||
|
||||
/*
|
||||
|
||||
These routines maintain lists of Spans, in order to implement the
|
||||
``touch-each-pixel-once'' rules of wide lines and arcs.
|
||||
|
||||
Written by Joel McCormack, Summer 1989.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
void miInitSpanGroup(spanGroup)
|
||||
SpanGroup *spanGroup;
|
||||
{
|
||||
spanGroup->size = 0;
|
||||
spanGroup->count = 0;
|
||||
spanGroup->group = NULL;
|
||||
spanGroup->ymin = MAXSHORT;
|
||||
spanGroup->ymax = MINSHORT;
|
||||
} /* InitSpanGroup */
|
||||
|
||||
#define YMIN(spans) (spans->points[0].y)
|
||||
#define YMAX(spans) (spans->points[spans->count-1].y)
|
||||
|
||||
void miSubtractSpans (spanGroup, sub)
|
||||
SpanGroup *spanGroup;
|
||||
Spans *sub;
|
||||
{
|
||||
int i, subCount, spansCount;
|
||||
int ymin, ymax, xmin, xmax;
|
||||
Spans *spans;
|
||||
DDXPointPtr subPt, spansPt;
|
||||
int *subWid, *spansWid;
|
||||
int extra;
|
||||
|
||||
ymin = YMIN(sub);
|
||||
ymax = YMAX(sub);
|
||||
spans = spanGroup->group;
|
||||
for (i = spanGroup->count; i; i--, spans++) {
|
||||
if (YMIN(spans) <= ymax && ymin <= YMAX(spans)) {
|
||||
subCount = sub->count;
|
||||
subPt = sub->points;
|
||||
subWid = sub->widths;
|
||||
spansCount = spans->count;
|
||||
spansPt = spans->points;
|
||||
spansWid = spans->widths;
|
||||
extra = 0;
|
||||
for (;;)
|
||||
{
|
||||
while (spansCount && spansPt->y < subPt->y)
|
||||
{
|
||||
spansPt++; spansWid++; spansCount--;
|
||||
}
|
||||
if (!spansCount)
|
||||
break;
|
||||
while (subCount && subPt->y < spansPt->y)
|
||||
{
|
||||
subPt++; subWid++; subCount--;
|
||||
}
|
||||
if (!subCount)
|
||||
break;
|
||||
if (subPt->y == spansPt->y)
|
||||
{
|
||||
xmin = subPt->x;
|
||||
xmax = xmin + *subWid;
|
||||
if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax)
|
||||
{
|
||||
;
|
||||
}
|
||||
else if (xmin <= spansPt->x)
|
||||
{
|
||||
if (xmax >= spansPt->x + *spansWid)
|
||||
{
|
||||
memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1));
|
||||
memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1));
|
||||
spansPt--;
|
||||
spansWid--;
|
||||
spans->count--;
|
||||
extra++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*spansWid = *spansWid - (xmax - spansPt->x);
|
||||
spansPt->x = xmax;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xmax >= spansPt->x + *spansWid)
|
||||
{
|
||||
*spansWid = xmin - spansPt->x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!extra) {
|
||||
DDXPointPtr newPt;
|
||||
int *newwid;
|
||||
|
||||
#define EXTRA 8
|
||||
newPt = (DDXPointPtr) realloc (spans->points, (spans->count + EXTRA) * sizeof (DDXPointRec));
|
||||
if (!newPt)
|
||||
break;
|
||||
spansPt = newPt + (spansPt - spans->points);
|
||||
spans->points = newPt;
|
||||
newwid = (int *) realloc (spans->widths, (spans->count + EXTRA) * sizeof (int));
|
||||
if (!newwid)
|
||||
break;
|
||||
spansWid = newwid + (spansWid - spans->widths);
|
||||
spans->widths = newwid;
|
||||
extra = EXTRA;
|
||||
}
|
||||
memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount));
|
||||
memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount));
|
||||
spans->count++;
|
||||
extra--;
|
||||
*spansWid = xmin - spansPt->x;
|
||||
spansWid++;
|
||||
spansPt++;
|
||||
*spansWid = *spansWid - (xmax - spansPt->x);
|
||||
spansPt->x = xmax;
|
||||
}
|
||||
}
|
||||
}
|
||||
spansPt++; spansWid++; spansCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void miAppendSpans(spanGroup, otherGroup, spans)
|
||||
SpanGroup *spanGroup;
|
||||
SpanGroup *otherGroup;
|
||||
Spans *spans;
|
||||
{
|
||||
register int ymin, ymax;
|
||||
register int spansCount;
|
||||
|
||||
spansCount = spans->count;
|
||||
if (spansCount > 0) {
|
||||
if (spanGroup->size == spanGroup->count) {
|
||||
spanGroup->size = (spanGroup->size + 8) * 2;
|
||||
spanGroup->group = (Spans *)
|
||||
realloc(spanGroup->group, sizeof(Spans) * spanGroup->size);
|
||||
}
|
||||
|
||||
spanGroup->group[spanGroup->count] = *spans;
|
||||
(spanGroup->count)++;
|
||||
ymin = spans->points[0].y;
|
||||
if (ymin < spanGroup->ymin) spanGroup->ymin = ymin;
|
||||
ymax = spans->points[spansCount - 1].y;
|
||||
if (ymax > spanGroup->ymax) spanGroup->ymax = ymax;
|
||||
if (otherGroup &&
|
||||
otherGroup->ymin < ymax &&
|
||||
ymin < otherGroup->ymax)
|
||||
{
|
||||
miSubtractSpans (otherGroup, spans);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free (spans->points);
|
||||
free (spans->widths);
|
||||
}
|
||||
} /* AppendSpans */
|
||||
|
||||
void miFreeSpanGroup(spanGroup)
|
||||
SpanGroup *spanGroup;
|
||||
{
|
||||
if (spanGroup->group != NULL) free(spanGroup->group);
|
||||
}
|
||||
|
||||
static void QuickSortSpansX(
|
||||
register DDXPointRec points[],
|
||||
register int widths[],
|
||||
register int numSpans )
|
||||
{
|
||||
register int x;
|
||||
register int i, j, m;
|
||||
register DDXPointPtr r;
|
||||
|
||||
/* Always called with numSpans > 1 */
|
||||
/* Sorts only by x, as all y should be the same */
|
||||
|
||||
#define ExchangeSpans(a, b) \
|
||||
{ \
|
||||
DDXPointRec tpt; \
|
||||
register int tw; \
|
||||
\
|
||||
tpt = points[a]; points[a] = points[b]; points[b] = tpt; \
|
||||
tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
|
||||
}
|
||||
|
||||
do {
|
||||
if (numSpans < 9) {
|
||||
/* Do insertion sort */
|
||||
register int xprev;
|
||||
|
||||
xprev = points[0].x;
|
||||
i = 1;
|
||||
do { /* while i != numSpans */
|
||||
x = points[i].x;
|
||||
if (xprev > x) {
|
||||
/* points[i] is out of order. Move into proper location. */
|
||||
DDXPointRec tpt;
|
||||
int tw, k;
|
||||
|
||||
for (j = 0; x >= points[j].x; j++) {}
|
||||
tpt = points[i];
|
||||
tw = widths[i];
|
||||
for (k = i; k != j; k--) {
|
||||
points[k] = points[k-1];
|
||||
widths[k] = widths[k-1];
|
||||
}
|
||||
points[j] = tpt;
|
||||
widths[j] = tw;
|
||||
x = points[i].x;
|
||||
} /* if out of order */
|
||||
xprev = x;
|
||||
i++;
|
||||
} while (i != numSpans);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Choose partition element, stick in location 0 */
|
||||
m = numSpans / 2;
|
||||
if (points[m].x > points[0].x) ExchangeSpans(m, 0);
|
||||
if (points[m].x > points[numSpans-1].x) ExchangeSpans(m, numSpans-1);
|
||||
if (points[m].x > points[0].x) ExchangeSpans(m, 0);
|
||||
x = points[0].x;
|
||||
|
||||
/* Partition array */
|
||||
i = 0;
|
||||
j = numSpans;
|
||||
do {
|
||||
r = &(points[i]);
|
||||
do {
|
||||
r++;
|
||||
i++;
|
||||
} while (i != numSpans && r->x < x);
|
||||
r = &(points[j]);
|
||||
do {
|
||||
r--;
|
||||
j--;
|
||||
} while (x < r->x);
|
||||
if (i < j) ExchangeSpans(i, j);
|
||||
} while (i < j);
|
||||
|
||||
/* Move partition element back to middle */
|
||||
ExchangeSpans(0, j);
|
||||
|
||||
/* Recurse */
|
||||
if (numSpans-j-1 > 1)
|
||||
QuickSortSpansX(&points[j+1], &widths[j+1], numSpans-j-1);
|
||||
numSpans = j;
|
||||
} while (numSpans > 1);
|
||||
} /* QuickSortSpans */
|
||||
|
||||
|
||||
static int UniquifySpansX(
|
||||
Spans *spans,
|
||||
register DDXPointRec *newPoints,
|
||||
register int *newWidths )
|
||||
{
|
||||
register int newx1, newx2, oldpt, i, y;
|
||||
register DDXPointRec *oldPoints;
|
||||
register int *oldWidths;
|
||||
int *startNewWidths;
|
||||
|
||||
/* Always called with numSpans > 1 */
|
||||
/* Uniquify the spans, and stash them into newPoints and newWidths. Return the
|
||||
number of unique spans. */
|
||||
|
||||
|
||||
startNewWidths = newWidths;
|
||||
|
||||
oldPoints = spans->points;
|
||||
oldWidths = spans->widths;
|
||||
|
||||
y = oldPoints->y;
|
||||
newx1 = oldPoints->x;
|
||||
newx2 = newx1 + *oldWidths;
|
||||
|
||||
for (i = spans->count-1; i != 0; i--) {
|
||||
oldPoints++;
|
||||
oldWidths++;
|
||||
oldpt = oldPoints->x;
|
||||
if (oldpt > newx2) {
|
||||
/* Write current span, start a new one */
|
||||
newPoints->x = newx1;
|
||||
newPoints->y = y;
|
||||
*newWidths = newx2 - newx1;
|
||||
newPoints++;
|
||||
newWidths++;
|
||||
newx1 = oldpt;
|
||||
newx2 = oldpt + *oldWidths;
|
||||
} else {
|
||||
/* extend current span, if old extends beyond new */
|
||||
oldpt = oldpt + *oldWidths;
|
||||
if (oldpt > newx2) newx2 = oldpt;
|
||||
}
|
||||
} /* for */
|
||||
|
||||
/* Write final span */
|
||||
newPoints->x = newx1;
|
||||
*newWidths = newx2 - newx1;
|
||||
newPoints->y = y;
|
||||
|
||||
return (newWidths - startNewWidths) + 1;
|
||||
} /* UniquifySpansX */
|
||||
|
||||
void
|
||||
miDisposeSpanGroup (spanGroup)
|
||||
SpanGroup *spanGroup;
|
||||
{
|
||||
int i;
|
||||
Spans *spans;
|
||||
|
||||
for (i = 0; i < spanGroup->count; i++)
|
||||
{
|
||||
spans = spanGroup->group + i;
|
||||
free (spans->points);
|
||||
free (spans->widths);
|
||||
}
|
||||
}
|
||||
|
||||
void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
SpanGroup *spanGroup;
|
||||
{
|
||||
register int i;
|
||||
register Spans *spans;
|
||||
register Spans *yspans;
|
||||
register int *ysizes;
|
||||
register int ymin, ylength;
|
||||
|
||||
/* Outgoing spans for one big call to FillSpans */
|
||||
register DDXPointPtr points;
|
||||
register int *widths;
|
||||
register int count;
|
||||
|
||||
if (spanGroup->count == 0) return;
|
||||
|
||||
if (spanGroup->count == 1) {
|
||||
/* Already should be sorted, unique */
|
||||
spans = spanGroup->group;
|
||||
(*pGC->ops->FillSpans)
|
||||
(pDraw, pGC, spans->count, spans->points, spans->widths, TRUE);
|
||||
free(spans->points);
|
||||
free(spans->widths);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Yuck. Gross. Radix sort into y buckets, then sort x and uniquify */
|
||||
/* This seems to be the fastest thing to do. I've tried sorting on
|
||||
both x and y at the same time rather than creating into all those
|
||||
y buckets, but it was somewhat slower. */
|
||||
|
||||
ymin = spanGroup->ymin;
|
||||
ylength = spanGroup->ymax - ymin + 1;
|
||||
|
||||
/* Allocate Spans for y buckets */
|
||||
yspans = (Spans *) malloc(ylength * sizeof(Spans));
|
||||
ysizes = (int *) malloc(ylength * sizeof (int));
|
||||
|
||||
if (!yspans || !ysizes)
|
||||
{
|
||||
if (yspans)
|
||||
free (yspans);
|
||||
if (ysizes)
|
||||
free (ysizes);
|
||||
miDisposeSpanGroup (spanGroup);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i != ylength; i++) {
|
||||
ysizes[i] = 0;
|
||||
yspans[i].count = 0;
|
||||
yspans[i].points = NULL;
|
||||
yspans[i].widths = NULL;
|
||||
}
|
||||
|
||||
/* Go through every single span and put it into the correct bucket */
|
||||
count = 0;
|
||||
for (i = 0, spans = spanGroup->group;
|
||||
i != spanGroup->count;
|
||||
i++, spans++) {
|
||||
int index;
|
||||
int j;
|
||||
|
||||
for (j = 0, points = spans->points, widths = spans->widths;
|
||||
j != spans->count;
|
||||
j++, points++, widths++) {
|
||||
index = points->y - ymin;
|
||||
if (index >= 0 && index < ylength) {
|
||||
Spans *newspans = &(yspans[index]);
|
||||
if (newspans->count == ysizes[index]) {
|
||||
DDXPointPtr newpoints;
|
||||
int *newwidths;
|
||||
ysizes[index] = (ysizes[index] + 8) * 2;
|
||||
newpoints = (DDXPointPtr) realloc(
|
||||
newspans->points,
|
||||
ysizes[index] * sizeof(DDXPointRec));
|
||||
newwidths = (int *) realloc(
|
||||
newspans->widths,
|
||||
ysizes[index] * sizeof(int));
|
||||
if (!newpoints || !newwidths)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < ylength; k++)
|
||||
{
|
||||
free (yspans[k].points);
|
||||
free (yspans[k].widths);
|
||||
}
|
||||
free (yspans);
|
||||
free (ysizes);
|
||||
miDisposeSpanGroup (spanGroup);
|
||||
return;
|
||||
}
|
||||
newspans->points = newpoints;
|
||||
newspans->widths = newwidths;
|
||||
}
|
||||
newspans->points[newspans->count] = *points;
|
||||
newspans->widths[newspans->count] = *widths;
|
||||
(newspans->count)++;
|
||||
} /* if y value of span in range */
|
||||
} /* for j through spans */
|
||||
count += spans->count;
|
||||
free(spans->points);
|
||||
spans->points = NULL;
|
||||
free(spans->widths);
|
||||
spans->widths = NULL;
|
||||
} /* for i thorough Spans */
|
||||
|
||||
/* Now sort by x and uniquify each bucket into the final array */
|
||||
points = (DDXPointPtr) malloc(count * sizeof(DDXPointRec));
|
||||
widths = (int *) malloc(count * sizeof(int));
|
||||
if (!points || !widths)
|
||||
{
|
||||
for (i = 0; i < ylength; i++)
|
||||
{
|
||||
free (yspans[i].points);
|
||||
free (yspans[i].widths);
|
||||
}
|
||||
free (yspans);
|
||||
free (ysizes);
|
||||
if (points)
|
||||
free (points);
|
||||
if (widths)
|
||||
free (widths);
|
||||
return;
|
||||
}
|
||||
count = 0;
|
||||
for (i = 0; i != ylength; i++) {
|
||||
int ycount = yspans[i].count;
|
||||
if (ycount > 0) {
|
||||
if (ycount > 1) {
|
||||
QuickSortSpansX(yspans[i].points, yspans[i].widths, ycount);
|
||||
count += UniquifySpansX
|
||||
(&(yspans[i]), &(points[count]), &(widths[count]));
|
||||
} else {
|
||||
points[count] = yspans[i].points[0];
|
||||
widths[count] = yspans[i].widths[0];
|
||||
count++;
|
||||
}
|
||||
free(yspans[i].points);
|
||||
free(yspans[i].widths);
|
||||
}
|
||||
}
|
||||
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, count, points, widths, TRUE);
|
||||
free(points);
|
||||
free(widths);
|
||||
free(yspans);
|
||||
free(ysizes);
|
||||
}
|
||||
|
||||
spanGroup->count = 0;
|
||||
spanGroup->ymin = MAXSHORT;
|
||||
spanGroup->ymax = MINSHORT;
|
||||
}
|
||||
|
||||
|
||||
void miFillSpanGroup(pDraw, pGC, spanGroup)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
SpanGroup *spanGroup;
|
||||
{
|
||||
register int i;
|
||||
register Spans *spans;
|
||||
|
||||
for (i = 0, spans = spanGroup->group; i != spanGroup->count; i++, spans++) {
|
||||
(*pGC->ops->FillSpans)
|
||||
(pDraw, pGC, spans->count, spans->points, spans->widths, TRUE);
|
||||
free(spans->points);
|
||||
free(spans->widths);
|
||||
}
|
||||
|
||||
spanGroup->count = 0;
|
||||
spanGroup->ymin = MAXSHORT;
|
||||
spanGroup->ymax = MINSHORT;
|
||||
} /* FillSpanGroup */
|
||||
115
nx-X11/programs/Xserver/mi/mispans.h
Normal file
115
nx-X11/programs/Xserver/mi/mispans.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1989, 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.
|
||||
|
||||
|
||||
Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
|
||||
typedef struct {
|
||||
int count; /* number of spans */
|
||||
DDXPointPtr points; /* pointer to list of start points */
|
||||
int *widths; /* pointer to list of widths */
|
||||
} Spans;
|
||||
|
||||
typedef struct {
|
||||
int size; /* Total number of *Spans allocated */
|
||||
int count; /* Number of *Spans actually in group */
|
||||
Spans *group; /* List of Spans */
|
||||
int ymin, ymax; /* Min, max y values encountered */
|
||||
} SpanGroup;
|
||||
|
||||
/* Initialize SpanGroup. MUST BE DONE before use. */
|
||||
extern void miInitSpanGroup(
|
||||
SpanGroup * /*spanGroup*/
|
||||
);
|
||||
|
||||
/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */
|
||||
extern void miAppendSpans(
|
||||
SpanGroup * /*spanGroup*/,
|
||||
SpanGroup * /*otherGroup*/,
|
||||
Spans * /*spans*/
|
||||
);
|
||||
|
||||
/* Paint a span group, possibly with some overlap */
|
||||
extern void miFillSpanGroup(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
SpanGroup * /*spanGroup*/
|
||||
);
|
||||
|
||||
/* Paint a span group, insuring that each pixel is painted at most once */
|
||||
extern void miFillUniqueSpanGroup(
|
||||
DrawablePtr /*pDraw*/,
|
||||
GCPtr /*pGC*/,
|
||||
SpanGroup * /*spanGroup*/
|
||||
);
|
||||
|
||||
/* Free up data in a span group. MUST BE DONE or you'll suffer memory leaks */
|
||||
extern void miFreeSpanGroup(
|
||||
SpanGroup * /*spanGroup*/
|
||||
);
|
||||
|
||||
extern void miSubtractSpans(
|
||||
SpanGroup * /*spanGroup*/,
|
||||
Spans * /*sub*/
|
||||
);
|
||||
|
||||
extern void miDisposeSpanGroup(
|
||||
SpanGroup * /*spanGroup*/
|
||||
);
|
||||
|
||||
extern int RegionClipSpans(
|
||||
RegionPtr /*prgnDst*/,
|
||||
DDXPointPtr /*ppt*/,
|
||||
int * /*pwidth*/,
|
||||
int /*nspans*/,
|
||||
DDXPointPtr /*pptNew*/,
|
||||
int * /*pwidthNew*/,
|
||||
int /*fSorted*/
|
||||
);
|
||||
|
||||
/* Rops which must use span groups */
|
||||
#define miSpansCarefulRop(rop) (((rop) & 0xc) == 0x8 || ((rop) & 0x3) == 0x2)
|
||||
#define miSpansEasyRop(rop) (!miSpansCarefulRop(rop))
|
||||
|
||||
828
nx-X11/programs/Xserver/mi/misprite.c
Normal file
828
nx-X11/programs/Xserver/mi/misprite.c
Normal file
@@ -0,0 +1,828 @@
|
||||
/*
|
||||
* misprite.c
|
||||
*
|
||||
* machine independent software sprite routines
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
# include <nx-X11/X.h>
|
||||
# include <nx-X11/Xproto.h>
|
||||
# include "misc.h"
|
||||
# include "pixmapstr.h"
|
||||
# include "input.h"
|
||||
# include "mi.h"
|
||||
# include "cursorstr.h"
|
||||
# include <X11/fonts/font.h>
|
||||
# include "scrnintstr.h"
|
||||
# include "colormapst.h"
|
||||
# include "windowstr.h"
|
||||
# include "gcstruct.h"
|
||||
# include "mipointer.h"
|
||||
# include "mispritest.h"
|
||||
# include "dixfontstr.h"
|
||||
# include <X11/fonts/fontstruct.h>
|
||||
|
||||
#ifdef RENDER
|
||||
# include "mipict.h"
|
||||
#endif
|
||||
# include "damage.h"
|
||||
|
||||
#define SPRITE_DEBUG_ENABLE 0
|
||||
#if SPRITE_DEBUG_ENABLE
|
||||
#define SPRITE_DEBUG(x) ErrorF x
|
||||
#else
|
||||
#define SPRITE_DEBUG(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* screen wrappers
|
||||
*/
|
||||
|
||||
static int miSpriteScreenIndex;
|
||||
static unsigned long miSpriteGeneration = 0;
|
||||
|
||||
static Bool miSpriteCloseScreen(ScreenPtr pScreen);
|
||||
static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
|
||||
int w, int h, unsigned int format,
|
||||
unsigned long planemask, char *pdstLine);
|
||||
static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax,
|
||||
DDXPointPtr ppt, int *pwidth, int nspans,
|
||||
char *pdstStart);
|
||||
static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
|
||||
int width, int height);
|
||||
static void miSpriteCopyWindow (WindowPtr pWindow,
|
||||
DDXPointRec ptOldOrg,
|
||||
RegionPtr prgnSrc);
|
||||
static void miSpriteBlockHandler(int i, void * blockData,
|
||||
void * pTimeout,
|
||||
void * pReadMask);
|
||||
static void miSpriteInstallColormap(ColormapPtr pMap);
|
||||
static void miSpriteStoreColors(ColormapPtr pMap, int ndef,
|
||||
xColorItem *pdef);
|
||||
|
||||
static void miSpriteSaveDoomedAreas(WindowPtr pWin,
|
||||
RegionPtr pObscured, int dx,
|
||||
int dy);
|
||||
static void miSpriteComputeSaved(ScreenPtr pScreen);
|
||||
|
||||
#define SCREEN_PROLOGUE(pScreen, field)\
|
||||
((pScreen)->field = \
|
||||
((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
|
||||
|
||||
#define SCREEN_EPILOGUE(pScreen, field)\
|
||||
((pScreen)->field = miSprite##field)
|
||||
|
||||
/*
|
||||
* pointer-sprite method table
|
||||
*/
|
||||
|
||||
static Bool miSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
static Bool miSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
|
||||
static void miSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCursor,
|
||||
int x, int y);
|
||||
static void miSpriteMoveCursor(ScreenPtr pScreen, int x, int y);
|
||||
|
||||
miPointerSpriteFuncRec miSpritePointerFuncs = {
|
||||
miSpriteRealizeCursor,
|
||||
miSpriteUnrealizeCursor,
|
||||
miSpriteSetCursor,
|
||||
miSpriteMoveCursor,
|
||||
};
|
||||
|
||||
/*
|
||||
* other misc functions
|
||||
*/
|
||||
|
||||
static void miSpriteRemoveCursor(ScreenPtr pScreen);
|
||||
static void miSpriteRestoreCursor(ScreenPtr pScreen);
|
||||
|
||||
static void
|
||||
miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
|
||||
{
|
||||
ScreenPtr pScreen = closure;
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
if (pScreenPriv->isUp &&
|
||||
RegionContainsRect(pRegion, &pScreenPriv->saved) != rgnOUT)
|
||||
{
|
||||
SPRITE_DEBUG(("Damage remove\n"));
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* miSpriteInitialize -- called from device-dependent screen
|
||||
* initialization proc after all of the function pointers have
|
||||
* been stored in the screen structure.
|
||||
*/
|
||||
|
||||
Bool
|
||||
miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
|
||||
ScreenPtr pScreen;
|
||||
miSpriteCursorFuncPtr cursorFuncs;
|
||||
miPointerScreenFuncPtr screenFuncs;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
VisualPtr pVisual;
|
||||
|
||||
if (!DamageSetup (pScreen))
|
||||
return FALSE;
|
||||
|
||||
if (miSpriteGeneration != serverGeneration)
|
||||
{
|
||||
miSpriteScreenIndex = AllocateScreenPrivateIndex ();
|
||||
if (miSpriteScreenIndex < 0)
|
||||
return FALSE;
|
||||
miSpriteGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) malloc (sizeof (miSpriteScreenRec));
|
||||
if (!pScreenPriv)
|
||||
return FALSE;
|
||||
|
||||
pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage,
|
||||
(DamageDestroyFunc) 0,
|
||||
DamageReportRawRegion,
|
||||
TRUE,
|
||||
pScreen,
|
||||
(void *) pScreen);
|
||||
|
||||
if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
|
||||
{
|
||||
free ((void *) pScreenPriv);
|
||||
return FALSE;
|
||||
}
|
||||
for (pVisual = pScreen->visuals;
|
||||
pVisual->vid != pScreen->rootVisual;
|
||||
pVisual++)
|
||||
;
|
||||
pScreenPriv->pVisual = pVisual;
|
||||
pScreenPriv->CloseScreen = pScreen->CloseScreen;
|
||||
pScreenPriv->GetImage = pScreen->GetImage;
|
||||
pScreenPriv->GetSpans = pScreen->GetSpans;
|
||||
pScreenPriv->SourceValidate = pScreen->SourceValidate;
|
||||
|
||||
pScreenPriv->CopyWindow = pScreen->CopyWindow;
|
||||
|
||||
pScreenPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas;
|
||||
|
||||
pScreenPriv->InstallColormap = pScreen->InstallColormap;
|
||||
pScreenPriv->StoreColors = pScreen->StoreColors;
|
||||
|
||||
pScreenPriv->BlockHandler = pScreen->BlockHandler;
|
||||
|
||||
pScreenPriv->pCursor = NULL;
|
||||
pScreenPriv->x = 0;
|
||||
pScreenPriv->y = 0;
|
||||
pScreenPriv->isUp = FALSE;
|
||||
pScreenPriv->shouldBeUp = FALSE;
|
||||
pScreenPriv->pCacheWin = NullWindow;
|
||||
pScreenPriv->isInCacheWin = FALSE;
|
||||
pScreenPriv->checkPixels = TRUE;
|
||||
pScreenPriv->pInstalledMap = NULL;
|
||||
pScreenPriv->pColormap = NULL;
|
||||
pScreenPriv->funcs = cursorFuncs;
|
||||
pScreenPriv->colors[SOURCE_COLOR].red = 0;
|
||||
pScreenPriv->colors[SOURCE_COLOR].green = 0;
|
||||
pScreenPriv->colors[SOURCE_COLOR].blue = 0;
|
||||
pScreenPriv->colors[MASK_COLOR].red = 0;
|
||||
pScreenPriv->colors[MASK_COLOR].green = 0;
|
||||
pScreenPriv->colors[MASK_COLOR].blue = 0;
|
||||
pScreen->devPrivates[miSpriteScreenIndex].ptr = (void *) pScreenPriv;
|
||||
|
||||
pScreen->CloseScreen = miSpriteCloseScreen;
|
||||
pScreen->GetImage = miSpriteGetImage;
|
||||
pScreen->GetSpans = miSpriteGetSpans;
|
||||
pScreen->SourceValidate = miSpriteSourceValidate;
|
||||
|
||||
pScreen->CopyWindow = miSpriteCopyWindow;
|
||||
|
||||
pScreen->SaveDoomedAreas = miSpriteSaveDoomedAreas;
|
||||
|
||||
pScreen->InstallColormap = miSpriteInstallColormap;
|
||||
pScreen->StoreColors = miSpriteStoreColors;
|
||||
|
||||
pScreen->BlockHandler = miSpriteBlockHandler;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Screen wrappers
|
||||
*/
|
||||
|
||||
/*
|
||||
* CloseScreen wrapper -- unwrap everything, free the private data
|
||||
* and call the wrapped function
|
||||
*/
|
||||
|
||||
static Bool
|
||||
miSpriteCloseScreen (pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
pScreen->CloseScreen = pScreenPriv->CloseScreen;
|
||||
pScreen->GetImage = pScreenPriv->GetImage;
|
||||
pScreen->GetSpans = pScreenPriv->GetSpans;
|
||||
pScreen->SourceValidate = pScreenPriv->SourceValidate;
|
||||
pScreen->BlockHandler = pScreenPriv->BlockHandler;
|
||||
pScreen->InstallColormap = pScreenPriv->InstallColormap;
|
||||
pScreen->StoreColors = pScreenPriv->StoreColors;
|
||||
|
||||
pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
|
||||
miSpriteIsUpFALSE (pScreen, pScreenPriv);
|
||||
DamageDestroy (pScreenPriv->pDamage);
|
||||
|
||||
free ((void *) pScreenPriv);
|
||||
|
||||
return (*pScreen->CloseScreen) (pScreen);
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
|
||||
DrawablePtr pDrawable;
|
||||
int sx, sy, w, h;
|
||||
unsigned int format;
|
||||
unsigned long planemask;
|
||||
char *pdstLine;
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
SCREEN_PROLOGUE (pScreen, GetImage);
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW &&
|
||||
pScreenPriv->isUp &&
|
||||
ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
|
||||
{
|
||||
SPRITE_DEBUG (("GetImage remove\n"));
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
|
||||
(*pScreen->GetImage) (pDrawable, sx, sy, w, h,
|
||||
format, planemask, pdstLine);
|
||||
|
||||
SCREEN_EPILOGUE (pScreen, GetImage);
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
|
||||
DrawablePtr pDrawable;
|
||||
int wMax;
|
||||
DDXPointPtr ppt;
|
||||
int *pwidth;
|
||||
int nspans;
|
||||
char *pdstStart;
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
SCREEN_PROLOGUE (pScreen, GetSpans);
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
|
||||
{
|
||||
register DDXPointPtr pts;
|
||||
register int *widths;
|
||||
register int nPts;
|
||||
register int xorg,
|
||||
yorg;
|
||||
|
||||
xorg = pDrawable->x;
|
||||
yorg = pDrawable->y;
|
||||
|
||||
for (pts = ppt, widths = pwidth, nPts = nspans;
|
||||
nPts--;
|
||||
pts++, widths++)
|
||||
{
|
||||
if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
|
||||
pts->x+xorg,*widths))
|
||||
{
|
||||
SPRITE_DEBUG (("GetSpans remove\n"));
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
|
||||
|
||||
SCREEN_EPILOGUE (pScreen, GetSpans);
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteSourceValidate (pDrawable, x, y, width, height)
|
||||
DrawablePtr pDrawable;
|
||||
int x, y, width, height;
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
SCREEN_PROLOGUE (pScreen, SourceValidate);
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
|
||||
ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
|
||||
x, y, width, height))
|
||||
{
|
||||
SPRITE_DEBUG (("SourceValidate remove\n"));
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
|
||||
if (pScreen->SourceValidate)
|
||||
(*pScreen->SourceValidate) (pDrawable, x, y, width, height);
|
||||
|
||||
SCREEN_EPILOGUE (pScreen, SourceValidate);
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||
{
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
SCREEN_PROLOGUE (pScreen, CopyWindow);
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
/*
|
||||
* Damage will take care of destination check
|
||||
*/
|
||||
if (pScreenPriv->isUp &&
|
||||
RegionContainsRect(prgnSrc, &pScreenPriv->saved) != rgnOUT)
|
||||
{
|
||||
SPRITE_DEBUG (("CopyWindow remove\n"));
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
|
||||
(*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
|
||||
SCREEN_EPILOGUE (pScreen, CopyWindow);
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
|
||||
int i;
|
||||
void * blockData;
|
||||
void * pTimeout;
|
||||
void * pReadmask;
|
||||
{
|
||||
ScreenPtr pScreen = screenInfo.screens[i];
|
||||
miSpriteScreenPtr pPriv;
|
||||
|
||||
pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
SCREEN_PROLOGUE(pScreen, BlockHandler);
|
||||
|
||||
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
|
||||
|
||||
SCREEN_EPILOGUE(pScreen, BlockHandler);
|
||||
|
||||
if (!pPriv->isUp && pPriv->shouldBeUp)
|
||||
{
|
||||
SPRITE_DEBUG (("BlockHandler restore\n"));
|
||||
miSpriteRestoreCursor (pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteInstallColormap (pMap)
|
||||
ColormapPtr pMap;
|
||||
{
|
||||
ScreenPtr pScreen = pMap->pScreen;
|
||||
miSpriteScreenPtr pPriv;
|
||||
|
||||
pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
SCREEN_PROLOGUE(pScreen, InstallColormap);
|
||||
|
||||
(*pScreen->InstallColormap) (pMap);
|
||||
|
||||
SCREEN_EPILOGUE(pScreen, InstallColormap);
|
||||
|
||||
pPriv->pInstalledMap = pMap;
|
||||
if (pPriv->pColormap != pMap)
|
||||
{
|
||||
pPriv->checkPixels = TRUE;
|
||||
if (pPriv->isUp)
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteStoreColors (pMap, ndef, pdef)
|
||||
ColormapPtr pMap;
|
||||
int ndef;
|
||||
xColorItem *pdef;
|
||||
{
|
||||
ScreenPtr pScreen = pMap->pScreen;
|
||||
miSpriteScreenPtr pPriv;
|
||||
int i;
|
||||
int updated;
|
||||
VisualPtr pVisual;
|
||||
|
||||
pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
|
||||
SCREEN_PROLOGUE(pScreen, StoreColors);
|
||||
|
||||
(*pScreen->StoreColors) (pMap, ndef, pdef);
|
||||
|
||||
SCREEN_EPILOGUE(pScreen, StoreColors);
|
||||
|
||||
if (pPriv->pColormap == pMap)
|
||||
{
|
||||
updated = 0;
|
||||
pVisual = pMap->pVisual;
|
||||
if (pVisual->class == DirectColor)
|
||||
{
|
||||
/* Direct color - match on any of the subfields */
|
||||
|
||||
#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
|
||||
|
||||
#define UpdateDAC(plane,dac,mask) {\
|
||||
if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
|
||||
pPriv->colors[plane].dac = pdef[i].dac; \
|
||||
updated = 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CheckDirect(plane) \
|
||||
UpdateDAC(plane,red,redMask) \
|
||||
UpdateDAC(plane,green,greenMask) \
|
||||
UpdateDAC(plane,blue,blueMask)
|
||||
|
||||
for (i = 0; i < ndef; i++)
|
||||
{
|
||||
CheckDirect (SOURCE_COLOR)
|
||||
CheckDirect (MASK_COLOR)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PseudoColor/GrayScale - match on exact pixel */
|
||||
for (i = 0; i < ndef; i++)
|
||||
{
|
||||
if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
|
||||
{
|
||||
pPriv->colors[SOURCE_COLOR] = pdef[i];
|
||||
if (++updated == 2)
|
||||
break;
|
||||
}
|
||||
if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
|
||||
{
|
||||
pPriv->colors[MASK_COLOR] = pdef[i];
|
||||
if (++updated == 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updated)
|
||||
{
|
||||
pPriv->checkPixels = TRUE;
|
||||
if (pPriv->isUp)
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteFindColors (ScreenPtr pScreen)
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr)
|
||||
pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
CursorPtr pCursor;
|
||||
xColorItem *sourceColor, *maskColor;
|
||||
|
||||
pCursor = pScreenPriv->pCursor;
|
||||
sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
|
||||
maskColor = &pScreenPriv->colors[MASK_COLOR];
|
||||
if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
|
||||
!(pCursor->foreRed == sourceColor->red &&
|
||||
pCursor->foreGreen == sourceColor->green &&
|
||||
pCursor->foreBlue == sourceColor->blue &&
|
||||
pCursor->backRed == maskColor->red &&
|
||||
pCursor->backGreen == maskColor->green &&
|
||||
pCursor->backBlue == maskColor->blue))
|
||||
{
|
||||
pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
|
||||
sourceColor->red = pCursor->foreRed;
|
||||
sourceColor->green = pCursor->foreGreen;
|
||||
sourceColor->blue = pCursor->foreBlue;
|
||||
FakeAllocColor (pScreenPriv->pColormap, sourceColor);
|
||||
maskColor->red = pCursor->backRed;
|
||||
maskColor->green = pCursor->backGreen;
|
||||
maskColor->blue = pCursor->backBlue;
|
||||
FakeAllocColor (pScreenPriv->pColormap, maskColor);
|
||||
/* "free" the pixels right away, don't let this confuse you */
|
||||
FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
|
||||
FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
|
||||
}
|
||||
pScreenPriv->checkPixels = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* BackingStore wrappers
|
||||
*/
|
||||
|
||||
static void
|
||||
miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
|
||||
WindowPtr pWin;
|
||||
RegionPtr pObscured;
|
||||
int dx, dy;
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
BoxRec cursorBox;
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
|
||||
SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
if (pScreenPriv->isUp)
|
||||
{
|
||||
cursorBox = pScreenPriv->saved;
|
||||
|
||||
if (dx || dy)
|
||||
{
|
||||
cursorBox.x1 += dx;
|
||||
cursorBox.y1 += dy;
|
||||
cursorBox.x2 += dx;
|
||||
cursorBox.y2 += dy;
|
||||
}
|
||||
if (RegionContainsRect(pObscured, &cursorBox) != rgnOUT)
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
|
||||
(*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy);
|
||||
|
||||
SCREEN_EPILOGUE (pScreen, SaveDoomedAreas);
|
||||
}
|
||||
|
||||
/*
|
||||
* miPointer interface routines
|
||||
*/
|
||||
|
||||
#define SPRITE_PAD 8
|
||||
|
||||
static Bool
|
||||
miSpriteRealizeCursor (pScreen, pCursor)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
if (pCursor == pScreenPriv->pCursor)
|
||||
pScreenPriv->checkPixels = TRUE;
|
||||
return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
|
||||
}
|
||||
|
||||
static Bool
|
||||
miSpriteUnrealizeCursor (pScreen, pCursor)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteSetCursor (pScreen, pCursor, x, y)
|
||||
ScreenPtr pScreen;
|
||||
CursorPtr pCursor;
|
||||
int x;
|
||||
int y;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
if (!pCursor)
|
||||
{
|
||||
pScreenPriv->shouldBeUp = FALSE;
|
||||
if (pScreenPriv->isUp)
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
pScreenPriv->pCursor = 0;
|
||||
return;
|
||||
}
|
||||
pScreenPriv->shouldBeUp = TRUE;
|
||||
if (pScreenPriv->x == x &&
|
||||
pScreenPriv->y == y &&
|
||||
pScreenPriv->pCursor == pCursor &&
|
||||
!pScreenPriv->checkPixels)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pScreenPriv->x = x;
|
||||
pScreenPriv->y = y;
|
||||
pScreenPriv->pCacheWin = NullWindow;
|
||||
if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor)
|
||||
{
|
||||
pScreenPriv->pCursor = pCursor;
|
||||
miSpriteFindColors (pScreen);
|
||||
}
|
||||
if (pScreenPriv->isUp) {
|
||||
int sx, sy;
|
||||
/*
|
||||
* check to see if the old saved region
|
||||
* encloses the new sprite, in which case we use
|
||||
* the flicker-free MoveCursor primitive.
|
||||
*/
|
||||
sx = pScreenPriv->x - (int)pCursor->bits->xhot;
|
||||
sy = pScreenPriv->y - (int)pCursor->bits->yhot;
|
||||
if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 &&
|
||||
sx < pScreenPriv->saved.x2 &&
|
||||
sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 &&
|
||||
sy < pScreenPriv->saved.y2 &&
|
||||
(int) pCursor->bits->width + (2 * SPRITE_PAD) ==
|
||||
pScreenPriv->saved.x2 - pScreenPriv->saved.x1 &&
|
||||
(int) pCursor->bits->height + (2 * SPRITE_PAD) ==
|
||||
pScreenPriv->saved.y2 - pScreenPriv->saved.y1
|
||||
)
|
||||
{
|
||||
DamageDrawInternal (pScreen, TRUE);
|
||||
miSpriteIsUpFALSE (pScreen, pScreenPriv);
|
||||
if (!(sx >= pScreenPriv->saved.x1 &&
|
||||
sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 &&
|
||||
sy >= pScreenPriv->saved.y1 &&
|
||||
sy + (int)pCursor->bits->height < pScreenPriv->saved.y2))
|
||||
{
|
||||
int oldx1, oldy1, dx, dy;
|
||||
|
||||
oldx1 = pScreenPriv->saved.x1;
|
||||
oldy1 = pScreenPriv->saved.y1;
|
||||
dx = oldx1 - (sx - SPRITE_PAD);
|
||||
dy = oldy1 - (sy - SPRITE_PAD);
|
||||
pScreenPriv->saved.x1 -= dx;
|
||||
pScreenPriv->saved.y1 -= dy;
|
||||
pScreenPriv->saved.x2 -= dx;
|
||||
pScreenPriv->saved.y2 -= dy;
|
||||
(void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
|
||||
pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y1,
|
||||
pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
|
||||
dx, dy);
|
||||
}
|
||||
(void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
|
||||
pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y1,
|
||||
pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
|
||||
sx - pScreenPriv->saved.x1,
|
||||
sy - pScreenPriv->saved.y1,
|
||||
pScreenPriv->colors[SOURCE_COLOR].pixel,
|
||||
pScreenPriv->colors[MASK_COLOR].pixel);
|
||||
miSpriteIsUpTRUE (pScreen, pScreenPriv);
|
||||
DamageDrawInternal (pScreen, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SPRITE_DEBUG (("SetCursor remove\n"));
|
||||
miSpriteRemoveCursor (pScreen);
|
||||
}
|
||||
}
|
||||
if (!pScreenPriv->isUp && pScreenPriv->pCursor)
|
||||
{
|
||||
SPRITE_DEBUG (("SetCursor restore\n"));
|
||||
miSpriteRestoreCursor (pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
miSpriteMoveCursor (pScreen, x, y)
|
||||
ScreenPtr pScreen;
|
||||
int x, y;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* undraw/draw cursor
|
||||
*/
|
||||
|
||||
static void
|
||||
miSpriteRemoveCursor (pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
|
||||
DamageDrawInternal (pScreen, TRUE);
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
miSpriteIsUpFALSE (pScreen, pScreenPriv);
|
||||
pScreenPriv->pCacheWin = NullWindow;
|
||||
if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
|
||||
pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y1,
|
||||
pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
|
||||
{
|
||||
miSpriteIsUpTRUE (pScreen, pScreenPriv);
|
||||
}
|
||||
DamageDrawInternal (pScreen, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from the block handler, restores the cursor
|
||||
* before waiting for something to do.
|
||||
*/
|
||||
|
||||
static void
|
||||
miSpriteRestoreCursor (pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
int x, y;
|
||||
CursorPtr pCursor;
|
||||
|
||||
DamageDrawInternal (pScreen, TRUE);
|
||||
miSpriteComputeSaved (pScreen);
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
pCursor = pScreenPriv->pCursor;
|
||||
x = pScreenPriv->x - (int)pCursor->bits->xhot;
|
||||
y = pScreenPriv->y - (int)pCursor->bits->yhot;
|
||||
if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
|
||||
pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y1,
|
||||
pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
|
||||
pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
|
||||
{
|
||||
if (pScreenPriv->checkPixels)
|
||||
miSpriteFindColors (pScreen);
|
||||
if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
|
||||
pScreenPriv->colors[SOURCE_COLOR].pixel,
|
||||
pScreenPriv->colors[MASK_COLOR].pixel))
|
||||
{
|
||||
miSpriteIsUpTRUE (pScreen, pScreenPriv);
|
||||
}
|
||||
}
|
||||
DamageDrawInternal (pScreen, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* compute the desired area of the screen to save
|
||||
*/
|
||||
|
||||
static void
|
||||
miSpriteComputeSaved (pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
miSpriteScreenPtr pScreenPriv;
|
||||
int x, y, w, h;
|
||||
int wpad, hpad;
|
||||
CursorPtr pCursor;
|
||||
|
||||
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
|
||||
pCursor = pScreenPriv->pCursor;
|
||||
x = pScreenPriv->x - (int)pCursor->bits->xhot;
|
||||
y = pScreenPriv->y - (int)pCursor->bits->yhot;
|
||||
w = pCursor->bits->width;
|
||||
h = pCursor->bits->height;
|
||||
wpad = SPRITE_PAD;
|
||||
hpad = SPRITE_PAD;
|
||||
pScreenPriv->saved.x1 = x - wpad;
|
||||
pScreenPriv->saved.y1 = y - hpad;
|
||||
pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
|
||||
pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
|
||||
}
|
||||
94
nx-X11/programs/Xserver/mi/misprite.h
Normal file
94
nx-X11/programs/Xserver/mi/misprite.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* misprite.h
|
||||
*
|
||||
* software-sprite/sprite drawing interface spec
|
||||
*
|
||||
* mi versions of these routines exist.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Bool (*RealizeCursor)(
|
||||
ScreenPtr /*pScreen*/,
|
||||
CursorPtr /*pCursor*/
|
||||
);
|
||||
Bool (*UnrealizeCursor)(
|
||||
ScreenPtr /*pScreen*/,
|
||||
CursorPtr /*pCursor*/
|
||||
);
|
||||
Bool (*PutUpCursor)(
|
||||
ScreenPtr /*pScreen*/,
|
||||
CursorPtr /*pCursor*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
unsigned long /*source*/,
|
||||
unsigned long /*mask*/
|
||||
);
|
||||
Bool (*SaveUnderCursor)(
|
||||
ScreenPtr /*pScreen*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*w*/,
|
||||
int /*h*/
|
||||
);
|
||||
Bool (*RestoreUnderCursor)(
|
||||
ScreenPtr /*pScreen*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*w*/,
|
||||
int /*h*/
|
||||
);
|
||||
Bool (*MoveCursor)(
|
||||
ScreenPtr /*pScreen*/,
|
||||
CursorPtr /*pCursor*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*w*/,
|
||||
int /*h*/,
|
||||
int /*dx*/,
|
||||
int /*dy*/,
|
||||
unsigned long /*source*/,
|
||||
unsigned long /*mask*/
|
||||
);
|
||||
Bool (*ChangeSave)(
|
||||
ScreenPtr /*pScreen*/,
|
||||
int /*x*/,
|
||||
int /*y*/,
|
||||
int /*w*/,
|
||||
int /*h*/,
|
||||
int /*dx*/,
|
||||
int /*dy*/
|
||||
);
|
||||
|
||||
} miSpriteCursorFuncRec, *miSpriteCursorFuncPtr;
|
||||
|
||||
extern Bool miSpriteInitialize(
|
||||
ScreenPtr /*pScreen*/,
|
||||
miSpriteCursorFuncPtr /*cursorFuncs*/,
|
||||
miPointerScreenFuncPtr /*screenFuncs*/
|
||||
);
|
||||
132
nx-X11/programs/Xserver/mi/mispritest.h
Normal file
132
nx-X11/programs/Xserver/mi/mispritest.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* mispritest.h
|
||||
*
|
||||
* mi sprite structures
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1989, 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _MISPRITEST_H_
|
||||
#define _MISPRITEST_H_
|
||||
|
||||
# include "misprite.h"
|
||||
#ifdef RENDER
|
||||
# include "picturestr.h"
|
||||
#endif
|
||||
# include "damage.h"
|
||||
|
||||
/*
|
||||
* per screen information
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* screen procedures */
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
GetImageProcPtr GetImage;
|
||||
GetSpansProcPtr GetSpans;
|
||||
SourceValidateProcPtr SourceValidate;
|
||||
|
||||
/* window procedures */
|
||||
CopyWindowProcPtr CopyWindow;
|
||||
|
||||
/* backing store procedures */
|
||||
SaveDoomedAreasProcPtr SaveDoomedAreas;
|
||||
|
||||
/* colormap procedures */
|
||||
InstallColormapProcPtr InstallColormap;
|
||||
StoreColorsProcPtr StoreColors;
|
||||
|
||||
/* os layer procedures */
|
||||
ScreenBlockHandlerProcPtr BlockHandler;
|
||||
|
||||
CursorPtr pCursor;
|
||||
int x; /* cursor hotspot */
|
||||
int y;
|
||||
BoxRec saved; /* saved area from the screen */
|
||||
Bool isUp; /* cursor in frame buffer */
|
||||
Bool shouldBeUp; /* cursor should be displayed */
|
||||
WindowPtr pCacheWin; /* window the cursor last seen in */
|
||||
Bool isInCacheWin;
|
||||
Bool checkPixels; /* check colormap collision */
|
||||
xColorItem colors[2];
|
||||
ColormapPtr pInstalledMap;
|
||||
ColormapPtr pColormap;
|
||||
VisualPtr pVisual;
|
||||
miSpriteCursorFuncPtr funcs;
|
||||
DamagePtr pDamage; /* damage tracking structure */
|
||||
} miSpriteScreenRec, *miSpriteScreenPtr;
|
||||
|
||||
#define SOURCE_COLOR 0
|
||||
#define MASK_COLOR 1
|
||||
|
||||
#define miSpriteIsUpTRUE(pScreen, pScreenPriv) if (!pScreenPriv->isUp) { \
|
||||
pScreenPriv->isUp = TRUE; \
|
||||
DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \
|
||||
}
|
||||
|
||||
#define miSpriteIsUpFALSE(pScreen, pScreenPriv) if (pScreenPriv->isUp) { \
|
||||
DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \
|
||||
pScreenPriv->isUp = FALSE; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Overlap BoxPtr and Box elements
|
||||
*/
|
||||
#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
|
||||
(((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
|
||||
((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
|
||||
|
||||
/*
|
||||
* Overlap BoxPtr, origins, and rectangle
|
||||
*/
|
||||
#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
|
||||
BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
|
||||
|
||||
/*
|
||||
* Overlap BoxPtr, origins and RectPtr
|
||||
*/
|
||||
#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
|
||||
ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \
|
||||
(int)((pRect)->width), (int)((pRect)->height))
|
||||
/*
|
||||
* Overlap BoxPtr and horizontal span
|
||||
*/
|
||||
#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
|
||||
|
||||
#define LINE_SORT(x1,y1,x2,y2) \
|
||||
{ int _t; \
|
||||
if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
|
||||
if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
|
||||
|
||||
#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \
|
||||
BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2))
|
||||
|
||||
#endif /* _MISPRITEST_H_ */
|
||||
63
nx-X11/programs/Xserver/mi/mistruct.h
Normal file
63
nx-X11/programs/Xserver/mi/mistruct.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef MISTRUCT_H
|
||||
#define MISTRUCT_H
|
||||
|
||||
#include "mi.h"
|
||||
#include "regionstr.h"
|
||||
|
||||
/* information about dashes */
|
||||
typedef struct _miDash {
|
||||
DDXPointRec pt;
|
||||
int e1, e2; /* keep these, so we don't have to do it again */
|
||||
int e; /* bresenham error term for this point on line */
|
||||
int which;
|
||||
int newLine;/* 0 if part of same original line as previous dash */
|
||||
} miDashRec;
|
||||
|
||||
#endif /* MISTRUCT_H */
|
||||
52
nx-X11/programs/Xserver/mi/mivalidate.h
Normal file
52
nx-X11/programs/Xserver/mi/mivalidate.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
Copyright 1993, 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef MIVALIDATE_H
|
||||
#define MIVALIDATE_H
|
||||
|
||||
#include "regionstr.h"
|
||||
|
||||
typedef union _Validate {
|
||||
struct BeforeValidate {
|
||||
DDXPointRec oldAbsCorner; /* old window position */
|
||||
RegionPtr borderVisible; /* visible region of border, */
|
||||
/* non-null when size changes */
|
||||
Bool resized; /* unclipped winSize has changed - */
|
||||
/* don't call SaveDoomedAreas */
|
||||
} before;
|
||||
struct AfterValidate {
|
||||
RegionRec exposed; /* exposed regions, absolute pos */
|
||||
RegionRec borderExposed;
|
||||
} after;
|
||||
} ValidateRec;
|
||||
|
||||
#endif /* MIVALIDATE_H */
|
||||
823
nx-X11/programs/Xserver/mi/mivaltree.c
Normal file
823
nx-X11/programs/Xserver/mi/mivaltree.c
Normal file
@@ -0,0 +1,823 @@
|
||||
/*
|
||||
* mivaltree.c --
|
||||
* Functions for recalculating window clip lists. Main function
|
||||
* is miValidateTree.
|
||||
*
|
||||
|
||||
Copyright 1987, 1988, 1989, 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.
|
||||
|
||||
*
|
||||
* Copyright 1987, 1988, 1989 by
|
||||
* Digital Equipment Corporation, Maynard, Massachusetts,
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of Digital not be
|
||||
* used in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
*
|
||||
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
/* The panoramix components contained the following notice */
|
||||
/*****************************************************************
|
||||
|
||||
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software.
|
||||
|
||||
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
|
||||
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
|
||||
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
|
||||
shall not be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Software without prior written authorization from Digital
|
||||
Equipment Corporation.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Aug '86: Susan Angebranndt -- original code
|
||||
* July '87: Adam de Boor -- substantially modified and commented
|
||||
* Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
|
||||
* In particular, much improved code for window mapping and
|
||||
* circulating.
|
||||
* Bob Scheifler -- avoid miComputeClips for unmapped windows,
|
||||
* valdata changes
|
||||
*/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include "scrnintstr.h"
|
||||
#include "validate.h"
|
||||
#include "windowstr.h"
|
||||
#include "mi.h"
|
||||
#include "regionstr.h"
|
||||
#include "mivalidate.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef SHAPE
|
||||
/*
|
||||
* Compute the visibility of a shaped window
|
||||
*/
|
||||
int
|
||||
miShapedWindowIn (pScreen, universe, bounding, rect, x, y)
|
||||
ScreenPtr pScreen;
|
||||
RegionPtr universe, bounding;
|
||||
BoxPtr rect;
|
||||
register int x, y;
|
||||
{
|
||||
BoxRec box;
|
||||
register BoxPtr boundBox;
|
||||
int nbox;
|
||||
Bool someIn, someOut;
|
||||
register int t, x1, y1, x2, y2;
|
||||
|
||||
nbox = RegionNumRects (bounding);
|
||||
boundBox = RegionRects (bounding);
|
||||
someIn = someOut = FALSE;
|
||||
x1 = rect->x1;
|
||||
y1 = rect->y1;
|
||||
x2 = rect->x2;
|
||||
y2 = rect->y2;
|
||||
while (nbox--)
|
||||
{
|
||||
if ((t = boundBox->x1 + x) < x1)
|
||||
t = x1;
|
||||
box.x1 = t;
|
||||
if ((t = boundBox->y1 + y) < y1)
|
||||
t = y1;
|
||||
box.y1 = t;
|
||||
if ((t = boundBox->x2 + x) > x2)
|
||||
t = x2;
|
||||
box.x2 = t;
|
||||
if ((t = boundBox->y2 + y) > y2)
|
||||
t = y2;
|
||||
box.y2 = t;
|
||||
if (box.x1 > box.x2)
|
||||
box.x2 = box.x1;
|
||||
if (box.y1 > box.y2)
|
||||
box.y2 = box.y1;
|
||||
switch (RegionContainsRect(universe, &box))
|
||||
{
|
||||
case rgnIN:
|
||||
if (someOut)
|
||||
return rgnPART;
|
||||
someIn = TRUE;
|
||||
break;
|
||||
case rgnOUT:
|
||||
if (someIn)
|
||||
return rgnPART;
|
||||
someOut = TRUE;
|
||||
break;
|
||||
default:
|
||||
return rgnPART;
|
||||
}
|
||||
boundBox++;
|
||||
}
|
||||
if (someIn)
|
||||
return rgnIN;
|
||||
return rgnOUT;
|
||||
}
|
||||
#endif
|
||||
|
||||
static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc;
|
||||
static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc;
|
||||
|
||||
void
|
||||
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
|
||||
GetRedirectBorderClipProcPtr getBorderClip)
|
||||
{
|
||||
miSetRedirectBorderClipProc = setBorderClip;
|
||||
miGetRedirectBorderClipProc = getBorderClip;
|
||||
}
|
||||
|
||||
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
|
||||
HasBorder(w) && \
|
||||
(w)->backgroundState == ParentRelative)
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
* miComputeClips --
|
||||
* Recompute the clipList, borderClip, exposed and borderExposed
|
||||
* regions for pParent and its children. Only viewable windows are
|
||||
* taken into account.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* clipList, borderClip, exposed and borderExposed are altered.
|
||||
* A VisibilityNotify event may be generated on the parent window.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
miComputeClips (
|
||||
register WindowPtr pParent,
|
||||
register ScreenPtr pScreen,
|
||||
register RegionPtr universe,
|
||||
VTKind kind,
|
||||
RegionPtr exposed ) /* for intermediate calculations */
|
||||
{
|
||||
int dx,
|
||||
dy;
|
||||
RegionRec childUniverse;
|
||||
register WindowPtr pChild;
|
||||
int oldVis, newVis;
|
||||
BoxRec borderSize;
|
||||
RegionRec childUnion;
|
||||
Bool overlap;
|
||||
RegionPtr borderVisible;
|
||||
Bool resized;
|
||||
/*
|
||||
* Figure out the new visibility of this window.
|
||||
* The extent of the universe should be the same as the extent of
|
||||
* the borderSize region. If the window is unobscured, this rectangle
|
||||
* will be completely inside the universe (the universe will cover it
|
||||
* completely). If the window is completely obscured, none of the
|
||||
* universe will cover the rectangle.
|
||||
*/
|
||||
borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
|
||||
borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
|
||||
dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
|
||||
if (dx > 32767)
|
||||
dx = 32767;
|
||||
borderSize.x2 = dx;
|
||||
dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
|
||||
if (dy > 32767)
|
||||
dy = 32767;
|
||||
borderSize.y2 = dy;
|
||||
|
||||
#ifdef COMPOSITE
|
||||
/*
|
||||
* In redirected drawing case, reset universe to borderSize
|
||||
*/
|
||||
if (pParent->redirectDraw)
|
||||
{
|
||||
if (miSetRedirectBorderClipProc)
|
||||
(*miSetRedirectBorderClipProc) (pParent, universe);
|
||||
RegionCopy(universe, &pParent->borderSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
oldVis = pParent->visibility;
|
||||
switch (RegionContainsRect(universe, &borderSize))
|
||||
{
|
||||
case rgnIN:
|
||||
newVis = VisibilityUnobscured;
|
||||
break;
|
||||
case rgnPART:
|
||||
newVis = VisibilityPartiallyObscured;
|
||||
#ifdef SHAPE
|
||||
{
|
||||
RegionPtr pBounding;
|
||||
|
||||
if ((pBounding = wBoundingShape (pParent)))
|
||||
{
|
||||
switch (miShapedWindowIn (pScreen, universe, pBounding,
|
||||
&borderSize,
|
||||
pParent->drawable.x,
|
||||
pParent->drawable.y))
|
||||
{
|
||||
case rgnIN:
|
||||
newVis = VisibilityUnobscured;
|
||||
break;
|
||||
case rgnOUT:
|
||||
newVis = VisibilityFullyObscured;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
newVis = VisibilityFullyObscured;
|
||||
break;
|
||||
}
|
||||
pParent->visibility = newVis;
|
||||
if (oldVis != newVis &&
|
||||
((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
|
||||
SendVisibilityNotify(pParent);
|
||||
|
||||
dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
|
||||
dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
|
||||
|
||||
/*
|
||||
* avoid computations when dealing with simple operations
|
||||
*/
|
||||
|
||||
switch (kind) {
|
||||
case VTMap:
|
||||
case VTStack:
|
||||
case VTUnmap:
|
||||
break;
|
||||
case VTMove:
|
||||
if ((oldVis == newVis) &&
|
||||
((oldVis == VisibilityFullyObscured) ||
|
||||
(oldVis == VisibilityUnobscured)))
|
||||
{
|
||||
pChild = pParent;
|
||||
while (1)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
{
|
||||
if (pChild->visibility != VisibilityFullyObscured)
|
||||
{
|
||||
RegionTranslate(&pChild->borderClip,
|
||||
dx, dy);
|
||||
RegionTranslate(&pChild->clipList,
|
||||
dx, dy);
|
||||
pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
if (pScreen->ClipNotify)
|
||||
(* pScreen->ClipNotify) (pChild, dx, dy);
|
||||
|
||||
}
|
||||
if (pChild->valdata)
|
||||
{
|
||||
RegionNull(
|
||||
&pChild->valdata->after.borderExposed);
|
||||
if (HasParentRelativeBorder(pChild))
|
||||
{
|
||||
RegionSubtract(
|
||||
&pChild->valdata->after.borderExposed,
|
||||
&pChild->borderClip,
|
||||
&pChild->winSize);
|
||||
}
|
||||
RegionNull(&pChild->valdata->after.exposed);
|
||||
}
|
||||
if (pChild->firstChild)
|
||||
{
|
||||
pChild = pChild->firstChild;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (!pChild->nextSib && (pChild != pParent))
|
||||
pChild = pChild->parent;
|
||||
if (pChild == pParent)
|
||||
break;
|
||||
pChild = pChild->nextSib;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
/*
|
||||
* To calculate exposures correctly, we have to translate the old
|
||||
* borderClip and clipList regions to the window's new location so there
|
||||
* is a correspondence between pieces of the new and old clipping regions.
|
||||
*/
|
||||
if (dx || dy)
|
||||
{
|
||||
/*
|
||||
* We translate the old clipList because that will be exposed or copied
|
||||
* if gravity is right.
|
||||
*/
|
||||
RegionTranslate(&pParent->borderClip, dx, dy);
|
||||
RegionTranslate(&pParent->clipList, dx, dy);
|
||||
}
|
||||
break;
|
||||
case VTBroken:
|
||||
RegionEmpty(&pParent->borderClip);
|
||||
RegionEmpty(&pParent->clipList);
|
||||
break;
|
||||
}
|
||||
|
||||
borderVisible = pParent->valdata->before.borderVisible;
|
||||
resized = pParent->valdata->before.resized;
|
||||
RegionNull(&pParent->valdata->after.borderExposed);
|
||||
RegionNull(&pParent->valdata->after.exposed);
|
||||
|
||||
/*
|
||||
* Since the borderClip must not be clipped by the children, we do
|
||||
* the border exposure first...
|
||||
*
|
||||
* 'universe' is the window's borderClip. To figure the exposures, remove
|
||||
* the area that used to be exposed from the new.
|
||||
* This leaves a region of pieces that weren't exposed before.
|
||||
*/
|
||||
|
||||
if (HasBorder (pParent))
|
||||
{
|
||||
if (borderVisible)
|
||||
{
|
||||
/*
|
||||
* when the border changes shape, the old visible portions
|
||||
* of the border will be saved by DIX in borderVisible --
|
||||
* use that region and destroy it
|
||||
*/
|
||||
RegionSubtract(exposed, universe, borderVisible);
|
||||
RegionDestroy(borderVisible);
|
||||
}
|
||||
else
|
||||
{
|
||||
RegionSubtract(exposed, universe, &pParent->borderClip);
|
||||
}
|
||||
if (HasParentRelativeBorder(pParent) && (dx || dy))
|
||||
RegionSubtract(&pParent->valdata->after.borderExposed,
|
||||
universe,
|
||||
&pParent->winSize);
|
||||
else
|
||||
RegionSubtract(&pParent->valdata->after.borderExposed,
|
||||
exposed, &pParent->winSize);
|
||||
|
||||
RegionCopy(&pParent->borderClip, universe);
|
||||
|
||||
/*
|
||||
* To get the right clipList for the parent, and to make doubly sure
|
||||
* that no child overlaps the parent's border, we remove the parent's
|
||||
* border from the universe before proceeding.
|
||||
*/
|
||||
|
||||
RegionIntersect(universe, universe, &pParent->winSize);
|
||||
}
|
||||
else
|
||||
RegionCopy(&pParent->borderClip, universe);
|
||||
|
||||
if ((pChild = pParent->firstChild) && pParent->mapped)
|
||||
{
|
||||
RegionNull(&childUniverse);
|
||||
RegionNull(&childUnion);
|
||||
if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
|
||||
((pChild->drawable.y == pParent->lastChild->drawable.y) &&
|
||||
(pChild->drawable.x < pParent->lastChild->drawable.x)))
|
||||
{
|
||||
for (; pChild; pChild = pChild->nextSib)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
RegionAppend(&childUnion, &pChild->borderSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
RegionAppend(&childUnion, &pChild->borderSize);
|
||||
}
|
||||
}
|
||||
RegionValidate(&childUnion, &overlap);
|
||||
|
||||
for (pChild = pParent->firstChild;
|
||||
pChild;
|
||||
pChild = pChild->nextSib)
|
||||
{
|
||||
if (pChild->viewable) {
|
||||
/*
|
||||
* If the child is viewable, we want to remove its extents
|
||||
* from the current universe, but we only re-clip it if
|
||||
* it's been marked.
|
||||
*/
|
||||
if (pChild->valdata) {
|
||||
/*
|
||||
* Figure out the new universe from the child's
|
||||
* perspective and recurse.
|
||||
*/
|
||||
RegionIntersect(&childUniverse,
|
||||
universe,
|
||||
&pChild->borderSize);
|
||||
miComputeClips (pChild, pScreen, &childUniverse, kind,
|
||||
exposed);
|
||||
}
|
||||
/*
|
||||
* Once the child has been processed, we remove its extents
|
||||
* from the current universe, thus denying its space to any
|
||||
* other sibling.
|
||||
*/
|
||||
if (overlap)
|
||||
RegionSubtract(universe, universe,
|
||||
&pChild->borderSize);
|
||||
}
|
||||
}
|
||||
if (!overlap)
|
||||
RegionSubtract(universe, universe, &childUnion);
|
||||
RegionUninit(&childUnion);
|
||||
RegionUninit(&childUniverse);
|
||||
} /* if any children */
|
||||
|
||||
/*
|
||||
* 'universe' now contains the new clipList for the parent window.
|
||||
*
|
||||
* To figure the exposure of the window we subtract the old clip from the
|
||||
* new, just as for the border.
|
||||
*/
|
||||
|
||||
if (oldVis == VisibilityFullyObscured ||
|
||||
oldVis == VisibilityNotViewable)
|
||||
{
|
||||
RegionCopy(&pParent->valdata->after.exposed, universe);
|
||||
}
|
||||
else if (newVis != VisibilityFullyObscured &&
|
||||
newVis != VisibilityNotViewable)
|
||||
{
|
||||
RegionSubtract(&pParent->valdata->after.exposed,
|
||||
universe, &pParent->clipList);
|
||||
}
|
||||
|
||||
/*
|
||||
* One last thing: backing storage. We have to try to save what parts of
|
||||
* the window are about to be obscured. We can just subtract the universe
|
||||
* from the old clipList and get the areas that were in the old but aren't
|
||||
* in the new and, hence, are about to be obscured.
|
||||
*/
|
||||
if (pParent->backStorage && !resized)
|
||||
{
|
||||
RegionSubtract(exposed, &pParent->clipList, universe);
|
||||
(* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
|
||||
}
|
||||
|
||||
/* HACK ALERT - copying contents of regions, instead of regions */
|
||||
{
|
||||
RegionRec tmp;
|
||||
|
||||
tmp = pParent->clipList;
|
||||
pParent->clipList = *universe;
|
||||
*universe = tmp;
|
||||
}
|
||||
|
||||
#ifdef NOTDEF
|
||||
RegionCopy(&pParent->clipList, universe);
|
||||
#endif
|
||||
|
||||
pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
|
||||
if (pScreen->ClipNotify)
|
||||
(* pScreen->ClipNotify) (pParent, dx, dy);
|
||||
}
|
||||
|
||||
static void
|
||||
miTreeObscured(
|
||||
register WindowPtr pParent )
|
||||
{
|
||||
register WindowPtr pChild;
|
||||
register int oldVis;
|
||||
|
||||
pChild = pParent;
|
||||
while (1)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
{
|
||||
oldVis = pChild->visibility;
|
||||
if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
|
||||
((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
|
||||
SendVisibilityNotify(pChild);
|
||||
if (pChild->firstChild)
|
||||
{
|
||||
pChild = pChild->firstChild;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (!pChild->nextSib && (pChild != pParent))
|
||||
pChild = pChild->parent;
|
||||
if (pChild == pParent)
|
||||
break;
|
||||
pChild = pChild->nextSib;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
* miValidateTree --
|
||||
* Recomputes the clip list for pParent and all its inferiors.
|
||||
*
|
||||
* Results:
|
||||
* Always returns 1.
|
||||
*
|
||||
* Side Effects:
|
||||
* The clipList, borderClip, exposed, and borderExposed regions for
|
||||
* each marked window are altered.
|
||||
*
|
||||
* Notes:
|
||||
* This routine assumes that all affected windows have been marked
|
||||
* (valdata created) and their winSize and borderSize regions
|
||||
* adjusted to correspond to their new positions. The borderClip and
|
||||
* clipList regions should not have been touched.
|
||||
*
|
||||
* The top-most level is treated differently from all lower levels
|
||||
* because pParent is unchanged. For the top level, we merge the
|
||||
* regions taken up by the marked children back into the clipList
|
||||
* for pParent, thus forming a region from which the marked children
|
||||
* can claim their areas. For lower levels, where the old clipList
|
||||
* and borderClip are invalid, we can't do this and have to do the
|
||||
* extra operations done in miComputeClips, but this is much faster
|
||||
* e.g. when only one child has moved...
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
miValidateTree (pParent, pChild, kind)
|
||||
WindowPtr pParent; /* Parent to validate */
|
||||
WindowPtr pChild; /* First child of pParent that was
|
||||
* affected */
|
||||
VTKind kind; /* What kind of configuration caused call */
|
||||
{
|
||||
RegionRec totalClip; /* Total clipping region available to
|
||||
* the marked children. pParent's clipList
|
||||
* merged with the borderClips of all
|
||||
* the marked children. */
|
||||
RegionRec childClip; /* The new borderClip for the current
|
||||
* child */
|
||||
RegionRec childUnion; /* the space covered by borderSize for
|
||||
* all marked children */
|
||||
RegionRec exposed; /* For intermediate calculations */
|
||||
register ScreenPtr pScreen;
|
||||
register WindowPtr pWin;
|
||||
Bool overlap;
|
||||
int viewvals;
|
||||
Bool forward;
|
||||
|
||||
pScreen = pParent->drawable.pScreen;
|
||||
if (pChild == NullWindow)
|
||||
pChild = pParent->firstChild;
|
||||
|
||||
RegionNull(&childClip);
|
||||
RegionNull(&exposed);
|
||||
|
||||
/*
|
||||
* compute the area of the parent window occupied
|
||||
* by the marked children + the parent itself. This
|
||||
* is the area which can be divied up among the marked
|
||||
* children in their new configuration.
|
||||
*/
|
||||
RegionNull(&totalClip);
|
||||
viewvals = 0;
|
||||
if (RegionBroken(&pParent->clipList) &&
|
||||
!RegionBroken(&pParent->borderClip))
|
||||
{
|
||||
kind = VTBroken;
|
||||
/*
|
||||
* When rebuilding clip lists after out of memory,
|
||||
* assume everything is busted.
|
||||
*/
|
||||
forward = TRUE;
|
||||
RegionCopy(&totalClip, &pParent->borderClip);
|
||||
RegionIntersect(&totalClip, &totalClip, &pParent->winSize);
|
||||
|
||||
for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib)
|
||||
{
|
||||
if (pWin->viewable)
|
||||
RegionSubtract(&totalClip, &totalClip, &pWin->borderSize);
|
||||
}
|
||||
for (pWin = pChild; pWin; pWin = pWin->nextSib)
|
||||
if (pWin->valdata && pWin->viewable)
|
||||
viewvals++;
|
||||
|
||||
RegionEmpty(&pParent->clipList);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
|
||||
((pChild->drawable.y == pParent->lastChild->drawable.y) &&
|
||||
(pChild->drawable.x < pParent->lastChild->drawable.x)))
|
||||
{
|
||||
forward = TRUE;
|
||||
for (pWin = pChild; pWin; pWin = pWin->nextSib)
|
||||
{
|
||||
if (pWin->valdata)
|
||||
{
|
||||
RegionPtr pBorderClip = &pWin->borderClip;
|
||||
#ifdef COMPOSITE
|
||||
if (pWin->redirectDraw && miGetRedirectBorderClipProc)
|
||||
pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
|
||||
#endif
|
||||
RegionAppend(&totalClip, pBorderClip );
|
||||
if (pWin->viewable)
|
||||
viewvals++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forward = FALSE;
|
||||
pWin = pParent->lastChild;
|
||||
while (1)
|
||||
{
|
||||
if (pWin->valdata)
|
||||
{
|
||||
RegionPtr pBorderClip = &pWin->borderClip;
|
||||
#ifdef COMPOSITE
|
||||
if (pWin->redirectDraw && miGetRedirectBorderClipProc)
|
||||
pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
|
||||
#endif
|
||||
RegionAppend(&totalClip, pBorderClip );
|
||||
if (pWin->viewable)
|
||||
viewvals++;
|
||||
}
|
||||
if (pWin == pChild)
|
||||
break;
|
||||
pWin = pWin->prevSib;
|
||||
}
|
||||
}
|
||||
RegionValidate(&totalClip, &overlap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now go through the children of the root and figure their new
|
||||
* borderClips from the totalClip, passing that off to miComputeClips
|
||||
* to handle recursively. Once that's done, we remove the child
|
||||
* from the totalClip to clip any siblings below it.
|
||||
*/
|
||||
|
||||
overlap = TRUE;
|
||||
if (kind != VTStack)
|
||||
{
|
||||
RegionUnion(&totalClip, &totalClip, &pParent->clipList);
|
||||
if (viewvals > 1)
|
||||
{
|
||||
/*
|
||||
* precompute childUnion to discover whether any of them
|
||||
* overlap. This seems redundant, but performance studies
|
||||
* have demonstrated that the cost of this loop is
|
||||
* lower than the cost of multiple Subtracts in the
|
||||
* loop below.
|
||||
*/
|
||||
RegionNull(&childUnion);
|
||||
if (forward)
|
||||
{
|
||||
for (pWin = pChild; pWin; pWin = pWin->nextSib)
|
||||
if (pWin->valdata && pWin->viewable)
|
||||
RegionAppend(&childUnion,
|
||||
&pWin->borderSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
pWin = pParent->lastChild;
|
||||
while (1)
|
||||
{
|
||||
if (pWin->valdata && pWin->viewable)
|
||||
RegionAppend(&childUnion,
|
||||
&pWin->borderSize);
|
||||
if (pWin == pChild)
|
||||
break;
|
||||
pWin = pWin->prevSib;
|
||||
}
|
||||
}
|
||||
RegionValidate(&childUnion, &overlap);
|
||||
if (overlap)
|
||||
RegionUninit(&childUnion);
|
||||
}
|
||||
}
|
||||
|
||||
for (pWin = pChild;
|
||||
pWin != NullWindow;
|
||||
pWin = pWin->nextSib)
|
||||
{
|
||||
if (pWin->viewable) {
|
||||
if (pWin->valdata) {
|
||||
RegionIntersect(&childClip,
|
||||
&totalClip,
|
||||
&pWin->borderSize);
|
||||
miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
|
||||
if (overlap)
|
||||
{
|
||||
RegionSubtract(&totalClip,
|
||||
&totalClip,
|
||||
&pWin->borderSize);
|
||||
}
|
||||
} else if (pWin->visibility == VisibilityNotViewable) {
|
||||
miTreeObscured(pWin);
|
||||
}
|
||||
} else {
|
||||
if (pWin->valdata) {
|
||||
RegionEmpty(&pWin->clipList);
|
||||
if (pScreen->ClipNotify)
|
||||
(* pScreen->ClipNotify) (pWin, 0, 0);
|
||||
RegionEmpty(&pWin->borderClip);
|
||||
pWin->valdata = (ValidatePtr)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RegionUninit(&childClip);
|
||||
if (!overlap)
|
||||
{
|
||||
RegionSubtract(&totalClip, &totalClip, &childUnion);
|
||||
RegionUninit(&childUnion);
|
||||
}
|
||||
|
||||
RegionNull(&pParent->valdata->after.exposed);
|
||||
RegionNull(&pParent->valdata->after.borderExposed);
|
||||
|
||||
/*
|
||||
* each case below is responsible for updating the
|
||||
* clipList and serial number for the parent window
|
||||
*/
|
||||
|
||||
switch (kind) {
|
||||
case VTStack:
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* totalClip contains the new clipList for the parent. Figure out
|
||||
* exposures and obscures as per miComputeClips and reset the parent's
|
||||
* clipList.
|
||||
*/
|
||||
RegionSubtract(&pParent->valdata->after.exposed,
|
||||
&totalClip, &pParent->clipList);
|
||||
/* fall through */
|
||||
case VTMap:
|
||||
if (pParent->backStorage) {
|
||||
RegionSubtract(&exposed, &pParent->clipList, &totalClip);
|
||||
(* pScreen->SaveDoomedAreas)(pParent, &exposed, 0, 0);
|
||||
}
|
||||
|
||||
RegionCopy(&pParent->clipList, &totalClip);
|
||||
pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
break;
|
||||
}
|
||||
|
||||
RegionUninit(&totalClip);
|
||||
RegionUninit(&exposed);
|
||||
if (pScreen->ClipNotify)
|
||||
(*pScreen->ClipNotify) (pParent, 0, 0);
|
||||
return (1);
|
||||
}
|
||||
2243
nx-X11/programs/Xserver/mi/miwideline.c
Normal file
2243
nx-X11/programs/Xserver/mi/miwideline.c
Normal file
File diff suppressed because it is too large
Load Diff
222
nx-X11/programs/Xserver/mi/miwideline.h
Normal file
222
nx-X11/programs/Xserver/mi/miwideline.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
|
||||
Copyright 1988, 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.
|
||||
|
||||
*/
|
||||
|
||||
/* Author: Keith Packard, MIT X Consortium */
|
||||
|
||||
#include "mispans.h"
|
||||
#include "mifpoly.h" /* for ICEIL */
|
||||
|
||||
/*
|
||||
* interface data to span-merging polygon filler
|
||||
*/
|
||||
|
||||
typedef struct _SpanData {
|
||||
SpanGroup fgGroup, bgGroup;
|
||||
} SpanDataRec, *SpanDataPtr;
|
||||
|
||||
#define AppendSpanGroup(pGC, pixel, spanPtr, spanData) { \
|
||||
SpanGroup *group, *othergroup = NULL; \
|
||||
if (pixel == pGC->fgPixel) \
|
||||
{ \
|
||||
group = &spanData->fgGroup; \
|
||||
if (pGC->lineStyle == LineDoubleDash) \
|
||||
othergroup = &spanData->bgGroup; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
group = &spanData->bgGroup; \
|
||||
othergroup = &spanData->fgGroup; \
|
||||
} \
|
||||
miAppendSpans (group, othergroup, spanPtr); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Polygon edge description for integer wide-line routines
|
||||
*/
|
||||
|
||||
typedef struct _PolyEdge {
|
||||
int height; /* number of scanlines to process */
|
||||
int x; /* starting x coordinate */
|
||||
int stepx; /* fixed integral dx */
|
||||
int signdx; /* variable dx sign */
|
||||
int e; /* initial error term */
|
||||
int dy;
|
||||
int dx;
|
||||
} PolyEdgeRec, *PolyEdgePtr;
|
||||
|
||||
#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
|
||||
|
||||
/*
|
||||
* types for general polygon routines
|
||||
*/
|
||||
|
||||
typedef struct _PolyVertex {
|
||||
double x, y;
|
||||
} PolyVertexRec, *PolyVertexPtr;
|
||||
|
||||
typedef struct _PolySlope {
|
||||
int dx, dy;
|
||||
double k; /* x0 * dy - y0 * dx */
|
||||
} PolySlopeRec, *PolySlopePtr;
|
||||
|
||||
/*
|
||||
* Line face description for caps/joins
|
||||
*/
|
||||
|
||||
typedef struct _LineFace {
|
||||
double xa, ya;
|
||||
int dx, dy;
|
||||
int x, y;
|
||||
double k;
|
||||
} LineFaceRec, *LineFacePtr;
|
||||
|
||||
/*
|
||||
* macros for polygon fillers
|
||||
*/
|
||||
|
||||
#define MIPOLYRELOADLEFT if (!left_height && left_count) { \
|
||||
left_height = left->height; \
|
||||
left_x = left->x; \
|
||||
left_stepx = left->stepx; \
|
||||
left_signdx = left->signdx; \
|
||||
left_e = left->e; \
|
||||
left_dy = left->dy; \
|
||||
left_dx = left->dx; \
|
||||
--left_count; \
|
||||
++left; \
|
||||
}
|
||||
|
||||
#define MIPOLYRELOADRIGHT if (!right_height && right_count) { \
|
||||
right_height = right->height; \
|
||||
right_x = right->x; \
|
||||
right_stepx = right->stepx; \
|
||||
right_signdx = right->signdx; \
|
||||
right_e = right->e; \
|
||||
right_dy = right->dy; \
|
||||
right_dx = right->dx; \
|
||||
--right_count; \
|
||||
++right; \
|
||||
}
|
||||
|
||||
#define MIPOLYSTEPLEFT left_x += left_stepx; \
|
||||
left_e += left_dx; \
|
||||
if (left_e > 0) \
|
||||
{ \
|
||||
left_x += left_signdx; \
|
||||
left_e -= left_dy; \
|
||||
}
|
||||
|
||||
#define MIPOLYSTEPRIGHT right_x += right_stepx; \
|
||||
right_e += right_dx; \
|
||||
if (right_e > 0) \
|
||||
{ \
|
||||
right_x += right_signdx; \
|
||||
right_e -= right_dy; \
|
||||
}
|
||||
|
||||
#define MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
|
||||
oldPixel = pGC->fgPixel; \
|
||||
if (pixel != oldPixel) { \
|
||||
DoChangeGC (pGC, GCForeground, (XID *) &pixel, FALSE); \
|
||||
ValidateGC (pDrawable, pGC); \
|
||||
} \
|
||||
}
|
||||
#define MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
|
||||
if (pixel != oldPixel) { \
|
||||
DoChangeGC (pGC, GCForeground, (XID *) &oldPixel, FALSE); \
|
||||
ValidateGC (pDrawable, pGC); \
|
||||
} \
|
||||
}
|
||||
|
||||
extern void miFillPolyHelper(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
unsigned long /*pixel*/,
|
||||
SpanDataPtr /*spanData*/,
|
||||
int /*y*/,
|
||||
int /*overall_height*/,
|
||||
PolyEdgePtr /*left*/,
|
||||
PolyEdgePtr /*right*/,
|
||||
int /*left_count*/,
|
||||
int /*right_count*/
|
||||
);
|
||||
extern int miRoundJoinFace(
|
||||
LineFacePtr /*face*/,
|
||||
PolyEdgePtr /*edge*/,
|
||||
Bool * /*leftEdge*/
|
||||
);
|
||||
|
||||
extern void miRoundJoinClip(
|
||||
LineFacePtr /*pLeft*/,
|
||||
LineFacePtr /*pRight*/,
|
||||
PolyEdgePtr /*edge1*/,
|
||||
PolyEdgePtr /*edge2*/,
|
||||
int * /*y1*/,
|
||||
int * /*y2*/,
|
||||
Bool * /*left1*/,
|
||||
Bool * /*left2*/
|
||||
);
|
||||
|
||||
extern int miRoundCapClip(
|
||||
LineFacePtr /*face*/,
|
||||
Bool /*isInt*/,
|
||||
PolyEdgePtr /*edge*/,
|
||||
Bool * /*leftEdge*/
|
||||
);
|
||||
|
||||
extern void miLineProjectingCap(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
unsigned long /*pixel*/,
|
||||
SpanDataPtr /*spanData*/,
|
||||
LineFacePtr /*face*/,
|
||||
Bool /*isLeft*/,
|
||||
double /*xorg*/,
|
||||
double /*yorg*/,
|
||||
Bool /*isInt*/
|
||||
);
|
||||
|
||||
extern SpanDataPtr miSetupSpanData(
|
||||
GCPtr /*pGC*/,
|
||||
SpanDataPtr /*spanData*/,
|
||||
int /*npt*/
|
||||
);
|
||||
|
||||
extern void miCleanupSpanData(
|
||||
DrawablePtr /*pDrawable*/,
|
||||
GCPtr /*pGC*/,
|
||||
SpanDataPtr /*spanData*/
|
||||
);
|
||||
|
||||
extern int miPolyBuildEdge(double x0, double y0, double k, int dx, int dy,
|
||||
int xi, int yi, int left, PolyEdgePtr edge);
|
||||
extern int miPolyBuildPoly(PolyVertexPtr vertices, PolySlopePtr slopes,
|
||||
int count, int xi, int yi, PolyEdgePtr left,
|
||||
PolyEdgePtr right, int *pnleft, int *pnright,
|
||||
int *h);
|
||||
|
||||
1192
nx-X11/programs/Xserver/mi/miwindow.c
Normal file
1192
nx-X11/programs/Xserver/mi/miwindow.c
Normal file
File diff suppressed because it is too large
Load Diff
853
nx-X11/programs/Xserver/mi/mizerarc.c
Normal file
853
nx-X11/programs/Xserver/mi/mizerarc.c
Normal file
@@ -0,0 +1,853 @@
|
||||
/************************************************************
|
||||
|
||||
Copyright 1989, 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.
|
||||
|
||||
Author: Bob Scheifler, MIT X Consortium
|
||||
|
||||
********************************************************/
|
||||
|
||||
|
||||
/* Derived from:
|
||||
* "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
|
||||
* by M. L. V. Pitteway
|
||||
* The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xprotostr.h>
|
||||
#include "regionstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "mi.h"
|
||||
#include "mizerarc.h"
|
||||
|
||||
#define FULLCIRCLE (360 * 64)
|
||||
#define OCTANT (45 * 64)
|
||||
#define QUADRANT (90 * 64)
|
||||
#define HALFCIRCLE (180 * 64)
|
||||
#define QUADRANT3 (270 * 64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define Dsin(d) ((d) == 0 ? 0.0 : ((d) == QUADRANT ? 1.0 : \
|
||||
((d) == HALFCIRCLE ? 0.0 : \
|
||||
((d) == QUADRANT3 ? -1.0 : sin((double)d*(M_PI/11520.0))))))
|
||||
|
||||
#define Dcos(d) ((d) == 0 ? 1.0 : ((d) == QUADRANT ? 0.0 : \
|
||||
((d) == HALFCIRCLE ? -1.0 : \
|
||||
((d) == QUADRANT3 ? 0.0 : cos((double)d*(M_PI/11520.0))))))
|
||||
|
||||
#define EPSILON45 64
|
||||
|
||||
typedef struct {
|
||||
int skipStart;
|
||||
int haveStart;
|
||||
DDXPointRec startPt;
|
||||
int haveLast;
|
||||
int skipLast;
|
||||
DDXPointRec endPt;
|
||||
int dashIndex;
|
||||
int dashOffset;
|
||||
int dashIndexInit;
|
||||
int dashOffsetInit;
|
||||
} DashInfo;
|
||||
|
||||
static miZeroArcPtRec oob = {65536, 65536, 0};
|
||||
|
||||
/*
|
||||
* (x - l)^2 / (W/2)^2 + (y + H/2)^2 / (H/2)^2 = 1
|
||||
*
|
||||
* where l is either 0 or .5
|
||||
*
|
||||
* alpha = 4(W^2)
|
||||
* beta = 4(H^2)
|
||||
* gamma = 0
|
||||
* u = 2(W^2)H
|
||||
* v = 4(H^2)l
|
||||
* k = -4(H^2)(l^2)
|
||||
*
|
||||
*/
|
||||
|
||||
Bool
|
||||
miZeroArcSetup(arc, info, ok360)
|
||||
register xArc *arc;
|
||||
register miZeroArcRec *info;
|
||||
Bool ok360;
|
||||
{
|
||||
int l;
|
||||
int angle1, angle2;
|
||||
int startseg, endseg;
|
||||
int startAngle, endAngle;
|
||||
int i, overlap;
|
||||
miZeroArcPtRec start, end;
|
||||
|
||||
l = arc->width & 1;
|
||||
if (arc->width == arc->height)
|
||||
{
|
||||
info->alpha = 4;
|
||||
info->beta = 4;
|
||||
info->k1 = -8;
|
||||
info->k3 = -16;
|
||||
info->b = 12;
|
||||
info->a = (arc->width << 2) - 12;
|
||||
info->d = 17 - (arc->width << 1);
|
||||
if (l)
|
||||
{
|
||||
info->b -= 4;
|
||||
info->a += 4;
|
||||
info->d -= 7;
|
||||
}
|
||||
}
|
||||
else if (!arc->width || !arc->height)
|
||||
{
|
||||
info->alpha = 0;
|
||||
info->beta = 0;
|
||||
info->k1 = 0;
|
||||
info->k3 = 0;
|
||||
info->a = -(int)arc->height;
|
||||
info->b = 0;
|
||||
info->d = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* initial conditions */
|
||||
info->alpha = (arc->width * arc->width) << 2;
|
||||
info->beta = (arc->height * arc->height) << 2;
|
||||
info->k1 = info->beta << 1;
|
||||
info->k3 = info->k1 + (info->alpha << 1);
|
||||
info->b = l ? 0 : -info->beta;
|
||||
info->a = info->alpha * arc->height;
|
||||
info->d = info->b - (info->a >> 1) - (info->alpha >> 2);
|
||||
if (l)
|
||||
info->d -= info->beta >> 2;
|
||||
info->a -= info->b;
|
||||
/* take first step, d < 0 always */
|
||||
info->b -= info->k1;
|
||||
info->a += info->k1;
|
||||
info->d += info->b;
|
||||
/* octant change, b < 0 always */
|
||||
info->k1 = -info->k1;
|
||||
info->k3 = -info->k3;
|
||||
info->b = -info->b;
|
||||
info->d = info->b - info->a - info->d;
|
||||
info->a = info->a - (info->b << 1);
|
||||
}
|
||||
info->dx = 1;
|
||||
info->dy = 0;
|
||||
info->w = (arc->width + 1) >> 1;
|
||||
info->h = arc->height >> 1;
|
||||
info->xorg = arc->x + (arc->width >> 1);
|
||||
info->yorg = arc->y;
|
||||
info->xorgo = info->xorg + l;
|
||||
info->yorgo = info->yorg + arc->height;
|
||||
if (!arc->width)
|
||||
{
|
||||
if (!arc->height)
|
||||
{
|
||||
info->x = 0;
|
||||
info->y = 0;
|
||||
info->initialMask = 0;
|
||||
info->startAngle = 0;
|
||||
info->endAngle = 0;
|
||||
info->start = oob;
|
||||
info->end = oob;
|
||||
return FALSE;
|
||||
}
|
||||
info->x = 0;
|
||||
info->y = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->x = 1;
|
||||
info->y = 0;
|
||||
}
|
||||
angle1 = arc->angle1;
|
||||
angle2 = arc->angle2;
|
||||
if ((angle1 == 0) && (angle2 >= FULLCIRCLE))
|
||||
{
|
||||
startAngle = 0;
|
||||
endAngle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (angle2 > FULLCIRCLE)
|
||||
angle2 = FULLCIRCLE;
|
||||
else if (angle2 < -FULLCIRCLE)
|
||||
angle2 = -FULLCIRCLE;
|
||||
if (angle2 < 0)
|
||||
{
|
||||
startAngle = angle1 + angle2;
|
||||
endAngle = angle1;
|
||||
}
|
||||
else
|
||||
{
|
||||
startAngle = angle1;
|
||||
endAngle = angle1 + angle2;
|
||||
}
|
||||
if (startAngle < 0)
|
||||
startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
|
||||
if (startAngle >= FULLCIRCLE)
|
||||
startAngle = startAngle % FULLCIRCLE;
|
||||
if (endAngle < 0)
|
||||
endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
|
||||
if (endAngle >= FULLCIRCLE)
|
||||
endAngle = endAngle % FULLCIRCLE;
|
||||
}
|
||||
info->startAngle = startAngle;
|
||||
info->endAngle = endAngle;
|
||||
if (ok360 && (startAngle == endAngle) && arc->angle2 &&
|
||||
arc->width && arc->height)
|
||||
{
|
||||
info->initialMask = 0xf;
|
||||
info->start = oob;
|
||||
info->end = oob;
|
||||
return TRUE;
|
||||
}
|
||||
startseg = startAngle / OCTANT;
|
||||
if (!arc->height || (((startseg + 1) & 2) && arc->width))
|
||||
{
|
||||
start.x = Dcos(startAngle) * ((arc->width + 1) / 2.0);
|
||||
if (start.x < 0)
|
||||
start.x = -start.x;
|
||||
start.y = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
start.y = Dsin(startAngle) * (arc->height / 2.0);
|
||||
if (start.y < 0)
|
||||
start.y = -start.y;
|
||||
start.y = info->h - start.y;
|
||||
start.x = 65536;
|
||||
}
|
||||
endseg = endAngle / OCTANT;
|
||||
if (!arc->height || (((endseg + 1) & 2) && arc->width))
|
||||
{
|
||||
end.x = Dcos(endAngle) * ((arc->width + 1) / 2.0);
|
||||
if (end.x < 0)
|
||||
end.x = -end.x;
|
||||
end.y = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
end.y = Dsin(endAngle) * (arc->height / 2.0);
|
||||
if (end.y < 0)
|
||||
end.y = -end.y;
|
||||
end.y = info->h - end.y;
|
||||
end.x = 65536;
|
||||
}
|
||||
info->firstx = start.x;
|
||||
info->firsty = start.y;
|
||||
info->initialMask = 0;
|
||||
overlap = arc->angle2 && (endAngle <= startAngle);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (overlap ?
|
||||
((i * QUADRANT <= endAngle) || ((i + 1) * QUADRANT > startAngle)) :
|
||||
((i * QUADRANT <= endAngle) && ((i + 1) * QUADRANT > startAngle)))
|
||||
info->initialMask |= (1 << i);
|
||||
}
|
||||
start.mask = info->initialMask;
|
||||
end.mask = info->initialMask;
|
||||
startseg >>= 1;
|
||||
endseg >>= 1;
|
||||
overlap = overlap && (endseg == startseg);
|
||||
if (start.x != end.x || start.y != end.y || !overlap)
|
||||
{
|
||||
if (startseg & 1)
|
||||
{
|
||||
if (!overlap)
|
||||
info->initialMask &= ~(1 << startseg);
|
||||
if (start.x > end.x || start.y > end.y)
|
||||
end.mask &= ~(1 << startseg);
|
||||
}
|
||||
else
|
||||
{
|
||||
start.mask &= ~(1 << startseg);
|
||||
if (((start.x < end.x || start.y < end.y) ||
|
||||
(start.x == end.x && start.y == end.y && (endseg & 1))) &&
|
||||
!overlap)
|
||||
end.mask &= ~(1 << startseg);
|
||||
}
|
||||
if (endseg & 1)
|
||||
{
|
||||
end.mask &= ~(1 << endseg);
|
||||
if (((start.x > end.x || start.y > end.y) ||
|
||||
(start.x == end.x && start.y == end.y && !(startseg & 1))) &&
|
||||
!overlap)
|
||||
start.mask &= ~(1 << endseg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!overlap)
|
||||
info->initialMask &= ~(1 << endseg);
|
||||
if (start.x < end.x || start.y < end.y)
|
||||
start.mask &= ~(1 << endseg);
|
||||
}
|
||||
}
|
||||
/* take care of case when start and stop are both near 45 */
|
||||
/* handle here rather than adding extra code to pixelization loops */
|
||||
if (startAngle &&
|
||||
((start.y < 0 && end.y >= 0) || (start.y >= 0 && end.y < 0)))
|
||||
{
|
||||
i = (startAngle + OCTANT) % OCTANT;
|
||||
if (i < EPSILON45 || i > OCTANT - EPSILON45)
|
||||
{
|
||||
i = (endAngle + OCTANT) % OCTANT;
|
||||
if (i < EPSILON45 || i > OCTANT - EPSILON45)
|
||||
{
|
||||
if (start.y < 0)
|
||||
{
|
||||
i = Dsin(startAngle) * (arc->height / 2.0);
|
||||
if (i < 0)
|
||||
i = -i;
|
||||
if (info->h - i == end.y)
|
||||
start.mask = end.mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = Dsin(endAngle) * (arc->height / 2.0);
|
||||
if (i < 0)
|
||||
i = -i;
|
||||
if (info->h - i == start.y)
|
||||
end.mask = start.mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (startseg & 1)
|
||||
{
|
||||
info->start = start;
|
||||
info->end = oob;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->end = start;
|
||||
info->start = oob;
|
||||
}
|
||||
if (endseg & 1)
|
||||
{
|
||||
info->altend = end;
|
||||
if (info->altend.x < info->end.x || info->altend.y < info->end.y)
|
||||
{
|
||||
miZeroArcPtRec tmp;
|
||||
tmp = info->altend;
|
||||
info->altend = info->end;
|
||||
info->end = tmp;
|
||||
}
|
||||
info->altstart = oob;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->altstart = end;
|
||||
if (info->altstart.x < info->start.x ||
|
||||
info->altstart.y < info->start.y)
|
||||
{
|
||||
miZeroArcPtRec tmp;
|
||||
tmp = info->altstart;
|
||||
info->altstart = info->start;
|
||||
info->start = tmp;
|
||||
}
|
||||
info->altend = oob;
|
||||
}
|
||||
if (!info->start.x || !info->start.y)
|
||||
{
|
||||
info->initialMask = info->start.mask;
|
||||
info->start = info->altstart;
|
||||
}
|
||||
if (!arc->width && (arc->height == 1))
|
||||
{
|
||||
/* kludge! */
|
||||
info->initialMask |= info->end.mask;
|
||||
info->initialMask |= info->initialMask << 1;
|
||||
info->end.x = 0;
|
||||
info->end.mask = 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define Pixelate(xval,yval) \
|
||||
{ \
|
||||
pts->x = xval; \
|
||||
pts->y = yval; \
|
||||
pts++; \
|
||||
}
|
||||
|
||||
#define DoPix(idx,xval,yval) if (mask & (1 << idx)) Pixelate(xval, yval);
|
||||
|
||||
DDXPointPtr
|
||||
miZeroArcPts(arc, pts)
|
||||
xArc *arc;
|
||||
register DDXPointPtr pts;
|
||||
{
|
||||
miZeroArcRec info;
|
||||
register int x, y, a, b, d, mask;
|
||||
register int k1, k3, dx, dy;
|
||||
Bool do360;
|
||||
|
||||
do360 = miZeroArcSetup(arc, &info, TRUE);
|
||||
MIARCSETUP();
|
||||
mask = info.initialMask;
|
||||
if (!(arc->width & 1))
|
||||
{
|
||||
DoPix(1, info.xorgo, info.yorg);
|
||||
DoPix(3, info.xorgo, info.yorgo);
|
||||
}
|
||||
if (!info.end.x || !info.end.y)
|
||||
{
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
if (do360 && (arc->width == arc->height) && !(arc->width & 1))
|
||||
{
|
||||
int yorgh = info.yorg + info.h;
|
||||
int xorghp = info.xorg + info.h;
|
||||
int xorghn = info.xorg - info.h;
|
||||
|
||||
while (1)
|
||||
{
|
||||
Pixelate(info.xorg + x, info.yorg + y);
|
||||
Pixelate(info.xorg - x, info.yorg + y);
|
||||
Pixelate(info.xorg - x, info.yorgo - y);
|
||||
Pixelate(info.xorg + x, info.yorgo - y);
|
||||
if (a < 0)
|
||||
break;
|
||||
Pixelate(xorghp - y, yorgh - x);
|
||||
Pixelate(xorghn + y, yorgh - x);
|
||||
Pixelate(xorghn + y, yorgh + x);
|
||||
Pixelate(xorghp - y, yorgh + x);
|
||||
MIARCCIRCLESTEP(;);
|
||||
}
|
||||
if (x > 1 && pts[-1].x == pts[-5].x && pts[-1].y == pts[-5].y)
|
||||
pts -= 4;
|
||||
x = info.w;
|
||||
y = info.h;
|
||||
}
|
||||
else if (do360)
|
||||
{
|
||||
while (y < info.h || x < info.w)
|
||||
{
|
||||
MIARCOCTANTSHIFT(;);
|
||||
Pixelate(info.xorg + x, info.yorg + y);
|
||||
Pixelate(info.xorgo - x, info.yorg + y);
|
||||
Pixelate(info.xorgo - x, info.yorgo - y);
|
||||
Pixelate(info.xorg + x, info.yorgo - y);
|
||||
MIARCSTEP(;,;);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (y < info.h || x < info.w)
|
||||
{
|
||||
MIARCOCTANTSHIFT(;);
|
||||
if ((x == info.start.x) || (y == info.start.y))
|
||||
{
|
||||
mask = info.start.mask;
|
||||
info.start = info.altstart;
|
||||
}
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
if ((x == info.end.x) || (y == info.end.y))
|
||||
{
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
MIARCSTEP(;,;);
|
||||
}
|
||||
}
|
||||
if ((x == info.start.x) || (y == info.start.y))
|
||||
mask = info.start.mask;
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
if (arc->height & 1)
|
||||
{
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
}
|
||||
return pts;
|
||||
}
|
||||
|
||||
#undef DoPix
|
||||
#define DoPix(idx,xval,yval) \
|
||||
if (mask & (1 << idx)) \
|
||||
{ \
|
||||
arcPts[idx]->x = xval; \
|
||||
arcPts[idx]->y = yval; \
|
||||
arcPts[idx]++; \
|
||||
}
|
||||
|
||||
static void
|
||||
miZeroArcDashPts(
|
||||
GCPtr pGC,
|
||||
xArc *arc,
|
||||
DashInfo *dinfo,
|
||||
register DDXPointPtr points,
|
||||
int maxPts,
|
||||
register DDXPointPtr *evenPts,
|
||||
register DDXPointPtr *oddPts )
|
||||
{
|
||||
miZeroArcRec info;
|
||||
register int x, y, a, b, d, mask;
|
||||
register int k1, k3, dx, dy;
|
||||
int dashRemaining;
|
||||
DDXPointPtr arcPts[4];
|
||||
DDXPointPtr startPts[5], endPts[5];
|
||||
int deltas[5];
|
||||
DDXPointPtr startPt, pt, lastPt, pts;
|
||||
int i, j, delta, ptsdelta, seg, startseg;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
arcPts[i] = points + (i * maxPts);
|
||||
(void)miZeroArcSetup(arc, &info, FALSE);
|
||||
MIARCSETUP();
|
||||
mask = info.initialMask;
|
||||
startseg = info.startAngle / QUADRANT;
|
||||
startPt = arcPts[startseg];
|
||||
if (!(arc->width & 1))
|
||||
{
|
||||
DoPix(1, info.xorgo, info.yorg);
|
||||
DoPix(3, info.xorgo, info.yorgo);
|
||||
}
|
||||
if (!info.end.x || !info.end.y)
|
||||
{
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
while (y < info.h || x < info.w)
|
||||
{
|
||||
MIARCOCTANTSHIFT(;);
|
||||
if ((x == info.firstx) || (y == info.firsty))
|
||||
startPt = arcPts[startseg];
|
||||
if ((x == info.start.x) || (y == info.start.y))
|
||||
{
|
||||
mask = info.start.mask;
|
||||
info.start = info.altstart;
|
||||
}
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
if ((x == info.end.x) || (y == info.end.y))
|
||||
{
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
MIARCSTEP(;,;);
|
||||
}
|
||||
if ((x == info.firstx) || (y == info.firsty))
|
||||
startPt = arcPts[startseg];
|
||||
if ((x == info.start.x) || (y == info.start.y))
|
||||
mask = info.start.mask;
|
||||
DoPix(0, info.xorg + x, info.yorg + y);
|
||||
DoPix(2, info.xorgo - x, info.yorgo - y);
|
||||
if (arc->height & 1)
|
||||
{
|
||||
DoPix(1, info.xorgo - x, info.yorg + y);
|
||||
DoPix(3, info.xorg + x, info.yorgo - y);
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
seg = (startseg + i) & 3;
|
||||
pt = points + (seg * maxPts);
|
||||
if (seg & 1)
|
||||
{
|
||||
startPts[i] = pt;
|
||||
endPts[i] = arcPts[seg];
|
||||
deltas[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
startPts[i] = arcPts[seg] - 1;
|
||||
endPts[i] = pt - 1;
|
||||
deltas[i] = -1;
|
||||
}
|
||||
}
|
||||
startPts[4] = startPts[0];
|
||||
endPts[4] = startPt;
|
||||
startPts[0] = startPt;
|
||||
if (startseg & 1)
|
||||
{
|
||||
if (startPts[4] != endPts[4])
|
||||
endPts[4]--;
|
||||
deltas[4] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startPts[0] > startPts[4])
|
||||
startPts[0]--;
|
||||
if (startPts[4] < endPts[4])
|
||||
endPts[4]--;
|
||||
deltas[4] = -1;
|
||||
}
|
||||
if (arc->angle2 < 0)
|
||||
{
|
||||
DDXPointPtr tmps, tmpe;
|
||||
int tmpd;
|
||||
|
||||
tmpd = deltas[0];
|
||||
tmps = startPts[0] - tmpd;
|
||||
tmpe = endPts[0] - tmpd;
|
||||
startPts[0] = endPts[4] - deltas[4];
|
||||
endPts[0] = startPts[4] - deltas[4];
|
||||
deltas[0] = -deltas[4];
|
||||
startPts[4] = tmpe;
|
||||
endPts[4] = tmps;
|
||||
deltas[4] = -tmpd;
|
||||
tmpd = deltas[1];
|
||||
tmps = startPts[1] - tmpd;
|
||||
tmpe = endPts[1] - tmpd;
|
||||
startPts[1] = endPts[3] - deltas[3];
|
||||
endPts[1] = startPts[3] - deltas[3];
|
||||
deltas[1] = -deltas[3];
|
||||
startPts[3] = tmpe;
|
||||
endPts[3] = tmps;
|
||||
deltas[3] = -tmpd;
|
||||
tmps = startPts[2] - deltas[2];
|
||||
startPts[2] = endPts[2] - deltas[2];
|
||||
endPts[2] = tmps;
|
||||
deltas[2] = -deltas[2];
|
||||
}
|
||||
for (i = 0; i < 5 && startPts[i] == endPts[i]; i++)
|
||||
;
|
||||
if (i == 5)
|
||||
return;
|
||||
pt = startPts[i];
|
||||
for (j = 4; startPts[j] == endPts[j]; j--)
|
||||
;
|
||||
lastPt = endPts[j] - deltas[j];
|
||||
if (dinfo->haveLast &&
|
||||
(pt->x == dinfo->endPt.x) && (pt->y == dinfo->endPt.y))
|
||||
{
|
||||
startPts[i] += deltas[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
dinfo->dashIndex = dinfo->dashIndexInit;
|
||||
dinfo->dashOffset = dinfo->dashOffsetInit;
|
||||
}
|
||||
if (!dinfo->skipStart && (info.startAngle != info.endAngle))
|
||||
{
|
||||
dinfo->startPt = *pt;
|
||||
dinfo->haveStart = TRUE;
|
||||
}
|
||||
else if (!dinfo->skipLast && dinfo->haveStart &&
|
||||
(lastPt->x == dinfo->startPt.x) &&
|
||||
(lastPt->y == dinfo->startPt.y) &&
|
||||
(lastPt != startPts[i]))
|
||||
endPts[j] = lastPt;
|
||||
if (info.startAngle != info.endAngle)
|
||||
{
|
||||
dinfo->haveLast = TRUE;
|
||||
dinfo->endPt = *lastPt;
|
||||
}
|
||||
dashRemaining = pGC->dash[dinfo->dashIndex] - dinfo->dashOffset;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
pt = startPts[i];
|
||||
lastPt = endPts[i];
|
||||
delta = deltas[i];
|
||||
while (pt != lastPt)
|
||||
{
|
||||
if (dinfo->dashIndex & 1)
|
||||
{
|
||||
pts = *oddPts;
|
||||
ptsdelta = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pts = *evenPts;
|
||||
ptsdelta = 1;
|
||||
}
|
||||
while ((pt != lastPt) && --dashRemaining >= 0)
|
||||
{
|
||||
*pts = *pt;
|
||||
pts += ptsdelta;
|
||||
pt += delta;
|
||||
}
|
||||
if (dinfo->dashIndex & 1)
|
||||
*oddPts = pts;
|
||||
else
|
||||
*evenPts = pts;
|
||||
if (dashRemaining <= 0)
|
||||
{
|
||||
if (++(dinfo->dashIndex) == pGC->numInDashList)
|
||||
dinfo->dashIndex = 0;
|
||||
dashRemaining = pGC->dash[dinfo->dashIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
dinfo->dashOffset = pGC->dash[dinfo->dashIndex] - dashRemaining;
|
||||
}
|
||||
|
||||
void
|
||||
miZeroPolyArc(pDraw, pGC, narcs, parcs)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int narcs;
|
||||
xArc *parcs;
|
||||
{
|
||||
int maxPts = 0;
|
||||
register int n, maxw = 0;
|
||||
register xArc *arc;
|
||||
register int i;
|
||||
DDXPointPtr points, pts, oddPts = NULL;
|
||||
register DDXPointPtr pt;
|
||||
int numPts;
|
||||
Bool dospans;
|
||||
int *widths = NULL;
|
||||
XID fgPixel = pGC->fgPixel;
|
||||
DashInfo dinfo;
|
||||
|
||||
for (arc = parcs, i = narcs; --i >= 0; arc++)
|
||||
{
|
||||
if (!miCanZeroArc(arc))
|
||||
miPolyArc(pDraw, pGC, 1, arc);
|
||||
else
|
||||
{
|
||||
if (arc->width > arc->height)
|
||||
n = arc->width + (arc->height >> 1);
|
||||
else
|
||||
n = arc->height + (arc->width >> 1);
|
||||
if (n > maxPts)
|
||||
maxPts = n;
|
||||
}
|
||||
}
|
||||
if (!maxPts)
|
||||
return;
|
||||
numPts = maxPts << 2;
|
||||
dospans = (pGC->fillStyle != FillSolid);
|
||||
if (dospans)
|
||||
{
|
||||
widths = (int *)malloc(sizeof(int) * numPts);
|
||||
if (!widths)
|
||||
return;
|
||||
maxw = 0;
|
||||
}
|
||||
if (pGC->lineStyle != LineSolid)
|
||||
{
|
||||
numPts <<= 1;
|
||||
dinfo.haveStart = FALSE;
|
||||
dinfo.skipStart = FALSE;
|
||||
dinfo.haveLast = FALSE;
|
||||
dinfo.dashIndexInit = 0;
|
||||
dinfo.dashOffsetInit = 0;
|
||||
miStepDash((int)pGC->dashOffset, &dinfo.dashIndexInit,
|
||||
(unsigned char *) pGC->dash, (int)pGC->numInDashList,
|
||||
&dinfo.dashOffsetInit);
|
||||
}
|
||||
points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * numPts);
|
||||
if (!points)
|
||||
{
|
||||
if (dospans)
|
||||
{
|
||||
free(widths);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (arc = parcs, i = narcs; --i >= 0; arc++)
|
||||
{
|
||||
if (miCanZeroArc(arc))
|
||||
{
|
||||
if (pGC->lineStyle == LineSolid)
|
||||
pts = miZeroArcPts(arc, points);
|
||||
else
|
||||
{
|
||||
pts = points;
|
||||
oddPts = &points[(numPts >> 1) - 1];
|
||||
dinfo.skipLast = i;
|
||||
miZeroArcDashPts(pGC, arc, &dinfo,
|
||||
oddPts + 1, maxPts, &pts, &oddPts);
|
||||
dinfo.skipStart = TRUE;
|
||||
}
|
||||
n = pts - points;
|
||||
if (!dospans)
|
||||
(*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, points);
|
||||
else
|
||||
{
|
||||
if (n > maxw)
|
||||
{
|
||||
while (maxw < n)
|
||||
widths[maxw++] = 1;
|
||||
}
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
for (pt = points; pt != pts; pt++)
|
||||
{
|
||||
pt->x += pDraw->x;
|
||||
pt->y += pDraw->y;
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, n, points, widths, FALSE);
|
||||
}
|
||||
if (pGC->lineStyle != LineDoubleDash)
|
||||
continue;
|
||||
if ((pGC->fillStyle == FillSolid) ||
|
||||
(pGC->fillStyle == FillStippled))
|
||||
{
|
||||
DoChangeGC(pGC, GCForeground, (XID *)&pGC->bgPixel, 0);
|
||||
ValidateGC(pDraw, pGC);
|
||||
}
|
||||
pts = &points[numPts >> 1];
|
||||
oddPts++;
|
||||
n = pts - oddPts;
|
||||
if (!dospans)
|
||||
(*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, oddPts);
|
||||
else
|
||||
{
|
||||
if (n > maxw)
|
||||
{
|
||||
while (maxw < n)
|
||||
widths[maxw++] = 1;
|
||||
}
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
for (pt = oddPts; pt != pts; pt++)
|
||||
{
|
||||
pt->x += pDraw->x;
|
||||
pt->y += pDraw->y;
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, n, oddPts, widths, FALSE);
|
||||
}
|
||||
if ((pGC->fillStyle == FillSolid) ||
|
||||
(pGC->fillStyle == FillStippled))
|
||||
{
|
||||
DoChangeGC(pGC, GCForeground, &fgPixel, 0);
|
||||
ValidateGC(pDraw, pGC);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(points);
|
||||
if (dospans)
|
||||
{
|
||||
free(widths);
|
||||
}
|
||||
}
|
||||
132
nx-X11/programs/Xserver/mi/mizerarc.h
Normal file
132
nx-X11/programs/Xserver/mi/mizerarc.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/************************************************************
|
||||
|
||||
Copyright 1989, 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.
|
||||
|
||||
********************************************************/
|
||||
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
int mask;
|
||||
} miZeroArcPtRec;
|
||||
|
||||
typedef struct {
|
||||
int x, y, k1, k3, a, b, d, dx, dy;
|
||||
int alpha, beta;
|
||||
int xorg, yorg;
|
||||
int xorgo, yorgo;
|
||||
int w, h;
|
||||
int initialMask;
|
||||
miZeroArcPtRec start, altstart, end, altend;
|
||||
int firstx, firsty;
|
||||
int startAngle, endAngle;
|
||||
} miZeroArcRec;
|
||||
|
||||
#define miCanZeroArc(arc) (((arc)->width == (arc)->height) || \
|
||||
(((arc)->width <= 800) && ((arc)->height <= 800)))
|
||||
|
||||
#define MIARCSETUP() \
|
||||
x = info.x; \
|
||||
y = info.y; \
|
||||
k1 = info.k1; \
|
||||
k3 = info.k3; \
|
||||
a = info.a; \
|
||||
b = info.b; \
|
||||
d = info.d; \
|
||||
dx = info.dx; \
|
||||
dy = info.dy
|
||||
|
||||
#define MIARCOCTANTSHIFT(clause) \
|
||||
if (a < 0) \
|
||||
{ \
|
||||
if (y == info.h) \
|
||||
{ \
|
||||
d = -1; \
|
||||
a = b = k1 = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dx = (k1 << 1) - k3; \
|
||||
k1 = dx - k1; \
|
||||
k3 = -k3; \
|
||||
b = b + a - (k1 >> 1); \
|
||||
d = b + ((-a) >> 1) - d + (k3 >> 3); \
|
||||
if (dx < 0) \
|
||||
a = -((-dx) >> 1) - a; \
|
||||
else \
|
||||
a = (dx >> 1) - a; \
|
||||
dx = 0; \
|
||||
dy = 1; \
|
||||
clause \
|
||||
} \
|
||||
}
|
||||
|
||||
#define MIARCSTEP(move1,move2) \
|
||||
b -= k1; \
|
||||
if (d < 0) \
|
||||
{ \
|
||||
x += dx; \
|
||||
y += dy; \
|
||||
a += k1; \
|
||||
d += b; \
|
||||
move1 \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
x++; \
|
||||
y++; \
|
||||
a += k3; \
|
||||
d -= a; \
|
||||
move2 \
|
||||
}
|
||||
|
||||
#define MIARCCIRCLESTEP(clause) \
|
||||
b -= k1; \
|
||||
x++; \
|
||||
if (d < 0) \
|
||||
{ \
|
||||
a += k1; \
|
||||
d += b; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
y++; \
|
||||
a += k3; \
|
||||
d -= a; \
|
||||
clause \
|
||||
}
|
||||
|
||||
/* mizerarc.c */
|
||||
|
||||
extern Bool miZeroArcSetup(
|
||||
xArc * /*arc*/,
|
||||
miZeroArcRec * /*info*/,
|
||||
Bool /*ok360*/
|
||||
);
|
||||
|
||||
extern DDXPointPtr miZeroArcPts(
|
||||
xArc * /*arc*/,
|
||||
DDXPointPtr /*pts*/
|
||||
);
|
||||
|
||||
635
nx-X11/programs/Xserver/mi/mizerclip.c
Normal file
635
nx-X11/programs/Xserver/mi/mizerclip.c
Normal file
@@ -0,0 +1,635 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "windowstr.h"
|
||||
#include "pixmap.h"
|
||||
#include "mi.h"
|
||||
#include "miline.h"
|
||||
|
||||
/*
|
||||
|
||||
The bresenham error equation used in the mi/mfb/cfb line routines is:
|
||||
|
||||
e = error
|
||||
dx = difference in raw X coordinates
|
||||
dy = difference in raw Y coordinates
|
||||
M = # of steps in X direction
|
||||
N = # of steps in Y direction
|
||||
B = 0 to prefer diagonal steps in a given octant,
|
||||
1 to prefer axial steps in a given octant
|
||||
|
||||
For X major lines:
|
||||
e = 2Mdy - 2Ndx - dx - B
|
||||
-2dx <= e < 0
|
||||
|
||||
For Y major lines:
|
||||
e = 2Ndx - 2Mdy - dy - B
|
||||
-2dy <= e < 0
|
||||
|
||||
At the start of the line, we have taken 0 X steps and 0 Y steps,
|
||||
so M = 0 and N = 0:
|
||||
|
||||
X major e = 2Mdy - 2Ndx - dx - B
|
||||
= -dx - B
|
||||
|
||||
Y major e = 2Ndx - 2Mdy - dy - B
|
||||
= -dy - B
|
||||
|
||||
At the end of the line, we have taken dx X steps and dy Y steps,
|
||||
so M = dx and N = dy:
|
||||
|
||||
X major e = 2Mdy - 2Ndx - dx - B
|
||||
= 2dxdy - 2dydx - dx - B
|
||||
= -dx - B
|
||||
Y major e = 2Ndx - 2Mdy - dy - B
|
||||
= 2dydx - 2dxdy - dy - B
|
||||
= -dy - B
|
||||
|
||||
Thus, the error term is the same at the start and end of the line.
|
||||
|
||||
Let us consider clipping an X coordinate. There are 4 cases which
|
||||
represent the two independent cases of clipping the start vs. the
|
||||
end of the line and an X major vs. a Y major line. In any of these
|
||||
cases, we know the number of X steps (M) and we wish to find the
|
||||
number of Y steps (N). Thus, we will solve our error term equation.
|
||||
If we are clipping the start of the line, we will find the smallest
|
||||
N that satisfies our error term inequality. If we are clipping the
|
||||
end of the line, we will find the largest number of Y steps that
|
||||
satisfies the inequality. In that case, since we are representing
|
||||
the Y steps as (dy - N), we will actually want to solve for the
|
||||
smallest N in that equation.
|
||||
|
||||
Case 1: X major, starting X coordinate moved by M steps
|
||||
|
||||
-2dx <= 2Mdy - 2Ndx - dx - B < 0
|
||||
2Ndx <= 2Mdy - dx - B + 2dx 2Ndx > 2Mdy - dx - B
|
||||
2Ndx <= 2Mdy + dx - B N > (2Mdy - dx - B) / 2dx
|
||||
N <= (2Mdy + dx - B) / 2dx
|
||||
|
||||
Since we are trying to find the smallest N that satisfies these
|
||||
equations, we should use the > inequality to find the smallest:
|
||||
|
||||
N = floor((2Mdy - dx - B) / 2dx) + 1
|
||||
= floor((2Mdy - dx - B + 2dx) / 2dx)
|
||||
= floor((2Mdy + dx - B) / 2dx)
|
||||
|
||||
Case 1b: X major, ending X coordinate moved to M steps
|
||||
|
||||
Same derivations as Case 1, but we want the largest N that satisfies
|
||||
the equations, so we use the <= inequality:
|
||||
|
||||
N = floor((2Mdy + dx - B) / 2dx)
|
||||
|
||||
Case 2: X major, ending X coordinate moved by M steps
|
||||
|
||||
-2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
|
||||
-2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
|
||||
-2dx <= 2Ndx - 2Mdy - dx - B < 0
|
||||
2Ndx >= 2Mdy + dx + B - 2dx 2Ndx < 2Mdy + dx + B
|
||||
2Ndx >= 2Mdy - dx + B N < (2Mdy + dx + B) / 2dx
|
||||
N >= (2Mdy - dx + B) / 2dx
|
||||
|
||||
Since we are trying to find the highest number of Y steps that
|
||||
satisfies these equations, we need to find the smallest N, so
|
||||
we should use the >= inequality to find the smallest:
|
||||
|
||||
N = ceiling((2Mdy - dx + B) / 2dx)
|
||||
= floor((2Mdy - dx + B + 2dx - 1) / 2dx)
|
||||
= floor((2Mdy + dx + B - 1) / 2dx)
|
||||
|
||||
Case 2b: X major, starting X coordinate moved to M steps from end
|
||||
|
||||
Same derivations as Case 2, but we want the smallest number of Y
|
||||
steps, so we want the highest N, so we use the < inequality:
|
||||
|
||||
N = ceiling((2Mdy + dx + B) / 2dx) - 1
|
||||
= floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
|
||||
= floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
|
||||
= floor((2Mdy + dx + B - 1) / 2dx)
|
||||
|
||||
Case 3: Y major, starting X coordinate moved by M steps
|
||||
|
||||
-2dy <= 2Ndx - 2Mdy - dy - B < 0
|
||||
2Ndx >= 2Mdy + dy + B - 2dy 2Ndx < 2Mdy + dy + B
|
||||
2Ndx >= 2Mdy - dy + B N < (2Mdy + dy + B) / 2dx
|
||||
N >= (2Mdy - dy + B) / 2dx
|
||||
|
||||
Since we are trying to find the smallest N that satisfies these
|
||||
equations, we should use the >= inequality to find the smallest:
|
||||
|
||||
N = ceiling((2Mdy - dy + B) / 2dx)
|
||||
= floor((2Mdy - dy + B + 2dx - 1) / 2dx)
|
||||
= floor((2Mdy - dy + B - 1) / 2dx) + 1
|
||||
|
||||
Case 3b: Y major, ending X coordinate moved to M steps
|
||||
|
||||
Same derivations as Case 3, but we want the largest N that satisfies
|
||||
the equations, so we use the < inequality:
|
||||
|
||||
N = ceiling((2Mdy + dy + B) / 2dx) - 1
|
||||
= floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
|
||||
= floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
|
||||
= floor((2Mdy + dy + B - 1) / 2dx)
|
||||
|
||||
Case 4: Y major, ending X coordinate moved by M steps
|
||||
|
||||
-2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
|
||||
-2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
|
||||
-2dy <= 2Mdy - 2Ndx - dy - B < 0
|
||||
2Ndx <= 2Mdy - dy - B + 2dy 2Ndx > 2Mdy - dy - B
|
||||
2Ndx <= 2Mdy + dy - B N > (2Mdy - dy - B) / 2dx
|
||||
N <= (2Mdy + dy - B) / 2dx
|
||||
|
||||
Since we are trying to find the highest number of Y steps that
|
||||
satisfies these equations, we need to find the smallest N, so
|
||||
we should use the > inequality to find the smallest:
|
||||
|
||||
N = floor((2Mdy - dy - B) / 2dx) + 1
|
||||
|
||||
Case 4b: Y major, starting X coordinate moved to M steps from end
|
||||
|
||||
Same analysis as Case 4, but we want the smallest number of Y steps
|
||||
which means the largest N, so we use the <= inequality:
|
||||
|
||||
N = floor((2Mdy + dy - B) / 2dx)
|
||||
|
||||
Now let's try the Y coordinates, we have the same 4 cases.
|
||||
|
||||
Case 5: X major, starting Y coordinate moved by N steps
|
||||
|
||||
-2dx <= 2Mdy - 2Ndx - dx - B < 0
|
||||
2Mdy >= 2Ndx + dx + B - 2dx 2Mdy < 2Ndx + dx + B
|
||||
2Mdy >= 2Ndx - dx + B M < (2Ndx + dx + B) / 2dy
|
||||
M >= (2Ndx - dx + B) / 2dy
|
||||
|
||||
Since we are trying to find the smallest M, we use the >= inequality:
|
||||
|
||||
M = ceiling((2Ndx - dx + B) / 2dy)
|
||||
= floor((2Ndx - dx + B + 2dy - 1) / 2dy)
|
||||
= floor((2Ndx - dx + B - 1) / 2dy) + 1
|
||||
|
||||
Case 5b: X major, ending Y coordinate moved to N steps
|
||||
|
||||
Same derivations as Case 5, but we want the largest M that satisfies
|
||||
the equations, so we use the < inequality:
|
||||
|
||||
M = ceiling((2Ndx + dx + B) / 2dy) - 1
|
||||
= floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
|
||||
= floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
|
||||
= floor((2Ndx + dx + B - 1) / 2dy)
|
||||
|
||||
Case 6: X major, ending Y coordinate moved by N steps
|
||||
|
||||
-2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
|
||||
-2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
|
||||
-2dx <= 2Ndx - 2Mdy - dx - B < 0
|
||||
2Mdy <= 2Ndx - dx - B + 2dx 2Mdy > 2Ndx - dx - B
|
||||
2Mdy <= 2Ndx + dx - B M > (2Ndx - dx - B) / 2dy
|
||||
M <= (2Ndx + dx - B) / 2dy
|
||||
|
||||
Largest # of X steps means smallest M, so use the > inequality:
|
||||
|
||||
M = floor((2Ndx - dx - B) / 2dy) + 1
|
||||
|
||||
Case 6b: X major, starting Y coordinate moved to N steps from end
|
||||
|
||||
Same derivations as Case 6, but we want the smallest # of X steps
|
||||
which means the largest M, so use the <= inequality:
|
||||
|
||||
M = floor((2Ndx + dx - B) / 2dy)
|
||||
|
||||
Case 7: Y major, starting Y coordinate moved by N steps
|
||||
|
||||
-2dy <= 2Ndx - 2Mdy - dy - B < 0
|
||||
2Mdy <= 2Ndx - dy - B + 2dy 2Mdy > 2Ndx - dy - B
|
||||
2Mdy <= 2Ndx + dy - B M > (2Ndx - dy - B) / 2dy
|
||||
M <= (2Ndx + dy - B) / 2dy
|
||||
|
||||
To find the smallest M, use the > inequality:
|
||||
|
||||
M = floor((2Ndx - dy - B) / 2dy) + 1
|
||||
= floor((2Ndx - dy - B + 2dy) / 2dy)
|
||||
= floor((2Ndx + dy - B) / 2dy)
|
||||
|
||||
Case 7b: Y major, ending Y coordinate moved to N steps
|
||||
|
||||
Same derivations as Case 7, but we want the largest M that satisfies
|
||||
the equations, so use the <= inequality:
|
||||
|
||||
M = floor((2Ndx + dy - B) / 2dy)
|
||||
|
||||
Case 8: Y major, ending Y coordinate moved by N steps
|
||||
|
||||
-2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
|
||||
-2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
|
||||
-2dy <= 2Mdy - 2Ndx - dy - B < 0
|
||||
2Mdy >= 2Ndx + dy + B - 2dy 2Mdy < 2Ndx + dy + B
|
||||
2Mdy >= 2Ndx - dy + B M < (2Ndx + dy + B) / 2dy
|
||||
M >= (2Ndx - dy + B) / 2dy
|
||||
|
||||
To find the highest X steps, find the smallest M, use the >= inequality:
|
||||
|
||||
M = ceiling((2Ndx - dy + B) / 2dy)
|
||||
= floor((2Ndx - dy + B + 2dy - 1) / 2dy)
|
||||
= floor((2Ndx + dy + B - 1) / 2dy)
|
||||
|
||||
Case 8b: Y major, starting Y coordinate moved to N steps from the end
|
||||
|
||||
Same derivations as Case 8, but we want to find the smallest # of X
|
||||
steps which means the largest M, so we use the < inequality:
|
||||
|
||||
M = ceiling((2Ndx + dy + B) / 2dy) - 1
|
||||
= floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
|
||||
= floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
|
||||
= floor((2Ndx + dy + B - 1) / 2dy)
|
||||
|
||||
So, our equations are:
|
||||
|
||||
1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx)
|
||||
1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx)
|
||||
2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
|
||||
2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
|
||||
|
||||
3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1
|
||||
3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx)
|
||||
4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1
|
||||
4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx)
|
||||
|
||||
5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1
|
||||
5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy)
|
||||
6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1
|
||||
6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy)
|
||||
|
||||
7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy)
|
||||
7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy)
|
||||
8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
|
||||
8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
|
||||
|
||||
We have the following constraints on all of the above terms:
|
||||
|
||||
0 < M,N <= 2^15 2^15 can be imposed by miZeroClipLine
|
||||
0 <= dx/dy <= 2^16 - 1
|
||||
0 <= B <= 1
|
||||
|
||||
The floor in all of the above equations can be accomplished with a
|
||||
simple C divide operation provided that both numerator and denominator
|
||||
are positive.
|
||||
|
||||
Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0
|
||||
and moving a Y coordinate implies dy != 0, we know that the denominators
|
||||
are all > 0.
|
||||
|
||||
For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
|
||||
bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1
|
||||
or > 0 to prove that the numerators are positive (or zero).
|
||||
|
||||
For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the
|
||||
constraints, the first four equations all have numerators >= 0.
|
||||
|
||||
For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy
|
||||
So (2Mdy - dy) > 0, since they are Y major lines. Also, (2Mdy + dy) >= 3dy
|
||||
or (2Mdy + dy) > 0. So all of their numerators are >= 0.
|
||||
|
||||
For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx)
|
||||
>= dx > 0. Similarly (2Ndx + dx) >= 3dx > 0. So all numerators >= 0.
|
||||
|
||||
For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators
|
||||
are > 0.
|
||||
|
||||
To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This
|
||||
is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
|
||||
<= 2^16 * (2^16 - 1) + (2^16 - 1)
|
||||
<= 2^32 - 2^16 + 2^16 - 1
|
||||
<= 2^32 - 1
|
||||
Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
|
||||
the numerator is therefore (2^32 - 1), which does not overflow an unsigned
|
||||
32 bit variable.
|
||||
|
||||
*/
|
||||
|
||||
/* Bit codes for the terms of the 16 clipping equations defined below. */
|
||||
|
||||
#define T_2NDX (1 << 0)
|
||||
#define T_2MDY (0) /* implicit term */
|
||||
#define T_DXNOTY (1 << 1)
|
||||
#define T_DYNOTX (0) /* implicit term */
|
||||
#define T_SUBDXORY (1 << 2)
|
||||
#define T_ADDDX (T_DXNOTY) /* composite term */
|
||||
#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */
|
||||
#define T_ADDDY (T_DYNOTX) /* composite term */
|
||||
#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */
|
||||
#define T_BIASSUBONE (1 << 3)
|
||||
#define T_SUBBIAS (0) /* implicit term */
|
||||
#define T_DIV2DX (1 << 4)
|
||||
#define T_DIV2DY (0) /* implicit term */
|
||||
#define T_ADDONE (1 << 5)
|
||||
|
||||
/* Bit masks defining the 16 equations used in miZeroClipLine. */
|
||||
|
||||
#define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
|
||||
#define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
|
||||
#define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
|
||||
#define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
|
||||
|
||||
#define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
|
||||
#define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
|
||||
#define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE)
|
||||
#define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX)
|
||||
|
||||
#define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
|
||||
#define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
|
||||
#define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE)
|
||||
#define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY)
|
||||
|
||||
#define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
|
||||
#define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
|
||||
#define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
|
||||
#define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
|
||||
|
||||
/* miZeroClipLine
|
||||
*
|
||||
* returns: 1 for partially clipped line
|
||||
* -1 for completely clipped line
|
||||
*
|
||||
*/
|
||||
int
|
||||
miZeroClipLine(xmin, ymin, xmax, ymax,
|
||||
new_x1, new_y1, new_x2, new_y2,
|
||||
adx, ady,
|
||||
pt1_clipped, pt2_clipped, octant, bias, oc1, oc2)
|
||||
int xmin, ymin, xmax, ymax;
|
||||
int *new_x1, *new_y1, *new_x2, *new_y2;
|
||||
int *pt1_clipped, *pt2_clipped;
|
||||
unsigned int adx, ady;
|
||||
int octant;
|
||||
unsigned int bias;
|
||||
int oc1, oc2;
|
||||
{
|
||||
int swapped = 0;
|
||||
int clipDone = 0;
|
||||
CARD32 utmp = 0;
|
||||
int clip1, clip2;
|
||||
int x1, y1, x2, y2;
|
||||
int x1_orig, y1_orig, x2_orig, y2_orig;
|
||||
int xmajor;
|
||||
int negslope = 0, anchorval = 0;
|
||||
unsigned int eqn = 0;
|
||||
|
||||
x1 = x1_orig = *new_x1;
|
||||
y1 = y1_orig = *new_y1;
|
||||
x2 = x2_orig = *new_x2;
|
||||
y2 = y2_orig = *new_y2;
|
||||
|
||||
clip1 = 0;
|
||||
clip2 = 0;
|
||||
|
||||
xmajor = IsXMajorOctant(octant);
|
||||
bias = ((bias >> octant) & 1);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((oc1 & oc2) != 0) /* trivial reject */
|
||||
{
|
||||
clipDone = -1;
|
||||
clip1 = oc1;
|
||||
clip2 = oc2;
|
||||
break;
|
||||
}
|
||||
else if ((oc1 | oc2) == 0) /* trivial accept */
|
||||
{
|
||||
clipDone = 1;
|
||||
if (swapped)
|
||||
{
|
||||
SWAPINT_PAIR(x1, y1, x2, y2);
|
||||
SWAPINT(clip1, clip2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else /* have to clip */
|
||||
{
|
||||
/* only clip one point at a time */
|
||||
if (oc1 == 0)
|
||||
{
|
||||
SWAPINT_PAIR(x1, y1, x2, y2);
|
||||
SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig);
|
||||
SWAPINT(oc1, oc2);
|
||||
SWAPINT(clip1, clip2);
|
||||
swapped = !swapped;
|
||||
}
|
||||
|
||||
clip1 |= oc1;
|
||||
if (oc1 & OUT_LEFT)
|
||||
{
|
||||
negslope = IsYDecreasingOctant(octant);
|
||||
utmp = xmin - x1_orig;
|
||||
if (utmp <= 32767) /* clip based on near endpt */
|
||||
{
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN2 : EQN1;
|
||||
else
|
||||
eqn = (swapped) ? EQN4 : EQN3;
|
||||
anchorval = y1_orig;
|
||||
}
|
||||
else /* clip based on far endpt */
|
||||
{
|
||||
utmp = x2_orig - xmin;
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN1B : EQN2B;
|
||||
else
|
||||
eqn = (swapped) ? EQN3B : EQN4B;
|
||||
anchorval = y2_orig;
|
||||
negslope = !negslope;
|
||||
}
|
||||
x1 = xmin;
|
||||
}
|
||||
else if (oc1 & OUT_ABOVE)
|
||||
{
|
||||
negslope = IsXDecreasingOctant(octant);
|
||||
utmp = ymin - y1_orig;
|
||||
if (utmp <= 32767) /* clip based on near endpt */
|
||||
{
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN6 : EQN5;
|
||||
else
|
||||
eqn = (swapped) ? EQN8 : EQN7;
|
||||
anchorval = x1_orig;
|
||||
}
|
||||
else /* clip based on far endpt */
|
||||
{
|
||||
utmp = y2_orig - ymin;
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN5B : EQN6B;
|
||||
else
|
||||
eqn = (swapped) ? EQN7B : EQN8B;
|
||||
anchorval = x2_orig;
|
||||
negslope = !negslope;
|
||||
}
|
||||
y1 = ymin;
|
||||
}
|
||||
else if (oc1 & OUT_RIGHT)
|
||||
{
|
||||
negslope = IsYDecreasingOctant(octant);
|
||||
utmp = x1_orig - xmax;
|
||||
if (utmp <= 32767) /* clip based on near endpt */
|
||||
{
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN2 : EQN1;
|
||||
else
|
||||
eqn = (swapped) ? EQN4 : EQN3;
|
||||
anchorval = y1_orig;
|
||||
}
|
||||
else /* clip based on far endpt */
|
||||
{
|
||||
/*
|
||||
* Technically since the equations can handle
|
||||
* utmp == 32768, this overflow code isn't
|
||||
* needed since X11 protocol can't generate
|
||||
* a line which goes more than 32768 pixels
|
||||
* to the right of a clip rectangle.
|
||||
*/
|
||||
utmp = xmax - x2_orig;
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN1B : EQN2B;
|
||||
else
|
||||
eqn = (swapped) ? EQN3B : EQN4B;
|
||||
anchorval = y2_orig;
|
||||
negslope = !negslope;
|
||||
}
|
||||
x1 = xmax;
|
||||
}
|
||||
else if (oc1 & OUT_BELOW)
|
||||
{
|
||||
negslope = IsXDecreasingOctant(octant);
|
||||
utmp = y1_orig - ymax;
|
||||
if (utmp <= 32767) /* clip based on near endpt */
|
||||
{
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN6 : EQN5;
|
||||
else
|
||||
eqn = (swapped) ? EQN8 : EQN7;
|
||||
anchorval = x1_orig;
|
||||
}
|
||||
else /* clip based on far endpt */
|
||||
{
|
||||
/*
|
||||
* Technically since the equations can handle
|
||||
* utmp == 32768, this overflow code isn't
|
||||
* needed since X11 protocol can't generate
|
||||
* a line which goes more than 32768 pixels
|
||||
* below the bottom of a clip rectangle.
|
||||
*/
|
||||
utmp = ymax - y2_orig;
|
||||
if (xmajor)
|
||||
eqn = (swapped) ? EQN5B : EQN6B;
|
||||
else
|
||||
eqn = (swapped) ? EQN7B : EQN8B;
|
||||
anchorval = x2_orig;
|
||||
negslope = !negslope;
|
||||
}
|
||||
y1 = ymax;
|
||||
}
|
||||
|
||||
if (swapped)
|
||||
negslope = !negslope;
|
||||
|
||||
utmp <<= 1; /* utmp = 2N or 2M */
|
||||
if (eqn & T_2NDX)
|
||||
utmp = (utmp * adx);
|
||||
else /* (eqn & T_2MDY) */
|
||||
utmp = (utmp * ady);
|
||||
if (eqn & T_DXNOTY)
|
||||
if (eqn & T_SUBDXORY)
|
||||
utmp -= adx;
|
||||
else
|
||||
utmp += adx;
|
||||
else /* (eqn & T_DYNOTX) */
|
||||
if (eqn & T_SUBDXORY)
|
||||
utmp -= ady;
|
||||
else
|
||||
utmp += ady;
|
||||
if (eqn & T_BIASSUBONE)
|
||||
utmp += bias - 1;
|
||||
else /* (eqn & T_SUBBIAS) */
|
||||
utmp -= bias;
|
||||
if (eqn & T_DIV2DX)
|
||||
utmp /= (adx << 1);
|
||||
else /* (eqn & T_DIV2DY) */
|
||||
utmp /= (ady << 1);
|
||||
if (eqn & T_ADDONE)
|
||||
utmp++;
|
||||
|
||||
if (negslope)
|
||||
utmp = -utmp;
|
||||
|
||||
if (eqn & T_2NDX) /* We are calculating X steps */
|
||||
x1 = anchorval + utmp;
|
||||
else /* else, Y steps */
|
||||
y1 = anchorval + utmp;
|
||||
|
||||
oc1 = 0;
|
||||
MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax);
|
||||
}
|
||||
}
|
||||
|
||||
*new_x1 = x1;
|
||||
*new_y1 = y1;
|
||||
*new_x2 = x2;
|
||||
*new_y2 = y2;
|
||||
|
||||
*pt1_clipped = clip1;
|
||||
*pt2_clipped = clip2;
|
||||
|
||||
return clipDone;
|
||||
}
|
||||
383
nx-X11/programs/Xserver/mi/mizerline.c
Normal file
383
nx-X11/programs/Xserver/mi/mizerline.c
Normal file
@@ -0,0 +1,383 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 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.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "windowstr.h"
|
||||
#include "pixmap.h"
|
||||
#include "mi.h"
|
||||
#include "miline.h"
|
||||
|
||||
/* Draw lineSolid, fillStyle-independent zero width lines.
|
||||
*
|
||||
* Must keep X and Y coordinates in "ints" at least until after they're
|
||||
* translated and clipped to accomodate CoordModePrevious lines with very
|
||||
* large coordinates.
|
||||
*
|
||||
* Draws the same pixels regardless of sign(dx) or sign(dy).
|
||||
*
|
||||
* Ken Whaley
|
||||
*
|
||||
*/
|
||||
|
||||
/* largest positive value that can fit into a component of a point.
|
||||
* Assumes that the point structure is {type x, y;} where type is
|
||||
* a signed type.
|
||||
*/
|
||||
#define MAX_COORDINATE ((1 << (((sizeof(DDXPointRec) >> 1) << 3) - 1)) - 1)
|
||||
|
||||
#define MI_OUTPUT_POINT(xx, yy)\
|
||||
{\
|
||||
if ( !new_span && yy == current_y)\
|
||||
{\
|
||||
if (xx < spans->x)\
|
||||
spans->x = xx;\
|
||||
++*widths;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
++Nspans;\
|
||||
++spans;\
|
||||
++widths;\
|
||||
spans->x = xx;\
|
||||
spans->y = yy;\
|
||||
*widths = 1;\
|
||||
current_y = yy;\
|
||||
new_span = FALSE;\
|
||||
}\
|
||||
}
|
||||
|
||||
void
|
||||
miZeroLine(pDraw, pGC, mode, npt, pptInit)
|
||||
DrawablePtr pDraw;
|
||||
GCPtr pGC;
|
||||
int mode; /* Origin or Previous */
|
||||
int npt; /* number of points */
|
||||
DDXPointPtr pptInit;
|
||||
{
|
||||
int Nspans, current_y = 0;
|
||||
DDXPointPtr ppt;
|
||||
DDXPointPtr pspanInit, spans;
|
||||
int *pwidthInit, *widths, list_len;
|
||||
int xleft, ytop, xright, ybottom;
|
||||
int new_x1, new_y1, new_x2, new_y2;
|
||||
int x = 0, y = 0, x1, y1, x2, y2, xstart, ystart;
|
||||
int oc1, oc2;
|
||||
int result;
|
||||
int pt1_clipped, pt2_clipped = 0;
|
||||
Bool new_span;
|
||||
int signdx, signdy;
|
||||
int clipdx, clipdy;
|
||||
int width, height;
|
||||
int adx, ady;
|
||||
int octant;
|
||||
unsigned int bias = miGetZeroLineBias(pDraw->pScreen);
|
||||
int e, e1, e2, e3; /* Bresenham error terms */
|
||||
int length; /* length of lines == # of pixels on major axis */
|
||||
|
||||
xleft = pDraw->x;
|
||||
ytop = pDraw->y;
|
||||
xright = pDraw->x + pDraw->width - 1;
|
||||
ybottom = pDraw->y + pDraw->height - 1;
|
||||
|
||||
if (!pGC->miTranslate)
|
||||
{
|
||||
/* do everything in drawable-relative coordinates */
|
||||
xleft = 0;
|
||||
ytop = 0;
|
||||
xright -= pDraw->x;
|
||||
ybottom -= pDraw->y;
|
||||
}
|
||||
|
||||
/* it doesn't matter whether we're in drawable or screen coordinates,
|
||||
* FillSpans simply cannot take starting coordinates outside of the
|
||||
* range of a DDXPointRec component.
|
||||
*/
|
||||
if (xright > MAX_COORDINATE)
|
||||
xright = MAX_COORDINATE;
|
||||
if (ybottom > MAX_COORDINATE)
|
||||
ybottom = MAX_COORDINATE;
|
||||
|
||||
/* since we're clipping to the drawable's boundaries & coordinate
|
||||
* space boundaries, we're guaranteed that the larger of width/height
|
||||
* is the longest span we'll need to output
|
||||
*/
|
||||
width = xright - xleft + 1;
|
||||
height = ybottom - ytop + 1;
|
||||
list_len = (height >= width) ? height : width;
|
||||
pspanInit = (DDXPointPtr)malloc(list_len * sizeof(DDXPointRec));
|
||||
pwidthInit = (int *)malloc(list_len * sizeof(int));
|
||||
if (!pspanInit || !pwidthInit)
|
||||
{
|
||||
free(pspanInit);
|
||||
free(pwidthInit);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Nspans = 0;
|
||||
new_span = TRUE;
|
||||
spans = pspanInit - 1;
|
||||
widths = pwidthInit - 1;
|
||||
ppt = pptInit;
|
||||
|
||||
xstart = ppt->x;
|
||||
ystart = ppt->y;
|
||||
if (pGC->miTranslate)
|
||||
{
|
||||
xstart += pDraw->x;
|
||||
ystart += pDraw->y;
|
||||
}
|
||||
|
||||
/* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify
|
||||
* iteration logic
|
||||
*/
|
||||
x2 = xstart;
|
||||
y2 = ystart;
|
||||
oc2 = 0;
|
||||
MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
|
||||
|
||||
while (--npt > 0)
|
||||
{
|
||||
if (Nspans > 0)
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
|
||||
pwidthInit, FALSE);
|
||||
Nspans = 0;
|
||||
new_span = TRUE;
|
||||
spans = pspanInit - 1;
|
||||
widths = pwidthInit - 1;
|
||||
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
oc1 = oc2;
|
||||
++ppt;
|
||||
|
||||
x2 = ppt->x;
|
||||
y2 = ppt->y;
|
||||
if (pGC->miTranslate && (mode != CoordModePrevious))
|
||||
{
|
||||
x2 += pDraw->x;
|
||||
y2 += pDraw->y;
|
||||
}
|
||||
else if (mode == CoordModePrevious)
|
||||
{
|
||||
x2 += x1;
|
||||
y2 += y1;
|
||||
}
|
||||
|
||||
oc2 = 0;
|
||||
MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
|
||||
|
||||
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
|
||||
|
||||
if (adx > ady)
|
||||
{
|
||||
e1 = ady << 1;
|
||||
e2 = e1 - (adx << 1);
|
||||
e = e1 - adx;
|
||||
length = adx; /* don't draw endpoint in main loop */
|
||||
|
||||
FIXUP_ERROR(e, octant, bias);
|
||||
|
||||
new_x1 = x1;
|
||||
new_y1 = y1;
|
||||
new_x2 = x2;
|
||||
new_y2 = y2;
|
||||
pt1_clipped = 0;
|
||||
pt2_clipped = 0;
|
||||
|
||||
if ((oc1 | oc2) != 0)
|
||||
{
|
||||
result = miZeroClipLine(xleft, ytop, xright, ybottom,
|
||||
&new_x1, &new_y1, &new_x2, &new_y2,
|
||||
adx, ady,
|
||||
&pt1_clipped, &pt2_clipped,
|
||||
octant, bias, oc1, oc2);
|
||||
if (result == -1)
|
||||
continue;
|
||||
|
||||
length = abs(new_x2 - new_x1);
|
||||
|
||||
/* if we've clipped the endpoint, always draw the full length
|
||||
* of the segment, because then the capstyle doesn't matter
|
||||
*/
|
||||
if (pt2_clipped)
|
||||
length++;
|
||||
|
||||
if (pt1_clipped)
|
||||
{
|
||||
/* must calculate new error terms */
|
||||
clipdx = abs(new_x1 - x1);
|
||||
clipdy = abs(new_y1 - y1);
|
||||
e += (clipdy * e2) + ((clipdx - clipdy) * e1);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw the segment */
|
||||
|
||||
x = new_x1;
|
||||
y = new_y1;
|
||||
|
||||
e3 = e2 - e1;
|
||||
e = e - e1;
|
||||
|
||||
while (length--)
|
||||
{
|
||||
MI_OUTPUT_POINT(x, y);
|
||||
e += e1;
|
||||
if (e >= 0)
|
||||
{
|
||||
y += signdy;
|
||||
e += e3;
|
||||
}
|
||||
x += signdx;
|
||||
}
|
||||
}
|
||||
else /* Y major line */
|
||||
{
|
||||
e1 = adx << 1;
|
||||
e2 = e1 - (ady << 1);
|
||||
e = e1 - ady;
|
||||
length = ady; /* don't draw endpoint in main loop */
|
||||
|
||||
SetYMajorOctant(octant);
|
||||
FIXUP_ERROR(e, octant, bias);
|
||||
|
||||
new_x1 = x1;
|
||||
new_y1 = y1;
|
||||
new_x2 = x2;
|
||||
new_y2 = y2;
|
||||
pt1_clipped = 0;
|
||||
pt2_clipped = 0;
|
||||
|
||||
if ((oc1 | oc2) != 0)
|
||||
{
|
||||
result = miZeroClipLine(xleft, ytop, xright, ybottom,
|
||||
&new_x1, &new_y1, &new_x2, &new_y2,
|
||||
adx, ady,
|
||||
&pt1_clipped, &pt2_clipped,
|
||||
octant, bias, oc1, oc2);
|
||||
if (result == -1)
|
||||
continue;
|
||||
|
||||
length = abs(new_y2 - new_y1);
|
||||
|
||||
/* if we've clipped the endpoint, always draw the full length
|
||||
* of the segment, because then the capstyle doesn't matter
|
||||
*/
|
||||
if (pt2_clipped)
|
||||
length++;
|
||||
|
||||
if (pt1_clipped)
|
||||
{
|
||||
/* must calculate new error terms */
|
||||
clipdx = abs(new_x1 - x1);
|
||||
clipdy = abs(new_y1 - y1);
|
||||
e += (clipdx * e2) + ((clipdy - clipdx) * e1);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw the segment */
|
||||
|
||||
x = new_x1;
|
||||
y = new_y1;
|
||||
|
||||
e3 = e2 - e1;
|
||||
e = e - e1;
|
||||
|
||||
while (length--)
|
||||
{
|
||||
MI_OUTPUT_POINT(x, y);
|
||||
e += e1;
|
||||
if (e >= 0)
|
||||
{
|
||||
x += signdx;
|
||||
e += e3;
|
||||
}
|
||||
y += signdy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* only do the capnotlast check on the last segment
|
||||
* and only if the endpoint wasn't clipped. And then, if the last
|
||||
* point is the same as the first point, do not draw it, unless the
|
||||
* line is degenerate
|
||||
*/
|
||||
if ( (! pt2_clipped) && (pGC->capStyle != CapNotLast) &&
|
||||
(((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1)))
|
||||
{
|
||||
MI_OUTPUT_POINT(x, y);
|
||||
}
|
||||
|
||||
if (Nspans > 0)
|
||||
(*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
|
||||
pwidthInit, FALSE);
|
||||
|
||||
free(pwidthInit);
|
||||
free(pspanInit);
|
||||
}
|
||||
|
||||
void
|
||||
miZeroDashLine(dst, pgc, mode, nptInit, pptInit)
|
||||
DrawablePtr dst;
|
||||
GCPtr pgc;
|
||||
int mode;
|
||||
int nptInit; /* number of points in polyline */
|
||||
DDXPointRec *pptInit; /* points in the polyline */
|
||||
{
|
||||
/* XXX kludge until real zero-width dash code is written */
|
||||
pgc->lineWidth = 1;
|
||||
miWideDash (dst, pgc, mode, nptInit, pptInit);
|
||||
pgc->lineWidth = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user