Logo Search packages:      
Sourcecode: vche version File versions  Download package

vclib.c

/*
   Virtual Console I/O
   --------------------------------------------------------------------
   VCHE - Virtual Console Hex Editor

   Copyright (C) 1998, 1999 Diego Javier Grigna <diego@grigna.com>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "common.h"

/*
 * Draws a box at 'x', 'y' with 'xlen' width and 'ylen' height
 */
void vc_box( int x, int y, int xlen, int ylen, int attr)
{
 char *buffer;
 int linesize;
 int i, j;

 buffer = ( char *) allocate_mem( vc_cols * 2);

 linesize = xlen * 2;

 lseek( vcsafd, 4 + 2 *( y * vc_cols + x), SEEK_SET);
 
 memset( buffer, attr, linesize);

 buffer[            0] = VC_LINE_TOPLEFT;
 buffer[ xlen * 2 - 2] = VC_LINE_TOPRIGHT;

 for( i = 2 ; i < xlen * 2 - 2; i += 2) buffer[ i] = VC_LINE_HORIZ;
 write( vcsafd, buffer, linesize); 

 buffer[ 0] = buffer[ xlen * 2 - 2] = VC_LINE_VERT;
 for( i = 2 ; i < xlen * 2 - 2; i += 2) 
      buffer[ i] = VC_LINE_NOTHING;

 for( j = 0; j < ylen - 2; j++) {
      lseek( vcsafd, vc_cols * 2 - linesize, SEEK_CUR);
      write( vcsafd, buffer, linesize); 
 }

 lseek( vcsafd, vc_cols * 2 - linesize, SEEK_CUR);

 buffer[            0] = VC_LINE_BOTTOMLEFT;
 buffer[ xlen * 2 - 2] = VC_LINE_BOTTOMRIGHT;

 for( i = 2 ; i < xlen * 2 - 2; i+=2) buffer[ i] = VC_LINE_HORIZ;
 write( vcsafd, buffer, linesize);

 free( buffer);
}

/* 
 * Write a string to /dev/vcsa* with character+attribute
 */
void vc_color_puts( int x, int y, int size, char *str, int attr)
{
 char *buffer;
 int i = 0;
 int nsize = size * 2;

 buffer = ( char *) allocate_mem( vc_cols * 2);

 if( !size) return;

 while( i < nsize) {
      buffer[ i++] = *str++;
      buffer[ i++] = attr;
 }

 lseek( vcsafd, 4 + 2 *( y * vc_cols + x), SEEK_SET);

 write( vcsafd, buffer, nsize);

 free( buffer);
}

/* 
 * Write a character+attribute to /dev/vcsa*
 */
void vc_color_putc( int x, int y, char byte, int attr)
{
 char buffer[ 2];

 buffer[ 0] = byte;
 buffer[ 1] = attr;

 lseek( vcsafd, 4 + 2 *( y * vc_cols + x), SEEK_SET);

 write( vcsafd, &buffer, 2);
}

/*
 * Write a string to the output buffer
 */
void vc_color_buffer_puts( int x, int y, int size, char *str, int attr)
{
 int pos = 2 *( y * vc_cols + x);
 int i   = 0;

 while( i < size * 2) {
      obuffer[ pos + i++] = *str++;
      obuffer[ pos + i++] = attr;
 }
}

/* 
 * Write a string to /dev/vcs* only character 
 * I had made test, and writing to /dev/vcs* is faster that writing
 * to /dev/vcsa*, the kernel code is faster and smaller.
 * (At least on 2.0.x kernels, I didn't test it on 2.1.x kernels)
 * So use this function if you don't need to modify the attributes 
 */
void vc_puts( int x, int y, int size, char *str)
{
 lseek( vcsfd, (long) (y * vc_cols + x), SEEK_SET);
 write( vcsfd, str, size);
}

void vc_putc( int x, int y, char byte)
{
 char buffer[2];

 buffer[0] = byte;

 lseek( vcsfd, (long) (y * vc_cols + x), SEEK_SET);
 write( vcsfd, buffer, 1);
}

/*
 * Save the screen in memory
 */
