⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hpcopyarea.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Copyright (c) 1986, 1987, 1988 by Hewlett-Packard CompanyHEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARDTO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Hewlett-Packard shall not be liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance, or use of this material.*//* $XConsortium: hpCopyArea.c,v 1.4 88/09/30 14:16:22 jim Exp $ *//*  * hpCopyArea.c : a copy area for HP displays * Author: C Durland  (aided and abetted by Mr. J. Daniels) */#include "X.h"#include "gcstruct.h"#include "pixmapstr.h"#include "windowstr.h"#include "scrnintstr.h"#include "regionstr.h"#include "mi.h"#include "servermd.h"#include "cfb.h"/*  MTOS : main memory to screen MTOM : main mem to main mem, screen to main mem STOS : screen to screen			    DESTINATION			       | screen | main memory			window | pixmap | pixmap	SOURCE	      .--------|--------|-------   window	      |  STOS  |  STOS  | MTOM   screen pixmap      |  STOS  |  STOS  | MTOM   main memory pixmap |  MTOS  |  MTOS  | MTOM			Dest clip list		Source clip list   window		composite clip		inferiors or window clip list   screen pixmap	maybe a client clip	no   main memory pixmap	maybe a client clip	no*/#define COPYROW(to,from,n) memcpy(to,from,n)#define PIXER(Drawable)  ((hpPrivPixmapPtr)((PixmapPtr)Drawable)->devPrivate.ptr)#define SCRMER(Drawable) getPrivScreenPtr(Drawable->pScreen)#define DEVKIND(Drawable) ((PixmapPtr)Drawable)->devKind#define SWEAT_PLANES_MASK(Drawable,planesmask)		\  ((SCRMER(Drawable)->planesMask & planesmask) !=	\    SCRMER(Drawable)->planesMask)	/* Clip rectangle (x,y)-(x+w,y+h) against (a,b)-(c,d)	 * Returns the cliped (x,y) and w,h	 */void clipper(x,y,w,h, a,b,c,d, cx,cy, cw,ch)     register int x,y,w,h, a,b,c,d;     int *cx,*cy, *cw,*ch;{    *cw = min(x+w,c) - (*cx = max(x,a));    *ch = min(y+h,d) - (*cy = max(y,b));}	/* Check to see if can copy area between two rectangles:	 *   If the dest is above the source: can copy	 *   else if they overlap:  Can't copy	 * Have to check horizontal because of clip lists.  boxes is the sum	 *  of the number of clip rectangles for the source and dest.	 * Returns: FALSE if can copy area (ie any overlap don't matter)	 *    true if got a overlap problem	 */static intlapdog(srcx,srcy, w,h, dstx,dsty, boxes)     int srcx,srcy, w,h, dstx,dsty, boxes;{    return	( (srcy <= dsty) || ((boxes > 2) && (srcx < dstx)) ) &&	    ( ((min(srcx,dstx)+w -max(srcx,dstx)) >0) &&	     ((min(srcy,dsty)+h -max(srcy,dsty)) >0) );}	/* Copy rectangles from screen to screen using the block mover	 * Overlapping moves:	 *   Assumes that block mover can handle overlapping copies.	 *   If there is a clip list, care must be taken so that copying	 *     a block does not trash a block to be copied.	 * (?tx, ?ty) are translation constants to convert pixmaps	 *   to screen coordinates.  0 if not a pixmap.	 */voidScreenToScreen(drawable,gc, sx,sy,width,height, dx,dy,	sbox,sboxes, dbox,dboxes, stx,sty, dtx,dty)     DrawablePtr drawable;     GCPtr gc;     int sx,sy,width,height, dx,dy, sboxes, dboxes, stx,sty, dtx,dty;     BoxPtr sbox, dbox;	/* the clip lists */{    register BoxPtr btr;    int j, x1,y1, w1,h1, x2,y2, w2,h2,   a,b,c,d, tx = sx-dx, ty = sy-dy;    ScreenPtr Screen = drawable->pScreen;    if (gc->alu==GXnoop)	return;			/* no op => don't do nothin */    for (; sboxes--; sbox++)	/* for each source box */    {	/* intersect source and source clip rectangle */	clipper(sx,sy,width,height, sbox->x1,sbox->y1, sbox->x2,sbox->y2,		&x1,&y1, &w1,&h1);	if (w1<=0 || h1<=0)	    continue;	/* translate box to dst coordinates */	a = x1 -tx; b = y1 -ty; c = a +w1; d = b +h1;	for (j = dboxes, btr = dbox; j--; btr++) /* copy to the dest box */	{	    /* intersect dst and dst clip rectangles */	    clipper(dx,dy,width,height, btr->x1,btr->y1, btr->x2,btr->y2,		    &x2,&y2, &w2,&h2);	    if (w2<=0 || h2<=0)		continue;	    /* intersect clipped src and clipped dst rectangles */	    clipper(x2,y2,w2,h2, a,b,c,d, &x1,&y1, &w1,&h1);	    if (w1<=0 || h1<=0)		continue;	    (*getPrivScreenPtr(Screen)->MoveBits)		(Screen, gc->planemask, gc->alu,		 x1+tx+stx, y1+ty+sty, x1+dtx, y1+dty, w1, h1);	}    }}	/* copy a rectangle of bytes: no processing */static voidCopyRec0(dst,w,h,dst_stride, alu)     register char *dst;     int w,h,dst_stride, alu;{    register int z;    switch (alu)    {      case GXclear: z = 0; break;		/* 0 */      case GXset: z = ~0; break;		/* 1 */    }    while (h--)			/* copy h rows */    {	memset(dst,z,w);	dst += dst_stride;	/* move to next row */    }}	/* copy a rectangle of bytes: only process src */	/* two cases: GXcopy & GXcopyInverted */static voidCopyRec1(src,dst,w,h,src_stride,dst_stride, alu)     register char *src, *dst;     int w,h,src_stride,dst_stride, alu;{    register int j;    if (alu==GXcopy)	while (h--)		/* copy h rows */	{	    COPYROW(dst,src,w);	    src += src_stride; dst += dst_stride;	/* move to next row */	}    else	while (h--)		/* copy h rows */	{	    j = w;	    while (j--) dst[j] = ~src[j];	    src += src_stride; dst += dst_stride;	/* move to next row */	}}	/* copy a rectangle of bytes: process src & dst */static voidCopyRec2(src,dst,w,h,src_stride,dst_stride, alu,planesmask)     register char *src, *dst;     int w,h,src_stride,dst_stride, alu;     register long int planesmask;{    register char a, b;    register int j;    /*!!! slime bag note: if planesmask > 8 bits this routine no workie */    while (h--)			/* copy h rows */    {	j = w;	while (j--)		/* copy a row */	{	    a = src[j]; b = dst[j];	    switch (alu)	    {	      case GXclear: a = 0; break;		/* 0 */	      case GXset: a = ~0; break;		/* 1 */	      case GXcopyInverted: b = ~a; break;	/* ~src *//*	      case GXcopy: a = a; break;		/* src */	      case GXand: a = a & b; break; 		/* src AND dst */	      case GXandReverse: a = a & (~b); break;   /* src AND NOT dst */	      case GXandInverted: a = (~a) & b; break;  /* NOT src AND dst */	      case GXxor: a = a ^ b; break;		/* src XOR dst */	      case GXor: a = a | b; break;		/* src OR dst */	      case GXnor: a = (~a) & (~b); break;     /* NOT src AND NOT dst */	      case GXequiv: a = (~a) ^ b; break;	/* NOT src XOR dst */	      case GXinvert: a = ~b; break;		/* NOT dst */	      case GXorReverse: a = a | (~b); break;    /* src OR NOT dst */	      case GXorInverted: a = (~a) | b; break;   /* NOT src OR dst */	      case GXnand: a = (~a) | (~b); break;    /* NOT src OR NOT dst */	    }	    dst[j] = (a & planesmask) | (b & ~planesmask);	}	src += src_stride; dst += dst_stride;	/* move to next row */    }}	/* move bytes from main memory to main memory	 *   or move bytes from screen to main memory	 * concerns: Replacement rule, overlapping copies,	 * Only works for depths of 1 and multiples of 8.	 */voidMemToMem(SrcDrawable,DstDrawable,gc, sx,sy,width,height, dx,dy,	 sbox,sboxes, dbox,dboxes)     DrawablePtr SrcDrawable,DstDrawable;     GCPtr gc;     int sx,sy,width,height, dx,dy, sboxes, dboxes;     BoxPtr sbox, dbox;	/* the clip lists */{    unsigned char *src, *dst, *presrc;    register int src_stride, dst_stride;    int	j, x1,y1, w1,h1, x2,y2, w2,h2,   a,b,c,d, tx = sx-dx, ty = sy-dy,	alu, fake_alu,	DepthInBytes = SrcDrawable->depth/8;    unsigned long int planesmask;    register BoxPtr btr;    if ((alu=gc->alu)==GXnoop) return;	/* no op => don't do nothin */    fake_alu = alu; planesmask = gc->planemask;    if (DepthInBytes<1)	/* moving bits */    {	DepthInBytes = 1;	/* fake around */	if (planesmask==0) return;	/* no bits will be changed */	planesmask = ~0;		/* all bits can be changed */    }	/* check to see if gotta sweat the planes mask */    if (SWEAT_PLANES_MASK(SrcDrawable,planesmask)) fake_alu = 666;    dst_stride = PIXER(DstDrawable)->stride;    if (SrcDrawable->type == DRAWABLE_WINDOW)	/* from screen */    {	src_stride = SCRMER(SrcDrawable)->stride;	presrc = SCRMER(SrcDrawable)->bits;    }    else			/* from main memory or offscreen pixmap */    {	src_stride = PIXER(SrcDrawable)->stride;	presrc = PIXER(SrcDrawable)->bits;    }    for (; sboxes--; sbox++)	/* for each source box */    {	/* intersect src and src clip rectangle */	clipper(sx,sy,width,height, sbox->x1,sbox->y1,sbox->x2,sbox->y2,		&x1,&y1, &w1,&h1);	if (w1<=0 || h1<=0) continue;	/* translate box to dst coordinates */	a = x1 -tx; b = y1 -ty; c = a +w1; d = b +h1;	for (j = dboxes, btr = dbox; j--; btr++)	{	    /* intersect dst and dst clip rectangles */	    clipper(dx,dy,width,height, btr->x1,btr->y1, btr->x2,btr->y2,		    &x2,&y2, &w2,&h2);	    if (w2<=0 || h2<=0) continue;	    /* intersect clipped src and clipped dst rectangles */	    clipper(x2,y2,w2,h2, a,b,c,d, &x1,&y1, &w1,&h1);	    if (w1<=0 || h1<=0) continue;	    w1 *= DepthInBytes;	    /* convert rectangle to addresses */	    src = presrc + (x1+tx)*DepthInBytes +(y1+ty)*src_stride;	    dst = PIXER(DstDrawable)->bits +x1*DepthInBytes +y1*dst_stride;	    switch (fake_alu)	    {	      case GXclear:	      case GXset:		CopyRec0(dst,w1,h1,dst_stride, alu); break;	      case GXcopy:	      case GXcopyInverted:		CopyRec1(src,dst,w1,h1,src_stride,dst_stride, alu);		break;	      default:		CopyRec2(src,dst,w1,h1,src_stride,dst_stride, alu,planesmask);	    }	}    }}	/* Move bytes from main memory to screen memory.	 * (dtx,dty) are translation constants to convert pixmaps	 *   to screen coordinates.  0 if not a pixmap.	 */voidMemToScreen(SrcDrawable,DstDrawable,gc, sx,sy,width,height, dx,dy,	    dboxes, dbox, dtx,dty)     DrawablePtr SrcDrawable,DstDrawable;     GCPtr gc;     int sx,sy,width,height, dx,dy, dboxes, dtx,dty;     BoxPtr dbox;	/* the dst clip list */{    register unsigned char *src, *dst;    register int src_stride, dst_stride;    int	w,h, x1,y1,	DepthInBytes = SrcDrawable->depth/8;	/* setup hardware */    SET_REGISTERS_FOR_WRITING(gc->pScreen,gc->planemask,gc->alu);    src_stride = PIXER(SrcDrawable)->stride;    dst_stride = SCRMER(DstDrawable)->stride;    for (; dboxes--; dbox++)    {	/* intersect dst and clip rectangles */	clipper(dx,dy,width,height, dbox->x1,dbox->y1,dbox->x2,dbox->y2,		&x1,&y1, &w,&h);	w *= DepthInBytes;	if (w<=0 || h<=0) continue;	/* convert rectangle to addresses */	src = PIXER(SrcDrawable)->bits	    +(sx +(x1-dx))*DepthInBytes +(sy +(y1-dy))*src_stride;	dst = SCRMER(DstDrawable)->bits	    +(x1+dtx)*DepthInBytes +(y1+dty)*dst_stride;	/* copy rectangle */	while (h--)	{	    COPYROW(dst,src,w);	    src += src_stride; dst += dst_stride;	/* move to next row */	}    }}	/* reverse banding */static voidspud(list,n)     BoxRec *list;     int n;{    register BoxRec box;    register int i, j, k;    for (j = 0, i = n, k = n/2; j<k; )    {	box = list[j]; list[j++] = list[--i]; list[i] = box;    }}	/* reverse horizontal banding */static voidspudd(list,n)     register BoxRec *list;     int n;{    register int i,j;    for (j=0; j<n; j = i)    {	for (i = j+1; i<n && list[i].y1==list[j].y1; i++)	    ;	spud(&list[j],i-j);    }}extern RegionPtr NotClippedByChildren();static RegionPtr hpfbCopyArea();RegionPtr hpcCopyArea(pSrcDrawable, pDstDrawable,	    pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut)     DrawablePtr pSrcDrawable, pDstDrawable;     GCPtr pGC;     int xIn, yIn, widthSrc, heightSrc, xOut, yOut;{    BoxRec *scl, *dcl, sbox;    int	srcx,srcy, dstx,dsty, width,height, dboxes,sboxes,	stx,sty, dtx,dty,	expose = 0, lowlife = 0;    RegionPtr sHitList = NULL;	/* the source hit list */    RegionPtr prgnExposed = NULL;    extern RegionPtr mfbCopyArea ();/* ignore UNDRAWABLE_WINDOWs in the hope DIX takes care of them */    if ((pDstDrawable->type == DRAWABLE_WINDOW) && 	(!((WindowPtr)pDstDrawable)->realized))	return (RegionPtr)NULL;    dstx = xOut; dsty = yOut; width = widthSrc; height = heightSrc;	/* clip the left and top edges of the source */    if (xIn<0)    { 	expose = 1; srcx = pSrcDrawable->x; width += xIn;    }    else	srcx = xIn + pSrcDrawable->x;    if (yIn<0)    {	expose = 1; srcy = pSrcDrawable->y; height += yIn;    }    else	srcy = yIn + pSrcDrawable->y;	/* lookup or create the source clip lists */    stx = sty = 0;    if (pSrcDrawable->type == DRAWABLE_PIXMAP)    {	/* clip right and bottom edges of source */	if (width > pSrcDrawable->width)	{	    expose = 1; width = pSrcDrawable->width;	}	if (height > pSrcDrawable->height)	{	    expose = 1; height = pSrcDrawable->height;	}	/* if screen pixmap & going to use the block mover, translate */	if (DEVKIND(pSrcDrawable) == PIXMAP_FRAME_BUFFER)	{	    stx = PIXER(pSrcDrawable)->pChunk->x;	    sty = PIXER(pSrcDrawable)->pChunk->y;	}	sbox.x2 = (sbox.x1 = srcx) + width;	sbox.y2 = (sbox.y1 = srcy) + height;	scl = &sbox; sboxes = 1;    }    else	/* source is a window */    {	expose = 1;	/* hard to figure out for a window so expose always */	/* translate window to screen coordinates */	if (pGC->subWindowMode == IncludeInferiors)	{	    /* included window can write over parent => overlap problem

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -