Added the drawtitle function to console
Added ability to pick a bg preset for the title bar Added counting program Added function to set the current consoles title name Removed some of the debug code
This commit is contained in:
5
Makefile
5
Makefile
@ -201,6 +201,7 @@ UPROGS=\
|
||||
_screen\
|
||||
_cls\
|
||||
_maze\
|
||||
_count\
|
||||
|
||||
fs.img: mkfs $(UPROGS)
|
||||
./mkfs fs.img $(UPROGS)
|
||||
@ -224,8 +225,8 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
|
||||
then echo "-gdb tcp::$(GDBPORT)"; \
|
||||
else echo "-s -p $(GDBPORT)"; fi)
|
||||
ifndef CPUS
|
||||
#CPUS := 2
|
||||
CPUS := 1 # For debugging
|
||||
CPUS := 2
|
||||
#CPUS := 1 # For debugging
|
||||
endif
|
||||
QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA)
|
||||
|
||||
|
219
console.c
219
console.c
@ -39,11 +39,13 @@ struct vconsole
|
||||
int pos;
|
||||
int active;
|
||||
int inuse;
|
||||
uint titlebgcol;
|
||||
char proctitle[20];
|
||||
char status[30];
|
||||
};
|
||||
|
||||
struct vconsole consoles[MAXVCONSOLES];
|
||||
struct vconsole *currentconsole = 0;
|
||||
//static uint currentconsoleindex = 0;
|
||||
|
||||
#define C(x) ((x) - '@') // Control-x
|
||||
|
||||
@ -62,10 +64,13 @@ static struct
|
||||
int locking;
|
||||
} cons;
|
||||
|
||||
static void printint(int xx, int base, int sign)
|
||||
// Split the printint so we can just get the char out in draw title
|
||||
// itoa is the function in the c standard library (?) so i reused the name
|
||||
// since it does something similar
|
||||
// Saves to the provided char array and returns the number of characters for looping
|
||||
static int itoa(int xx, int base, int sign, char* buf)
|
||||
{
|
||||
static char digits[] = "0123456789abcdef";
|
||||
char buf[16];
|
||||
static char digits[] = "0123456789abcdef";
|
||||
int i;
|
||||
uint x;
|
||||
|
||||
@ -89,6 +94,15 @@ static void printint(int xx, int base, int sign)
|
||||
buf[i++] = '-';
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void printint(int xx, int base, int sign)
|
||||
{
|
||||
int i = 0;
|
||||
char buf[16];
|
||||
i = itoa(xx, base, sign, buf);
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
consputc(buf[i]);
|
||||
@ -162,6 +176,88 @@ void cprintf(char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
void sprintf(char* strbuffer, char *fmt, ...)
|
||||
{
|
||||
int i, c, si;
|
||||
uint *argp;
|
||||
char *s;
|
||||
|
||||
char buf[16];
|
||||
int x;
|
||||
|
||||
if (fmt == 0)
|
||||
{
|
||||
panic("null fmt");
|
||||
}
|
||||
|
||||
si = 0;
|
||||
argp = (uint *)(void *)(&fmt + 1);
|
||||
for (i = 0; (c = fmt[i] & 0xff) != 0; i++)
|
||||
{
|
||||
if (c != '%')
|
||||
{
|
||||
strbuffer[si] = c;
|
||||
si++;
|
||||
continue;
|
||||
}
|
||||
c = fmt[++i] & 0xff;
|
||||
if (c == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
// Clear any existing buf data
|
||||
memset(buf, 0, sizeof buf);
|
||||
x = itoa(*argp++, 10, 1, buf);
|
||||
|
||||
while (--x >= 0)
|
||||
{
|
||||
strbuffer[si] = buf[x];
|
||||
si++;
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
case 'p':
|
||||
// Clear any existing buf data
|
||||
memset(buf, 0, sizeof buf);
|
||||
x = itoa(*argp++, 16, 0, buf);
|
||||
|
||||
while (--x >= 0)
|
||||
{
|
||||
strbuffer[si] = buf[x];
|
||||
si++;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if ((s = (char *)*argp++) == 0)
|
||||
{
|
||||
s = "(null)";
|
||||
}
|
||||
for (; *s; s++)
|
||||
{
|
||||
strbuffer[si] = *s;
|
||||
si++;
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
strbuffer[i] = '%';
|
||||
si++;
|
||||
break;
|
||||
default:
|
||||
// Print unknown % sequence to draw attention.
|
||||
strbuffer[si] = '%';
|
||||
si++;
|
||||
strbuffer[si] = c;
|
||||
si++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add string terminator to the end
|
||||
strbuffer[si] = '\0';
|
||||
}
|
||||
|
||||
void panic(char *s)
|
||||
{
|
||||
int i;
|
||||
@ -218,12 +314,66 @@ struct vconsole* getvalidprocessconsoleptr(void)
|
||||
return inconsoleptr;
|
||||
}
|
||||
|
||||
void setconsoleproctitle(struct vconsole* consoleptr, char* newtitle)
|
||||
{
|
||||
acquire(&consoleptr->lock);
|
||||
//Clear the current buffer
|
||||
memset(consoleptr->proctitle, 0, sizeof(consoleptr->proctitle));
|
||||
//Copy the new title into the console title buffer
|
||||
safestrcpy(consoleptr->proctitle, newtitle, sizeof(consoleptr->proctitle));
|
||||
//Redraw the title since its been updated now
|
||||
drawtitle();
|
||||
release(&consoleptr->lock);
|
||||
}
|
||||
|
||||
#define BACKSPACE 0x100
|
||||
#define CRTPORT 0x3d4
|
||||
#define TITLEOFF (SCRWIDTH * 1) // Size of the offset we need for the title bar
|
||||
|
||||
static ushort *crt = (ushort *)P2V(0xb8000); // CGA memory
|
||||
|
||||
void drawtitle(void)
|
||||
{
|
||||
struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
|
||||
|
||||
if (inconsoleptr->inuse)
|
||||
{
|
||||
int pos = 0;
|
||||
char c = ' ';
|
||||
char menutext[] = "(M)enu";
|
||||
char consoletitletext[10]; // + (inconsoleptr->consoleindex + 1);
|
||||
sprintf(consoletitletext, "Console %d", inconsoleptr->consoleindex + 1);
|
||||
|
||||
for (pos = 0; pos < SCRWIDTH; pos++)
|
||||
{
|
||||
int offset = 0;
|
||||
if (pos < 6) {
|
||||
c = menutext[pos - offset];
|
||||
}
|
||||
else if (pos >= 10 && pos < 20)
|
||||
{
|
||||
offset = 10;
|
||||
c = consoletitletext[pos - offset];
|
||||
}
|
||||
else if (pos >= 25 && pos < 45)
|
||||
{
|
||||
offset = 25;
|
||||
c = inconsoleptr->proctitle[pos - offset];
|
||||
}
|
||||
else if (pos >= 50 && pos < 80)
|
||||
{
|
||||
offset = 50;
|
||||
c = inconsoleptr->status[pos - offset];
|
||||
}
|
||||
else
|
||||
{
|
||||
c = ' ';
|
||||
}
|
||||
crt[pos] = (c & 0xff) | inconsoleptr->titlebgcol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cgaputc(int c)
|
||||
{
|
||||
int pos;
|
||||
@ -397,7 +547,7 @@ void consoleintr(int (*getc)(void))
|
||||
{
|
||||
if (currentconsole->consoleindex != 0)
|
||||
{
|
||||
switchtoconsole(0);
|
||||
switchtoconsole(getbaseconsoleptr());
|
||||
}
|
||||
}
|
||||
if (doconsoleswitch)
|
||||
@ -473,15 +623,17 @@ int consoleread(struct inode *ip, char *dst, int n)
|
||||
int consolewrite(struct inode *ip, char *buf, int n)
|
||||
{
|
||||
int i;
|
||||
//struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
|
||||
struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
|
||||
|
||||
iunlock(ip);
|
||||
acquire(&cons.lock);
|
||||
//acquire(&cons.lock);
|
||||
acquire(&inconsoleptr->lock);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
consputc(buf[i] & 0xff);
|
||||
}
|
||||
release(&cons.lock);
|
||||
//release(&cons.lock);
|
||||
release(&inconsoleptr->lock);
|
||||
ilock(ip);
|
||||
|
||||
return n;
|
||||
@ -514,7 +666,7 @@ struct vconsole* getbaseconsoleptr(void)
|
||||
void clearconsole(ushort *bufferin)
|
||||
{
|
||||
// Flood the screen buffer with blank spaces
|
||||
memset(bufferin, 0, sizeof(bufferin[0]) * SCRHEIGHT * SCRWIDTH);
|
||||
memset(bufferin, 0, sizeof(bufferin[0]) * SCRHEIGHT * SCRWIDTH);
|
||||
}
|
||||
|
||||
void loadscreenbuffer(ushort *bufferin)
|
||||
@ -530,26 +682,19 @@ void savescreenbuffer(ushort *bufferin)
|
||||
}
|
||||
|
||||
void clearscreen(void)
|
||||
{
|
||||
// cprintf("process id: %d", myproc()->consoleIndex);
|
||||
// return;
|
||||
// cprintf("size of buffer item: %d\n", sizeof(consoles[currentconsoleindex].screenbuffer[0]) * (SCRHEIGHT * SCRWIDTH));
|
||||
// cprintf("size of crt item: %d\n", sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH));
|
||||
// return;
|
||||
|
||||
{
|
||||
// Check if a process has actually been created otherwise use the base console
|
||||
struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
|
||||
|
||||
acquire(&cons.lock);
|
||||
int pos = TITLEOFF;
|
||||
clearconsole(inconsoleptr->screenbuffer);
|
||||
clearconsole(inconsoleptr->screenbuffer);
|
||||
inconsoleptr->pos = pos;
|
||||
release(&cons.lock);
|
||||
|
||||
|
||||
if (inconsoleptr->inuse)
|
||||
{
|
||||
acquire(&cons.lock);
|
||||
loadscreenbuffer(inconsoleptr->screenbuffer);
|
||||
{
|
||||
loadscreenbuffer(inconsoleptr->screenbuffer);
|
||||
drawtitle();
|
||||
release(&cons.lock);
|
||||
|
||||
outb(CRTPORT, 14);
|
||||
@ -557,6 +702,10 @@ void clearscreen(void)
|
||||
outb(CRTPORT, 15);
|
||||
outb(CRTPORT + 1, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
release(&cons.lock);
|
||||
}
|
||||
}
|
||||
|
||||
void consoleinit(void)
|
||||
@ -570,7 +719,8 @@ void consoleinit(void)
|
||||
consoles[i].pos = 0;
|
||||
consoles[i].active = 0;
|
||||
consoles[i].inuse = 0;
|
||||
|
||||
consoles[i].titlebgcol = 0x4F00;
|
||||
|
||||
//initlock(&consoles[i].lock, "vconsole" + i);
|
||||
}
|
||||
|
||||
@ -590,7 +740,7 @@ void consoleinit(void)
|
||||
ioapicenable(IRQ_KBD, 0);
|
||||
}
|
||||
|
||||
struct vconsole* newconsole(void)
|
||||
struct vconsole* newconsole(int bgpreset)
|
||||
{
|
||||
struct vconsole* result = 0;
|
||||
|
||||
@ -600,6 +750,7 @@ struct vconsole* newconsole(void)
|
||||
if (!consoles[i].active)
|
||||
{
|
||||
consoles[i].processowner = myproc();
|
||||
consoles[i].titlebgcol = bgpreset;
|
||||
result = &consoles[i];
|
||||
break;
|
||||
}
|
||||
@ -621,17 +772,7 @@ int switchtoconsole(struct vconsole* consoleptr)
|
||||
{
|
||||
int pos;
|
||||
|
||||
/*outb(CRTPORT, 14);
|
||||
pos = inb(CRTPORT + 1) << 8;
|
||||
outb(CRTPORT, 15);
|
||||
pos |= inb(CRTPORT + 1);*/
|
||||
|
||||
// consoles[currentconsoleindex].pos = pos;
|
||||
|
||||
// savescreenbuffer(consoles[currentconsoleindex].screenbuffer);
|
||||
|
||||
// acquire(¤tconsole->lock);
|
||||
// sleep(&(currentconsole), ¤tconsole->lock);
|
||||
acquire(&consoleptr->lock);
|
||||
acquire(&cons.lock);
|
||||
releaseallconsoles();
|
||||
currentconsole = consoleptr;
|
||||
@ -640,16 +781,18 @@ int switchtoconsole(struct vconsole* consoleptr)
|
||||
// ioapicenable(IRQ_KBD, 0);
|
||||
|
||||
loadscreenbuffer(currentconsole->screenbuffer);
|
||||
drawtitle();
|
||||
release(&cons.lock);
|
||||
|
||||
if (!currentconsole->active)
|
||||
{
|
||||
clearscreen();
|
||||
drawtitle();
|
||||
cprintf("Welcome to Console: %d\n", currentconsole->consoleindex);
|
||||
currentconsole->active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
pos = currentconsole->pos;
|
||||
|
||||
outb(CRTPORT, 14);
|
||||
@ -658,7 +801,7 @@ int switchtoconsole(struct vconsole* consoleptr)
|
||||
outb(CRTPORT + 1, pos);
|
||||
}
|
||||
|
||||
// wakeup(myproc()->chan);
|
||||
release(&consoleptr->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -666,7 +809,7 @@ int closeconsole(void)
|
||||
{
|
||||
struct vconsole* consoleptr = myproc()->consoleptr;
|
||||
|
||||
cprintf("Console Owner PID: %d\n", consoleptr->processowner->pid);
|
||||
//cprintf("Console Owner PID: %d\n", consoleptr->processowner->pid);
|
||||
|
||||
if (myproc() == consoleptr->processowner)
|
||||
{
|
||||
|
22
count.c
Normal file
22
count.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include "types.h"
|
||||
#include "user.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int countto = 1000;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-c") == 0) {
|
||||
countto = atoi(argv[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
cls();
|
||||
printf(1, "Start Count\n");
|
||||
for (int i = 0; i < countto; i++)
|
||||
{
|
||||
printf(1, "%d\n", i);
|
||||
sleep(10);
|
||||
}
|
||||
printf(1, "Count Ended\n");
|
||||
exit();
|
||||
}
|
13
defs.h
13
defs.h
@ -22,12 +22,23 @@ void cprintf(char*, ...);
|
||||
void consoleintr(int (*)(void));
|
||||
int consoleget(void);
|
||||
void panic(char*) __attribute__((noreturn));
|
||||
struct vconsole* newconsole(void);
|
||||
|
||||
// Function to return a new console ptr for a process to use
|
||||
struct vconsole* newconsole(int);
|
||||
// Function to swithc to the provided console using the ptr
|
||||
int switchtoconsole(struct vconsole*);
|
||||
// Function to close and reset the current proc console
|
||||
int closeconsole(void);
|
||||
// Function to get the current inuse console index
|
||||
int getcurrentconsoleindex(void);
|
||||
// Function to clear the current screen buffer
|
||||
void clearscreen(void);
|
||||
// Function to get the base consoles ptr
|
||||
struct vconsole* getbaseconsoleptr(void);
|
||||
// Function to provide cprintf functionality but saved into a char array
|
||||
void sprintf(char*, char*, ...);
|
||||
void setconsoleproctitle(struct vconsole* consoleptr, char* newtitle);
|
||||
void drawtitle();
|
||||
|
||||
// exec.c
|
||||
int exec(char*, char**);
|
||||
|
5
exec.c
5
exec.c
@ -130,6 +130,11 @@ int exec(char *path, char **argv) {
|
||||
}
|
||||
safestrcpy(curproc->name, last, sizeof(curproc->name));
|
||||
|
||||
if (curproc->consoleptr != 0)
|
||||
{
|
||||
setconsoleproctitle(curproc->consoleptr, curproc->name);
|
||||
}
|
||||
|
||||
// Commit to the user image.
|
||||
oldpgdir = curproc->pgdir;
|
||||
curproc->pgdir = pgdir;
|
||||
|
1
maze.c
1
maze.c
@ -62,5 +62,6 @@ int main(int argc, char *argv[]) {
|
||||
printf(1, "\n");
|
||||
sleep(10);
|
||||
}
|
||||
printf(1, "Maze Ended\n");
|
||||
exit();
|
||||
}
|
5
proc.c
5
proc.c
@ -272,6 +272,11 @@ void exit(void) {
|
||||
closeconsole();
|
||||
}
|
||||
|
||||
if (curproc->consoleptr != 0)
|
||||
{
|
||||
setconsoleproctitle(curproc->consoleptr, curproc->parent->name);
|
||||
}
|
||||
|
||||
// Jump into the scheduler, never to return.
|
||||
curproc->state = ZOMBIE;
|
||||
sched();
|
||||
|
51
screen.c
51
screen.c
@ -1,14 +1,53 @@
|
||||
#include "types.h"
|
||||
#include "user.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
//int consoles = 0;
|
||||
int main(int argc, char *argv[]) {
|
||||
int pid;
|
||||
//char* comment = "";
|
||||
int bgcol = 0x4F00;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-c") == 0) {
|
||||
|
||||
if (strcmp(argv[i], "-bg") == 0)
|
||||
{
|
||||
int selopt = atoi(argv[i + 1]);
|
||||
switch(selopt)
|
||||
{
|
||||
case 1:
|
||||
bgcol = 0x1F00;
|
||||
break;
|
||||
case 2:
|
||||
bgcol = 0x2F00;
|
||||
break;
|
||||
case 3:
|
||||
bgcol = 0x3F00;
|
||||
break;
|
||||
case 4:
|
||||
bgcol = 0x5F00;
|
||||
break;
|
||||
case 5:
|
||||
bgcol = 0xF000;
|
||||
break;
|
||||
case 6:
|
||||
bgcol = 0x8F00;
|
||||
break;
|
||||
case 7:
|
||||
bgcol = 0x9F00;
|
||||
break;
|
||||
case 8:
|
||||
bgcol = 0xAF00;
|
||||
break;
|
||||
case 9:
|
||||
bgcol = 0xCF00;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[i], "-help") == 0)
|
||||
{
|
||||
printf(1, "Creates a new virtual console.\n");
|
||||
printf(1, "Options:\n");
|
||||
printf(1, "-bg [0 - 9] : Sets a background preset for the title bar.");
|
||||
exit();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +56,7 @@ int main(int argc, char *argv[]) {
|
||||
printf(1, "screen: fork failed\n");
|
||||
}
|
||||
if (pid == 0) {
|
||||
if (screen() != 0)
|
||||
if (screen(bgcol) != 0)
|
||||
{
|
||||
exec("sh", argv);
|
||||
printf(1, "screen: exec sh failed\n");
|
||||
|
3
sh.c
3
sh.c
@ -146,8 +146,7 @@ int getcmd(char *buf, int nbuf) {
|
||||
int main(void) {
|
||||
static char buf[100];
|
||||
int fd;
|
||||
|
||||
printf(1, "SH PID: %d\n", getpid());
|
||||
|
||||
// Ensure that three file descriptors are open.
|
||||
while ((fd = open("console", O_RDWR)) >= 0) {
|
||||
if (fd >= 3) {
|
||||
|
10
sysproc.c
10
sysproc.c
@ -130,9 +130,15 @@ int sys_screen(void)
|
||||
struct proc *curproc = myproc();
|
||||
int result = 0;
|
||||
struct vconsole* consoleptr = 0;
|
||||
if ((consoleptr = newconsole()) != 0)
|
||||
int bgcol;
|
||||
if (argint(0, &bgcol) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((consoleptr = newconsole(bgcol)) != 0)
|
||||
{
|
||||
curproc->consoleptr = consoleptr;
|
||||
curproc->consoleptr = consoleptr;
|
||||
switchtoconsole(consoleptr);
|
||||
result = 1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user