void vc_save_screen( void)
{
 int size;

 size = (vc_lines * vc_cols) * 2 + sizeof( struct vcscrn);

 vcs_save_buffer[ vcs_save_index] = 
                  (char *) allocate_mem( (size + 1) * sizeof( char));

 lseek( vcsafd, (long) 0, SEEK_SET);
 read( vcsafd, vcs_save_buffer[ vcs_save_index], size);

 vcs_save_index++;

 if( vcs_save_index + 1 == MAX_VCS_SAVE ) {
     fprintf( stderr, "Saved screens numbers exceeded\n");
     do_exit( 1);
 }

}

/*
 * Restore a previously saved screen
 */
void vc_load_screen( void)
{
 int size;

 vcs_save_index--;

 size = (vc_lines * vc_cols) * 2 + sizeof( struct vcscrn);

 lseek( vcsafd, (long) 0, SEEK_SET);
 write( vcsafd, vcs_save_buffer[ vcs_save_index], size);

 free( vcs_save_buffer[ vcs_save_index]);
}

/*
 * Draws a dialog box.
 */
void vc_dialog_box( char *titlestr, char *valuestr, int size, int tattr, int vattr)
{
 char buf[ 2048];
 int titlelen, len;
 int x, y;

 titlelen = strlen( titlestr);
 len = titlelen > size ? titlelen : size;

 y = vc_lines / 2;

 sprintf( buf, "%-250.250s", valuestr);

 x = ( vc_cols - len - 4) / 2;
 vc_box( x, y - 2, len + 4, 4, tattr);

 x = ( vc_cols - len    ) / 2;
 vc_puts( x, y - 1, titlelen, titlestr);

 x = ( vc_cols - size   ) / 2;
 vc_color_puts( x, y, size, buf, vattr);
}

/*
 * Fill the screen with attribute 'attr'
 */
void vc_fill_screen( int attr)
{
 char *buffer;
 int size;
 int i = 0;

 size = (vc_lines * vc_cols) * 2;

 buffer = (char *) allocate_mem( (size + 1) * sizeof( char));

 while( i < size) {
        buffer[ i++] = ' ';
        buffer[ i++] = attr;
 }

 lseek( vcsafd, (long) 4, SEEK_SET);
 write( vcsafd, buffer, size);

 free( buffer);
}

/*
 * Shows an error (or attention) message box and wait for a key.
 */
void vc_show_alert_box( char *str, int addy)
{
 char *buf;
 int len;
 int x, y;

 len = strlen( str);
 buf = ( char *) allocate_mem( len + 64);

 strcpy( buf, str);

 vc_save_screen();

 if( len < 16) len = 16;
 if( len > vc_cols - 4) {
     len = vc_cols - 4;
     buf[ vc_cols - 5] = '\x1a';
 }

 y = vc_lines / 2;
 y+= addy;

 x = ( vc_cols - len - 4) / 2;

 term_beep();

 vc_box(  x, y - 2, len + 4, 4, VC_COLOR_ATTENTION);

 x = ( vc_cols - len) / 2;
 vc_puts( x, y - 1, len, buf               );

 x = ( vc_cols -  16) / 2;
 vc_puts( x, y    , 16 , "Press any key...");

 key_wait_for_any();
 vc_load_screen();
 free( buf);
}

/*
 * Do a box, fill it with '\n' separated lines of text and wait for a key
 */
void vc_show_screentext( char *text, char *title)
{
 char *buffer;
 char *p = text;
 int y = 2, i = 0;

 buffer = ( char *) allocate_mem( vc_cols * 2);

 vc_save_screen();

 vc_box( 0, 0, vc_cols, vc_lines, VC_COLOR_BACKCYAN);

 vc_do_title( title);

 while( *p && y < (vc_lines - 3)) {

        /* 
         * I love C language :) 
         * Print the line if we reach an '\n' or the end of the screen
         */

        if( ((*p == '\n') ? *p++: 0) || i == vc_cols - 4) {
            vc_puts( 2, y++, i, buffer);
            i = 0;
            continue;
        }
        buffer[ i++] = *p++;
 }

 vc_color_puts( ( vc_cols - 18) / 2, vc_lines - 2, 18, " Press any key... ", VC_COLOR_BACKGRAY);

 key_wait_for_any();

 vc_load_screen();

 free( buffer);
}

/*
 * Write a title
 */
