summaryrefslogtreecommitdiffstats
path: root/tools/qvfb
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:18:55 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:18:55 (GMT)
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /tools/qvfb
downloadQt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2
Long live Qt 4.5!
Diffstat (limited to 'tools/qvfb')
-rw-r--r--tools/qvfb/ClamshellPhone.qrc5
-rw-r--r--tools/qvfb/ClamshellPhone.skin/ClamshellPhone.skin30
-rw-r--r--tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-closed.pngbin0 -> 68200 bytes
-rw-r--r--tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-pressed.pngbin0 -> 113907 bytes
-rw-r--r--tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5.pngbin0 -> 113450 bytes
-rw-r--r--tools/qvfb/ClamshellPhone.skin/defaultbuttons.conf78
-rw-r--r--tools/qvfb/DualScreenPhone.skin/DualScreen-pressed.pngbin0 -> 115575 bytes
-rw-r--r--tools/qvfb/DualScreenPhone.skin/DualScreen.pngbin0 -> 104711 bytes
-rw-r--r--tools/qvfb/DualScreenPhone.skin/DualScreenPhone.skin29
-rw-r--r--tools/qvfb/DualScreenPhone.skin/defaultbuttons.conf78
-rw-r--r--tools/qvfb/LICENSE.GPL280
-rw-r--r--tools/qvfb/PDAPhone.qrc5
-rw-r--r--tools/qvfb/PDAPhone.skin/PDAPhone.skin18
-rw-r--r--tools/qvfb/PDAPhone.skin/defaultbuttons.conf36
-rw-r--r--tools/qvfb/PDAPhone.skin/finger.pngbin0 -> 40343 bytes
-rw-r--r--tools/qvfb/PDAPhone.skin/pda_down.pngbin0 -> 52037 bytes
-rw-r--r--tools/qvfb/PDAPhone.skin/pda_up.pngbin0 -> 100615 bytes
-rw-r--r--tools/qvfb/PortableMedia.qrc5
-rw-r--r--tools/qvfb/PortableMedia.skin/PortableMedia.skin14
-rw-r--r--tools/qvfb/PortableMedia.skin/defaultbuttons.conf23
-rw-r--r--tools/qvfb/PortableMedia.skin/portablemedia-pressed.pngbin0 -> 6183 bytes
-rw-r--r--tools/qvfb/PortableMedia.skin/portablemedia.pngbin0 -> 6182 bytes
-rw-r--r--tools/qvfb/PortableMedia.skin/portablemedia.xcfbin0 -> 41592 bytes
-rw-r--r--tools/qvfb/README51
-rw-r--r--tools/qvfb/SmartPhone.qrc5
-rw-r--r--tools/qvfb/SmartPhone.skin/SmartPhone-pressed.pngbin0 -> 111515 bytes
-rw-r--r--tools/qvfb/SmartPhone.skin/SmartPhone.pngbin0 -> 101750 bytes
-rw-r--r--tools/qvfb/SmartPhone.skin/SmartPhone.skin28
-rw-r--r--tools/qvfb/SmartPhone.skin/defaultbuttons.conf78
-rw-r--r--tools/qvfb/SmartPhone2.qrc5
-rw-r--r--tools/qvfb/SmartPhone2.skin/SmartPhone2-pressed.pngbin0 -> 134749 bytes
-rw-r--r--tools/qvfb/SmartPhone2.skin/SmartPhone2.pngbin0 -> 121915 bytes
-rw-r--r--tools/qvfb/SmartPhone2.skin/SmartPhone2.skin25
-rw-r--r--tools/qvfb/SmartPhone2.skin/defaultbuttons.conf52
-rw-r--r--tools/qvfb/SmartPhoneWithButtons.qrc5
-rw-r--r--tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.pngbin0 -> 103838 bytes
-rw-r--r--tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.pngbin0 -> 88470 bytes
-rw-r--r--tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin31
-rw-r--r--tools/qvfb/SmartPhoneWithButtons.skin/defaultbuttons.conf103
-rw-r--r--tools/qvfb/TouchscreenPhone.qrc5
-rw-r--r--tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone-pressed.pngbin0 -> 88599 bytes
-rw-r--r--tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.pngbin0 -> 61809 bytes
-rw-r--r--tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.skin16
-rw-r--r--tools/qvfb/TouchscreenPhone.skin/defaultbuttons.conf45
-rw-r--r--tools/qvfb/Trolltech-Keypad.qrc5
-rw-r--r--tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-closed.pngbin0 -> 69447 bytes
-rw-r--r--tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-down.pngbin0 -> 242107 bytes
-rw-r--r--tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.pngbin0 -> 230638 bytes
-rw-r--r--tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.skin35
-rw-r--r--tools/qvfb/Trolltech-Keypad.skin/defaultbuttons.conf142
-rw-r--r--tools/qvfb/Trolltech-Touchscreen.qrc5
-rw-r--r--tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.pngbin0 -> 133117 bytes
-rw-r--r--tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.pngbin0 -> 133180 bytes
-rw-r--r--tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin17
-rw-r--r--tools/qvfb/Trolltech-Touchscreen.skin/defaultbuttons.conf53
-rw-r--r--tools/qvfb/config.ui2528
-rw-r--r--tools/qvfb/gammaview.h59
-rw-r--r--tools/qvfb/images/logo-nt.pngbin0 -> 1965 bytes
-rw-r--r--tools/qvfb/images/logo.pngbin0 -> 2238 bytes
-rw-r--r--tools/qvfb/main.cpp155
-rw-r--r--tools/qvfb/pda.qrc5
-rw-r--r--tools/qvfb/pda.skin14
-rw-r--r--tools/qvfb/pda_down.pngbin0 -> 102655 bytes
-rw-r--r--tools/qvfb/pda_up.pngbin0 -> 100615 bytes
-rw-r--r--tools/qvfb/qanimationwriter.cpp451
-rw-r--r--tools/qvfb/qanimationwriter.h71
-rw-r--r--tools/qvfb/qtopiakeysym.h67
-rw-r--r--tools/qvfb/qvfb.cpp1137
-rw-r--r--tools/qvfb/qvfb.h159
-rw-r--r--tools/qvfb/qvfb.pro73
-rw-r--r--tools/qvfb/qvfb.qrc7
-rw-r--r--tools/qvfb/qvfbmmap.cpp222
-rw-r--r--tools/qvfb/qvfbmmap.h91
-rw-r--r--tools/qvfb/qvfbprotocol.cpp193
-rw-r--r--tools/qvfb/qvfbprotocol.h173
-rw-r--r--tools/qvfb/qvfbratedlg.cpp103
-rw-r--r--tools/qvfb/qvfbratedlg.h74
-rw-r--r--tools/qvfb/qvfbshmem.cpp314
-rw-r--r--tools/qvfb/qvfbshmem.h90
-rw-r--r--tools/qvfb/qvfbview.cpp824
-rw-r--r--tools/qvfb/qvfbview.h209
-rw-r--r--tools/qvfb/qvfbx11view.cpp388
-rw-r--r--tools/qvfb/qvfbx11view.h121
-rw-r--r--tools/qvfb/translations/translations.pro32
-rw-r--r--tools/qvfb/x11keyfaker.cpp626
-rw-r--r--tools/qvfb/x11keyfaker.h80
86 files changed, 9573 insertions, 0 deletions
diff --git a/tools/qvfb/ClamshellPhone.qrc b/tools/qvfb/ClamshellPhone.qrc
new file mode 100644
index 0000000..39cd422
--- /dev/null
+++ b/tools/qvfb/ClamshellPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>ClamshellPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone.skin b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone.skin
new file mode 100644
index 0000000..cb24a8e
--- /dev/null
+++ b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone.skin
@@ -0,0 +1,30 @@
+[SkinFile]
+Up=ClamshellPhone1-5.png
+Down=ClamshellPhone1-5-pressed.png
+Closed=ClamshellPhone1-5-closed.png
+Screen=72 84 176 208
+Areas=22
+HasMouseHover=false
+
+"Power" 0x0100000a 205 563 249 586
+"1" 0x0031 62 414 119 438
+"2" 0x0032 130 414 189 438
+"3" 0x0033 198 413 257 438
+"4" 0x0034 54 444 117 470
+"5" 0x0035 128 444 189 471
+"6" 0x0036 202 444 264 471
+"7" 0x0037 47 477 113 507
+"8" 0x0038 126 477 190 507
+"9" 0x0039 205 478 270 509
+"*" 0x002a 39 515 110 552
+"0" 0x0030 122 515 195 553
+"#" 0x0023 207 516 280 553
+"Context1" 0x01100000 137 360 108 383 123 410 90 409 60 387 63 378 100 362
+"Back" 0x01000061 184 361 206 376 213 387 197 410 226 410 256 392 258 381 244 369
+"Backspace" 0x01000003 68 563 113 587
+"Select" 0x01010000 160 391 172 390 181 386 184 381 180 377 173 373 165 372 155 372 145 375 138 378 136 382 138 387 147 390
+"Left" 0x1000012 141 390 136 385 136 381 143 375 132 371 120 380 121 393 129 401
+"Down" 0x1000015 143 389 130 402 162 412 191 404 175 390
+"Right" 0x1000014 186 370 176 375 184 382 182 387 175 390 190 404 201 396 202 375
+"Up" 0x1000013 133 370 143 374 176 374 185 370 169 362 149 362
+"Flip" 0x01100006 98 325 225 353
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-closed.png b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
new file mode 100644
index 0000000..88ba3a1
--- /dev/null
+++ b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
Binary files differ
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
new file mode 100644
index 0000000..971cdef
--- /dev/null
+++ b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
Binary files differ
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5.png b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5.png
new file mode 100644
index 0000000..f3550ee
--- /dev/null
+++ b/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5.png
Binary files differ
diff --git a/tools/qvfb/ClamshellPhone.skin/defaultbuttons.conf b/tools/qvfb/ClamshellPhone.skin/defaultbuttons.conf
new file mode 100644
index 0000000..e349dbc
--- /dev/null
+++ b/tools/qvfb/ClamshellPhone.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Flip
+Key4=Backspace
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#=#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/tools/qvfb/DualScreenPhone.skin/DualScreen-pressed.png b/tools/qvfb/DualScreenPhone.skin/DualScreen-pressed.png
new file mode 100644
index 0000000..d62ef4a
--- /dev/null
+++ b/tools/qvfb/DualScreenPhone.skin/DualScreen-pressed.png
Binary files differ
diff --git a/tools/qvfb/DualScreenPhone.skin/DualScreen.png b/tools/qvfb/DualScreenPhone.skin/DualScreen.png
new file mode 100644
index 0000000..cb3d1a7
--- /dev/null
+++ b/tools/qvfb/DualScreenPhone.skin/DualScreen.png
Binary files differ
diff --git a/tools/qvfb/DualScreenPhone.skin/DualScreenPhone.skin b/tools/qvfb/DualScreenPhone.skin/DualScreenPhone.skin
new file mode 100644
index 0000000..a82ef23
--- /dev/null
+++ b/tools/qvfb/DualScreenPhone.skin/DualScreenPhone.skin
@@ -0,0 +1,29 @@
+[SkinFile]
+Up=DualScreen.png
+Down=DualScreen-pressed.png
+Screen=128 155 176 208
+BackScreen=18 44 98 119
+Areas=21
+HasMouseHover=false
+
+"Context1" 0x1100000 144 368 189 368 168 396 176 427 150 398
+"Back" 0x1000061 245 365 291 366 283 398 258 424 265 394
+"Select" 0x1010000 202 401 210 389 224 388 233 402 224 415 208 415
+"Up" 0x1000013 202 381 196 374 218 363 239 373 229 382
+"Left" 0x1000012 199 385 189 375 176 403 185 426 197 415 194 401
+"Right" 0x1000014 235 390 248 379 253 402 246 421 238 413
+"Down" 0x1000015 204 421 233 422 241 432 214 443 191 430
+"Call" 0x1100004 163 452 137 450 125 465 136 484 159 485 169 467
+"Hangup" 0x1100005 266 475 279 448 295 447 309 460 301 480 289 487
+"1" 0x31 175 514 147 504 133 518 161 532 180 534
+"2" 0x32 199 515 229 519 238 533 222 540 195 538
+"2" 0x32 260 512 286 506 299 513 284 527 264 535 248 525
+"4" 0x34 164 541 177 546 182 560 164 565 146 560 135 545 154 539
+"5" 0x35 204 546 225 546 243 560 231 574 205 573 191 558
+"6" 0x36 257 547 281 537 294 540 287 555 274 566 254 561
+"7" 0x37 145 569 176 578 177 595 156 597 138 584
+"8" 0x38 197 582 229 584 241 593 226 604 201 603 189 594
+"9" 0x39 253 577 288 564 301 578 283 593 259 597 251 586
+"*" 0x2a 145 598 181 611 182 623 163 632 144 623 138 607
+"0" 0x30 196 611 233 613 240 630 220 642 193 637 191 622
+"#" 0x23 255 610 286 600 302 615 279 625 258 629 247 616
diff --git a/tools/qvfb/DualScreenPhone.skin/defaultbuttons.conf b/tools/qvfb/DualScreenPhone.skin/defaultbuttons.conf
new file mode 100644
index 0000000..1103350
--- /dev/null
+++ b/tools/qvfb/DualScreenPhone.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/tools/qvfb/LICENSE.GPL b/tools/qvfb/LICENSE.GPL
new file mode 100644
index 0000000..b6e1c33
--- /dev/null
+++ b/tools/qvfb/LICENSE.GPL
@@ -0,0 +1,280 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/tools/qvfb/PDAPhone.qrc b/tools/qvfb/PDAPhone.qrc
new file mode 100644
index 0000000..1a1c35a
--- /dev/null
+++ b/tools/qvfb/PDAPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>PDAPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/PDAPhone.skin/PDAPhone.skin b/tools/qvfb/PDAPhone.skin/PDAPhone.skin
new file mode 100644
index 0000000..d6a1966
--- /dev/null
+++ b/tools/qvfb/PDAPhone.skin/PDAPhone.skin
@@ -0,0 +1,18 @@
+[SkinFile]
+Up=pda_up.png
+Down=pda_down.png
+Screen=42 59 176 220
+Cursor=finger.png 20 20
+Areas=10
+HasMouseHover=false
+
+"Power" 0x0100000a 117 21 141 42
+"Context1" 0x01100000 43 284 74 315
+"Call" 0x01100004 74 284 104 315
+"Hangup" 0x01100005 154 284 184 315
+"Back" 0x01000061 184 284 214 315
+"Left" 0x1000012 123 315 110 326 106 307 113 288 123 300 120 307
+"Down" 0x1000015 123 315 130 318 138 315 150 326 129 335 111 325
+"Right" 0x1000014 137 301 149 290 155 308 150 324 138 315 140 308
+"Up" 0x1000013 123 300 112 289 130 282 149 290 137 300 130 298
+"Select" 0x01010000 131 298 137 300 140 307 138 315 130 318 123 316 120 307 123 300
diff --git a/tools/qvfb/PDAPhone.skin/defaultbuttons.conf b/tools/qvfb/PDAPhone.skin/defaultbuttons.conf
new file mode 100644
index 0000000..e3ae813
--- /dev/null
+++ b/tools/qvfb/PDAPhone.skin/defaultbuttons.conf
@@ -0,0 +1,36 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Back
+Key2=Select
+Key3=Call
+Key4=Hangup
+[Device]
+PrimaryInput=Touchscreen
diff --git a/tools/qvfb/PDAPhone.skin/finger.png b/tools/qvfb/PDAPhone.skin/finger.png
new file mode 100644
index 0000000..24cf0cb
--- /dev/null
+++ b/tools/qvfb/PDAPhone.skin/finger.png
Binary files differ
diff --git a/tools/qvfb/PDAPhone.skin/pda_down.png b/tools/qvfb/PDAPhone.skin/pda_down.png
new file mode 100644
index 0000000..f65c059
--- /dev/null
+++ b/tools/qvfb/PDAPhone.skin/pda_down.png
Binary files differ
diff --git a/tools/qvfb/PDAPhone.skin/pda_up.png b/tools/qvfb/PDAPhone.skin/pda_up.png
new file mode 100644
index 0000000..541e3c4
--- /dev/null
+++ b/tools/qvfb/PDAPhone.skin/pda_up.png
Binary files differ
diff --git a/tools/qvfb/PortableMedia.qrc b/tools/qvfb/PortableMedia.qrc
new file mode 100644
index 0000000..a902f1a
--- /dev/null
+++ b/tools/qvfb/PortableMedia.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>PortableMedia.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/PortableMedia.skin/PortableMedia.skin b/tools/qvfb/PortableMedia.skin/PortableMedia.skin
new file mode 100644
index 0000000..b76e5cf
--- /dev/null
+++ b/tools/qvfb/PortableMedia.skin/PortableMedia.skin
@@ -0,0 +1,14 @@
+[SkinFile]
+Up=portablemedia.png
+Down=portablemedia-pressed.png
+Screen=18 20 480 272
+Areas=7
+HasMouseHover=false
+
+"Context1" 0x01100000 530 192 565 223
+"Back" 0x01000061 530 138 565 173
+"Select" 0x01010000 530 65 565 98
+"Left" 0x1000012 529 67 519 57 511 65 511 104 519 110 529 100 529 98
+"Down" 0x1000015 530 102 520 111 529 120 569 120 577 114 566 103 564 103
+"Right" 0x1000014 565 65 576 52 585 67 585 102 578 113 567 104
+"Up" 0x1000013 530 65 519 55 528 48 567 48 573 51 564 66
diff --git a/tools/qvfb/PortableMedia.skin/defaultbuttons.conf b/tools/qvfb/PortableMedia.skin/defaultbuttons.conf
new file mode 100644
index 0000000..514e881
--- /dev/null
+++ b/tools/qvfb/PortableMedia.skin/defaultbuttons.conf
@@ -0,0 +1,23 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Map=123
+Default=1
+1=Applications/mediaplayer.desktop
+2=Applications/photoedit.desktop
+3=Settings
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+[Device]
+PrimaryInput=Keypad
diff --git a/tools/qvfb/PortableMedia.skin/portablemedia-pressed.png b/tools/qvfb/PortableMedia.skin/portablemedia-pressed.png
new file mode 100644
index 0000000..730e762
--- /dev/null
+++ b/tools/qvfb/PortableMedia.skin/portablemedia-pressed.png
Binary files differ
diff --git a/tools/qvfb/PortableMedia.skin/portablemedia.png b/tools/qvfb/PortableMedia.skin/portablemedia.png
new file mode 100644
index 0000000..e44cbe1
--- /dev/null
+++ b/tools/qvfb/PortableMedia.skin/portablemedia.png
Binary files differ
diff --git a/tools/qvfb/PortableMedia.skin/portablemedia.xcf b/tools/qvfb/PortableMedia.skin/portablemedia.xcf
new file mode 100644
index 0000000..127e07c
--- /dev/null
+++ b/tools/qvfb/PortableMedia.skin/portablemedia.xcf
Binary files differ
diff --git a/tools/qvfb/README b/tools/qvfb/README
new file mode 100644
index 0000000..bfab467
--- /dev/null
+++ b/tools/qvfb/README
@@ -0,0 +1,51 @@
+Qt for Embedded Linux Virtual Framebuffer
+===============================
+
+The virtual frame buffer allows a Qt for Embedded Linux program to be developed
+on your desktop machine, without switching between consoles and X11. The virtual
+framebuffer consists of a shared memory region (the virtual frame buffer)
+and a utility to display the framebuffer in a window. The display is updated
+periodically, so you will see discrete snapshots of the framebuffer rather
+than each individual drawing operation. For this reason drawing problems
+such as flickering may not be apparent until the program is run using a real
+framebuffer.
+
+To use the virtual framebuffer:
+
+1. Ensure QT_NO_QWS_VFB is not set in qconfig.h (when you configure Qt,
+ add the -qvfb option).
+2. Start qvfb (qvfb should be compiled as a normal Qt for X11 application,
+ NOT as a Qt for Embedded Linux application!).
+3. Start a Qt for Embedded Linux server (i.e. construct QApplication with
+ QApplication::GuiServer flag, or run a client with the -qws option).
+
+qvfb supports the following command line options:
+
+[-width width] the width of the virtual framebuffer (default: 240).
+[-height height] the height of the virtual framebuffer (default: 320).
+[-depth depth] the depth of the virtual framebuffer (1,4,8 or 32, default: 8).
+[-nocursor] do not display the X11 cursor in the framebuffer window.
+[-qwsdisplay] the Qt for Embedded Linux display ID, e.g. -qwsdisplay :1 (default :0).
+[-skin skinfile] tells qvfb to load a skin file, e.g. -skin pda.skin
+
+Please refer to the file "pda.skin" as an example of what a skin file looks like.
+The format for skin files is:
+ Image filename of skin with buttons in their up positions
+ Image filename of skin with buttons in their down positions
+ X offset of top left corner of the virtual screen on the skin image
+ Y offset of top left corner of the virtual screen on the skin image
+ Width of the virtual screen on the skin image
+ Height of the virtual screen on the skin image
+ Number of defined button regions
+Then for each button region the format is:
+ Button identifier
+ Qt scan codes to generate for the button
+ Top left X coordinate of the button region
+ Top left Y coordinate of the button region
+ Bottom right X coordinate of the button region
+ Bottom right Y coordinate of the button region
+
+The virtual framebuffer is a development tool only. No security issues have
+been considered in the virtual framebuffer design. It should not be used
+in a production environment and QT_NO_QWS_VFB should always be in force
+in production libraries.
diff --git a/tools/qvfb/SmartPhone.qrc b/tools/qvfb/SmartPhone.qrc
new file mode 100644
index 0000000..8bb5325
--- /dev/null
+++ b/tools/qvfb/SmartPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/SmartPhone.skin/SmartPhone-pressed.png b/tools/qvfb/SmartPhone.skin/SmartPhone-pressed.png
new file mode 100644
index 0000000..d0db2ed
--- /dev/null
+++ b/tools/qvfb/SmartPhone.skin/SmartPhone-pressed.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone.skin/SmartPhone.png b/tools/qvfb/SmartPhone.skin/SmartPhone.png
new file mode 100644
index 0000000..e6ac5a0
--- /dev/null
+++ b/tools/qvfb/SmartPhone.skin/SmartPhone.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone.skin/SmartPhone.skin b/tools/qvfb/SmartPhone.skin/SmartPhone.skin
new file mode 100644
index 0000000..2f44c5a
--- /dev/null
+++ b/tools/qvfb/SmartPhone.skin/SmartPhone.skin
@@ -0,0 +1,28 @@
+[SkinFile]
+Up=SmartPhone.png
+Down=SmartPhone-pressed.png
+Screen=90 107 176 208
+Areas=21
+HasMouseHover=false
+
+"1" 0x0031 138 459 149 473 142 483 120 484 102 477 95 464 99 457 121 454
+"2" 0x0032 153 467 202 492
+"3" 0x0033 258 457 260 470 243 483 215 484 207 474 218 460 248 453
+"4" 0x0034 138 492 149 506 142 516 120 517 102 510 95 497 99 490 121 487
+"5" 0x0035 153 499 202 524
+"6" 0x0036 258 489 260 502 243 515 215 516 207 506 218 492 248 485
+"7" 0x0037 138 524 149 538 142 548 120 549 102 542 95 529 99 522 121 519
+"8" 0x0038 153 531 202 556
+"9" 0x0039 258 521 260 534 243 547 215 548 207 538 218 524 248 517
+"*" 0x002a 138 556 149 570 142 580 120 581 102 574 95 561 99 554 121 551
+"0" 0x0030 153 564 202 589
+"#" 0x0023 258 554 260 567 243 580 215 581 207 571 218 557 248 550
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Select" 0x01010000 160 338 195 371
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
diff --git a/tools/qvfb/SmartPhone.skin/defaultbuttons.conf b/tools/qvfb/SmartPhone.skin/defaultbuttons.conf
new file mode 100644
index 0000000..1103350
--- /dev/null
+++ b/tools/qvfb/SmartPhone.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/tools/qvfb/SmartPhone2.qrc b/tools/qvfb/SmartPhone2.qrc
new file mode 100644
index 0000000..751e985
--- /dev/null
+++ b/tools/qvfb/SmartPhone2.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhone2.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/SmartPhone2.skin/SmartPhone2-pressed.png b/tools/qvfb/SmartPhone2.skin/SmartPhone2-pressed.png
new file mode 100644
index 0000000..d4eb5b0
--- /dev/null
+++ b/tools/qvfb/SmartPhone2.skin/SmartPhone2-pressed.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone2.skin/SmartPhone2.png b/tools/qvfb/SmartPhone2.skin/SmartPhone2.png
new file mode 100644
index 0000000..48ccc1c
--- /dev/null
+++ b/tools/qvfb/SmartPhone2.skin/SmartPhone2.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone2.skin/SmartPhone2.skin b/tools/qvfb/SmartPhone2.skin/SmartPhone2.skin
new file mode 100644
index 0000000..16884bf
--- /dev/null
+++ b/tools/qvfb/SmartPhone2.skin/SmartPhone2.skin
@@ -0,0 +1,25 @@
+SmartPhone2.png SmartPhone2-pressed.png
+90 107
+176 220
+21
+"Menu" 0x01100000 70 400 115 427
+"Backspace" 0x01000003 238 400 285 427
+"1" 0x0031 138 437 149 451 142 461 120 462 102 455 95 442 99 435 121 432
+"2" 0x0032 153 445 202 470
+"3" 0x0033 258 435 260 448 243 461 215 462 207 452 218 438 248 431
+"4" 0x0034 138 470 149 484 142 494 120 495 102 488 95 475 99 468 121 465
+"5" 0x0035 153 477 202 502
+"6" 0x0036 258 467 260 480 243 493 215 494 207 484 218 470 248 463
+"7" 0x0037 138 502 149 516 142 526 120 527 102 520 95 507 99 500 121 497
+"8" 0x0038 153 509 202 534
+"9" 0x0039 258 499 260 512 243 525 215 526 207 516 218 502 248 495
+"*" 0x002a 138 534 149 548 142 558 120 559 102 552 95 539 99 532 121 529
+"0" 0x0030 153 542 202 567
+"#" 0x0023 258 532 260 545 243 558 215 559 207 549 218 535 248 528
+"Yes" 0x01010001 91 343 141 393
+"No" 0x01010002 219 343 269 393
+"Select" 0x01010000 160 356 195 389
+"Left" 0x1000012 159 356 149 346 141 354 141 391 149 399 159 389 159 387
+"Down" 0x1000015 160 391 150 400 159 409 199 409 207 403 196 392 194 392
+"Right" 0x1000014 195 354 206 341 215 356 215 391 208 402 197 393
+"Up" 0x1000013 160 354 149 344 158 337 197 337 203 340 194 355
diff --git a/tools/qvfb/SmartPhone2.skin/defaultbuttons.conf b/tools/qvfb/SmartPhone2.skin/defaultbuttons.conf
new file mode 100644
index 0000000..b083203
--- /dev/null
+++ b/tools/qvfb/SmartPhone2.skin/defaultbuttons.conf
@@ -0,0 +1,52 @@
+[Button]
+[IMethod]
+key_count = 5
+key_hold_action_1 = insertText
+key_hold_action_2 = insertText
+key_hold_action_3 = insertSymbol
+key_hold_action_4 = changeMode
+key_hold_arg_1 = 1
+key_hold_arg_2 = 0
+key_id_1 = 1
+key_id_2 = 0
+key_id_3 = *
+key_id_4 = #
+key_id_5 = *
+key_mode_1 = Abc
+key_mode_2 = Abc
+key_mode_3 = Abc
+key_mode_4 = Abc
+key_mode_5 = Phone
+key_tap_action_1 = insertText
+key_tap_action_2 = insertSpace
+key_tap_action_3 = modifyText
+key_tap_action_4 = changeShift
+key_tap_action_5 = insertText
+key_tap_arg_1 = .,'?!-@:〓
+key_tap_arg_5 = *+pw
+[Menu]
+1 = Applications/camera.desktop
+2 = Applications/datebook.desktop
+3 = Games
+4 = Applications/qtmail.desktop
+5 = Applications/addressbook.desktop
+6 = Settings
+7 = Settings/Beaming.desktop
+8 = Applications
+9 = Documents
+Columns = 3
+Default = 5
+Map = 123456789
+Rows = 3
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+[SystemButtons]
+Count=5
+Key0=Yes
+Key1=Select
+Key2=No
+Key3=Menu
+Key4=Backspace
+[Device]
+PrimaryInput=Keypad
diff --git a/tools/qvfb/SmartPhoneWithButtons.qrc b/tools/qvfb/SmartPhoneWithButtons.qrc
new file mode 100644
index 0000000..f3393ba
--- /dev/null
+++ b/tools/qvfb/SmartPhoneWithButtons.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhoneWithButtons.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png b/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
new file mode 100644
index 0000000..456a068
--- /dev/null
+++ b/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
Binary files differ
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png b/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
new file mode 100644
index 0000000..5ffbd6e
--- /dev/null
+++ b/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
Binary files differ
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin b/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
new file mode 100644
index 0000000..9afa67f
--- /dev/null
+++ b/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
@@ -0,0 +1,31 @@
+[SkinFile]
+Up=SmartPhoneWithButtons.png
+Down=SmartPhoneWithButtons-pressed.png
+Screen=90 107 176 208
+Areas=24
+HasMouseHover=false
+
+"1" 0x0031 138 459 149 473 142 483 120 484 102 477 95 464 99 457 121 454
+"2" 0x0032 153 467 202 492
+"3" 0x0033 258 457 260 470 243 483 215 484 207 474 218 460 248 453
+"4" 0x0034 138 492 149 506 142 516 120 517 102 510 95 497 99 490 121 487
+"5" 0x0035 153 499 202 524
+"6" 0x0036 258 489 260 502 243 515 215 516 207 506 218 492 248 485
+"7" 0x0037 138 524 149 538 142 548 120 549 102 542 95 529 99 522 121 519
+"8" 0x0038 153 531 202 556
+"9" 0x0039 258 521 260 534 243 547 215 548 207 538 218 524 248 517
+"*" 0x002a 138 556 149 570 142 580 120 581 102 574 95 561 99 554 121 551
+"0" 0x0030 153 564 202 589
+"#" 0x0023 258 554 260 567 243 580 215 581 207 571 218 557 248 550
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Select" 0x01010000 160 338 195 371
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
+"Home" 0x1000010 164 402 195 434
+"F1" 0x1000030 138 422 163 448
+"F2" 0x1000031 196 422 220 448
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/defaultbuttons.conf b/tools/qvfb/SmartPhoneWithButtons.skin/defaultbuttons.conf
new file mode 100644
index 0000000..ebd6926
--- /dev/null
+++ b/tools/qvfb/SmartPhoneWithButtons.skin/defaultbuttons.conf
@@ -0,0 +1,103 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Button]
+Count=3
+[Button0]
+Name[]=Calendar Button
+Key=F1
+PressedActionService=Calendar
+PressedActionMessage=raiseToday()
+HeldActionService=Calendar
+HeldActionMessage=newEvent()
+[Button1]
+Name[]=Tasks Button
+Key=F2
+PressedActionService=Tasks
+PressedActionMessage=raise()
+HeldActionService=Tasks
+HeldActionMessage=newTask()
+[Button2]
+Name[]=Home Button
+Key=Home
+PressedActionMappable=0
+PressedActionService=TaskManager
+PressedActionMessage=multitask()
+HeldActionMappable=0
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/tools/qvfb/TouchscreenPhone.qrc b/tools/qvfb/TouchscreenPhone.qrc
new file mode 100644
index 0000000..023144d
--- /dev/null
+++ b/tools/qvfb/TouchscreenPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>TouchscreenPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone-pressed.png b/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
new file mode 100644
index 0000000..01acb86
--- /dev/null
+++ b/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
Binary files differ
diff --git a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.png b/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.png
new file mode 100644
index 0000000..e90de0d
--- /dev/null
+++ b/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.png
Binary files differ
diff --git a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.skin b/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.skin
new file mode 100644
index 0000000..24316a1
--- /dev/null
+++ b/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.skin
@@ -0,0 +1,16 @@
+[SkinFile]
+Up=TouchscreenPhone.png
+Down=TouchscreenPhone-pressed.png
+Screen=90 107 176 208
+Areas=9
+HasMouseHover=false
+
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
+"Select" 0x01010000 160 338 195 371
diff --git a/tools/qvfb/TouchscreenPhone.skin/defaultbuttons.conf b/tools/qvfb/TouchscreenPhone.skin/defaultbuttons.conf
new file mode 100644
index 0000000..a13dfdc
--- /dev/null
+++ b/tools/qvfb/TouchscreenPhone.skin/defaultbuttons.conf
@@ -0,0 +1,45 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Back
+Key2=Select
+Key3=Call
+Key4=Hangup
+[Button]
+Count=1
+[Button0]
+Name=Power Button
+Key=Hangup
+HeldActionService=Launcher
+HeldActionMessage=execute(QString)
+HeldActionArgs=@ByteArray(\0\0\0\x1\0\0\0\n\0\0\0\0\x10\0s\0h\0u\0t\0\x64\0o\0w\0n)
+[Device]
+PrimaryInput=Touchscreen
+
diff --git a/tools/qvfb/Trolltech-Keypad.qrc b/tools/qvfb/Trolltech-Keypad.qrc
new file mode 100644
index 0000000..4775068
--- /dev/null
+++ b/tools/qvfb/Trolltech-Keypad.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>Trolltech-Keypad.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png
new file mode 100644
index 0000000..8dd5719
--- /dev/null
+++ b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-down.png b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-down.png
new file mode 100644
index 0000000..5e1e6be
--- /dev/null
+++ b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-down.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.png b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.png
new file mode 100644
index 0000000..fb3d549
--- /dev/null
+++ b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.skin b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.skin
new file mode 100644
index 0000000..4d90321
--- /dev/null
+++ b/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.skin
@@ -0,0 +1,35 @@
+[SkinFile]
+Up=Trolltech-Keypad.png
+Down=Trolltech-Keypad-down.png
+Closed=Trolltech-Keypad-closed.png
+ClosedAreas=F1 F2 F3 Flip
+ClosedScreen=95 456 128 96
+Screen=75 85 176 220
+Areas=25
+HasMouseHover=false
+"1" 0x0031 65 542 68 536 76 532 114 536 114 573 64 568
+"2" 0x0032 133 537 188 574
+"3" 0x0033 206 536 246 532 252 536 256 542 258 569 205 572
+"4" 0x0034 64 578 114 618
+"5" 0x0035 133 581 188 618
+"6" 0x0036 206 580 256 577 258 613 206 616
+"7" 0x0037 66 622 116 625 114 662 66 658
+"8" 0x0038 133 626 188 662
+"9" 0x0039 206 625 256 622 256 658 206 661
+"*" 0x002a 68 667 116 670 114 705 86 699 76 693 69 686
+"0" 0x0030 133 671 188 708
+"#" 0x0023 206 670 254 665 254 684 245 692 232 699 206 704
+"Context1" 0x01100000 69 420 75 410 85 404 101 404 102 458 69 458
+"Back" 0x01000061 218 404 234 404 240 408 248 418 248 456 218 457
+"Home" 0x1000010 140 494 180 514
+"Hangup" 0x01100005 218 457 248 456 248 496 243 507 230 514 194 514 194 494 206 492 213 486 218 478
+"Call" 0x01100004 68 458 102 460 102 479 108 487 118 492 126 494 126 514 86 514 77 507 72 496
+"Select" 0x01010000 138 426 182 458
+"Up" 0x1000013 118 406 201 402 184 423 134 422
+"Right" 0x1000014 184 424 201 402 202 476 184 460
+"Down" 0x1000015 135 462 184 461 199 477 118 477
+"Left" 0x1000012 118 406 134 424 134 461 117 476
+"F1" 0x1000030 0 408 45 456
+"F2" 0x1000031 0 456 45 509
+"F3" 0x1000032 0 545 45 582
+"Flip" 0x1100006 32 353 293 386
diff --git a/tools/qvfb/Trolltech-Keypad.skin/defaultbuttons.conf b/tools/qvfb/Trolltech-Keypad.skin/defaultbuttons.conf
new file mode 100644
index 0000000..6a78e67
--- /dev/null
+++ b/tools/qvfb/Trolltech-Keypad.skin/defaultbuttons.conf
@@ -0,0 +1,142 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Button]
+Count=8
+[Button7]
+Name[]=Home Down Button
+Key=Down
+Context=HomeScreen
+PressedActionMappable=0
+HeldActionService=Messaging
+HeldActionMessage=raise()
+[Button6]
+Name[]=Home Up Button
+Key=Up
+Context=HomeScreen
+PressedActionMappable=0
+HeldActionService=Contacts
+HeldActionMessage=raise()
+[Button5]
+Name[]=Home Right Button
+Key=Right
+Context=HomeScreen
+PressedActionMappable=0
+HeldActionService=mediaplayer
+HeldActionMessage=raise()
+[Button4]
+Name[]=Calender Button
+Key=Left
+Context=HomeScreen
+PressedActionMappable=0
+HeldActionService=Calendar
+HeldActionMessage=raiseToday()
+[Button3]
+Name[]=Left Soft Key
+Key=Context1
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+HeldActionMappable=0
+PressActionMappable=0
+[Button2]
+Name[]=VoiceNotes Button
+Key=F1
+PressedActionService=mediarecorder
+PressedActionMessage=raise()
+HeldActionService=mediarecorder
+HeldActionMessage=newEvent()
+[Button1]
+Name[]=Camera Button
+Key=F2
+PressedActionService=Camera
+PressedActionMessage=raise()
+HeldActionService=Tasks
+HeldActionMessage=newTask()
+[Button0]
+Name[]=Home Button
+Key=Home
+PressedActionMappable=0
+PressedActionService=TaskManager
+PressedActionMessage=multitask()
+HeldActionMappable=0
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/mediaplayer.desktop
+3=Applications/simapp.desktop,Applications/calculator.desktop
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Applications/datebook.desktop
+7=Games
+8=Settings/Beaming.desktop
+9=Applications/todolist.desktop
+*=Settings
+0=Applications
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=6
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+Key5=Flip
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
+[Environment]
+QWS_DISPLAY=Multi: LinuxFb:mmHeight57:0 LinuxFb:offset=0,320:1 :0
diff --git a/tools/qvfb/Trolltech-Touchscreen.qrc b/tools/qvfb/Trolltech-Touchscreen.qrc
new file mode 100644
index 0000000..40fafeb
--- /dev/null
+++ b/tools/qvfb/Trolltech-Touchscreen.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>Trolltech-Touchscreen.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png b/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png
new file mode 100644
index 0000000..c1a422f
--- /dev/null
+++ b/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png b/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png
new file mode 100644
index 0000000..544a425
--- /dev/null
+++ b/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin b/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin
new file mode 100644
index 0000000..5de882e
--- /dev/null
+++ b/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin
@@ -0,0 +1,17 @@
+[SkinFile]
+Up=Trolltech-Touchscreen.png
+Down=Trolltech-Touchscreen-down.png
+Screen=40 109 176 220
+Areas=10
+HasMouseHover=false
+
+"Context1" 0x01100000 38 420 44 408 52 404 68 403 68 458 40 458
+"Back" 0x01000061 185 42 202 398 211 410 216 418 219 456 186 456
+"Call" 0x01100004 38 458 70 458 71 478 75 486 83 492 94 494 94 516 56 516 45 507 38 498
+"Hangup" 0x01100005 186 458 220 458 220 496 214 508 200 516 162 516 161 494 172 492 180 486 185 478
+"Left" 0x1000012 86 405 106 426 106 461 85 478
+"Down" 0x1000015 106 460 151 460 170 480 85 480
+"Right" 0x1000014 151 424 170 404 170 480 151 460
+"Up" 0x1000013 85 403 168 403 150 424 106 424
+"Select" 0x01010000 106 426 150 456
+"Home" 0x1000010 105 493 145 512
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/defaultbuttons.conf b/tools/qvfb/Trolltech-Touchscreen.skin/defaultbuttons.conf
new file mode 100644
index 0000000..6665125
--- /dev/null
+++ b/tools/qvfb/Trolltech-Touchscreen.skin/defaultbuttons.conf
@@ -0,0 +1,53 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/mediaplayer.desktop
+3=Applications/simapp.desktop,Applications/calculator.desktop
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Applications/datebook.desktop
+7=Games
+8=Settings/beaming.desktop
+9=Applications/todolist.desktop
+*=Settings
+0=Applications
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Back
+Key2=Select
+Key3=Call
+Key4=Hangup
+[Device]
+PrimaryInput=Touchscreen
+[Button]
+Count=2
+[Button0]
+Name[]=Home Button
+Key=Home
+PressedActionMappable=0
+PressedActionService=TaskManager
+PressedActionMessage=multitask()
+HeldActionMappable=0
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+[Button1]
+Name=Power Button
+Key=Hangup
+HeldActionService=Launcher
+HeldActionMessage=execute(QString)
+HeldActionArgs=@ByteArray(\0\0\0\x1\0\0\0\n\0\0\0\0\x10\0s\0h\0u\0t\0\x64\0o\0w\0n)
diff --git a/tools/qvfb/config.ui b/tools/qvfb/config.ui
new file mode 100644
index 0000000..7a45bfe
--- /dev/null
+++ b/tools/qvfb/config.ui
@@ -0,0 +1,2528 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>Config</class>
+ <widget class="QDialog" name="Config" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>650</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Configure</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>8</number>
+ </property>
+ <property name="topMargin" >
+ <number>8</number>
+ </property>
+ <property name="rightMargin" >
+ <number>8</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>8</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="ButtonGroup1" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Size</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>11</number>
+ </property>
+ <property name="topMargin" >
+ <number>11</number>
+ </property>
+ <property name="rightMargin" >
+ <number>11</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="size_176_220" >
+ <property name="text" >
+ <string>176x220 "SmartPhone"</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_240_320" >
+ <property name="text" >
+ <string>240x320 "PDA"</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_320_240" >
+ <property name="text" >
+ <string>320x240 "TV" / "QVGA"</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_640_480" >
+ <property name="text" >
+ <string>640x480 "VGA"</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_800_600" >
+ <property name="text" >
+ <string>800x600</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="size_1024_768" >
+ <property name="text" >
+ <string>1024x768</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="size_custom" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Custom</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="size_width" >
+ <property name="minimum" >
+ <number>1</number>
+ </property>
+ <property name="maximum" >
+ <number>1280</number>
+ </property>
+ <property name="singleStep" >
+ <number>16</number>
+ </property>
+ <property name="value" >
+ <number>400</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="size_height" >
+ <property name="minimum" >
+ <number>1</number>
+ </property>
+ <property name="maximum" >
+ <number>1024</number>
+ </property>
+ <property name="singleStep" >
+ <number>16</number>
+ </property>
+ <property name="value" >
+ <number>300</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="ButtonGroup2" >
+ <property name="title" >
+ <string>Depth</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>11</number>
+ </property>
+ <property name="topMargin" >
+ <number>11</number>
+ </property>
+ <property name="rightMargin" >
+ <number>11</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="depth_1" >
+ <property name="text" >
+ <string>1 bit monochrome</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_4gray" >
+ <property name="text" >
+ <string>4 bit grayscale</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_8" >
+ <property name="text" >
+ <string>8 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_12" >
+ <property name="text" >
+ <string>12 (16) bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_15" >
+ <property name="text" >
+ <string>15 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_16" >
+ <property name="text" >
+ <string>16 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_18" >
+ <property name="text" >
+ <string>18 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_24" >
+ <property name="text" >
+ <string>24 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_32" >
+ <property name="text" >
+ <string>32 bit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_32_argb" >
+ <property name="text" >
+ <string>32 bit ARGB</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1_3" >
+ <property name="text" >
+ <string>Skin</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="skin" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text" >
+ <string>None</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="touchScreen" >
+ <property name="text" >
+ <string>Emulate touch screen (no mouse move)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="lcdScreen" >
+ <property name="text" >
+ <string>Emulate LCD screen (Only with fixed zoom of 3.0 times magnification)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>&lt;p>Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth &lt;i>above&lt;/i>. You may freely modify the Gamma &lt;i>below&lt;/i>.</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1" >
+ <property name="title" >
+ <string>Gamma</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>11</number>
+ </property>
+ <property name="topMargin" >
+ <number>11</number>
+ </property>
+ <property name="rightMargin" >
+ <number>11</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>11</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="6" column="0" >
+ <widget class="QLabel" name="TextLabel3" >
+ <property name="text" >
+ <string>Blue</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" >
+ <widget class="QSlider" name="bslider" >
+ <property name="palette" >
+ <palette>
+ <active>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>127</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>38</red>
+ <green>38</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>127</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>38</red>
+ <green>38</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>127</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>38</red>
+ <green>38</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum" >
+ <number>400</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2" >
+ <widget class="QLabel" name="blabel" >
+ <property name="text" >
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="TextLabel2" >
+ <property name="text" >
+ <string>Green</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QSlider" name="gslider" >
+ <property name="palette" >
+ <palette>
+ <active>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>38</red>
+ <green>255</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>127</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>170</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>38</red>
+ <green>255</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>127</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>170</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>38</red>
+ <green>255</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>127</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>170</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum" >
+ <number>400</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2" >
+ <widget class="QLabel" name="glabel" >
+ <property name="text" >
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel7" >
+ <property name="text" >
+ <string>All</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="TextLabel8" >
+ <property name="text" >
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSlider" name="gammaslider" >
+ <property name="palette" >
+ <palette>
+ <active>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum" >
+ <number>400</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="TextLabel1_2" >
+ <property name="text" >
+ <string>Red</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QLabel" name="rlabel" >
+ <property name="text" >
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QSlider" name="rslider" >
+ <property name="palette" >
+ <palette>
+ <active>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>38</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>38</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>38</green>
+ <blue>38</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>127</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="maximum" >
+ <number>400</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0" colspan="3" >
+ <widget class="QPushButton" name="PushButton3" >
+ <property name="text" >
+ <string>Set all to 1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="9" row="0" column="3" >
+ <widget class="GammaView" native="1" name="MyCustomWidget1" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOk" >
+ <property name="text" >
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="text" >
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <customwidgets>
+ <customwidget>
+ <class>GammaView</class>
+ <extends></extends>
+ <header>gammaview.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>size_width</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>size_custom</receiver>
+ <slot>click()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>152</x>
+ <y>193</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>94</x>
+ <y>199</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>size_height</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>size_custom</receiver>
+ <slot>click()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>259</x>
+ <y>196</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>64</x>
+ <y>188</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/qvfb/gammaview.h b/tools/qvfb/gammaview.h
new file mode 100644
index 0000000..53717a6
--- /dev/null
+++ b/tools/qvfb/gammaview.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GAMMAVIEW_H
+#define GAMMAVIEW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class GammaView: public QWidget
+{
+ Q_OBJECT
+public:
+ GammaView( QWidget *parent = 0, Qt::WindowFlags f = 0 )
+ : QWidget(parent,f) { }
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/images/logo-nt.png b/tools/qvfb/images/logo-nt.png
new file mode 100644
index 0000000..92f77d8
--- /dev/null
+++ b/tools/qvfb/images/logo-nt.png
Binary files differ
diff --git a/tools/qvfb/images/logo.png b/tools/qvfb/images/logo.png
new file mode 100644
index 0000000..0093177
--- /dev/null
+++ b/tools/qvfb/images/logo.png
Binary files differ
diff --git a/tools/qvfb/main.cpp b/tools/qvfb/main.cpp
new file mode 100644
index 0000000..b0eb4e7
--- /dev/null
+++ b/tools/qvfb/main.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfb.h"
+
+#include <QApplication>
+#include <QRegExp>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#ifdef Q_WS_X11
+#include <QX11Info>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+void fn_quit_qvfb(int)
+{
+ // pretend that we have quit normally
+ qApp->quit();
+}
+
+
+void usage( const char *app )
+{
+ printf( "Usage: %s [-width width] [-height height] [-depth depth] [-zoom zoom]"
+ "[-mmap] [-nocursor] [-qwsdisplay :id] [-x11display :id] [-skin skindirectory]\n"
+ "Supported depths: 1, 4, 8, 12, 15, 16, 18, 24, 32\n", app );
+}
+int qvfb_protocol = 0;
+
+int runQVfb( int argc, char *argv[] )
+{
+ Q_INIT_RESOURCE(qvfb);
+
+ QApplication app( argc, argv );
+
+ int width = 0;
+ int height = 0;
+ int depth = -32; // default, but overridable by skin
+ bool depthSet = false;
+ int rotation = 0;
+ bool cursor = true;
+ QVFb::DisplayType displayType = QVFb::QWS;
+ double zoom = 1.0;
+ QString displaySpec( ":0" );
+ QString skin;
+
+ for ( int i = 1; i < argc; i++ ){
+ QString arg = argv[i];
+ if ( arg == "-width" ) {
+ width = atoi( argv[++i] );
+ } else if ( arg == "-height" ) {
+ height = atoi( argv[++i] );
+ } else if ( arg == "-skin" ) {
+ skin = argv[++i];
+ } else if ( arg == "-depth" ) {
+ depth = atoi( argv[++i] );
+ depthSet = true;
+ } else if ( arg == "-nocursor" ) {
+ cursor = false;
+ } else if ( arg == "-mmap" ) {
+ qvfb_protocol = 1;
+ } else if ( arg == "-zoom" ) {
+ zoom = atof( argv[++i] );
+ } else if ( arg == "-qwsdisplay" ) {
+ displaySpec = argv[++i];
+ displayType = QVFb::QWS;
+#ifdef Q_WS_X11
+ } else if ( arg == "-x11display" ) {
+ displaySpec = argv[++i];
+ displayType = QVFb::X11;
+
+ // Usually only the default X11 depth will work with Xnest,
+ // so override the default of 32 with the actual X11 depth.
+ if (!depthSet)
+ depth = -QX11Info::appDepth(); // default, but overridable by skin
+#endif
+ } else {
+ printf( "Unknown parameter %s\n", arg.toLatin1().constData() );
+ usage( argv[0] );
+ exit(1);
+ }
+ }
+
+ int displayId = 0;
+ QRegExp r( ":[0-9]+" );
+ int m = r.indexIn( displaySpec, 0 );
+ int len = r.matchedLength();
+ if ( m >= 0 ) {
+ displayId = displaySpec.mid( m+1, len-1 ).toInt();
+ }
+ QRegExp rotRegExp( "Rot[0-9]+" );
+ m = rotRegExp.indexIn( displaySpec, 0 );
+ len = rotRegExp.matchedLength();
+ if ( m >= 0 ) {
+ rotation = displaySpec.mid( m+3, len-3 ).toInt();
+ }
+
+ signal(SIGINT, fn_quit_qvfb);
+ signal(SIGTERM, fn_quit_qvfb);
+
+ QVFb mw( displayId, width, height, depth, rotation, skin, displayType );
+ mw.setZoom(zoom);
+ //app.setMainWidget( &mw );
+ mw.enableCursor(cursor);
+ mw.show();
+
+ return app.exec();
+}
+
+QT_END_NAMESPACE
+
+int main( int argc, char *argv[] )
+{
+ return QT_PREPEND_NAMESPACE(runQVfb)(argc, argv);
+}
diff --git a/tools/qvfb/pda.qrc b/tools/qvfb/pda.qrc
new file mode 100644
index 0000000..b14e7b3
--- /dev/null
+++ b/tools/qvfb/pda.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>pda.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/qvfb/pda.skin b/tools/qvfb/pda.skin
new file mode 100644
index 0000000..037f750
--- /dev/null
+++ b/tools/qvfb/pda.skin
@@ -0,0 +1,14 @@
+pda_up.png pda_down.png
+57 81
+240 320
+11
+"Power" 0x0100000a 277 36 302 57
+"F1" 0x01000030 52 439 81 470
+"F2" 0x01000031 101 422 130 451
+"F3" 0x01000032 232 423 260 452
+"F4" 0x01000033 279 445 309 473
+"Left" 0x01000012 155 438 176 472
+"Down" 0x01000015 169 471 203 486
+"Right" 0x01000014 193 448 215 472
+"Up" 0x01000013 166 427 199 451
+"Enter" 0x01000005 177 448 193 468
diff --git a/tools/qvfb/pda_down.png b/tools/qvfb/pda_down.png
new file mode 100644
index 0000000..0ea157d
--- /dev/null
+++ b/tools/qvfb/pda_down.png
Binary files differ
diff --git a/tools/qvfb/pda_up.png b/tools/qvfb/pda_up.png
new file mode 100644
index 0000000..541e3c4
--- /dev/null
+++ b/tools/qvfb/pda_up.png
Binary files differ
diff --git a/tools/qvfb/qanimationwriter.cpp b/tools/qvfb/qanimationwriter.cpp
new file mode 100644
index 0000000..caa7e95
--- /dev/null
+++ b/tools/qvfb/qanimationwriter.cpp
@@ -0,0 +1,451 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanimationwriter.h"
+#include <QFile>
+#include <QString>
+#include <QPainter>
+#include <png.h>
+#include <limits.h>
+#include <netinet/in.h> // for htonl
+
+#ifdef QT_LINUXBASE
+# include <arpa/inet.h> // for htonl (LSB only)
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QAnimationWriterData
+{
+public:
+ QAnimationWriterData(QIODevice* d) : framerate(1000), dev(d) {}
+ void setFrameRate(int d) { framerate = d; }
+ virtual ~QAnimationWriterData() { }
+ virtual void setImage(const QImage& src)=0;
+ virtual bool canCompose() const { return false; }
+ virtual void composeImage(const QImage&, const QPoint& ) {}
+
+protected:
+ int framerate;
+ QIODevice* dev;
+};
+
+
+class QAnimationWriterMNG : public QAnimationWriterData {
+ bool first;
+ png_structp png_ptr;
+ png_infop info_ptr;
+public:
+ QAnimationWriterMNG(QIODevice* d) : QAnimationWriterData(d)
+ {
+ first = true;
+ begin_png();
+ }
+
+ ~QAnimationWriterMNG()
+ {
+ if (first) {
+ // Eh? Not images.
+ QImage dummy(1,1,QImage::Format_RGB32);
+ setImage(dummy);
+ }
+ writeMEND();
+ end_png();
+ }
+
+ void begin_png()
+ {
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
+ info_ptr = png_create_info_struct(png_ptr);
+ png_set_compression_level(png_ptr,9);
+ png_set_write_fn(png_ptr, (void*)this, write, 0);
+ }
+
+ void end_png()
+ {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ }
+
+ static void write( png_structp png_ptr, png_bytep data, png_size_t length)
+ {
+ QAnimationWriterMNG* that = (QAnimationWriterMNG*)png_get_io_ptr(png_ptr);
+ /*uint nw =*/ that->dev->write((const char*)data,length);
+ }
+
+ void writePNG(const QImage& image)
+ {
+#ifndef QT_LINUXBASE
+ // LSB disallows accessing the info_ptr directly. LSB's png_set_IHDR sets
+ // the channels anyways, so just comment it out for LSB usage
+ info_ptr->channels = 4;
+#endif
+ png_set_sig_bytes(png_ptr, 8); // Pretend we already wrote the sig
+ png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
+ 8, image.hasAlphaChannel()
+ ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
+ 0, 0, 0);
+ png_write_info(png_ptr, info_ptr);
+ if (!image.hasAlphaChannel())
+ png_set_filler(png_ptr, 0,
+ QSysInfo::ByteOrder == QSysInfo::BigEndian ?
+ PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
+ //if ( QImage::systemByteOrder() == QImage::BigEndian ) {
+ //png_set_swap_alpha(png_ptr);
+ //}
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ png_set_bgr(png_ptr);
+ }
+
+ int height = image.height();
+ png_bytep *row_pointers = new png_bytep[height];
+ for (int i = 0; i < height; ++i)
+ row_pointers[i] = (png_bytep)image.scanLine(i);
+ png_write_image(png_ptr, row_pointers);
+ delete [] row_pointers;
+ png_write_end(png_ptr, info_ptr);
+ end_png();
+ begin_png();
+ }
+
+ void writeMHDR(const QSize& size, int framerate)
+ {
+ dev->write("\212MNG\r\n\032\n", 8);
+
+ struct {
+ int width;
+ int height;
+ int framerate;
+ int a,b,c;
+ int profile;
+ } chunk;
+ chunk.width = htonl(size.width());
+ chunk.height = htonl(size.height());
+ chunk.framerate = htonl(framerate);
+ chunk.a=0;
+ chunk.b=0;
+ chunk.c=0;
+ chunk.profile = htonl(0x00000003);
+
+ png_write_chunk(png_ptr, (png_byte*)"MHDR", (png_byte*)&chunk, sizeof(chunk));
+ }
+
+ void writeMEND()
+ {
+ png_write_chunk(png_ptr, (png_byte*)"MEND", 0, 0);
+ }
+
+ void writeDEFI(const QPoint& offset, const QSize& /*size*/)
+ {
+ struct {
+ ushort o;
+ uchar s;
+ uchar concrete;
+ int x,y;
+ int lc,rc,tc,bc;
+ } chunk;
+ chunk.o=0;
+ chunk.s=0;
+ chunk.concrete=1;
+ chunk.x=htonl(offset.x());
+ chunk.y=htonl(offset.y());
+ chunk.lc=0;
+ chunk.rc=0;
+ chunk.tc=htonl(INT_MAX);
+ chunk.bc=htonl(INT_MAX);
+
+ png_write_chunk(png_ptr, (png_byte*)"DEFI", (png_byte*)&chunk, sizeof(chunk));
+ }
+
+ void writeFRAM(const QSize& size)
+ {
+ struct {
+ uchar mode;
+ uchar n;
+ uchar nu;
+ uchar d;
+ uchar t;
+ uchar clip;
+ uchar s;
+ uchar deltatype;
+ uint left;
+ uint right;
+ uint top;
+ uint bottom;
+ } chunk;
+ chunk.mode=1;
+ chunk.n='a';
+ chunk.nu=0;
+ chunk.d=0;
+ chunk.clip=1;
+ chunk.t=0;
+ chunk.s=0;
+ chunk.deltatype=0;
+ chunk.left=0;
+ chunk.right=htonl(size.width());
+ chunk.top=0;
+ chunk.bottom=htonl(size.height());
+
+ png_write_chunk(png_ptr, (png_byte*)"FRAM", (png_byte*)&chunk, sizeof(chunk));
+ }
+
+ void writeMOVE(const QPoint& offset)
+ {
+ struct {
+ uchar filler[3];
+ uchar z[5];
+ int x,y;
+ } chunk;
+ memset(chunk.z,0,5);
+ chunk.x=htonl(offset.x());
+ chunk.y=htonl(offset.y());
+
+ png_write_chunk(png_ptr, (png_byte*)"MOVE", ((png_byte*)&chunk)+3, sizeof(chunk)-3);
+ }
+
+ void setImage(const QImage& src)
+ {
+ if (first) {
+ first = false;
+ writeMHDR(src.size(),framerate);
+ }
+ composeImage(src,QPoint(0,0));
+ }
+
+ bool canCompose() const { return true; }
+
+ void composeImage(const QImage& src, const QPoint& offset)
+ {
+ writeMOVE(offset);
+ //writeFRAM(src.size());
+ writePNG(src);
+ }
+};
+
+QAnimationWriter::QAnimationWriter(const QString& filename, const char* format)
+{
+ if (qstrncmp(format, "MNG", 4)) {
+ qWarning("Format \"%s\" not supported, only MNG", format);
+ dev = 0;
+ d = 0;
+ } else {
+ QFile *f = new QFile(filename);
+ f->open(QIODevice::WriteOnly);
+ dev = f;
+ d = new QAnimationWriterMNG(dev);
+ }
+}
+
+bool QAnimationWriter::okay() const
+{
+ if (!dev)
+ return false;
+ QFile *file = qobject_cast<QFile*>(dev);
+ Q_ASSERT(file);
+ return (file->error() == QFile::NoError);
+}
+
+QAnimationWriter::~QAnimationWriter()
+{
+ delete d;
+ delete dev;
+}
+
+void QAnimationWriter::setFrameRate(int r)
+{
+ if (d)
+ d->setFrameRate(r);
+}
+
+void QAnimationWriter::appendFrame(const QImage& frm, const QPoint& offset)
+{
+ if (!dev)
+ return;
+
+ const QImage frame = frm.convertToFormat(QImage::Format_RGB32);
+ const int alignx = 1;
+ if (prev.isNull() || !d->canCompose()) {
+ d->setImage(frame);
+ } else {
+ bool done;
+ int minx, maxx, miny, maxy;
+ int w = frame.width();
+ int h = frame.height();
+
+ const quint32 *framePtr = reinterpret_cast<const quint32*>(frame.bits());
+ const quint32 *prevPtr = reinterpret_cast<const quint32*>(prev.bits());
+ const int frameStride = frame.bytesPerLine() / sizeof(quint32);
+ const int prevStride = prev.bytesPerLine() / sizeof(quint32);
+
+ // Find left edge of change
+ done = false;
+ for (minx = 0; minx < w && !done; ++minx) {
+ const quint32 *p1 = framePtr + minx;
+ const quint32 *p2 = prevPtr + minx + offset.x();
+ for (int y = 0; y < h; ++y) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ p1 += frameStride;
+ p2 += prevStride;
+ }
+ }
+ --minx;
+
+ // Find right edge of change
+ done = false;
+ for (maxx = w-1; maxx >= 0 && !done; --maxx) {
+ const quint32 *p1 = framePtr + maxx;
+ const quint32 *p2 = prevPtr + maxx + offset.x();
+ for (int y = 0; y < h; ++y) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ p1 += frameStride;
+ p2 += prevStride;
+ }
+ }
+ ++maxx;
+
+ // Find top edge of change
+ done = false;
+ for (miny = 0; miny < h && !done; ++miny) {
+ const quint32 *p1 = framePtr + miny * frameStride;
+ const quint32 *p2 = prevPtr + miny * prevStride + offset.x();
+ for (int x = 0; x < w; ++x) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ ++p1;
+ ++p2;
+ }
+ }
+ --miny;
+
+ // Find right edge of change
+ done = false;
+ for (maxy = h-1; maxy >= 0 && !done; --maxy) {
+ const quint32 *p1 = framePtr + maxy * frameStride;
+ const quint32 *p2 = prevPtr + maxy * prevStride + offset.x();
+ for (int x = 0; x < w; ++x) {
+ if (*p1 != *p2) {
+ done = true;
+ break;
+ }
+ ++p1;
+ ++p2;
+ }
+ }
+ ++maxy;
+
+ if (minx > maxx)
+ minx = maxx = 0;
+ if (miny > maxy)
+ miny = maxy = 0;
+
+ if (alignx > 1) {
+ minx -= minx % alignx;
+ maxx = maxx - maxx % alignx + alignx - 1;
+ }
+
+ int dw = maxx - minx + 1;
+ int dh = maxy - miny + 1;
+
+ QImage diff(dw, dh, QImage::Format_ARGB32);
+
+ int x, y;
+ for (y = 0; y < dh; ++y) {
+ QRgb* li = (QRgb*)frame.scanLine(y+miny)+minx;
+ QRgb* lp = (QRgb*)prev.scanLine(y+miny+offset.y())+minx+offset.x();
+ QRgb* ld = (QRgb*)diff.scanLine(y);
+ if (alignx) {
+ for (x = 0; x < dw; x += alignx) {
+ int i;
+ for (i = 0; i < alignx; ++i) {
+ if (li[x+i] != lp[x+i])
+ break;
+ }
+ if (i == alignx) {
+ // All the same
+ for (i = 0; i < alignx; ++i)
+ ld[x+i] = qRgba(0,0,0,0);
+ } else {
+ // Some different
+ for (i = 0; i < alignx; ++i)
+ ld[x+i] = 0xff000000 | li[x+i];
+ }
+ }
+ } else {
+ for (x = 0; x < dw; ++x) {
+ if (li[x] != lp[x])
+ ld[x] = 0xff000000 | li[x];
+ else
+ ld[x] = qRgba(0,0,0,0);
+ }
+ }
+ }
+
+ d->composeImage(diff, QPoint(minx, miny) + offset);
+ }
+ if (prev.isNull() || (prev.size() == frame.size() && offset == QPoint(0,0))) {
+ prev = frame;
+ } else {
+ QPainter p(&prev);
+ p.drawImage(offset.x(), offset.y(), frame, 0, 0,
+ frame.width(), frame.height());
+ }
+}
+
+void QAnimationWriter::appendFrame(const QImage& frm)
+{
+ appendFrame(frm, QPoint(0,0));
+}
+
+void QAnimationWriter::appendBlankFrame()
+{
+ QImage i(1,1,QImage::Format_ARGB32);
+ i.fill(0);
+ d->composeImage(i, QPoint(0,0));
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/qanimationwriter.h b/tools/qvfb/qanimationwriter.h
new file mode 100644
index 0000000..8440a89
--- /dev/null
+++ b/tools/qvfb/qanimationwriter.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANIMATIONWRITER_H
+#define QANIMATIONWRITER_H
+
+#include <QImage>
+
+QT_BEGIN_NAMESPACE
+
+class QAnimationWriterData;
+
+class QAnimationWriter
+{
+public:
+ QAnimationWriter(const QString& filename, const char* format = "MNG");
+ ~QAnimationWriter();
+
+ bool okay() const;
+ void setFrameRate(int);
+ void appendBlankFrame();
+ void appendFrame(const QImage&);
+ void appendFrame(const QImage&, const QPoint& offset);
+
+private:
+ QImage prev;
+ QIODevice* dev;
+ QAnimationWriterData* d;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/qtopiakeysym.h b/tools/qvfb/qtopiakeysym.h
new file mode 100644
index 0000000..2641e91
--- /dev/null
+++ b/tools/qvfb/qtopiakeysym.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2006 TROLLTECH ASA. All rights reserved.
+**
+** This file is part of the Phone Edition of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTKEYSYM_H
+#define QTKEYSYM_H
+
+/* Special keys used by Qtopia, mapped into the X11 private keypad range */
+#define QTOPIAXK_Select 0x11000601
+#define QTOPIAXK_Yes 0x11000602
+#define QTOPIAXK_No 0x11000603
+
+#define QTOPIAXK_Cancel 0x11000604
+#define QTOPIAXK_Printer 0x11000605
+#define QTOPIAXK_Execute 0x11000606
+#define QTOPIAXK_Sleep 0x11000607
+#define QTOPIAXK_Play 0x11000608
+#define QTOPIAXK_Zoom 0x11000609
+
+#define QTOPIAXK_Context1 0x1100060A
+#define QTOPIAXK_Context2 0x1100060B
+#define QTOPIAXK_Context3 0x1100060C
+#define QTOPIAXK_Context4 0x1100060D
+#define QTOPIAXK_Call 0x1100060E
+#define QTOPIAXK_Hangup 0x1100060F
+#define QTOPIAXK_Flip 0x11000610
+
+#define QTOPIAXK_Min QTOPIAXK_Select
+#define QTOPIAXK_Max QTOPIAXK_Flip
+
+#endif
diff --git a/tools/qvfb/qvfb.cpp b/tools/qvfb/qvfb.cpp
new file mode 100644
index 0000000..b6a715c
--- /dev/null
+++ b/tools/qvfb/qvfb.cpp
@@ -0,0 +1,1137 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfb.h"
+#include "qvfbview.h"
+#ifdef Q_WS_X11
+#include "qvfbx11view.h"
+#endif
+#include "qvfbratedlg.h"
+#include "ui_config.h"
+#include "qanimationwriter.h"
+
+#include <deviceskin.h>
+
+#include <QMenuBar>
+#include <QMenu>
+#include <QApplication>
+#include <QMessageBox>
+#include <QComboBox>
+#include <QLabel>
+#include <QFileDialog>
+#include <QSlider>
+#include <QSpinBox>
+#include <QLayout>
+#include <QRadioButton>
+#include <QImage>
+#include <QPixmap>
+#include <QCheckBox>
+#include <QCursor>
+#include <QTime>
+#include <QScrollArea>
+#include <QProgressBar>
+#include <QPushButton>
+#include <QTextStream>
+#include <QFile>
+#include <QFileInfo>
+#include <QDebug>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+QT_BEGIN_NAMESPACE
+
+// =====================================================================
+
+static const char *red_on_led_xpm[] = {
+"11 11 10 1",
+" c None",
+". c #FF0000",
+"+ c #FF4C4C",
+"@ c #FF7A7A",
+"# c #D30000",
+"$ c #FF9393",
+"% c #BA0000",
+"& c #FFFFFF",
+"* c #7F0000",
+"= c #000000",
+" ",
+" .++@@ ",
+" .....+@ ",
+" ##...$.+@ ",
+" %#..$&$.+ ",
+" *#...$..+ ",
+" *%#...... ",
+" =*%#..... ",
+" =*%###. ",
+" ===*. ",
+" "};
+
+static const char *red_off_led_xpm[] = {
+"11 11 12 1",
+" c None",
+". c #CDB7B4",
+"+ c #D2BFBD",
+"@ c #DBCBCA",
+"# c #E5D9D8",
+"$ c #BC9E9B",
+"% c #E2D6D5",
+"& c #AD8986",
+"* c #FFFFFF",
+"= c #A8817D",
+"- c #B2908D",
+"; c #6F4D4A",
+" ",
+" .++@# ",
+" .....@# ",
+" $$...%.@# ",
+" &$..%*%.@ ",
+" =-...%..+ ",
+" =&-...... ",
+" ;==-..... ",
+" ;=&-$$. ",
+" ;==&$ ",
+" "};
+
+static bool copyButtonConfiguration(const QString &prefix, int displayId)
+{
+ const QString destDir = QString(QLatin1String("/tmp/qtembedded-%1/")).arg(displayId);
+ const QFileInfo src(prefix + QLatin1String("defaultbuttons.conf"));
+ const QFileInfo dst(destDir + QLatin1String("defaultbuttons.conf"));
+ unlink(dst.absoluteFilePath().toLatin1().constData());
+ if (!src.exists())
+ return false;
+ const bool rc = QFile::copy(src.absoluteFilePath(), dst.absoluteFilePath());
+ if (!rc)
+ qWarning() << "Failed to copy the button configuration file " << src.absoluteFilePath() << " to " << dst.absoluteFilePath() << '.';
+ return rc;
+}
+
+// =====================================================================
+
+class AnimationSaveWidget : public QWidget {
+ Q_OBJECT
+public:
+ AnimationSaveWidget(QVFbAbstractView *v);
+ ~AnimationSaveWidget();
+ bool detectPpmtoMpegCommand();
+ void timerEvent(QTimerEvent *te);
+ void convertToMpeg(QString filename);
+ void removeTemporaryFiles();
+protected slots:
+ void toggleRecord();
+ void reset();
+ void save();
+private:
+ QVFbAbstractView *view;
+ QProgressBar *progressBar;
+ QLabel *statusText;
+ bool haveMpeg, savingAsMpeg, recording;
+ QCheckBox *mpegSave;
+ QAnimationWriter *animation;
+ QPushButton *recBt, *resetBt, *saveBt;
+ QLabel *timeDpy, *recLED;
+ int timerId, progressTimerId;
+ QPixmap recOn, recOff;
+ QTime tm;
+ int elapsed, imageNum;
+};
+
+// =====================================================================
+
+Zoomer::Zoomer(QVFb* target) :
+ qvfb(target)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QSlider *sl = new QSlider(Qt::Horizontal);
+ sl->setMinimum(10);
+ sl->setMaximum(64);
+ sl->setPageStep(1);
+ sl->setValue(32);
+ layout->addWidget(sl);
+ connect(sl,SIGNAL(valueChanged(int)),this,SLOT(zoom(int)));
+ label = new QLabel();
+ layout->addWidget(label);
+}
+
+void Zoomer::zoom(int z)
+{
+ double d = (double)z/32.0;
+ qvfb->setZoom(d);
+ label->setText(QString::number(d,'g',2));
+}
+
+// =====================================================================
+
+QVFb::QVFb( int display_id, int w, int h, int d, int r, const QString &skin, DisplayType displayType, QWidget *parent, Qt::WindowFlags flags )
+ : QMainWindow( parent, flags )
+{
+ this->displayType = displayType;
+ view = 0;
+ secondaryView = 0;
+ scroller = 0;
+ this->skin = 0;
+ currentSkinIndex = -1;
+ findSkins(skin);
+ zoomer = 0;
+ QPixmap pix(":/res/images/logo.png");
+ setWindowIcon( pix );
+ rateDlg = 0;
+ refreshRate = 30;
+#if QT_VERSION >= 0x030000
+ // When compiling with Qt 3 we need to create the menu first to
+ // avoid scroll bars in the main window
+ createMenu( menuBar() );
+ init( display_id, w, h, d, r, skin );
+ enableCursor( true );
+#else
+ init( display_id, w, h, d, r, skin );
+ createMenu( menuBar() );
+#endif
+}
+
+QVFb::~QVFb()
+{
+}
+
+void QVFb::popupMenu()
+{
+ QMenu *pm = new QMenu( this );
+ createMenu( pm );
+ pm->exec(QCursor::pos());
+}
+
+void QVFb::init( int display_id, int pw, int ph, int d, int r, const QString& skin_name )
+{
+ delete view;
+ view = 0;
+ delete secondaryView;
+ secondaryView = 0;
+ delete scroller;
+ scroller = 0;
+ delete skin;
+ skin = 0;
+
+ skinscaleH = skinscaleV = 1.0;
+ QVFbView::Rotation rot = ((r == 90) ? QVFbView::Rot90 :
+ ((r == 180) ? QVFbView::Rot180 :
+ ((r == 270) ? QVFbView::Rot270 :
+ QVFbView::Rot0 )));
+ if ( !skin_name.isEmpty() ) {
+ const bool vis = isVisible();
+ DeviceSkinParameters parameters;
+ QString readError;
+ if (parameters.read(skin_name,DeviceSkinParameters::ReadAll, &readError)) {
+ skin = new DeviceSkin(parameters, this);
+ connect(skin, SIGNAL(popupMenu()), this, SLOT(popupMenu()));
+ const int sw = parameters.screenSize().width();
+ const int sh = parameters.screenSize().height();
+ const int sd = parameters.screenDepth;
+ if (!pw) pw = sw;
+ if (!ph) ph = sh;
+ if (d < 0) {
+ if (sd)
+ d = sd;
+ else
+ d = -d;
+ }
+ if (vis)
+ hide();
+ menuBar()->hide();
+ scroller = 0;
+#ifdef Q_WS_X11
+ if (displayType == X11)
+ view = new QVFbX11View( display_id, pw, ph, d, rot, skin );
+ else
+#endif
+ view = new QVFbView( display_id, pw, ph, d, rot, skin );
+ skin->setView( view );
+ view->setContentsMargins( 0, 0, 0, 0 );
+ view->setTouchscreenEmulation(!parameters.hasMouseHover);
+ connect(skin, SIGNAL(skinKeyPressEvent(int,QString,bool)), view, SLOT(skinKeyPressEvent(int,QString,bool)));
+ connect(skin, SIGNAL(skinKeyReleaseEvent(int,QString,bool)), view, SLOT(skinKeyReleaseEvent(int,QString,bool)));
+
+ copyButtonConfiguration(skin->prefix(), view->displayId());
+
+ setCentralWidget( skin );
+ adjustSize();
+ skinscaleH = (double)sw/pw;
+ skinscaleV = (double)sh/ph;
+ if ( skinscaleH != 1.0 || skinscaleH != 1.0 )
+ setZoom(skinscaleH);
+ view->show();
+
+ if (parameters.hasSecondaryScreen()) {
+ const QSize ssize = parameters.secondaryScreenSize();
+ // assumes same depth and rotation
+#ifdef Q_WS_X11
+ if (displayType == X11)
+ secondaryView = new QVFbX11View( display_id+1, ssize.width(), ssize.height(), d, rot, skin );
+ else
+#endif
+ secondaryView = new QVFbView( display_id+1, ssize.width(), ssize.height(), d, rot, skin );
+ skin->setSecondaryView(secondaryView);
+ secondaryView->show();
+ }
+
+ if ( vis ) show();
+ } else {
+ qWarning("%s", qPrintable(readError));
+ }
+ }
+
+ // If we failed to get a skin or we were not supplied
+ // with one then fallback to a framebuffer without
+ // a skin
+ if (!skin){
+ // Default values
+ if (!pw)
+ pw = 240;
+ if (!ph)
+ ph = 320;
+ if (!d)
+ d = 32;
+ else if (d < 0)
+ d = -d;
+
+ if (currentSkinIndex != -1) {
+ clearMask();
+ setParent( 0, 0 );
+ move( pos() );
+ show();
+ //unset fixed size:
+ setMinimumSize(0,0);
+ setMaximumSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX);
+ }
+ menuBar()->show();
+ scroller = new QScrollArea(this);
+ scroller->setFocusPolicy(Qt::NoFocus); // don't steal key events from the embedded app
+#ifdef Q_WS_X11
+ if (displayType == X11)
+ view = new QVFbX11View( display_id, pw, ph, d, rot, scroller );
+ else
+#endif
+ view = new QVFbView( display_id, pw, ph, d, rot, scroller );
+ scroller->setWidget(view);
+ view->setContentsMargins( 0, 0, 0, 0 );
+ setCentralWidget(scroller);
+#if QT_VERSION >= 0x030000
+ ph += 2; // avoid scrollbar
+#endif
+ scroller->show();
+ // delete defaultbuttons.conf if it was left behind...
+ unlink(QFileInfo(QString("/tmp/qtembedded-%1/defaultbuttons.conf").arg(view->displayId())).absoluteFilePath().toLatin1().constData());
+ if (secondaryView)
+ unlink(QFileInfo(QString("/tmp/qtembedded-%1/defaultbuttons.conf").arg(view->displayId()+1)).absoluteFilePath().toLatin1().constData());
+ }
+ view->setRate(refreshRate);
+ if (secondaryView) {
+ secondaryView->setRate(refreshRate);
+ }
+ // Resize QVFb to the new size
+ QSize newSize = view->sizeHint();
+
+ // ... fudge factor
+ newSize += QSize(20, 35);
+
+ resize(newSize);
+
+ setWindowTitle(QString("Virtual framebuffer %1x%2 %3bpp Display :%4 Rotate %5")
+ .arg(view->displayWidth()).arg(view->displayHeight())
+ .arg(d).arg(display_id).arg(r));
+}
+
+void QVFb::enableCursor( bool e )
+{
+ if ( skin && skin->hasCursor() ) {
+ view->setCursor( Qt::BlankCursor );
+ if (secondaryView)
+ secondaryView->setCursor( Qt::BlankCursor );
+ } else {
+ view->setCursor( e ? Qt::ArrowCursor : Qt::BlankCursor );
+ if (secondaryView)
+ secondaryView->setCursor( e ? Qt::ArrowCursor : Qt::BlankCursor );
+ }
+ cursorAction->setChecked( e );
+}
+
+template <typename T>
+void QVFb::createMenu(T *menu)
+{
+ menu->addMenu( createFileMenu() );
+ menu->addMenu( createViewMenu() );
+ menu->addSeparator();
+ menu->addMenu( createHelpMenu() );
+}
+
+QMenu* QVFb::createFileMenu()
+{
+ QMenu *file = new QMenu( "File", this );
+ file->addAction( "Configure...", this, SLOT(configure()), 0 );
+ file->addSeparator();
+ file->addAction( "&Save image...", this, SLOT(saveImage()), 0 );
+ file->addAction( "&Animation...", this, SLOT(toggleAnimation()), 0 );
+ file->addSeparator();
+ file->addAction( "&Quit", qApp, SLOT(quit()) );
+ return file;
+}
+
+QMenu* QVFb::createViewMenu()
+{
+ viewMenu = new QMenu( "View", this );
+ cursorAction = viewMenu->addAction( "Show &Cursor", this,
+ SLOT(toggleCursor()) );
+ cursorAction->setCheckable(true);
+ if ( view )
+ enableCursor(true);
+ viewMenu->addAction( "&Refresh Rate...", this, SLOT(changeRate()) );
+ viewMenu->addSeparator();
+ viewMenu->addAction( "No rotation", this, SLOT(setRot0()) );
+ viewMenu->addAction( "90\260 rotation", this, SLOT(setRot90()) );
+ viewMenu->addAction( "180\260 rotation", this, SLOT(setRot180()) );
+ viewMenu->addAction( "270\260 rotation", this, SLOT(setRot270()) );
+ viewMenu->addSeparator();
+ viewMenu->addAction( "Zoom scale &0.5", this, SLOT(setZoomHalf()) );
+ viewMenu->addAction( "Zoom scale 0.75", this, SLOT(setZoom075()) );
+ viewMenu->addAction( "Zoom scale &1", this, SLOT(setZoom1()) );
+ viewMenu->addAction( "Zoom scale &2", this, SLOT(setZoom2()) );
+ viewMenu->addAction( "Zoom scale &3", this, SLOT(setZoom3()) );
+ viewMenu->addAction( "Zoom scale &4", this, SLOT(setZoom4()) );
+ viewMenu->addSeparator();
+ viewMenu->addAction( "Zoom scale...", this, SLOT(setZoom()) );
+ return viewMenu;
+}
+
+
+QMenu* QVFb::createHelpMenu()
+{
+ QMenu *help = new QMenu( "Help", this );
+ help->addAction("About...", this, SLOT(about()));
+ return help;
+}
+
+void QVFb::setZoom(double z)
+{
+ view->setZoom(z,z*skinscaleV/skinscaleH);
+ if (secondaryView)
+ secondaryView->setZoom(z,z*skinscaleV/skinscaleH);
+
+ if (skin) {
+ skin->setTransform(QMatrix().scale(z/skinscaleH,z/skinscaleV).rotate(90*view->displayRotation()));
+ if (secondaryView)
+ secondaryView->setFixedSize(
+ int(secondaryView->displayWidth()*z),
+ int(secondaryView->displayHeight()*z*skinscaleV/skinscaleH));
+ }
+}
+
+void QVFb::setRotation(QVFbView::Rotation r)
+{
+ view->setRotation(r);
+ if (secondaryView)
+ secondaryView->setRotation(r);
+ setZoom(view->zoomH());
+}
+
+void QVFb::setRot0()
+{
+ setRotation(QVFbView::Rot0);
+}
+
+void QVFb::setRot90()
+{
+ setRotation(QVFbView::Rot90);
+}
+
+void QVFb::setRot180()
+{
+ setRotation(QVFbView::Rot180);
+}
+
+void QVFb::setRot270()
+{
+ setRotation(QVFbView::Rot270);
+}
+
+void QVFb::setZoomHalf()
+{
+ setZoom(0.5);
+}
+
+void QVFb::setZoom075()
+{
+ setZoom(0.75);
+}
+
+void QVFb::setZoom1()
+{
+ setZoom(1);
+}
+
+void QVFb::setZoom()
+{
+ if ( !zoomer )
+ zoomer = new Zoomer(this);
+ zoomer->show();
+}
+
+void QVFb::setZoom2()
+{
+ setZoom(2);
+}
+
+void QVFb::setZoom3()
+{
+ setZoom(3);
+}
+
+void QVFb::setZoom4()
+{
+ setZoom(4);
+}
+
+void QVFb::saveImage()
+{
+ QImage img = view->image();
+ QString filename = QFileDialog::getSaveFileName(this, "Save Main Screen image", "snapshot.png", "Portable Network Graphics (*.png)");
+ if (!filename.isEmpty()){
+ if(!img.save(filename,"PNG"))
+ QMessageBox::critical(this, "Save Main Screen Image", "Save failed. Check that you have permission to write to the target directory.");
+ }
+ if (secondaryView) {
+ QImage img = view->image();
+ QString filename = QFileDialog::getSaveFileName(this, "Save Second Screen image", "snapshot.png", "Portable Network Graphics (*.png)");
+ if (!filename.isEmpty()) {
+ if(!img.save(filename,"PNG"))
+ QMessageBox::critical(this, "Save Second Screen Image", "Save failed. Check that you have permission to write to the target directory.");
+ }
+ }
+}
+
+void QVFb::toggleAnimation()
+{
+ static AnimationSaveWidget *animWidget = 0;
+ if ( !animWidget )
+ animWidget = new AnimationSaveWidget(view);
+ if ( animWidget->isVisible() )
+ animWidget->hide();
+ else
+ animWidget->show();
+}
+
+void QVFb::toggleCursor()
+{
+ enableCursor(cursorAction->isChecked());
+}
+
+void QVFb::changeRate()
+{
+ if ( !rateDlg ) {
+ rateDlg = new QVFbRateDialog( refreshRate, this );
+ connect( rateDlg, SIGNAL(updateRate(int)), this, SLOT(setRate(int)) );
+ }
+
+ rateDlg->show();
+}
+
+void QVFb::setRate(int i)
+{
+ refreshRate = i;
+ view->setRate(i);
+ if (secondaryView)
+ secondaryView->setRate(i);
+}
+
+
+void QVFb::about()
+{
+ QMessageBox::about(this, "About QVFB",
+ "<h2>The Qt for Embedded Linux Virtual X11 Framebuffer</h2>"
+ "<p>This application runs under Qt for X11, emulating a simple framebuffer, "
+ "which the Qt for Embedded Linux server and clients can attach to just as if "
+ "it was a hardware Linux framebuffer. "
+ "<p>With the aid of this development tool, you can develop Qt for Embedded "
+ "Linux applications under X11 without having to switch to a virtual console. "
+ "This means you can comfortably use your other development tools such "
+ "as GUI profilers and debuggers."
+ );
+}
+
+void QVFb::findSkins(const QString &currentSkin)
+{
+ skinnames.clear();
+ skinfiles.clear();
+ QDir dir(":/skins/","*.skin");
+ const QFileInfoList l = dir.entryInfoList();
+ int i = 1; // "None" is already in list at index 0
+ for (QFileInfoList::const_iterator it = l.begin(); it != l.end(); ++it) {
+ skinnames.append((*it).baseName()); // should perhaps be in file
+ skinfiles.append((*it).filePath());
+ if (((*it).baseName() + ".skin") == currentSkin)
+ currentSkinIndex = i;
+ i++;
+ }
+}
+
+class Config : public QDialog, public Ui::Config
+{
+public:
+ Config(QWidget *parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ setModal(true);
+
+ connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+ }
+};
+
+void QVFb::configure()
+{
+ config = new Config(this);
+
+ int w = view->displayWidth();
+ int h = view->displayHeight();
+
+ // Need to block signals, because we connect to animateClick(),
+ // since QCheckBox doesn't have setChecked(bool) in 2.x.
+ chooseSize(QSize(w,h));
+ config->skin->insertItems(config->skin->count(), skinnames);
+ if (currentSkinIndex > 0)
+ config->skin->setCurrentIndex(currentSkinIndex);
+ config->skin->addItem(tr("Browse..."));
+ config->touchScreen->setChecked(view->touchScreenEmulation());
+ config->lcdScreen->setChecked(view->lcdScreenEmulation());
+ chooseDepth(view->displayDepth(), view->displayFormat());
+ connect(config->skin, SIGNAL(activated(int)), this, SLOT(skinConfigChosen(int)));
+ if ( view->gammaRed() == view->gammaGreen() && view->gammaGreen() == view->gammaBlue() ) {
+ config->gammaslider->setValue(int(view->gammaRed()*400));
+ config->rslider->setValue(100);
+ config->gslider->setValue(100);
+ config->bslider->setValue(100);
+ } else {
+ config->gammaslider->setValue(100);
+ config->rslider->setValue(int(view->gammaRed()*400));
+ config->gslider->setValue(int(view->gammaGreen()*400));
+ config->bslider->setValue(int(view->gammaBlue()*400));
+ }
+ connect(config->gammaslider, SIGNAL(valueChanged(int)), this, SLOT(setGamma400(int)));
+ connect(config->rslider, SIGNAL(valueChanged(int)), this, SLOT(setR400(int)));
+ connect(config->gslider, SIGNAL(valueChanged(int)), this, SLOT(setG400(int)));
+ connect(config->bslider, SIGNAL(valueChanged(int)), this, SLOT(setB400(int)));
+ updateGammaLabels();
+
+ double ogr=view->gammaRed(), ogg=view->gammaGreen(), ogb=view->gammaBlue();
+ qApp->setQuitOnLastWindowClosed(false);
+
+ hide();
+ if ( config->exec() ) {
+ int id = view->displayId(); // not settable yet
+ if ( config->size_176_220->isChecked() ) {
+ w=176; h=220;
+ } else if ( config->size_240_320->isChecked() ) {
+ w=240; h=320;
+ } else if ( config->size_320_240->isChecked() ) {
+ w=320; h=240;
+ } else if ( config->size_640_480->isChecked() ) {
+ w=640; h=480;
+ } else if ( config->size_800_600->isChecked() ) {
+ w=800; h=600;
+ } else if ( config->size_1024_768->isChecked() ) {
+ w=1024; h=768;
+ } else {
+ w=config->size_width->value();
+ h=config->size_height->value();
+ }
+ int d;
+ if ( config->depth_1->isChecked() )
+ d=1;
+ else if ( config->depth_4gray->isChecked() )
+ d=4;
+ else if ( config->depth_8->isChecked() )
+ d=8;
+ else if ( config->depth_12->isChecked() )
+ d=12;
+ else if ( config->depth_15->isChecked() )
+ d = 15;
+ else if ( config->depth_16->isChecked() )
+ d=16;
+ else if ( config->depth_18->isChecked() )
+ d=18;
+ else if ( config->depth_24->isChecked() )
+ d=24;
+ else
+ d=32;
+ QVFbView::PixelFormat displayFormat = config->depth_32_argb->isChecked()
+ ? QVFbView::ARGBFormat : QVFbView::DefaultFormat;
+ int skinIndex = config->skin->currentIndex();
+ if ( w != view->displayWidth() || h != view->displayHeight()
+ || d != view->displayDepth() || skinIndex != currentSkinIndex ) {
+ QVFbView::Rotation rot = view->displayRotation();
+ int r = ((rot == QVFbView::Rot90) ? 90 :
+ ((rot == QVFbView::Rot180) ? 180 :
+ ((rot == QVFbView::Rot270) ? 270 : 0 )));
+ currentSkinIndex = skinIndex;
+ init( id, w, h, d, r, skinIndex > 0 ? skinfiles[skinIndex-1] : QString::null );
+ }
+ view->setViewFormat(displayFormat);
+ view->setTouchscreenEmulation( config->touchScreen->isChecked() );
+ bool lcdEmulation = config->lcdScreen->isChecked();
+ view->setLcdScreenEmulation( lcdEmulation );
+ if ( lcdEmulation )
+ setZoom3();
+ } else {
+ view->setGamma(ogr, ogg, ogb);
+ }
+ show();
+ qApp->setQuitOnLastWindowClosed(true);
+ delete config;
+ config=0;
+}
+
+void QVFb::chooseSize(const QSize& sz)
+{
+ config->size_width->blockSignals(true);
+ config->size_height->blockSignals(true);
+ config->size_width->setValue(sz.width());
+ config->size_height->setValue(sz.height());
+ config->size_width->blockSignals(false);
+ config->size_height->blockSignals(false);
+ config->size_custom->setChecked(true); // unless changed by settings below
+ config->size_176_220->setChecked(sz == QSize(176,220));
+ config->size_240_320->setChecked(sz == QSize(240,320));
+ config->size_320_240->setChecked(sz == QSize(320,240));
+ config->size_640_480->setChecked(sz == QSize(640,480));
+ config->size_800_600->setChecked(sz == QSize(800,600));
+ config->size_1024_768->setChecked(sz == QSize(1024,768));
+}
+
+void QVFb::chooseDepth(int depth, QVFbView::PixelFormat displayFormat)
+{
+ config->depth_1->setChecked(depth==1);
+ config->depth_4gray->setChecked(depth==4);
+ config->depth_8->setChecked(depth==8);
+ config->depth_12->setChecked(depth==12);
+ config->depth_15->setChecked(depth==15);
+ config->depth_16->setChecked(depth==16);
+ config->depth_18->setChecked(depth==18);
+ config->depth_24->setChecked(depth==24);
+ config->depth_32->setChecked(depth==32 && displayFormat != QVFbView::ARGBFormat);
+ config->depth_32_argb->setChecked(depth==32 && displayFormat == QVFbView::ARGBFormat);
+}
+
+void QVFb::skinConfigChosen(int i)
+{
+ if (i == config->skin->count() - 1) { // Browse... ?
+ QFileDialog dlg(this);
+ dlg.setFileMode(QFileDialog::DirectoryOnly);
+ dlg.setWindowTitle(tr("Load Custom Skin..."));
+ dlg.setFilter(tr("All QVFB Skins (*.skin)"));
+ dlg.setDirectory(QDir::current());
+ if (dlg.exec() && dlg.selectedFiles().count() == 1) {
+ skinfiles.append(dlg.selectedFiles().first());
+ i = skinfiles.count();
+ config->skin->insertItem(i, QFileInfo(skinfiles.last()).baseName());
+ config->skin->setCurrentIndex(i);
+ } else {
+ i = 0;
+ }
+ }
+ if ( i ) {
+ DeviceSkinParameters parameters;
+ QString readError;
+ if (parameters.read(skinfiles[i-1], DeviceSkinParameters::ReadSizeOnly, &readError)) {
+ chooseSize(parameters.screenSize());
+ if (parameters.screenDepth)
+ chooseDepth(parameters.screenDepth,QVFbView::ARGBFormat);
+ config->touchScreen->setChecked(!parameters.hasMouseHover);
+ } else {
+ qWarning("%s", qPrintable(readError));
+ }
+ }
+}
+
+void QVFb::setGamma400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(config->rslider->value()/100.0*g,
+ config->gslider->value()/100.0*g,
+ config->bslider->value()/100.0*g);
+ updateGammaLabels();
+}
+
+void QVFb::setR400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(config->rslider->value()/100.0*g,
+ view->gammaGreen(),
+ view->gammaBlue());
+ updateGammaLabels();
+}
+
+void QVFb::setG400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(view->gammaRed(),
+ config->gslider->value()/100.0*g,
+ view->gammaBlue());
+ updateGammaLabels();
+}
+
+void QVFb::setB400(int n)
+{
+ double g = n/100.0;
+ view->setGamma(view->gammaRed(),
+ view->gammaGreen(),
+ config->bslider->value()/100.0*g);
+ updateGammaLabels();
+}
+
+void QVFb::updateGammaLabels()
+{
+ config->rlabel->setText(QString::number(view->gammaRed(),'g',2));
+ config->glabel->setText(QString::number(view->gammaGreen(),'g',2));
+ config->blabel->setText(QString::number(view->gammaBlue(),'g',2));
+}
+
+QSize QVFb::sizeHint() const
+{
+ return QSize(int(view->displayWidth()*view->zoomH()),
+ int(menuBar()->height()+view->displayHeight()*view->zoomV()));
+}
+
+// =====================================================================
+
+AnimationSaveWidget::AnimationSaveWidget(QVFbAbstractView *v) :
+ QWidget((QWidget*)0,0),
+ view(v), recording(false), animation(0),
+ timerId(-1), progressTimerId(-1),
+ recOn(red_on_led_xpm), recOff(red_off_led_xpm),
+ imageNum(0)
+{
+ // Create the animation record UI dialog
+ QVBoxLayout *vlayout = new QVBoxLayout( this );
+
+ QWidget *hbox = new QWidget( this );
+ vlayout->addWidget(hbox);
+ QHBoxLayout *hlayout = new QHBoxLayout(hbox);
+ recBt = new QPushButton( tr("Record"), hbox );
+ hlayout->addWidget(recBt);
+ resetBt = new QPushButton( tr("Reset"), hbox );
+ hlayout->addWidget(resetBt);
+ saveBt = new QPushButton( tr("Save"), hbox );
+ hlayout->addWidget(saveBt);
+ recBt->setFixedWidth( 100 );
+ resetBt->setFixedWidth( 100 );
+ saveBt->setFixedWidth( 100 );
+ timeDpy = new QLabel( "00:00", hbox );
+ hlayout->addWidget(timeDpy);
+ recLED = new QLabel( hbox );
+ hlayout->addWidget(recLED);
+ recLED->setPixmap( recOff );
+ timeDpy->setMargin( 5 );
+ connect( recBt, SIGNAL(clicked()), this, SLOT(toggleRecord()) );
+ connect( resetBt, SIGNAL(clicked()), this, SLOT(reset()) );
+ connect( saveBt, SIGNAL(clicked()), this, SLOT(save()) );
+ elapsed = 0;
+ vlayout->setMargin( 5 );
+ vlayout->setSpacing( 5 );
+ haveMpeg = detectPpmtoMpegCommand();
+ mpegSave = new QCheckBox( tr("Save in MPEG format (requires netpbm package installed)"), this );
+ vlayout->addWidget(mpegSave);
+ mpegSave->setChecked( haveMpeg );
+ mpegSave->setEnabled( haveMpeg );
+ savingAsMpeg = haveMpeg;
+ QWidget *hbox2 = new QWidget( this );
+ vlayout->addWidget(hbox2);
+ QHBoxLayout *hlayout2 = new QHBoxLayout( hbox2 );
+ statusText = new QLabel( tr("Click record to begin recording."), hbox2 );
+ hlayout2->addWidget(statusText);
+ progressBar = new QProgressBar( hbox2 );
+ progressBar->setValue( 0 );
+ hlayout2->addWidget(progressBar);
+ progressBar->hide();
+}
+
+AnimationSaveWidget::~AnimationSaveWidget()
+{
+ // clean up
+ removeTemporaryFiles();
+ delete animation;
+}
+
+// returns true if we have ppmtompeg command, else returns false
+bool AnimationSaveWidget::detectPpmtoMpegCommand()
+{
+ // search the PATH for the ppmtompeg command to test we can record to mpeg
+ QStringList paths = QString(::getenv("PATH")).split(":");
+ for ( int i = 0; i < paths.count(); i++ )
+ if ( QFile::exists( paths[i] + "/" + "ppmtompeg" ) )
+ return true;
+ return false;
+}
+
+void AnimationSaveWidget::timerEvent( QTimerEvent *te )
+{
+ QString str;
+
+ // Recording timer
+ if ( te->timerId() == timerId ) {
+
+ // Add a frame to the animation
+ if ( savingAsMpeg && view )
+ view->image().save( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", imageNum), "PPM");
+ else if ( animation && view )
+ animation->appendFrame(view->image());//QPoint(0,0));
+ imageNum++;
+
+ // Update the display of number of seconds that have been recorded.
+ int tmMsec = tm.elapsed();
+ timeDpy->setText( str.sprintf("%02d:%02d", tmMsec/60000, (tmMsec%60000)/1000) );
+ QObject::timerEvent( te );
+
+ // Make the recording LED blink
+ static int tick = 0;
+ static bool on = false;
+ if ( tick > 10 ) {
+ tick = 0;
+ if ( on )
+ recLED->setPixmap( recOff );
+ else
+ recLED->setPixmap( recOn );
+ on = !on;
+ }
+ tick++;
+ }
+
+ // Saving progress timer
+ if ( te->timerId() == progressTimerId ) {
+ // Parse output log file to work out the encoding progress.
+ QFile f("/tmp/qvfb_tmp_output.log");
+ f.open(QIODevice::ReadOnly);
+ int largestNum = 0;
+ bool done = false;
+ char buffer[1024];
+ while ( !f.atEnd() ) {
+ // example of the output log entries
+ // During each frame:
+ // "FRAME 764 (B): I BLOCKS: 0......
+ // When complete:
+ // "======FRAMES READ: 766"
+ f.readLine(buffer, 1024);
+ str = QString(buffer);
+ if ( str.left(6) == "FRAME " ) {
+ int num = str.mid(6, str.indexOf(QChar(' '), 6) - 6).toInt();
+ if ( num > largestNum )
+ largestNum = num;
+ } else if ( str.left(18) == "======FRAMES READ:" ) {
+ done = true;
+ }
+ }
+ f.close();
+
+ // Update the progress bar with the frame we are up to
+ progressBar->setValue( largestNum );
+
+ // Finished saving
+ if ( done ) {
+ progressBar->hide();
+ statusText->setText( tr("Finished saving."));
+ removeTemporaryFiles();
+ killTimer( progressTimerId );
+ progressTimerId = -1;
+ reset();
+ }
+ }
+}
+
+// Takes the saved ppm files and converts them to a mpeg file named filename
+void AnimationSaveWidget::convertToMpeg(QString filename)
+{
+ recLED->setPixmap( recOff );
+ killTimer( timerId );
+
+ progressBar->show();
+ progressBar->setRange( 0, imageNum );
+ progressBar->setValue( 0 );
+
+ // Build parameter file required by ppmtompeg
+ QFile file("/tmp/qvfb_tmp_ppmtompeg.params");
+ if ( file.open( QIODevice::WriteOnly ) ) {
+ QTextStream t( &file );
+ t << "PATTERN IBBPBBPBBPBBPBB\n";
+ t << "OUTPUT " << filename << "\n";
+ t << "INPUT_DIR /tmp\n";
+ t << "INPUT\n";
+ QString str;
+ str = str.sprintf("%04d", imageNum - 1);
+ t << "qvfb_tmp_image_*.ppm [0000-" << str << "]\n";
+ t << "END_INPUT\n";
+ t << "BASE_FILE_FORMAT PPM\n";
+ t << "INPUT_CONVERT *\n";
+ t << "GOP_SIZE 15\n";
+ t << "SLICES_PER_FRAME 1\n";
+ t << "PIXEL HALF\n";
+ t << "RANGE 5\n";
+ t << "PSEARCH_ALG LOGARITHMIC\n";
+ t << "BSEARCH_ALG SIMPLE\n";
+ t << "IQSCALE 1\n";
+ t << "PQSCALE 1\n";
+ t << "BQSCALE 1\n";
+ t << "REFERENCE_FRAME DECODED\n";
+ t << "ASPECT_RATIO 1\n";
+ t << "FRAME_RATE 24\n";
+ t << "BIT_RATE 64000\n"; // Quality
+ t << "BUFFER_SIZE 2048\n";
+ }
+ file.close();
+
+ // ### can't use QProcess, not in Qt 2.3
+ // ### but it's certainly in Qt 4! use it?
+ // Execute the ppmtompeg command as a seperate process to do the encoding
+ pid_t pid = ::fork();
+ if ( !pid ) {
+ // Child process
+ // redirect stdout to log file
+ freopen("/tmp/qvfb_tmp_output.log", "w", stdout);
+ // ppmtompeg tool is from the netpbm package
+ ::execlp("ppmtompeg", "ppmtompeg", "/tmp/qvfb_tmp_ppmtompeg.params", (void *)0);
+ exit(0);
+ }
+
+ // Update the saving progress bar every 200ms
+ progressTimerId = startTimer( 200 );
+}
+
+// Cleanup temporary files created during creating a mpeg file
+void AnimationSaveWidget::removeTemporaryFiles()
+{
+ QString str;
+ for ( int i = 0; i < imageNum; i++ )
+ QFile::remove( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", i) );
+ QFile::remove("/tmp/qvfb_tmp_ppmtompeg.params");
+ QFile::remove("/tmp/qvfb_tmp_output.log");
+ imageNum = 0;
+}
+
+// toggles between recording and paused (usually when record button clicked)
+void AnimationSaveWidget::toggleRecord()
+{
+ if ( recording ) {
+ recLED->setPixmap( recOff );
+ recBt->setText( tr("Record") );
+ statusText->setText( tr("Paused. Click record to resume, or save if done."));
+ killTimer( timerId );
+ timerId = -1;
+ elapsed = tm.elapsed();
+ } else {
+ recLED->setPixmap( recOn );
+ recBt->setText( tr("Pause") );
+ statusText->setText( tr("Recording..."));
+ tm.start();
+ if ( elapsed == 0 ) {
+ savingAsMpeg = mpegSave->isChecked();
+ if ( !savingAsMpeg ) {
+ delete animation;
+ animation = new QAnimationWriter("/tmp/qvfb_tmp_animation.mng","MNG");
+ animation->setFrameRate(24);
+ if ( view )
+ animation->appendFrame(view->image());
+ }
+ }
+ tm = tm.addMSecs(-elapsed);
+ elapsed = 0;
+ timerId = startTimer(1000 / 24);
+ }
+ recording = !recording;
+}
+
+// Reset everything to initial state of not recording
+void AnimationSaveWidget::reset()
+{
+ if ( recording ) {
+ toggleRecord();
+ statusText->setText( tr("Click record to begin recording."));
+ removeTemporaryFiles();
+ }
+ progressBar->setValue( 0 );
+ timeDpy->setText( "00:00" );
+ elapsed = 0;
+ imageNum = 0;
+ delete animation;
+ animation = 0;
+}
+
+// Prompt for filename to save to and put animation in that file
+void AnimationSaveWidget::save()
+{
+ if ( recording )
+ toggleRecord(); // pauses
+ statusText->setText( tr("Saving... "));
+
+ QString filename;
+ if ( savingAsMpeg ) {
+ filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mpg");
+ if ( !filename.isNull() )
+ convertToMpeg(filename);
+ } else {
+ filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mng");
+ if (filename.isNull()) {
+ statusText->setText(tr("Save canceled."));
+ } else {
+ QFile::remove(filename);
+ bool success = QFile::rename(QLatin1String("/tmp/qvfb_tmp_animation.mng"),
+ filename);
+ if (success) {
+ statusText->setText(tr("Finished saving."));
+ reset();
+ } else {
+ statusText->setText(tr("Save failed!"));
+ }
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "qvfb.moc"
diff --git a/tools/qvfb/qvfb.h b/tools/qvfb/qvfb.h
new file mode 100644
index 0000000..90f2a33
--- /dev/null
+++ b/tools/qvfb/qvfb.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFB_H
+#define QVFB_H
+
+#include <QMainWindow>
+#include <QStringList>
+#include "qvfbview.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVFbAbstractView;
+class QVFbRateDialog;
+class QPopupMenu;
+class QMenuData;
+class QAction;
+class Config;
+class DeviceSkin;
+class QVFb;
+class QLabel;
+class QMenu;
+class QScrollArea;
+
+class Zoomer : public QWidget {
+ Q_OBJECT
+public:
+ Zoomer(QVFb* target);
+
+private slots:
+ void zoom(int);
+
+private:
+ QVFb *qvfb;
+ QLabel *label;
+};
+
+class QVFb: public QMainWindow
+{
+ Q_OBJECT
+public:
+ enum DisplayType { QWS, X11 };
+
+ QVFb( int display_id, int w, int h, int d, int r, const QString &skin, DisplayType displayType, QWidget *parent = 0, Qt::WindowFlags wflags = 0 );
+ ~QVFb();
+
+ void enableCursor( bool e );
+
+ QSize sizeHint() const;
+
+public slots:
+ void popupMenu();
+
+protected slots:
+ void saveImage();
+ void toggleAnimation();
+ void toggleCursor();
+ void changeRate();
+ void setRate(int);
+ void about();
+
+ void configure();
+ void skinConfigChosen(int i);
+ void chooseSize(const QSize& sz);
+ void chooseDepth(int depth, QVFbView::PixelFormat displayFormat);
+
+ void setZoom1();
+ void setZoom2();
+ void setZoom3();
+ void setZoom4();
+ void setZoomHalf();
+ void setZoom075();
+
+ void setZoom();
+
+ void setRot0();
+ void setRot90();
+ void setRot180();
+ void setRot270();
+
+public slots:
+ void setZoom(double);
+ void setRotation(QVFbView::Rotation);
+
+protected:
+ template <typename T>
+ void createMenu(T *menu);
+ QMenu* createFileMenu();
+ QMenu* createViewMenu();
+ QMenu* createHelpMenu();
+
+private:
+ void findSkins(const QString &currentSkin);
+ void init( int display_id, int w, int h, int d, int r, const QString& skin );
+ DeviceSkin *skin;
+ double skinscaleH,skinscaleV;
+ QVFbAbstractView *view;
+ QVFbAbstractView *secondaryView;
+ QVFbRateDialog *rateDlg;
+ QMenu *viewMenu;
+ QAction *cursorAction;
+ Config* config;
+ QStringList skinnames;
+ QStringList skinfiles;
+ int currentSkinIndex;
+ Zoomer *zoomer;
+ QScrollArea* scroller;
+ DisplayType displayType;
+
+ int refreshRate;
+private slots:
+ void setGamma400(int n);
+ void setR400(int n);
+ void setG400(int n);
+ void setB400(int n);
+ void updateGammaLabels();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/qvfb.pro b/tools/qvfb/qvfb.pro
new file mode 100644
index 0000000..a3b55ab
--- /dev/null
+++ b/tools/qvfb/qvfb.pro
@@ -0,0 +1,73 @@
+TEMPLATE = app
+CONFIG += qt warn_on uic
+TARGET = qvfb
+DESTDIR = ../../bin
+
+!win32:!embedded:!mac:CONFIG += x11
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+DEPENDPATH = ../../include
+
+FORMS = config.ui
+HEADERS = qvfb.h \
+ qvfbview.h \
+ qvfbratedlg.h \
+ qanimationwriter.h \
+ gammaview.h \
+ qvfbprotocol.h \
+ qvfbshmem.h \
+ qvfbmmap.h \
+ qvfbhdr.h \
+ qlock_p.h \
+ qwssignalhandler_p.h
+
+SOURCES = qvfb.cpp \
+ qvfbview.cpp \
+ qvfbratedlg.cpp \
+ main.cpp \
+ qanimationwriter.cpp \
+ qvfbprotocol.cpp \
+ qvfbshmem.cpp \
+ qvfbmmap.cpp \
+ qlock.cpp \
+ qwssignalhandler.cpp
+
+include($$QT_SOURCE_TREE/tools/shared/deviceskin/deviceskin.pri)
+
+contains(QT_CONFIG, opengl) {
+ QT += opengl
+}
+
+contains(QT_CONFIG, system-png) {
+ LIBS += -lpng
+} else {
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/libpng
+}
+contains(QT_CONFIG, system-zlib) {
+ LIBS += -lz
+} else {
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/zlib
+}
+
+unix:x11 {
+ HEADERS += qvfbx11view.h \
+ x11keyfaker.h \
+ qtopiakeysym.h
+ SOURCES += qvfbx11view.cpp \
+ x11keyfaker.cpp
+ LIBS += -lXtst
+}
+
+RESOURCES += qvfb.qrc \
+ ClamshellPhone.qrc \
+ PDAPhone.qrc \
+ SmartPhone2.qrc \
+ SmartPhone.qrc \
+ SmartPhoneWithButtons.qrc \
+ TouchscreenPhone.qrc \
+ Trolltech-Keypad.qrc \
+ Trolltech-Touchscreen.qrc \
+ PortableMedia.qrc
+
diff --git a/tools/qvfb/qvfb.qrc b/tools/qvfb/qvfb.qrc
new file mode 100644
index 0000000..27c39df
--- /dev/null
+++ b/tools/qvfb/qvfb.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res">
+ <file>images/logo.png</file>
+ <file>images/logo-nt.png</file>
+</qresource>
+</RCC>
+
diff --git a/tools/qvfb/qvfbmmap.cpp b/tools/qvfb/qvfbmmap.cpp
new file mode 100644
index 0000000..d8230f7
--- /dev/null
+++ b/tools/qvfb/qvfbmmap.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbmmap.h"
+#include "qvfbhdr.h"
+
+#include <QTimer>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+QMMapViewProtocol::QMMapViewProtocol(int displayid, const QSize &s,
+ int d, QObject *parent)
+ : QVFbViewProtocol(displayid, parent), hdr(0), dataCache(0), windowId(0)
+{
+ switch (d) {
+ case 1:
+ case 4:
+ case 8:
+ case 12:
+ case 15:
+ case 16:
+ case 18:
+ case 24:
+ case 32:
+ break;
+ default:
+ qFatal("Unsupported bit depth %d\n", d);
+ }
+
+ fileName = QString("/tmp/.qtvfb_map-%1").arg(displayid);
+
+ int w = s.width();
+ int h = s.height();
+
+
+ kh = new QVFbKeyPipeProtocol(displayid);
+ mh = new QVFbMouseLinuxTP(displayid);
+
+ int bpl;
+ if (d < 8)
+ bpl = (w * d + 7) / 8;
+ else
+ bpl = w * ((d + 7) / 8);
+
+ displaySize = bpl * h;
+
+ unsigned char *data;
+ uint data_offset_value = sizeof(QVFbHeader);
+ const int page_size = getpagesize();
+ if (data_offset_value % page_size)
+ data_offset_value += page_size - (data_offset_value % page_size);
+
+ dataSize = bpl * h + data_offset_value;
+
+ unlink(fileName.toLocal8Bit().data());
+ fd = ::open( fileName.toLocal8Bit().data(), O_CREAT|O_RDWR, 0666 );
+ ::lseek(fd, dataSize, SEEK_SET);
+ ::write(fd, "\0", 1);
+ if (fd < 0) {
+ data = (unsigned char *)-1;
+ } else {
+ // might need to do something about size?
+ data = (unsigned char *)mmap(NULL, dataSize, PROT_WRITE | PROT_READ,
+ MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED)
+ data = (unsigned char *)-1;
+ }
+
+ if ( (long)data == -1 ){
+ delete kh;
+ delete mh;
+ qFatal( "Cannot attach to mapped file %s", fileName.toLocal8Bit().data());
+ }
+ dataCache = (unsigned char *)malloc(displaySize);
+ memset(dataCache, 0, displaySize);
+ memset(data+sizeof(QVFbHeader), 0, displaySize);
+
+ hdr = (QVFbHeader *)data;
+ hdr->width = w;
+ hdr->height = h;
+ hdr->depth = d;
+ hdr->linestep = bpl;
+ hdr->numcols = 0;
+ hdr->dataoffset = data_offset_value;
+ hdr->update = QRect();
+ hdr->brightness = 255;
+ hdr->windowId = 0;
+
+ mRefreshTimer = new QTimer(this);
+ connect(mRefreshTimer, SIGNAL(timeout()), this, SLOT(flushChanges()));
+}
+
+QMMapViewProtocol::~QMMapViewProtocol()
+{
+ munmap((char *)hdr, dataSize);
+ ::close(fd);
+ unlink(fileName.toLocal8Bit().constData());
+ free(dataCache);
+ delete kh;
+ delete mh;
+}
+
+int QMMapViewProtocol::brightness() const
+{
+ return hdr->brightness;
+}
+
+int QMMapViewProtocol::width() const
+{
+ return hdr->width;
+}
+
+int QMMapViewProtocol::height() const
+{
+ return hdr->height;
+}
+
+int QMMapViewProtocol::depth() const
+{
+ return hdr->depth;
+}
+
+int QMMapViewProtocol::linestep() const
+{
+ return hdr->linestep;
+}
+
+int QMMapViewProtocol::numcols() const
+{
+ return hdr->numcols;
+}
+
+QVector<QRgb> QMMapViewProtocol::clut() const
+{
+ QVector<QRgb> vector(hdr->numcols);
+ for (int i=0; i < hdr->numcols; ++i)
+ vector[i] = hdr->clut[i];
+
+ return vector;
+}
+
+unsigned char *QMMapViewProtocol::data() const
+{
+ return dataCache;
+ //return ((unsigned char *)hdr)+hdr->dataoffset;
+}
+
+void QMMapViewProtocol::flushChanges()
+{
+ // based of dirty rect, copy changes from hdr to hdrcopy
+ memcpy(dataCache, ((char *)hdr) + hdr->dataoffset, displaySize);
+ emit displayDataChanged(QRect(0, 0, width(), height()));
+}
+
+void QMMapViewProtocol::setRate(int interval)
+{
+ if (interval > 0)
+ return mRefreshTimer->start(1000/interval);
+ else
+ mRefreshTimer->stop();
+}
+
+int QMMapViewProtocol::rate() const
+{
+ int i = mRefreshTimer->interval();
+ if (i > 0)
+ return 1000/i;
+ else
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/qvfbmmap.h b/tools/qvfb/qvfbmmap.h
new file mode 100644
index 0000000..5b580ac
--- /dev/null
+++ b/tools/qvfb/qvfbmmap.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QVFB_MMAP_PROTOCOL_H
+#define QVFB_MMAP_PROTOCOL_H
+
+#include "qvfbprotocol.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVFbHeader;
+class QTimer;
+class QMMapViewProtocol : public QVFbViewProtocol
+{
+ Q_OBJECT
+public:
+ QMMapViewProtocol(int display_id, const QSize &size, int depth, QObject *parent = 0);
+ ~QMMapViewProtocol();
+
+ int width() const;
+ int height() const;
+ int depth() const;
+ int linestep() const;
+ int numcols() const;
+ QVector<QRgb> clut() const;
+ unsigned char *data() const;
+ int brightness() const;
+
+ void setRate(int);
+ int rate() const;
+
+protected slots:
+ void flushChanges();
+
+protected:
+ QVFbKeyProtocol *keyHandler() const { return kh; }
+ QVFbMouseProtocol *mouseHandler() const { return mh; }
+
+private:
+ QVFbKeyPipeProtocol *kh;
+ QVFbMouseLinuxTP *mh;
+ QVFbHeader *hdr;
+ QString fileName;
+ int fd;
+ size_t dataSize;
+ size_t displaySize;
+ unsigned char *dataCache;
+ QTimer *mRefreshTimer;
+ WId windowId;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/qvfbprotocol.cpp b/tools/qvfb/qvfbprotocol.cpp
new file mode 100644
index 0000000..08d2973
--- /dev/null
+++ b/tools/qvfb/qvfbprotocol.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbprotocol.h"
+#include "qvfbhdr.h"
+
+#include <QDebug>
+#include <QTimer>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <math.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef Q_OS_UNIX
+#include <unistd.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QVFbViewProtocol::QVFbViewProtocol(int display_id, QObject *parent) :
+ QObject(parent), mDisplayId(display_id) { }
+
+QVFbViewProtocol::~QVFbViewProtocol() {}
+
+void QVFbViewProtocol::flushChanges() {}
+
+void QVFbViewProtocol::sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat)
+{
+ if (keyHandler())
+ keyHandler()->sendKeyboardData(unicode, keycode, modifiers, press, repeat);
+}
+
+void QVFbViewProtocol::sendMouseData(const QPoint &pos, int buttons, int wheel)
+{
+ if (mouseHandler())
+ mouseHandler()->sendMouseData(pos, buttons, wheel);
+}
+
+static int openPipe(const char *fileName)
+{
+ unlink(fileName);
+
+ mkfifo(fileName, 0666);
+ int fd = ::open(fileName, O_RDWR | O_NDELAY);
+ return fd;
+}
+
+QVFbKeyPipeProtocol::QVFbKeyPipeProtocol(int display_id)
+ : QVFbKeyProtocol(display_id)
+{
+ fileName = QString(QT_VFB_KEYBOARD_PIPE).arg(display_id);
+ fd = openPipe(fileName.toLocal8Bit().constData());
+
+ if (fd == -1)
+ qFatal("Cannot open keyboard pipe %s", fileName.toLocal8Bit().data());
+}
+
+QVFbKeyPipeProtocol::~QVFbKeyPipeProtocol()
+{
+ sendKeyboardData(0, 0, 0, true, false); // magic die key
+ ::close(fd);
+ unlink(fileName.toLocal8Bit().constData());
+}
+
+void QVFbKeyPipeProtocol::sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat)
+{
+ QVFbKeyData kd;
+ kd.unicode = unicode[0].unicode();
+ kd.keycode = keycode;
+ kd.modifiers = static_cast<Qt::KeyboardModifier>(modifiers);
+ kd.press = press;
+ kd.repeat = repeat;
+ write(fd, &kd, sizeof(QVFbKeyData));
+}
+
+QVFbMousePipe::QVFbMousePipe(int display_id)
+ : QVFbMouseProtocol(display_id)
+{
+ fileName = QString(QT_VFB_MOUSE_PIPE).arg(display_id);
+ fd = openPipe(fileName.toLocal8Bit().constData());
+
+ if (fd == -1)
+ qFatal("Cannot open mouse pipe %s", fileName.toLocal8Bit().data());
+}
+
+QVFbMousePipe::~QVFbMousePipe()
+{
+ ::close(fd);
+ unlink(fileName.toLocal8Bit().constData());
+}
+
+
+void QVFbMousePipe::sendMouseData(const QPoint &pos, int buttons, int wheel)
+{
+ write(fd, &pos, sizeof(QPoint));
+ write(fd, &buttons, sizeof(int));
+ write(fd, &wheel, sizeof(int));
+}
+
+QVFbMouseLinuxTP::QVFbMouseLinuxTP(int display_id)
+ : QObject(), QVFbMousePipe(display_id), lastPos(-1,-1)
+{
+ /* the timer is needed because a real touch screen send data as long as
+ there is pressure. And the linux tp driver will filter, requiring
+ a minimum of 5 samples before it even registers a press.
+ */
+ repeater = new QTimer(this);
+ connect(repeater, SIGNAL(timeout()), this, SLOT(repeatLastPress()));
+}
+
+QVFbMouseLinuxTP::~QVFbMouseLinuxTP()
+{
+}
+
+
+void QVFbMouseLinuxTP::sendMouseData(const QPoint &pos, int buttons, int)
+{
+ if (buttons & Qt::LeftButton) {
+ // press
+ repeater->start(5);
+ writeToPipe(pos, 1);
+ lastPos = pos;
+ } else {
+ // release
+ if (lastPos == QPoint(-1,-1))
+ return; /* only send one release */
+ repeater->stop();
+ writeToPipe(pos, 0);
+ lastPos = QPoint(-1,-1);
+ }
+}
+
+void QVFbMouseLinuxTP::writeToPipe(const QPoint &pos, ushort pressure)
+{
+ ushort v;
+ write(fd, &pressure, sizeof(ushort));
+ v = pos.x();
+ write(fd, &v, sizeof(ushort));
+ v = pos.y();
+ write(fd, &v, sizeof(ushort));
+ v = 1; // pad
+ write(fd, &v, sizeof(ushort));
+}
+
+void QVFbMouseLinuxTP::repeatLastPress()
+{
+ writeToPipe(lastPos, 1);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/qvfbprotocol.h b/tools/qvfb/qvfbprotocol.h
new file mode 100644
index 0000000..e7b6f63
--- /dev/null
+++ b/tools/qvfb/qvfbprotocol.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QVFBPROTOCOL_H
+#define QVFBPROTOCOL_H
+
+#include <QImage>
+#include <QVector>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+class QVFbKeyProtocol;
+class QVFbMouseProtocol;
+class QVFbViewProtocol : public QObject
+{
+ Q_OBJECT
+public:
+ QVFbViewProtocol(int display_id, QObject *parent = 0);
+
+ virtual ~QVFbViewProtocol();
+
+ int id() const { return mDisplayId; }
+
+ void sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat);
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+
+ virtual int width() const = 0;
+ virtual int height() const = 0;
+ virtual int depth() const = 0;
+ virtual int linestep() const = 0;
+ virtual int numcols() const = 0;
+ virtual QVector<QRgb> clut() const = 0;
+ virtual unsigned char *data() const = 0;
+ virtual int brightness() const = 0;
+
+ virtual void setRate(int) {}
+public slots:
+ virtual void flushChanges();
+
+signals:
+ void displayDataChanged(const QRect &);
+ void displayEmbedRequested(WId windowId);
+
+protected:
+ virtual QVFbKeyProtocol *keyHandler() const = 0;
+ virtual QVFbMouseProtocol *mouseHandler() const = 0;
+
+private:
+ int mDisplayId;
+};
+
+class QVFbKeyProtocol
+{
+public:
+ QVFbKeyProtocol(int display_id) : mDisplayId(display_id) {}
+ virtual ~QVFbKeyProtocol() {}
+
+ int id() const { return mDisplayId; }
+
+ virtual void sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat) = 0;
+
+private:
+ int mDisplayId;
+};
+
+class QVFbMouseProtocol
+{
+public:
+ QVFbMouseProtocol(int display_id) : mDisplayId(display_id) {}
+ virtual ~QVFbMouseProtocol() {}
+
+ int id() const { return mDisplayId; }
+
+ virtual void sendMouseData(const QPoint &pos, int buttons, int wheel) = 0;
+
+private:
+ int mDisplayId;
+};
+
+/* since there is very little variation in input protocols defaults are
+ provided */
+
+class QVFbKeyPipeProtocol : public QVFbKeyProtocol
+{
+public:
+ QVFbKeyPipeProtocol(int display_id);
+ ~QVFbKeyPipeProtocol();
+
+ void sendKeyboardData(QString unicode, int keycode,
+ int modifiers, bool press, bool repeat);
+
+ QString pipeName() const { return fileName; }
+private:
+ int fd;
+ QString fileName;
+};
+
+class QVFbMousePipe: public QVFbMouseProtocol
+{
+public:
+ QVFbMousePipe(int display_id);
+ ~QVFbMousePipe();
+
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+
+ QString pipeName() const { return fileName; }
+protected:
+ int fd;
+ QString fileName;
+};
+
+class QTimer;
+class QVFbMouseLinuxTP : public QObject, public QVFbMousePipe
+{
+ Q_OBJECT
+public:
+ QVFbMouseLinuxTP(int display_id);
+ ~QVFbMouseLinuxTP();
+
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+
+protected slots:
+ void repeatLastPress();
+
+protected:
+ void writeToPipe(const QPoint &pos, ushort pressure);
+ QPoint lastPos;
+ QTimer *repeater;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/qvfbratedlg.cpp b/tools/qvfb/qvfbratedlg.cpp
new file mode 100644
index 0000000..594e3f1
--- /dev/null
+++ b/tools/qvfb/qvfbratedlg.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbratedlg.h"
+#include <QLayout>
+#include <QLabel>
+#include <qslider.h>
+#include <QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+QVFbRateDialog::QVFbRateDialog(int rate, QWidget *parent)
+ : QDialog(parent)
+{
+ oldRate = rate;
+
+ QVBoxLayout *tl = new QVBoxLayout(this);
+ tl->setMargin(5);
+
+ QLabel *label = new QLabel("Target frame rate:", this);
+ tl->addWidget(label);
+
+ QHBoxLayout *hl = new QHBoxLayout();
+ tl->addItem(hl);
+ rateSlider = new QSlider(Qt::Horizontal);
+ rateSlider->setMinimum(1);
+ rateSlider->setMaximum(100);
+ rateSlider->setPageStep(10);
+ rateSlider->setValue(rate);
+ hl->addWidget(rateSlider);
+ connect(rateSlider, SIGNAL(valueChanged(int)), this, SLOT(rateChanged(int)));
+ rateLabel = new QLabel(QString("%1fps").arg(rate), this);
+ hl->addWidget(rateLabel);
+
+ hl = new QHBoxLayout();
+ tl->addItem(hl);
+ QPushButton *pb = new QPushButton("OK", this);
+ connect(pb, SIGNAL(clicked()), this, SLOT(ok()));
+ hl->addWidget(pb);
+ pb = new QPushButton("Cancel", this);
+ connect(pb, SIGNAL(clicked()), this, SLOT(cancel()));
+ hl->addWidget(pb);
+}
+
+void QVFbRateDialog::rateChanged(int r)
+{
+ if (rateSlider->value() != r)
+ rateSlider->setValue(r);
+ rateLabel->setText(QString("%1fps").arg(r));
+ emit updateRate(r);
+}
+
+void QVFbRateDialog::cancel()
+{
+ rateChanged(oldRate);
+ reject();
+}
+
+void QVFbRateDialog::ok()
+{
+ oldRate = rateSlider->value();
+ accept();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/qvfbratedlg.h b/tools/qvfb/qvfbratedlg.h
new file mode 100644
index 0000000..1611c76
--- /dev/null
+++ b/tools/qvfb/qvfbratedlg.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFBRATEDLG_H
+#define QVFBRATEDLG_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QLabel;
+class QSlider;
+
+class QVFbRateDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ QVFbRateDialog(int value, QWidget *parent = 0);
+
+signals:
+ void updateRate(int r);
+
+protected slots:
+ void rateChanged(int r);
+ void cancel();
+ void ok();
+
+private:
+ QLabel *rateLabel;
+ QSlider *rateSlider;
+ int oldRate;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/qvfbshmem.cpp b/tools/qvfb/qvfbshmem.cpp
new file mode 100644
index 0000000..d07cd0f
--- /dev/null
+++ b/tools/qvfb/qvfbshmem.cpp
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlock_p.h"
+
+#include "qvfbshmem.h"
+#include "qvfbhdr.h"
+
+#define QTE_PIPE "QtEmbedded-%1"
+
+#include <QFile>
+#include <QTimer>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_QWS
+#error qvfb must be compiled with the Qt for X11 package
+#endif
+
+// Get the name of the directory where Qt for Embedded Linux temporary data should
+// live.
+static QString qws_dataDir(int qws_display_id)
+{
+ QByteArray dataDir = QString("/tmp/qtembedded-%1").arg(qws_display_id).toLocal8Bit();
+ if (mkdir(dataDir, 0700)) {
+ if (errno != EEXIST) {
+ qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
+ }
+ }
+
+ struct stat buf;
+ if (lstat(dataDir, &buf))
+ qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData());
+
+ if (!S_ISDIR(buf.st_mode))
+ qFatal("%s is not a directory", dataDir.constData());
+ if (buf.st_uid != getuid())
+ qFatal("Qt for Embedded Linux data directory is not owned by user %uh", getuid());
+
+ if ((buf.st_mode & 0677) != 0600)
+ qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
+ dataDir += "/";
+
+ return QString(dataDir);
+}
+
+
+static QString displayPipe;
+static QString displayPiped;
+class DisplayLock
+{
+public:
+ DisplayLock() : qlock(0) {
+ if (QFile::exists(displayPiped)) {
+ qlock = new QLock(displayPipe, 'd', false);
+ qlock->lock(QLock::Read);
+ }
+ }
+ ~DisplayLock() {
+ if (qlock) {
+ qlock->unlock();
+ delete qlock;
+ qlock = 0;
+ }
+ }
+private:
+ QLock *qlock;
+};
+
+QShMemViewProtocol::QShMemViewProtocol(int displayid, const QSize &s,
+ int d, QObject *parent)
+ : QVFbViewProtocol(displayid, parent), hdr(0), dataCache(0), lockId(-1),
+ windowId(0)
+{
+ int w = s.width();
+ int h = s.height();
+
+ QString username = "unknown";
+ const char *logname = getenv("LOGNAME");
+ if ( logname )
+ username = logname;
+
+ QString oldPipe = "/tmp/qtembedded-" + username + "/" + QString(QTE_PIPE).arg(displayid);
+ int oldPipeSemkey = ftok(oldPipe.toLatin1().constData(), 'd');
+ if (oldPipeSemkey != -1) {
+ int oldPipeLockId = semget(oldPipeSemkey, 0, 0);
+ if (oldPipeLockId >= 0){
+ sembuf sops;
+ sops.sem_num = 0;
+ sops.sem_op = 1;
+ sops.sem_flg = SEM_UNDO;
+ int rv;
+ do {
+ rv = semop(lockId,&sops,1);
+ } while (rv == -1 && errno == EINTR);
+
+ perror("QShMemViewProtocol::QShMemViewProtocol");
+ qFatal("Cannot create lock file as an old version of QVFb has "
+ "opened %s. Close other QVFb and try again",
+ oldPipe.toLatin1().constData());
+ }
+ }
+
+ kh = new QVFbKeyPipeProtocol(displayid);
+ /* should really depend on receiving qt version, but how can
+ one tell? */
+ mh = new QVFbMousePipe(displayid);
+
+ QString mousePipe = mh->pipeName();
+
+ key_t key = ftok(mousePipe.toLatin1().constData(), 'b');
+
+ int bpl;
+ if (d < 8)
+ bpl = (w * d + 7) / 8;
+ else
+ bpl = w * ((d + 7) / 8);
+
+ displaySize = bpl * h;
+
+ unsigned char *data;
+ uint data_offset_value = sizeof(QVFbHeader);
+
+ int dataSize = bpl * h + data_offset_value;
+ shmId = shmget(key, dataSize, IPC_CREAT | 0666);
+ if (shmId != -1)
+ data = (unsigned char *)shmat(shmId, 0, 0);
+ else {
+ struct shmid_ds shm;
+ shmctl(shmId, IPC_RMID, &shm);
+ shmId = shmget(key, dataSize, IPC_CREAT | 0666);
+ if (shmId == -1) {
+ perror("QShMemViewProtocol::QShMemViewProtocol");
+ qFatal("Cannot get shared memory 0x%08x", key);
+ }
+ data = (unsigned char *)shmat(shmId, 0, 0);
+ }
+
+ if ((long)data == -1) {
+ delete kh;
+ delete mh;
+ perror("QShMemViewProtocol::QShMemViewProtocol");
+ qFatal("Cannot attach to shared memory %d",shmId);
+ }
+ dataCache = (unsigned char *)malloc(displaySize);
+ memset(dataCache, 0, displaySize);
+ memset(data+sizeof(QVFbHeader), 0, displaySize);
+
+ hdr = (QVFbHeader *)data;
+ hdr->width = w;
+ hdr->height = h;
+ hdr->depth = d;
+ hdr->linestep = bpl;
+ hdr->dataoffset = data_offset_value;
+ hdr->update = QRect();
+ hdr->dirty = 0;
+ hdr->numcols = 0;
+ hdr->viewerVersion = QT_VERSION;
+ hdr->brightness = 255;
+ hdr->windowId = 0;
+
+ displayPipe = qws_dataDir(displayid) + QString(QTE_PIPE).arg(displayid);
+
+ displayPiped = displayPipe + 'd';
+
+
+ mRefreshTimer = new QTimer(this);
+ connect(mRefreshTimer, SIGNAL(timeout()), this, SLOT(flushChanges()));
+}
+
+QShMemViewProtocol::~QShMemViewProtocol()
+{
+ struct shmid_ds shm;
+ shmdt( (char*)hdr );
+ shmctl( shmId, IPC_RMID, &shm );
+ free(dataCache);
+ delete kh;
+ delete mh;
+}
+
+int QShMemViewProtocol::width() const
+{
+ return hdr->width;
+}
+
+int QShMemViewProtocol::height() const
+{
+ return hdr->height;
+}
+
+int QShMemViewProtocol::depth() const
+{
+ return hdr->depth;
+}
+
+int QShMemViewProtocol::linestep() const
+{
+ return hdr->linestep;
+}
+
+int QShMemViewProtocol::numcols() const
+{
+ return hdr->numcols;
+}
+
+QVector<QRgb> QShMemViewProtocol::clut() const
+{
+ QVector<QRgb> vector(hdr->numcols);
+ for (int i=0; i < hdr->numcols; ++i)
+ vector[i]=hdr->clut[i];
+
+ return vector;
+}
+
+unsigned char *QShMemViewProtocol::data() const
+{
+ return dataCache;
+ //return ((unsigned char *)hdr)+hdr->dataoffset;
+}
+
+int QShMemViewProtocol::brightness() const
+{
+ return hdr->brightness;
+}
+
+void QShMemViewProtocol::flushChanges()
+{
+ QRect r;
+ if (hdr->dirty) {
+ DisplayLock();
+
+ hdr->dirty = false;
+ r = hdr->update;
+ hdr->update = QRect();
+
+ if (hdr->windowId != windowId) {
+ windowId = hdr->windowId;
+ emit displayEmbedRequested(hdr->windowId);
+ } else if (!hdr->windowId) {
+ // copy the memory area, for now, be inefficient.
+ memcpy(dataCache, ((char *)hdr) + hdr->dataoffset, displaySize);
+ }
+ }
+ emit displayDataChanged(r);
+}
+
+void QShMemViewProtocol::setRate(int interval)
+{
+ if (interval > 0)
+ return mRefreshTimer->start(1000/interval);
+ else
+ mRefreshTimer->stop();
+}
+
+int QShMemViewProtocol::rate() const
+{
+ int i = mRefreshTimer->interval();
+ if (i > 0)
+ return 1000/i;
+ else
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/qvfbshmem.h b/tools/qvfb/qvfbshmem.h
new file mode 100644
index 0000000..166ff07
--- /dev/null
+++ b/tools/qvfb/qvfbshmem.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QVFB_SHM_PROTOCOL_H
+#define QVFB_SHM_PROTOCOL_H
+
+#include "qvfbprotocol.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVFbHeader;
+class QTimer;
+class QShMemViewProtocol : public QVFbViewProtocol
+{
+ Q_OBJECT
+public:
+ QShMemViewProtocol(int display_id, const QSize &size, int depth, QObject *parent = 0);
+ ~QShMemViewProtocol();
+
+ int width() const;
+ int height() const;
+ int depth() const;
+ int linestep() const;
+ int numcols() const;
+ QVector<QRgb> clut() const;
+ unsigned char *data() const;
+ int brightness() const;
+
+ void setRate(int);
+ int rate() const;
+
+protected slots:
+ void flushChanges();
+
+protected:
+ QVFbKeyProtocol *keyHandler() const { return kh; }
+ QVFbMouseProtocol *mouseHandler() const { return mh; }
+
+private:
+ QVFbKeyPipeProtocol *kh;
+ QVFbMousePipe *mh;
+ QVFbHeader *hdr;
+ size_t displaySize;
+ unsigned char *dataCache;
+ int lockId;
+ int shmId;
+ QTimer *mRefreshTimer;
+ WId windowId;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/qvfbview.cpp b/tools/qvfb/qvfbview.cpp
new file mode 100644
index 0000000..53a5360
--- /dev/null
+++ b/tools/qvfb/qvfbview.cpp
@@ -0,0 +1,824 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbview.h"
+#include "qvfbshmem.h"
+#include "qvfbmmap.h"
+
+#include "qanimationwriter.h"
+#include <QApplication>
+#include <QPainter>
+#include <QImage>
+#include <QBitmap>
+#include <QMatrix>
+#include <QPaintEvent>
+#include <QScrollArea>
+#include <QFile>
+#include <QDebug>
+
+#ifdef Q_WS_X11
+#include <QX11EmbedContainer>
+#include <QHBoxLayout>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+extern int qvfb_protocol;
+
+QVFbAbstractView::QVFbAbstractView( QWidget *parent )
+#ifdef QVFB_USE_GLWIDGET
+ : QGLWidget( parent )
+#else
+ : QWidget( parent )
+#endif
+{
+}
+
+QVFbAbstractView::~QVFbAbstractView()
+{
+}
+
+QVFbView::QVFbView(int id, int w, int h, int d, Rotation r, QWidget *parent)
+ : QVFbAbstractView(parent),
+ viewdepth(d), viewFormat(DefaultFormat), rsh(0), gsh(0), bsh(0), rmax(15), gmax(15), bmax(15),
+ contentsWidth(w), contentsHeight(h), gred(1.0), ggreen(1.0), gblue(1.0),
+ gammatable(0), refreshRate(30), animation(0),
+ hzm(0.0), vzm(0.0), mView(0),
+ emulateTouchscreen(false), emulateLcdScreen(false), rotation(r)
+#ifdef Q_WS_X11
+ , embedContainer(0)
+#endif
+{
+ switch(qvfb_protocol) {
+ default:
+ case 0:
+ mView = new QShMemViewProtocol(id, QSize(w, h), d, this);
+ break;
+ case 1:
+ mView = new QMMapViewProtocol(id, QSize(w, h), d, this);
+ break;
+ }
+
+ connect(mView, SIGNAL(displayDataChanged(const QRect &)),
+ SLOT(refreshDisplay(const QRect &)));
+#ifdef Q_WS_X11
+ connect(mView, SIGNAL(displayEmbedRequested(WId)),
+ this, SLOT(embedDisplay(WId)));
+#endif
+
+ setAttribute(Qt::WA_PaintOnScreen, viewFormat != ARGBFormat);
+ setMouseTracking(true);
+ setFocusPolicy(Qt::StrongFocus);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ setZoom(1.0,1.0);
+
+ setGamma(1.0,1.0,1.0);
+ mView->setRate(30);
+}
+
+QVFbView::~QVFbView()
+{
+ stopAnimation();
+ sendKeyboardData(0, 0, 0, true, false); // magic die key
+#ifdef Q_WS_X11
+ delete embedContainer;
+#endif
+}
+
+QSize QVFbView::sizeHint() const
+{
+ return QSize(contentsWidth, contentsHeight);
+}
+
+void QVFbView::setRate(int i)
+{
+ mView->setRate(i);
+}
+
+void QVFbView::setGamma(double gr, double gg, double gb)
+{
+ gred = gr; ggreen = gg; gblue = gb;
+
+ switch (viewdepth) {
+ case 12:
+ rsh = 12;
+ gsh = 7;
+ bsh = 1;
+ rmax = 15;
+ gmax = 15;
+ bmax = 15;
+ break;
+ case 15:
+ rsh = 10;
+ gsh = 5;
+ bsh = 0;
+ rmax = 31;
+ gmax = 31;
+ bmax = 31;
+ break;
+ case 16:
+ rsh = 11;
+ gsh = 5;
+ bsh = 0;
+ rmax = 31;
+ gmax = 63;
+ bmax = 31;
+ break;
+ case 18:
+ rsh = 12;
+ gsh = 6;
+ bsh = 0;
+ rmax = 63;
+ gmax = 63;
+ bmax = 63;
+ break;
+ case 24:
+ case 32:
+ rsh = 16;
+ gsh = 8;
+ bsh = 0;
+ rmax = 255;
+ gmax = 255;
+ bmax = 255;
+ }
+ int mm = qMax(rmax,qMax(gmax,bmax))+1;
+ if (gammatable)
+ delete [] gammatable;
+ gammatable = new QRgb[mm];
+ for (int i=0; i<mm; i++) {
+ int r = int(pow(i,gr)*255/rmax);
+ int g = int(pow(i,gg)*255/gmax);
+ int b = int(pow(i,gb)*255/bmax);
+ if (r > 255) r = 255;
+ if (g > 255) g = 255;
+ if (b > 255) b = 255;
+ gammatable[i] = qRgb(r,g,b);
+//qDebug("%d: %d,%d,%d",i,r,g,b);
+ }
+
+ mView->flushChanges();
+}
+
+void QVFbView::getGamma(int i, QRgb& rgb)
+{
+ if (i > 255) i = 255;
+ if (i < 0) i = 0;
+ rgb = qRgb(qRed(gammatable[i*rmax/255]),
+ qGreen(gammatable[i*rmax/255]),
+ qBlue(gammatable[i*rmax/255]));
+}
+
+int QVFbView::displayId() const
+{
+ return mView->id();
+}
+
+int QVFbView::displayWidth() const
+{
+ return mView->width();
+}
+
+int QVFbView::displayHeight() const
+{
+ return mView->height();
+}
+
+int QVFbView::displayDepth() const
+{
+ return viewdepth;
+}
+
+QVFbView::PixelFormat QVFbView::displayFormat() const
+{
+ return viewFormat;
+}
+
+QVFbView::Rotation QVFbView::displayRotation() const
+{
+ return rotation;
+}
+
+void QVFbView::setZoom(double hz, double vz)
+{
+ if (hzm != hz || vzm != vz) {
+ hzm = hz;
+ vzm = vz;
+ mView->flushChanges();
+
+ contentsWidth = int(displayWidth()*hz);
+ contentsHeight = int(displayHeight()*vz);
+ if (rotation & 1)
+ qSwap(contentsWidth,contentsHeight);
+ resize(contentsWidth, contentsHeight);
+
+ if (isVisible()) {
+ updateGeometry();
+ qApp->sendPostedEvents();
+ topLevelWidget()->adjustSize();
+ update();
+ }
+ }
+}
+
+void QVFbView::setRotation(QVFbView::Rotation r)
+{
+ rotation = r;
+ // Force update...
+ double ohzm = hzm;
+ hzm=0.0;
+ setZoom(ohzm,vzm);
+}
+
+static QRect mapToDevice(const QRect &r, const QSize &s, QVFbView::Rotation rotation)
+{
+ int x1 = r.x();
+ int y1 = r.y();
+ int x2 = r.right();
+ int y2 = r.bottom();
+ int w = s.width();
+ int h = s.height();
+ switch (rotation) {
+ case QVFbView::Rot90:
+ return QRect(
+ QPoint(y1, w - x1),
+ QPoint(y2, w - x2)).normalized();
+ case QVFbView::Rot180:
+ return QRect(
+ QPoint(w - x1, h - y1),
+ QPoint(w - x2, h - y2)).normalized();
+ case QVFbView::Rot270:
+ return QRect(
+ QPoint(h - y1, x1),
+ QPoint(h - y2, x2)).normalized();
+ default:
+ break;
+ }
+ return r;
+}
+
+static QRect mapFromDevice(const QRect &r, const QSize &s, QVFbView::Rotation rotation)
+{
+ return mapToDevice(r,s,QVFbView::Rotation(4-(int)rotation));
+}
+
+void QVFbView::sendMouseData(const QPoint &pos, int buttons, int wheel)
+{
+ QPoint p = mapToDevice(QRect(pos,QSize(1,1)), QSize(int(width()/hzm), int(height()/vzm)), rotation).topLeft();
+ mView->sendMouseData(p, buttons, wheel);
+}
+
+void QVFbView::sendKeyboardData(QString unicode, int keycode, int modifiers,
+ bool press, bool repeat)
+{
+ mView->sendKeyboardData(unicode, keycode, modifiers, press, repeat);
+}
+
+void QVFbView::refreshDisplay(const QRect &r)
+{
+ if (animation) {
+ if (r.isEmpty()) {
+ animation->appendBlankFrame();
+ } else {
+ int l;
+ QImage img = getBuffer(r, l);
+ animation->appendFrame(img,QPoint(r.x(),r.y()));
+ }
+ }
+ if (!r.isNull()) {
+ if (hzm == 1.0 && vzm == 1.0) // hw: workaround for 4.3.1
+ update(mapFromDevice(r, QSize(displayWidth(), displayHeight()), rotation));
+ else
+ update();
+ }
+}
+
+static void dim(QRgb* rgb, int n, int brightness)
+{
+ uchar* b = (uchar*)rgb;
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ b++;
+#endif
+ while (n--) {
+ b[0] = (uint)b[0] * brightness / 255;
+ b[1] = (uint)b[1] * brightness / 255;
+ b[2] = (uint)b[2] * brightness / 255;
+ b += 4;
+ }
+}
+
+QImage QVFbView::getBuffer(const QRect &r, int &leading) const
+{
+ const int brightness = mView->brightness();
+ if ( brightness == 0 ) {
+ QImage img(r.size(),QImage::Format_RGB32);
+ img.fill(0);
+ leading = 0;
+ return img;
+ }
+
+ static QByteArray buffer;
+
+ const int requiredSize = r.width() * r.height() * 4;
+
+ QImage img;
+ leading = 0;
+
+ switch (viewdepth) {
+ case 1: {
+ if (requiredSize > buffer.size())
+ buffer.resize(requiredSize);
+
+ // XXX: hw: replace by drawhelper functionality
+
+ const int pixelsPerByte = 8;
+ quint8 *src = reinterpret_cast<quint8*>(mView->data())
+ + r.y() * mView->linestep() + r.x() / pixelsPerByte;
+ const int align = qMin(r.width(), (8 - (r.x() & 7)) & 7);
+ const int doAlign = (align > 0 ? 1 : 0);
+ const int tail = qMin(r.width(), (r.width() - align) & 7);
+ const int doTail = (tail > 0 ? 1 : 0);
+ const int width8 = (r.width() - align) / pixelsPerByte;
+ const int stride = mView->linestep() - (width8 + doAlign);
+
+ uchar *b = reinterpret_cast<uchar*>(buffer.data());
+ img = QImage(b, r.width(), r.height(), QImage::Format_RGB32);
+ for (int y = 0; y < r.height(); ++y) {
+ quint32 *dest = reinterpret_cast<quint32*>(img.scanLine(y));
+ quint8 c;
+
+ if (doAlign) {
+ switch (align) {
+ case 7: c = ((*src & 0x40) >> 6) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 6: c = ((*src & 0x20) >> 5) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 5: c = ((*src & 0x10) >> 4) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 4: c = ((*src & 0x08) >> 3) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 3: c = ((*src & 0x04) >> 2) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 2: c = ((*src & 0x02) >> 1) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ case 1: c = ((*src & 0x01)) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ }
+ ++src;
+ }
+ for (int i = 0; i < width8; ++i) {
+ c = ((*src & 0x80) >> 7) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x40) >> 6) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x20) >> 5) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x10) >> 4) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x08) >> 3) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x04) >> 2) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x02) >> 1) * 0xff;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x01)) * 0xff;
+ *dest++ = qRgb(c, c, c);
+
+ ++src;
+ }
+ if (doTail) {
+ switch (tail) {
+ case 7: c = ((*src & 0x02) >> 1) * 0xff;
+ dest[6] = qRgb(c, c, c);
+ case 6: c = ((*src & 0x04) >> 2) * 0xff;
+ dest[5] = qRgb(c, c, c);
+ case 5: c = ((*src & 0x08) >> 3) * 0xff;
+ dest[4] = qRgb(c, c, c);
+ case 4: c = ((*src & 0x10) >> 4) * 0xff;
+ dest[3] = qRgb(c, c, c);
+ case 3: c = ((*src & 0x20) >> 5) * 0xff;
+ dest[2] = qRgb(c, c, c);
+ case 2: c = ((*src & 0x40) >> 6) * 0xff;
+ dest[1] = qRgb(c, c, c);
+ case 1: c = ((*src & 0x80) >> 7) * 0xff;
+ dest[0] = qRgb(c, c, c);
+ }
+ }
+ src += stride;
+ }
+ break;
+ }
+ case 4: {
+ if (requiredSize > buffer.size())
+ buffer.resize(requiredSize);
+
+ // XXX: hw: replace by drawhelper functionality
+
+ const int pixelsPerByte = 2;
+ const int doAlign = r.x() & 1;
+ const int doTail = (r.width() - doAlign) & 1;
+ const int width8 = (r.width() - doAlign) / pixelsPerByte;
+
+ uchar *b = reinterpret_cast<uchar*>(buffer.data());
+ img = QImage(b, r.width(), r.height(), QImage::Format_RGB32);
+ for (int y = 0; y < r.height(); ++y) {
+ const quint8 *sptr = mView->data()
+ + (r.y() + y) * mView->linestep()
+ + r.x() / pixelsPerByte;
+ quint32 *dptr = reinterpret_cast<quint32*>(img.scanLine(y));
+
+ if (doAlign) {
+ quint8 c = (*sptr++ & 0x0f);
+ c |= (c << 4);
+ *dptr++ = qRgb(c, c, c);
+ }
+
+ for (int i = 0; i < width8; ++i) {
+ quint8 c1 = (*sptr >> 4);
+ quint8 c2 = (*sptr & 0x0f);
+ c1 |= (c1 << 4);
+ c2 |= (c2 << 4);
+ *dptr++ = qRgb(c1, c1, c1);
+ *dptr++ = qRgb(c2, c2, c2);
+ ++sptr;
+ }
+
+ if (doTail) {
+ quint8 c = *sptr >> 4;
+ c |= (c << 4);
+ *dptr = qRgb(c, c, c);
+ }
+ }
+ break;
+ }
+ case 12:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 2),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB444);
+ break;
+ case 15:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 2),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB555);
+ break;
+ case 16:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 2),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB16);
+ break;
+ case 18:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 3),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB666);
+ break;
+ case 24:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 3),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_RGB888);
+ break;
+ case 32:
+ img = QImage((const uchar*)(mView->data() + r.y() * mView->linestep() + r.x() * 4),
+ r.width(), r.height(), mView->linestep(),
+ viewFormat == ARGBFormat ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+ break;
+ case 8:
+ img = QImage(mView->data() + r.y() * mView->linestep() + r.x(),
+ r.width(), r.height(), mView->linestep(),
+ QImage::Format_Indexed8);
+ img.setColorTable(mView->clut());
+ if (img.numColors() <= 0)
+ img = QImage();
+ break;
+ }
+
+ if ( brightness != 255 ) {
+ if (img.format() == QImage::Format_Indexed8) {
+ QVector<QRgb> c = img.colorTable();
+ dim(c.data(),c.count(),brightness);
+ img.setColorTable(c);
+ } else {
+ if ( img.format() != QImage::Format_ARGB32_Premultiplied )
+ img = img.convertToFormat(QImage::Format_RGB32);
+
+ // NOTE: calling bits() may change numBytes(), so do not
+ // pass them as parameters (which are evaluated right-to-left).
+ QRgb *b = (QRgb*)img.bits();
+ int n = img.numBytes()/4;
+ dim(b,n,brightness);
+ }
+ }
+
+ return img;
+}
+
+static int findMultiple(int start, double m, int limit, int step)
+{
+ int r = start;
+ while (r != limit) {
+ if (int(int(r * m)/m) == r)
+ break;
+ r += step;
+ }
+ return r;
+}
+
+void QVFbView::drawScreen(const QRect &rect)
+{
+ QRect r = QRect(0, 0, mView->width(), mView->height());
+
+ if (hzm == 1.0 && vzm == 1.0) // hw: workaround for 4.3.1
+ r &= rect;
+
+ if (int(hzm) != hzm || int(vzm) != vzm) {
+ r.setLeft(findMultiple(r.left(),hzm,0,-1));
+ r.setTop(findMultiple(r.top(),vzm,0,-1));
+ int w = findMultiple(r.width(),hzm,mView->width(),1);
+ int h = findMultiple(r.height(),vzm,mView->height(),1);
+ r.setRight(r.left()+w-1);
+ r.setBottom(r.top()+h-1);
+ }
+
+ int leading;
+ const QImage img = getBuffer(r, leading);
+
+ QPixmap pm;
+ if (hzm == 1.0 && vzm == 1.0) {
+ pm = QPixmap::fromImage(img);
+ } else if (emulateLcdScreen && hzm == 3.0 && vzm == 3.0) {
+ QImage img2(img.width()*3, img.height(), QImage::Format_RGB32);
+ for (int row = 0; row < img2.height(); row++) {
+ QRgb *dptr = (QRgb*)img2.scanLine(row);
+ QRgb *sptr = (QRgb*)img.scanLine(row);
+ for (int col = 0; col < img.width(); col++) {
+ QRgb s = *sptr++;
+ *dptr++ = qRgb(qRed(s),0,0);
+ *dptr++ = qRgb(0,qGreen(s),0);
+ *dptr++ = qRgb(0,0,qBlue(s));
+ }
+ }
+ QMatrix m;
+ m.scale(1.0, 3.0);
+ pm = QPixmap::fromImage(img2);
+ pm = pm.transformed(m);
+ } else if (int(hzm) == hzm && int(vzm) == vzm) {
+ QMatrix m;
+ m.scale(hzm,vzm);
+ pm = QPixmap::fromImage(img);
+ pm = pm.transformed(m);
+ } else {
+ pm = QPixmap::fromImage(img.scaled(int(img.width()*hzm),int(img.height()*vzm), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+
+ int x1 = r.x();
+ int y1 = r.y();
+ int leadingX = leading;
+ int leadingY = 0;
+
+ // Do the rotation thing
+ int rotX1 = mView->width() - x1 - img.width();
+ int rotY1 = mView->height() - y1 - img.height();
+ int rotLeadingX = (leading) ? mView->width() - leadingX - img.width() : 0;
+ int rotLeadingY = 0;
+ switch (rotation) {
+ case Rot0:
+ break;
+ case Rot90:
+ leadingY = leadingX;
+ leadingX = rotLeadingY;
+ y1 = x1;
+ x1 = rotY1;
+ break;
+ case Rot180:
+ leadingX = rotLeadingX;
+ leadingY = leadingY;
+ x1 = rotX1;
+ y1 = rotY1;
+ break;
+ case Rot270:
+ leadingX = leadingY;
+ leadingY = rotLeadingX;
+ x1 = y1;
+ y1 = rotX1;
+ break;
+ default:
+ break;
+ }
+ x1 = int(x1*hzm);
+ y1 = int(y1*vzm);
+ leadingX = int(leadingX*hzm);
+ leadingY = int(leadingY*vzm);
+ if (rotation != 0) {
+ QMatrix m;
+ m.rotate(rotation * 90.0);
+ pm = pm.transformed(m);
+ }
+
+ QPainter p(this);
+ if (viewFormat == ARGBFormat) {
+ QPixmap bg(":/res/images/logo-nt.png");
+ p.fillRect(x1,y1,pm.width(), pm.height(), QBrush(bg));
+ }
+ p.drawPixmap(x1, y1, pm, leadingX, leadingY, pm.width(), pm.height());
+}
+
+//bool QVFbView::eventFilter(QObject *obj, QEvent *e)
+//{
+// if (obj == this &&
+// (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut))
+// return true;
+//
+// return QWidgetView::eventFilter(obj, e);
+//}
+
+void QVFbView::paintEvent(QPaintEvent *e)
+{
+ drawScreen(mapToDevice(e->rect(),QSize(int(width()/hzm), int(height()/vzm)),rotation));
+}
+
+void QVFbView::mousePressEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::contextMenuEvent(QContextMenuEvent*)
+{
+
+}
+
+void QVFbView::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::mouseReleaseEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::skinMouseEvent(QMouseEvent *e)
+{
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!emulateTouchscreen || (e->buttons() & Qt::MouseButtonMask))
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), 0);
+}
+
+void QVFbView::wheelEvent(QWheelEvent *e)
+{
+ if (!e)
+ return;
+ sendMouseData(QPoint(int(e->x()/hzm),int(e->y()/vzm)), e->buttons(), e->delta());
+}
+
+void QVFbView::setTouchscreenEmulation(bool b)
+{
+ emulateTouchscreen = b;
+}
+
+void QVFbView::setLcdScreenEmulation(bool b)
+{
+ emulateLcdScreen = b;
+}
+
+void QVFbView::setViewFormat(PixelFormat f)
+{
+ if (viewFormat == f)
+ return;
+ viewFormat = f;
+ setAttribute(Qt::WA_PaintOnScreen, viewFormat != ARGBFormat);
+}
+
+#ifdef Q_WS_X11
+void QVFbView::embedDisplay(WId windowId)
+{
+ if (windowId == 0) {
+ delete embedContainer;
+ embedContainer = 0;
+ return;
+ }
+
+ if (!embedContainer) {
+ embedContainer = new QX11EmbedContainer(this);
+ embedContainer->setGeometry(rect());
+ embedContainer->show();
+ }
+ embedContainer->embedClient(windowId);
+}
+#endif
+
+bool QVFbView::event(QEvent *e)
+{
+ if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ sendKeyboardData(ke->text(), ke->key(),
+ ke->modifiers()&(Qt::ShiftModifier|Qt::ControlModifier|Qt::AltModifier),
+ ke->type() == QEvent::KeyPress, ke->isAutoRepeat());
+ ke->accept();
+ return true;
+ }
+ return QVFbAbstractView::event(e);
+}
+
+void QVFbView::keyPressEvent(QKeyEvent *e)
+{
+ sendKeyboardData(e->text(), e->key(),
+ e->modifiers()&(Qt::ShiftModifier|Qt::ControlModifier|Qt::AltModifier),
+ true, e->isAutoRepeat());
+}
+
+void QVFbView::keyReleaseEvent(QKeyEvent *e)
+{
+ sendKeyboardData(e->text(), e->key(),
+ e->modifiers()&(Qt::ShiftModifier|Qt::ControlModifier|Qt::AltModifier),
+ false, e->isAutoRepeat());
+}
+
+
+QImage QVFbView::image() const
+{
+ int l;
+ QImage r = getBuffer(QRect(0, 0, mView->width(), mView->height()), l).copy();
+ return r;
+}
+
+void QVFbView::startAnimation(const QString& filename)
+{
+ delete animation;
+ animation = new QAnimationWriter(filename,"MNG");
+ animation->setFrameRate(refreshRate);
+ animation->appendFrame(QImage(mView->data(),
+ mView->width(), mView->height(), QImage::Format_RGB32));
+}
+
+void QVFbView::stopAnimation()
+{
+ delete animation;
+ animation = 0;
+}
+
+
+void QVFbView::skinKeyPressEvent(int code, const QString& text, bool autorep)
+{
+ QKeyEvent e(QEvent::KeyPress,code,0,text,autorep);
+ keyPressEvent(&e);
+}
+
+void QVFbView::skinKeyReleaseEvent(int code, const QString& text, bool autorep)
+{
+ QKeyEvent e(QEvent::KeyRelease,code,0,text,autorep);
+ keyReleaseEvent(&e);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/qvfbview.h b/tools/qvfb/qvfbview.h
new file mode 100644
index 0000000..d533613
--- /dev/null
+++ b/tools/qvfb/qvfbview.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFBVIEW_H
+#define QVFBVIEW_H
+
+//#ifdef QT_NO_OPENGL
+#include <QWidget>
+//#else
+//#define QVFB_USE_GLWIDGET
+//#include <QGLWidget>
+//#endif
+
+QT_BEGIN_NAMESPACE
+
+class QImage;
+class QTimer;
+class QAnimationWriter;
+struct QVFbHeader;
+class QVFbViewProtocol;
+class QX11EmbedContainer;
+
+class QVFbAbstractView :
+#ifdef QVFB_USE_GLWIDGET
+ public QGLWidget
+#else
+ public QWidget
+#endif
+{
+ Q_OBJECT
+public:
+ enum Rotation { Rot0, Rot90, Rot180, Rot270 };
+ enum PixelFormat { DefaultFormat, GrayscaleFormat, RGBFormat, ARGBFormat };
+ QVFbAbstractView( QWidget *parent = 0);
+ virtual ~QVFbAbstractView();
+
+ virtual int displayId() const = 0;
+ virtual int displayWidth() const = 0;
+ virtual int displayHeight() const = 0;
+ virtual int displayDepth() const = 0;
+ virtual PixelFormat displayFormat() const { return DefaultFormat; }
+ virtual Rotation displayRotation() const = 0;
+
+ virtual void setGamma(double gr, double gg, double gb) = 0;
+ virtual double gammaRed() const = 0;
+ virtual double gammaGreen() const = 0;
+ virtual double gammaBlue() const = 0;
+ virtual void getGamma(int i, QRgb& rgb) = 0;
+
+ virtual bool touchScreenEmulation() const = 0;
+ virtual bool lcdScreenEmulation() const = 0;
+ virtual int rate() = 0;
+ virtual bool animating() const = 0;
+ virtual QImage image() const = 0;
+ virtual void setRate(int) = 0;
+
+ virtual double zoomH() const = 0;
+ virtual double zoomV() const = 0;
+
+public slots:
+ virtual void setTouchscreenEmulation( bool ) = 0;
+ virtual void setLcdScreenEmulation( bool ) = 0;
+ virtual void setZoom( double, double ) = 0;
+ virtual void setRotation(Rotation) = 0;
+ virtual void startAnimation( const QString& ) = 0;
+ virtual void stopAnimation() = 0;
+ virtual void skinKeyPressEvent( int code, const QString& text, bool autorep=FALSE ) = 0;
+ virtual void skinKeyReleaseEvent( int code, const QString& text, bool autorep=FALSE ) = 0;
+ virtual void setViewFormat(PixelFormat) {}
+ virtual void embedDisplay(WId) {}
+};
+
+class QVFbView : public QVFbAbstractView
+{
+ Q_OBJECT
+public:
+ QVFbView(int id, int w, int h, int d, Rotation r, QWidget *parent = 0);
+ virtual ~QVFbView();
+
+ int displayId() const;
+ int displayWidth() const;
+ int displayHeight() const;
+ int displayDepth() const;
+ PixelFormat displayFormat() const;
+ Rotation displayRotation() const;
+
+ bool touchScreenEmulation() const { return emulateTouchscreen; }
+ bool lcdScreenEmulation() const { return emulateLcdScreen; }
+ int rate() { return refreshRate; }
+ bool animating() const { return !!animation; }
+ QImage image() const;
+
+ void setGamma(double gr, double gg, double gb);
+ double gammaRed() const { return gred; }
+ double gammaGreen() const { return ggreen; }
+ double gammaBlue() const { return gblue; }
+ void getGamma(int i, QRgb& rgb);
+ void skinMouseEvent(QMouseEvent *e);
+
+ double zoomH() const { return hzm; }
+ double zoomV() const { return vzm; }
+
+ QSize sizeHint() const;
+ void setRate(int);
+
+public slots:
+ void setTouchscreenEmulation(bool);
+ void setLcdScreenEmulation(bool);
+ void setZoom(double, double);
+ void setRotation(Rotation);
+ void startAnimation(const QString&);
+ void stopAnimation();
+ void skinKeyPressEvent(int code, const QString& text, bool autorep=FALSE);
+ void skinKeyReleaseEvent(int code, const QString& text, bool autorep=FALSE);
+ void setViewFormat(PixelFormat);
+#ifdef Q_WS_X11
+ void embedDisplay(WId id);
+#endif
+
+protected slots:
+ void refreshDisplay(const QRect &);
+
+protected:
+ QImage getBuffer(const QRect &r, int &leading) const;
+ void drawScreen(const QRect &r);
+ void sendMouseData(const QPoint &pos, int buttons, int wheel);
+ void sendKeyboardData(QString unicode, int keycode, int modifiers,
+ bool press, bool repeat);
+ //virtual bool eventFilter(QObject *obj, QEvent *e);
+ virtual void paintEvent(QPaintEvent *pe);
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void wheelEvent(QWheelEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void keyReleaseEvent(QKeyEvent *e);
+ virtual bool event(QEvent *event);
+
+private:
+ void setDirty(const QRect&);
+ int viewdepth; // "faked" depth
+ PixelFormat viewFormat;
+ int rsh;
+ int gsh;
+ int bsh;
+ int rmax;
+ int gmax;
+ int bmax;
+ int contentsWidth;
+ int contentsHeight;
+ double gred, ggreen, gblue;
+ QRgb* gammatable;
+
+ int refreshRate;
+ QAnimationWriter *animation;
+ double hzm,vzm;
+ QVFbViewProtocol *mView;
+ bool emulateTouchscreen;
+ bool emulateLcdScreen;
+ Rotation rotation;
+
+#ifdef Q_WS_X11
+ QX11EmbedContainer *embedContainer;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/qvfbx11view.cpp b/tools/qvfb/qvfbx11view.cpp
new file mode 100644
index 0000000..cad0b2c
--- /dev/null
+++ b/tools/qvfb/qvfbx11view.cpp
@@ -0,0 +1,388 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2006 TROLLTECH ASA. All rights reserved.
+**
+** This file is part of the Phone Edition of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvfbx11view.h"
+#include "x11keyfaker.h"
+#include <qevent.h>
+#include <QX11Info>
+#include <QTimer>
+#include <QProcess>
+#include <QDebug>
+#include <QUuid>
+#include <QDataStream>
+#include <QTemporaryFile>
+#include <X11/Xlib.h>
+
+QT_BEGIN_NAMESPACE
+
+QVFbX11View::QVFbX11View
+ (int id, int w, int h, int d, Rotation r, QWidget *parent)
+ : QVFbAbstractView(parent)
+{
+ this->id = id;
+ this->w = w;
+ this->h = h;
+ this->d = d;
+ this->rotation = r;
+ this->gr = 1.0;
+ this->gg = 1.0;
+ this->gb = 1.0;
+ this->touchscreen = false;
+ this->lcd = false;
+ this->keyFaker = 0;
+ this->xnest = 0;
+ this->serverAuthFile = 0;
+ this->shutdown = false;
+
+ // Try to find Xephyr, as it is better than Xnest in many ways.
+ if (QFile::exists("/usr/bin/Xephyr"))
+ xserver = "/usr/bin/Xephyr";
+ else if (QFile::exists("/usr/local/bin/Xephyr"))
+ xserver = "/usr/local/bin/Xephyr";
+ else if (QFile::exists("/usr/X11R6/bin/Xephyr"))
+ xserver = "/usr/X11R6/bin/Xephyr";
+ else
+ xserver = "Xnest";
+}
+
+QVFbX11View::~QVFbX11View()
+{
+ shutdown = true;
+ if (xnest) {
+ xnest->terminate();
+ xnestStopped();
+ }
+}
+
+int QVFbX11View::displayId() const
+{
+ return id;
+}
+
+int QVFbX11View::displayWidth() const
+{
+ return ( (int)rotation & 0x01 ) ? h : w;
+}
+
+int QVFbX11View::displayHeight() const
+{
+ return ( (int)rotation & 0x01 ) ? w : h;
+}
+
+int QVFbX11View::displayDepth() const
+{
+ return d;
+}
+
+QVFbX11View::Rotation QVFbX11View::displayRotation() const
+{
+ return rotation;
+}
+
+void QVFbX11View::skinKeyPressEvent(int code, const QString&, bool)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(code, true);
+}
+
+void QVFbX11View::skinKeyReleaseEvent(int code, const QString&, bool)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(code, false);
+}
+
+void QVFbX11View::setGamma(double gr, double gg, double gb)
+{
+ // We remember the values, but don't do anything with them.
+ this->gr = gr;
+ this->gg = gg;
+ this->gb = gb;
+}
+
+double QVFbX11View::gammaRed() const
+{
+ return gr;
+}
+
+double QVFbX11View::gammaGreen() const
+{
+ return gg;
+}
+
+double QVFbX11View::gammaBlue() const
+{
+ return gb;
+}
+
+void QVFbX11View::getGamma(int, QRgb& rgb)
+{
+ rgb = qRgb(255, 255, 255);
+}
+
+bool QVFbX11View::touchScreenEmulation() const
+{
+ return touchscreen;
+}
+
+bool QVFbX11View::lcdScreenEmulation() const
+{
+ return lcd;
+}
+
+int QVFbX11View::rate()
+{
+ // We don't support refresh rates, so return a default value.
+ return 30;
+}
+
+bool QVFbX11View::animating() const
+{
+ // We don't support animation.
+ return false;
+}
+
+QImage QVFbX11View::image() const
+{
+ // We don't support image capture.
+ return QImage();
+}
+
+void QVFbX11View::setRate(int)
+{
+ // We don't support rate adjustments.
+}
+
+
+double QVFbX11View::zoomH() const
+{
+ // Zoom is not possible with Xnest.
+ return 1.0;
+}
+
+double QVFbX11View::zoomV() const
+{
+ // Zoom is not possible with Xnest.
+ return 1.0;
+}
+
+QSize QVFbX11View::sizeHint() const
+{
+ return QSize(w, h);
+}
+
+void QVFbX11View::setTouchscreenEmulation( bool flag )
+{
+ touchscreen = flag;
+}
+
+void QVFbX11View::setLcdScreenEmulation( bool flag )
+{
+ lcd = flag;
+}
+
+void QVFbX11View::setZoom( double, double )
+{
+ // Zoom is not possible with Xnest.
+}
+
+void QVFbX11View::setRotation( Rotation )
+{
+ // Rotation is not possible with Xnest.
+}
+
+void QVFbX11View::startAnimation( const QString& )
+{
+ // Animation is not supported.
+}
+
+void QVFbX11View::stopAnimation()
+{
+ // Animation is not supported.
+}
+
+// Generate a 16-byte magic cookie string.
+static QString generateMagicCookie()
+{
+ static const char hexchars[] = "0123456789abcdef";
+ QUuid uuid = QUuid::createUuid();
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ stream << uuid;
+ QString value;
+ foreach ( char ch, ba ) {
+ value += QChar( hexchars[(ch >> 4) & 0x0F] );
+ value += QChar( hexchars[ch & 0x0F] );
+ }
+ return value;
+}
+
+void QVFbX11View::showEvent(QShowEvent *e)
+{
+ if (!xnest)
+ startXnest();
+ QWidget::showEvent(e);
+}
+
+void QVFbX11View::keyPressEvent(QKeyEvent *e)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(e->key(), true);
+ QWidget::keyPressEvent(e);
+}
+
+void QVFbX11View::keyReleaseEvent(QKeyEvent *e)
+{
+ if (keyFaker)
+ keyFaker->sendKeyEvent(e->key(), false);
+ QWidget::keyReleaseEvent(e);
+}
+
+void QVFbX11View::startXnest()
+{
+ // Add authentication credentials to the XAUTHORITY file.
+ QString cookie = generateMagicCookie();
+ QStringList xauthargs;
+ xauthargs += "add";
+ xauthargs += ":" + QString::number(displayId());
+ xauthargs += "MIT-MAGIC-COOKIE-1";
+ xauthargs += cookie;
+ if (QProcess::execute("xauth", xauthargs) != 0)
+ qWarning() << "xauth: failed to add Xnest client authentication credentials";
+
+ // Write the credentials to another authentication file for the server.
+ serverAuthFile = new QTemporaryFile(this);
+ QString authFilename;
+ if (serverAuthFile->open()) {
+ authFilename = serverAuthFile->fileName();
+ serverAuthFile->close();
+ xauthargs.clear();
+ xauthargs += "-f";
+ xauthargs += authFilename;
+ xauthargs += "add";
+ xauthargs += ":" + QString::number(displayId());
+ xauthargs += "MIT-MAGIC-COOKIE-1";
+ xauthargs += cookie;
+ if (QProcess::execute("xauth", xauthargs) != 0)
+ qWarning() << "xauth: failed to add Xnest server authentication credentials";
+ }
+
+ // Create a raw X11 window to act as the Xnest's root window.
+ // We cannot use winId() directly because qvfb is already
+ // selecting for events that Xnest wants to select for.
+ WId root = XCreateSimpleWindow
+ (QX11Info::display(), winId(), 0, 0, w, h, 0,
+ BlackPixel(QX11Info::display(), QX11Info::appScreen()),
+ BlackPixel(QX11Info::display(), QX11Info::appScreen()));
+ XMapWindow(QX11Info::display(), root);
+
+ // Warn the user if the visual number looks wrong. Xnest expects
+ // its root window to be on the default visual.
+ if (QX11Info::appVisual() != DefaultVisual(QX11Info::display(), QX11Info::appScreen())) {
+ qWarning() << "*** Qt is not using the default visual. Xnest may fail "
+ "with a BadMatch error.";
+ qWarning() << "*** If it fails, then restart qvfb with \" -visual"
+ << DefaultVisual(QX11Info::display(), QX11Info::appScreen())
+ ->visualid << "\"";
+ }
+
+ // Make sure the root window is in the X server before Xnest starts.
+ XSync(QX11Info::display(), False);
+
+ // Start the Xnest process.
+ xnest = new QProcess(this);
+ connect(xnest, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(xnestStopped()));
+ connect(xnest, SIGNAL(finished(int,QProcess::ExitStatus)),
+ this, SLOT(xnestStopped()));
+ QStringList args;
+ args += "-auth";
+ args += authFilename;
+ if (!xserver.contains("Xephyr")) {
+ args += "-geometry";
+ args += QString::number(w) + "x" + QString::number(h) + "+0+0";
+ args += "-depth";
+ args += QString::number(d);
+ }
+ args += "-br"; // Start Xnest with a black background.
+ args += "-parent";
+ args += "0x" + QString::number(root, 16);
+ args += ":" + QString::number(displayId());
+ xnest->setProcessChannelMode(QProcess::ForwardedChannels);
+ xnest->start(xserver, args);
+ //qDebug() << args;
+
+ QTimer::singleShot(200, this, SLOT(startKeyFaker()));
+}
+
+void QVFbX11View::xnestStopped()
+{
+ if (!shutdown) {
+ if (xnest && xnest->error() == QProcess::FailedToStart)
+ qWarning() << xserver << "could not be started";
+ else
+ qWarning() << xserver << "stopped unexpectedly";
+ }
+ if (keyFaker) {
+ delete keyFaker;
+ keyFaker = 0;
+ }
+ if (xnest) {
+ xnest->deleteLater();
+ xnest = 0;
+
+ QStringList xauthargs;
+ xauthargs += "remove";
+ xauthargs += ":" + QString::number(displayId());
+ if (QProcess::execute("xauth", xauthargs) != 0)
+ qWarning() << "xauth: failed to remove Xnest authentication credentials";
+ }
+ if (serverAuthFile) {
+ delete serverAuthFile;
+ serverAuthFile = 0;
+ }
+}
+
+void QVFbX11View::startKeyFaker()
+{
+ if (!keyFaker && xnest)
+ keyFaker = new X11KeyFaker(":" + QString::number(displayId()), this);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/qvfbx11view.h b/tools/qvfb/qvfbx11view.h
new file mode 100644
index 0000000..a96fa6d
--- /dev/null
+++ b/tools/qvfb/qvfbx11view.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2006 TROLLTECH ASA. All rights reserved.
+**
+** This file is part of the Phone Edition of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVFBX11VIEW_H
+#define QVFBX11VIEW_H
+
+#include "qvfbview.h"
+
+QT_BEGIN_NAMESPACE
+
+class X11KeyFaker;
+class QProcess;
+class QTemporaryFile;
+
+class QVFbX11View : public QVFbAbstractView
+{
+ Q_OBJECT
+public:
+ QVFbX11View( int id, int w, int h, int d, Rotation r, QWidget *parent = 0);
+ virtual ~QVFbX11View();
+
+ QString xServerPath() const { return xserver; }
+ void setXServerPath(const QString& path) { xserver = path; }
+
+ int displayId() const;
+ int displayWidth() const;
+ int displayHeight() const;
+ int displayDepth() const;
+ Rotation displayRotation() const;
+
+ void skinKeyPressEvent( int code, const QString& text, bool autorep=FALSE );
+ void skinKeyReleaseEvent( int code, const QString& text, bool autorep=FALSE );
+
+ void setGamma(double gr, double gg, double gb);
+ double gammaRed() const;
+ double gammaGreen() const;
+ double gammaBlue() const;
+ void getGamma(int i, QRgb& rgb);
+
+ bool touchScreenEmulation() const;
+ bool lcdScreenEmulation() const;
+ int rate();
+ bool animating() const;
+ QImage image() const;
+ void setRate(int);
+
+ double zoomH() const;
+ double zoomV() const;
+
+ QSize sizeHint() const;
+
+public slots:
+ void setTouchscreenEmulation( bool );
+ void setLcdScreenEmulation( bool );
+ void setZoom( double, double );
+ void setRotation(Rotation);
+ void startAnimation( const QString& );
+ void stopAnimation();
+
+protected:
+ void showEvent(QShowEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void keyReleaseEvent(QKeyEvent *);
+
+private slots:
+ void startXnest();
+ void xnestStopped();
+ void startKeyFaker();
+
+private:
+ int id, w, h, d;
+ Rotation rotation;
+ double gr, gg, gb;
+ bool touchscreen, lcd;
+ X11KeyFaker *keyFaker;
+ QProcess *xnest;
+ QTemporaryFile *serverAuthFile;
+ bool shutdown;
+ QString xserver;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qvfb/translations/translations.pro b/tools/qvfb/translations/translations.pro
new file mode 100644
index 0000000..736a72c
--- /dev/null
+++ b/tools/qvfb/translations/translations.pro
@@ -0,0 +1,32 @@
+# Include those manually as they do not contain any directory specification
+
+FORMS = ../config.ui
+HEADERS = ../qvfb.h \
+ ../qvfbview.h \
+ ../qvfbratedlg.h \
+ ../qanimationwriter.h \
+ ../gammaview.h \
+ ../qvfbprotocol.h \
+ ../qvfbshmem.h \
+ ../qvfbmmap.h \
+ ../qvfbhdr.h \
+ ../qlock_p.h \
+ ../qwssignalhandler_p.h \
+ ../../shared/deviceskin/deviceskin.cpp
+
+SOURCES = ../qvfb.cpp \
+ ../qvfbview.cpp \
+ ../qvfbratedlg.cpp \
+ ../main.cpp \
+ ../qanimationwriter.cpp \
+ ../qvfbprotocol.cpp \
+ ../qvfbshmem.cpp \
+ ../qvfbmmap.cpp \
+ ../qlock.cpp \
+ ../qwssignalhandler.cpp \
+ ../../shared/deviceskin/deviceskin.cpp
+
+TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qvfb_pl.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qvfb_untranslated.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qvfb_zh_CN.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qvfb_zh_TW.ts
diff --git a/tools/qvfb/x11keyfaker.cpp b/tools/qvfb/x11keyfaker.cpp
new file mode 100644
index 0000000..76d6e6a
--- /dev/null
+++ b/tools/qvfb/x11keyfaker.cpp
@@ -0,0 +1,626 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2006 TROLLTECH ASA. All rights reserved.
+**
+** This file is part of the Phone Edition of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "x11keyfaker.h"
+#include <QTimer>
+#include <QSocketNotifier>
+#include <QDebug>
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+#include <X11/extensions/XTest.h>
+#include <X11/keysym.h>
+#include <X11/XF86keysym.h>
+#include "qtopiakeysym.h"
+#include <unistd.h>
+#include <fcntl.h>
+
+QT_BEGIN_NAMESPACE
+
+X11KeyFaker::X11KeyFaker(const QString& displayName, QObject *parent)
+ : QObject(parent)
+{
+ this->displayName = displayName;
+ this->dpy = 0;
+ this->retryCount = 0;
+ this->shiftKeycode = 0;
+ this->modeSwitchKeycode = 0;
+ this->modifiers = 0;
+ connect();
+}
+
+X11KeyFaker::~X11KeyFaker()
+{
+ if (dpy)
+ XCloseDisplay(dpy);
+}
+
+void X11KeyFaker::sendKeyEvent(int qtCode, bool isPress)
+{
+ if (!dpy)
+ return;
+
+ // Convert the Qt key code into an X keysym.
+ KeySym keysym = NoSymbol;
+ switch (qtCode) {
+ case Qt::Key_Escape: keysym = XK_Escape; break;
+ case Qt::Key_Tab: keysym = XK_Tab; break;
+ case Qt::Key_Backtab: keysym = XK_ISO_Left_Tab; break;
+ case Qt::Key_Backspace: keysym = XK_BackSpace; break;
+ case Qt::Key_Return: keysym = XK_Return; break;
+ case Qt::Key_Enter: keysym = XK_KP_Enter; break;
+ case Qt::Key_Insert: keysym = XK_KP_Insert; break;
+ case Qt::Key_Delete: keysym = XK_KP_Delete; break;
+ case Qt::Key_Pause: keysym = XK_Pause; break;
+ case Qt::Key_Print: keysym = XK_Print; break;
+ case Qt::Key_SysReq: keysym = 0x1005FF60; break;
+ case Qt::Key_Clear: keysym = XK_KP_Begin; break;
+ case Qt::Key_Home: keysym = XK_Home; break;
+ case Qt::Key_End: keysym = XK_End; break;
+ case Qt::Key_Left: keysym = XK_Left; break;
+ case Qt::Key_Up: keysym = XK_Up; break;
+ case Qt::Key_Right: keysym = XK_Right; break;
+ case Qt::Key_Down: keysym = XK_Down; break;
+ case Qt::Key_PageUp: keysym = XK_Prior; break;
+ case Qt::Key_PageDown: keysym = XK_Next; break;
+ case Qt::Key_Shift: keysym = XK_Shift_L; break;
+ case Qt::Key_Control: keysym = XK_Control_L; break;
+ case Qt::Key_Meta: keysym = XK_Meta_L; break;
+ case Qt::Key_Alt: keysym = XK_Alt_L; break;
+ case Qt::Key_CapsLock: keysym = XK_Caps_Lock; break;
+ case Qt::Key_NumLock: keysym = XK_Num_Lock; break;
+ case Qt::Key_ScrollLock: keysym = XK_Scroll_Lock; break;
+ case Qt::Key_F1: keysym = XK_F1; break;
+ case Qt::Key_F2: keysym = XK_F2; break;
+ case Qt::Key_F3: keysym = XK_F3; break;
+ case Qt::Key_F4: keysym = XK_F4; break;
+ case Qt::Key_F5: keysym = XK_F5; break;
+ case Qt::Key_F6: keysym = XK_F6; break;
+ case Qt::Key_F7: keysym = XK_F7; break;
+ case Qt::Key_F8: keysym = XK_F8; break;
+ case Qt::Key_F9: keysym = XK_F9; break;
+ case Qt::Key_F10: keysym = XK_F10; break;
+ case Qt::Key_F11: keysym = XK_F11; break;
+ case Qt::Key_F12: keysym = XK_F12; break;
+ case Qt::Key_F13: keysym = XK_F13; break;
+ case Qt::Key_F14: keysym = XK_F14; break;
+ case Qt::Key_F15: keysym = XK_F15; break;
+ case Qt::Key_F16: keysym = XK_F16; break;
+ case Qt::Key_F17: keysym = XK_F17; break;
+ case Qt::Key_F18: keysym = XK_F18; break;
+ case Qt::Key_F19: keysym = XK_F19; break;
+ case Qt::Key_F20: keysym = XK_F20; break;
+ case Qt::Key_F21: keysym = XK_F21; break;
+ case Qt::Key_F22: keysym = XK_F22; break;
+ case Qt::Key_F23: keysym = XK_F23; break;
+ case Qt::Key_F24: keysym = XK_F24; break;
+ case Qt::Key_F25: keysym = XK_F25; break;
+ case Qt::Key_F26: keysym = XK_F26; break;
+ case Qt::Key_F27: keysym = XK_F27; break;
+ case Qt::Key_F28: keysym = XK_F28; break;
+ case Qt::Key_F29: keysym = XK_F29; break;
+ case Qt::Key_F30: keysym = XK_F30; break;
+ case Qt::Key_F31: keysym = XK_F31; break;
+ case Qt::Key_F32: keysym = XK_F32; break;
+ case Qt::Key_F33: keysym = XK_F33; break;
+ case Qt::Key_F34: keysym = XK_F34; break;
+ case Qt::Key_F35: keysym = XK_F35; break;
+ case Qt::Key_Super_L: keysym = XK_Super_L; break;
+ case Qt::Key_Super_R: keysym = XK_Super_R; break;
+ case Qt::Key_Menu: keysym = XK_Menu; break;
+ case Qt::Key_Hyper_L: keysym = XK_Hyper_L; break;
+ case Qt::Key_Hyper_R: keysym = XK_Hyper_R; break;
+ case Qt::Key_Help: keysym = XK_Help; break;
+ case Qt::Key_Direction_L: keysym = NoSymbol; break; // ???
+ case Qt::Key_Direction_R: keysym = NoSymbol; break; // ???
+ case Qt::Key_Space: keysym = XK_space; break;
+ case Qt::Key_Exclam: keysym = XK_exclam; break;
+ case Qt::Key_QuoteDbl: keysym = XK_quotedbl; break;
+ case Qt::Key_NumberSign: keysym = XK_numbersign; break;
+ case Qt::Key_Dollar: keysym = XK_dollar; break;
+ case Qt::Key_Percent: keysym = XK_percent; break;
+ case Qt::Key_Ampersand: keysym = XK_ampersand; break;
+ case Qt::Key_Apostrophe: keysym = XK_apostrophe; break;
+ case Qt::Key_ParenLeft: keysym = XK_parenleft; break;
+ case Qt::Key_ParenRight: keysym = XK_parenright; break;
+ case Qt::Key_Asterisk: keysym = XK_asterisk; break;
+ case Qt::Key_Plus: keysym = XK_plus; break;
+ case Qt::Key_Comma: keysym = XK_comma; break;
+ case Qt::Key_Minus: keysym = XK_minus; break;
+ case Qt::Key_Period: keysym = XK_period; break;
+ case Qt::Key_Slash: keysym = XK_slash; break;
+ case Qt::Key_0: keysym = XK_0; break;
+ case Qt::Key_1: keysym = XK_1; break;
+ case Qt::Key_2: keysym = XK_2; break;
+ case Qt::Key_3: keysym = XK_3; break;
+ case Qt::Key_4: keysym = XK_4; break;
+ case Qt::Key_5: keysym = XK_5; break;
+ case Qt::Key_6: keysym = XK_6; break;
+ case Qt::Key_7: keysym = XK_7; break;
+ case Qt::Key_8: keysym = XK_8; break;
+ case Qt::Key_9: keysym = XK_9; break;
+ case Qt::Key_Colon: keysym = XK_colon; break;
+ case Qt::Key_Semicolon: keysym = XK_semicolon; break;
+ case Qt::Key_Less: keysym = XK_less; break;
+ case Qt::Key_Equal: keysym = XK_equal; break;
+ case Qt::Key_Greater: keysym = XK_greater; break;
+ case Qt::Key_Question: keysym = XK_question; break;
+ case Qt::Key_At: keysym = XK_at; break;
+ case Qt::Key_A: keysym = XK_a; break; // Must be lower case keysyms
+ case Qt::Key_B: keysym = XK_b; break; // for correct shift handling.
+ case Qt::Key_C: keysym = XK_c; break;
+ case Qt::Key_D: keysym = XK_d; break;
+ case Qt::Key_E: keysym = XK_e; break;
+ case Qt::Key_F: keysym = XK_f; break;
+ case Qt::Key_G: keysym = XK_g; break;
+ case Qt::Key_H: keysym = XK_h; break;
+ case Qt::Key_I: keysym = XK_i; break;
+ case Qt::Key_J: keysym = XK_j; break;
+ case Qt::Key_K: keysym = XK_k; break;
+ case Qt::Key_L: keysym = XK_l; break;
+ case Qt::Key_M: keysym = XK_m; break;
+ case Qt::Key_N: keysym = XK_n; break;
+ case Qt::Key_O: keysym = XK_o; break;
+ case Qt::Key_P: keysym = XK_p; break;
+ case Qt::Key_Q: keysym = XK_q; break;
+ case Qt::Key_R: keysym = XK_r; break;
+ case Qt::Key_S: keysym = XK_s; break;
+ case Qt::Key_T: keysym = XK_t; break;
+ case Qt::Key_U: keysym = XK_u; break;
+ case Qt::Key_V: keysym = XK_v; break;
+ case Qt::Key_W: keysym = XK_w; break;
+ case Qt::Key_X: keysym = XK_x; break;
+ case Qt::Key_Y: keysym = XK_y; break;
+ case Qt::Key_Z: keysym = XK_z; break;
+ case Qt::Key_BracketLeft: keysym = XK_bracketleft; break;
+ case Qt::Key_Backslash: keysym = XK_backslash; break;
+ case Qt::Key_BracketRight: keysym = XK_bracketright; break;
+ case Qt::Key_AsciiCircum: keysym = XK_asciicircum; break;
+ case Qt::Key_Underscore: keysym = XK_underscore; break;
+ case Qt::Key_QuoteLeft: keysym = XK_quoteleft; break;
+ case Qt::Key_BraceLeft: keysym = XK_braceleft; break;
+ case Qt::Key_Bar: keysym = XK_bar; break;
+ case Qt::Key_BraceRight: keysym = XK_braceright; break;
+ case Qt::Key_AsciiTilde: keysym = XK_asciitilde; break;
+
+ case Qt::Key_nobreakspace: keysym = XK_nobreakspace; break;
+ case Qt::Key_exclamdown: keysym = XK_exclamdown; break;
+ case Qt::Key_cent: keysym = XK_cent; break;
+ case Qt::Key_sterling: keysym = XK_sterling; break;
+ case Qt::Key_currency: keysym = XK_currency; break;
+ case Qt::Key_yen: keysym = XK_yen; break;
+ case Qt::Key_brokenbar: keysym = XK_brokenbar; break;
+ case Qt::Key_section: keysym = XK_section; break;
+ case Qt::Key_diaeresis: keysym = XK_diaeresis; break;
+ case Qt::Key_copyright: keysym = XK_copyright; break;
+ case Qt::Key_ordfeminine: keysym = XK_ordfeminine; break;
+ case Qt::Key_guillemotleft: keysym = XK_guillemotleft; break;
+ case Qt::Key_notsign: keysym = XK_notsign; break;
+ case Qt::Key_hyphen: keysym = XK_hyphen; break;
+ case Qt::Key_registered: keysym = XK_registered; break;
+ case Qt::Key_macron: keysym = XK_macron; break;
+ case Qt::Key_degree: keysym = XK_degree; break;
+ case Qt::Key_plusminus: keysym = XK_plusminus; break;
+ case Qt::Key_twosuperior: keysym = XK_twosuperior; break;
+ case Qt::Key_threesuperior: keysym = XK_threesuperior; break;
+ case Qt::Key_acute: keysym = XK_acute; break;
+ case Qt::Key_mu: keysym = XK_mu; break;
+ case Qt::Key_paragraph: keysym = XK_paragraph; break;
+ case Qt::Key_periodcentered: keysym = XK_periodcentered; break;
+ case Qt::Key_cedilla: keysym = XK_cedilla; break;
+ case Qt::Key_onesuperior: keysym = XK_onesuperior; break;
+ case Qt::Key_masculine: keysym = XK_masculine; break;
+ case Qt::Key_guillemotright: keysym = XK_guillemotright; break;
+ case Qt::Key_onequarter: keysym = XK_onequarter; break;
+ case Qt::Key_onehalf: keysym = XK_onehalf; break;
+ case Qt::Key_threequarters: keysym = XK_threequarters; break;
+ case Qt::Key_questiondown: keysym = XK_questiondown; break;
+ case Qt::Key_Agrave: keysym = XK_agrave; break; // Lower case keysyms
+ case Qt::Key_Aacute: keysym = XK_aacute; break; // for shift handling.
+ case Qt::Key_Acircumflex: keysym = XK_acircumflex; break;
+ case Qt::Key_Atilde: keysym = XK_atilde; break;
+ case Qt::Key_Adiaeresis: keysym = XK_adiaeresis; break;
+ case Qt::Key_Aring: keysym = XK_aring; break;
+ case Qt::Key_AE: keysym = XK_ae; break;
+ case Qt::Key_Ccedilla: keysym = XK_ccedilla; break;
+ case Qt::Key_Egrave: keysym = XK_egrave; break;
+ case Qt::Key_Eacute: keysym = XK_eacute; break;
+ case Qt::Key_Ecircumflex: keysym = XK_ecircumflex; break;
+ case Qt::Key_Ediaeresis: keysym = XK_ediaeresis; break;
+ case Qt::Key_Igrave: keysym = XK_igrave; break;
+ case Qt::Key_Iacute: keysym = XK_iacute; break;
+ case Qt::Key_Icircumflex: keysym = XK_icircumflex; break;
+ case Qt::Key_Idiaeresis: keysym = XK_idiaeresis; break;
+ case Qt::Key_ETH: keysym = XK_eth; break;
+ case Qt::Key_Ntilde: keysym = XK_ntilde; break;
+ case Qt::Key_Ograve: keysym = XK_ograve; break;
+ case Qt::Key_Oacute: keysym = XK_oacute; break;
+ case Qt::Key_Ocircumflex: keysym = XK_ocircumflex; break;
+ case Qt::Key_Otilde: keysym = XK_otilde; break;
+ case Qt::Key_Odiaeresis: keysym = XK_odiaeresis; break;
+ case Qt::Key_multiply: keysym = XK_multiply; break;
+ case Qt::Key_Ooblique: keysym = XK_ooblique; break;
+ case Qt::Key_Ugrave: keysym = XK_ugrave; break;
+ case Qt::Key_Uacute: keysym = XK_uacute; break;
+ case Qt::Key_Ucircumflex: keysym = XK_ucircumflex; break;
+ case Qt::Key_Udiaeresis: keysym = XK_udiaeresis; break;
+ case Qt::Key_Yacute: keysym = XK_yacute; break;
+ case Qt::Key_THORN: keysym = XK_thorn; break;
+ case Qt::Key_ssharp: keysym = XK_ssharp; break;
+ case Qt::Key_division: keysym = XK_division; break;
+ case Qt::Key_ydiaeresis: keysym = XK_ydiaeresis; break;
+
+ case Qt::Key_AltGr: keysym = XK_ISO_Level3_Shift; break;
+ case Qt::Key_Multi_key: keysym = XK_Multi_key; break;
+ case Qt::Key_Codeinput: keysym = XK_Codeinput; break;
+ case Qt::Key_SingleCandidate: keysym = XK_SingleCandidate; break;
+ case Qt::Key_MultipleCandidate: keysym = XK_MultipleCandidate; break;
+ case Qt::Key_PreviousCandidate: keysym = XK_PreviousCandidate; break;
+
+ case Qt::Key_Mode_switch: keysym = XK_Mode_switch; break;
+
+ case Qt::Key_Kanji: keysym = XK_Kanji; break;
+ case Qt::Key_Muhenkan: keysym = XK_Muhenkan; break;
+ case Qt::Key_Henkan: keysym = XK_Henkan; break;
+ case Qt::Key_Romaji: keysym = XK_Romaji; break;
+ case Qt::Key_Hiragana: keysym = XK_Hiragana; break;
+ case Qt::Key_Katakana: keysym = XK_Katakana; break;
+ case Qt::Key_Hiragana_Katakana: keysym = XK_Hiragana_Katakana; break;
+ case Qt::Key_Zenkaku: keysym = XK_Zenkaku; break;
+ case Qt::Key_Hankaku: keysym = XK_Hankaku; break;
+ case Qt::Key_Zenkaku_Hankaku: keysym = XK_Zenkaku_Hankaku; break;
+ case Qt::Key_Touroku: keysym = XK_Touroku; break;
+ case Qt::Key_Massyo: keysym = XK_Massyo; break;
+ case Qt::Key_Kana_Lock: keysym = XK_Kana_Lock; break;
+ case Qt::Key_Kana_Shift: keysym = XK_Kana_Shift; break;
+ case Qt::Key_Eisu_Shift: keysym = XK_Eisu_Shift; break;
+ case Qt::Key_Eisu_toggle: keysym = XK_Eisu_toggle; break;
+
+ case Qt::Key_Hangul: keysym = XK_Hangul; break;
+ case Qt::Key_Hangul_Start: keysym = XK_Hangul_Start; break;
+ case Qt::Key_Hangul_End: keysym = XK_Hangul_End; break;
+ case Qt::Key_Hangul_Hanja: keysym = XK_Hangul_Hanja; break;
+ case Qt::Key_Hangul_Jamo: keysym = XK_Hangul_Jamo; break;
+ case Qt::Key_Hangul_Romaja: keysym = XK_Hangul_Romaja; break;
+ case Qt::Key_Hangul_Jeonja: keysym = XK_Hangul_Jeonja; break;
+ case Qt::Key_Hangul_Banja: keysym = XK_Hangul_Banja; break;
+ case Qt::Key_Hangul_PreHanja: keysym = XK_Hangul_PreHanja; break;
+ case Qt::Key_Hangul_PostHanja: keysym = XK_Hangul_PostHanja; break;
+ case Qt::Key_Hangul_Special: keysym = XK_Hangul_Special; break;
+
+ case Qt::Key_Dead_Grave: keysym = XK_dead_grave; break;
+ case Qt::Key_Dead_Acute: keysym = XK_dead_acute; break;
+ case Qt::Key_Dead_Circumflex: keysym = XK_dead_circumflex; break;
+ case Qt::Key_Dead_Tilde: keysym = XK_dead_tilde; break;
+ case Qt::Key_Dead_Macron: keysym = XK_dead_macron; break;
+ case Qt::Key_Dead_Breve: keysym = XK_dead_breve; break;
+ case Qt::Key_Dead_Abovedot: keysym = XK_dead_abovedot; break;
+ case Qt::Key_Dead_Diaeresis: keysym = XK_dead_diaeresis; break;
+ case Qt::Key_Dead_Abovering: keysym = XK_dead_abovering; break;
+ case Qt::Key_Dead_Doubleacute: keysym = XK_dead_doubleacute; break;
+ case Qt::Key_Dead_Caron: keysym = XK_dead_caron; break;
+ case Qt::Key_Dead_Cedilla: keysym = XK_dead_cedilla; break;
+ case Qt::Key_Dead_Ogonek: keysym = XK_dead_ogonek; break;
+ case Qt::Key_Dead_Iota: keysym = XK_dead_iota; break;
+ case Qt::Key_Dead_Voiced_Sound: keysym = XK_dead_voiced_sound; break;
+ case Qt::Key_Dead_Semivoiced_Sound: keysym = XK_dead_semivoiced_sound; break;
+ case Qt::Key_Dead_Belowdot: keysym = XK_dead_belowdot; break;
+ case Qt::Key_Dead_Hook: keysym = XK_dead_hook; break;
+ case Qt::Key_Dead_Horn: keysym = XK_dead_horn; break;
+
+ case Qt::Key_Back: keysym = XF86XK_Back; break;
+ case Qt::Key_Forward: keysym = XF86XK_Forward; break;
+ case Qt::Key_Stop: keysym = XF86XK_Stop; break;
+ case Qt::Key_Refresh: keysym = XF86XK_Refresh; break;
+
+ case Qt::Key_VolumeDown: keysym = XF86XK_AudioLowerVolume; break;
+ case Qt::Key_VolumeMute: keysym = XF86XK_AudioMute; break;
+ case Qt::Key_VolumeUp: keysym = XF86XK_AudioRaiseVolume; break;
+ case Qt::Key_BassBoost: keysym = NoSymbol; break; // ???
+ case Qt::Key_BassUp: keysym = NoSymbol; break; // ???
+ case Qt::Key_BassDown: keysym = NoSymbol; break; // ???
+ case Qt::Key_TrebleUp: keysym = NoSymbol; break; // ???
+ case Qt::Key_TrebleDown: keysym = NoSymbol; break; // ???
+
+ case Qt::Key_MediaPlay: keysym = XF86XK_AudioPlay; break;
+ case Qt::Key_MediaStop: keysym = XF86XK_AudioStop; break;
+ case Qt::Key_MediaPrevious: keysym = XF86XK_AudioPrev; break;
+ case Qt::Key_MediaNext: keysym = XF86XK_AudioNext; break;
+ case Qt::Key_MediaRecord: keysym = XF86XK_AudioRecord; break;
+
+ case Qt::Key_HomePage: keysym = XF86XK_HomePage; break;
+ case Qt::Key_Favorites: keysym = XF86XK_Favorites; break;
+ case Qt::Key_Search: keysym = XF86XK_Search; break;
+ case Qt::Key_Standby: keysym = XF86XK_Standby; break;
+ case Qt::Key_OpenUrl: keysym = XF86XK_OpenURL; break;
+
+ case Qt::Key_LaunchMail: keysym = XF86XK_Mail; break;
+ case Qt::Key_LaunchMedia: keysym = XF86XK_AudioMedia; break;
+ case Qt::Key_Launch0: keysym = XF86XK_Launch0; break;
+ case Qt::Key_Launch1: keysym = XF86XK_Launch1; break;
+ case Qt::Key_Launch2: keysym = XF86XK_Launch2; break;
+ case Qt::Key_Launch3: keysym = XF86XK_Launch3; break;
+ case Qt::Key_Launch4: keysym = XF86XK_Launch4; break;
+ case Qt::Key_Launch5: keysym = XF86XK_Launch5; break;
+ case Qt::Key_Launch6: keysym = XF86XK_Launch6; break;
+ case Qt::Key_Launch7: keysym = XF86XK_Launch7; break;
+ case Qt::Key_Launch8: keysym = XF86XK_Launch8; break;
+ case Qt::Key_Launch9: keysym = XF86XK_Launch9; break;
+ case Qt::Key_LaunchA: keysym = XF86XK_LaunchA; break;
+ case Qt::Key_LaunchB: keysym = XF86XK_LaunchB; break;
+ case Qt::Key_LaunchC: keysym = XF86XK_LaunchC; break;
+ case Qt::Key_LaunchD: keysym = XF86XK_LaunchD; break;
+ case Qt::Key_LaunchE: keysym = XF86XK_LaunchE; break;
+ case Qt::Key_LaunchF: keysym = XF86XK_LaunchF; break;
+
+ case Qt::Key_MediaLast: keysym = NoSymbol; break; // ???
+
+ case Qt::Key_Select: keysym = QTOPIAXK_Select; break;
+ case Qt::Key_Yes: keysym = QTOPIAXK_Yes; break;
+ case Qt::Key_No: keysym = QTOPIAXK_No; break;
+
+ case Qt::Key_Cancel: keysym = QTOPIAXK_Cancel; break;
+ case Qt::Key_Printer: keysym = QTOPIAXK_Printer; break;
+ case Qt::Key_Execute: keysym = QTOPIAXK_Execute; break;
+ case Qt::Key_Sleep: keysym = QTOPIAXK_Sleep; break;
+ case Qt::Key_Play: keysym = QTOPIAXK_Play; break;
+ case Qt::Key_Zoom: keysym = QTOPIAXK_Zoom; break;
+
+ case Qt::Key_Context1: keysym = QTOPIAXK_Context1; break;
+ case Qt::Key_Context2: keysym = QTOPIAXK_Context2; break;
+ case Qt::Key_Context3: keysym = QTOPIAXK_Context3; break;
+ case Qt::Key_Context4: keysym = QTOPIAXK_Context4; break;
+ case Qt::Key_Call: keysym = QTOPIAXK_Call; break;
+ case Qt::Key_Hangup: keysym = QTOPIAXK_Hangup; break;
+ case Qt::Key_Flip: keysym = QTOPIAXK_Flip; break;
+
+ case Qt::Key_unknown: keysym = NoSymbol; break;
+ }
+ if (keysym == NoSymbol)
+ return;
+
+ // Convert the X keysym into an X keycode.
+ KeyCode keycode = XKeysymToKeycode(dpy, keysym);
+ if (keycode == NoSymbol)
+ return;
+
+ // Determine if we need to fake shift keys as well.
+ int index = 0;
+ while (index < 4 && XKeycodeToKeysym(dpy, keycode, index) != keysym)
+ ++index;
+ int extraModifiers = 0;
+ if ((index & 1) != 0)
+ extraModifiers |= ShiftMask;
+ if ((index & 2) != 0)
+ extraModifiers |= Mod2Mask;
+ if ((modifiers & LockMask) != 0) {
+ // If Caps Lock is set, then flip the shift state for alphabetic keys.
+ if (qtCode >= Qt::Key_A && qtCode <= Qt::Key_Z)
+ extraModifiers ^= ShiftMask;
+ if (qtCode >= Qt::Key_Agrave && qtCode <= Qt::Key_THORN &&
+ qtCode != Qt::Key_multiply)
+ extraModifiers ^= ShiftMask;
+ }
+
+ // Adjust modifier keys for the shift states. This is needed for
+ // things like the * and # phone keys, which need Shift to be pressed
+ // when entering from a keyboard, but don't need Shift from a skin.
+ unsigned long delay = 0;
+ if (extraModifiers != 0) {
+ if ((extraModifiers & ShiftMask) != 0) {
+ if ((modifiers & ShiftMask) == 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, true, delay++);
+ } else {
+ if ((modifiers & ShiftMask) != 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, false, delay++);
+ }
+ if ((extraModifiers & Mod2Mask) != 0) {
+ if ((modifiers & Mod2Mask) == 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, true, delay++);
+ } else {
+ if ((modifiers & Mod2Mask) != 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, false, delay++);
+ }
+ }
+
+ // Fake the actual key.
+ XTestFakeKeyEvent(dpy, keycode, (Bool)isPress, delay++);
+
+ // Adjust the modifiers back.
+ if (extraModifiers != 0) {
+ if ((extraModifiers & ShiftMask) != 0) {
+ if ((modifiers & ShiftMask) == 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, false, delay++);
+ } else {
+ if ((modifiers & ShiftMask) != 0)
+ XTestFakeKeyEvent(dpy, shiftKeycode, true, delay++);
+ }
+ if ((extraModifiers & Mod2Mask) != 0) {
+ if ((modifiers & Mod2Mask) == 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, false, delay++);
+ } else {
+ if ((modifiers & Mod2Mask) != 0)
+ XTestFakeKeyEvent(dpy, modeSwitchKeycode, true, delay++);
+ }
+ }
+
+ // Flush the key events.
+ XFlush(dpy);
+
+ // Update the modifiers if this was a shift key.
+ if (isPress) {
+ if (qtCode == Qt::Key_Shift)
+ modifiers |= ShiftMask;
+ if (qtCode == Qt::Key_CapsLock)
+ modifiers |= LockMask;
+ if (qtCode == Qt::Key_Mode_switch)
+ modifiers |= Mod2Mask;
+ } else {
+ if (qtCode == Qt::Key_Shift)
+ modifiers &= ~ShiftMask;
+ if (qtCode == Qt::Key_CapsLock)
+ modifiers &= ~LockMask;
+ if (qtCode == Qt::Key_Mode_switch)
+ modifiers &= ~Mod2Mask;
+ }
+}
+
+// Determine if an X11 keycode is currently mapped to one or more keysyms.
+static bool keycodeInUse(Display *dpy, int keycode)
+{
+ for (int index = 0; index < 8; ++index) {
+ if (XKeycodeToKeysym(dpy, keycode, index) != NoSymbol)
+ return true;
+ }
+ return false;
+}
+
+// Allocate a keycode for a special keysym.
+static bool allocateSpecialKeysym
+ (Display *dpy, int& min_keycode, int& max_keycode, KeySym key)
+{
+ if (XKeysymToKeycode(dpy, key) != NoSymbol)
+ return true; // There is already a mapping for this key. Good!
+ while (max_keycode >= min_keycode) {
+ if (!keycodeInUse(dpy, max_keycode))
+ break;
+ --max_keycode;
+ }
+ if (max_keycode < min_keycode)
+ return false;
+ XChangeKeyboardMapping(dpy, max_keycode, 1, &key, 1);
+ --max_keycode;
+ return true;
+}
+
+void X11KeyFaker::connect()
+{
+ // Open the display.
+ dpy = XOpenDisplay(displayName.toLatin1().data());
+ if (!dpy) {
+ // Try again in a few milliseconds. Xnest may not be alive yet.
+ // Give up after 10 seconds.
+ if (++retryCount < 50)
+ QTimer::singleShot(200, this, SLOT(connect()));
+ else
+ QTimer::singleShot(0, this, SIGNAL(couldNotConnect()));
+ return;
+ }
+
+ // Query the XTest extension, which we need to fake the key events.
+ int event_base, error_base, major, minor;
+ if (!XTestQueryExtension
+ (dpy, &event_base, &error_base, &major, &minor)) {
+ XCloseDisplay(dpy);
+ dpy = 0;
+ QTimer::singleShot(0, this, SIGNAL(couldNotConnect()));
+ return;
+ }
+
+ // Modify the Xnest's keyboard mappings to add Qtopia's special keysyms.
+ int min_keycode = 1, max_keycode = 255;
+ XDisplayKeycodes(dpy, &min_keycode, &max_keycode);
+ bool ok = true;
+ for (KeySym key = QTOPIAXK_Max; key >= QTOPIAXK_Min; --key) {
+ // This is an extension keysym, not part of the standard X11 set.
+ if (!allocateSpecialKeysym(dpy, min_keycode, max_keycode, key)) {
+ ok = false;
+ break;
+ }
+ }
+ static const KeySym specials[] = {
+ XF86XK_Back, // Qt::Key_Back
+ XF86XK_AudioLowerVolume, // Qt::Key_VolumeUp
+ XF86XK_AudioRaiseVolume, // Qt::Key_VolumeDown
+ XK_F28, // Qt::Key_F28
+ NoSymbol
+ };
+ int index = 0;
+ while (ok && specials[index] != NoSymbol) {
+ // This is a standard X11/XFree86 keysym that Qtopia uses,
+ // but it may not be on the user's physical keyboard.
+ if (!allocateSpecialKeysym
+ (dpy, min_keycode, max_keycode, specials[index]))
+ ok = false;
+ ++index;
+ }
+ if (!ok)
+ qWarning() << "There are insufficient spare X11 keycodes to allocate the special Qtopia keys";
+
+ // Change the root cursor to something more reasonable than "X".
+ Cursor cursor = XCreateFontCursor(dpy, XC_left_ptr);
+ XDefineCursor(dpy, RootWindow(dpy, DefaultScreen(dpy)), cursor);
+
+ // Look up the shift keys.
+ shiftKeycode = XKeysymToKeycode(dpy, XK_Shift_L);
+ if (shiftKeycode == NoSymbol)
+ shiftKeycode = XKeysymToKeycode(dpy, XK_Shift_R);
+ modeSwitchKeycode = XKeysymToKeycode(dpy, XK_Mode_switch);
+
+ // Make sure all of the above changes are flushed.
+ XFlush(dpy);
+
+ // Set up event handling for the display.
+ QSocketNotifier *notifier = new QSocketNotifier
+ (ConnectionNumber(dpy), QSocketNotifier::Read, this);
+ QObject::connect(notifier, SIGNAL(activated(int)), this, SLOT(readyRead()));
+
+ // Make sure the file descriptor is not inherited across exec's.
+ fcntl(ConnectionNumber(dpy), F_SETFD, 1);
+
+ // Notify interested parties that we are now connected to the X display.
+ QTimer::singleShot(0, this, SIGNAL(connected()));
+}
+
+void X11KeyFaker::readyRead()
+{
+ if (dpy) {
+ // Read incoming events and discard them. The only event
+ // we care about is keyboard mapping changes. Since we
+ // don't have any active windows, there's nothing more to do.
+ while (XEventsQueued(dpy, QueuedAfterFlush)) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+ if (event.xany.type == MappingNotify)
+ XRefreshKeyboardMapping(&event.xmapping);
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qvfb/x11keyfaker.h b/tools/qvfb/x11keyfaker.h
new file mode 100644
index 0000000..32417df
--- /dev/null
+++ b/tools/qvfb/x11keyfaker.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2006 TROLLTECH ASA. All rights reserved.
+**
+** This file is part of the Phone Edition of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef X11KEYFAKER_H
+#define X11KEYFAKER_H
+
+#include <QObject>
+#include <QX11Info>
+#include <qnamespace.h>
+
+QT_BEGIN_NAMESPACE
+
+class X11KeyFaker : public QObject
+{
+ Q_OBJECT
+public:
+ X11KeyFaker(const QString& displayName, QObject *parent = 0);
+ ~X11KeyFaker();
+
+ bool isConnected() const { return dpy != 0; }
+
+ void sendKeyEvent(int qtCode, bool isPress);
+
+private slots:
+ void connect();
+ void readyRead();
+
+signals:
+ void connected();
+ void couldNotConnect();
+
+private:
+ QString displayName;
+ Display *dpy;
+ int retryCount;
+ int shiftKeycode;
+ int modeSwitchKeycode;
+ int modifiers;
+};
+
+QT_END_NAMESPACE
+
+#endif