Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
ltermPrivate.h File Reference
#include <string.h>
#include "lineterm.h"
#include "tracelog.h"
#include "ptystream.h"
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/poll.h>
#include <pthread.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  LtermRead
struct  LtermInput
struct  LtermOutput
struct  LtermProcess
struct  lterms
struct  LtermGlobal

Defines

#define LTERM_ERROR   TLOG_ERROR
#define LTERM_WARNING   TLOG_WARNING
#define LTERM_LOG(procname, level, args)   TLOG_PRINT(LTERM_TLOG_MODULE,procname,level,args)
#define LTERM_LOGUNICODE(procname, level, args)   TLOG_UNICHAR(LTERM_TLOG_MODULE,procname,level,args)
#define int32   long
#define MALLOC(x)   malloc(x)
#define REALLOC(x, y)   realloc((x),(y))
#define CALLOC(x, y)   calloc((x),(y))
#define FREE(x)   free(x)
#define NULL_FILEDESC   -1
#define VALID_FILEDESC(x)   (x >= 0)
#define SIZE_T   size_t
#define WRITE   write
#define READ   read
#define CLOSE(x)   close(x)
#define PIPE(x)   pipe(x)
#define POLL(x, y, z)   poll((x),(y),(z))
#define POLLFD   pollfd
#define POLL_EVENTS   events
#define POLL_REVENTS   revents
#define POLL_READ   POLLIN
#define PROCESS   long
#define NULL_PROCESS   0
#define VALID_PROCESS(x)   (x > 0)
#define MUTEX_DECLARE(x)   pthread_mutex_t x
#define MUTEX_INITIALIZE(x)   pthread_mutex_init(&(x), NULL)
#define MUTEX_LOCK(x)   pthread_mutex_lock(&(x))
#define MUTEX_UNLOCK(x)   pthread_mutex_unlock(&(x))
#define MUTEX_DESTROY(x)   pthread_mutex_destroy(&(x))
#define THREAD_DECLARE(x)   pthread_t x
#define THREAD_CREATE(x, y, z)   pthread_create(&(x),NULL,(y),(z))
#define THREAD_SELF   pthread_self
#define THREAD_EQUAL(x, y)   pthread_equal(x,y)
#define THREAD_JOIN(x)   pthread_join((x),NULL)
#define MAXTERM
#define MAXCOL
#define MAXROW
#define MAXPROMPT   256 /* Maximum length of prompt regexp+1 */
#define MAXRAWINCOMPLETE   5 /* Maximum incomplete raw buffer size */
#define MAXSTREAMTERM   11 /* Maximum stream terminator buffer size */
#define MAXCOOKIESTR   64 /* Maximum length of cookie string+1 */
#define MAXESCAPEPARAMS   16 /* Maximum no. of numeric ESCAPE parameters */
#define MAXSTRINGPARAM   512 /* Maximum length of string ESCAPE parameters */
#define MAXSHELLINITCMD   2 /* Maximum no. of shell init commands */
#define MAXSHELLINITSTR   256 /* Maximum length of shell init string+1 */
#define MAXPTYIN   128 /* 1/2 POSIX minimum MAX_INPUT for PTY */
#define MAXCOLM1   (MAXCOL-1) /* Maximum columns in line buffer - 1 */
#define MAXTTYCONTROL   8 /* Maximum TTY control character list */
#define TTYINTERRUPT   0
#define TTYERASE   1
#define TTYKILL   2
#define TTYEOF   3
#define TTYSUSPEND   4
#define TTYREPRINT   5
#define TTYDISCARD   6
#define TTYWERASE   7
#define LTERM0_RAW_MODE   0
#define LTERM1_CANONICAL_MODE   1
#define LTERM2_EDIT_MODE   2
#define LTERM3_COMPLETION_MODE   3
#define LTERM_NO_COMPLETION   0
#define LTERM_TAB_COMPLETION   1
#define LTERM_HISTORY_COMPLETION   2
#define LTERM0_STREAM_MODE   0
#define LTERM1_SCREEN_MODE   1
#define LTERM2_LINE_MODE   2
#define LTERM_INSERT_ACTION   0
#define LTERM_DELETE_ACTION   1
#define LTERM_ERASE_ACTION   2
#define LTERM_AMP_ESCAPE   0
#define LTERM_LT_ESCAPE   1
#define LTERM_GT_ESCAPE   2
#define LTERM_QUOT_ESCAPE   3
#define LTERM_APOS_ESCAPE   4
#define LTERM_XML_ESCAPES   5
#define LTERM_PLAIN_ESCAPES   3
#define LTERM_MAXCHAR_ESCAPE   6
#define PIPEHEADER   2
#define PHDR_CHARS   0
#define PHDR_TYPE   1
#define POLL_COUNT   3
#define POLL_INPUTBUF   0
#define POLL_STDOUT   1
#define POLL_STDERR   2

Typedefs

typedef int FILEDESC
typedef FILE FILESTREAM

Functions

int ltermInterruptOutput (struct lterms *lts)
 Interrupts output operations in response to an input TTY interrupt signal.
int ltermSendLine (struct lterms *lts, UNICHAR uch, int echoControl, int completionCode)
 Transmits input line + optional control character UCH to child process.
int ltermRead (struct lterms *lts, struct LtermRead *ltr, int timeout)
 Reads a (possibly incomplete) line from LTERM.
int ltermPlainTextInput (struct lterms *lts, const UNICHAR *buf, int count, int *opcodes)
 Processes plain text input data and returns OPCODES ::= LINEDATA ( INPUT ( NEWLINE HIDE? )? | INPUT META ( COMPLETION | NEWLINE HIDE? ) ) if echoable input data was processed.
int ltermCancelCompletion (struct lterms *lts)
 Cancels a prior command line completion request.
int ltermInsertChar (struct LtermInput *lti, UNICHAR uch)
 Inserts plain text character UCH as a single-column glyph at the current input cursor location, translating to escape sequence if needed.
void ltermSwitchToRawMode (struct lterms *lts)
 switches to raw input mode
void ltermClearInputLine (struct lterms *lts)
 clears input line buffer and switches to regular input mode
int ltermDeleteGlyphs (struct LtermInput *lti, int count)
 Deletes glyphs from the input line.
int ltermSendData (struct lterms *lts, const UNICHAR *buf, int count)
 Transmits COUNT Unicode characters from BUF to child process after translating Unicode to UTF8 or Latin1, as appropriate.
int ltermSendChar (struct lterms *lts, const char *buf, int count)
 Transmits COUNT characters from BUF to child process.
int ltermProcessOutput (struct lterms *lts, int *opcodes, int *opvals, int *oprow)
 Processes output from decoded output buffer and returns *opcodes: OPCODES ::= SCREENDATA BELL? ( CLEAR | INSERT | DELETE | SCROLL )? if ScreenMode data is being returned.
int ltermReceiveData (struct lterms *lts, int readERR)
 Reads data from process STDOUT and/or STDERR using file descriptors from the LTERM POLL structure, and converts to Unicode, saving incomplete character encodings in corresponding incomplete raw buffers.
void ltermClearOutputLine (struct lterms *lts)
 Clears output line buffer.
int ltermClearOutputScreen (struct lterms *lts)
 Clears output screen buffer (allocating memory, if first time/resized)
int ltermSwitchToStreamMode (struct lterms *lts, int streamOpcodes, const UNICHAR *streamTerminator)
 Saves current output mode value and switches to stream output mode, with specified opcodes and terminator string.
int ltermSwitchToScreenMode (struct lterms *lts)
 Switches to screen output mode.
int ltermSwitchToLineMode (struct lterms *lts)
 Switches to line output mode.
int ltermProcessEscape (struct lterms *lts, const UNICHAR *buf, int count, const UNISTYLE *style, int *consumed, int *opcodes, int *opvals, int *oprow)
 Processes ESCAPE sequence in string BUF containing COUNT characters, returning the number of characters CONSUMED and the OPCODES.
int ltermInsDelEraseChar (struct lterms *lts, int count, int action)
 Insert/delete/erase COUNT characters at current output cursor position.
int ltermInsDelEraseLine (struct lterms *lts, int count, int row, int action)
 Insert COUNT blank lines about current current line, scrolling down, or delete COUNT lines at and below current line, scrolling up remaining lines, or erase COUNT lines at and below current line.

Variables

LtermGlobal ltermGlobal

Class Documentation

struct LtermRead

Definition at line 286 of file ltermPrivate.h.

Collaboration diagram for LtermRead:
Class Members
UNICHAR * buf
int buf_col
int buf_row
int cursor_col
int cursor_row
int max_count
int opcodes
int opvals
int read_count
UNISTYLE * style
struct LtermInput

Definition at line 300 of file ltermPrivate.h.

Collaboration diagram for LtermInput:
Class Members
int clearInputLine
int escapeCSIArg
int escapeCSIFlag
int escapeFlag
UNICHAR inputBuf
int inputBufBytes
int inputChars
unsigned short inputColCharIndex
int inputCols
int inputCursorGlyph
unsigned short inputGlyphCharIndex
unsigned short inputGlyphColIndex
int inputGlyphs
UNICHAR inputLine
int inputMode
int inputOpcodes
struct LtermOutput

Definition at line 375 of file ltermPrivate.h.

Collaboration diagram for LtermOutput:
Class Members
int automaticNewline
int botScrollRow
long callbackTag
int cursorCol
int cursorRow
int decodedChars
UNICHAR decodedOutput
UNISTYLE decodedStyle
int incompleteEscapeSequence
int insertMode
int modifiedCol
int nfds
int outputChars
int outputCursorChar
UNICHAR outputLine
int outputMode
int outputModifiedChar
UNISTYLE outputStyle
int promptChars
char rawERRBuf
int rawERRBytes
char rawOUTBuf
int rawOUTBytes
int returnedCursorCol
int returnedCursorRow
int savedOutputMode
UNICHAR * screenChar
UNISTYLE * screenStyle
int streamOpcodes
UNICHAR streamTerminator
UNISTYLE styleMask
int topScrollRow
struct LtermProcess

Definition at line 435 of file ltermPrivate.h.

Class Members
FILEDESC processERR
PROCESS processID
FILEDESC processIN
FILEDESC processOUT

Define Documentation

#define CALLOC (   x,
  y 
)    calloc((x),(y))

Definition at line 105 of file ltermPrivate.h.

#define CLOSE (   x)    close(x)

Definition at line 161 of file ltermPrivate.h.

#define FREE (   x)    free(x)

Definition at line 106 of file ltermPrivate.h.

#define int32   long

Definition at line 101 of file ltermPrivate.h.

Definition at line 245 of file ltermPrivate.h.

Definition at line 256 of file ltermPrivate.h.

Definition at line 246 of file ltermPrivate.h.

Definition at line 257 of file ltermPrivate.h.

Definition at line 247 of file ltermPrivate.h.

Definition at line 258 of file ltermPrivate.h.

Definition at line 248 of file ltermPrivate.h.

Definition at line 266 of file ltermPrivate.h.

Definition at line 270 of file ltermPrivate.h.

Definition at line 262 of file ltermPrivate.h.

Definition at line 263 of file ltermPrivate.h.

Definition at line 77 of file ltermPrivate.h.

Definition at line 268 of file ltermPrivate.h.

Definition at line 253 of file ltermPrivate.h.

Definition at line 261 of file ltermPrivate.h.

#define LTERM_LOG (   procname,
  level,
  args 
)    TLOG_PRINT(LTERM_TLOG_MODULE,procname,level,args)

Definition at line 79 of file ltermPrivate.h.

