Пример #1
0
/*:::::*/
int fb_ConsoleLineInputWstr( const FB_WCHAR *text, FB_WCHAR *dst, int max_chars,
							 int addquestion, int addnewline )
{
	int res;
    size_t len;
    int old_x, old_y;

    /* !!!FIXME!!! no support for unicode input */

    fb_PrintBufferEx( NULL, 0, FB_PRINT_FORCE_ADJUST );
    fb_GetXY( &old_x, &old_y );

	FB_LOCK();

    if( text != NULL )
    {
		fb_PrintWstr( 0, text, 0 );

        if( addquestion != FB_FALSE )
            fb_PrintFixString( 0, pszDefaultQuestion, 0 );
    }

    {
        FBSTRING str_result = { 0 };

        res = fb_DevFileReadLineDumb( stdin, &str_result, hWrapper );

        len = FB_STRSIZE(&str_result);

        if( !addnewline )
        {
            int cols, rows;
            int old_y;

            fb_GetSize( &cols, &rows );
            fb_GetXY( NULL, &old_y );

            old_x += len - 1;
            old_x %= cols;
            old_x += 1;
            old_y -= 1;

            fb_Locate( old_y, old_x, -1, 0, 0 );
        }

        fb_WstrAssignFromA( dst, max_chars, (void *)&str_result, -1 );

        fb_StrDelete( &str_result );
    }

	FB_UNLOCK();

    return res;
}
Пример #2
0
void fb_DevScrnInit_Screen( void )
{
    int cols;
	DEV_SCRN_INFO *info = (DEV_SCRN_INFO*) malloc(sizeof(DEV_SCRN_INFO));

    fb_GetSize( &cols, NULL );
    info->length = 0;

    FB_HANDLE_SCREEN->opaque = info;
    FB_HANDLE_SCREEN->line_length = fb_GetX() - 1;
    FB_HANDLE_SCREEN->width = cols;
}
Пример #3
0
FBCALL void fb_PrintSPC( int fnum, ssize_t n )
{
    FB_FILE *handle;
    int col, row, cols, rows, newcol;

    if( n==0 )
        return;

    fb_DevScrnInit_NoOpen( );

    FB_LOCK();

    handle = FB_FILE_TO_HANDLE(fnum);

	if( FB_HANDLE_IS_SCREEN(handle) || handle->type == FB_FILE_TYPE_CONSOLE )
	{
		if( n == 0 )
			return;

        if( handle->type == FB_FILE_TYPE_CONSOLE ) {
            if( handle->hooks && handle->hooks->pfnFlush )
                handle->hooks->pfnFlush( handle );
        }

        /* Ensure that we get the "real" cursor position - this quirk is
         * required for cursor positions at the right bottom of the screen */
        fb_PrintBufferEx( NULL, 0, FB_PRINT_FORCE_ADJUST );
		fb_GetXY( &col, &row );
		fb_GetSize( &cols, &rows );

    	newcol = col + n;
        if( newcol > cols ) {
            fb_PrintVoidEx ( handle, FB_PRINT_NEWLINE );
            newcol %= cols;
        }

        fb_Locate( 0, newcol, -1, 0, 0 );

    } else {

        fb_PrintStringEx( handle, fb_StrFill1( n, ' ' ), 0 );

    }

    FB_UNLOCK();
}
Пример #4
0
FBCALL void fb_PrintTab( int fnum, int newcol )
{
    FB_FILE *handle;
    int col, row, cols, rows;

    fb_DevScrnInit_NoOpen( );

    FB_LOCK();

    handle = FB_FILE_TO_HANDLE(fnum);

	if( FB_HANDLE_IS_SCREEN(handle) || handle->type == FB_FILE_TYPE_CONSOLE )
    {
        if( handle->type == FB_FILE_TYPE_CONSOLE ) {
            if( handle->hooks && handle->hooks->pfnFlush )
                handle->hooks->pfnFlush( handle );
        }

        /* Ensure that we get the "real" cursor position - this quirk is
         * required for cursor positions at the right bottom of the screen */
        fb_PrintBufferEx( NULL, 0, FB_PRINT_FORCE_ADJUST );
		fb_GetXY( &col, &row );
		fb_GetSize( &cols, &rows );

    	if( newcol > cols )
    		newcol %= cols;

        if( col > newcol ) {
            fb_PrintVoidEx ( handle, FB_PRINT_NEWLINE );
			fb_Locate( 0, newcol, -1, 0, 0 );

        } else if( newcol < 1 )
    		fb_Locate( 0, 1, -1, 0, 0 );

    	else
            fb_Locate( 0, newcol, -1, 0, 0 );

    } else {

        if( handle->type==FB_FILE_TYPE_PIPE ) {

            fb_PrintPadEx ( handle, 0 );

        } else {

            if( (newcol >= 0) && ((unsigned int)newcol > handle->line_length) ) {
                fb_PrintStringEx( handle,
                                  fb_StrFill1( newcol - handle->line_length - 1, ' ' ),
                                  0 );
            } else {

                if( handle->mode==FB_FILE_MODE_BINARY ) {
                    fb_PrintStringEx( handle,
                                      fb_StrAllocTempDescF( FB_BINARY_NEWLINE, sizeof( FB_BINARY_NEWLINE ) ),
                                      0 );
                } else {
                    fb_PrintStringEx( handle,
                                      fb_StrAllocTempDescF( FB_NEWLINE, sizeof( FB_NEWLINE ) ),
                                      0 );
                }

                if( newcol > 0 ) {
                    fb_PrintStringEx( handle,
                                      fb_StrFill1( newcol - 1, ' ' ),
                                      0 );
                }

            }

        }

    }

    FB_UNLOCK();
}
Пример #5
0
void fb_GfxPrintBufferEx( const void *buffer, size_t len, int mask )
{
	FB_GFXCTX *context;
    const char *pachText = (const char *) buffer;
    int win_left, win_top, win_cols, win_rows;
    int view_top, view_bottom;
    fb_PrintInfo info;
    fb_ConHooks hooks;

	FB_GRAPHICS_LOCK( );

    /* Do we want to correct the console cursor position? */
    if( (mask & FB_PRINT_FORCE_ADJUST)==0 ) {
        /* No, we can check for the length to avoid unnecessary stuff ... */
        if( len==0 ) {
            FB_GRAPHICS_UNLOCK( );
            return;
        }
    }

	context = fb_hGetContext( );
	fb_hPrepareTarget(context, NULL);
	fb_hSetPixelTransfer(context, MASK_A_32);

	DRIVER_LOCK();

    fb_GetSize( &win_cols, &win_rows );
    fb_ConsoleGetView( &view_top, &view_bottom );
    win_left = win_top = 0;

    hooks.Opaque        = &info;
    hooks.Scroll        = fb_hHookConScroll;
    hooks.Write         = fb_hHookConWrite;
    hooks.Border.Left   = win_left;
    hooks.Border.Top    = win_top + view_top - 1;
    hooks.Border.Right  = win_left + win_cols - 1;
    hooks.Border.Bottom = win_top + view_bottom - 1;

	info.context = context;
    info.dirty_start = info.dirty_end = 0;

    {
        hooks.Coord.X = __fb_gfx->cursor_x;
        hooks.Coord.Y = __fb_gfx->cursor_y;

        if( __fb_gfx->flags & PRINT_SCROLL_WAS_OFF ) {
            __fb_gfx->flags &= ~PRINT_SCROLL_WAS_OFF;
            ++hooks.Coord.Y;
            hooks.Coord.X = hooks.Border.Left;
            fb_hConCheckScroll( &hooks );
        }

        fb_ConPrintTTY( &hooks,
                        pachText,
                        len,
                        TRUE );

        if( hooks.Coord.X != hooks.Border.Left
            || hooks.Coord.Y != (hooks.Border.Bottom+1) )
        {
            fb_hConCheckScroll( &hooks );
        } else {
            __fb_gfx->flags |= PRINT_SCROLL_WAS_OFF;
            hooks.Coord.X = hooks.Border.Right;
            hooks.Coord.Y = hooks.Border.Bottom;
        }
        fb_GfxLocateRaw( hooks.Coord.Y, hooks.Coord.X, -1 );
    }

    SET_DIRTY(context, info.dirty_start, info.dirty_end - info.dirty_start);

    DRIVER_UNLOCK();
	FB_GRAPHICS_UNLOCK( );
}
Пример #6
0
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(&current_x, &current_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( &current_x, &current_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( &current_x, &current_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( &current_x, &current_y, -1, 0, cols, rows );
                --pos;
            }
            break;
        case FB_MAKE_EXT_KEY(0x4D):
            /* Cursor RIGHT */
            if( pos != len ) {
                DoMove( &current_x, &current_y, 1, 0, cols, rows );
                ++pos;
            }
            break;
        case FB_MAKE_EXT_KEY(0x47):
            /* HOME */
            DoMove( &current_x, &current_y, -pos, 0, cols, rows );
            pos = 0;
            break;
        case FB_MAKE_EXT_KEY(0x4F):
            /* END */
            DoMove( &current_x, &current_y, len-pos, 0, cols, rows );
            pos = len;
            break;
        case FB_MAKE_EXT_KEY(0x48):
            /* Cursor UP */
            if( pos >= cols) {
                DoMove( &current_x, &current_y, -cols, 0, cols, rows );
                pos -= cols;
            }
            break;
        case FB_MAKE_EXT_KEY(0x50):
            /* Cursor DOWN */
            if( ( pos + cols ) <= len ) {
                DoMove( &current_x, &current_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( &current_x, &current_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(&current_x, &current_y);

            if( pos==(len-tmp_buffer_len) ) {
                current_x = old_x; current_y = old_y;
                DoMove( &current_x, &current_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( &current_x, &current_y, -(len - pos - tmp_buffer_len), 0, cols, rows );
                } else {
                    current_x = old_x; current_y = old_y;
                    DoMove( &current_x, &current_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(&current_x, &current_y);
    DoMove( &current_x, &current_y, len - pos, 0, cols, rows );

    /* Restore old cursor visibility */
    fb_Locate( 0, 0, cursor_visible, 0, 0 );

    FB_UNLOCK();

	return fb_StrAllocTempResult( &result );
}
Пример #7
0
/*:::::*/
int fb_ConsoleLineInput( FBSTRING *text, void *dst, int dst_len, int fillrem,
						 int addquestion, int addnewline )
{
	int res;
    size_t len;
    int old_x, old_y;

    fb_PrintBufferEx( NULL, 0, FB_PRINT_FORCE_ADJUST );
    fb_GetXY( &old_x, &old_y );

	FB_LOCK();

    if( text != NULL )
    {
        if( text->data != NULL )
        {
            fb_PrintString( 0, text, 0 );
        }
    	/* del if temp */
    	else
    	{
    		fb_hStrDelTemp( text );
    	}

        if( addquestion != FB_FALSE )
        {
            fb_PrintFixString( 0, pszDefaultQuestion, 0 );
        }
    }

    {
        /* create temporary string */
        FBSTRING str_result = { 0 };

        res = fb_DevFileReadLineDumb( stdin, &str_result, hWrapper );

        len = FB_STRSIZE(&str_result);

        /* We have to handle the NEWLINE stuff here because we *REQUIRE*
         * the *COMPLETE* temporary input string for the correct position
         * adjustment. */
        if( !addnewline ) {
            /* This is the easy and dumb method to do the position adjustment.
             * The problem is that it doesn't take TAB's into account. */
            int cols, rows;
            int old_y;

            fb_GetSize( &cols, &rows );
            fb_GetXY( NULL, &old_y );

            old_x += len - 1;
            old_x %= cols;
            old_x += 1;
            old_y -= 1;

            fb_Locate( old_y, old_x, -1, 0, 0 );
        }


        /* add contents of tempporary string to result buffer */
        fb_StrAssign( dst, dst_len, (void *)&str_result, -1, fillrem );

        fb_StrDelete( &str_result );

    }

	FB_UNLOCK();

    return res;
}