Annotation of researchv10no/ncurses/screen/ll_refresh.c, revision 1.1

1.1     ! root        1: /*     @(#)ll_refresh.c        1.1     (1.22)  */
        !             2: #include "curses.ext"
        !             3: 
        !             4: extern int InputPending;
        !             5: extern int outchcount;
        !             6: 
        !             7: extern int *context;
        !             8: 
        !             9: int didntdobotright;   /* writechars didn't output char in bot right corner */
        !            10: 
        !            11: /*
        !            12:  * Optimally make the screen (which currently looks like SP->cur_body)
        !            13:  * look like SP->std_body.  If use_idl is 1, this routine will call
        !            14:  * out all its horses, including some code to figure out
        !            15:  * how to use insert/delete line.  If use_idl is 0, or if the terminal
        !            16:  * does not have insert/delete line, a simpler scheme will
        !            17:  * be used, and the insert/delete line features of the terminal will not
        !            18:  * be used.
        !            19:  *
        !            20:  * While the original intent of this parameter was speed (insert/delete
        !            21:  * line was slow) the parameter currently is there to avoid annoying
        !            22:  * the user with unnecessary insert/delete lines.
        !            23:  */
        !            24: int
        !            25: _ll_refresh (use_idl)
        !            26: int    use_idl;
        !            27: {
        !            28:        register int n, i, j;
        !            29:        register struct line *dln, *pln;
        !            30:        struct line *_line_alloc();
        !            31: 
        !            32: #ifdef DEBUG
        !            33:        if(outf) fprintf(outf, "_ll_refresh(%d)\n", use_idl);
        !            34:        if(outf) fprintf(outf, "phys cursor at (%d,%d), want cursor at (%d,%d)\n",
        !            35:                SP->phys_y, SP->phys_x, SP->virt_y, SP->virt_x);
        !            36: #endif DEBUG
        !            37:        outchcount = 0;
        !            38: #ifdef FIONREAD
        !            39:        if( SP->check_fd >= 0 )
        !            40:        {
        !            41:                ioctl (SP->check_fd, FIONREAD, &InputPending);
        !            42:        }
        !            43:        else
        !            44:        {
        !            45:                InputPending = 0;
        !            46:        }
        !            47:        if( InputPending )
        !            48:        {
        !            49: #ifdef DEBUG
        !            50:                if (outf) fprintf(outf, "InputPending %d, aborted ll_refresh at start\n", InputPending);
        !            51: #endif DEBUG
        !            52:                return 0;
        !            53:        }
        !            54: #endif FIONREAD
        !            55: #ifdef         NONSTANDARD
        !            56:        input_wait();
        !            57: #endif         NONSTANDARD
        !            58: #ifdef DEBUG
        !            59:        if (outf) fprintf(outf, "virt cursor at y=%d, x=%d, length %d, length-1 %d\n",
        !            60:                SP->virt_y, SP->virt_x, SP->std_body[SP->virt_y+1]->length,
        !            61:                SP->std_body[SP->virt_y]->length);
        !            62: #endif DEBUG
        !            63:        if( SP->virt_y >= 0 && SP->std_body[SP->virt_y+1]->length < SP->virt_x )
        !            64:        {
        !            65:                SP->std_body[SP->virt_y+1]->length =
        !            66:                    SP->virt_x >= columns ? columns : SP->virt_x;
        !            67:        }
        !            68:        /* Get rid of trailing blanks on all lines */
        !            69:        for( n = 1; n <= lines; n++ )
        !            70:        {
        !            71:                dln = SP->std_body[n];
        !            72:                pln = SP->cur_body[n];
        !            73:                if( dln && dln != pln )
        !            74:                {
        !            75:                        register chtype *p;
        !            76: 
        !            77:                        if( i = dln->length )
        !            78:                        {
        !            79:                                p = dln->body + i;
        !            80:                                while( *--p == ' ' && --i > 0 )
        !            81:                                        ;
        !            82:                                dln->length = i;
        !            83:                        }
        !            84:                }
        !            85: 
        !            86:                if( pln )
        !            87:                {
        !            88:                        register chtype *p;
        !            89: 
        !            90:                        if( i = pln->length )
        !            91:                        {
        !            92:                                p = pln->body + i;
        !            93:                                while( *--p == ' ' && --i > 0 )
        !            94:                                        ;
        !            95:                                pln->length = i;
        !            96:                        }
        !            97:                }
        !            98:        }
        !            99:        if( magic_cookie_glitch > 0 )
        !           100:                _toss_cookies();
        !           101: #ifdef DEBUG
        !           102:        if(outf) fprintf(outf, "what we have:\n");
        !           103:        for( i=1; i<=lines; i++ )
        !           104:        {
        !           105:                if(outf) fprintf(outf, "%8x: ", SP->cur_body[i]);
        !           106:                if( SP->cur_body[i] == NULL )
        !           107:                {
        !           108:                        if(outf) fprintf(outf, "()\n");
        !           109:                }
        !           110:                else
        !           111:                {
        !           112:                        if(outf) fprintf(outf, "%4d ", SP->cur_body[i]->length);
        !           113:                        for( j=0; j<SP->cur_body[i]->length; j++ )
        !           114:                        {
        !           115:                                n = SP->cur_body[i]->body[j];
        !           116:                                if( n & A_ATTRIBUTES )
        !           117:                                {
        !           118:                                        putc('\'', outf);
        !           119:                                }
        !           120:                                n &= 0177;
        !           121:                                if(outf) fprintf(outf, "%c", n>=' ' ? n : '.');
        !           122:                        }
        !           123:                        if(outf) fprintf(outf, "\n");
        !           124:                }
        !           125:        }
        !           126:        if(outf) fprintf(outf, "what we want:\n");
        !           127:        for (i=1; i<=lines; i++)
        !           128:        {
        !           129:                if(outf) fprintf(outf, "%8x: ", SP->std_body[i]);
        !           130:                if (SP->std_body[i] == NULL)
        !           131:                {
        !           132:                        if(outf) fprintf(outf, "()\n");
        !           133:                }
        !           134:                else
        !           135:                {
        !           136:                        if(outf) fprintf(outf, "%4d ", SP->std_body[i]->length);
        !           137:                        for (j=0; j<SP->std_body[i]->length; j++)
        !           138:                        {
        !           139:                                n = SP->std_body[i]->body[j];
        !           140:                                if (n & A_ATTRIBUTES)
        !           141:                                {
        !           142:                                        putc('\'', outf);
        !           143:                                }
        !           144:                                n &= 0177;
        !           145:                                if(outf) fprintf(outf, "%c", n>=' ' ? n : '.');
        !           146:                        }
        !           147:                        if(outf) fprintf(outf, "\n");
        !           148:                }
        !           149:        }
        !           150:        if(outf) fprintf(outf, "----\n");
        !           151:        if(outf) fflush(outf);
        !           152: #endif DEBUG
        !           153:        SP->check_input = SP->baud / 2400;
        !           154:        if (SP->doclear)
        !           155:        {
        !           156: #ifdef DEBUG
        !           157:                if(outf) fprintf(outf, "SP->doclear, clearing screen\n");
        !           158: #endif
        !           159:                _reset();
        !           160:                SP->doclear = 0;
        !           161:                for( n = 0; n <= lines; n++ )
        !           162:                {
        !           163:                        if( SP->cur_body[n] != SP->std_body[n] )
        !           164:                        {
        !           165:                                _line_free( SP->cur_body[n] );
        !           166:                        }
        !           167:                        SP->cur_body[n] = 0;
        !           168:                }
        !           169:        }
        !           170: 
        !           171:        /* Choose between two updating algorithms. */
        !           172:        if( use_idl && _cost(ilfixed) < INFINITY )
        !           173:        {
        !           174: #ifdef DEBUG
        !           175:                if(outf) fprintf(outf, "use_idl\n");
        !           176: #endif
        !           177:                for( n = 1; n <= lines; n++ )
        !           178:                {
        !           179:                        if( SP->cur_body[n] == 0 )
        !           180:                        {
        !           181:                                SP->cur_body[n] = _line_alloc();
        !           182:                        }
        !           183:                        if( SP->std_body[n] == 0 )
        !           184:                        {
        !           185:                                SP->std_body[n] = SP->cur_body[n];
        !           186:                        }
        !           187:                        else
        !           188:                        {
        !           189:                                _comphash( SP->std_body[n] );
        !           190:                        }
        !           191:                        _comphash( SP->cur_body[n] );
        !           192:                }
        !           193:                /*
        !           194:                 * Count number of matches if we scroll 1 line and if we
        !           195:                 * don't scroll at all.  This is primarily useful for the
        !           196:                 * case where we scroll the whole screen.  Scrolling a portion
        !           197:                 * of the screen will be handled by the ins/del line routines,
        !           198:                 * although a special case here might buy some CPU speed.
        !           199:                 */
        !           200:                for( i=1,n=0,j=0; i<lines; i++ )
        !           201:                {
        !           202:                        if( SP->cur_body[i+1]->hash == SP->std_body[i]->hash )
        !           203:                                n++;
        !           204:                        if( SP->cur_body[i]->hash == SP->std_body[i]->hash )
        !           205:                                j++;
        !           206:                }
        !           207:                if( n > lines-3 && n > j )
        !           208:                {
        !           209:                        _window(0, lines-1, 0, columns-1);
        !           210:                        _scrollf(1);
        !           211:                        _line_free(SP->cur_body[1]);
        !           212:                        for( i=1; i<lines; i++ )
        !           213:                        {
        !           214:                                /* Copy line with two references since they
        !           215:                                 * are no longer the same row on screen. */
        !           216:                                if( SP->cur_body[i+1] == SP->std_body[i+1] )
        !           217:                                {
        !           218:                                        struct line *p;
        !           219:                                        int l;
        !           220:                                        chtype *b1, *b2;
        !           221:                                        p = _line_alloc ();
        !           222:                                        p->length=l=SP->cur_body[i+1]->length;
        !           223:                                        p->hash = SP->cur_body[i+1]->hash;
        !           224:                                        b1 = &(p->body[0]);
        !           225:                                        b2 = &(SP->cur_body[i+1]->body[0]);
        !           226:                                        for(  ; l>0; l-- )
        !           227:                                        {
        !           228:                                                *b1++ = *b2++;
        !           229:                                        }
        !           230:                                        SP->std_body[i+1] = p;
        !           231:                                }
        !           232:                                SP->cur_body[i] = SP->cur_body[i+1];
        !           233:                        }
        !           234:                        SP->cur_body[lines] = _line_alloc();
        !           235:                }
        !           236:                i = 1;
        !           237:                /*
        !           238:                 * Break the screen (from 1 to lines) into clumps of
        !           239:                 * lines that are different.  Thus we ignore the ones that
        !           240:                 * are identical.
        !           241:                 */
        !           242:                for( ;; )
        !           243:                {
        !           244:                        while( i<=lines && SP->cur_body[i]==SP->std_body[i] )
        !           245:                        {
        !           246:                                i++;
        !           247:                        }
        !           248:                        if( i > lines )
        !           249:                        {
        !           250:                                break;
        !           251:                        }
        !           252:                        for( j=i; j <= lines &&
        !           253:                                SP->cur_body[j] != SP->std_body[j]; j++)
        !           254:                                        ;
        !           255:                        j--;
        !           256: #ifdef DEBUG
        !           257:                        if(outf) fprintf(outf, "window from %d to %d\n", i, j);
        !           258: #endif
        !           259:                        /* i thru j is a window of different lines. */
        !           260:                        if( i == j )
        !           261:                        {
        !           262:                                _id_char(SP->cur_body[i], SP->std_body[i], i-1);
        !           263:                                if( SP->cur_body[i] != SP->std_body[i] )
        !           264:                                {
        !           265:                                        _line_free (SP->cur_body[i]);
        !           266:                                }
        !           267:                                SP->cur_body[i] = SP->std_body[i];
        !           268:                        }
        !           269:                        else
        !           270:                        {
        !           271:                                _window(i-1, j-1, 0, columns-1);
        !           272:                                _setwind();   /* Force action for moves, etc */
        !           273:                                _id_line(i, j);
        !           274:                        }
        !           275:                        i = j+1;
        !           276:                }
        !           277:        }
        !           278:        else                    /* fast update */
        !           279:        {
        !           280: #ifdef DEBUG
        !           281:                if(outf) fprintf(outf, "Fast Update, lines %d\n", lines);
        !           282: #endif
        !           283:                _window(0, lines-1, 0, columns-1);
        !           284:                _setwind();   /* Force action for moves, etc */
        !           285:                for( n = 1; n <= lines; n++ )
        !           286:                        if( SP->std_body[n] != SP->cur_body[n] )
        !           287:                        {
        !           288:                                _id_char( SP->cur_body[n],SP->std_body[n],n-1 );
        !           289:                                if( SP->cur_body[n] != SP->std_body[n] )
        !           290:                                {
        !           291:                                        _line_free (SP->cur_body[n]);
        !           292:                                }
        !           293:                                SP->cur_body[n] = SP->std_body[n];
        !           294:                        }
        !           295:        }
        !           296: 
        !           297:        /*
        !           298:         * Didn't output char in bottom right corner of screen.
        !           299:         * Remember this fact so that next time when it's higher
        !           300:         * on the screen, we'll fix it up.
        !           301:         */
        !           302:        if( didntdobotright )
        !           303:        {
        !           304:                int holdvx, holdvy;
        !           305: #ifdef DEBUG
        !           306:                if (outf) fprintf(outf, "didntdobotright so setting SP->cur_body[%d]->body[%d] from '%c' to space.\n", lines, columns-1, SP->cur_body[lines]->body[columns-1]);
        !           307: #endif
        !           308:                holdvx = SP->virt_x;
        !           309:                holdvy = SP->virt_y;
        !           310:                /*
        !           311:                 * This code in effect marks the last line dirty
        !           312:                 * so that the next time it will get fixed.  It also
        !           313:                 * splits the line back into virt/phys so we don't
        !           314:                 * clobber the virtual part too.
        !           315:                 */
        !           316:                _ll_move(lines-1, columns-1);
        !           317:                SP->cur_body[lines]->body[columns-1] = ' ';
        !           318:                didntdobotright = 0;
        !           319:                /* Now restore the cursor we clobbered. */
        !           320:                _ll_move(holdvy, holdvx);
        !           321:        }
        !           322: 
        !           323:        _hlmode(0); _sethl();
        !           324: #ifdef DEBUG
        !           325:        if(outf) fprintf(outf, "at end, phys SP->curptr at (%d,%d), want SP->curptr at (%d,%d)\n",
        !           326:                SP->phys_y, SP->phys_x, SP->virt_y, SP->virt_x);
        !           327: #endif DEBUG
        !           328: #ifdef notdef
        !           329:        if(magic_cookie_glitch > 0)
        !           330:                _fixcursor();
        !           331: #endif notdef
        !           332:        if( !InputPending && SP->virt_x >= 0 && SP->virt_y >= 0 )
        !           333:        {
        !           334:                _pos (SP->virt_y, SP->virt_x);
        !           335:        }
        !           336:        __cflush();
        !           337: #ifdef DEBUG
        !           338:        if(outf) fprintf(outf, "end of _ll_refresh, InputPending %d\n", InputPending);
        !           339:        if(outf) fflush(outf);
        !           340: #endif DEBUG
        !           341:        return outchcount;
        !           342: }
        !           343: 
        !           344: /*
        !           345:  * This routine is only needed on terminals with the "magic cookie"
        !           346:  * effect.  The problem is that the designers of
        !           347:  * these terminals didn't allocate 16 bits for
        !           348:  * each character (7 for the character and 9 for attributes) but instead
        !           349:  * created some reserved "magic cookie" characters to tell the scan
        !           350:  * routine "you should change attributes now".  This would be fine except
        !           351:  * that these cookies take up a space in memory, and usually display as a
        !           352:  * blank.  This makes it impossible to display what the user really
        !           353:  * wanted, if he is using attributes for underlining, bold, etc.  Such
        !           354:  * terminals include the Teleray 1061, TVI 912 and 950, Teletype
        !           355:  * DataSpeed 40, and Adds Regent 40.
        !           356:  *
        !           357:  * One approach to this problem is to make everybody pay the price of
        !           358:  * this effect, forcing the programmer to allocate a blank space
        !           359:  * when attributes are changed.  This works cleanly but I consider it
        !           360:  * unacceptable.
        !           361:  *
        !           362:  * My approach is to simulate what the programmer (who wasn't thinking
        !           363:  * about these terminals) wanted as closely as possible.  If there
        !           364:  * is a desired blank in there, we use that slot.  If not, we shove the
        !           365:  * rest of the line to the right one space.  (When several attributes
        !           366:  * are changed on one line, this can result in losing several characters
        !           367:  * from the right of the line.)
        !           368:  *
        !           369:  * This routine looks for places in SP->std_body where shoving to the
        !           370:  * right is needed, and does the required shoving.
        !           371:  */
        !           372: static
        !           373: _toss_cookies()
        !           374: {
        !           375:        register int i, j, len;
        !           376:        register struct line *dsi;
        !           377:        register chtype *b;
        !           378: 
        !           379: #ifdef DEBUG
        !           380:        if(outf) fprintf(outf, "_toss_cookies\n");
        !           381: #endif
        !           382:        for( i=1; i<=lines; i++ )
        !           383:        {
        !           384:                dsi = SP->std_body[i];
        !           385:                if( dsi && dsi != SP->cur_body[i] )
        !           386:                {
        !           387:                        len = dsi->length;
        !           388:                        b = dsi->body;
        !           389:                        for( j=0; j<len; j++ )
        !           390:                        {
        !           391:                                if( b[j]&A_ATTRIBUTES )
        !           392:                                {
        !           393: #ifdef DEBUG
        !           394:                                        if(outf) fprintf(outf, "_shove, line %d, char %d, val %o\n", i, j, b[j]);
        !           395: #endif
        !           396:                                        dsi->length = _shove(b, len, i);
        !           397:                                        break;
        !           398:                                }
        !           399:                        }
        !           400:                }
        !           401:        }
        !           402: }

unix.superglobalmegacorp.com

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