diff --git a/docs/manual.docx b/docs/manual.docx index 16ac025..140736a 100644 Binary files a/docs/manual.docx and b/docs/manual.docx differ diff --git a/docs/quickstart.md b/docs/quickstart.md index 9191322..fb18e8e 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,6 +1,6 @@ # Tek4010 Quick Start -This is a Tektronix 4010 graphics terminal emulator. +This is a Tektronix 4010/4014 graphics terminal emulator. It is not a full VT100/xterm terminal. Basic usage: @@ -38,6 +38,43 @@ detects slow graphics response. This may take a while. --- +## Keyboard + +The following keys are handled locally by tek4010 and are not passed +to the child process or remote system. + +Clear screen + + Mac: Fn-Left Arrow + Linux: Home + Windows: Home + +Break + + Mac: Left Option-B + Linux: Alt-B + Windows: Alt-B + +Quit + + Window close button + Fullscreen mode: Left Option-Q / Alt-Q + +APL mode (only if APL support enabled) + + Left Option-N switch to APL character set + Left Option-O switch back to normal character set + +History convenience + + Up Arrow previous command + Down Arrow next command + +All normal ASCII keys and control characters (Ctrl-C, Ctrl-D, etc.) +are passed through unchanged. + +--- + ## Options By default, the screen clears automatically when the bottom is reached. diff --git a/src/main.c b/src/main.c index 9daf855..fdd97b9 100755 --- a/src/main.c +++ b/src/main.c @@ -99,6 +99,12 @@ long now_msec(void) return tv.tv_sec * 1000L + tv.tv_usec / 1000L; } +void main_finished() +{ + printf("tek4010 - finished"); + gtk_window_set_title(GTK_WINDOW(window), "tek4010 - finished"); +} + void check_graphics_response(long lag) { static int slowCount = 0; @@ -249,13 +255,11 @@ static void do_drawing(cairo_t *cr, GtkWidget *widget) static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { - int ch; + int ch; + // printf("key pressed, state =%04X, keyval=%04X, isGinMode = %d\r\n", event->state, event->keyval, isGinMode); - if ((event->keyval == 0xFF50) || // "home" key - (event->keyval == 0xFF55) || // "page up" key - (event->keyval == 0xFF56)) // "page down" key - { + if (event->keyval == 0xFF50) { // "home" key, use fn on Mac tube_doClearPersistent = 1; gtk_widget_queue_draw(widget); return; @@ -263,55 +267,46 @@ static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_da if (event->keyval == 0x8BF) { // "option b" sends break code to target if (putKeys) { - // printf("sending break code\n"); - if (argPty) - tcsendbreak(fileno(putKeys), 0); - else { - putc(0xFF, putKeys); - putc(0xF3, putKeys); - } - fflush(putKeys); + // printf("sending break code\n"); + tcsendbreak(fileno(putKeys), 0); } } + + // alt/option keys: local tek4010 functions + else if (event->state & GDK_MOD1_MASK) { + + if ((event->keyval == 0x0071) || // Alt-Q + (event->keyval == 0x13BD)) { // Mac left Option-Q + on_quit_event(); + return; + } + else if (argAPL && + ((event->keyval == 0x006E) || // Alt-N + (event->keyval == 0x02DC))) { // Mac left Option-N + aplMode = 1; + return; + } + else if (argAPL && + ((event->keyval == 0x006F) || // Alt-O + (event->keyval == 0x00F8))) { // Mac left Option-O + aplMode = 0; + return; + } + else if ((event->keyval == 0x0062) || // Alt-B + (event->keyval == 0x222B)) { // Mac left Option-B + tcsendbreak(fileno(putKeys), 0); + return; + } +} // control keys else if ((event->keyval >= 0xFF00) && (event->keyval <= 0xFF1F)) ch = event->keyval & 0x1F; - else if (event->state & GDK_CONTROL_MASK) { - if ((event->keyval == 0xFF51) || // "left arrow" key - (event->keyval == 0xFF52)) { // "up arrow" key - tube_doClearPersistent = 1; - gtk_widget_queue_draw(widget); - return; - } - else if (event->keyval == 0x0077) { // "w" makes screendump - system("scrot --focussed"); - return; - } - else if (event->keyval == 0x0071) { // "q" quits tek4010 - on_quit_event(); - return; - } - else if (argAPL && (event->keyval == 0x006E)) { // "n" switch to alternative character set - aplMode = 1; - // printf("Setting APL mode to 1 from keyboard\n"); - return; - } - else if (argAPL && (event->keyval == 0x006F)) { // "o" switch to normalcharacter set - aplMode = 0; - // printf("Setting APL mode to 0 from keyboard\n"); - return; - } - else - ch = event->keyval & 0x1F; - } - else if (event->keyval == 0xFF52) ch = 16; // arrow up for history up - else if (event->keyval == 0xFF54) ch = 14; // arrow down for history down - - else if ((event->state & GDK_MOD1_MASK) && (aplMode)) { // alt key - // printf("alt key, ch = %4X\n", event->keyval & 0x7F); - ch = (event->keyval & 0x7F) + 128; - } + + + // Up/Down arrows generate Ctrl-P/Ctrl-N for simple shell history navigation. + else if (event->keyval == 0xFF52) ch = 16; // Up -> Ctrl-P + else if (event->keyval == 0xFF54) ch = 14; // Down -> Ctrl-N // normal keys else if ((event->keyval >= 0x0020) && (event->keyval <= 0x007F)) @@ -338,17 +333,6 @@ static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_da } else { -/* if (ch == '\r') - printf("KEY \n"); - else if (ch == '\n') - printf("KEY \n"); - else if ((ch >= 32) && (ch < 127)) - printf("KEY %c\n", ch); - else - printf("KEY <%02X>\n", ch & 0xFF); - fflush(stdout); -*/ - putc(ch, putKeys); fflush(putKeys); } diff --git a/src/main.h b/src/main.h index 8f9fefb..0aa54ad 100644 --- a/src/main.h +++ b/src/main.h @@ -14,6 +14,7 @@ void tek4010_clicked(int x, int y); int tube_on_timer_event(); int tube_clicked(int button, int x, int y); void tube_quit(); +void main_finished(); void ards_draw(cairo_t *cr, cairo_t *cr2, int first); diff --git a/src/tube.c b/src/tube.c index f760554..b47cbf1 100755 --- a/src/tube.c +++ b/src/tube.c @@ -468,10 +468,10 @@ void tube_init(int argc, char* argv[]) exit(1); } else if (pid == 0) { - setenv("TERM", "vt100", 1); + setenv("TERM", "tek4014", 1); if (argPty) { - setenv("PS1", "tek4010$ ", 1); + // setenv("PS1", "tek4010$ ", 1); execl("/bin/sh", "sh", "-i", (char *) NULL); } else { @@ -545,6 +545,7 @@ int tube_on_timer_event() // is child process still running? + static int childFinishedShown = 0; int status; int childExited = 0; @@ -560,6 +561,11 @@ int tube_on_timer_event() printf("Process has been terminated\n"); exit(0); } + + if (!childFinishedShown) { + main_finished(); + childFinishedShown = 1; + } if (argWait) { if (firstWait == 0)