From e8dd3511db74a8ae1e749e2c700d9ce2c68f84b1 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 1 Sep 2014 14:03:55 -0700 Subject: [PATCH] Add some tolerance in the tap to click code. Implement right clicking. --- libs/limelight-common.jar | Bin 416365 -> 416374 bytes src/com/limelight/Game.java | 96 ++++++++---------- .../limelight/binding/input/TouchContext.java | 93 +++++++++++++++++ 3 files changed, 138 insertions(+), 51 deletions(-) create mode 100644 src/com/limelight/binding/input/TouchContext.java diff --git a/libs/limelight-common.jar b/libs/limelight-common.jar index 3c3b9166a39f1b377460a4ffaee6e174479e049f..9e9c6f512bd5cd960819d7ceaf86ec421be1c7cc 100644 GIT binary patch delta 2939 zcmaF6Me^GgN!|c&W)=|!4h{|mwk*YsybBDNS!3ijZ!lGOmc%y0;3VFWXd2WEmrrZ-wL zYHW@U?EwoCLejcfk(bY@7Xo1FX@YBps|| z^Q_V?u+-#8AC2h`T-o?0Unu3-oLS+;4pKMSpu}wY1~)eL&7bRiz=k74>YH^~k=5{R z{?suGqQ)TrY?jF8(>*C*`zAw0IHza3vk7i4nYtQmJIL9S?T>IzH}GI%-yA=EDa=4^ zm?+<7@45YOLnk|I{yvgLrIK zDM)~KI=>ei*K|EsHjd3bTi78|kvY1sOhFUxpDbC$%~L$Rx0X zH-9-A3$|u+$SEd>V;wHpZJvI98Q8$h4wv#E(i^W`1xs)4yz?F`HF@D@jp-Y_*+dub zxX%Z&Ve-PyHk-e{b%4p*Y%cqt0ru(Ug`ZWxq98};PCoaUe>2Os!w?ZrDxCb`tMF#l zpSwlC#>^_!nEc@@>-G=4jBa2zP6oyLhp(*D0@#$ccknZ=2I~aHFG$_A05*Z?H34kg z+v|iFTOm@QfP`q^pZ*|#jcvP!C}RQGAKQ0JG8TdrZP%A!+yr4gkz@QX%zQLc5u8L5 z!Wh}6ix@L1)L+nM)H2^0FS1m8$%EMLjLU2tEteK<<@s>I(|bb3Y=g|M!^?lL?pvjN z_2WVQ4~u2Kd#(;yd1l5;mGrlpzun4yU%c=Ck6*k8gtqM|Fw~iH#%s-*@GYDEeLB%6 zsUCX!(iJZs^SXRds4-i~6PWRv0>)CqG*0tJU5@+#tP&85ed6^tnMayv$ zzscLyzq%C-9}>9b zlxnuJ@?Z82KB7^3Tq8*BOl_ZA&3r>SN&CYgDQ|RZ9N$~-Xx?Xhrl#Q2x?;b}`)3<5 z&rpb;yu`lVaiZp#OXo_QIn4_$zbqFi<_MJC_h|3uQ;9CKruK90eqk^FrQY$2^0ZeK z3tW^-kGzh!+39ANxQy>&q|a5ww=Si^$9EwGbeEz2r1kFRPgugR=DZ&lrwce&kR zpV@+d&^BLn`@g~g-s~K+u5O(Biiv^2o|S2n3hL{@@!|1SmRT3k#Fa*^h2H|W%(-p$lShw#gI2T-ygR8;qe$|ZL z;4-*X;=znPj%>+bhLRK1 zoJuFQ9I(g>C$=~+!_%291I*as%$5meD7Zk)sda&>x#z-`0+w=hg*s!ED^!Zx4a&%Y zG0wU{U8v&@Wpukk)x3c*d_AC2YhVm+PpAu%JfU`-^n}`_=f#!^wtboxTLGBC>CKi0 zW>k4YeR>DRu=9cXVwDeDHdu{>FIy~_Q2}GzfH5rmpi(pZAXZHChsHphKhzaR{h{U= z20)!NEdc8FuK{d9V1vB^A-bn;3S2~Jyh#{D{y_+vCRmgwlueq+F9IS8_EbXzqpWs- zHzSh>1Ed8Ba&}z8w1!oz3=A5)3=C!{&W@NqA(YJ(>^Ik0?ab?07#KcqqAN;E0$E@< zT`i0a+?t$j6UHXZRGAJEHJIKR#wG-I%sh~&P##EB36zR>UYieGN=%H%LmU8Y1Oa%_upYD*~!ZGJ;K-X+|qV%0Gh5 znNer@Hd*yT8vYtS4FbfG0vL4Gm_1b a@xk=pk!*g93Ddoz*ksvO+Ojb)FaQ899^7jH delta 3141 zcmeyiMe^+yN!|c&W)=|!4h{~6=QXk$c^4QkTWpZnyuqN63B;JLU(KkoImUP+6SEYT z^kxCG*I>rvg)th_bM4uLHd|QA34;~t6f%N^c&1;lXA{}H&}R-aNPM$HKno+7aXc^+ zEHYg_k5Oa#0|z$o%|)T5V7bY**?N=D$FNP73qJ``JKZsiQDgc{M>g5b`VlH%U7N$A zJ-})=FN`r`0V&#iE5Q^jGTER+d$VoQ4Tw64wEqy%jn_0LJETcZ=W}7>*_@ei5$vDM zw%H#zz`6}e(!uIB&noQ#OHBv)V6%Tk3Oh)CvO$U2<~Q}hU_-&2ie_V0n9TH@Zfty; zKXuH4NIL{*O!lwfn=a+f#9q4EAwKL z+8lpm64;@ezZ{JP+p{_36cgBykXWhpVH2Bv-kXhm^Stx(A%=rv3nad|?vepS&&F$4 z!Fo1#-gysJG2OYHkWR_!(D2^nxN8B%!dqPKdD;ECz}wkdVlBCsD>Su=}^~mSijhOK#VfVcY~^ zJ&|Ml4@v8eVT^jyeS_GmKjfNMBpl`Pl2uduz3Y~Rj9Lp*Gjy44N-hbh z+*0$I_2`3UUE}&!9;G!OnEz-Tuf3!ds%4y}b~5t!n!Vp{{hssQeqSB)hK3$?zP6o{ z0z0Q}?TWeMI(n0UZ?dyQi#WImgr%R7Y=`>pU?@jG(Y)! zZ_^gFgt_OB`!;FbeY9{&!}C2mybXPy_8bh|xL zI=8If{vfd`vrA&>dkNQ5Ej!O&?D%ecO!@Ki89hCFTen~T%(pJ?y=9a9n?1AVB>$FQ zUZ>`v>#(nBiM+yAO`pqt3l_H2NAJk}Zrvr>vVt%EYJE zu~!ue?#iV{UPs*Qb+c29XwT4Bdp)6SacRz;|8G+}Vj5m?gd|P~QTHfs^DDY_Z*%Ev zJC;vdIcKgi%DMUT<@^9|c8;F@>eh!$3=GDs3=D|+!eWDjD+2=q!(`V0<>~AF7}>Tb zm@%q@voNHL2Z>GR3uY7Ce$tXr36hE4Su?(81LfK651bg6aD!N&qG9`bKgR7~71JL$ zFMM~AWrZ(kO{xCd$hgM4L__qXoFw0K0p8e-Yzca1p*; zznZZaT>4H2)r0M4TN&HWwlcM!ZDnph+sd;2Y%A-F?aa?>WT)@2Wvc=CWxBZ?n;V$X zV8<2>sxznGvttVbGtBMTLcmge_H0RD#%FuB7%(Hqfh`owSmnSL31+Z4vPFRz$&PIC zV8&5Lwq!6v+X-q;lM`DGSmdJJfKorVGI#Zs0*__p>|#JgxY29#g+=T zeZCi40hl4=&6WpdG3v*nHd=L;2J=T z5=$gae8Ft8V3+6xvq>}Eutt`0W)zsNW5dWXUBjM@2dro!NYN=LR7GMs0p5&EA`Fm* z9mv6t7U#@qVq#!$VPRk}0$B;ig?@0o(g?S{j5*9u&ceXZ%fY~43|9+c1P8*^vrX>{ zVN(M8jb-l@#vP0d3+dO#i{-}K0EXawfemBd_QU|?`$WMD7{ zxfPDZ3gMcBrhA98Nr5f-QN-Ys!@tdQ)0-pN>=-9bKNQL4$b8+3ZTep;Hl^tr pQEXZ&;kIlHdg+-Zndy1?MX3SatZX2c_%rx3Y?onRSYQj{0suN0D 1) { + // The original secondary touch now becomes primary + context.touchDownEvent((int)event.getX(1), (int)event.getY(1)); + } break; case MotionEvent.ACTION_MOVE: - touchMoveEvent(eventX, eventY); + // ACTION_MOVE is special because it always has actionIndex == 0 + // We'll call the move handlers for all indexes manually + for (int i = 0; i < touchContextMap.length; i++) { + touchContextMap[i].touchMoveEvent(eventX, eventY); + } break; default: return super.onTouchEvent(event); @@ -441,28 +435,28 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM if ((changedButtons & MotionEvent.BUTTON_PRIMARY) != 0) { if ((event.getButtonState() & MotionEvent.BUTTON_PRIMARY) != 0) { - conn.sendMouseButtonDown((byte) 0x01); + conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_LEFT); } else { - conn.sendMouseButtonUp((byte) 0x01); + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT); } } if ((changedButtons & MotionEvent.BUTTON_SECONDARY) != 0) { if ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) { - conn.sendMouseButtonDown((byte) 0x03); + conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_RIGHT); } else { - conn.sendMouseButtonUp((byte) 0x03); + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_RIGHT); } } if ((changedButtons & MotionEvent.BUTTON_TERTIARY) != 0) { if ((event.getButtonState() & MotionEvent.BUTTON_TERTIARY) != 0) { - conn.sendMouseButtonDown((byte) 0x02); + conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_MIDDLE); } else { - conn.sendMouseButtonUp((byte) 0x02); + conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_MIDDLE); } } diff --git a/src/com/limelight/binding/input/TouchContext.java b/src/com/limelight/binding/input/TouchContext.java new file mode 100644 index 00000000..ad215458 --- /dev/null +++ b/src/com/limelight/binding/input/TouchContext.java @@ -0,0 +1,93 @@ +package com.limelight.binding.input; + +import com.limelight.nvstream.NvConnection; +import com.limelight.nvstream.input.MouseButtonPacket; + +public class TouchContext { + private int lastTouchX = 0; + private int lastTouchY = 0; + private int originalTouchX = 0; + private int originalTouchY = 0; + private long originalTouchTime = 0; + + private NvConnection conn; + private int actionIndex; + + private static final int TAP_MOVEMENT_THRESHOLD = 5; + private static final int TAP_TIME_THRESHOLD = 500; + + public TouchContext(NvConnection conn, int actionIndex) + { + this.conn = conn; + this.actionIndex = actionIndex; + } + + private boolean isTap() + { + int xDelta = Math.abs(lastTouchX - originalTouchX); + int yDelta = Math.abs(lastTouchY - originalTouchY); + long timeDelta = System.currentTimeMillis() - originalTouchTime; + + return xDelta <= TAP_MOVEMENT_THRESHOLD && + yDelta <= TAP_MOVEMENT_THRESHOLD && + timeDelta <= TAP_TIME_THRESHOLD; + } + + private byte getMouseButtonIndex() + { + if (actionIndex == 1) { + return MouseButtonPacket.BUTTON_RIGHT; + } + else { + return MouseButtonPacket.BUTTON_LEFT; + } + } + + public boolean touchDownEvent(int eventX, int eventY) + { + originalTouchX = lastTouchX = eventX; + originalTouchY = lastTouchY = eventY; + originalTouchTime = System.currentTimeMillis(); + + return true; + } + + public void touchUpEvent(int eventX, int eventY) + { + if (isTap()) + { + byte buttonIndex = getMouseButtonIndex(); + + // Lower the mouse button + conn.sendMouseButtonDown(buttonIndex); + + // We need to sleep a bit here because some games + // do input detection by polling + try { + Thread.sleep(100); + } catch (InterruptedException e) {} + + // Raise the mouse button + conn.sendMouseButtonUp(buttonIndex); + } + } + + public boolean touchMoveEvent(int eventX, int eventY) + { + if (eventX != lastTouchX || eventY != lastTouchY) + { + // We only send moves for the primary touch point + if (actionIndex == 0) { + conn.sendMouseMove((short)(eventX - lastTouchX), + (short)(eventY - lastTouchY)); + } + + lastTouchX = eventX; + lastTouchY = eventY; + + return true; + } + + return false; + } +}