From 1212b2cceb358db00a6558ce70b62cf4eb8eb7fb Mon Sep 17 00:00:00 2001 From: Rudi Date: Fri, 21 Aug 2026 16:32:48 -0400 Subject: [PATCH] Add tn3270(no e) and fix animations --- README.md | 9 +- build/j3270/org/pubvm/j3270/J3270App$1.class | Bin 960 -> 960 bytes build/j3270/org/pubvm/j3270/J3270App$2.class | Bin 3088 -> 3088 bytes build/j3270/org/pubvm/j3270/J3270App.class | Bin 20394 -> 21193 bytes .../org/pubvm/j3270/config/Settings.class | Bin 11522 -> 11911 bytes .../org/pubvm/j3270/ui/ConnectDialog.class | Bin 7494 -> 7854 bytes .../org/pubvm/j3270/ui/TerminalPanel$1.class | Bin 2347 -> 2347 bytes .../org/pubvm/j3270/ui/TerminalPanel$2.class | Bin 689 -> 689 bytes .../org/pubvm/j3270/ui/TerminalPanel.class | Bin 25301 -> 25789 bytes .../org/lib3270j/ConnectionConfig.class | Bin 5382 -> 5966 bytes .../datastream/DataStreamProcessor.class | Bin 17822 -> 18288 bytes .../datastream/QueryReplyBuilder.class | Bin 8573 -> 8590 bytes .../org/lib3270j/screen/ScreenBuffer.class | Bin 7189 -> 8178 bytes .../lib3270j/telnet/TelnetConnection.class | Bin 7262 -> 7231 bytes .../telnet/TelnetFSM$TN3270ESubmode.class | Bin 1287 -> 1287 bytes .../org/lib3270j/telnet/TelnetFSM.class | Bin 17208 -> 19415 bytes .../main/java/org/pubvm/j3270/J3270App.java | 43 ++-- .../java/org/pubvm/j3270/config/Settings.java | 18 +- .../org/pubvm/j3270/ui/ConnectDialog.java | 19 +- .../org/pubvm/j3270/ui/TerminalPanel.java | 58 +++--- .../java/org/lib3270j/ConnectionConfig.java | 49 +++-- .../datastream/DataStreamProcessor.java | 149 +++++++------ .../datastream/QueryReplyBuilder.java | 18 +- .../graphics/ProgramSymbolManager.java | 110 +++++++--- .../lib3270j/graphics/ProgramSymbolSet.java | 61 ++++++ .../org/lib3270j/screen/ScreenBuffer.java | 50 ++++- .../org/lib3270j/telnet/TelnetConnection.java | 4 +- .../java/org/lib3270j/telnet/TelnetFSM.java | 195 +++++++++++++++--- .../datastream/QueryReplyBuilderTest.java | 80 ++++++- .../lib3270j/graphics/GraphicsModeTest.java | 6 +- .../graphics/ProgramSymbolManagerTest.java | 27 ++- 31 files changed, 698 insertions(+), 198 deletions(-) diff --git a/README.md b/README.md index f2e8b81..e706762 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,11 @@ java -jar j3270.jar -s mainframe.example.com 992 # Or using standard x3270 L: prefix java -jar j3270.jar L:mainframe.example.com:992 +# Connect via Plain TN3270 (Non-E) +java -jar j3270.jar -P mainframe.example.com 23 +# Or using standard x3270 P: prefix +java -jar j3270.jar P:mainframe.example.com:23 + # Connect with unverified/self-signed certificate verification bypass java -jar j3270.jar --tls --insecure mainframe.example.com 992 @@ -43,7 +48,7 @@ java -jar j3270.jar -c config.ini ## ✨ Features -- **TN3270 & TN3270E Protocol Support**: RFC 2355 compliant state machine, negotiation, Device-Type query, and SSL/TLS encryption. +- **TN3270 & TN3270E Protocol Support**: RFC 2355 compliant state machine, negotiation, Device-Type query, plain TN3270 fallback, and SSL/TLS encryption. - **SSL/TLS Security**: - Encrypted TN3270 over TLS connections on standard port `992` or custom ports. - Interactive certificate verification prompt for self-signed or untrusted certificates with fingerprint, subject, issuer, and validity inspection. @@ -71,7 +76,7 @@ The project includes self-contained, portable build scripts: # Build executable JAR in 2 seconds: sh ./build_all.sh -# Run all 48 automated unit tests in ~500ms: +# Run all 56 automated unit tests in ~500ms: sh ./test_all.sh ``` diff --git a/build/j3270/org/pubvm/j3270/J3270App$1.class b/build/j3270/org/pubvm/j3270/J3270App$1.class index 8ca98afbfd7d3548fa1daad88d0cae92998bace6..2b00d04c1b018919049bd7a246c2b7dc2ea919ec 100644 GIT binary patch delta 45 zcmX@Wet><$TP8;P$?urL1f3Yz8Jrme8C)2o8C)4u8Qdm^GF!2FGjKEbOrFB50{{<$TP8-k$?urL1RWXJ8Jrjd8JroU8C)1t8C)laGF!2FF>o_@PoBc80{{-d B3LXFe diff --git a/build/j3270/org/pubvm/j3270/J3270App$2.class b/build/j3270/org/pubvm/j3270/J3270App$2.class index 5113d3fcd68b2b38fd2ca82a055035b4e5ed598b..397f3f6f525c0dffc1d893a49eba9dde97d5356a 100644 GIT binary patch delta 121 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 literal 20394 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 diff --git a/build/j3270/org/pubvm/j3270/config/Settings.class b/build/j3270/org/pubvm/j3270/config/Settings.class index 80473947eeae9479dc14cde79b3c4706fa119c6e..4e44635a8248d7a91caec7e3e18dcd823622142e 100644 GIT binary patch literal 11911 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 CVVi&e literal 11522 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®h7fd`lF@{$H<6(yzW0B2L4sU5gnvMoiPx6hi0rK_!)n~6f zfEuseJbCXuxD_gco7%22o5wEXI&0F%{2X8dMbHS(M-qrlS`#(1)2Az$^@7HhzsccpYUp zg>r5R_u@S6<2>i$66WC=?#FdhPzox^f(4X@g_Ma!l!Gdoh{aThYAQwzm7l5?+g{Vzv*b=9Ff1#Vjr!<;0g2xBRGeAC;4<#IG zeZ1FxeJ}Fya+*G~wbwvDuhI0RVnCyr8qG;cuNl(4o|M=C>q9|0s797hjM<%H`5{39ZU!phpuKa=T$|=5Dr?DJwVGZ6!5bvOi@5mE4 zi#>P`dvOj2@II~L-LjB!11>XVEHzW^4UC~1F-&EVOSPKDCC@vXLm>vIa;)=SQ|{bs-I``__6qO$3Af^_Z2M*sVb6BO zZu@`Ah|lbj{-#Ji)suXx;*m!W=T;FCyZ#ud_z4s7r|ie?o1~v!H$B5tKF{jWmYA&D zA%^mcDhZA4W~5Ha8qQ2-Mmf)~xiy^BGffi9y$?=D7jtUKKG=1ACe?8Pdf{^KM-~eS zlTjQ;SF$t-?&NY(zz!Z`ocyEwHhPSU`8fB~Z=r&jQCE#84MK3`zvMqWOo1%O)XYv2 jZJ-d(6IhP&ZzFBuUt-lZy4uXEt&CDQp>4E-9)bG#7z3kyS3y_#l4!24G*c^b*vXgqxQ(7Ax~n@ VCR3^8)q*!=@2dJ%e1_j>`XAY2GiCq) delta 179 zcmWNKI}1T^07s8OZWeVHR#GM@DHdfhSY)**pFm7DB9ynTH{~slJ6w5{*vvi$v+Vx; z)^pBpFYjgTt=DCgkNy|RAyL3Y5i=z$lyOtRPn94w!qkb;AVHHXEwMI3IxOg-(&J2@ z2Lqmr6o=vEoM2~)iy2<#1OyjhNt_ia*5uiU?pF9a#;A%-(ySUr4#*twa1wuKqFhLF MCC!ZtcjYVj{#zt5^#A|> diff --git a/build/j3270/org/pubvm/j3270/ui/TerminalPanel$2.class b/build/j3270/org/pubvm/j3270/ui/TerminalPanel$2.class index c26fa2c1e00e46b0164e61e62672cdc1778672e3..5664c15b095cb0f92a0d71633c232425b9c55a48 100644 GIT binary patch delta 27 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 O7((P5@=f_Rxc?v1g*Rsa delta 8928 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 IYvdpP1M+Rvj{pDw literal 5382 zcmcgw?N=1n9eyq>%(4uyEG`7_J*cp-V#Hzv6BPtq1vG(RG&N>e1{hs-ad$wmX_J`R zq%UdO^d&KEZJMT~FKKI1A*t!xCqMLa|A6+Ko}SZ>{o2#kKEK(;Wrxvo%t?Fn?7egE z^Lys^e(&(d|J?i?fP?r$07WR);L}lpQib4IW6o$#7|F@@V`FE{xUEpS*GgLUBMQaM zEu&@dqfA3UM>%wbb*c1Zd%_y)*tvVh+4kO4GD#6DmE>%~npE)3q|&5Nu`*PmN<&ab zH9`sv1#%;1dfG}FiNVyknNSGCdIrysanG4u3Tp@M4(%3g*60WeWy!Qi%SxS&2T)JN z6SG6cw5bpp$XhjRr>*3qBiX29E!J_{yl9)radZ5jVH?~xjcKZUN~kvI*eHFCFyf|Se#k1z(2 zFFb1&pWw$%8x;XvP3FwB(ksZ^ zcgv_Bk0}%lbjkZhbUcnxW^Tqd(st&AWlt%DJvdva#1j-tIAW)CJc&q>O zig_62$5WI#+2zO69OoVBF&%O7Pr02MNL?_~y++3LL!!b|AyUeZS;m>gbbiv0a~w{K zy3;z6NGbT45w>9^GYX9>mF=A}(!=KYSu+_oyIW3)$ax)U5T{uzl#9nE$W29KvNbDK z%qi41$GlV*$VDCVxFi*6CMU%=Y$cBDGdezl&vGNqR~}%e5Z2xRp2PDRF6(#!pHryL zSFa@Vq*RlC#z<#OKHkO8F%6$r*pQbTnw=gq)BUORv|;yMjGHskrbM@wbbLW9D^D01 zJC?OBz?A%wjxXb7365z$?o_{McdBJHz*hE(j<1UEt0ql*IWb1&XH409Rmaz5uZDX) zjLFJK4h!1FvdPXq>)lV`9CkzVy`Vx|M&f~7=N9KL z&)2Y+JsNeG5U+K=m01p3m6c(u%{OcI6biYPYWZ4^ZmiJiwvI)0x7N)tlG&4{&1LvK zSi}pJRA)Hf^0`3bf(6Mhp0je|-f8~KI(h%9)iAL`tIh(}4$)rglGlZ;eyiIH%PqX% zNMNk1NLeVl&1Jc_q!?W>Y#Z@&gT_p*CRUbL_9z$jIGsS!c=>cVe!pem%HEv& z?p$MN)C2TK-^7GmZsuGC9T-l{rsHP6B}E)|%WjtrgiY)xMZ9lS@R#QtXGL;G4LO}Oi{G7W!RDn?otu`jZgrskFHp(5br@cxyp#~>Q;7|jx;U&|?dol5)2_{7JrbYvaF zk=MMR?gKO7{xx4u%{NfsxAqTy1nrxs{T6D!mD+D}eE)h*`p_MkY(S|5aV>>OlibFX&)^U{DEQ#E}zU!Q1 z>q<%&tQv(k@NND|8Ly|w(nd<1+|IiVcdwPa~` z5%oR1=|NlL*0z(N@8hjiw5-Gx$&jVpP1FxOolxth-9zZx-cG1>JE4o%AL3|Eg_TZd za64fyK|jLFIcVOubV7rh_Fd)`b+PSMclM8Vy}DV zZPe`qiR-)Gc^h@p4iNjEC+!Y5?GT~A@}}M4raeaN4J`6kDsrW7_qv_%C_zi$iR(a* z=888MX}txlbpfUMqqN95O65;6JOFuMj^G2%>QThc82@b%Re@&i2ESxUMt{{lLr!LB8|*r|oJYiJ2;BI_G}3+r=|S#Y#C zN9{<7H|k5mrELspn-kIsI;Kmj*TTLfe6e1W8^WLP7yK1hlu~u70av&p7pF^X=RCc5 zMLNTqg~2m=44YwM7bY0!N$kfI&kT!ySU5}6Im{u!kLYPUiy2(Td7dCPOMI4zJI9z^ z;9KVTo=f-}p26SwRs9csS1UZHD)GFk!)3LWAH=)xqUy#=PIkS9P-XeQQLmv_l~ml1CHZ~6 zk?Hr_JGni~CpibV@Nn$71-}f}`O|QfIe7y$OZdtH0@>NuB=@tvt#q!EuR!Bhx{g;J Td;KWZgZ)&3gz~q~BK-cpU4}r- diff --git a/build/lib3270j/org/lib3270j/datastream/DataStreamProcessor.class b/build/lib3270j/org/lib3270j/datastream/DataStreamProcessor.class index e6c94974e29565585509334bd27631a1a1ae979a..83744b6dd820f2ccc242c3ed4982b14a0e3d69f9 100644 GIT binary patch literal 18288 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 CZ;Fus diff --git a/build/lib3270j/org/lib3270j/datastream/QueryReplyBuilder.class b/build/lib3270j/org/lib3270j/datastream/QueryReplyBuilder.class index 1ffce09fc20872f40ba91d6bbd0fedc90525fb8e..481ce265614eb92ce160e05f2b66d1fea386b1c5 100644 GIT binary patch delta 4142 zcma)9dvsLA8UM|`Zgw+C?h^7?b~o9Ggs__hwFMF7kxfDpAbg0&O^EH6bUXp6MeM{PZ)r#+|V=s7+5NA*9eX!_0Ez1f>o&hebx znfV^`J%01e+?g*DyK8-Ke0laffI7Ul*SE)&Sg^Qp@AF297d`|y#vq@;HGjeUdJQ3l zuz1TEZuTLFG7b&pB&%wgutYK{IBt>*_r~t_-lPvYZsr(=N(R1SLwm=nMH@OhTf6(@ zj0wvUQeMR|0a0;+&Gb}r#4%C)mqk3caNLU9M7d*Z>YE&srGY$Upth~GyC>P(Bd6ZZ zF;z-@rlhN*t6Q?Caoj1{e#LHVU)|P0|K9estEF^0#|$YgP|}v+IyBHSN3*wH*~j(i;iMX9Y;MX#XlS+!3K^-+{Tcj=GU$2lt$-p%q4k&v((ef zF&_&=+*!HiZjP30f` zl!{xmQgMsBA`(Q3W2=gzw=2=to2=>XZtatyKFaYJE$@1FkZ+e}b}$rIH8qKkJw+8k z?39)B1cO$!EYXyyCbtaoDUPSHTU>LON59Xp7rSX?7u~aP;ewXM^>xedZdsnFSybk-|A#dZc+)dErw@lYUc|4D=V@1&_je4AWeJUR|CKYFT@h8@sqCs~ z^-jzGlMmPMXAN)4?A{WGz3;HUh(~-;*IyaR#8zLKxZ*2L5#qGb#^5FV1`J1N?7(k{ zK5CS;h^3hJtgkX9bIvn z#-re(b_TTpc$Q_?5J&A&2q~n0pFNT}iL`J`s^y^Sg+u|&7V{izTBOk!>( z2|XHn9a_wQX8^-P^rm{-iVDu0&0eF_C;@ioIRuyb9b_>)%@uI@u``WG zR1UUA(-@n^ctvcB21DUAViw&W4W%*3qPCOjH!NZY5mPMUaU$-ph@B~-?vfN`m&VL} z(3SD0h+S(bJsb7wv{1AEUu_?$HCbv0DWEjw*|qLf#txCzLQCr?5sNJ1SaeAm^fNOW zAkk8jNaNdT>Iq_f*OI4+SV_bH9tgP7SR-RTjkRad3kq+OPhrUZQQVe=3FrxWTR|+QQsm=M`Ejk+$V9*oqO8tram?2+wzMqM>w(8(7^k{ zoZ#INipMAwxx5C>4Oe_=grc?d2A)xhsUhEw4QX1<^^i{QGm5as5MCbmV?b?EG2uoApMdRd2^X@aM9yEVu+Jyg7p?gI66U z7a602CaB?}$SaI%bdgZyS5sJ48Hp9qo*vvnyE{fjCOg_ckyzXrKcB|q@?4{{MrVc}E_LGU5$_d-Mn(GF%ozNTYSxNTct)3}WQaGz zbseP?6@4Qv4Z;hL3YCJqL_bCc+ovccKXlbGy|OTz@X*X-(yLyWIhklnL;^0SYJ+;t z=1ejHS8!+)va>^eq*S^Amwl@4Qx*tKvgXGJHmfGj^q_Ysf$lXsPF*n6HpLxq6}jzR zie%+VP>0R~^TfUn#ef)Fv~&sG+cIc&QeN^KGo4Tzou=AT-H+O)%RDtobADVpkK59S zQx?j+DapVq7wYYzaVfe7nx-8m$TWS>9DZ|we!P!uR^Zi;)p@ku`^j!h8jq=rV!BKy zrm!&CN@gl(SzUc-D6t_sXNDO1xO9qG5?a%OAD_sv$5gx|J0;ZVTM&t5=5Li_eU@yq z9(4Om9=`Mru=7vS0lMX z3i*-@@{bN#v?D)amLm194Ls!~p`G}3fVb_)iqc)9<&JcNea^N~z0hkx){nSQy17VR zY1B1?tsx0L7?fl|pw1@QL=t)|D9NEfMJhW-TBB!xS&evts?kaIniUc`ghX?-Ownv? zo44B9yVYOGlu1^rCR_MqHcIy?u0UKS|edJy*8Un7Nfq zCS4RVv|cKQwlLyWY+t<}GZ8uEUi^4Wy+-dBh09&R$u`7ZBwXnIq9i+l9X81klF$oA zNwm$W6M;s1Om#}A zXO9dubWRWH`hLtcOI3bx2JpQ2tZeL9`XH%8p-62&Il13K-;k5`Z^*3jhRnUn@dakm zH-vpgS6PRAzo~@wmmjXqg767)aGCyQ{2!^a7PvZ!LfU^ChmPX`u`x1}?GdLUTN-y| vvZf64Rk7-H>kkpU6Nq|^xDLFI-z%vDed<4ZJwUEFz2___N5+KyF zph1IB1YXr*TdUTxVl9OvEMGQS1*_81s^y=~w4F}dKWaPe*qL^0MbmTc+n0SwrQ^)* zd-t5*x#!&TanHN=aOKAp-nT!wI0T>y*N=K1Q&z2BRV`4gKkF_&dU>x)K~Ny9|3-xC zya*s)g@TZPV@B=F^~@+xQOFGE&Ui~#%nJ>ZRosFp0%~J-OY7Ek-ED0R@gANrb7KYL zQ&mjEbp47bbInu{K~(qJid>~CW?{B|t8Gf+b1LSrf^kwoWphKkGuG9~Q*To-ml3al zw70g$nf(P7^O^0J>}4%Y&8_tBYT4ez=t32@GnysQ`dCM6PhI=g7%B8(k&4AA6Ub}n zTp!!g)gG^jH|X!$a$V&rDlkR=n=LQDN<}qh3%KR{s;zCTv_{1;!i($y*K!pruu@-a zpSEq4iq)Bw*LU2%s-cYyX;`bGK7){zj^>sv61h{wU5xmo`kLCdh9()tyH$KK!!PgN zRTbO8n(k4t5ns};+2_yyvWiU^k(x>~9t|oQEymXMv^BQ3c6w;?RuwUPMPKZgdP@M! zDq66OGSk_zJ0@VCF|*c-RUU8^ewT@2@rUYwLT<}JEOK% z7fR0L0QPesJuINi*jQ1UE-ojp`GAT?aZvxAvoP{?6^C(<620!OHEUMa-&tL?X>I+c zit=^UUL3(u1;{5~bZ>30I=E^EOg2z=n!8~tMtgEhJSAF|Vnfh<4IF2%XhpW){ zEqq(ScT_x0W}b1)^F4!S6+EZndw5>|y=$&}2TrI+;)Q_%<*M+!B4FECp^)r9+)Kq9 z`U1~<@unX4EFAx~7gzB!1wUu+uIU#&?}>Nx!`_JFJ%IxKsJB4>wKq3G3839J2`BL) zMdAlEw&5kBe`ujk5&a_zeVXVq7P=o3kc&JyHyh)nK8lQdQ?TTlLWu#gFi6x~vSFjQ zKXOiQ_f4F9mc|p{pyy(G2H`^)MS2NID@gGi{dwQ?gy$@>&X9}^ET0P}JuA}kl_Xz9 z8LP%Q;znT`CN*{int~$=?JPmVVVY@S*(6F3&f`LQVPSd;Qs9gXBI`5_gtX;i=3?4n z0vB}C^4!1Bzmh!JWRyrP2v$E=9xra zf~W;dk#{NFaU7adeu&shOrggkevN`&`M+YvNo=Vpc7hg^LakNmZmH}AlBzSMP7|@l zB+f+Er?AeX`UxVM-AiGEoH|IXdrdq=#AYJ;v4tg?c+KZ=-$mRHT3$EvzRDS*YS3?t zyRVM(uEKr;k17aE`-nP+z{~it5pKt86mB12Z=_tgqeD+YjfBEEq+`!%O9Grhr;&hx z!SQ(_QAFmGHhYA*`_l59fu#7m5-IVON3LBSR$cb$r!f3?3QG=BrRD=ipDXM%|s=|ve9!FNb&@^Vx%r9rjMCw zW-lqmMH1|{X&0Z2ku+1A#2-f)!SykMXUG-KdJ>mL3%)c)(5#3gj!D79i0y|)BvnGF zT$1P*t*c=~!ib+)N=ej=7Mwpu&@8hg3PuZNMP^(4?{$mhjrX}0$$V3E=pyzRWk{r1 zh6Dfd`$U-QumY1k?qL+bBYVt{5Y&GH3WoH8?9vr<+(@^OM(SSN#pWobL!0M0qB#!D zy_;gbhk5`J=7_3~8MNQR(NcTqPzt@=2dOvdPh?M>MaP@8zT>nT6hbPwrqAJ#l_So2 z`q3vl)FJ)P*`W#HUZ+S7zaPykUeB9YnBcV+!*PSx8lZ2=tHbbs&Ro<*iSsJ`1U14B z>6~TblagUogkgt^W}acIT6VgV(cTIN9d`N5&$tzI@V`DH|`fxKT=8Nc9Gi4lgI_4>?m4bc{4q+XhKB zeE@BKBSB9d7rSNf%1P_Ws2>lK-Y6@NN{^x%I~0|%FxV0^1eA=dHZtVcke&-83~g#E zK`aifp}~(2c9p|m80}zL#q5{QgVUxJxfSs6*m*3 z_Qp##lvUnLN*iUf>ZW3*Q5MjurI@ro#skifjC|hzjr^EdlGHwP;AsgQ+F73^@Rl7p zCvb2g??@-aM`9n<3tcw2e)M+&yL0#mB#$Lx8zFSxkjUm>l?B;F2;DU#av?Z5k(tBV z=oVpABMwkC+DTuXjD(vaQCGq)8V}3nEiw0Q$)_^e$rAa<6h5hq(D@5uKlBZgrX}cZ zlD2vwy}eqb)!fW}V$-FXkDsi}*h&VI&Jt-_3-Hjgj8b!LpS~Z{E3)%m6#3N(U4LX; z>hkAWBK9K1g|0smc{0D%f}A3REq~o09*&pAs?m8aM2GO1M7>5_8(zm{iQ4cM>AWJJ SKgBPI$A|o1;$8d-!T$nL28pi# diff --git a/build/lib3270j/org/lib3270j/screen/ScreenBuffer.class b/build/lib3270j/org/lib3270j/screen/ScreenBuffer.class index 728073b13cca1cd969257d832f5f823fe84c14b9..2b173d04f4623f0d53f1db286f6223c37e5897d2 100644 GIT binary patch literal 8178 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 A`2YX_ literal 7189 zcmb7J33yc175?vJk}=7HB!oo5Ohk~-WC#RM5XgdANJu28B%sEsOlDq^fyqpqnJ898 zTNi|a`vxurH?*cImY}uO*0#{9-S<{ot+lq_=lXU3tYZIj-<#FY+Jt-0yZ4@V?%B_I z;e{hlKMSA@e{jK}P!)*|)`f!oCoVd9!N$6gXe1u-M?!UNJ+jdn3CH5Ta6DE3CvsiL zGvLB83dI|J7y9Z#zVKk(Y5f~be_SE2As7zEn-p@YYu4wZ0EI3X1}0&$!toh*#Qagy z4A=E&&@wtOU`7@4qvlBH;_gVmR8TGQezAcPOi?ffg3(yKb%>Xl0UmbB;Zy@j2qpQ{>I`Z9L%wLtjMuH~_XmRh-XvnZ5bzq9D`L3F?%K#j z`l@*b<|p=ABO$7O0T#Nj$iRs>Nnv^h^+nnIH#XxIfFM+qxK)dWY zqqb1140P%ZKdHNLYPR3mKCyCh+zbcIKyy4E4fc=5%>r~GSGZYY;53|`X4vMBY5Hh1 zsOc`OHP9mlbPV`pxz50Py$t#bNc}7WXNzAK`9h(HpSrW$QtROy1E0pZbnt%LRjbd* zwD5nqw*coG*dTA`Q|%T}k*42(U(_+lKN^iiqRoLo)QsudOalY@#JVl*WXM1e8%fE! zk7i~t^c5h4VHd&%A{bGaoC?ftUwnw>r==8ft2;YuIz`f`ftW~|>kpZ}sHj(a{e=cD z(!>WM(P3XaZU%(Siw%56b|+a^+A%0EU25PmY@z1_W9>mRlrorhIC7}-UAWG` z^?EtL2=2m-25!>Je!aZKz^!^YNWltlyMa5fOQCci7!Is4H^~%in zu^dvtTV3->eVVz7FSeQ?W*aXpnaSEwL&18@%1D|3(*W}(Np)M9B)O0jVlCRNoS0ms zPU!m%#Hw-VV% zBJ<+(C9k$fS-Q02)gqO(B{bHisvPTN3n}r+v`uGqi(Hp$Mtw0F%~{=7v)(27qg3xS zhe8=nTuPFeF5AqkAUu=FUGB4TQBC##;h$As!b(vB*-gU ztsEiG?aeJ0$7#NTp2%p_Z?*>|081?Aw47qT=!g-kDwuox`wRP8nW(c$a1S8>x_o1DjKqeXvlQ0AsaLendmiS&!r*TD-GFB zX~+gjL$*vBvPsgAZ4u!VX@m$DF!8(aAm@Et9YGF%f$O|aBFCFEj(o3U97Qsf%CcOh z3Yk1I&5&u9w{{#=-r{NFsPPt`K8{-N+=Hka$6|p?$5HR~9>C&pGzqL9N3+11akL5K zyB*%IqU-D@v3eZc-03cUZX9RGgL53c-h()EKRHr(i1T?kma~^On2vmD1~CJrn8g*v7VMC+cZU zb``cR?%*w=i`8VMiKBU_!RvkoUE}Dp;dwcY9{0UCfrot_TZSGk&Py(?a;SYD{Z6#x zlPMsQIJ6{QdJ@pYc?E583gv00ceRk$R`Suz-<9mh+Hop6@Gvn8;P?<8rQWBM3SYz{ zHkXxzis!k)#N&Lh6qTnpyEu>GOPs~HtrW*WSn0kK#ctxaadZsr#W954j|&0!A|YXM z$Q${*2Icf@;lK$;iIb!r#Yr~7^t;=}h?0JH4_A*(h}w~j+Dp{OCq!+^MqNkL{S%@# zXQQqs>Jt;9)?}leNz^Y-h+3PCdKOU+Oo+NT8})3Wj!%eMpN-l_)PvZt*kp%fvqwKS zCqm6K|11Uqa6UijHqZrp{2uc&r~(Walb$p{w;a-Lk&B#?3OCvL%7mi&viaXc)Ti-P zoB!kJWa4Id!mckB=$8M6i1oE3*;&LCS1%y{K8}u1Htk`aKXY{ak!<`h@t;lNr>i}X zjXFZquTRXjj_P#Rzks;kz;m3lt(l)qHb$gx;#)RqhBorEwGk)Qw{ghE-A!#sDe9)# zE^zPCT3NggE-I#`(O%bE>)Ix9fx$hPO3>z^mx%T%wU^LA+PsyLglT}mRDPPn{0dyk zD=x!Sdgg3gjs{%8Z2CE7sViyztFW4%1CkkvkXzKMK0u+8xk3^WKUr)(_mj_DBCX|} zeXHj_+nCc->A4rBb1N4ucUCwLB7Rj4ljJ+8Bq>j$UMBy|@-%VD;epnV<*UneN!vz7 zx3e^FV^P>ahIgU{*D;}9&t!iill)C&{$?_N3z@%_%-@DHaJv>@5*$ZR;KE_0{zW1R z-$}5qiWy+S{!USysBNerM?_%W4~s+zDK6OsZ-w&!&M3i0Tb{z@yHW0Jte}A0Dn7F1 zMwYaFSd!DY4+}lJFt5T%39i)hHG1Bz=bd`KLC-hqxmRoFX0JErAa0W~B6>-gX+8g{ z0^H5=a1RXZVKLmxNM%jJeJpeL)3+aFA$f?OUSDJ?e+0d(2Ysvv8<@rin4d#TyisP< z&3tzYQ_xoCmL1G4V%9R`9^u!SqD_~$(B*s|^WLW}lze^J#@%8&;Zmw%bT@JxV@WkN zx}|8cq8tQulj|OH--CR&Gq4YN9%rDzUAgC@*BlZK>FMS1k?GK09W`)8}noR*{m_Yme7`5W5>accG9BbW{JrRG(*&JSFd& ztZ{#gJp6?9_otdRlgRonI@3BvOn_=`N=a^WcG5}p1qNoIyk z#wF_eSg}zO2|qdtayElXvf+;*MMO%%Oi~tC&DWHNJR7p~r3#7olL=M3IUBWzs6S2m zK{Y8$jVu;F*qmzKvy{xVrtq`mTVfD-D=(Q{(#n}C;n~me3(ms(FmYXk3#DK*NrTZW z^`pjHM!%}{mgP#@QI;odKeyZTc1NPMu*hn!SH~h(O+$gIK#`h`GUbL_c`#E|Vvafv zwQ2?ysN;F*FOzH@W;K$Mw<&2&+rK}}4f^+*c{vegPankH8iiX2P?g%<%UvBH52ONQJ__03o4R7rz%699j-H(K#Qil5B{U4$sedJb*jH`MPF5&?nfvY)Cx}1InL*E zJ>k_HuW;<(TGYOiu!8VzLJ#4+94~QviR)6rM+wO&Q#({0A^Ul15=`;JJlGL~OoQz% z)Lg=+2~Q+^hOnHF|I?s~2)|BvGU2y5-sCvM@du8>9Dn8b4#&SaUL>Bl^3OQl<@hCjPw=A69rrK?PB`m(^mts+Qn&3iM~S z6mO|zcuy_I->Be!sRn$Y8X5Ra%BfbUV^oVW*v1sAHZ@hPRL81zHC=V6O0`NIuR7Ii z)upP{sj613Rtr?OI!UcjOVw$rL7lEnQERo;XTbe$yquHqjler<HR^;No8ntl4edyz+cnw`d#)>7O*8PJwW%ISSj0Twxv zkv4$2YLHQ8HS+R(C)dBkT4aU#g}hGU?UYY=VWoZl_M_fEo%I$f!uv;f{{_4|isdSX z6)LV(m*C;Itc4a2ga1=#>yHH#pZTX(7q={-txGTArI+#x`Z7lB77BhjFTWz=(pQqn zyn~lY0hyUCcy5mFCEV;KbOK2^oBmo>TT!a6O%j!I@@ld_`Pk=o!hC5&(;5_u;0+{r NV+O(BlP?Ee`wtoSu3`WH diff --git a/build/lib3270j/org/lib3270j/telnet/TelnetConnection.class b/build/lib3270j/org/lib3270j/telnet/TelnetConnection.class index 6508f81d0759d598d8d753815481eeb3f51c524a..a668bc8e266457ced143b2731295d3f57f028058 100644 GIT binary patch delta 673 zcmYjO-%C?b9RGZ6?q27;OLvzw@14$CIrl@8UL=TWHN?mTT8a_H4Yzd3#+Eo%m=N?5 zCBgN@60@j=7Pi!GB~cHBLPWjwkkCI+??D*$-71I!-}616U*~)|U)$ca6$;Wxd>~ZB zW3m2lZa8+qMiu0cNP(456-)LXi$`O_*;MBIVSQK^XbV9}=p%Z|ke)o(a(p0@%Iar_ zViovITP50tF9d6Mq$ko95vkUwlAB30_RH>i6(bIa$Q6Yii5iMRq4!`{v?JOs(hlR2 ztSXHX`LKuaR5Fsuq%tD;jaj*|(pmJ{kQ1ocSd%qJh;~aTr&fZ+*U{8tqmWT%f5&yz z9;VQuZL?-O@E+x`0Ql~>`AR(MUqWFLX}^h$NhJ6*5ikk+v?tcj&m-N*H0QgR3Yz3zraI%3OB<_K zXnT-FMKj~xW!edtv?~waUx(*kSkr&Hz%m6(x~DwB3B)l-PM+o>MoBI0(@2;06~@b` zm#4e}57%pqUWbAk&@c{ZInC7H;jN%S1V+L1o7ZbS0%seyq z8GV3qTUNM!vINNgrf7?7IHESd$aax|n3ANWzel-7}Tb@O!?)cn|R%9<}WVw=0$?WzE)p_nha?s`sm`=TRrGeGQelYQPQHaT78o;89OG zUE|%DL_hA~JnnPSG)6InF+9Lk%y2@AxktE#S=_}Op5QTFvNn&WT$5PBGpyh_K6AH< z7x>EVcf7(6yha8K)WtJ>uw-Bm=u8InRFMJE2Fh9lD&BxOFCa)Hy8{A-ssb#jKb;QI t-z6K*F41n)=IW__hazbFwoCBhJ(~I4iZr_MA(w4I!6qyM|LKRWncw_Hvxxuz diff --git a/build/lib3270j/org/lib3270j/telnet/TelnetFSM$TN3270ESubmode.class b/build/lib3270j/org/lib3270j/telnet/TelnetFSM$TN3270ESubmode.class index 89f0eb331a4ea9216ffd9b6b050297f782e3ac3c..d3c9d7d0accdf077e0d9ca93de91a2f0c6da5dea 100644 GIT binary patch delta 37 ncmZqYYUkRplbO+P@-Ak5Ao+^f97rm$L;}egmINSqmqiNz-`opx delta 37 ncmZqYYUkRplbO+X@-Ak5Ao+^f97rm$L;}egmINSqmqiNz--ios diff --git a/build/lib3270j/org/lib3270j/telnet/TelnetFSM.class b/build/lib3270j/org/lib3270j/telnet/TelnetFSM.class index 58aed75b3c66a8efdc2ca329d99c0cd89d6796fc..6a1d85cf17baaef374d70fb9f59a7a4aa49c127b 100644 GIT binary patch literal 19415 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 MRF^uax+(L20d<}!vH$=8 literal 17208 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 { - // During an active file transfer, let the CUT/DFT handler drive - // keyboard state. In x3270, ft_cut_data() runs before WCC - // keyboard-restore is applied — the keyboard stays locked for the - // entire CUT transfer. - if (fileTransfer != null) { - fileTransfer.onScreenUpdated(); - } - if (client != null && (fileTransfer == null || !fileTransfer.isTransferActive())) { - client.getInputProcessor().setKeyboardLocked(false); - } - terminalPanel.repaint(); - statusBar.updateStatus(); - }); + if (screenUpdatePending.compareAndSet(false, true)) { + SwingUtilities.invokeLater(() -> { + screenUpdatePending.set(false); + // During an active file transfer, let the CUT/DFT handler drive + // keyboard state. In x3270, ft_cut_data() runs before WCC + // keyboard-restore is applied — the keyboard stays locked for the + // entire CUT transfer. + if (fileTransfer != null) { + fileTransfer.onScreenUpdated(); + } + if (client != null && (fileTransfer == null || !fileTransfer.isTransferActive())) { + client.getInputProcessor().setKeyboardLocked(false); + } + terminalPanel.repaint(); + statusBar.updateStatus(); + }); + } } @Override @@ -442,6 +446,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate boolean debug = false; boolean cliTls = false; boolean cliNoVerifyCert = false; + Boolean cliTn3270e = null; org.lib3270j.graphics.GraphicsMode cliGraphicsMode = null; String configFile = null; java.util.List remainingArgs = new java.util.ArrayList<>(); @@ -452,6 +457,10 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate cliTls = true; } else if ("--no-verify-cert".equals(args[i]) || "--insecure".equals(args[i]) || "-k".equals(args[i])) { cliNoVerifyCert = true; + } else if ("--no-tn3270e".equals(args[i]) || "--plain-tn3270".equals(args[i]) || "--plain".equals(args[i]) || "-P".equals(args[i]) || "-p".equals(args[i]) || "--non-e".equals(args[i])) { + cliTn3270e = false; + } else if ("--tn3270e".equals(args[i])) { + cliTn3270e = true; } else if (args[i].startsWith("--graphics=")) { cliGraphicsMode = org.lib3270j.graphics.GraphicsMode.fromString(args[i].substring(11)); } else if (("--graphics".equals(args[i]) || "-g".equals(args[i])) && i + 1 < args.length && !args[i + 1].startsWith("-")) { @@ -529,6 +538,7 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate final boolean finalTls = cliTls; final boolean finalNoVerify = cliNoVerifyCert; + final Boolean finalTn3270e = cliTn3270e; final org.lib3270j.graphics.GraphicsMode finalGraphicsMode = cliGraphicsMode; SwingUtilities.invokeLater(() -> { @@ -560,6 +570,9 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate if (finalNoVerify) { config.setTlsVerifyCert(false); } + if (finalTn3270e != null) { + config.setTn3270eEnabled(finalTn3270e); + } if (finalGraphicsMode != null) { config.setGraphicsMode(finalGraphicsMode); } else { @@ -578,9 +591,11 @@ public class J3270App extends JFrame implements ConnectionListener, ScreenUpdate int port = org.pubvm.j3270.config.Settings.getAutoConnectPort(); boolean tls = org.pubvm.j3270.config.Settings.getAutoConnectTls(); boolean verify = org.pubvm.j3270.config.Settings.getAutoConnectVerifyCert(); + boolean tn3270e = org.pubvm.j3270.config.Settings.getAutoConnectTn3270e(); if (host != null && !host.isEmpty()) { ConnectionConfig config = new ConnectionConfig(host, port, TerminalModel.IBM_3279_4, tls); config.setTlsVerifyCert(verify); + config.setTn3270eEnabled(finalTn3270e != null ? finalTn3270e : tn3270e); if (finalGraphicsMode != null) { config.setGraphicsMode(finalGraphicsMode); } else { diff --git a/j3270/src/main/java/org/pubvm/j3270/config/Settings.java b/j3270/src/main/java/org/pubvm/j3270/config/Settings.java index ff780b7..927f28e 100644 --- a/j3270/src/main/java/org/pubvm/j3270/config/Settings.java +++ b/j3270/src/main/java/org/pubvm/j3270/config/Settings.java @@ -78,13 +78,21 @@ public class Settings { prefs.putBoolean("autoConnectVerifyCert", verify); } + public static boolean getAutoConnectTn3270e() { + return prefs.getBoolean("autoConnectTn3270e", true); + } + + public static void setAutoConnectTn3270e(boolean tn3270e) { + prefs.putBoolean("autoConnectTn3270e", tn3270e); + } + public static org.lib3270j.graphics.GraphicsMode getGraphicsMode() { - String modeStr = prefs.get("graphicsMode", org.lib3270j.graphics.GraphicsMode.NONE.name()); + String modeStr = prefs.get("graphicsMode", org.lib3270j.graphics.GraphicsMode.BOTH.name()); return org.lib3270j.graphics.GraphicsMode.fromString(modeStr); } public static void setGraphicsMode(org.lib3270j.graphics.GraphicsMode mode) { - prefs.put("graphicsMode", (mode != null ? mode : org.lib3270j.graphics.GraphicsMode.NONE).name()); + prefs.put("graphicsMode", (mode != null ? mode : org.lib3270j.graphics.GraphicsMode.BOTH).name()); } public static Color getColorOverride(int index, Color defaultColor) { @@ -243,6 +251,11 @@ public class Settings { case "tlsVerifyCert": setAutoConnectVerifyCert(Boolean.parseBoolean(value)); break; + case "autoConnectTn3270e": + case "tn3270e": + case "enableTn3270e": + setAutoConnectTn3270e(Boolean.parseBoolean(value)); + break; case "blockSelectMode": setBlockSelectMode(Boolean.parseBoolean(value)); break; default: log.warning("Unknown behavior/connection key: " + key); @@ -309,6 +322,7 @@ public class Settings { w.println("autoConnectPort = " + getAutoConnectPort()); w.println("autoConnectTls = " + getAutoConnectTls()); w.println("autoConnectVerifyCert = " + getAutoConnectVerifyCert()); + w.println("autoConnectTn3270e = " + getAutoConnectTn3270e()); } w.println("blockSelectMode = " + getBlockSelectMode()); w.println(); diff --git a/j3270/src/main/java/org/pubvm/j3270/ui/ConnectDialog.java b/j3270/src/main/java/org/pubvm/j3270/ui/ConnectDialog.java index b6ac0bb..12edd6a 100644 --- a/j3270/src/main/java/org/pubvm/j3270/ui/ConnectDialog.java +++ b/j3270/src/main/java/org/pubvm/j3270/ui/ConnectDialog.java @@ -18,6 +18,7 @@ public class ConnectDialog extends JDialog { private JTextField luField; private JCheckBox tlsCheckBox; private JCheckBox verifyCertCheckBox; + private JCheckBox tn3270eCheckBox; private boolean confirmed; private ConnectionConfig result; @@ -146,6 +147,17 @@ public class ConnectDialog extends JDialog { verifyCertCheckBox.setFocusPainted(false); mainPanel.add(verifyCertCheckBox, gbc); + // TN3270E Checkbox + gbc.gridx = 1; + gbc.gridy = 7; + tn3270eCheckBox = new JCheckBox("Enable TN3270E (Extended 3270)"); + tn3270eCheckBox.setBackground(new Color(30, 30, 30)); + tn3270eCheckBox.setForeground(fg); + tn3270eCheckBox.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 13)); + tn3270eCheckBox.setSelected(org.pubvm.j3270.config.Settings.getAutoConnectTn3270e()); + tn3270eCheckBox.setFocusPainted(false); + mainPanel.add(tn3270eCheckBox, gbc); + // Buttons JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); buttonPanel.setBackground(new Color(30, 30, 30)); @@ -169,7 +181,7 @@ public class ConnectDialog extends JDialog { buttonPanel.add(connectBtn); gbc.gridx = 0; - gbc.gridy = 7; + gbc.gridy = 8; gbc.gridwidth = 2; mainPanel.add(buttonPanel, gbc); @@ -214,6 +226,7 @@ public class ConnectDialog extends JDialog { result.setGraphicsMode((org.lib3270j.graphics.GraphicsMode) graphicsCombo.getSelectedItem()); result.setUseTls(tlsCheckBox.isSelected()); result.setTlsVerifyCert(verifyCertCheckBox.isSelected()); + result.setTn3270eEnabled(tn3270eCheckBox.isSelected()); confirmed = true; dispose(); } @@ -243,4 +256,8 @@ public class ConnectDialog extends JDialog { public void setInitialVerifyCert(boolean verify) { verifyCertCheckBox.setSelected(verify); } + + public void setInitialTn3270e(boolean tn3270e) { + tn3270eCheckBox.setSelected(tn3270e); + } } diff --git a/j3270/src/main/java/org/pubvm/j3270/ui/TerminalPanel.java b/j3270/src/main/java/org/pubvm/j3270/ui/TerminalPanel.java index eb12183..f5a77bc 100644 --- a/j3270/src/main/java/org/pubvm/j3270/ui/TerminalPanel.java +++ b/j3270/src/main/java/org/pubvm/j3270/ui/TerminalPanel.java @@ -22,6 +22,7 @@ public class TerminalPanel extends JPanel { // Font and cell dimensions private Font terminalFont; + private Font boldTerminalFont; private int cellWidth; private int cellHeight; private int fontAscent; @@ -47,6 +48,14 @@ public class TerminalPanel extends JPanel { // ========== Selection / Copy-Paste state ========== private boolean blockSelectMode = false; + + private static final String[] CHAR_STRINGS = new String[128]; + static { + for (int i = 0; i < 128; i++) { + CHAR_STRINGS[i] = String.valueOf((char) i); + } + } + private static final Color CURSOR_COLOR = new Color(255, 255, 255, 180); private int selectionStartRow = -1, selectionStartCol = -1; private int selectionEndRow = -1, selectionEndCol = -1; private boolean isDragging = false; @@ -779,6 +788,7 @@ public class TerminalPanel extends JPanel { cellHeight = fm.getHeight(); fontAscent = fm.getAscent(); fontDescent = fm.getDescent(); + boldTerminalFont = terminalFont.deriveFont(Font.BOLD); } private void setupCursorBlink() { @@ -818,6 +828,8 @@ public class TerminalPanel extends JPanel { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); + g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); // Clear entire panel with background color g2.setColor(bgColor); @@ -828,8 +840,8 @@ public class TerminalPanel extends JPanel { int oy = getRenderOffsetY(); ScreenBuffer sb = client.getScreenBuffer(); - int rows = sb.getRows(); - int cols = sb.getCols(); + int rows = sb.getDisplayRows(); + int cols = sb.getDisplayCols(); boolean isColorModel = client.getConfig().getModel().isColor(); // Track current field attribute for monochrome color decisions @@ -839,7 +851,7 @@ public class TerminalPanel extends JPanel { for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { int baddr = row * cols + col; - ExtendedAttribute ea = sb.getCell(baddr); + ExtendedAttribute ea = sb.getDisplayCell(baddr); int x = ox + col * cellWidth; int y = oy + row * cellHeight; @@ -854,10 +866,7 @@ public class TerminalPanel extends JPanel { if (ea.isFieldAttribute()) { currentFA = ea.fa; currentFieldEa = ea; - // Field attributes display as blanks - g2.setColor(this.bgColor); - g2.fillRect(x, y, cellWidth, cellHeight); - // Selection highlight on field attribute cells too + // Selection highlight on field attribute cells if (isCellSelected(row, col)) { g2.setColor(SELECTION_COLOR); g2.fillRect(x, y, cellWidth, cellHeight); @@ -892,12 +901,9 @@ public class TerminalPanel extends JPanel { // Handle invisible fields (zero intensity / password fields) // Modern UX: render '*' for typed characters so user sees length/digit count if (faIsZero(currentFA & 0xFF)) { - g2.setColor(this.bgColor); - g2.fillRect(x, y, cellWidth, cellHeight); - char ch = ea.ucs4; if (ch > 0x20 && ch != 0xFF) { - Font f = bold ? terminalFont.deriveFont(Font.BOLD) : terminalFont; + Font f = bold ? boldTerminalFont : terminalFont; g2.setFont(f); g2.setColor(fgColor); g2.drawString("*", x, y + fontAscent); @@ -917,9 +923,11 @@ public class TerminalPanel extends JPanel { bgColor = tmp; } - // Draw background - g2.setColor(bgColor); - g2.fillRect(x, y, cellWidth, cellHeight); + // Draw background only if different from default panel bgColor or if inverted + if (!bgColor.equals(this.bgColor) || reverse) { + g2.setColor(bgColor); + g2.fillRect(x, y, cellWidth, cellHeight); + } // Draw character or Programmed Symbol int cs = (ea.cs != 0) ? (ea.cs & 0xFF) : (currentFieldEa != null ? (currentFieldEa.cs & 0xFF) : 0); @@ -927,21 +935,25 @@ public class TerminalPanel extends JPanel { if (cs >= 0x40 && client.getProgramSymbolManager() != null) { org.lib3270j.graphics.ProgramSymbolSet.SymbolSlot slot = client.getProgramSymbolManager().getSymbol(cs, ea.ec & 0xFF); if (slot != null) { - int[] rgb = slot.getRgbPixels(fgColor.getRGB(), bgColor.getRGB()); - java.awt.image.BufferedImage img = new java.awt.image.BufferedImage(slot.getWidth(), slot.getHeight(), java.awt.image.BufferedImage.TYPE_INT_ARGB); - img.setRGB(0, 0, slot.getWidth(), slot.getHeight(), rgb, 0, slot.getWidth()); - g2.drawImage(img, x, y, cellWidth, cellHeight, null); - drawnAsPs = true; + java.awt.image.BufferedImage img = slot.getScaledImage(cellWidth, cellHeight, fgColor.getRGB(), bgColor.getRGB()); + if (img != null) { + g2.drawImage(img, x, y, null); + drawnAsPs = true; + } } } if (!drawnAsPs) { char ch = ea.ucs4; if (ch > 0x20 && ch != 0xFF) { - Font f = bold ? terminalFont.deriveFont(Font.BOLD) : terminalFont; + Font f = bold ? boldTerminalFont : terminalFont; g2.setFont(f); g2.setColor(fgColor); - g2.drawString(String.valueOf(ch), x, y + fontAscent); + if (ch < 128) { + g2.drawString(CHAR_STRINGS[ch], x, y + fontAscent); + } else { + g2.drawString(String.valueOf(ch), x, y + fontAscent); + } } } @@ -975,13 +987,13 @@ public class TerminalPanel extends JPanel { // Draw cursor if (cursorVisible && client.getConnectionState().isFullSession()) { - int curAddr = sb.getCursorAddress(); + int curAddr = sb.getDisplayCursorAddress(); int curRow = curAddr / cols; int curCol = curAddr % cols; int cx = ox + curCol * cellWidth; int cy = oy + curRow * cellHeight; - g2.setColor(new Color(255, 255, 255, 180)); + g2.setColor(CURSOR_COLOR); g2.setXORMode(bgColor); g2.fillRect(cx, cy, cellWidth, cellHeight); g2.setPaintMode(); diff --git a/lib3270j/src/main/java/org/lib3270j/ConnectionConfig.java b/lib3270j/src/main/java/org/lib3270j/ConnectionConfig.java index cb45cb4..431d72a 100644 --- a/lib3270j/src/main/java/org/lib3270j/ConnectionConfig.java +++ b/lib3270j/src/main/java/org/lib3270j/ConnectionConfig.java @@ -17,7 +17,8 @@ public class ConnectionConfig { private int connectTimeoutMs = 15000; private int nopIntervalSeconds = 0; private String terminalName = null; // override terminal type string - private org.lib3270j.graphics.GraphicsMode graphicsMode = org.lib3270j.graphics.GraphicsMode.NONE; + private boolean tn3270eEnabled = true; + private org.lib3270j.graphics.GraphicsMode graphicsMode = org.lib3270j.graphics.GraphicsMode.BOTH; public ConnectionConfig() {} @@ -66,6 +67,9 @@ public class ConnectionConfig { public boolean isTlsVerifyCert() { return tlsVerifyCert; } public void setTlsVerifyCert(boolean verify) { this.tlsVerifyCert = verify; } + public boolean isTn3270eEnabled() { return tn3270eEnabled; } + public void setTn3270eEnabled(boolean enabled) { this.tn3270eEnabled = enabled; } + public org.lib3270j.tls.TlsCertificateVerifier getCertificateVerifier() { return certificateVerifier; } public void setCertificateVerifier(org.lib3270j.tls.TlsCertificateVerifier verifier) { this.certificateVerifier = verifier; } @@ -87,8 +91,8 @@ public class ConnectionConfig { public void setTerminalName(String name) { this.terminalName = name; } /** - * Parse a host connection string which may include prefixes for TLS (e.g. "L:host:port", "ssl:host:port", "y:host:port") - * or standard "host:port" formats. + * Parse a host connection string which may include prefixes for TLS (e.g. "L:host:port", "ssl:host:port", "y:host:port"), + * plain TN3270 (e.g. "P:host:port", "plain:host:port", "non-e:host:port"), or standard "host:port" formats. */ public static ConnectionConfig parseHostString(String hostStr, int defaultPort, TerminalModel defaultModel) { if (hostStr == null || hostStr.trim().isEmpty()) { @@ -96,17 +100,35 @@ public class ConnectionConfig { } String s = hostStr.trim(); boolean tls = false; + boolean tn3270e = true; - // Check TLS prefixes - if (s.startsWith("L:") || s.startsWith("l:")) { - tls = true; - s = s.substring(2); - } else if (s.startsWith("Y:") || s.startsWith("y:")) { - tls = true; - s = s.substring(2); - } else if (s.toLowerCase().startsWith("ssl:") || s.toLowerCase().startsWith("tls:")) { - tls = true; - s = s.substring(4); + // Parse chained x3270-style prefixes (e.g. "L:P:host:port" or "P:host:port") + boolean prefixFound = true; + while (prefixFound) { + prefixFound = false; + if (s.startsWith("L:") || s.startsWith("l:") || s.startsWith("Y:") || s.startsWith("y:")) { + tls = true; + s = s.substring(2); + prefixFound = true; + } else if (s.toLowerCase().startsWith("ssl:") || s.toLowerCase().startsWith("tls:")) { + tls = true; + s = s.substring(4); + prefixFound = true; + } else if (s.startsWith("N:") || s.startsWith("n:") || s.toLowerCase().startsWith("notls:") || s.toLowerCase().startsWith("nossl:")) { + tls = false; + int colon = s.indexOf(':'); + s = s.substring(colon + 1); + prefixFound = true; + } else if (s.startsWith("P:") || s.startsWith("p:")) { + tn3270e = false; + s = s.substring(2); + prefixFound = true; + } else if (s.toLowerCase().startsWith("plain:") || s.toLowerCase().startsWith("non-e:")) { + tn3270e = false; + int colon = s.indexOf(':'); + s = s.substring(colon + 1); + prefixFound = true; + } } String host = s; @@ -133,6 +155,7 @@ public class ConnectionConfig { ConnectionConfig config = new ConnectionConfig(host, port, defaultModel != null ? defaultModel : TerminalModel.IBM_3279_4); config.setUseTls(tls); + config.setTn3270eEnabled(tn3270e); return config; } diff --git a/lib3270j/src/main/java/org/lib3270j/datastream/DataStreamProcessor.java b/lib3270j/src/main/java/org/lib3270j/datastream/DataStreamProcessor.java index 1e04775..2596c4d 100644 --- a/lib3270j/src/main/java/org/lib3270j/datastream/DataStreamProcessor.java +++ b/lib3270j/src/main/java/org/lib3270j/datastream/DataStreamProcessor.java @@ -9,6 +9,7 @@ import static org.lib3270j.protocol.DS3270Constants.*; import java.io.ByteArrayOutputStream; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -105,74 +106,92 @@ public class DataStreamProcessor { return; int cmd = data[offset] & 0xFF; - log.info(">>> CMD: " + commandName(cmd) + " (0x" + String.format("%02x", cmd) + ") " + length + " bytes"); + synchronized (screen.getRenderLock()) { + if (log.isLoggable(Level.FINE)) { + log.fine(">>> CMD: " + commandName(cmd) + " (0x" + String.format("%02x", cmd) + ") " + length + " bytes"); + } - switch (cmd) { - case CMD_W: - case SNA_CMD_W: - processWrite(data, offset, length, false); - break; - case CMD_EW: - case SNA_CMD_EW: - log.info(">>> ERASE/WRITE: clearing screen (default size)"); { - int oldRows = screen.getRows(); - int oldCols = screen.getCols(); - screen.erase(false); - graphicsPlane.clear(); - processWrite(data, offset, length, true); - if (oldRows != screen.getRows() || oldCols != screen.getCols()) { - notifyScreenSizeChanged(); - } + switch (cmd) { + case CMD_W: + case SNA_CMD_W: + programSymbolManager.commitStagedSymbols(); + processWrite(data, offset, length, false); + break; + case CMD_EW: + case SNA_CMD_EW: + programSymbolManager.commitStagedSymbols(); + if (log.isLoggable(Level.FINE)) { + log.fine(">>> ERASE/WRITE: clearing screen (default size)"); + } + { + int oldRows = screen.getRows(); + int oldCols = screen.getCols(); + screen.erase(false); + graphicsPlane.clear(); + processWrite(data, offset, length, true); + if (oldRows != screen.getRows() || oldCols != screen.getCols()) { + notifyScreenSizeChanged(); + } + } + break; + case CMD_EWA: + case SNA_CMD_EWA: + programSymbolManager.commitStagedSymbols(); + if (log.isLoggable(Level.FINE)) { + log.fine(">>> ERASE/WRITE ALTERNATE: clearing screen (alt size)"); + } + { + int oldRows = screen.getRows(); + int oldCols = screen.getCols(); + screen.erase(true); + graphicsPlane.clear(); + processWrite(data, offset, length, true); + if (oldRows != screen.getRows() || oldCols != screen.getCols()) { + notifyScreenSizeChanged(); + } + } + break; + case CMD_RB: + case SNA_CMD_RB: + programSymbolManager.commitStagedSymbols(); + processReadBuffer(); + break; + case CMD_RM: + case SNA_CMD_RM: + programSymbolManager.commitStagedSymbols(); + processReadModified(false); + break; + case CMD_RMA: + case SNA_CMD_RMA: + programSymbolManager.commitStagedSymbols(); + processReadModified(true); + break; + case CMD_EAU: + case SNA_CMD_EAU: + programSymbolManager.commitStagedSymbols(); + log.info(">>> EAU: erasing all unprotected fields"); + screen.eraseAllUnprotected(); + break; + case CMD_WSF: + case SNA_CMD_WSF: + processWriteStructuredField(data, offset, length); + break; + case CMD_NOP: + log.info(">>> NOP command"); + break; + default: + log.warning(">>> UNKNOWN 3270 command: " + String.format("0x%02x", cmd)); + break; } - break; - case CMD_EWA: - case SNA_CMD_EWA: - log.info(">>> ERASE/WRITE ALTERNATE: clearing screen (alt size)"); { - int oldRows = screen.getRows(); - int oldCols = screen.getCols(); - screen.erase(true); - graphicsPlane.clear(); - processWrite(data, offset, length, true); - if (oldRows != screen.getRows() || oldCols != screen.getCols()) { - notifyScreenSizeChanged(); - } - } - break; - case CMD_RB: - case SNA_CMD_RB: - processReadBuffer(); - break; - case CMD_RM: - case SNA_CMD_RM: - processReadModified(false); - break; - case CMD_RMA: - case SNA_CMD_RMA: - processReadModified(true); - break; - case CMD_EAU: - case SNA_CMD_EAU: - log.info(">>> EAU: erasing all unprotected fields"); - screen.eraseAllUnprotected(); - break; - case CMD_WSF: - case SNA_CMD_WSF: - processWriteStructuredField(data, offset, length); - break; - case CMD_NOP: - log.info(">>> NOP command"); - break; - default: - log.warning(">>> UNKNOWN 3270 command: " + String.format("0x%02x", cmd)); - break; + + // Translate EBCDIC to Unicode for display + screen.translateToUnicode(); + screen.markAllChanged(); + screen.updateDisplaySnapshot(); } - // Translate EBCDIC to Unicode for display - screen.translateToUnicode(); - screen.markAllChanged(); - // Debug: dump non-empty screen lines - if (cmd == SNA_CMD_EWA || cmd == CMD_EWA || cmd == SNA_CMD_EW || cmd == CMD_EW) { + if (log.isLoggable(Level.FINE) && (cmd == SNA_CMD_EWA || cmd == CMD_EWA || cmd == SNA_CMD_EW || cmd == CMD_EW)) { int r = screen.getRows(); int c = screen.getCols(); StringBuilder dump = new StringBuilder(); @@ -205,7 +224,7 @@ public class DataStreamProcessor { } } if (dump.length() > 0) { - log.info("Screen content after " + commandName(cmd) + ":\n" + dump.toString()); + log.fine("Screen content after " + commandName(cmd) + ":\n" + dump.toString()); } } } @@ -798,7 +817,6 @@ public class DataStreamProcessor { byte[] psData = new byte[fieldLen - 3]; System.arraycopy(data, pos + 3, psData, 0, psData.length); programSymbolManager.loadps(psData); - notifyScreenUpdated(); } break; case org.lib3270j.graphics.GocaConstants.SF_LOADPS: { // 0x0F: 2-byte Structured Field prefix @@ -810,7 +828,6 @@ public class DataStreamProcessor { byte[] psData = new byte[fieldLen - 4]; System.arraycopy(data, pos + 4, psData, 0, psData.length); programSymbolManager.loadps(psData); - notifyScreenUpdated(); } break; case org.lib3270j.graphics.GocaConstants.SF_OBJCNTL_SUB: // 0x11: Object Control (Procedure orders) diff --git a/lib3270j/src/main/java/org/lib3270j/datastream/QueryReplyBuilder.java b/lib3270j/src/main/java/org/lib3270j/datastream/QueryReplyBuilder.java index 3cac7ab..0172521 100644 --- a/lib3270j/src/main/java/org/lib3270j/datastream/QueryReplyBuilder.java +++ b/lib3270j/src/main/java/org/lib3270j/datastream/QueryReplyBuilder.java @@ -22,7 +22,7 @@ public class QueryReplyBuilder { private static final int Yr_3279_2 = 0x0002006f; private final ScreenBuffer screen; - private GraphicsMode graphicsMode = GraphicsMode.NONE; + private GraphicsMode graphicsMode = GraphicsMode.BOTH; // Base query reply codes (text mode) private static final int[] SUPPORTED_QR_BASE = { @@ -313,9 +313,9 @@ public class QueryReplyBuilder { private byte[] buildCharsets() { if (graphicsMode.isProgrammedSymbolsEnabled()) { - // Programmed Symbols mode (3279 PS with LoadPS 0x0A) + // Programmed Symbols mode (3279 PS with LoadPS 0x0A, flags1 = 0xA2 for GE + PS + CGCSGID) ByteArrayOutputStream out = new ByteArrayOutputStream(65); - out.write(0x82); // flags: GE, CGCSGID present + out.write(0xa2); // flags: GE (0x80), PS/Loadable Charsets (0x20), CGCSGID present (0x02) out.write(0x00); // more flags out.write(SW_3279_2); // SDW (9) out.write(SH_3279_2); // SDH (12) @@ -328,14 +328,14 @@ public class QueryReplyBuilder { out.write(0x00); out.write(0x10); out.write(0x00); out.write(0x02); out.write(0xb9); out.write(0x00); out.write(0x25); // Descriptor 2 (SET 1): APL/GE character set out.write(0x01); out.write(0x00); out.write(0xf1); out.write(0x03); out.write(0xc3); out.write(0x01); out.write(0x36); - // Loadable Single-Plane PS Sets (PSA, PSB: Slots 2, 3) + // Loadable Single-Plane PS Sets (PSA, PSB: Slots 2, 3) - Flags = 0x80 (Loadable, single plane) out.write(0x02); out.write(0x80); out.write(0x40); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x03); out.write(0x80); out.write(0x41); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); - // Loadable Triple-Plane PS Sets (PSC, PSD, PSE, PSF: Slots 4, 5, 6, 7) - out.write(0x04); out.write(0x80); out.write(0x42); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); - out.write(0x05); out.write(0x80); out.write(0x43); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); - out.write(0x06); out.write(0x80); out.write(0x44); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); - out.write(0x07); out.write(0x80); out.write(0x45); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); + // Loadable Triple-Plane PS Sets (PSC, PSD, PSE, PSF: Slots 4, 5, 6, 7) - Flags = 0xC0 (0x80 Loadable | 0x40 Triple-plane) + out.write(0x04); out.write(0xc0); out.write(0x42); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); + out.write(0x05); out.write(0xc0); out.write(0x43); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); + out.write(0x06); out.write(0xc0); out.write(0x44); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); + out.write(0x07); out.write(0xc0); out.write(0x45); out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); return out.toByteArray(); } diff --git a/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolManager.java b/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolManager.java index 791c7a2..49933f3 100644 --- a/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolManager.java +++ b/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolManager.java @@ -17,12 +17,31 @@ public class ProgramSymbolManager { public static final int NUMBER_TRIPLE_PLANE_PS_SETS = 4; // RWS 4..7 (Sets 2..5) public static final int NUMBER_GRAPHICS_SYMBOL_SETS = 4; // RWS 8..11 (Sets 6..9) + private int defaultCellWidth = 9; + private int defaultCellHeight = 12; // Standard IBM 3279 PS Slot Default Height (SDH = 0x0C = 12) + + public void setDefaultCellDimensions(int width, int height) { + this.defaultCellWidth = (width > 0) ? width : 9; + this.defaultCellHeight = (height > 0) ? height : 12; + } + + public int getDefaultCellWidth() { + return defaultCellWidth; + } + + public int getDefaultCellHeight() { + return defaultCellHeight; + } + private final ProgramSymbolSet[] sets = new ProgramSymbolSet[NUMBER_SYMBOL_SETS]; + private final ProgramSymbolSet[] stagingSets = new ProgramSymbolSet[NUMBER_SYMBOL_SETS]; + private final ProgramSymbolSet[] lcidMap = new ProgramSymbolSet[256]; public ProgramSymbolManager() { for (int i = 0; i < NUMBER_SYMBOL_SETS; i++) { boolean isTriple = (i >= NUMBER_SINGLE_PLANE_PS_SETS && i < NUMBER_SINGLE_PLANE_PS_SETS + NUMBER_TRIPLE_PLANE_PS_SETS); sets[i] = new ProgramSymbolSet(isTriple); + stagingSets[i] = new ProgramSymbolSet(isTriple); } } @@ -30,32 +49,67 @@ public class ProgramSymbolManager { * Resets all symbol sets. */ public synchronized void clearAll() { - for (ProgramSymbolSet set : sets) { - set.clear(); - set.setLcid(0); + Arrays.fill(lcidMap, null); + for (int i = 0; i < NUMBER_SYMBOL_SETS; i++) { + sets[i].clear(); + sets[i].setLcid(0); + stagingSets[i].clear(); + stagingSets[i].setLcid(0); + } + } + + /** + * Commits all staged multi-plane symbol sets to the active presentation sets atomically. + */ + public synchronized void commitStagedSymbols() { + for (int i = 0; i < NUMBER_SYMBOL_SETS; i++) { + int lcid = stagingSets[i].getLcid(); + if (lcid > 0) { + ProgramSymbolSet staged = stagingSets[i]; + ProgramSymbolSet active = sets[i]; + active.setLcid(lcid); + for (int slot = 0; slot < ProgramSymbolSet.NUM_SLOTS; slot++) { + active.setSlot(slot, staged.getSlot(slot)); + } + if (lcid < 256) { + lcidMap[lcid] = active; + } + } } } /** * Retrieves the symbol set corresponding to a given LCID (0x40 - 0xFE). */ - public synchronized ProgramSymbolSet getSymbolSet(int lcid) { - if (lcid <= 0) { + public ProgramSymbolSet getSymbolSet(int lcid) { + if (lcid <= 0 || lcid >= 256) { return null; } - for (ProgramSymbolSet set : sets) { - if (set.getLcid() == lcid) { - return set; + ProgramSymbolSet set = lcidMap[lcid]; + if (set == null) { + for (ProgramSymbolSet s : stagingSets) { + if (s.getLcid() == lcid) return s; } } - return null; + return set; } /** * Retrieves a specific symbol glyph by LCID and character code point (0x40 - 0xFE). */ - public synchronized ProgramSymbolSet.SymbolSlot getSymbol(int lcid, int codePoint) { - ProgramSymbolSet set = getSymbolSet(lcid); + public ProgramSymbolSet.SymbolSlot getSymbol(int lcid, int codePoint) { + if (lcid <= 0 || lcid >= 256) { + return null; + } + ProgramSymbolSet set = lcidMap[lcid]; + if (set == null) { + for (ProgramSymbolSet s : stagingSets) { + if (s.getLcid() == lcid) { + set = s; + break; + } + } + } if (set == null) { return null; } @@ -98,12 +152,12 @@ public class ProgramSymbolManager { return; } - ProgramSymbolSet set = sets[setIndex]; boolean isTriplePlane = (rws >= 4 && rws <= 7); + ProgramSymbolSet set = isTriplePlane ? stagingSets[setIndex] : sets[setIndex]; int extHeaderLen = 0; - int cellWidth = 9; - int cellHeight = 16; + int cellWidth = defaultCellWidth; + int cellHeight = defaultCellHeight; int colorPlane = 0; // 0 = all planes, 1 = Red, 2 = Green, 4 = Blue if (hasExtHeader && data.length > 4) { @@ -121,10 +175,10 @@ public class ProgramSymbolManager { } } - if (clearAll) { - set.clear(); - } set.setLcid(lcid); + if (!isTriplePlane && lcid > 0 && lcid < 256) { + lcidMap[lcid] = set; + } int offset = 4 + (hasExtHeader ? extHeaderLen : 0); int remaining = data.length - offset; @@ -142,12 +196,10 @@ public class ProgramSymbolManager { } while (remaining >= bytesPerSymbol && codeIndex < ProgramSymbolSet.NUM_SLOTS) { - byte[] pixelData; + byte[] pixelData = new byte[cellWidth * cellHeight]; ProgramSymbolSet.SymbolSlot existing = set.getSlot(codeIndex); - if (existing != null && existing.getWidth() == cellWidth && existing.getHeight() == cellHeight) { - pixelData = existing.getPixelData(); - } else { - pixelData = new byte[cellWidth * cellHeight]; + if (!clearAll && existing != null && existing.getWidth() == cellWidth && existing.getHeight() == cellHeight) { + System.arraycopy(existing.getPixelData(), 0, pixelData, 0, Math.min(existing.getPixelData().length, pixelData.length)); } if (loadFormat == 1) { @@ -163,9 +215,17 @@ public class ProgramSymbolManager { remaining -= bytesPerSymbol; } - logger.info(String.format("LOADPS: Loaded PS Set LCID=0x%02X (RWS=%d, %s, %dx%d, %d glyphs)", - lcid, rws, isTriplePlane ? "Triple-Plane" : "Single-Plane", - cellWidth, cellHeight, codeIndex - ((startCodePoint >= 0x40) ? (startCodePoint - 0x40) : startCodePoint))); + if (clearAll) { + for (int i = codeIndex; i < ProgramSymbolSet.NUM_SLOTS; i++) { + set.clearSlot(i); + } + } + + if (logger.isLoggable(Level.FINE)) { + logger.fine(String.format("LOADPS: Loaded PS Set LCID=0x%02X (RWS=%d, %s, %dx%d, %d glyphs)", + lcid, rws, isTriplePlane ? "Triple-Plane" : "Single-Plane", + cellWidth, cellHeight, codeIndex - ((startCodePoint >= 0x40) ? (startCodePoint - 0x40) : startCodePoint))); + } } /** diff --git a/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolSet.java b/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolSet.java index f41eb72..8971921 100644 --- a/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolSet.java +++ b/lib3270j/src/main/java/org/lib3270j/graphics/ProgramSymbolSet.java @@ -64,6 +64,12 @@ public class ProgramSymbolSet { private int[] cachedRgbArray; private int cachedFgRgb = -1; private int cachedBgRgb = -1; + private java.awt.image.BufferedImage cachedImage; + private java.awt.image.BufferedImage cachedScaledImage; + private int cachedTargetW = 0; + private int cachedTargetH = 0; + private int cachedScaledFgRgb = -1; + private int cachedScaledBgRgb = -1; public SymbolSlot(int width, int height, byte[] pixelData, boolean isTriplePlane) { this.width = width > 0 ? width : 9; @@ -88,6 +94,61 @@ public class ProgramSymbolSet { return isTriplePlane; } + /** + * Returns an image scaled directly to target dimensions (cellWidth x cellHeight). + * Enables unscaled 1:1 hardware blitting in Java2D. + */ + public synchronized java.awt.image.BufferedImage getScaledImage(int targetW, int targetH, int fgArgb, int bgArgb) { + if (targetW <= 0 || targetH <= 0) { + return getImage(fgArgb, bgArgb); + } + if (targetW == width && targetH == height) { + return getImage(fgArgb, bgArgb); + } + if (cachedScaledImage != null && cachedTargetW == targetW && cachedTargetH == targetH + && cachedScaledFgRgb == fgArgb && cachedScaledBgRgb == bgArgb) { + return cachedScaledImage; + } + int[] srcRgb = getRgbPixels(fgArgb, bgArgb); + java.awt.image.BufferedImage scaled = new java.awt.image.BufferedImage(targetW, targetH, java.awt.image.BufferedImage.TYPE_INT_ARGB); + int[] dstRgb = ((java.awt.image.DataBufferInt) scaled.getRaster().getDataBuffer()).getData(); + + for (int dy = 0; dy < targetH; dy++) { + int sy = dy * height / targetH; + int srcRowOffset = sy * width; + int dstRowOffset = dy * targetW; + for (int dx = 0; dx < targetW; dx++) { + int sx = dx * width / targetW; + dstRgb[dstRowOffset + dx] = srcRgb[srcRowOffset + sx]; + } + } + + this.cachedScaledImage = scaled; + this.cachedTargetW = targetW; + this.cachedTargetH = targetH; + this.cachedScaledFgRgb = fgArgb; + this.cachedScaledBgRgb = bgArgb; + return scaled; + } + + /** + * Computes and returns the cached BufferedImage for this symbol glyph. + * Eliminates per-cell heap allocations during high frame rate rendering. + */ + public synchronized java.awt.image.BufferedImage getImage(int fgArgb, int bgArgb) { + if (cachedImage != null && cachedFgRgb == fgArgb && cachedBgRgb == bgArgb) { + return cachedImage; + } + int[] rgb = getRgbPixels(fgArgb, bgArgb); + java.awt.image.BufferedImage img = new java.awt.image.BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_INT_ARGB); + int[] imgData = ((java.awt.image.DataBufferInt) img.getRaster().getDataBuffer()).getData(); + System.arraycopy(rgb, 0, imgData, 0, rgb.length); + this.cachedImage = img; + this.cachedFgRgb = fgArgb; + this.cachedBgRgb = bgArgb; + return img; + } + /** * Computes and returns the 32-bit ARGB pixel array for this symbol. * The returned array has length (width * height). diff --git a/lib3270j/src/main/java/org/lib3270j/screen/ScreenBuffer.java b/lib3270j/src/main/java/org/lib3270j/screen/ScreenBuffer.java index fae33f0..c217566 100644 --- a/lib3270j/src/main/java/org/lib3270j/screen/ScreenBuffer.java +++ b/lib3270j/src/main/java/org/lib3270j/screen/ScreenBuffer.java @@ -36,8 +36,12 @@ public class ScreenBuffer { private byte defaultGr = 0x00; private byte defaultCs = 0x00; private byte defaultIc = 0x00; - private final EbcdicTranslator translator; + private final Object renderLock = new Object(); + + public Object getRenderLock() { + return renderLock; + } public ScreenBuffer(TerminalModel model, EbcdicTranslator translator) { this.translator = translator; @@ -79,6 +83,50 @@ public class ScreenBuffer { return buffer[addr]; } + private ExtendedAttribute[] displaySnapshot; + private int displayRows; + private int displayCols; + private int displayCursorAddress; + + /** + * Atomically creates a snapshot of the current presentation buffer for tear-free rendering. + * Takes ~2 microseconds and eliminates mutual thread contention with the UI thread. + */ + public synchronized void updateDisplaySnapshot() { + int size = rows * cols; + if (displaySnapshot == null || displaySnapshot.length < size) { + displaySnapshot = new ExtendedAttribute[size]; + for (int i = 0; i < size; i++) { + displaySnapshot[i] = new ExtendedAttribute(); + } + } + for (int i = 0; i < size; i++) { + displaySnapshot[i].copyFrom(buffer[i]); + } + this.displayRows = rows; + this.displayCols = cols; + this.displayCursorAddress = cursorAddress; + } + + public synchronized ExtendedAttribute getDisplayCell(int addr) { + if (displaySnapshot == null || addr < 0 || addr >= displayRows * displayCols) { + return getCell(addr); + } + return displaySnapshot[addr]; + } + + public synchronized int getDisplayRows() { + return displayRows > 0 ? displayRows : rows; + } + + public synchronized int getDisplayCols() { + return displayCols > 0 ? displayCols : cols; + } + + public synchronized int getDisplayCursorAddress() { + return displayRows > 0 ? displayCursorAddress : cursorAddress; + } + // ========== Dimension accessors ========== public int getRows() { return rows; } public int getCols() { return cols; } diff --git a/lib3270j/src/main/java/org/lib3270j/telnet/TelnetConnection.java b/lib3270j/src/main/java/org/lib3270j/telnet/TelnetConnection.java index 0d967f7..a6126cf 100644 --- a/lib3270j/src/main/java/org/lib3270j/telnet/TelnetConnection.java +++ b/lib3270j/src/main/java/org/lib3270j/telnet/TelnetConnection.java @@ -149,9 +149,7 @@ public class TelnetConnection { log.fine("RCVD " + n + " bytes: " + formatHex(buf, 0, n)); } try { - for (int i = 0; i < n; i++) { - fsm.feedByte(buf[i] & 0xFF); - } + fsm.feedBytes(buf, 0, n); fsm.endOfNetworkData(); } catch (Throwable t) { log.log(Level.SEVERE, "Exception processing incoming data stream", t); diff --git a/lib3270j/src/main/java/org/lib3270j/telnet/TelnetFSM.java b/lib3270j/src/main/java/org/lib3270j/telnet/TelnetFSM.java index ce2c6b0..d6436ba 100644 --- a/lib3270j/src/main/java/org/lib3270j/telnet/TelnetFSM.java +++ b/lib3270j/src/main/java/org/lib3270j/telnet/TelnetFSM.java @@ -58,6 +58,7 @@ public class TelnetFSM { private int eXmitSeq; private int responseRequired = RSF_NO_RESPONSE; private boolean deferredWillTtype; + private boolean tn3270eDeviceTypeSent; // Connection references private TelnetConnection connection; @@ -103,6 +104,7 @@ public class TelnetFSM { java.util.Arrays.fill(hisOpts, false); java.util.Arrays.fill(eFuncs, false); tn3270eNegotiated = false; + tn3270eDeviceTypeSent = false; tn3270eSubmode = TN3270ESubmode.UNBOUND; tn3270eBound = false; eXmitSeq = 0; @@ -118,6 +120,37 @@ public class TelnetFSM { changeState(ConnectionState.TELNET_PENDING); } + /** + * Feed a bulk buffer of bytes from the network into the FSM. + */ + public void feedBytes(byte[] buf, int offset, int len) { + int end = offset + len; + int i = offset; + while (i < end) { + if (state == TNS_DATA) { + int start = i; + while (i < end && (buf[i] & 0xFF) != IAC) { + i++; + } + if (i > start) { + if (connectionState == ConnectionState.TELNET_PENDING) { + changeState(ConnectionState.CONNECTED_NVT); + } + if (connectionState.is3270() || connectionState.isTn3270e() || connectionState == ConnectionState.TELNET_PENDING) { + ibuf.write(buf, start, i - start); + } + } + if (i < end) { + state = TNS_IAC; + i++; + } + } else { + feedByte(buf[i] & 0xFF); + i++; + } + } + } + /** * Feed a single byte from the network into the FSM. */ @@ -172,8 +205,8 @@ public class TelnetFSM { changeState(ConnectionState.CONNECTED_NVT); } - // Accumulate data for 3270, TN3270E (including SSCP-LU and unbound states) - if (connectionState.is3270() || connectionState.isTn3270e()) { + // Accumulate data for 3270, TN3270E (including SSCP-LU and unbound states, and pending) + if (connectionState.is3270() || connectionState.isTn3270e() || connectionState == ConnectionState.TELNET_PENDING) { ibuf.write(c); } // NVT data would go to NVT processor (not implemented in initial version) @@ -189,7 +222,7 @@ public class TelnetFSM { break; case EOR: // End of record — process accumulated 3270 data log.fine("RCVD EOR"); - if (connectionState.is3270() || connectionState.isTn3270e()) { + if (connectionState.is3270() || connectionState.isTn3270e() || connectionState == ConnectionState.TELNET_PENDING) { processEndOfRecord(); } ibuf.reset(); @@ -235,7 +268,9 @@ public class TelnetFSM { break; case TELOPT_TN3270E: - if (!hisOpts[opt]) { + if (!config.isTn3270eEnabled()) { + sendCommand(DONT, opt); + } else if (!hisOpts[opt]) { hisOpts[opt] = true; sendCommand(DO, opt); } @@ -278,7 +313,7 @@ public class TelnetFSM { case TELOPT_TTYPE: if (!myOpts[opt]) { myOpts[opt] = true; - if (hisOpts[TELOPT_TN3270E]) { + if (config.isTn3270eEnabled() && hisOpts[TELOPT_TN3270E]) { // Defer TTYPE response until TN3270E negotiation completes deferredWillTtype = true; } else { @@ -288,11 +323,16 @@ public class TelnetFSM { break; case TELOPT_TN3270E: - if (!myOpts[opt]) { + if (!config.isTn3270eEnabled()) { + sendCommand(WONT, opt); + } else if (!myOpts[opt]) { myOpts[opt] = true; sendCommand(WILL, opt); // Start TN3270E sub-negotiation: send device type request - sendTN3270EDeviceTypeRequest(); + if (!tn3270eDeviceTypeSent) { + sendTN3270EDeviceTypeRequest(); + tn3270eDeviceTypeSent = true; + } } break; @@ -428,7 +468,10 @@ public class TelnetFSM { switch (op) { case OP_SEND: // Host asks us to send device-type request - sendTN3270EDeviceTypeRequest(); + if (!tn3270eDeviceTypeSent) { + sendTN3270EDeviceTypeRequest(); + tn3270eDeviceTypeSent = true; + } break; case OP_DEVICE_TYPE: @@ -488,14 +531,19 @@ public class TelnetFSM { pos++; } + // Check if REJECT if (pos < data.length && (data[pos] & 0xFF) == OP_REJECT) { - // Rejection pos++; - int reason = -1; - if (pos < data.length && (data[pos] & 0xFF) == OP_REASON) { - pos++; - if (pos < data.length) { - reason = data[pos] & 0xFF; + int reason = (pos < data.length) ? (data[pos] & 0xFF) : REASON_UNSUPPORTED_REQ; + if (reason == REASON_INV_DEVICE_TYPE || reason == REASON_UNSUPPORTED_REQ) { + // Try fallback model 2 if we were requesting something else + if (config.getModel() != TerminalModel.IBM_3278_2 && + config.getModel() != TerminalModel.IBM_3279_2) { + log.warning("TN3270E device-type rejected (" + + TN3270EConstants.reasonName(reason) + "), retrying with IBM-3278-2"); + config.setModel(TerminalModel.IBM_3278_2); + sendTN3270EDeviceTypeRequest(); + return; } } log.warning("TN3270E device-type rejected: " + TN3270EConstants.reasonName(reason)); @@ -563,33 +611,86 @@ public class TelnetFSM { log.info("SENT SB TN3270E FUNCTIONS REQUEST " + funcNames + " SE"); } - private void handleTN3270EFunctions(byte[] data) { - // Parse: TN3270E FUNCTIONS IS [func...] - int pos = 2; // Skip TN3270E, FUNCTIONS + private void sendTN3270EFunctionsIs() { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write(IAC); + out.write(SB); + out.write(TELOPT_TN3270E); + out.write(OP_FUNCTIONS); + out.write(OP_IS); - if (pos < data.length && (data[pos] & 0xFF) == OP_IS) { - pos++; // Skip IS + StringBuilder funcNames = new StringBuilder(); + for (int i = 0; i < eFuncs.length; i++) { + if (eFuncs[i]) { + out.write(i); + if (funcNames.length() > 0) funcNames.append(" "); + funcNames.append(TN3270EConstants.functionName(i)); + } } - // The remaining bytes are the agreed-upon functions - java.util.Arrays.fill(eFuncs, false); - StringBuilder funcNames = new StringBuilder(); + out.write(IAC); + out.write(SE); + sendBytes(out.toByteArray()); + log.info("SENT SB TN3270E FUNCTIONS IS " + funcNames + " SE"); + } + + private void handleTN3270EFunctions(byte[] data) { + // Parse: TN3270E FUNCTIONS REQUEST [func...] or TN3270E FUNCTIONS IS [func...] + int pos = 1; + boolean isRequest = false; + + while (pos < data.length) { + int b = data[pos] & 0xFF; + if (b == OP_FUNCTIONS) { + pos++; + } else if (b == OP_REQUEST) { + isRequest = true; + pos++; + break; + } else if (b == OP_IS) { + isRequest = false; + pos++; + break; + } else { + pos++; + } + } + + // The remaining bytes are the proposed/agreed functions + boolean[] hostFuncs = new boolean[8]; while (pos < data.length) { int func = data[pos] & 0xFF; if (func <= FUNC_SNA_SENSE) { - eFuncs[func] = true; - if (funcNames.length() > 0) funcNames.append(" "); - funcNames.append(TN3270EConstants.functionName(func)); + hostFuncs[func] = true; } pos++; } + if (isRequest) { + // Host sent FUNCTIONS REQUEST -> We reply with FUNCTIONS IS (intersection of functions) + for (int i = 0; i < eFuncs.length; i++) { + eFuncs[i] = eFuncs[i] && hostFuncs[i]; + } + sendTN3270EFunctionsIs(); + } else { + // Host sent FUNCTIONS IS -> Accept host's agreed function list + for (int i = 0; i < eFuncs.length; i++) { + eFuncs[i] = hostFuncs[i]; + } + } + tn3270eNegotiated = true; - log.info("TN3270E functions IS: " + funcNames); + log.info("TN3270E functions negotiated: " + getNegotiatedFunctionNames()); log.info("TN3270E negotiation complete"); - // Move to CONNECTED_UNBOUND or CONNECTED_SSCP - changeState(ConnectionState.CONNECTED_UNBOUND); + // RFC 2355: If BIND-IMAGE function is not negotiated, the emulation session is considered + // to be bound immediately upon completion of the FUNCTIONS negotiation. + if (eFuncs[FUNC_BIND_IMAGE]) { + changeState(ConnectionState.CONNECTED_UNBOUND); + } else { + changeState(ConnectionState.CONNECTED_TN3270E); + tn3270eSubmode = TN3270ESubmode.E_3270; + } // Notify listeners for (ConnectionListener l : connectionListeners) { @@ -597,12 +698,29 @@ public class TelnetFSM { } } + private String getNegotiatedFunctionNames() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < eFuncs.length; i++) { + if (eFuncs[i]) { + if (sb.length() > 0) sb.append(" "); + sb.append(TN3270EConstants.functionName(i)); + } + } + return sb.length() > 0 ? sb.toString() : ""; + } + // ========== End of Record processing ========== private void processEndOfRecord() { byte[] data = ibuf.toByteArray(); + ibuf.reset(); if (data.length == 0) return; + if (connectionState == ConnectionState.TELNET_PENDING && !tn3270eNegotiated) { + log.info("Received EOR during TELNET_PENDING - transitioning to plain TN3270 mode"); + changeState(ConnectionState.CONNECTED_3270); + } + if (tn3270eNegotiated) { // TN3270E mode: data starts with 5-byte header processTN3270ERecord(data); @@ -701,11 +819,11 @@ public class TelnetFSM { bindRa = screenBuffer.getMaxRows(); bindCa = screenBuffer.getMaxCols(); break; - case 0x7e: + case 0x7E: // Both default and alternate = specified values bindRa = bindRd; bindCa = bindCd; break; - case 0x7f: + case 0x7F: // Default and alternate are both specified separately bindRa = data[EH_SIZE + BIND_OFF_RA] & 0xFF; bindCa = data[EH_SIZE + BIND_OFF_CA] & 0xFF; @@ -767,7 +885,20 @@ public class TelnetFSM { break; default: - log.info("Unhandled TN3270E data type: " + dataType); + // Check if the host sent a raw 3270 data stream (e.g. 0xF5 EraseWrite, 0x7E EW Alternate, 0xF1 Write, etc.) + // This happens when the server ignores or drops TN3270E framing and speaks plain 3270 data stream. + if (dataType == 0xF5 || dataType == 0x7E || dataType == 0xF1 || dataType == 0x6F || + dataType == 0x6E || dataType == 0xF2 || dataType == 0xF6 || dataType == 0x05 || + dataType == 0x0D || dataType == 0x01 || (data.length >= 2 && (data[0] & 0xFF) == 0x11)) { + log.warning("Received plain 3270 command (0x" + Integer.toHexString(dataType) + + ") in TN3270E mode — automatically switching to plain TN3270 mode"); + tn3270eNegotiated = false; + changeState(ConnectionState.CONNECTED_3270); + dsProcessor.processRecord(data, 0, data.length, true); + notifyScreenUpdate(); + } else { + log.info("Unhandled TN3270E data type: " + dataType); + } break; } } @@ -790,7 +921,7 @@ public class TelnetFSM { if (connectionState != ConnectionState.TELNET_PENDING) return; // For TN3270E, we wait for TN3270E negotiation to complete - if (myOpts[TELOPT_TN3270E] && hisOpts[TELOPT_TN3270E]) { + if (config.isTn3270eEnabled() && myOpts[TELOPT_TN3270E] && hisOpts[TELOPT_TN3270E]) { return; // TN3270E in progress } diff --git a/lib3270j/src/test/java/org/lib3270j/datastream/QueryReplyBuilderTest.java b/lib3270j/src/test/java/org/lib3270j/datastream/QueryReplyBuilderTest.java index 071a3a9..447929f 100644 --- a/lib3270j/src/test/java/org/lib3270j/datastream/QueryReplyBuilderTest.java +++ b/lib3270j/src/test/java/org/lib3270j/datastream/QueryReplyBuilderTest.java @@ -15,8 +15,27 @@ public class QueryReplyBuilderTest { private final QueryReplyBuilder qrBuilder = new QueryReplyBuilder(screen); @Test - public void testBuildAllQueryRepliesDefaultNone() { - assertEquals(GraphicsMode.NONE, qrBuilder.getGraphicsMode()); + public void testBuildAllQueryRepliesDefaultBoth() { + assertEquals(GraphicsMode.BOTH, qrBuilder.getGraphicsMode()); + byte[] replies = qrBuilder.buildAllQueryReplies(80, 43, 80 * 43); + assertNotNull(replies); + assertTrue(replies.length > 0); + assertEquals((byte) AID_SF, replies[0]); + + // In GraphicsMode.BOTH, Vector Graphics QR 0xB0 must be present + boolean hasB0 = false; + for (int i = 0; i < replies.length - 3; i++) { + if ((replies[i] & 0xFF) == 0x81 && (replies[i + 1] & 0xFF) == QR_GRAPHICS) { + hasB0 = true; + break; + } + } + assertTrue(hasB0); + } + + @Test + public void testBuildAllQueryRepliesExplicitNone() { + qrBuilder.setGraphicsMode(GraphicsMode.NONE); byte[] replies = qrBuilder.buildAllQueryReplies(80, 43, 80 * 43); assertNotNull(replies); assertTrue(replies.length > 0); @@ -156,4 +175,61 @@ public class QueryReplyBuilderTest { assertEquals(80, altCols); assertEquals(43, altRows); } + + @Test + public void testProgrammedSymbolsDescriptorsSingleAndTriplePlane() { + qrBuilder.setGraphicsMode(GraphicsMode.PROGRAMMED_SYMBOLS); + byte[] requested = new byte[] { (byte) QR_CHARSETS }; + byte[] replies = qrBuilder.buildQueryReplies(requested, 80, 43, 80 * 43); + + assertNotNull(replies); + int offset = -1; + for (int i = 0; i < replies.length - 3; i++) { + if ((replies[i] & 0xFF) == 0x81 && (replies[i + 1] & 0xFF) == QR_CHARSETS) { + offset = i + 2; + break; + } + } + assertTrue(offset >= 0, "QR_CHARSETS must be present"); + + // QR_CHARSETS payload structure: + // Flags (2 bytes), SDW (1 byte), SDH (1 byte), Form (1 byte), DevType (2 bytes), Res (1 byte), DL (1 byte) + // DL is at offset + 8, and is 7 bytes per descriptor. + int dl = replies[offset + 8] & 0xFF; + assertEquals(7, dl); + + int descOffset = offset + 9; + + // Descriptor 1: SET 0 (Base) -> flags 0x10 + assertEquals(0x00, replies[descOffset] & 0xFF); + assertEquals(0x10, replies[descOffset + 1] & 0xFF); + + // Descriptor 2: SET 1 (APL) -> flags 0x00 + assertEquals(0x01, replies[descOffset + 7] & 0xFF); + assertEquals(0x00, replies[descOffset + 7 + 1] & 0xFF); + + // Descriptor 3: PSA (Single plane) -> flags 0x80 (Loadable, single-plane) + assertEquals(0x02, replies[descOffset + 14] & 0xFF); + assertEquals(0x80, replies[descOffset + 14 + 1] & 0xFF); + + // Descriptor 4: PSB (Single plane) -> flags 0x80 (Loadable, single-plane) + assertEquals(0x03, replies[descOffset + 21] & 0xFF); + assertEquals(0x80, replies[descOffset + 21 + 1] & 0xFF); + + // Descriptor 5: PSC (Triple plane) -> flags 0xC0 (Loadable | Triple-plane) + assertEquals(0x04, replies[descOffset + 28] & 0xFF); + assertEquals(0xC0, replies[descOffset + 28 + 1] & 0xFF); + + // Descriptor 6: PSD (Triple plane) -> flags 0xC0 (Loadable | Triple-plane) + assertEquals(0x05, replies[descOffset + 35] & 0xFF); + assertEquals(0xC0, replies[descOffset + 35 + 1] & 0xFF); + + // Descriptor 7: PSE (Triple plane) -> flags 0xC0 (Loadable | Triple-plane) + assertEquals(0x06, replies[descOffset + 42] & 0xFF); + assertEquals(0xC0, replies[descOffset + 42 + 1] & 0xFF); + + // Descriptor 8: PSF (Triple plane) -> flags 0xC0 (Loadable | Triple-plane) + assertEquals(0x07, replies[descOffset + 49] & 0xFF); + assertEquals(0xC0, replies[descOffset + 49 + 1] & 0xFF); + } } diff --git a/lib3270j/src/test/java/org/lib3270j/graphics/GraphicsModeTest.java b/lib3270j/src/test/java/org/lib3270j/graphics/GraphicsModeTest.java index e1bcaa2..e7afd15 100644 --- a/lib3270j/src/test/java/org/lib3270j/graphics/GraphicsModeTest.java +++ b/lib3270j/src/test/java/org/lib3270j/graphics/GraphicsModeTest.java @@ -46,11 +46,11 @@ public class GraphicsModeTest { @Test public void testConnectionConfigDefault() { ConnectionConfig config = new ConnectionConfig(); - assertEquals(GraphicsMode.NONE, config.getGraphicsMode()); - - config.setGraphicsMode(GraphicsMode.BOTH); assertEquals(GraphicsMode.BOTH, config.getGraphicsMode()); + config.setGraphicsMode(GraphicsMode.NONE); + assertEquals(GraphicsMode.NONE, config.getGraphicsMode()); + config.setGraphicsMode(null); assertEquals(GraphicsMode.NONE, config.getGraphicsMode()); } diff --git a/lib3270j/src/test/java/org/lib3270j/graphics/ProgramSymbolManagerTest.java b/lib3270j/src/test/java/org/lib3270j/graphics/ProgramSymbolManagerTest.java index 0568190..efb22a4 100644 --- a/lib3270j/src/test/java/org/lib3270j/graphics/ProgramSymbolManagerTest.java +++ b/lib3270j/src/test/java/org/lib3270j/graphics/ProgramSymbolManagerTest.java @@ -51,7 +51,7 @@ public class ProgramSymbolManagerTest { ProgramSymbolSet.SymbolSlot slot = manager.getSymbol(0x40, 0x41); assertNotNull(slot); assertEquals(9, slot.getWidth()); - assertEquals(16, slot.getHeight()); + assertEquals(12, slot.getHeight()); assertFalse(slot.isTriplePlane()); // Verify pixel data (Row 0 Col 0 is 1) @@ -64,10 +64,33 @@ public class ProgramSymbolManagerTest { int bg = 0xFF000000; // Black int[] rgb = slot.getRgbPixels(fg, bg); assertNotNull(rgb); - assertEquals(9 * 16, rgb.length); + assertEquals(9 * 12, rgb.length); assertEquals(fg, rgb[0]); // Row 0 Col 0 pixel should be foreground Green } + @Test + public void testExplicitCellDimensions() { + ProgramSymbolManager manager = new ProgramSymbolManager(); + manager.setDefaultCellDimensions(9, 16); + + byte[] payload = new byte[4 + 18]; + payload[0] = 0x01; // Format 1 + payload[1] = 0x40; // LCID 0x40 + payload[2] = 0x41; // Code point 0x41 + payload[3] = 0x02; // RWS 2 + payload[4] = (byte) 0x80; + payload[5] = (byte) 0x00; + for (int r = 0; r < 16; r++) { + payload[6 + r] = (byte) 0xFF; + } + + manager.loadps(payload); + ProgramSymbolSet.SymbolSlot slot = manager.getSymbol(0x40, 0x41); + assertNotNull(slot); + assertEquals(9, slot.getWidth()); + assertEquals(16, slot.getHeight()); + } + @Test public void testTriplePlaneMultiColorComposite() { ProgramSymbolManager manager = new ProgramSymbolManager();