Annotation of researchv10no/ncurses/screen/ll_refresh.c, revision 1.1.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.