1 /* $NetBSD: color.c,v 1.41 2017/01/06 13:53:18 roy Exp $ */ 2 3 /* 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __RCSID("$NetBSD: color.c,v 1.41 2017/01/06 13:53:18 roy Exp $"); 35 #endif /* not lint */ 36 37 #include "curses.h" 38 #include "curses_private.h" 39 40 /* Have we initialised colours? */ 41 int __using_color = 0; 42 43 /* Default colour number */ 44 attr_t __default_color = 0; 45 46 /* Default colour pair values - white on black. */ 47 struct __pair __default_pair = {COLOR_WHITE, COLOR_BLACK, 0}; 48 49 /* Default colour values */ 50 /* Flags for colours and pairs */ 51 #define __USED 0x01 52 53 static void 54 __change_pair(short); 55 56 static int 57 init_color_value(short, short, short, short); 58 59 /* 60 * has_colors -- 61 * Check if terminal has colours. 62 */ 63 bool 64 has_colors(void) 65 { 66 if (max_colors > 0 && max_pairs > 0 && 67 ((set_a_foreground != NULL && set_a_background != NULL) || 68 initialize_pair != NULL || initialize_color != NULL || 69 (set_background != NULL && set_foreground != NULL))) 70 return true; 71 else 72 return false; 73 } 74 75 /* 76 * can_change_color -- 77 * Check if terminal can change colours. 78 */ 79 bool 80 can_change_color(void) 81 { 82 return can_change ? true : false; 83 } 84 85 /* 86 * start_color -- 87 * Initialise colour support. 88 */ 89 int 90 start_color(void) 91 { 92 int i; 93 attr_t temp_nc; 94 struct __winlist *wlp; 95 WINDOW *win; 96 int y, x; 97 98 if (has_colors() == FALSE) 99 return ERR; 100 101 /* Max colours and colour pairs */ 102 if (max_colors == -1) 103 COLORS = 0; 104 else { 105 COLORS = max_colors > MAX_COLORS ? MAX_COLORS : max_colors; 106 if (max_pairs == -1) { 107 COLOR_PAIRS = 0; 108 COLORS = 0; 109 } else { 110 COLOR_PAIRS = (max_pairs > MAX_PAIRS - 1 ? 111 MAX_PAIRS - 1 : max_pairs); 112 /* Use the last colour pair for curses default. */ 113 __default_color = COLOR_PAIR(MAX_PAIRS - 1); 114 } 115 } 116 if (!COLORS) 117 return ERR; 118 119 _cursesi_screen->COLORS = COLORS; 120 _cursesi_screen->COLOR_PAIRS = COLOR_PAIRS; 121 122 /* Reset terminal colour and colour pairs. */ 123 if (orig_colors != NULL) 124 tputs(orig_colors, 0, __cputchar); 125 if (orig_pair != NULL) { 126 tputs(orig_pair, 0, __cputchar); 127 curscr->wattr &= _cursesi_screen->mask_op; 128 } 129 130 /* Type of colour manipulation - ANSI/TEK/HP/other */ 131 if (set_a_foreground != NULL && set_a_background != NULL) 132 _cursesi_screen->color_type = COLOR_ANSI; 133 else if (initialize_pair != NULL) 134 _cursesi_screen->color_type = COLOR_HP; 135 else if (initialize_color != NULL) 136 _cursesi_screen->color_type = COLOR_TEK; 137 else if (set_foreground != NULL && set_background != NULL) 138 _cursesi_screen->color_type = COLOR_OTHER; 139 else 140 return(ERR); /* Unsupported colour method */ 141 142 #ifdef DEBUG 143 __CTRACE(__CTRACE_COLOR, "start_color: COLORS = %d, COLOR_PAIRS = %d", 144 COLORS, COLOR_PAIRS); 145 switch (_cursesi_screen->color_type) { 146 case COLOR_ANSI: 147 __CTRACE(__CTRACE_COLOR, " (ANSI style)\n"); 148 break; 149 case COLOR_HP: 150 __CTRACE(__CTRACE_COLOR, " (HP style)\n"); 151 break; 152 case COLOR_TEK: 153 __CTRACE(__CTRACE_COLOR, " (Tektronics style)\n"); 154 break; 155 case COLOR_OTHER: 156 __CTRACE(__CTRACE_COLOR, " (Other style)\n"); 157 break; 158 } 159 #endif 160 161 /* 162 * Attributes that cannot be used with color. 163 * Store these in an attr_t for wattrset()/wattron(). 164 */ 165 _cursesi_screen->nca = __NORMAL; 166 if (no_color_video != -1) { 167 temp_nc = (attr_t)t_no_color_video(_cursesi_screen->term); 168 if (temp_nc & 0x0001) 169 _cursesi_screen->nca |= __STANDOUT; 170 if (temp_nc & 0x0002) 171 _cursesi_screen->nca |= __UNDERSCORE; 172 if (temp_nc & 0x0004) 173 _cursesi_screen->nca |= __REVERSE; 174 if (temp_nc & 0x0008) 175 _cursesi_screen->nca |= __BLINK; 176 if (temp_nc & 0x0010) 177 _cursesi_screen->nca |= __DIM; 178 if (temp_nc & 0x0020) 179 _cursesi_screen->nca |= __BOLD; 180 if (temp_nc & 0x0040) 181 _cursesi_screen->nca |= __BLANK; 182 if (temp_nc & 0x0080) 183 _cursesi_screen->nca |= __PROTECT; 184 if (temp_nc & 0x0100) 185 _cursesi_screen->nca |= __ALTCHARSET; 186 } 187 #ifdef DEBUG 188 __CTRACE(__CTRACE_COLOR, "start_color: _cursesi_screen->nca = %08x\n", 189 _cursesi_screen->nca); 190 #endif 191 192 /* Set up initial 8 colours */ 193 #define RGB_ON 680 /* Allow for bright colours */ 194 if (COLORS >= COLOR_BLACK) 195 (void)init_color_value(COLOR_BLACK, 0, 0, 0); 196 if (COLORS >= COLOR_RED) 197 (void)init_color_value(COLOR_RED, RGB_ON, 0, 0); 198 if (COLORS >= COLOR_GREEN) 199 (void)init_color_value(COLOR_GREEN, 0, RGB_ON, 0); 200 if (COLORS >= COLOR_YELLOW) 201 (void)init_color_value(COLOR_YELLOW, RGB_ON, RGB_ON, 0); 202 if (COLORS >= COLOR_BLUE) 203 (void)init_color_value(COLOR_BLUE, 0, 0, RGB_ON); 204 if (COLORS >= COLOR_MAGENTA) 205 (void)init_color_value(COLOR_MAGENTA, RGB_ON, 0, RGB_ON); 206 if (COLORS >= COLOR_CYAN) 207 (void)init_color_value(COLOR_CYAN, 0, RGB_ON, RGB_ON); 208 if (COLORS >= COLOR_WHITE) 209 (void)init_color_value(COLOR_WHITE, RGB_ON, RGB_ON, RGB_ON); 210 211 /* Initialise other colours */ 212 for (i = 8; i < COLORS; i++) { 213 _cursesi_screen->colours[i].red = 0; 214 _cursesi_screen->colours[i].green = 0; 215 _cursesi_screen->colours[i].blue = 0; 216 _cursesi_screen->colours[i].flags = 0; 217 } 218 219 /* Initialise pair 0 to default colours. */ 220 _cursesi_screen->colour_pairs[0].fore = -1; 221 _cursesi_screen->colour_pairs[0].back = -1; 222 _cursesi_screen->colour_pairs[0].flags = 0; 223 224 /* Initialise user colour pairs to default (white on black) */ 225 for (i = 0; i < COLOR_PAIRS; i++) { 226 _cursesi_screen->colour_pairs[i].fore = COLOR_WHITE; 227 _cursesi_screen->colour_pairs[i].back = COLOR_BLACK; 228 _cursesi_screen->colour_pairs[i].flags = 0; 229 } 230 231 /* Initialise default colour pair. */ 232 _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore = 233 __default_pair.fore; 234 _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back = 235 __default_pair.back; 236 _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags = 237 __default_pair.flags; 238 239 __using_color = 1; 240 241 /* Set all positions on all windows to curses default colours. */ 242 for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) { 243 win = wlp->winp; 244 if (wlp->winp != __virtscr && wlp->winp != curscr) { 245 /* Set color attribute on other windows */ 246 win->battr |= __default_color; 247 for (y = 0; y < win->maxy; y++) { 248 for (x = 0; x < win->maxx; x++) { 249 win->alines[y]->line[x].attr &= ~__COLOR; 250 win->alines[y]->line[x].attr |= __default_color; 251 } 252 } 253 __touchwin(win); 254 } 255 } 256 257 return(OK); 258 } 259 260 /* 261 * init_pair -- 262 * Set pair foreground and background colors. 263 * Our default colour ordering is ANSI - 1 = red, 4 = blue, 3 = yellow, 264 * 6 = cyan. The older style (Sb/Sf) uses 1 = blue, 4 = red, 3 = cyan, 265 * 6 = yellow, so we swap them here and in pair_content(). 266 */ 267 int 268 init_pair(short pair, short fore, short back) 269 { 270 int changed; 271 272 #ifdef DEBUG 273 __CTRACE(__CTRACE_COLOR, "init_pair: %d, %d, %d\n", pair, fore, back); 274 #endif 275 276 if (pair < 0 || pair >= COLOR_PAIRS) 277 return ERR; 278 279 if (pair == 0) /* Ignore request for pair 0, it is default. */ 280 return OK; 281 282 if (fore >= COLORS) 283 return ERR; 284 if (back >= COLORS) 285 return ERR; 286 287 /* Swap red/blue and yellow/cyan */ 288 if (_cursesi_screen->color_type == COLOR_OTHER) { 289 switch (fore) { 290 case COLOR_RED: 291 fore = COLOR_BLUE; 292 break; 293 case COLOR_BLUE: 294 fore = COLOR_RED; 295 break; 296 case COLOR_YELLOW: 297 fore = COLOR_CYAN; 298 break; 299 case COLOR_CYAN: 300 fore = COLOR_YELLOW; 301 break; 302 } 303 switch (back) { 304 case COLOR_RED: 305 back = COLOR_BLUE; 306 break; 307 case COLOR_BLUE: 308 back = COLOR_RED; 309 break; 310 case COLOR_YELLOW: 311 back = COLOR_CYAN; 312 break; 313 case COLOR_CYAN: 314 back = COLOR_YELLOW; 315 break; 316 } 317 } 318 319 if ((_cursesi_screen->colour_pairs[pair].flags & __USED) && 320 (fore != _cursesi_screen->colour_pairs[pair].fore || 321 back != _cursesi_screen->colour_pairs[pair].back)) 322 changed = 1; 323 else 324 changed = 0; 325 326 _cursesi_screen->colour_pairs[pair].flags |= __USED; 327 _cursesi_screen->colour_pairs[pair].fore = fore; 328 _cursesi_screen->colour_pairs[pair].back = back; 329 330 /* XXX: need to initialise HP style (Ip) */ 331 332 if (changed) 333 __change_pair(pair); 334 return OK; 335 } 336 337 /* 338 * pair_content -- 339 * Get pair foreground and background colours. 340 */ 341 int 342 pair_content(short pair, short *forep, short *backp) 343 { 344 if (pair < 0 || pair > _cursesi_screen->COLOR_PAIRS) 345 return ERR; 346 347 *forep = _cursesi_screen->colour_pairs[pair].fore; 348 *backp = _cursesi_screen->colour_pairs[pair].back; 349 350 /* Swap red/blue and yellow/cyan */ 351 if (_cursesi_screen->color_type == COLOR_OTHER) { 352 switch (*forep) { 353 case COLOR_RED: 354 *forep = COLOR_BLUE; 355 break; 356 case COLOR_BLUE: 357 *forep = COLOR_RED; 358 break; 359 case COLOR_YELLOW: 360 *forep = COLOR_CYAN; 361 break; 362 case COLOR_CYAN: 363 *forep = COLOR_YELLOW; 364 break; 365 } 366 switch (*backp) { 367 case COLOR_RED: 368 *backp = COLOR_BLUE; 369 break; 370 case COLOR_BLUE: 371 *backp = COLOR_RED; 372 break; 373 case COLOR_YELLOW: 374 *backp = COLOR_CYAN; 375 break; 376 case COLOR_CYAN: 377 *backp = COLOR_YELLOW; 378 break; 379 } 380 } 381 return OK; 382 } 383 384 /* 385 * init_color_Value -- 386 * Set colour red, green and blue values. 387 */ 388 static int 389 init_color_value(short color, short red, short green, short blue) 390 { 391 if (color < 0 || color >= _cursesi_screen->COLORS) 392 return ERR; 393 394 _cursesi_screen->colours[color].red = red; 395 _cursesi_screen->colours[color].green = green; 396 _cursesi_screen->colours[color].blue = blue; 397 return OK; 398 } 399 400 /* 401 * init_color -- 402 * Set colour red, green and blue values. 403 * Change color on screen. 404 */ 405 int 406 init_color(short color, short red, short green, short blue) 407 { 408 #ifdef DEBUG 409 __CTRACE(__CTRACE_COLOR, "init_color: %d, %d, %d, %d\n", 410 color, red, green, blue); 411 #endif 412 if (init_color_value(color, red, green, blue) == ERR) 413 return ERR; 414 if (!can_change || t_initialize_color(_cursesi_screen->term) == NULL) 415 return ERR; 416 tputs(tiparm(t_initialize_color(_cursesi_screen->term), 417 color, red, green, blue), 0, __cputchar); 418 return OK; 419 } 420 421 /* 422 * color_content -- 423 * Get colour red, green and blue values. 424 */ 425 int 426 color_content(short color, short *redp, short *greenp, short *bluep) 427 { 428 if (color < 0 || color >= _cursesi_screen->COLORS) 429 return ERR; 430 431 *redp = _cursesi_screen->colours[color].red; 432 *greenp = _cursesi_screen->colours[color].green; 433 *bluep = _cursesi_screen->colours[color].blue; 434 return OK; 435 } 436 437 /* 438 * use_default_colors -- 439 * Use terminal default colours instead of curses default colour. 440 */ 441 int 442 use_default_colors() 443 { 444 #ifdef DEBUG 445 __CTRACE(__CTRACE_COLOR, "use_default_colors\n"); 446 #endif 447 448 return (assume_default_colors(-1, -1)); 449 } 450 451 /* 452 * assume_default_colors -- 453 * Set the default foreground and background colours. 454 */ 455 int 456 assume_default_colors(short fore, short back) 457 { 458 #ifdef DEBUG 459 __CTRACE(__CTRACE_COLOR, "assume_default_colors: %d, %d\n", 460 fore, back); 461 __CTRACE(__CTRACE_COLOR, "assume_default_colors: default_colour = %d, pair_number = %d\n", __default_color, PAIR_NUMBER(__default_color)); 462 #endif 463 464 /* Swap red/blue and yellow/cyan */ 465 if (_cursesi_screen->color_type == COLOR_OTHER) { 466 switch (fore) { 467 case COLOR_RED: 468 fore = COLOR_BLUE; 469 break; 470 case COLOR_BLUE: 471 fore = COLOR_RED; 472 break; 473 case COLOR_YELLOW: 474 fore = COLOR_CYAN; 475 break; 476 case COLOR_CYAN: 477 fore = COLOR_YELLOW; 478 break; 479 } 480 switch (back) { 481 case COLOR_RED: 482 back = COLOR_BLUE; 483 break; 484 case COLOR_BLUE: 485 back = COLOR_RED; 486 break; 487 case COLOR_YELLOW: 488 back = COLOR_CYAN; 489 break; 490 case COLOR_CYAN: 491 back = COLOR_YELLOW; 492 break; 493 } 494 } 495 __default_pair.fore = fore; 496 __default_pair.back = back; 497 __default_pair.flags = __USED; 498 499 if (COLOR_PAIRS) { 500 _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].fore = fore; 501 _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].back = back; 502 _cursesi_screen->colour_pairs[PAIR_NUMBER(__default_color)].flags = __USED; 503 } 504 505 /* 506 * If we've already called start_color(), make sure all instances 507 * of the curses default colour pair are dirty. 508 */ 509 if (__using_color) 510 __change_pair(PAIR_NUMBER(__default_color)); 511 512 return(OK); 513 } 514 515 /* no_color_video is a terminfo macro, but we need to retain binary compat */ 516 #ifdef __strong_alias 517 #undef no_color_video 518 __strong_alias(no_color_video, no_color_attributes) 519 #endif 520 /* 521 * no_color_attributes -- 522 * Return attributes that cannot be combined with color. 523 */ 524 attr_t 525 no_color_attributes(void) 526 { 527 return(_cursesi_screen->nca); 528 } 529 530 /* 531 * __set_color -- 532 * Set terminal foreground and background colours. 533 */ 534 void 535 __set_color( /*ARGSUSED*/ WINDOW *win, attr_t attr) 536 { 537 short pair; 538 539 if ((curscr->wattr & __COLOR) == (attr & __COLOR)) 540 return; 541 542 pair = PAIR_NUMBER((uint32_t)attr); 543 #ifdef DEBUG 544 __CTRACE(__CTRACE_COLOR, "__set_color: %d, %d, %d\n", pair, 545 _cursesi_screen->colour_pairs[pair].fore, 546 _cursesi_screen->colour_pairs[pair].back); 547 #endif 548 switch (_cursesi_screen->color_type) { 549 /* Set ANSI forground and background colours */ 550 case COLOR_ANSI: 551 if (_cursesi_screen->colour_pairs[pair].fore < 0 || 552 _cursesi_screen->colour_pairs[pair].back < 0) 553 __unset_color(curscr); 554 if (_cursesi_screen->colour_pairs[pair].fore >= 0) 555 tputs(tiparm(t_set_a_foreground(_cursesi_screen->term), 556 (int)_cursesi_screen->colour_pairs[pair].fore), 557 0, __cputchar); 558 if (_cursesi_screen->colour_pairs[pair].back >= 0) 559 tputs(tiparm(t_set_a_background(_cursesi_screen->term), 560 (int)_cursesi_screen->colour_pairs[pair].back), 561 0, __cputchar); 562 break; 563 case COLOR_HP: 564 /* XXX: need to support HP style */ 565 break; 566 case COLOR_TEK: 567 /* XXX: need to support Tek style */ 568 break; 569 case COLOR_OTHER: 570 if (_cursesi_screen->colour_pairs[pair].fore < 0 || 571 _cursesi_screen->colour_pairs[pair].back < 0) 572 __unset_color(curscr); 573 if (_cursesi_screen->colour_pairs[pair].fore >= 0) 574 tputs(tiparm(t_set_foreground(_cursesi_screen->term), 575 (int)_cursesi_screen->colour_pairs[pair].fore), 576 0, __cputchar); 577 if (_cursesi_screen->colour_pairs[pair].back >= 0) 578 tputs(tiparm(t_set_background(_cursesi_screen->term), 579 (int)_cursesi_screen->colour_pairs[pair].back), 580 0, __cputchar); 581 break; 582 } 583 curscr->wattr &= ~__COLOR; 584 curscr->wattr |= attr & __COLOR; 585 } 586 587 /* 588 * __unset_color -- 589 * Clear terminal foreground and background colours. 590 */ 591 void 592 __unset_color(WINDOW *win) 593 { 594 #ifdef DEBUG 595 __CTRACE(__CTRACE_COLOR, "__unset_color\n"); 596 #endif 597 switch (_cursesi_screen->color_type) { 598 /* Clear ANSI forground and background colours */ 599 case COLOR_ANSI: 600 if (orig_pair != NULL) { 601 tputs(orig_pair, 0, __cputchar); 602 win->wattr &= __mask_op; 603 } 604 break; 605 case COLOR_HP: 606 /* XXX: need to support HP style */ 607 break; 608 case COLOR_TEK: 609 /* XXX: need to support Tek style */ 610 break; 611 case COLOR_OTHER: 612 if (orig_pair != NULL) { 613 tputs(orig_pair, 0, __cputchar); 614 win->wattr &= __mask_op; 615 } 616 break; 617 } 618 } 619 620 /* 621 * __restore_colors -- 622 * Redo color definitions after restarting 'curses' mode. 623 */ 624 void 625 __restore_colors(void) 626 { 627 if (can_change != 0) 628 switch (_cursesi_screen->color_type) { 629 case COLOR_HP: 630 /* XXX: need to re-initialise HP style (Ip) */ 631 break; 632 case COLOR_TEK: 633 /* XXX: need to re-initialise Tek style (Ic) */ 634 break; 635 } 636 } 637 638 /* 639 * __change_pair -- 640 * Mark dirty all positions using pair. 641 */ 642 void 643 __change_pair(short pair) 644 { 645 struct __winlist *wlp; 646 WINDOW *win; 647 int y, x; 648 __LINE *lp; 649 uint32_t cl = COLOR_PAIR(pair); 650 651 652 for (wlp = _cursesi_screen->winlistp; wlp != NULL; wlp = wlp->nextp) { 653 #ifdef DEBUG 654 __CTRACE(__CTRACE_COLOR, "__change_pair: win = %p\n", 655 wlp->winp); 656 #endif 657 win = wlp->winp; 658 if (win == __virtscr) 659 continue; 660 else if (win == curscr) { 661 /* Reset colour attribute on curscr */ 662 #ifdef DEBUG 663 __CTRACE(__CTRACE_COLOR, 664 "__change_pair: win == curscr\n"); 665 #endif 666 for (y = 0; y < curscr->maxy; y++) { 667 lp = curscr->alines[y]; 668 for (x = 0; x < curscr->maxx; x++) { 669 if ((lp->line[x].attr & __COLOR) == cl) 670 lp->line[x].attr &= ~__COLOR; 671 } 672 } 673 } else { 674 /* Mark dirty those positions with colour pair "pair" */ 675 for (y = 0; y < win->maxy; y++) { 676 lp = win->alines[y]; 677 for (x = 0; x < win->maxx; x++) 678 if ((lp->line[x].attr & 679 __COLOR) == cl) { 680 if (!(lp->flags & __ISDIRTY)) 681 lp->flags |= __ISDIRTY; 682 /* 683 * firstchp/lastchp are shared 684 * between parent window and 685 * sub-window. 686 */ 687 if (*lp->firstchp > x) 688 *lp->firstchp = x; 689 if (*lp->lastchp < x) 690 *lp->lastchp = x; 691 } 692 #ifdef DEBUG 693 if ((win->alines[y]->flags & __ISDIRTY)) 694 __CTRACE(__CTRACE_COLOR, 695 "__change_pair: first = %d, " 696 "last = %d\n", 697 *win->alines[y]->firstchp, 698 *win->alines[y]->lastchp); 699 #endif 700 } 701 } 702 } 703 } 704