home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / x / x11p-13.zip / do_copyarea.c < prev    next >
C/C++ Source or Header  |  1991-06-03  |  12KB  |  508 lines

  1. /*****************************************************************************
  2. Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
  3.  
  4.                         All Rights Reserved
  5.  
  6. Permission to use, copy, modify, and distribute this software and its 
  7. documentation for any purpose and without fee is hereby granted, 
  8. provided that the above copyright notice appear in all copies and that
  9. both that copyright notice and this permission notice appear in 
  10. supporting documentation, and that the name of Digital not be
  11. used in advertising or publicity pertaining to distribution of the
  12. software without specific, written prior permission.  
  13.  
  14. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  18. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20. SOFTWARE.
  21.  
  22. ******************************************************************************/
  23.  
  24. #include "x11perf.h"
  25.  
  26. #define NUMPOINTS 100
  27.  
  28. static Pixmap   pix;
  29. static XImage   *image;
  30. static XPoint   points[NUMPOINTS];
  31. static XSegment *segsa, *segsb;
  32.  
  33. #define NegMod(x, y) ((y) - (((-x)-1) % (7)) - 1)
  34.  
  35. int InitScroll(xp, p, reps)
  36.     XParms  xp;
  37.     Parms   p;
  38.     int     reps;
  39. {
  40.     int i, x, y;
  41.  
  42.     points[0].x = points[0].y = y = 0;
  43.     for (i = 1; i != NUMPOINTS/2; i++) {    
  44.     if (i & 1) {
  45.         points[i].x = WIDTH-1;
  46.     } else {
  47.         points[i].x = 0;
  48.     }
  49.     y += HEIGHT / (NUMPOINTS/2);
  50.     points[i].y = y;
  51.     }
  52.     
  53.     x = 0;
  54.     for (i = NUMPOINTS/2; i!= NUMPOINTS; i++) {
  55.     if (i & 1) {
  56.         points[i].y = HEIGHT-1;
  57.     } else {
  58.         points[i].y = 0;
  59.     }
  60.     x += WIDTH / (NUMPOINTS/2);
  61.     points[i].x = x;
  62.     }
  63.     
  64.     XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin);
  65.     return reps;
  66. }
  67.  
  68. void DoScroll(xp, p, reps)
  69.     XParms  xp;
  70.     Parms   p;
  71.     int     reps;
  72. {
  73.     int i, size, x, y, xorg, yorg, delta;
  74.  
  75.     size = p->special;
  76.     xorg = 0;   yorg = 0;
  77.     x    = 0;   y    = 0;
  78.     if (xp->version == VERSION1_2) {
  79.     delta = 1;
  80.     } else {
  81.     /* Version 1.2 only scrolled up by 1 scanline, which made hardware
  82.        using page-mode access to VRAM look better on paper than it would
  83.        perform in a more realistic scroll.  So we've changed to scroll by
  84.        the height of the 6x13 fonts. */
  85.     delta = 13;
  86.     }
  87.  
  88.     for (i = 0; i != reps; i++) {
  89.     XCopyArea(xp->d, xp->w, xp->w, xp->fggc, x, y + delta,
  90.         size, size, x, y);
  91.     y += size;
  92.     if (y + size + delta > HEIGHT) {
  93.         yorg += delta;
  94.         if (yorg >= size || yorg + size + delta > HEIGHT) {
  95.         yorg = 0;
  96.         xorg++;
  97.         if (xorg >= size || xorg + size > WIDTH) {
  98.             xorg = 0;
  99.         }
  100.         }
  101.         y = yorg;
  102.         x += size;
  103.         if (x + size > WIDTH) {
  104.         x = xorg;
  105.         }
  106.     }
  107.     }
  108. }
  109.  
  110. void MidScroll(xp, p)
  111.     XParms  xp;
  112.     Parms   p;
  113. {
  114.     XClearWindow(xp->d, xp->w);
  115.     XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin);
  116. }
  117.  
  118. void EndScroll(xp, p)
  119.     XParms  xp;
  120.     Parms   p;
  121. {
  122. }
  123.  
  124. static void InitCopyLocations(xp, p, reps)
  125.     XParms  xp;
  126.     Parms   p;
  127.     int     reps;
  128. {
  129.     int x1, y1, x2, y2, size, i;
  130.     int xinc, yinc;
  131.     int width, height;
  132.  
  133.     /* Try to exercise all alignments of src and destination equally, as well
  134.        as all 4 top-to-bottom/bottom-to-top, left-to-right, right-to-left
  135.        copying directions.  Computation done here just to make sure slow
  136.        machines aren't measuring anything but the XCopyArea calls.
  137.     */
  138.     size = p->special;
  139.     xinc = (size & ~3) + 1;
  140.     yinc = xinc + 3;
  141.  
  142.     width = (WIDTH - size) & ~31;
  143.     height = (HEIGHT - size) & ~31;
  144.     
  145.     x1 = 0;
  146.     y1 = 0;
  147.     x2 = width;
  148.     y2 = height;
  149.     
  150.     segsa = (XSegment *)malloc(reps * sizeof(XSegment));
  151.     segsb = (XSegment *)malloc(reps * sizeof(XSegment));
  152.     for (i = 0; i != reps; i++) {
  153.     segsa[i].x1 = x1;
  154.     segsa[i].y1 = y1;
  155.     segsa[i].x2 = x2;
  156.     segsa[i].y2 = y2;
  157.  
  158.     /* Move x2, y2, location backward */
  159.     x2 -= xinc;
  160.     if (x2 < 0) {
  161.         x2 = NegMod(x2, width);
  162.         y2 -= yinc;
  163.         if (y2 < 0) {
  164.         y2 = NegMod(y2, height);
  165.         }
  166.     }
  167.  
  168.     segsb[i].x1 = x1;
  169.     segsb[i].y1 = y1;
  170.     segsb[i].x2 = x2;
  171.     segsb[i].y2 = y2;
  172.  
  173.     /* Move x1, y1 location forward */
  174.     x1 += xinc;
  175.     if (x1 > width) {
  176.         x1 %= 32;
  177.         y1 += yinc;
  178.         if (y1 > height) {
  179.         y1 %= 32;
  180.         }
  181.     }
  182.     } /* end for */
  183. }
  184.  
  185.  
  186. int InitCopyWin(xp, p, reps)
  187.     XParms  xp;
  188.     Parms   p;
  189.     int     reps;
  190. {
  191.     (void) InitScroll(xp, p, reps);
  192.     InitCopyLocations(xp, p, reps);
  193.     return reps;
  194. }
  195.  
  196. int InitCopyPix(xp, p, reps)
  197.     XParms  xp;
  198.     Parms   p;
  199.     int     reps;
  200. {
  201.     (void) InitCopyWin(xp, p, reps);
  202.  
  203.     /* Create pixmap to write stuff into, and initialize it */
  204.     pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, xp->vinfo.depth);
  205.     XCopyArea(xp->d, xp->w, pix, xp->fggc, 0, 0, WIDTH, HEIGHT, 0, 0);
  206.     return reps;
  207. }
  208.  
  209. Bool InitGetImage(xp, p, reps)
  210.     XParms  xp;
  211.     Parms   p;
  212.     int     reps;
  213. {
  214.     (void) InitCopyWin(xp, p, reps);
  215.  
  216.     /* Create image to stuff bits into */
  217.     image = XGetImage(xp->d, xp->w, 0, 0, WIDTH, HEIGHT, ~0, ZPixmap);
  218.     return reps;
  219. }
  220.  
  221. Bool InitPutImage(xp, p, reps)
  222.     XParms  xp;
  223.     Parms   p;
  224.     int     reps;
  225. {
  226.     (void) InitGetImage(xp, p, reps);
  227.     XClearWindow(xp->d, xp->w);
  228.     return reps;
  229. }
  230.  
  231. static void CopyArea(xp, p, reps, src, dst)
  232.     XParms  xp;
  233.     Parms   p;
  234.     int     reps;
  235.     Drawable src, dst;
  236. {
  237.     int i, size;
  238.     XSegment *sa, *sb;
  239.  
  240.     size = p->special;
  241.     for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
  242.     XCopyArea(xp->d, src, dst, xp->fggc,
  243.         sa->x1, sa->y1, size, size, sa->x2, sa->y2);
  244.     XCopyArea(xp->d, src, dst, xp->fggc,
  245.         sa->x2, sa->y2, size, size, sa->x1, sa->y1);
  246.     XCopyArea(xp->d, src, dst, xp->fggc,
  247.         sb->x2, sb->y2, size, size, sb->x1, sb->y1);
  248.     XCopyArea(xp->d, src, dst, xp->fggc,
  249.         sb->x1, sb->y1, size, size, sb->x2, sb->y2);
  250.     }
  251. }
  252.  
  253. void DoCopyWinWin(xp, p, reps)
  254.     XParms  xp;
  255.     Parms   p;
  256.     int     reps;
  257. {
  258.     CopyArea(xp, p, reps, xp->w, xp->w);
  259. }
  260.  
  261. void DoCopyPixWin(xp, p, reps)
  262.     XParms  xp;
  263.     Parms   p;
  264.     int     reps;
  265. {
  266.     CopyArea(xp, p, reps, pix, xp->w);
  267. }
  268.  
  269. void DoCopyWinPix(xp, p, reps)
  270.     XParms  xp;
  271.     Parms   p;
  272.     int     reps;
  273. {
  274.     CopyArea(xp, p, reps, xp->w, pix);
  275. }
  276.  
  277. void DoCopyPixPix(xp, p, reps)
  278.     XParms  xp;
  279.     Parms   p;
  280.     int     reps;
  281. {
  282.     CopyArea(xp, p, reps, pix, pix);
  283. }
  284.  
  285. void DoGetImage(xp, p, reps)
  286.     XParms  xp;
  287.     Parms   p;
  288.     int     reps;
  289. {
  290.     int i, size;
  291.     XSegment *sa, *sb;
  292.  
  293.     size = p->special;
  294.     for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
  295.     XDestroyImage(image);
  296.     image = XGetImage(xp->d, xp->w, sa->x1, sa->y1, size, size,
  297.         ~0, ZPixmap);
  298.     XDestroyImage(image);
  299.     image = XGetImage(xp->d, xp->w, sa->x2, sa->y2, size, size,
  300.         ~0, ZPixmap);
  301.     XDestroyImage(image);
  302.     image = XGetImage(xp->d, xp->w, sb->x2, sb->y2, size, size,
  303.         ~0, ZPixmap);
  304.     XDestroyImage(image);
  305.     image = XGetImage(xp->d, xp->w, sb->x1, sb->y1, size, size,
  306.         ~0, ZPixmap);
  307. /*
  308.  
  309. One might expect XGetSubImage to be slightly faster than XGetImage.  Go look
  310. at the code in Xlib.  MIT X11R3 ran approximately 30 times slower for a 500x500
  311. rectangle.
  312.  
  313.     (void) XGetSubImage(xp->d, xp->w, sa->x1, sa->y1, size, size,
  314.         ~0, ZPixmap, image, sa->x2, sa->y2);
  315.     (void) XGetSubImage(xp->d, xp->w, sa->x2, sa->y2, size, size,
  316.         ~0, ZPixmap, image, sa->x1, sa->y1);
  317.     (void) XGetSubImage(xp->d, xp->w, sb->x2, sb->y2, size, size,
  318.         ~0, ZPixmap, image, sb->x2, sb->y2);
  319.     (void) XGetSubImage(xp->d, xp->w, sb->x1, sb->y1, size, size,
  320.         ~0, ZPixmap, image, sb->x2, sb->y2);
  321. */
  322.     }
  323. }
  324.  
  325. void DoPutImage(xp, p, reps)
  326.     XParms  xp;
  327.     Parms   p;
  328.     int     reps;
  329. {
  330.     int i, size;
  331.     XSegment *sa, *sb;
  332.  
  333.     size = p->special;
  334.     for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
  335.     XPutImage(xp->d, xp->w, xp->fggc, image,
  336.         sa->x1, sa->y1, sa->x2, sa->y2, size, size);
  337.     XPutImage(xp->d, xp->w, xp->fggc, image,
  338.         sa->x2, sa->y2, sa->x1, sa->y1, size, size);
  339.     XPutImage(xp->d, xp->w, xp->fggc, image,
  340.         sb->x2, sb->y2, sb->x2, sb->y2, size, size);
  341.     XPutImage(xp->d, xp->w, xp->fggc, image,
  342.         sb->x1, sb->y1, sb->x2, sb->y2, size, size);
  343.     }
  344. }
  345.  
  346. #ifdef MITSHM
  347.  
  348. #include <sys/types.h>
  349. #include <sys/ipc.h>
  350. #include <sys/shm.h>
  351. #include <X11/extensions/XShm.h>
  352.  
  353. static XImage        shm_image;
  354. static XShmSegmentInfo    shminfo;
  355.  
  356. int InitShmPutImage (xp, p, reps)
  357.     XParms  xp;
  358.     Parms   p;
  359.     int     reps;
  360. {
  361.     int    image_size;
  362.  
  363.     (void) InitGetImage(xp, p);
  364.     XClearWindow(xp->d, xp->w);
  365.     shm_image = *image;
  366.     image_size = image->bytes_per_line * image->height;
  367.     shminfo.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777);
  368.     if (shminfo.shmid < 0)
  369.     {
  370.     perror ("shmget");
  371.     return False;
  372.     }
  373.     shminfo.shmaddr = (char *) shmat(shminfo.shmid, 0, 0);
  374.     if (shminfo.shmaddr == ((char *) -1))
  375.     {
  376.     perror ("shmat");
  377.     return False;
  378.     }
  379.     shminfo.readOnly = True;
  380.     XShmAttach (xp->d, &shminfo);
  381.     shm_image.data = shminfo.shmaddr;
  382.     bcopy (image->data, shm_image.data, image_size);
  383.     shm_image.obdata = (char *) &shminfo;
  384.     return reps;
  385. }
  386.  
  387. void DoShmPutImage(xp, p, reps)
  388.     XParms  xp;
  389.     Parms   p;
  390.     int     reps;
  391. {
  392.     int i, size;
  393.     XSegment *sa, *sb;
  394.  
  395.     size = p->special;
  396.     for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
  397.     XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
  398.         sa->x1, sa->y1, sa->x2, sa->y2, size, size, False);
  399.     XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
  400.         sa->x2, sa->y2, sa->x1, sa->y1, size, size, False);
  401.     XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
  402.         sb->x2, sb->y2, sb->x2, sb->y2, size, size, False);
  403.     XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image,
  404.         sb->x1, sb->y1, sb->x2, sb->y2, size, size, False);
  405.     }
  406. }
  407.  
  408. void EndShmPutImage(xp, p)
  409.     XParms  xp;
  410.     Parms   p;
  411. {
  412.     void    EndGetImage();
  413.  
  414.     EndGetImage (xp, p);
  415.     XShmDetach (xp->d, &shminfo);
  416.     shmdt (shminfo.shmaddr);
  417.     shmctl (shminfo.shmid, IPC_RMID, 0);
  418. }
  419.  
  420. #endif
  421.  
  422.  
  423. void MidCopyPix(xp, p)
  424.     XParms  xp;
  425.     Parms   p;
  426. {
  427.     XClearWindow(xp->d, xp->w);
  428. }
  429.  
  430. void EndCopyWin(xp, p)
  431.     XParms  xp;
  432.     Parms   p;
  433. {
  434.     EndScroll(xp, p);
  435.     free(segsa);
  436.     free(segsb);
  437. }
  438.  
  439. void EndCopyPix(xp, p)
  440.     XParms  xp;
  441.     Parms   p;
  442. {
  443.     EndCopyWin(xp, p);
  444.     XFreePixmap(xp->d, pix);
  445. }
  446.  
  447. void EndGetImage(xp, p)
  448.     XParms  xp;
  449.     Parms   p;
  450. {
  451.     EndCopyWin(xp, p);
  452.     XDestroyImage(image);
  453. }
  454.  
  455. Bool InitCopyPlane(xp, p, reps)
  456.     XParms  xp;
  457.     Parms   p;
  458.     int     reps;
  459. {
  460.     int        i;
  461.     XGCValues   gcv;
  462.     GC        pixgc;
  463.  
  464.     for (i = 0; i != NUMPOINTS; i++) {    
  465.         points[i].x = rand() % WIDTH;
  466.         points[i].y = rand() % HEIGHT;
  467.     }
  468.     InitCopyLocations(xp, p, reps);
  469.  
  470.     /* Create bitmap to write stuff into, and initialize it */
  471.     pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, 1);
  472.     gcv.graphics_exposures = False;
  473.     gcv.foreground = 0;
  474.     gcv.background = 1;
  475.     pixgc = XCreateGC(xp->d, pix, 
  476.         GCForeground | GCBackground | GCGraphicsExposures, &gcv);
  477.     XFillRectangle(xp->d, pix, pixgc, 0, 0, WIDTH, HEIGHT);
  478.     gcv.foreground = 1;
  479.     gcv.background = 0;
  480.     XChangeGC(xp->d, pixgc, GCForeground | GCBackground, &gcv);
  481.     XDrawLines(xp->d, pix, pixgc, points, NUMPOINTS, CoordModeOrigin);
  482.     XFreeGC(xp->d, pixgc);
  483.  
  484.     return reps;
  485. }
  486.  
  487. void DoCopyPlane(xp, p, reps)
  488.     XParms  xp;
  489.     Parms   p;
  490.     int     reps;
  491. {
  492.     int        i, size;
  493.     XSegment    *sa, *sb;
  494.  
  495.     size = p->special;
  496.     for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) {
  497.     XCopyPlane(xp->d, pix, xp->w, xp->fggc,
  498.         sa->x1, sa->y1, size, size, sa->x2, sa->y2, 1);
  499.     XCopyPlane(xp->d, pix, xp->w, xp->fggc,
  500.         sa->x2, sa->y2, size, size, sa->x1, sa->y1, 1);
  501.     XCopyPlane(xp->d, pix, xp->w, xp->fggc,
  502.         sb->x2, sb->y2, size, size, sb->x1, sb->y1, 1);
  503.     XCopyPlane(xp->d, pix, xp->w, xp->fggc,
  504.         sb->x1, sb->y1, size, size, sb->x2, sb->y2, 1);
  505.     }
  506. }
  507.  
  508.