Refactored the system to use the new Terminal interface.

This will allow development of a better terminal providing stdin.

Added new system calls settermmode(2) and gettermmode(2) declared in
<sys/termmode.h>. They allow querying and changing the current mode of
terminals (enabling raw keyboard data, signal handling, line buffering,
UTF-8 encoding stdin, and more). However, all that is unsupported by the
current terminal device driver.

Added KBKEY_ENCODE and KBKEY_DECODE macros to <sys/keycodes.h> which allows
encoding the kbkey format in UTF-32 characters.
This commit is contained in:
Jonas 'Sortie' Termansen 2012-01-22 16:48:57 +01:00
parent ead0e1523f
commit ecc3114f2a
14 changed files with 328 additions and 23 deletions

View File

@ -51,6 +51,7 @@ c/h/errno.h \
c/h/error.h \
c/h/dirent.h \
c/h/sys/keycodes.h \
c/h/sys/termmode.h \
c/h/sys/readdirents.h \
c/h/sys/stat.h \
c/h/sys/types.h \
@ -67,6 +68,7 @@ sortix-sound.o \
process.o \
thread.o \
io.o \
terminal.o \
init.o \
signal.o \
$(CPU)/signal.o \

View File

@ -0,0 +1,39 @@
/******************************************************************************
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/>.
termmode.h
Provides access to the various modes Sortix terminals can operate in.
******************************************************************************/
#ifndef _SYS_TERMMODE_H
#define _SYS_TERMMODE_H 1
#include <features.h>
#include <sortix/termmode.h>
__BEGIN_DECLS
int settermmode(int fd, unsigned mode);
int gettermmode(int fd, unsigned* mode);
__END_DECLS
#endif

View File

@ -49,7 +49,6 @@ namespace Maxsi
DEFN_SYSCALL1(int, SysChDir, SYSCALL_CHDIR, const char*);
DEFN_SYSCALL2(char*, SysGetCWD, SYSCALL_GETCWD, char*, size_t);
DEFN_SYSCALL1(int, SysUnlink, SYSCALL_UNLINK, const char*);
DEFN_SYSCALL1(int, SysIsATTY, SYSCALL_ISATTY, int);
DEFN_SYSCALL3_VOID(SysSeek, SYSCALL_SEEK, int, off_t*, int);
DEFN_SYSCALL2(int, SysMkDir, SYSCALL_MKDIR, const char*, mode_t);
DEFN_SYSCALL1(int, SysRmDir, SYSCALL_RMDIR, const char*);
@ -279,11 +278,6 @@ namespace Maxsi
{
return SysFTruncate(fd, length);
}
extern "C" int isatty(int fd)
{
return SysIsATTY(fd);
}
#endif
}

50
libmaxsi/terminal.cpp Normal file
View File

@ -0,0 +1,50 @@
/******************************************************************************
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/>.
terminal.cpp
Allows user-space to access terminals.
******************************************************************************/
#include "platform.h"
#include "syscall.h"
#include <sys/termmode.h>
#include <unistd.h>
namespace Maxsi
{
DEFN_SYSCALL2(int, SysSetTermMode, SYSCALL_SETTERMMODE, int, unsigned);
DEFN_SYSCALL2(int, SysGetTermMode, SYSCALL_GETTERMMODE, int, unsigned*);
DEFN_SYSCALL1(int, SysIsATTY, SYSCALL_ISATTY, int);
extern "C" int settermmode(int fd, unsigned mode)
{
return SysSetTermMode(fd, mode);
}
extern "C" int gettermmode(int fd, unsigned* mode)
{
return SysGetTermMode(fd, mode);
}
extern "C" int isatty(int fd)
{
return SysIsATTY(fd);
}
}

View File

@ -77,6 +77,7 @@ syscall.o \
sound.o \
pci.o \
uart.o \
terminal.o \
vgaterminal.o \
serialterminal.o \
descriptors.o \

View File

