CLI Multi-screen Code
Added code to support switching between text screens and new layout of CLI screen.
This commit is contained in:
parent
50797494e6
commit
17b4d77c2d
150
src/cli/cli.c
150
src/cli/cli.c
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
|
@ -85,6 +86,12 @@ extern short cmd_screen(short channel, int argc, const char * argv[]);
|
|||
/** The channel to use for interactions */
|
||||
short g_current_channel = 0;
|
||||
|
||||
/** Flag to indicate that the current working directory has changed */
|
||||
short g_cwd_changed = 0;
|
||||
|
||||
/** The number of text screens on this machine */
|
||||
short g_num_screens = 0;
|
||||
|
||||
/** The history of previous commands issued */
|
||||
char cli_history[MAX_HISTORY_DEPTH][MAX_COMMAND_SIZE];
|
||||
|
||||
|
@ -672,6 +679,86 @@ short cli_process_line(short channel, const char * command_line) {
|
|||
}
|
||||
}
|
||||
|
||||
void cli_draw_window(short channel, const char * status, short is_active) {
|
||||
const char * title_header = "Foenix/MCP - ";
|
||||
unsigned char foreground, background;
|
||||
char buffer[128];
|
||||
t_point cursor;
|
||||
t_rect region, old_region, full_region;
|
||||
short i = 0, j;
|
||||
|
||||
// Save the current region and cursor location
|
||||
sys_txt_get_xy(channel, &cursor);
|
||||
sys_txt_get_region(channel, &old_region);
|
||||
sys_txt_get_color(channel, &foreground, &background);
|
||||
|
||||
// Return to the full region and get its dimensions
|
||||
region.origin.x = 0;
|
||||
region.origin.y = 0;
|
||||
region.size.width = 0;
|
||||
region.size.height = 0;
|
||||
sys_txt_set_region(channel, ®ion);
|
||||
sys_txt_get_region(channel, &full_region);
|
||||
|
||||
// Display the titlebar
|
||||
i = 0;
|
||||
sys_txt_set_xy(channel, 0, 0);
|
||||
if (is_active) {
|
||||
sys_txt_set_color(channel, background, foreground);
|
||||
}
|
||||
for (j = 0; j < strlen(title_header); j++) {
|
||||
buffer[i++] = title_header[j];
|
||||
}
|
||||
for (j = 0; j < strlen(status); j++) {
|
||||
buffer[i++] = status[j];
|
||||
}
|
||||
while (i < full_region.size.width) {
|
||||
if (is_active) {
|
||||
buffer[i++] = ' ';
|
||||
} else {
|
||||
buffer[i++] = 0xB0;
|
||||
}
|
||||
}
|
||||
buffer[i++] = 0;
|
||||
print(channel, buffer);
|
||||
|
||||
// Restore the region and cursor location
|
||||
sys_txt_set_color(channel, foreground, background);
|
||||
sys_txt_set_region(channel, &old_region);
|
||||
sys_txt_set_xy(channel, cursor.x, cursor.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the text screen (set up regions, windows, etc.)
|
||||
*/
|
||||
void cli_setup_screen(short channel, const char * path, short is_active) {
|
||||
t_rect full_region, command_region;
|
||||
|
||||
// Get the size of the screen
|
||||
full_region.origin.x = 0;
|
||||
full_region.origin.y = 0;
|
||||
full_region.size.width = 0;
|
||||
full_region.size.height = 0;
|
||||
sys_txt_set_region(channel, &full_region);
|
||||
sys_txt_get_region(channel, &full_region);
|
||||
|
||||
// Clear the screen
|
||||
print(channel, "\x1b[2J\x1b[H");
|
||||
|
||||
// Figure out the size of the command box and its region
|
||||
command_region.origin.x = 0;
|
||||
command_region.origin.y = 1;
|
||||
command_region.size.width = full_region.size.width;
|
||||
command_region.size.height = full_region.size.height - 1;
|
||||
|
||||
// Restrict the region to the command panel
|
||||
sys_txt_set_region(channel, &command_region);
|
||||
|
||||
// Draw the window
|
||||
cli_draw_window(channel, path, is_active);
|
||||
print(channel, "\x1b[2J\x1b[1;2H");
|
||||
}
|
||||
|
||||
//
|
||||
// Enter the CLI's read-eval-print loop
|
||||
//
|
||||
|
@ -680,7 +767,10 @@ short cli_repl(short channel, const char * init_cwd) {
|
|||
char cwd_buffer[MAX_PATH_LEN];
|
||||
short result = 0;
|
||||
short i = 0;
|
||||
t_point cursor;
|
||||
short old_channel;
|
||||
|
||||
old_channel = channel;
|
||||
g_current_channel = channel;
|
||||
|
||||
if (init_cwd != 0) {
|
||||
|
@ -692,14 +782,41 @@ short cli_repl(short channel, const char * init_cwd) {
|
|||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
sys_chan_write(g_current_channel, "\n", 1);
|
||||
// TODO: write the current directory to the status line
|
||||
// if(sys_fsys_get_cwd(cwd_buffer, MAX_PATH_LEN) == 0) {
|
||||
// sys_chan_write(channel, cwd_buffer, strlen(cwd_buffer));
|
||||
// }
|
||||
sys_chan_write(g_current_channel, "\x10 ", 2); // Print our prompt
|
||||
// Set up the screen(s)
|
||||
cli_setup_screen(channel, init_cwd, 1); // Initialize our main main screen
|
||||
if (g_num_screens > 1) {
|
||||
for (i = 0; i < g_num_screens; i++) { // Set up each screen we aren't using
|
||||
if (i != channel) {
|
||||
cli_setup_screen(i, init_cwd, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_cwd_changed = 1;
|
||||
cursor.x = 0;
|
||||
cursor.y = 0;
|
||||
|
||||
while (1) {
|
||||
// Refresh window if the current working directory has changed
|
||||
if (g_cwd_changed || (old_channel != g_current_channel)) {
|
||||
g_cwd_changed = 0;
|
||||
|
||||
// Get and display the new working directory
|
||||
if (sys_fsys_get_cwd(cwd_buffer, MAX_PATH_LEN) == 0) {
|
||||
// char message[80];
|
||||
// sprintf(message, "%d", strlen(cwd_buffer));
|
||||
print(0, "");
|
||||
if (old_channel != g_current_channel) {
|
||||
|
||||
// If channel has changed, deactivate old channel
|
||||
cli_draw_window(old_channel, cwd_buffer, 0);
|
||||
old_channel = g_current_channel;
|
||||
}
|
||||
cli_draw_window(g_current_channel, cwd_buffer, 1);
|
||||
}
|
||||
}
|
||||
|
||||
sys_chan_write(g_current_channel, "\x10 ", 2); // Print our prompt
|
||||
result = cli_readline(g_current_channel, command_line);
|
||||
switch (result) {
|
||||
case -1:
|
||||
|
@ -720,11 +837,12 @@ short cli_repl(short channel, const char * init_cwd) {
|
|||
strcpy(cli_history[0], command_line);
|
||||
break;
|
||||
}
|
||||
// sys_chan_readline(channel, command_line, MAX_COMMAND_SIZE); // Attempt to read line
|
||||
|
||||
sys_chan_write(g_current_channel, "\n", 1);
|
||||
|
||||
print(g_current_channel, "\n");
|
||||
cli_process_line(g_current_channel, command_line);
|
||||
|
||||
print(g_current_channel, "\n");
|
||||
sys_txt_get_xy(channel, &cursor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -865,6 +983,13 @@ long cli_eval_number(const char * arg) {
|
|||
return cli_eval_dec(arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the current working directory has changed
|
||||
*/
|
||||
void cli_flag_cwd() {
|
||||
g_cwd_changed = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the CLI
|
||||
//
|
||||
|
@ -872,6 +997,7 @@ long cli_eval_number(const char * arg) {
|
|||
// 0 on success, negative number on error
|
||||
//
|
||||
short cli_init() {
|
||||
t_sys_info info;
|
||||
short i;
|
||||
|
||||
// Clear out the command history
|
||||
|
@ -879,6 +1005,10 @@ short cli_init() {
|
|||
cli_history[i][0] = 0;
|
||||
}
|
||||
|
||||
// Figure out how many screens we have
|
||||
sys_get_info(&info);
|
||||
g_num_screens = info.screens;
|
||||
|
||||
cli_set_init();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -68,4 +68,9 @@ extern void cli_channel_set(short channel);
|
|||
*/
|
||||
extern short cli_channel_get();
|
||||
|
||||
/**
|
||||
* Indicate that the current working directory has changed
|
||||
*/
|
||||
extern void cli_flag_cwd();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -239,6 +239,7 @@ short cmd_cd(short screen, int argc, const char * argv[]) {
|
|||
err_print(screen, "Unable to change directory", result);
|
||||
return result;
|
||||
} else {
|
||||
cli_flag_cwd();
|
||||
print(screen, "Changed to: ");
|
||||
print(screen, argv[1]);
|
||||
print(screen, "\n");
|
||||
|
|
|
@ -274,8 +274,8 @@ void txt_a2560k_b_set_cursor(short enable, short rate, char c) {
|
|||
*
|
||||
* @return 0 on success, any other number means the region was invalid
|
||||
*/
|
||||
short txt_a2560k_b_set_region(p_rect region) {
|
||||
if ((region == 0) || (region->size.width == 0) || (region->size.height == 0)) {
|
||||
short txt_a2560k_b_set_region(p_rect region) {
|
||||
if ((region->size.width == 0) || (region->size.height == 0)) {
|
||||
/* Set the region to the default (full screen) */
|
||||
a2560k_b_region.origin.x = 0;
|
||||
a2560k_b_region.origin.y = 0;
|
||||
|
@ -289,6 +289,22 @@ short txt_a2560k_b_set_region(p_rect region) {
|
|||
a2560k_b_region.size.height = region->size.height;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the current region
|
||||
*
|
||||
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
|
||||
*
|
||||
* @return 0 on success, any other number means the region was invalid
|
||||
*/
|
||||
short txt_a2560k_b_get_region(p_rect region) {
|
||||
region->origin.x = a2560k_b_region.origin.x;
|
||||
region->origin.y = a2560k_b_region.origin.y;
|
||||
region->size.width = a2560k_b_region.size.width;
|
||||
region->size.height = a2560k_b_region.size.height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -303,6 +319,18 @@ short txt_a2560k_b_set_color(unsigned char foreground, unsigned char background)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default foreground and background colors for printing
|
||||
*
|
||||
* @param pointer to the foreground the Text LUT index of the new current foreground color (0 - 15)
|
||||
* @param pointer to the background the Text LUT index of the new current background color (0 - 15)
|
||||
*/
|
||||
short txt_a2560k_b_get_color(unsigned char * foreground, unsigned char * background) {
|
||||
*foreground = (a2560k_b_color & 0xf0) >> 4;
|
||||
*background = a2560k_b_color & 0x0f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scroll the text in the current region
|
||||
|
@ -595,7 +623,9 @@ short txt_a2560k_b_install() {
|
|||
device.set_font = txt_a2560k_b_set_font;
|
||||
device.set_cursor = txt_a2560k_b_set_cursor;
|
||||
device.set_region = txt_a2560k_b_set_region;
|
||||
device.get_region = txt_a2560k_b_get_region
|
||||
device.set_color = txt_a2560k_b_set_color;
|
||||
device.get_color = txt_a2560k_b_get_color;
|
||||
device.set_xy = txt_a2560k_b_set_xy;
|
||||
device.get_xy = txt_a2560k_b_get_xy;
|
||||
device.put = txt_a2560k_b_put;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* Uniform routines to manage the text screens
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifndef __TXT_SCREEN_H
|
||||
#define __TXT_SCREEN_H
|
||||
|
||||
|
@ -15,36 +17,6 @@
|
|||
#define TXT_MODE_TILE 0x0008 /**< The bit to enable tile graphics mode */
|
||||
#define TXT_MODE_SLEEP 0x0010 /**< The bit to put the monitor to sleep by disabling sync */
|
||||
|
||||
/**
|
||||
* @struct s_extent
|
||||
*
|
||||
* An extent or size of a rectangular area
|
||||
*/
|
||||
typedef struct s_extent {
|
||||
short width; /**< The width of the region */
|
||||
short height; /**< The height of the region */
|
||||
} t_extent, *p_extent;
|
||||
|
||||
/**
|
||||
* @struct s_point
|
||||
*
|
||||
* A point on a plane
|
||||
*/
|
||||
typedef struct s_point {
|
||||
short x; /**< The column of the point */
|
||||
short y; /**< The row of the point */
|
||||
} t_point, *p_point;
|
||||
|
||||
/**
|
||||
* @struct s_rect
|
||||
*
|
||||
* A rectangle on the screen
|
||||
*/
|
||||
typedef struct s_rect {
|
||||
t_point origin; /**< The upper-left corner of the rectangle */
|
||||
t_extent size; /**< The size of the rectangle */
|
||||
} t_rect, *p_rect;
|
||||
|
||||
/**
|
||||
* @struct s_txt_capabilities
|
||||
*
|
||||
|
|
7981
src/foenixmcp.s68
7981
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
|
@ -716,4 +716,68 @@ extern short sys_kbd_layout(const char * tables);
|
|||
*/
|
||||
extern short sys_proc_run(const char * path, int argc, char * argv[]);
|
||||
|
||||
//
|
||||
// Text screen calls
|
||||
//
|
||||
|
||||
/**
|
||||
* Set the position of the cursor to (x, y) relative to the current region
|
||||
* If the (x, y) coordinate is outside the region, it will be clipped to the region.
|
||||
* If y is greater than the height of the region, the region will scroll until that relative
|
||||
* position would be within view.
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param x the column for the cursor
|
||||
* @param y the row for the cursor
|
||||
*/
|
||||
extern void sys_txt_set_xy(short screen, short x, short y);
|
||||
|
||||
/**
|
||||
* Get the position of the cursor (x, y) relative to the current region
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param position pointer to a t_point record to fill out
|
||||
*/
|
||||
extern void sys_txt_get_xy(short screen, p_point position);
|
||||
|
||||
/**
|
||||
* Get the current region.
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
|
||||
*
|
||||
* @return 0 on success, any other number means the region was invalid
|
||||
*/
|
||||
extern short sys_txt_get_region(short screen, p_rect region);
|
||||
|
||||
/**
|
||||
* Set a region to restrict further character display, scrolling, etc.
|
||||
* Note that a region of zero size will reset the region to the full size of the screen.
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
|
||||
*
|
||||
* @return 0 on success, any other number means the region was invalid
|
||||
*/
|
||||
extern short sys_txt_set_region(short screen, p_rect region);
|
||||
|
||||
/**
|
||||
* Set the default foreground and background colors for printing
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param foreground the Text LUT index of the new current foreground color (0 - 15)
|
||||
* @param background the Text LUT index of the new current background color (0 - 15)
|
||||
*/
|
||||
extern void sys_txt_set_color(short screen, unsigned char foreground, unsigned char background);
|
||||
|
||||
/*
|
||||
* Get the foreground and background color for printing
|
||||
*
|
||||
* Inputs:
|
||||
* screen = the screen number 0 for channel A, 1 for channel B
|
||||
* foreground = pointer to the foreground color number
|
||||
* background = pointer to the background color number
|
||||
*/
|
||||
extern void sys_txt_get_color(short screen, unsigned char * foreground, unsigned char * background);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,14 +8,35 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
* Function types
|
||||
/**
|
||||
* @struct s_extent
|
||||
*
|
||||
* An extent or size of a rectangular area
|
||||
*/
|
||||
typedef struct s_extent {
|
||||
short width; /**< The width of the region */
|
||||
short height; /**< The height of the region */
|
||||
} t_extent, *p_extent;
|
||||
|
||||
/*
|
||||
* Integer types in their standard sizes, signed and unsigned.
|
||||
/**
|
||||
* @struct s_point
|
||||
*
|
||||
* A point on a plane
|
||||
*/
|
||||
typedef struct s_point {
|
||||
short x; /**< The column of the point */
|
||||
short y; /**< The row of the point */
|
||||
} t_point, *p_point;
|
||||
|
||||
/**
|
||||
* @struct s_rect
|
||||
*
|
||||
* A rectangle on the screen
|
||||
*/
|
||||
typedef struct s_rect {
|
||||
t_point origin; /**< The upper-left corner of the rectangle */
|
||||
t_extent size; /**< The size of the rectangle */
|
||||
} t_rect, *p_rect;
|
||||
|
||||
//
|
||||
// A color (BGR)
|
||||
|
|
17256
src/mapfile
17256
src/mapfile
File diff suppressed because it is too large
Load diff
|
@ -694,3 +694,79 @@ short sys_kbd_layout(const char * tables) {
|
|||
short sys_proc_run(const char * path, int argc, char * argv[]) {
|
||||
return syscall(KFN_RUN, path, argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// Text system calls
|
||||
//
|
||||
|
||||
/**
|
||||
* Set the position of the cursor to (x, y) relative to the current region
|
||||
* If the (x, y) coordinate is outside the region, it will be clipped to the region.
|
||||
* If y is greater than the height of the region, the region will scroll until that relative
|
||||
* position would be within view.
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param x the column for the cursor
|
||||
* @param y the row for the cursor
|
||||
*/
|
||||
void sys_txt_set_xy(short screen, short x, short y) {
|
||||
syscall(KFN_TXT_SET_XY, screen, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position of the cursor (x, y) relative to the current region
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param position pointer to a t_point record to fill out
|
||||
*/
|
||||
void sys_txt_get_xy(short screen, p_point position) {
|
||||
syscall(KFN_TXT_GET_XY, screen, position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current region.
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
|
||||
*
|
||||
* @return 0 on success, any other number means the region was invalid
|
||||
*/
|
||||
short sys_txt_get_region(short screen, p_rect region) {
|
||||
syscall(KFN_TXT_GET_REGION, screen, region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a region to restrict further character display, scrolling, etc.
|
||||
* Note that a region of zero size will reset the region to the full size of the screen.
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
|
||||
*
|
||||
* @return 0 on success, any other number means the region was invalid
|
||||
*/
|
||||
short sys_txt_set_region(short screen, p_rect region) {
|
||||
syscall(KFN_TXT_SET_REGION, screen, region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default foreground and background colors for printing
|
||||
*
|
||||
* @param screen the number of the text device
|
||||
* @param foreground the Text LUT index of the new current foreground color (0 - 15)
|
||||
* @param background the Text LUT index of the new current background color (0 - 15)
|
||||
*/
|
||||
short sys_txt_set_color(short screen, unsigned char foreground, unsigned char background) {
|
||||
return syscall(KFN_TXT_SET_COLOR, screen, foreground, background);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the foreground and background color for printing
|
||||
*
|
||||
* Inputs:
|
||||
* screen = the screen number 0 for channel A, 1 for channel B
|
||||
* foreground = pointer to the foreground color number
|
||||
* background = pointer to the background color number
|
||||
*/
|
||||
void sys_txt_get_color(short screen, unsigned char * foreground, unsigned char * background) {
|
||||
syscall(KFN_TXT_GET_COLOR, screen, foreground, background);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue