Merge branch 'ansi_console'
This commit is contained in:
commit
f904ed112b
|
@ -20,6 +20,8 @@ t_channel g_channels[CHAN_MAX];
|
|||
void cdev_init_system() {
|
||||
int i;
|
||||
|
||||
TRACE("cdev_init_system");
|
||||
|
||||
// Clear out all the channel device records...
|
||||
for (i = 0; i < CDEV_DEVICES_MAX; i++) {
|
||||
g_channel_devs[i].number = 0;
|
||||
|
@ -31,13 +33,6 @@ void cdev_init_system() {
|
|||
g_channels[i].number = -1;
|
||||
g_channels[i].dev = -1;
|
||||
}
|
||||
|
||||
// Pre-open a channel for the console and EVID
|
||||
g_channels[0].number = 0;
|
||||
g_channels[0].dev = 0;
|
||||
|
||||
g_channels[1].number = 1;
|
||||
g_channels[1].dev = 1;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -54,6 +49,8 @@ short cdev_register(p_dev_chan device) {
|
|||
cdev->number = device->number;
|
||||
cdev->name = device->name;
|
||||
cdev->init = device->init;
|
||||
cdev->open = device->open;
|
||||
cdev->close = device->close;
|
||||
cdev->read = device->read;
|
||||
cdev->readline = device->readline;
|
||||
cdev->read_b = device->read_b;
|
||||
|
@ -69,19 +66,33 @@ short cdev_register(p_dev_chan device) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get a free channel
|
||||
//
|
||||
// Returns:
|
||||
// A pointer to the free channel, 0 if none are available.
|
||||
//
|
||||
p_channel chan_alloc() {
|
||||
/*
|
||||
* Get a free channel
|
||||
*
|
||||
* Inputs:
|
||||
* the device to associate with the channel
|
||||
*
|
||||
* Returns:
|
||||
* A pointer to the free channel, 0 if none are available.
|
||||
*/
|
||||
p_channel chan_alloc(short dev) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CHAN_MAX; i++) {
|
||||
if (g_channels[i].number < 0) {
|
||||
g_channels[i].number = i;
|
||||
return &g_channels[i];
|
||||
TRACE("chan_alloc");
|
||||
|
||||
if ((dev == CDEV_CONSOLE) || (dev == CDEV_EVID)) {
|
||||
/* For CONSOLE and EVID, the channel is always the same number as the device */
|
||||
g_channels[dev].number = dev;
|
||||
g_channels[dev].dev = dev;
|
||||
return &g_channels[dev];
|
||||
|
||||
} else {
|
||||
for (i = CDEV_EVID + 1; i < CHAN_MAX; i++) {
|
||||
if (g_channels[i].number < 0) {
|
||||
g_channels[i].number = i;
|
||||
g_channels[i].dev = dev;
|
||||
return &g_channels[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,6 +123,39 @@ void chan_free(p_channel chan) {
|
|||
chan->dev = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Find the records for the channel and the channel's device, given the channel number
|
||||
//
|
||||
// Inputs:
|
||||
// channel = the number of the channel to look up
|
||||
// chan = pointer to the channel structure pointer to set
|
||||
// cdev = pointer to the channel device structure pointer to set
|
||||
//
|
||||
// Returns:
|
||||
// 0 on success, a negative number on error
|
||||
//
|
||||
short chan_get_records(short channel, p_channel * chan, p_dev_chan * cdev) {
|
||||
if (channel < CHAN_MAX) {
|
||||
*chan = &g_channels[channel];
|
||||
if ((*chan)->number == channel) {
|
||||
if ((*chan)->dev < CDEV_DEVICES_MAX) {
|
||||
*cdev = &g_channel_devs[(*chan)->dev];
|
||||
return 0;
|
||||
} else {
|
||||
log_num(LOG_ERROR, "chan_get_records 1: ", (*chan)->dev);
|
||||
return DEV_ERR_BADDEV;
|
||||
}
|
||||
|
||||
} else {
|
||||
log_num(LOG_ERROR, "chan_get_records 2: ", channel);
|
||||
return DEV_ERR_BADDEV;
|
||||
}
|
||||
|
||||
} else {
|
||||
return ERR_BADCHANNEL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the device
|
||||
//
|
||||
|
@ -132,37 +176,72 @@ short cdev_init(short dev) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Find the records for the channel and the channel's device, given the channel number
|
||||
//
|
||||
// Inputs:
|
||||
// channel = the number of the channel to look up
|
||||
// chan = pointer to the channel structure pointer to set
|
||||
// cdev = pointer to the channel device structure pointer to set
|
||||
//
|
||||
// Returns:
|
||||
// 0 on success, a negative number on error
|
||||
//
|
||||
short chan_get_records(short channel, p_channel * chan, p_dev_chan * cdev) {
|
||||
if (channel < CHAN_MAX) {
|
||||
*chan = &g_channels[channel];
|
||||
if ((*chan)->number == channel) {
|
||||
if ((*chan)->dev < CDEV_DEVICES_MAX) {
|
||||
*cdev = &g_channel_devs[(*chan)->dev];
|
||||
return 0;
|
||||
} else {
|
||||
return DEV_ERR_BADDEV;
|
||||
}
|
||||
/*
|
||||
* Open a channel
|
||||
*
|
||||
* Inputs:
|
||||
* dev = the device number to have a channel opened
|
||||
* path = a "path" describing how the device is to be open
|
||||
* mode = is the device to be read, written, both?
|
||||
*
|
||||
* Returns:
|
||||
* the number of the channel opened, negative number on error
|
||||
*/
|
||||
short chan_open(short dev, uint8_t * path, short mode) {
|
||||
short result;
|
||||
p_channel chan;
|
||||
p_dev_chan cdev;
|
||||
|
||||
} else {
|
||||
TRACE("chan_open");
|
||||
log_num(LOG_DEBUG, "dev = ", dev);
|
||||
|
||||
if (dev < CDEV_DEVICES_MAX) {
|
||||
/* Get the device record */
|
||||
cdev = &g_channel_devs[dev];
|
||||
if (cdev->number != dev) {
|
||||
/* Double check we have a real device */
|
||||
return DEV_ERR_BADDEV;
|
||||
}
|
||||
|
||||
/* Grab a channel */
|
||||
chan = chan_alloc(dev);
|
||||
if (chan == 0) {
|
||||
return ERR_OUT_OF_HANDLES;
|
||||
}
|
||||
|
||||
/* Open the channel */
|
||||
result = cdev->open(chan, path, mode);
|
||||
if (result == 0) {
|
||||
/* Success: return the channel number */
|
||||
return chan->number;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
return ERR_BADCHANNEL;
|
||||
return DEV_ERR_BADDEV;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a channel
|
||||
*
|
||||
* Inputs:
|
||||
* chan = the number of the channel to close
|
||||
*
|
||||
* Returns:
|
||||
* nothing useful
|
||||
*/
|
||||
short chan_close(short channel) {
|
||||
p_channel chan;
|
||||
p_dev_chan cdev;
|
||||
if (chan_get_records(channel, &chan, &cdev) == 0) {
|
||||
cdev->close(chan);
|
||||
chan_free(chan);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Read bytes from the channel
|
||||
//
|
||||
|
@ -258,7 +337,8 @@ short chan_write(short channel, const uint8_t * buffer, short size) {
|
|||
if (res == 0) {
|
||||
return cdev->write(chan, buffer, size);
|
||||
} else {
|
||||
DEBUG("chan_write error\n");
|
||||
log_num(LOG_ERROR, "chan_write error: ", res);
|
||||
while (1) ;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ typedef struct s_dev_chan {
|
|||
short number; // The number of the device (assigned by registration)
|
||||
char * name; // The name of the device
|
||||
FUNC_V_2_S init; // short init() -- Initialize the device
|
||||
FUNC_CBS_2_S open; // short open(t_channel * chan, uint8_t * path, short mode) -- open a channel for the device
|
||||
FUNC_V_2_S close; // short close(t_channel * chan) -- called when a channel is closed
|
||||
FUNC_CBS_2_S read; // short read(t_channel *, uint8_t * buffer, short size) -- Read a a buffer from the device
|
||||
FUNC_CBS_2_S readline; // short readline(t_channel *, uint8_t * buffer, short size) -- Read a line of text from the device
|
||||
FUNC_C_2_S read_b; // short read_b(t_channel *) -- read a single uint8_t from the device
|
||||
|
@ -126,6 +128,30 @@ extern p_channel chan_get_record(short c);
|
|||
*/
|
||||
extern short cdev_init(short dev);
|
||||
|
||||
/*
|
||||
* Open a channel
|
||||
*
|
||||
* Inputs:
|
||||
* dev = the device number to have a channel opened
|
||||
* path = a "path" describing how the device is to be open
|
||||
* mode = is the device to be read, written, both?
|
||||
*
|
||||
* Returns:
|
||||
* the number of the channel opened, negative number on error
|
||||
*/
|
||||
extern short chan_open(short dev, uint8_t * path, short mode);
|
||||
|
||||
/*
|
||||
* Close a channel
|
||||
*
|
||||
* Inputs:
|
||||
* chan = the number of the channel to close
|
||||
*
|
||||
* Returns:
|
||||
* nothing useful
|
||||
*/
|
||||
extern short chan_close(short chan);
|
||||
|
||||
/*
|
||||
* Read bytes from the channel
|
||||
*
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "log.h"
|
||||
#include "types.h"
|
||||
#include "constants.h"
|
||||
#include "dev/channel.h"
|
||||
|
@ -13,6 +16,135 @@
|
|||
#include "dev/kbd_mo.h"
|
||||
#include "dev/text_screen_iii.h"
|
||||
|
||||
#define ANSI_BUFFER_SIZE 16
|
||||
#define MAX_ANSI_ARGS 10
|
||||
|
||||
#define CON_CTRL_ANSI 0x80 /* Set to enable ANSI escape processing */
|
||||
|
||||
typedef void (*ansi_handler)(p_channel, short, short[]);
|
||||
|
||||
/*
|
||||
* Structure to map an ANSI escape sequence pattern to a handler
|
||||
*/
|
||||
typedef struct s_ansi_seq {
|
||||
char * pattern;
|
||||
ansi_handler handler;
|
||||
} t_ansi_seq, *p_ansi_seq;
|
||||
|
||||
/*
|
||||
* Structure to track console state
|
||||
*/
|
||||
typedef struct s_console_data {
|
||||
unsigned char control; /* Control flags for the console: e.g. process ANSI codes */
|
||||
unsigned char ansi_buffer_count; /* Number of characters in the ANSI BUFFER */
|
||||
char ansi_buffer[ANSI_BUFFER_SIZE]; /* Used to keep track of characters in the ANSI escape sequences */
|
||||
} t_console_data, *p_console_data;
|
||||
|
||||
/*
|
||||
* Forwards
|
||||
*/
|
||||
|
||||
extern void ansi_cuu(p_channel chan, short arg_count, short args[]);
|
||||
extern void ansi_cuf(p_channel chan, short arg_count, short args[]);
|
||||
extern void ansi_cub(p_channel chan, short arg_count, short args[]);
|
||||
extern void ansi_cud(p_channel chan, short arg_count, short args[]);
|
||||
|
||||
/*
|
||||
* Console variables and constants
|
||||
*/
|
||||
|
||||
/*
|
||||
* ANSI escape sequences:
|
||||
* # is a placeholder for any number of numerals
|
||||
*
|
||||
*/
|
||||
const t_ansi_seq ansi_sequence[] = {
|
||||
{ "\x27[#A", ansi_cuu },
|
||||
{ "\x27[#B", ansi_cuf },
|
||||
{ "\x27[#C", ansi_cub },
|
||||
{ "\x27[#D", ansi_cud },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* ANSI Handler: cursor up
|
||||
*/
|
||||
void ansi_cuu(p_channel chan, short arg_count, short args[]) {
|
||||
unsigned short x, y;
|
||||
short delta = 1;
|
||||
|
||||
TRACE("ansi_cuu");
|
||||
|
||||
if (arg_count > 0) {
|
||||
delta = args[0];
|
||||
}
|
||||
|
||||
if (delta == 0) delta = 1;
|
||||
|
||||
text_get_xy(chan->dev, &x, &y);
|
||||
y -= delta;
|
||||
text_set_xy(chan->dev, x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* ANSI Handler: cursor forward
|
||||
*/
|
||||
void ansi_cuf(p_channel chan, short arg_count, short args[]) {
|
||||
unsigned short x, y;
|
||||
short delta = 1;
|
||||
|
||||
TRACE("ansi_cuf");
|
||||
|
||||
if (arg_count > 0) {
|
||||
delta = args[0];
|
||||
}
|
||||
|
||||
if (delta == 0) delta = 1;
|
||||
|
||||
text_get_xy(chan->dev, &x, &y);
|
||||
x += delta;
|
||||
text_set_xy(chan->dev, x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* ANSI Handler: cursor back
|
||||
*/
|
||||
void ansi_cub(p_channel chan, short arg_count, short args[]) {
|
||||
unsigned short x, y;
|
||||
short delta = 1;
|
||||
|
||||
TRACE("ansi_cub");
|
||||
|
||||
if (arg_count > 0) {
|
||||
delta = args[0];
|
||||
}
|
||||
|
||||
if (delta == 0) delta = 1;
|
||||
|
||||
text_get_xy(chan->dev, &x, &y);
|
||||
x -= delta;
|
||||
text_set_xy(chan->dev, x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* ANSI Handler: cursor down
|
||||
*/
|
||||
void ansi_cud(p_channel chan, short arg_count, short args[]) {
|
||||
unsigned short x, y;
|
||||
short delta = 1;
|
||||
|
||||
TRACE("ansi_cud");
|
||||
|
||||
if (arg_count > 0) {
|
||||
delta = args[0];
|
||||
}
|
||||
|
||||
if (delta == 0) delta = 1;
|
||||
|
||||
text_get_xy(chan->dev, &x, &y);
|
||||
y += delta;
|
||||
text_set_xy(chan->dev, x, y);
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the console... nothing needs to happen here
|
||||
|
@ -21,17 +153,205 @@ short con_init() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Send a uint8_t to the console screen
|
||||
//
|
||||
short con_write_b(p_channel chan, uint8_t b) {
|
||||
text_put_raw(chan->dev, (char)b);
|
||||
/*
|
||||
* Open the consolde device for the given channel
|
||||
*
|
||||
* Inputs:
|
||||
* chan = the channel record for this console device
|
||||
* path = unused
|
||||
* mode = unused
|
||||
*
|
||||
* Returns
|
||||
* 0 on success, negative number on failure
|
||||
*/
|
||||
short con_open(p_channel chan, uint8_t * path, short mode) {
|
||||
int i;
|
||||
p_console_data con_data;
|
||||
|
||||
TRACE("con_open");
|
||||
|
||||
/* Initialize the console data for this channel */
|
||||
|
||||
con_data = &(chan->data);
|
||||
con_data->control = CON_CTRL_ANSI;
|
||||
con_data->ansi_buffer_count = 0;
|
||||
for (i = 0; i < ANSI_BUFFER_SIZE; i++) {
|
||||
con_data->ansi_buffer[i] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to read from the keyboard.
|
||||
//
|
||||
/*
|
||||
* Flush the output to the console...
|
||||
*
|
||||
* Really only does something if the console is set to process ANSI escape codes
|
||||
*
|
||||
*/
|
||||
short con_flush(p_channel chan) {
|
||||
int i;
|
||||
p_console_data con_data;
|
||||
|
||||
con_data = &(chan->data);
|
||||
if (con_data->control & CON_CTRL_ANSI) {
|
||||
for (i = 0; i < con_data->ansi_buffer_count; i++) {
|
||||
text_put_raw(chan->dev, con_data->ansi_buffer[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the console channel... just flush the data
|
||||
*
|
||||
* Inputs:
|
||||
* chan = the channel record for this console device
|
||||
*/
|
||||
short con_close(p_channel chan) {
|
||||
con_flush(chan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if a character is an initial character for an ANSI escape code
|
||||
*
|
||||
* Inputs:
|
||||
* c = the character to test
|
||||
*
|
||||
* Returns:
|
||||
* 0 if the character is not an ANSI initial, 1 if it is
|
||||
*/
|
||||
short ansi_start_code(char c) {
|
||||
switch (c) {
|
||||
case '\x27':
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to match a pattern to what's in the buffer
|
||||
* Calls the sequence's handler if the pattern matches
|
||||
*
|
||||
* Inputs:
|
||||
* chan = pointer to the channel record
|
||||
* con_data = pointer to the console data record for this channel
|
||||
* sequence = pointer to the ANSI sequence mapping to check
|
||||
*
|
||||
* Returns
|
||||
* 0 if not a match, 1 if it is a match
|
||||
*/
|
||||
short ansi_match_pattern(p_channel chan, p_console_data con_data, p_ansi_seq sequence) {
|
||||
short arg_idx = 0;
|
||||
short arg[MAX_ANSI_ARGS];
|
||||
short i, j;
|
||||
char * pattern = sequence->pattern;
|
||||
char * buffer = con_data->ansi_buffer;
|
||||
short buffer_count = con_data->ansi_buffer_count;
|
||||
|
||||
for (i = 0, j = 0; i < strlen(pattern); i++) {
|
||||
if (buffer[j] == pattern[i]) {
|
||||
/* Character matches... advance to the next character in the buffer and pattern */
|
||||
j++;
|
||||
|
||||
} else if (pattern[i] == '#') {
|
||||
/* Parse a number of decimal digits */
|
||||
arg[arg_idx] = 0;
|
||||
while (isdigit(buffer[j]) && (j < buffer_count)) {
|
||||
arg[arg_idx] = arg[arg_idx] * 10 + (buffer[j] - '0');
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j == buffer_count) {
|
||||
/* This pattern does not match */
|
||||
return 0;
|
||||
} else {
|
||||
/* We've read a number */
|
||||
arg_idx++;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == strlen(pattern)) {
|
||||
/* The pattern has been completely matched */
|
||||
|
||||
/* Clear the buffer */
|
||||
for (i = 0; i < buffer_count; i++) {
|
||||
buffer[i] = 0;
|
||||
}
|
||||
con_data->ansi_buffer_count = 0;
|
||||
|
||||
sequence->handler(chan, arg_idx, arg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to match what's in the buffer to known ANSI escape sequences
|
||||
*
|
||||
* Inputs:
|
||||
* chan = pointer to the channel record
|
||||
* con_data = pointer to the console data record for this channel
|
||||
*/
|
||||
void ansi_match_buffer(p_channel chan, p_console_data con_data) {
|
||||
short arg[MAX_ANSI_ARGS];
|
||||
short arg_count = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_ANSI_ARGS; i++) {
|
||||
arg[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; ansi_sequence[i].pattern; i++) {
|
||||
if (ansi_match_pattern(chan, con_data, &ansi_sequence[i])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not currently matching, but the buffer is full, we need to flush */
|
||||
if (con_data->ansi_buffer_count == ANSI_BUFFER_SIZE) {
|
||||
con_flush(chan);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a byte to the console screen
|
||||
*/
|
||||
short con_write_b(p_channel chan, uint8_t b) {
|
||||
p_console_data con_data;
|
||||
|
||||
/* Check to see if we need to process ANSI codes */
|
||||
con_data = &(chan->data);
|
||||
if (con_data->control & CON_CTRL_ANSI) {
|
||||
/* ANSI codes are to be processed */
|
||||
if ((con_data->ansi_buffer_count > 0) || ansi_start_code(b)) {
|
||||
/* We're working on a sequence: add the character to the buffer */
|
||||
con_data->ansi_buffer[con_data->ansi_buffer_count++] = b;
|
||||
|
||||
/* Attempt to match the buffer to an escape sequence */
|
||||
ansi_match_buffer(chan, con_data);
|
||||
|
||||
} else {
|
||||
/* We're not working on a sequence: just print the character */
|
||||
text_put_raw(chan->dev, (char)b);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Not processing ANSI codes... just pass it to the text driver */
|
||||
text_put_raw(chan->dev, (char)b);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to read from the keyboard.
|
||||
*/
|
||||
short con_read_b(p_channel chan) {
|
||||
char c;
|
||||
do {
|
||||
|
@ -128,12 +448,14 @@ short con_readline(p_channel chan, uint8_t * buffer, short size) {
|
|||
short con_write(p_channel chan, const uint8_t * buffer, short size) {
|
||||
int i;
|
||||
|
||||
TRACE("con_write");
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
char c = (char)buffer[i];
|
||||
if (c == 0) {
|
||||
break;
|
||||
} else {
|
||||
text_put_raw(chan->dev, c);
|
||||
con_write_b(chan, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,13 +471,6 @@ short con_status(p_channel chan) {
|
|||
return CDEV_STAT_READABLE | CDEV_STAT_WRITABLE;
|
||||
}
|
||||
|
||||
//
|
||||
// Flush the output to the console... this does nothing...
|
||||
//
|
||||
short con_flush(p_channel chan) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// We can't seek on the console... just return 0
|
||||
//
|
||||
|
@ -171,11 +486,14 @@ short con_ioctrl(p_channel chan, short command, uint8_t * buffer, short size) {
|
|||
// Install the console device driver
|
||||
//
|
||||
short con_install() {
|
||||
short result;
|
||||
t_dev_chan dev;
|
||||
|
||||
dev.name = "CONSOLE";
|
||||
dev.number = CDEV_CONSOLE;
|
||||
dev.init = con_init;
|
||||
dev.open = con_open;
|
||||
dev.close = con_close;
|
||||
dev.read = con_read;
|
||||
dev.readline = con_readline;
|
||||
dev.read_b = con_read_b;
|
||||
|
@ -186,11 +504,16 @@ short con_install() {
|
|||
dev.status = con_status;
|
||||
dev.ioctrl = con_ioctrl;
|
||||
|
||||
cdev_register(&dev);
|
||||
result = cdev_register(&dev);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
dev.name = "EVID";
|
||||
dev.number = CDEV_EVID;
|
||||
dev.init = con_init;
|
||||
dev.open = con_open;
|
||||
dev.close = con_close;
|
||||
dev.read = con_read;
|
||||
dev.readline = con_readline;
|
||||
dev.read_b = con_read_b;
|
||||
|
@ -201,5 +524,15 @@ short con_install() {
|
|||
dev.status = con_status;
|
||||
dev.ioctrl = con_ioctrl;
|
||||
|
||||
return cdev_register(&dev);
|
||||
result = cdev_register(&dev);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Pre-open the console and EVID channels */
|
||||
|
||||
chan_open(CDEV_CONSOLE, 0, 0);
|
||||
// chan_open(CDEV_EVID, 0, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -199,6 +199,21 @@ void text_set_xy(short screen, unsigned short x, unsigned short y) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the position of the cursor on the screen.
|
||||
*
|
||||
* Inputs:
|
||||
* screen = the screen number 0 for channel A, 1 for channel B
|
||||
* x = pointer to the location to store the column (0 is left most)
|
||||
* y = pointer to the location to store the row (0 is right most)
|
||||
*/
|
||||
void text_get_xy(short screen, unsigned short * x, unsigned short * y) {
|
||||
p_text_channel chan = &text_channel[screen];
|
||||
|
||||
*x = chan->x;
|
||||
*y = chan->y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the size information for the text screen based on the current settings in VICKY
|
||||
* These settings are needed to correctly position text on the screen.
|
||||
|
|
|
@ -35,6 +35,16 @@ extern void text_set_cursor(short screen, short color, char character, short rat
|
|||
*/
|
||||
extern void text_set_xy(short screen, unsigned short x, unsigned short y);
|
||||
|
||||
/*
|
||||
* Get the position of the cursor on the screen.
|
||||
*
|
||||
* Inputs:
|
||||
* screen = the screen number 0 for channel A, 1 for channel B
|
||||
* x = pointer to the location to store the column (0 is left most)
|
||||
* y = pointer to the location to store the row (0 is right most)
|
||||
*/
|
||||
extern void text_get_xy(short screen, unsigned short * x, unsigned short * y);
|
||||
|
||||
/*
|
||||
* Compute the size information for the text screen based on the current settings in VICKY
|
||||
* These settings are needed to correctly position text on the screen.
|
||||
|
@ -53,15 +63,6 @@ extern void text_setsizes(short screen);
|
|||
*/
|
||||
extern void text_put_raw(short screen, char c);
|
||||
|
||||
/*
|
||||
* Send a character to the screen... but handle ANSI escape codes and process accordingly.
|
||||
*
|
||||
* Inputs:
|
||||
* screen = the screen number 0 for channel A, 1 for channel B
|
||||
* c = the character to print
|
||||
*/
|
||||
void text_put_ansi(short screen, char c);
|
||||
|
||||
/*
|
||||
* Set the foreground and background color for printing
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue