do_blt.c revision e4ee1255
1264fa531Smrg/*****************************************************************************
2264fa531SmrgCopyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3264fa531Smrg
4264fa531Smrg                        All Rights Reserved
5264fa531Smrg
6264fa531SmrgPermission to use, copy, modify, and distribute this software and its
7264fa531Smrgdocumentation for any purpose and without fee is hereby granted,
8264fa531Smrgprovided that the above copyright notice appear in all copies and that
9264fa531Smrgboth that copyright notice and this permission notice appear in
10264fa531Smrgsupporting documentation, and that the name of Digital not be
11264fa531Smrgused in advertising or publicity pertaining to distribution of the
12264fa531Smrgsoftware without specific, written prior permission.
13264fa531Smrg
14264fa531SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15264fa531SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16264fa531SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17264fa531SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18264fa531SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19264fa531SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20264fa531SmrgSOFTWARE.
21264fa531Smrg
22264fa531Smrg******************************************************************************/
23264fa531Smrg
24264fa531Smrg#include "x11perf.h"
25264fa531Smrg#include <stdio.h>
26264fa531Smrg
27264fa531Smrg#define NUMPOINTS 100
28264fa531Smrg
29264fa531Smrgstatic Pixmap   pix;
30264fa531Smrgstatic XImage   *image;
31264fa531Smrgstatic XPoint   points[NUMPOINTS];
32264fa531Smrgstatic XSegment *segsa, *segsb;
33264fa531Smrg
34264fa531Smrg#define NegMod(x, y) ((y) - (((-x)-1) % (7)) - 1)
35264fa531Smrg
36264fa531Smrgstatic void
37264fa531SmrgInitBltLines(void)
38264fa531Smrg{
39264fa531Smrg    int i, x, y;
40264fa531Smrg
41264fa531Smrg    points[0].x = points[0].y = y = 0;
42264fa531Smrg    for (i = 1; i != NUMPOINTS/2; i++) {
43264fa531Smrg	if (i & 1) {
44264fa531Smrg	    points[i].x = WIDTH-1;
45264fa531Smrg	} else {
46264fa531Smrg	    points[i].x = 0;
47264fa531Smrg	}
48264fa531Smrg	y += HEIGHT / (NUMPOINTS/2);
49264fa531Smrg	points[i].y = y;
50264fa531Smrg    }
51264fa531Smrg
52264fa531Smrg    x = 0;
53264fa531Smrg    for (i = NUMPOINTS/2; i!= NUMPOINTS; i++) {
54264fa531Smrg	if (i & 1) {
55264fa531Smrg	    points[i].y = HEIGHT-1;
56264fa531Smrg	} else {
57264fa531Smrg	    points[i].y = 0;
58264fa531Smrg	}
59264fa531Smrg	x += WIDTH / (NUMPOINTS/2);
60264fa531Smrg	points[i].x = x;
61264fa531Smrg    }
62264fa531Smrg}
63264fa531Smrg
64264fa531Smrgint
65264fa531SmrgInitScroll(XParms xp, Parms p, int reps)
66264fa531Smrg{
67264fa531Smrg    InitBltLines();
68264fa531Smrg    XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin);
69264fa531Smrg    return reps;
70264fa531Smrg}
71264fa531Smrg
72264fa531Smrgvoid
73264fa531SmrgDoScroll(XParms xp, Parms p, int reps)
74264fa531Smrg{
75264fa531Smrg    int i, size, x, y, xorg, yorg, delta;
76264fa531Smrg
77264fa531Smrg    size = p->special;
78264fa531Smrg    xorg = 0;   yorg = 0;
79264fa531Smrg    x    = 0;   y    = 0;
80264fa531Smrg    if (xp->version == VERSION1_2) {
81264fa531Smrg	delta = 1;
82264fa531Smrg    } else {
83264fa531Smrg	/* Version 1.2 only scrolled up by 1 scanline, which made hardware
84264fa531Smrg	   using page-mode access to VRAM look better on paper than it would
85264fa531Smrg	   perform in a more realistic scroll.  So we've changed to scroll by
86264fa531Smrg	   the height of the 6x13 fonts. */
87264fa531Smrg	delta = 13;
88264fa531Smrg    }
89264fa531Smrg
90264fa531Smrg    for (i = 0; i != reps; i++) {
91264fa531Smrg	XCopyArea(xp->d, xp->w, xp->w, xp->fggc, x, y + delta,
92264fa531Smrg	    size, size, x, y);
93264fa531Smrg	y += size;
94264fa531Smrg	if (y + size + delta > HEIGHT) {
95264fa531Smrg	    yorg += delta;
96264fa531Smrg	    if (yorg >= size || yorg + size + delta > HEIGHT) {
97264fa531Smrg		yorg = 0;
98264fa531Smrg		xorg++;
99264fa531Smrg		if (xorg >= size || xorg + size > WIDTH) {
100264fa531Smrg		    xorg = 0;
101264fa531Smrg		}
102264fa531Smrg	    }
103264fa531Smrg	    y = yorg;
104264fa531Smrg	    x += size;
105264fa531Smrg	    if (x + size > WIDTH) {
106264fa531Smrg		x = xorg;
107264fa531Smrg	    }
108264fa531Smrg	}
109264fa531Smrg	CheckAbort ();
110264fa531Smrg    }
111264fa531Smrg}
112264fa531Smrg
113264fa531Smrgvoid
114264fa531SmrgMidScroll(XParms xp, Parms p)
115264fa531Smrg{
116264fa531Smrg    XClearWindow(xp->d, xp->w);
117264fa531Smrg    XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin);
118264fa531Smrg}
119264fa531Smrg
120264fa531Smrgvoid
121264fa531SmrgEndScroll(XParms xp, Parms p)
122264fa531Smrg{
123264fa531Smrg}
124264fa531Smrg
125264fa531Smrgstatic void
126264fa531SmrgInitCopyLocations(XParms xp, Parms p, int reps)
127264fa531Smrg{
128264fa531Smrg    int x1, y1, x2, y2, size, i;
129264fa531Smrg    int xinc, yinc;
130264fa531Smrg    int width, height;
131264fa531Smrg
132264fa531Smrg    /* Try to exercise all alignments of src and destination equally, as well
133264fa531Smrg       as all 4 top-to-bottom/bottom-to-top, left-to-right, right-to-left
134264fa531Smrg       copying directions.  Computation done here just to make sure slow
135264fa531Smrg       machines aren't measuring anything but the XCopyArea calls.
136264fa531Smrg    */
137264fa531Smrg    size = p->special;
138264fa531Smrg    xinc = (size & ~3) + 1;
139264fa531Smrg    yinc = xinc + 3;
140264fa531Smrg
141264fa531Smrg    width = (WIDTH - size) & ~31;
142264fa531Smrg    height = (HEIGHT - size) & ~31;
143264fa531Smrg
144264fa531Smrg    x1 = 0;
145264fa531Smrg    y1 = 0;
146264fa531Smrg    x2 = width;
147264fa531Smrg    y2 = height;
148264fa531Smrg
149264fa531Smrg    segsa = (XSegment *)malloc(reps * sizeof(XSegment));
150264fa531Smrg    segsb = (XSegment *)malloc(reps * sizeof(XSegment));
151264fa531Smrg    for (i = 0; i != reps; i++) {
152264fa531Smrg	segsa[i].x1 = x1;
153264fa531Smrg	segsa[i].y1 = y1;
154264fa531Smrg	segsa[i].x2 = x2;
155264fa531Smrg	segsa[i].y2 = y2;
156264fa531Smrg
157264fa531Smrg	/* Move x2, y2, location backward */
158264fa531Smrg	x2 -= xinc;
159264fa531Smrg	if (x2 < 0) {
160264fa531Smrg	    x2 = NegMod(x2, width);
161264fa531Smrg	    y2 -= yinc;
162264fa531Smrg	    if (y2 < 0) {
163264fa531Smrg		y2 = NegMod(y2, height);
164264fa531Smrg	    }
165264fa531Smrg	}
166264fa531Smrg
167264fa531Smrg	segsb[i].x1 = x1;
168264fa531Smrg	segsb[i].y1 = y1;
169264fa531Smrg	segsb[i].x2 = x2;
170264fa531Smrg	segsb[i].y2 = y2;
171264fa531Smrg
172264fa531Smrg	/* Move x1, y1 location forward */
173264fa531Smrg	x1 += xinc;
174264fa531Smrg	if (x1 > width) {
175264fa531Smrg	    x1 %= 32;
176264fa531Smrg	    y1 += yinc;
177264fa531Smrg	    if (y1 > height) {
178264fa531Smrg		y1 %= 32;
179264fa531Smrg	    }
180264fa531Smrg	}
181264fa531Smrg    } /* end for */
182264fa531Smrg}
183264fa531Smrg
184264fa531Smrg
185264fa531Smrgint
186264fa531SmrgInitCopyWin(XParms xp, Parms p, int reps)
187264fa531Smrg{
188264fa531Smrg    (void) InitScroll(xp, p, reps);
189264fa531Smrg    InitCopyLocations(xp, p, reps);
190264fa531Smrg    return reps;
191264fa531Smrg}
192264fa531Smrg
193264fa531Smrgint
194264fa531SmrgInitCopyPix(XParms xp, Parms p, int reps)
195264fa531Smrg{
196264fa531Smrg    GC		pixgc;
197264fa531Smrg    (void) InitCopyWin(xp, p, reps);
198264fa531Smrg
199264fa531Smrg    /* Create pixmap to write stuff into, and initialize it */
200264fa531Smrg    pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, xp->vinfo.depth);
201c37a63b8Smrg    pixgc = XCreateGC(xp->d, pix, 0, NULL);
202264fa531Smrg    /* need a gc with GXcopy cos pixmaps contain junk on creation. mmm */
203264fa531Smrg    XCopyArea(xp->d, xp->w, pix, pixgc, 0, 0, WIDTH, HEIGHT, 0, 0);
204264fa531Smrg    XFreeGC(xp->d, pixgc);
205264fa531Smrg    return reps;
206264fa531Smrg}
207264fa531Smrg
208264fa531Smrgint
209264fa531SmrgInitGetImage(XParms xp, Parms p, int reps)
210264fa531Smrg{
211264fa531Smrg    (void) InitCopyWin(xp, p, reps);
212264fa531Smrg
213264fa531Smrg    /* Create image to stuff bits into */
214264fa531Smrg    image = XGetImage(xp->d, xp->w, 0, 0, WIDTH, HEIGHT, xp->planemask,
215c37a63b8Smrg		      p->font==NULL?ZPixmap:XYPixmap);
216c37a63b8Smrg    if(image==NULL){
217264fa531Smrg	printf("XGetImage failed\n");
218264fa531Smrg	return False;
219264fa531Smrg    }
220264fa531Smrg    return reps;
221264fa531Smrg}
222264fa531Smrg
223264fa531Smrgint
224264fa531SmrgInitPutImage(XParms xp, Parms p, int reps)
225264fa531Smrg{
226264fa531Smrg    if(!InitGetImage(xp, p, reps))return False;
227264fa531Smrg    XClearWindow(xp->d, xp->w);
228264fa531Smrg    return reps;
229264fa531Smrg}
230264fa531Smrg
231264fa531Smrgstatic void
232264fa531SmrgCopyArea(XParms xp, Parms p, int reps, Drawable src, Drawable dst)
233264fa531Smrg{
234264fa531Smrg    int i, size;
235264fa531Smrg    XSegment *sa, *sb;
236264fa531Smrg
237264fa531Smrg    size = p->special;
238264fa531Smrg    for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
239264fa531Smrg	XCopyArea(xp->d, src, dst, xp->fggc,
240264fa531Smrg	    sa->x1, sa->y1, size, size, sa->x2, sa->y2);
241264fa531Smrg	XCopyArea(xp->d, src, dst, xp->fggc,
242264fa531Smrg	    sa->x2, sa->y2, size, size, sa->x1, sa->y1);
243264fa531Smrg	XCopyArea(xp->d, src, dst, xp->fggc,
244264fa531Smrg	    sb->x2, sb->y2, size, size, sb->x1, sb->y1);
245264fa531Smrg	XCopyArea(xp->d, src, dst, xp->fggc,
246264fa531Smrg	    sb->x1, sb->y1, size, size, sb->x2, sb->y2);
247264fa531Smrg	CheckAbort ();
248264fa531Smrg    }
249264fa531Smrg}
250264fa531Smrg
251264fa531Smrgvoid
252264fa531SmrgDoCopyWinWin(XParms xp, Parms p, int reps)
253264fa531Smrg{
254264fa531Smrg    CopyArea(xp, p, reps, xp->w, xp->w);
255264fa531Smrg}
256264fa531Smrg
257264fa531Smrgvoid
258264fa531SmrgDoCopyPixWin(XParms xp, Parms p, int reps)
259264fa531Smrg{
260264fa531Smrg    CopyArea(xp, p, reps, pix, xp->w);
261264fa531Smrg}
262264fa531Smrg
263264fa531Smrgvoid
264264fa531SmrgDoCopyWinPix(XParms xp, Parms p, int reps)
265264fa531Smrg{
266264fa531Smrg    CopyArea(xp, p, reps, xp->w, pix);
267264fa531Smrg    xp->p = pix;	/* HardwareSync will now sync on pixmap */
268264fa531Smrg}
269264fa531Smrg
270264fa531Smrgvoid
271264fa531SmrgDoCopyPixPix(XParms xp, Parms p, int reps)
272264fa531Smrg{
273264fa531Smrg    CopyArea(xp, p, reps, pix, pix);
274264fa531Smrg    xp->p = pix;	/* HardwareSync will now sync on pixmap */
275264fa531Smrg}
276264fa531Smrg
277264fa531Smrgvoid
278264fa531SmrgDoGetImage(XParms xp, Parms p, int reps)
279264fa531Smrg{
280264fa531Smrg    int i, size;
281264fa531Smrg    XSegment *sa, *sb;
282264fa531Smrg    int format;
283264fa531Smrg
284264fa531Smrg    size = p->special;
285c37a63b8Smrg    format = (p->font == NULL) ? ZPixmap : XYPixmap;
286264fa531Smrg    for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
287264fa531Smrg	XDestroyImage(image);
288264fa531Smrg	image = XGetImage(xp->d, xp->w, sa->x1, sa->y1, size, size,
289264fa531Smrg	    xp->planemask, format);
290264fa531Smrg	if (image) XDestroyImage(image);
291264fa531Smrg	image = XGetImage(xp->d, xp->w, sa->x2, sa->y2, size, size,
292264fa531Smrg	    xp->planemask, format);
293264fa531Smrg	if (image) XDestroyImage(image);
294264fa531Smrg	image = XGetImage(xp->d, xp->w, sb->x2, sb->y2, size, size,
295264fa531Smrg	    xp->planemask, format);
296264fa531Smrg	if (image) XDestroyImage(image);
297264fa531Smrg	image = XGetImage(xp->d, xp->w, sb->x1, sb->y1, size, size,
298264fa531Smrg	    xp->planemask, format);
299264fa531Smrg/*
300264fa531Smrg
301264fa531SmrgOne might expect XGetSubImage to be slightly faster than XGetImage.  Go look
302264fa531Smrgat the code in Xlib.  MIT X11R3 ran approximately 30 times slower for a 500x500
303264fa531Smrgrectangle.
304264fa531Smrg
305264fa531Smrg	(void) XGetSubImage(xp->d, xp->w, sa->x1, sa->y1, size, size,
306264fa531Smrg	    xp->planemask, ZPixmap, image, sa->x2, sa->y2);
307264fa531Smrg	(void) XGetSubImage(xp->d, xp->w, sa->x2, sa->y2, size, size,
308264fa531Smrg	    xp->planemask, ZPixmap, image, sa->x1, sa->y1);
309264fa531Smrg	(void) XGetSubImage(xp->d, xp->w, sb->x2, sb->y2, size, size,
310264fa531Smrg	    xp->planemask, ZPixmap, image, sb->x2, sb->y2);
311264fa531Smrg	(void) XGetSubImage(xp->d, xp->w, sb->x1, sb->y1, size, size,
312264fa531Smrg	    xp->planemask, ZPixmap, image, sb->x2, sb->y2);
313264fa531Smrg*/
314264fa531Smrg	CheckAbort ();
315264fa531Smrg    }
316264fa531Smrg}
317264fa531Smrg
318264fa531Smrgvoid
319264fa531SmrgDoPutImage(XParms xp, Parms p, int reps)
320264fa531Smrg{
321264fa531Smrg    int i, size;
322264fa531Smrg    XSegment *sa, *sb;
323264fa531Smrg
324264fa531Smrg    size = p->special;
325264fa531Smrg    for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
326264fa531Smrg	XPutImage(xp->d, xp->w, xp->fggc, image,
327264fa531Smrg	    sa->x1, sa->y1, sa->x2, sa->y2, size, size);
328264fa531Smrg	XPutImage(xp->d, xp->w, xp->fggc, image,
329264fa531Smrg	    sa->x2, sa->y2, sa->x1, sa->y1, size, size);
330264fa531Smrg	XPutImage(xp->d, xp->w, xp->fggc, image,
331264fa531Smrg	    sb->x2, sb->y2, sb->x2, sb->y2, size, size);
332264fa531Smrg	XPutImage(xp->d, xp->w, xp->fggc, image,
333264fa531Smrg	    sb->x1, sb->y1, sb->x2, sb->y2, size, size);
334264fa531Smrg	CheckAbort ();
335264fa531Smrg    }
336264fa531Smrg}
337264fa531Smrg
338264fa531Smrg#ifdef MITSHM
339264fa531Smrg
340264fa531Smrg#include <sys/types.h>
341264fa531Smrg#ifndef Lynx
342264fa531Smrg#include <sys/ipc.h>
343264fa531Smrg#include <sys/shm.h>
344264fa531Smrg#else
345264fa531Smrg#include <ipc.h>
346264fa531Smrg#include <shm.h>
347264fa531Smrg#endif
348264fa531Smrg#include <X11/extensions/XShm.h>
349264fa531Smrg
350264fa531Smrgstatic XImage		shm_image;
351264fa531Smrgstatic XShmSegmentInfo	shm_info;
352264fa531Smrg
353264fa531Smrgstatic int haderror;
354264fa531Smrgstatic int (*origerrorhandler)(Display *, XErrorEvent *);
355264fa531Smrg
356264fa531Smrgstatic int
357264fa531Smrgshmerrorhandler(Display *d, XErrorEvent *e)
358264fa531Smrg{
359264fa531Smrg    haderror++;
360264fa531Smrg    if(e->error_code==BadAccess) {
361264fa531Smrg	fprintf(stderr,"failed to attach shared memory\n");
362264fa531Smrg	return 0;
363264fa531Smrg    } else
364264fa531Smrg	return (*origerrorhandler)(d,e);
365264fa531Smrg}
366264fa531Smrg
367e4ee1255Smrgstatic int
368e4ee1255SmrgInitShmImage(XParms xp, Parms p, int reps, Bool read_only)
369264fa531Smrg{
370264fa531Smrg    int	image_size;
371264fa531Smrg
372264fa531Smrg    if(!InitGetImage(xp, p, reps))return False;
373264fa531Smrg    if (!XShmQueryExtension(xp->d)) {
374264fa531Smrg	/*
375264fa531Smrg 	 * Clean up here because cleanup function is not called if this
376264fa531Smrg	 * function fails
377264fa531Smrg	 */
378264fa531Smrg       	if (image)
379264fa531Smrg      	    XDestroyImage(image);
380264fa531Smrg    	image = NULL;
381264fa531Smrg    	free(segsa);
382264fa531Smrg    	free(segsb);
383264fa531Smrg    	return False;
384264fa531Smrg    }
385264fa531Smrg    shm_image = *image;
386264fa531Smrg    image_size = image->bytes_per_line * image->height;
387264fa531Smrg    /* allow XYPixmap choice: */
388264fa531Smrg    if(p->font)image_size *= xp->vinfo.depth;
389264fa531Smrg    shm_info.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777);
390264fa531Smrg    if (shm_info.shmid < 0)
391264fa531Smrg    {
392264fa531Smrg	/*
393264fa531Smrg	 * Clean up here because cleanup function is not called if this
394264fa531Smrg	 * function fails
395264fa531Smrg	 */
396264fa531Smrg	if (image)
397264fa531Smrg	    XDestroyImage(image);
398264fa531Smrg	image = NULL;
399264fa531Smrg	free(segsa);
400264fa531Smrg	free(segsb);
401264fa531Smrg	perror ("shmget");
402264fa531Smrg	return False;
403264fa531Smrg    }
404c37a63b8Smrg    shm_info.shmaddr = (char *) shmat(shm_info.shmid, NULL, 0);
405264fa531Smrg    if (shm_info.shmaddr == ((char *) -1))
406264fa531Smrg    {
407264fa531Smrg	/*
408264fa531Smrg	 * Clean up here because cleanup function is not called if this
409264fa531Smrg	 * function fails
410264fa531Smrg	 */
411264fa531Smrg	if (image)
412264fa531Smrg	    XDestroyImage(image);
413264fa531Smrg	image = NULL;
414264fa531Smrg	free(segsa);
415264fa531Smrg	free(segsb);
416264fa531Smrg	perror ("shmat");
417c37a63b8Smrg	shmctl (shm_info.shmid, IPC_RMID, NULL);
418264fa531Smrg	return False;
419264fa531Smrg    }
420e4ee1255Smrg    shm_info.readOnly = read_only;
421264fa531Smrg    XSync(xp->d,True);
422264fa531Smrg    haderror = False;
423264fa531Smrg    origerrorhandler = XSetErrorHandler(shmerrorhandler);
424264fa531Smrg    XShmAttach (xp->d, &shm_info);
425264fa531Smrg    XSync(xp->d,True);	/* wait for error or ok */
426264fa531Smrg    XSetErrorHandler(origerrorhandler);
427264fa531Smrg    if(haderror){
428264fa531Smrg	/*
429264fa531Smrg	 * Clean up here because cleanup function is not called if this
430264fa531Smrg	 * function fails
431264fa531Smrg	 */
432264fa531Smrg	if (image)
433264fa531Smrg	    XDestroyImage(image);
434264fa531Smrg	image = NULL;
435264fa531Smrg	free(segsa);
436264fa531Smrg	free(segsb);
437264fa531Smrg	if(shmdt (shm_info.shmaddr)==-1)
438264fa531Smrg	    perror("shmdt:");
439c37a63b8Smrg	if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1)
440264fa531Smrg	    perror("shmctl rmid:");
441264fa531Smrg	return False;
442264fa531Smrg    }
443264fa531Smrg    shm_image.data = shm_info.shmaddr;
444264fa531Smrg    memmove( shm_image.data, image->data, image_size);
445264fa531Smrg    shm_image.obdata = (char *) &shm_info;
446264fa531Smrg    return reps;
447264fa531Smrg}
448264fa531Smrg
449e4ee1255Smrgint
450e4ee1255SmrgInitShmPutImage(XParms xp, Parms p, int reps)
451e4ee1255Smrg{
452e4ee1255Smrg    if (!InitShmImage(xp, p, reps, True)) return False;
453e4ee1255Smrg    XClearWindow(xp->d, xp->w);
454e4ee1255Smrg    return reps;
455e4ee1255Smrg}
456e4ee1255Smrg
457e4ee1255Smrgint
458e4ee1255SmrgInitShmGetImage(XParms xp, Parms p, int reps)
459e4ee1255Smrg{
460e4ee1255Smrg    return InitShmImage(xp, p, reps, False);
461e4ee1255Smrg}
462e4ee1255Smrg
463e4ee1255Smrgvoid
464264fa531SmrgDoShmPutImage(XParms xp, Parms p, int reps)
465264fa531Smrg{
466264fa531Smrg    int i, size;
467264fa531Smrg    XSegment *sa, *sb;
468264fa531Smrg
469264fa531Smrg    size = p->special;
470264fa531Smrg    for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
471264fa531Smrg	XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
472264fa531Smrg	    sa->x1, sa->y1, sa->x2, sa->y2, size, size, False);
473264fa531Smrg	XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
474264fa531Smrg	    sa->x2, sa->y2, sa->x1, sa->y1, size, size, False);
475264fa531Smrg	XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
476264fa531Smrg	    sb->x2, sb->y2, sb->x2, sb->y2, size, size, False);
477264fa531Smrg	XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
478264fa531Smrg	    sb->x1, sb->y1, sb->x2, sb->y2, size, size, False);
479264fa531Smrg	CheckAbort ();
480264fa531Smrg    }
481264fa531Smrg}
482264fa531Smrg
483e4ee1255Smrgvoid
484e4ee1255SmrgDoShmGetImage(XParms xp, Parms p, int reps)
485264fa531Smrg{
486e4ee1255Smrg    int i, size;
487e4ee1255Smrg    XSegment *sa, *sb;
488e4ee1255Smrg
489e4ee1255Smrg    size = p->special;
490e4ee1255Smrg
491e4ee1255Smrg    shm_image.width = size;
492e4ee1255Smrg    shm_image.height = size;
493e4ee1255Smrg
494e4ee1255Smrg    for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
495e4ee1255Smrg	/* compute offsets into image data? */
496e4ee1255Smrg	XShmGetImage(xp->d, xp->w, &shm_image, sa->x1, sa->y1, xp->planemask);
497e4ee1255Smrg	XShmGetImage(xp->d, xp->w, &shm_image, sa->x2, sa->y2, xp->planemask);
498e4ee1255Smrg	XShmGetImage(xp->d, xp->w, &shm_image, sb->x2, sb->y2, xp->planemask);
499e4ee1255Smrg	XShmGetImage(xp->d, xp->w, &shm_image, sb->x1, sb->y1, xp->planemask);
500e4ee1255Smrg	CheckAbort ();
501e4ee1255Smrg    }
502e4ee1255Smrg}
503264fa531Smrg
504e4ee1255Smrgstatic void
505e4ee1255SmrgEndShmImage(XParms xp, Parms p)
506e4ee1255Smrg{
507264fa531Smrg    EndGetImage (xp, p);
508264fa531Smrg    XShmDetach (xp->d, &shm_info);
509264fa531Smrg    XSync(xp->d, False);	/* need server to detach so can remove id */
510264fa531Smrg    if(shmdt (shm_info.shmaddr)==-1)
511264fa531Smrg	perror("shmdt:");
512c37a63b8Smrg    if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1)
513264fa531Smrg	perror("shmctl rmid:");
514264fa531Smrg}
515264fa531Smrg
516e4ee1255Smrgvoid
517e4ee1255SmrgEndShmGetImage(XParms xp, Parms p)
518e4ee1255Smrg{
519e4ee1255Smrg    EndShmImage(xp, p);
520e4ee1255Smrg}
521e4ee1255Smrg
522e4ee1255Smrgvoid
523e4ee1255SmrgEndShmPutImage(XParms xp, Parms p)
524e4ee1255Smrg{
525e4ee1255Smrg    EndShmImage(xp, p);
526e4ee1255Smrg}
527264fa531Smrg#endif
528264fa531Smrg
529264fa531Smrg
530264fa531Smrgvoid
531264fa531SmrgMidCopyPix(XParms xp, Parms p)
532264fa531Smrg{
533264fa531Smrg    XClearWindow(xp->d, xp->w);
534264fa531Smrg}
535264fa531Smrg
536264fa531Smrgvoid
537264fa531SmrgEndCopyWin(XParms xp, Parms p)
538264fa531Smrg{
539264fa531Smrg    EndScroll(xp, p);
540264fa531Smrg    free(segsa);
541264fa531Smrg    free(segsb);
542264fa531Smrg}
543264fa531Smrg
544264fa531Smrgvoid
545264fa531SmrgEndCopyPix(XParms xp, Parms p)
546264fa531Smrg{
547264fa531Smrg    EndCopyWin(xp, p);
548264fa531Smrg    XFreePixmap(xp->d, pix);
549264fa531Smrg    /*
550264fa531Smrg     * Ensure that the next test doesn't try and sync on the pixmap
551264fa531Smrg     */
552264fa531Smrg    xp->p = (Pixmap)0;
553264fa531Smrg}
554264fa531Smrg
555264fa531Smrgvoid
556264fa531SmrgEndGetImage(XParms xp, Parms p)
557264fa531Smrg{
558264fa531Smrg    EndCopyWin(xp, p);
559264fa531Smrg    if (image) XDestroyImage(image);
560264fa531Smrg}
561264fa531Smrg
562264fa531Smrgint
563264fa531SmrgInitCopyPlane(XParms xp, Parms p, int reps)
564264fa531Smrg{
565264fa531Smrg    XGCValues   gcv;
566264fa531Smrg    GC		pixgc;
567264fa531Smrg
568264fa531Smrg    InitBltLines();
569264fa531Smrg    InitCopyLocations(xp, p, reps);
570264fa531Smrg
571264fa531Smrg    /* Create pixmap to write stuff into, and initialize it */
572264fa531Smrg    pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT,
573c37a63b8Smrg	    p->font==NULL ? 1 : xp->vinfo.depth);
574264fa531Smrg    gcv.graphics_exposures = False;
575264fa531Smrg    gcv.foreground = 0;
576264fa531Smrg    gcv.background = 1;
577264fa531Smrg    pixgc = XCreateGC(xp->d, pix,
578264fa531Smrg		GCForeground | GCBackground | GCGraphicsExposures, &gcv);
579264fa531Smrg    XFillRectangle(xp->d, pix, pixgc, 0, 0, WIDTH, HEIGHT);
580264fa531Smrg    gcv.foreground = 1;
581264fa531Smrg    gcv.background = 0;
582264fa531Smrg    XChangeGC(xp->d, pixgc, GCForeground | GCBackground, &gcv);
583264fa531Smrg    XDrawLines(xp->d, pix, pixgc, points, NUMPOINTS, CoordModeOrigin);
584264fa531Smrg    XFreeGC(xp->d, pixgc);
585264fa531Smrg
586264fa531Smrg    return reps;
587264fa531Smrg}
588264fa531Smrg
589264fa531Smrgvoid
590264fa531SmrgDoCopyPlane(XParms xp, Parms p, int reps)
591264fa531Smrg{
592264fa531Smrg    int		i, size;
593264fa531Smrg    XSegment    *sa, *sb;
594264fa531Smrg
595264fa531Smrg    size = p->special;
596264fa531Smrg    for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
597264fa531Smrg	XCopyPlane(xp->d, pix, xp->w, xp->fggc,
598264fa531Smrg	    sa->x1, sa->y1, size, size, sa->x2, sa->y2, 1);
599264fa531Smrg	XCopyPlane(xp->d, pix, xp->w, xp->fggc,
600264fa531Smrg	    sa->x2, sa->y2, size, size, sa->x1, sa->y1, 1);
601264fa531Smrg	XCopyPlane(xp->d, pix, xp->w, xp->fggc,
602264fa531Smrg	    sb->x2, sb->y2, size, size, sb->x1, sb->y1, 1);
603264fa531Smrg	XCopyPlane(xp->d, pix, xp->w, xp->fggc,
604264fa531Smrg	    sb->x1, sb->y1, size, size, sb->x2, sb->y2, 1);
605264fa531Smrg	CheckAbort ();
606264fa531Smrg    }
607264fa531Smrg}
608264fa531Smrg
609c37a63b8Smrg#include <X11/extensions/Xrender.h>
610c37a63b8Smrg
611c37a63b8Smrgstatic Picture	winPict, pixPict;
612c37a63b8Smrg
613c37a63b8Smrgint
614c37a63b8SmrgInitCompositeWin(XParms xp, Parms p, int reps)
615c37a63b8Smrg{
616c37a63b8Smrg    XRenderPictFormat	*format;
617c37a63b8Smrg    (void) InitScroll (xp, p, reps);
618c37a63b8Smrg    InitCopyLocations (xp, p, reps);
619c37a63b8Smrg    format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual);
620c37a63b8Smrg    winPict = XRenderCreatePicture (xp->d, xp->w, format, 0, NULL);
621c37a63b8Smrg    return reps;
622c37a63b8Smrg}
623c37a63b8Smrg
624c37a63b8Smrgint
625c37a63b8SmrgInitCompositePix(XParms xp, Parms p, int reps)
626c37a63b8Smrg{
627c37a63b8Smrg    XRenderPictFormat	*format = NULL;
628c37a63b8Smrg    int			depth;
629c37a63b8Smrg
630c37a63b8Smrg    (void) InitCompositeWin (xp, p, reps);
631c37a63b8Smrg
632c37a63b8Smrg    /* Create pixmap to write stuff into, and initialize it */
633c37a63b8Smrg    switch (xp->planemask) {
634c37a63b8Smrg    case PictStandardNative:
635c37a63b8Smrg	depth = xp->vinfo.depth;
636c37a63b8Smrg	format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual);
637c37a63b8Smrg	break;
638c37a63b8Smrg    case PictStandardRGB24:
639c37a63b8Smrg	depth = 24;
640c37a63b8Smrg	break;
641c37a63b8Smrg    case PictStandardARGB32:
642c37a63b8Smrg	depth = 32;
643c37a63b8Smrg	break;
644c37a63b8Smrg    case PictStandardA8:
645c37a63b8Smrg	depth = 8;
646c37a63b8Smrg	break;
647c37a63b8Smrg    case PictStandardA4:
648c37a63b8Smrg	depth = 4;
649c37a63b8Smrg	break;
650c37a63b8Smrg    case PictStandardA1:
651c37a63b8Smrg	depth = 1;
652c37a63b8Smrg	break;
653c37a63b8Smrg    default:
654c37a63b8Smrg	depth = 0;
655c37a63b8Smrg	break;
656c37a63b8Smrg    }
657c37a63b8Smrg    if (!format)
658c37a63b8Smrg	format = XRenderFindStandardFormat (xp->d, xp->planemask);
659c37a63b8Smrg
660c37a63b8Smrg    pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, depth);
661c37a63b8Smrg    pixPict = XRenderCreatePicture (xp->d, pix, format, 0, NULL);
662c37a63b8Smrg
663c37a63b8Smrg    XRenderComposite (xp->d, PictOpClear,
664c37a63b8Smrg		      winPict, None, pixPict,
665c37a63b8Smrg		      0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
666c37a63b8Smrg
667c37a63b8Smrg#if 1
668c37a63b8Smrg    XRenderComposite (xp->d, PictOpOver,
669c37a63b8Smrg		      winPict, None, pixPict,
670c37a63b8Smrg		      0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
671c37a63b8Smrg#endif
672c37a63b8Smrg    return reps;
673c37a63b8Smrg}
674c37a63b8Smrg
675c37a63b8Smrgvoid
676c37a63b8SmrgEndCompositeWin (XParms xp, Parms p)
677c37a63b8Smrg{
678c37a63b8Smrg    if (winPict)
679c37a63b8Smrg    {
680c37a63b8Smrg	XRenderFreePicture (xp->d, winPict);
681c37a63b8Smrg	winPict = None;
682c37a63b8Smrg    }
683c37a63b8Smrg    if (pixPict)
684c37a63b8Smrg    {
685c37a63b8Smrg	XRenderFreePicture (xp->d, pixPict);
686c37a63b8Smrg	pixPict = None;
687c37a63b8Smrg    }
688c37a63b8Smrg}
689c37a63b8Smrg
690c37a63b8Smrgstatic void
691c37a63b8SmrgCompositeArea(XParms xp, Parms p, int reps, Picture src, Picture dst)
692c37a63b8Smrg{
693c37a63b8Smrg    int i, size;
694c37a63b8Smrg    XSegment *sa, *sb;
695c37a63b8Smrg
696c37a63b8Smrg    size = p->special;
697c37a63b8Smrg    for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
698c37a63b8Smrg	XRenderComposite (xp->d, xp->func,
699c37a63b8Smrg			  src, None, dst,
700c37a63b8Smrg			  sa->x1, sa->y1, 0, 0,
701c37a63b8Smrg			  sa->x2, sa->y2, size, size);
702c37a63b8Smrg	XRenderComposite (xp->d, xp->func,
703c37a63b8Smrg			  src, None, dst,
704c37a63b8Smrg			  sa->x2, sa->y2, 0, 0, sa->x1, sa->y1, size, size);
705c37a63b8Smrg	XRenderComposite (xp->d, xp->func,
706c37a63b8Smrg			  src, None, dst,
707c37a63b8Smrg			  sb->x2, sb->y2, 0, 0, sb->x1, sb->y1, size, size);
708c37a63b8Smrg	XRenderComposite (xp->d, xp->func,
709c37a63b8Smrg			  src, None, dst,
710c37a63b8Smrg			  sb->x1, sb->y1, 0, 0, sb->x2, sb->y2, size, size);
711c37a63b8Smrg	CheckAbort ();
712c37a63b8Smrg    }
713c37a63b8Smrg}
714c37a63b8Smrg
715c37a63b8Smrgvoid
716c37a63b8SmrgDoCompositeWinWin (XParms xp, Parms p, int reps)
717c37a63b8Smrg{
718c37a63b8Smrg    CompositeArea (xp, p, reps, winPict, winPict);
719c37a63b8Smrg}
720c37a63b8Smrg
721c37a63b8Smrgvoid
722c37a63b8SmrgDoCompositePixWin (XParms xp, Parms p, int reps)
723c37a63b8Smrg{
724c37a63b8Smrg    CompositeArea (xp, p, reps, pixPict, winPict);
725c37a63b8Smrg}
726