FreeBASIC  0.91.0
con_print_tty_uni.h
Go to the documentation of this file.
1 /* print text data - using TTY (teletype) interpretation */
2 
3 #ifndef OUTPUT_BUFFER_SIZE
4 #define OUTPUT_BUFFER_SIZE 1024
5 #endif
6 
8  (
10  const FB_TCHAR *pachText,
11  size_t TextLength,
12  int is_text_mode
13  )
14 {
15  static const FB_TCHAR achTabSpaces[8] = { 32, 32, 32, 32, 32, 32, 32, 32 };
16  FB_TCHAR OutputBuffer[OUTPUT_BUFFER_SIZE];
17  size_t OutputBufferLength = 0, OutputBufferChars = 0;
18  fb_Rect *pBorder = &handle->Border;
19  fb_Coord *pCoord = &handle->Coord;
20 
21  fb_Coord dwCurrentCoord;
22  size_t IndexText;
23  int fGotNewCoordinate = FALSE;
24  int BorderWidth = pBorder->Right - pBorder->Left + 1;
25 
26  DBG_ASSERT( BorderWidth != 0 );
27 
28  memcpy( &dwCurrentCoord, pCoord, sizeof( fb_Coord ) );
29 
30  fb_Coord dwMoveCoord = { 0 };
31  for( IndexText=0; IndexText!=TextLength; ++IndexText )
32  {
33  const FB_TCHAR *pachOutputData = pachText;
34  size_t OutputDataLength = 0, OutputDataChars = 0;
35  int fDoFlush = FALSE;
36  int fSetNewCoord = FALSE;
37  FB_TCHAR ch = FB_TCHAR_GET( pachOutputData );
38 
39  switch ( ch )
40  {
41  case _TC('\a'):
42  /* ALARM */
43  fb_Beep();
44  break;
45 
46  case _TC('\b'):
47  /* BACKSPACE */
48  fSetNewCoord = TRUE;
49  if( dwCurrentCoord.X > pBorder->Left ) {
50  dwMoveCoord.X = -1;
51  } else {
52  dwMoveCoord.X = 0;
53  }
54  dwMoveCoord.Y = 0;
55  break;
56 
57  case _TC('\n'):
58  /* LINE FEED / NEW LINE */
59  fSetNewCoord = TRUE;
60  if( is_text_mode ) {
61  dwMoveCoord.X = pBorder->Left - dwCurrentCoord.X;
62  dwMoveCoord.Y = 1;
63  } else {
64  dwMoveCoord.X = 0;
65  dwMoveCoord.Y = 1;
66  }
67  break;
68 
69  case _TC('\r'):
70  /* CARRIAGE RETURN */
71  fSetNewCoord = TRUE;
72  dwMoveCoord.X = pBorder->Left - dwCurrentCoord.X;
73  dwMoveCoord.Y = 0;
74  break;
75 
76  case _TC('\t'):
77  /* TAB */
78  pachOutputData = achTabSpaces;
79  OutputDataLength =
80  OutputDataChars =
81  ((dwCurrentCoord.X - pBorder->Left + 8) & ~7) -
82  (dwCurrentCoord.X - pBorder->Left);
83  break;
84 
85  default:
86  OutputDataLength = FB_TCHAR_GET_CHAR_SIZE( pachOutputData );
87  OutputDataChars = 1;
88  break;
89  }
90 
91  if( OutputDataLength + OutputBufferLength > OUTPUT_BUFFER_SIZE ) {
92  fDoFlush = TRUE;
93  } else if( fSetNewCoord ) {
94  fDoFlush = TRUE;
95  }
96 
97  if( fDoFlush ) {
98  fDoFlush = FALSE;
99  if( OutputBufferLength!=0 ) {
100  FB_CONPRINTRAW( handle,
101  OutputBuffer,
102  OutputBufferChars );
103  OutputBufferLength = OutputBufferChars = 0;
104  fGotNewCoordinate = FALSE;
105  }
106  }
107 
108  if( fSetNewCoord ) {
109  fSetNewCoord = FALSE;
110  pCoord->X += dwMoveCoord.X;
111  pCoord->Y += dwMoveCoord.Y;
112  memcpy( &dwCurrentCoord, pCoord, sizeof( fb_Coord ) );
113  fGotNewCoordinate = TRUE;
114  }
115 
116  if( OutputDataLength!=0 ) {
117  dwCurrentCoord.X += OutputDataChars;
118  if( dwCurrentCoord.X > pBorder->Right ) {
119  int NormalX = dwCurrentCoord.X - pBorder->Left;
120  dwCurrentCoord.X = (NormalX % BorderWidth) + pBorder->Left;
121  dwCurrentCoord.Y += NormalX / BorderWidth;
122  }
123  while( OutputDataLength-- ) {
124  OutputBuffer[OutputBufferLength++] = *pachOutputData++;
125  }
126  OutputBufferChars += OutputDataChars;
127  }
128 
129  FB_TCHAR_ADVANCE( pachText, 1 );
130  }
131 
132  if( OutputBufferLength!=0 )
133  {
134  FB_CONPRINTRAW( handle, OutputBuffer, OutputBufferChars );
135  }
136  else if( fGotNewCoordinate )
137  {
138  fb_hConCheckScroll( handle );
139  }
140 }