#include "x11perf.h"
#include <stdio.h>
#define NUMPOINTS 100
static Pixmap pix;
static XImage *image;
static XPoint points[NUMPOINTS];
static XSegment *segsa, *segsb;
#define NegMod(x, y) ((y) - (((-x)-1) % (7)) - 1)
static void
InitBltLines(void)
{
int i, x, y;
points[0].x = points[0].y = y = 0;
for (i = 1; i != NUMPOINTS/2; i++) {
if (i & 1) {
points[i].x = WIDTH-1;
} else {
points[i].x = 0;
}
y += HEIGHT / (NUMPOINTS/2);
points[i].y = y;
}
x = 0;
for (i = NUMPOINTS/2; i!= NUMPOINTS; i++) {
if (i & 1) {
points[i].y = HEIGHT-1;
} else {
points[i].y = 0;
}
x += WIDTH / (NUMPOINTS/2);
points[i].x = x;
}
}
int
InitScroll(XParms xp, Parms p, int reps)
{
InitBltLines();
XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin);
return reps;
}
void
DoScroll(XParms xp, Parms p, int reps)
{
int i, size, x, y, xorg, yorg, delta;
size = p->special;
xorg = 0; yorg = 0;
x = 0; y = 0;
if (xp->version == VERSION1_2) {
delta = 1;
} else {
delta = 13;
}
for (i = 0; i != reps; i++) {
XCopyArea(xp->d, xp->w, xp->w, xp->fggc, x, y + delta,
size, size, x, y);
y += size;
if (y + size + delta > HEIGHT) {
yorg += delta;
if (yorg >= size || yorg + size + delta > HEIGHT) {
yorg = 0;
xorg++;
if (xorg >= size || xorg + size > WIDTH) {
xorg = 0;
}
}
y = yorg;
x += size;
if (x + size > WIDTH) {
x = xorg;
}
}
CheckAbort ();
}
}
void
MidScroll(XParms xp, Parms p)
{
XClearWindow(xp->d, xp->w);
XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin);
}
void
EndScroll(XParms xp, Parms p)
{
}
static void
InitCopyLocations(XParms xp, Parms p, int reps)
{
int x1, y1, x2, y2, size, i;
int xinc, yinc;
int width, height;
size = p->special;
xinc = (size & ~3) + 1;
yinc = xinc + 3;
width = (WIDTH - size) & ~31;
height = (HEIGHT - size) & ~31;
x1 = 0;
y1 = 0;
x2 = width;
y2 = height;
segsa = (XSegment *)malloc(reps * sizeof(XSegment));
segsb = (XSegment *)malloc(reps * sizeof(XSegment));
for (i = 0; i != reps; i++) {
segsa[i].x1 = x1;
segsa[i].y1 = y1;
segsa[i].x2 = x2;
segsa[i].y2 = y2;
x2 -= xinc;
if (x2 < 0) {
x2 = NegMod(x2, width);
y2 -= yinc;
if (y2 < 0) {
y2 = NegMod(y2, height);
}
}
segsb[i].x1 = x1;
segsb[i].y1 = y1;
segsb[i].x2 = x2;
segsb[i].y2 = y2;
x1 += xinc;
if (x1 > width) {
x1 %= 32;
y1 += yinc;
if (y1 > height) {
y1 %= 32;
}
}
}
}
int
InitCopyWin(XParms xp, Parms p, int reps)
{
(void) InitScroll(xp, p, reps);
InitCopyLocations(xp, p, reps);
return reps;
}
int
InitCopyPix(XParms xp, Parms p, int reps)
{
GC pixgc;
(void) InitCopyWin(xp, p, reps);
pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, xp->vinfo.depth);
pixgc = XCreateGC(xp->d, pix, 0, 0);
XCopyArea(xp->d, xp->w, pix, pixgc, 0, 0, WIDTH, HEIGHT, 0, 0);
XFreeGC(xp->d, pixgc);
return reps;
}
int
InitGetImage(XParms xp, Parms p, int reps)
{
(void) InitCopyWin(xp, p, reps);
image = XGetImage(xp->d, xp->w, 0, 0, WIDTH, HEIGHT, xp->planemask,
p->font==0?ZPixmap:XYPixmap);
if(image==0){
printf("XGetImage failed\n");
return False;
}
return reps;
}
int
InitPutImage(XParms xp, Parms p, int reps)
{
if(!InitGetImage(xp, p, reps))return False;
XClearWindow(xp->d, xp->w);
return reps;
}
static void
CopyArea(XParms xp, Parms p, int reps, Drawable src, Drawable dst)
{
int i, size;
XSegment *sa, *sb;
size = p->special;
for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
XCopyArea(xp->d, src, dst, xp->fggc,
sa->x1, sa->y1, size, size, sa->x2, sa->y2);
XCopyArea(xp->d, src, dst, xp->fggc,
sa->x2, sa->y2, size, size, sa->x1, sa->y1);
XCopyArea(xp->d, src, dst, xp->fggc,
sb->x2, sb->y2, size, size, sb->x1, sb->y1);
XCopyArea(xp->d, src, dst, xp->fggc,
sb->x1, sb->y1, size, size, sb->x2, sb->y2);
CheckAbort ();
}
}
void
DoCopyWinWin(XParms xp, Parms p, int reps)
{
CopyArea(xp, p, reps, xp->w, xp->w);
}
void
DoCopyPixWin(XParms xp, Parms p, int reps)
{
CopyArea(xp, p, reps, pix, xp->w);
}
void
DoCopyWinPix(XParms xp, Parms p, int reps)
{
CopyArea(xp, p, reps, xp->w, pix);
xp->p = pix;
}
void
DoCopyPixPix(XParms xp, Parms p, int reps)
{
CopyArea(xp, p, reps, pix, pix);
xp->p = pix;
}
void
DoGetImage(XParms xp, Parms p, int reps)
{
int i, size;
XSegment *sa, *sb;
int format;
size = p->special;
format = (p->font == 0) ? ZPixmap : XYPixmap;
for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
XDestroyImage(image);
image = XGetImage(xp->d, xp->w, sa->x1, sa->y1, size, size,
xp->planemask, format);
if (image) XDestroyImage(image);
image = XGetImage(xp->d, xp->w, sa->x2, sa->y2, size, size,
xp->planemask, format);
if (image) XDestroyImage(image);
image = XGetImage(xp->d, xp->w, sb->x2, sb->y2, size, size,
xp->planemask, format);
if (image) XDestroyImage(image);
image = XGetImage(xp->d, xp->w, sb->x1, sb->y1, size, size,
xp->planemask, format);
CheckAbort ();
}
}
void
DoPutImage(XParms xp, Parms p, int reps)
{
int i, size;
XSegment *sa, *sb;
size = p->special;
for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
XPutImage(xp->d, xp->w, xp->fggc, image,
sa->x1, sa->y1, sa->x2, sa->y2, size, size);
XPutImage(xp->d, xp->w, xp->fggc, image,
sa->x2, sa->y2, sa->x1, sa->y1, size, size);
XPutImage(xp->d, xp->w, xp->fggc, image,
sb->x2, sb->y2, sb->x2, sb->y2, size, size);
XPutImage(xp->d, xp->w, xp->fggc, image,
sb->x1, sb->y1, sb->x2, sb->y2, size, size);
CheckAbort ();
}
}
#ifdef MITSHM
#include <sys/types.h>
#ifndef Lynx
#include <sys/ipc.h>
#include <sys/shm.h>
#else
#include <ipc.h>
#include <shm.h>
#endif
#include <X11/extensions/XShm.h>
static XImage shm_image;
static XShmSegmentInfo shm_info;
static int haderror;
static int (*origerrorhandler)(Display *, XErrorEvent *);
static int
shmerrorhandler(Display *d, XErrorEvent *e)
{
haderror++;
if(e->error_code==BadAccess) {
fprintf(stderr,"failed to attach shared memory\n");
return 0;
} else
return (*origerrorhandler)(d,e);
}
int
InitShmPutImage(XParms xp, Parms p, int reps)
{
int image_size;
if(!InitGetImage(xp, p, reps))return False;
if (!XShmQueryExtension(xp->d)) {
if (image)
XDestroyImage(image);
image = NULL;
free(segsa);
free(segsb);
return False;
}
XClearWindow(xp->d, xp->w);
shm_image = *image;
image_size = image->bytes_per_line * image->height;
if(p->font)image_size *= xp->vinfo.depth;
shm_info.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777);
if (shm_info.shmid < 0)
{
if (image)
XDestroyImage(image);
image = NULL;
free(segsa);
free(segsb);
perror ("shmget");
return False;
}
shm_info.shmaddr = (char *) shmat(shm_info.shmid, 0, 0);
if (shm_info.shmaddr == ((char *) -1))
{
if (image)
XDestroyImage(image);
image = NULL;
free(segsa);
free(segsb);
perror ("shmat");
shmctl (shm_info.shmid, IPC_RMID, 0);
return False;
}
shm_info.readOnly = True;
XSync(xp->d,True);
haderror = False;
origerrorhandler = XSetErrorHandler(shmerrorhandler);
XShmAttach (xp->d, &shm_info);
XSync(xp->d,True);
XSetErrorHandler(origerrorhandler);
if(haderror){
if (image)
XDestroyImage(image);
image = NULL;
free(segsa);
free(segsb);
if(shmdt (shm_info.shmaddr)==-1)
perror("shmdt:");
if(shmctl (shm_info.shmid, IPC_RMID, 0)==-1)
perror("shmctl rmid:");
return False;
}
shm_image.data = shm_info.shmaddr;
memmove( shm_image.data, image->data, image_size);
shm_image.obdata = (char *) &shm_info;
return reps;
}
void
DoShmPutImage(XParms xp, Parms p, int reps)
{
int i, size;
XSegment *sa, *sb;
size = p->special;
for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
sa->x1, sa->y1, sa->x2, sa->y2, size, size, False);
XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
sa->x2, sa->y2, sa->x1, sa->y1, size, size, False);
XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
sb->x2, sb->y2, sb->x2, sb->y2, size, size, False);
XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
sb->x1, sb->y1, sb->x2, sb->y2, size, size, False);
CheckAbort ();
}
}
void
EndShmPutImage(XParms xp, Parms p)
{
EndGetImage (xp, p);
XShmDetach (xp->d, &shm_info);
XSync(xp->d, False);
if(shmdt (shm_info.shmaddr)==-1)
perror("shmdt:");
if(shmctl (shm_info.shmid, IPC_RMID, 0)==-1)
perror("shmctl rmid:");
}
#endif
void
MidCopyPix(XParms xp, Parms p)
{
XClearWindow(xp->d, xp->w);
}
void
EndCopyWin(XParms xp, Parms p)
{
EndScroll(xp, p);
free(segsa);
free(segsb);
}
void
EndCopyPix(XParms xp, Parms p)
{
EndCopyWin(xp, p);
XFreePixmap(xp->d, pix);
xp->p = (Pixmap)0;
}
void
EndGetImage(XParms xp, Parms p)
{
EndCopyWin(xp, p);
if (image) XDestroyImage(image);
}
int
InitCopyPlane(XParms xp, Parms p, int reps)
{
XGCValues gcv;
GC pixgc;
InitBltLines();
InitCopyLocations(xp, p, reps);
pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT,
p->font==0 ? 1 : xp->vinfo.depth);
gcv.graphics_exposures = False;
gcv.foreground = 0;
gcv.background = 1;
pixgc = XCreateGC(xp->d, pix,
GCForeground | GCBackground | GCGraphicsExposures, &gcv);
XFillRectangle(xp->d, pix, pixgc, 0, 0, WIDTH, HEIGHT);
gcv.foreground = 1;
gcv.background = 0;
XChangeGC(xp->d, pixgc, GCForeground | GCBackground, &gcv);
XDrawLines(xp->d, pix, pixgc, points, NUMPOINTS, CoordModeOrigin);
XFreeGC(xp->d, pixgc);
return reps;
}
void
DoCopyPlane(XParms xp, Parms p, int reps)
{
int i, size;
XSegment *sa, *sb;
size = p->special;
for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
XCopyPlane(xp->d, pix, xp->w, xp->fggc,
sa->x1, sa->y1, size, size, sa->x2, sa->y2, 1);
XCopyPlane(xp->d, pix, xp->w, xp->fggc,
sa->x2, sa->y2, size, size, sa->x1, sa->y1, 1);
XCopyPlane(xp->d, pix, xp->w, xp->fggc,
sb->x2, sb->y2, size, size, sb->x1, sb->y1, 1);
XCopyPlane(xp->d, pix, xp->w, xp->fggc,
sb->x1, sb->y1, size, size, sb->x2, sb->y2, 1);
CheckAbort ();
}
}