Date: Wed, 5 Aug 1998 16:40:59 -0700 (PDT) From: Julian Elischer <julian@whistle.com> To: current@FreeBSD.ORG Cc: Kelly Yancey <kbyanc@freedomnet.com> Subject: syscons update Message-ID: <Pine.BSF.3.95.980805163541.19956A-100000@current1.whistle.com>
next in thread | raw e-mail | index | archive | help
here is the outcome from the discussion on this in 93
I seem to remember it stalled at this point.
contributors at that time were:
dawes@physics.su.OZ.AU
Holger.Veit@gmd.de.
terry@icarus.weber.edu
mycroft@gnu.ai.mit.edu
bsdealwi@undergrad.math.uwaterloo.ca
ache@astral.msk.su
hm@hcshh.hcs.de
rgrimes@cdrom.com
joerg_wunsch@uriah.sax.de
sos@kmd-ac.dk
vak@zebub.msk.su
kojima@kuis.kyoto-u.ac.jp
ukai@kuamp.kyoto-u.ac.jp
rich@lamprey.utmb.edu
---------------------------------------------
BASIC CONSOLE ARCHITECTURE: $Date: 93/07/30 23:42:04 $ $Revision: 1.6 $
Foreword:
The basic model that I propose has drawn heavily from the comments by all
the members of the group.
I have decided that I will use some concepts from Object Oriented techniques
in this, defining a number of "classes" that can be loaded at will, or in
the absense of loadable modules, could be compiled in.
-----------------------------------------------------------------------
Definitions:
A CLASS defines a set of INSTANCES that have the same external interfaces,
e.g. all terminal emulators must have the same interface. Two terminal
emulators, (e.g. vt10 and wyse60) must have the same interface, however they
have different code associated with them. They are still of the same CLASS.
A DERIVED CLASS is the set of all INSTANCES that are both in the same class
and also have the same code associated with them. (e.g. the set of all
INSTANCES with the terminal emulator interface and running the vt100 code)
The DERIVED CLASS supplies a table of methods, referenced by the INSTANCES
of that DERIVED CLASS
An INSTANCE is a specific instance of a CLASS and DERIVED CLASS,
that contains it's own STATE. There is no state held in a CLASS or
DERIVED CLASS. An INSTANCE is based around a structure which is
defined by the CLASS, and which has a pointer to a table of pointers
to methods (supplied by a particular DERIVED CLASS) and values,
(defined in meaning by the CLASS, but representative of state for
that INSTANCE only).. The structure defined for the INSTANCE by the
CLASS has also a (void *) pointer to a structure that is only
defined for each DERIVED CLASS and which code external to the
DERIVED CLASS cannot interpret. This structure is used to hold the
PRIVATE STATE of the INSTANCE, and can only be interretted by the
METHODS supplied by that DERIVED CLASS.
Each DERIVED CLASS supplies a single init routine, which when run
will link the DERIVED CLASS into any needed global structures.
e.g. "List of available terminal emulators". It also supplies
a CONSTRUCTOR routine that when called (from the list above)
will produce an INSTANCE of the required DERIVED CLASS.
I imagine the list being of the form: (for example);
TEs----->[name ]-->"vt100" /-->[name ]-->"wyse50"
[constructor ]-->0xFE200016 | [constructor ]-->0xFE201542
[next ]----------------/ [next ]-->0
The various INSTANCES include both private data, private methods, public
data and public methods. All DERIVED CLASSES put themselves
into ASCII identified lists, so that a list of available (loaded) TE
DERIVED CLASSES may look like, "vt100","adm3a","wyse60".
VC's inherit all their INSTANCE DERIVED CLASSES from the base VC (or
possibly the VC running at the time of creation), but can
substitute an INSTANCE which is a member of a different DERIVED CLASS.
e.g. replace an adm3a with a vt100.
Whether the VC INSTANCE actually exists for each VC or is 'virtual'
depends on whether we want a special body of code to call the other
modules (INSTANCES) or whether they call each other, so that no explicitly
written VC layer exists. In either case a VC STRUCTURE certainly
exists for each VC. Each INSTANCE in the console system contains a backpointer
to the VC structure with which it is associated, to allow it to identify
state from the VC and also find other INSTANCES associated with that VC.
It may be that the central VC code calls methods
from each INSTANCE PLUS they might call methods from each other,
(e.g. the VS 'refresh' method might call the renderer's
methods directly in order to refresh the screen to the state it requires.
The classes I have defined (so far) are:
Terminal_emulator All terminal emulators are members of this
class, though differnt VCs may use different
instantiations of the same emulator DERIVED
CLASS they may use differnt DERIVED CLASSES
(e.g. a vt100 or a adm31a DERIVED CLASS
of the TE class).
i.e. they have the same public interfaces.
The TE only talks to the VS (virtual screen)
code when 'rendering'. The VS methods pass
these calls on to the actual RENDERER methods
only if that VC is actually ON-SCREEN.
While this implies that a person COULD change
TEs on the fly, it's more intended that a new
VC could be created using a different TE to
the TE that was running when it ws created.
(a 3274 TE and a normal TE on differnt VC's).
Changing TE's on the fly would require very
careful state management and would probably
not work (in initial versions, at least though
I don't see this as being a needed feature).
The state of each TE is internally held
and considered private in scope.
virt_screen The virt_screen CLASS defines a set of methods
that the external world (e.g. the TE) can
use to draw on the screen. It draws however on
a 'virtual screen' regardless of what hardware
is present and whether that VC is presently
being shown on the real screen. When that
VC is selected for display, it uses it's
internal virtual screen to refresh the real
screen, using the renderer methods form the
VC's renderer INSTANCE. Requests to the methods
that arrive while it is "on screen" are passed
down to the annalogous renderer method.
because virt_screen and renderer classes are
so closely related they might even both be
implimented as DERIVED CLASSES of the same
RENDERER CLASS. (e.g. if VC's were not
being supported, the renderer INSTANCE might be
placed into the VS slot?). The virt_screen
INSTANCE can store it's virtual screen in any way
it likes, as that's private to the DERIVED
CLASS, however, it will be handed characters
in the 'internal' character set. I can imagine
needing upto 32 bits per character position.
(including attributes). The VS has NO IDEA
what the characters look like. It has only
the SYMBOLS.
It is possible the the TE should
hold the VS map and should redraw
the screen through calls directly
to the renderer when asked by the
refresh() entrypoint. In that scenario
there would be no VS objects.
renderer The renderer supplies methods similar to the
virtual screen, however they result in changes
on the physical display. The VS INSTANCE talks
to the renderer, and might instruct it to
refresh the entire display or just write a
single character and attribute to a fixed
place. The renderer is hardware specific
and could alternatively be called the
"frame-buffer" driver, or "display driver".
Terry points out that a hard-copy renderer
might be of interest to allow screen dumps etc.
The renderer might work in graphics mode,
but the virtual screen INSTANCES and renderer
methods are basically character oriented,
using whatever means it can to render the
internal character set elements, using
information taken from the 'FONT' INSTANCE
associated with that VC. It has also been
pointed out that there could be such a thing
as a 'serial line terminal' renderer. 8-)
exter_intern_mapper For each external coding used by the
user, there is a different DERIVED CLASS.
The default DERIVED CLASS would simply deliver
the bottom 8 bits of the internal
representation the user and visa versa.
(if we decide to use unicode as the internal
representation then the default 8-bit code
presented to the user would be ISO 8859-1).
A VC that was using a JIS 208/212 external
mapping would use an INSTANCE that did the
appropriate (more complex) mapping.
(Assuming that one was loaded).
Keyboard_mapper Different DERIVED CLASSES would be used to
map different national keyboards. The keyboard
INSTANCE for each VT may be of different
keyboard DERIVED CLASSES. NOTE: this is not the
keyboard driver, which is responsible for
handling different types of keyboards.
There are two levels of keyboard handling.
One of them knows what scancodes respond to
what keys and produces a standard scancode
set..(PS2?) and the other knows
what internal code should be generated
from each of those scancodes, for the
language(s) presently being used.(and
taking account of language 'SHIFT' effects).
The present X interface would not use this
INSTANCE, except when loading the default map.
(I know this is not what Terry wants, but
It fits in better with what X needs at
the moment)
Font A Font INSTANCE can return font information
for any internally represented character,
as well as information about the font.
(including 'not supported.. use "BLOB"')
This includes font size, ligature information
etc. The font INSTANCE is used almost
exclusively by the renderer,
to impliment requests from the VS. It also
has an interaction with the mode control code.
There would probably be a method associated
with enabling the rendering agent
to efficiently and quickly load fonts into
hardware. I can imagine a font INSTANCE that
returns a particular version of a character
depending on the surrounding characters..
e.g. arabic or indian linking of word-parts.
This would be of little use for character based
hardware, however graphics based hardware
could make use of this in non-western
languages.
Other modules that could be defined in object form (but not neccesarily)
include the VC control module and the Keyboard driver itself, though
one might not necessarily want multiple instances of either.
the overall picture looks as follows:
(This is the connection and flow for a Single VC, another VC would
talk to other instances of the 'CLASSES').
+-----------------------------------------+
| | TTY IN | | other | TTY OUT |
| RAW | I/F |VC I/F |RAW I/F| I/F |
| KBD | | | | |
| I/F |----^----|-------|-------|---v-----|
| | INT/EXT | | EXT/INT |
| | CONV | | CONV |
| < (int/ext| |(int/ext |
| | object) | VC CODE | object)|
| |----^----| |---v-----|
| | | | |
| | TE IN | | TE OUT |
| | ( TE | | ( TE |
| | object) | | object) |
| |----^----| +------|---v-----|
| | | | Font | |
| < KBD MAP | |(Font | VS CODE | <-- The VS may become
| |(kbd obj)| | obj) | | part of the TE
|--^-------^-------^--^v----v------^v-----|
| Keyboard driver | Renderer |
| | and Mode control |
| | |
+-----------------------------------------+
The TE ,TTY, and EXT/INT modules are shown as separate in and out modules,
however they would be in fact not split. That's just for clarity.
Each VC has pointers to the following tables/INSTANCES in it's local table:
font INSTANCE
ext/int INSTANCE
keyboard obj
TE obj
VS storage pointer (an INSTANCE?)
renderer private info.(an INSTANCE?)
TTY interface to use.
The VS code you are probably wondering about is the Virtual Screen.
each VC has a VS associated with which it talks in character oriented
primatives. (at least the basic version would).
If the VC is presently on screen, these calls are
passed on to the renderer, otherwise, only the VS is updated.
The VS is used to update the screen when a VC is 'exposed'.
The VS code is not likely to need differnt versions of itself
co-existing, so it is unlikely that it need be implimented as
an 'object'. the same goes for the VC code. It may be worthwhile
considering the VS code as an object, just so we get the
encapsulation and to make it similar to the other modules.
Possibly an enhansed VS could be written to support graphics actions.
The present state of the art regarding X servers requires some support
in the renderer, for Process notification on VC switch, but I don't
think that the raw graphics interfaces can be expected to go through
the VS layer. This would be a good 'project' for someone, and we should
not consider that it will never happen.
While the inclusion from the start of VCs may seem to over-specify, I feel
that this is a feature that must be built in from the start. If it were
not, then it would be very hard to retro-fit 'per VC' instances of each
of the INSTANCES.
All INSTANCES would be dynamically allocated, and the act of loading
a new module and running it's "init" routine would be the equivalent
of definign a new available DERIVED CLASS. By this I mean, the 'struct' is
dynamically allocated. (public and private parts) The code will have
to be either loaded using terry's stuff or compiled in.
This need not be large or cumbersome. Properly coded in C this approach
should lead to highly separatable and replacable modules, without
much speed penalty.
I see the implimentation being in C rather than C++ though this is
more for non technical reasons.
I briefly outline below some first sketches
of the implimentation.
--------------------------------------------------------------------
Preliminary example:
Each 'INSTANCE' is based around a structure that
is always the same. It has a pointer to the DERIVED CLASS (including
methods), and a pointer to the PRIVATE STATE data. It also has a pointer to
the VC with which it is associated.
Control is passed around between the INSTANCES and the VC code
so as to achieve the desired result. (and between the INSTANCES)
All methods have as their first argument, the address of the INSTANCE they
were called from ('this' in C++).
Below is a quick sketch of how they would look. they are not complete,
and the methods and variables needed for each INSTANCE are open to discussion.
Each INSTANCE has a few items in common.
A pointer back to the VC of which it is a part.
A pointer (type void*) to that INSTANCE's private data (that could be
differently defined for different DERIVED CLASSES (e.g. vt100 would
keep different private data to wy50).
A pointer to the DERIVED CLASS's methods.
Each DERIVED CLASS in turn has:
A name pointer (e.g. "vt100" or "ISO-8859-1")
A pointer to a 'delete operation to delete all the resources used
by this INSTANCE if that VC is destroyed,
(or an alternate INSTANCE is swapped in)
As well as these there are entry points to methods to allow the INSTANCE to
do it's work.
typedef long int externalchar;
typedef long int internalchar;
typedef long int attributes;
typedef unsigned char scancode; /* short? */
typedef int status;
/* Each VC has one of these that identifies each INSTANCE that makes it up */
struct virt_cons
{
struct virt_cons *next;
struct c_baseobj *ext_int;
struct c_baseobj *term;
struct c_baseobj *kbd_map
struct c_baseobj *font;
struct c_baseobj *vs;
struct c_baseobj *renderer;
};
All the INSTANCES point to DERIVED CLASSES
ALL the DERIVED CLASS structures contain the following information:
These are the STANDARD ENTRIES and in C++ would be inherrited from the BASE
CLASS
char *name;
status (print*)(struct c_baseobj *); /* print out an instance */
status (delete*)(struct c_baseobj *); /* delete an instance */
status (create*)(struct c_baseobj **); /* delete an instance */
as well as specialist methods (shown below)
/*
* the central struct for the translation module that translates the
* internal code to whatever charater set the user wants to recieve data in.
* Defines methods to translate incoming and outgoing data.
*/
struct extern_intern /* may need changing to suport multi-length codes */
{
STANDARD ENTRIES plus:
internalchar (fromuser*)(struct extern_intern *,externalchar);
externalchar (fromte*)(struct extern_intern *,internalchar);
};
/*
* Methods and data for the terminal emulator, including:
* a method to call with data from the user,
* a method to call with data from the keyboard,
*/
struct term_emul
{
STANDARD ENTRIES plus:
status (fromuser*)(struct term_emul *,internalchar);
status (fromkbd*)(struct term_emul *,internalchar);
};
/*
* Methods and data for an object that translates scancode type data
* from the keyboard, into internalchar form.
* (Handles shift, meta, cntrl, alt etc.)
*/
struct kbd_map
{
STANDARD ENTRIES plus:
internalchar (fromkbd*)(struct kbd_map *,scancode);
};
/*
* Methods and data for a particular font,
* Including methods that return a pointer to a bitmap given an internalchar,
* or given a font position, returns the internalchar it represents.
*/
struct font_type
{
STANDARD ENTRIES plus:
int (mapchar*)(struct font_type *,internalchar);
status (mapglyph*(struct font_type *,int,internalchar *);
int height,width,number;/* what if 'variable' sized? */
};
/*
* Methods and data for the hardware independent virtual screens
*/
struct virt_screen
{
STANDARD ENTRIES plus:
status (drawchar*)(struct virt_screen *,internalchar,
attributes,int,int);
status (drawmany*)(struct virt_screen *,internalchar *,
attributes *,int x,int y,int n);
status (setsize*)(struct virt_screen *,int x,int y); /* x,y */
internalchar (returnchar)(struct virt_screen *,int x,int y,attribute *);
/* the scrolls start at the {row/column} in the 2nd arg */
status (scrollup*)(struct virt_screen *,int);
status (scrolldown*)(struct virt_screen *,int);
status (scrollleft*)(struct virt_screen *,int);
status (scrollright*)(struct virt_screen *,int);
status (refresh*)(struct virt_screen *); /* tell VS */
/* to redraw entire screen, using renderer commands*/
};
/*
* Methods and data for the hardware specific 'driver'
*/
struct renderer
{
STANDARD ENTRIES plus:
status (drawchar*)(struct renderer *, internalchar,
attributes,int x,int y);
status (drawmany*)(struct renderer *, internalchar *,
attributes *,int x,int y,int n);
/* the scrolls start at the {row/column} in the 2nd arg */
status (scrollup*)(struct renderer *,int);
status (scrolldown*)(struct renderer *,int);
status (scrollleft*)(struct renderer *,int);
status (scrollright*)(struct renderer *,int);
status (setmode*)(struct renderer *);/* on VC switch to us */
char *modename; /* e.g. "80x25x9x15" or "640x480x256"*/
status (setnewmode*)(struct renderer *,mode);
char *(listmodes*)(struct renderer *);
status (addmode*)(struct renderer *,script);
status (loadfont*)(struct renderer *);
};
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95.980805163541.19956A-100000>
