void text_write_buf(TW *tw, const char *str, int cnt) { #ifdef WINDOWS_NO_UNICODE BYTE *p; #else wchar_t *p; #endif int count, limit; int n; if (tw->quitnow) return; /* don't write error message as we shut down */ while (cnt>0) { p = tw->ScreenBuffer + tw->CursorPos.y*tw->ScreenSize.x + tw->CursorPos.x; limit = tw->ScreenSize.x - tw->CursorPos.x; for (count=0; (count < limit) && (cnt>0) && ( #ifdef WINDOWS_NO_UNICODE isprint((unsigned char)(*str)) #else ((*str >= 32) && (*str <= 0x7F)) #endif || *str=='\t'); count++) { if (*str=='\t') { for (n = 8 - ((tw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ ) *p++ = ' '; str++; count--; } else { *p++ = *str++; } cnt--; } if (count>0) { text_update_text(tw, count); } if (cnt > 0) { if (*str=='\n') { text_new_line(tw); str++; cnt--; } else if (! #ifdef WINDOWS_NO_UNICODE isprint((unsigned char)(*str)) #else ((*str >= 32) && (*str <= 0x7f)) #endif && *str!='\t') { text_putch(tw, *(const unsigned char *)str++); cnt--; } } } }
/* (not including trailing NULL) */ int text_gets(TW *tw, char *line, int len) { LPSTR dest = line; LPSTR limit = dest + len; /* don't leave room for '\0' */ int ch; do { if (dest >= limit) break; ch = text_getch(tw); switch(ch) { case 26: /* ^Z == EOF */ return 0; case '\b': /* ^H */ case 0x7f: /* DEL */ if (dest > line) { text_putch(tw, '\b'); text_putch(tw, ' '); text_putch(tw, '\b'); #ifndef WINDOWS_NO_UNICODE while ((dest > line) && ((dest[-1] & 0xC0) == 0x80)) { /* It's a UTF-8 continuation char. */ --(dest); } if (dest == line) break; #endif --dest; } break; case 21: /* ^U */ while (dest > line) { text_putch(tw, '\b'); text_putch(tw, ' '); text_putch(tw, '\b'); --dest; } break; default: *dest++ = ch; text_putch(tw, ch); break; } } while (ch != '\n'); *dest = '\0'; return (dest-line); }
int text_putch(TW *tw, int ch) { int pos; int n; if (tw->quitnow) return ch; /* don't write error message as we shut down */ switch(ch) { case '\r': tw->CursorPos.x = 0; if (tw->CursorFlag) text_to_cursor(tw); break; case '\n': text_new_line(tw); break; case 7: MessageBeep(-1); if (tw->CursorFlag) text_to_cursor(tw); break; case '\t': { for (n = 8 - (tw->CursorPos.x % 8); n>0; n-- ) text_putch(tw, ' '); } break; case 0x08: case 0x7f: tw->CursorPos.x--; if (tw->CursorPos.x < 0) { tw->CursorPos.x = tw->ScreenSize.x - 1; tw->CursorPos.y--; } if (tw->CursorPos.y < 0) tw->CursorPos.y = 0; break; default: pos = tw->CursorPos.y*tw->ScreenSize.x + tw->CursorPos.x; tw->ScreenBuffer[pos] = ch; text_update_text(tw, 1); } return ch; }
void text_write_buf(TW *tw, const char *str, int cnt) { BYTE *p; int count, limit; int n; if (tw->quitnow) return; /* don't write error message as we shut down */ while (cnt>0) { p = tw->ScreenBuffer + tw->CursorPos.y*tw->ScreenSize.x + tw->CursorPos.x; limit = tw->ScreenSize.x - tw->CursorPos.x; for (count=0; (count < limit) && (cnt>0) && (isprint((unsigned char)(*str)) || *str=='\t'); count++) { if (*str=='\t') { for (n = 8 - ((tw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ ) *p++ = ' '; str++; count--; } else { *p++ = *str++; } cnt--; } if (count>0) { text_update_text(tw, count); } if (cnt > 0) { if (*str=='\n') { text_new_line(tw); str++; cnt--; } else if (!isprint((unsigned char)(*str)) && *str!='\t') { text_putch(tw, *str++); cnt--; } } } }
/* (not including trailing NULL) */ int text_gets(TW *tw, char *line, int len) { LPSTR dest = line; LPSTR limit = dest + len; /* don't leave room for '\0' */ int ch; do { if (dest >= limit) break; ch = text_getch(tw); switch(ch) { case 26: /* ^Z == EOF */ return 0; case '\b': /* ^H */ case 0x7f: /* DEL */ if (dest > line) { text_putch(tw, '\b'); text_putch(tw, ' '); text_putch(tw, '\b'); --dest; } break; case 21: /* ^U */ while (dest > line) { text_putch(tw, '\b'); text_putch(tw, ' '); text_putch(tw, '\b'); --dest; } break; default: *dest++ = ch; text_putch(tw, ch); break; } } while (ch != '\n'); *dest = '\0'; return (dest-line); }
/* Read line from keyboard using buffered input * Return at most 'len' characters * Does NOT add null terminating character * This is NOT the same as fgets() * Do not mix this with calls to text_getch() */ int text_read_line(TW *tw, char *line, int len) { int ch; if (tw->line_eof) return 0; while (!tw->line_complete) { /* we have not yet collected a full line */ ch = text_getch(tw); switch(ch) { case EOF: case 26: /* ^Z == EOF */ tw->line_eof = TRUE; tw->line_complete = TRUE; break; case '\b': /* ^H */ case 0x7f: /* DEL */ if (tw->line_end) { text_putch(tw, '\b'); text_putch(tw, ' '); text_putch(tw, '\b'); #ifndef WINDOWS_NO_UNICODE while ((tw->line_end) && ((tw->line_buf[tw->line_end-1] & 0xC0) == 0x80)) { /* It's a UTF-8 continuation char. */ --(tw->line_end); } if (tw->line_end == 0) break; #endif --(tw->line_end); } break; case 21: /* ^U */ while (tw->line_end) { text_putch(tw, '\b'); text_putch(tw, ' '); text_putch(tw, '\b'); --(tw->line_end); } break; case '\r': case '\n': tw->line_complete = TRUE; /* fall through */ default: tw->line_buf[tw->line_end++] = ch; text_putch(tw, ch); break; } if (tw->line_end >= sizeof(tw->line_buf)) tw->line_complete = TRUE; } if (tw->quitnow) return -1; if (tw->line_complete) { /* We either filled the buffer or got CR, LF or EOF */ int count = min(len, tw->line_end - tw->line_start); memcpy(line, tw->line_buf + tw->line_start, count); tw->line_start += count; if (tw->line_start == tw->line_end) { tw->line_start = tw->line_end = 0; tw->line_complete = FALSE; } return count; } return 0; }
int text_putch(TW *tw, int ch) { int pos; int n; #ifndef WINDOWS_NO_UNICODE int shift = tw->utf8shift; tw->utf8shift=0; #endif if (tw->quitnow) return ch; /* don't write error message as we shut down */ switch(ch) { case '\r': tw->CursorPos.x = 0; if (tw->CursorFlag) text_to_cursor(tw); break; case '\n': text_new_line(tw); break; case 7: MessageBeep(-1); if (tw->CursorFlag) text_to_cursor(tw); break; case '\t': { for (n = 8 - (tw->CursorPos.x % 8); n>0; n-- ) text_putch(tw, ' '); } break; case 0x08: case 0x7f: tw->CursorPos.x--; if (tw->CursorPos.x < 0) { tw->CursorPos.x = tw->ScreenSize.x - 1; tw->CursorPos.y--; } if (tw->CursorPos.y < 0) tw->CursorPos.y = 0; break; default: pos = tw->CursorPos.y*tw->ScreenSize.x + tw->CursorPos.x; #ifndef WINDOWS_NO_UNICODE /* Are we continuing a unicode char? */ if ((ch & 0xC0) == 0x80) { tw->ScreenBuffer[pos] |= (ch & 0x3F)<<shift; if (shift > 0) tw->utf8shift = shift-6; else text_update_text(tw, 1); /* Only update when complete */ } else if (ch >= 0xe0) { /* 2 more to come */ tw->ScreenBuffer[pos] = (ch & 0x0f)<<12; tw->utf8shift = 6; } else if (ch >= 0xC0) { /* 1 more to come */ tw->ScreenBuffer[pos] = (ch & 0x01f)<<6; tw->utf8shift = 0; } else #endif { tw->ScreenBuffer[pos] = ch; text_update_text(tw, 1); } } return ch; }