@ -35,7 +35,7 @@ namespace Sortix
static const unsigned VGABUFFER = 2;
static const unsigned FILESYSTEM = 3;
static const unsigned DIRECTORY = 4;
static const unsigned TTY = 5;
static const unsigned TERMINAL = 5;
public:
Device();

View File

@ -29,6 +29,7 @@
#include "../filesystem.h"
#include "../directory.h"
#include "../stream.h"
#include "../terminal.h"
#include "../vga.h"
#include "../ata.h"
#include "devfs.h"
@ -149,10 +150,11 @@ namespace Sortix
atalist[ataid]->Refer();
}
class DevLogTTY : public DevStream
// TODO: Remove this deprecated class!
class DevLogTTY : public DevTerminal
{
public:
typedef DevStream BaseClass;
typedef DevTerminal BaseClass;
public:
DevLogTTY();
@ -163,7 +165,12 @@ namespace Sortix
virtual ssize_t Write(const byte* src, size_t count);
virtual bool IsReadable();
virtual bool IsWritable();
virtual bool IsType(unsigned type) const;
virtual bool SetMode(unsigned mode);
virtual bool SetWidth(unsigned width);
virtual bool SetHeight(unsigned height);
virtual unsigned GetMode() const;
virtual unsigned GetWidth() const;
virtual unsigned GetHeight() const;
};
@ -199,9 +206,37 @@ namespace Sortix
return true;
}
bool DevLogTTY::IsType(unsigned type) const
bool DevLogTTY::SetMode(unsigned mode)
{
return type == Device::TTY || BaseClass::IsType(type);
if ( mode ) { Error::Set(ENOSYS); return false; }
return true;
}
bool DevLogTTY::SetWidth(unsigned width)
{
if ( width != GetWidth() ) { Error::Set(ENOTSUP); return false; }
return true;
}
bool DevLogTTY::SetHeight(unsigned height)
{
if ( height != GetHeight() ) { Error::Set(ENOTSUP); return false; }
return true;
}
unsigned DevLogTTY::GetMode() const
{
return 0;
}
unsigned DevLogTTY::GetWidth() const
{
return 25;
}
unsigned DevLogTTY::GetHeight() const
{
return 80;
}
class DevNull : public DevStream

View File

@ -167,22 +167,12 @@ namespace Sortix
return process->descriptors.Allocate(dev);
}
int SysIsATTY(int fd)
{
Process* process = CurrentProcess();
Device* dev = process->descriptors.Get(fd);
if ( !dev ) { Error::Set(EBADF); return 0; }
if ( !dev->IsType(Device::TTY) ) { Error::Set(ENOTTY); return 0; }
return 1;
}
void Init()
{
Syscall::Register(SYSCALL_WRITE, (void*) SysWrite);
Syscall::Register(SYSCALL_READ, (void*) SysRead);
Syscall::Register(SYSCALL_CLOSE, (void*) SysClose);
Syscall::Register(SYSCALL_DUP, (void*) SysDup);
Syscall::Register(SYSCALL_ISATTY, (void*) SysIsATTY);
Syscall::Register(SYSCALL_SEEK, (void*) SysSeek);
}
}

View File

@ -39,6 +39,7 @@
#include "syscall.h"
#include "pci.h"
#include "uart.h"
#include "terminal.h"
#include "serialterminal.h"
#include "vgaterminal.h"
#include "elf.h"
@ -224,6 +225,9 @@ namespace Sortix
// Initialize the keyboard.
Keyboard::Init();
// Initialize the terminal.
Terminal::Init();
// Initialize the VGA driver.
VGA::Init();

View File

