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

  1. /*
  2.  * Copyright IBM Corporation 1987,1988,1989
  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. #ifndef lint
  25. static char *rcsid = "$Id: mpelCursor.c,v 5.0 1992/02/06 13:49:48 jfc Exp jfc $";
  26. #endif
  27.  
  28. /*
  29.  * xcursor.c -- software cursor
  30.  */
  31.  
  32. #include "X.h"
  33. #include "Xproto.h"
  34. #include "cursorstr.h"
  35. #include "misc.h"
  36. #include "scrnintstr.h"
  37. #include "colormapst.h"
  38. #include "pixmapstr.h"
  39.  
  40. #include "OScompiler.h"
  41.  
  42. #include "ibmScreen.h"
  43. #include "ibmColor.h"
  44.  
  45. #ifdef PGC
  46. #include "pgc.h"
  47. extern pgcScreenRec pgcScreenInfo[]; 
  48. #define    CMAP(scr) pgcScreenInfo[scr->myNum].InstalledColormap
  49. #else
  50. #include "ppc.h"
  51. #define    CMAP(scr) ((ppcScrnPriv *)scr->devPrivate)->InstalledColormap
  52. #endif
  53.  
  54. #include "mpel.h"
  55. #include "mpelHdwr.h"
  56. #include "mpelFifo.h"
  57.  
  58. #include "ibmTrace.h"
  59.  
  60. #define    CURSOR_MAX_SIZE        ((32 / 8) * 32)
  61.  
  62. static void mpel4x4();
  63.  
  64. /* Global Cursor State Semaphore */
  65. int mpelcursorSemaphore = 0;
  66.  
  67. static int screen_index;
  68. static short c_x;
  69. static short c_y;
  70. static int cursor_not_displayed = TRUE;
  71. static int cursor_is_valid = FALSE;
  72. static mpelRectangle last_save;
  73.  
  74. /*** ==================================================================***/
  75.  
  76. /*
  77.  * mpelPutCursorOn( x, y )
  78.  */
  79.  
  80. static void
  81. mpelPutCursorOn( x, y )
  82.     register short int x, y;
  83. {
  84.     register CursorPtr curCursor;
  85.     register unsigned int byteSize;
  86.     int w, h;
  87.     mpelVPMBLTDestination saveBlit;
  88.  
  89.     if ( ibmScreenState( screen_index ) != SCREEN_ACTIVE )
  90.     return;
  91.  
  92.     curCursor = ibmCurrentCursor( screen_index );
  93.     if (x >= MPEL_WIDTH || (x + curCursor->bits->width) < 0)
  94.       return;        /* off the screen, don't bother */
  95.  
  96.     MPELSetPlaneMask(0);
  97.  
  98.     h = MIN(curCursor->bits->height, 32);
  99.     w = (curCursor->bits->width > 16) ? 32 : 16;
  100.     byteSize = (w >> 3) * h;
  101.  
  102.     /* Save The Existing Image */
  103.     saveBlit.destaddr = mpelAddr( MPEL_CURSOR_SAVE );
  104.     saveBlit.source.lleft.x = x;
  105.     saveBlit.source.lleft.y = MPEL_HEIGHT - h - y;
  106.     saveBlit.source.uright.x = x + w - 1;
  107.     saveBlit.source.uright.y = MPEL_HEIGHT - 1 - y;
  108.     saveBlit.comp = 0x0001;
  109.     last_save = saveBlit.source;
  110.  
  111.     MPELVPMBLTDest(&saveBlit);
  112.  
  113.     if (x > MPEL_WIDTH - w || x < w || y < h || y > MPEL_HEIGHT - h) {
  114.       mpelBLTImmedWColorExpansion cursorBlit;
  115.  
  116.       cursorBlit.dest.lleft.x  = x;
  117.       cursorBlit.dest.lleft.y  = MPEL_HEIGHT - h - y;
  118.       cursorBlit.dest.uright.x = x + 31;
  119.       cursorBlit.dest.uright.y = MPEL_HEIGHT - 1 - y;
  120.       cursorBlit.alu = GXcopy + 1;
  121.       cursorBlit.color = ((unsigned int *)curCursor->devPriv[screen_index])[0];
  122.  
  123.       /* round width up to 32 for byteSize */
  124.       if(w < 32)
  125.     byteSize = 4 * h;
  126.       MPELBLTImmedWColorExpansion(byteSize, &cursorBlit);
  127.       if(x + w > MPEL_WIDTH)
  128.     {
  129.       int i;
  130.       unsigned int mask = (-1) << ((x + w) - MPEL_WIDTH);
  131.       int xxx[32];
  132.  
  133.       if(w == 16)
  134.         mask <<= 16;
  135.       for(i = 0;i < h;i++)
  136.         xxx[i] = ((unsigned int *)curCursor->bits->devPriv[screen_index])[64+i]&mask;
  137.       MPELSendData(byteSize, xxx);
  138.       cursorBlit.color =
  139.         ((unsigned int *)curCursor->devPriv[screen_index])[1];
  140.       MPELBLTImmedWColorExpansion(byteSize, &cursorBlit);
  141.       for(i = 0;i < h;i++)
  142.         xxx[i] = ((unsigned int *)curCursor->bits->devPriv[screen_index])[96+i]&mask;
  143.       MPELSendData(byteSize, xxx);
  144.     } else {
  145.       MPELSendData(byteSize,
  146.                (char *)curCursor->bits->devPriv[screen_index]+256);
  147.       cursorBlit.color =
  148.         ((unsigned int *)curCursor->devPriv[screen_index])[1];
  149.       MPELBLTImmedWColorExpansion(byteSize, &cursorBlit);
  150.       MPELSendData(byteSize,
  151.                (char *)curCursor->bits->devPriv[screen_index]+384);
  152.     }
  153.     } else {
  154.       mpelBLTImmed4x4WColorExpansion cursorBlit;
  155.  
  156.       h = (h + 3) & ~3;
  157.       byteSize = (w >> 3) * h;
  158.       cursorBlit.dest.lleft.x = x;
  159.       cursorBlit.dest.lleft.y = MPEL_HEIGHT - h - y;
  160.       cursorBlit.dest.uright.x = x + w - 1;
  161.       cursorBlit.dest.uright.y = MPEL_HEIGHT - 1 - y;
  162.       cursorBlit.color = ((unsigned int *)curCursor->devPriv[screen_index])[0];
  163.       
  164.       MPELBLTImmed4x4WColorExpansion(byteSize, &cursorBlit);
  165.       MPELSendData(byteSize,
  166.            (unsigned short *)curCursor->bits->devPriv[screen_index]);
  167.       
  168.       cursorBlit.color = ((unsigned int *)curCursor->devPriv[screen_index])[1];
  169.       MPELBLTImmed4x4WColorExpansion(byteSize, &cursorBlit);
  170.       MPELSendData(byteSize,
  171.            (unsigned short *)curCursor->bits->devPriv[screen_index] + 64);
  172.     }
  173.     /* Cursor Is Now Active */
  174.     cursor_not_displayed = 0;
  175.     return;
  176. }
  177.  
  178. /*** ==================================================================***/
  179.  
  180. int
  181. mpelRemoveCursor()
  182. {
  183.     if (!cursor_not_displayed
  184.       && (ibmScreenState(screen_index) == SCREEN_ACTIVE)) {
  185.     register CursorPtr curCursor;
  186.     mpelSrcBLTVPM blt;
  187.  
  188.     MPELSetPlaneMask(0);
  189.  
  190.     curCursor = ibmCurrentCursor(screen_index);
  191.     blt.srcaddr = mpelAddr(MPEL_CURSOR_SAVE);
  192.     blt.dest = last_save;
  193.     blt.bpixel = 0x0008;
  194.     blt.alu = GXcopy + 1;
  195.  
  196.     MPELSrcBLTVPM(&blt);
  197.     }
  198.  
  199.     return cursor_not_displayed = TRUE;
  200. }
  201.  
  202. /*** ==================================================================***/
  203.  
  204. void
  205. mpelShowCursor( x, y )
  206.     register short x, y;
  207. {
  208. register CursorPtr curCursor = ibmCurrentCursor( screen_index );
  209.  
  210.     if ( ibmScreenState( screen_index ) != SCREEN_ACTIVE ) {
  211.     c_x = x - curCursor->bits->xhot;
  212.     c_y = y - curCursor->bits->yhot;
  213.     }
  214.     if ( !cursor_not_displayed ) {
  215.     (void) mpelRemoveCursor();
  216.     x -= curCursor->bits->xhot;
  217.     y -= curCursor->bits->yhot;
  218.     }
  219.     c_x = x;
  220.     c_y = y;
  221.     if ( cursor_is_valid )
  222.     mpelPutCursorOn( x, y );
  223.     return;
  224. }
  225.  
  226. /*** ================================================================== ***/
  227.  
  228. /* check if the cursor is in this rectangle.  if so, remove and return TRUE
  229.     else return FALSE */
  230. int
  231. mpelCheckCursor(x, y, lx, ly)
  232. register const int x, y, lx, ly;
  233. {
  234. register CursorPtr curCursor = ibmCurrentCursor(screen_index);
  235.  
  236. if (!mpelcursorSemaphore && !cursor_not_displayed 
  237.   && (ibmScreenState(screen_index) == SCREEN_ACTIVE)
  238.   && !(( x >= ( c_x + (curCursor->bits->width > 16 ? 32 : 16)))
  239.      || (y >= ( c_y + MIN(curCursor->bits->height, 32)))
  240.      || (( x + lx ) <= c_x)
  241.      || (( y + ly ) <= c_y)))
  242.     return mpelRemoveCursor();
  243. else
  244.     return FALSE;
  245. /*NOTREACHED*/
  246. }
  247.  
  248. /*** ==================================================================***/
  249.  
  250. void mpelReplaceCursor()
  251. {
  252.  
  253. if (cursor_not_displayed && !mpelcursorSemaphore &&
  254.     ibmScreenState(screen_index) == SCREEN_ACTIVE)
  255.     mpelShowCursor(c_x, c_y);
  256.  
  257. return;
  258. }
  259.  
  260. /*** ==================================================================***/
  261.  
  262. void mpelRecolorCursor(pScr, pCurs, displayed)
  263. ScreenPtr pScr;
  264. CursorPtr pCurs;
  265. Bool displayed;
  266. {
  267.   TRACE(("mpelRecolorCursor(%#x, %#x, %d)\n", pScr, pCurs, displayed));
  268.   if(displayed)
  269.     mpelDisplayCursor(pScr, pCurs);
  270. }
  271.  
  272.  
  273. static void
  274. mpelCursorColormap(pCurs, cmap, pScrn)
  275.     register ColormapPtr cmap;
  276.     register CursorPtr pCurs;
  277.     ScreenPtr pScrn;
  278. {
  279.     xColorItem c;
  280.     register int scrn;
  281.     if (pScrn)
  282.       scrn = pScrn->myNum;
  283.     else
  284.       scrn = screen_index;
  285.     if(pCurs == NULL)
  286.       {
  287.     pCurs = ibmCurrentCursor(scrn);
  288.     if (pCurs == NULL)
  289.       {
  290.         ErrorF("mpelCursorColormap: no cursor\n");
  291.         return;
  292.       }
  293.       }
  294.     if(pCurs->devPriv[scrn] == NULL)
  295.       {
  296.     ErrorF("mpelCursorColormap: cursor unrealized\n");
  297.     return;
  298.       }
  299.  
  300.     c.pixel = 0;
  301.     c.red = pCurs->foreRed;
  302.     c.green = pCurs->foreGreen;
  303.     c.blue = pCurs->foreBlue;
  304.     c.flags = DoRed | DoGreen | DoBlue;
  305.     FakeAllocColor(cmap, &c);
  306.     ((unsigned int *)pCurs->devPriv[scrn])[0] = c.pixel;
  307.     FakeFreeColor(cmap, c.pixel);
  308.     c.red = pCurs->backRed;
  309.     c.green = pCurs->backGreen;
  310.     c.blue = pCurs->backBlue;
  311.     FakeAllocColor(cmap, &c);
  312.     ((unsigned int *)pCurs->devPriv[scrn])[1] = c.pixel;
  313.     FakeFreeColor(cmap, c.pixel);
  314.     return;
  315. }
  316.  
  317. void mpel_ppcRecolorCursor(cmap)
  318.     ColormapPtr cmap;
  319. {
  320.     mpelCursorColormap(0, cmap, 0);
  321. }
  322.  
  323. /* ************************************************************************** */
  324.  
  325. void
  326. mpelCursorInit( index )
  327. register int index;
  328. {
  329.     TRACE( ( "mpelCursorInit()\n" ));
  330.  
  331.     ibmCursorShow( index ) = mpelShowCursor;
  332.  
  333.     ibmCurrentCursor( index ) = NULL;
  334.     cursor_is_valid = FALSE;
  335.  
  336.     screen_index = index;
  337.  
  338.     c_x = 0;
  339.     c_y = 0;
  340.     mpelcursorSemaphore = 0;
  341.     cursor_not_displayed = TRUE;
  342.     return;
  343. }
  344.  
  345. /*** ============================================================***/
  346.  
  347. Bool
  348. mpelRealizeCursor( pScr, pCurs )
  349.     register ScreenPtr    pScr;
  350.     register CursorPtr    pCurs;
  351. {
  352.     register unsigned long int *pFG, *pBG;
  353.     register unsigned long int *psrcImage;
  354.     register unsigned long int *psrcMask;
  355.     register int i;
  356.     register unsigned long int endbits;
  357.     int srcWidth;
  358.     int srcHeight;
  359.     int srcRealWidth;
  360.     char *tmpbits;
  361.  
  362.     if (pCurs == 0)
  363.       {
  364.     ErrorF("mpelRealizeCursor: no cursor\n");
  365.     return FALSE;
  366.       }
  367.     if (!(pCurs->bits->devPriv[pScr->myNum] = (pointer) Xalloc(512)) ||
  368.     !(pCurs->devPriv[pScr->myNum] = (pointer) Xalloc(8)))
  369.       {
  370.     pCurs->bits->devPriv[pScr->myNum] = 0;
  371.     ErrorF("mpelRealizeCursor: can't malloc\n");
  372.     return FALSE;
  373.       }
  374.     TRACE(("mpelRealizeCursor(pScr=0x%x,pCurs=0x%x) {devPriv[%d] = %#x, %#x}\n",
  375.        pScr, pCurs, pScr->myNum, pCurs->devPriv[pScr->myNum], 
  376.        pCurs->bits->devPriv[pScr->myNum]));
  377.  
  378.     tmpbits = (char *)pCurs->bits->devPriv[pScr->myNum] + 256;
  379.     bzero(tmpbits, 256);
  380.     pFG = (unsigned long *) tmpbits;
  381.     pBG = pFG + 32;
  382.     psrcImage = (unsigned long int *) pCurs->bits->source;
  383.     psrcMask = (unsigned long int *) pCurs->bits->mask;
  384.     srcRealWidth = ( pCurs->bits->width + 31 ) / 32;
  385.  
  386.     srcWidth = MIN( pCurs->bits->width, 32 );
  387.     srcHeight = MIN( pCurs->bits->height, 32 );
  388.  
  389.     endbits = -1 << ( 32 - srcWidth );
  390.  
  391.     for ( i = srcHeight; i-- ; )
  392.       {
  393.     *pFG++ = (*psrcMask & endbits) & *psrcImage;
  394.     *pBG++ = (*psrcMask & endbits) & ~ *psrcImage;
  395.     psrcImage = psrcImage + srcRealWidth;
  396.     psrcMask = psrcMask + srcRealWidth;
  397.       }
  398.     mpel4x4(tmpbits, srcWidth, srcHeight,
  399.         (unsigned short *)pCurs->bits->devPriv[pScr->myNum]);
  400.     mpel4x4(tmpbits+128, srcWidth, srcHeight,
  401.         (unsigned short *)pCurs->bits->devPriv[pScr->myNum] + 64);
  402.     mpelCursorColormap(pCurs, CMAP(pScr), pScr);
  403.     TRACE(("exiting mpelRealizeCursor\n"));
  404.     return TRUE;
  405. }
  406.  
  407. /*** ============================================================***/
  408.  
  409. Bool
  410. mpelUnrealizeCursor( pScr, pCurs )
  411.     register ScreenPtr     pScr;
  412.     register CursorPtr     pCurs;
  413. {
  414.  
  415.     TRACE(("mpelUnrealizeCursor(pScr=0x%x,pCurs=0x%x)\n", pScr, pCurs));
  416.  
  417.     if(pCurs == ibmCurrentCursor(pScr->myNum))
  418.       {
  419.     TRACE(("\tcursor %#x busy.\n", pCurs));
  420.     return FALSE;
  421.       }
  422.     if(pCurs->bits->refcnt <= 1)
  423.       {
  424.     Xfree((char *)pCurs->bits->devPriv[pScr->myNum]);
  425.     pCurs->bits->devPriv[ pScr->myNum ] = 0;
  426.       }
  427.     Xfree((char *) pCurs->devPriv[pScr->myNum]);
  428.     pCurs->devPriv[pScr->myNum] = 0;
  429.     if ( ibmCurrentCursor( pScr->myNum ) == pCurs )
  430.     cursor_is_valid = FALSE;
  431.     return TRUE;
  432. }
  433.  
  434. /*** ============================================================***/
  435.  
  436. Bool
  437. mpelDisplayCursor( pScr, pCurs )
  438.     ScreenPtr    pScr;
  439.     CursorPtr    pCurs;
  440. {
  441.     register int i;
  442.  
  443.     TRACE(("mpelDisplayCursor(%#x, %#x) {%#x, %#x}\n",
  444.        pScr, pCurs,
  445.        pCurs->devPriv[pScr->myNum], pCurs->bits->devPriv[pScr->myNum]));
  446.     /* cleanup old cursor */
  447.  
  448.     if ( cursor_is_valid ) {
  449.     CursorPtr curCursor;
  450.  
  451.     if ( !cursor_not_displayed )
  452.         (void) mpelRemoveCursor();
  453.     curCursor = ibmCurrentCursor( pScr->myNum );
  454.     c_x += curCursor->bits->xhot;
  455.     c_y += curCursor->bits->yhot;
  456.     }
  457.     i = pScr->myNum;
  458.     TRACE(("\tscreen %d, bits %#x\n", i, pCurs->bits));
  459.     ibmCurrentCursor( i ) = pCurs;
  460.     ibmCursorHotX( i ) = pCurs->bits->xhot;
  461.     ibmCursorHotY( i ) = pCurs->bits->yhot;
  462.     mpelCursorColormap(pCurs, CMAP(pScr), pScr);
  463.     c_x -= pCurs->bits->xhot;
  464.     c_y -= pCurs->bits->yhot;
  465.     mpelPutCursorOn( c_x, c_y );
  466.     return cursor_is_valid = TRUE;
  467. }
  468.  
  469. /*** ==================================================================***/
  470.  
  471. void
  472. mpelRevalidateCursor()
  473. {
  474.     cursor_not_displayed = FALSE;
  475.     if ( cursor_is_valid )
  476.     mpelPutCursorOn( c_x, c_y );
  477.     return;
  478. }
  479.  
  480. /* Take a pointer to bitmap data, and format it into a set of 4x4 blocks
  481.  * suitable for use with mpel blt vpm 4x4 w/ color expansion.
  482.  *
  483.  * bits -- source data
  484.  * dst  -- where to put formatted bits (round up size to multiple of 4)
  485.  * sw, sh -- source dimensions
  486.  */
  487.  
  488. static void mpel4x4(bits, sw, sh, dst)
  489. char *bits;
  490. short *dst;
  491. int sw, sh;
  492. {
  493.   int dw = (sw + 15) & ~15;
  494.   int dh = (sh + 15) & ~15;
  495.   int xc, yc;
  496.   int src_al = (sw / 8 + 3) & ~3;
  497.  
  498.   TRACE(("mpel4x4(%#x, %d, %d, %#x) src_al %d dw %d dh %d\n",
  499.      bits, sw, sh, dst, src_al, dw, dh));
  500.  
  501.   bzero((char *)dst, 128);
  502.   
  503.   if(sh & 3)
  504.     {
  505.       yc = (sh & ~3);
  506.       for(xc = 0; xc < (dw >> 3); xc++)
  507.     {
  508.       register unsigned int i;
  509.       union { unsigned int i;
  510.           unsigned char c[4];
  511.         } u;
  512.       u.i = 0;
  513.       switch(sh & 3)
  514.         {
  515.         case 3:
  516.           u.c[2] = *(bits + xc + (yc + 2) * src_al);
  517.         case 2:
  518.           u.c[1] = *(bits + xc + (yc + 1) * src_al);
  519.         case 1:
  520.           u.c[0] = *(bits + xc + yc * src_al);
  521.         }
  522.       i = u.i;
  523.       *dst++ = ((i & 0xf0000000) >> 16) | ((i & 0x00f00000) >> 12) |
  524.         ((i & 0x0000f000) >> 8) | ((i & 0x000000f0) >> 4);
  525.       *dst++ = ((i & 0x0f000000) >> 12) | ((i & 0x000f0000) >> 8) |
  526.         ((i & 0x00000f00) >> 4) | (i & 0x0000000f);
  527.     }
  528.     }
  529.   for(yc = ((sh-4)&~3); yc >= 0; yc -= 4)
  530.     {
  531.       register int yaddr;    /* y * src_al */
  532.       yaddr = yc * src_al;
  533.       for(xc = 0; xc < (dw>>3); xc++)
  534.     {
  535.       register unsigned int i;
  536.       union { unsigned int i;
  537.           unsigned char c[4];
  538.         } u;
  539.       
  540.       u.c[0] = *(bits + xc + yaddr);
  541.       u.c[1] = *(bits + xc + yaddr + src_al);
  542.       u.c[2] = *(bits + xc + yaddr + 2 * src_al);
  543.       u.c[3] = *(bits + xc + yaddr + 3 * src_al);
  544.       i = u.i;
  545.       *dst++ = ((i & 0xf0000000) >> 16) | ((i & 0x00f00000) >> 12) |
  546.         ((i & 0x0000f000) >> 8) | ((i & 0x000000f0) >> 4);
  547.       *dst++ = ((i & 0x0f000000) >> 12) | ((i & 0x000f0000) >> 8) |
  548.         ((i & 0x00000f00) >> 4) | (i & 0x0000000f);
  549.     }
  550.     }
  551. }
  552.