From 143120d1601af8b6d2282faccc849994a1b27f98 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 24 Jul 2012 18:43:34 +0200 Subject: [PATCH] Added tcgetwinsize(2) for determining terminal resolution. Unfortunately this area is not standardized by POSIX. Linux uses an ioctl which is not that bad, but I'd like to have a designated function. I'm not sure if this facility is powerful enough and whether it should be improved. Also note that I use a struct winsize as on Linux, but I use size_ts instead for the heck of it. Perhaps I should use another name for the struct. --- libmaxsi/Makefile | 1 + libmaxsi/include/termios.h | 40 +++++++++++++++++++++++++++ libmaxsi/winsize.cpp | 38 ++++++++++++++++++++++++++ sortix/include/sortix/kernel/log.h | 41 +++++++++++++++++++--------- sortix/include/sortix/syscallnum.h | 3 ++- sortix/include/sortix/termios.h | 43 ++++++++++++++++++++++++++++++ sortix/kernel.cpp | 12 ++++++++- sortix/log.cpp | 9 ++++++- sortix/logterminal.cpp | 4 +-- sortix/terminal.cpp | 21 ++++++++++++++- sortix/textterminal.cpp | 16 +++++++++++ sortix/textterminal.h | 4 ++- 12 files changed, 212 insertions(+), 20 deletions(-) create mode 100644 libmaxsi/include/termios.h create mode 100644 libmaxsi/winsize.cpp create mode 100644 sortix/include/sortix/termios.h diff --git a/libmaxsi/Makefile b/libmaxsi/Makefile index 31aa1d23..e2e088ef 100644 --- a/libmaxsi/Makefile +++ b/libmaxsi/Makefile @@ -43,6 +43,7 @@ process.o \ thread.o \ io.o \ ioleast.o \ +winsize.o \ terminal.o \ kernelinfo.o \ init.o \ diff --git a/libmaxsi/include/termios.h b/libmaxsi/include/termios.h new file mode 100644 index 00000000..14109238 --- /dev/null +++ b/libmaxsi/include/termios.h @@ -0,0 +1,40 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2012. + + This file is part of LibMaxsi. + + LibMaxsi is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License + along with LibMaxsi. If not, see . + + termios.h + Defines values for termios. + +*******************************************************************************/ + +/* TODO: POSIX-1.2008 compliance is only partial */ + +#ifndef _TERMIOS_H +#define _TERMIOS_H 1 + +#include +#include + +__BEGIN_DECLS + +int tcgetwinsize(int fd, struct winsize* ws); + +__END_DECLS + +#endif + diff --git a/libmaxsi/winsize.cpp b/libmaxsi/winsize.cpp new file mode 100644 index 00000000..63379e85 --- /dev/null +++ b/libmaxsi/winsize.cpp @@ -0,0 +1,38 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2012. + + This file is part of LibMaxsi. + + LibMaxsi is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License + along with LibMaxsi. If not, see . + + winsize.cpp + Access to terminal resolution. + +******************************************************************************/ + +#include +#include +#include + +namespace Maxsi { + +DEFN_SYSCALL2(int, SysTCGetWinSize, SYSCALL_TCGETWINSIZE, int, struct winsize*); + +extern "C" int tcgetwinsize(int fd, struct winsize* ws) +{ + return SysTCGetWinSize(fd, ws); +} + +} // namespace Maxsi diff --git a/sortix/include/sortix/kernel/log.h b/sortix/include/sortix/kernel/log.h index 447ffcab..d29e030a 100644 --- a/sortix/include/sortix/kernel/log.h +++ b/sortix/include/sortix/kernel/log.h @@ -1,26 +1,26 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. - This file is part of Sortix. + This file is part of LibMaxsi. - Sortix is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or (at your option) any later - version. + LibMaxsi is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. - Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU Lesser General Public License + along with LibMaxsi. If not, see . log.h A system for logging various messages to the kernel log. -******************************************************************************/ +*******************************************************************************/ #ifndef SORTIX_LOG_H #define SORTIX_LOG_H @@ -33,15 +33,30 @@ namespace Sortix namespace Log { extern Maxsi::Format::Callback deviceCallback; + extern size_t (*deviceWidth)(void*); + extern size_t (*deviceHeight)(void*); extern void* devicePointer; - void Init(Maxsi::Format::Callback callback, void* user); + void Init(Maxsi::Format::Callback callback, + size_t (*widthfunc)(void*), + size_t (*heightfunc)(void*), + void* user); inline void Flush() { if ( deviceCallback ) { deviceCallback(devicePointer, NULL, 0); } } + inline size_t Width() + { + return deviceWidth(devicePointer); + } + + inline size_t Height() + { + return deviceHeight(devicePointer); + } + inline size_t Print(const char* str) { using namespace Maxsi; diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h index b1779f9e..ab219adc 100644 --- a/sortix/include/sortix/syscallnum.h +++ b/sortix/include/sortix/syscallnum.h @@ -74,7 +74,8 @@ #define SYSCALL_PREAD 49 #define SYSCALL_PWRITE 50 #define SYSCALL_SFORKR 51 -#define SYSCALL_MAX_NUM 52 /* index of highest constant + 1 */ +#define SYSCALL_TCGETWINSIZE 52 +#define SYSCALL_MAX_NUM 53 /* index of highest constant + 1 */ #endif diff --git a/sortix/include/sortix/termios.h b/sortix/include/sortix/termios.h new file mode 100644 index 00000000..b26f0566 --- /dev/null +++ b/sortix/include/sortix/termios.h @@ -0,0 +1,43 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2012. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + sortix/termios.h + Defines values for termios. + +*******************************************************************************/ + +#ifndef SORTIX_TERMIOS_H +#define SORTIX_TERMIOS_H + +#include + +__BEGIN_DECLS + +struct winsize +{ + size_t ws_row; + size_t ws_col; + size_t ws_xpixel; + size_t ws_ypixel; +}; + +__END_DECLS + +#endif + diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index 835cb669..1c623e92 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -99,6 +99,16 @@ static size_t PrintToTextTerminal(void* user, const char* str, size_t len) return ((TextTerminal*) user)->Print(str, len); } +static size_t TextTermWidth(void* user) +{ + return ((TextTerminal*) user)->Width(); +} + +static size_t TextTermHeight(void* user) +{ + return ((TextTerminal*) user)->Height(); +} + extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo) { // Initialize system calls. @@ -119,7 +129,7 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo) TextTerminal textterm(&textbufhandle); // Register the text terminal as the kernel log and initialize it. - Log::Init(PrintToTextTerminal, &textterm); + Log::Init(PrintToTextTerminal, TextTermWidth, TextTermHeight, &textterm); // Display the boot welcome screen. DoWelcome(); diff --git a/sortix/log.cpp b/sortix/log.cpp index 8779908c..fe4d8955 100644 --- a/sortix/log.cpp +++ b/sortix/log.cpp @@ -35,6 +35,8 @@ namespace Sortix namespace Log { Maxsi::Format::Callback deviceCallback = NULL; + size_t (*deviceWidth)(void*) = NULL; + size_t (*deviceHeight)(void*) = NULL; void* devicePointer = NULL; size_t SysPrintString(const char* str) @@ -44,9 +46,14 @@ namespace Sortix return Print(str); } - void Init(Maxsi::Format::Callback callback, void* user) + void Init(Maxsi::Format::Callback callback, + size_t (*widthfunc)(void*), + size_t (*heightfunc)(void*), + void* user) { deviceCallback = callback; + deviceWidth = widthfunc; + deviceHeight = heightfunc; devicePointer = user; Syscall::Register(SYSCALL_PRINT_STRING, (void*) SysPrintString); diff --git a/sortix/logterminal.cpp b/sortix/logterminal.cpp index 8f806b84..30cf7576 100644 --- a/sortix/logterminal.cpp +++ b/sortix/logterminal.cpp @@ -96,12 +96,12 @@ namespace Sortix unsigned LogTerminal::GetWidth() const { - return 80U; + return (unsigned) Log::Width(); } unsigned LogTerminal::GetHeight() const { - return 25U; + return (unsigned) Log::Height(); } void LogTerminal::OnKeystroke(Keyboard* kb, void* /*user*/) diff --git a/sortix/terminal.cpp b/sortix/terminal.cpp index f780cd09..439505be 100644 --- a/sortix/terminal.cpp +++ b/sortix/terminal.cpp @@ -1,6 +1,6 @@ /****************************************************************************** - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + Copyright(C) Jonas 'Sortie' Termansen 2012. This file is part of Sortix. @@ -23,6 +23,7 @@ ******************************************************************************/ #include +#include #include #include "syscall.h" #include "process.h" @@ -63,11 +64,29 @@ namespace Sortix return 1; } + int SysTCGetWinSize(int fd, struct winsize* ws) + { + Process* process = CurrentProcess(); + Device* dev = process->descriptors.Get(fd); + if ( !dev ) { Error::Set(EBADF); return -1; } + if ( !dev->IsType(Device::TERMINAL) ) { Error::Set(ENOTTY); return -1; } + DevTerminal* term = (DevTerminal*) dev; + struct winsize ret; + ret.ws_col = term->GetWidth(); + ret.ws_row = term->GetHeight(); + ret.ws_xpixel = 0; // Not supported by DevTerminal interface. + ret.ws_ypixel = 0; // Not supported by DevTerminal interface. + // TODO: Check that ws is a valid user-space pointer. + *ws = ret; + return 0; + } + void Terminal::Init() { Syscall::Register(SYSCALL_SETTERMMODE, (void*) SysSetTermMode); Syscall::Register(SYSCALL_GETTERMMODE, (void*) SysGetTermMode); Syscall::Register(SYSCALL_ISATTY, (void*) SysIsATTY); + Syscall::Register(SYSCALL_TCGETWINSIZE, (void*) SysTCGetWinSize); } } diff --git a/sortix/textterminal.cpp b/sortix/textterminal.cpp index 00a70140..87aeaaaa 100644 --- a/sortix/textterminal.cpp +++ b/sortix/textterminal.cpp @@ -65,6 +65,22 @@ size_t TextTerminal::Print(const char* string, size_t stringlen) return stringlen; } +size_t TextTerminal::Width() const +{ + TextBuffer* textbuf = textbufhandle->Acquire(); + size_t width = textbuf->Width(); + textbufhandle->Release(textbuf); + return width; +} + +size_t TextTerminal::Height() const +{ + TextBuffer* textbuf = textbufhandle->Acquire(); + size_t height = textbuf->Height(); + textbufhandle->Release(textbuf); + return height; +} + void TextTerminal::PutChar(TextBuffer* textbuf, char c) { if ( ansimode ) diff --git a/sortix/textterminal.h b/sortix/textterminal.h index ad23125e..90738bcd 100644 --- a/sortix/textterminal.h +++ b/sortix/textterminal.h @@ -35,6 +35,8 @@ public: TextTerminal(TextBufferHandle* textbufhandle); ~TextTerminal(); size_t Print(const char* string, size_t stringlen); + size_t Width() const; + size_t Height() const; private: void PutChar(TextBuffer* textbuf, char c); @@ -48,7 +50,7 @@ private: void Reset(); private: - TextBufferHandle* textbufhandle; + mutable TextBufferHandle* textbufhandle; uint8_t vgacolor; unsigned column; unsigned line;