@ -141,5 +141,22 @@
#define KBKEY_RSUPER (0x80 + 0x5C)
#define KBKEY_MENU (0x80 + 0x5D)
#define KBKEY_ENCODE(_kbkey) \
({ \
int kbkey = (_kbkey); \
uint32_t codepoint = (1U<<30U) | ((unsigned) kbkey); \
codepoint &= ~(1U<<31U); \
codepoint; \
})
#define KBKEY_DECODE(_codepoint) \
({ \
uint32_t codepoint = (_codepoint); \
if ( !(codepoint & (1U<<30U)) ) { codepoint = 0U; } \
if ( codepoint & (1U<<29U) ) { codepoint |= (1U<<31U); } \
int kbkey = (int) codepoint; \
kbkey; \
})
#endif

View File

@ -67,7 +67,9 @@
#define SYSCALL_RMDIR 39
#define SYSCALL_TRUNCATE 40
#define SYSCALL_FTRUNCATE 41
#define SYSCALL_MAX_NUM 42 /* index of highest constant + 1 */
#define SYSCALL_SETTERMMODE 42
#define SYSCALL_GETTERMMODE 43
#define SYSCALL_MAX_NUM 44 /* index of highest constant + 1 */
#endif

73
sortix/terminal.cpp Normal file
View File

@ -0,0 +1,73 @@
/******************************************************************************
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/>.
terminal.cpp
Provides an interface to terminals for user-space.
******************************************************************************/
#include "platform.h"
#include <libmaxsi/error.h>
#include "syscall.h"
#include "process.h"
#include "terminal.h"
using namespace Maxsi;
namespace Sortix
{
int SysSetTermMode(int fd, unsigned mode)
{
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;
return term->SetMode(mode) ? 0 : -1;
}
int SysGetTermMode(int fd, unsigned* mode)
{
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;
// TODO: Check that mode is a valid user-space pointer.
*mode = term->GetMode();
return 0;
}
int SysIsATTY(int fd)
{
Process* process = CurrentProcess();
Device* dev = process->descriptors.Get(fd);
if ( !dev ) { Error::Set(EBADF); return 0; }
if ( !dev->IsType(Device::TERMINAL) ) { Error::Set(ENOTTY); return 0; }
return 1;
}
void Terminal::Init()
{
Syscall::Register(SYSCALL_SETTERMMODE, (void*) SysSetTermMode);
Syscall::Register(SYSCALL_GETTERMMODE, (void*) SysGetTermMode);
Syscall::Register(SYSCALL_ISATTY, (void*) SysIsATTY);
}
}

62
sortix/terminal.h Normal file
View File

@ -0,0 +1,62 @@
/******************************************************************************
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/>.
terminal.h
Reads data from an input source (such as a keyboard), optionally does line-
buffering, and redirects data to an output device (such as the VGA).
******************************************************************************/
#ifndef SORTIX_TERMINAL_H
#define SORTIX_TERMINAL_H
#include "device.h"
#include "stream.h"
#include "termmode.h"
namespace Sortix
{
class DevTerminal : public DevStream
{
public:
typedef DevStream BaseClass;
public:
virtual bool IsType(unsigned type) const
{
return type == Device::TERMINAL || BaseClass::IsType(type);
}
public:
virtual bool SetMode(unsigned mode) = 0;
virtual bool SetWidth(unsigned width) = 0;
virtual bool SetHeight(unsigned height) = 0;
virtual unsigned GetMode() const = 0;
virtual unsigned GetWidth() const = 0;
virtual unsigned GetHeight() const = 0;
};
namespace Terminal
{
void Init();
}
}
#endif

36
sortix/termmode.h Normal file
View File

@ -0,0 +1,36 @@
/******************************************************************************
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/>.
termmode.h
Defines constants for various terminal modes.
******************************************************************************/
#ifndef SORTIX_TERMMODE_H
#define SORTIX_TERMMODE_H
#define TERMMODE_KBKEY (1U<<0U)
#define TERMMODE_UNICODE (1U<<1U)
#define TERMMODE_SIGNAL (1U<<2U)
#define TERMMODE_UTF8 (1U<<3U)
#define TERMMODE_LINEBUFFER (1U<<4U)
#define TERMMODE_ECHO (1U<<5U)
#endif