void vc_do_title( char *title)
{
 int len;
 int x;

 len = strlen( title);
 x = ( vc_cols - len) / 2;

 vc_putc( x -   1, 0, '');
 vc_putc( x + len, 0, '');
 vc_color_puts( x, 0, len, title, VC_COLOR_BACKGRAY);
}

/*
 * Write a centered bottom line
 */
void vc_put_bottom_line( char *text)
{
 int len;
 int x;
 int y;

 len = strlen( text);
 x = ( vc_cols - len) / 2;
 y = vc_lines - 1;

 vc_color_puts( 0, y, vc_cols, space_buffer, VC_COLOR_BACKGRAY);
 vc_puts( x, y, len, text);
}

/*
 * Flush the output buffer to /dev/vcsa*
 */
void vc_flush( void)
{
 lseek( vcsafd, 4 + 2 * vc_cols, SEEK_SET);
 write( vcsafd, obuffer, vc_cols * 2 * ( vc_lines - 2));
}

/*
 * Shows a question message, and let navigate options.
 */
int vc_ask( char *msg, char *q1, char *q2, char *q3, int posit)
{
 int lenmsg;
 int lenqs;
 int lq1,lq2,lq3;
 int len;
 int xq1, xq2, xq3;
 int x, y;
 int pos = posit;
 int c;

 vc_save_screen();
 term_hide_cursor();

 lq1 = strlen( q1);
 lq2 = strlen( q2);
 lq3 = strlen( q3);

 lenmsg = strlen( msg);
 lenqs  = lq1 + lq2 + lq3 + 2;

 len = lenmsg > lenqs ? lenmsg : lenqs;
 y = vc_lines / 2;

 x = ( vc_cols - len - 4) / 2;
 vc_box(  x, y - 2, len + 4, 4, VC_COLOR_ATTENTION);

 x = ( vc_cols - len) / 2;
 vc_puts( x, y - 1, lenmsg, msg);

 xq1 = ( vc_cols - lenqs) / 2;
 xq2 = xq1 + lq1 + 1;
 xq3 = xq2 + lq2 + 1;

 while( 1) {
        if( pos > 2) pos = 0;
        if( pos < 0) pos = 2;

        switch( pos) {
                case 0: vc_color_puts( xq1, y, lq1, q1, VC_COLOR_BACKGRAY  );
                        vc_color_puts( xq2, y, lq2, q2, VC_COLOR_ATTENTION );
                        vc_color_puts( xq3, y, lq3, q3, VC_COLOR_ATTENTION );
                        break;
                case 1: vc_color_puts( xq1, y, lq1, q1, VC_COLOR_ATTENTION );
                        vc_color_puts( xq2, y, lq2, q2, VC_COLOR_BACKGRAY  );
                        vc_color_puts( xq3, y, lq3, q3, VC_COLOR_ATTENTION );
                        break;
                case 2: vc_color_puts( xq1, y, lq1, q1, VC_COLOR_ATTENTION );
                        vc_color_puts( xq2, y, lq2, q2, VC_COLOR_ATTENTION );
                        vc_color_puts( xq3, y, lq3, q3, VC_COLOR_BACKGRAY  );
                        break;
        }

        c = key_get();

        switch( c) {
                case '\n': term_unhide_cursor();
                           vc_load_screen();
                           return pos;
                case VC_KEY_RIGHT : pos++;
                                    break;
                case VC_KEY_LEFT  : pos--;
                                    break;
                case VC_KEY_HOME  : pos = 0;
                                    break;
                case VC_KEY_END   : pos = 2;
                                    break;
        } /* end switch( c) */
 } /* end while( 1) */

}

/*
 * Shows a message without waiting for a key
 */
void vc_show_message( char *msg, int addy)
{
 int len;
 int x, y;

 len = strlen( msg);

 y = ( vc_lines / 2) - 1;
 y += addy;

 x = ( vc_cols - len - 4) / 2;
 vc_box(  x, y - 1, len + 4, 3, VC_COLOR_ATTENTION);

 x = ( vc_cols - len) / 2;
 vc_puts( x, y   , len, msg);
}

void vc_fill_obuffer( void)
{
 int i = 0;
 int obuffer_size = vc_cols * 2 * ( vc_lines - 2);

 while( i < obuffer_size) {
        obuffer[ i++] = ' ';
        obuffer[ i++] = VC_COLOR_BACKBLUE;
 }
}


Generated by  Doxygen 1.6.0   Back to index