- make
TODO
+- Maybe cleanup code checking boundaries, using max or other similar
+ macros or inline functions.
- When blinking and double-underline, the line doesn't blink.
- Italics is currently mapped to inverse, like in rxvt.
- There's an apparent bug in utf8wc.c's utf8_split() function.
See L1 and L2 usage with strncpy(3).
- vt100 double line? $ printf '\033#3Foo\n\033#4Foo\n'
It seems that this is not used with modern terminfo/curses
- applications.
+ applications. Xterm itself appears to only support it with
+ certain fonts.
- Jump/fast scroll, smooth/slow scroll (one line at a time).
- h/l 1: Application Cursor Keys
- O_o, in xterm: \033[5 q , [1 q , [2 q , [3 q , [4 q , 5, 6...
- Cursor color '\033]12;green\007' quite interestingly labels work.
Numerics not always?
- Maybe line position relative/absolute (d/e vpa/vpr?)
-- Verify if in xterm when scrolling blank lines really have color
- disabled. Since pseudocolor support was added, vifm seems to have
- strange color problems in relation to scrolling.
- Confirmed that xterm uses the background color when creating blank
- spaces. Analogterm improved but still some oddities with vifm to
- fix, related to scrolling.
-- With the current pseudocolors impementation, the current cursor
- position in sc(1) is no longer visible... Ignoring black bg
- color improves things for now.
- Update: the cursor no longer uses text blinking support. The custom
- implementation fixes this.
- Now that pseudocolors are implemented, dialog(1) and possibly
other programs look strange.
- When under tmux/screen, dialog(1) attempts to use higher characters
rather than DEC Special Graphics. May perhaps be configurable...
-- When under tmux, dialog(1) no longer uses DEC Special Graphics.
Some programs also use those extended characters like wordgrinder.
-- Interestingly, since we're a monochrome terminal, when using
- "xterm" for $TERM tmux uses color for copy-paste text selection
- and appears to have no option to change that. On the other hand,
- if using "xtermm" for xterm-monochrome, tmux then correctly uses
- the inverse attribute. This also affects the status bar if colors
- are used. However, vim doesn't automatically switch to t_Co=0, and
- when told so, no longer behaves the same, it strangely no longer
- uses underline. When using dialog(1), the colors appear inversed
- with "xtermm". With "xtermm" dialog(1) also no longer uses DEC
- Special Graphics. Under Linux via ssh it seemingly attempts to use
- it unsuccessfully since the common chars like q are used, and it's
- in inverse mode. Verify if inverse works with the gfx mode. The
- terminfo entry explains everything. Apparently it's an unsupported
- historical variant.
- Various key sequences are not properly supported, smacs (DEC
- Special Graphics) issues ^N instead of \E(0, underline mode is
- unsupported, etc. Let's use xterm and simulate pseudocolors instead.
- It would still be interesting to carefully look at the entry to determine
+- It would still be interesting to carefully look at the entry to determine
what affects the behavior of applications, like determining if colors are
available or not. The "colors" terminfo entry depends on the terminfo entry
set in $TERM and is not a terminal-related code, only a number. This means
termcap/terminfo and applications degrade.
- Add explicit TERM setting, seems to be in generic xscreensaver
command handling code.
-- Maybe try to implement smooth scrolling and line/char delete/insert
- - xterm's line insert functionality seems to not be implemented yet
- (L). This explains why scrolling up in more/less fails and only
- updates the first row. Terminfo db has il1 and il <param>.
- Line insertion is basically reverse-scrolling starting at a
- particular offset and that can extend the wanted number of
- lines. The scrolling window should be restricted to the field
- if any is configured.
- - Plus there's rmir/smir to enable/disable automatic insert mode
- ([4l, [4h)...
- - Then kich1=\E[2~, the insert key.
+- Maybe implement smooth scrolling. This would be restricted to the case
+ where the cursor is at the bottom and one line is scrolled at a time only.
+ In screen/tmux, this means that the status bar must either be disabled or at
+ the top rather than at the bottom. It may still possibly behave oddly when
+ at top, to test. The analog overscan emulation interestingly allows to have
+ a sliding window if we use an offset that is reset when scrolling and that
+ the main loop redjusts gradually.
+ Well, perhaps that smooth scrolling in the other direction could also be
+ allowed under the same reverse conditions.
+- rmir/smir to enable/disable automatic insert mode ([4l, [4h)...
+- kich1=\E[2~, the insert key.
- Cleanup headerfile, removing unnecessary prototypes/definitions
-- Add common graphics characters to make frames. Lynx uses some
- to implement its scrollbar. Wordgrinder also uses some.
- This entry seems redundant.
- Maybe support read-only text/regions
- Maybe support text windows (?)
-- Delete acts like backspace but should delete
- This is inverted in utils/textclient.c textclient_putc()
- This entry seems redundant.
- Isolate code outside of xscreensaver, make a GNUmakefile.
Ironically the result will be more portable on common unix.
And much cleaner once consolidated.
implement or swallow. Also, xterm uses 0x9B too not only ESC.
- Tack seems to be a decent program for terminal testing, other
than vttest.
-- ninvaders is very slow and not very responsive. This could serve
- to work on some optimizations. It's also possible that it has
- to do with user input handling. When reducing refresh rate like
- with 0 delay using more CPU, it's more responsive.
- This should be configurable.
+- ninvaders has good animation but its input is very responsive.
+ This could serve to work on some optimizations.
+ Input handling could probably be improved and considered
+ prioritary. When increasing the refresh rate like with 0 delay
+ using more CPU, it's more responsive. This should be configurable.
+
+CONTROLS
From the xanalogtv man page:
Notable X resources supported include the following which correspond to
standard TV controls: analogTVTint, analogTVColor, analogTVBrightness,
oscillator."
https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Ntsc_channel.svg/800px-Ntsc_channel.svg.png
-$ hacks/analogterm -fast -geometry 1024x768 -program /bin/sh -tv-brightness 3 -tv-contrast 100
-$ hacks/analogterm -fast -geometry 1024x768 -program /bin/sh -tv-brightness 0 -tv-contrast 70
--geometry 1364x1024
-
+FONT
https://retrocomputing.stackexchange.com/questions/17312/did-any-european-computers-use-10-line-fonts
"The Videx Videoterm 80 column card for the Apple II (very different
from the 80 column display on the Apple //e) used an 6845 that had
sentiment of "to get 25 text lines, an 8x10 font would be ideal"
was not shared by everyone ... though you could have burned your
own EEPROM to get such a font."
-"
+
+VIM
+Vim can be told to not use color with :set t_Co=0 in which case it falls back
+to attributes like bold/underline/inverse. However, some functionality is
+lost. Unless t_Co=8 or over, :hi MatchParen cterm=underline for instance
+still doesn't work. This means that for ideal vim support, a colorscheme
+designed for monochrome helps.
+
+
+USAGE EXAMPLES
+
+hacks/analogterm -fast -geometry 1024x768 -program /bin/sh -tv-brightness 3 -tv-contrast 100
+hacks/analogterm -fast -geometry 1024x768 -program /bin/sh -tv-brightness 0 -tv-contrast 70
hacks/analogterm -fast -geometry 1364x1024 -program /bin/sh -tv-color 10
-1152x921 is approx 12" 5/4 on a 24" monitor
912x720 is approx 12" 5/4 old display on a modern 24" monitor.
hacks/analogterm -fast -geometry 1364x1024 -program /bin/sh -tv-color 0
hacks/analogterm -fast -geometry 1364x1024 -program /bin/sh -tv-color 0 -tv-brightness 2 -tv-contrast 140 -del -bs
hacks/analogterm -geometry 1364x1024 -bs
-stty then often useful to set ERASE properly (to fix).
+stty erase ^H then often useful to set ERASE properly (to fix).
* CPU time. Then 1 and over immediately affect performance.
* Running cursor effects are also more noticeable at 5000 and lower.
* This should be user-configurable.
+ * After more changes it is unclear if 0 gives better performance, sometimes
+ * it seems to be the contrary.
*/
return /*5000*//*20000*/1; /* Note: use 0 for faster response like for games */
#endif
void
at_clear(analogterm_state_t *st, int x, int y, int len)
{
- int f, t;
uint16_t *mptr, *tptr;
(void)memset(&st->textlines_char[y][x], ' ', len);
* XXX
* - This memory design is very inefficient
* - Should probably use a well-defined range instead of full cycle
- * - Blinking speed should rely in a configurable timer
+ * - Blinking speed should rely on a configurable timer
*/
for (y = 0; y < 8; y++) {
pp = &sim->inp->signal[(ANALOGTV_TOP+3) + (8 * st->cursy) + y]
{
int y;
+ /* XXX */
+ /*
+ if (st->cursy == 24 && offset == -1)
+ (void)fprintf(stderr, "Smooth scroll possible.\n");
+ */
+
/* Nothing to do */
if (offset == 0)
return;
if (c == '\n') /* ^J == NL */
{
- if (st->cursy==st->scroll_bottom)
+ if (st->cursy == st->scroll_bottom)
{
if (scroll_p)
at_scroll(st);
{
st->cursy++;
}
- st->cursx=0;
+ st->cursx = 0;
}
else if (c == 014) /* ^L == CLS, Home */
{
at_cls(st);
- at_goto(st,0,0);
+ at_goto(st, 0, 0);
}
else if (c == '\t') /* ^I == tab */
{
- at_goto(st, st->cursy, (st->cursx+8)&~7);
+ at_goto(st, st->cursy, (st->cursx + 8) & ~7);
}
else if (c == 010) /* ^H == backspace */
- /* XXX May not behave standardly, to check. Could use at_clear(). */
+ /* XXX May not behave standardly, to check. */
{
- st->textlines_char[st->cursy][st->cursx] = ' ';
- st->textlines_mode[st->cursy][st->cursx] = m & TMODE_BGCOLOR;
- at_goto(st, st->cursy, st->cursx-1);
+ at_clear(st, st->cursx, st->cursy, 1);
+ at_goto(st, st->cursy, st->cursx - 1);
}
else if (c == '\r') /* ^M == CR */
{
- st->cursx=0;
+ st->cursx = 0;
}
else
{
st->textlines_char[st->cursy][st->cursx] = c;
st->textlines_mode[st->cursy][st->cursx] = m;
st->cursx++;
- if (st->cursx==80) {
- if (st->cursy==st->scroll_bottom) {
+ if (st->cursx == 80) {
+ if (st->cursy == st->scroll_bottom) {
if (scroll_p)
at_scroll(st);
} else {
st->cursy++;
}
- st->cursx=0;
+ st->cursx = 0;
}
}
}
#include "images/analogtermfont.xbm"
#include "images/analogtermgfxfont.xbm"
-static void
-at_make_font(analogterm_sim_t *sim)
-{
- Pixmap text_pm = XCreatePixmapFromBitmapData (sim->dpy, sim->window,
- (char *) analogterm_font_bits,
- analogterm_font_width,
- analogterm_font_height,
- 1, 0, 1);
- if (analogterm_font_width != 96*7) abort();
- if (analogterm_font_height != 8) abort();
- sim->text_im[0] = XGetImage(sim->dpy, text_pm, 0, 0,
- analogterm_font_width, analogterm_font_height,
- ~0L, ZPixmap);
- XFreePixmap(sim->dpy, text_pm);
-}
+/*
+ * XXX So many contortions just to get at the bits, that we could probably
+ * directly use from the bits ourselves... In any case, this does the
+ * preconversion at initialization for now.
+ */
static void
-at_make_font_gfx(analogterm_sim_t *sim)
+at_make_font(analogterm_sim_t *sim, int fi, char *bits, unsigned int width,
+ unsigned int height)
{
- Pixmap text_pm = XCreatePixmapFromBitmapData (sim->dpy, sim->window,
- (char *) analogtermgfx_font_bits,
- analogtermgfx_font_width,
- analogtermgfx_font_height,
- 1, 0, 1);
- if (analogtermgfx_font_width != 96*7) abort();
- if (analogtermgfx_font_height != 8) abort();
- sim->text_im[1] = XGetImage(sim->dpy, text_pm, 0, 0,
- analogtermgfx_font_width, analogtermgfx_font_height,
- ~0L, ZPixmap);
- XFreePixmap(sim->dpy, text_pm);
+ Pixmap pm;
+ XImage *xi;
+ unsigned long (*f)[8][7];
+ int c, r, b;
+
+ assert(width == 96 * 7 && height == 8);
+
+ pm = XCreatePixmapFromBitmapData(sim->dpy, sim->window, bits, width,
+ height, 1, 0, 1);
+ xi = XGetImage(sim->dpy, pm, 0, 0, width, height, ~0L, ZPixmap);
+ (void)XFreePixmap(sim->dpy, pm);
+
+ /* Fill structure element with font data */
+ f = sim->text_font[fi];
+ for (c = 0; c < 96; c++) {
+ for (r = 0; r < 8; r++) {
+ for (b = 0; b < 7; b++)
+ f[c][r][b] = XGetPixel(xi, (c * 7) + b, r % 8);
+ }
+ }
+
+ /* Strange freeing procedure */
+ free(xi->data);
+ xi->data = NULL;
+ XDestroyImage(xi);
}
analogterm_sim_t *
sim->st->scroll_top = 0;
sim->st->scroll_bottom = 24; /* XXX Use definition/macro */
- at_make_font(sim);
- at_make_font_gfx(sim);
+ at_make_font(sim, 0, analogterm_font_bits, analogterm_font_width,
+ analogterm_font_height);
+ at_make_font(sim, 1, analogtermgfx_font_bits, analogtermgfx_font_width,
+ analogtermgfx_font_height);
sim->stepno=0;
at_goto(sim->st,24,0);
XClearWindow(sim->dpy, sim->window);
- /* free sim */
- /* This is from at_make_font */
- free(sim->text_im[0]->data);
- sim->text_im[0]->data = 0;
- XDestroyImage(sim->text_im[0]);
- free(sim->text_im[1]->data);
- sim->text_im[1]->data = 0;
- XDestroyImage(sim->text_im[1]);
-
- /* And free else */
+ /* Free sim and else */
analogtv_release(sim->dec);
free(st);
free(sim->inp);
analogtv_setup_sync(sim->inp, /* XXX 1 */0, 0);
analogtv_setup_frame(sim->dec);
- for (textrow=0; textrow<25; textrow++) {
+ for (textrow = 0; textrow < 25; textrow++) {
int row;
- for (row=textrow*8; row<textrow*8+8; row++) {
+ int rowmul = textrow * 8;
+
+ for (row = rowmul; row < rowmul + 8; row++) {
signed char *pp;
int col;
- int lastrow = row == textrow * 8 + 7;
- int midrow = row == textrow * 8 + 3;
+ int lastrow = row == rowmul + 7;
+ int midrow = row == rowmul + 4;
+ int rowm = row % 8;
/* First we generate the pattern that the video circuitry shifts out
of memory. It has a 14.something MHz dot clock, equal to 4 times
Each character position, or byte in hires, defines 14 dots, so odd
and even bytes have different color spaces. So, pattern[0..600]
gets the dots for one scan line. */
- /* With 25 lines the offset was changed to 3 to avoid loss */
- pp=&sim->inp->signal[row+ANALOGTV_TOP+/*4*/3][ANALOGTV_PIC_START+100];
- for (col=0; col<80; col++) {
+ /*
+ * With 25 lines the offset was changed from 4 to 3 to avoid loss
+ * XXX Interestingly the signal appears to start low enough end end
+ * high enough that it would be possible to implement smooth scrolling
+ * by sliding a window.
+ */
+ pp=&sim->inp->signal[row + ANALOGTV_TOP + 3][ANALOGTV_PIC_START + 100];
+ for (col = 0; col < 80; col++) {
int rev, level, olevel, iblink;
- int c = st->textlines_char[textrow][col] & 0xff; /* XXX */
+ int c = st->textlines_char[textrow][col];
uint16_t m = st->textlines_mode[textrow][col];
- XImage *im = sim->text_im[(m & TMODE_GFX) != 0 ? 1 : 0];
+ unsigned long (*f)[8][7] =
+ sim->text_font[(m & TMODE_GFX) != 0 ? 1 : 0];
+ unsigned long (*cf)[7];
rev = ((m & (TMODE_INVERSE | TMODE_BGCOLOR)) != 0);
else
iblink = 0;
+ /* XXX Restricts to ASCII/DEC Special Graphics */
+ if (c < 32 || c > 126)
+ c = /* XXX originally space 32 */95;
+ else
+ c -= 32;
+ cf = f[c];
+
/*
* Font is 96 7x8 glyphs including embedded spacing.
* Virtual resolution is 280x192 but at 80 columns it gives a less
* the IBM 3270 one). This would however require a 720x350
* resolution.
*/
- for (i=0; i<7; i++) {
- unsigned long pix;
+ for (i = 0; i < 7; i++) {
+ unsigned long *cb = cf[rowm], pix;
- if (c < 32 || c > 126)
- c = 32;
if ((m & TMODE_INVISIBLE) != 0)
pix = 0;
else
- pix = XGetPixel(im, (c - 32) * 7 + i, row % 8);
+ pix = cb[i];
if (lastrow &&
(m & (TMODE_UNDERLINE | TMODE_DUNDERLINE)) != 0) {
Display *dpy;
Window window;
XWindowAttributes xgwa;
- XImage *text_im[CHARSETS];
+ unsigned long text_font[CHARSETS][96][8][7];
struct timeval basetime_tv;
double curtime;