From c65c58a954e77bfce2b5c4ad068cb5621737d293 Mon Sep 17 00:00:00 2001 From: iDunnoDev Date: Fri, 16 Dec 2022 15:23:38 +0000 Subject: [PATCH] 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 --- Makefile | 5 +- console.c | 219 ++++++++++++++++++++++++++++++++++++++++++++---------- count.c | 22 ++++++ defs.h | 13 +++- exec.c | 5 ++ maze.c | 1 + proc.c | 5 ++ screen.c | 51 +++++++++++-- sh.c | 3 +- sysproc.c | 10 ++- user.h | 2 +- 11 files changed, 284 insertions(+), 52 deletions(-) create mode 100644 count.c diff --git a/Makefile b/Makefile index 5285406..da185f0 100644 --- a/Makefile +++ b/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) diff --git a/console.c b/console.c index d56bbba..271a3e3 100644 --- a/console.c +++ b/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) { diff --git a/count.c b/count.c new file mode 100644 index 0000000..05fd448 --- /dev/null +++ b/count.c @@ -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(); +} \ No newline at end of file diff --git a/defs.h b/defs.h index 09c349a..5b968f7 100644 --- a/defs.h +++ b/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**); diff --git a/exec.c b/exec.c index 73c54b1..9524288 100644 --- a/exec.c +++ b/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; diff --git a/maze.c b/maze.c index 8e9db0e..237ac21 100644 --- a/maze.c +++ b/maze.c @@ -62,5 +62,6 @@ int main(int argc, char *argv[]) { printf(1, "\n"); sleep(10); } + printf(1, "Maze Ended\n"); exit(); } \ No newline at end of file diff --git a/proc.c b/proc.c index f8203aa..d7507b6 100644 --- a/proc.c +++ b/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(); diff --git a/screen.c b/screen.c index 6675d49..62e2bac 100644 --- a/screen.c +++ b/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"); diff --git a/sh.c b/sh.c index f9e2301..a0c94cf 100644 --- a/sh.c +++ b/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) { diff --git a/sysproc.c b/sysproc.c index f0b3396..384c478 100644 --- a/sysproc.c +++ b/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; } diff --git a/user.h b/user.h index 94da047..0df72ad 100644 --- a/user.h +++ b/user.h @@ -26,7 +26,7 @@ int uptime(void); int getch(void); int greeting(void); int shutdown(int restart); -int screen(void); +int screen(int bgcol); int cls(void); // ulib.c