diff --git a/LICENSE b/LICENSE index 008e290..679dea4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Matthew R. Wilson +Copyright (c) 2020, 2025 Matthew R. Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/example1/example1.go b/example1/example1.go index b4dbd73..835b904 100644 --- a/example1/example1.go +++ b/example1/example1.go @@ -9,6 +9,7 @@ import ( "net" "os" "strings" + "time" "github.com/racingmars/go3270" ) @@ -63,6 +64,11 @@ var screen2 = go3270.Screen{ {Row: 22, Col: 0, Content: "PF3 Exit"}, } +var goodbyeScreen = go3270.Screen{ + {Row: 0, Col: 27, Intense: true, Content: "3270 Example Application"}, + {Row: 2, Col: 0, Content: "Thank you using this application. Goodbye."}, +} + func main() { ln, err := net.Listen("tcp", ":3270") if err != nil { @@ -111,6 +117,8 @@ mainLoop: // If the user pressed PF3, exit if response.AID == go3270.AIDPF3 { + go3270.ShowScreenNoResponse(goodbyeScreen, nil, 0, 0, conn) + time.Sleep(2 * time.Second) break mainLoop } @@ -159,6 +167,8 @@ mainLoop: // If the user pressed PF3, exit if response.AID == go3270.AIDPF3 { + go3270.ShowScreenNoResponse(goodbyeScreen, nil, 0, 0, conn) + time.Sleep(2 * time.Second) break } diff --git a/screen.go b/screen.go index 1d4e107..8f75b22 100644 --- a/screen.go +++ b/screen.go @@ -1,6 +1,6 @@ // This file is part of https://github.com/racingmars/go3270/ -// Copyright 2020 by Matthew R. Wilson, licensed under the MIT license. See -// LICENSE in the project root for license information. +// Copyright 2020, 2025 by Matthew R. Wilson, licensed under the MIT license. +// See LICENSE in the project root for license information. package go3270 @@ -106,10 +106,47 @@ type fieldmap map[int]string // field. The values map may be nil if no overrides are needed. After writing // the fields, the cursor is set to crow, ccol, which are 0-based positions: // row 0-23 and col 0-79. Errors from conn.Write() are returned if -// encountered. +// encountered. ShowScreen will wait for the client to provide data before +// returning, and the data from the client will be returned as a Response. func ShowScreen(screen Screen, values map[string]string, crow, ccol int, conn net.Conn) (Response, error) { + fm, err := showScreenInternal(screen, values, crow, ccol, conn) + if err != nil { + return Response{}, err + } + + response, err := readResponse(conn, fm) + if err != nil { + return response, err + } + + // Strip leading+trailing spaces from field values + for _, fld := range screen { + if !fld.KeepSpaces { + if _, ok := response.Values[fld.Name]; ok { + response.Values[fld.Name] = + strings.TrimSpace(response.Values[fld.Name]) + } + } + } + + return response, nil +} + +// ShowScreenNoResponse writes the screen to the connection, just like +// ShowScreen(), but immediately returns instead of waiting for data +// from the client. +func ShowScreenNoResponse(screen Screen, values map[string]string, + crow, ccol int, conn net.Conn) error { + + _, err := showScreenInternal(screen, values, crow, ccol, conn) + return err +} + +func showScreenInternal(screen Screen, values map[string]string, + crow, ccol int, conn net.Conn) (fieldmap, error) { + var b bytes.Buffer var fm = make(fieldmap) // field buffer positions -> name @@ -162,25 +199,10 @@ func ShowScreen(screen Screen, values map[string]string, crow, ccol int, // Now write the datastream to the writer, returning any potential error. debugf("sending datastream: %x\n", b.Bytes()) if _, err := conn.Write(b.Bytes()); err != nil { - return Response{}, err + return nil, err } - response, err := readResponse(conn, fm) - if err != nil { - return response, err - } - - // Strip leading+trailing spaces from field values - for _, fld := range screen { - if !fld.KeepSpaces { - if _, ok := response.Values[fld.Name]; ok { - response.Values[fld.Name] = - strings.TrimSpace(response.Values[fld.Name]) - } - } - } - - return response, nil + return fm, nil } // sba is the "set buffer address" 3270 command.