home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / apa16 / apa16Curs.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  18KB  |  558 lines

  1. /***********************************************************
  2.         Copyright IBM Corporation 1987,1988
  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 IBM not be
  11. used in advertising or publicity pertaining to distribution of the
  12. software without specific, written prior permission.  
  13.  
  14. IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16. IBM 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. Copyright 1989 by the Massachusetts Institute of Technology
  25.  
  26.                      All rights reserved.
  27.  
  28. Permission to use, copy, modify, and distribute this software and its
  29. documentation for any purpose and without fee is hereby granted,
  30. provided that the above copyright notice appear in all copies and that
  31. both that copyright notice and this permission notice appear in
  32. supporting documentation, and that the name of the Massachusetts
  33. Institute of Technology (M.I.T.) not be used in advertising or publicity
  34. pertaining to distribution of the software without specific, written
  35. prior permission.
  36.  
  37. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. SOFTWARE.
  44.  
  45. ******************************************************************/
  46. /* $Header: /afs/athena.mit.edu/astaff/project/x11r5/src/athena/ibm/apa16/RCS/apa16Curs.c,v 5.1 1992/02/12 00:31:09 jfc Exp $ */
  47. /* $Source: /afs/athena.mit.edu/astaff/project/x11r5/src/athena/ibm/apa16/RCS/apa16Curs.c,v $ */
  48.  
  49. #ifndef lint
  50. static char *rcsid = "$Header: /afs/athena.mit.edu/astaff/project/x11r5/src/athena/ibm/apa16/RCS/apa16Curs.c,v 5.1 1992/02/12 00:31:09 jfc Exp $";
  51. #endif
  52.  
  53. #include "X.h"
  54. #include "Xmd.h"
  55. #include "miscstruct.h"
  56. #include "scrnintstr.h"
  57. #include "cursorstr.h"
  58.  
  59. #include "mfb.h"
  60. #include "maskbits.h"
  61.  
  62. #include "OScompiler.h"
  63.  
  64. #if defined(BSDrt)
  65. #include "bsdIO.h"
  66. #else
  67. #include "OSio.h"
  68. #endif
  69.  
  70. #include "ibmScreen.h"
  71. #include "ibmTrace.h"
  72. #include "apa16Hdwr.h"
  73.  
  74. /***============================================================***/
  75.  
  76.     /*
  77.      * NOTES ON THE APA16 HARDWARE CURSOR:
  78.      * The apa16 supports a 48x64 hardware cursor which 'AND's and
  79.      * 'XOR's two different patterns simultaneously on the screen.
  80.      * The cursor patterns are stored at (0,784) and (48,784) on
  81.      * the apa16 adapter.
  82.      *
  83.      * Writes to the adapter registers (CURSOR_X and CURSOR_Y) move
  84.      * the cursor on the screen.
  85.      * 
  86.      * The CURSOR_Y register may be set to any value -- the cursor
  87.      * is not displayed if CURSOR_Y is <0 or >830 (767+64).
  88.      * A partial cursor is displayed for CURSOR_Y<64 or CURSOR_Y>767.
  89.      *
  90.      * The CURSOR_X register must be in the range 0<=CURSOR_X<=976
  91.      * (1024-48).   Values outside of this range distort the screen
  92.      * image.   The apa16 does *NOT* display a partial cursor image
  93.      * for a cursor that falls off of the left or right of the screen
  94.      * we have slide the cursor image(s) around in the reserved
  95.      * hardware area to simulate the cursor moving off of the screen.
  96.      *
  97.      * NOTES ON THE RT/PC X11 SERVER CURSOR SUPPORT (../librt/rtcursor.c):
  98.      * The X emulator in the kernel normally tries to track the cursor.
  99.      * Unfortunately, the kernel apa16 locator code uses the apa16 rasterop
  100.      * processor to copy and clear cursor images.  If the X server is
  101.      * trying to use the apa16 hardware at the same time, it can get
  102.      * pretty messy.  This means that we have to track the cursor in the
  103.      * server.   
  104.      *
  105.      * The area to the right of the active cursor area on the adapter
  106.      * (the rectangle with corners at (96,767) and (1023,847) is used 
  107.      * to store additional cursor patterns.   When a cursor is "realized" 
  108.      * we allocate space (if available) in this rectangle and copy 
  109.      * the image into it.
  110.      * When a "realized" cursor is displayed, we can use the apa16
  111.      * rasterop processor to copy the image from the reserved area (on
  112.      * the adapter) into the active cursor area.
  113.      */
  114.  
  115. /***============================================================***/
  116.  
  117.     /*
  118.      * all cursor images are between scan-lines 784 and 847 (inclusive),
  119.      * and consist of two 48x64 masks.
  120.      * For each "realized" cursor we need to know the X coordinate
  121.      * of the left edge of the masks.
  122.      *
  123.      * We use "next" to keep track of the next free space for the cursor.
  124.      *
  125.      * MAXCURSORS is the number of cursor images we have reserved space
  126.      * for on the adapter.
  127.      *
  128.      * XOR_EDGE and AND_EDGE calculate the right edge of the masks
  129.      * for a cursor.  We need the right edge because the apa16 hardware
  130.      * uses the lower right corner of the area to be copied.
  131.      */
  132.  
  133. typedef struct A16CURSOR {
  134.     struct    A16CURSOR    *next;
  135.     short            edge;
  136. } apa16Cursor;
  137.  
  138. #define ACTIVE_CURSOR    (&cursors[0])
  139. #define    TEMP_CURSOR    (&cursors[1])
  140.  
  141. #define XOR_EDGE(c)    ((c)->edge+2*CURSOR_WIDTH)
  142. #define AND_EDGE(c)    ((c)->edge+CURSOR_WIDTH)
  143.  
  144. /***============================================================***/
  145.  
  146.     /*
  147.      * "cursors" is an array of structures describing the available
  148.      * cursor images.
  149.      * "nextFree" is structure describing the next area to be allocated.
  150.      * "currentCursor" is the most recently displayed cursor.
  151.      */
  152.  
  153. static    apa16Cursor    cursors[MAXCURSORS]; 
  154. static    apa16Cursor    *nextFree;
  155. static    apa16Cursor    *currentCursor;
  156.  
  157. /***============================================================***/
  158.  
  159. #if defined(DEBUG) && !defined(NDEBUG)
  160. void
  161. copyoutcursor()
  162. {
  163. unsigned cmd;
  164.  
  165.     APA16_GET_CMD_COPY(ROP_RECT_COPY,GXcopy,cmd);
  166.     COPY_RECT(cmd,300,    300,
  167.           XOR_EDGE(ACTIVE_CURSOR),    CURSOR_AREA_BOTTOM,
  168.           2*CURSOR_WIDTH,    CURSOR_HEIGHT);
  169.     return;
  170. }
  171. #endif
  172.  
  173. /***============================================================***/
  174.  
  175.     /*
  176.      * Clear the image of the cursor area described by "Curs."
  177.      * To clear a cursor image, we want to set the AND mask to
  178.      * all 1's and the XOR mask to all 0's.
  179.      */
  180.  
  181. static void
  182. apa16ClearCursor(Curs)
  183. apa16Cursor    *Curs;
  184. {
  185. unsigned cmd;
  186.  
  187.     TRACE(("apa16ClearCursor( Curs= 0x%x )\n",Curs));
  188.  
  189.     APA16_GET_CMD_FILL(RROP_WHITE,cmd);
  190.     FILL_RECT(cmd,AND_EDGE(Curs),CURSOR_AREA_BOTTOM,CURSOR_WIDTH,CURSOR_HEIGHT);
  191.     APA16_GET_CMD_FILL(RROP_BLACK,cmd);
  192.     FILL_RECT(cmd,XOR_EDGE(Curs),CURSOR_AREA_BOTTOM,CURSOR_WIDTH,CURSOR_HEIGHT);
  193.     return ;
  194. }
  195. /***============================================================***/
  196.  
  197. static void
  198. apa16CopyCursor(srcCurs,dstCurs)
  199. apa16Cursor    *srcCurs,*dstCurs;
  200. {
  201. unsigned cmd;
  202.  
  203.     TRACE(("apa16CopyCursor( srcCurs= 0x%x, dstCurs= 0x%x)\n",srcCurs,dstCurs));
  204.  
  205.     APA16_GET_CMD_COPY(ROP_RECT_COPY,GXcopy,cmd);
  206.     COPY_RECT(cmd,XOR_EDGE(dstCurs),    CURSOR_AREA_BOTTOM,
  207.           XOR_EDGE(srcCurs),    CURSOR_AREA_BOTTOM,
  208.           2*CURSOR_WIDTH,    CURSOR_HEIGHT);
  209.     return ;
  210. }
  211.  
  212. /***============================================================***/
  213.  
  214.     /*
  215.      * The RT/PC server will take care of updating the cursor location
  216.      * (through ibmCursorX and ibmCursorY) for most of the screen.
  217.      * The apa16 hardware is brain-damaged and can't handle the cursor
  218.      * around the left and right edges of the screen, so we have to 
  219.      * slide the cursor image around without moving the box to simulate
  220.      * the cursor going off of the screen.   apa16ShowCursor() takes
  221.      * care of this.
  222.      * Keep in mind that the COPY_RECT uses the <<lower right>> corner
  223.      * of the source and destination areas.
  224.      *
  225.      */
  226.  
  227. void
  228. apa16ShowCursor(x,y)
  229. register short x,y;
  230. {
  231. register unsigned cmd;
  232. register int    offset;
  233. static    int    obscured= TRUE;
  234.  
  235.     TRACE(("apa16ShowCursor( x= %d, y= %d )\n",x,y));
  236.  
  237.     if (ibmScreenState(ibmCurrentScreen)!= SCREEN_ACTIVE ||
  238.     currentCursor == NULL) {
  239.     return;
  240.     }
  241.  
  242.     APA16_GET_CMD_COPY(ROP_RECT_COPY,GXcopy,cmd);
  243.     if (x<ibmCursorHotX(ibmCurrentScreen)) {
  244.     offset= ibmCursorHotX(ibmCurrentScreen)-x;
  245.     apa16ClearCursor(ACTIVE_CURSOR);
  246.     if (offset < CURSOR_WIDTH) {
  247.         COPY_RECT(cmd, AND_EDGE(ACTIVE_CURSOR)-offset,  CURSOR_AREA_BOTTOM,
  248.                    AND_EDGE(currentCursor),        CURSOR_AREA_BOTTOM,
  249.                CURSOR_WIDTH-offset,                CURSOR_HEIGHT);
  250.         COPY_RECT(cmd, XOR_EDGE(ACTIVE_CURSOR)-offset,  CURSOR_AREA_BOTTOM,
  251.                    XOR_EDGE(currentCursor),        CURSOR_AREA_BOTTOM,
  252.                    CURSOR_WIDTH-offset,                CURSOR_HEIGHT);
  253.     }
  254.     CURSOR_X= 0;
  255.     CURSOR_Y= y-ibmCursorHotY(ibmCurrentScreen);
  256.     obscured= TRUE;
  257.     }
  258.     else if (x>APA16_WIDTH-CURSOR_WIDTH+ibmCursorHotX(ibmCurrentScreen)) {
  259.     offset= x-APA16_WIDTH-ibmCursorHotX(ibmCurrentScreen)+CURSOR_WIDTH;
  260.     apa16ClearCursor(ACTIVE_CURSOR);
  261.     if (offset < CURSOR_WIDTH) {
  262.         COPY_RECT(cmd, AND_EDGE(ACTIVE_CURSOR),            CURSOR_AREA_BOTTOM,
  263.                    AND_EDGE(currentCursor)-offset,  CURSOR_AREA_BOTTOM,
  264.                    CURSOR_WIDTH-offset,            CURSOR_HEIGHT);
  265.         COPY_RECT(cmd, XOR_EDGE(ACTIVE_CURSOR),        CURSOR_AREA_BOTTOM,
  266.                    XOR_EDGE(currentCursor)-offset,  CURSOR_AREA_BOTTOM,
  267.                    CURSOR_WIDTH-offset,            CURSOR_HEIGHT);
  268.     }
  269.     CURSOR_X= APA16_WIDTH-48;
  270.     CURSOR_Y= y-ibmCursorHotY(ibmCurrentScreen);
  271.     obscured= TRUE;
  272.     }
  273.     else {
  274.     if (obscured) {
  275.         apa16CopyCursor(currentCursor,ACTIVE_CURSOR);
  276.         obscured= FALSE;
  277.     }
  278.     CURSOR_X= x-ibmCursorHotX(ibmCurrentScreen);
  279.     CURSOR_Y= y-ibmCursorHotY(ibmCurrentScreen);
  280.     }
  281.     return;
  282. }
  283.  
  284. /***============================================================***/
  285.  
  286.     /*
  287.      * Copy the upper left (48x64) rectangle of mask and source
  288.      * onto reserved space on the apa16 adapter.
  289.      * (server pads cursor images to longword boundaries)
  290.      *
  291.      * The code to copy treats each mask as three 16 bit wide
  292.      * vertical bands.  SET_BAND sets band 'n' in both destination
  293.      * masks (sD,mD) to the values in band 'n' of the source masks (sS,mS).
  294.      * 
  295.      * We copy the X "source" onto the XOR area and the X "mask" onto the
  296.      * "AND" area.
  297.      */
  298.  
  299. #define SERVER_PAD(w)    ((((w)+31)/32)*4)
  300.  
  301. #define    SET_BAND(ndx,fg,w,sS,mS,aD,xD)\
  302.     if ((w)>=((ndx+1)*16)) {\
  303.         (aD)[(ndx)]=    ~(mS)[(ndx)];\
  304.             (xD)[(ndx)]=    ((mS)[(ndx)])&((fg)^((sS)[(ndx)]));\
  305.     }
  306.  
  307. static
  308. apa16CopyXCursor(srcCurs,dstCurs)
  309. CursorPtr    srcCurs;
  310. apa16Cursor    *dstCurs;
  311. {
  312.     CARD16    *srcSrc,*mskSrc;
  313.     volatile CARD16 *andDst,*xorDst;
  314.     CARD16    fg;
  315.     int        srcWidth,dstWidth;
  316.     unsigned    endbits,i,rightEdge;
  317.  
  318.     TRACE(("apa16CopyXCursor(srcCurs= 0x%x, dstCurs= 0x%x)\n",srcCurs,dstCurs));
  319.     /* set up pointers to source and destination */
  320.     mskSrc=     (CARD16 *)srcCurs->bits->mask;
  321.     srcSrc=     (CARD16 *)srcCurs->bits->source;
  322.     srcWidth=    SERVER_PAD(srcCurs->bits->width)/2;
  323.     andDst=     SCREEN_ADDR(dstCurs->edge,CURSOR_AREA_TOP);
  324.     xorDst=     SCREEN_ADDR((dstCurs->edge+48),CURSOR_AREA_TOP);
  325.     dstWidth=    APA16_WIDTH/16;
  326.  
  327.     if ((srcCurs->foreRed+srcCurs->foreGreen+srcCurs->foreBlue)>
  328.     (srcCurs->backRed+srcCurs->backGreen+srcCurs->backBlue)) {
  329.     fg= 0;
  330.     }
  331.     else fg= 0xffff;
  332.  
  333.     apa16ClearCursor(dstCurs);
  334.     QUEUE_WAIT();
  335.  
  336.         /* endtab is 32 bit masks, turn it into a 16 bit mask */
  337.     endbits=   endtab[srcCurs->bits->width&0xf]>>16;
  338.     rightEdge= srcCurs->bits->width/16;
  339.     for (i=0;i<srcCurs->bits->height;i++) {
  340.     SET_BAND(0,fg,srcCurs->bits->width,srcSrc,mskSrc,andDst,xorDst);
  341.     SET_BAND(1,fg,srcCurs->bits->width,srcSrc,mskSrc,andDst,xorDst);
  342.     SET_BAND(2,fg,srcCurs->bits->width,srcSrc,mskSrc,andDst,xorDst);
  343.     if ((srcCurs->bits->width&0xf)&&(rightEdge<=2)) {
  344.         andDst[rightEdge]=    ~(mskSrc[rightEdge]&endbits);
  345.         xorDst[rightEdge]= (mskSrc[rightEdge]&(fg^srcSrc[rightEdge]))&
  346.                                     endbits;
  347.     }
  348.     srcSrc+= srcWidth; mskSrc+= srcWidth;
  349.     andDst+= dstWidth; xorDst+= dstWidth;
  350.     }
  351.     return TRUE;
  352. }
  353.  
  354. /***============================================================***/
  355.  
  356. /*ARGSUSED*/
  357. void
  358. apa16RemoveCursor(scrIndex)
  359.     int    scrIndex;
  360. {
  361.  
  362.     TRACE(("apa16RemoveCursor(scrIndex=%d)\n",scrIndex));
  363.     if ( ibmScreenState( ibmCurrentScreen )==SCREEN_ACTIVE )
  364.     apa16ClearCursor(ACTIVE_CURSOR);
  365.     return;
  366. }
  367.  
  368. /***============================================================***/
  369.  
  370.     /*
  371.      * Initialize the apa16cursor package.  Sets up data structures
  372.      * and such so the RT/PC specific code will track the cursor
  373.      * correctly.  Called by apa16ScreenInit().
  374.      *
  375.      * I had trouble convinving the kernel *not* to track the cursor
  376.      * automatically.  The magic sequence of ioctls below seems to
  377.      * do the trick.
  378.      */
  379.  
  380. apa16CursorInit(scrIndex)
  381.     int    scrIndex;
  382. {
  383. int  i,col;
  384.  
  385.     TRACE(("apa16CursorInit( scrIndex=%d )\n",scrIndex));
  386.     /* Initialize data structures */
  387.     for (i=0,col=0;i<MAXCURSORS;i++,col+=2*CURSOR_WIDTH) {
  388.     cursors[i].next=     &cursors[i+1];
  389.     cursors[i].edge=     col;
  390.     }
  391.     cursors[MAXCURSORS-1].next=    NULL;
  392.     nextFree= &cursors[2];
  393.  
  394.     if ( ibmScreenState( scrIndex ) == SCREEN_ACTIVE ) {
  395.     apa16RemoveCursor(scrIndex);
  396.     apa16ClearCursor(ACTIVE_CURSOR);
  397.     }
  398.     return TRUE;
  399. }
  400.  
  401. /***============================================================***/
  402.  
  403.     /*
  404.      * Lots of cursors that will never actually be used get
  405.      * realized, so don't bother to save space for cursors until
  406.      * they are actually used.
  407.      * The ibmCurrentCursor stuff is a hack.  Right now, the DIX
  408.      * layer doesn't bother to display a cursor when we switch screens
  409.      * so there is no active cursor.   Easy enough to fix:
  410.      * the first realized cursor becomes the default unless another
  411.      * cursor is explicitly displayed.  Easy, but a hack.
  412.      */
  413.  
  414. Bool
  415. apa16RealizeCursor( pScr, pCurs)
  416.     ScreenPtr    pScr;
  417.     CursorPtr    pCurs;    /* a SERVER-DEPENDENT cursor */
  418. {
  419.     TRACE(("apa16RealizeCursor( pScr= 0x%x, pCurs= 0x%x )\n",pScr,pCurs));
  420.     pCurs->devPriv[ pScr->myNum ]= (pointer)NULL;
  421.     if (!ibmCurrentCursor(pScr->myNum)) {
  422.     ibmCurrentCursor(pScr->myNum)= pCurs;
  423.     }
  424.     return TRUE;
  425. }
  426.  
  427. /***============================================================***/
  428.  
  429.     /*
  430.      * Free up the space reserved for 'pCurs'
  431.      */
  432.  
  433. Bool
  434. apa16UnrealizeCursor( pScr, pCurs)
  435.     ScreenPtr     pScr;
  436.     CursorPtr     pCurs;
  437. {
  438. apa16Cursor *cur;
  439.  
  440.     TRACE(("apa16UnrealizeCursor( pScr= 0x%x, pCurs= 0x%x )\n",pScr,pCurs));
  441.     if (pCurs->devPriv[ pScr->myNum ]) {
  442.  
  443.     cur= (apa16Cursor *)pCurs->devPriv[ pScr->myNum ];
  444.     if (cur&&(!cur->next)) {
  445.         cur->next=    nextFree;
  446.         nextFree=    cur;
  447.         pCurs->devPriv[ pScr->myNum ]= NULL;
  448.     }
  449.     }
  450.     return TRUE;
  451. }
  452.  
  453. /***============================================================***/
  454.  
  455.     /*
  456.      *  Display (and track) the cursor described by "pCurs"
  457.      *  Copies the cursor image into the hardware active cursor
  458.      *  area.
  459.      *
  460.      *  If the cursor image has not already been copied into the
  461.      *  adapted off-screen memory (cursor is not "realized"), try
  462.      *  to realize it.  If the area reserved for cursor images is
  463.      *  full, print an error message and bail out.
  464.      *
  465.      *  After copying the cursor image, adjust ibmCursorHotX and 
  466.      *  ibmCursorHotY so that the cursor is displayed with it's
  467.      *  hot spot at the coordinates of mouse motion events.
  468.      *  Bearing in mind that we are tracking the cursor hot spot
  469.      *  (NOT the edges of the cursor), we have to adjust the
  470.      *  acceptable bounds (ibmCursorBounds) of the cursor so we bump 
  471.      *  the cursor image around at the right times).
  472.      */
  473.  
  474. int
  475. apa16DisplayCursor( pScr, pCurs )
  476.     ScreenPtr     pScr;
  477.     CursorPtr     pCurs;
  478. {
  479. apa16Cursor    *aCurs;
  480.  
  481.     TRACE(("apa16DisplayCursor( pScr= 0x%x, pCurs= 0x%x )\n",pScr,pCurs));
  482.     if ( ibmScreenState( pScr->myNum )==SCREEN_ACTIVE ) {
  483.     if (!(aCurs= (apa16Cursor*)pCurs->devPriv[ pScr->myNum ])) {
  484.         /* actually find someplace to store the cursor */
  485.         if (!(aCurs=nextFree)) { /* nothing free */
  486.         aCurs= TEMP_CURSOR;
  487.         }
  488.         else {
  489.         nextFree=       nextFree->next;
  490.         aCurs->next= NULL;
  491.         pCurs->devPriv[ pScr->myNum ]= (pointer)aCurs;
  492.         }
  493.         apa16CopyXCursor(pCurs,aCurs);
  494.     }
  495.     apa16CopyCursor(aCurs,ACTIVE_CURSOR);
  496.     }
  497.  
  498.     ibmCursorHotX(pScr->myNum)=        pCurs->bits->xhot;
  499.     ibmCursorHotY(pScr->myNum)=        pCurs->bits->yhot-CURSOR_HEIGHT;
  500.     ibmCurrentCursor(pScr->myNum)=    pCurs;
  501.     currentCursor= aCurs;
  502.  
  503.     apa16ShowCursor(CURRENT_X(),CURRENT_Y());
  504.     return TRUE;
  505. }
  506.  
  507. /***====================================================================***/
  508.  
  509. #define    CURS_SAVE_WIDTH    (2*CURSOR_WIDTH*MAXCURSORS)
  510. #define    CURS_SV_WIDTH_WDS    ((CURS_SAVE_WIDTH)/16)
  511.  
  512. static    unsigned short    apa16CursSave[CURS_SV_WIDTH_WDS*CURSOR_HEIGHT];
  513.  
  514. void
  515. apa16InvalidateCursor()
  516. {
  517. register apa16MemoryPtr    pSrc,pDst;
  518. register int         x,y;
  519.  
  520.     TRACE(("apa16InvalidateCursor()\n"));
  521.     pDst= apa16CursSave;
  522.     pSrc= SCREEN_ADDR(0,CURSOR_AREA_TOP);
  523.     QUEUE_WAIT();
  524.     y= CURSOR_HEIGHT;
  525.     while (y-->0) {
  526.     x= CURS_SV_WIDTH_WDS;
  527.     while (x-->0) {
  528.         *pDst++= *pSrc++;
  529.     }
  530.     pSrc+= ((APA16_WIDTH-CURS_SAVE_WIDTH)/16);
  531.     }
  532.     return;
  533. }
  534.  
  535. /***====================================================================***/
  536.  
  537. void
  538. apa16ReinitializeCursor()
  539. {
  540. register apa16MemoryPtr    pSrc,pDst;
  541. register int         x,y;
  542.  
  543.     TRACE(("apa16ReinitializeCursor()\n"));
  544.     pDst= SCREEN_ADDR(0,CURSOR_AREA_TOP);
  545.     pSrc= apa16CursSave;
  546.     QUEUE_WAIT();
  547.     y= CURSOR_HEIGHT;
  548.     while (y--) {
  549.     x= CURS_SV_WIDTH_WDS;
  550.     while (x--) {
  551.         *pDst++= *pSrc++;
  552.     }
  553.     pDst+= ((APA16_WIDTH-CURS_SAVE_WIDTH)/16);
  554.     }
  555.     apa16ShowCursor(CURRENT_X(),CURRENT_Y());
  556.     return;
  557. }
  558.