#define LTERM_LOGUNICODE (   procname,
  level,
  args 
)    TLOG_UNICHAR(LTERM_TLOG_MODULE,procname,level,args)

Definition at line 80 of file ltermPrivate.h.

Definition at line 267 of file ltermPrivate.h.

Definition at line 276 of file ltermPrivate.h.

Definition at line 251 of file ltermPrivate.h.

Definition at line 273 of file ltermPrivate.h.

Definition at line 269 of file ltermPrivate.h.

Definition at line 252 of file ltermPrivate.h.

Definition at line 78 of file ltermPrivate.h.

Definition at line 272 of file ltermPrivate.h.

#define MALLOC (   x)    malloc(x)

Definition at line 103 of file ltermPrivate.h.

Value:
4096            /* Maximum columns in line buffer;
                                * affects static memory "footprint";
                                * the only limitation on this value is that
                                * it must fit into a UNICHAR, because of the
                                * way lterm_write and ltermWrite implement
                                * the input buffer pipe.
                                */

Definition at line 214 of file ltermPrivate.h.

#define MAXCOLM1   (MAXCOL-1) /* Maximum columns in line buffer - 1 */

Definition at line 232 of file ltermPrivate.h.

#define MAXCOOKIESTR   64 /* Maximum length of cookie string+1 */

Definition at line 224 of file ltermPrivate.h.

#define MAXESCAPEPARAMS   16 /* Maximum no. of numeric ESCAPE parameters */

Definition at line 225 of file ltermPrivate.h.

#define MAXPROMPT   256 /* Maximum length of prompt regexp+1 */

Definition at line 221 of file ltermPrivate.h.

#define MAXPTYIN   128 /* 1/2 POSIX minimum MAX_INPUT for PTY */

Definition at line 230 of file ltermPrivate.h.

#define MAXRAWINCOMPLETE   5 /* Maximum incomplete raw buffer size */

Definition at line 222 of file ltermPrivate.h.

Value:
1024            /* Maximum rows in screen;
                                * primarily affects dynamically allocated
                                * memory
                                */

Definition at line 216 of file ltermPrivate.h.

#define MAXSHELLINITCMD   2 /* Maximum no. of shell init commands */

Definition at line 227 of file ltermPrivate.h.

#define MAXSHELLINITSTR   256 /* Maximum length of shell init string+1 */

Definition at line 228 of file ltermPrivate.h.

#define MAXSTREAMTERM   11 /* Maximum stream terminator buffer size */

Definition at line 223 of file ltermPrivate.h.

#define MAXSTRINGPARAM   512 /* Maximum length of string ESCAPE parameters */

Definition at line 226 of file ltermPrivate.h.

Value:
256            /* Maximum number of LTERMs;
                                * affects static memory "footprint"
                                */

Definition at line 212 of file ltermPrivate.h.

#define MAXTTYCONTROL   8 /* Maximum TTY control character list */

Definition at line 234 of file ltermPrivate.h.

Definition at line 197 of file ltermPrivate.h.

Definition at line 201 of file ltermPrivate.h.

Definition at line 198 of file ltermPrivate.h.

Definition at line 199 of file ltermPrivate.h.

Definition at line 200 of file ltermPrivate.h.

Definition at line 153 of file ltermPrivate.h.

Definition at line 171 of file ltermPrivate.h.

#define PHDR_CHARS   0

Definition at line 282 of file ltermPrivate.h.

#define PHDR_TYPE   1

Definition at line 283 of file ltermPrivate.h.

#define PIPE (   x)    pipe(x)

Definition at line 162 of file ltermPrivate.h.

#define PIPEHEADER   2

Definition at line 279 of file ltermPrivate.h.

#define POLL (   x,
  y,
 
)    poll((x),(y),(z))

Definition at line 164 of file ltermPrivate.h.

#define POLL_COUNT   3

Definition at line 369 of file ltermPrivate.h.

#define POLL_EVENTS   events

Definition at line 166 of file ltermPrivate.h.

Definition at line 370 of file ltermPrivate.h.

#define POLL_READ   POLLIN

Definition at line 168 of file ltermPrivate.h.

#define POLL_REVENTS   revents

Definition at line 167 of file ltermPrivate.h.

Definition at line 372 of file ltermPrivate.h.

Definition at line 371 of file ltermPrivate.h.

#define POLLFD   pollfd

Definition at line 165 of file ltermPrivate.h.

Definition at line 170 of file ltermPrivate.h.

#define READ   read

Definition at line 160 of file ltermPrivate.h.

#define REALLOC (   x,
  y 
)    realloc((x),(y))

Definition at line 104 of file ltermPrivate.h.

#define SIZE_T   size_t

Definition at line 158 of file ltermPrivate.h.

#define THREAD_CREATE (   x,
  y,
 
)    pthread_create(&(x),NULL,(y),(z))

Definition at line 204 of file ltermPrivate.h.

Definition at line 203 of file ltermPrivate.h.

#define THREAD_EQUAL (   x,
  y 
)    pthread_equal(x,y)

Definition at line 206 of file ltermPrivate.h.

Definition at line 207 of file ltermPrivate.h.

Definition at line 205 of file ltermPrivate.h.

#define TTYDISCARD   6

Definition at line 241 of file ltermPrivate.h.

#define TTYEOF   3

Definition at line 238 of file ltermPrivate.h.

#define TTYERASE   1

Definition at line 236 of file ltermPrivate.h.

Definition at line 235 of file ltermPrivate.h.

#define TTYKILL   2

Definition at line 237 of file ltermPrivate.h.

#define TTYREPRINT   5

Definition at line 240 of file ltermPrivate.h.

#define TTYSUSPEND   4

Definition at line 239 of file ltermPrivate.h.

#define TTYWERASE   7

Definition at line 242 of file ltermPrivate.h.

#define VALID_FILEDESC (   x)    (x >= 0)

Definition at line 154 of file ltermPrivate.h.

#define VALID_PROCESS (   x)    (x > 0)

Definition at line 172 of file ltermPrivate.h.

Definition at line 159 of file ltermPrivate.h.


Typedef Documentation

typedef int FILEDESC

Definition at line 152 of file ltermPrivate.h.

typedef FILE FILESTREAM

Definition at line 156 of file ltermPrivate.h.


Function Documentation

int ltermCancelCompletion ( struct lterms lts)

Cancels a prior command line completion request.

Returns:
0 on success, -1 on error

Definition at line 172 of file ltermInput.c.

