diff --git a/main.c b/main.c index da15b86..c720c43 100644 --- a/main.c +++ b/main.c @@ -45,6 +45,7 @@ #include #include "main.h" +#include "tube.h" extern FILE *putKeys; @@ -156,7 +157,7 @@ static void do_drawing(cairo_t *cr, GtkWidget *widget) static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { int ch; - // printf("key pressed, state =%04X, keyval=%04X\r\n", event->state, event->keyval); + // 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 @@ -196,8 +197,13 @@ static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_da ch = event->keyval & 0x7F; else return; + + if (isGinMode) { // need to pass key to GIN mode handling, not to child process + isGinMode = ch; + gtk_widget_queue_draw(widget); + } - if (putKeys) + else if (putKeys) putc(ch,putKeys); // pipe key to child process, if stream open } diff --git a/main.h b/main.h index 4ecb85a..89bdcf1 100644 --- a/main.h +++ b/main.h @@ -3,6 +3,7 @@ void tube_init(int argc, char* argv[]); void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first); +void tek4010_clicked(int x, int y); int tube_on_timer_event(); int tube_clicked(int button, int x, int y); void tube_quit(); diff --git a/tek4010 b/tek4010 index 6bb838e..5d72464 100755 Binary files a/tek4010 and b/tek4010 differ diff --git a/tek4010.c b/tek4010.c index aa34fdc..2d01a2d 100755 --- a/tek4010.c +++ b/tek4010.c @@ -62,12 +62,14 @@ // // mode 40 incremental plot mode; is ignored until exit from incremental plot received // mode 50 special point plot mode; not yet implemented +// mode 60 crosshair mode // mode 101 ignore until group separator int mode, savemode; int penDown = 1; extern int leftmargin; +extern FILE *putKeys; static long startPaintTime; static int xh,xl,yh,yl,xy4014; @@ -105,13 +107,65 @@ void tek4010_checkLimits() void tek4010_bell() { - // bell function, delay 0.1 sec + // bell function, delay 0.05 sec tube_u100ResetSeconds(1); usleep(50000); showCursor=0; todo = 0; } +void sendCoordinates() +{ + // send 4 coordinate bytes + putc((tube_x0 >> 5) + 0xa0,putKeys); + putc((tube_x0 & 31) + 0xa0,putKeys); + putc((tube_y0 >> 5) + 0xa0,putKeys); + putc((tube_y0 & 31) + 0xa0,putKeys); +} + +void enqMode() +{ + // activated by sending ESC ENQ + int status; + status = 0xa0; + if (leftmargin == 0) status += 2; + if (mode == 0) status += 4; + putc(status,putKeys); // send status byte + sendCoordinates(); + putc(13 + 128, putKeys); // cr, bit 8 set + // cannot send a EOT here +} + +void ginMode(cairo_t *cr, cairo_t *cr2) +{ + // activated by sending ESC SUB + if (DEBUG) printf("GIN, mode = %d\n", mode); + tube_crosshair(cr, cr2); + mode = 60; + todo = 0; + showCursor = 0; + isGinMode = 1; +} + +void ginSend(int ch) +{ + // user has stoken a key during GIN mode + if (DEBUG) printf("ginSend, ch = %d\n", ch); + putc(ch + 128,putKeys); + sendCoordinates(); + putc(13+128,putKeys); // cr, bit 8 set + // cannot send a EOT here +} + +void tek4010_clicked(int x, int y) +{ + if (DEBUG) printf("Clicked, mode = %d\n", mode); + if (mode == 60) { + tube_x0 = x; + tube_y0 = y; + } +} + void tek4010_escapeCodeHandler(cairo_t *cr, cairo_t *cr2, int ch) // handle escape sequencies, see 4014 user manual, table page G-1 // codes identical for all modes are handled elsewhere @@ -120,8 +174,7 @@ void tek4010_escapeCodeHandler(cairo_t *cr, cairo_t *cr2, int ch) case 0: break; // ignore filler 0 case 5: // ENQ: ask for status and position - // not yet implemented, needs to send 7 bytes - if (DEBUG) printf("ENQ not supported, ignored\n"); + enqMode(); mode = 0; break; case 6: break; @@ -153,8 +206,7 @@ void tek4010_escapeCodeHandler(cairo_t *cr, cairo_t *cr2, int ch) case 23: system("scrot --focussed"); mode= 0; break; case 26: // sub - if (DEBUG) printf("GIN mode not supported, ignored\n"); - mode = 0; + ginMode(cr, cr2); break; // modes 27 and 29 - 31 are identical in all modes @@ -276,7 +328,7 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) todo = 4 * TODO; // for text speed else todo = TODO; - + do { ch = tube_getInputChar(); @@ -286,7 +338,7 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) if (ch == -1) { if ((mode == 0) && showCursor) tube_doCursor(cr2); - return; // no char available, need to allow for updates + if (mode != 60) return; // no char available, need to allow for updates } if (DEBUG) { @@ -517,7 +569,17 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) intensity = intensityTable[ch - 32]; if (DEBUG) printf("defocussed = %d, intensity = %d%%\n", defocussed, intensity); mode = 5; // coordinates follow - break; + break; + case 60:// crosshair mode + if (isGinMode > 1) { // key stroken by user + ginSend(isGinMode); + mode = 0; + todo = 0; + isGinMode = 0; + } + else + ginMode(cr, cr2); + break; case 101: if (DEBUG) printf("Ignore until group separator, ch = %02x\n", ch); if (ch == 29) mode = 1; diff --git a/tube.c b/tube.c index 4b0ed70..8782873 100755 --- a/tube.c +++ b/tube.c @@ -74,6 +74,7 @@ double dashset[] = {2,6,2,2,6,3,3,3,6,6}; int plotPointMode = 0; // plot point mode int writeThroughMode = 0; // write through mode +int isGinMode = 0; // set if GIN mode is active int tube_doClearPersistent; int specialPlotMode = 0; @@ -178,7 +179,7 @@ void tube_init(int argc, char* argv[]) char *argv2[20]; size_t bufsize = 127; int firstArg = 1; - printf("tek4010 version 1.2.5\n"); + printf("tek4010 version 1.2.6\n"); windowName = "Tektronix 4010/4014 emulator"; if ((argc<2) || (argc>19)) { printf("Error:number of arguments\n"); @@ -377,7 +378,12 @@ int tube_clicked(int button, int x, int y) // x and y are the coordinates // if the function returns 1, the window is redrawn by calling applicatin_draw { - return 1; + if (argARDS) return 0; + if (button == 1) { + tek4010_clicked(x, y); + return 1; + } + return 0; } void tube_quit() @@ -534,6 +540,18 @@ void tube_drawPoint(cairo_t *cr, cairo_t *cr2) isBrightSpot = 1; } +void tube_crosshair(cairo_t *cr, cairo_t *cr2) +{ + // printf("crosshair at %d,%d\n", tube_x0, tube_y0); + cairo_set_line_width (cr2, 1); + cairo_set_source_rgb(cr2, 0.0, WRITE_TROUGH_INTENSITY, 0.0); + cairo_move_to(cr2, tube_x0, 0); + cairo_line_to(cr2, tube_x0, windowHeight); + cairo_move_to(cr2, 0, tube_y0); + cairo_line_to(cr2, windowWidth, tube_y0); + cairo_stroke (cr2); +} + void tube_drawVector(cairo_t *cr, cairo_t *cr2) { if (DEBUG) { diff --git a/tube.h b/tube.h index 23b695a..c92ccb0 100644 --- a/tube.h +++ b/tube.h @@ -19,6 +19,7 @@ extern long refreshCount; extern int showCursor; // set of cursor is shown (not set in graphics mode) extern int isBrightSpot; // set if there is currently a bright spot on the screen +extern int isGinMode; // set if GIN mode is active extern int specialPlotMode; extern int defocussed; @@ -37,6 +38,7 @@ extern void tube_clearSecond(cairo_t *cr2); extern int tube_isInput(); extern int tube_getInputChar(); extern void tube_emulateDeflectionTime(); +extern void tube_crosshair(cairo_t *cr, cairo_t *cr2); extern void tube_drawVector(cairo_t *cr, cairo_t *cr2); extern void tube_drawCharacter(cairo_t *cr, cairo_t *cr2, char ch); extern void tube_drawPoint(cairo_t *cr, cairo_t *cr2); diff --git a/versions.txt b/versions.txt index 5c38312..9ec28f0 100644 --- a/versions.txt +++ b/versions.txt @@ -1,3 +1,8 @@ +Version 1.2.6 April 26, 2019 +============================ +New features +- GIN mode added, Tek4014 emulation is now complete + Version 1.2.5 April 19, 2019 ============================ Bug fixes