1264fa531Smrg/***************************************************************************** 2264fa531SmrgCopyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 3264fa531Smrg 4264fa531Smrg All Rights Reserved 5264fa531Smrg 6dfac8f13SmrgPermission to use, copy, modify, and distribute this software and its 7dfac8f13Smrgdocumentation for any purpose and without fee is hereby granted, 8264fa531Smrgprovided that the above copyright notice appear in all copies and that 9dfac8f13Smrgboth 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 12dfac8f13Smrgsoftware 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; 33533545b5Smrgstatic XSegment *segsa2, *segsb2; 34264fa531Smrg 35264fa531Smrg#define NegMod(x, y) ((y) - (((-x)-1) % (7)) - 1) 36264fa531Smrg 37dfac8f13Smrgstatic void 38264fa531SmrgInitBltLines(void) 39264fa531Smrg{ 40c9e4df9bSmrg int x, y; 41264fa531Smrg 42264fa531Smrg points[0].x = points[0].y = y = 0; 43c9e4df9bSmrg for (int i = 1; i != NUMPOINTS/2; i++) { 44264fa531Smrg if (i & 1) { 45264fa531Smrg points[i].x = WIDTH-1; 46264fa531Smrg } else { 47264fa531Smrg points[i].x = 0; 48264fa531Smrg } 49264fa531Smrg y += HEIGHT / (NUMPOINTS/2); 50264fa531Smrg points[i].y = y; 51264fa531Smrg } 52dfac8f13Smrg 53264fa531Smrg x = 0; 54c9e4df9bSmrg for (int i = NUMPOINTS/2; i!= NUMPOINTS; i++) { 55264fa531Smrg if (i & 1) { 56264fa531Smrg points[i].y = HEIGHT-1; 57264fa531Smrg } else { 58264fa531Smrg points[i].y = 0; 59264fa531Smrg } 60264fa531Smrg x += WIDTH / (NUMPOINTS/2); 61264fa531Smrg points[i].x = x; 62264fa531Smrg } 63264fa531Smrg} 64264fa531Smrg 65dfac8f13Smrgint 66533545b5SmrgInitScroll(XParms xp, Parms p, int64_t reps) 67264fa531Smrg{ 68264fa531Smrg InitBltLines(); 69dfac8f13Smrg XSetFunction(xp->d, xp->fggc, GXcopy); 70264fa531Smrg XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin); 71dfac8f13Smrg XSetFunction(xp->d, xp->fggc, xp->func); 72264fa531Smrg return reps; 73264fa531Smrg} 74264fa531Smrg 75dfac8f13Smrgvoid 76533545b5SmrgDoScroll(XParms xp, Parms p, int64_t reps) 77264fa531Smrg{ 78c9e4df9bSmrg int size, x, y, xorg, yorg, delta; 79264fa531Smrg 80264fa531Smrg size = p->special; 81264fa531Smrg xorg = 0; yorg = 0; 82264fa531Smrg x = 0; y = 0; 83264fa531Smrg if (xp->version == VERSION1_2) { 84264fa531Smrg delta = 1; 85264fa531Smrg } else { 86264fa531Smrg /* Version 1.2 only scrolled up by 1 scanline, which made hardware 87264fa531Smrg using page-mode access to VRAM look better on paper than it would 88264fa531Smrg perform in a more realistic scroll. So we've changed to scroll by 89264fa531Smrg the height of the 6x13 fonts. */ 90264fa531Smrg delta = 13; 91264fa531Smrg } 92264fa531Smrg 93c9e4df9bSmrg for (int i = 0; i != reps; i++) { 94264fa531Smrg XCopyArea(xp->d, xp->w, xp->w, xp->fggc, x, y + delta, 95264fa531Smrg size, size, x, y); 96264fa531Smrg y += size; 97264fa531Smrg if (y + size + delta > HEIGHT) { 98264fa531Smrg yorg += delta; 99264fa531Smrg if (yorg >= size || yorg + size + delta > HEIGHT) { 100264fa531Smrg yorg = 0; 101264fa531Smrg xorg++; 102264fa531Smrg if (xorg >= size || xorg + size > WIDTH) { 103264fa531Smrg xorg = 0; 104264fa531Smrg } 105264fa531Smrg } 106264fa531Smrg y = yorg; 107264fa531Smrg x += size; 108264fa531Smrg if (x + size > WIDTH) { 109264fa531Smrg x = xorg; 110264fa531Smrg } 111264fa531Smrg } 112264fa531Smrg CheckAbort (); 113264fa531Smrg } 114264fa531Smrg} 115264fa531Smrg 116dfac8f13Smrgvoid 117264fa531SmrgMidScroll(XParms xp, Parms p) 118264fa531Smrg{ 119264fa531Smrg XClearWindow(xp->d, xp->w); 120264fa531Smrg XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin); 121264fa531Smrg} 122264fa531Smrg 123dfac8f13Smrgvoid 124264fa531SmrgEndScroll(XParms xp, Parms p) 125264fa531Smrg{ 126264fa531Smrg} 127264fa531Smrg 128dfac8f13Smrgstatic void 129dfac8f13SmrgInitCopyLocations(int size, int mul, int div, 130533545b5Smrg int64_t reps, XSegment **ap, XSegment **bp) 131264fa531Smrg{ 132c9e4df9bSmrg int x1, y1, x2, y2; 133264fa531Smrg int xinc, yinc; 134264fa531Smrg int width, height; 135533545b5Smrg XSegment *a, *b; 136264fa531Smrg 137533545b5Smrg size = size * mul / div; 138264fa531Smrg /* Try to exercise all alignments of src and destination equally, as well 139264fa531Smrg as all 4 top-to-bottom/bottom-to-top, left-to-right, right-to-left 140264fa531Smrg copying directions. Computation done here just to make sure slow 141264fa531Smrg machines aren't measuring anything but the XCopyArea calls. 142264fa531Smrg */ 143264fa531Smrg xinc = (size & ~3) + 1; 144264fa531Smrg yinc = xinc + 3; 145264fa531Smrg 146264fa531Smrg width = (WIDTH - size) & ~31; 147264fa531Smrg height = (HEIGHT - size) & ~31; 148dfac8f13Smrg 149264fa531Smrg x1 = 0; 150264fa531Smrg y1 = 0; 151264fa531Smrg x2 = width; 152264fa531Smrg y2 = height; 153dfac8f13Smrg 154c9e4df9bSmrg *ap = a = malloc(reps * sizeof(XSegment)); 155c9e4df9bSmrg *bp = b = malloc(reps * sizeof(XSegment)); 156c9e4df9bSmrg for (int i = 0; i != reps; i++) { 157533545b5Smrg a[i].x1 = x1 * div / mul; 158533545b5Smrg a[i].y1 = y1 * div / mul; 159533545b5Smrg a[i].x2 = x2 * div / mul; 160533545b5Smrg a[i].y2 = y2 * div / mul; 161264fa531Smrg 162264fa531Smrg /* Move x2, y2, location backward */ 163264fa531Smrg x2 -= xinc; 164264fa531Smrg if (x2 < 0) { 165264fa531Smrg x2 = NegMod(x2, width); 166264fa531Smrg y2 -= yinc; 167264fa531Smrg if (y2 < 0) { 168264fa531Smrg y2 = NegMod(y2, height); 169264fa531Smrg } 170264fa531Smrg } 171264fa531Smrg 172533545b5Smrg b[i].x1 = x1 * div / mul; 173533545b5Smrg b[i].y1 = y1 * div / mul; 174533545b5Smrg b[i].x2 = x2 * div / mul; 175533545b5Smrg b[i].y2 = y2 * div / mul; 176264fa531Smrg 177264fa531Smrg /* Move x1, y1 location forward */ 178264fa531Smrg x1 += xinc; 179264fa531Smrg if (x1 > width) { 180264fa531Smrg x1 %= 32; 181264fa531Smrg y1 += yinc; 182264fa531Smrg if (y1 > height) { 183264fa531Smrg y1 %= 32; 184264fa531Smrg } 185264fa531Smrg } 186264fa531Smrg } /* end for */ 187264fa531Smrg} 188264fa531Smrg 189264fa531Smrg 190dfac8f13Smrgint 191533545b5SmrgInitCopyWin(XParms xp, Parms p, int64_t reps) 192264fa531Smrg{ 193264fa531Smrg (void) InitScroll(xp, p, reps); 194533545b5Smrg InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 195264fa531Smrg return reps; 196264fa531Smrg} 197264fa531Smrg 198dfac8f13Smrgint 199533545b5SmrgInitCopyPix(XParms xp, Parms p, int64_t reps) 200264fa531Smrg{ 201264fa531Smrg GC pixgc; 202264fa531Smrg (void) InitCopyWin(xp, p, reps); 203264fa531Smrg 204264fa531Smrg /* Create pixmap to write stuff into, and initialize it */ 205264fa531Smrg pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, xp->vinfo.depth); 206c37a63b8Smrg pixgc = XCreateGC(xp->d, pix, 0, NULL); 207264fa531Smrg /* need a gc with GXcopy cos pixmaps contain junk on creation. mmm */ 208264fa531Smrg XCopyArea(xp->d, xp->w, pix, pixgc, 0, 0, WIDTH, HEIGHT, 0, 0); 209264fa531Smrg XFreeGC(xp->d, pixgc); 210264fa531Smrg return reps; 211264fa531Smrg} 212264fa531Smrg 213dfac8f13Smrgstatic int 214dfac8f13SmrgInitImage(XParms xp, Parms p, int64_t reps, long pm) 215264fa531Smrg{ 216264fa531Smrg (void) InitCopyWin(xp, p, reps); 217264fa531Smrg 218264fa531Smrg /* Create image to stuff bits into */ 219dfac8f13Smrg image = XGetImage(xp->d, xp->w, 0, 0, WIDTH, HEIGHT, pm, 220dfac8f13Smrg p->font==NULL ? ZPixmap : (strcmp(p->font, "XY") == 0? XYPixmap : ZPixmap)); 221c37a63b8Smrg if(image==NULL){ 222264fa531Smrg printf("XGetImage failed\n"); 223264fa531Smrg return False; 224dfac8f13Smrg } 225dfac8f13Smrg if (p->font && !strcmp(p->font, "XYBitmap")) { 226dfac8f13Smrg int bytes_per_line = (WIDTH + 31) / 8; 227dfac8f13Smrg char *data = malloc (bytes_per_line * HEIGHT); 228dfac8f13Smrg XImage *new = XCreateImage(xp->d, xp->vinfo.visual, 1, XYBitmap, 0, 229dfac8f13Smrg data, WIDTH, HEIGHT, 32, bytes_per_line); 230dfac8f13Smrg int x, y; 231dfac8f13Smrg unsigned long zero_pixel; 232dfac8f13Smrg int has_zero = 0; 233dfac8f13Smrg 234dfac8f13Smrg for (y = 0; y < HEIGHT; y++) 235dfac8f13Smrg for (x = 0; x < WIDTH; x++) { 236dfac8f13Smrg unsigned long src_pixel = XGetPixel(image, x, y); 237dfac8f13Smrg unsigned long dst_pixel = 0; 238dfac8f13Smrg if (!has_zero) { 239dfac8f13Smrg zero_pixel = src_pixel; 240dfac8f13Smrg has_zero = 1; 241dfac8f13Smrg } 242dfac8f13Smrg if (src_pixel == zero_pixel) 243dfac8f13Smrg dst_pixel = 0; 244dfac8f13Smrg else 245dfac8f13Smrg dst_pixel = 1; 246dfac8f13Smrg XPutPixel(new, x, y, dst_pixel); 247dfac8f13Smrg } 248dfac8f13Smrg XDestroyImage(image); 249dfac8f13Smrg image = new; 250dfac8f13Smrg } 251264fa531Smrg return reps; 252264fa531Smrg} 253264fa531Smrg 254dfac8f13Smrgint 255dfac8f13SmrgInitGetImage(XParms xp, Parms p, int64_t reps) 256dfac8f13Smrg{ 257dfac8f13Smrg return InitImage(xp, p, reps, xp->planemask); 258dfac8f13Smrg} 259dfac8f13Smrg 260dfac8f13Smrgint 261533545b5SmrgInitPutImage(XParms xp, Parms p, int64_t reps) 262264fa531Smrg{ 263dfac8f13Smrg if(!InitImage(xp, p, reps, 0xffffffff))return False; 264264fa531Smrg XClearWindow(xp->d, xp->w); 265264fa531Smrg return reps; 266264fa531Smrg} 267264fa531Smrg 268dfac8f13Smrgstatic void 269533545b5SmrgCopyArea(XParms xp, Parms p, int64_t reps, Drawable src, Drawable dst) 270264fa531Smrg{ 271264fa531Smrg int i, size; 272264fa531Smrg XSegment *sa, *sb; 273264fa531Smrg 274264fa531Smrg size = p->special; 275264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 276264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 277264fa531Smrg sa->x1, sa->y1, size, size, sa->x2, sa->y2); 278264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 279264fa531Smrg sa->x2, sa->y2, size, size, sa->x1, sa->y1); 280264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 281264fa531Smrg sb->x2, sb->y2, size, size, sb->x1, sb->y1); 282264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 283264fa531Smrg sb->x1, sb->y1, size, size, sb->x2, sb->y2); 284264fa531Smrg CheckAbort (); 285264fa531Smrg } 286264fa531Smrg} 287264fa531Smrg 288dfac8f13Smrgvoid 289533545b5SmrgDoCopyWinWin(XParms xp, Parms p, int64_t reps) 290264fa531Smrg{ 291264fa531Smrg CopyArea(xp, p, reps, xp->w, xp->w); 292264fa531Smrg} 293264fa531Smrg 294dfac8f13Smrgvoid 295533545b5SmrgDoCopyPixWin(XParms xp, Parms p, int64_t reps) 296264fa531Smrg{ 297264fa531Smrg CopyArea(xp, p, reps, pix, xp->w); 298264fa531Smrg} 299264fa531Smrg 300dfac8f13Smrgvoid 301533545b5SmrgDoCopyWinPix(XParms xp, Parms p, int64_t reps) 302264fa531Smrg{ 303264fa531Smrg CopyArea(xp, p, reps, xp->w, pix); 304264fa531Smrg xp->p = pix; /* HardwareSync will now sync on pixmap */ 305264fa531Smrg} 306264fa531Smrg 307dfac8f13Smrgvoid 308533545b5SmrgDoCopyPixPix(XParms xp, Parms p, int64_t reps) 309264fa531Smrg{ 310264fa531Smrg CopyArea(xp, p, reps, pix, pix); 311264fa531Smrg xp->p = pix; /* HardwareSync will now sync on pixmap */ 312264fa531Smrg} 313264fa531Smrg 314dfac8f13Smrgvoid 315533545b5SmrgDoGetImage(XParms xp, Parms p, int64_t reps) 316264fa531Smrg{ 317264fa531Smrg int i, size; 318264fa531Smrg XSegment *sa, *sb; 319264fa531Smrg int format; 320264fa531Smrg 321264fa531Smrg size = p->special; 322c37a63b8Smrg format = (p->font == NULL) ? ZPixmap : XYPixmap; 323264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 324264fa531Smrg XDestroyImage(image); 325264fa531Smrg image = XGetImage(xp->d, xp->w, sa->x1, sa->y1, size, size, 326264fa531Smrg xp->planemask, format); 327264fa531Smrg if (image) XDestroyImage(image); 328264fa531Smrg image = XGetImage(xp->d, xp->w, sa->x2, sa->y2, size, size, 329264fa531Smrg xp->planemask, format); 330264fa531Smrg if (image) XDestroyImage(image); 331264fa531Smrg image = XGetImage(xp->d, xp->w, sb->x2, sb->y2, size, size, 332264fa531Smrg xp->planemask, format); 333264fa531Smrg if (image) XDestroyImage(image); 334264fa531Smrg image = XGetImage(xp->d, xp->w, sb->x1, sb->y1, size, size, 335264fa531Smrg xp->planemask, format); 336264fa531Smrg/* 337264fa531Smrg 338264fa531SmrgOne might expect XGetSubImage to be slightly faster than XGetImage. Go look 339264fa531Smrgat the code in Xlib. MIT X11R3 ran approximately 30 times slower for a 500x500 340264fa531Smrgrectangle. 341264fa531Smrg 342264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sa->x1, sa->y1, size, size, 343264fa531Smrg xp->planemask, ZPixmap, image, sa->x2, sa->y2); 344264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sa->x2, sa->y2, size, size, 345264fa531Smrg xp->planemask, ZPixmap, image, sa->x1, sa->y1); 346264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sb->x2, sb->y2, size, size, 347264fa531Smrg xp->planemask, ZPixmap, image, sb->x2, sb->y2); 348264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sb->x1, sb->y1, size, size, 349264fa531Smrg xp->planemask, ZPixmap, image, sb->x2, sb->y2); 350264fa531Smrg*/ 351264fa531Smrg CheckAbort (); 352264fa531Smrg } 353264fa531Smrg} 354264fa531Smrg 355dfac8f13Smrgvoid 356533545b5SmrgDoPutImage(XParms xp, Parms p, int64_t reps) 357264fa531Smrg{ 358264fa531Smrg int i, size; 359264fa531Smrg XSegment *sa, *sb; 360264fa531Smrg 361264fa531Smrg size = p->special; 362264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 363264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 364264fa531Smrg sa->x1, sa->y1, sa->x2, sa->y2, size, size); 365264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 366264fa531Smrg sa->x2, sa->y2, sa->x1, sa->y1, size, size); 367264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 368264fa531Smrg sb->x2, sb->y2, sb->x2, sb->y2, size, size); 369264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 370264fa531Smrg sb->x1, sb->y1, sb->x2, sb->y2, size, size); 371264fa531Smrg CheckAbort (); 372264fa531Smrg } 373264fa531Smrg} 374264fa531Smrg 375264fa531Smrg#ifdef MITSHM 376264fa531Smrg 377264fa531Smrg#include <sys/types.h> 378264fa531Smrg#ifndef Lynx 379264fa531Smrg#include <sys/ipc.h> 380264fa531Smrg#include <sys/shm.h> 381264fa531Smrg#else 382264fa531Smrg#include <ipc.h> 383264fa531Smrg#include <shm.h> 384264fa531Smrg#endif 385264fa531Smrg#include <X11/extensions/XShm.h> 386264fa531Smrg 387264fa531Smrgstatic XImage shm_image; 388264fa531Smrgstatic XShmSegmentInfo shm_info; 389264fa531Smrg 390264fa531Smrgstatic int haderror; 391264fa531Smrgstatic int (*origerrorhandler)(Display *, XErrorEvent *); 392264fa531Smrg 393dfac8f13Smrgstatic int 394264fa531Smrgshmerrorhandler(Display *d, XErrorEvent *e) 395264fa531Smrg{ 396264fa531Smrg haderror++; 397264fa531Smrg if(e->error_code==BadAccess) { 398264fa531Smrg fprintf(stderr,"failed to attach shared memory\n"); 399264fa531Smrg return 0; 400dfac8f13Smrg } else 401264fa531Smrg return (*origerrorhandler)(d,e); 402264fa531Smrg} 403264fa531Smrg 404e4ee1255Smrgstatic int 405533545b5SmrgInitShmImage(XParms xp, Parms p, int64_t reps, Bool read_only) 406264fa531Smrg{ 407264fa531Smrg int image_size; 408264fa531Smrg 409dfac8f13Smrg if(!InitImage(xp, p, reps, 0xffffffff))return False; 410264fa531Smrg if (!XShmQueryExtension(xp->d)) { 411264fa531Smrg /* 412264fa531Smrg * Clean up here because cleanup function is not called if this 413264fa531Smrg * function fails 414264fa531Smrg */ 415264fa531Smrg if (image) 416264fa531Smrg XDestroyImage(image); 417264fa531Smrg image = NULL; 418264fa531Smrg free(segsa); 419264fa531Smrg free(segsb); 420264fa531Smrg return False; 421dfac8f13Smrg } 422264fa531Smrg shm_image = *image; 423264fa531Smrg image_size = image->bytes_per_line * image->height; 424264fa531Smrg /* allow XYPixmap choice: */ 425dfac8f13Smrg if(p->font && strcmp(p->font, "XYBitmap") != 0) image_size *= xp->vinfo.depth; 426264fa531Smrg shm_info.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777); 427264fa531Smrg if (shm_info.shmid < 0) 428264fa531Smrg { 429264fa531Smrg /* 430264fa531Smrg * Clean up here because cleanup function is not called if this 431264fa531Smrg * function fails 432264fa531Smrg */ 433264fa531Smrg if (image) 434264fa531Smrg XDestroyImage(image); 435264fa531Smrg image = NULL; 436264fa531Smrg free(segsa); 437264fa531Smrg free(segsb); 438264fa531Smrg perror ("shmget"); 439264fa531Smrg return False; 440264fa531Smrg } 441c37a63b8Smrg shm_info.shmaddr = (char *) shmat(shm_info.shmid, NULL, 0); 442264fa531Smrg if (shm_info.shmaddr == ((char *) -1)) 443264fa531Smrg { 444264fa531Smrg /* 445264fa531Smrg * Clean up here because cleanup function is not called if this 446264fa531Smrg * function fails 447264fa531Smrg */ 448264fa531Smrg if (image) 449264fa531Smrg XDestroyImage(image); 450264fa531Smrg image = NULL; 451264fa531Smrg free(segsa); 452264fa531Smrg free(segsb); 453264fa531Smrg perror ("shmat"); 454c37a63b8Smrg shmctl (shm_info.shmid, IPC_RMID, NULL); 455264fa531Smrg return False; 456264fa531Smrg } 457e4ee1255Smrg shm_info.readOnly = read_only; 458264fa531Smrg XSync(xp->d,True); 459264fa531Smrg haderror = False; 460264fa531Smrg origerrorhandler = XSetErrorHandler(shmerrorhandler); 461264fa531Smrg XShmAttach (xp->d, &shm_info); 462264fa531Smrg XSync(xp->d,True); /* wait for error or ok */ 463264fa531Smrg XSetErrorHandler(origerrorhandler); 464264fa531Smrg if(haderror){ 465264fa531Smrg /* 466264fa531Smrg * Clean up here because cleanup function is not called if this 467264fa531Smrg * function fails 468264fa531Smrg */ 469264fa531Smrg if (image) 470264fa531Smrg XDestroyImage(image); 471264fa531Smrg image = NULL; 472264fa531Smrg free(segsa); 473264fa531Smrg free(segsb); 474264fa531Smrg if(shmdt (shm_info.shmaddr)==-1) 475264fa531Smrg perror("shmdt:"); 476c37a63b8Smrg if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1) 477264fa531Smrg perror("shmctl rmid:"); 478264fa531Smrg return False; 479264fa531Smrg } 480264fa531Smrg shm_image.data = shm_info.shmaddr; 481264fa531Smrg memmove( shm_image.data, image->data, image_size); 482264fa531Smrg shm_image.obdata = (char *) &shm_info; 483264fa531Smrg return reps; 484264fa531Smrg} 485264fa531Smrg 486e4ee1255Smrgint 487533545b5SmrgInitShmPutImage(XParms xp, Parms p, int64_t reps) 488e4ee1255Smrg{ 489e4ee1255Smrg if (!InitShmImage(xp, p, reps, True)) return False; 490e4ee1255Smrg XClearWindow(xp->d, xp->w); 491e4ee1255Smrg return reps; 492e4ee1255Smrg} 493e4ee1255Smrg 494e4ee1255Smrgint 495533545b5SmrgInitShmGetImage(XParms xp, Parms p, int64_t reps) 496e4ee1255Smrg{ 497e4ee1255Smrg return InitShmImage(xp, p, reps, False); 498e4ee1255Smrg} 499e4ee1255Smrg 500dfac8f13Smrgvoid 501533545b5SmrgDoShmPutImage(XParms xp, Parms p, int64_t reps) 502264fa531Smrg{ 503264fa531Smrg int i, size; 504264fa531Smrg XSegment *sa, *sb; 505264fa531Smrg 506264fa531Smrg size = p->special; 507264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 508264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 509264fa531Smrg sa->x1, sa->y1, sa->x2, sa->y2, size, size, False); 510264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 511264fa531Smrg sa->x2, sa->y2, sa->x1, sa->y1, size, size, False); 512264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 513264fa531Smrg sb->x2, sb->y2, sb->x2, sb->y2, size, size, False); 514264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 515264fa531Smrg sb->x1, sb->y1, sb->x2, sb->y2, size, size, False); 516264fa531Smrg CheckAbort (); 517264fa531Smrg } 518264fa531Smrg} 519264fa531Smrg 520e4ee1255Smrgvoid 521533545b5SmrgDoShmGetImage(XParms xp, Parms p, int64_t reps) 522264fa531Smrg{ 523e4ee1255Smrg int i, size; 524e4ee1255Smrg XSegment *sa, *sb; 525e4ee1255Smrg 526e4ee1255Smrg size = p->special; 527e4ee1255Smrg 528e4ee1255Smrg shm_image.width = size; 529e4ee1255Smrg shm_image.height = size; 530e4ee1255Smrg 531e4ee1255Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 532e4ee1255Smrg /* compute offsets into image data? */ 533e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sa->x1, sa->y1, xp->planemask); 534e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sa->x2, sa->y2, xp->planemask); 535e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sb->x2, sb->y2, xp->planemask); 536e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sb->x1, sb->y1, xp->planemask); 537e4ee1255Smrg CheckAbort (); 538e4ee1255Smrg } 539e4ee1255Smrg} 540264fa531Smrg 541e4ee1255Smrgstatic void 542e4ee1255SmrgEndShmImage(XParms xp, Parms p) 543e4ee1255Smrg{ 544264fa531Smrg EndGetImage (xp, p); 545264fa531Smrg XShmDetach (xp->d, &shm_info); 546264fa531Smrg XSync(xp->d, False); /* need server to detach so can remove id */ 547264fa531Smrg if(shmdt (shm_info.shmaddr)==-1) 548264fa531Smrg perror("shmdt:"); 549c37a63b8Smrg if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1) 550264fa531Smrg perror("shmctl rmid:"); 551264fa531Smrg} 552264fa531Smrg 553e4ee1255Smrgvoid 554e4ee1255SmrgEndShmGetImage(XParms xp, Parms p) 555e4ee1255Smrg{ 556e4ee1255Smrg EndShmImage(xp, p); 557e4ee1255Smrg} 558e4ee1255Smrg 559e4ee1255Smrgvoid 560e4ee1255SmrgEndShmPutImage(XParms xp, Parms p) 561e4ee1255Smrg{ 562e4ee1255Smrg EndShmImage(xp, p); 563e4ee1255Smrg} 564264fa531Smrg#endif 565264fa531Smrg 566264fa531Smrg 567dfac8f13Smrgvoid 568264fa531SmrgMidCopyPix(XParms xp, Parms p) 569264fa531Smrg{ 570264fa531Smrg XClearWindow(xp->d, xp->w); 571264fa531Smrg} 572264fa531Smrg 573dfac8f13Smrgvoid 574264fa531SmrgEndCopyWin(XParms xp, Parms p) 575264fa531Smrg{ 576264fa531Smrg EndScroll(xp, p); 577264fa531Smrg free(segsa); 578264fa531Smrg free(segsb); 579533545b5Smrg if (segsa2) 580533545b5Smrg free (segsa2); 581533545b5Smrg if (segsb2) 582533545b5Smrg free (segsb2); 583533545b5Smrg segsa = segsb = segsa2 = segsb2 = NULL; 584264fa531Smrg} 585264fa531Smrg 586dfac8f13Smrgvoid 587264fa531SmrgEndCopyPix(XParms xp, Parms p) 588264fa531Smrg{ 589264fa531Smrg EndCopyWin(xp, p); 590264fa531Smrg XFreePixmap(xp->d, pix); 591264fa531Smrg /* 592264fa531Smrg * Ensure that the next test doesn't try and sync on the pixmap 593264fa531Smrg */ 594264fa531Smrg xp->p = (Pixmap)0; 595264fa531Smrg} 596264fa531Smrg 597dfac8f13Smrgvoid 598264fa531SmrgEndGetImage(XParms xp, Parms p) 599264fa531Smrg{ 600264fa531Smrg EndCopyWin(xp, p); 601264fa531Smrg if (image) XDestroyImage(image); 602264fa531Smrg} 603264fa531Smrg 604264fa531Smrgint 605533545b5SmrgInitCopyPlane(XParms xp, Parms p, int64_t reps) 606264fa531Smrg{ 607264fa531Smrg XGCValues gcv; 608264fa531Smrg GC pixgc; 609264fa531Smrg 610264fa531Smrg InitBltLines(); 611533545b5Smrg InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 612264fa531Smrg 613264fa531Smrg /* Create pixmap to write stuff into, and initialize it */ 614dfac8f13Smrg pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, 615c37a63b8Smrg p->font==NULL ? 1 : xp->vinfo.depth); 616264fa531Smrg gcv.graphics_exposures = False; 617264fa531Smrg gcv.foreground = 0; 618264fa531Smrg gcv.background = 1; 619dfac8f13Smrg pixgc = XCreateGC(xp->d, pix, 620264fa531Smrg GCForeground | GCBackground | GCGraphicsExposures, &gcv); 621264fa531Smrg XFillRectangle(xp->d, pix, pixgc, 0, 0, WIDTH, HEIGHT); 622264fa531Smrg gcv.foreground = 1; 623264fa531Smrg gcv.background = 0; 624264fa531Smrg XChangeGC(xp->d, pixgc, GCForeground | GCBackground, &gcv); 625264fa531Smrg XDrawLines(xp->d, pix, pixgc, points, NUMPOINTS, CoordModeOrigin); 626264fa531Smrg XFreeGC(xp->d, pixgc); 627264fa531Smrg 628264fa531Smrg return reps; 629264fa531Smrg} 630264fa531Smrg 631dfac8f13Smrgvoid 632533545b5SmrgDoCopyPlane(XParms xp, Parms p, int64_t reps) 633264fa531Smrg{ 634264fa531Smrg int i, size; 635264fa531Smrg XSegment *sa, *sb; 636264fa531Smrg 637264fa531Smrg size = p->special; 638264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 639264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 640264fa531Smrg sa->x1, sa->y1, size, size, sa->x2, sa->y2, 1); 641264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 642264fa531Smrg sa->x2, sa->y2, size, size, sa->x1, sa->y1, 1); 643264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 644264fa531Smrg sb->x2, sb->y2, size, size, sb->x1, sb->y1, 1); 645264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 646264fa531Smrg sb->x1, sb->y1, size, size, sb->x2, sb->y2, 1); 647264fa531Smrg CheckAbort (); 648264fa531Smrg } 649264fa531Smrg} 650264fa531Smrg 651c37a63b8Smrg#include <X11/extensions/Xrender.h> 652c37a63b8Smrg 653c37a63b8Smrgstatic Picture winPict, pixPict; 654c37a63b8Smrg 655c37a63b8Smrgint 656533545b5SmrgInitCompositeWin(XParms xp, Parms p, int64_t reps) 657c37a63b8Smrg{ 658c37a63b8Smrg XRenderPictFormat *format; 659533545b5Smrg 660c37a63b8Smrg (void) InitScroll (xp, p, reps); 661533545b5Smrg InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 662533545b5Smrg if (p->fillStyle) { 663533545b5Smrg int mul = 0x10000; 664533545b5Smrg int div = p->fillStyle; 665533545b5Smrg InitCopyLocations (p->special, mul, div, reps, &segsa2, &segsb2); 666533545b5Smrg } 667c37a63b8Smrg format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual); 668c37a63b8Smrg winPict = XRenderCreatePicture (xp->d, xp->w, format, 0, NULL); 669c37a63b8Smrg return reps; 670c37a63b8Smrg} 671c37a63b8Smrg 672c37a63b8Smrgint 673533545b5SmrgInitCompositePix(XParms xp, Parms p, int64_t reps) 674c37a63b8Smrg{ 675c37a63b8Smrg XRenderPictFormat *format = NULL; 676c37a63b8Smrg int depth; 677533545b5Smrg static XRenderColor c = { 0xffff, 0x0000, 0xffff, 0xffff }; 678c37a63b8Smrg 679c37a63b8Smrg (void) InitCompositeWin (xp, p, reps); 680dfac8f13Smrg 681c37a63b8Smrg /* Create pixmap to write stuff into, and initialize it */ 682c37a63b8Smrg switch (xp->planemask) { 683c37a63b8Smrg case PictStandardNative: 684c37a63b8Smrg depth = xp->vinfo.depth; 685c37a63b8Smrg format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual); 686c37a63b8Smrg break; 687c37a63b8Smrg case PictStandardRGB24: 688c37a63b8Smrg depth = 24; 689c37a63b8Smrg break; 690c37a63b8Smrg case PictStandardARGB32: 691c37a63b8Smrg depth = 32; 692c37a63b8Smrg break; 693c37a63b8Smrg case PictStandardA8: 694c37a63b8Smrg depth = 8; 695c37a63b8Smrg break; 696c37a63b8Smrg case PictStandardA4: 697c37a63b8Smrg depth = 4; 698c37a63b8Smrg break; 699c37a63b8Smrg case PictStandardA1: 700c37a63b8Smrg depth = 1; 701c37a63b8Smrg break; 702c37a63b8Smrg default: 703c37a63b8Smrg depth = 0; 704c37a63b8Smrg break; 705c37a63b8Smrg } 706c37a63b8Smrg if (!format) 707c37a63b8Smrg format = XRenderFindStandardFormat (xp->d, xp->planemask); 708dfac8f13Smrg 709c37a63b8Smrg pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, depth); 710c37a63b8Smrg pixPict = XRenderCreatePicture (xp->d, pix, format, 0, NULL); 711dfac8f13Smrg 712c37a63b8Smrg XRenderComposite (xp->d, PictOpClear, 713c37a63b8Smrg winPict, None, pixPict, 714c37a63b8Smrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 715dfac8f13Smrg 716533545b5Smrg XRenderFillRectangle (xp->d, PictOpSrc, 717533545b5Smrg pixPict, &c, 0, 0, WIDTH, HEIGHT); 718c37a63b8Smrg#if 1 719533545b5Smrg XRenderComposite (xp->d, PictOpSrc, 720c37a63b8Smrg winPict, None, pixPict, 721c37a63b8Smrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 722c37a63b8Smrg#endif 723533545b5Smrg if (p->fillStyle) { 724533545b5Smrg XTransform transform; 725533545b5Smrg memset (&transform, '\0', sizeof (transform)); 726533545b5Smrg transform.matrix[0][0] = ((long long) 0x10000 * 0x10000) / p->fillStyle; 727533545b5Smrg transform.matrix[1][1] = ((long long) 0x10000 * 0x10000) / p->fillStyle; 728533545b5Smrg transform.matrix[2][2] = 0x10000; 729533545b5Smrg XRenderSetPictureTransform (xp->d, pixPict, &transform); 730533545b5Smrg XRenderSetPictureFilter (xp->d, pixPict, FilterBilinear, NULL, 0); 731533545b5Smrg } 732c37a63b8Smrg return reps; 733c37a63b8Smrg} 734c37a63b8Smrg 735c37a63b8Smrgvoid 736c37a63b8SmrgEndCompositeWin (XParms xp, Parms p) 737c37a63b8Smrg{ 738c37a63b8Smrg if (winPict) 739c37a63b8Smrg { 740c37a63b8Smrg XRenderFreePicture (xp->d, winPict); 741c37a63b8Smrg winPict = None; 742c37a63b8Smrg } 743c37a63b8Smrg if (pixPict) 744c37a63b8Smrg { 745c37a63b8Smrg XRenderFreePicture (xp->d, pixPict); 746c37a63b8Smrg pixPict = None; 747c37a63b8Smrg } 748c37a63b8Smrg} 749c37a63b8Smrg 750dfac8f13Smrgstatic void 751533545b5SmrgCompositeArea(XParms xp, Parms p, int64_t reps, Picture src, Picture dst) 752c37a63b8Smrg{ 753c9e4df9bSmrg int size; 754c37a63b8Smrg XSegment *sa, *sb; 755533545b5Smrg XSegment *sa2, *sb2; 756dfac8f13Smrg 757c37a63b8Smrg 758c37a63b8Smrg size = p->special; 759533545b5Smrg sa = segsa; 760533545b5Smrg sb = segsb; 761533545b5Smrg sa2 = segsa2 ? segsa2 : segsa; 762533545b5Smrg sb2 = segsb2 ? segsb2 : segsb; 763c9e4df9bSmrg for (int i = 0; i < reps; i++) { 764c37a63b8Smrg XRenderComposite (xp->d, xp->func, 765c37a63b8Smrg src, None, dst, 766533545b5Smrg sa2->x1, sa2->y1, 0, 0, sa->x2, sa->y2, size, size); 767c37a63b8Smrg XRenderComposite (xp->d, xp->func, 768c37a63b8Smrg src, None, dst, 769533545b5Smrg sa2->x2, sa2->y2, 0, 0, sa->x1, sa->y1, size, size); 770c37a63b8Smrg XRenderComposite (xp->d, xp->func, 771c37a63b8Smrg src, None, dst, 772533545b5Smrg sb2->x2, sb2->y2, 0, 0, sb->x1, sb->y1, size, size); 773c37a63b8Smrg XRenderComposite (xp->d, xp->func, 774c37a63b8Smrg src, None, dst, 775533545b5Smrg sb2->x1, sb2->y1, 0, 0, sb->x2, sb->y2, size, size); 776c37a63b8Smrg CheckAbort (); 777533545b5Smrg sa++; sb++; 778533545b5Smrg sa2++; sb2++; 779c37a63b8Smrg } 780c37a63b8Smrg} 781c37a63b8Smrg 782c37a63b8Smrgvoid 783533545b5SmrgDoCompositeWinWin (XParms xp, Parms p, int64_t reps) 784c37a63b8Smrg{ 785c37a63b8Smrg CompositeArea (xp, p, reps, winPict, winPict); 786c37a63b8Smrg} 787c37a63b8Smrg 788c37a63b8Smrgvoid 789533545b5SmrgDoCompositePixWin (XParms xp, Parms p, int64_t reps) 790c37a63b8Smrg{ 791c37a63b8Smrg CompositeArea (xp, p, reps, pixPict, winPict); 792c37a63b8Smrg} 793