{

  LTERM_LOG(ltermCancelCompletion,40,
            ("++++++++++++ CANCELED COMPLETION REQUEST\n\n"));

  if (lts->completionRequest != LTERM_NO_COMPLETION) {

    /* Kill input line transmitted to process */
    if (ltermSendData(lts, lts->control+TTYKILL, 1) != 0)
      return -1;

    lts->completionRequest = LTERM_NO_COMPLETION;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ltermClearInputLine ( struct lterms lts)

clears input line buffer and switches to regular input mode

Definition at line 299 of file ltermInput.c.

{
  struct LtermInput *lti = &(lts->ltermInput);

  LTERM_LOG(ltermClearInputLine,40,("\n"));

  lti->inputChars = 0;

  lti->inputCols = 0;
  lti->inputColCharIndex[0] = 0;

  lti->inputGlyphs = 0;
  lti->inputGlyphCharIndex[0] = 0;
  lti->inputGlyphColIndex[0] = 0;

  lti->inputCursorGlyph = 0;

  if (lts->maxInputMode >= LTERM2_EDIT_MODE)
    lti->inputMode = LTERM2_EDIT_MODE;
  else
    lti->inputMode = lts->maxInputMode;

  lti->escapeFlag = 0;
  lti->escapeCSIFlag = 0;
  lti->escapeCSIArg = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ltermClearOutputLine ( struct lterms lts)

Clears output line buffer.

Definition at line 409 of file ltermOutput.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);

  LTERM_LOG(ltermClearOutputLine,40,("\n"));

  lto->outputChars = 0;
  lto->outputCursorChar = 0;
  lto->outputModifiedChar = 0;
  lto->promptChars = 0;

  lts->commandNumber = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermClearOutputScreen ( struct lterms lts)

Clears output screen buffer (allocating memory, if first time/resized)

Definition at line 425 of file ltermOutput.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);
  int j;

  LTERM_LOG(ltermClearOutputScreen,40,("\n"));

  if (lto->screenChar == NULL) {
    /* Allocate memory for full screen */
    int screenSize = lts->nRows * lts->nCols;

    lto->screenChar = (UNICHAR *) MALLOC(screenSize * sizeof(UNICHAR));

    if (lto->screenChar == NULL) {
      LTERM_ERROR("ltermClearOutputScreen: Error - failed to allocate memory for chars\n");
      return -1;
    }

    assert(lto->screenStyle == NULL);
    lto->screenStyle = (UNISTYLE *) MALLOC(screenSize * sizeof(UNISTYLE));

    if (lto->screenStyle == NULL) {
      LTERM_ERROR("ltermClearOutputScreen: Error - failed to allocate memory for style\n");
      return -1;
    }
  }  

  /* Position cursor at home */
  lto->cursorRow = lts->nRows - 1;
  lto->cursorCol = 0;

  /* Blank out entire screen */
  if (ltermInsDelEraseLine(lts, lts->nRows, lts->nRows-1, LTERM_ERASE_ACTION) != 0)
    return -1;

  /* No rows modified yet */
  for (j=0; j<lts->nRows; j++) {
    lto->modifiedCol[j] = -1;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermDeleteGlyphs ( struct LtermInput lti,
int  count 
)

Deletes glyphs from the input line.

If COUNT > 0, glyphs are deleted to the left of the cursor. If COUNT < 0, glyphs are deleted to the right of the cursor. Called from ltermLineInput.

Returns:
0 on success, -1 on error.

Definition at line 707 of file ltermInput.c.

{
  int leftGlyph, leftColIndex, leftCharIndex;
  int rightGlyph, rightColIndex, rightCharIndex;
  int deleteGlyphs, deleteCols, deleteChars, j;

  LTERM_LOG(ltermDeleteGlyphs,40,("deleting %d glyphs from glyph %d\n",
            count, lti->inputCursorGlyph));

  if (count >= 0) {
    /* Delete to the left */
    deleteGlyphs = count;

    /* Limit the number of glyphs deleted to that present to the left */
    if (deleteGlyphs > lti->inputCursorGlyph)
      deleteGlyphs = lti->inputCursorGlyph;

    rightGlyph = lti->inputCursorGlyph;
    leftGlyph = rightGlyph - deleteGlyphs;

  } else {
    /* Delete to the right */
    deleteGlyphs = -count;

    /* Limit the number of glyphs deleted to that present to the right */
    if (deleteGlyphs > (lti->inputGlyphs - lti->inputCursorGlyph))
      deleteGlyphs = lti->inputGlyphs - lti->inputCursorGlyph;

    leftGlyph = lti->inputCursorGlyph;
    rightGlyph = leftGlyph + deleteGlyphs;
  }

  leftColIndex = lti->inputGlyphColIndex[leftGlyph];
  leftCharIndex = lti->inputGlyphCharIndex[leftGlyph];

  rightColIndex = lti->inputGlyphColIndex[rightGlyph];
  rightCharIndex = lti->inputGlyphCharIndex[rightGlyph];

  deleteCols =  rightColIndex  - leftColIndex;
  deleteChars = rightCharIndex - leftCharIndex;

  LTERM_LOG(ltermDeleteGlyphs,41,("deleteCols=%d, deleteChars=%d\n",
                                    deleteCols, deleteChars));

  LTERM_LOG(ltermDeleteGlyphs,42,("leftGlyph=%d, leftCol=%d, leftChar=%d\n",
                                    leftGlyph, leftColIndex, leftCharIndex));

  LTERM_LOG(ltermDeleteGlyphs,42,("rightGlyph=%d, rightCol=%d, rightChar=%d\n",
                                    rightGlyph, rightColIndex, rightCharIndex));

  /* Shift portion of input line to the left;
     remember that the column/glyph index arrays have an extra element */
  for (j = leftCharIndex; j < lti->inputChars-deleteChars; j++)
    lti->inputLine[j] = lti->inputLine[j+deleteChars];

  for (j = leftColIndex; j <= lti->inputCols-deleteCols; j++)
    lti->inputColCharIndex[j] =  lti->inputColCharIndex[j+deleteCols]
                               - deleteChars;

  for (j = leftGlyph; j <= lti->inputGlyphs-deleteGlyphs; j++)
    lti->inputGlyphColIndex[j] =  lti->inputGlyphColIndex[j+deleteGlyphs]
                                - deleteCols;

  lti->inputChars -= deleteChars;             /* Decrement character count */

  lti->inputCols -= deleteCols;               /* Decrement column count */

  lti->inputGlyphs -= deleteGlyphs;           /* Decrement glyph count */

  if (count > 0)
    lti->inputCursorGlyph -= deleteGlyphs;    /* Reposition glyph cursor */

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermInsDelEraseChar ( struct lterms lts,
int  count,
int  action 
)

Insert/delete/erase COUNT characters at current output cursor position.

Parameters:
action= LTERM_INSERT_ACTION (insert) LTERM_DELETE_ACTION (delete) LTERM_ERASE_ACTION (erase)
Returns:
0 on success and -1 on error.

Definition at line 1315 of file ltermEscape.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);
  int charCount = count;
  int j;

  assert(count >= 0);

  LTERM_LOG(ltermInsDelEraseChar,60,("count=%d, action=%d\n",
                 count, action));

  if (lto->outputMode == LTERM2_LINE_MODE) {
    /* Line mode */
    switch (action) {

    case LTERM_INSERT_ACTION:

      if (lto->outputChars + charCount > MAXCOLM1) {
        /* Output buffer overflow; ignore extra inserts */
        LTERM_WARNING("ltermInsDelEraseChar: Warning - output line buffer overflow\n");
        charCount = MAXCOLM1 - lto->outputChars;
      }

      LTERM_LOG(ltermInsDelEraseChar,62,("Line insert %d blank chars\n",
                     charCount));

      /* Shift characters to the right to make room for insertion */
      for (j=lto->outputChars-1; j>=lto->outputCursorChar; j--) {
        lto->outputLine[j+charCount] = lto->outputLine[j];
        lto->outputStyle[j+charCount] = lto->outputStyle[j];
      }

      /* Insert blank characters */
      for (j=lto->outputCursorChar; j<lto->outputCursorChar+charCount; j++) {
        lto->outputLine[j] = U_SPACE;
        lto->outputStyle[j] = LTERM_STDOUT_STYLE | lto->styleMask;
      }

      /* Increment character count */
      lto->outputChars += charCount;
      break;

    case LTERM_DELETE_ACTION:
      if (lto->outputCursorChar+charCount > lto->outputChars)
        charCount = lto->outputChars - lto->outputCursorChar;

      LTERM_LOG(ltermInsDelEraseChar,62,("Line delete %d chars\n",
                     charCount));

      /* Shift characters to the left */
      for (j=lto->outputCursorChar; j<lto->outputChars-charCount; j++) {
        lto->outputLine[j] = lto->outputLine[j+charCount];
        lto->outputStyle[j] = lto->outputStyle[j+charCount];
      }

      /* Decrement character count */
      lto->outputChars -= charCount;
      break;

    case LTERM_ERASE_ACTION:
      if (lto->outputCursorChar+charCount > lto->outputChars)
        charCount = lto->outputChars - lto->outputCursorChar;

      LTERM_LOG(ltermInsDelEraseChar,62,("Line erase %d chars\n",
                     charCount));

      /* Erase characters */
      for (j=lto->outputCursorChar; j<lto->outputCursorChar+charCount; j++) {
        lto->outputLine[j] = U_SPACE;
        lto->outputStyle[j] = LTERM_STDOUT_STYLE | lto->styleMask;
      }

      break;
    }

    /* Note modifications */
    if (lto->outputCursorChar < lto->outputModifiedChar)
      lto->outputModifiedChar = lto->outputCursorChar;

  } else if (lto->outputMode == LTERM1_SCREEN_MODE) {
    /* Screen mode */
    int j0 = lto->cursorRow*lts->nCols;

    switch (action) {

    case LTERM_INSERT_ACTION:
      if (lto->cursorCol+charCount > lts->nCols) {
        /* Ignore inserts beyond screen width */
        LTERM_WARNING("ltermInsDelEraseChar: Warning - screen insert overflow\n");
        charCount = lts->nCols - lto->cursorCol;
      }

      LTERM_LOG(ltermInsDelEraseChar,62,
                ("Screen insert %d blank chars at column %d\n",
                 charCount, lto->cursorCol));

      if (charCount > 0) {
        /* Shift characters to the right to make room for insertion */
        for (j=lts->nCols-1+j0; j>=lto->cursorCol+charCount+j0; j--) {
          lto->screenChar[j] = lto->screenChar[j-charCount];
          lto->screenStyle[j] = lto->screenStyle[j-charCount];
        }

        /* Insert blank characters */
        for (j=lto->cursorCol+j0; j<lto->cursorCol+charCount+j0; j++) {
          lto->screenChar[j] = U_SPACE;
          lto->screenStyle[j] = LTERM_STDOUT_STYLE | lto->styleMask;
        }

        /* Note modified column */
        lto->modifiedCol[lto->cursorRow] = lts->nCols-1;
      }
      break;

    case LTERM_DELETE_ACTION:
      if (lto->cursorCol+charCount > lts->nCols)
        charCount = lts->nCols - lto->cursorCol;

      LTERM_LOG(ltermInsDelEraseChar,62,
                ("Screen delete %d chars at column %d\n",
                 charCount, lto->cursorCol));

      if (charCount > 0) {
        /* Shift characters to the left */
        for (j=lto->cursorCol+j0; j<lts->nCols-charCount+j0; j++) {
          lto->screenChar[j] = lto->screenChar[j+charCount];
          lto->screenStyle[j] = lto->screenStyle[j+charCount];
        }

        /* Note modified column */
        lto->modifiedCol[lto->cursorRow] = lts->nCols-1;
      }

      break;

    case LTERM_ERASE_ACTION:
      if (lto->cursorCol+charCount > lts->nCols)
        charCount = lts->nCols - lto->cursorCol;

      LTERM_LOG(ltermInsDelEraseChar,62,
                ("Screen erase %d chars at column %d\n",
                 charCount, lto->cursorCol));

      if (charCount > 0) {
        /* Erase characters */
        for (j=lto->cursorCol+j0; j<lto->cursorCol+charCount+j0; j++) {
          lto->screenChar[j] = U_SPACE;
          lto->screenStyle[j] = LTERM_STDOUT_STYLE | lto->styleMask;
        }

        /* Note modified column */
        if (lto->modifiedCol[lto->cursorRow] < lto->cursorCol+charCount-1)
          lto->modifiedCol[lto->cursorRow] = lto->cursorCol+charCount-1;
      }

      break;
    }
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermInsDelEraseLine ( struct lterms lts,
int  count,
int  row,
int  action 
)

Insert COUNT blank lines about current current line, scrolling down, or delete COUNT lines at and below current line, scrolling up remaining lines, or erase COUNT lines at and below current line.

Displayed lines above the current line are unaffected, cursor is not moved and no new modification flags are set.

Parameters:
countno. of lines to be inserted/deleted/erased
rowrow for insertion/deletion/erasure
action= LTERM_INSERT_ACTION (insert) LTERM_DELETE_ACTION (delete) LTERM_ERASE_ACTION (erase)
Returns:
0 on success and -1 on error.

Definition at line 1490 of file ltermEscape.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);
  int lineCount, kblank1, kblank2;
  int joffset, jscroll, j, k;

  LTERM_LOG(ltermInsDelEraseLine,60, ("count=%d, row=%d, action=%d\n",
                                      count, row, action));

  lineCount = count;

  switch (action) {

  case LTERM_ERASE_ACTION:
    /* Erase lines down; no scrolling */
    if (lineCount > row + 1)
      lineCount = row + 1;

    kblank1 = row-lineCount+1;
    kblank2 = row;
    break;

  case LTERM_INSERT_ACTION:
    /* Scroll down for insertion */
    if ( (row < lto->botScrollRow) ||
         (row > lto->topScrollRow) ) {
      /* Cursor located outside scrollable region */
      return 0;
    }

    if (lineCount > row - lto->botScrollRow + 1)
      lineCount = row - lto->botScrollRow + 1;

    kblank1 = row-lineCount+1;
    kblank2 = row;

    for (k=lto->botScrollRow; k<=row-lineCount; k++) {
      joffset = k*lts->nCols;
      jscroll = lineCount*lts->nCols;

      lto->modifiedCol[k] = lto->modifiedCol[k+lineCount];

      for (j=0+joffset; j<=lts->nCols-1+joffset; j++) {
        lto->screenChar[j] = lto->screenChar[j+jscroll];
        lto->screenStyle[j] = lto->screenStyle[j+jscroll];
      }
    }

    break;

  case LTERM_DELETE_ACTION:
    /* Scroll up for deletion */
    if ( (row < lto->botScrollRow) ||
         (row > lto->topScrollRow) ) {
      /* Cursor located outside scrollable region */
      return 0;
    }

    if (lineCount > row - lto->botScrollRow + 1)
      lineCount = row - lto->botScrollRow + 1;

    kblank1 = lto->botScrollRow;
    kblank2 = lto->botScrollRow + lineCount-1;

    /* Scroll up */
    for (k=row; k>=lto->botScrollRow+lineCount; k--) {
      joffset = k*lts->nCols;
      jscroll = lineCount*lts->nCols;

      lto->modifiedCol[k] = lto->modifiedCol[k-lineCount];

      for (j=0+joffset; j<=lts->nCols-1+joffset; j++) {
        lto->screenChar[j] = lto->screenChar[j-jscroll];
        lto->screenStyle[j] = lto->screenStyle[j-jscroll];
      }
    }

    break;

  default:
    kblank1 = 0;
    kblank2 = -1;
    break;
  }

  /* Blank out lines (assumed to be displayed already) */
  for (k=kblank1; k<=kblank2; k++) {
    joffset = k*lts->nCols;

    lto->modifiedCol[k] = -1;

    for (j=0+joffset; j<=lts->nCols-1+joffset; j++) {
      lto->screenChar[j] = U_SPACE;
      lto->screenStyle[j] = LTERM_STDOUT_STYLE;
    }
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermInsertChar ( struct LtermInput lti,
UNICHAR  uch 
)

Inserts plain text character UCH as a single-column glyph at the current input cursor location, translating to escape sequence if needed.

Returns:
0 on success, -1 on error.

Definition at line 195 of file ltermInput.c.

{
  UNICHAR* escapeSequence;
  int insChars, insertColIndex, insertCharIndex, j;

  LTERM_LOG(ltermInsertChar,40,("inserting character 0x%x at glyph %d\n",
                                   uch, lti->inputCursorGlyph));

  /* Ignore null character */
  if (uch == 0)
    return 0;

  escapeSequence = NULL;
  insChars = 1;

#if 0
  /* COMMENTED OUT: Plain text not escaped; use code later in HTML insert */
  /* Check if plain text character needs to be escaped for XML/HTML */
  for (j=0; j<LTERM_PLAIN_ESCAPES; j++) {

    if (uch == ltermGlobal.escapeChars[j]) {
      /* Insert escape sequence rather than character */
      escapeSequence = ltermGlobal.escapeSeq[j];
      insChars =       ltermGlobal.escapeLen[j];
      LTERM_LOG(ltermInsertChar,42,("escape index=%d\n", j));
      break;
    }
  }
#endif /* 0 */

  if (lti->inputChars+insChars > MAXCOLM1) {
    /* Input buffer overflow; ignore insert character */
    LTERM_WARNING("ltermInsertChar: Warning - input line buffer overflow\n");
    return 0;
  }

  assert(lti->inputChars >= 0);
  assert(lti->inputCols >= 0);
  assert(lti->inputGlyphs >= 0);
  assert(lti->inputCursorGlyph >= 0);

  assert(lti->inputCols <= lti->inputChars);
  assert(lti->inputGlyphs <= lti->inputCols);

  insertColIndex = lti->inputGlyphColIndex[lti->inputCursorGlyph];
  insertCharIndex = lti->inputColCharIndex[insertColIndex];

  LTERM_LOG(ltermInsertChar,41,("insertColIndex=%d, insertCharIndex=%d, insChars=%d\n",
           insertColIndex, insertCharIndex, insChars));

  /* Shift portion of input line to the right;
     remember that the column/glyph index arrays have an extra element */
  for (j=lti->inputChars - 1; j >= insertCharIndex; j--)
    lti->inputLine[j+insChars] = lti->inputLine[j];

  for (j=lti->inputCols; j >= insertColIndex; j--)
    lti->inputColCharIndex[j+1] = lti->inputColCharIndex[j]+insChars;

  for (j=lti->inputGlyphs; j >= lti->inputCursorGlyph; j--) {
    lti->inputGlyphCharIndex[j+1] = lti->inputGlyphCharIndex[j]+insChars;
    lti->inputGlyphColIndex[j+1] = lti->inputGlyphColIndex[j]+1;
  }

  /* Insert character(s) in input line */
  if (escapeSequence == NULL) {
    lti->inputLine[insertCharIndex] = uch;
  } else {
    for (j=0; j < insChars; j++)
      lti->inputLine[j+insertCharIndex] = escapeSequence[j];
  }

  /* Insert column/glyph */
  lti->inputColCharIndex[insertColIndex] = insertCharIndex;

  lti->inputGlyphCharIndex[lti->inputCursorGlyph] = insertCharIndex;
  lti->inputGlyphColIndex[lti->inputCursorGlyph] = insertColIndex;

  lti->inputChars += insChars;       /* Increment character count */

  lti->inputCols++;                  /* Increment column count */

  lti->inputGlyphs++;                /* Increment glyph count */

  lti->inputCursorGlyph++;           /* Reposition cursor */

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermInterruptOutput ( struct lterms lts)

Interrupts output operations in response to an input TTY interrupt signal.

Returns:
0 if successful, -1 if an error occurred

Definition at line 818 of file ltermIO.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);

  if (lto->outputMode == LTERM0_STREAM_MODE) {
    /* Abnormally terminate output stream */
    lto->streamOpcodes |= LTERM_ERROR_CODE;
  }

  return 0;
}

Here is the caller graph for this function:

int ltermPlainTextInput ( struct lterms lts,
const UNICHAR buf,
int  count,
int opcodes 
)

Processes plain text input data and returns OPCODES ::= LINEDATA ( INPUT ( NEWLINE HIDE? )? | INPUT META ( COMPLETION | NEWLINE HIDE? ) ) if echoable input data was processed.

(OPCODES is set to zero if raw input data was processed) Called from ltermWrite

Returns:
0 on success, -1 on error, and -2 if pseudo-TTY has been closed.

Definition at line 63 of file ltermInput.c.

{
  struct LtermInput *lti = &(lts->ltermInput);
  int returnCode;

  LTERM_LOG(ltermPlainTextInput,20,
    ("count=%d, lti->inputMode=%d\n", count, lti->inputMode));

  if (lti->inputMode == LTERM0_RAW_MODE) {
    /* Transmit characters immediately to child process; no buffering */

    LTERM_LOG(ltermPlainTextInput,29,
                                    ("Raw mode, transmitting %d characters\n",
                                     count));

    if (ltermSendData(lts, buf, count) != 0)
      return -1;

    *opcodes = 0;

  } else {
    /* Not raw input mode; process line mode input */
    int processTrailingTab = 0;

    LTERM_LOG(ltermPlainTextInput,21,
              ("Line mode, lts->commandNumber=%d, inputMode=%d\n",
               lts->commandNumber, lti->inputMode));

    if ((lti->inputMode >= LTERM3_COMPLETION_MODE) &&
        (lts->commandNumber == 0)) {
      /* Downgrade input mode */
      lti->inputMode = LTERM2_EDIT_MODE;

      LTERM_LOG(ltermPlainTextInput,21,
                ("------------ Downgraded input mode=%d\n\n",
                 lti->inputMode));

    } else  if ((lti->inputMode < lts->maxInputMode) &&
                (lts->commandNumber != 0)) {
      /* Upgrade input mode */
      int priorInputMode = lti->inputMode;

      /* Set input mode (possibly allowing completion) */
      lti->inputMode = lts->maxInputMode;

      /* Do not allow command completion without TTY echo */
      if ( (lts->disabledInputEcho || lts->noTTYEcho) &&
           (lti->inputMode > LTERM2_EDIT_MODE) )
        lti->inputMode = LTERM2_EDIT_MODE;

      if ((lti->inputChars > 0) &&
          (priorInputMode < LTERM3_COMPLETION_MODE) &&
          (lti->inputMode >= LTERM3_COMPLETION_MODE)) {
        /* Process prior input TABs before switching to completion mode */
        int j;

        if ((count == 0) &&
            (lti->inputCursorGlyph == lti->inputGlyphs) &&
            (lti->inputGlyphColIndex[lti->inputGlyphs] == lti->inputCols) &&
            (lti->inputColCharIndex[lti->inputCols] == lti->inputChars) &&
            (lti->inputLine[lti->inputChars] == U_TAB)) {
          /* Trailing TAB in prior input; delete it, and process it later */
          if (ltermDeleteGlyphs(lti, 1) != 0)
              return -1;
          processTrailingTab = 1;
        }

        /* Replace all input TABs with spaces */
        for (j=0; j < lti->inputChars; j++) {
          if (lti->inputLine[j] == U_TAB)
            lti->inputLine[j] = U_SPACE;
        }
      }

      LTERM_LOG(ltermPlainTextInput,21,
                ("------------ Upgraded input mode=%d, trailingTab=%d\n\n",
                 lti->inputMode, processTrailingTab));

    }

    if (processTrailingTab) {
      /* Re-process trailing TAB */
      UNICHAR uch = U_TAB;

      assert(count == 0);

      LTERM_LOG(ltermPlainTextInput,21,("Reprocessing trailing TAB\n"));

      returnCode= ltermLineInput(lts, &uch, 1, opcodes);
      if (returnCode < 0)
        return returnCode;

    } else {
      /* Process new input characters */
      returnCode = ltermLineInput(lts, buf, count, opcodes) != 0;
      if (returnCode < 0)
        return returnCode;
    }
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermProcessEscape ( struct lterms lts,
const UNICHAR buf,
int  count,
const UNISTYLE style,
int consumed,
int opcodes,
int opvals,
int oprow 
)

Processes ESCAPE sequence in string BUF containing COUNT characters, returning the number of characters CONSUMED and the OPCODES.

Using Extended Backus-Naur Form notation: OPCODES ::= 0 if the sequence was processed without any change of outputMode or terminating condition. OPCODES ::= LINEDATA OUTPUT if a switch from LineMode to ScreenMode or StreamMode was triggered by the ESCAPE sqeuence. OPCODES ::= SCREENDATA ( CLEAR | INSERT | DELETE | SCROLL )? for screenMode escape sequences or if a switch from ScreenMode to StreamMode was triggered by the ESCAPE sequence. (A switch from ScreenMode to LineMode is not considered a terminating condition and occurs transparently.) OPVALS contains return value(s) for specific screen operations such as INSERT, DELETE, and SCROLL. OPROW contains the row value for specific screen operations such as INSERT, DELETE, and SCROLL (or -1, cursor row is to be used).

OPVALS contains return value(s) for specific screen operations such as INSERT and DELETE. OPROW contains the row value for specific screen operations such as INSERT and DELETE (or -1, cursor row is to be used).

Returns:
0 on successful processing of the ESCAPE sequence, 1 if BUF contains an incomplete ESCAPE sequence, -1 if error an error occurred.

Definition at line 85 of file ltermEscape.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);

  LTERM_LOG(ltermProcessEscape,50,("count=%d, buf[1]=0x%x, cursorChar=%d, Chars=%d\n",
                count, buf[1], lto->outputCursorChar, lto->outputChars));

  if (count < 2) {
    /* Incomplete Escape sequence */
    *consumed = 0;
    return 1;
  }

  if (buf[1] == U_LBRACKET) {
    /* ESC [ Process CSI sequence */
    return ltermProcessCSISequence(lts, buf, count, style, consumed,
                                   opcodes, opvals, oprow);
  }

  if (buf[1] == U_RBRACKET) {
    /* ESC ] Process XTERM sequence */
    return ltermProcessXTERMSequence(lts, buf, count, style, consumed,
                                     opcodes);
  }

  if (buf[1] == U_LCURLY) {
    /* ESC { Process XMLTerm sequence */
    return ltermProcessXMLTermSequence(lts, buf, count, style, consumed,
                                       opcodes);
  }

  /* Assume two characters will be consumed at this point */
  *consumed = 2;

  switch (buf[1]) {

  /* Three character sequences */
  case U_NUMBER:            /* ESC # 8 DEC Screen Alignment Test */
  case U_LPAREN:            /* ESC ( C Designate G0 Character Set */
  case U_RPAREN:            /* ESC ) C Designate G1 Character Set */
  case U_STAR:              /* ESC * C Designate G2 Character Set */
  case U_PLUS:              /* ESC + C Designate G3 Character Set */
  case U_DOLLAR:            /* ESC $ C Designate Kanji Character Set */
    LTERM_LOG(ltermProcessEscape,51,("3 char sequence, buf[1:2]=0x%x,0x%x\n",
                  buf[1], buf[2]));

    if (count < 3) {
      /* Incomplete Escape sequence */
      *consumed = 0;
      return 1;
    }
    *consumed = 3;

    if (buf[1] == U_NUMBER) {
      /* ESC # 8 DEC Screen Alignment Test */
    } else {
      /* ESC ()*+$ C Designate Character Set */
    }
    return 0;

  /* Two character sequences */
  case U_SEVEN:             /* ESC 7 Save Cursor */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_EIGHT:             /* ESC 8 Restore Cursor */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_EQUALS:            /* ESC = Application Keypad */
    LTERM_LOG(ltermProcessEscape,52,("Application Keypad\n"));
    if (lto->outputMode == LTERM2_LINE_MODE) {
      ltermSwitchToScreenMode(lts);
      *opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE;
    }
    return 0;

  case U_GREATERTHAN:       /* ESC > Normal Keypad */
    LTERM_LOG(ltermProcessEscape,52,("Normal Keypad\n"));
    if (lto->outputMode == LTERM1_SCREEN_MODE) {
      ltermSwitchToLineMode(lts);
      *opcodes = LTERM_SCREENDATA_CODE | LTERM_CLEAR_CODE;
    }
    return 0;

  case U_D_CHAR:            /* ESC D Index (IND) */
    LTERM_LOG(ltermProcessEscape,52,("Index\n"));
    if (lto->outputMode == LTERM1_SCREEN_MODE) {
      /* Scroll up */
      if (ltermInsDelEraseLine(lts, 1, lto->topScrollRow, LTERM_DELETE_ACTION) != 0)
        return -1;
      *opcodes = LTERM_SCREENDATA_CODE | LTERM_DELETE_CODE;
      *opvals = 1;
      *oprow = lto->topScrollRow;
    }
    return 0;

  case U_E_CHAR:            /* ESC E Next Line (NEL) */
    if (lto->outputMode == LTERM1_SCREEN_MODE) {
      if (lto->cursorRow > 0)
        lto->cursorRow--;
    }
    return 0;

  case U_H_CHAR:            /* ESC H Tab Set (HTS) */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_M_CHAR:            /* ESC M Reverse Index (TI) */
    LTERM_LOG(ltermProcessEscape,52,("Reverse Index\n"));
    if (lto->outputMode == LTERM1_SCREEN_MODE) {
      /* Scroll down */
      if (ltermInsDelEraseLine(lts, 1, lto->topScrollRow, LTERM_INSERT_ACTION) != 0)
        return -1;
      *opcodes = LTERM_SCREENDATA_CODE | LTERM_INSERT_CODE;
      *opvals = 1;
      *oprow = lto->topScrollRow;
    }
    return 0;

  case U_N_CHAR:            /* ESC N Single Shift Select of G2 Character Set */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_O_CHAR:            /* ESC O Single Shift Select of G3 Character Set */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_Z_CHAR:            /* ESC Z Obsolete form of ESC[c */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_c_CHAR:            /* ESC c Full reset (RIS)  */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_n_CHAR:            /* ESC n Invoke the G2 Character Set  */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  case U_o_CHAR:            /* ESC o Invoke the G3 Character Set */
    LTERM_LOG(ltermProcessEscape,2,("Unimplemented 0x%x\n", buf[1]));
    return 0;

  default:
    LTERM_WARNING("ltermProcessEscape: Warning - unknown sequence 0x%x\n",
                  buf[1]);
    return 0;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermProcessOutput ( struct lterms lts,
int opcodes,
int opvals,
int oprow 
)

Processes output from decoded output buffer and returns *opcodes: OPCODES ::= SCREENDATA BELL? ( CLEAR | INSERT | DELETE | SCROLL )? if ScreenMode data is being returned.

OPCODES ::= LINEDATA BELL? ( CLEAR | OUTPUT NEWLINE?) if LineMode data is being returned. OPVALS contains return value(s) for specific screen operations such as INSERT, DELETE, and SCROLL. OPROW contains the row value for specific screen operations such as INSERT, DELETE, and SCROLL (or -1, cursor row is to be used).

Returns:
0 on success and -1 on error.

Definition at line 70 of file ltermOutput.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);
  UNICHAR uch;
  UNISTYLE ustyle;
  int charIndex, returnCode, consumedChars, remainingChars, j;
  int bellFlag;

  LTERM_LOG(ltermProcessOutput,30,("lto->outputMode=%d, cursorChar=%d, Chars=%d\n",
                lto->outputMode, lto->outputCursorChar, lto->outputChars));

  LTERM_LOG(ltermProcessOutput,32, ("lts->commandNumber=%d\n",
                                      lts->commandNumber));

  /* Set default returned opcodes, opvals, oprow */
  *opcodes = 0;
  *opvals = 0;
  *oprow = -1;

  charIndex = 0;
  bellFlag = 0;

  while ((*opcodes == 0) && (charIndex < lto->decodedChars)) {
    uch = lto->decodedOutput[charIndex];
    ustyle = lto->decodedStyle[charIndex] | lto->styleMask;

    consumedChars = 1;

    if (uch == U_ESCAPE) {
      /* Process escape sequence */
      int savedOutputMode = lto->outputMode;

      LTERM_LOG(ltermProcessOutput,31,("ESCAPE sequence\n"));

      returnCode = ltermProcessEscape(lts, lto->decodedOutput+charIndex,
                                      lto->decodedChars-charIndex,
                                      lto->decodedStyle+charIndex,
                                      &consumedChars, opcodes, opvals, oprow);
      if (returnCode < 0)
        return -1;

      if (returnCode == 1) {
        /* Incomplete escape sequence */
        lto->incompleteEscapeSequence = 1;
        if (lto->outputMode == LTERM1_SCREEN_MODE)
          *opcodes = LTERM_SCREENDATA_CODE;
        else
          *opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE;
      }

      /* Assert that change in output mode is a loop terminating condition */
      if (lto->outputMode != savedOutputMode)
        assert(*opcodes != 0);

    } else if (lto->outputMode == LTERM1_SCREEN_MODE) {
      /* Screen mode processing */

      if ((uch >= (UNICHAR)U_SPACE) && (uch != (UNICHAR)U_DEL)) {
        /* Printable non-TAB character */

        LTERM_LOG(ltermProcessOutput,39,("Screen mode, printable char - %c\n",
                      (char) uch));

        if (lto->insertMode) {
          /* Insert blank character at cursor position */
          if (ltermInsDelEraseChar(lts, 1, LTERM_INSERT_ACTION) != 0)
            return -1;
        }

        /* Mark column as being modified */
        if ((lto->modifiedCol[lto->cursorRow] == -1) ||
            (lto->modifiedCol[lto->cursorRow] > lto->cursorCol))
          lto->modifiedCol[lto->cursorRow] = lto->cursorCol;

        /* Replace character and style info at current cursor location */
        j = lto->cursorRow*lts->nCols + lto->cursorCol;

        assert(j < (lts->nRows * lts->nCols));

        lto->screenChar[j] = uch;
        lto->screenStyle[j] = ustyle;

        if (lto->cursorCol < lts->nCols-1) {
          /* Move cursor right */
          lto->cursorCol++;
        }

      } else {
        /* Control character */

        switch (uch) {
        case U_BACKSPACE:                 /* Backspace */
          LTERM_LOG(ltermProcessOutput,32,("Screen mode, BACKSPACE\n"));
          if (lto->cursorCol > 0)
            lto->cursorCol--;
          break;

        case U_TAB:                       /* Tab */
          LTERM_LOG(ltermProcessOutput,32,("Screen mode, TAB\n"));
          lto->cursorCol = ((lto->cursorCol/8)+1)*8;
          if (lto->cursorCol > lts->nCols-1)
            lto->cursorCol = lts->nCols-1;
          break;

        case U_BEL:                       /* Bell */
          LTERM_LOG(ltermProcessOutput,32,("************ Screen mode, BELL\n"));
          bellFlag = 1;
          break;

        case U_CRETURN:                   /* Carriage return */
          lto->cursorCol = 0;
          break;

        case U_LINEFEED:                  /* Newline */
          LTERM_LOG(ltermProcessOutput,32,("************ Screen mode, NEWLINE\n\n"));

          *opcodes =  LTERM_SCREENDATA_CODE;

          if (lto->cursorRow > lto->botScrollRow) {
            /* Not bottom scrolling line; simply move cursor down one row */
            lto->cursorRow--;

          } else {
            /* Delete top scrollable line, scrolling up */
            if (ltermInsDelEraseLine(lts, 1, lto->topScrollRow, LTERM_DELETE_ACTION) != 0)
              return -1;
            *opcodes |= LTERM_DELETE_CODE;
            *opvals = 1;
            *oprow = lto->topScrollRow;
          }
          break;

        default:
          /* Ignore other control characters (including NULs) */
          break;
        }
      }

    } else {
      /* Line mode processing */

      if ( ((uch >= (UNICHAR)U_SPACE) && (uch != (UNICHAR)U_DEL)) ||
           (uch == (UNICHAR)U_TAB)) {
        /* Printable/TAB character; replace/insert at current cursor location
           or append to end of line */

        LTERM_LOG(ltermProcessOutput,39,("Line mode, printable char - %c\n",
                      (char) uch));

        if (lto->outputCursorChar == lto->outputChars) {
          /* Append single character to end of line */

          if (lto->outputChars+1 > MAXCOLM1) {
            /* Output buffer overflow; ignore character */
            LTERM_WARNING("ltermProcessOutput: Warning - output line buffer overflow\n");
          }

          lto->outputLine[lto->outputChars] = uch;
          lto->outputStyle[lto->outputChars] = ustyle;
          lto->outputChars++;           /* Insert character in output line */

          lto->outputCursorChar++;      /* Reposition cursor */

        } else {
          /* Replace/insert single character in the middle of line */

          if (lto->insertMode) {
            /* Insert blank character at cursor position */
            if (ltermInsDelEraseChar(lts, 1, LTERM_INSERT_ACTION) != 0)
              return -1;
          }

          /* Overwrite single character in the middle of line */
          lto->outputLine[lto->outputCursorChar] = uch;
          lto->outputStyle[lto->outputCursorChar] = ustyle;

          /* Note modifications */
          if (lto->outputCursorChar < lto->outputModifiedChar)
            lto->outputModifiedChar = lto->outputCursorChar;

          lto->outputCursorChar++;      /* Reposition cursor */
        }

      } else {
        /* Control character */

        switch (uch) {
        case U_BACKSPACE:                /* Backspace */
          LTERM_LOG(ltermProcessOutput,32,("Line mode, BACKSPACE\n"));
          if (lto->outputCursorChar > 0)
            lto->outputCursorChar--;
          break;

        case U_CRETURN:                  /* Carriage return */
          LTERM_LOG(ltermProcessOutput,32,("Line mode, CRETURN\n"));
          lto->outputCursorChar = 0;
          break;

        case U_BEL:                      /* Bell */
          LTERM_LOG(ltermProcessOutput,32,("************ Line mode, BELL\n"));
          bellFlag = 1;
          break;

        case U_CTL_L:                    /* Formfeed; clear line and return */
          LTERM_LOG(ltermProcessOutput,32,("************ Line mode, FORMFEED\n\n"));

          ltermClearOutputLine(lts);
          *opcodes = LTERM_LINEDATA_CODE | LTERM_CLEAR_CODE;
          break;

        case U_LINEFEED:                  /* Newline; return complete line */
          LTERM_LOG(ltermProcessOutput,32,("************ Line mode, NEWLINE\n\n"));

          *opcodes =  LTERM_LINEDATA_CODE
                     | LTERM_OUTPUT_CODE
                     | LTERM_NEWLINE_CODE;
          break;

        default:
          /* Ignore other control characters (including NULs) */
          break;
        }
      }
    }

    /* Increment character index */
    charIndex += consumedChars;
  }

  /* Determine count of unprocessed characters */
  remainingChars = lto->decodedChars - charIndex;

  if (remainingChars > 0) {
    /* Move unprocessed output to beginning of decode buffer */

    LTERM_LOG(ltermProcessOutput,32,("Moved %d chars to beginning of decodedOutput\n", remainingChars));
    for (j=0; j<remainingChars; j++) {
      lto->decodedOutput[j] = lto->decodedOutput[j+charIndex];
      lto->decodedStyle[j] = lto->decodedStyle[j+charIndex];
    }
  }

  /* Update remaining decoded character count */
  lto->decodedChars = remainingChars;

  if (*opcodes == 0) {
    /* All output processed; without any special terminating condition */
    if (lto->outputMode == LTERM1_SCREEN_MODE) {
      /* Full screen mode */
      *opcodes = LTERM_SCREENDATA_CODE;

    } else {
      /* Line mode */
      *opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE;
    }
  }

  /* Set bell code */
  if (bellFlag)
    *opcodes |= LTERM_BELL_CODE;

  if (*opcodes & LTERM_LINEDATA_CODE) {
    /* Returning line mode data; check for prompt */

    if ((lts->commandNumber == 0) ||
        (lto->outputModifiedChar < lto->promptChars)) {
      /* If not command line or if "prompt string" may have been modified,
       * search for prompt
       */
      int promptLen;

      LTERM_LOG(ltermProcessOutput,39,("Prompt? modifiedChar=%d, promptChars=%d\n",
                     lto->outputModifiedChar, lto->promptChars));

      /* Reset modification marker */
      lto->outputModifiedChar = lto->outputChars;

      /* Check if prompt string is present in output */
      promptLen = ltermPromptLocate(lts);

      if (promptLen > 0) {
        /* Prompt string found */
        lto->promptChars = promptLen;

        if (lts->commandNumber == 0) {
          /* Set command number */

          /* New command number */
          if (lts->lastCommandNum == 0xFFFF)
            lts->lastCommandNum = 0;
          lts->lastCommandNum++;

          lts->commandNumber = lts->lastCommandNum;

          LTERM_LOG(ltermProcessOutput,32,
                    ("************ Prompt found; commandNumber=%d\n\n",
                     lts->commandNumber));
        }

      } else {
        /* No prompt string */
        if (lts->commandNumber != 0) {
          /* Unset command number and prompt columns */
          UNICHAR temLine[2] = {0, LTERM_WRITE_PLAIN_INPUT};

          lts->commandNumber = 0;
          lto->promptChars = 0;

          /* Notify "input thread" by writing null input record */
          WRITE(lts->writeBUFFER, temLine, 2*sizeof(UNICHAR));

          LTERM_LOG(ltermProcessOutput,32,
                    ("************  No prompt found; not command line\n\n"));
        }
      }
    }
  }

  if (lto->outputMode == LTERM1_SCREEN_MODE) {
    char modifiedRows[81];
    int showRows = (lts->nRows < 80) ? lts->nRows : 80;
    for (j=0; j<showRows; j++) {
      if (lto->modifiedCol[j] > -1)
        modifiedRows[j] = 'M';
      else
        modifiedRows[j] = '.';
    }
    modifiedRows[showRows] = '\0';
    LTERM_LOG(ltermProcessOutput,38,("modifiedRows=%s\n", modifiedRows));
  }

  LTERM_LOG(ltermProcessOutput,31,("returned opcodes=0x%X\n", *opcodes));

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermRead ( struct lterms lts,
struct LtermRead ltr,
int  timeout 
)

Reads a (possibly incomplete) line from LTERM.

The LtermRead structure *LTR contains both input and output parameters, returning opcodes values of OPCODES ::= STREAMDATA NEWLINE? ERROR? COOKIESTR? DOCSTREAM? XMLSTREAM? WINSTREAM? if StreamMode data is being returned.

OPCODES ::= SCREENDATA BELL? ( OUTPUT | CLEAR | INSERT | DELETE | SCROLL )? if ScreenMode data is being returned.

OPCODES ::= LINEDATA BELL? ( CLEAR | OUTPUT NEWLINE? ) if LineMode data is being returned.

(Auxiliary procedure for lterm_read.)

Returns:
0 if successful, -1 if an error occurred while reading, -2 if pseudo-TTY has been closed, -3 if more than MAX_COUNT characters are present in the line (in this case the first MAX_COUNT characters are returned in BUF, and the rest are discarded).

Definition at line 477 of file ltermIO.c.

{
  struct LtermInput *lti = &(lts->ltermInput);
  struct LtermOutput *lto = &(lts->ltermOutput);
  int waitTime, nfds_all, pollCode, rePoll;
  int inputAvailable, newOutputAvailable;
  int outOpcodes, outOpvals, outOprow, returnCode;
  int j;

  LTERM_LOG(ltermRead,20,("start outputMode=%d\n", lto->outputMode));

  if (lto->outputMode == LTERM1_SCREEN_MODE) {
    char modifiedRows[81];
    int showRows = (lts->nRows < 80) ? lts->nRows : 80;
    for (j=0; j<showRows; j++) {
      if (lto->modifiedCol[j] > -1)
        modifiedRows[j] = 'M';
      else
        modifiedRows[j] = '.';
    }
    modifiedRows[showRows] = '\0';
    LTERM_LOG(ltermRead,28,("modifiedRows=%s\n", modifiedRows));
  }

  waitTime = timeout;

  if (lts->inputBufRecord) {
    /* Complete input record available in buffer */

    LTERM_LOG(ltermRead,21,("inputBufRecord=%d\n", lts->inputBufRecord));
    waitTime = 0;

  } else if ((lto->decodedChars > 0) && !lto->incompleteEscapeSequence) {
    /* Do not wait if there are decoded characters to be processed that are
       not part of an incomplete ESCAPE sequence */

    LTERM_LOG(ltermRead,21,("decodedChars=%d,incompleteEscapeSequence=%d\n",
                  lto->decodedChars, lto->incompleteEscapeSequence));

    waitTime = 0;

  } else if (lto->outputMode == LTERM1_SCREEN_MODE) {
    /* Screen mode: do not wait if there are any modified rows */
    for (j=0; j<lts->nRows; j++)
      if (lto->modifiedCol[j] >= 0) {
        waitTime = 0;
        break;
      }

    if (j<lts->nRows) {
      LTERM_LOG(ltermRead,21,("j=%d, modifiedCol[j] = %d\n",
                    j, lto->modifiedCol[j]));
    }
  }

  /* If stream mode, do not poll STDERR output */
  if (lto->outputMode == LTERM0_STREAM_MODE)
    nfds_all = POLL_COUNT-1;
  else
    nfds_all = lto->nfds;

  do {
    /* Do not re-poll unless something special occurs */
    rePoll = 0;

    /* Default return values in LtermRead structure */
    ltr->read_count = 0;
    ltr->opcodes = 0;
    ltr->opvals = 0;
    ltr->buf_row = -1;
    ltr->buf_col = -1;
    ltr->cursor_row = -1;
    ltr->cursor_col = -1;

    LTERM_LOG(ltermRead,21,("polling nfds = %d, waitTime = %d\n",
                lto->nfds, waitTime));

    /* Poll all files for data to read */
    pollCode = POLL(lto->pollFD, (SIZE_T) lto->nfds, waitTime);

    if (pollCode == -1) {
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
      int errcode = errno;
      perror("ltermRead");
#else
      int errcode = 0;
#endif
      LTERM_ERROR( "ltermRead: Error return from poll, code=%d\n", errcode);
      return -1;
    }

    /* Do not wait for polling the second time around */
    waitTime = 0;

    /* Check if input data is available */
    inputAvailable = lts->inputBufRecord ||
                     ( (pollCode > 0) &&
                       (lto->pollFD[POLL_INPUTBUF].POLL_REVENTS != 0) );

    /* Check if STDOUT/STDERR data is available */
    newOutputAvailable = (pollCode > 0) &&
                          ( (lto->pollFD[POLL_STDOUT].POLL_REVENTS != 0) ||
                            (lto->pollFD[POLL_STDERR].POLL_REVENTS != 0) );

    LTERM_LOG(ltermRead,21,
            ("inputAvailable=%d, newOutputAvailable=%d, completionRequest=%d\n",
            inputAvailable, newOutputAvailable, lts->completionRequest));

    if (inputAvailable && (!newOutputAvailable ||
                           (lts->completionRequest == LTERM_NO_COMPLETION)) ) {
      /* Process an input data record; either no new output is available, or
       * output is available but command completion has not been requested
       */
      int inOpcodes;

      returnCode = ltermWrite(lts, &inOpcodes);
      if (returnCode < 0)
        return returnCode;

      if (inOpcodes != 0) {
        /* Echoable input data processed; return input line */
        returnCode = ltermReturnInputLine(lts, ltr, 0);
        if (returnCode < 0)
          return returnCode;

        if (inOpcodes & LTERM_META_CODE) {
          ltr->opcodes |= LTERM_META_CODE;

          if (inOpcodes & LTERM_COMPLETION_CODE)
            ltr->opcodes |= LTERM_COMPLETION_CODE;
        }

        if (inOpcodes & LTERM_NEWLINE_CODE) {
          /* Input line break */
          ltr->opcodes |= LTERM_NEWLINE_CODE;

          if (inOpcodes & LTERM_HIDE_CODE)
            ltr->opcodes |= LTERM_HIDE_CODE;

          /* Clear input line buffer */
          ltermClearInputLine(lts);
        }

        if (lts->disabledInputEcho) {
          /* Input echo is disabled, re-poll */
          rePoll = 1;
          LTERM_LOG(ltermRead,32,("Input echo disabled; RE-POLLING\n\n"));
          continue;
        }

        return 0;
      }

      inputAvailable = 0;
    }

    if (newOutputAvailable) {
      /* Read data from STDOUT/STDERR */
      int outChars;

      outChars = ltermReceiveData(lts, nfds_all==POLL_COUNT);
      if (outChars < 0)
        return outChars;
    }

    if (lto->outputMode == LTERM0_STREAM_MODE) {
      /* Stream mode */
      return ltermReturnStreamData(lts, ltr);
    }

    /* If there is some complete decoded output, process it */
    if ((lto->decodedChars > 0) && !lto->incompleteEscapeSequence) {
      returnCode = ltermProcessOutput(lts, &outOpcodes, &outOpvals, &outOprow);
      if (returnCode < 0)
        return -1;

    } else {
      /* No new output to process */
      if (lto->outputMode == LTERM1_SCREEN_MODE) {
        outOpcodes = LTERM_SCREENDATA_CODE;
        outOpvals = 0;
        outOprow = -1;
      } else {
        /* No new output in line mode; return nothing */
        return 0;
      }
    }

    if (outOpcodes & LTERM_SCREENDATA_CODE) {
      /* Return screen mode output */
      return ltermReturnScreenData(lts, ltr, outOpcodes, outOpvals, outOprow);
    }

    if (outOpcodes & LTERM_LINEDATA_CODE) {

      LTERM_LOG(ltermRead,32,
       ("inputLineBreak=%d, completionRequest=%d, completionChars=%d\n",
        lts->inputLineBreak, lts->completionRequest, lts->completionChars));

      if (outOpcodes & LTERM_OUTPUT_CODE) {
        /* Return output line */
        int echoMatch = 0;

        returnCode = ltermReturnOutputLine(lts, ltr);
        if (returnCode < 0)
          return returnCode;

        LTERM_LOG(ltermRead,33, ("read_count=%d, echoChars=%d\n",
                                 ltr->read_count, lts->echoChars));

        if (lts->inputLineBreak) {
          /* Compare output line to initial portion of echo line */
          echoMatch = 1;

          if ( (ltr->read_count > lts->echoChars) ||
               ((ltr->read_count != lts->echoChars) &&
                (outOpcodes & LTERM_NEWLINE_CODE)) ) {
            echoMatch = 0;
          } else {
            int k;
            for (k=0; k<ltr->read_count; k++) {
              if (ltr->buf[k] != lts->echoLine[k]) {
                echoMatch = 0;
                break;
              }
            }
          }
        }

        if (outOpcodes & LTERM_NEWLINE_CODE) {
          /* Complete output line */
          if (!echoMatch)
            ltr->opcodes |= LTERM_NEWLINE_CODE;

          /* Clear output line buffer */
          ltermClearOutputLine(lts);

          /* Clear input line break flag */
          lts->inputLineBreak = 0;

        } else {
          /* Incomplete output line */

          if (lts->completionRequest != LTERM_NO_COMPLETION) {
            /* Completion requested;
             * Compare first/last part of output line to parts of echo line
             */
            int k;
            int extraChars = ltr->read_count - lts->echoChars;
            int compChars = ltr->read_count;
            int preMatch = 1;

            if (extraChars > 0)
              compChars = lts->echoChars;

            for (k=0; k<compChars; k++) {
              if (ltr->buf[k] != lts->echoLine[k]) {
                preMatch = 0;
                break;
              }
            }

            if (!preMatch) {
              /* No match; cancel completion request */
              if (ltermCancelCompletion(lts) != 0)
                return -1;

            } else if (extraChars >= 0) {
              /* Matched complete echo line and perhaps more */

              if ((extraChars > 0) && (extraChars <= MAXCOLM1)) {
                /* Insert extra characters into input line */
                lts->completionChars = extraChars;

                for (k=0; k<extraChars; k++) {
                  if (ltermInsertChar(lti, ltr->buf[compChars+k]) != 0)
                    return -1;
                }

                LTERM_LOG(ltermRead,32,
                          ("++++++++++++ COMPLETION SUCCESSFUL\n"));

                LTERM_LOGUNICODE(ltermRead,32,
                                 (ltr->buf+compChars, extraChars));
              }

              /* Return updated input line, prefixed with prompt */
              returnCode = ltermReturnInputLine(lts, ltr, 1);
              if (returnCode < 0)
                return returnCode;

            } else {
              /* Partial match; do not echo */
              echoMatch = 1;
            }

          } else if (lto->promptChars == lto->outputChars) {
            /* Incomplete output line with just a prompt */

            LTERM_LOG(ltermRead,32,("Prompt-only line\n"));

            /* Return updated input line, prefixed with prompt */
            returnCode = ltermReturnInputLine(lts, ltr, 0);
            if (returnCode < 0)
              return returnCode;
          }
        }

        if (echoMatch) {
          /* Do not display output line; re-poll */
          rePoll = 1;
          LTERM_LOG(ltermRead,32,("Echo match; RE-POLLING\n\n"));
          continue;
        } else {
          return 0;
        }

      } else {
        /* Line mode data with modifier flags; return just cursor position */
        ltr->opcodes = outOpcodes;
        ltr->opvals = 0;

        /* Copy full screen cursor position */
        ltr->cursor_row = -1;
        ltr->cursor_col = 0;

        ltr->read_count = 0;

        return 0;
      }
    }

  } while (rePoll);

  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermReceiveData ( struct lterms lts,
int  readERR 
)

Reads data from process STDOUT and/or STDERR using file descriptors from the LTERM POLL structure, and converts to Unicode, saving incomplete character encodings in corresponding incomplete raw buffers.

Decoded characters are appended to the decodedOutput buffer, with appropriate style settings. If READERR is false, STDERR is never read.

Returns:
the number of decoded characters appended (>=0) if successful, -1 if an error occurred during processing, or -2 if pseudo-TTY has been closed.

Definition at line 616 of file ltermOutput.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);
  char temERRBuf[MAXCOL], temOUTBuf[MAXCOL];
  int readERRMax, readOUTMax;
  int nReadERR, nTotalERR, nReadOUT, nTotalOUT;
  int interleavedBytes, n_decoded, n_decoded_tot, j;

  LTERM_LOG(ltermReceiveData,30,("\n"));

  nTotalERR = 0;
  if (readERR && (lto->pollFD[POLL_STDERR].POLL_REVENTS != 0)) {
    /* Read data from STDERR */

    /* Read maximum number of bytes that will all fit into decodedOutput
       when decoded, assuming number of decoded characters will not exceed
       the number of encoded bytes */

    readERRMax = MAXCOLM1 - lto->decodedChars - lto->rawERRBytes;

    /* Reduce by half to leave some space for STDOUT data */
    readERRMax = readERRMax / 2;

    if (readERRMax <= 0) {
      /* Decoded buffer overflow */
      LTERM_WARNING("ltermReceiveData: Warning - decoded buffer overflow\n");

      /* Non-fatal error recovery; return without reading */
      return 0;
    }

    /* Copy any incomplete raw output to beginning of buffer */
    for (j=0; j<lto->rawERRBytes; j++)
      temERRBuf[j] = lto->rawERRBuf[j];

    /* Read STDERRdata (blocking mode) */
    nReadERR = READ(lto->pollFD[POLL_STDERR].fd,
                    temERRBuf + lto->rawERRBytes, (SIZE_T) readERRMax);

    if (nReadERR < 0) {
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
      int errcode = errno;
      /*    perror("ltermReceiveData"); */
#else
      int errcode = 0;
#endif
      LTERM_ERROR( "ltermReceiveData: Error %d in reading from process STDERR\n",
                   errcode);
      return -1;
    }

    if (nReadERR == 0) {
      /* End of file => pseudo-TTY has been closed */
      LTERM_LOG(ltermReceiveData,31,("pseudo-TTY has been closed\n"));

      /* Suspend LTERM */
      lts->suspended = 1;

      return -2;
    }


    LTERM_LOG(ltermReceiveData,32,("Read %d raw bytes from STDERR\n", nReadERR));
    nTotalERR = nReadERR + lto->rawERRBytes;
  }

  nTotalOUT = 0;
  if (lto->pollFD[POLL_STDOUT].POLL_REVENTS != 0) {
    /* Read data from STDOUT */

    /* Read maximum number of bytes that will all fit into decodedOutput
       when decoded, assuming number of decoded characters will not exceed
       the number of encoded bytes */
    readOUTMax = MAXCOLM1 - lto->decodedChars - lto->rawOUTBytes - nTotalERR;

    if (readOUTMax <= 0) {
      /* Decoded buffer overflow */
      LTERM_WARNING("ltermReceiveData: Warning - decoded buffer overflow\n");

      /* Non-fatal error recovery; return without reading */
      return 0;
    }

    /* Copy any incomplete raw output to beginning of buffer */
    for (j=0; j<lto->rawOUTBytes; j++)
      temOUTBuf[j] = lto->rawOUTBuf[j];

    /* Read STDOUTdata (blocking mode) */
    nReadOUT = READ(lto->pollFD[POLL_STDOUT].fd,
                    temOUTBuf + lto->rawOUTBytes, (SIZE_T) readOUTMax);

    if (nReadOUT < 0) {
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
      int errcode = errno;
      /*    perror("ltermReceiveData"); */
#else
      int errcode = 0;
#endif
      LTERM_ERROR( "ltermReceiveData: Error %d in reading from process STDOUT\n",
                   errcode);
      return -1;
    }

    if (nReadOUT == 0) {
      /* End of file => pseudo-TTY has been closed */
      LTERM_LOG(ltermReceiveData,31,("pseudo-TTY has been closed\n"));

      /* Suspend LTERM */
      lts->suspended = 1;

      return -2;
    }

    LTERM_LOG(ltermReceiveData,32,("Read %d raw bytes from STDOUT\n", nReadOUT));

    nTotalOUT = nReadOUT + lto->rawOUTBytes;
  }

  n_decoded_tot = 0;

  if (lts->readERRfirst) {
    /* Decode STDERR data first */
    interleavedBytes = 0;
    n_decoded = ltermAppendOutput(lts, temERRBuf, nTotalERR,
                                  LTERM_STDERR_STYLE,
                                  lts->interleave, &interleavedBytes,
                                  MAXRAWINCOMPLETE,
                                  &(lto->rawERRBytes), lto->rawERRBuf);
    if (n_decoded < 0)
      return -1;
    n_decoded_tot += n_decoded;

    /* Decode STDOUT data next */
    n_decoded = ltermAppendOutput(lts, temOUTBuf, nTotalOUT,
                                  LTERM_STDOUT_STYLE,
                                  0, NULL,
                                  MAXRAWINCOMPLETE,
                                  &(lto->rawOUTBytes), lto->rawOUTBuf);
    if (n_decoded < 0)
      return -1;
    n_decoded_tot += n_decoded;

    if (interleavedBytes > 0) {
      /* Decode remaining STDERR data */
      n_decoded = ltermAppendOutput(lts, temERRBuf+interleavedBytes,
                                    nTotalERR-interleavedBytes,
                                    LTERM_STDERR_STYLE,
                                    0, NULL,
                                    MAXRAWINCOMPLETE,
                                    &(lto->rawERRBytes), lto->rawERRBuf);
      if (n_decoded < 0)
        return -1;
      n_decoded_tot += n_decoded;
    }

  } else {
    /* Decode STDOUT data first */
    interleavedBytes = 0;
    n_decoded = ltermAppendOutput(lts, temOUTBuf, nTotalOUT,
                                  LTERM_STDOUT_STYLE,
                                  lts->interleave, &interleavedBytes,
                                  MAXRAWINCOMPLETE,
                                  &(lto->rawOUTBytes), lto->rawOUTBuf);
    if (n_decoded < 0)
      return -1;
    n_decoded_tot += n_decoded;

    /* Decode STDERR data next */
    n_decoded = ltermAppendOutput(lts, temERRBuf, nTotalERR,
                                  LTERM_STDERR_STYLE,
                                  0, NULL,
                                  MAXRAWINCOMPLETE,
                                  &(lto->rawERRBytes), lto->rawERRBuf);
    if (n_decoded < 0)
      return -1;
    n_decoded_tot += n_decoded;

    if (interleavedBytes > 0) {
      /* Decode remaining STDOUT data */
      n_decoded = ltermAppendOutput(lts, temOUTBuf+interleavedBytes,
                                    nTotalOUT-interleavedBytes,
                                    LTERM_STDOUT_STYLE,
                                    0, NULL,
                                    MAXRAWINCOMPLETE,
                                    &(lto->rawOUTBytes), lto->rawOUTBuf);
      if (n_decoded < 0)
        return -1;
      n_decoded_tot += n_decoded;
    }
  }

  if (n_decoded_tot > 0) {
    /* New characters have been decoded; no longer incomplete escape seq. */
    lto->incompleteEscapeSequence = 0;
  }

  return n_decoded_tot;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermSendChar ( struct lterms lts,
const char *  buf,
int  count 
)

Transmits COUNT characters from BUF to child process.

Returns:
0 on successful write, -1 on error.

Definition at line 852 of file ltermInput.c.

{
  int success;

  LTERM_LOG(ltermSendChar,50,("count=%d\n", count));

  if (lts->ptyMode)
#ifndef USE_NSPR_IO
    success = (write(lts->pty.ptyFD, buf,
                     (SIZE_T) count) == count);
#else
  assert(0);
#endif
  else
    success = (WRITE(lts->ltermProcess.processIN, buf,
                     (SIZE_T) count) == count);

  if (!success) {
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
    int errcode = errno;
    perror("ltermSendChar");
#else
    int errcode = 0;
#endif
    LTERM_ERROR("ltermSendChar: Error %d in writing to child STDIN\n",
                errcode);
    return -1;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermSendData ( struct lterms lts,
const UNICHAR buf,
int  count 
)

Transmits COUNT Unicode characters from BUF to child process after translating Unicode to UTF8 or Latin1, as appropriate.

The data is transmitted in smallish chunks so as not to overflow the PTY input buffer.

Returns:
0 on successful write, -1 on error.

Definition at line 789 of file ltermInput.c.

{
  char ch, ptyBuf[MAXPTYIN];
  int remainingChars, chunkSize, success;

  assert(lts != NULL);
  assert(count >= 0);

  LTERM_LOG(ltermSendData,40,("count=%d\n", count));
  LTERM_LOGUNICODE(ltermSendData,41,(buf, count));

  if ((count == 1) && (*buf < 0x80)) { 
    /* Optimized code to transmit single ASCII character */
    ch = (char) *buf;

    if (lts->ptyMode)
#ifndef USE_NSPR_IO
      success = (write(lts->pty.ptyFD, &ch, 1) == 1);
#else
      assert(0);
#endif
    else
      success = (WRITE(lts->ltermProcess.processIN, &ch, 1) == 1);

    if (!success) {
#if defined(DEBUG_LTERM) && !defined(USE_NSPR_IO)
      int errcode = errno;
      perror("ltermSendData");
#else
      int errcode = 0;
#endif
      LTERM_ERROR("ltermSendData: Error %d in writing to child STDIN\n",
                  errcode);
      return -1;
    }

    return 0;
  }

  remainingChars = count;
  while (remainingChars > 0) {
    /* Convert Unicode to UTF8 */
    ucstoutf8(&buf[count-remainingChars], remainingChars,
              ptyBuf, MAXPTYIN,
              &remainingChars, &chunkSize);

    assert(chunkSize > 0);

    LTERM_LOG(ltermSendData,42,("remainingChars=%d, chunkSize=%d\n",
                                 remainingChars, chunkSize));

    /* Send UTF8 to process */
    if (ltermSendChar(lts, ptyBuf, chunkSize) != 0)
      return -1;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermSendLine ( struct lterms lts,
UNICHAR  uch,
int  echoControl,
int  completionCode 
)

Transmits input line + optional control character UCH to child process.

If UCH is 0, no control character is transmitted. Copy of the transmitted plain text (without any markup or character escapes) is saved in the echo buffer, prefixed by the prompt. If echoControl is true, control character is echoed in printable form. If completionCode == LTERM_NO_COMPLETION, transmit complete line and set input line break flag. If completionCode != LTERM_NO_COMPLETION, transmit only characters to left of current and set completion request flag. Called from ltermLineInput.

Returns:
0 on success, -1 on error.

Definition at line 69 of file ltermIO.c.

{
  struct LtermInput *lti = &(lts->ltermInput);
  struct LtermOutput *lto = &(lts->ltermOutput);
  UNICHAR insch;
  int glyphCount, prefixChars, charCount, sendCount;
  int j, k, startCol, nCols, charIndex;

  LTERM_LOG(ltermSendLine,40,
       ("uch=0x%x, echoControl=%d, completionCode=%d, completionRequest=%d\n",
         uch, echoControl, completionCode, lts->completionRequest));

  if ((lts->completionRequest == LTERM_HISTORY_COMPLETION) &&
      (lts->completionChars > 0)) {
    /* Delete prior completion inserts */
    if (ltermDeleteGlyphs(lti, lts->completionChars) != 0)
      return -1;
  }

  if (completionCode != LTERM_NO_COMPLETION) {
    /* Send only glyphs to left of cursor */
    glyphCount = lti->inputCursorGlyph;

  } else {
    /* Send all glyphs in input line */
    glyphCount = lti->inputGlyphs;
  }

  if (lto->promptChars > 0) {
    /* Insert output prompt into echo buffer */
    prefixChars = lto->promptChars;
  } else {
    /* Insert entire output line into echo buffer */
    prefixChars = lto->outputChars;
  }

  charCount = prefixChars;

  LTERM_LOG(ltermSendLine,42,
            ("lto->promptChars=%d, outputChars=%d, glyphCount=%d\n",
             lto->promptChars, lto->outputChars, glyphCount));

  if (charCount >= MAXCOLM1) {
    /* Buffer overflow; error return */
    LTERM_ERROR("ltermSendLine: Error - character buffer overflow\n");
    return -1;
  }

  for (j=0; j<charCount; j++)
    lts->echoLine[j] = lto->outputLine[j];

  /* Append input line */
  for (j=0; j<glyphCount; j++) {
    startCol = lti->inputGlyphColIndex[j];
    nCols = lti->inputGlyphColIndex[j+1] - startCol;

    for (k=startCol; k<startCol+nCols; k++) {
      charIndex = lti->inputColCharIndex[k];

      insch = lti->inputLine[charIndex];

#if 0
      /* COMMENTED OUT: Plain text not escaped; use later in HTML insert */
      if (insch == U_AMPERSAND) {
        /* Escaped character */

        /* Assert that there is one free character position in buffer */
        assert(lti->inputChars < MAXCOL);

        /* Insert null character at the end of the input buffer */
        lti->inputLine[lti->inputChars] = U_NUL;

        /* Match escape sequence against known escape sequences */
        for (m=0; m<LTERM_XML_ESCAPES; m++) {
          if (ucsncmp(lti->inputLine+charIndex,
                      ltermGlobal.escapeSeq[m],
                      (unsigned int) ltermGlobal.escapeLen[m]) == 0)
            break;
        }

        if (m < LTERM_XML_ESCAPES) {
          /* Subsitute single character for escape sequence */
          insch = (UNICHAR) ltermGlobal.escapeChars[m];
        } else {
          LTERM_WARNING("ltermSendLine: Warning - unknown XML character escape sequence\n");
        }
      }
#endif /* 0 */

      if (charCount >= MAXCOLM1) {
        /* Buffer overflow; error return */
        LTERM_ERROR("ltermSendLine: Error - character buffer overflow\n");
        return -1;

      } else {
        /* Insert character into echo line buffer */
        lts->echoLine[charCount++] = insch;
      }
    }
  }


  /* Transmit data to process */
  sendCount = charCount - prefixChars;

  if (lts->completionRequest != LTERM_NO_COMPLETION) {
    /* Completion already requested */

    /* Send only control character */
    if (uch != U_NUL) {
      if (ltermSendData(lts, &uch, 1) != 0)
        return -1;
    }

  } else {
    if (uch != U_NUL) {
      /* Send line+control character to child process */

      /* Insert control character at the end of the buffer (temporarily) */
      lts->echoLine[charCount] = uch;

      sendCount++;
    }

    if (ltermSendData(lts, lts->echoLine+prefixChars, sendCount) != 0)
      return -1;
  }

  if (completionCode != LTERM_NO_COMPLETION) {
    /* Request completion */
    lts->completionRequest = completionCode;

    /* No completion text inserted yet */
    lts->completionChars = 0;

  } else {
    /* Set input line break flag;
     * cleared only by output line break processing
     */
    lts->inputLineBreak = 1;
  }

  if (echoControl && (charCount+2 < MAXCOLM1)) {
    /* Echo control character in printable form */
    lts->echoLine[charCount++] = U_CARET;
    lts->echoLine[charCount++] = U_ATSIGN + uch;
  }

  /* Set count of echo characters (excluding control character) */
  lts->echoChars = charCount;

  LTERM_LOG(ltermSendLine,41,("glyphCount=%d, sendCount=%d\n",
                                 glyphCount, sendCount));
  LTERM_LOGUNICODE(ltermSendLine,41,(lts->echoLine, charCount));

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermSwitchToLineMode ( struct lterms lts)

Switches to line output mode.

Returns:
0 on success and -1 on error.

Definition at line 564 of file ltermOutput.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);
  int j;

  LTERM_LOG(ltermSwitchToLineMode,40,("\n"));

  if (lto->outputMode == LTERM1_SCREEN_MODE) {
    /* Switching from screen mode to line mode */

    /* Switch to line input mode */
    ltermClearInputLine(lts);

    if (lts->restoreInputEcho) {
      /* Re-enable input echo */
      lts->disabledInputEcho = 0;
      lts->restoreInputEcho = 0;
    }

    /* Clear styleMask */
    lto->styleMask = 0;

    /* Clear output line */
    ltermClearOutputLine(lts);

    /* Copy bottom line to line output buffer ??? */
    lto->outputChars = lts->nCols;

    assert(lts->nCols < MAXCOL);

    for (j=0; j<lts->nCols; j++) {
      lto->outputLine[j] =  lto->screenChar[j];
      lto->outputStyle[j] = lto->screenStyle[j];
    }

  }

  lto->outputMode = LTERM2_LINE_MODE;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ltermSwitchToRawMode ( struct lterms lts)

switches to raw input mode

Definition at line 285 of file ltermInput.c.

{
  struct LtermInput *lti = &(lts->ltermInput);

  LTERM_LOG(ltermSwitchToRawMode,40,("\n"));

  if (lti->inputMode != LTERM0_RAW_MODE) {
    /* Do other things ... */
    lti->inputMode = LTERM0_RAW_MODE;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermSwitchToScreenMode ( struct lterms lts)

Switches to screen output mode.

Returns:
0 on success and -1 on error.

Definition at line 523 of file ltermOutput.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);

  LTERM_LOG(ltermSwitchToScreenMode,40,("\n"));

  if (lto->outputMode == LTERM2_LINE_MODE) {
    /* Switching from line mode to screen mode */

    /* Clear styleMask */
    lto->styleMask = 0;

    /* Clear screen */
    if (ltermClearOutputScreen(lts) != 0)
      return -1;

    /* Reset returned cursor location */
    lto->returnedCursorRow = -1;
    lto->returnedCursorCol = -1;

    /* Scrolling region */
    lto->topScrollRow = lts->nRows-1;
    lto->botScrollRow = 0;

    /* Disable input echo */
    lts->restoreInputEcho = !lts->disabledInputEcho;
    lts->disabledInputEcho = 1;

    /* Switch to raw input mode */
    ltermSwitchToRawMode(lts);

  }

  lto->outputMode = LTERM1_SCREEN_MODE;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ltermSwitchToStreamMode ( struct lterms lts,
int  streamOpcodes,
const UNICHAR streamTerminator 
)

Saves current output mode value and switches to stream output mode, with specified opcodes and terminator string.

Returns:
0 on success and -1 on error.

Definition at line 473 of file ltermOutput.c.

{
  struct LtermOutput *lto = &(lts->ltermOutput);
  int strLength;

  LTERM_LOG(ltermSwitchToStreamMode,40,("streamOpcodes=0x%x\n",streamOpcodes));

  if (streamTerminator != NULL) {
    /* Save terminator string (may be null) */
    strLength = ucslen(streamTerminator);
    ucsncpy( lto->streamTerminator, streamTerminator, MAXSTREAMTERM);

    LTERM_LOGUNICODE(ltermSwitchToStreamMode,41,(streamTerminator,
                                                 (int) strLength));
  } else {
    /* Null terminator */
    strLength = 0;
    lto->streamTerminator[0] = U_NUL;
  }

  if (strLength > MAXSTREAMTERM-1) {
    LTERM_ERROR("ltermSwitchToStreamMode: Error - terminator string too long\n");
    return -1;
  }

  if (lts->options & LTERM_NONUL_FLAG) {
    /* No decoding of NUL characters */
    if (strLength == 0) {
      LTERM_ERROR("ltermSwitchToStreamMode: Error - null terminator string not allowed\n");
      return -1;
    }
  } else {
    /* Decoding NUL characters */
    if (strLength > 0) {
      LTERM_ERROR("ltermSwitchToStreamMode: Error - terminator string must be NUL\n");
      return -1;
    }
  }

  lto->savedOutputMode = lto->outputMode;
  lto->outputMode = LTERM0_STREAM_MODE;
  lto->streamOpcodes = streamOpcodes;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 47 of file ltermManager.c.