Annotation of 43BSDTahoe/new/X/libibm/bitblt/bitblt.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *rcsid_bitblt_c = "$Header: bitblt.c,v 10.1 86/11/19 10:50:19 jg Exp $";
        !             3: #endif lint
        !             4: /*
        !             5:  *             Copyright (c) 1986 Brown University
        !             6:  *
        !             7:  * Permission to use, copy, modify and distribute this software and its
        !             8:  * documentation for any purpose and without fee is hereby granted, provided
        !             9:  * that the above copyright notice appear in all copies, and that both
        !            10:  * that copyright notice and this permission notice appear in supporting
        !            11:  * documentation, and that the name of Brown University not be used in
        !            12:  * advertising or publicity pertaining to distribution of the software without
        !            13:  * specific, written prior permission. Brown University makes no
        !            14:  * representations about the suitability of this software for any purpose.
        !            15:  * It is provided "as-is" without express or implied warranty.
        !            16:  *
        !            17:  * Written by Daniel Stone, Brown University/IRIS November 21, 1985 and
        !            18:  * "enhanced" a number of times since.
        !            19:  *
        !            20:  * ABOUT BITBLT.C:  This program and related 'C' files (bitblt_int.h,
        !            21:  * bitblt_subr.c, bitblt_apa16.c, bitblt_apa16.h) were originally written to go
        !            22:  * into the Unix 4.2 kernel as a "bitblt" driver.  Later we were able
        !            23:  * to put in some ifdef's and use it for Smalltalk and X.  Whatever
        !            24:  * version you have, there may be some strange ifdef's that may not
        !            25:  * make any sense at all.  We tried to remove all ifdef's not relevant
        !            26:  * to the system being compiled but then no one's perfect.
        !            27:  * Also some strange things are done to support the APA8, APA8C and the AED
        !            28:  * (viking).  You will encounter ifdef's for all these things.  if you define
        !            29:  * all the screens (-DAED -DAPA8 -DAPA16 ... on the compile line) the bitblt
        !            30:  * routine will work on every screen.
        !            31:  */
        !            32: 
        !            33: #include "bitblt_int.h"
        !            34: 
        !            35: #ifdef USE_APA16_HDWR
        !            36: #include "bitblt_apa16.h"
        !            37: #endif
        !            38: 
        !            39: #ifdef BLT_DEBUG
        !            40: int blt_debug = 0;
        !            41: #endif
        !            42: 
        !            43: #define MSK_SKEW 0x01
        !            44: #define SRC_SKEW 0x02
        !            45: 
        !            46: Blt_sysdata blt_info;          /* internal variables used by bitblt() */
        !            47: Blt_Rectangle changed_rect;    /* describes the area changed by the bltter */
        !            48: 
        !            49: /*
        !            50:  * Array of short masks used to compute the masks to mask out the edges
        !            51:  * of the destination that should not be affected.  A one means that bit
        !            52:  * in the destination can be changed.  The values in leftMasks are set up 
        !            53:  * to be used with the left edge and the values in rightMasks are to be used
        !            54:  * in right edge. 
        !            55:  */
        !            56: static unsigned short leftMasks[] = {
        !            57:        0xffff,0x7fff,0x3fff,0x1fff,0x0fff,0x07ff,0x03ff,0x01ff,
        !            58:        0x00ff,0x007f,0x003f,0x001f,0x000f,0x0007,0x0003,0x0001,
        !            59:        0x0000
        !            60: };
        !            61: 
        !            62: static unsigned short rightMasks[] = {
        !            63:        0xffff,0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,
        !            64:        0xff00,0xff80,0xffc0,0xffe0,0xfff0,0xfff8,0xfffc,0xfffe,
        !            65:        0x0000
        !            66: };
        !            67: 
        !            68: static Blt_Tile white = {
        !            69:        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        !            70:        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        !            71: };
        !            72: static Blt_Tile black = {
        !            73:        0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
        !            74:        0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
        !            75: };
        !            76:  
        !            77: /*
        !            78:  * Defines used to indicate whether 1 or 2 source words are needed to make
        !            79:  * the first destination word.
        !            80:  * NOTE: Changing the value of MUST_PRIME may have bad side effects because
        !            81:  *      the variable "preload_src" is added to something in calculateOffsets.
        !            82:  *      THIS IS SEMI-HOOKY BUT IT WORKS.
        !            83:  */
        !            84: #define MUST_PRIME 1
        !            85: #define DONT_PRIME 0
        !            86: 
        !            87: #define SAVE_LOCATOR() {                                               \
        !            88:        if (blt_cur_screen.cursortype & SOFT_CURSOR) {                  \
        !            89:                saved_loc = 0;                                          \
        !            90:                if (IS_SCREEN(u_info->dst_bitmap)) {                    \
        !            91:                        if (sys_info->is_src && IS_SCREEN(u_info->src_bitmap)){\
        !            92:                                saved_loc = 1;                          \
        !            93:                                save_cursor(MIN(sys_info->dst.rect.origin_x,  \
        !            94:                                               sys_info->src.rect.origin_x),  \
        !            95:                                            MIN(sys_info->dst.rect.origin_y,  \
        !            96:                                               sys_info->src.rect.origin_y),  \
        !            97:                                            MAX(sys_info->dst.rect.corner_x,  \
        !            98:                                               sys_info->src.rect.corner_x)+1,\
        !            99:                                            MAX(sys_info->dst.rect.corner_y,  \
        !           100:                                               sys_info->src.rect.corner_y)+1);\
        !           101:                        }                                               \
        !           102:                        else {                                          \
        !           103:                                saved_loc = 1;                          \
        !           104:                                save_cursor(sys_info->dst.rect.origin_x,     \
        !           105:                                            sys_info->dst.rect.origin_y,     \
        !           106:                                            sys_info->dst.rect.corner_x + 1, \
        !           107:                                            sys_info->dst.rect.corner_y + 1);\
        !           108:                        }                                               \
        !           109:                }                                                       \
        !           110:                else if (sys_info->is_src && IS_SCREEN(u_info->src_bitmap)) { \
        !           111:                        saved_loc = 1;                                  \
        !           112:                        save_cursor(sys_info->src.rect.origin_x,        \
        !           113:                                    sys_info->src.rect.origin_y,        \
        !           114:                                    sys_info->src.rect.corner_x + 1,    \
        !           115:                                    sys_info->src.rect.corner_y + 1);   \
        !           116:                }                                                       \
        !           117:        }                                                               \
        !           118: }
        !           119: 
        !           120: #define RESTORE_LOCATOR() {                                            \
        !           121:        if ((blt_cur_screen.cursortype & SOFT_CURSOR) && saved_loc) {   \
        !           122:                restore_cursor();                                       \
        !           123:        }                                                               \
        !           124: }
        !           125: 
        !           126: /*
        !           127:  * Macros to calculate the skew and preload flag depending on the direction
        !           128:  * of the blt.
        !           129:  */
        !           130: #define computeSkewPos(SI) {                                   \
        !           131:        if ((MOD_BPW(SI->dst.rect.origin_x))<(MOD_BPW(SI->src.rect.origin_x))){\
        !           132:                SI->skew_src = MOD_BPW(SI->src.rect.origin_x) - \
        !           133:                               MOD_BPW(SI->dst.rect.origin_x);  \
        !           134:                SI->preload_src = MUST_PRIME;                   \
        !           135:        }                                                       \
        !           136:        else {                                                  \
        !           137:                SI->skew_src = BPW - (MOD_BPW(SI->dst.rect.origin_x) -  \
        !           138:                               MOD_BPW(SI->src.rect.origin_x));         \
        !           139:                 SI->preload_src = DONT_PRIME;                  \
        !           140:        }                                                       \
        !           141: }
        !           142: 
        !           143: #define computeSkewMskPos(SI) {                                                \
        !           144:        if ((MOD_BPW(SI->dst.rect.origin_x))<(MOD_BPW(SI->msk.rect.origin_x))){\
        !           145:                SI->skew_msk = MOD_BPW(SI->msk.rect.origin_x) -         \
        !           146:                               MOD_BPW(SI->dst.rect.origin_x);          \
        !           147:                SI->preload_msk = MUST_PRIME;                           \
        !           148:        }                                                               \
        !           149:        else {                                                          \
        !           150:                SI->skew_msk = BPW - (MOD_BPW(SI->dst.rect.origin_x) -  \
        !           151:                               MOD_BPW(SI->msk.rect.origin_x));         \
        !           152:                 SI->preload_msk = DONT_PRIME;                          \
        !           153:        }                                                               \
        !           154: }
        !           155: 
        !           156: #define computeSkewNeg(SI) {                                           \
        !           157:        if ((MOD_BPW(SI->dst.rect.corner_x))>(MOD_BPW(SI->src.rect.corner_x))){\
        !           158:                SI->skew_src = MOD_BPW(SI->dst.rect.corner_x) -         \
        !           159:                               MOD_BPW(SI->src.rect.corner_x);          \
        !           160:                    SI->preload_src = MUST_PRIME;                       \
        !           161:        }                                                               \
        !           162:        else {                                                          \
        !           163:                SI->skew_src = BPW - (MOD_BPW(SI->src.rect.corner_x) -  \
        !           164:                               MOD_BPW(SI->dst.rect.corner_x));         \
        !           165:                SI->preload_src = DONT_PRIME;                           \
        !           166:        }                                                               \
        !           167: }
        !           168: 
        !           169: #define computeSkewMskNeg(SI) {                                                \
        !           170:        if ((MOD_BPW(SI->dst.rect.corner_x))>(MOD_BPW(SI->msk.rect.corner_x))){\
        !           171:                SI->skew_msk = MOD_BPW(SI->dst.rect.corner_x) -         \
        !           172:                               MOD_BPW(SI->msk.rect.corner_x);          \
        !           173:                SI->preload_msk = MUST_PRIME;                           \
        !           174:        }                                                               \
        !           175:        else {                                                          \
        !           176:                SI->skew_msk = BPW - (MOD_BPW(SI->msk.rect.corner_x) -  \
        !           177:                               MOD_BPW(SI->dst.rect.corner_x));         \
        !           178:                SI->preload_msk = DONT_PRIME;                           \
        !           179:        }                                                               \
        !           180: }
        !           181: 
        !           182: /*
        !           183:  * Make a mask for the first and last destination word in each scanline.
        !           184:  * 1's mean those bits can be changed in the destination.
        !           185:  * Combine the masks if only one destination word is effected and set
        !           186:  * BOTH masks equal to it so as not to screw up copyBitNeg. 
        !           187:  *
        !           188:  * NOTE: The +1 with dst.rect.corner_x. This is because dst.rect.corner_x was
        !           189:  *       set to the rectangle size -1. (see blt_setup())
        !           190:  */
        !           191: #define computeMasks(SI) {                                             \
        !           192:        if (SI->nshorts == 1) {                                         \
        !           193:                SI->right_mask = SI->left_mask =                        \
        !           194:                                 leftMasks[MOD_BPW(SI->dst.rect.origin_x)] &\
        !           195:                                 rightMasks[MOD_BPW(SI->dst.rect.corner_x+1)];\
        !           196:        }                                                               \
        !           197:        else {                                                          \
        !           198:                SI->left_mask = leftMasks[MOD_BPW(SI->dst.rect.origin_x)];\
        !           199:                SI->right_mask = rightMasks[MOD_BPW(SI->dst.rect.corner_x+1)];\
        !           200:        }                                                               \
        !           201: }
        !           202: 
        !           203: /*
        !           204:  * CheckOverlap checks for overlapping source and destination. 
        !           205:  * (See checkOverlap in Smalltalk-80)  It set SI->top_to_bot to
        !           206:  * non-zero if we must copy from bottom to top, right to left
        !           207:  * instead of top to bottom, left to right.
        !           208:  *
        !           209:  * NOTE: The +1 for both src.rect.corner_y and src.rect.corner_x this is because
        !           210:  *       these local variables have "closed" corners. (See blt_setup())
        !           211:  *
        !           212:  * IF the destination and source have the same bitmap
        !           213:  *                        AND 
        !           214:  *           TEST AREA 1  OR  TEST AREA 2
        !           215:  * THEN
        !           216:  *             (We must copy from right to left bottom to top)
        !           217:  *
        !           218:  *    TEST AREA 1:  The destination top is GREATER than or EQUAL to the
        !           219:  *                  source top and its less than the source bottom
        !           220:  *            (src.rect.origin_y <= dst.rect.origin_y < src.rect.corner_y+1) AND
        !           221:  *                 the destination left is greater than or equal to
        !           222:  *                  the source left and its less than the source right.
        !           223:  *           (src.rect.origin_x <= dst.rect.origin_x < src.rect.corner_x+1)
        !           224:  *                 IN OTHER WORDS, the top left corner of the destination
        !           225:  *                 is in the source area.
        !           226:  *
        !           227:  *    TEST AREA 2:  The destination top is GREATER than the source top 
        !           228:  *                  and its less than the source bottom:
        !           229:  *                 (src.rect.origin_y < dst.rect.origin_y < src.rect.corner_y+1)
        !           230:  *                  AND the source left is greater than the destination left
        !           231:  *                  and its less than the destination right.
        !           232:  *                 (dst.rect.origin_x < src.rect.origin_x < dst.rect.corner_x+1)
        !           233:  *                 IN OTHER WORDS, the top horizontal line of the destination
        !           234:  *                 intersects the left vertical line of the source, causing
        !           235:  *                 the right top corner of the destination to be in the
        !           236:  *                 source.
        !           237:  *
        !           238:  *                              src.rect.origin_x
        !           239:  *                              src.rect.origin_y +----------------------------
        !           240:  *   src.rect.origin_y - 1  -----------------------|
        !           241:  *                                                 |
        !           242:  *                           TEST AREA 2          |    TEST AREA 1
        !           243:  *                                                 |
        !           244:  *                                                 |
        !           245:  *    src.rect.corner_y+1   ------------------------------------------------
        !           246:  */
        !           247: #define checkOverlap(UI,SI) \
        !           248:        SI->top_to_bot = ((UI->src_bitmap.base == UI->dst_bitmap.base)  \
        !           249:                  && (((SI->src.rect.origin_y <= SI->dst.rect.origin_y &&\
        !           250:                        SI->dst.rect.origin_y < (SI->src.rect.corner_y+1))\
        !           251:                  && (SI->src.rect.origin_x <= SI->dst.rect.origin_x && \
        !           252:                        SI->dst.rect.origin_x < (SI->src.rect.corner_x+1)))\
        !           253:                  || ((SI->src.rect.origin_y < SI->dst.rect.origin_y && \
        !           254:                        SI->dst.rect.origin_y < (SI->src.rect.corner_y+1))\
        !           255:                  && (SI->dst.rect.origin_x < SI->src.rect.origin_x &&  \
        !           256:                        SI->src.rect.origin_x < (SI->dst.rect.corner_x+1)))))
        !           257: 
        !           258: /*
        !           259:  * CalculateOffsetDst sets up pointers to a word in the destination and
        !           260:  * possibly to the mask bitmap using the dst_x,dst_y points given.
        !           261:  * It calculates the increment for each pointer from the end of one 
        !           262:  * rectangle scanline to the beginning of the next.
        !           263:  */
        !           264: calculateOffsetDst(u_info,s_info,dst_x,dst_y)
        !           265: register Blt_userdata *u_info;
        !           266: register Blt_sysdata *s_info;
        !           267: short  dst_x,dst_y; /* top,left or bottom,right */
        !           268: {
        !           269:        /*
        !           270:         * Set up the destination pointer and increment.
        !           271:         * NOTE that (dst_y * u_info->dst_bitmap.nshorts) + DIV_BPW(dst_x)
        !           272:         * gives the WORD offset to base.  Since we need the byte address
        !           273:         * this quantity must be multiplied by 2 (MUL_2).
        !           274:         *
        !           275:         * Set up destination to point to a word offset from the base address.
        !           276:         */
        !           277: #if (APA8 || APA8C)
        !           278:        if (IS_APA8orAPA8C(u_info->dst_bitmap)) {
        !           279:                s_info->dst_plus = 4;
        !           280:                s_info->dst.data = (unsigned short *)(
        !           281:                                   (long)u_info->dst_bitmap.base +
        !           282:                                   MUL_4((dst_y *
        !           283:                                        u_info->dst_bitmap.nshorts) +
        !           284:                                        DIV_BPW(dst_x)));
        !           285:                s_info->dst.nextline = MUL_4(u_info->dst_bitmap.nshorts -
        !           286:                                             s_info->nshorts + 1);
        !           287:        }
        !           288:        else {
        !           289:                s_info->dst_plus = 2;
        !           290:                s_info->dst.data = (unsigned short *)(
        !           291:                                   (long)u_info->dst_bitmap.base +
        !           292:                                   MUL_2((dst_y * u_info->dst_bitmap.nshorts) +
        !           293:                                         DIV_BPW(dst_x)));
        !           294:                s_info->dst.nextline = MUL_2(u_info->dst_bitmap.nshorts -
        !           295:                                             s_info->nshorts + 1);
        !           296:        }
        !           297: #else no APA8 stuff
        !           298:        s_info->dst.data = (unsigned short *)((long)u_info->dst_bitmap.base +
        !           299:                            MUL_2((dst_y * u_info->dst_bitmap.nshorts) +
        !           300:                                  DIV_BPW(dst_x)));
        !           301: 
        !           302:        /*
        !           303:         * NOTE: This increment shows the increment for the number of BYTES.
        !           304:         */
        !           305:        s_info->dst.nextline = MUL_2(u_info->dst_bitmap.nshorts -
        !           306:                                     s_info->nshorts + 1);
        !           307: #endif APA8
        !           308: 
        !           309:        /*
        !           310:         * Set up the masking bitmap (if given) to point to a word
        !           311:         * offset from the base address.
        !           312:         */
        !           313:        if (u_info->blt_flags & BLT_MASKON) {
        !           314:                /*
        !           315:                 * Calculate the shift amount (skew) that is needed
        !           316:                 * to align a word in the mask bitmap with a word
        !           317:                 * in the destination.
        !           318:                 */
        !           319:                if (s_info->top_to_bot) {
        !           320:                        computeSkewMskNeg(s_info);
        !           321: 
        !           322:                        /*
        !           323:                         * Calculate the mask pointer.
        !           324:                         */
        !           325:                        s_info->msk.data = (unsigned short *)(
        !           326:                                           (long)(u_info->msk_bitmap.base) +
        !           327:                                           MUL_2((s_info->msk.rect.corner_y *
        !           328:                                                 u_info->msk_bitmap.nshorts) +
        !           329:                                           DIV_BPW(s_info->msk.rect.corner_x)));
        !           330:                }
        !           331:                else {
        !           332:                        computeSkewMskPos(s_info);
        !           333: 
        !           334:                        /*
        !           335:                         * Calculate the mask pointer.
        !           336:                         */
        !           337:                        s_info->msk.data = (unsigned short *)(
        !           338:                                           (long)(u_info->msk_bitmap.base) + 
        !           339:                                           MUL_2((s_info->msk.rect.origin_y *
        !           340:                                                  u_info->msk_bitmap.nshorts) +
        !           341:                                           DIV_BPW(s_info->msk.rect.origin_x)));
        !           342:                }
        !           343: 
        !           344:                /*
        !           345:                 * Calculate the mask increment.
        !           346:                 */
        !           347:                s_info->msk.nextline = MUL_2( u_info->msk_bitmap.nshorts -
        !           348:                                             (s_info->nshorts +
        !           349:                                              s_info->preload_msk) + 1);
        !           350:        }
        !           351:        else {
        !           352:                s_info->msk.data = (unsigned short *)0;
        !           353:                s_info->msk.nextline = 0;
        !           354:        }
        !           355: }
        !           356: 
        !           357: /*
        !           358:  * CalculateOffsetSrcNeg sets up pointers to the last word in the
        !           359:  * source.  It also determines if "priming" must be done.
        !           360:  * (i.e. 2 words of source are needed for the first word of the destination.)
        !           361:  * When going from right to left this happens when for example you have 
        !           362:  * 3 bits in the source (at the end of the line) (0-2) and 5 bits to fill
        !           363:  * in the destination (0-4).  One must take those 3 bits from the source
        !           364:  * and put them in 2-4 in the destination and increment the source.
        !           365:  *
        !           366:  * It then calculates the increment for the source.
        !           367:  */
        !           368: 
        !           369: #if (APA8 || APA8C)
        !           370: #define calculateOffsetSrcNeg(UI,SI) {                                 \
        !           371:        if (IS_APA8orAPA8C(UI->src_bitmap)) {                           \
        !           372:                SI->src_plus = 4;                                       \
        !           373:                SI->src.data = (unsigned short *)((long)(UI->src_bitmap.base) +\
        !           374:                             MUL_4((SI->src.rect.corner_y *     \
        !           375:                                          UI->src_bitmap.nshorts) +     \
        !           376:                                         DIV_BPW(SI->src.rect.corner_x)));\
        !           377:                SI->src.nextline = MUL_4(UI->src_bitmap.nshorts -       \
        !           378:                                         (SI->nshorts+SI->preload_src) + 1);\
        !           379:        }                                                               \
        !           380:        else {                                                          \
        !           381:                SI->src_plus = 2;                                       \
        !           382:                SI->src.data = (unsigned short *)((long)(UI->src_bitmap.base) +\
        !           383:                            MUL_2((SI->src.rect.corner_y *              \
        !           384:                                   UI->src_bitmap.nshorts) +            \
        !           385:                                   DIV_BPW(SI->src.rect.corner_x)));    \
        !           386:                SI->src.nextline = MUL_2(UI->src_bitmap.nshorts -       \
        !           387:                                   (SI->nshorts + SI->preload_src) + 1);\
        !           388:        }                                                               \
        !           389: }
        !           390: #else no APA8 stuff
        !           391: #define calculateOffsetSrcNeg(UI,SI) {                                 \
        !           392:        SI->src.data = (unsigned short *)((long)(UI->src_bitmap.base) + \
        !           393:                     MUL_2((SI->src.rect.corner_y * UI->src_bitmap.nshorts) +\
        !           394:                           DIV_BPW(SI->src.rect.corner_x)));            \
        !           395:        SI->src.nextline = MUL_2(UI->src_bitmap.nshorts -               \
        !           396:                           (SI->nshorts+SI->preload_src) + 1);          \
        !           397: }
        !           398: #endif
        !           399: 
        !           400: /*
        !           401:  * CalculateOffsetSrcPos sets up pointers to the first word in the
        !           402:  * source.  It also determines if "priming" must be done. (i.e. 2 words 
        !           403:  * of source are needed for the first word of the destination.)
        !           404:  * When going from left to right this happens when for example you have 
        !           405:  * 3 bits in the source (13-15) and 5 bits to fill in the destination (11-15).
        !           406:  * One must take those 3 bits from the source and put them in 11-13
        !           407:  * and then increment the source.
        !           408:  *
        !           409:  * It then calculates the increment for the source.
        !           410:  */
        !           411: #if (APA8 || APA8C)
        !           412: #define calculateOffsetSrcPos(UI,SI) {                                 \
        !           413:        if (IS_APA8orAPA8C(UI->src_bitmap)) {                           \
        !           414:                SI->src_plus = 4;                                       \
        !           415:                SI->src.data = (unsigned short *)((long)UI->src_bitmap.base +  \
        !           416:                               MUL_4((SI->src.rect.origin_y *           \
        !           417:                                      UI->src_bitmap.nshorts) + \
        !           418:                                      DIV_BPW(SI->src.rect.origin_x)));\
        !           419:                SI->src.nextline = MUL_4(UI->src_bitmap.nshorts -       \
        !           420:                                         (SI->nshorts + SI->preload_src) + 1);\
        !           421:        }                                                               \
        !           422:        else {                                                          \
        !           423:                SI->src_plus = 2;                                       \
        !           424:                SI->src.data = (unsigned short *)((long)UI->src_bitmap.base +\
        !           425:                                MUL_2((SI->src.rect.origin_y *          \
        !           426:                                      UI->src_bitmap.nshorts) +         \
        !           427:                                      DIV_BPW(SI->src.rect.origin_x))); \
        !           428:                SI->src.nextline = MUL_2(UI->src_bitmap.nshorts -       \
        !           429:                                   (SI->nshorts+SI->preload_src) + 1);  \
        !           430:        }                                                               \
        !           431: }
        !           432: #else no APA8 stuff
        !           433: #define calculateOffsetSrcPos(UI,SI) {                                 \
        !           434:        SI->src.data = (unsigned short *)((long)UI->src_bitmap.base +   \
        !           435:                     MUL_2((SI->src.rect.origin_y * UI->src_bitmap.nshorts) +\
        !           436:                           DIV_BPW(SI->src.rect.origin_x)));            \
        !           437:        SI->src.nextline = MUL_2(UI->src_bitmap.nshorts -               \
        !           438:                           (SI->nshorts+SI->preload_src) + 1);          \
        !           439: }
        !           440: #endif
        !           441: 
        !           442: /*
        !           443:  * Set up destination offsets.
        !           444:  */
        !           445: #define calculateOffsetDstNeg(UI,SI) calculateOffsetDst(UI,SI,         \
        !           446:                                                        SI->dst.rect.corner_x,\
        !           447:                                                        SI->dst.rect.corner_y)
        !           448: #define calculateOffsetDstPos(UI,SI) calculateOffsetDst(UI,SI,         \
        !           449:                                                        SI->dst.rect.origin_x, \
        !           450:                                                        SI->dst.rect.origin_y)
        !           451: 
        !           452: /*
        !           453:  * If a rule specifies the type of tile to be used then set tile_ptr.
        !           454:  * If tile_ptr has already been set then don't change it.
        !           455:  */
        !           456: #define calculateOffsetTile(UI,SI) {                           \
        !           457:        if (SI->rule == DstClear || SI->rule == TileDstClear) { \
        !           458:                SI->tile_ptr = &white.tile[0];                  \
        !           459:        }                                                       \
        !           460:        else if (SI->rule == DstSet || SI->rule == TileDstSet   \
        !           461:                || SI->rule == NotDstCopy) {                    \
        !           462:                SI->tile_ptr = &black.tile[0];                  \
        !           463:        }                                                       \
        !           464:        else if (SI->tile_ptr == (unsigned short *)0){          \
        !           465:                SI->tile_ptr = (unsigned short *)UI->tile_ptr;  \
        !           466:        }                                                       \
        !           467: }
        !           468: 
        !           469: /*
        !           470:  * Do the bit block transfer using the information in u_info. Return -1 if
        !           471:  * bad pointers are given, 0 if the area clipped down to a null blt and 1 if
        !           472:  * the "bitblt" was done.
        !           473:  */
        !           474: bitblt(u_info)
        !           475: register Blt_userdata *u_info;
        !           476: {
        !           477:        register Blt_sysdata *sys_info = &blt_info;
        !           478:        register tmp;
        !           479:        register saved_loc;
        !           480:        int blt_status;
        !           481: 
        !           482:        DEBUGF((blt_debug > 1),printf("Enter bitblt.\r\n"));
        !           483: 
        !           484:        /*
        !           485:         * Set up to do this blt.  blt_setup does clipping if necessary, sets
        !           486:         * up either the source or tile (depending on the combination rule
        !           487:         * being used) and sets the width and height of the blt.  It returns
        !           488:         * zero if the blt is to be done.
        !           489:         */
        !           490:        if ((blt_status = blt_setup(u_info,sys_info)) != 1) {
        !           491:                /*
        !           492:                 * Bad pointers or the combination rule was such that nothing
        !           493:                 * has to be done.
        !           494:                 */
        !           495:                return(blt_status);
        !           496:        }
        !           497:        else if (sys_info->width <= 0 || sys_info->height <= 0) {
        !           498:                /*
        !           499:                 * Nothing to do.
        !           500:                 */
        !           501:                return(0);
        !           502:        }
        !           503: 
        !           504: #ifdef USE_APA16_HDWR
        !           505:        /*
        !           506:         * Are we using hardware??  This is for debugging purposes, we
        !           507:         * know the software works so to test the hardware stuff we have this
        !           508:         * flag in blt_flags.  However if we are using a mask bitmap then
        !           509:         * the hardware can not be used.
        !           510:         */
        !           511:        if ((u_info->blt_flags & BLT_MASKON) == 0) {
        !           512:                register int ret_flag;  /* Hardware return flag */
        !           513: 
        !           514:                /*
        !           515:                 * One can only use the hardware assist if the destination
        !           516:                 * bitmap is the screen.
        !           517:                 */
        !           518:                ret_flag = 1;
        !           519:                if (IS_APA16(u_info->dst_bitmap)) {
        !           520:                        extern unsigned short execute_cmd[];
        !           521: 
        !           522:                        /*
        !           523:                         * Check and see if there is a hardware function
        !           524:                         * (execute command) for this rule.
        !           525:                         */
        !           526:                        if (execute_cmd[sys_info->rule]) {
        !           527:                                if (sys_info->is_src) {
        !           528:                                        if (IS_APA16(u_info->src_bitmap)) {
        !           529:                                                /*
        !           530:                                                 * Pass in the pointers to
        !           531:                                                 * the screen because if they
        !           532:                                                 * are greater than the first
        !           533:                                                 * byte address in the APA16
        !           534:                                                 * buffer things will not
        !           535:                                                 * work.
        !           536:                                                 */
        !           537:                                                sys_info->dst.data =
        !           538:                                                        u_info->dst_bitmap.base;
        !           539:                                                sys_info->src.data =
        !           540:                                                        u_info->src_bitmap.base;
        !           541:                                                ret_flag = apa16_StoS(sys_info);
        !           542:                                        }
        !           543:                                        else {
        !           544:                                                /*
        !           545:                                                 * The APA-16 does memory to
        !           546:                                                 * screen stuff.  But first
        !           547:                                                 * The source address and
        !           548:                                                 * and the source "nextline"
        !           549:                                                 * field must also be
        !           550:                                                 * calculated.
        !           551:                                                 *
        !           552:                                                 * NOT IMPLEMENTED YET.
        !           553:                                                 *
        !           554:                                                 * computeSkewPos(sys_info);
        !           555:                                                 * calculateOffsetSrcPos(u_info,
        !           556:                                                 *                    sys_info);
        !           557:                                                 * ret_flag =
        !           558:                                                 *         apa16_MtoS(sys_info);
        !           559:                                                 */
        !           560:                                        }
        !           561:                                }
        !           562:                                else {
        !           563:                                        /*
        !           564:                                         * The tile ptr has not been set up yet.
        !           565:                                         */
        !           566:                                        sys_info->tile_ptr = (unsigned short *)
        !           567:                                                             u_info->tile_ptr;
        !           568:                                        ret_flag = apa16_copyTile(sys_info);
        !           569:                                }
        !           570: 
        !           571:                                /*
        !           572:                                 * Check the status of the hardware blt, if
        !           573:                                 * its 0 then everything was done successfully.
        !           574:                                 */
        !           575:                                if (ret_flag == 0) {
        !           576: 
        !           577:                                        /*
        !           578:                                         * Indicate that a blt was done.
        !           579:                                         */
        !           580:                                        return(1);
        !           581:                                }
        !           582:                        }
        !           583:                }
        !           584:        }
        !           585: 
        !           586:        /*
        !           587:         * Regardless of the hardware flag, if we get here it means
        !           588:         * that we are going to use the software to blt.  If the screen
        !           589:         * is to be changed then we must wait for the rasterop engine to finish
        !           590:         * with the screen if it is still using the screen.
        !           591:         */
        !           592:        if (*QUE_COUNT_R != 0) {
        !           593:                if (IS_APA16(u_info->dst_bitmap) || 
        !           594:                    (IS_APA16(u_info->src_bitmap))) {
        !           595:                        WAIT_QUE(tmp,0);
        !           596:                }
        !           597:        }
        !           598: 
        !           599: #endif USE_APA16_HDWR
        !           600: 
        !           601: #ifdef AED
        !           602:        /*  
        !           603:         * If this is a screen to screen blt on the AED have the microcode
        !           604:         * make the screen changes while the bltter alters the 
        !           605:         * offscreen bitmap.
        !           606:         */ 
        !           607: 
        !           608:        if (IS_AED(u_info->src_bitmap) && IS_AED(u_info->dst_bitmap) &&
        !           609:            (u_info->blt_flags & BLT_ECHO)) {
        !           610:                aed_screen_copy(sys_info->src.rect.origin_x,
        !           611:                                 sys_info->src.rect.origin_y,
        !           612:                                 sys_info->dst.rect.origin_x,
        !           613:                                 sys_info->dst.rect.origin_y,
        !           614:                                 (short) sys_info->width,
        !           615:                                 (short) sys_info->height,
        !           616:                                 sys_info->rule);
        !           617:                blt_status = 0;
        !           618:        }
        !           619: #endif AED
        !           620: 
        !           621:        /*
        !           622:         * Remove the locator from the screen if it is a software locator that
        !           623:         * is actually in (on) the source or destination bitmap.  Hardware
        !           624:         * locators (as in the APA-16) are not removed.
        !           625:         */
        !           626:        SAVE_LOCATOR();
        !           627: 
        !           628:        /*
        !           629:         * Calculate the edge masks for the destination. (See computeMasks
        !           630:         * in Smalltalk-80)
        !           631:         */
        !           632:        computeMasks(sys_info);
        !           633: 
        !           634:        /*
        !           635:         * If the source is to be used then things will be done differently
        !           636:         * than if a tile is used.
        !           637:         */
        !           638:        if (sys_info->is_src) {
        !           639:                /*
        !           640:                 * Check for overlapping source and destination. (See
        !           641:                 * checkOverlap in Smalltalk-80)  Sets sys_info->top_to_bot
        !           642:                 * non-zero if we must copy from bottom to top, right to
        !           643:                 * left instead of top to bottom, left to right.
        !           644:                 */
        !           645:                checkOverlap(u_info,sys_info);
        !           646: 
        !           647:                if (sys_info->top_to_bot) {
        !           648:                        /*
        !           649:                         * Calculate the shift amount (skew) that is needed
        !           650:                         * to align a word in the source with a word in the
        !           651:                         * destination.
        !           652:                         */
        !           653:                        computeSkewNeg(sys_info);
        !           654: 
        !           655:                        /*
        !           656:                         * Set up pointers to the source, destination 
        !           657:                         * and possibly to the mask bitmap. Also set up
        !           658:                         * shift amounts (skews) for the mask bitmap if needed.
        !           659:                         * Calculate the increment for each pointer from
        !           660:                         * the end of one rectangle scanline to the beginning
        !           661:                         * of the next.
        !           662:                         */
        !           663:                        calculateOffsetSrcNeg(u_info,sys_info);
        !           664:                        calculateOffsetDstNeg(u_info,sys_info);
        !           665: 
        !           666:                        /*
        !           667:                         * Do the blt from bottom to top, right to left!!
        !           668:                         */
        !           669:                        if (u_info->blt_flags & BLT_MASKON) {
        !           670:                                maskBitNeg(sys_info);
        !           671:                        }
        !           672:                        else {
        !           673:                                /*
        !           674:                                 * Just copy from source to destination
        !           675:                                 * going bottom to top, right to left.
        !           676:                                 * No mask bitmap to worry about.
        !           677:                                 */
        !           678:                                copyBitNeg(sys_info);
        !           679:                        }
        !           680:                }
        !           681:                else {
        !           682:                        /*
        !           683:                         * Calculate the shift amount (skew) that is needed
        !           684:                         * to align a word in the source with a word in the
        !           685:                         * destination.
        !           686:                         */
        !           687:                        computeSkewPos(sys_info);
        !           688: 
        !           689:                        /*
        !           690:                         * Set up pointers to the source, destination 
        !           691:                         * and possibly to the mask bitmap.
        !           692:                         * Also set up shift amounts (skews) for the mask
        !           693:                         * bitmap if needed.  Calculate the increment for
        !           694:                         * each pointer from the end of one rectangle
        !           695:                         * scanline to the beginning of the next.
        !           696:                         */
        !           697:                        calculateOffsetSrcPos(u_info,sys_info);
        !           698:                        calculateOffsetDstPos(u_info,sys_info);
        !           699: 
        !           700:                        /*
        !           701:                         * Do the blt from top to bottom, left to right!!
        !           702:                         */
        !           703:                        if (u_info->blt_flags & BLT_MASKON) {
        !           704:                                /*
        !           705:                                 * Copy from source to destination going
        !           706:                                 * top to bottom, left to right. Use the
        !           707:                                 * mask bitmap.
        !           708:                                 */
        !           709:                                maskBitPos(sys_info);
        !           710:                        }
        !           711:                        else {
        !           712:                                /*
        !           713:                                 * Just copy from source to destination
        !           714:                                 * going top to bottom, left to right.
        !           715:                                 */
        !           716:                                if (sys_info->nshorts < 3) {
        !           717:                                        /*
        !           718:                                         * Optimize this very important routine
        !           719:                                         * for one and two shorts in the dst
        !           720:                                         * changed.
        !           721:                                         */
        !           722:                                        smallcopyBitPos(sys_info);
        !           723:                                }
        !           724:                                else {
        !           725:                                        copyBitPos(sys_info);
        !           726:                                }
        !           727:                        }
        !           728:                }
        !           729:        }
        !           730:        else { 
        !           731:                /*
        !           732:                 * We have a TILE rule.
        !           733:                 */
        !           734:                sys_info->top_to_bot = 0;
        !           735: 
        !           736:                /*
        !           737:                 * Set up pointers to the tile and destination and possibly
        !           738:                 * to the mask bitmap.  Calculate the increment for
        !           739:                 * each pointer from the end of one rectangle scanline to
        !           740:                 * the beginning of the next.
        !           741:                 * NOTE: The pointer to the tile may have been set in
        !           742:                 *       blt_setup.
        !           743:                 */
        !           744:                calculateOffsetTile(u_info,sys_info);
        !           745:                calculateOffsetDstPos(u_info,sys_info);
        !           746: 
        !           747:                /*
        !           748:                 * Do the tile blt!
        !           749:                 */
        !           750:                if (u_info->blt_flags & BLT_MASKON) {
        !           751:                        maskTile(sys_info);
        !           752:                }
        !           753:                else {
        !           754:                        copyTile(sys_info);
        !           755:                }
        !           756:        }
        !           757: 
        !           758:        /*
        !           759:         * Restore the locator if the screen was dealt with.
        !           760:         */
        !           761:        RESTORE_LOCATOR();
        !           762: 
        !           763: #ifdef AED
        !           764:        /*  
        !           765:         * If we are echoing to AED, keep track of bounding
        !           766:         * rectangle of the updated screen area.
        !           767:         */ 
        !           768: 
        !           769:        if (IS_AED(u_info->dst_bitmap) && blt_status &&
        !           770:            (u_info->blt_flags & BLT_ECHO)) {
        !           771:                aed_echo_rect(&changed_rect);
        !           772:        }
        !           773: #endif AED
        !           774: 
        !           775:        /*
        !           776:         * Indicate that a blt was done.
        !           777:         */
        !           778:        return(1);
        !           779: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.