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