/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* * * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company * * (c) Copyright 1993, 1994, 1996 International Business Machines Corp. * * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. * * (c) Copyright 1993, 1994, 1996 Novell, Inc. * * (c) Copyright 1996 Digital Equipment Corporation. * * (c) Copyright 1996 FUJITSU LIMITED. * * (c) Copyright 1996 Hitachi. * */ #define USE_MEMCPY /* use memcpy for line movement... */ #include #include "TermPrim.h" #include "TermHeader.h" /* for MIN/MAX */ #include "TermBufferP.h" #include "TermEnhance.h" /* ** clear "count" enhancements starting at startCol */ static void clearEnhancements ( TermBuffer tb, short row, short startCol, short count ); static void insertEnhancements ( TermBuffer tb, short row, short col, short insertCount ); static void deleteEnhancement ( TermBuffer tb, short row, short col ); static void _DtTermClearEnhancements ( TermBuffer tb, short row, short col, short count ); static int _DtTermSetEnhancement ( TermBuffer tb, short row, short col, unsigned char id, enhValue value ); static Boolean _DtTermGetEnhancement ( const TermBuffer tb, const short row, const short col, enhValue **enhancements, short *count, const countSpec countWhich ); static termChar * _DtTermGetCharacterPointer ( TermBuffer tb, short row, short col ); static void _DtTermInsertEnhancements ( const TermBuffer tb, const short row, const short col, short insertCount, const Boolean insertFlag ); static Boolean _DtTermBufferCreateEnhancement ( TermBuffer tb, short row, short col ); static void _DtTermBufferResize ( TermBuffer newTb, short *newRows, short *newCols ); static void _DtTermDeleteEnhancement ( TermBuffer tb, short row, short col, short width ); static short _DtTermInsert ( TermBuffer tb, short row, short col, termChar *newChars, short numChars, Boolean insertFlag, /* if TRUE, insert, else overwrite */ termChar **returnChars, /* pointer to overflow buffer */ short *returnCount /* count of characters in overflow buffer */ ); static Boolean _DtTermSetLineLength ( TermBuffer tb, short row, short newLength ); static short _DtTermGetLineLength ( TermBuffer tb, short row ); static Boolean _DtTermClearLine ( TermBuffer tb, short row, short newLength ); #if (defined(TEST) || defined(__CODECENTER__) || defined(VALIDATE_ENH)) static void validateEnhancements ( TermBuffer tb, short row ); # define VALIDATE_ENHANCEMENTS(tb, row) validateEnhancements((tb), (row)) #else # define VALIDATE_ENHANCEMENTS(tb, row) #endif /* TEST || __CODECENTER__ || VALIDATE_ENH */ /* ** A blank enhancement structure, it will come in handy. */ static DtTermEnhPart blankEnh = {0, 0, 0, 0, 0}; /* ** Create and initialize the Dt-specific parts of the term buffer. */ TermBuffer _DtTermBufferCreateBuffer ( const Widget w, const short rows, const short cols, const short sizeOfBuffer, const short sizeOfLine, const short sizeOfEnh ) { int i; TermBuffer newTB; DtLine *lines; newTB = _DtTermPrimBufferCreateBuffer(w, rows, cols, sizeOfBuffer, sizeOfLine, sizeOfEnh); if (newTB) { VALUE_LIST(newTB) = (enhValues) malloc(NUM_ENHANCEMENT_FIELDS * sizeof(enhValue)); if (!VALUE_LIST(newTB)) { _DtTermPrimBufferFreeBuffer(newTB); return((TermBuffer) NULL); } NUM_ENH_FIELDS(newTB) = NUM_ENHANCEMENT_FIELDS; for (lines = DT_LINES(newTB); lines < DT_LINES(newTB) + ROWS(newTB); lines++) { DT_ENH(*lines) = (DtEnh) NULL; } DT_ENH_STATE(newTB) = blankEnh; DT_ENH_DIRTY(newTB) = 0; ENH_PROC(newTB) = _DtTermEnhProc; BUFFER_CREATE(newTB) = _DtTermBufferCreateBuffer; BUFFER_FREE(newTB) = _DtTermBufferFreeBuffer; BUFFER_RESIZE(newTB) = _DtTermBufferResize; CLEAR_ENH(newTB) = _DtTermClearEnhancements; INSERT_ENH(newTB) = _DtTermInsertEnhancements; DELETE_ENH(newTB) = _DtTermDeleteEnhancement; SET_ENH(newTB) = _DtTermSetEnhancement; GET_ENH(newTB) = _DtTermGetEnhancement; SET_LINE_LENGTH(newTB) = _DtTermSetLineLength; CLEAR_LINE(newTB) = _DtTermClearLine; } return(newTB); } /* ** Resize buffer, this is a helper function, if malloc fails, then the ** appropriate dimensions are forced to the current maximums */ static void _DtTermBufferResize ( TermBuffer tb, short *newRows, short *newCols ) { short i; DtEnh enh; DtLine *lines; /* ** make any necessary width adjustments first... ** ** NOTE: ** We do not take any action if the new column width is less ** than the current column width. It is the responsibility of ** the rendering code to make sure that two column characters ** are handled properly if the second column falls past the last ** column in the window. */ if (*newCols > MAX_COLS(tb)) { termChar *newLineBuffer; /* ** now extend the line buffers and enhancements for all lines, ** (even lines that are not being used at the moment ** (ROWS < MAX_ROWS))... */ lines = DT_LINES(tb); for (i = 0; i < MAX_ROWS(tb); i++) { /* ** only copy the enhancement information when it exists */ if (DT_ENH(lines[i])) { enh = (DtEnh) malloc(*newCols * sizeof(DtTermEnhPart)); if (enh) { /* ** copy the enhancment info for all characters on ** the line, zero out the rest */ (void) memcpy(enh, DT_ENH(lines[i]), WIDTH(lines[i]) * sizeof(DtTermEnhPart)); (void) memset(&enh[WIDTH(lines[i])], 0, (*newCols - WIDTH(lines[i])) * sizeof(DtTermEnhPart)); free(DT_ENH(lines[i])); DT_ENH(lines[i]) = enh; } else { /* ** the malloc failed, revert back to MAX_COLS */ *newCols = MAX_COLS(tb); *newRows = MIN(*newRows, MAX_ROWS(tb)); break; } } newLineBuffer = (termChar *) malloc((unsigned) *newCols * BYTES_PER_CHAR(tb)); if (newLineBuffer == NULL) { /* ** line buffer malloc failed, we can only increase the ** width to the current maximum... */ *newCols = MAX_COLS(tb); *newRows = MIN(*newRows, MAX_ROWS(tb)); break; } memcpy(newLineBuffer, BUFFER(lines[i]), LENGTH(lines[i]) * BYTES_PER_CHAR(tb)); free(BUFFER(lines[i])); BUFFER(lines[i]) = newLineBuffer; WRAPPED(lines[i]) = False; } MAX_COLS(tb) = *newCols; } COLS(tb) = *newCols; /* ** now adjust the length of the buffer as necessary... */ if (*newRows > MAX_ROWS(tb)) { /* ** the number of rows is increasing */ lines = (DtLine *) malloc((unsigned) *newRows * sizeof(DtLine)); if (lines != NULL) { /* ** the malloc succeeded, copy the old information, and then ** free it... */ memcpy(lines, DT_LINES(tb), sizeof(DtLine) * MAX_ROWS(tb)); free(DT_LINES(tb)); LINES(tb) = (TermLine *)lines; /* ** now initialize the new lines... ** ** NOTE: ** If we are unable to malloc any part of a line, adjust ** "newRows" and break. */ for (i = MAX_ROWS(tb); i < *newRows; i++) { lines[i] = (DtLine) malloc(SIZE_OF_LINE(tb)); if (lines[i]) { DT_ENH(lines[i]) = NULL; BUFFER(lines[i]) = (termChar *) malloc((unsigned) COLS(tb) * BYTES_PER_CHAR(tb)); if (BUFFER(lines[i])) { LENGTH(lines[i]) = 0; WIDTH(lines[i]) = 0; WRAPPED(lines[i]) = False; } else { /* ** the line buffer malloc failed... */ *newRows = i; break; } } else { /* ** we couldn't malloc this line... */ *newRows = i; break; } } MAX_ROWS(tb) = *newRows; } else { /* ** the malloc for the row buffer failed, revert back to MAX_ROWS */ *newRows = MAX_ROWS(tb); } } ROWS(tb) = *newRows; } /* ** Free the buffer. ** ** NOTE: This is a helper function, and should only be called by ** TermPrimBufferFreeBuffer. */ void _DtTermBufferFreeBuffer ( const TermBuffer tb ) { DtLine *lines; /* ** Free the Dt-specific buffer info... */ for (lines = DT_LINES(tb); lines < DT_LINES(tb) + ROWS(tb); lines++) { if (DT_ENH(*lines)) { (void) free(DT_ENH(*lines)); } } if (VALUE_LIST(tb)) { (void) free(VALUE_LIST(tb)); } } /* ** clear all the enhancements from startCol through stopCol */ static void clearEnhancements ( TermBuffer tb, short row, short col, short count ) { DtEnh enh; int i; enh = DT_ENH(DT_LINE_OF_TBUF(tb, row)); if (enh) { enh += col; for(i = 0; i < count; i++) { /* ** Clear all of the enhancement information. */ *enh = blankEnh; enh++; } } } /* ** Clear "count" enhancement blocks, starting at the specified row and column. */ static void _DtTermClearEnhancements ( TermBuffer tb, short row, short col, short count ) { clearEnhancements(tb, row, col, count); } /* ** Insert the desired number of enhancements at the specified ** position... ** ** NOTE: ** We depend on the calling function to insure that insertCount ** has been properly clipped to insure that we don't go out of ** bounds. ** Results are undefined if this function is called when the specified ** column is at the end of the line. */ static void _DtTermInsertEnhancements ( const TermBuffer tb, const short row, const short col, short insertCount, const Boolean insertFlag ) { DtTermEnhPart fillEnh; DtEnh enh; DtLine line; int i; int copyCount; line = DT_LINE_OF_TBUF(tb, row); enh = DT_ENH(line); /* ** There's nothing to do if we're past the end of the line or ** the dirty bit is clear and there are no ehancements on ** this line... */ if ((col < WIDTH(line)) && ((DT_ENH_DIRTY(tb)) || (enh != NULL))) { if ((enh == NULL)) { /* ** there are currently no enhancements on this line, ** allocate an enhancement buffer, and reset 'enh'... */ _DtTermBufferCreateEnhancement(tb, row, col); enh = DT_ENH(line); } /* ** get a copy of the current enhancement (we'll insert 'copyCount' ** copies of it into the enhancement buffer) */ fillEnh = DT_ENH_STATE(tb); if (insertFlag) { /* ** we're in insert mode, move any existing enhancements... */ copyCount = MIN((WIDTH(line) - col), (COLS(tb) - col - insertCount)); copyCount = MAX(0, copyCount); memmove(enh + col + insertCount, enh + col, copyCount * sizeof(DtTermEnhPart)); } #ifdef NOCODE /* ** insert insertCount copies of fillEnh into the enhancement buffer ** starting at line->enh[col + 1]... */ enh += col + 1; for (i = 0; i < insertCount; i++) { *enh = fillEnh; enh++; } #else /* NOCODE */ /* ** insert insertCount copies of fillEnh into the enhancement buffer ** starting at line->enh[col + 1]... */ enh += col; for (i = 0; i < insertCount; i++) { *enh = fillEnh; enh++; } #endif /* NOCODE */ } } void _DtTermBufferDelete ( TermBuffer tb, short *row, short *col, short *count /* number of columns to delete */ ) { _DtTermPrimBufferDelete(tb, row, col, count, NULL, NULL); } /* ** delete the desired enhancements starting the specified position... */ static void _DtTermDeleteEnhancement ( TermBuffer tb, short row, short col, short width ) { DtEnh enh; DtTermEnhPart fillEnh; DtLine line; int copyCount; line = DT_LINE_OF_TBUF(tb, row); enh = DT_ENH(line); if ((enh == NULL) || (WIDTH(line) <= col)) { /* ** no enhancements, or at (or past) the end of the line, return */ return; } /* ** move all of the enhancement blocks between col + width and the ** end of the line to col */ copyCount = WIDTH(line) - (col + width); memmove(enh + col , enh + col + width, copyCount * sizeof(DtTermEnhPart)); } /* ** Create an enhancement block at the specified row and column. ** ** NOTE: For the time being, we simply allocate an entire row's worth ** of enhancement blocks if it doesn't exist already. We may ** get smarter later on. */ /*ARGSUSED*/ static Boolean _DtTermBufferCreateEnhancement ( TermBuffer tb, short row, short col ) { DtLine line; DtEnh *enh; if (!VALID_ROW(tb, row) || !VALID_COL(tb, col)) { return(False); } line = DT_LINE_OF_TBUF(tb, row); enh = &(DT_ENH(line)); /* ** If this row already has enhancement blocks allocated, return. */ if (*enh == NULL) { /* ** Otherwise, allocate and initialize a row of enhancement blocks. */ *enh = (DtEnh) malloc(MAX_COLS(tb) * sizeof(DtTermEnhPart)); if (*enh == NULL) { return(False); } /* ** Clear all the enhancements... */ (void) memset(*enh, 0, MAX_COLS(tb) * sizeof(DtTermEnhPart)); } return(True); } /* ** Free the enhancement block at the specified row and column. ** ** NOTE: We may get smarter later on. */ Boolean _DtTermBufferFreeEnhancement ( TermBuffer tb, short row, short col ) { return(True); } /* ** Set the desired enhancement. ** ** This function does the right thing (as far as I can tell regarding ** propagating enhancements). ** ** Return: ** -1 : the enhancement was not set ** >= 0 : the number of characters (as opposed to character positions) ** that the enhancement affects */ static int _DtTermSetEnhancement ( TermBuffer tb, short row, short col, unsigned char id, enhValue value ) { int i; DtEnh enhState; enhState = (DtEnh) &(DT_ENH_STATE(tb)); /* ** Set the value. */ switch (id) { case enhVideo: enhState->video = value & VIDEO_MASK; break; case enhField: enhState->field = value & FIELD_MASK; break; case enhFgColor: enhState->fgColor = value & COLOR_MASK; break; case enhBgColor: enhState->bgColor = value & COLOR_MASK; break; case enhFont: enhState->font = value & FONT_MASK; break; default: return(-1); } /* ** We've set the value, now decide if this anything but the blank ** enhancement. */ DT_ENH_DIRTY(tb) = ((enhState->video != blankEnh.video ) || (enhState->field != blankEnh.field ) || (enhState->fgColor != blankEnh.fgColor) || (enhState->bgColor != blankEnh.bgColor) || (enhState->font != blankEnh.font )); /* ** return the correct count (which in this case will always be 0) */ return(0); } /* ** Get the enhancements for the desired row and column. ** ** enhValues: ** a pointer to an array of the current enhancement values ** ** count: ** the number of columns for which the enhancements are ** valid, or the number of columns until the enhancements ** were modified by an escape sequence (see 'countWhich' below) ** ** countWhich: ** if 'countWhich' is countAll then count until any enhancement value ** changes ** if 'countAll' is countNew then count until a new enhancement value ** starts (regardless of whether it is the same or not). ** ** Return: ** True if row and col are valid */ static Boolean _DtTermGetEnhancement ( const TermBuffer tb, const short row, const short col, enhValue **values, short *count, const countSpec countWhich ) { /* ** store the current enhancement values here */ int i; DtLine line; DtEnh enh; /* ** First we do some simple bounds checking */ VALIDATE_ENHANCEMENTS(tb, row); if (!VALID_ROW(tb, row) || !VALID_COL(tb, col)) { return(False); } line = DT_LINE_OF_TBUF(tb, row); /* ** point to the correct enhancement chunk. */ if (DT_ENH(line) == NULL || (WIDTH(line) <= col)) { /* ** There are either no enhancements allocated for this line, ** or we're past the end of the line, in either case return ** a blank enhancement. */ enh = &blankEnh; } else { /* ** We're in the line get the current enhancement values */ enh = &(DT_ENH(line)[col]); } /* ** Shove the enhancement values into their correct locations... */ *values = (VALUE_LIST(tb)); (*values)[(int)enhVideo ] = (enh->video & VIDEO_MASK); (*values)[(int)enhField ] = (enh->field & FIELD_MASK); (*values)[(int)enhFgColor] = (enh->fgColor & COLOR_MASK); (*values)[(int)enhBgColor] = (enh->bgColor & COLOR_MASK); (*values)[(int)enhFont ] = (enh->font & FONT_MASK ); /* ** Now count how many characters are affected by the enhancements. */ if (DT_ENH(line) == NULL) { /* ** There no enhancements allocated for this line, the default ** enhancement is active for the remainder of the line. ** NOTE: Make sure count >= 0. */ *count = MAX(0, WIDTH(line) - col); } else if (WIDTH(line) <= col) { /* ** We're past the end of the line, count will always == 0; */ *count = 0; } else { /* ** We're in the line, determine the number of characters that ** these enhancements apply to. */ switch (countWhich) { case countNew: /* ** For Vt220 emulation, countNew is the same as countAll... ** JRM 08/30/93 */ case countAll: /* ** count until an enhancement value changes */ for (i = 0; i < (WIDTH(line) - col); i++) { if (((*values)[(int)enhVideo ] != (enh->video & VIDEO_MASK))|| ((*values)[(int)enhField ] != (enh->field & FIELD_MASK))|| ((*values)[(int)enhFgColor] != (enh->fgColor & COLOR_MASK))|| ((*values)[(int)enhBgColor] != (enh->bgColor & COLOR_MASK))|| ((*values)[(int)enhFont ] != (enh->font & FONT_MASK )) ) { /* ** the enhancements differ; break out */ break; } enh++; } break; default: VALIDATE_ENHANCEMENTS(tb, row); return(False); } *count = i; } VALIDATE_ENHANCEMENTS(tb, row); return(True); } /* ** This is a vt-specific helper function for setting the line length. ** By the time the function is called, termBufferSetLineLength() ** as already validated the newLength, the row, and insured that the ** new length is > the current length ** ** This function propagates the correct enhancement to the new end of line. */ static Boolean _DtTermSetLineLength ( TermBuffer tb, short row, short newLength ) { return(True); } /* ** _DtTermPrimBufferClearLine will reset the line width, this is ** our chance to clear any enhancements that may exist on this line... */ static Boolean _DtTermClearLine ( TermBuffer tb, short row, short newWidth ) { DtLine line; DtEnh enh; line = DT_LINE_OF_TBUF(tb, row); enh = DT_ENH(line); if (enh != NULL) { /* ** We have enhancements, clear all those between the current ** and the new length... */ (void) memset(&enh[newWidth], 0, (WIDTH(line) - newWidth) * sizeof(DtTermEnhPart)); } return(True); } /* ** Erase characters on the specified row (and clear the enhancements) with ** the appropriate semantics. For VT class emulators, there are several ** ways to erase characters: ** - from the active position to the end of line ** - erase the specified number of characters starting at the current ** cursor position ** - from the start of the line to the active position ** - erase the entire line ** - from the active position to the end of the buffer ** - erase the specified number of lines starting at the current ** cursor position ** - from the start of the buffer to the active position ** - erase the entire buffer */ void _DtTermBufferErase ( TermBuffer tb, short row, short col, short count, DtEraseMode eraseSwitch ) { short startCol = 0; short lastCol = 0; switch(eraseSwitch) { case eraseFromCol0: /* ** erase from col 0 to the current cursor position */ startCol = 0; lastCol = MIN(col, WIDTH(DT_LINE_OF_TBUF(tb, row)) - 1); break; case eraseCharCount: /* ** erase "count" characters from the current cursor position */ startCol = col; lastCol = MIN(col + count - 1, WIDTH(DT_LINE_OF_TBUF(tb, row)) - 1); break; case eraseLineCount: case eraseToEOL: case eraseLine: case eraseBuffer: case eraseFromRow0Col0: case eraseToEOB: /* ** These cases should have been handled by _DtTermFuncErase() */ return; } _DtTermPrimBufferErase(tb, row, startCol, lastCol); /* ** now clear the corresponding enhancements... */ clearEnhancements(tb, row, startCol, lastCol - startCol + 1); } #if (defined(TEST) || defined(__CODECENTER__) || defined(VALIDATE_ENH)) static void _DtTermValidateEnhancements ( TermBuffer tb, short row ) { DtTermEnhPart refEnh; DtEnh thisEnh; DtLine thisLine; short col; Boolean validatePassed; validatePassed = True; thisLine = DT_LINE_OF_TBUF(tb, row); if (DT_ENH(thisLine)) { /* ** Initialize the reference enhancement */ refEnh = blankEnh; refEnh.videoStart = 0; refEnh.fieldStart = 0; refEnh.colorStart = 0; refEnh.fontStart = 0; for(col = 0, thisEnh = DT_ENH(thisLine); col < WIDTH(thisLine) + (DANGLE(thisLine) >= 0 ? 1 : 0); col++, thisEnh++) { if (thisEnh->videoStart) { refEnh.video = thisEnh->video; } else if (refEnh.video != thisEnh->video) { fprintf(stderr, "Video enhancements don't match:"); fprintf(stderr, " row : %3.3d, col : %3.3d\n", row, col); fprintf(stderr, " refEnh.video : %d\n", (int)(refEnh.video & VIDEO_MASK)); fprintf(stderr, " thisEnh->video: %d\n", (int)(thisEnh->video & VIDEO_MASK)); validatePassed = False; } if (thisEnh->fieldStart) { refEnh.field = thisEnh->field; } else if (refEnh.field != thisEnh->field) { fprintf(stderr, "Field enhancements don't match:"); fprintf(stderr, " row : %3.3d, col : %3.3d\n", row, col); fprintf(stderr, " refEnh.field : %d\n", (int)(refEnh.field & FIELD_MASK)); fprintf(stderr, " thisEnh->field: %d\n", (int)(thisEnh->field & FIELD_MASK)); validatePassed = False; } if (thisEnh->colorStart) { refEnh.color = thisEnh->color; } else if (refEnh.color != thisEnh->color) { fprintf(stderr, "Color enhancements don't match:"); fprintf(stderr, " row : %3.3d, col : %3.3d\n", row, col); fprintf(stderr, " refEnh.color : %d\n", (int)(refEnh.color & COLOR_MASK)); fprintf(stderr, " thisEnh->color: %d\n", (int)(thisEnh->color & COLOR_MASK)); validatePassed = False; } if (thisEnh->font <= 2) { if (thisEnh->fontStart) { refEnh.font = thisEnh->font; } else if (refEnh.font != thisEnh->font) { fprintf(stderr, "Font enhancements don't match:"); fprintf(stderr, " row : %3.3d, col : %3.3d\n", row, col); fprintf(stderr, " refEnh.font : %d\n", (int)(refEnh.font & FONT_MASK)); fprintf(stderr, " thisEnh->font: %d\n", (int)(thisEnh->font & FONT_MASK)); validatePassed = False; } } else { fprintf(stderr, "Font enhancement out of range:"); fprintf(stderr, " row : %3.3d, col : %3.3d\n", row, col); fprintf(stderr, " thisEnh->font: %d\n", (int)(thisEnh->font & FONT_MASK)); validatePassed = False; } } } if (validatePassed == False) { fprintf(stderr, "validateEnhancement failed\n"); } } #endif /* TEST || __CODECENTER__ || DEBUG || VALIDATE_ENH */ #if (defined(TEST) || defined(__CODECENTER__) || defined(DEBUG)) #ifdef NOCODE static void _printLine ( TermBuffer tb, short row ) { DtLine line; termChar *pChar; short j; printf("Line: %d\n", row); line = tb->lines[row]; printf(" length: %3d\n", line->length); if (line->length > 0) { printf(" buffer: <"); pChar = line->buffer; for (j = 0; j < line->length; j++) { printf("%X", *pChar++); } printf(">\n"); } } static int _DtTermPrintEnhancement ( TermBuffer tb, short row, short col ) { enhValue enhancements[NUM_ENHANCEMENT_FIELDS]; short enhCount; _DtTermPrimBufferGetEnhancement(tb, row, col, enhancements, &enhCount, countNew); printf(" col : %d\n", col); printf(" Count: %d\n", enhCount); printf(" Video: '_"); printf("%s", IS_BOLD(enhancements[enhVideo]) != 0 ? "B":"b"); printf("_"); printf("%s", IS_SECURE(enhancements[enhVideo]) != 0 ? "S":"s"); printf("_"); printf("%s", IS_HALF_BRIGHT(enhancements[enhVideo]) != 0 ? "H":"h"); printf("_"); printf("%s", IS_UNDERLINE(enhancements[enhVideo]) != 0 ? "U":"u"); printf("_"); printf("%s", IS_INVERSE(enhancements[enhVideo]) != 0 ? "I":"i"); printf("_"); printf("%s", IS_BLINK(enhancements[enhVideo]) != 0 ? "B":"b"); printf("_'\n"); /* ** Field type */ printf(" Field: "); switch (enhancements[enhField]) { case FIELD_PROTECT: printf("PROTECT"); break; case FIELD_UNPROTECT: printf("UNPROTECT"); break; case FIELD_TRANSMIT: printf("TRANSMIT"); break; case FIELD_END: printf("END"); break; } printf("\n"); /* ** Color id */ printf(" Color: %1d\n", enhancements[enhFont]); /* ** Font id */ printf(" Font : "); switch (enhancements[enhFont]) { case FONT_NORMAL: printf("NORMAL"); break; case FONT_LINEDRAW: printf("LINEDRAW"); break; } printf("\n"); return(enhCount); } #endif /* NOCODE */ static void printEnh ( DtEnh enh ) { printf(" video : %d\n", enh->video); printf(" field : %d\n", enh->field); printf(" fgColor: %d\n", enh->fgColor); printf(" bgColor: %d\n", enh->bgColor); printf(" font : %d\n", enh->font); } /* ** Print the contents of the TermBuffer. */ static void _DtTermPrintBuffer ( DtTermBuffer tb ) { short i; short j; short k; if (tb == NULL) { printf("TermBuffer has been freed.\n"); return; } printf("TermBuffer dimensions:\n"); printf(" rows: %d\n", ROWS(tb)); printf(" cols: %d\n", COLS(tb)); printf(" enhDirty: %d\n", DT_ENH_DIRTY(tb)); printf(" enhState:\n"); printEnh(&(DT_ENH_STATE(tb))); #ifdef NOCODE for (i = 0; i < ROWS(tb); i++) { _printLine(tb, i); j = 0; do { k = _termBufferPrintEnhancement(tb, i, j); if (k == 0) { break; } j += k; } while (j < COLS(tb)); } #endif /* NOCODE */ } #endif /* (defined(TEST) || defined(__CODECENTER__)) */ #ifdef TEST /* ** Some simple tests of the termBuffer. */ /* the following is to allow for a single main function in the code... */ #define termBufMain main termBufMain() { TermBuffer myTB; printf("Sizeof DtTermEnhPart : %d\n", sizeof(struct _DtTermEnhPart)); printf("Sizeof termBufferRec : %d\n", sizeof(struct _TermBufferRec)); myTB = _DtTermPrimBufferCreateBuffer(12, 80); _termBufferPrintBuffer(myTB); printf("[0,0] %d\n", _DtTermPrimBufferSetEnhancement(myTB, 0, 0, enhVideo, BLINK)); _termBufferPrintEnhancement(myTB, 0, 0); printf("[0,1] %d\n", _DtTermPrimBufferSetEnhancement(myTB, 0, 1, enhVideo, INVERSE)); _termBufferPrintEnhancement(myTB, 0, 0); _termBufferPrintEnhancement(myTB, 0, 1); printf("[0,9] %d\n", _DtTermPrimBufferSetEnhancement(myTB, 0, 9, enhVideo, UNDERLINE)); _termBufferPrintEnhancement(myTB, 0, 0); _termBufferPrintEnhancement(myTB, 0, 1); _termBufferPrintEnhancement(myTB, 0, 9); printf("[0,6] %d\n", _DtTermPrimBufferSetEnhancement(myTB, 0, 6, enhVideo, HALF_BRIGHT)); _termBufferPrintEnhancement(myTB, 0, 0); _termBufferPrintEnhancement(myTB, 0, 1); _termBufferPrintEnhancement(myTB, 0, 6); _termBufferPrintEnhancement(myTB, 0, 9); _termBufferPrintBuffer(myTB); _DtTermPrimBufferSetEnhancement(myTB, 10, 10, enhVideo, BLINK); _DtTermPrimBufferSetEnhancement(myTB, 10, 20, enhColor, 3); _termBufferPrintBuffer(myTB); _DtTermPrimBufferResizeBuffer(&myTB, 6, 40); _termBufferPrintBuffer(myTB); _DtTermPrimBufferSetEnhancement(myTB, 10, 10, enhVideo, BLINK); _DtTermPrimBufferResizeBuffer(&myTB, 12, 80); _termBufferPrintBuffer(myTB); _DtTermPrimBufferFreeBuffer(myTB); } #endif /* TEST */