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:
iDunnoDev
2022-12-16 15:23:38 +00:00
committed by iDunnoDev
parent 924d90c066
commit c65c58a954
11 changed files with 284 additions and 52 deletions

View File

@ -201,6 +201,7 @@ UPROGS=\
_screen\ _screen\
_cls\ _cls\
_maze\ _maze\
_count\
fs.img: mkfs $(UPROGS) fs.img: mkfs $(UPROGS)
./mkfs fs.img $(UPROGS) ./mkfs fs.img $(UPROGS)
@ -224,8 +225,8 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
then echo "-gdb tcp::$(GDBPORT)"; \ then echo "-gdb tcp::$(GDBPORT)"; \
else echo "-s -p $(GDBPORT)"; fi) else echo "-s -p $(GDBPORT)"; fi)
ifndef CPUS ifndef CPUS
#CPUS := 2 CPUS := 2
CPUS := 1 # For debugging #CPUS := 1 # For debugging
endif 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) 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
View File

@ -39,11 +39,13 @@ struct vconsole
int pos; int pos;
int active; int active;
int inuse; int inuse;
uint titlebgcol;
char proctitle[20];
char status[30];
}; };
struct vconsole consoles[MAXVCONSOLES]; struct vconsole consoles[MAXVCONSOLES];
struct vconsole *currentconsole = 0; struct vconsole *currentconsole = 0;
//static uint currentconsoleindex = 0;
#define C(x) ((x) - '@') // Control-x #define C(x) ((x) - '@') // Control-x
@ -62,10 +64,13 @@ static struct
int locking; int locking;
} cons; } 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"; static char digits[] = "0123456789abcdef";
char buf[16];
int i; int i;
uint x; uint x;
@ -89,6 +94,15 @@ static void printint(int xx, int base, int sign)
buf[i++] = '-'; 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) while (--i >= 0)
{ {
consputc(buf[i]); 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) void panic(char *s)
{ {
int i; int i;
@ -218,12 +314,66 @@ struct vconsole* getvalidprocessconsoleptr(void)
return inconsoleptr; 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 BACKSPACE 0x100
#define CRTPORT 0x3d4 #define CRTPORT 0x3d4
#define TITLEOFF (SCRWIDTH * 1) // Size of the offset we need for the title bar #define TITLEOFF (SCRWIDTH * 1) // Size of the offset we need for the title bar
static ushort *crt = (ushort *)P2V(0xb8000); // CGA memory 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) static void cgaputc(int c)
{ {
int pos; int pos;
@ -397,7 +547,7 @@ void consoleintr(int (*getc)(void))
{ {
if (currentconsole->consoleindex != 0) if (currentconsole->consoleindex != 0)
{ {
switchtoconsole(0); switchtoconsole(getbaseconsoleptr());
} }
} }
if (doconsoleswitch) 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 consolewrite(struct inode *ip, char *buf, int n)
{ {
int i; int i;
//struct vconsole* inconsoleptr = getvalidprocessconsoleptr(); struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
iunlock(ip); iunlock(ip);
acquire(&cons.lock); //acquire(&cons.lock);
acquire(&inconsoleptr->lock);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
consputc(buf[i] & 0xff); consputc(buf[i] & 0xff);
} }
release(&cons.lock); //release(&cons.lock);
release(&inconsoleptr->lock);
ilock(ip); ilock(ip);
return n; return n;
@ -514,7 +666,7 @@ struct vconsole* getbaseconsoleptr(void)
void clearconsole(ushort *bufferin) void clearconsole(ushort *bufferin)
{ {
// Flood the screen buffer with blank spaces // 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) void loadscreenbuffer(ushort *bufferin)
@ -530,26 +682,19 @@ void savescreenbuffer(ushort *bufferin)
} }
void clearscreen(void) 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 // Check if a process has actually been created otherwise use the base console
struct vconsole* inconsoleptr = getvalidprocessconsoleptr(); struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
acquire(&cons.lock); acquire(&cons.lock);
int pos = TITLEOFF; int pos = TITLEOFF;
clearconsole(inconsoleptr->screenbuffer); clearconsole(inconsoleptr->screenbuffer);
inconsoleptr->pos = pos; inconsoleptr->pos = pos;
release(&cons.lock);
if (inconsoleptr->inuse) if (inconsoleptr->inuse)
{ {
acquire(&cons.lock); loadscreenbuffer(inconsoleptr->screenbuffer);
loadscreenbuffer(inconsoleptr->screenbuffer); drawtitle();
release(&cons.lock); release(&cons.lock);
outb(CRTPORT, 14); outb(CRTPORT, 14);
@ -557,6 +702,10 @@ void clearscreen(void)
outb(CRTPORT, 15); outb(CRTPORT, 15);
outb(CRTPORT + 1, pos); outb(CRTPORT + 1, pos);
} }
else
{
release(&cons.lock);
}
} }
void consoleinit(void) void consoleinit(void)
@ -570,7 +719,8 @@ void consoleinit(void)
consoles[i].pos = 0; consoles[i].pos = 0;
consoles[i].active = 0; consoles[i].active = 0;
consoles[i].inuse = 0; consoles[i].inuse = 0;
consoles[i].titlebgcol = 0x4F00;
//initlock(&consoles[i].lock, "vconsole" + i); //initlock(&consoles[i].lock, "vconsole" + i);
} }
@ -590,7 +740,7 @@ void consoleinit(void)
ioapicenable(IRQ_KBD, 0); ioapicenable(IRQ_KBD, 0);
} }
struct vconsole* newconsole(void) struct vconsole* newconsole(int bgpreset)
{ {
struct vconsole* result = 0; struct vconsole* result = 0;
@ -600,6 +750,7 @@ struct vconsole* newconsole(void)
if (!consoles[i].active) if (!consoles[i].active)
{ {
consoles[i].processowner = myproc(); consoles[i].processowner = myproc();
consoles[i].titlebgcol = bgpreset;
result = &consoles[i]; result = &consoles[i];
break; break;
} }
@ -621,17 +772,7 @@ int switchtoconsole(struct vconsole* consoleptr)
{ {
int pos; int pos;
/*outb(CRTPORT, 14); acquire(&consoleptr->lock);
pos = inb(CRTPORT + 1) << 8;
outb(CRTPORT, 15);
pos |= inb(CRTPORT + 1);*/
// consoles[currentconsoleindex].pos = pos;
// savescreenbuffer(consoles[currentconsoleindex].screenbuffer);
// acquire(&currentconsole->lock);
// sleep(&(currentconsole), &currentconsole->lock);
acquire(&cons.lock); acquire(&cons.lock);
releaseallconsoles(); releaseallconsoles();
currentconsole = consoleptr; currentconsole = consoleptr;
@ -640,16 +781,18 @@ int switchtoconsole(struct vconsole* consoleptr)
// ioapicenable(IRQ_KBD, 0); // ioapicenable(IRQ_KBD, 0);
loadscreenbuffer(currentconsole->screenbuffer); loadscreenbuffer(currentconsole->screenbuffer);
drawtitle();
release(&cons.lock); release(&cons.lock);
if (!currentconsole->active) if (!currentconsole->active)
{ {
clearscreen(); clearscreen();
drawtitle();
cprintf("Welcome to Console: %d\n", currentconsole->consoleindex); cprintf("Welcome to Console: %d\n", currentconsole->consoleindex);
currentconsole->active = 1; currentconsole->active = 1;
} }
else else
{ {
pos = currentconsole->pos; pos = currentconsole->pos;
outb(CRTPORT, 14); outb(CRTPORT, 14);
@ -658,7 +801,7 @@ int switchtoconsole(struct vconsole* consoleptr)
outb(CRTPORT + 1, pos); outb(CRTPORT + 1, pos);
} }
// wakeup(myproc()->chan); release(&consoleptr->lock);
return 0; return 0;
} }
@ -666,7 +809,7 @@ int closeconsole(void)
{ {
struct vconsole* consoleptr = myproc()->consoleptr; 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) if (myproc() == consoleptr->processowner)
{ {

22
count.c Normal file
View 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
View File

@ -22,12 +22,23 @@ void cprintf(char*, ...);
void consoleintr(int (*)(void)); void consoleintr(int (*)(void));
int consoleget(void); int consoleget(void);
void panic(char*) __attribute__((noreturn)); 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*); int switchtoconsole(struct vconsole*);
// Function to close and reset the current proc console
int closeconsole(void); int closeconsole(void);
// Function to get the current inuse console index
int getcurrentconsoleindex(void); int getcurrentconsoleindex(void);
// Function to clear the current screen buffer
void clearscreen(void); void clearscreen(void);
// Function to get the base consoles ptr
struct vconsole* getbaseconsoleptr(void); 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 // exec.c
int exec(char*, char**); int exec(char*, char**);

5
exec.c
View File

@ -130,6 +130,11 @@ int exec(char *path, char **argv) {
} }
safestrcpy(curproc->name, last, sizeof(curproc->name)); safestrcpy(curproc->name, last, sizeof(curproc->name));
if (curproc->consoleptr != 0)
{
setconsoleproctitle(curproc->consoleptr, curproc->name);
}
// Commit to the user image. // Commit to the user image.
oldpgdir = curproc->pgdir; oldpgdir = curproc->pgdir;
curproc->pgdir = pgdir; curproc->pgdir = pgdir;

1
maze.c
View File

@ -62,5 +62,6 @@ int main(int argc, char *argv[]) {
printf(1, "\n"); printf(1, "\n");
sleep(10); sleep(10);
} }
printf(1, "Maze Ended\n");
exit(); exit();
} }

