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.
This commit is contained in:
Jonas 'Sortie' Termansen 2012-07-24 18:43:34 +02:00
parent 1761db9f27
commit 143120d160
12 changed files with 212 additions and 20 deletions

View File

@ -43,6 +43,7 @@ process.o \
thread.o \
io.o \
ioleast.o \
winsize.o \
terminal.o \
kernelinfo.o \
init.o \

View File

@ -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 <http://www.gnu.org/licenses/>.
termios.h
Defines values for termios.
*******************************************************************************/
/* TODO: POSIX-1.2008 compliance is only partial */
#ifndef _TERMIOS_H
#define _TERMIOS_H 1
#include <features.h>
#include <sortix/termios.h>
__BEGIN_DECLS
int tcgetwinsize(int fd, struct winsize* ws);
__END_DECLS
#endif

38
libmaxsi/winsize.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
winsize.cpp
Access to terminal resolution.
******************************************************************************/
#include <libmaxsi/platform.h>
#include <libmaxsi/syscall.h>
#include <termios.h>
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

View File

@ -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 <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public License
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
sortix/termios.h
Defines values for termios.
*******************************************************************************/
#ifndef SORTIX_TERMIOS_H
#define SORTIX_TERMIOS_H
#include <features.h>
__BEGIN_DECLS
struct winsize
{
size_t ws_row;
size_t ws_col;
size_t ws_xpixel;
size_t ws_ypixel;
};
__END_DECLS
#endif

View File

@ -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();

View File

@ -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);

View File

@ -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*/)

View File

@ -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 <sortix/kernel/platform.h>
#include <sortix/termios.h>
#include <libmaxsi/error.h>
#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);
}
}

View File

@ -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 )

View File

@ -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;