char *fb_ConsoleReadStr( char *buffer, int len ) { int k, x, y, cols, pos = 0; char ch[2] = { 0, '\0' }; if (!__fb_con.inited) return fgets(buffer, len, stdin); fb_ConsoleGetSize(&cols, NULL); do { while( ((k = fb_hGetCh(TRUE)) == -1) || (k > 0xFF) ) fb_Delay( 10 ); /* drop subsequent keypresses, if any; this is needed to avoid escape * sequence parsing problems in the fb_ConsoleGetXY() call below. */ while( fb_hGetCh(TRUE) >= 0 ) fb_Delay( 10 ); fb_ConsoleGetXY(&x, &y); if (k == 8) { if (pos > 0) { x--; if (x <= 0) { x = cols; y--; if (y <= 0) x = y = 1; } fb_hTermOut(SEQ_LOCATE, x-1, y-1); fb_hTermOut(SEQ_DEL_CHAR, 0, 0); pos--; } } else if (k != '\t') { if (pos < len - 1) { buffer[pos++] = ch[0] = k; fb_ConsolePrintBuffer(ch, 0); if (x == cols) fputc( '\n', stdout ); } } } while (k != '\r'); fputc( '\n', stdout ); buffer[pos] = '\0'; return buffer; }
int fb_DevScrnRead( FB_FILE *handle, void* value, size_t *pLength ) { size_t length; DEV_SCRN_INFO *info; int copy_length; char *pachBuffer = (char*) value; FB_LOCK(); DBG_ASSERT(pLength!=NULL); length = *pLength; info = (DEV_SCRN_INFO*) FB_HANDLE_DEREF(handle)->opaque; while( length > 0 ) { copy_length = (length > info->length) ? info->length : length; if (copy_length==0) { while( fb_KeyHit( ) == 0 ) fb_Delay( 25 ); /* release time slice */ fb_DevScrnFillInput( info ); if( info->length != 0 ) continue; break; } memcpy(pachBuffer, info->buffer, copy_length); info->length -= copy_length; if (info->length!=0) { memmove(info->buffer, info->buffer + copy_length, info->length); } length -= copy_length; pachBuffer += copy_length; } FB_UNLOCK(); if (length!=0) memset(pachBuffer, 0, length); *pLength -= length; return fb_ErrorSetNum( FB_RTERROR_OK ); }
FBCALL FBSTRING *fb_ConReadLine( int soft_cursor ) { FBSTRING result = { 0 }; int current_x, current_y; int cols, rows; size_t pos, len, tmp_buffer_len = 0; int cursor_visible; int k; char ch, tmp_buffer[12]; fb_GetSize(&cols, &rows); cursor_visible = (fb_Locate( 0, 0, -1, 0, 0 ) & 0x10000) != 0; fb_Locate( 0, 0, FALSE, 0, 0 ); pos = len = 0; fb_PrintBufferEx( NULL, 0, 0 ); /* Ensure that the cursor is visible during INPUT */ fb_Locate( 0, 0, (soft_cursor == FALSE), 0, 0 ); do { size_t delete_char_count = 0, add_char = FALSE; FBSTRING *sTmp; fb_GetXY(¤t_x, ¤t_y); if( soft_cursor ) { fb_PrintFixString( 0, "\377", 0 ); fb_Locate( current_y, current_x, FALSE, 0, 0 ); } while( fb_KeyHit( ) == 0 ) { fb_Delay( 25 ); /* release time slice */ } sTmp = fb_Inkey( ); if( sTmp->data != NULL ) { if( FB_STRSIZE(sTmp) == 2 ) { k = FB_MAKE_EXT_KEY(sTmp->data[1]); ch = 0; } else { k = FB_MAKE_KEY(ch = sTmp->data[0]); } fb_hStrDelTemp( sTmp ); } else { k = 0; continue; } if( soft_cursor ) { char mask[2] = { ((result.data != NULL) && (pos < len)? result.data[pos]: ' '), '\0' }; fb_PrintFixString( 0, mask, 0 ); fb_Locate( current_y, current_x, FALSE, 0, 0 ); } switch (k) { case 8: /* DEL */ if (pos!=0) { DoMove( ¤t_x, ¤t_y, -1, 0, cols, rows ); --pos; delete_char_count = 1; } break; case 9: /* TAB */ tmp_buffer_len = ((pos + 8) / 8 * 8) - pos; memset(tmp_buffer, 32, tmp_buffer_len); add_char = TRUE; break; case 27: /* ESC */ DoMove( ¤t_x, ¤t_y, -pos, 0, cols, rows ); pos = 0; delete_char_count = len; break; case FB_MAKE_EXT_KEY(0x53): /* CLeaR */ if( len!=pos ) { delete_char_count = 1; } else { fb_Beep(); } break; case FB_MAKE_EXT_KEY(0x4B): /* Cursor LEFT */ if( pos != 0 ) { DoMove( ¤t_x, ¤t_y, -1, 0, cols, rows ); --pos; } break; case FB_MAKE_EXT_KEY(0x4D): /* Cursor RIGHT */ if( pos != len ) { DoMove( ¤t_x, ¤t_y, 1, 0, cols, rows ); ++pos; } break; case FB_MAKE_EXT_KEY(0x47): /* HOME */ DoMove( ¤t_x, ¤t_y, -pos, 0, cols, rows ); pos = 0; break; case FB_MAKE_EXT_KEY(0x4F): /* END */ DoMove( ¤t_x, ¤t_y, len-pos, 0, cols, rows ); pos = len; break; case FB_MAKE_EXT_KEY(0x48): /* Cursor UP */ if( pos >= cols) { DoMove( ¤t_x, ¤t_y, -cols, 0, cols, rows ); pos -= cols; } break; case FB_MAKE_EXT_KEY(0x50): /* Cursor DOWN */ if( ( pos + cols ) <= len ) { DoMove( ¤t_x, ¤t_y, cols, 0, cols, rows ); pos += cols; } break; default: if( k>=32 && k<=255 ) { tmp_buffer[0] = (char) k; tmp_buffer_len = 1; add_char = TRUE; /* DoMove( ¤t_x, ¤t_y, 1, 0, cols ); */ } break; } if( delete_char_count!=0 || add_char ) { /* Turn off the cursor during output (speed-up) */ fb_Locate( 0, 0, FALSE, 0, 0 ); } if( delete_char_count ) { FBSTRING *str_fill; FBSTRING *str_left = fb_StrMid( &result, 1, pos ); FBSTRING *str_right = fb_StrMid( &result, pos + 1 + delete_char_count, len - pos - delete_char_count); fb_StrAssign( &result, -1, str_left, -1, FALSE ); fb_StrConcatAssign( &result, -1, str_right, -1, FALSE ); len -= delete_char_count; FB_LOCK(); fb_PrintBufferEx( result.data + pos, len - pos, 0 ); /* Overwrite all deleted characters with SPC's */ str_fill = fb_StrFill1 ( delete_char_count, ' ' ); fb_PrintBufferEx( str_fill->data, delete_char_count, 0 ); fb_hStrDelTemp( str_fill ); fb_Locate( current_y, current_x, -1, 0, 0 ); FB_UNLOCK(); } if( add_char ) { tmp_buffer[tmp_buffer_len] = 0; } if( add_char ) { int old_x = current_x, old_y = current_y; FBSTRING *str_add = fb_StrAllocTempDescF( tmp_buffer, tmp_buffer_len + 1 ); FBSTRING *str_left = fb_StrMid( &result, 1, pos ); FBSTRING *str_right = fb_StrMid( &result, pos + 1, len - pos); fb_StrAssign( &result, -1, str_left, -1, FALSE ); fb_StrConcatAssign( &result, -1, str_add, -1, FALSE ); fb_StrConcatAssign( &result, -1, str_right, -1, FALSE ); len += tmp_buffer_len; FB_LOCK(); fb_PrintBufferEx( result.data + pos, len - pos, 0 ); fb_GetXY(¤t_x, ¤t_y); if( pos==(len-tmp_buffer_len) ) { current_x = old_x; current_y = old_y; DoMove( ¤t_x, ¤t_y, tmp_buffer_len, 0, cols, rows ); } else { int tmp_x_2 = old_x, tmp_y_2 = old_y; DoAdjust( &tmp_x_2, &tmp_y_2, len - pos, 0, cols, rows ); if( tmp_y_2 > (rows+1) || (tmp_y_2==(rows+1) && tmp_x_2>1) ) { DoMove( ¤t_x, ¤t_y, -(len - pos - tmp_buffer_len), 0, cols, rows ); } else { current_x = old_x; current_y = old_y; DoMove( ¤t_x, ¤t_y, tmp_buffer_len, 0, cols, rows ); } } pos += tmp_buffer_len; FB_UNLOCK(); } fb_Locate( 0, 0, (soft_cursor == FALSE), 0, 0 ); } while (k!='\r' && k!='\n'); FB_LOCK(); /* set cursor to end of line */ fb_GetXY(¤t_x, ¤t_y); DoMove( ¤t_x, ¤t_y, len - pos, 0, cols, rows ); /* Restore old cursor visibility */ fb_Locate( 0, 0, cursor_visible, 0, 0 ); FB_UNLOCK(); return fb_StrAllocTempResult( &result ); }
char *fb_ConsoleReadStr( char *buffer, int len ) { #if defined( HOST_UNIX ) int k, x, y, cols, pos = 0; char ch[2] = { 0, '\0' }; if (!__fb_con.inited) return fgets(buffer, len, stdin); fb_ConsoleGetSize(&cols, NULL); do { while( ((k = fb_hGetCh(TRUE)) == -1) || (k & 0x100) ) fb_Delay( 10 ); /* drop subsequent keypresses, if any; this is needed to avoid escape * sequence parsing problems in the fb_ConsoleGetXY() call below. */ while( fb_hGetCh(TRUE) >= 0 ) fb_Delay( 10 ); fb_ConsoleGetXY(&x, &y); if (k == 8) { if (pos > 0) { x--; if (x <= 0) { x = cols; y--; if (y <= 0) x = y = 1; } fb_hTermOut(SEQ_LOCATE, x-1, y-1); fb_hTermOut(SEQ_DEL_CHAR, 0, 0); pos--; } } else if (k != '\t') { if (pos < len - 1) { buffer[pos++] = ch[0] = k; fb_ConsolePrintBuffer(ch, 0); if (x == cols) fputc('\n', __fb_con.f_out); } } } while (k != '\r'); fputc('\n', __fb_con.f_out); buffer[pos] = '\0'; return buffer; #elif defined( HOST_WIN32 ) char *res; fb_hRestoreConsoleWindow( ); FB_CON_CORRECT_POSITION(); fb_hConsolePutBackEvents( ); res = fgets( buffer, len, stdin ); fb_hUpdateConsoleWindow( ); return res; #else return fgets( buffer, len, stdin ); #endif }