From 120855b88a15f731db18b063e69aa59d7bf36d6f Mon Sep 17 00:00:00 2001 From: Juan Carlos de Guzman Torres Date: Thu, 12 Aug 2010 23:26:17 +0800 Subject: [PATCH] Initial commit. corresponds to 1.0-1 release --- data/26x26/flashstrobe.png | Bin 0 -> 2011 bytes data/48x48/flashstrobe.png | Bin 0 -> 4464 bytes data/64x64/flashstrobe.png | Bin 0 -> 6235 bytes data/maemo/flashstrobe.xpm | 291 +++++++++++++++++++++++++++ debian/changelog | 6 + debian/compat | 1 + debian/control | 120 +++++++++++ debian/copyright | 28 +++ debian/flashstrobe.postinst | 5 + debian/rules | 85 ++++++++ flashstrobe.pro | 9 + src/camera.cpp | 468 +++++++++++++++++++++++++++++++++++++++++++ src/camera.h | 215 ++++++++++++++++++++ src/flashstrobe.desktop | 9 + src/main.cpp | 62 ++++++ src/mainwindow.cpp | 121 +++++++++++ src/mainwindow.h | 89 ++++++++ src/mainwindow.ui | 68 +++++++ src/musicplayer.cpp | 156 +++++++++++++++ src/musicplayer.h | 115 +++++++++++ src/src.pro | 49 +++++ 21 files changed, 1897 insertions(+) create mode 100644 data/26x26/flashstrobe.png create mode 100644 data/48x48/flashstrobe.png create mode 100644 data/64x64/flashstrobe.png create mode 100644 data/maemo/flashstrobe.xpm create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100755 debian/flashstrobe.postinst create mode 100755 debian/rules create mode 100644 flashstrobe.pro create mode 100644 src/camera.cpp create mode 100644 src/camera.h create mode 100644 src/flashstrobe.desktop create mode 100644 src/main.cpp create mode 100644 src/mainwindow.cpp create mode 100644 src/mainwindow.h create mode 100644 src/mainwindow.ui create mode 100644 src/musicplayer.cpp create mode 100644 src/musicplayer.h create mode 100644 src/src.pro diff --git a/data/26x26/flashstrobe.png b/data/26x26/flashstrobe.png new file mode 100644 index 0000000000000000000000000000000000000000..f24c18876a925a47d2c0a29b478ba6da35f22b06 GIT binary patch literal 2011 zcmV<12PF83P)1j383*=ABFKT zpq)w5xRy>HwwX+4qU}tYRFgK7L_5~RPRG<~j6v&+wv)`*m|!xKnKmINpm`aqMnnk+ zh_C_zvcR(My_aAAAQGvm&G)Z+=bU@K_dM=B$Hf1^{oC6Lr4;Lhkd;ElvoK8QLQ0~s zaGw;yE2OBCQXFeMy!P^)?3n(Sz_X*%Eu^T4M57)#ZbDHlOmihul9z<4Xtedl=pPy( z7#zj#AHp}>Un`~9-2UcBqchA)aRl~=tTPm1e=(_D9;g~@*4#^4M z9`Cpg2R;zgfAJ+<-7QCi6q|?ZHjUntE4Lb$UGc=>GmT$7xMrS}*SD`FdzypJzA?5R zy2z!jFw06(0cf}oV%r-5K5J3v98}0ogRC^DC^3_il1+agvDAC5EhpOf&)VCFJUco) z-rlZ1tXt?{&y%ZB6*I5Zp69Wb>S^g7qk3fycjqMmaOUzD7p{Z|M4*4f%xA4Cx(2f{ zpezRzODY#SMoUMXb1%y7y00gRJUcqw!Eo^XNTAF9_idG^ikTljQ_G$srx4QM-sQP$ zeW(moF#}MNYv(8Bi7YNu@%iIi8!~9VrgC)vmK4J5Oz8G!(b#-(b=1A=Fg+iK%m6}) z8t=6$u6 z%uy~}h2xE2QDM_s3rm+&x_}x0<^Jt$g=1r*uT?H^@Nm^EuJrnObmwuT9OvM(l~k{p z!-;d<VU?OLzshn!+E)FCu zIAWGktPe%P{BUkM0DpY_JW`r?prVistBRs29SrHIEU&7Y{K#&#d7s`1Rmg$#{G*t+*5 z`+vJ;l4#@FA~voqno{o1AL`(qf&@IvEu3l%(Bd@#7INI+PRl^oZIxyr<5@`#jdYid z!I20)%D}4I zvQ!a|r||JoU6S< zG+h~{YLSbKRLRwW0PVd_7S7U`lkLFiOifqi_&AE90$?(m&{Pdoo!Bdi8IxJ1vCT(Z z#1SG+T*PtMEtB3fcMcJb1c}FE07Ro9!Vwcv3P3~1I9ADazR*5EI2>Shb^=lwG_~KrtlB8Z&?a+kGAn&%DTH?f~o8-%^FW*ev6e&znZ8ca#yoABQe* zC8`XJ#PMFgfmOG8&ENDB+Im6&%qvVq(^L+=*GY=g!j50eM^!aeEttW}Ppn|y)>V@~ z1i*deg*5EjfGg3;pWZl2I1;2ddm^;WT>)aTFuHE5GfOFsMPpIUcT5m%zAu*qo6gB5 zA0M2)&bl9DviGT_m`nz2+We?|)b_^_Fy$1h>XFi%w%0`Pg$4GhD; zs@snNQ1sBdZ?D>N#%S&e8irvQZ#DE8OMmr=vGU22#`|CP8HQmPK7Z5*hU3O}p|-x& za8>@rVDXE_t8aZ}7=~e-ZM|WXKKh|i@tccp!#AI5O7Vtz|Cs-=-VvLjutzCX*XFHjeYQ<#wwg<^^gROf%W!qmrClV9fzsmyU+)1^0IN{NZX{Phw%AgVpoXNOo8_-!VpePk^Hzd-=R+fc52B z02l`Rd}lrHp16WlS9xjEa&|wl5|atGzVZ<*y;fYV=|8L6m49Z^BLIKPv9FEvl|^2k zxl|fDrFnMBW;$83z>O~;35F#dy+Q6>mQG@V#;di>)Sv66;+{+nJ-3?5#W_S`f@fbl z$A%{BrjRLNb+%^t>awZrl9c?=wcfljtTaD|UM!N7CbUyYlZmoJ_&u7u`UOE7k2ubSC3WaFXFp zW=^gXDFuyf!`v7RV=^gNbQ?}bYOSu@HrMUS|Ni6Fe-Rccin?CcZIxEtmSwj)({+m# t&0_7d>Nc;g+v=>k{n&{=m)voH{10vDP2r1stMmW>002ovPDHLkV1jR^;|u@* literal 0 HcmV?d00001 diff --git a/data/48x48/flashstrobe.png b/data/48x48/flashstrobe.png new file mode 100644 index 0000000000000000000000000000000000000000..beb0b5178a90aa0827809acef1caeeca75b61902 GIT binary patch literal 4464 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 c #8AAEFA", +", c #8EB1FF", +"' c #6997F9", +") c #5284E9", +"! c #4779DA", +"~ c #396BC7", +"{ c #275AB0", +"] c #497AD5", +"^ c #3265BE", +"/ c #85A3DA", +"( c #BFD0EE", +"_ c #E9EFFA", +": c #FFFFFF", +"< c #ECF2FF", +"[ c #CDDDFF", +"} c #A3C0FF", +"| c #5283E7", +"1 c #275AB2", +"2 c #5382DF", +"3 c #3567BF", +"4 c #3966AD", +"5 c #CDD9EC", +"6 c #F6F9FE", +"7 c #EFF4FE", +"8 c #DCE7FF", +"9 c #75A0FB", +"0 c #3467C4", +"a c #15499C", +"b c #1F53A6", +"c c #6E8DBA", +"d c #F6F8FB", +"e c #DEE6F2", +"f c #6D90CC", +"g c #8BA8DC", +"h c #BACEF4", +"i c #5285ED", +"j c #6D9AF9", +"k c #95B7FF", +"l c #E8EFFF", +"m c #F9FBFF", +"n c #A5C2FF", +"o c #4679DB", +"p c #0E4394", +"q c #3668C0", +"r c #7391BF", +"s c #FEFEFF", +"t c #94ABCF", +"u c #1B4E9F", +"v c #1C51A8", +"w c #A9BDE1", +"x c #A8C0EC", +"y c #4F80E2", +"z c #5C8EF8", +"A c #6797FF", +"B c #BAD0FF", +"C c #FEFFFF", +"D c #2B5FBA", +"E c #4879D4", +"F c #3764AB", +"G c #4E74AC", +"H c #003685", +"I c #093F91", +"J c #5F83BC", +"K c #F8FAFC", +"L c #FCFDFE", +"M c #DDE7F9", +"N c #8AACF3", +"O c #6193FF", +"P c #8FB3FF", +"Q c #749FF9", +"R c #0E4396", +"S c #2B5DB2", +"T c #CCD7E9", +"U c #96ADD0", +"V c #083E8E", +"W c #134691", +"X c #A8BAD5", +"Y c #8EAADC", +"Z c #B8CAEC", +"` c #F0F4FC", +" . c #C4D5F9", +".. c #6695F8", +"+. c #477ADC", +"@. c #4272CC", +"#. c #7C9ACB", +"$. c #DDE5F1", +"%. c #194D9C", +"&. c #0D4293", +"*. c #ABBDD8", +"=. c #C0CDE1", +"-. c #D3DEEE", +";. c #2559B3", +">. c #2E62BF", +",. c #4777CE", +"'. c #BFD0F1", +"). c #C3D5F9", +"!. c #194EA4", +"~. c #386AC3", +"{. c #B9C9E4", +"]. c #6588C1", +"^. c #164A9D", +"/. c #5E81B9", +"(. c #ACBED9", +"_. c #7F9BC3", +":. c #A2B7D8", +"<. c #376BCA", +"[. c #3465BD", +"}. c #E6ECF6", +"|. c #3664AF", +"1. c #1A4EA2", +"2. c #D4DEED", +"3. c #ECF0F7", +"4. c #20519B", +"5. c #B8C8DF", +"6. c #7B9DDC", +"7. c #4376D9", +"8. c #0A4092", +"9. c #4371C2", +"0. c #EAEFF7", +"a. c #2356AB", +"b. c #2657A9", +"c. c #FBFCFE", +"d. c #ACBEDC", +"e. c #124798", +"f. c #EFF2F8", +"g. c #4573C6", +"h. c #6593F3", +"i. c #12479B", +"j. c #4070CA", +"k. c #6E92D0", +"l. c #BFCEE9", +"m. c #527ABD", +"n. c #7F9CCB", +"o. c #194C9E", +"p. c #456FAF", +"q. c #426CAB", +"r. c #3E68A7", +"s. c #3B65A4", +"t. c #A2B6D3", +"u. c #F1F4FA", +"v. c #8BA8DB", +"w. c #6992DF", +"x. c #497CE1", +"y. c #CBDAFA", +"z. c #1F54AD", +"A. c #3D6EC8", +"B. c #7195D4", +"C. c #C0D0EA", +"D. c #2C5EB5", +"E. c #567EC1", +"F. c #829FCD", +"G. c #114698", +"H. c #AEC0D9", +"I. c #C7D3E7", +"J. c #86A3D5", +"K. c #628BD5", +"L. c #4074D6", +"M. c #C8D7F6", +"N. c #275BB5", +"O. c #4D7ACC", +"P. c #EBF0F9", +"Q. c #3062BA", +"R. c #3363B7", +"S. c #FCFCFE", +"T. c #B0C3E1", +"U. c #1F52A6", +"V. c #D8E1ED", +"W. c #99AFD1", +"X. c #13489C", +"Y. c #AEC1E0", +"Z. c #3567C1", +"`. c #ECF1FB", +" + c #5B8AE8", +".+ c #285DB8", +"++ c #E8EEF9", +"@+ c #4A76C5", +"#+ c #D8E1F1", +"$+ c #EEF2F9", +"%+ c #3463B2", +"&+ c #174A9A", +"*+ c #FBFCFD", +"=+ c #6888B7", +"-+ c #1C4E9A", +";+ c #ECF1F7", +">+ c #D5DFEF", +",+ c #4372C6", +"'+ c #3E72D4", +")+ c #3064C1", +"!+ c #3A6BC4", +"~+ c #C3D3EF", +"{+ c #7A9CD7", +"]+ c #3567BE", +"^+ c #7394D0", +"/+ c #B6C7E4", +"(+ c #5C81BE", +"_+ c #A3B8D9", +":+ c #B6C6DD", +"<+ c #DCE3EE", +"[+ c #386CCB", +"}+ c #3365BD", +"|+ c #93B0E5", +"1+ c #E3EAF7", +"2+ c #4070C5", +"3+ c #B8C9E7", +"4+ c #5D82C1", +"5+ c #A7BAD5", +"6+ c #4273CC", +"7+ c #D6E1F5", +"8+ c #ABC0E7", +"9+ c #396BC3", +"0+ c #4170C2", +"a+ c #F5F7FB", +"b+ c #ADBFD9", +"c+ c #2D60BB", +"d+ c #3F72D4", +"e+ c #2558AE", +"f+ c #638CDA", +"g+ c #F8FAFD", +"h+ c #7799D8", +"i+ c #FDFEFE", +"j+ c #7191C2", +"k+ c #3865AD", +"l+ c #3B6ECF", +"m+ c #2D60B6", +"n+ c #99B4E8", +"o+ c #5C83C6", +"p+ c #5C81BD", +"q+ c #2B5FBB", +"r+ c #3A6CC4", +"s+ c #E4EAF5", +"t+ c #92ABD5", +"u+ c #1A4FA4", +"v+ c #4679DD", +"w+ c #2457AC", +"x+ c #628BDA", +"y+ c #E3E9F6", +"z+ c #3663AA", +"A+ c #2C60BC", +"B+ c #0C4191", +"C+ c #3869C1", +"D+ c #3A6DCE", +"E+ c #13489A", +"F+ c #2155AA", +"G+ c #2E60B7", +"H+ c #4875C7", +"I+ c #3F6DBF", +"J+ c #2B5EB6", +"K+ c #2C5FB9", +"L+ c #3266C2", +"M+ c #2357B0", +" . + @ # $ % ", +" & * = - ; > , ' ) ! ~ { ", +" ] ^ / ( _ : : : : < [ } | 1 ", +" 2 3 4 5 : : : : : 6 7 : : : 8 9 0 a ", +" 2 b c d : e f g : : h i j k l : m n o p ", +" q r : s t u v w : : x y i z A B C : n D ", +" E F d s G H I J K : : : L M N z O P C m Q R ", +" & S T : U V W X : : : L Y Z ` : ...O B : 8 +.H ", +" @.#.: $.%.&.*.: =.: : -.;.>.,.'.: ).z A l : } !. ", +" ~.{.: ].^./.: (._.: : :.v ;.>.<.'.: N z k : [ >. ", +". [.}.: |.1.2.3.4.5.: : : : : : : 6.` M i j : < 7.8.", +"+ 9.: 0.a.b.c.d.e.f.: : : : : : : g.Z L y i 7 : h.i.", +"j.k.: l.{ m.: n.o.p.q.r.s.t.: : u.;.v.: w.x.y.: , z.", +"A.B.: C.D.E.: F.1.^.G.&.V H.: : I.v J.: K.L.M.: > N.", +"$ O.: P.Q.R.S.T.U.1.^.G.&.V.: : W.X.Y.S.Z.<.`.: +.+", +"% A.++: @+Q.#+$+%+U.1.^.&+*+: : =+-+;+>+;.,+: _ '+)+", +" !+~+: {+]+^+: /+a.(+_+d.: : : :+<+: J v f : ( [+ ", +" }+|+: 1+2+]+3+: /+4+: : : : : : : 5+I u e : / <. ", +" { 6+7+: 8+9+0+3+: $+a+: : : : : b+W H t : 5 c+d+ ", +" e+f+g+s h+9+]+^+#+i+: : : L j+&.V G s d k+l+ ", +" m+n+: s 8+2+]+Q.o+: : s p+^.%.U s : c q+ ", +" a r+n+g+: 1+{+@+Q.s+: t+|.].$.: d r u+v+ ", +" p w+x+7+: : : P.y+$+0.: : : T z+A+v+ ", +" B+C+|+~+++: : : : }.{.#.e+D+ ", +" H E+F+G+H+B.k.I+J+K+L+d+ ", +" 8.i.v M+.+)+ "}; diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..8d32e94 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +flashstrobe (1.0-1) unstable; urgency=low + + * Initial packaging + + -- Juan Carlos Torres Wed, 11 Aug 2010 15:48:56 +0800 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..2b661e3 --- /dev/null +++ b/debian/control @@ -0,0 +1,120 @@ +Source: flashstrobe +Section: user/other +Priority: extra +Maintainer: Juan Carlos Torres +Build-Depends: debhelper (>= 5), libqt4-dev +Standards-Version: 3.7.2 + +Package: flashstrobe +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +XB-Description: Strobe light program for the N900 + Use the N900's flash LEDs as a strobe light. The user can set the + frequency of the strobing in beats per minute (bpm). Additionally, + the user can open any audio file to play in the background. The + camera shutter need to be kept open to use this program. And for + best results, please close any program using the camera. + . + Do not point the flash at anyone's eyes. +XB-Maemo-Display-Name: Flash Strobe +XB-Maemo-Icon-26: + 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 + psNh8q7VqXD85IgA0DB0ZlVkkOFKnUBzcJCEoYNlJk/AEu8I00QIk/2n0tJN + ls0pSAsDdhwKOn0r5hZz67KKDwUxZULK9H6QTjZ2Yhg6n7u2ihsWT3Tat77T + nBY7La3JTpu3p76PWLwPWdFQVe0dVQixUwizf0jXvU0dOh0hnXG5tmItnZ3H + 5lfOM1zj29sQ4g9727hxsR06fP+OGvbVd9Lebbv+u1ZPZWF1oeMD8rMyuBxt + +vZKXKrM8rnlTtuLO87w+r5mR7ElCZbNSYlge88Qp1siSfnX+lVV2ykffnbF + gBBix+BAP7KisO9USkyKctysnFfoyLQsK2x66QzBsJ1hBTI1Nt+7gOL8TGRZ + JhwzWDV/PNctmMD1C8uYN73wsgDWXFXJqgUVaKotHq1dUe57ancqYjV0Vs0r + pDgvtQlvHQ9hGHakqqrajn1PzR1I5gNim57QEWaCN470YlmpD33txnLcLtUB + ER+0eOiF007/3Km5bH98Jbcuq2DXkXZ0Y3Ri81Ho7o1/ojscdURHshJ85wsz + nX7LglffbsUwDRRFRVW1rTCc0FhiqxAiFu4L0xzUeet4KjYpyXPz2WUlTggs + yzIHTvfyqz81OWMCmRqPf30uP/7mAhqawn8184/+Zj87DjSl5Q53rp5MeVEq + SPzj3lbqG3tsB6ZqMVXVtkEyJ+46/tuBvOrbXIOD/cv8mQGaOw1umJ9SwE9N + DnD0XJTOXt2ppBx8L8zxxl7mTc3B57HN3KQSP8V5Xj4qtXXH+OKG7Ty/7QR2 + zmVXOxZVl/Dcv9c6zlI3BPc8vpd+HbICeaiq9sibT0yvg7SqhLlJCBEMdrXT + 1SfYti/kfEhVJDbeNZni3IxRJ3Hbg/v5w962v3rXt719noVffZFdRy6mWbGy + cQFeevhGXGoqVHl22yma2nqHQ+igqmibhvucUaH6l/XsGev6B4cGV3szMjnb + Lpg9yUNBll2g8bgV5k3NZv+pXuJDwjkJ3bB482gn9ed7SSQEsiyR63dftuxu + WfDYfx3mgZ/vYVBP2DWOZLVjQqGfbU9+hkmlKdP5bkM76x97E483m8LCUlRF + e2DHo1V7RgEAyJr+maNCiLW9kd5x2Vk5HDk3xNWz/GRm2MNy/Bq1c/M51RJP + EyeQuNDZz64jQV7a2UJHaIDlVxSNCeCJ3x7jJy8ehxHVUgmJBdXF1P1kHRUl + KeYvBiNc9+1XGDIVJlfW4NLcx1RVW3/uz5vHLi32nd4i/FNved00E1/sjfRm + +v0F1DcPsGx2AC1ZUve4Fa67Mh89YfH+xfiIeqfk7PrFzn7uuL5ilBPbdbiN + f/vPAyNaJNyqzNdvreGZ79Wm1ZhiAzrX3/sSja0RZs1cgNfj71JVbUXdxvI0 + KzEqJo6+/2pf5uS17+rG0JfiA3FFdedx+EyMeVMynZOQZYkrp2Wx6soCwrEE + zR0DWCNA6IaguiKLieNSBYJLnXG+8vDbDOkmICHLsHZJBS9sqOWWa6rSottL + nVFW/+sWjp3rYsb0eeTmFBmqqq2p21h+4oP8jhnUx89ubfFUrumK98fWxGIx + FFcOfz4ZY3pZhqMTAH6vyvI5eaxZVERpvgfDtAiGdSxAkeHapBgNGYK7H91L + W08/C2cW8tUbp/Gj9Qv4wqopZPvSK3vvNnSw5v5XaemIM3XKpygqmICqav9S + t7F8y1i8fugVU/bKX6wXQvzU483UZk2fg8/r5Usr8li7KBdNHXvqwJBJV+8Q + vTGD6kkBZEmiuSMOWBTlePC4x06EdMPkma31/PBX+7HQqKqswefLMVRVu7du + Y/llr5j+4hWdb/lPlwphviLLSkH1tDnk5xVSkCXz5ZUFLJud/ckv+Sx47e0m + HnnhEC3tETIzsygrm4bb5elSVW1d3cbyj3/JN0wZV29yrllzcvKZVjUTv8/P + xCIXK6/IZtGMgBMAflS61BVnx8E2frerkZONPaiqi7y8EgKBPFRFO6aq2s11 + G8s/+TXrMKmLHlOFZV90A0WlxROoLJ+Mx+tDmCYV41wsnJFFWaGbvCyNgiwX + BVk2qM7eIYLhQbrCg5xrjbLzcDunmkKYpokkq/h8Ofj9ucNO6iFV1Z6p21j+ + t7voTqP5D/uw6/P3Az6vx0tBfjH5uQUE/FlYluVUJIRpOtUKIUxMM/lugaxo + uFweXC7PcGzzpKpom3Y8WvX3+anBGEDysCvEa0Gq1VTNq7nceD2ZZLg9uF1u + NJfb+YCFhCxrKIqCqrqG4/kdqqptU1Vt65tPTP/H/NhjLNIWP+FRVG2FpmpL + VFUrVVWtxHnamVObqrpaVVVNPrV3VFXbue+puZ/45zb/D69n+b2nYzkjAAAA + AElFTkSuQmCC diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..becaf09 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,28 @@ +This package was debianized by Juan Carlos Torres on +Sat, 31 Jul 2010 16:36:41 +0800. + +Upstream Author: Juan Carlos Torres + +Copyright: 2010 by Juan Carlos Torres + +License: + + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This package 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. + +The Debian packaging is (C) 2010, Juan Carlos Torres and +is licensed under the GPL, see above. diff --git a/debian/flashstrobe.postinst b/debian/flashstrobe.postinst new file mode 100755 index 0000000..4a45a4f --- /dev/null +++ b/debian/flashstrobe.postinst @@ -0,0 +1,5 @@ +#!/bin/sh + +gtk-update-icon-cache -f /usr/share/icons/hicolor + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..9f8a821 --- /dev/null +++ b/debian/rules @@ -0,0 +1,85 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +APPNAME = flashstrobe + +builddir: + mkdir -p builddir + +builddir/Makefile: builddir + cd builddir && qmake-qt4 PREFIX=/usr ../$(APPNAME).pro + +build: build-stamp + +build-stamp: builddir/Makefile + dh_testdir + # Add here commands to compile the package. + #$(MAKE) + #docbook-to-man debian/flashstrobe.sgml > flashstrobe.1 + cd builddir && $(MAKE) + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + # Add here commands to clean up after the build process. + # -$(MAKE) clean + rm -rf builddir + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/flashstrobe. + cd builddir && $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/$(APPNAME) install + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installchangelogs + dh_installdocs + dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + dh_strip --dbg-package=flashstrobe-dbg + dh_compress + dh_fixperms +# dh_perl +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/flashstrobe.pro b/flashstrobe.pro new file mode 100644 index 0000000..36119cd --- /dev/null +++ b/flashstrobe.pro @@ -0,0 +1,9 @@ +QMAKEVERSION = $$[QMAKE_VERSION] +ISQT4 = $$find(QMAKEVERSION, ^[2-9]) +isEmpty( ISQT4 ) { +error("Use the qmake include with Qt4.4 or greater, on Debian that is qmake-qt4"); +} + +TEMPLATE = subdirs +SUBDIRS = src + diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 0000000..ec2652a --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,468 @@ +/* + Copyright (C) 2010 by Juan Carlos Torres + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor appro- + ved by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#include "camera.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/** + * This section sets up the necessary types and methods + * to create a D-Bus connection using Qt. + */ + +#define HAL_CAM_SHUTTER_UDI "/org/freedesktop/Hal/devices/platform_cam_shutter" +#define HAL_CAM_SHUTTER_STATE "button.state.value" + +Q_DECLARE_METATYPE(Property) +Q_DECLARE_METATYPE(QList) + +const QDBusArgument & operator<<(QDBusArgument &arg, const Property &change) +{ + arg.beginStructure(); + arg << change.name << change.added << change.removed; + arg.endStructure(); + return arg; +} +const QDBusArgument & operator>>(const QDBusArgument &arg, Property &change) +{ + arg.beginStructure(); + arg >> change.name >> change.added >> change.removed; + arg.endStructure(); + return arg; +} + + +/** + * Camera class definition + */ + +int Camera::m_fd = 0; +char Camera::m_deviceName[15] = ""; + +Camera::Camera(QObject* parent) : QObject(parent) +{ + m_buffers = NULL; + m_numBuffers = 0; +} + +Camera::~Camera() +{ + if (m_fd != -1) + { + close(); + } +} + +/** + * Open and acquire a file descriptor for a file connected to + * the character device representing the camera, usually /dev/video0 + */ +int Camera::open(char* device) +{ + struct stat st; + + if (device == NULL) + { + qDebug() << "Device name not specified"; + return Camera::GenericError; + } + + memcpy(m_deviceName, device, sizeof(m_deviceName)); + + if (stat(m_deviceName, &st) == -1) + { + qDebug() << "Cannot identify device:" << m_deviceName; + return Camera::GenericError; + } + + if (!S_ISCHR(st.st_mode)) + { + qDebug() << "No such device: " << m_deviceName; + return Camera::GenericError; + } + + m_fd = ::open(m_deviceName, O_RDWR | O_NONBLOCK, 0); + + if (m_fd == -1) + { + qDebug() << "Cannot open device: " << m_deviceName; + return Camera::GenericError; + } + + return m_fd; +} + +int Camera::close() +{ + if (m_fd != -1) + { + if (::close(m_fd) == -1) + { + qDebug() << "Cannot close device: " << m_deviceName; + return Camera::GenericError; + } + } + + m_fd = -1; + + return Camera::NoError; +} + +/** + * Initializes the camera by setting up the + * cropping rectangle, data format and memory buffers + * + * Based on @ref http://v4l2spec.bytesex.org/spec/capture-example.html + */ +int Camera::init() +{ + struct v4l2_cropcap cropcap; + struct v4l2_crop crop; + struct v4l2_format fmt; + struct v4l2_requestbuffers req; + + // Set cropping rectangle + cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(m_fd, VIDIOC_CROPCAP, &cropcap) != -1) + { + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + crop.c = cropcap.defrect; // reset to default + + if (ioctl(m_fd, VIDIOC_S_CROP, &crop) == -1) + { + qDebug() << "Unable to set cropping rectangle"; + return Camera::GenericError; + } + } + else + { + qDebug() << "Unable to get crop capabilities"; + return Camera::GenericError; + } + + // Set data format + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = 640; + fmt.fmt.pix.height = 480; + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; + + if (ioctl(m_fd, VIDIOC_S_FMT, &fmt) == -1) + { + qDebug() << "Unable to set data format"; + return Camera::GenericError; + } + + // Set up memory mapped buffers + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + + if (ioctl(m_fd, VIDIOC_REQBUFS, &req) == -1) + { + qDebug() << "No memory mapping support"; + return Camera::GenericError; + } + + if (req.count < 2) + { + qDebug() << "Insufficient buffer memory on device: " << m_deviceName; + return Camera::GenericError; + } + + m_buffers = static_cast(calloc(req.count, sizeof(*m_buffers))); + + if (!m_buffers) + { + qDebug() << "Out of memory"; + return Camera::GenericError; + } + + for (m_numBuffers = 0; m_numBuffers < req.count; ++m_numBuffers) + { + struct v4l2_buffer buf; + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = m_numBuffers; + + if (ioctl(m_fd, VIDIOC_QUERYBUF, &buf) == -1) + { + qDebug() << "Unable to query the status of buffer number: " << m_numBuffers; + return Camera::GenericError; + } + + m_buffers[m_numBuffers].length = buf.length; + m_buffers[m_numBuffers].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, + MAP_SHARED, m_fd, buf.m.offset); + + if (m_buffers[m_numBuffers].start == MAP_FAILED) + { + qDebug() << "Unable to map memmory"; + return Camera::GenericError; + } + } + + return Camera::NoError; +} + +int Camera::deinit() +{ + quint32 i; + + // Unmap memory mapped buffers + if (m_numBuffers > 0) + { + for (i = 0; i < m_numBuffers; ++i) + { + if (munmap(m_buffers[i].start, m_buffers[i].length) == -1) + { + qDebug() << "Unable to unmap memory"; + return Camera::GenericError; + } + } + + m_numBuffers = 0; + } + + // Free allocated memory + if (m_buffers) + { + free (m_buffers); + } + + m_buffers = NULL; + + return Camera::NoError; +} + +int Camera::stream(bool stream) +{ + enum v4l2_buf_type type; + + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + // Start or stop streaming + if (stream) + { + if (ioctl(m_fd, VIDIOC_STREAMON, &type) == -1) + { + qDebug() << "Camera::stream: Unable to start streaming"; + return Camera::GenericError; + } + } + else + { + if (ioctl(m_fd, VIDIOC_STREAMOFF, &type) == -1) + { + qDebug() << "Camera::stream: Unable to stop streaming"; + return Camera::GenericError; + } + } + + return Camera::NoError; +} + +/** + * Strobes the camera flash ONCE only + */ +int Camera::strobe() +{ + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_FLASH_STROBE; + + if (ioctl(m_fd, VIDIOC_S_CTRL, &ctrl) == -1) + { + qDebug() << "Cannot set flash"; + return Camera::GenericError; + } + + return Camera::NoError; +} + +/** + * Sets the LED intensity for strobe (flash) mode only. + * + * Formulas: + * code = (intensity - 35)/15 + * intensity = (code * 15) + 35 + * + * Range: 215mA to 500mA + * + * @param intensity Intensity in mA + */ +int Camera::setFlashIntensity(int intensity) +{ + struct v4l2_control ctrl; + int intensityCode = (intensity - 35)/15; + + // Set intensity to safe limits + if (intensityCode > 31) + { + intensityCode = 31; + } + else if (intensityCode < 0) + { + intensityCode = 0; + } + + // Set flash intensity + ctrl.id = V4L2_CID_FLASH_INTENSITY; + ctrl.value = intensityCode; + if (ioctl(m_fd, VIDIOC_S_CTRL, &ctrl) == -1) + { + qDebug() << "Cannot set intensity"; + return Camera::GenericError; + } + + if (intensity > 0) + { + stream(true); + } + else + { + stream(false); + } + + return Camera::NoError; +} + +int Camera::flashIntensity() const +{ + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_FLASH_INTENSITY; + + if (ioctl(m_fd, VIDIOC_G_CTRL, &ctrl) == -1) { + qDebug() << "Cannot get intensity"; + return Camera::GenericError; + } + + return 35 + (ctrl.value * 15); +} + +/** + * Sets the flash timeout. Works only in strobe (flash) mode. + * Formulas: + * 1 sec = 1,000 ms = 1,000,000 us (microseconds) + * + * Range: 54,600us to 820,000us (54.6ms to 820ms) + * + * @param timeout Timeout in microseconds + */ +int Camera::setTimeout(quint32 timeout) +{ + struct v4l2_control ctrl; + + // Set timeout to safe limits + if (timeout < 54600) + { + timeout = 54600; + } + else if (timeout > 820000) + { + timeout = 820000; + } + + // Set flash timeout + ctrl.id = V4L2_CID_FLASH_TIMEOUT; + ctrl.value = timeout; + + if (ioctl(m_fd, VIDIOC_S_CTRL, &ctrl) == -1) + { + qDebug() << "Cannot set timeout"; + return Camera::GenericError; + } + + return Camera::NoError; +} + +quint32 Camera::timeout() const +{ + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_FLASH_TIMEOUT; + + if (ioctl(m_fd, VIDIOC_G_CTRL, &ctrl) == -1) { + qDebug() << "Cannot get timeout"; + return Camera::GenericError; + } + + return ctrl.value; +} + +/** + * Sets up a D-Bus connection to listen for camera shutter + * state changes and calls the slot @ref shutterPropertyModified() + */ +void Camera::registerDbusWatcher() +{ + qDBusRegisterMetaType< Property >(); + qDBusRegisterMetaType< QList >(); + + QDBusConnection::systemBus().connect( + QString(), + HAL_CAM_SHUTTER_UDI, + "org.freedesktop.Hal.Device", + "PropertyModified", + this, + SLOT(shutterPropertyModified(int, QList))); +} + +/** + * Checks for the status of the camera shutter using D-Bus and HAL + */ +bool Camera::isShutterOpen() const +{ + QDBusInterface propertyInterface("org.freedesktop.Hal", + HAL_CAM_SHUTTER_UDI, + "org.freedesktop.Hal.Device", + QDBusConnection::systemBus()); + + bool isOpen = propertyInterface.call("GetProperty", + HAL_CAM_SHUTTER_STATE).arguments().at(0).toBool(); + + return !isOpen; +} + +/** + * Called when camera shutter state changes. Checks for the + * actual state using @ref isShutterOpen() and emits the + * @ref shutterStateChanged() signal + */ +void Camera::shutterPropertyModified(int /*numUpdates*/, QList< Property > /*updates*/) +{ + bool isOpen = isShutterOpen(); + + emit shutterStateChanged(isOpen); +} diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 0000000..6a6e973 --- /dev/null +++ b/src/camera.h @@ -0,0 +1,215 @@ +/* + Copyright (C) 2010 by Juan Carlos Torres + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor appro- + ved by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#ifndef CAMERA_H +#define CAMERA_H + +#include +#include +#include +#include + +struct buffer +{ + void* start; + size_t length; +}; + +struct Property +{ + QString name; + bool added; + bool removed; +}; + +const QDBusArgument& operator<<(QDBusArgument& arg, const Property& change); +const QDBusArgument& operator>>(QDBusArgument& arg, const Property& change); + +/** + * @brief Qt-based class for accessing the N900 camera and flash LEDs + * + * This class provides easy access to the N900's camera and flash LED + * functionality, specifically initializing the camera and controlling + * the LED torch and flash modes. It also reports on the status of + * the camera shutter. + * + */ +// TODO: Implement torch functionality +class Camera : public QObject +{ + Q_OBJECT + + public: + /** + * Error codes for easier error message handling + */ + enum ErrorCode + { + NoError = 0, /**< No error */ + GenericError = -1 /**< Generic Error */ + }; + + Camera(QObject* parent = 0); + ~Camera(); + + /** + * Opens a character device connected to the camera + * and gets a file descriptor. + * + * @param device Device name, normally /dev/video0 + * @return @c int Identifying the file descriptor + * @return @c int -1 Of opening the device was unsuccessful + */ + static int open(char* device); + + /** + * Closes the character device connected to the camera. + * + * @return @c int 0 If closing the device was successful + * @return @c int -1 If closing the device was unsuccessful + */ + int close(); + + /** + * Initializes the camera. This specifically does the following: + * @li Get and set the cropping properties + * @li Set the camera data format + * @li Allocate memory-mapped buffers + * + * @return @c int 0 If initialization was successful + * @return @c int -1 If initialization was unsuccessful + */ + int init(); + + /** + * Deinitializes the camera, freeing any allocated memory + * used during initialization. + * + * @return @c int 0 If deinitialization was successful + * @return @c int -1 If deinitialization was unsuccessful + */ + int deinit(); + + /** + * Returns the current set flash intensity. This + * is different from the torch intensity used in + * torch modes. + * + * @return @c int The current flash intensity + */ + int flashIntensity() const; + + /** + * Returns the strobe timeout. Used only in strobe mode. + * + * @return @c quint32 Current timeout in microseconds + */ + quint32 timeout() const; + + /** + * Convenience function to create a D-Bus connection + * to listen for changes in the camera shutter status. + */ + void registerDbusWatcher(); + + /** + * Function to manually query the status of the camera + * shutter using D-Bus and HAL. + * + * @return @c true If the camera shutter is open + * @return @c false If the camera shutter is closed + */ + bool isShutterOpen() const; + + public slots: + + /** + * Starts or stops camera data streaming. Used to block + * and unblock the camera while using the flash. + * + * @param stream Whether streaming is on (@c true) or off (@c false) + * + * @return @c int 0 If starting or stopping the stream was successful + * @return @c int 1 If starting or stopping the stream was unsuccessful + */ + int stream(bool stream); + + /** + * Flash the LED in strobe mode. This will only flash + * the LED once. Repetition must be controlled by the + * client of this class. + * + * @return @c int 0 If strobing was successful + * @return @c int -1 If strobing was unsuccessful + */ + int strobe(); + + /** + * Sets the intensity of the LED in flash mode. + * + * @param intensity intensity in mA. Valid values range + * from 215 to 500 only + * + * @return @c int 0 If setting the flash intensity was successful + * @return @c int -1 If setting the flash intensity was unsuccessful + */ + int setFlashIntensity(int intensity); + + /** + * Sets the strobe timeout. Used only in strobe mode. + * + * @param timeout Timeout in microseconds. Valid values range + * from 54600 to 820000 only + */ + int setTimeout(quint32 timeout); + + /** + * Slot that is called when the camera shutter status + * changes, that is, when it is opened or closed. Internally + * calls @ref isShutterOpen() to get the current shutter + * status and emits the @ref shutterStateChanged() signal. + * + * @param numUpdates Unused parameter to match the signal signature + * @param updates Unused parameter to match the signal signature + */ + void shutterPropertyModified(int numUpdates, QList updates); + + signals: + /** + * Signal to notify change in the camera shutter status. + * Users of this class should connect to this to monitor + * the shutter state. + * + * @param open Determines whether the shutter is open (@c true) + * or closed (@c false). + */ + void shutterStateChanged(bool open); + + private: + static char m_deviceName[15]; + static int m_fd; + + quint32 m_numBuffers; + struct buffer* m_buffers; + +}; + +#endif diff --git a/src/flashstrobe.desktop b/src/flashstrobe.desktop new file mode 100644 index 0000000..0bfe1e8 --- /dev/null +++ b/src/flashstrobe.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Type=Application +Name=Flash Strobe +Exec=/usr/bin/flashstrobe +Icon=flashstrobe +X-HildonDesk-ShowInToolbar=true +X-Osso-Type=application/x-executable diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..003a002 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,62 @@ +/* + Copyright (C) 2010 by Juan Carlos Torres + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor appro- + ved by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + +/** + * Flash Strobe - Strobe light application for the N900 + * + * Use the N900's flash LEDs as a strobe light. The user can set the + * frequency of the strobing in beats per minute (bpm). Additionally, + * the user can open any audio file to play in the background. The + * camera shutters need to be kept open. For best results, close any + * program using the camera. + * + * 18 Do not point the flash at anyone's eyes + */ + +#include "camera.h" +#include "mainwindow.h" + +#include +#include + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + char device[15] = "/dev/video0"; + + // First check if there is even a camera at all. If none is found, notify the user and quit + if (Camera::open(device) == -1) + { + QMessageBox msg; + msg.setWindowTitle(QObject::tr("No Camera")); + msg.setText(QObject::tr("There was no camera found on this device. The program will now close")); + msg.exec(); + + return -1; + } + else + { + app.setApplicationName("flashstrobe"); + MainWindow window; + window.show(); + + return app.exec(); + } +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 0000000..cfdfbe9 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,121 @@ +/* + Copyright (C) 2010 by Juan Carlos Torres + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor appro- + ved by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#include "mainwindow.h" +#include "camera.h" +#include "musicplayer.h" + +#include +#include +#include + +MainWindow::MainWindow(QWidget* parent): QWidget(parent) +{ + m_camera = new Camera(this); + m_timer = new QTimer(this); + + //Setup the UI widgets and layout + m_ui = new Ui::MainWindow; + m_player = new MusicPlayer(this); + + m_ui->setupUi(this); + m_ui->verticalLayout->insertWidget(0, m_player, 0); + + m_ui->frequencyLabel->setFont(QFont("Sans Serif", 48)); + +#ifdef Q_WS_MAEMO_5 + setAttribute(Qt::WA_Maemo5PortraitOrientation,true); +#endif + + frequencyChanged(m_ui->frequencyDial->value()); + connect(m_ui->frequencyDial, SIGNAL(valueChanged(int)), this, SLOT(frequencyChanged(int))); + connect(m_ui->strobeButton, SIGNAL(toggled(bool)), this, SLOT(toggleStrobe(bool))); + connect(m_camera, SIGNAL(shutterStateChanged(bool)), this, SLOT(toggleAppState(bool))); + connect(m_timer, SIGNAL(timeout()), m_camera, SLOT(strobe())); + + // Start listening for camera shutter state changes + m_camera->registerDbusWatcher(); + + toggleAppState(m_camera->isShutterOpen()); +} + +MainWindow::~MainWindow() +{ + m_camera->deinit(); +} + +/** + * The user has changed the frequency, normally through the QDial. + * The flashing interval is computed as hertz (in milliseconds) while + * the actual flash LED timeout is computed as half of that (in microseconds). + * + * @param frequency Frequency in hertz + */ +void MainWindow::frequencyChanged(int frequency) +{ + m_ui->frequencyLabel->setText(QString("%1 bpm").arg(frequency*60)); + m_camera->setTimeout((1000000/frequency)/2); + m_timer->setInterval(1000/frequency); +} + +void MainWindow::toggleStrobe(bool checked) +{ + int timeout = m_ui->frequencyDial->value(); + if (checked) + { + if (m_camera->init() == -1) + { + QMessageBox::information(this, tr("Camera Unavailable"), + tr("Please close any application using the camera")); + m_ui->strobeButton->setChecked(false); + } + else + { + m_camera->setTimeout((1000000/timeout)/2); + m_camera->setFlashIntensity(215); + m_timer->start(1000/timeout); + } + } + else + { + m_timer->stop(); + m_camera->setTimeout(0); + m_camera->setFlashIntensity(0); + m_camera->deinit(); + } +} + +void MainWindow::toggleAppState(bool enable) +{ + m_ui->strobeButton->setEnabled(enable); + m_ui->frequencyDial->setEnabled(enable); + + if (!enable) + { + QMessageBox::information(this, tr("Shutter Closed"), + tr("Please open the camera shutter before using")); + + if (m_ui->strobeButton->isChecked()) + { + m_ui->strobeButton->setChecked(false); + } + } +} diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 0000000..d23c00d --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,89 @@ +/* + Copyright (C) 2010 by Juan Carlos Torres + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor appro- + ved by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class Camera; +class MusicPlayer; + +class QTimer; + +#include "ui_mainwindow.h" + +/** + * @brief Flash Strobe main window + * + * This is the main window for Flash Strobe. This simple + * class creates the widgets for controlling the flash + * and adds a MusicPlayer widget for playing music. + */ +class MainWindow : public QWidget +{ + Q_OBJECT + + public: + MainWindow(QWidget* parent = 0); + ~MainWindow(); + + public slots: + /** + * Slot for changing the strobing frequency. The actual + * frequency is computed to and displayed as beats per minute (bpm) + * + * @param frequency Strobing frequency in hertz. Valid range is + * from 2 to 8 Hz (120 to 600 bpm) + */ + void frequencyChanged(int frequency); + + /** + * Slot to turn strobing on or off. Strobing frequency is + * set by the user. Flash intensity is fixed at 215 mA. The + * strobing repetition is controlled by a QTimer. + * + * @param checked Determines if strobing is on (@c true) or off (@c false) + */ + void toggleStrobe(bool checked); + + /** + * Slot to enable or disable the widgets, depending on certain + * conditions, such as the camera shutter state. If the shutter + * is closed, widgets are disabled. The MusicPlayer widgets are + * controlled independently of the overall application state. + * + * @param enable Specifies if widgets are enabled (@c true) or disabled (@c false) + */ + void toggleAppState(bool enable); + + private: + Ui::MainWindow* m_ui; + + int m_timeout; + + Camera* m_camera; + MusicPlayer* m_player; + + QTimer* m_timer; +}; + +#endif diff --git a/src/mainwindow.ui b/src/mainwindow.ui new file mode 100644 index 0000000..e5226a8 --- /dev/null +++ b/src/mainwindow.ui @@ -0,0 +1,68 @@ + + + MainWindow + + + + 0 + 0 + 480 + 800 + + + + Flash Strobe + + + + + + + 48 + + + + Frequency + + + Qt::AlignCenter + + + + + + + 2 + + + 10 + + + 1 + + + 6 + + + false + + + true + + + + + + + Strobe + + + true + + + + + + + + diff --git a/src/musicplayer.cpp b/src/musicplayer.cpp new file mode 100644 index 0000000..7228d15 --- /dev/null +++ b/src/musicplayer.cpp @@ -0,0 +1,156 @@ +/* + Copyright (C) 2010 by Juan Carlos Torres + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor appro- + ved by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#include "musicplayer.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +MusicPlayer::MusicPlayer(QWidget* parent, Qt::WindowFlags flags): QWidget(parent, flags) +{ + // Create the Phonon objects and paths + m_player = new Phonon::MediaObject(this); + m_audio = new Phonon::AudioOutput(Phonon::MusicCategory, this); + Phonon::createPath(m_player, m_audio); + + // Setup the UI widgets and layout + QPushButton* openButton = new QPushButton(this); + openButton->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton)); + + m_rewindButton = new QPushButton(this); + m_rewindButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward)); + m_rewindButton->setEnabled(false); + + m_playButton = new QPushButton(this); + m_playIcon = style()->standardIcon(QStyle::SP_MediaPlay); + m_pauseIcon = style()->standardIcon(QStyle::SP_MediaPause); + m_playButton->setIcon(m_playIcon); + m_playButton->setCheckable(true); + m_playButton->setChecked(false); + m_playButton->setEnabled(false); + + m_filenameEdit = new QLineEdit(this); + m_filenameEdit->setPlaceholderText(tr("Open audio file")); + + QHBoxLayout* fileLayout = new QHBoxLayout; + fileLayout->addWidget(m_filenameEdit, 1); + fileLayout->addWidget(openButton, 0); + + QHBoxLayout* buttonsLayout = new QHBoxLayout; + buttonsLayout->addWidget(m_rewindButton, 0); + buttonsLayout->addWidget(m_playButton, 0); + + QVBoxLayout* mainLayout = new QVBoxLayout(this); + mainLayout->addLayout(fileLayout, 0); + mainLayout->addLayout(buttonsLayout, 0); + + setLayout(mainLayout); + + // Setup connections + connect(openButton, SIGNAL(clicked(bool)), this, SLOT(openFile())); + connect(m_filenameEdit, SIGNAL(textChanged(QString)), this, SLOT(enableButtons(QString))); + connect(m_playButton, SIGNAL(toggled(bool)), this, SLOT(playOrPause(bool))); + connect(m_rewindButton, SIGNAL(clicked(bool)), this, SLOT(rewind())); +} + +MusicPlayer::~MusicPlayer() +{ + +} + +void MusicPlayer::openFile() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open a music file"), QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); + + if (!filename.isEmpty()) + { + m_filenameEdit->setText(filename); + } +} + +void MusicPlayer::playOrPause(bool checked) +{ + QString filename = m_filenameEdit->text(); + + // Only set the currentSource if the filename is different + // to prevent rewinding the file + if (filename != m_player->currentSource().fileName()) + { + m_player->setCurrentSource(Phonon::MediaSource(filename)); + } + + // checked == true, play the file + if (checked) + { + m_playButton->setIcon(m_pauseIcon); + m_player->play(); + + // If the file cannot be played, do not play ("pause") + if (m_player->state() == Phonon::ErrorState) + { + m_playButton->setChecked(false); + } + } + else + { + m_playButton->setIcon(m_playIcon); + m_player->pause(); + } +} + +void MusicPlayer::enableButtons(QString filename) +{ + if (!filename.isEmpty()) + { + m_rewindButton->setEnabled(true); + m_playButton->setEnabled(true); + } + else + { + m_rewindButton->setEnabled(false); + m_playButton->setEnabled(false); + } +} + +void MusicPlayer::rewind() +{ + m_player->seek(0); +} + +void MusicPlayer::setVolume(qreal volume) +{ + m_audio->setVolume(volume); +} + +qreal MusicPlayer::volume() const +{ + return m_audio->volume(); +} diff --git a/src/musicplayer.h b/src/musicplayer.h new file mode 100644 index 0000000..3965f97 --- /dev/null +++ b/src/musicplayer.h @@ -0,0 +1,115 @@ +/* + Copyright (C) 2010 by Juan Carlos Torres + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor appro- + ved by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#ifndef MUSICPLAYER_H +#define MUSICPLAYER_H + +#include +#include + +class QPushButton; +class QIcon; +class QLineEdit; + +namespace Phonon +{ + class MediaObject; + class AudioOutput; + class VolumeSlider; +} + +/** + * @brief A simple Phonon-based music player widget + * + * This class implements a very simple widget for playing music + * using Phonon. Features include opening a file, playing/pausing, + * rewinding, and adjusting the volume. + */ +class MusicPlayer : public QWidget +{ + Q_OBJECT + + public: + MusicPlayer(QWidget* parent = 0, Qt::WindowFlags flags = 0); + virtual ~MusicPlayer(); + + /** + * Returns the current volume level. + * + * @return @c qreal Volume level, between 0 and 1.0 + */ + qreal volume() const; + + public slots: + /** + * Calls a QFileDialog for opening a file, initially + * from the platform's Music directory. + */ + void openFile(); + + /** + * Plays or pauses the file currently contained in the + * selection. Also updates the player buttons to the + * appropriate state. For example, the Play button + * displays a pause icon if the file is currently playing, + * and a play icon if the file is paused. + * + * @param checked Determines whether to play (@c true) or + * pause (@false) the file + */ + void playOrPause(bool checked); + + /** + * Rewinds the current audio file to teh beginning. + */ + void rewind(); + + /** + * Updates the state of the controls in the player depending on + * the state of the line edit indicating the audio file to play. + * If the line edit is not empty, the controls are enabled. Otherwise + * they are disabled. + * + * @param filename A string containing the contents of the line edit + */ + void enableButtons(QString filename); + + /** + * Sets the current volume level. + * + * @param volume Volume level, between 0 and 1.0 + */ + void setVolume(qreal volume); + + private: + Phonon::MediaObject* m_player; + Phonon::AudioOutput* m_audio; + + QPushButton* m_playButton; + QPushButton* m_rewindButton; + + QIcon m_playIcon; + QIcon m_pauseIcon; + + QLineEdit* m_filenameEdit; +}; + +#endif diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 0000000..95f6253 --- /dev/null +++ b/src/src.pro @@ -0,0 +1,49 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Sat Jul 31 16:32:47 2010 +###################################################################### + +TEMPLATE = app +TARGET = flashstrobe +DEPENDPATH += . +INCLUDEPATH += . +QT += dbus phonon + +# Input +HEADERS += camera.h mainwindow.h musicplayer.h +FORMS += mainwindow.ui +SOURCES += camera.cpp mainwindow.cpp musicplayer.cpp main.cpp + +unix { + #VARIABLES + isEmpty(PREFIX) { + PREFIX = /usr/local + } + BINDIR = $$PREFIX/bin + DATADIR =$$PREFIX/share + + DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\" + + #MAKE INSTALL + + INSTALLS += target desktop service iconxpm icon26 icon48 icon64 + + target.path =$$BINDIR + + desktop.path = $$DATADIR/applications/hildon + desktop.files += $${TARGET}.desktop + + service.path = $$DATADIR/dbus-1/services + service.files += $${TARGET}.service + + iconxpm.path = $$DATADIR/pixmaps + iconxpm.files += ../data/maemo/$${TARGET}.xpm + + icon26.path = $$DATADIR/icons/hicolor/26x26/apps + icon26.files += ../data/26x26/$${TARGET}.png + + icon48.path = $$DATADIR/icons/hicolor/48x48/apps + icon48.files += ../data/48x48/$${TARGET}.png + + icon64.path = $$DATADIR/icons/hicolor/64x64/apps + icon64.files += ../data/64x64/$${TARGET}.png +} -- 1.7.9.5