5
proc.c
View File

@ -272,6 +272,11 @@ void exit(void) {
closeconsole(); closeconsole();
} }
if (curproc->consoleptr != 0)
{
setconsoleproctitle(curproc->consoleptr, curproc->parent->name);
}
// Jump into the scheduler, never to return. // Jump into the scheduler, never to return.
curproc->state = ZOMBIE; curproc->state = ZOMBIE;
sched(); sched();

View File

@ -1,14 +1,53 @@
#include "types.h" #include "types.h"
#include "user.h" #include "user.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
//int consoles = 0;
int pid; int pid;
//char* comment = ""; int bgcol = 0x4F00;
for (int i = 1; i < argc; i++) { 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"); printf(1, "screen: fork failed\n");
} }
if (pid == 0) { if (pid == 0) {
if (screen() != 0) if (screen(bgcol) != 0)
{ {
exec("sh", argv); exec("sh", argv);
printf(1, "screen: exec sh failed\n"); printf(1, "screen: exec sh failed\n");

3
sh.c
View File

@ -146,8 +146,7 @@ int getcmd(char *buf, int nbuf) {
int main(void) { int main(void) {
static char buf[100]; static char buf[100];
int fd; int fd;
printf(1, "SH PID: %d\n", getpid());
// Ensure that three file descriptors are open. // Ensure that three file descriptors are open.
while ((fd = open("console", O_RDWR)) >= 0) { while ((fd = open("console", O_RDWR)) >= 0) {
if (fd >= 3) { if (fd >= 3) {

View File

@ -130,9 +130,15 @@ int sys_screen(void)
struct proc *curproc = myproc(); struct proc *curproc = myproc();
int result = 0; int result = 0;
struct vconsole* consoleptr = 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); switchtoconsole(consoleptr);
result = 1; result = 1;
} }

2
user.h
View File

@ -26,7 +26,7 @@ int uptime(void);
int getch(void); int getch(void);
int greeting(void); int greeting(void);
int shutdown(int restart); int shutdown(int restart);
int screen(void); int screen(int bgcol);
int cls(void); int cls(void);
// ulib.c // ulib.c