From 55e9514a6265cb58c01aabdb095d84446bdfde1d Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov <lyubomir.marinov@jitsi.org> Date: Tue, 15 Jan 2013 21:33:53 +0000 Subject: [PATCH] Fixes an issue of overlapping videos which could cause the local video in a call to be displayed bellow the remote video. Works on remedying issues with telephony conferences utilizing the Jitsi VideoBridge server-side technology. --- lib/native/linux-64/libjnawtrenderer.so | Bin 13905 -> 13592 bytes lib/native/linux/libjnawtrenderer.so | Bin 10863 -> 10442 bytes lib/native/mac/libjnawtrenderer.jnilib | Bin 59876 -> 41576 bytes lib/native/windows-64/jnawtrenderer.dll | Bin 65024 -> 50329 bytes lib/native/windows/jnawtrenderer.dll | Bin 58368 -> 47636 bytes src/native/build.xml | 71 +- src/native/jawtrenderer/JAWTRenderer.h | 23 +- src/native/jawtrenderer/JAWTRenderer_Linux.c | 3 +- src/native/jawtrenderer/JAWTRenderer_MacOSX.m | 890 +++++------------ .../jawtrenderer/JAWTRenderer_Windows.c | 279 ++++++ .../jawtrenderer/JAWTRenderer_Windows.cpp | 178 ---- ...jmfext_media_renderer_video_JAWTRenderer.c | 117 +-- ...jmfext_media_renderer_video_JAWTRenderer.h | 36 +- .../jawtrenderer/windows/d3d_context.cpp | 68 -- src/native/jawtrenderer/windows/d3d_context.h | 71 -- .../jawtrenderer/windows/d3d_device.cpp | 196 ---- src/native/jawtrenderer/windows/d3d_device.h | 103 -- .../jawtrenderer/windows/d3d_surface.cpp | 77 -- src/native/jawtrenderer/windows/d3d_surface.h | 90 -- src/native/jawtrenderer/windows/d3dx9_utils.c | 273 ------ src/native/jawtrenderer/windows/d3dx9_utils.h | 82 -- .../impl/neomedia/AudioMediaStreamImpl.java | 177 +++- .../jitsi/impl/neomedia/MediaServiceImpl.java | 19 +- .../device/AudioMediaDeviceSession.java | 4 +- .../device/AudioMixerMediaDevice.java | 2 +- .../neomedia/device/DeviceConfiguration.java | 6 +- .../impl/neomedia/format/MediaFormatImpl.java | 475 +++++---- .../media/renderer/video/JAWTRenderer.java | 75 +- .../JAWTRendererSwingVideoComponent.java | 910 ------------------ .../video/JAWTRendererVideoComponent.java | 17 +- .../transform/csrc/CsrcTransformEngine.java | 35 +- src/org/jitsi/util/swing/FitLayout.java | 9 +- src/org/jitsi/util/swing/VideoContainer.java | 192 +--- src/org/jitsi/util/swing/VideoLayout.java | 49 +- 34 files changed, 1088 insertions(+), 3439 deletions(-) create mode 100644 src/native/jawtrenderer/JAWTRenderer_Windows.c delete mode 100644 src/native/jawtrenderer/JAWTRenderer_Windows.cpp delete mode 100644 src/native/jawtrenderer/windows/d3d_context.cpp delete mode 100644 src/native/jawtrenderer/windows/d3d_context.h delete mode 100644 src/native/jawtrenderer/windows/d3d_device.cpp delete mode 100644 src/native/jawtrenderer/windows/d3d_device.h delete mode 100644 src/native/jawtrenderer/windows/d3d_surface.cpp delete mode 100644 src/native/jawtrenderer/windows/d3d_surface.h delete mode 100644 src/native/jawtrenderer/windows/d3dx9_utils.c delete mode 100644 src/native/jawtrenderer/windows/d3dx9_utils.h rename src/{net/java/sip/communicator => org/jitsi}/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java (88%) delete mode 100644 src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java diff --git a/lib/native/linux-64/libjnawtrenderer.so b/lib/native/linux-64/libjnawtrenderer.so index 45cf80b7b3e5013ac938613d236c181bfb25b4cb..f6c61a4ff2d534e7e6350fa43e6b85abb5b712a3 100755 GIT binary patch literal 13592 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 AS^xk5 literal 13905 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 Ui*sjps+@LHTC_P^*^(&#-{+H!$^ZZW diff --git a/lib/native/linux/libjnawtrenderer.so b/lib/native/linux/libjnawtrenderer.so index 1d164d2746e0b7a9897c068dec2b5e539009f1f0..9285b223974048497bed4d0165d400110eeb8099 100755 GIT binary patch literal 10442 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 literal 10863 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 diff --git a/lib/native/mac/libjnawtrenderer.jnilib b/lib/native/mac/libjnawtrenderer.jnilib index 1f7e95feda0cbd6d913ad74b2d58579d42a93fc8..6ed7922fa292f68bc364bece78af059dc1e34f40 100755 GIT binary patch literal 41576 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 Zzw6=-G2)Ip;&RmSM*PpevvMr*e*pp;FW~?H literal 59876 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 diff --git a/lib/native/windows-64/jnawtrenderer.dll b/lib/native/windows-64/jnawtrenderer.dll index 9fa486a4ce8724895c4745ccfb1fdf1b4ba5a1cc..57548dbe3e98e949cb93807b9a68d7b37f393735 100755 GIT binary patch literal 50329 zcmeFa3w%`7)i-=5nF$F5PJjfXf{Yq$B1jXImQkoVWCqUQ1S2<5&?Mvn(U8RC3<+K! zI5WcWFgR_!J=R)k?NeKAi`L4esFMVe0A2!k;i4s=)iVqzph5t3-v8R?oVldx)8G3& z-}n2T_wD>R*?X_O_S$Q&z4qE`U(TWU)&Q5xahw@XB*Jl<5Yn%Z{r&zwt;ilSddm>* zrL;FL-DGmTap{~THBHur#`?vL<x8y<<#l!Sl66s)wb5N?t*NuxZ=7viT3=Z;e(>Od zIXdYQ2gg-DFo?^l|DuF@l;iF<aoh>+ipvHiC5_-}fpi6)OpdeS;WDVuk_P(A;z=6c zl(cY2&@UeZ(3o%5m{_||l7Y3d6lFxBK@`%9dQlXWb4$_)s{ht=+y)Yk@w1w~Up5&g zF4w?~3m-qlaeYMpJAUJ(sul@(C+@%>Vv*V&UoVnYuB2>yWw}(2cn}ZQiieu5Ndyt? zSICtF$2V$-`4+$ecvA2*YWc?BLawZEe1nF^+PEG$gx6wVXkj6jUpT%+!)qa)HsB$= z6<WUWm*FjHYNB+>aQq2U?4N(FTv>2@l}3-rycams4sRkZqgSKhu|7G0{DF8L=#N(z z9A7kR4ngO$EC`zDQM==Qg&gptTE?G9aP$?!`&k?kqL2&ZS5;eIL2>-h=M3**O2mHP zZ)z;{KQlI4^c=Hp=FmWOXbs1Sa)&6lsgDjq)OS#nEyvmkXgQ8R8eR|-yU18@qGy|R zK?gs&klTck(WIT@ggJ9>p2vv#_K5Nu#qu`yeTwDLKXaTf$gleeusy123l)+rt$-E; zPl)^rS-%ARg43ceC@Q1&AK|#y2t&H4I<Q$qg^|6Ye1h<%xQQKK(5)(#MTmO(l6db~ zpl%+GKkCg(V8Egb-ClZ|u&~2(&cs0OaFwW-$K(S~R2ovXdMA$2=t(xw*2#PGQ5Fo$ z2LlC>@L*~mgJ%OCWu%W7nRu*CW8_f5LB;YO5}rO2?<GZ1EZs<=wO&$J#j?f79EMEa zLH9tadbQ;_fJMc!wvN$}1{ce{Tat)5ITY#fSStR+aT?=H)>>Qm(U4bYbR-g~=0|IT zMN|emK}mfZHjBh3cS=scrVuPhFm$LVoGRM>-aK4XhKs&E(q{yS>;Y)maZx_0<}C(V zmn8*7=!fX%K^Eh>ENAtY#`77Z`pfrkCg6tpzKKNm(dd8CpS9yS1%qEi&}G?#B7~vt zss`GpK-0SFc}gBa5(Qed0(T)$p8>qfaz9FuFhZ{bqZ+^QMtgPb$|dc3OWx~}x64_R zmvWqYnqtZSBgtL5U2TT?I%Ty0IA_&ATnt_7^qf!Tz0f!G0Pp=BLit3OB?2Q0VMZY0 z+yxMEM|D8G4rTpC5p-vB0cgkvh{hFPM<VD^-%}`9a5~%(<HvK}#QQb_tp02Wt5hp6 z5taIaa;JMW5Zw0{>;WkvGz#!&!Wy6G_$m@1CVdO2d!y}*vhevuG4gV!`Y_OaK{i|S z_7kD;D8%F+#qR(<alrd-K^|jsDk8|NMLT4aeKy<}BtFAyHxij<@!2IY|v<gG} z7!=~va}<Y?pEF5=AuTZ^F_c11o|BU=%C4MAF4>-wtNw8?B#}Fm<6H`oqJj*CFsO)t zA^~O^oQjz1f@1o1NGYOXij-uC$_=Rr$w4|?-p}+u<gMg58jsAj<ZiZtnS#^mG|X;H z>pP^2woC$SGt;%jKn7SECd%0u5ilNF52JrYC0UgBqsDNE$&1mO?^Nze6_q5Hyh~KX z)JRtKAtG=Z+}Vn<rHe(mD7&kO26t5b=P$UO**{T9!5E5^Wcz|G?~9&$aye-V!TfV_ zL`T662TZ1XQiPPO1$!a^nvj5av0f@5f}}6Fd?5)+G$fHCuvT>0bI4e62$@5H(25R> zfF$+c$w**6N`n%r5h;_9W0`A^3e5yQ)uqhNMUIQr0(K1SNPtX~!AuDw7iA>;49S}r z^KGpKL8`?s<rIqYuFa`bN<Q<s_?#WRZb$111!flt_JDLl39=EoNM52c2vLcm2=7JE zijX*`^b!rlL>xsMO9LNiChkbdd{AiX8!h^0r=IC?DK}(mHF<iIQ1u+hjD!mnlyY)e z?N%#_M*^+*3(2O6T}8w#>2WKDc!xGQl{uBdROO|d4ak8aDqC}CB$3Jt6l@Loyw?K8 zpp&`ibz~rC2b4+I)FL9vx`YZ06_pH3nUPr;v8wLL=A@ehxlcX?T~jwh@6qXnOvnAR zbA`<#KoZ$H^SMBaYrmD+9|=(NVRF{|0x7vEU%rRNNG`Ls#LYs{Z_g=lDQk1q6M~d8 zzwP5BP!W+L=@p_l`pBL$DM}j}KvE*nW+Ag+k9=>=LZqm>s0j0))bl7P@56X0BXI=; zTT2G-JBcO;N{Q9ChxfXnQ=wiq{K?+yq9`~R-VwkrbTRBooV^a+keH782W6uC9*q)o z-7Z*hm;5GJ$TxE)P9?3FY?3lrW23y#WRCI6WEz=+c4@O6>~kAK#F%~-g=l0z9}|iZ zY+g1BIOT29B+)a8lO`x$*5?=!`A#|Hl>1!r5i(&SGDs~*c2@O+^O1;4J}h@c=2;n) z-0)Kg^N}!5m>X>qx_B$=5A<vS=GI+K`R!tPd$If`WG~9+Fy2x~nGo-kZbL;uR8%aV zES6Q&4qc)C(iuZEUuT7}RpHHfme}%}AJABvfH_It4tpkSCXI2z$jRr(wgvi738ov* zwnCcJgoVOw0vW4TV8MUrpl*u(B4ZvuwWJ{sh>Uq+9~@?cPqWaNZ^>R$7s01Ej4`6t zqHjb`Uxe`>En}uY9Z(9OGMJ_#^#(#v25&`N<MUboTz--)dK*IAPvBhj;O&IxB1ngN z1uNtNj%>M`sAK`4n;FYp1bB(iS*PYNfQ!06l6B>Nf*?-H3Lsn}(nrs+Ty;8`J<Q-2 z2FdOxG??<?17&;8B}>B%UnZ9ddr3U-Q!tIk-~nyE@k|+B1&>4;*ku_&5g>ZbB}v0* zKD<7PjVU1@`bVAp2yFN#o}$3^xztNj4h%(7q(}60z!Ur2eLTL1dJAd{Z~2b?5#{cV zc>jme(auAJ@i&Q#!F-y5%Uqa?mr#GfD$ds=z3MjNCu^8Qfmo()9)^elOQ0@hIbxY8 zAAtI(y~t1(02YY(9|`&m#5a|}Y0sd%{2m6aZwJ4Q#vc6GW50oJ9jp$xFn_viZ#Kf& zEXh!2r8-T!k>u}xn?%-O5<S6e+b%bB;G{Z~M@cp&dGCJ^m5PHde{D{_%YV%Rc;Qcg zqO<MeWS8l4%)c4h!b9DPLIPZhbYT-s7^11iB_BmTrf<s<lt96@cR6l`;>u6OvVq)i zvZU}v=6L$dyswS;usDEe(kQUvCw0_IW2o+laE#c9I;k5&eI$j1g&Y^v7sfFvb)nMm zAFBhNzCx+f<#*+b6E+nRgWwf2JFE<lMgu9bH%eDMv%ui2P#OvLqzhO{JGdPeD;U`u zNaUacmGIslLCIap;HIY`kbYGan@&cuUVMj5Aig2Mi)5LRf>Z9p7J%HYcEWaO<E7wW zr~$Sd(z}uff!kD|T>-S2iakG7eG-@ee0dj&%coSomP|oDG-eBRfw~;9fH8jNit;~% zIr=QCjC$kOVB(-ONc30r!Wan)Z|mr?yaXTw&8auSTNEFMNh`#&{Sp$Fr}u=qi4?;> z@u$lu81*26E=vGq=qKiFBW1V3P%H<CT)R9NfW84Mp2XilE3UR<{e}__`1!tHp@3b< za<TLt-uDno4=!Zs9qtjJJ_&KVlI*~mQc`X(`*ygODzj5Du6f@O40DXwbc|Tua~+u! z|CBd+;V^F{Mo6kCpd|Az&rTIheWK~C=Uj$M;dt*TG>%_=07#y5sl2xcNr><c5@DBv zj5wz{Fe_^IiirQ6dcZ%W0mMO4^v``p*klG8Xey@UWHKAF;~BL9g}_WBR-C@|G~5bK zL%-LpM`@QbX6IfMP^SD1L3m_TKRuloa~;{&O`MGqyr0~5^z~1W5Ka4(44A?X$mP{X zlYj08A@VjGHK#ZtXUPPn%U}GAsLbsamEsL{#he{^FZ`_MoR#<f5;&f7g}iSRgyGB! zx{^&`{#lpocvjeyicIwt%%6q~?|%c8hYEpe=QpMa{Knl*d5?3|PLgG{!?(l9i+jYp zc9*GL*hCgql;=K6<kS`r32(OZFQd@QMj?=KcoWJ%%&{_dD&w;&X?A%hswqx8(ys<4 zU!#T*zz)p;NiliUWzZUQ*X8xp{vz~fQL0jss{Z^Oa{YsA0ajNdt{Y*RPavju*lfl; z$WgHKie(!C{3S3;g{h*P^;b$l$3A2eQk;LJ%`YfWbPHtJ7m+)paoBkAPrMpwX;47k z7s>4OgiY?#sQe+~5Hs3>+e4XWNr4KX1i&2t-0%RVPjZL9$RxLmp2_cW?o;8H6w4h? zksXjyK4<HdF3UWmNmOAkH6h-28TAlxxoN`FhpzgMv51kU2t>?c9nuBj8EnFgx{olT zjs^K+Fm={Q)+;@<<g29UgNVx8^{^|F^#`O0D_`!6WW7OnaCNRG$8QswgCDXBj*126 z#DY`erR}2afHYc^d&Dz6klWWZL&=tu#A?M&uis|fQ~frivE^!=+wgAIezHGIrVW^@ zAhLU*qgc-o56Y;;XgYafe&{l}5H}N;W}r6Six~lII(n$plc?2BI2KTPEPKcmL)Jbv zor-=-E@)C5jUB}ZTZVuzAx`uotIP7?uQ@Kw%muqFA0VdbrR4~s=;yJlMUGxX^R=iN z$@=?SRQcdvVP=VBokSv%bshe0AtJQ6$a(`QH8__jIG|6KUlI#`7M*}-s0DIl8p-@M z#Wdxo*nMrDI>nEm@lNI+7wplTwFij`oFh?g*Gv`mgqS}fr7?ua9!Q9JRHR>19tH*8 z`&S60xoOJJSOO!KoAPr+rT;V>nW+CY1;ZZrw8O%$euxk;lv{c4qZG9u&;2?W!5#~z znsi2Z?<+_$qq71LmKo{6M%OYlYRV&2&w?o^A9Vi|MQPlsomi_-8+h;IT2W~_%V5Q> zN3p2=!~B*UpPn*`=xv;`76I>@f-Ix8+I*<lUA_5s-3e9ap}vA3Z5<tf4P*XmGB(#} zk0aCr2;0!qS~ZrThPFhZjNvQ|`V647e2DX}qWh)lVOkr=+Z9X6dK$6rF{1CdWQAHR zxs#OYM}U$lsZNLy(vmU_;afE~U)zuHPs{`2=6qnf{9}FzrGtrJYjv0W$qQDj*)h|+ zOVfDXXW^?cel7O_N9Z)apC(V<r%X+kQ<A5qI{lg0&49m_cT}F2Do-<up3Zd9bKWXl zjgg~vYAis7+^=GvnD^cVLCOcPKS|DwfAD|8hDNf~*P)p=BWH^h+=M@h?ca#XQ23}y zlH9iHF!HUd&K4C-$Aq#DcuaMdP1hA~9Gc8O@GilbCfvp}f%kp{2+_kZx{wSu<T0Jr z7R)+|kzT_e(MEvtRg#=B0@lnz0j53Q07^wSYntD~ERse;Ur(H#YKAMY1WbmHu<=0p zExpIDCVRnjTiVI=n)i_m4BZ|Rts<yZ!Fy*RTi5OIV^RHNLrPlBh7<3jZM;wk{zUT) zjeq+lgJ+LH&_o1DyCOZIBE*^fD>xm>iZ8F}`(|C=--P~!E{M<9G?&fQccBX3Y2Hhl zf@%(wk=h#yMHQJ1S{IN)??hotxhD~<4KP?BV}BM(Agm`PxD(a_rgtF{&=jbTa#iXs z0!_IKIRRx*<Q=SrBkw`shtQT=8YW#>xRW%CF33O;_xtGM`-qBv@Tb((tcy!;W1Y+y z^(mGYkymh9egjJr&>Cdy`C(UgOE!e0?F<%|5F4<m9nuszSCm`G+kKpAYx@r3%JLVg z!avwcfjsKBEGWu|WSvKL9L-lD#7OuFZ9h}7Oaz|13-$8MoUp@@R@6$QY{-jbRWR~d zbBG|ku8~TTZJ&E^c&1(91lvC82N+ADG8GLDx{sldnH72fg$#n4eS))=A<8rGw5bg@ zGWz>5`9!i705!aqk&rE)0)#m<ydNuvW4W|So!*#5OWrcWX0Ro%oz5rj1}-YCRxAyO zVOY4~QVjMY-etKJf9V&=da@hj+p7bLWd_5Se!wVoS$>Qp4KC^y_ybr+X!(z-Ct+m5 z4}sPsK;Q=ug`Mg_g8rP%RrIGISiQ<te5*8o+!OF4R@^jMH0@qxql01hQOaJPJt&EP zIB4Vx$Zz8}3Yl03n6mke&J=8i<@%lQ&eCP9pSp7uF<p?mowlCl)MOD0?wyT;u<p!t z*}B~y6$C#|SWoMRRd5#6<uj=jeW}fNg6EImT&Sh!V_1g;VntTQJLLXZ-XNdD)WdHq zLG=qWP<>$vFl_!p<eFPW|Ggc#;WSvzT+w!3x=izewLL5KQqYH>vCl(07G$&`FEY;2 zB<v^KAE))Ze{eam@IHnWD#%9qCaN393wb+P@epmwL4GU&;doh3F@MxQcnp=Lg+aj{ zlpZctSZ<`!{;YHa{Kh#+De$nU$KvWcxff+>wfaiX<Wa1I<p98<sh!_Al_Z{oCeKQN z0+0940=>+iVOOUoH#VQ0F8qNNV;Ccy$1xMF_aTWMw`%aI^XH?wIGsPp)lHS~@V<1m zqV`Yok4Z}8&CR4@JD@?3V;YkieBlmcOr-MI8qC|N9-z4mjqX+E=bYKw79JhNBYS4p z3nt;n9+116k&~(+qp?KAKT!p^;JC6iB><87BGR?mHh|iyQ@)bYrc>^LVQYZ3u{~3n zK}*L0m_AYS#lC|pKT+;T7foM^Y#&ZLT+-|_wgqWx&Ny$<<gZvNe*xt~SxAkJR-^4N z*x|p$q)vk(Qtn;+%Nd>{hg#1SyQlFlmzY?5w)<MdlURJ7dpzRFEMDZk3~@7y&vK7I z+#>Jx96r=~c8-+pIhx;kE^V1v-XDI7d6?mCi~;zT`=5a6_erP{`Uu&cT|~n-c{}oD z%T{ED<|9uZ!3RG~*p3R^R3c8H`wQgpXE$Cbt_rb~Cyf)YVlkH6{E3*?CIUGBmc-%# zW>w-~{nOANkv0IZ(Piv*!J~J|yG3~?^T{`JWyC0)cr||nVmNt<BS-dd60oVX6-7{% z6;RC@?xc8JY9jFGWBqvW%KiWN#i8C0_MP5lk}f{I&CGl6hjL(0q+-2bPe#08PdKYO zfGqco1{hF)$8fE*IC?S%0k-{<iG7jw>GJVdX~)M7DR*FIvXf`YcrTWF)RUJm_UCt; z-c~66z@SMh<1HPp!HE8j^qFcm15^O7J^Vy<z(6CDEVr*Z5?RS{tB(Gp5WPk{s?S$b zF~jZ!S$C>3E5|lFcg3*N+pO-(#fqXF91^cdPf}**c-l?!>>OPkqvw&xR?D22H~JwM z_9wQUqys+rP1^Y#r!D{9DcGYfy#_^#GH@JXv2EvXRF$H1+xGib=BYTUEJ|OIa=IwZ zEZyTfzG4o)aYU>vyw4=H0A+o_71uIbdoS%1R+<a=S9!9Do-UJmDca|<ed0dmId1YD zU-@b{gY;KEu-OV(sI&?|ZT=G24taL^%8$`9eSf^8t0*10k??Bl->D`r60>KlFo>uf zFjiDvr1CeUyFU)iLy@SzBPfNKli!rzL9<!w+KtxneylY(qlJ0YLigobHQ+BwzoI{V zza!#1jtM2jBu$F(!@oL&wYSrx7NCS^`^J4Nu30NCiZ*zdPB6Z~n$<Cy`%97!#)EH% z&{dd05|E&Y&`F0fKeZDB<SLi{CX?X#(2B#qsr<|4fu7z&_OyLPYs>?ko;H)yb2i!i ziPJwTne6T<)Q91+ZBhpn7tVB$TOegHf<$aA5evT{obD);E{sB<|A77?YVTNvQ{EX~ zqxn0up4aB+Tszz&JGPWDmB{Zp<z3jb6L@D(IMYss#qJj`kOozI?zX~seT=G=Y3YKk zP2h{$u*K*J!mwg%@iy9z%G)NKZl}3A$BN@SY+|qZ5k{5JdSs;?i=ATML6^Lr_c{T? zv5<4~8?S4>@HCQ_?GW!>0P?4&rDaG3)t(hrPQrw+Pt5Bh7q0Ex^<vx6pTI}(^g=9{ zWczUO;72H+wTE^U;G6j8o1AA30~6N3{4>!Mggx}M<-;=+)?jSzc0XoUre&aoD}E^A zpfGQrU<y*|QUMA`wfW}^GST?&<nqxt6V0(-z#|!i*m>T&Olv<1+(L6z-T_m)GA-4& zN1m6yV#e=-$dyt&M@>j7^RNfVuL(g#$#h+%%uDyrhyZhD`U)$xS3aeUpAJY4BGtyv zJd7U@e704p?@YdmEfj5snhKacVbYgR@vjb2e@e2poriwLijjWm1RMJk#2&FqD_NM0 z^P#t)P1HW2v(PjS;z|m&148!IB#rG%9!qtGAFK}8<?b!>=FXja<|txqeWUZ*1=H>j zc@~<ypDpCQWzg)-WGfY6n|x#!IjnD1ouiW+-p5Qstlj*&92C&cV>*-b!9Ep@w)|L# zR$h8O^w4?cV5keO0h`~InHf+h?@BO$qO8g$#HmT+5e7(~wKEmn^W2mT(R<F;yW}nh zY=|K5RGL%yN7}I68G@0<T*be<W6LlgP4kaCJ^&$a@5v8(+Gx+3^#4q!rv5oer2Z>O z{eOoJwkxIS4%_>7c^`(rwzwg1Yabf|aM55ubFk<pMR&;Wy5tW9&&SsAAm`rDn%R+J zc-5EN$yezx*)Q$(m%v}Jt@zLr{4w(FX(y1srYPe6z-fD*_ofgD+KXO_nq6{lRAKpb zG*;r3_Ma5iW&4o#{uWsBK6_rTVC&%54M55ve<0*-cleIm<@)p$xq|0hy_9u&dRnT) z3x3BpRN1eIw7lJ}OsA2;uc7OFg5MosxI-E4Ap4r(okb?<h$PTjaUGy$_e4SdQtv+j zlLdx|rsIbo8W1=6f-66<`|GeZg!Qnq6MPU^FuE+0IkoaR((f054Ve2F5xzvH=lL{7 zE&v4oG@=%QZuhYB4?2s*J)`J+YR9!NLw|d9{e3%heN=zDrn9N(RRAKwEBF%$jlv%& zx90CtTY29mWK(;2@1GDe6z^%omFcNtNY|%ms{R2$)MV;d{~T=B%lqOxq`2ZZt7(RR z;aHPi9Z`(qSGf_whKA3Kt7t0Xdiz&>961BA$REnhsi6=?1tj-1Iw?e>0QQ0DzkWWH z?^&MtH6~4McaYzBQ+72L7Nugvv`nY`QPgJt{!6B?F2CdbF30;A0B|lBlJ~Y>y<{A7 z31(<6L9z+{&#QxI9RQ_Ohk_Aie_S9IJAWbrG#*6Mlc#CIie<3z8_nH|-0=2*UZW}% zqFN;bM<MTv{^A3|CQLb;IunFoWHb1Ua}QL@^Rne>nW0JO9)9Dz?C>dOzoPqlcDai- zC*JizI=dW-kj}4r2*bv1>*D=1KL~k!4p~TNnoQ^6aFgt|An(73<&pKb!!zO6U4S%c z|HmjSz>n}n82lj`G}Qs1t+>>8ocF#*#gMI+lhU!Ra(Y_|@4cDIALo6Q2pJ6fTUUS< zETyj%p)xz&w`aw0WW_0tcLZ{Lkyl7nUH%Fyzpe-X^e6vv3fpV+2BiV~tKD$api>9b zN6=@U&p?^RBy;%qb>)asr=5jX_~1)rNSB8y0Q(LSvp@n!y2F;S(pV+4dmz#Aqx&+# zCK?*P2*2(;^b9^$2JfZyakb|j7)0;Ki283#Vj~UH#M#kjj^^#8L%wx%!H`70j`q3i zaxkw4vuSu(bbL{scP+RiSqiqG`%{v3=n-J+`l9=nzxhJ*52NlDb;6TCBZurNQkGS~ z2t5Ue#vYr`H1;+EDEFN?F847D;5W~LQuuxiDBK0MLx(#k>aVH%S^&{CY!2tWW04At zz@I3;pq<M5h&>1c^C$298{(!uoS;Yf%_nX?{~SHkWor2}^jLg(CW{stx1>AJ$B=|X zZ2VJe#!~sepnRwYdE`gTPB-ik<um#}M}C}Ry7J?A?RjWB3MTSXLG<<jOcbnC!%YOK z1BA87JDS)Ggwg;&rvrftO+=h+r^ooyXH`L$+AatDC1KNIU^(Tza1oppCk6Dsa7JxA zmn6tNj=XLuN7zgVj320gfKCvw`Vr2AfMbV8A@{gHQSKRsks;X5VLCnMpPpoEUpZS> zJ{Mh|*e|f9syYaVw7ATu6pceeAYcey?)DtE4koY5v%?`5rK-)R&?Wbz1A*>ATnI%E zuyq!8g!0-UOk5-|<jM9wmXPavFc0nkb<di|(e{J);`SGObr;>L$=^&1P!Y!wCA50P zRRdfHVe3e?)})wKop2Hgjtm#JTZL79Tr1rD3hhQ<JJ?rekv|q&Ag#DO+CNqhS36ko zqI41{xUgdlv=UocC)F)b2V#E-c4DdnT~jkK+u%k5{bfres)BjF?dn75Q7W=Jz6k5U z=y+!BZHcy5@bq!~+8>jZ@D9aaG`ozNjq7i?<i##NQDe)fiG>tfLNT^Ozyx4buREbN zdtt2E@K@M??)#cwdoS38mBGkfDQRPeW*9JO2c1c3)wSeFA!g4D(h@a;UvrR3xJbUI zNNgA5EI3|l3!?h_Q&#i0NNmlOn#5WlF{;yzF461z(x%sk(TCco9#n#=)XUk>IH}$c zR~Yse@<v-AZ~7ae>D_Z@hAG@>=ucvQyn=kR1e8NInx;mxmgv265<MJ#l9_*g-9^YY z^^mEfg<))b#ocyW!ZdP!5Pg!*c1NnmaE|IJ98Tq)f<E#a@6DMcpIvpBwm*2^<zP_X zL(%apIPU>o^{P)ID|zp5<WmRcSFidka=kJ;!*gy(vkjYGEfy?~mY?4|gf)})I>g;- z-tM-;NzT2!E)&K>E~o%!Gmku$A?{UCP{d`TLf-om<l5<avHYn66R*5eSoI-?0}sJ- z#2PL@MVRf_VrX`T*rs9|Pg>+To3`Rk0j{nit;fD5g-vQS4`5FoOTwVw>E)p?cDc<R z6m6e255Z*<cbZ+f6Q0rW6$3g`#<LRGN?$hAe{%%v;;JK3h&P{tPr1YW6cs~>3Y7S$ z<u|A*Kl~^gZ>wgcwxX8MZuAt{Zzhrgy3K|WK-1W3NkQbSJ&5QQ6Qc5aFu)|C)1fZF zK$!R5iMbgKwJQtKg{_FQ+c4{Xg9ubzK4s@$`z-IMKRt<taW{YC?lH_Z(S12Pc6d|Z z9Bv_lc;=|k_VsAkKzX-4FC<+qyh2bme}ZG!$K!%$n+f@OJF#N@#KFJzk%QcKy4CE+ z>k!cOumZTzj<kR~^$-&jYQ-hd5mJ9VVeG8@*p9n5v^M8`bODf7_6RiHL3b7MzOhJC zaW=)|Q*r9p1F)~29rM-E8a=o`S72NvNme$B$j)j7BFFmGN8Rv)a52BJ$Xe|SR%6JI z$30)zm+{8LtBwUtph>wRTzl-kc+QTON<C-CN!V^Yp#BjQ!@bc8o?;cme3p;n*eg+6 zk!v?qq_4Uml>{#Guf0VyF8oZh|1hB1ZB4r0sP4sVAATS}($J?F-W#S4Mq`*eF#*&< zCjha_3(`ZKdKR0TFQ6<sq$6Z2x?Qypgto9SBZc;2iuz!m6I<>6tjWdLJKUjuiB_^p z1OQzH5Sp(ZCRim#KaC#W9w-!6?|!!ln>mH!J5#Wx>NJHOhgrfH3Lg^Aw9%--D3d-6 z@B5zltEHBd2Sy`){vstMRsWv(tMMptk~n`AXp;*JWV@P#)fP=ISC0AC`G{7|VL1>t z8=0tQQQ&M&tUy4xIqt^es$<WhluLOghb=8}1R=i*Hy-}Gu<B#3405f)o+LJJhr7te zOrl%p4R-u#!M5zZkX)q8o6`ysden<3<Q1s~cn#t>V)N##Wf9mx!~+KKVI3%M&7s*| zwNO1c0Lb89&0v?Kuz!ymsLKYc3$B1$(Q7)h&l60Ry*W<;+b*AIeVwkyPuA8${w5Qx z*j_}I=j<5X*UfN<%NTbKc6pxh%)eY@a?thVGcNzaoO?z8RX5y#ck_bMA~^US)hhZ+ zO_OisAHWR|(6jLmJptJYp0AVn)d9pjXMf1ATa5^eA@6g+0tl}_+d1s3Nm+uDOdiZY zWc$sne!I|v4RQYE=~y%z@&;iS<@2<H(>V6g>kEoEhlC-n+D3h03=!dWp%iCcg%JLn zoCZ<;T)jL5ZKb=8{L4YH!tTS2phkKFg6Ak+>*&QY*~CAv+X6yLzSFY}FPq?`n=B$} zz{&}<Sx(!{AazpBg{HB=g831Ra1XNEAS~Yd1lr<MGIN}G4<eOeZ*Bnvr~C!owk=bw zpQ4<CL5AAQPQ{$Vdyk_=R=4*G5(Hfu9*Do#65NQi@-S-~@grx1ZbC`yXPs58V29=} zdU@wIv}g-Z(a?$iiG6qGQjx#}_R@~<iWzy6Yk42J`RJJ><Ru9&CWoFwnyt?W6;mL3 zflwjm(9c;GDI<(4BSrnAlUl<2*oDw2DRZbS4j%)sg|*+)ZGF}Z9fMrXf;=_%V6N61 zu%Cqx3Wj*0Iu6U|P&1TX-yit4^83H1{8zN-`SJIc55anTSN-?Gs|}rj!He$qFnx&A zeAYb=yapNyZp@Ghfd4YKexQz71MgBDp@PZ_pb}W+%4umOX|YZ`3eKrhdGD<duCv0N zL)4tmNz6(p$a^0F956H91i+dc3Azhh#^j`0No5y+sz&V3QDUQs7+6VlC^?LxORgkh z3!=ofK^u|qoOMfoqMO2Siov=1R2US~Krw26zfInBvGu#;HIn+P3qmvYv(R3%rW*P% z4b6$Ck8zKIl?~RJCPj7Zhd`q7$&3KK6GDQc7n%(!Ll}aVe;)O*eCVN(|0&~vS&iQc zXK1|`;e9i~xd2UL62|r?Y{#1Udfkw)gU*Q$h5o{ddeKX|5&8uH^p+A{I$M~N&uYqm z?X~ADBoy^=?Bd|MI)*e`Sh#X-)wg%*N77b{9rDd}DJZ#OFpkc1ZmpIdW|kV}mW(%X z9GcAPEY$3g`shcH;wri&s<j`Ptk%?6`-ZRrdi#OtfqV*$#-9WLU1*0+8sqI*TwcEb zQV>2c=Y%p5(emRJnF+=)O{B%QYFaFRL7vU6Y8i1A#>LSDqNfa^pCO|0dj+az{6gFY zOSc0?>xFoJ2A~faKW0R}h2I|-`8m;iA{TFuCjW@{`XR*0SM$C;u-3XVX#(&26fqbx zni-OX7n4GNM_Qu~eM{Pe9_Q@5T@5`8xKp_%2R8`rfv}u7(n)p7U%|MGcq@`@`TOJO z9vsF7&SsFj?L&w_g{NSwkBA?rP0Tnh)0nu1_tnHP5n9M<g67fOK|?!qHQGd@C<dtm zB+jI-$q21LO?nT3Wiaw&PAfttgjXP3E@TE>PbgoI2N5vzB?`omsK&H#EkI;hV)bl> z>abA|<>d=N&@+?ux}e+~cx(yHWKF;fxp@pgG);bW7y|f&c1HQv&<YG1tu<Aoj!<qu zwz1hPv>p(e{p?H=Fmlhp83_FhZ4@hF^Ogt>A7|uV1v!n@g+%M+X!2$x<J6Qap(gau z05na%M_>f~{4a7<_&n`JJqMOS@>>FXrAkl=;DyO2JiP#zC>((ICz>1KzFq`H5G&00 z<IYOtNC3AUP^uGW7ovX}EXXyP=muM#`x5~Nm_p}({4E8j!r?DBt;rBxu_Eq*nmjNX zG(1~#Xe9&F;AOAVb*8|xvf^C^bP#2T@&tR@SU%Tyjj#_s3h|rZqbPX=J3L=oS7dA= z+SLIQPHs%L?JLiyQ*pfSlsj?ETkM~i-PUIjA9u++i~Vq2T(WBDr;>_&aI-v6^t79u zwqVm|E?oa<JDMa`v}1;NAQRWea9&5-LOv6DHy&ES$~)1%u4!m0vvOq=QnMmIAbSS0 z^*jI$xtI6-5&bGCGc(~I`hKlr$#m~PS<BjNv{l<*=rS>R_y_-GD$Hj2h17tq&^fpV z7@S_J1qC103i<~>2qb}x)vhGkZ8B)7xq3mmGH3|b$b>WPWaVHgxh`BC#togmY^|c7 z62AXo#yy&2hl=N`gK}Ubp|_{_p}0Ij3xs^K)wzP-o`IeA0}gDmwH>vd;;-z+ZHNeu z6QeeI=itQkv=4}*R<Z4{)tR=_F7I&B6j9K2iq9ZQc{^5xCPF-?_=T3g3lQ9nQ~WK1 zk0FN8@-_?S8)4gu4Aj6d_GmdEGp@Uuzxi}EKmG*0l*O;^h1V;$Ipp0K4dm0B@U$Jy z^k)tg+m3*T-JW}MmW(KtcQyY=tf1Gp{8^(Q3%V+j3#PQc=A9te#y{{E7(q`h-k{Zq zffkd4KGG<e*G_x082$Vj2dajYme5)6ay@QB4zP{&hd!x6>+``_8ozpX5^B&=7Jl8E zlzN`!nG1qC9DeL`X&9joZI9u?8Ttw^h-3REOxn1ChDvA=L(N6>NdyFk8m`eGlPCv2 zlIxR&6pri0`KG*<_4FFNK*hS6<bc=A7s9K28Mk$yddl>4{$<M6dY!V-^@UjVW4i>} zQ7c*5Vu>$C-1BiN0}W;>ITjE~dhtf<aWD_z)DD7xc;6vPy~H|*NggcIaG@VMp)w~I zmsE!#W;uI31~fl@8^8Jm>`hhkx!W*ks7a^z`P=YVP5?nuOBcw)`RKtWMg*HoR(~sQ z5q~AN^`h6?X>FEEm1+V3q1SQW0^^8;h7R*iAB5Esj{W^vLkdY9K#S^s0p#PD6Dy#8 z87%L1^G?Wcx6|Kjg7&tfEB1KW^My4RAf>6#>Yp(_Gp@RZH6r&N<m^Uc+R^Qp=utVf z8Jpm?cIXAgc|W~HfEq@np-6aw?jM5NxU!EVmhCahu3O2<-m(i_+(E4AEUg(qn+OJ1 z%U%QrZ;~y(8|PHNgc1p_&{P(xVZKKzqO?qdA^Xu~OkBiQ9_AT`-)s&|#59BVQ7U!_ z^1RHpBNl;w#l9}va{^ZaAhEL0c@V+=w3n$ck+OV)AvEO-Mg#w7FmxrnANV)AVw-W( zAFHmY`unazHp&`$jGiW~O~xpNnvzPxti$kX3c#-$4dy*(hv+KIKiYn2d+2KNuRw!_ zKK(+)%qz+zU19nXoboT}3u&661k5HZw5&r(W)@ak*wD+!@-oQH)Z5+s>I=|PXd;xC z*+zDX&<++bZkAj(J(GXvuawxzv{$UazL4b^#!E(K4~~%@a*@UGvKF_gqrE}ido4j; zV)$4{`!+&-(Y0AAC`BWb^b<A|mG|(TCy;5!yFp8^rvRV3h1!md!z5Bq%)kW&IM}uV zhA*F}gR^N4yBA2jw+Y^Xcpc)rFOMzU;UTNXE`Z=}L5{9}cJu^w3OkeTKuu$7bIO#P z&Dfm9L4IDywp*X>cz-#Jd9*{lvtub(F$YpYUXS1}G}-lWXiSsXO}s!aW?C`WrVUbl z?WHK8JkP8r1knl>*bQ@&m&HxA8Y`j3z{s><^fzFa`EuXs6{E40&;YSF@HckmX}Hkf z2EDSpPE@`Yv{316M5$%8@jMKbVQaa77LP6RQFR(-P#3)k-^S>xBTy5@1tmmv2VG@E z6*zV2#6Tu;c}IEQJJ12`68t8}kX|&=_M1@EFrd-a6ZJrtF}>YrG4z!P(2rj?jP@+F zQm>5$gf^rUM<(p8_&EQ{y}oSEnbBkKMf)DkX+^f@GqdND(WZ0Q#G;WZ_dy23X!v$9 z2Y}j2aFULx9eFsp52?=~Ph*b83HddD1LJn=!I5djb~*o0A0j$`N&LE_M8Z%-_jT+| z`_L9B45yBUB$!y>`)^lox`^nlxRB{0DPV}M{>CXKRYIfMC4WOYNv20Q^M0rjSW*Ax z%mJuy19CXnwpIk8-$EH<=Og3=(3m3&mVq2LMTb%dM_bRqV&tu5B_Uc8I{nV<hovAn zhwcMrqFP1AOz5v*#I8K4>pR}MF+no^%%4DXJkt!dj&&Y1&aQVnee$Elfl0(S9wSzi zpUi1REvT6UkET*vMFnF_lxyh?a(s#b{pUiWEVKpL0T<pgXn`Y%VaD8okUN`ntL!vq zau1<-x0Z~FmxI}%rS2Lx1aBXt`3ZQT1ASX|IteF2w*ij)hdzc1+1Fg5&y-~SZQ3-? zd&$b6_t0Tm2BK=U9Mw{9+73aH83<p{;k^%1o&$N<B}cZN(WOpcpbn4THmVv8I?47P z)rmM8!ZjbH1-Z-aFUwbpNK}vx&hZZ5ev0Zr+K!hiaK1yfgk1{5wlY&6@-v4cpFV1n zkGm|Nunn<RFv6*S8%~tF@J3148=F6Hv)~ZsBWO5jt=^#+CwbdpK&YedyHIW)s}0VA z<EDiD1YI^@V$Cg(nn6P|GP<D%Jw(*C@?cS&m_-gzC;R$_2$Su76SEzCaA@l=C{<f* z{zTV5PJH7R`Y~3AdYV+hjtPL&-$B<X=q3op7^Q~@{G(l{i{jvo0)1Y$%jclCH2YoJ zjtDh1RE!OzxJtsm7v-bG;a-eIXo@@mlU`gev+<!W1D9m2q888h4{i1(+T6+^(b4{p zLKBZxr(R>CGV7CA_%eNdK-Gqls2QlmP!H6mGj`EnG#wfNtt554PBT_3I}0Mvpjz_3 znlQ{TC)L8UeH>B2vmz7y`!4#1e|cU6FW&ZBW9A@-tuZxAgDFm%;F!%B0im-gGLCP} zQPXD3-0oBS?c}~;0dXZ=yJK$KEr2X+gJJ39l~l6Anp0+bm<gTtegZL(Z?<$I6A$$S z+=P$Ayn(oz_jYK&Zo1g56~~ml3uvh6b~uUSf~YZw8V#@P762Dw4Kw~tLc04U#9nv* z$uOUEMi6=nXWS4?8E*P~h=wWC&2%tm+s3bZ8%YSe6_uJiFqyPYA;pLGaG{Nqsks|N z;^e@lC(T((!M?A+z5<7QQaM&`8MA=s7BXpG+V`b?fqA(O6J(UJ(01IY&<;N1tb1rJ zyO;(CS@WgauVEsCv%<Oqj$<4rFpCh*NJyP}1%I=K13f%E0BAd0J?I`;P{;+{HEuVq zt))YFy1a7R;BBuN0W~EYX5-r2oggy!o2yxwz3}*SZ@U7Ae~>b|0e;#8^D%f>CqH-% z+6JSIzYudcBRc;?buFLvGo%ybEr*;S0#jCts{*p>pbra?F^5@i5HVe}f(cq<yZ~al z?*2lT95nhgqQ!JEZDCGHczOV%fQ`<OW>+yF)csi9xNM(cBxx|--Uk%=Y|CrN!6<?o zg5jj@#vDKc$ti!pKB^H?4`IOJ_TzJc=PO&W91^iOE8)F#YXd_8_Y1Ay3>C7DBQeo> ztA(;cC(wgbA@#cY_|W)j9;8u>)9{B@!jiZL3auYO`I->d+cuAeD4V>)7OV%b_p>6R z3G4Hih6LzxnPyS-UPncE)o!fjNQCmy5rX2x_b<{>Hw-}wKAn;QVqyhegYvZFBB0rq zO3Yo2d4aJ>+l!yVXTaO!p`X*tuUQNps!r{vYaIX7Exh-6w9w(N&4Jqq519$TzJ}c& zh}sNO=m-V_R3-@3zyj??6hW+qjE^1NzU1zK?$l=?gbQ$>sjryc$3Xek8d(jY%P@P8 zi$HdQ4J9{j=8!8*_Lio<b#DSd8aoo(W5Q-yuS4@+*NnwbtUA~_0w7B=5NNThg|r9r zy^CF#c&Z~bid`o{lj))rQv~e4QO}=7#puawX#cHf1g4C2PoaRJ40gD<`P7I>>MAy; z8`{?d(L*g_TLJvKuThRfFU@fH%c3@z8Sl3!OIuvtgIc1Z4DH1Uil9ux=iGSTC73qJ z$o&l%U^DbC@;Xy&OoXJaTWr)4i-r~ct=`MuI{u_C@{ZO$f&wvKLUb6+9JlBcwG>Nz z7)BBiMiv~ol>?2rZzXM!Q3i}Rn`x7vqrC4F^eeOkJTRecf)ubd?odO|Xrlx7<#`{y z(W?nL^cA9s^JnNaGPN|PX#(LNs?i2hw#jkfapBB6g6AI@p}BxT7JAP-i4?0r?@o9n zj3o)AjGbI9r1z)bA>vwHHCEwE+{3GJEW$O<S~GMLjcwc;n~(SR=H$5Sw97?b60~;V zj2~I-`xE&T(Y}XAyV8?rD}M>TT!v2~99c)kMM}lsbiw}qRoxE<u#3AA1vZhsGSUI< zJ|J$yS@r;5yEu$>`nx!+=N<S2#M+BtXE(kp$S`R81vpGMP*J=vf=^1Z@1Mng-z&f1 zv{QZ;Z)f7$N0F?XP}HgXM8Jl*Vv&eCuHq`W(o}l;u?8>iyGK?B!ZXE+Zqc+$G`-n+ zPlUq@HlD5|(e~xCAMqP6aL6I-!qROIx~u_9xmWD!WW2LCjfsQU=exWl3Rst)gbzEr z-~y2FJ~f5$wU*=VobVgEzk}5~TaJmQcU$i@<K2|Yj0&Gag>)!n)oN82X;r=%Rv4YN zT7R+ock}Tc3cYYC@8!MY(M`qV;!i+?e|eaon1n9sI@(|>r0uicBMv1cx6-t1Wh+j7 zF?OFpie9qAh8<pXgT@5_h-Ce7Ep;0C(b%d(hIFG77o+$GP9himp38Is7bvX8N6q$a zAuAg#?_=d*HUZQ=5(5RIi-*SkGZd0)!uz2P{^jIqIVGxQz=D5XO}w+0QCYD7b{7Ss zVy#Z5gQRDLVGs6;5}6|Y=xR^`QzsOri5Ih~!p}sh)A=Xe%#VZv>SWAXampFG2VgKL ztT8c+(4CY9zW#pde5ll=Xe%k~OuV9m&*R~}_G)l56Vk{f-DT2^WbM+|B^Vlme^^dR zcp9s>T!`LE3m)Eqg8S7mV1sEjT20?Mjo!D6yY1pRR*1VEpOsO6?_hfVrjvJs@M20N zs|vMXl?1L7G`84x+OAloCZ{q2nj+naI;A^s_UencFA6&eT7kDaJCj6H2Tozw0&c{z zOYt%l=14n^vU8nz`|RM-iZAb}4>Bt+x2^2L#W;Ly>3q`wL%-RZyZTFd>?3yczH}IO z`*4HCp7RsD#dN|he+*FUdq-6H;|cX{CZ+!gtJbKKK6W;oRlD-7@PE(+)Tlgk`Qwva zmS1C~$wmP_b=IL*sN_bnZlUcHf7Z@Y5;oqI2X#Z@)I{EnTfOXR=muCxCUlVroeePd zzHh-n&)JJt3}xRM!GRFHTXcbK=e=K`qsGCJ#YanV<^vOi7lF0+pJ8&ap@rK=>Q?9p zUJb%)V>g%_-k^OA)G;WHit0aoCCLdNT!fQ~?;|<Zq~db|=$>SkjC+jq+A+QU9&4}e zx^yeful631MKj!-ujG={kQaQAJ|>*U;a$Okpwfu9GvF`o7Orz+=Wqsw1ikd)zcstq zUzP2u_{Qn!GEY<NTT+V@`zxt4{Iy$B3-)Li22aqLeJ6BtoVJdaar5|Kv3!JmUX<;R zIFw|kr^D>x|J**qKbdnVNqGOw^9kEEcjomK=XDp;5lWJi&coV5R>5=F<g$Ix)HPjM z_)02W#GH78-~I|Z2;W|U6rHwhO{4MF;8$>Sq=8|amjQ|N3<qUk8`+J=1lgU5cY$3{ z#;Y)}aphDJm^XU3U=Q8q8fRCM6-X3p<pt@TKDk{c0h{Sy$#Vp++<nmWzF5&o^*I!~ z4>bhc1vs9=C8RhuE>>oIh1;d6;bHXMtppZ6B^F>5$DxZR#jHN=IBETl?@3{DQ%2o> z8?@t1P|ue4$rDSEGWyi8f9i8>P&$9sGe02Z#WZ>GYEsjnbOn7<L$-`03j4Y&4WLKH ztbciY9|}423qMKykNG=S$(jKeSRSTW-e0Jdfh}z%EcH6AzUfAN&pn{kmmTS0x+PnF zk0Nr`0Fa={Iuy&}0N`!uFbxQ!eP2`|yW%81=q(kZebpOGCstby0f@v*91600WmFZY z<6C|H!Rgg{<T+v@<xkjjusjcRtSun)%$Ko+-9{w+>G+O_<zt^#`GVW=)ex%VM~dZs zWMl4ekH*(YszFxUpJPkV$X>-#p=C>-68ax?F?Cr)fT<3=Yt8i4GsQ-bxbIisGr5*& zfPo8Hul_Y3l967LCma9l1PbkoR1yog5(e`6_te2m0b%<GCxHfQ>ZL@CnL_IVP@&-) z8^8Md4)UA0#JK@R-t$e`%8}r}z5s<P-W8RRJ>-ty3&Yr5P45X`EuUno>b;-%r;~B= zr~A-zoY)ph_NU<}G+7-87nI#T>yR#%n^NU_(m^^4W~Zx&X+~EO`Iu3T;3VlJ!TNa2 zavEivy2gn6Em_1)9$t?PC5v*8=P<@|U$SWG7N=ODh0PD(Em(ZA(()-*dU&fdu6^3~ z5qvvf0i`0(^3=4ISAiY+exX=_@9z063vLBv1-&ezrSc$rg^Oevs)Q^w{iW12Y$$5| zrAay_KjV84%3YZ_baVM{$;KT6XT?6TVh`)z=}M*oW3<O<I^dG`PM0$kdh=Oq3tR2B zH&-4e*$%s|IsLv1G5%pQ<b|uV<z`ruK22jV*D5!rqJ%n|W?;J1w;kWWp|xbibbL?a z=Ga2=D3;IIu@mLb)B%uo0=@8`@ICrJMD+)sV5YIFMo0`8+XLnK*<FR1`go?#M?~kd ze)c=pRZ*Vls%Qj<_&Du*4%-*^@puIho?daq$4>bzSH+2f9Yy|YuDPx$o&Qx^@(ro# z6Ivy__b=4zP$_>)Hm=qOvT3rjeb$sAbdf%An03r9+xF%YF8`gF3U1EEON774zR_Q~ zF}v7yq-mxme}{4rnQj<r`jQkjWJ3_UUBU8q0$J2z{?8r7rW3^`GV^vhiCueunHO!l zn)lo38bp`5*!FhwCLE<)ZdV*%;ahGn?f49HIFt34=s9Xu2ExKyVBOs(<p!+QwU2FR z-@%1RO&C8$|Kl<=eNP@QZSy`Et!X=-1Qu@+m5Dpc(QMyocV?&!@ZIO7$u1=Y9<gM1 z$(^S=Owut-_q5f@t|w?cyj1VVpFnoI&%57@^+&vBP=9J2c^d0CQ5jDk{3>J+T%%Th zjYWF+De~t1SyL{@!V!+;<4WfJs;Kn{cAa_O9H<K2i;3wQ<L0EA9Mv~bPLbXhwN48E zTC32<DxCOf8Ec!wYtSE}#!wz8ZoUgPP7N6KV5`*90aWP`gUnmTd=vLR2v%=z$yiCf zV^<buwtZv4={$B&1k)FSe_@Wv*0CZT{<n7jrGxIjpfYVh@LpIve0s{|7qeH4L^F%J z%&Pz)l``3Fohv`XRu?Yk`9{*9v132kKRw%XWHi1<zB*gFZIczKxWkp#1Nsgn1D*+7 znKnln?tTn)DA}Z#7_??#Z`ft)Z2myN(GT>`Azvu)j`!&UF7jFVwoL7Pb$a1BrZ4#Z zwUR;Q1$iiupz_DVugBRZSH+A>MaZ=0b-TyT^r!pDHoE)*lz+}Z_&%;Qcp*pO%Z1E# zWuV=b<{sj-bvK6TYe%g><t_|*x=nH8Rk!CDp78h8r_dMd&5wTom0wHOZwgN1Hoi)m z4iFxWfB?dK9+`3jEJ;x|iO_|y=d8daDg8WKthgCg=HAD$3-)N^Pf#urlvL(Dp;=<y zeld?eog&Ea8a0PT-UXM&WqYsrZM3$S+@h{!*P*bN*u`Zb6sCgTUaGVC@8TJJ*E{pa zbV;e$@A?@;A2P!&8==)tDFHHfC_~93ga1CCMyM4|54+C|<DQ2d4YF!^x=HIQ#Nq>b zs$*d)WM6Z`RdI{}_Fqci(<gt^<;naBG+W3Nm|lqfyC9G`t1_JaTT_eux1t+v_zG78 z+Hf&I$P0S<2Exj$bg~b#;ZvbdzPz@*N3{z=bSuYY`+L&>yHeCA>{b0@7T%ZH+iOn? zifOPHxS-4Shtb8`vf1*o5Pl7nNKt0@70Y`CxgGb<2T9ipo5rFAc6m2$8s-Isy@%x< z`18W59dr+AuPUUqIol3fowm=Hr3lJ`ul9y1fA`+rw0*9$?(ie16^9fj@MVc!D{2mV zWA;Sf-(cfcyK4fyfnlP()?D@PbTg0C#E<Hocuf%wEAAf&bQ3DFQlO9T;X+i~Q4Fe` z)aDG@4aD}*PT0OGJHPdyUEaSpjKRWt>9+r7D{IA0d)|JGu-$3<WicBV!rqYJIg5A7 z#gP~8@U&rY?UBVyw_U8jTUr)jRd@m|CSI8nKsBR1r$*=PmWM!OY=cGMx9-sU8Dyw- z|1DNf%4RK+wifvx9{vU_g?zyl9Bpv+yaO`sjA&)aeq!be-yb&~MY%hS;TAOUFVmel zlXnMJK%adc{j3kO_w@0n<xmo5rrd*zceZZcPuh(Oc>aY7TYSN~V29V^^e;)3R$`OY zllm&PUEU4lPtSW7tQO-<rw4umm{UF{D4cw9Z!cbxO6wNnB!@OeXpm`$&3||1g`NJQ z^SJwygjX^>Be4dt%c&B)8yZV}1jlPgXiwD1Vmi;(jZRw_GbKJ7wd@GKuf|q2#(lt! z=Fh}4@67PqN5O;BN$ce3ZN*G!Bcp)nA?(-2AB_yre-p-peO0#0*4~t>IJ4=UG-*)y z0@zPBccORNagYOr>}mcKrfTaBQ+G!}kob!VQrj*Hz`5QG4@}|o?<LZD0pBbn7nyy> zf6I8pun<w{O>Y|2L*V>i@w6>BbPFKb_sinGzpkwZ)PKCBPYxZ@Rha(fjbubH8@uj? zSNtvrVM^*5fGG)k<z%m!du<1n-?ALKjocTJ8_kQ_FAy8Wi0wD1oVx{7x)qen`XMWs z)e<e)f$!lDya#O3_wi9Pg-7(zNVoS(Kd7f?>7kLHp{MWH!!3Gfl;5MLjj*vF{$+al z4m~vL|AU@3@bA{s2EK-8*zd@gyO-<j(ZdJz@JNdWKc$E5{X!#uppHN6zX-3?^BZ+K zM!7wDdX^rZ)59n9aDpD*t%nBQ{d)SS9xl?uMm^Nap$q8;tz$ne6-yiNe}~^LAM3^X z|F5SDNWD8TUASFKmj$(u273Ij5Q&c0B9Y+r+WrFN4WU2!4`ZI~I~eKK9f|Y<Es1I4 zW7G!z8~TTzjr706|7Q{?uBltxd{y(0uA%>=QL0&5Wvwo+sdYD2U5h0%enMqsV^vd= zbxebGNqLjCuHIU+w0v>ZRZUeDQcZmwXSL3&X_VaMwKut|8ke)eRh8E2`bO)RO6#KK zQdN_+T(Xu&sTkZw%at_NOQ2<xY_5@(SS#?KL|XG(#$aSyt#j+{tgCOXvo<tUxhw0f z?EmE}r@HAsnw07*>T9jbsv4UJFs5?6#`X7?TT~-in`-W^ipMwjGX6hABfXSs;+An0 z_^%TsZai0s|CX`V$YSBl@|m2ot{VU6V;$#axp{!+*12nI^SF{(&Y5$jl{)5^+&I%Q zb55z<Io&yDHkZC764`|bj-F#UTcz-QJ*?G3f{jBwT~8mwnbzxg2>xVTc}oB9JgamX zE<GHF@O?a6_4HSINVK2V>;1NRX8!G;>mT|(_y&zy9p~PSs1wg*JYT(xIG(i>B3+A+ z@CAe;@f`kZBto>GM;N7pIN`<DX~YSRzNx9Jk(P7RQTZJAgI6Mv25h3!6F|HSPpm`x zt}idDulU{SJ=g!GyG+S_u=D!!%YRie+`jjE^SS$eIpV5^Cr`L_`dmtDW$1=C{c;Lf zz@_TpNIlHdL#~xe`1R`LIIgs*N-C{)OAT(R6r*Noxx|$&{wGjE;crRw=i`<_hE({F z7Ov^g!aMp{*y<fGP=3#_3Kn|bdyIuuZ@fXFwRC;bRD|j>@y8TC{qRLg5f=XA$^54g z1}@pQ^<9M5T=C_d=|x;??~j*v2u0lbeZHHoSyse#&s@B;?YSa+#=GpJ`G<=N*Z#F- z)St8LC7&I6_oIt$u>b6x;*_^ew8B%<ep}^zkG;6($;ns$?%8)PKkc+l`P~=xule6j z_~m13-%8!GU`$c{^Od<N-Nvvsip4^`{tN0XfBoyGpHKVp?De7K8z&V{7?pokY`*{2 z$*(o7{NTncx|YaYi08goNfs+DEv>C6C4<udvsPN|uB+e@K>hIlk4s|1;s)BZ*uZfm z2!Dee+*HIjAiNO!z1fIc5!U0$MV!tJp2w3<I0(<<nS?l(#c?BX#m`Ro2v6WCL7YNY zHpeYQobE%<#j^zQGK6%fSc`ZA!mH6a4Tu*a4B=@-`~<?!@jQ&U^&*bjiRW>|dk}tv zXFcH{9DOmqUPU+vWjq@Y4<P(Go~?+lNB9h$AmSSkzJzBR;z5KXuo&n@+)9grOE~Ur z#7hufdnpD0;)Mv^c)mis6=5$P^9x$|72+9)bC+@4E<Blt_fQ<0bvYDA*f<6w1@Tsd zwO8OhN5mTt7Ux1Ph?gLI1<!oMg9xw3^sxl-LWGC#v>@J#u=z^RK)e;<b9mMuz5(GE zc-A7$VS~YsCxCbWVK<&95${3BjYInh2Vn!A=MksyF+49Jz8>K*JX;YzfpEoDD35q6 zLL1g^`w%ZgScIn+@c_a{@qC2%dW8RpM@4)C!hhg7hWH7DLw^YV5Vs=y49`~tM>stn zGJFwjM|gb!$E71)i12GXBN68&aNHAk#v#5QVLev<*C5`2aOouI7{w7TwBbR#3}M@3 zz!2|2_}CQij`(_nt8hxZ7V!YWD+-}Mi031`85Zan#LE!!4qPTcJOkmXna~Zy0|;kT za@_lbgYXcZKE!(wj;;ca*bTQL99Rwh5zj!lb}?Xx2N0gdGY)ZX3EmQ^LBA6Y!aMPl zAl`s*J)SbeDf}GI62iX&GQcAtZbi8MPUryPARJi>+5|^<FP<k6Z$)_RQnUr}LWH$= zHXz=B@I^c?As$5da2@&=@%0E#<LO46tA{S&=|Ox0!gulXBHoMe^9J-O;oODs-H7ld z&__723GJXb!Uyo=ARa)tLxO!kya(aSZuA%8L4@0v0hiziRXi@lPar(n3^`C7VL=P} z5%EHVGw_rlUV?Bno=U_62uCkR+YtZv@4r_9CQA}$nPAE{4NTz%PDshOl$jfnOOk@7 zR123n)tsMPmegP>!J5r%;>`CWH1JcBxs<6%`KB_!DE_n_A7JJNoJ!75Dl;{hDE^`z z2iqoksGb+&>KT&C4QU*hpH`OIFrXwQXzoesWq4H2EbvA3PDME*jIY<ANg=@(={yk4 z7yHp1Jis?NdGL#A`Ke_C8d8GMHWBUqG>ON?I35RDd;^mQ?jZ;(XYkfvX7P0T%ddah zkfYHqqb($}3A)Vs<MdB|UwsCyL6<_K4=G%vr=Lb>;P!8Kf1ZtUgHjxWk_Sy4ke^a! zfp(aNrp+CiJaod~{PeOx4FiLzJt@6RPJ;)`h0JFq$h^PI;@eB@X^+#XBYHf20GHmL znm?c{rNL5S4kq>JeP-YeAIJ?iWpU~GgUSXrq?M!wQ+mw3NheGfr*juC8HBtG|2dD^ zLT#t|XX)}Ly_wZdZ-}R-bv{TQPsfdkZ_{1ExjzoakZpWlQD0=FaT$yHbF8;(s$L)Q z_-*=W(2SRz0qfsq2At}f`YrYK$0u1&?I&yEH@+@v%Vj!`@$zFjX6B66vvF+bUB7k! z{O{lYPbBbJ-50R%9CvFk`Wc}`e{zwYjHiU2Y|P7e$X6#HoqY3Jz&GJZKFo19;`t>W zqL9QTb7t<2y7FeJv8t}Js<EnZd}VDdH=}%6d1-y);?g^6q^6qEnxzf3rFB*HORFkt z%1iH9T3yv5m1+s2Sn0Bw%BuR(8N$tTX6cklD{AYTs{Wg3)i+et{Wp<nD6grL{<~;3 z)>mND?Z1gy)AFVYsdmxwy7HyuxF-JApNORcU%)>;1z#`@CiY=%1z0c+HXpD}fc3<| z_5s!n*rt;)dakpe^*PomfE&MsfVHBYfA#ldKiud0rC;rrKA@*h>EXaHwVE!`!)x?# zh92Ikhjn_`s)tYL;UDy{Qx6a5;VC^#I<3*q*24*UDC*%tJzS=T59;BwdbmLkx9Q;? zJ^WM;xicF53_UdDc7>k4Mh~az;VeBY)5AOTaG4&i(8D!)_%l6xLJyzT!{_zzB|Y4# zhn;%(wjTan4^=(<LJz;u!&K-6{WA6N5<Se-LoF9ezJBR{_q!&U|J(Zg4on(svS7_8 z!(TeRN<x72K+ay%h_iyL?M01M<x-Umi&Fd5_W7>*^2*un#_IBls%ee&ON*<P);BKa z-s9|5wN+A8QDco%Q&C<!TR*Wl!#V1ts>c3c?sXF?Dsnes?vZdP!3^*l{|s|ha=YW8 zbC!UWN&q=N3FTeoO_HOrvA&VxE~j*HeWkm$N-VFdtgRBT`$aG!t{<ylzltEUmp4gO zOXuM9MQEB<Q(Hwb?l+V(r>5f0qI#Un;2rTKCpNNc%4>0Q(VzJt$<8MG)S}rg@G=#L zE{+!5OGrj)**~FjHzt$3Ts4at%Nv*9jGd+AVt1`nL&fIQ-;DXTXi0e^w<(z&=#*47 zvR&!AiYmrNRU`LJ@+_$q{7=JHDILSiDPL4u#YG5ORNf%r=%}b30&bDG6f<D1`uaQF z4F)nqkFMbcQ;vRcG`Fs~rVjFZ(mcCLnp?Mo$*R)PQc=}F<RK6A7WaGe?AofT25zHy zPF3U5nmTm9(MjB^<~g-Z5Z1i%T6Yz<%lw^0@VPC$Qk11rC)_qQAgs9@H^^d$U`~Bh zF5FD)3B!Y_ud8aQk+|7N)zmN2HjB9hNG)AdTH$UiU0M#gw{WH9OPdy#GE{CWS6bEB zSce^zOH8G75`o4n<vga++WLw+x!j~uo#tCfrS3WgTbEqEsJ>C+9!oBl>ai>Ii)1J- za&Y}7xf;g=72K=I)s0n{%HK?04E?TK#&IW;flyvsRZ&l=zT~BP3C_H<YH39SB!00O z2Mrn$H_F^pv$(DtJ4bouCaJMv3AFWx6a%NExf3W}3(ts~NU^$#r43xIxw)c=!9Gs9 z8U0n?Ohe6HM8h-_en92bl{RDC=4$B{Tj@1d8?ecM{eSt~;FvYj;ktT)QGW^Q|9|^g z+O({qQMX=|sBi9U$E+9!%%J_x`IC`&4sS4S+z&W$(YNOtc>fOnXGlQEsA(Wh?Rq#; zzt@q^Y4HCUt@t;W|JxGC!1)CVCtZs_t+3??GS*wy=dYi%zIA<IJ+0?~!euiEWol_| zed_v*_1Vb(_wRqQ1jbjx-$Vn<c)p2n++q`^Ft|G7;cvwMD8B@ciL+vVhkirwSOL}` z2Avc@qjVNkEv~7HQ8I9-q=thC==J~o7=Q+YvZ;TrmY#uNgMq_93+XSmu3{X*>Ef(l zC<b{DkP}ge!OsXlWBmLIsl?wABui3tI^V$$y(V2|;IQJ$0cl8pYzL$;EuNp@5ao#| z#Na0z<u!h)%kS*BWn<vr*!#c4!IAcViG!o={}Kns*g6h8Qsx53`V?7QHCkaE_}%h> zuTE|=*JI#tMk~fdDZ`;}lFH#dMfJ|W$&2DhwM|X#h8PCb&2dds`=EHK-VaD13Nh%6 z1+K1{<cC+aRK+M6IQdZ=EHM^0moBNQZNS~KDB?O$UT;wT4o!FpI2#O{XiKk-Qr7OV zUB&LPMG13%La7oAjKtAoi<VkkQLz*|jIjd9!HyeB6%PGw$rH{2;ItYzv{nHbobg5> zM%!^fuFGd}Qz_)!fJI1rb;m%58}|KmB`2eo4V-A(?NQ3GEv4E5uQ87F2r4!F`zhxG zr!~uv4+wJ80BOL`O_bQQXkE~jrR0uR5HkB2ExiFLO%s44EorQb!y&}mKsks(7_%F9 z146srF~}2u^hO~D<>Dx1qVp%<#C`_OtpI7YH&oFr%6^q|?I_iX;mzv$4jrR!`E4+8 zSQQ^pUAWH@<B-0}Pq$!VkP)z#JqeKUfN(GqF&qJqh6Kn>fUHk|)B$oL0TKYDb(BHJ zXlZG*rA4#mlvXzs<j2~IB<__~Nrf;#-_=qbg^S`uHL5&H`MWJ-MHHvDW)X(ZgjnTK zI=G~v_XVcBe&fqtTU$&+CGb5Q8ZEsuo(}ep8kfgahP*$J4F3f>G-GMHq1hiu0H+Go zQDXGPfDQiw9bCvrptGzWp>FEIe}N7*6B6h&Xjc@Y{OkvvjEVjG{qAU~#g$Thc@!I9 z*dGRC_i?_f-wmm*h|+1sK(1f9D2|d2;d<v7wG;Ia__5A4AO;;zl+MycpwnCtM@NTn z0qlguM#1Nx!_7A!z+pQd8Mhb^gEILOT7Ok8t!av<iwyj}2Au|@)OU>Kboeam4IEZ# zBp@8jM2w#w0Ah_ojM^UpnpQg%yM{_7{ALj41v;JYsJ)UXFEr{hDE|_43_bjoW^pS} zDtMbwiYis8uG`}wj{(BL1jJhLTR=7>K>iF!ZvupUxD&%WR%!=u3Kzvg=*xSB7~V0Q zUO)l~kT4)UmGL-V0uro>heQac+JG2se>&Rs#oyYegWx}&FiL%gRI>>O#zo`Mp!`gf zG9ug<;KY6g&VK@=N&dSn+q3@y&L92-oag@qoIm{wI2-;2oP&_H)-DWX9OcFhL6pWF zHb^5i>K__=k(;ppsmV~=FNKd3g&2FE8=??nhcXz25ak)5yd(-S_Cs4@5Ph%I8ii1) zxzsyReh5+yNJbQ*?a^X%M@t#Iw1rWKvCG;TgXp`dfhdG1-vi3I36KW>>5f9QU0<Bd zMj=!x0G#y+kY4~YDGD+6ou7?DwEbk<=Zr#(ecm<k5VjxO6NOM+zXj#_QHZfqT^5CC z`_Z^r8HJRVwp5g2BESNOz75Nf^T=^8fKD&NF(9u3lK;q(2D*i>;d}r{U$RzGgM<Lt z2SP+kgIES=I~6g=#emR{@->_*0qMPi^v8hM2$DeA0m!BVoOythCEzRtq$B}H1|$`h zJy!dpfRKk8gZv&4`axlIel{_P(Nf5#wiI?Q7x^*yY$M7Eb?pWuBLNa32ueXHI%TRh zAL9!Q=#Wf6HYD(K1t9dnECf2vG(-y%S}_lhfS#|(u#(X6i}lXE1VQyN$RiBL8VC6^ zAYdmBvI~%0Kw>TZ01#TeAOJs18nD)rqBx~+%}Ze??102%coygx2|UyH&grMoq1YvW z^wq@o`&d9oVuY%-YYL*zMr)^1vjOQ&kXR)kxe28tKzb5zRsm87oEV2|0kI}<_#c4K z{1of27XeWdYTpG&cC?pE$z3j<!zcqy=lKwDTBA4sb74T1BtYmtUZ7vBu7O}}QUcF8 zfFx?mbU+Fd=-duSVlOWP<U|6`G9cLrEqxe}`3ZHs07wuJ{L@>p6%g)@_}<wCh!wyX z&j$bz0iniF`*EWj5c*#}W4$~8E9};U+AjhmBLU|sKw@;*30^6j4g6x-I|Vq2kXeAF zCeUdBq$Po8A1h^yWh(zLK@#}+6(ExmO1(fh31g=V5ES}f?VV4EWW^oF+l`kfi4k(x zgNH$KSV4`BQG_VCGt<%?$DVel7xp03_MbO9FVoZg>_6j<L=w!!qk`gI0*hX9O7<us zVIhI!;6Z|iC6}nD^&l!F5HI5AS5>d7e%-G}A$YT4W#0Ey{i^C$zxvhhReh_pt#mE@ zH^{RzJht>p5Irh?EDN^$P>R>jX^;!5tOr5lt1QZS9OO}j{0c<--hGgUYWqtd7eX$# z2a6@-X%D_ink&jS-U7MqYv<Z^4di`Q!@qz$Mw(c|8z5IznomI5tPD8Yz)R#Zr>v1H z+QxrLBbGq5y*6(B5!Mpq6n$Cl!B$nSJ4w?9iKX8IB0s6GtMge9?KhqQDS~84oq;qE z66L%I^1jl>6%am`6AOO}WG%Ey<h%nSzu2z#Kz^dq{0rnmCHX%fmsNk=E{m%QSp(6U z|2c?^%2?+OkVfcbsmBh;|5RCfAo7c2=NRM(CFc#0s|u0-HOf^b=kFjFRaqZ^Tvt8# zF~|cd&1WFeEwS`dchIM*th+(3sNQ)D1TjgjXF%3eu6@a+YIp?lM<wU?ATNhpcDBL} zpFnc#uQy4vAJXuu_BW853i&6<Ka}K;Kt5E+XCRG$SeqwK&~_+~*FqX8>!%=vDr*ho z<&XwBeTg^Z7wi16h(%b`Y73;H(p&^VaFS*Oat#Ef*?)Zff&5OD{s)kYp>z_~{tR+m zA%6vVCFHVN?bGk1jWxVM8mZ51{FCxHVFYqojf*cp9#E2h$m-^mAX#$V1#&|n_kzf7 zSDbe?LEctrIv{719cCaDm$dywkO4>>O|OGoR>+?~_LZD>LF5-T{{hGaghV-?E~WVj zq^;!K&T6ZiSGxsSPCutX&M5uJt!#zL^-GYops|vJ(#TUeEz;;X;Ub8X5$pUL5cx&q zHIUDh4&MY3-y8M(4#+E^bjdGk#%-1BCWtQmHrjN9;-h}<25FExTFW}f8IYK!39?Os zi1b0Ol15r`s&;=q=+3%7`vnj7_XA>4!cHG22z078Cx?y6nyqH1=GO&@(RO9SVqVk~ zJ=u|CWXnLop0%73nH~8!MI48Cf$nUnZd=(=-iP(9QhSox|I4VBs(#PR{&wW^;=5yJ zyA@wg2P0TL9@%do8@w3)oMf_cI;oifG_OHsiZM&WFyk;+{aj@ELytaU{Cy6_Uzi{{ z&0uUU4adFi(1@t1Li!$IPht*b^4PM~I2k=Y$TJd7GT9I^m!|%H2q0JE-Fico8pe}y zXD7Uos+-L3_i(IzG=~(|ceK7FvElX!CyTup!&MRHAUn1dM3R0vf!cYLrSDxGI@`Ol z{L<^fsZ00Q?i=P)*<dkH17)CRO}V^cqdTQVPr_nr*GpEYe%v^230b~uBHTis?#c0_ zq;4+1bVN-pseU=5cm%ZTN!iV5Ydm@$Eem(DIr6Min;;aLjpm1PMnbgC4u-HbjZpZd z*IcVv0W*$s=Cvul$ucb4VjCfyU;Gcx<!(R#{IY(H1vI<PKCK=0<S(8{GdVJLiOg)R zpXG71@GNUTvdqt`=jLO2$fonwoL+1o{ord}ap^(QriJSe%tl)LhLq>4atLu%?8Q|q zU+*Qj|FalB|F9(UkHhJHzE?iLYxM9S-`n$l_SQ>zgCLJ(vVNI#l1i9OxGd!bn=^Jv zd6@w1UF0h#ywQ}}yqd(EP)Q?yGvRthN@+?^RRm4O(7E%iPV?!yY46t0Z|#_K_3fQa zv)$b7FwIdV)Zmsgx%eROF&O#pK{gp>!-v*Qmm=&~*oRvj-wWT9c#=|?K8@YFx5CU; zXXl)j?Urtr2+FSDB_8nZ2_#^b#V@qF2gPNksj_SoYZHeYBQSEaWjt3=u3aCB+ZxWG z8jR&e4rX13z|0g=>qxzHueMa_u0AJprB!t7MSaVJm1O!*ue*J`I&LfPPpwAfrW!Ne zlUDT)@W+RTcva~){X%wAC-_ErbJ+bg?sz)yar6gbx$*boxDJv%c-9`HlBEBusq(H# zZu!}m=F{yR7N)l9yPM~lZRutq>(|oze<<5n`T3&!1>(MwoLG0v=%O#5z;UNzuX?@X z`Gogex|8v6z{FAnZh=olH+#<-So#t2>~Wa;orFBTL@qa`H%%={lofd4319xiQC4ql zq5BnN_}Gz*up;eXDT@k6yY>Ac<Zt)qN|C5%YTeQT-`!bww<yf)xDY9>yNZSGsysR1 zid^t5zK-#nLKIncBxPca<Eb)3pRaNlGKDRl&ydpPhL#?aw>4yuV0Sc7!lpiWfJ)tA z4<;^{?uYEi+bocba)yZC>nEh?PPxJ=@p^N{Q0nuNNvZVeHEWC{9Mo2xGhnQo?fB0K zr!~Lr^le-*%~?8K;e?dCV!rd!8N~bHQstYe6V{G9I`$g2rO&50V=slw@)2i3yd9A? z>0>R@#~?Brcnu%*`$M9es9|SjeXo=1CWg7k%`N4;W8G%8Nr<y2ipw~1QI>4o+T7an zEZTQJv2Pb)TWX?LWR+8J8n18%-f+cz#7NL6h1(kAo8qAm-+%7Zg?p$_zM5t5`o4Or z4&pdDRmW9+D~{Q;&Tns<PUC#*DYJF9BcYqr-EaBP)%m5+yY7`gHDZi#LKlXPWNk7r zR-Zpw{id9ZDu#bWL?FYaoR}77cB#M#15RFlbLdd6bfA3Qfoar&b?T!@RVsEGbL-(N zyk$8*TeqH0&u%cxLQ8R1VXC$hd-(<CKE7m1D2ADMG2e&jjJ0IEwd(0f6tplI;HqT= zmE+wF44!HyTin8gFM?wjszNCFhAl%Vn=Bria{5anS@p$h!si?u%rx#SJv5rI_PrF8 zL^HSNmP-3`lSdi|rS68KN+HfAT<vmZ-Rup!5FyI|Sv~<cCndAn{=sy1z=szP-rbc> zhvppk@;w(J_D%>vbTldIwqeZ5fXz*x%k{Sk^=HPk);Zhe)qYY~S2b;}{!nlsjO(@7 lC?7;wwMbaW=e}J#Tj(?#x@eeWLFwh35xjg@cJM0>Ujv~f3H1N~ literal 65024 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 L{ayl>l)(Q19B!=- diff --git a/lib/native/windows/jnawtrenderer.dll b/lib/native/windows/jnawtrenderer.dll index 6163f058f9fc10b9c5a94eb526117012ccf53f36..e5465904230447c901d1ea3540cfa256b538b16d 100644 GIT binary patch literal 47636 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 VK^c$iKUl0e7jw3%q8V`Le*r*??uGyW literal 58368 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 diff --git a/src/native/build.xml b/src/native/build.xml index 69960938..45102fa6 100644 --- a/src/native/build.xml +++ b/src/native/build.xml @@ -174,79 +174,72 @@ </target> <!-- compile jnawtrenderer library --> - <target name="jawtrenderer" description="Build jnawtrenderer shared library" depends="init-native,jawtrenderer-windows" - unless="is.running.windows"> + <target name="jawtrenderer" description="Build jnawtrenderer shared library" depends="init-native"> <cc outtype="shared" name="gcc" outfile="${native_install_dir}/jnawtrenderer" objdir="${obj}"> <!-- common compiler flags --> + <compilerarg value="-D_JNI_IMPLEMENTATION_" /> + <compilerarg value="-m32" if="cross_32" unless="is.running.macos" /> + <compilerarg value="-m64" if="cross_64" unless="is.running.macos" /> + <compilerarg value="-O2" /> <compilerarg value="-std=c99" /> <compilerarg value="-Wall" /> - <compilerarg value="-O2" /> - <linkerarg value="-L${system.JAVA_HOME}/jre/lib/amd64" /> - <linkerarg value="-L${system.JAVA_HOME}/jre/lib/x86" /> + <compilerarg value="-I${system.JAVA_HOME}/include" unless="is.running.macos" /> + + <linkerarg value="-m32" if="cross_32" unless="is.running.macos" /> + <linkerarg value="-m64" if="cross_64" unless="is.running.macos" /> <linkerarg value="-ljawt" location="end" /> - <!-- Linux specific flags --> - <compilerarg value="-m32" if="cross_32" unless="is.running.macos" /> - <compilerarg value="-m64" if="cross_64" unless="is.running.macos" /> - <compilerarg value="-I${system.JAVA_HOME}/include" if="is.running.linux" /> + <!-- Linux-specific flags --> <compilerarg value="-I${system.JAVA_HOME}/include/linux" if="is.running.linux" /> - <linkerarg value="-m32" if="cross_32" unless="is.running.macos" /> - <linkerarg value="-m64" if="cross_64" unless="is.running.macos" /> + <linkerarg value="-L${system.JAVA_HOME}/jre/lib/i386" if="is.running.linux" /> + <linkerarg value="-L${system.JAVA_HOME}/jre/lib/amd64" if="is.running.linux" /> <linkerarg value="-lXv" location="end" if="is.running.linux" /> <linkerarg value="-lX11" location="end" if="is.running.linux" /> - <fileset dir="${src}/native/jawtrenderer" includes="net*.c JAWTRenderer_Linux.c" if="is.running.linux"/> + <fileset dir="${src}/native/jawtrenderer" includes="org*.c JAWTRenderer_Linux.c" if="is.running.linux"/> - <!-- Mac OS X specific flags --> + <!-- Mac OS X-specific flags --> <compilerarg value="-mmacosx-version-min=10.5" if="is.running.macos"/> <compilerarg value="-arch" if="is.running.macos" /> - <compilerarg value="x86_64" if="is.running.macos" /> - <compilerarg value="-arch" if="is.running.macos" /> <compilerarg value="i386" if="is.running.macos" /> + <compilerarg value="-arch" if="is.running.macos" /> + <compilerarg value="x86_64" if="is.running.macos" /> <compilerarg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" if="is.running.macos" /> <linkerarg value="-o" location="end" if="is.running.macos" /> <linkerarg value="libjnawtrenderer.jnilib" location="end" if="is.running.macos" /> - <linkerarg value="-arch" if="is.running.macos" /> - <linkerarg value="x86_64" if="is.running.macos" /> + <linkerarg value="-dynamiclib" if="is.running.macos" /> <linkerarg value="-arch" if="is.running.macos" /> <linkerarg value="i386" if="is.running.macos" /> + <linkerarg value="-arch" if="is.running.macos" /> + <linkerarg value="x86_64" if="is.running.macos" /> <linkerarg value="-framework" if="is.running.macos" /> <linkerarg value="OpenGL" if="is.running.macos" /> <linkerarg value="-framework" if="is.running.macos" /> <linkerarg value="Foundation" if="is.running.macos" /> <linkerarg value="-framework" if="is.running.macos" /> <linkerarg value="AppKit" if="is.running.macos" /> + <linkerarg value="-framework" if="is.running.macos" /> + <linkerarg value="QuartzCore" if="is.running.macos" /> <linkerarg value="-L/System/Library/Frameworks/JavaVM.framework/Libraries/" if="is.running.macos" /> - <fileset dir="${src}/native/jawtrenderer" includes="net*.c JAWTRenderer_MacOSX.m" if="is.running.macos" /> - - </cc> - </target> + <fileset dir="${src}/native/jawtrenderer" includes="org*.c JAWTRenderer_MacOSX.m" if="is.running.macos" /> - <!-- compile jnawtrenderer library for Windows --> - <target name="jawtrenderer-windows" description="Build jnawtrenderer shared library for Windows" depends="init-native" - if="is.running.windows"> - <cc outtype="shared" name="msvc" outfile="${native_install_dir}/jnawtrenderer" objdir="${obj}"> - <compilerarg value="/O2" /> - <compilerarg value="/MT" location="end" /> - <compilerarg value="/IC:\Program Files\Microsoft DirectX SDK (February 2010)\Include" /> - <compilerarg value="/IC:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Include" /> - <compilerarg value="-I${system.JAVA_HOME}/include" /> - <compilerarg value="-I${system.JAVA_HOME}/include/win32" /> + <!-- Windows-specific flags --> + <compilerarg value="-D_WIN32_WINNT=0x0502" if="is.running.windows" /> + <compilerarg value="-DWINVER=0x0502" if="is.running.windows" /> + <compilerarg value="-I${system.JAVA_HOME}/include/win32" if="is.running.windows" /> - <!-- <linkerarg value="/LD" /> --> - <linkerarg value="/LIBPATH:C:\Program Files\Microsoft DirectX SDK (February 2010)\lib\x86" /> - <linkerarg value="/LIBPATH:C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\lib\x64" /> - <linkerarg value="/LIBPATH:${system.JAVA_HOME}\\lib" /> - <linkerarg value="d3d9.lib" location="end" /> - <linkerarg value="user32.lib" location="end" /> - <linkerarg value="jawt.lib" location="end" /> + <linkerarg value="-ojnawtrenderer.dll" if="is.running.windows" /> + <linkerarg value="-Wl,--kill-at" if="is.running.windows" /> + <linkerarg value="-L${system.JAVA_HOME}/lib" if="is.running.windows" /> + <linkerarg value="-ld3d9" location="end" if="is.running.windows" /> + <linkerarg value="-ld3dx9" location="end" if="is.running.windows" /> - <fileset dir="${src}/native/jawtrenderer" includes="net*.c JAWTRenderer_Windows.cpp windows/*.cpp windows/*.c"/> + <fileset dir="${src}/native/jawtrenderer" includes="org*.c JAWTRenderer_Windows.c" if="is.running.windows"/> </cc> </target> diff --git a/src/native/jawtrenderer/JAWTRenderer.h b/src/native/jawtrenderer/JAWTRenderer.h index a493c293..a5105e9e 100644 --- a/src/native/jawtrenderer/JAWTRenderer.h +++ b/src/native/jawtrenderer/JAWTRenderer.h @@ -16,26 +16,17 @@ extern "C" { #endif void JAWTRenderer_close - (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component); -jlong JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component); + (JNIEnv *env, jclass clazz, jlong handle, jobject component); +jlong JAWTRenderer_open(JNIEnv *env, jclass clazz, jobject component); jboolean JAWTRenderer_paint - (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g); + (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, + jobject g, jint zOrder); jboolean JAWTRenderer_process - (JNIEnv *jniEnv, jclass clazz, - jlong handle, jobject component, - jint *data, jint length, - jint width, jint height); + (JNIEnv *env, jclass clazz,jlong handle, jobject component, jint *data, + jint length, jint width, jint height); #ifdef __APPLE__ -void JAWTRenderer_addNotifyLightweightComponent - (jlong handle, jobject component, jlong parentHandle); -jboolean JAWTRenderer_paintLightweightComponent - (jlong handle, jobject component, jobject g); -void JAWTRenderer_processLightweightComponentEvent - (jlong handle, jint x, jint y, jint width, jint height); -void JAWTRenderer_removeNotifyLightweightComponent - (jlong handle, jobject component); -jstring JAWTRenderer_sysctlbyname(JNIEnv *jniEnv, jstring name); +jstring JAWTRenderer_sysctlbyname(JNIEnv *env, jstring name); #endif /* #ifdef __APPLE__ */ #ifdef __cplusplus diff --git a/src/native/jawtrenderer/JAWTRenderer_Linux.c b/src/native/jawtrenderer/JAWTRenderer_Linux.c index dde3bc29..e2d8554c 100644 --- a/src/native/jawtrenderer/JAWTRenderer_Linux.c +++ b/src/native/jawtrenderer/JAWTRenderer_Linux.c @@ -91,7 +91,8 @@ JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component) jboolean JAWTRenderer_paint - (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g) + (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, + jobject g, jint zOrder) { JAWT_X11DrawingSurfaceInfo *x11dsi; JAWTRenderer *renderer; diff --git a/src/native/jawtrenderer/JAWTRenderer_MacOSX.m b/src/native/jawtrenderer/JAWTRenderer_MacOSX.m index 81e3a545..51d4e50a 100644 --- a/src/native/jawtrenderer/JAWTRenderer_MacOSX.m +++ b/src/native/jawtrenderer/JAWTRenderer_MacOSX.m @@ -16,324 +16,247 @@ #include <sys/types.h> #include <sys/sysctl.h> -#import <AppKit/NSOpenGL.h> #import <AppKit/NSView.h> -#import <Foundation/NSArray.h> #import <Foundation/NSAutoreleasePool.h> -#import <Foundation/NSNotification.h> #import <Foundation/NSObject.h> #import <OpenGL/gl.h> #import <OpenGL/OpenGL.h> +#import <QuartzCore/CALayer.h> +#import <QuartzCore/CAOpenGLLayer.h> #define JAWT_RENDERER_TEXTURE GL_TEXTURE_RECTANGLE_EXT #define JAWT_RENDERER_TEXTURE_FORMAT GL_BGRA #define JAWT_RENDERER_TEXTURE_TYPE GL_UNSIGNED_BYTE -@interface JAWTRenderer : NSObject +@interface JAWTRendererLayer : CAOpenGLLayer { +/* + * XXX The fields of JAWTRendererLayer are declared public for the sake of + * performance so that the function JAWTRenderer_process may effectively be + * implemented as a member of the class. + */ @public - /** - * The OpenGL context of this <tt>JAWTRenderer</tt> which shares - * <tt>texture</tt> with the OpenGL contexts of <tt>subrenderers</tt> and - * enables this <tt>JAWTRederer</tt> to not directly access the OpenGL - * contexts of <tt>subrenderers</tt> because it cannot guarantee - * synchronized access to them anyway. - */ - NSOpenGLContext *glContext; - - jint height; - GLuint texture; - jint width; - - CGFloat frameHeight; - CGFloat frameWidth; - CGFloat frameX; - CGFloat frameY; - - CGFloat boundsHeight; - CGFloat boundsWidth; - CGFloat boundsX; - CGFloat boundsY; - - NSView *view; - - /** - * The <tt>JAWTRenderer</tt>s which are to have their <tt>layer</tt>s - * contained in the <tt>layer</tt> of this <tt>JAWTRenderer</tt>. - */ - NSMutableArray *subrenderers; - /** - * The <tt>JAWTRenderer</tt> which has this <tt>JAWTRenderer</tt> in its - * <tt>subrenderers</tt>. - */ - JAWTRenderer *superrenderer; + CGLContextObj _glContext; + jint _height; + CGLPixelFormatObj _pixelFormat; + GLuint _texture; + jint _width; } -- (void)addSubrenderer:(JAWTRenderer *)subrenderer; -- (void)boundsDidChange:(NSNotification *)notification; -- (void)copyCGLContext:(NSOpenGLContext *)glContext - forPixelFormat:(CGLPixelFormatObj)pixelFormat; +- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat; +- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask; - (void)dealloc; -- (void)frameDidChange:(NSNotification *)notification; +- (void)drawInCGLContext:(CGLContextObj)glContext + pixelFormat:(CGLPixelFormatObj)pixelFormat + forLayerTime:(CFTimeInterval)timeInterval + displayTime:(const CVTimeStamp *)timeStamp; - (id)init; -- (void)paint; -- (void)removeFromSuperrenderer; -- (void)removeSubrenderer:(JAWTRenderer *)subrenderer; -- (void)removeSubrendererAtIndex:(NSUInteger)index; -- (void)reshape; -- (void)setSuperrenderer:(JAWTRenderer *)aSuperrenderer; -- (void)setView:(NSView *)aView; -- (void)update; -@end /* JAWTRenderer */ - -void -JAWTRenderer_addNotifyLightweightComponent - (jlong handle, jobject component, jlong parentHandle) -{ - JAWTRenderer *renderer; - JAWTRenderer *parentRenderer; - NSAutoreleasePool *autoreleasePool; - - renderer = (JAWTRenderer *) (intptr_t) handle; - parentRenderer = (JAWTRenderer *) (intptr_t) parentHandle; - autoreleasePool = [[NSAutoreleasePool alloc] init]; - - if (parentRenderer) - [parentRenderer addSubrenderer:renderer]; - [renderer copyCGLContext:nil forPixelFormat:0]; - - [autoreleasePool release]; -} +@end /* JAWTRendererLayer */ void -JAWTRenderer_close - (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component) +JAWTRenderer_close(JNIEnv *env, jclass clazz, jlong handle, jobject component) { - JAWTRenderer *renderer; + JAWTRendererLayer **thiz; NSAutoreleasePool *autoreleasePool; - renderer = (JAWTRenderer *) (intptr_t) handle; + thiz = (JAWTRendererLayer **) (intptr_t) handle; autoreleasePool = [[NSAutoreleasePool alloc] init]; - JAWTRenderer_removeNotifyLightweightComponent(handle, component); - [renderer release]; + if (*thiz) + [*thiz release]; + free(thiz); [autoreleasePool release]; } jlong -JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component) +JAWTRenderer_open(JNIEnv *env, jclass clazz, jobject component) { - NSAutoreleasePool *autoreleasePool; - JAWTRenderer *renderer; - - autoreleasePool = [[NSAutoreleasePool alloc] init]; - - renderer = [[JAWTRenderer alloc] init]; - - [autoreleasePool release]; - return (jlong) (intptr_t) renderer; + return (jlong) (intptr_t) calloc(1, sizeof(JAWTRendererLayer *)); } jboolean JAWTRenderer_paint - (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g) + (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, + jobject g, jint zOrder) { - NSView *component; + NSAutoreleasePool *autoreleasePool; + JAWTRendererLayer *thizLayer; + jboolean wantsPaint = JNI_TRUE; + JAWTRendererLayer **thiz; - component - = ((JAWT_MacOSXDrawingSurfaceInfo *) (dsi->platformInfo))->cocoaViewRef; - if (component) - { - JAWTRenderer *renderer; - NSAutoreleasePool *autoreleasePool; + autoreleasePool = [[NSAutoreleasePool alloc] init]; - renderer = (JAWTRenderer *) (intptr_t) handle; - autoreleasePool = [[NSAutoreleasePool alloc] init]; + /* + * The native peer of the AWT Canvas that is the component of this + * JAWTRenderer should be a JAWTRendererLayer. + */ + if (JAWT_MACOSX_USE_CALAYER == (version & JAWT_MACOSX_USE_CALAYER)) + { + id<JAWT_SurfaceLayers> surfaceLayers + = (id<JAWT_SurfaceLayers>) (dsi->platformInfo); + CALayer *layer = surfaceLayers.layer; - if (renderer->view != component) - [renderer setView:component]; + if (layer && [layer isKindOfClass:[JAWTRendererLayer class]]) + thizLayer = (JAWTRendererLayer *) layer; else { - // update - NSRect frame; - - frame = [component frame]; - if ((renderer->frameX != frame.origin.x) - || (renderer->frameY != frame.origin.y) - || (renderer->frameWidth != frame.size.width) - || (renderer->frameHeight != frame.size.height)) - [renderer update]; + thizLayer = [JAWTRendererLayer layer]; + if (thizLayer) + surfaceLayers.layer = thizLayer; else + wantsPaint = JNI_FALSE; + } + } + else + { + NSView *view + = ((JAWT_MacOSXDrawingSurfaceInfo *) (dsi->platformInfo)) + ->cocoaViewRef; + CALayer *layer = [view layer]; + + if (layer && [layer isKindOfClass:[JAWTRendererLayer class]]) + thizLayer = (JAWTRendererLayer *) layer; + else + { + thizLayer = [JAWTRendererLayer layer]; + if (thizLayer) { - // reshape - NSRect bounds; - - bounds = [component bounds]; - if ((renderer->boundsX != bounds.origin.x) - || (renderer->boundsY != bounds.origin.y) - || (renderer->boundsWidth != bounds.size.width) - || (renderer->boundsHeight != bounds.size.height)) - [renderer reshape]; + [view setLayer:thizLayer]; + [view setWantsLayer:YES]; } + else + wantsPaint = JNI_FALSE; } - - [renderer paint]; - - [autoreleasePool release]; } - return JNI_TRUE; -} -jboolean -JAWTRenderer_paintLightweightComponent - (jlong handle, jobject component, jobject g) -{ - JAWTRenderer *renderer; - NSAutoreleasePool *autoreleasePool; - - renderer = (JAWTRenderer *) (intptr_t) handle; - autoreleasePool = [[NSAutoreleasePool alloc] init]; + /* + * This JAWTRenderer should paint into the JAWTRendererLayer which is the + * native peer of the AWT Canvas that is the component of this JAWTRenderer. + */ + thiz = (JAWTRendererLayer **) (intptr_t) handle; + if (*thiz != thizLayer) + { + if (*thiz) + [*thiz release]; + *thiz = thizLayer; + if (thizLayer) + [thizLayer retain]; + } - // TODO Auto-generated method stub + /* + * Forward the paint request from the AWT Canvas to the JAWTRendererLayer + * that is the former's native peer. + */ + if (thizLayer) + { + if (zOrder > -1) + thizLayer.zPosition = zOrder; + [thizLayer setNeedsDisplay]; + } [autoreleasePool release]; - return JNI_TRUE; + return wantsPaint; } jboolean JAWTRenderer_process - (JNIEnv *jniEnv, jclass clazz, - jlong handle, jobject component, - jint *data, jint length, - jint width, jint height) + (JNIEnv *env, jclass clazz, jlong handle, jobject component, jint *data, + jint length, jint width, jint height) { - JAWTRenderer *renderer; - NSAutoreleasePool *autoreleasePool; + JAWTRendererLayer *thiz = *((JAWTRendererLayer **) (intptr_t) handle); - renderer = (JAWTRenderer *) (intptr_t) handle; - autoreleasePool = [[NSAutoreleasePool alloc] init]; - - if (data && length) + if (thiz && data && length) { - @synchronized (renderer) - { - if (renderer->glContext) - { - [renderer->glContext makeCurrentContext]; + NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init]; + CGLContextObj glContext = thiz->_glContext; - if (renderer->texture - && ((width != renderer->width) - || (height != renderer->height))) - { - glDeleteTextures(1, &(renderer->texture)); - renderer->texture = 0; - } - if (renderer->texture) - { - glBindTexture(JAWT_RENDERER_TEXTURE, renderer->texture); - glTexSubImage2D( - JAWT_RENDERER_TEXTURE, - 0, - 0, 0, width, height, - JAWT_RENDERER_TEXTURE_FORMAT, - JAWT_RENDERER_TEXTURE_TYPE, - data); - } - else - { - glGenTextures(1, &(renderer->texture)); - glBindTexture(JAWT_RENDERER_TEXTURE, renderer->texture); - glTexParameterf( - JAWT_RENDERER_TEXTURE, - GL_TEXTURE_PRIORITY, - 1.0); - glTexParameteri( - JAWT_RENDERER_TEXTURE, - GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE); - glTexParameteri( - JAWT_RENDERER_TEXTURE, - GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE); - glTexParameteri( - JAWT_RENDERER_TEXTURE, - GL_TEXTURE_MAG_FILTER, - GL_LINEAR); - glTexParameteri( - JAWT_RENDERER_TEXTURE, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glTexParameteri( - JAWT_RENDERER_TEXTURE, - GL_TEXTURE_STORAGE_HINT_APPLE, - GL_STORAGE_SHARED_APPLE); - - glTexImage2D( - JAWT_RENDERER_TEXTURE, - 0, - 4, - width, height, - 0, - JAWT_RENDERER_TEXTURE_FORMAT, - JAWT_RENDERER_TEXTURE_TYPE, - data); - } - renderer->width = width; - renderer->height = height; - } - } - } + if (glContext && (kCGLNoError == CGLLockContext(glContext))) + { + GLuint texture = thiz->_texture; - [autoreleasePool release]; - return JNI_TRUE; -} + CGLSetCurrentContext(glContext); -void -JAWTRenderer_processLightweightComponentEvent - (jlong handle, jint x, jint y, jint width, jint height) -{ - JAWTRenderer *renderer; - NSAutoreleasePool *autoreleasePool; + if (texture + && ((width != thiz->_width) || (height != thiz->_height))) + { + glDeleteTextures(1, &texture); + thiz->_texture = texture = 0; + } + if (texture) + { + glBindTexture(JAWT_RENDERER_TEXTURE, texture); + glTexSubImage2D( + JAWT_RENDERER_TEXTURE, + 0, + 0, 0, width, height, + JAWT_RENDERER_TEXTURE_FORMAT, + JAWT_RENDERER_TEXTURE_TYPE, + data); + } + else + { + glGenTextures(1, &texture); + thiz->_texture = texture; + + glBindTexture(JAWT_RENDERER_TEXTURE, texture); + glTexParameterf( + JAWT_RENDERER_TEXTURE, + GL_TEXTURE_PRIORITY, + 1.0); + glTexParameteri( + JAWT_RENDERER_TEXTURE, + GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri( + JAWT_RENDERER_TEXTURE, + GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + glTexParameteri( + JAWT_RENDERER_TEXTURE, + GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri( + JAWT_RENDERER_TEXTURE, + GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexParameteri( + JAWT_RENDERER_TEXTURE, + GL_TEXTURE_STORAGE_HINT_APPLE, + GL_STORAGE_SHARED_APPLE); + + glTexImage2D( + JAWT_RENDERER_TEXTURE, + 0, + 4, + width, height, + 0, + JAWT_RENDERER_TEXTURE_FORMAT, + JAWT_RENDERER_TEXTURE_TYPE, + data); + } + thiz->_width = width; + thiz->_height = height; - renderer = (JAWTRenderer *) (intptr_t) handle; - autoreleasePool = [[NSAutoreleasePool alloc] init]; + CGLUnlockContext(glContext); + } - @synchronized (renderer) - { - renderer->boundsX = x; - renderer->boundsY = y; - renderer->boundsWidth = width; - renderer->boundsHeight = height; + [autoreleasePool release]; } - [autoreleasePool release]; -} - -void -JAWTRenderer_removeNotifyLightweightComponent(jlong handle, jobject component) -{ - JAWTRenderer *renderer; - NSAutoreleasePool *autoreleasePool; - - renderer = (JAWTRenderer *) (intptr_t) handle; - autoreleasePool = [[NSAutoreleasePool alloc] init]; - - [renderer removeFromSuperrenderer]; - - [autoreleasePool release]; + return JNI_TRUE; } jstring -JAWTRenderer_sysctlbyname(JNIEnv *jniEnv, jstring name) +JAWTRenderer_sysctlbyname(JNIEnv *env, jstring name) { const char *_name; jstring value = NULL; - _name = (*jniEnv)->GetStringUTFChars(jniEnv, name, NULL); + _name = (*env)->GetStringUTFChars(env, name, NULL); if (_name) { size_t valueLength; @@ -357,443 +280,144 @@ JAWTRenderer_sysctlbyname(JNIEnv *jniEnv, jstring name) } else _value = NULL; - (*jniEnv)->ReleaseStringUTFChars(jniEnv, name, _name); + (*env)->ReleaseStringUTFChars(env, name, _name); if (_value) { - value = (*jniEnv)->NewStringUTF(jniEnv, _value); + value = (*env)->NewStringUTF(env, _value); free(_value); } } return value; } -@implementation JAWTRenderer -- (void)addSubrenderer:(JAWTRenderer *)subrenderer +@implementation JAWTRendererLayer +- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat { - @synchronized (self) + CGLContextObj glContext = CGLRetainContext(_glContext); + + /* + * Perform any one-time configuration/preparation of the newly-initialized + * OpenGL context which this CAOpenGLLayer will be drawing into + * (in the future). + */ + if (glContext && (kCGLNoError == CGLLockContext(glContext))) { - if (!subrenderers) - subrenderers = [[NSMutableArray arrayWithCapacity:1] retain]; - if (NSNotFound == [subrenderers indexOfObject:subrenderer]) - { - [subrenderers addObject:subrenderer]; - [subrenderer retain]; - [subrenderer setSuperrenderer:self]; - } + GLint param; + + CGLSetCurrentContext(glContext); + + param = 1; + CGLSetParameter(glContext, kCGLCPSurfaceOpacity, ¶m); + param = 0; + CGLSetParameter(glContext, kCGLCPSwapInterval, ¶m); + + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_DITHER); + glDisable(GL_LIGHTING); + glDisable(GL_SCISSOR_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask(GL_FALSE); + glStencilMask(0); + glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + CGLUnlockContext(glContext); } -} -- (void)boundsDidChange:(NSNotification *)notification -{ - if ([notification object] == view) - [self reshape]; + return glContext; } -- (void)copyCGLContext:(NSOpenGLContext *)glContext - forPixelFormat:(CGLPixelFormatObj)pixelFormat +- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { - @synchronized (self) - { - if (self->glContext) - { - [self->glContext makeCurrentContext]; - if (texture) - { - glDeleteTextures(1, &texture); - texture = 0; - } - [NSOpenGLContext clearCurrentContext]; - - [self->glContext release]; - self->glContext = nil; - } - - if (glContext) - { - NSOpenGLPixelFormat *format = [NSOpenGLPixelFormat alloc]; - - /* - * Unfortunately, initWithCGLPixelFormatObj: is available starting - * with Mac OS X 10.6. - */ - if ([format - respondsToSelector:@selector(initWithCGLPixelFormatObj:)]) - { - format = [format initWithCGLPixelFormatObj:pixelFormat]; - } - else - { - NSOpenGLPixelFormatAttribute pixelFormatAttribs[] - = { NSOpenGLPFAWindow, 0 }; - - format = [format initWithAttributes:pixelFormatAttribs]; - } - - self->glContext - = [[NSOpenGLContext alloc] - initWithFormat:format - shareContext:glContext]; - [format release]; - } - } + return CGLRetainPixelFormat(_pixelFormat); } - (void)dealloc { - /* subrenderers */ - @synchronized (self) - { - if (subrenderers) - { - NSUInteger subrendererCount = [subrenderers count]; - - while (subrendererCount > 0) - { - --subrendererCount; - [self removeSubrendererAtIndex:subrendererCount]; - } - [subrenderers release]; - subrenderers = nil; - } - } - - [self setView:nil]; + if (_glContext) + CGLReleaseContext(_glContext); + if (_pixelFormat) + CGLReleasePixelFormat(_pixelFormat); [super dealloc]; } -- (void)frameDidChange:(NSNotification *)notification -{ - if ([notification object] == view) - [self update]; -} - -- (id)init +- (void)drawInCGLContext:(CGLContextObj)glContext + pixelFormat:(CGLPixelFormatObj)pixelFormat + forLayerTime:(CFTimeInterval)timeInterval + displayTime:(const CVTimeStamp *)timeStamp { - if ((self = [super init])) + if (kCGLNoError == CGLLockContext(glContext)) { + glClear(GL_COLOR_BUFFER_BIT); - glContext = nil; - - height = 0; - texture = 0; - width = 0; - - frameHeight = 0; - frameWidth = 0; - frameX = 0; - frameY = 0; - - boundsHeight = 0; - boundsWidth = 0; - boundsX = 0; - boundsY = 0; - - view = nil; - - subrenderers = nil; - superrenderer = nil; - } - return self; -} - -- (void)paint -{ - if (!glContext) - return; - - [glContext makeCurrentContext]; - - // drawRect: - glClear(GL_COLOR_BUFFER_BIT); - - @synchronized (self) - { - if (texture) + if (_texture) { /* * It may be a misunderstanding of OpenGL context sharing but * JAWT_RENDERER_TEXTURE does not seem to work in glContext unless * it is explicitly bound to texture while glContext is current. */ - glBindTexture(JAWT_RENDERER_TEXTURE, texture); + glBindTexture(JAWT_RENDERER_TEXTURE, _texture); glEnable(JAWT_RENDERER_TEXTURE); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(-1.0, 1.0); - glTexCoord2f(width, 0); + glTexCoord2f(_width, 0); glVertex2f(1.0, 1.0); - glTexCoord2f(width, height); + glTexCoord2f(_width, _height); glVertex2f(1.0, -1.0); - glTexCoord2f(0, height); + glTexCoord2f(0, _height); glVertex2f(-1.0, -1.0); glEnd(); glDisable(JAWT_RENDERER_TEXTURE); } - - /* Draw the subrenderers of this JAWTRenderer. */ - if (subrenderers) - { - NSUInteger subrendererIndex = 0; - NSUInteger subrendererCount = [subrenderers count]; - CGLPixelFormatObj pixelFormat = 0; - for (; - subrendererIndex < subrendererCount; - subrendererIndex++) - { - JAWTRenderer *subrenderer - = [subrenderers objectAtIndex:subrendererIndex]; - - @synchronized (subrenderer) - { - GLfloat subrendererBoundsHeight; - GLfloat subrendererBoundsWidth; - - /* - * Make sure the subrenderer has an NSOpenGLContext - * which is compatible with glContext and shares its - * object state. - */ - if (!(subrenderer->glContext)) - { - if (!pixelFormat) - pixelFormat - = CGLGetPixelFormat([glContext CGLContextObj]); - [subrenderer copyCGLContext:glContext - forPixelFormat:pixelFormat]; - } - - subrendererBoundsHeight = subrenderer->boundsHeight; - subrendererBoundsWidth = subrenderer->boundsWidth; - if (subrenderer->texture - && (subrendererBoundsHeight > 0) - && (subrendererBoundsWidth > 0)) - { - GLfloat x_1 - = -1.0 + 2 * subrenderer->boundsX / boundsWidth; - GLfloat y1 - = 1 - 2 * subrenderer->boundsY / boundsHeight; - GLfloat x1 - = x_1 + 2 * subrendererBoundsWidth / boundsWidth; - GLfloat y_1 - = y1 - 2 * subrendererBoundsHeight / boundsHeight; - - glBindTexture( - JAWT_RENDERER_TEXTURE, - subrenderer->texture); - glEnable(JAWT_RENDERER_TEXTURE); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(x_1, y1); - glTexCoord2f(subrenderer->width, 0); - glVertex2f(x1, y1); - glTexCoord2f(subrenderer->width, subrenderer->height); - glVertex2f(x1, y_1); - glTexCoord2f(0, subrenderer->height); - glVertex2f(x_1, y_1); - glEnd(); - glDisable(JAWT_RENDERER_TEXTURE); - } - } - } - } + CGLUnlockContext(glContext); } - glFlush(); + [super drawInCGLContext:glContext + pixelFormat:pixelFormat + forLayerTime:timeInterval + displayTime:timeStamp]; } -- (void)removeFromSuperrenderer -{ - if (superrenderer) - [superrenderer removeSubrenderer:self]; - [self copyCGLContext:nil forPixelFormat:nil]; -} - -- (void)removeSubrenderer:(JAWTRenderer *)subrenderer -{ - @synchronized (self) - { - if (subrenderers) - { - NSUInteger index = [subrenderers indexOfObject:subrenderer]; - - if (NSNotFound != index) - [self removeSubrendererAtIndex:index]; - } - } -} - -- (void)removeSubrendererAtIndex:(NSUInteger)index -{ - @synchronized (self) - { - if (subrenderers) - { - JAWTRenderer *subrenderer = [subrenderers objectAtIndex:index]; - - [subrenderers removeObjectAtIndex:index]; - [subrenderer setSuperrenderer:nil]; - [subrenderer release]; - } - } -} - -- (void)reshape -{ - NSRect bounds; - - bounds = [view bounds]; - boundsHeight = bounds.size.height; - boundsWidth = bounds.size.width; - boundsX = bounds.origin.x; - boundsY = bounds.origin.y; - if ((bounds.size.width > 0) && (bounds.size.height > 0) && glContext) - { - [glContext makeCurrentContext]; - - glViewport( - bounds.origin.x, bounds.origin.y, - bounds.size.width, bounds.size.height); - } -} - -- (void)setSuperrenderer:(JAWTRenderer *)aSuperrenderer -{ - if (superrenderer != aSuperrenderer) - { - if (superrenderer) - [superrenderer release]; - - superrenderer = aSuperrenderer; - - if (superrenderer) - [superrenderer retain]; - } -} - -- (void)setView:(NSView *)aView +- (id)init { - if (view != aView) + if ((self = [super init])) { - if (view) + CGLPixelFormatAttribute attribs[] + = { kCGLPFAAccelerated, kCGLPFAWindow, 0 }; + GLint npix; + + _glContext = NULL; + _height = 0; + _pixelFormat = NULL; + _texture = 0; + _width = 0; + + if ((kCGLNoError == CGLChoosePixelFormat(attribs, &_pixelFormat, &npix)) + && (kCGLNoError + == CGLCreateContext(_pixelFormat, NULL, &_glContext))) { -#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER - NSNotificationCenter *notificationCenter; - - notificationCenter = [NSNotificationCenter defaultCenter]; - if (notificationCenter) - { - [notificationCenter - removeObserver:self - name:NSViewBoundsDidChangeNotification - object:view]; - [notificationCenter - removeObserver:self - name:NSViewFrameDidChangeNotification - object:view]; - } -#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */ - - [self copyCGLContext:nil forPixelFormat:0]; - - [view release]; + self.asynchronous = YES; + /* + * The AWT Canvas that corresponds to this CAOpenGLLayer will ensure + * that the latter will be displayed on bounds changes. + */ + self.needsDisplayOnBoundsChange = NO; } - - view = aView; - - if (view) + else { - NSOpenGLPixelFormatAttribute pixelFormatAttribs[] - = { NSOpenGLPFAWindow, 0 }; - NSOpenGLPixelFormat *pixelFormat; - -#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER - NSNotificationCenter *notificationCenter; -#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */ - - [view retain]; - - pixelFormat - = [[NSOpenGLPixelFormat alloc] - initWithAttributes:pixelFormatAttribs]; - if (pixelFormat) - { - glContext - = [[NSOpenGLContext alloc] initWithFormat:pixelFormat - shareContext:nil]; - if (glContext) - { - GLint surfaceOpacity; - GLint swapInterval; - - // prepareOpenGL - [glContext makeCurrentContext]; - - surfaceOpacity = 1; - [glContext setValues:&surfaceOpacity - forParameter:NSOpenGLCPSurfaceOpacity]; - swapInterval = 0; - [glContext setValues:&swapInterval - forParameter:NSOpenGLCPSwapInterval]; - - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_DITHER); - glDisable(GL_LIGHTING); - glDisable(GL_SCISSOR_TEST); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glDepthMask(GL_FALSE); - glStencilMask(0); - glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - } - [pixelFormat release]; - } - - if (glContext && ([glContext view] != view)) - [glContext setView:view]; - -#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER - notificationCenter = [NSNotificationCenter defaultCenter]; - if (notificationCenter) - { - [view setPostsBoundsChangedNotifications:YES]; - [notificationCenter - addObserver:self - selector:@selector(boundsDidChange:) - name:NSViewBoundsDidChangeNotification - object:view]; - [view setPostsFrameChangedNotifications:YES]; - [notificationCenter - addObserver:self - selector:@selector(frameDidChange:) - name:NSViewFrameDidChangeNotification - object:view]; - } -#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */ - - [self update]; + [self release]; + self = nil; } } + return self; } - -- (void)update -{ - NSRect frame; - - frame = [view frame]; - frameHeight = frame.size.height; - frameWidth = frame.size.width; - frameX = frame.origin.x; - frameY = frame.origin.y; - if (glContext) - [glContext update]; - - [self reshape]; -} -@end /* JAWTRenderer */ +@end /* JAWTRendererLayer */ diff --git a/src/native/jawtrenderer/JAWTRenderer_Windows.c b/src/native/jawtrenderer/JAWTRenderer_Windows.c new file mode 100644 index 00000000..bf161c0d --- /dev/null +++ b/src/native/jawtrenderer/JAWTRenderer_Windows.c @@ -0,0 +1,279 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +#include "JAWTRenderer.h" + +#include <d3d9.h> +#include <d3dx9tex.h> +#include <jawt_md.h> +#include <stdint.h> +#include <stdlib.h> + +typedef struct _JAWTRenderer +{ + LPDIRECT3D9 d3d; + LPDIRECT3DDEVICE9 device; + jint height; + HWND hwnd; + BOOL lost; + LPDIRECT3DSURFACE9 surface; + jint width; +} +JAWTRenderer; + +HRESULT _JAWTRenderer_createDevice(JAWTRenderer *thiz, jint width, jint height); + +void +JAWTRenderer_close(JNIEnv *env, jclass clazz, jlong handle, jobject component) +{ + JAWTRenderer *thiz = (JAWTRenderer *) (intptr_t) handle; + + if (thiz->surface) + IDirect3DSurface9_Release(thiz->surface); + if (thiz->device) + IDirect3DDevice9_Release(thiz->device); + IDirect3D9_Release(thiz->d3d); + free(thiz); +} + +jlong +JAWTRenderer_open(JNIEnv *env, jclass clazz, jobject component) +{ + LPDIRECT3D9 d3d = Direct3DCreate9(D3D_SDK_VERSION); + JAWTRenderer *thiz; + + if (d3d) + { + thiz = calloc(1, sizeof(JAWTRenderer)); + if (thiz) + thiz->d3d = d3d; + else + IDirect3D9_Release(d3d); + } + else + thiz = NULL; + return (jlong) (intptr_t) thiz; +} + +jboolean +JAWTRenderer_paint + (jint version, JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, + jobject g, jint zOrder) +{ + HDC hdc = ((JAWT_Win32DrawingSurfaceInfo *) (dsi->platformInfo))->hdc; + JAWTRenderer *thiz = (JAWTRenderer *) (intptr_t) handle; + + LPDIRECT3DDEVICE9 device = thiz->device; + HWND hwnd = WindowFromDC(hdc); + + if (device && (thiz->hwnd == hwnd)) + { + HRESULT hr; + + /* + * Check whether Direct3D considers the device of this JAWTRenderer + * functional/valid. + */ + hr = IDirect3DDevice9_TestCooperativeLevel(device); + if (SUCCEEDED(hr)) + { + /* + * If we do not have a Direct3D surface to present, we will make + * sure that the display is cleared. Otherwise, we do not have to + * clear it because we render complete frames in the whole viewport + * with transparency. + */ + BOOL clear = TRUE; + + /* Copy the Direct3D surface into the back buffer. */ + if (thiz->surface) + { + LPDIRECT3DSURFACE9 backBuffer; + + hr + = IDirect3DDevice9_GetBackBuffer( + device, + 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer); + if (SUCCEEDED(hr)) + { + hr = IDirect3DDevice9_BeginScene(device); + if (SUCCEEDED(hr)) + { + IDirect3DDevice9_UpdateSurface( + device, + thiz->surface, NULL, backBuffer, NULL); + IDirect3DDevice9_EndScene(device); + clear = FALSE; + } + IDirect3DSurface9_Release(backBuffer); + } + } + if (clear) + { + /* Clear the Direct3D back buffer. */ + IDirect3DDevice9_Clear( + device, + 0, + 0, + D3DCLEAR_TARGET, + D3DCOLOR_XRGB(0xff, 0xff, 0xff), + 0.0f, + 0); + } + + /* Present the Direct3D back buffer. */ + IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + } + else + thiz->lost = TRUE; + } + else + { + thiz->hwnd = hwnd; + thiz->lost = TRUE; + } + + return JNI_TRUE; +} + +jboolean +JAWTRenderer_process + (JNIEnv *env, jclass clazz, jlong handle, jobject component, jint *data, + jint length, jint width, jint height) +{ + JAWTRenderer *thiz = (JAWTRenderer *) (intptr_t) handle; + + if (!(thiz->device) + || (thiz->width != width) + || (thiz->height != height) + || thiz->lost) + { + /* + * Release the device and the surface if any because it appears we have + * to re-create them. + */ + thiz->lost = FALSE; + if (thiz->surface) + { + IDirect3DSurface9_Release(thiz->surface); + thiz->surface = NULL; + } + if (thiz->device) + { + IDirect3DDevice9_Release(thiz->device); + thiz->device = NULL; + } + + if (thiz->hwnd) + { + HRESULT hr; + + hr = _JAWTRenderer_createDevice(thiz, width, height); + if (SUCCEEDED(hr)) + { + hr + = IDirect3DDevice9_CreateOffscreenPlainSurface( + thiz->device, + width, + height, + D3DFMT_X8R8G8B8, + D3DPOOL_SYSTEMMEM, + &(thiz->surface), + NULL); + if (SUCCEEDED(hr)) + { + thiz->width = width; + thiz->height = height; + } + else + { + thiz->surface = NULL; + /* + * Well, we do not know why we would fail to create the + * surface but such a scenario seems grave enough to us to + * give up this JAWTRenderer. + */ + return JNI_FALSE; + } + } + /* + * If we failed to create the Direct3D device, we will try again + * next time in the hope that we will succeed eventually. + */ + } + } + + if (thiz->surface) + { + RECT rect; + + rect.bottom = height; + rect.left = 0; + rect.right = width; + rect.top = 0; + D3DXLoadSurfaceFromMemory( + thiz->surface, + NULL, + NULL, + data, + D3DFMT_A8R8G8B8, + width * 4, + NULL, + &rect, + D3DX_FILTER_NONE, + 0); + } + + return JNI_TRUE; +} + +HRESULT +_JAWTRenderer_createDevice(JAWTRenderer *thiz, jint width, jint height) +{ + D3DPRESENT_PARAMETERS params; + HRESULT hr; + + ZeroMemory(¶ms, sizeof(D3DPRESENT_PARAMETERS)); + + params.AutoDepthStencilFormat = D3DFMT_D16; + params.BackBufferCount = 1; + params.BackBufferFormat = D3DFMT_UNKNOWN; + params.BackBufferHeight = height; + params.BackBufferWidth = width; + params.EnableAutoDepthStencil = FALSE; + params.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + params.FullScreen_RefreshRateInHz = 0; + params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + params.SwapEffect = D3DSWAPEFFECT_DISCARD; + params.Windowed = TRUE; + + hr + = IDirect3D9_CheckDeviceMultiSampleType( + thiz->d3d, + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + params.BackBufferFormat, + params.Windowed, + D3DMULTISAMPLE_2_SAMPLES, + NULL); + params.MultiSampleQuality + = SUCCEEDED(hr) ? D3DMULTISAMPLE_2_SAMPLES : D3DMULTISAMPLE_NONE; + + hr + = IDirect3D9_CreateDevice( + thiz->d3d, + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + thiz->hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + ¶ms, + &(thiz->device)); + if (FAILED(hr)) + thiz->device = NULL; + + return hr; +} diff --git a/src/native/jawtrenderer/JAWTRenderer_Windows.cpp b/src/native/jawtrenderer/JAWTRenderer_Windows.cpp deleted file mode 100644 index e150d571..00000000 --- a/src/native/jawtrenderer/JAWTRenderer_Windows.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -#include "jawt_md.h" -#include "JAWTRenderer.h" - -#include "windows/d3d_context.h" -#include "windows/d3d_device.h" -#include "windows/d3d_surface.h" - -struct D3DBlitter -{ - D3DContext* d3d; - D3DDevice* device; - D3DSurface* surface; - HWND hwnd; - size_t width; - size_t height; - bool lost; -}; - -void JAWTRenderer_close - (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component) -{ - D3DBlitter* blitter = reinterpret_cast<D3DBlitter*>(handle); - - if(!blitter) - { - return; - } - - if(blitter->surface) - { - delete blitter->surface; - blitter->surface = NULL; - } - - if(blitter->device) - { - delete blitter->device; - blitter->device = NULL; - } - - if(blitter->d3d) - { - delete blitter->d3d; - blitter->d3d = NULL; - } - - delete blitter; -} - -jlong JAWTRenderer_open(JNIEnv *jniEnv, jclass clazz, jobject component) -{ - D3DBlitter* ret = new D3DBlitter(); - - ret->d3d = D3DContext::createD3DContext(); - ret->surface = NULL; - ret->device = NULL; - ret->width = 0; - ret->height = 0; - ret->lost = false; - - /* failed to initialize Direct3D */ - if(!ret->d3d) - { - delete ret; - ret = NULL; - } - - return (jlong)ret; -} - -jboolean JAWTRenderer_paint - (JAWT_DrawingSurfaceInfo *dsi, jclass clazz, jlong handle, jobject g) -{ - JAWT_Win32DrawingSurfaceInfo* dsi_win = - reinterpret_cast<JAWT_Win32DrawingSurfaceInfo*>(dsi->platformInfo); - D3DBlitter* blitter = reinterpret_cast<D3DBlitter*>(handle); - HWND hwnd = WindowFromDC(dsi_win->hdc); - - if(!blitter) - return JNI_FALSE; - - if(blitter->device == NULL || blitter->hwnd != hwnd) - { - blitter->hwnd = hwnd; - blitter->lost = true; - return JNI_TRUE; - } - - if(!blitter->device->validate()) - { - blitter->lost = true; - return JNI_TRUE; - } - - blitter->device->render(blitter->surface); - return JNI_TRUE; -} - -jboolean JAWTRenderer_process - (JNIEnv *jniEnv, jclass clazz, - jlong handle, jobject component, - jint *data, jint length, - jint width, jint height) -{ - D3DBlitter* blitter = reinterpret_cast<D3DBlitter*>(handle); - - if(!blitter) - { - return JNI_FALSE; - } - - if(!blitter->device || blitter->width != width || blitter->height != height - || blitter->lost) - { - D3DSurface* oldSurface = NULL; - D3DDevice* oldDevice = NULL; - - blitter->lost = false; - - /* size has changed, recreate our device and surface */ - if(blitter->surface) - { - delete blitter->surface; - blitter->surface = NULL; - } - - if(blitter->device) - { - delete blitter->device; - blitter->device = NULL; - } - - if(blitter->hwnd == NULL) - { - return JNI_TRUE; - } - - blitter->device = blitter->d3d->createDevice(blitter->hwnd, width, - height); - - if(!blitter->device) - { - /* device creation failed */ - - blitter->surface = NULL; - /* maybe we go fullscreen and/or hwnd of the window has changed - * so we return true to force native method to be called and so - * update blitter->hwnd for the next call - */ - return JNI_TRUE; - } - - blitter->surface = blitter->device->createSurface(width, height); - - if(!blitter->surface) - { - return JNI_FALSE; - } - - blitter->width = width; - blitter->height = height; - } - - if(blitter->surface) - { - blitter->surface->loadData(reinterpret_cast<char*>(data), - width, height); - } - return JNI_TRUE; -} - diff --git a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c index 46592300..236350e2 100644 --- a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c +++ b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.c @@ -8,45 +8,57 @@ #include "org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h" #include "JAWTRenderer.h" -JNIEXPORT void JNICALL -Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_addNotifyLightweightComponent - (JNIEnv *jniEnv, jclass clazz, - jlong handle, jobject component, - jlong parentHandle) -{ -#ifdef __APPLE__ - JAWTRenderer_addNotifyLightweightComponent(handle, component, parentHandle); -#endif /* #ifdef __APPLE__ */ -} - JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_close - (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component) + (JNIEnv *env, jclass clazz, jlong handle, jobject component) { - JAWTRenderer_close(jniEnv, clazz, handle, component); + JAWTRenderer_close(env, clazz, handle, component); } JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_open - (JNIEnv *jniEnv, jclass clazz, jobject component) + (JNIEnv *env, jclass clazz, jobject component) { - return JAWTRenderer_open(jniEnv, clazz, component); + return JAWTRenderer_open(env, clazz, component); } JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint - (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component, jobject g) + (JNIEnv *env, jclass clazz, jlong handle, jobject component, jobject g, + jint zOrder) { JAWT awt; + jboolean awtIsAvailable; jboolean wantsPaint; - awt.version = JAWT_VERSION_1_3; + awt.version = JAWT_VERSION_1_4; +#ifdef __APPLE__ +#ifndef JAWT_MACOSX_USE_CALAYER +#define JAWT_MACOSX_USE_CALAYER 0x80000000 +#endif /* #ifndef JAWT_MACOSX_USE_CALAYER */ + + awt.version |= JAWT_MACOSX_USE_CALAYER; + awtIsAvailable = JAWT_GetAWT(env, &awt); + /* + * We do not know whether JAWT_GetAWT will fail when JAWT_MACOSX_USE_CALAYER + * is specified and not supported or it will rather remove the flag from the + * version field of JAWT. That's why we will call the function in question + * again in case of failure with the flag removed. + */ + if (JNI_FALSE == awtIsAvailable) + { + awt.version &= ~JAWT_MACOSX_USE_CALAYER; + awtIsAvailable = JAWT_GetAWT(env, &awt); + } +#else /* #ifdef __APPLE__ */ + awtIsAvailable = JAWT_GetAWT(env, &awt); +#endif /* #ifdef __APPLE__ */ wantsPaint = JNI_TRUE; - if (JAWT_GetAWT(jniEnv, &awt) != JNI_FALSE) + if (JNI_TRUE == awtIsAvailable) { JAWT_DrawingSurface *ds; - ds = awt.GetDrawingSurface(jniEnv, component); + ds = awt.GetDrawingSurface(env, component); if (ds) { jint dsLock; @@ -60,12 +72,19 @@ Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint if (dsi && dsi->platformInfo) { /* - * The function arguments jniEnv and component are now + * The function arguments env and component are now * available as the fields env and target, respectively, of * the JAWT_DrawingSurface which is itself the value of the * field ds of the JAWT_DrawingSurfaceInfo. */ - wantsPaint = JAWTRenderer_paint(dsi, clazz, handle, g); + wantsPaint + = JAWTRenderer_paint( + awt.version, + dsi, + clazz, + handle, + g, + zOrder); ds->FreeDrawingSurfaceInfo(dsi); } ds->Unlock(ds); @@ -76,45 +95,25 @@ Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint return wantsPaint; } -JNIEXPORT jboolean JNICALL -Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paintLightweightComponent - (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component, jobject g) -{ - jboolean wantsPaint; - -#ifdef __APPLE__ - wantsPaint = JAWTRenderer_paintLightweightComponent(handle, component, g); -#else /* #ifdef __APPLE__ */ - /* - * There is really no point in delivering any paint events/notifications - * because there is no implementation. - */ - wantsPaint = JNI_FALSE; -#endif /* #ifdef __APPLE__ */ - return wantsPaint; -} - JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_process - (JNIEnv *jniEnv, jclass clazz, - jlong handle, jobject component, - jintArray data, jint offset, jint length, - jint width, jint height) + (JNIEnv *env, jclass clazz, jlong handle, jobject component, jintArray data, + jint offset, jint length, jint width, jint height) { jint *dataPtr; jboolean processed; - dataPtr = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, data, NULL); + dataPtr = (*env)->GetPrimitiveArrayCritical(env, data, NULL); if (dataPtr) { processed = JAWTRenderer_process( - jniEnv, clazz, + env, clazz, handle, component, dataPtr + offset, length, width, height); - (*jniEnv)->ReleasePrimitiveArrayCritical( - jniEnv, + (*env)->ReleasePrimitiveArrayCritical( + env, data, dataPtr, JNI_ABORT); } @@ -123,32 +122,12 @@ Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_process return processed; } -JNIEXPORT void JNICALL -Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_processLightweightComponentEvent - (JNIEnv *jniEnv, jclass clazz, - jlong handle, - jint x, jint y, jint width, jint height) -{ -#ifdef __APPLE__ - JAWTRenderer_processLightweightComponentEvent(handle, x, y, width, height); -#endif /* #ifdef __APPLE__ */ -} - -JNIEXPORT void JNICALL -Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_removeNotifyLightweightComponent - (JNIEnv *jniEnv, jclass clazz, jlong handle, jobject component) -{ -#ifdef __APPLE__ - JAWTRenderer_removeNotifyLightweightComponent(handle, component); -#endif /* #ifdef __APPLE__ */ -} - JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_sysctlbyname - (JNIEnv *jniEnv, jclass clazz, jstring name) + (JNIEnv *env, jclass clazz, jstring name) { #ifdef __APPLE__ - return JAWTRenderer_sysctlbyname(jniEnv, name); + return JAWTRenderer_sysctlbyname(env, name); #else /* #ifdef __APPLE__ */ return NULL; #endif /* #ifdef __APPLE__ */ diff --git a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h index a2508d2d..29d983bb 100644 --- a/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h +++ b/src/native/jawtrenderer/org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer.h @@ -7,14 +7,6 @@ #ifdef __cplusplus extern "C" { #endif -/* - * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer - * Method: addNotifyLightweightComponent - * Signature: (JLjava/awt/Component;J)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_addNotifyLightweightComponent - (JNIEnv *, jclass, jlong, jobject, jlong); - /* * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer * Method: close @@ -34,18 +26,10 @@ JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video /* * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer * Method: paint - * Signature: (JLjava/awt/Component;Ljava/awt/Graphics;)Z + * Signature: (JLjava/awt/Component;Ljava/awt/Graphics;I)Z */ JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paint - (JNIEnv *, jclass, jlong, jobject, jobject); - -/* - * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer - * Method: paintLightweightComponent - * Signature: (JLjava/awt/Component;Ljava/awt/Graphics;)Z - */ -JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_paintLightweightComponent - (JNIEnv *, jclass, jlong, jobject, jobject); + (JNIEnv *, jclass, jlong, jobject, jobject, jint); /* * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer @@ -55,22 +39,6 @@ JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_vi JNIEXPORT jboolean JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_process (JNIEnv *, jclass, jlong, jobject, jintArray, jint, jint, jint, jint); -/* - * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer - * Method: processLightweightComponentEvent - * Signature: (JIIII)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_processLightweightComponentEvent - (JNIEnv *, jclass, jlong, jint, jint, jint, jint); - -/* - * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer - * Method: removeNotifyLightweightComponent - * Signature: (JLjava/awt/Component;)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer_removeNotifyLightweightComponent - (JNIEnv *, jclass, jlong, jobject); - /* * Class: org_jitsi_impl_neomedia_jmfext_media_renderer_video_JAWTRenderer * Method: sysctlbyname diff --git a/src/native/jawtrenderer/windows/d3d_context.cpp b/src/native/jawtrenderer/windows/d3d_context.cpp deleted file mode 100644 index 218d9e91..00000000 --- a/src/native/jawtrenderer/windows/d3d_context.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/** - * \file d3d_context.cpp - * \brief Direct3D context. - * \author Sebastien Vincent - * \date 2010 - */ - -#include "d3d_context.h" - -D3DContext* D3DContext::createD3DContext() -{ - D3DContext* ret = new D3DContext(); - - if(ret->getDirect3D()) - { - return ret; - } - else - { - /* fail to initialize Direct3D */ - delete ret; - return NULL; - } -} - -D3DContext::D3DContext() -{ - m_d3d = Direct3DCreate9(D3D_SDK_VERSION); -} - -D3DContext::~D3DContext() -{ - if(m_d3d) - { - m_d3d->Release(); - m_d3d = NULL; - } -} - -LPDIRECT3D9 D3DContext::getDirect3D() const -{ - return m_d3d; -} - -D3DDevice* D3DContext::createDevice(HWND hwnd, size_t width, size_t height) -{ - D3DDevice* ret = NULL; - - ret = new D3DDevice(hwnd, getDirect3D(), width, height, false); - if(ret->getDevice()) - { - return ret; - } - else - { - /* problem to create Direct3D device */ - delete ret; - return NULL; - } -} - diff --git a/src/native/jawtrenderer/windows/d3d_context.h b/src/native/jawtrenderer/windows/d3d_context.h deleted file mode 100644 index 36a044bb..00000000 --- a/src/native/jawtrenderer/windows/d3d_context.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/** - * \file d3d_context.h - * \brief Direct3D context. - * \author Sebastien Vincent - * \date 2010 - */ - -#ifndef D3D_CONTEXT_H -#define D3D_CONTEXT_H - -#include <cstdlib> - -#include <d3d9.h> -#include <d3dx9.h> - -#include "d3d_device.h" - -/** - * \class D3DContext - * \brief Direct3D context. - */ -class D3DContext -{ - public: - /** - * \briefCreate a Direct3D context. - * \return Direct3D context pointer or NULL if failed - */ - static D3DContext* createD3DContext(); - - /** - * \brief Constructor. - */ - D3DContext(); - - /** - * \brief Destructor. - */ - ~D3DContext(); - - /** - * \brief Get raw Direct3D context pointer. - * \return Direct3D - */ - LPDIRECT3D9 getDirect3D() const; - - /** - * \brief Create Direct3D device. - * \param hwnd handle of a window - * \param width width of the device - * \param height height of the device - * \return Direct3D device - */ - D3DDevice* createDevice(HWND hwnd, size_t width, size_t height); - - private: - /** - * \brief Direct3D context pointer. - */ - LPDIRECT3D9 m_d3d; -}; - -#endif /* D3D_CONTEXT_H */ - diff --git a/src/native/jawtrenderer/windows/d3d_device.cpp b/src/native/jawtrenderer/windows/d3d_device.cpp deleted file mode 100644 index 45b981c2..00000000 --- a/src/native/jawtrenderer/windows/d3d_device.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/** - * \file d3d_device.cpp - * \brief Direct3D device. - * \author Sebastien Vincent - * \date 2010 - */ - -#include "d3d_device.h" - -D3DDevice::D3DDevice(HWND hwnd, LPDIRECT3D9 d3d, size_t width, size_t height, - bool fullscreen) -{ - HRESULT ret = 0; - D3DPRESENT_PARAMETERS settings; - D3DDISPLAYMODE dmode; - - ZeroMemory(&settings, sizeof(D3DPRESENT_PARAMETERS)); - - ret = d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dmode); - if(FAILED(ret)) - { - return; - } - - settings.BackBufferWidth = width; - settings.BackBufferHeight = height; - settings.BackBufferFormat = fullscreen ? dmode.Format : D3DFMT_UNKNOWN; - settings.BackBufferCount = 1; - //settings.hDeviceWindow = hwnd; - settings.Windowed = !fullscreen; - settings.SwapEffect = D3DSWAPEFFECT_DISCARD; - - if(SUCCEEDED(d3d->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, settings.BackBufferFormat, !fullscreen, - D3DMULTISAMPLE_2_SAMPLES, NULL))) - { - settings.MultiSampleQuality = D3DMULTISAMPLE_2_SAMPLES; - } - else - { - settings.MultiSampleQuality = D3DMULTISAMPLE_NONE; - } - - settings.EnableAutoDepthStencil = false; - settings.AutoDepthStencilFormat = D3DFMT_D16; - settings.FullScreen_RefreshRateInHz = 0; - settings.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //0; - settings.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; - - ret = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, - D3DCREATE_SOFTWARE_VERTEXPROCESSING, &settings, &m_device); - - if(FAILED(ret)) - { - m_device = NULL; - /* TODO */ - return; - } - - /* copy settings */ - memcpy(&m_settings, &settings, sizeof(settings)); -} - -D3DDevice::~D3DDevice() -{ - if(m_backSurface) - { - //m_backSurface->Release(); - } - - if(m_device) - { - m_device->Release(); - m_device = NULL; - } -} - -LPDIRECT3DDEVICE9 D3DDevice::getDevice() const -{ - return m_device; -} - -bool D3DDevice::validate() -{ - HRESULT ret = 0; - - ret = m_device->TestCooperativeLevel(); - - if(FAILED(ret)) - { - /* device is lost (window not shown) */ - if(ret == D3DERR_DEVICELOST) - { - return false; - } - - /* ready to reset */ - if(ret == D3DERR_DEVICENOTRESET) - { - /* XXX in this case we simply delete and recreate device since - * it always failed to Reset in JAWT but not in pure Windows - * binary - */ - -#if 0 - if(m_backSurface) - { - m_backSurface->Release(); - m_backSurface = NULL; - } - - ret = m_device->Reset(&m_settings); - - if(FAILED(ret)) - { - return false; - } - - ret = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, - &m_backSurface); - - if(FAILED(ret)) - { - return false; - } -#endif - } - } - return true; -} - -D3DSurface* D3DDevice::createSurface(size_t width, size_t height) -{ - D3DSurface* ret = NULL; - - ret = new D3DSurface(getDevice(), width, height); - - if(ret->getSurface()) - { - return ret; - } - else - { - /* problem allocating surface */ - delete ret; - return NULL; - } -} - -void D3DDevice::render(D3DSurface* surface) -{ - HRESULT ret = 0; - LPDIRECT3DSURFACE9 surfacePointer = surface->getSurface(); - - if(!surfacePointer) - { - return; - } - - /* clear the back buffer */ - m_device->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0xff, 0xff, 0xff), - 0.0f, 0); - - /* Get the back buffer */ - ret = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, - &m_backSurface); - if(FAILED(ret)) - { - return; - } - - ret = m_device->BeginScene(); - if(FAILED(ret)) - { - return; - } - - /* copy content on surface */ - m_device->UpdateSurface(surfacePointer, NULL, m_backSurface, NULL); - - /* finish scene and cleanup */ - m_device->EndScene(); - m_backSurface->Release(); - m_backSurface = NULL; - - /* present the back buffer to the display adapter to be drawn */ - m_device->Present(NULL, NULL, NULL, NULL); -} - diff --git a/src/native/jawtrenderer/windows/d3d_device.h b/src/native/jawtrenderer/windows/d3d_device.h deleted file mode 100644 index 61a191cf..00000000 --- a/src/native/jawtrenderer/windows/d3d_device.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/** - * \file d3d_device.h - * \brief Direct3D device. - * \author Sebastien Vincent - * \date 2010 - */ - -#ifndef D3D_DEVICE_H -#define D3D_DEVICE_H - -#include <cstdlib> - -#include <d3d9.h> -#include <d3dx9.h> - -#include "d3d_surface.h" - -/** - * \class D3DDevice - * \brief Direct3D device. - * - * It is used to render contents on screen. - */ -class D3DDevice -{ - public: - /** - * \brief Constructor. - * \param hwnd Handle of the Window - * \param d3d raw Direct3D context - * \param width width of the future device - * \param height height of the future device - * \param fullscreen create device for fullscreen mode - */ - D3DDevice(HWND hwnd, LPDIRECT3D9 d3d, size_t width, size_t height, bool fullscreen); - - /** - * \brief Destructor. - */ - ~D3DDevice(); - - /** - * \brief Get raw Direct3D device pointer. - * \return Direct3D device pointer - */ - LPDIRECT3DDEVICE9 getDevice() const; - - /** - * \brief Validate the device. - * \return true if validation succeed, false otherwise - */ - bool validate(); - - /** - * \brief Create a surface. - * \param width width of the surface - * \param height height of the surface - * \return surface or NULL if problem - */ - D3DSurface* createSurface(size_t width, size_t height); - - /** - * \brief Render a surface on the screen. - * \param surface surface to render on the screen - */ - void render(D3DSurface* surface); - - private: - /** - * \brief Raw Direct3D device. - */ - LPDIRECT3DDEVICE9 m_device; - - /** - * \brief Settings of the device. - */ - D3DPRESENT_PARAMETERS m_settings; - - /** - * \brief Back surface. - */ - LPDIRECT3DSURFACE9 m_backSurface; - - /** - * \brief Width of the device. - */ - size_t m_width; - - /** - * \brief Height of the device. - */ - size_t m_height; -}; - -#endif /* D3D_DEVICE_H */ - diff --git a/src/native/jawtrenderer/windows/d3d_surface.cpp b/src/native/jawtrenderer/windows/d3d_surface.cpp deleted file mode 100644 index c892e02e..00000000 --- a/src/native/jawtrenderer/windows/d3d_surface.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/** - * \file d3d_surface.cpp - * \brief Direct3D surface. - * \author Sebastien Vincent - * \date 2010 - */ - -#include "d3d_surface.h" -#include "d3dx9_utils.h" - -D3DSurface::D3DSurface(LPDIRECT3DDEVICE9 device, size_t width, size_t height) -{ - HRESULT ret = device->CreateOffscreenPlainSurface(width, height, - D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &m_surface, NULL); - - if(FAILED(ret)) - { - m_surface = NULL; - return; - } - - m_width = width; - m_height = height; -} - -D3DSurface::~D3DSurface() -{ - if(m_surface) - { - m_surface->Release(); - m_surface = NULL; - } -} - -LPDIRECT3DSURFACE9 D3DSurface::getSurface() const -{ - return m_surface; -} - -size_t D3DSurface::getWidth() -{ - return m_width; -} - -size_t D3DSurface::getHeight() -{ - return m_height; -} - -bool D3DSurface::loadData(char *data, size_t width, size_t height) -{ - HRESULT ret = 0; - RECT rect; - - rect.left = 0; - rect.top = 0; - rect.right = width; - rect.bottom = height; - - if(!m_surface) - { - return false; - } - - /* load image from memory */ - ret = D3DXLoadSurfaceFromMemory(m_surface, NULL, NULL, data, - D3DFMT_A8R8G8B8, width * 4, NULL, &rect, D3DX_FILTER_NONE, NULL); - return !FAILED(ret); -} - diff --git a/src/native/jawtrenderer/windows/d3d_surface.h b/src/native/jawtrenderer/windows/d3d_surface.h deleted file mode 100644 index b9074f78..00000000 --- a/src/native/jawtrenderer/windows/d3d_surface.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/** - * \file d3d_surface.h - * \brief Direct3D surface. - * \author Sebastien Vincent - * \date 2010 - */ - -#ifndef D3D_SURFACE_H -#define D3D_SURFACE_H - -#include <cstdlib> - -#include <d3d9.h> -#include <d3dx9.h> - -class D3DDevice; - -/** - * \class D3DSurface - * \brief Direct3D surface. - */ -class D3DSurface -{ - public: - /** - * \brief Constructor. - * \param device device that will create surface - * \param width width of the surface - * \param height height of the surface - */ - D3DSurface(LPDIRECT3DDEVICE9 device, size_t width, size_t height); - - /** - * \brief Destructor. - */ - ~D3DSurface(); - - /** - * \brief Get raw pointer of Direct3D surface. - * \return Direct3D surface. - */ - LPDIRECT3DSURFACE9 getSurface() const; - - /** - * \brief Load data into surface. - * \param data array of bytes - * \param width width of image - * \param height height of image - * \return true if data is loaded, false otherwise - */ - bool loadData(char* data, size_t width, size_t height); - - /** - * \brief Get surface width. - * \return surface width - */ - size_t getWidth(); - - /** - * \brief Get surface height. - * \return surface height - */ - size_t getHeight(); - - private: - /** - * \brief Raw Direct3D surface. - */ - LPDIRECT3DSURFACE9 m_surface; - - /** - * \brief Width of surface. - */ - size_t m_width; - - /** - * \brief Height of surface. - */ - size_t m_height; -}; - -#endif /* D3D_SURFACE_H */ - diff --git a/src/native/jawtrenderer/windows/d3dx9_utils.c b/src/native/jawtrenderer/windows/d3dx9_utils.c deleted file mode 100644 index d974f5ee..00000000 --- a/src/native/jawtrenderer/windows/d3dx9_utils.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/* - * Copyright (C) 2009 Tony Wasserka - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -/** - * \file d3dx9_utils.c - * \brief DirectX functions implementation coming from Wine project. - * \author Wine project - */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <d3d9.h> -#include <d3dx9.h> - -#ifdef __cplusplus -extern "C" { /* } */ -#endif - -/* Following structures and functions functions comes from the Wine project. - * There are used to avoid linking to d3dx9_xx.dll since this DLL cannot be - * redistributed directly (it must be installed using DirectXSetup). - */ - -typedef enum _FormatType -{ - FORMAT_ARGB, /* unsigned */ - FORMAT_UNKNOWN - -} FormatType; - -typedef struct _PixelFormatDesc -{ - D3DFORMAT format; - BYTE bits[4]; - BYTE shift[4]; - UINT bytes_per_pixel; - FormatType type; -} PixelFormatDesc; - -/************************************************************ - * pixel format table providing info about number of bytes per pixel, - * number of bits per channel and format type. - * - * Call get_format_info to request information about a specific format. - */ -static const PixelFormatDesc formats[] = -{ - /* format bits per channel shifts per channel bpp type */ - { D3DFMT_R8G8B8, { 0, 8, 8, 8 }, { 0, 16, 8, 0 }, 3, FORMAT_ARGB }, - { D3DFMT_A8R8G8B8, { 8, 8, 8, 8 }, { 24, 16, 8, 0 }, 4, FORMAT_ARGB }, - { D3DFMT_X8R8G8B8, { 0, 8, 8, 8 }, { 0, 16, 8, 0 }, 4, FORMAT_ARGB }, - { D3DFMT_A8B8G8R8, { 8, 8, 8, 8 }, { 24, 0, 8, 16 }, 4, FORMAT_ARGB }, - { D3DFMT_X8B8G8R8, { 0, 8, 8, 8 }, { 0, 0, 8, 16 }, 4, FORMAT_ARGB }, - { D3DFMT_R5G6B5, { 0, 5, 6, 5 }, { 0, 11, 5, 0 }, 2, FORMAT_ARGB }, - { D3DFMT_X1R5G5B5, { 0, 5, 5, 5 }, { 0, 10, 5, 0 }, 2, FORMAT_ARGB }, - { D3DFMT_A1R5G5B5, { 1, 5, 5, 5 }, { 15, 10, 5, 0 }, 2, FORMAT_ARGB }, - { D3DFMT_R3G3B2, { 0, 3, 3, 2 }, { 0, 5, 2, 0 }, 1, FORMAT_ARGB }, - { D3DFMT_A8R3G3B2, { 8, 3, 3, 2 }, { 8, 5, 2, 0 }, 2, FORMAT_ARGB }, - { D3DFMT_A4R4G4B4, { 4, 4, 4, 4 }, { 12, 8, 4, 0 }, 2, FORMAT_ARGB }, - { D3DFMT_X4R4G4B4, { 0, 4, 4, 4 }, { 0, 8, 4, 0 }, 2, FORMAT_ARGB }, - { D3DFMT_A2R10G10B10, { 2, 10, 10, 10 }, { 30, 20, 10, 0 }, 4, FORMAT_ARGB }, - { D3DFMT_A2B10G10R10, { 2, 10, 10, 10 }, { 30, 0, 10, 20 }, 4, FORMAT_ARGB }, - { D3DFMT_G16R16, { 0, 16, 16, 0 }, { 0, 0, 16, 0 }, 4, FORMAT_ARGB }, - { D3DFMT_A8, { 8, 0, 0, 0 }, { 0, 0, 0, 0 }, 1, FORMAT_ARGB }, - { D3DFMT_UNKNOWN, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, FORMAT_UNKNOWN }, /* marks last element */ -}; - -/************************************************************ - * get_format_info - * - * Returns information about the specified format. - * If the format is unsupported, it's filled with the D3DFMT_UNKNOWN desc. - * - * PARAMS - * format [I] format whose description is queried - * desc [O] pointer to a StaticPixelFormatDesc structure - * - */ -const PixelFormatDesc *get_format_info(D3DFORMAT format) -{ - unsigned int i = 0; - while(formats[i].format != format && formats[i].format != D3DFMT_UNKNOWN) i++; - return &formats[i]; -} - -/************************************************************ - * copy_simple_data - * - * Copies the source buffer to the destination buffer, performing - * any necessary format conversion and color keying. - * Works only for ARGB formats with 1 - 4 bytes per pixel. - */ -static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize, CONST PixelFormatDesc *srcformat, - CONST BYTE *dest, UINT destpitch, POINT destsize, CONST PixelFormatDesc *destformat, - DWORD dwFilter) -{ - DWORD srcshift[4], destshift[4]; - DWORD srcmask[4], destmask[4]; - BOOL process_channel[4]; - DWORD channels[4]; - DWORD channelmask = 0; - - UINT minwidth, minheight; - BYTE *srcptr, *destptr; - UINT i, x, y; - - ZeroMemory(channels, sizeof(channels)); - ZeroMemory(process_channel, sizeof(process_channel)); - - for(i = 0;i < 4;i++) { - /* srcshift is used to extract the _relevant_ components */ - srcshift[i] = srcformat->shift[i] + max( srcformat->bits[i] - destformat->bits[i], 0); - - /* destshift is used to move the components to the correct position */ - destshift[i] = destformat->shift[i] + max(destformat->bits[i] - srcformat->bits[i], 0); - - srcmask[i] = ((1 << srcformat->bits[i]) - 1) << srcformat->shift[i]; - destmask[i] = ((1 << destformat->bits[i]) - 1) << destformat->shift[i]; - - /* channelmask specifies bits which aren't used in the source format but in the destination one */ - if(destformat->bits[i]) { - if(srcformat->bits[i]) process_channel[i] = TRUE; - else channelmask |= destmask[i]; - } - } - - minwidth = (srcsize.x < destsize.x) ? srcsize.x : destsize.x; - minheight = (srcsize.y < destsize.y) ? srcsize.y : destsize.y; - - for(y = 0;y < minheight;y++) { - srcptr = (BYTE*)( src + y * srcpitch); - destptr = (BYTE*)(dest + y * destpitch); - for(x = 0;x < minwidth;x++) { - /* extract source color components */ - if(srcformat->type == FORMAT_ARGB) { - const DWORD col = *(DWORD*)srcptr; - for(i = 0;i < 4;i++) - if(process_channel[i]) - channels[i] = (col & srcmask[i]) >> srcshift[i]; - } - - /* recombine the components */ - if(destformat->type == FORMAT_ARGB) { - DWORD* const pixel = (DWORD*)destptr; - *pixel = 0; - - for(i = 0;i < 4;i++) { - if(process_channel[i]) { - /* necessary to make sure that e.g. an X4R4G4B4 white maps to an R8G8B8 white instead of 0xf0f0f0 */ - signed int shift; - for(shift = destshift[i]; shift > destformat->shift[i]; shift -= srcformat->bits[i]) *pixel |= channels[i] << shift; - *pixel |= (channels[i] >> (destformat->shift[i] - shift)) << destformat->shift[i]; - } - } - *pixel |= channelmask; /* new channels are set to their maximal value */ - } - srcptr += srcformat->bytes_per_pixel; - destptr += destformat->bytes_per_pixel; - } - } -} - -/************************************************************ - * D3DXLoadSurfaceFromMemory - * - * Loads data from a given memory chunk into a surface, - * applying any of the specified filters. - * - * PARAMS - * pDestSurface [I] pointer to the surface - * pDestPalette [I] palette to use - * pDestRect [I] to be filled area of the surface - * pSrcMemory [I] pointer to the source data - * SrcFormat [I] format of the source pixel data - * SrcPitch [I] number of bytes in a row - * pSrcPalette [I] palette used in the source image - * pSrcRect [I] area of the source data to load - * dwFilter [I] filter to apply on stretching - * Colorkey [I] colorkey - * - * RETURNS - * Success: D3D_OK, if we successfully load the pixel data into our surface or - * if pSrcMemory is NULL but the other parameters are valid - * Failure: D3DERR_INVALIDCALL, if pDestSurface, SrcPitch or pSrcRect are NULL or - * if SrcFormat is an invalid format (other than D3DFMT_UNKNOWN) - * D3DXERR_INVALIDDATA, if we fail to lock pDestSurface - * E_FAIL, if SrcFormat is D3DFMT_UNKNOWN or the dimensions of pSrcRect are invalid - * - * NOTES - * pSrcRect specifies the dimensions of the source data; - * negative values for pSrcRect are allowed as we're only looking at the width and height anyway. - * - */ -HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface, - CONST PALETTEENTRY *pDestPalette, - CONST RECT *pDestRect, - LPCVOID pSrcMemory, - D3DFORMAT SrcFormat, - UINT SrcPitch, - CONST PALETTEENTRY *pSrcPalette, - CONST RECT *pSrcRect, - DWORD dwFilter, - D3DCOLOR Colorkey) -{ - CONST PixelFormatDesc *srcformatdesc, *destformatdesc; - D3DSURFACE_DESC surfdesc; - D3DLOCKED_RECT lockrect; - POINT srcsize, destsize; - HRESULT hr; - - //TRACE("(%p, %p, %p, %p, %x, %u, %p, %p %u, %#x)\n", pDestSurface, pDestPalette, pDestRect, pSrcMemory, - // SrcFormat, SrcPitch, pSrcPalette, pSrcRect, dwFilter, Colorkey); - - if( !pDestSurface || !pSrcMemory || !pSrcRect ) return D3DERR_INVALIDCALL; - if(SrcFormat == D3DFMT_UNKNOWN || pSrcRect->left >= pSrcRect->right || pSrcRect->top >= pSrcRect->bottom) return E_FAIL; - - if(dwFilter != D3DX_FILTER_NONE) return E_NOTIMPL; - - IDirect3DSurface9_GetDesc(pDestSurface, &surfdesc); - - srcformatdesc = get_format_info(SrcFormat); - destformatdesc = get_format_info(surfdesc.Format); - if( srcformatdesc->type == FORMAT_UNKNOWN || srcformatdesc->bytes_per_pixel > 4) return E_NOTIMPL; - if(destformatdesc->type == FORMAT_UNKNOWN || destformatdesc->bytes_per_pixel > 4) return E_NOTIMPL; - - srcsize.x = pSrcRect->right - pSrcRect->left; - srcsize.y = pSrcRect->bottom - pSrcRect->top; - if( !pDestRect ) { - destsize.x = surfdesc.Width; - destsize.y = surfdesc.Height; - } else { - destsize.x = pDestRect->right - pDestRect->left; - destsize.y = pDestRect->bottom - pDestRect->top; - } - - hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0); - if(FAILED(hr)) return D3DXERR_INVALIDDATA; - - copy_simple_data((CONST BYTE*)pSrcMemory, SrcPitch, srcsize, srcformatdesc, - (CONST BYTE*)lockrect.pBits, lockrect.Pitch, destsize, destformatdesc, - dwFilter); - - IDirect3DSurface9_UnlockRect(pDestSurface); - return D3D_OK; -} - -#ifdef __cplusplus -} -#endif - diff --git a/src/native/jawtrenderer/windows/d3dx9_utils.h b/src/native/jawtrenderer/windows/d3dx9_utils.h deleted file mode 100644 index d49457da..00000000 --- a/src/native/jawtrenderer/windows/d3dx9_utils.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/* - * Copyright (C) 2009 Tony Wasserka - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -/** - * \file d3dx9_utils.h - * \brief DirectX functions implementation coming from Wine project. - * \author Wine project - */ - -#ifdef __cplusplus -extern "C" { /* } */ -#endif - -/************************************************************ - * D3DXLoadSurfaceFromMemory - * - * Loads data from a given memory chunk into a surface, - * applying any of the specified filters. - * - * PARAMS - * pDestSurface [I] pointer to the surface - * pDestPalette [I] palette to use - * pDestRect [I] to be filled area of the surface - * pSrcMemory [I] pointer to the source data - * SrcFormat [I] format of the source pixel data - * SrcPitch [I] number of bytes in a row - * pSrcPalette [I] palette used in the source image - * pSrcRect [I] area of the source data to load - * dwFilter [I] filter to apply on stretching - * Colorkey [I] colorkey - * - * RETURNS - * Success: D3D_OK, if we successfully load the pixel data into our surface or - * if pSrcMemory is NULL but the other parameters are valid - * Failure: D3DERR_INVALIDCALL, if pDestSurface, SrcPitch or pSrcRect are NULL or - * if SrcFormat is an invalid format (other than D3DFMT_UNKNOWN) - * D3DXERR_INVALIDDATA, if we fail to lock pDestSurface - * E_FAIL, if SrcFormat is D3DFMT_UNKNOWN or the dimensions of pSrcRect are invalid - * - * NOTES - * pSrcRect specifies the dimensions of the source data; - * negative values for pSrcRect are allowed as we're only looking at the width and height anyway. - * - */ -HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface, - CONST PALETTEENTRY *pDestPalette, - CONST RECT *pDestRect, - LPCVOID pSrcMemory, - D3DFORMAT SrcFormat, - UINT SrcPitch, - CONST PALETTEENTRY *pSrcPalette, - CONST RECT *pSrcRect, - DWORD dwFilter, - D3DCOLOR Colorkey); - -#ifdef __cplusplus -} -#endif - diff --git a/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java b/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java index 26f6d179..dafadd8b 100644 --- a/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java +++ b/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java @@ -35,7 +35,7 @@ public class AudioMediaStreamImpl extends MediaStreamImpl implements AudioMediaStream, - PropertyChangeListener + PropertyChangeListener { /** @@ -73,21 +73,22 @@ public class AudioMediaStreamImpl = Logger.getLogger(AudioMediaStreamImpl.class); /** - * A property change notifier which will inform this stream if a selected - * audio device (capture, playback or notification device) has changed. We - * want to listen to these events, especially for those generated after the - * audio system has changed. + * A <tt>PropertyChangeNotifier<tt> which will inform this + * <tt>AudioStream</tt> if a selected audio device (capture, playback or + * notification device) has changed. We want to listen to these events, + * especially for those generated after the <tt>AudioSystem</tt> has + * changed. */ - private PropertyChangeNotifier audioSystemChangeNotifier; + private final PropertyChangeNotifier audioSystemChangeNotifier; /** * The listener that gets notified of changes in the audio level of * remote conference participants. */ - private CsrcAudioLevelListener csrcAudioLevelListener = null; + private CsrcAudioLevelListener csrcAudioLevelListener; /** - * The list of DTMF listeners; + * The list of DTMF listeners. */ private final List<DTMFListener> dtmfListeners = new ArrayList<DTMFListener>(); @@ -95,7 +96,21 @@ public class AudioMediaStreamImpl /** * The transformer that we use for sending and receiving DTMF packets. */ - private DtmfTransformEngine dtmfTransfrmEngine ; + private DtmfTransformEngine dtmfTransfrmEngine; + + /** + * The listener which has been set on this instance to get notified of + * changes in the levels of the audio that the local peer/user is sending to + * the remote peer(s). + */ + private SimpleAudioLevelListener localUserAudioLevelListener; + + /** + * The listener which has been set on this instance to get notified of + * changes in the levels of the audios that the local peer/user is receiving + * from the remote peer(s). + */ + private SimpleAudioLevelListener streamAudioLevelListener; /** * Initializes a new <tt>AudioMediaStreamImpl</tt> instance which will use @@ -109,20 +124,23 @@ public class AudioMediaStreamImpl * <tt>StreamConnector</tt> * @param srtpControl a control which is already created, used to control * the srtp operations. - * @param audioSystemChangeNotifier A property change notifier which will - * inform this stream if a selected audio device (capture, playback or - * notification device) has changed. We want to listen to these events, - * especially for those generated after the audio system has changed. */ - public AudioMediaStreamImpl(StreamConnector connector, - MediaDevice device, - SrtpControl srtpControl, - PropertyChangeNotifier audioSystemChangeNotifier - ) + public AudioMediaStreamImpl( + StreamConnector connector, + MediaDevice device, + SrtpControl srtpControl) { super(connector, device, srtpControl); - this.audioSystemChangeNotifier = audioSystemChangeNotifier; - this.audioSystemChangeNotifier.addPropertyChangeListener(this); + + MediaService mediaService = LibJitsi.getMediaService(); + + if (mediaService instanceof PropertyChangeNotifier) + { + audioSystemChangeNotifier = (PropertyChangeNotifier) mediaService; + audioSystemChangeNotifier.addPropertyChangeListener(this); + } + else + audioSystemChangeNotifier = null; } /** @@ -167,6 +185,23 @@ public void addRTPExtension(byte extensionID, RTPExtension rtpExtension) } } + /** + * Delivers the <tt>audioLevels</tt> map to whoever's interested. This + * method is meant for use primarily by the transform engine handling + * incoming RTP packets (currently <tt>CsrcTransformEngine</tt>). + * + * @param audioLevels a array mapping CSRC IDs to audio levels in + * consecutive elements. + */ + public void audioLevelsReceived(long[] audioLevels) + { + CsrcAudioLevelListener csrcAudioLevelListener + = this.csrcAudioLevelListener; + + if (csrcAudioLevelListener != null) + csrcAudioLevelListener.audioLevelsReceived(audioLevels); + } + /** * Releases the resources allocated by this instance in the course of its * execution and prepares it to be garbage collected. @@ -180,10 +215,12 @@ public void close() if(dtmfTransfrmEngine != null) { - dtmfTransfrmEngine = null; + dtmfTransfrmEngine.close(); + dtmfTransfrmEngine = null; } - this.audioSystemChangeNotifier.removePropertyChangeListener(this); + if (audioSystemChangeNotifier != null) + audioSystemChangeNotifier.removePropertyChangeListener(this); } /** @@ -264,20 +301,44 @@ protected DtmfTransformEngine createDtmfTransformEngine() } /** - * Delivers the <tt>audioLevels</tt> map to whoever's interested. This - * method is meant for use primarily by the transform engine handling - * incoming RTP packets (currently <tt>CsrcTransformEngine</tt>). + * {@inheritDoc} * - * @param audioLevels a array mapping CSRC IDs to audio levels in - * consecutive elements. + * Makes sure that {@link #localUserAudioLevelListener} and + * {@link #streamAudioLevelListener} which have been set on this + * <tt>AudioMediaStream</tt> will be automatically updated when a new + * <tt>MediaDevice</tt> is set on this instance. */ - public void fireConferenceAudioLevelEvent(long[] audioLevels) + @Override + protected void deviceSessionChanged( + MediaDeviceSession oldValue, + MediaDeviceSession newValue) { - CsrcAudioLevelListener csrcAudioLevelListener - = this.csrcAudioLevelListener; + if (oldValue != null) + { + AudioMediaDeviceSession deviceSession + = (AudioMediaDeviceSession) oldValue; - if (csrcAudioLevelListener != null) - csrcAudioLevelListener.audioLevelsReceived(audioLevels); + if (localUserAudioLevelListener != null) + deviceSession.setLocalUserAudioLevelListener(null); + if (streamAudioLevelListener != null) + deviceSession.setStreamAudioLevelListener(null); + } + if (newValue != null) + { + AudioMediaDeviceSession deviceSession + = (AudioMediaDeviceSession) newValue; + + if (localUserAudioLevelListener != null) + { + deviceSession.setLocalUserAudioLevelListener( + localUserAudioLevelListener); + } + if (streamAudioLevelListener != null) + { + deviceSession.setStreamAudioLevelListener( + streamAudioLevelListener); + } + } } /** @@ -352,14 +413,20 @@ protected int getPriority() /** * Receives and reacts to property change events: if the selected device * (for capture, playback or notifications) has changed, then create or - * recreate the streams in order to use it. - * We want to listen to these events, especially for those generated after - * the audio system has changed. + * recreate the streams in order to use it. We want to listen to these + * events, especially for those generated after the audio system has + * changed. * - * @param evt The event which may contain a audio system change event. + * @param ev The event which may contain a audio system change event. */ - public void propertyChange(PropertyChangeEvent evt) + public void propertyChange(PropertyChangeEvent ev) { + /* + * FIXME It is very wrong to do the following upon every + * PropertyChangeEvent fired by MediaServiceImpl. Moreover, it does not + * seem right that we'd want to start this MediaStream upon a + * PropertyChangeEvent (regardless of its specifics). + */ if (sendStreamsAreCreated) recreateSendStreams(); else @@ -421,7 +488,7 @@ public void removeDTMFListener(DTMFListener listener) */ public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener) { - this.csrcAudioLevelListener = listener; + csrcAudioLevelListener = listener; } /** @@ -434,9 +501,20 @@ public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener) * measurements. */ public void setLocalUserAudioLevelListener( - SimpleAudioLevelListener listener) + SimpleAudioLevelListener listener) { - getDeviceSession().setLocalUserAudioLevelListener(listener); + if (localUserAudioLevelListener != listener) + { + localUserAudioLevelListener = listener; + + AudioMediaDeviceSession deviceSession = getDeviceSession(); + + if (deviceSession != null) + { + deviceSession.setLocalUserAudioLevelListener( + localUserAudioLevelListener); + } + } } /** @@ -450,7 +528,18 @@ public void setLocalUserAudioLevelListener( */ public void setStreamAudioLevelListener(SimpleAudioLevelListener listener) { - getDeviceSession().setStreamAudioLevelListener(listener); + if (streamAudioLevelListener != listener) + { + streamAudioLevelListener = listener; + + AudioMediaDeviceSession deviceSession = getDeviceSession(); + + if (deviceSession != null) + { + deviceSession.setStreamAudioLevelListener( + streamAudioLevelListener); + } + } } /** @@ -518,8 +607,8 @@ public void stopSendingDTMF(DTMFMethod dtmfMethod) switch (dtmfMethod) { case INBAND_DTMF: - // The INBAND DTMF is send by impluse of constant duration and - // does not need to be stopped explecitely. + // The INBAND DTMF is sent by impluse of constant duration and does + // not need to be stopped explicitly. break; case RTP_DTMF: @@ -528,7 +617,7 @@ public void stopSendingDTMF(DTMFMethod dtmfMethod) break; case SIP_INFO_DTMF: - // The SIP-INFO DTMF is not managed directly by the + // The SIP-INFO DTMF is managed directly by the // OperationSetDTMFSipImpl. break; diff --git a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java index 438f844e..861ca1a2 100644 --- a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java +++ b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java @@ -359,8 +359,7 @@ else if ((device != null) && !mediaType.equals(device.getMediaType())) switch (mediaType) { case AUDIO: - return - new AudioMediaStreamImpl(connector, device, srtpControl, this); + return new AudioMediaStreamImpl(connector, device, srtpControl); case VIDEO: return new VideoMediaStreamImpl(connector, device, srtpControl); default: @@ -1006,8 +1005,10 @@ public Object getVideoPreviewComponent( final JComponent videoContainer = new VideoContainer(noPreview, false); if ((preferredWidth > 0) && (preferredHeight > 0)) + { videoContainer.setPreferredSize( new Dimension(preferredWidth, preferredHeight)); + } try { @@ -1015,7 +1016,7 @@ public Object getVideoPreviewComponent( if ((device != null) && ((captureDeviceInfo - = ((MediaDeviceImpl)device) + = ((MediaDeviceImpl) device) .getCaptureDeviceInfo()) != null)) { @@ -1059,7 +1060,8 @@ public void controllerUpdate(ControllerEvent event) { if (t instanceof ThreadDeath) throw (ThreadDeath) t; - logger.error("Failed to create video preview", t); + else + logger.error("Failed to create video preview", t); } return videoContainer; @@ -1231,8 +1233,13 @@ public void windowClosing(WindowEvent event) previewContainer.add(preview); - previewContainer.revalidate(); - previewContainer.repaint(); + if (previewContainer.isDisplayable()) + { + previewContainer.revalidate(); + previewContainer.repaint(); + } + else + previewContainer.doLayout(); } else disposePlayer(player); diff --git a/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java b/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java index df731e0c..3548ebfd 100644 --- a/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java +++ b/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceSession.java @@ -243,7 +243,7 @@ private void registerStreamAudioLevelJMFEffect(TrackControl trackControl) public void setLocalUserAudioLevelListener( SimpleAudioLevelListener listener) { - this.localUserAudioLevelEffect.setAudioLevelListener(listener); + localUserAudioLevelEffect.setAudioLevelListener(listener); } /** @@ -261,6 +261,6 @@ public void setLocalUserAudioLevelListener( */ public void setStreamAudioLevelListener(SimpleAudioLevelListener listener) { - this.streamAudioLevelEffect.setAudioLevelListener(listener); + streamAudioLevelEffect.setAudioLevelListener(listener); } } diff --git a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java index 697e8000..ccd5a5ec 100644 --- a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java +++ b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java @@ -1149,7 +1149,7 @@ public void setLocalUserAudioLevelListener(SimpleAudioLevelListener l) if (l != null) { - this.localUserAudioLevelListener = l; + localUserAudioLevelListener = l; // add the listener only if we are not muted // this happens when holding a conversation, stream is muted diff --git a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java index 85a67b23..92df100f 100644 --- a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java +++ b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java @@ -67,11 +67,11 @@ public class DeviceConfiguration private static final String[] CUSTOM_RENDERERS = new String[] { - OSUtils.IS_ANDROID ? "org.jitsi.impl.neomedia.jmfext.media.renderer.audio.AudioTrackRenderer" : null, - OSUtils.IS_ANDROID ? "org.jitsi.impl.neomedia.jmfext.media.renderer.audio.OpenSLESRenderer" : null, + OSUtils.IS_ANDROID ? ".audio.AudioTrackRenderer" : null, + OSUtils.IS_ANDROID ? ".audio.OpenSLESRenderer" : null, OSUtils.IS_LINUX ? ".audio.PulseAudioRenderer" : null, OSUtils.IS_ANDROID ? null : ".audio.PortAudioRenderer", - "net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video.JAWTRenderer" + ".video.JAWTRenderer" }; /** diff --git a/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java b/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java index 29dc9cee..8aa72515 100644 --- a/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java +++ b/src/org/jitsi/impl/neomedia/format/MediaFormatImpl.java @@ -39,14 +39,6 @@ public abstract class MediaFormatImpl<T extends Format> static final Map<String, String> EMPTY_FORMAT_PARAMETERS = Collections.emptyMap(); - /** - * The value of the <tt>codecSettings</tt> property of - * <tt>MediaFormatImpl</tt> when no codec-specific settings. - * Explicitly defined in order to reduce unnecessary allocations. - */ - static final Map<String, String> EMPTY_CODEC_SETTINGS - = Collections.emptyMap(); - /** * The name of the <tt>encoding</tt> property of <tt>MediaFormatImpl</tt>. */ @@ -58,11 +50,6 @@ public abstract class MediaFormatImpl<T extends Format> */ public static final String FORMAT_PARAMETERS_PNAME = "fmtps"; - /** - * The additional codec settings. - */ - private Map<String, String> codecSettings = EMPTY_CODEC_SETTINGS; - /** * Creates a new <tt>MediaFormat</tt> instance for a specific JMF * <tt>Format</tt>. @@ -96,7 +83,7 @@ else if (format instanceof VideoFormat) * @param clockRate the clock rate of the new instance * @param formatParameters the set of format-specific parameters of the new * instance - * @param advancedAttrs advanced attributes of the new instance + * @param advancedAttributess advanced attributes of the new instance * @return a new <tt>MediaFormat</tt> instance for the specified JMF * <tt>Format</tt> and with the specified clock rate and set of * format-specific parameters @@ -105,7 +92,7 @@ public static MediaFormatImpl<? extends Format> createInstance( Format format, double clockRate, Map<String, String> formatParameters, - Map<String, String> advancedAttrs) + Map<String, String> advancedAttributess) { if (format instanceof AudioFormat) { @@ -122,88 +109,22 @@ public static MediaFormatImpl<? extends Format> createInstance( (AudioFormat) clockRateAudioFormat.intersects(audioFormat), formatParameters, - advancedAttrs); + advancedAttributess); } else if (format instanceof VideoFormat) + { return new VideoMediaFormatImpl( (VideoFormat) format, clockRate, -1, formatParameters, - advancedAttrs); + advancedAttributess); + } else return null; } - /** - * Determines whether a specific set of advanced attributes is equal to - * another set of advanced attributes in the sense that they define an equal - * number of parameters and assign them equal values. Since the values are - * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the - * empty <tt>String</tt>. - * <p> - * - * @param adv the first set of advanced attributes to be tested for - * equality - * @param adv2 the second set of advanced attributes to be tested for - * equality - * @return <tt>true</tt> if the specified sets of advanced attributes - * equal; <tt>false</tt>, otherwise - */ - public boolean advancedAttributesAreEqual(Map<String, String> adv, - Map<String, String> adv2) - { - if(adv == null && adv2 != null || adv != null && adv2 == null) - return false; - - if(adv == null && adv2 == null) - return true; - - if(adv.size() != adv2.size()) - return false; - - for(Map.Entry<String, String> a : adv.entrySet()) - { - String value = adv2.get(a.getKey()); - if(value == null) - return false; - else - if(!value.equals(a.getValue())) - return false; - } - return true; - } - - /** - * Determines whether a specific set of format parameters is equal to - * another set of format parameters in the sense that they define an equal - * number of parameters and assign them equal values. Since the values are - * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the - * empty <tt>String</tt>. - * <p> - * The two <tt>Map</tt> instances of format parameters to be checked for - * equality are presumed to be modifiable in the sense that if the lack of a - * format parameter in a given <tt>Map</tt> is equivalent to it having a - * specific value, an association of the format parameter to the value in - * question may be added to or removed from the respective <tt>Map</tt> - * instance for the purposes of determining equality. - * </p> - * - * @param fmtps1 the first set of format parameters to be tested for - * equality - * @param fmtps2 the second set of format parameters to be tested for - * equality - * @return <tt>true</tt> if the specified sets of format parameters are - * equal; <tt>false</tt>, otherwise - */ - protected boolean formatParametersAreEqual( - Map<String, String> fmtps1, - Map<String, String> fmtps2) - { - return formatParametersAreEqual(getEncoding(), fmtps1, fmtps2); - } - /** * Determines whether a specific set of format parameters is equal to * another set of format parameters in the sense that they define an equal @@ -267,17 +188,15 @@ else if (!value1.equals(value2)) } /** - * {@inheritDoc} - * <p> - * The default implementation of <tt>MediaFormatImpl</tt> always returns - * <tt>true</tt> because format parameters in general do not cause the - * distinction of payload types. - * </p> + * The advanced parameters of this instance which have been received + * via SIP/SDP or XMPP/Jingle. */ - public boolean formatParametersMatch(Map<String, String> fmtps) - { - return true; - } + private final Map<String, String> advancedAttributes; + + /** + * The additional codec settings. + */ + private Map<String, String> codecSettings = EMPTY_FORMAT_PARAMETERS; /** * The JMF <tt>Format</tt> this instance wraps and provides an @@ -291,12 +210,6 @@ public boolean formatParametersMatch(Map<String, String> fmtps) */ private final Map<String, String> formatParameters; - /** - * The advanced parameters of this instance which have been received - * via SIP/SDP or XMPP/Jingle. - */ - private final Map<String, String> advancedParameters; - /** * Initializes a new <tt>MediaFormatImpl</tt> instance which is to provide * an implementation of <tt>MediaFormat</tt> for a specific <tt>Format</tt>. @@ -318,13 +231,13 @@ protected MediaFormatImpl(T format) * implementation of <tt>MediaFormat</tt> for * @param formatParameters any codec-specific parameters that have been * received via SIP/SDP or XMPP/Jingle - * @param advancedParameters any parameters that have been + * @param advancedAttributes any parameters that have been * received via SIP/SDP or XMPP/Jingle */ protected MediaFormatImpl( T format, Map<String, String> formatParameters, - Map<String, String> advancedParameters) + Map<String, String> advancedAttributes) { if (format == null) throw new NullPointerException("format"); @@ -334,10 +247,49 @@ protected MediaFormatImpl( = ((formatParameters == null) || formatParameters.isEmpty()) ? EMPTY_FORMAT_PARAMETERS : new HashMap<String, String>(formatParameters); - this.advancedParameters - = ((advancedParameters == null) || advancedParameters.isEmpty()) + this.advancedAttributes + = ((advancedAttributes == null) || advancedAttributes.isEmpty()) ? EMPTY_FORMAT_PARAMETERS - : new HashMap<String, String>(advancedParameters); + : new HashMap<String, String>(advancedAttributes); + } + + /** + * Determines whether a specific set of advanced attributes is equal to + * another set of advanced attributes in the sense that they define an equal + * number of parameters and assign them equal values. Since the values are + * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the + * empty <tt>String</tt>. + * <p> + * + * @param adv the first set of advanced attributes to be tested for + * equality + * @param adv2 the second set of advanced attributes to be tested for + * equality + * @return <tt>true</tt> if the specified sets of advanced attributes + * equal; <tt>false</tt>, otherwise + */ + public boolean advancedAttributesAreEqual(Map<String, String> adv, + Map<String, String> adv2) + { + if(adv == null && adv2 != null || adv != null && adv2 == null) + return false; + + if(adv == null && adv2 == null) + return true; + + if(adv.size() != adv2.size()) + return false; + + for(Map.Entry<String, String> a : adv.entrySet()) + { + String value = adv2.get(a.getKey()); + if(value == null) + return false; + else + if(!value.equals(a.getValue())) + return false; + } + return true; } /** @@ -368,6 +320,94 @@ && formatParametersAreEqual( mediaFormatImpl.getFormatParameters()); } + /** + * Determines whether a specific set of format parameters is equal to + * another set of format parameters in the sense that they define an equal + * number of parameters and assign them equal values. Since the values are + * <tt>String</tt>s, presumes that a value of <tt>null</tt> is equal to the + * empty <tt>String</tt>. + * <p> + * The two <tt>Map</tt> instances of format parameters to be checked for + * equality are presumed to be modifiable in the sense that if the lack of a + * format parameter in a given <tt>Map</tt> is equivalent to it having a + * specific value, an association of the format parameter to the value in + * question may be added to or removed from the respective <tt>Map</tt> + * instance for the purposes of determining equality. + * </p> + * + * @param fmtps1 the first set of format parameters to be tested for + * equality + * @param fmtps2 the second set of format parameters to be tested for + * equality + * @return <tt>true</tt> if the specified sets of format parameters are + * equal; <tt>false</tt>, otherwise + */ + protected boolean formatParametersAreEqual( + Map<String, String> fmtps1, + Map<String, String> fmtps2) + { + return formatParametersAreEqual(getEncoding(), fmtps1, fmtps2); + } + + /** + * {@inheritDoc} + * <p> + * The default implementation of <tt>MediaFormatImpl</tt> always returns + * <tt>true</tt> because format parameters in general do not cause the + * distinction of payload types. + * </p> + */ + public boolean formatParametersMatch(Map<String, String> fmtps) + { + return true; + } + + /** + * Returns additional codec settings. + * + * @return additional settings represented by a map. + */ + public Map<String, String> getAdditionalCodecSettings() + { + return codecSettings; + } + + /** + * Implements MediaFormat#getAdvancedAttributes(). Returns a copy of the + * attribute properties of this instance. Modifications to the returned Map + * do no affect the format properties of this instance. + * + * @return a copy of the attribute properties of this instance. + * Modifications to the returned Map do no affect the format properties of + * this instance. + */ + public Map<String, String> getAdvancedAttributes() + { + return (advancedAttributes == EMPTY_FORMAT_PARAMETERS) + ? EMPTY_FORMAT_PARAMETERS + : new HashMap<String, String>(advancedAttributes); + } + + /** + * Returns a <tt>String</tt> representation of the clock rate associated + * with this <tt>MediaFormat</tt> making sure that the value appears as + * an integer (i.e. its long-casted value is equal to its original one) + * unless it is actually a non integer. + * + * @return a <tt>String</tt> representation of the clock rate associated + * with this <tt>MediaFormat</tt>. + */ + public String getClockRateString() + { + double clockRate = getClockRate(); + long clockRateL = (long) clockRate; + + if (clockRateL == clockRate) + return Long.toString(clockRateL); + else + return Double.toString(clockRate); + } + /** * Implements MediaFormat#getEncoding() and returns the encoding of the JMF * <tt>Format</tt> that we are encapsulating here but it is the RFC-known @@ -424,22 +464,6 @@ public Map<String, String> getFormatParameters() : new HashMap<String, String>(formatParameters); } - /** - * Implements MediaFormat#getAdvancedParameters(). Returns a copy of the - * attribute properties of this instance. Modifications to the returned Map - * do no affect the format properties of this instance. - * - * @return a copy of the attribute properties of this instance. - * Modifications to the returned Map do no affect the format properties of - * this instance. - */ - public Map<String, String> getAdvancedAttributes() - { - return (advancedParameters == EMPTY_FORMAT_PARAMETERS) - ? EMPTY_FORMAT_PARAMETERS - : new HashMap<String, String>(advancedParameters); - } - /** * Gets the encoding of the JMF <tt>Format</tt> represented by this * instance as it is known to JMF (in contrast to its RFC name). @@ -452,61 +476,6 @@ public String getJMFEncoding() return format.getEncoding(); } - /** - * Gets the RTP payload type (number) of this <tt>MediaFormat</tt> as it is - * known in RFC 3551 "RTP Profile for Audio and Video Conferences with - * Minimal Control". - * - * @return the RTP payload type of this <tt>MediaFormat</tt> if it is known - * in RFC 3551 "RTP Profile for Audio and Video Conferences with Minimal - * Control"; otherwise, {@link #RTP_PAYLOAD_TYPE_UNKNOWN} - * @see MediaFormat#getRTPPayloadType() - */ - public byte getRTPPayloadType() - { - return MediaUtils.getRTPPayloadType(getJMFEncoding(), getClockRate()); - } - - /** - * Overrides Object#hashCode() because Object#equals(Object) is overridden. - * - * @return a hash code value for this <tt>MediaFormat</tt>. - */ - @Override - public int hashCode() - { - /* - * XXX We've experienced a case of JMF's VideoFormat#hashCode() - * returning different values for instances which are reported equal by - * VideoFormat#equals(Object) which is inconsistent with the protocol - * covering the two methods in question and causes problems, - * for example, with Map. While jmfEncoding is more generic than format, - * it still provides a relatively good distribution given that we do not - * have a lot of instances with one and the same jmfEncoding. - */ - return getJMFEncoding().hashCode() | getFormatParameters().hashCode(); - } - - /** - * Returns a <tt>String</tt> representation of the clock rate associated - * with this <tt>MediaFormat</tt> making sure that the value appears as - * an integer (i.e. its long-casted value is equal to its original one) - * unless it is actually a non integer. - * - * @return a <tt>String</tt> representation of the clock rate associated - * with this <tt>MediaFormat</tt>. - */ - public String getClockRateString() - { - double clockRate = getClockRate(); - long clockRateL = (long) clockRate; - - if (clockRateL == clockRate) - return Long.toString(clockRateL); - else - return Double.toString(clockRate); - } - /** * Returns a <tt>String</tt> representation of the real used clock rate * associated with this <tt>MediaFormat</tt> making sure that the value @@ -533,80 +502,38 @@ public String getRealUsedClockRateString() } /** - * Sets additional codec settings. - * - * @param settings additional settings represented by a map. - */ - public void setAdditionalCodecSettings(Map<String, String> settings) - { - codecSettings = settings; - } - - /** - * Returns additional codec settings. + * Gets the RTP payload type (number) of this <tt>MediaFormat</tt> as it is + * known in RFC 3551 "RTP Profile for Audio and Video Conferences with + * Minimal Control". * - * @return additional settings represented by a map. + * @return the RTP payload type of this <tt>MediaFormat</tt> if it is known + * in RFC 3551 "RTP Profile for Audio and Video Conferences with Minimal + * Control"; otherwise, {@link #RTP_PAYLOAD_TYPE_UNKNOWN} + * @see MediaFormat#getRTPPayloadType() */ - public Map<String, String> getAdditionalCodecSettings() + public byte getRTPPayloadType() { - return codecSettings; + return MediaUtils.getRTPPayloadType(getJMFEncoding(), getClockRate()); } /** - * Returns a <tt>String</tt> representation of this <tt>MediaFormat</tt> - * containing, among other things, its encoding and clockrate values. + * Overrides Object#hashCode() because Object#equals(Object) is overridden. * - * @return a <tt>String</tt> representation of this <tt>MediaFormat</tt>. + * @return a hash code value for this <tt>MediaFormat</tt>. */ @Override - public String toString() + public int hashCode() { - StringBuffer str = new StringBuffer(); - - str.append("rtpmap:"); - str.append(getRTPPayloadType()); - str.append(' '); - str.append(getEncoding()); - str.append('/'); - str.append(getClockRateString()); - /* - * If the number of channels is 1, it does not have to be mentioned - * because it is the default. + * XXX We've experienced a case of JMF's VideoFormat#hashCode() + * returning different values for instances which are reported equal by + * VideoFormat#equals(Object) which is inconsistent with the protocol + * covering the two methods in question and causes problems, + * for example, with Map. While jmfEncoding is more generic than format, + * it still provides a relatively good distribution given that we do not + * have a lot of instances with one and the same jmfEncoding. */ - if (MediaType.AUDIO.equals(getMediaType())) - { - int channels = ((AudioFormat) getFormat()).getChannels(); - - if (channels != 1) - { - str.append('/'); - str.append(channels); - } - } - - Map<String, String> formatParameters = getFormatParameters(); - - if (!formatParameters.isEmpty()) - { - str.append(" fmtp:"); - - boolean prependSeparator = false; - - for (Map.Entry<String, String> formatParameter - : formatParameters.entrySet()) - { - if (prependSeparator) - str.append(';'); - else - prependSeparator = true; - str.append(formatParameter.getKey()); - str.append('='); - str.append(formatParameter.getValue()); - } - } - - return str.toString(); + return getJMFEncoding().hashCode() | getFormatParameters().hashCode(); } /** @@ -691,4 +618,74 @@ public boolean matches(MediaType mediaType, // formatParameters return formatParametersMatch(formatParameters); } + + /** + * Sets additional codec settings. + * + * @param settings additional settings represented by a map. + */ + public void setAdditionalCodecSettings(Map<String, String> settings) + { + codecSettings + = ((settings == null) || settings.isEmpty()) + ? EMPTY_FORMAT_PARAMETERS + : settings; + } + + /** + * Returns a <tt>String</tt> representation of this <tt>MediaFormat</tt> + * containing, among other things, its encoding and clockrate values. + * + * @return a <tt>String</tt> representation of this <tt>MediaFormat</tt>. + */ + @Override + public String toString() + { + StringBuffer str = new StringBuffer(); + + str.append("rtpmap:"); + str.append(getRTPPayloadType()); + str.append(' '); + str.append(getEncoding()); + str.append('/'); + str.append(getClockRateString()); + + /* + * If the number of channels is 1, it does not have to be mentioned + * because it is the default. + */ + if (MediaType.AUDIO.equals(getMediaType())) + { + int channels = ((AudioFormat) getFormat()).getChannels(); + + if (channels != 1) + { + str.append('/'); + str.append(channels); + } + } + + Map<String, String> formatParameters = getFormatParameters(); + + if (!formatParameters.isEmpty()) + { + str.append(" fmtp:"); + + boolean prependSeparator = false; + + for (Map.Entry<String, String> formatParameter + : formatParameters.entrySet()) + { + if (prependSeparator) + str.append(';'); + else + prependSeparator = true; + str.append(formatParameter.getKey()); + str.append('='); + str.append(formatParameter.getValue()); + } + } + + return str.toString(); + } } diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java similarity index 88% rename from src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java rename to src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java index f1568666..fac7bf20 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java @@ -4,7 +4,7 @@ * Distributable under LGPL license. * See terms of license at gnu.org. */ -package net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video; +package org.jitsi.impl.neomedia.jmfext.media.renderer.video; import java.awt.*; import java.lang.reflect.*; @@ -15,8 +15,6 @@ import javax.swing.*; import org.jitsi.impl.neomedia.jmfext.media.renderer.*; -import org.jitsi.service.configuration.*; -import org.jitsi.service.libjitsi.*; import org.jitsi.util.*; import org.jitsi.util.swing.*; @@ -69,49 +67,9 @@ public class JAWTRenderer 0x00FF0000, 0x0000FF00, 0x000000FF) }; - /** - * The indicator which determines whether <tt>CALayer</tt>-based painting is - * to be performed by <tt>JAWTRenderer</tt> on Mac OS X. - */ - private static final boolean USE_MACOSX_CALAYERS; - static { System.loadLibrary("jnawtrenderer"); - - /* - * XXX The native JAWTRenderer implementation on Mac OS X which paints - * in a CALayer-like fashion has been determined through testing to not - * work as expected on MacBookPro8. Unfortunately, the cause of the - * problem has not been determined. As a workaround, fall back to the - * alternative implementation (currently used on the other supported - * operating systems) on the problematic model. - */ - if (OSUtils.IS_MAC) - { - ConfigurationService cfg = LibJitsi.getConfigurationService(); - - if ((cfg == null) - || cfg.getBoolean( - JAWTRenderer.class.getName() - + ".USE_MACOSX_CALAYERS", - false)) - { - String hwModel = sysctlbyname("hw.model"); - - USE_MACOSX_CALAYERS - = (hwModel == null) - || !(hwModel.startsWith("MacBookPro8") - || hwModel.startsWith("MacBookAir4")); - } - else - USE_MACOSX_CALAYERS = false; - } - else - { - // CALayer-like painting is currently only supported on Mac OS X. - USE_MACOSX_CALAYERS = false; - } } /** @@ -143,10 +101,6 @@ public JAWTRenderer() { } - public static native void addNotifyLightweightComponent( - long handle, Component component, - long parentHandle); - /** * Closes this <tt>PlugIn</tt> and releases the resources it has retained * during its execution. No more data will be accepted by this @@ -199,7 +153,7 @@ public synchronized void close() * platform-specific info of <tt>component</tt> is not guaranteed to be * valid. */ - public static native void close(long handle, Component component); + private static native void close(long handle, Component component); /** * Gets the region in the component of this <tt>VideoRenderer</tt> where the @@ -231,9 +185,7 @@ public synchronized Component getComponent() "org.jitsi" + ".impl.neomedia.jmfext.media.renderer.video" + ".JAWTRenderer"); - if (USE_MACOSX_CALAYERS && OSUtils.IS_MAC) - componentClassName.append("Swing"); - else if (OSUtils.IS_ANDROID) + if (OSUtils.IS_ANDROID) componentClassName.append("Android"); componentClassName.append("VideoComponent"); @@ -395,7 +347,7 @@ public void run() * is to draw into the specified AWT <tt>Component</tt> * @throws ResourceUnavailableException if there is a problem during opening */ - public static native long open(Component component) + private static native long open(Component component) throws ResourceUnavailableException; /** @@ -413,6 +365,7 @@ public static native long open(Component component) * <tt>paint</tt>. * @param g the <tt>Graphics</tt> context into which the drawing is to be * performed + * @param zOrder * @return <tt>true</tt> if the native counterpart of a * <tt>JAWTRenderer</tt> wants to continue receiving the <tt>paint</tt> * calls on the AWT <tt>Component</tt>; otherwise, false. For example, after @@ -423,11 +376,10 @@ public static native long open(Component component) * indicate with <tt>false</tt> that it does not need further <tt>paint</tt> * deliveries. */ - public static native boolean paint( - long handle, Component component, Graphics g); - - public static native boolean paintLightweightComponent( - long handle, Component component, Graphics g); + static native boolean paint( + long handle, + Component component, Graphics g, + int zOrder); /** * Processes the data provided in a specific <tt>Buffer</tt> and renders it @@ -510,19 +462,12 @@ public synchronized int process(Buffer buffer) * @param height the height of the video frame in <tt>data</tt> * @return <tt>true</tt> if data has been successfully processed */ - public static native boolean process( + static native boolean process( long handle, Component component, int[] data, int offset, int length, int width, int height); - public static native void processLightweightComponentEvent( - long handle, - int x, int y, int width, int height); - - public static native void removeNotifyLightweightComponent( - long handle, Component component); - /** * Sets the region in the component of this <tt>VideoRenderer</tt> where the * video is to be rendered. diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java deleted file mode 100644 index 9071d1de..00000000 --- a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererSwingVideoComponent.java +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package org.jitsi.impl.neomedia.jmfext.media.renderer.video; - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.util.*; -import java.util.List; - -import javax.media.*; -import javax.swing.*; - -import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video.*; - -import org.jitsi.util.*; -import org.jitsi.util.swing.*; - -/** - * Implements a Swing <tt>Component</tt> in which <tt>JAWTRenderer</tt> paints. - * - * @author Lyubomir Marinov - */ -public class JAWTRendererSwingVideoComponent - extends JPanel -{ - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The <tt>Logger</tt> used by the <tt>JAWTRendererSwingVideoComponent</tt> - * class and its instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(JAWTRendererSwingVideoComponent.class); - - /** - * The <tt>SwingVideoComponentCanvas</tt> in which this - * <tt>SwingVideoComponent</tt> is painted according to the last call to - * {@link #addNotify()}. - */ - private SwingVideoComponentCanvas canvas; - - /** - * The <tt>Container</tt> which is the last-known parent of this - * <tt>SwingVideoComponent</tt>. - */ - private Container parent; - - /** - * The <tt>ComponentListener</tt> which is to be or is listening to - * <tt>ComponentEvent</tt>s fired by {@link #parent}. - */ - private final ComponentListener parentComponentListener - = new ComponentAdapter() - { - @Override - public void componentResized(ComponentEvent e) - { - /* - * It is necessary to call - * #procesLightweightComponentEvent() when the parent gets - * resized only if the native counterpart of this - * SwingVideoComponent expects bounds in a coordinate system - * which changes with respect to the bounds of this - * SwingVideoComponent when the parent gets resized. - */ - //processLightweightComponentEvent(); - } - }; - - /** - * The <tt>JAWTRenderer</tt> which paints in this - * <tt>JAWTRendererSwingVideoComponent</tt>. - */ - private final JAWTRenderer renderer; - - /** - * The indicator which determines whether the native counterpart of this - * <tt>JAWTRenderer</tt> wants <tt>paint</tt> calls on its Swing - * <tt>Component</tt> to be delivered. - * - * @see JAWTRendererVideoComponent#wantsPaint - */ - private boolean wantsPaint = true; - - /** - * Constructor. - * - * @param renderer <tt>JAWTRenderer</tt> instance - */ - public JAWTRendererSwingVideoComponent(JAWTRenderer renderer) - { - if (VideoContainer.DEFAULT_BACKGROUND_COLOR != null) - setBackground(VideoContainer.DEFAULT_BACKGROUND_COLOR); - - this.renderer = renderer; - } - - @Override - public void addNotify() - { - /* - * Since JAWTRenderer#open() may be performing the call, it may be - * wrong about this SwingVideoComponent having a parent. - */ - Container parent = getParent(); - - if (parent == null) - return; - - super.addNotify(); - - wantsPaint = true; - - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (handle != 0) - { - SwingVideoComponentCanvas canvas = findCanvas(); - - if (canvas == null) - { - JAWTRenderer.addNotifyLightweightComponent( - handle, this, - 0); - } - else - { - long canvasHandle; - - synchronized (canvas.getHandleLock()) - { - canvasHandle = canvas.getHandle(); - JAWTRenderer.addNotifyLightweightComponent( - handle, this, - canvasHandle); - } - if ((canvasHandle != 0) && (this.canvas != canvas)) - { - this.canvas = canvas; - } - } - - /* - * Emulate a ComponentEvent so that, for example, the native - * counterpart of this Component gets its bounds up to date. - */ - processLightweightComponentEvent(); - } - } - - if (this.parent != parent) - { - this.parent = parent; - this.parent.addComponentListener(parentComponentListener); - } - } - - /** - * Creates a new AWT <tt>Component</tt> in which - * <tt>SwingVideoComponent</tt>s can be rendered. - * @return new AWT <tt>Component</tt> in which <tt>SwingVideoComponent</tt>s - * can be rendered - */ - public Component createCanvas() - { - return new SwingVideoComponentCanvas(renderer); - } - - /** - * Finds a <tt>SwingVideoComponentCanvas</tt> in which this - * <tt>SwingVideoComponent</tt> can be painted. - * - * @return a <tt>SwingVideoComponentCanvas</tt> in which this - * <tt>SwingVideoComponent</tt> can be painted if any; otherwise, - * <tt>null</tt> - */ - private SwingVideoComponentCanvas findCanvas() - { - Container parent = getParent(); - - if (parent != null) - for (Component component : parent.getComponents()) - if (component instanceof SwingVideoComponentCanvas) - return (SwingVideoComponentCanvas) component; - return null; - } - - /** - * Gets the <tt>SwingVideoComponentCanvas</tt> in which this - * <tt>SwingVideoComponent</tt> is being painted. - * - * @return the <tt>SwingVideoComponentCanvas</tt> in which this - * <tt>SwingVideoComponent</tt> is being painted if any; otherwise, - * <tt>null</tt> - */ - SwingVideoComponentCanvas getCanvas() - { - return canvas; - } - - @Override - public void paint(Graphics g) - { - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (wantsPaint && (handle != 0)) - { - wantsPaint - = JAWTRenderer.paintLightweightComponent( - handle, - this, - g); - } - } - } - - @Override - protected void processComponentEvent(ComponentEvent e) - { - super.processComponentEvent(e); - - if (equals(e.getComponent())) - { - switch(e.getID()) - { - case ComponentEvent.COMPONENT_MOVED: - case ComponentEvent.COMPONENT_RESIZED: - processLightweightComponentEvent(); - break; - } - } - } - - /** - * Notifies this <tt>SwingVideoComponent</tt> that a - * <tt>ComponentEvent</tt> related to it has occurred. - */ - private void processLightweightComponentEvent() - { - Rectangle bounds = getBounds(); - - if (bounds != null) - { - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (handle != 0) - { - JAWTRenderer.processLightweightComponentEvent( - handle, - bounds.x, - bounds.y, - bounds.width, - bounds.height); - } - } - } - } - - @Override - public void removeNotify() - { - if (parent != null) - { - parent.removeComponentListener(parentComponentListener); - parent = null; - } - - synchronized (renderer.getHandleLock()) - { - long handle = renderer.getHandle(); - - if (handle != 0) - { - if (canvas != null) - { - synchronized (canvas.getHandleLock()) - { - JAWTRenderer.removeNotifyLightweightComponent( - handle, this); - } - canvas = null; - } - else - { - JAWTRenderer.removeNotifyLightweightComponent( - handle, this); - } - } - } - - /* - * In case the associated JAWTRenderer has said that it does not - * want paint events/notifications, ask it again next time because - * the native handle of this Canvas may be recreated. - */ - wantsPaint = true; - - super.removeNotify(); - } - - @Override - public void repaint() - { - super.repaint(); - - /* - * Since SwingVideoComponent is to be painted in a - * SwingVideoComponentCanvas, the latter should repaint when the - * former does. - */ - Component canvas = getCanvas(); - - if (canvas != null) - canvas.repaint(); - } - - @Override - public void setBounds(int x, int y, int width, int height) - { - super.setBounds(x, y, width, height); - - /* - * Calling #setBounds(int, int, int, int) does not seem to cause - * this SwingVideoComponent to process a ComponentEvent so force it - * because it is really necessary to deliver the up-to-date bounds - * to the native counterpart. - */ - processLightweightComponentEvent(); - } - - @Override - public void setLocation(int x, int y) - { - super.setLocation(x, y); - - processLightweightComponentEvent(); - } - - /** - * Represents a <tt>Component</tt> which is neither a - * <tt>AWTVideoComponent</tt> nor a <tt>SwingVideoComponent</tt> but which - * is to be painted by a <tt>SwingVideoComponentCanvas</tt> anyway. - */ - private static class NonVideoComponent - { - /** - * The <tt>BufferedImage</tt> into which {@link #component} is to be - * painted so that it can be processed and then rendered by - * {@link #handle}. - */ - private BufferedImage bufferedImage; - - /** - * The <tt>Component</tt> represented by this <tt>NonVideoComponent</tt> - * instance. - */ - public final Component component; - - /** - * The handle of the native <tt>JAWTRenderer</tt> which paints this - * <tt>NonVideoComponent</tt>. - */ - private long handle; - - /** - * The height in pixels of {@link #bufferedImage} and {@link #rgb}. - */ - private int height; - - /** - * The pixels of {@link #bufferedImage} to be processed by - * {@link #handle}. - */ - private int[] rgb; - - /** - * The width in pixels of {@link #bufferedImage} and {@link #rgb}. - */ - private int width; - - /** - * Initializes a new <tt>NonVideoComponent</tt> instance which is to - * paint a specific <tt>Component</tt> in the context of a parent - * <tt>JAWTRenderer</tt>. - * - * @param component the <tt>Component</tt> to be painted - * @param parentHandle the handle of the native <tt>JAWTRenderer</tt> in - * the context of which <tt>component</tt> is to be painted - */ - public NonVideoComponent(Component component, long parentHandle) - { - this.component = component; - - try - { - handle = JAWTRenderer.open(this.component); - if (handle != 0) - { - JAWTRenderer.addNotifyLightweightComponent( - handle, this.component, - parentHandle); - } - } - catch (ResourceUnavailableException rue) - { - logger.error( - "Failed to JAWTRenderer.open for NonVideoComponent", - rue); - } - } - - /** - * Releases the resources of this <tt>NonVideoComponent</tt> and - * prepares it to be garbage collected. - */ - public void dispose() - { - if (handle != 0) - { - JAWTRenderer.removeNotifyLightweightComponent( - handle, component); - JAWTRenderer.close(handle, component); - handle = 0; - } - } - - /** - * Paints the <tt>Component</tt> associated with this - * <tt>NonVideoComponent</tt> instance. - */ - public void paint() - { - if (handle != 0) - { - /* - * Make sure the location, the size and the visibility known to - * the associated native JAWTRenderer are in sync with these of - * the component. - */ - Rectangle bounds = component.getBounds(); - - if (!component.isVisible()) - { - bounds.height = 0; - bounds.width = 0; - } - JAWTRenderer.processLightweightComponentEvent( - handle, - bounds.x, bounds.y, bounds.width, bounds.height); - - /* - * If the component is not visible, the native JAWTRenderer - * already knows that it is not to be rendered. - */ - if ((bounds.height < 1) || (bounds.width < 1)) - return; - - /* - * Paint the component and tell the native JAWTRenderer about - * the latest painting. - */ - if ((height != bounds.height) || (width != bounds.width)) - { - rgb = new int[bounds.width * bounds.height]; - bufferedImage - = new BufferedImage( - bounds.width, bounds.height, - BufferedImage.TYPE_INT_ARGB); - height = bounds.height; - width = bounds.width; - } - if ((bufferedImage != null) && (rgb != null)) - { - Graphics g = bufferedImage.createGraphics(); - boolean process = false; - - try - { - component.paint(g); - process = true; - } - finally - { - g.dispose(); - } - if (process) - { - bufferedImage.getRGB( - 0, 0, width, height, - rgb, 0, width); - JAWTRenderer.process( - handle, component, - rgb, 0, rgb.length, - width, height); - } - } - } - } - } - - /** - * Implements an AWT <tt>Component</tt> in which - * <tt>SwingVideoComponent</tt>s can be rendered. - */ - private static class SwingVideoComponentCanvas - extends JAWTRendererVideoComponent - { - /** - * Serial version UID. - */ - private static final long serialVersionUID = 0L; - - /** - * The handle to the native <tt>JAWTRenderer</tt> which does the actual - * painting of this <tt>SwingVideoComponentCanvas</tt>. - */ - private long handle; - - /** - * The <tt>Component</tt> to which this - * <tt>SwingVideoComponentCanvas</tt> has dispatched a - * {@link MouseEvent#MOUSE_PRESSED}. - */ - private Component mousePressedComponent; - - /** - * The <tt>NoVideoComponent</tt>s painted by this - * <tt>SwingVideoComponentCanvas</tt>. - */ - private final List<NonVideoComponent> nonVideoComponents - = new LinkedList<NonVideoComponent>(); - - /** - * The <tt>Container</tt> which is the last-known parent of this - * <tt>SwingVideoComponentCanvas</tt>. - */ - private Container parent; - - /** - * The <tt>ContainerListener</tt> which listens to {@link #parent}. - */ - private final ContainerListener parentContainerListener - = new ContainerListener() - { - public void componentAdded(ContainerEvent e) - { - Component c = e.getChild(); - - if (!(c instanceof JAWTRendererVideoComponent) - && !(c instanceof JAWTRendererSwingVideoComponent)) - { - nonVideoComponentAdded(c); - } - } - - public void componentRemoved(ContainerEvent e) - { - Component c = e.getChild(); - - if (mousePressedComponent == c) - mousePressedComponent = null; - - if (!(c instanceof JAWTRendererVideoComponent) - && !(c instanceof JAWTRendererSwingVideoComponent)) - { - nonVideoComponentRemoved(c); - } - else if (SwingVideoComponentCanvas.this.equals(c)) - removeAllNonVideoComponents(); - } - }; - - /** - * Initializes a new <tt>SwingVideoComponentCanvas</tt> instance. - * - * @param renderer - */ - public SwingVideoComponentCanvas(JAWTRenderer renderer) - { - super(renderer); - - enableEvents( - AWTEvent.MOUSE_EVENT_MASK - | AWTEvent.MOUSE_MOTION_EVENT_MASK); - } - - @Override - public void addNotify() - { - super.addNotify(); - - synchronized (getHandleLock()) - { - if (getHandle() == 0) - { - try - { - this.handle = JAWTRenderer.open(this); - } - catch (ResourceUnavailableException rue) - { - throw new RuntimeException(rue); - } - if (getHandle() == 0) - { - throw new RuntimeException( - "JAWTRenderer#open(Component)"); - } - } - } - - Container parent = getParent(); - - if ((parent != null) && (this.parent != parent)) - { - this.parent = parent; - this.parent.addContainerListener(parentContainerListener); - } - } - - @Override - public boolean contains(int x, int y) - { - /* - * Act as a "glass pane" i.e. be transparent with respect to points - * and pretend they are in whatever is underneath. - */ - return false; - } - - /** - * Dispatches <tt>MouseEvent</tt>s to whatever is underneath this - * <tt>SwingVideoComponentCanvas</tt> because it only renders - * <tt>Component</tt>s i.e. it is like a "glass pane". - */ - private boolean dispatchMouseEvent(MouseEvent e) - { - Component srcc = e.getComponent(); - - if (srcc != null) - { - int id = e.getID(); - Component dstc = null; - - /* - * After a MOUSE_PRESSED, this SwingVideoComponentCanvas will - * continue to receive, for example, MouseMotionEvents even - * when the point has moved out of it. Emulate the same behavior - * for the Components this SwingVideoComponentCanvas dispatches - * events to since it is transparent in this respect. - */ - if (MouseEvent.MOUSE_PRESSED == id) - mousePressedComponent = null; - else if (mousePressedComponent != null) - { - dstc = mousePressedComponent; - if ((MouseEvent.MOUSE_CLICKED == id) - || (MouseEvent.MOUSE_RELEASED == id)) - mousePressedComponent = null; - } - - if (dstc == null) - { - Container parent = getParent(); - - if (parent != null) - { - Point parentPoint - = SwingUtilities.convertPoint( - srcc, - e.getPoint(), - parent); - - dstc = getComponentAt(parent, parentPoint); - } - } - - if (dstc != null) - { - if (MouseEvent.MOUSE_PRESSED == id) - mousePressedComponent = dstc; - dstc.dispatchEvent( - SwingUtilities.convertMouseEvent( - srcc, - e, - dstc)); - return true; - } - } - return false; - } - - /** - * Determines the <tt>Component</tt> which is a child of a specific - * <tt>Container</tt> which contains a specific <tt>Point</tt>. Since - * <tt>SwingVideoComponentCanvas</tt> is like a "glass pane", it never - * contains the specified <tt>point</tt>. - * - * @param parent the <tt>Container</tt> which contains the - * <tt>Component</tt>s which may contain the specified <tt>point</tt> - * @param point the point in the coordinate system of <tt>parent</tt> - * which is to be determined which <tt>Component</tt> contains it - * @return the <tt>Component</tt> which is a child of the specified - * <tt>Container</tt> and contains the specified <tt>Point</tt> or - * <tt>null</tt> if there is no such <tt>Component</tt> - */ - private Component getComponentAt(Container parent, Point point) - { - Component[] components = parent.getComponents(); - - for (int componentIndex = components.length - 1; - componentIndex >= 0; - componentIndex--) - { - Component component = components[componentIndex]; - - if (!equals(component) - && component.isVisible() - && component.contains( - SwingUtilities.convertPoint( - parent, - point, - component))) - { - return component; - } - } - return null; - } - - /* Overrides JAWTRendererVideoComponent#getHandle(). */ - @Override - protected long getHandle() - { - return handle; - } - - /* Overrides JAWTRendererVideoComponent#getHandleLock(). */ - @Override - protected Object getHandleLock() - { - return this; - } - - /** - * Notifies this <tt>SwingVideoComponentCanvas</tt> that a - * <tt>Component</tt> which is neither an <tt>AWTVideoComponent</tt> nor - * a <tt>SwingVideoComponent</tt> has been added to {@link #parent}. - * - * @param c the component which has been added - */ - private void nonVideoComponentAdded(Component c) - { - synchronized (getHandleLock()) - { - synchronized (nonVideoComponents) - { - for (NonVideoComponent nonVideoComponent - : nonVideoComponents) - { - if (nonVideoComponent.component.equals(c)) - return; - } - - nonVideoComponents.add( - new NonVideoComponent(c, getHandle())); - } - } - } - - /** - * Notifies this <tt>SwingVideoComponentCanvas</tt> that a - * <tt>Component</tt> which is neither an <tt>AWTVideoComponent</tt> nor - * a <tt>SwingVideoComponent</tt> has been removed from {@link #parent}. - * - * @param c the component which has been removed - */ - private void nonVideoComponentRemoved(Component c) - { - synchronized (nonVideoComponents) - { - Iterator<NonVideoComponent> nonVideoComponentIter - = nonVideoComponents.iterator(); - - while (nonVideoComponentIter.hasNext()) - { - NonVideoComponent nonVideoComponent - = nonVideoComponentIter.next(); - - if (nonVideoComponent.component.equals(c)) - { - nonVideoComponentIter.remove(); - nonVideoComponent.dispose(); - break; - } - } - } - } - - @Override - public void paint(Graphics g) - { - try - { - synchronized (nonVideoComponents) - { - for (NonVideoComponent nonVideoComponent - : nonVideoComponents) - nonVideoComponent.paint(); - } - } - finally - { - super.paint(g); - } - } - - @Override - protected void processMouseEvent(MouseEvent e) - { - /* - * Act as a "glass pane" i.e. be transparent with respect to - * MouseEvents and dispatch them to whatever is underneath. - */ - if (!dispatchMouseEvent(e)) - super.processMouseEvent(e); - } - - @Override - protected void processMouseMotionEvent(MouseEvent e) - { - /* - * Act as a "glass pane" i.e. be transparent with respect to - * MouseEvents and dispatch them to whatever is underneath. - */ - if (!dispatchMouseEvent(e)) - super.processMouseMotionEvent(e); - } - - /** - * Removes all <tt>NonVideoComponent</tt>s from this - * <tt>SwingVideoComponentCanvas</tt> so that their associated - * <tt>Component</tt>s are no longer painted by the represented native - * <tt>JAWTRenderer</tt>. - */ - private void removeAllNonVideoComponents() - { - synchronized (nonVideoComponents) - { - Iterator<NonVideoComponent> nonVideoComponentIter - = nonVideoComponents.iterator(); - - while (nonVideoComponentIter.hasNext()) - { - NonVideoComponent nonVideoComponent - = nonVideoComponentIter.next(); - - nonVideoComponentIter.remove(); - nonVideoComponent.dispose(); - } - } - } - - @Override - public void removeNotify() - { - mousePressedComponent = null; - - if (parent != null) - { - parent.removeContainerListener(parentContainerListener); - removeAllNonVideoComponents(); - parent = null; - } - - synchronized (getHandleLock()) - { - long handle = getHandle(); - - if (handle != 0) - { - try - { - JAWTRenderer.close(handle, this); - } - finally - { - this.handle = 0; - } - } - } - - super.removeNotify(); - } - } -} diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java index 26f05e62..de8e03a8 100644 --- a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/video/JAWTRendererVideoComponent.java @@ -8,10 +8,6 @@ import java.awt.*; -import net.java.sip.communicator.impl.neomedia.jmfext.media.renderer.video.*; - -import org.jitsi.util.swing.*; - /** * Implements an AWT <tt>Component</tt> in which <tt>JAWTRenderer</tt> paints. * @@ -52,9 +48,6 @@ public class JAWTRendererVideoComponent */ public JAWTRendererVideoComponent(JAWTRenderer renderer) { - if (VideoContainer.DEFAULT_BACKGROUND_COLOR != null) - setBackground(VideoContainer.DEFAULT_BACKGROUND_COLOR); - this.renderer = renderer; } @@ -110,7 +103,15 @@ public void paint(Graphics g) long handle; if ((handle = getHandle()) != 0) - wantsPaint = JAWTRenderer.paint(handle, this, g); + { + Container parent = getParent(); + int zOrder + = (parent == null) + ? -1 + : parent.getComponentZOrder(this); + + wantsPaint = JAWTRenderer.paint(handle, this, g, zOrder); + } } } } diff --git a/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java index 1d012222..b310a8db 100644 --- a/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java +++ b/src/org/jitsi/impl/neomedia/transform/csrc/CsrcTransformEngine.java @@ -280,40 +280,33 @@ public void run() { isRunning = true; - //no point in listening if our stream is not an audio one. + // Audio levels are received in RTP audio streams only. if(!(mediaStream instanceof AudioMediaStreamImpl)) return; - long[] temp = null; + AudioMediaStreamImpl audioStream + = (AudioMediaStreamImpl) mediaStream; while(isRunning) { + long[] audioLevels; + synchronized(this) { if(lastReportedLevels == null) { - try - { - wait(); - } - catch (InterruptedException ie) {} + try { wait(); } catch (InterruptedException ie) {} + continue; } - - temp = lastReportedLevels; - // make lastReportedLevels to null - // so we will wait for the next level on next iteration - lastReportedLevels = null; - } - - if(temp != null) - { - //now notify our listener - if (mediaStream != null) + else { - ((AudioMediaStreamImpl)mediaStream) - .fireConferenceAudioLevelEvent(temp); + audioLevels = lastReportedLevels; + lastReportedLevels = null; } } + + if(audioLevels != null) + audioStream.audioLevelsReceived(audioLevels); } } @@ -328,7 +321,6 @@ public void addLevels(long[] levels) synchronized(this) { this.lastReportedLevels = levels; - notifyAll(); } } @@ -343,7 +335,6 @@ public void stop() { this.lastReportedLevels = null; isRunning = false; - notifyAll(); } } diff --git a/src/org/jitsi/util/swing/FitLayout.java b/src/org/jitsi/util/swing/FitLayout.java index 6af174e3..e61c6cd2 100644 --- a/src/org/jitsi/util/swing/FitLayout.java +++ b/src/org/jitsi/util/swing/FitLayout.java @@ -62,12 +62,13 @@ protected void layoutComponent( /* * XXX The following is a quick and dirty hack for the purposes of video * conferencing which adds transparent JPanels to VideoContainer and - * does not want them fitted because they contains VideoContainers + * does not want them fitted because they contain VideoContainers * themselves and the videos get fitted in them. */ - if ((component instanceof JPanel) - && !component.isOpaque() - && (((Container) component).getComponentCount() > 1)) + if (((component instanceof JPanel) + && !component.isOpaque() + && (((Container) component).getComponentCount() > 1)) + || (component instanceof VideoContainer)) { componentSize = bounds.getSize(); } diff --git a/src/org/jitsi/util/swing/VideoContainer.java b/src/org/jitsi/util/swing/VideoContainer.java index 7a126792..41194e97 100644 --- a/src/org/jitsi/util/swing/VideoContainer.java +++ b/src/org/jitsi/util/swing/VideoContainer.java @@ -8,7 +8,6 @@ import java.awt.*; import java.awt.event.*; -import java.lang.reflect.*; import org.jitsi.util.*; @@ -29,34 +28,12 @@ public class VideoContainer */ private static final long serialVersionUID = 0L; - /** - * The <tt>Logger</tt> used by the <tt>VideoContainer</tt> class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(VideoContainer.class); - /** * The default background color. */ public static final Color DEFAULT_BACKGROUND_COLOR = OSUtils.IS_MAC ? Color.BLACK : null; - /** - * The name of the instance method of <tt>Component</tt>s added to - * <tt>VideoContainer</tt> which creates a new <tt>Component</tt> acting as - * a canvas in which the other <tt>Component</tt>s contained in the - * <tt>VideoContainer</tt> are painted. - */ - private static final String VIDEO_CANVAS_FACTORY_METHOD_NAME - = "createCanvas"; - - /** - * The <tt>Component</tt> which is the canvas, if any, in which the other - * <tt>Component</tt>s contained in this <tt>VideoContainer</tt> are - * painted. - */ - private Component canvas; - private int inAddOrRemove; /** @@ -87,16 +64,6 @@ public VideoContainer(Component noVideoComponent, boolean conference) this.noVideoComponent = noVideoComponent; - /* - * JAWTRenderer on Mac OS X will by default occupy the whole video - * container and will, consequently, draw a black background. In certain - * problematic cases which it will try to provide a workaround, it will - * not occupy the whole video container. To make the experience - * relatively the same, always use a black background. - */ - if (DEFAULT_BACKGROUND_COLOR != null) - setBackground(DEFAULT_BACKGROUND_COLOR); - addContainerListener( new ContainerListener() { @@ -165,94 +132,6 @@ public void add(Component comp, Object constraints, int index) remove(noVideoComponent); } - if ((canvas == null) || (canvas.getParent() != this)) - { - if (OSUtils.IS_MAC && (comp != canvas)) - { - /* - * Unless the comp has a createCanvas() method, it makes no - * sense to consider any exception a problem. - */ - boolean ignoreException; - Throwable exception; - - ignoreException = true; - exception = null; - canvas = null; - - try - { - Method m - = comp.getClass().getMethod( - VIDEO_CANVAS_FACTORY_METHOD_NAME); - - if (m != null) - { - ignoreException = false; - - Object c = m.invoke(comp); - - if (c instanceof Component) - canvas = (Component) c; - } - } - catch (ClassCastException cce) - { - exception = cce; - } - catch (ExceptionInInitializerError eiie) - { - exception = eiie; - } - catch (IllegalAccessException illegalAccessException) - { - exception = illegalAccessException; - } - catch (IllegalArgumentException illegalArgumentException) - { - exception = illegalArgumentException; - } - catch (InvocationTargetException ita) - { - exception = ita; - } - catch (NoSuchMethodException nsme) - { - exception = nsme; - } - catch (NullPointerException npe) - { - exception = npe; - } - catch (SecurityException se) - { - exception = se; - } - if (canvas != null) - add(canvas, VideoLayout.CANVAS, 0); - else if ((exception != null) && !ignoreException) - logger.error("Failed to create video canvas.", exception); - } - } - if ((canvas != null) - && (canvas.getParent() == this) - && OSUtils.IS_MAC - && (comp != canvas)) - { - /* - * The canvas in which the other components are to be painted - * should always be at index 0. And the order of adding is - * important so no index should be specified. - */ - index = -1; - } - - /* - * XXX Do not call #remove(Component) beyond this point and before - * #add(Component, Object, int) because #removeCanvasIfNecessary() - * will remove the canvas. - */ - super.add(comp, constraints, index); } finally @@ -297,29 +176,10 @@ private void exitAddOrRemove() private void onContainerEvent(ContainerEvent ev) { - try - { - if (DEFAULT_BACKGROUND_COLOR != null) - { - int componentCount = getComponentCount(); - - if ((componentCount == 1) - && (getComponent(0) - == VideoContainer.this.noVideoComponent)) - { - componentCount = 0; - } - - setOpaque(componentCount > 0); - } - } - finally + synchronized (syncRoot) { - synchronized (syncRoot) - { - if (inAddOrRemove != 0) - validateAndRepaint = true; - } + if (inAddOrRemove != 0) + validateAndRepaint = true; } } @@ -337,13 +197,6 @@ public void remove(Component comp) { super.remove(comp); - if ((comp == canvas) - && (canvas != null) - && (canvas.getParent() != this)) - { - canvas = null; - } - Component[] components = getComponents(); VideoLayout videoLayout = (VideoLayout) getLayout(); boolean hasComponentsAtCenterRemote = false; @@ -365,8 +218,6 @@ public void remove(Component comp) { add(noVideoComponent, VideoLayout.CENTER_REMOTE); } - - removeCanvasIfNecessary(); } finally { @@ -391,9 +242,6 @@ public void removeAll() { super.removeAll(); - if ((canvas != null) && (canvas.getParent() != this)) - canvas = null; - if (noVideoComponent != null) add(noVideoComponent, VideoLayout.CENTER_REMOTE); } @@ -402,38 +250,4 @@ public void removeAll() exitAddOrRemove(); } } - - /** - * Removes {@link #canvas} from this <tt>VideoContainer</tt> if no sibling - * <tt>Component</tt> needs it. - */ - private void removeCanvasIfNecessary() - { - if ((canvas == null) || !OSUtils.IS_MAC) - return; - - boolean removeCanvas = true; - - for (Component component : getComponents()) - { - if (component == canvas) - continue; - try - { - component.getClass().getMethod( - VIDEO_CANVAS_FACTORY_METHOD_NAME); - removeCanvas = false; - break; - } - catch (NoSuchMethodException nsme) - { - /* - * Ignore it because we already presume that component does not - * need the canvas. - */ - } - } - if (removeCanvas) - remove(canvas); - } } diff --git a/src/org/jitsi/util/swing/VideoLayout.java b/src/org/jitsi/util/swing/VideoLayout.java index d3a94827..2e34da87 100644 --- a/src/org/jitsi/util/swing/VideoLayout.java +++ b/src/org/jitsi/util/swing/VideoLayout.java @@ -301,6 +301,7 @@ else if (remoteCount > 0) int columns = calculateColumnCount(remotes); int columnsMinus1 = columns - 1; int rows = (remoteCount + columnsMinus1) / columns; + int rowsMinus1 = rows - 1; Rectangle bounds = new Rectangle( 0, @@ -314,31 +315,47 @@ else if (remoteCount > 0) */ (parentSize.width - (columnsMinus1 * HGAP)) / columns, parentSize.height / rows); - int i = 0; - for (Component remote : remotes) + for (int i = 0; i < remoteCount; i++) { + int column = i % columns; + int row = i / columns; + /* - * We want the remote videos ordered from right to left so that - * the local video does not cover a remote video when possible. - */ - /* - * We account for the HGAP between the Components being laid out - * by this VideoLayout. + * On the x axis, the first column starts at zero and each + * subsequent column starts relative to the end of its preceding + * column. */ - bounds.x - = (columnsMinus1 - (i % columns)) * (bounds.width + HGAP); - bounds.y = (i / columns) * bounds.height; + if (column == 0) + { + bounds.x = 0; + /* + * Eventually, there may be empty cells in the last row. + * Center the non-empty cells horizontally. + */ + if (row == rowsMinus1) + { + int available = remoteCount - i; + + if (available < columns) + { + bounds.x + = (parentSize.width + - available * bounds.width + - (available - 1) * HGAP) + / 2; + } + } + } + else + bounds.x += (bounds.width + HGAP); + bounds.y = row * bounds.height; super.layoutComponent( - remote, + remotes.get(i), bounds, Component.CENTER_ALIGNMENT, Component.CENTER_ALIGNMENT); - - i++; - if (i >= remoteCount) - break; } } -- GitLab