123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335 |
- /*
- * 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 <Xm/Xm.h>
- #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 */
|