mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
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:
parent
ead0e1523f
commit
ecc3114f2a
14 changed files with 328 additions and 23 deletions
|
@ -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 \
|
||||
|
|
39
libmaxsi/c/hsrc/sys/termmode.h
Normal file
39
libmaxsi/c/hsrc/sys/termmode.h
Normal 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
|
||||
|
|
@ -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
50
libmaxsi/terminal.cpp
Normal 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);
|
||||
}
|
||||
}
|
|
@ -77,6 +77,7 @@ syscall.o \
|
|||
sound.o \
|
||||
pci.o \
|
||||
uart.o \
|
||||
terminal.o \
|
||||
vgaterminal.o \
|
||||
serialterminal.o \
|
||||
descriptors.o \
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
73
sortix/terminal.cpp
Normal 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
62
sortix/terminal.h
Normal 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
36
sortix/termmode.h
Normal 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
|
||||
|
Loading…
Reference in a new issue