Merge lp:~timo-jyrinki/ciborium/port_to_qml.v1 into lp:ciborium

Proposed by Timo Jyrinki on 2015-06-11
Status: Merged
Approved by: Manuel de la Peña on 2015-06-12
Approved revision: 142
Merged at revision: 138
Proposed branch: lp:~timo-jyrinki/ciborium/port_to_qml.v1
Merge into: lp:ciborium
Diff against target: 12638 lines (+6477/-5713)
83 files modified
cmd/ciborium-ui/main.go (+3/-2)
debian/changelog (+6/-0)
debian/copyright (+2/-2)
qml.v0/LICENSE (+0/-185)
qml.v0/README.md (+0/-151)
qml.v0/all.cpp (+0/-8)
qml.v0/bridge.go (+0/-632)
qml.v0/cpp/capi.cpp (+0/-849)
qml.v0/cpp/capi.h (+0/-206)
qml.v0/cpp/connector.cpp (+0/-46)
qml.v0/cpp/connector.h (+0/-58)
qml.v0/cpp/govalue.cpp (+0/-237)
qml.v0/cpp/govalue.h (+0/-56)
qml.v0/cpp/govaluetype.cpp (+0/-254)
qml.v0/cpp/govaluetype.h (+0/-48)
qml.v0/cpp/idletimer.cpp (+0/-58)
qml.v0/cpp/moc_all.cpp (+0/-4)
qml.v0/cpp/moc_connector.cpp (+0/-211)
qml.v0/cpp/moc_govalue.cpp (+0/-155)
qml.v0/cpp/moc_idletimer.cpp (+0/-108)
qml.v0/cpp/private/qmetaobject_p.h (+0/-2)
qml.v0/cpp/private/qmetaobjectbuilder_p.h (+0/-2)
qml.v0/cpp/private/qobject_p.h (+0/-2)
qml.v0/cpp/private/qtheader.h (+0/-70)
qml.v0/cpp/update-moc.sh (+0/-19)
qml.v0/cpptest/cpptest.cpp (+0/-14)
qml.v0/cpptest/cpptest.go (+0/-30)
qml.v0/cpptest/cpptest.h (+0/-23)
qml.v0/cpptest/moc_testtype.cpp (+0/-202)
qml.v0/cpptest/testtype.h (+0/-45)
qml.v0/cpptest/update-moc.sh (+0/-12)
qml.v0/datatype.go (+0/-527)
qml.v0/doc.go (+0/-166)
qml.v0/log.go (+0/-157)
qml.v0/qml.go (+0/-1059)
qml.v0/stats.go (+0/-68)
qml.v0/tref/tref.c (+0/-6)
qml.v0/tref/tref.go (+0/-5)
qml.v0/tref/tref_test.go (+0/-34)
qml.v1/.gitignore (+5/-0)
qml.v1/LICENSE (+185/-0)
qml.v1/README.md (+157/-0)
qml.v1/all.cpp (+12/-0)
qml.v1/bridge.go (+681/-0)
qml.v1/cdata/cdata.go (+6/-0)
qml.v1/cdata/cdata12.c (+18/-0)
qml.v1/cdata/cdata14_386.s (+17/-0)
qml.v1/cdata/cdata14_amd64.s (+17/-0)
qml.v1/cdata/cdata14_arm.s (+18/-0)
qml.v1/cdata/cdata_test.go (+42/-0)
qml.v1/cpp/capi.cpp (+874/-0)
qml.v1/cpp/capi.h (+211/-0)
qml.v1/cpp/connector.cpp (+46/-0)
qml.v1/cpp/connector.h (+58/-0)
qml.v1/cpp/govalue.cpp (+236/-0)
qml.v1/cpp/govalue.h (+56/-0)
qml.v1/cpp/govaluetype.cpp (+254/-0)
qml.v1/cpp/govaluetype.h (+48/-0)
qml.v1/cpp/idletimer.cpp (+58/-0)
qml.v1/cpp/mmemwin.cpp (+27/-0)
qml.v1/cpp/moc_all.cpp (+4/-0)
qml.v1/cpp/moc_connector.cpp (+211/-0)
qml.v1/cpp/moc_govalue.cpp (+155/-0)
qml.v1/cpp/moc_idletimer.cpp (+108/-0)
qml.v1/cpp/private/qmetaobject_p.h (+2/-0)
qml.v1/cpp/private/qmetaobjectbuilder_p.h (+2/-0)
qml.v1/cpp/private/qobject_p.h (+2/-0)
qml.v1/cpp/private/qtheader.h (+70/-0)
qml.v1/cpp/update-moc.sh (+19/-0)
qml.v1/cpptest/cpptest.cpp (+14/-0)
qml.v1/cpptest/cpptest.go (+30/-0)
qml.v1/cpptest/cpptest.h (+23/-0)
qml.v1/cpptest/moc_testtype.cpp (+202/-0)
qml.v1/cpptest/testtype.h (+45/-0)
qml.v1/cpptest/update-moc.sh (+12/-0)
qml.v1/datatype.go (+531/-0)
qml.v1/doc.go (+199/-0)
qml.v1/gl/glbase/glbase.go (+33/-0)
qml.v1/log.go (+157/-0)
qml.v1/qml.go (+1109/-0)
qml.v1/resources.go (+375/-0)
qml.v1/stats.go (+68/-0)
qml.v1/testing.go (+69/-0)
To merge this branch: bzr merge lp:~timo-jyrinki/ciborium/port_to_qml.v1
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) 2015-06-11 Approve on 2015-06-12
PS Jenkins bot continuous-integration Approve on 2015-06-12
Review via email: mp+261707@code.launchpad.net

Commit Message

Port to qml.v1, fixing FTBFS.

Description of the Change

(trust me, I don't know what I'm doing, but it builds and runs its unit tests)

To post a comment you must log in.
141. By Timo Jyrinki on 2015-06-11

Update debian/copyright

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Timo Jyrinki (timo-jyrinki) wrote :

Build on x86, fails to build on armhf due to some OpenGL stuff.

142. By Timo Jyrinki on 2015-06-12

Remove everything from qml.v1/gl except for glbase

Manuel de la Peña (mandel) wrote :

Looks good to get around the build issues.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmd/ciborium-ui/main.go'
2--- cmd/ciborium-ui/main.go 2015-03-11 01:54:55 +0000
3+++ cmd/ciborium-ui/main.go 2015-06-12 10:54:44 +0000
4@@ -28,7 +28,7 @@
5
6 "log"
7
8- "launchpad.net/ciborium/qml.v0"
9+ "launchpad.net/ciborium/qml.v1"
10 "launchpad.net/ciborium/udisks2"
11 "launchpad.net/go-dbus/v1"
12 "launchpad.net/go-xdg/v0"
13@@ -77,7 +77,8 @@
14 // set default logger flags to get more useful info
15 log.SetFlags(log.LstdFlags | log.Lshortfile)
16
17- qml.Init(nil)
18+ // not in qml.v1
19+ //qml.Init(nil)
20 engine := qml.NewEngine()
21 component, err := engine.LoadFile(mainQmlPath)
22 if err != nil {
23
24=== modified file 'debian/changelog'
25--- debian/changelog 2015-03-18 10:06:56 +0000
26+++ debian/changelog 2015-06-12 10:54:44 +0000
27@@ -1,3 +1,9 @@
28+ciborium (0.2.12+15.04.20150611-0ubuntu1) UNRELEASED; urgency=medium
29+
30+ * Port to QML.v1
31+
32+ -- Timo Jyrinki <timo-jyrinki@ubuntu.com> Thu, 11 Jun 2015 10:12:09 +0000
33+
34 ciborium (0.2.12+15.04.20150316.7-0ubuntu2) vivid; urgency=medium
35
36 * No-change rebuild against Qt 5.4.1.
37
38=== modified file 'debian/copyright'
39--- debian/copyright 2014-08-26 23:42:39 +0000
40+++ debian/copyright 2015-06-12 10:54:44 +0000
41@@ -6,8 +6,8 @@
42 Copyright: 2012-2013 José Carlos Nieto
43 License: MIT
44
45-Files: qml.v0/*
46-Copyright: 2013-2014, Gustavo Niemeyer <gustavo@niemeyer.net>
47+Files: qml.v1/*
48+Copyright: 2013-2015, Gustavo Niemeyer <gustavo@niemeyer.net> and gopkg.in/qml.v1 contributors
49 License: LGPL-3
50
51 Files: *
52
53=== removed directory 'qml.v0'
54=== removed file 'qml.v0/LICENSE'
55--- qml.v0/LICENSE 2014-08-26 19:38:51 +0000
56+++ qml.v0/LICENSE 1970-01-01 00:00:00 +0000
57@@ -1,185 +0,0 @@
58-This software is licensed under the LGPLv3, included below.
59-
60-As a special exception to the GNU Lesser General Public License version 3
61-("LGPL3"), the copyright holders of this Library give you permission to
62-convey to a third party a Combined Work that links statically or dynamically
63-to this Library without providing any Minimal Corresponding Source or
64-Minimal Application Code as set out in 4d or providing the installation
65-information set out in section 4e, provided that you comply with the other
66-provisions of LGPL3 and provided that you meet, for the Application the
67-terms and conditions of the license(s) which apply to the Application.
68-
69-Except as stated in this special exception, the provisions of LGPL3 will
70-continue to comply in full to this Library. If you modify this Library, you
71-may apply this exception to your version of this Library, but you are not
72-obliged to do so. If you do not wish to do so, delete this exception
73-statement from your version. This exception does not (and cannot) modify any
74-license terms which apply to the Application, with which you must still
75-comply.
76-
77-
78- GNU LESSER GENERAL PUBLIC LICENSE
79- Version 3, 29 June 2007
80-
81- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
82- Everyone is permitted to copy and distribute verbatim copies
83- of this license document, but changing it is not allowed.
84-
85-
86- This version of the GNU Lesser General Public License incorporates
87-the terms and conditions of version 3 of the GNU General Public
88-License, supplemented by the additional permissions listed below.
89-
90- 0. Additional Definitions.
91-
92- As used herein, "this License" refers to version 3 of the GNU Lesser
93-General Public License, and the "GNU GPL" refers to version 3 of the GNU
94-General Public License.
95-
96- "The Library" refers to a covered work governed by this License,
97-other than an Application or a Combined Work as defined below.
98-
99- An "Application" is any work that makes use of an interface provided
100-by the Library, but which is not otherwise based on the Library.
101-Defining a subclass of a class defined by the Library is deemed a mode
102-of using an interface provided by the Library.
103-
104- A "Combined Work" is a work produced by combining or linking an
105-Application with the Library. The particular version of the Library
106-with which the Combined Work was made is also called the "Linked
107-Version".
108-
109- The "Minimal Corresponding Source" for a Combined Work means the
110-Corresponding Source for the Combined Work, excluding any source code
111-for portions of the Combined Work that, considered in isolation, are
112-based on the Application, and not on the Linked Version.
113-
114- The "Corresponding Application Code" for a Combined Work means the
115-object code and/or source code for the Application, including any data
116-and utility programs needed for reproducing the Combined Work from the
117-Application, but excluding the System Libraries of the Combined Work.
118-
119- 1. Exception to Section 3 of the GNU GPL.
120-
121- You may convey a covered work under sections 3 and 4 of this License
122-without being bound by section 3 of the GNU GPL.
123-
124- 2. Conveying Modified Versions.
125-
126- If you modify a copy of the Library, and, in your modifications, a
127-facility refers to a function or data to be supplied by an Application
128-that uses the facility (other than as an argument passed when the
129-facility is invoked), then you may convey a copy of the modified
130-version:
131-
132- a) under this License, provided that you make a good faith effort to
133- ensure that, in the event an Application does not supply the
134- function or data, the facility still operates, and performs
135- whatever part of its purpose remains meaningful, or
136-
137- b) under the GNU GPL, with none of the additional permissions of
138- this License applicable to that copy.
139-
140- 3. Object Code Incorporating Material from Library Header Files.
141-
142- The object code form of an Application may incorporate material from
143-a header file that is part of the Library. You may convey such object
144-code under terms of your choice, provided that, if the incorporated
145-material is not limited to numerical parameters, data structure
146-layouts and accessors, or small macros, inline functions and templates
147-(ten or fewer lines in length), you do both of the following:
148-
149- a) Give prominent notice with each copy of the object code that the
150- Library is used in it and that the Library and its use are
151- covered by this License.
152-
153- b) Accompany the object code with a copy of the GNU GPL and this license
154- document.
155-
156- 4. Combined Works.
157-
158- You may convey a Combined Work under terms of your choice that,
159-taken together, effectively do not restrict modification of the
160-portions of the Library contained in the Combined Work and reverse
161-engineering for debugging such modifications, if you also do each of
162-the following:
163-
164- a) Give prominent notice with each copy of the Combined Work that
165- the Library is used in it and that the Library and its use are
166- covered by this License.
167-
168- b) Accompany the Combined Work with a copy of the GNU GPL and this license
169- document.
170-
171- c) For a Combined Work that displays copyright notices during
172- execution, include the copyright notice for the Library among
173- these notices, as well as a reference directing the user to the
174- copies of the GNU GPL and this license document.
175-
176- d) Do one of the following:
177-
178- 0) Convey the Minimal Corresponding Source under the terms of this
179- License, and the Corresponding Application Code in a form
180- suitable for, and under terms that permit, the user to
181- recombine or relink the Application with a modified version of
182- the Linked Version to produce a modified Combined Work, in the
183- manner specified by section 6 of the GNU GPL for conveying
184- Corresponding Source.
185-
186- 1) Use a suitable shared library mechanism for linking with the
187- Library. A suitable mechanism is one that (a) uses at run time
188- a copy of the Library already present on the user's computer
189- system, and (b) will operate properly with a modified version
190- of the Library that is interface-compatible with the Linked
191- Version.
192-
193- e) Provide Installation Information, but only if you would otherwise
194- be required to provide such information under section 6 of the
195- GNU GPL, and only to the extent that such information is
196- necessary to install and execute a modified version of the
197- Combined Work produced by recombining or relinking the
198- Application with a modified version of the Linked Version. (If
199- you use option 4d0, the Installation Information must accompany
200- the Minimal Corresponding Source and Corresponding Application
201- Code. If you use option 4d1, you must provide the Installation
202- Information in the manner specified by section 6 of the GNU GPL
203- for conveying Corresponding Source.)
204-
205- 5. Combined Libraries.
206-
207- You may place library facilities that are a work based on the
208-Library side by side in a single library together with other library
209-facilities that are not Applications and are not covered by this
210-License, and convey such a combined library under terms of your
211-choice, if you do both of the following:
212-
213- a) Accompany the combined library with a copy of the same work based
214- on the Library, uncombined with any other library facilities,
215- conveyed under the terms of this License.
216-
217- b) Give prominent notice with the combined library that part of it
218- is a work based on the Library, and explaining where to find the
219- accompanying uncombined form of the same work.
220-
221- 6. Revised Versions of the GNU Lesser General Public License.
222-
223- The Free Software Foundation may publish revised and/or new versions
224-of the GNU Lesser General Public License from time to time. Such new
225-versions will be similar in spirit to the present version, but may
226-differ in detail to address new problems or concerns.
227-
228- Each version is given a distinguishing version number. If the
229-Library as you received it specifies that a certain numbered version
230-of the GNU Lesser General Public License "or any later version"
231-applies to it, you have the option of following the terms and
232-conditions either of that published version or of any later version
233-published by the Free Software Foundation. If the Library as you
234-received it does not specify a version number of the GNU Lesser
235-General Public License, you may choose any version of the GNU Lesser
236-General Public License ever published by the Free Software Foundation.
237-
238- If the Library as you received it specifies that a proxy can decide
239-whether future versions of the GNU Lesser General Public License shall
240-apply, that proxy's public statement of acceptance of any version is
241-permanent authorization for you to choose that version for the
242-Library.
243
244=== removed file 'qml.v0/README.md'
245--- qml.v0/README.md 2014-08-26 19:38:51 +0000
246+++ qml.v0/README.md 1970-01-01 00:00:00 +0000
247@@ -1,151 +0,0 @@
248-# QML support for the Go language
249-
250-This is an ALPHA release
251-------------------------
252-
253-This package is in an alpha stage, and still in heavy development. APIs
254-may change, and things may break.
255-
256-At this time contributors and developers that are interested in tracking
257-the development closely are encouraged to use it. If you'd prefer a more
258-stable release, please hold on a bit and subscribe to the mailing list
259-for news. It's in a pretty good state, so it shall not take too long.
260-
261-
262-Demos
263------
264-
265-These introductory videos demonstrate the use of Go QML:
266-
267- * [Initial demo and overview](http://youtu.be/FVQlMrPa7lI)
268- * [Initial demo running on an Ubuntu Touch phone](http://youtu.be/HB-3o8Cysec)
269- * [Spinning Gopher with Go + QML + OpenGL](http://youtu.be/qkH7_dtOyPk)
270- * [SameGame QML tutorial in Go](http://youtu.be/z8noX48hiMI)
271-
272-
273-Community
274----------
275-
276-Please join the [mailing list](https://groups.google.com/forum/#!forum/go-qml) for
277-following relevant development news and discussing project details.
278-
279-
280-Documentation
281--------------
282-
283-The introductory documentation as well as the detailed API documentation is
284-available at [gopkg.in/qml.v0](http://godoc.org/gopkg.in/qml.v0).
285-
286-
287-Installation
288-------------
289-
290-To try the alpha release you'll need:
291-
292- * Go 1.2, for the C++ support of _go build_
293- * Qt 5.0.X or 5.1.X with the development files
294- * The Qt headers qmetaobject_p.h and qmetaobjectbuilder_p.h, for the dynamic meta object support
295-
296-See below for more details about getting these requirements installed in different environments and operating systems.
297-
298-After the requirements are satisfied, _go get_ should work as usual:
299-
300- go get gopkg.in/qml.v0
301-
302-
303-Requirements on Ubuntu
304-----------------------
305-
306-If you are using Ubuntu, the [Ubuntu SDK](http://developer.ubuntu.com/get-started/) will take care of the Qt dependencies:
307-
308- $ sudo add-apt-repository ppa:ubuntu-sdk-team/ppa
309- $ sudo apt-get update
310- $ sudo apt-get install ubuntu-sdk qtbase5-private-dev qtdeclarative5-private-dev libqt5opengl5-dev
311-
312-and Go 1.2 may be installed using [godeb](http://blog.labix.org/2013/06/15/in-flight-deb-packages-of-go):
313-
314- $ # Pick the right one for your system: 386 or amd64
315- $ ARCH=amd64
316- $ wget -q https://godeb.s3.amazonaws.com/godeb-$ARCH.tar.gz
317- $ tar xzvf godeb-$ARCH.tar.gz
318- godeb
319- $ sudo mv godeb /usr/local/bin
320- $ godeb install 1.2
321- $ go get gopkg.in/qml.v0
322-
323-
324-Requirements on Ubuntu Touch
325-----------------------------
326-
327-After following the [installation instructions](https://wiki.ubuntu.com/Touch/Install) for Ubuntu Touch,
328-run the following commands to get a working build environment inside the device:
329-
330- $ adb shell
331- # cd /tmp
332- # wget https://github.com/go-qml/qml/raw/master/cmd/ubuntu-touch/setup.sh
333- # /bin/bash setup.sh
334- # su - phablet
335- $
336-
337-At the end of setup.sh, the phablet user will have GOPATH=$HOME in the environment,
338-the qml package will be built, and the particle example will be built and run. For
339-stopping it from the command line, run as the phablet user:
340-
341- $ upstart-app-stop gopkg.in.qml.particle-example
342-
343-for running it again:
344-
345- $ upstart-app-launch gopkg.in.qml.particle-example
346-
347-These commands depend on the following file, installed by setup.sh:
348-
349- ~/.local/share/applications/gopkg.in.qml.particle-example.desktop
350-
351-
352-Requirements on Mac OS X
353-------------------------
354-
355-On Mac OS X you'll need gcc (not a symlinked clang, as it complains about `-std=c++11`), and
356-must specify the `CXX`, `PKG_CONFIG_PATH`, and `CGO_CPPFLAGS` environment variables.
357-
358-Something along these lines should be effective:
359-
360- $ brew tap homebrew/versions
361- $ brew install gcc48 qt5
362-
363- $ export PKG_CONFIG_PATH=`brew --prefix qt5`/lib/pkgconfig
364- $ CXX=g++-4.8 go get gopkg.in/qml.v0
365-
366-For Mac OS X Mavericks you may need to use `brew install qt5 --HEAD` and check that QT5VERSION
367-is something reasonable like `5.2.0`, `ls /usr/local/Cellar/qt5/HEAD/include/QtCore/ | grep '^5'`
368-should also work.
369-
370-Requirements on Windows
371------------------------
372-
373-On Windows you'll need the following:
374-
375- * [MinGW gcc](http://sourceforge.net/projects/mingw/files/latest/download) 4.8.1 (install mingw-get and install the gcc from within the setup GUI)
376- * [Qt 5.1.1](http://download.qt-project.org/official_releases/qt/5.1/5.1.1/qt-windows-opensource-5.1.1-mingw48_opengl-x86-offline.exe) for MinGW 4.8
377- * [Go 1.2rc1](https://code.google.com/p/go/downloads/list?can=1&q=go1.2rc1) for Windows
378-
379-Then, assuming Qt was installed under `C:\Qt5.1.1\`, set up the following environment variables in the respective configuration:
380-
381- CPATH += C:\Qt5.1.1\5.1.1\mingw48_32\include
382- LIBRARY_PATH += C:\Qt5.1.1\5.1.1\mingw48_32\lib
383- PATH += C:\Qt5.1.1\5.1.1\mingw48_32\bin
384-
385-After reopening the shell for the environment changes to take effect, this should work:
386-
387- go get gopkg.in/qml.v0
388-
389-
390-Requirements everywhere else
391-----------------------------
392-
393-If your operating system does not offer these dependencies readily,
394-you may still have success installing [Go 1.2rc1](https://code.google.com/p/go/downloads/list?can=1&q=go1.2rc1)
395-and [Qt 5.0.2](http://download.qt-project.org/archive/qt/5.0/5.0.2/)
396-directly from the upstreams. Note that you'll likely have to adapt
397-environment variables to reflect the custom installation path for
398-these libraries. See the instructions above for examples.
399
400=== removed file 'qml.v0/all.cpp'
401--- qml.v0/all.cpp 2014-08-26 19:38:51 +0000
402+++ qml.v0/all.cpp 1970-01-01 00:00:00 +0000
403@@ -1,8 +0,0 @@
404-
405-#include "cpp/capi.cpp"
406-#include "cpp/govalue.cpp"
407-#include "cpp/govaluetype.cpp"
408-#include "cpp/idletimer.cpp"
409-#include "cpp/connector.cpp"
410-
411-#include "cpp/moc_all.cpp"
412
413=== removed file 'qml.v0/bridge.go'
414--- qml.v0/bridge.go 2014-08-26 19:38:51 +0000
415+++ qml.v0/bridge.go 1970-01-01 00:00:00 +0000
416@@ -1,632 +0,0 @@
417-package qml
418-
419-// #cgo CPPFLAGS: -I./cpp
420-// #cgo CXXFLAGS: -std=c++0x -pedantic-errors -Wall -fno-strict-aliasing
421-// #cgo LDFLAGS: -lstdc++
422-// #cgo pkg-config: Qt5Core Qt5Widgets Qt5Quick
423-//
424-// #include <stdlib.h>
425-//
426-// #include "cpp/capi.h"
427-//
428-import "C"
429-
430-import (
431- "fmt"
432- "os"
433- "reflect"
434- "runtime"
435- "sync"
436- "sync/atomic"
437- "unsafe"
438-
439- "launchpad.net/ciborium/qml.v0/tref"
440-)
441-
442-var hookWaiting C.int
443-
444-// guiLoop runs the main GUI thread event loop in C++ land.
445-func guiLoop() {
446- // This is not an option in Init to avoid forcing people to patch
447- // and recompile an application just so it runs on Ubuntu Touch.
448- deskfile := os.Getenv("DESKTOP_FILE_HINT")
449- cdeskfile := (*C.char)(nil)
450- if deskfile != "" {
451- os.Setenv("DESKTOP_FILE_HINT", "")
452- cdeskfile = C.CString("--desktop_file_hint=" + deskfile)
453- }
454-
455- runtime.LockOSThread()
456- guiLoopRef = tref.Ref()
457- C.newGuiApplication(cdeskfile)
458- C.idleTimerInit(&hookWaiting)
459- guiLoopReady.Unlock()
460- C.applicationExec()
461-}
462-
463-var (
464- guiFunc = make(chan func())
465- guiDone = make(chan struct{})
466- guiLock = 0
467- guiLoopReady sync.Mutex
468- guiLoopRef uintptr
469- guiPaintRef uintptr
470-)
471-
472-// RunMain runs f in the main QML thread and waits for f to return.
473-//
474-// This is meant for extensions that integrate directly with the
475-// underlying QML logic.
476-func RunMain(f func()) {
477- ref := tref.Ref()
478- if ref == guiLoopRef || ref == atomic.LoadUintptr(&guiPaintRef) {
479- // Already within the GUI or render threads. Attempting to wait would deadlock.
480- f()
481- return
482- }
483-
484- // Tell Qt we're waiting for the idle hook to be called.
485- if atomic.AddInt32((*int32)(unsafe.Pointer(&hookWaiting)), 1) == 1 {
486- C.idleTimerStart()
487- }
488-
489- // Send f to be executed by the idle hook in the main GUI thread.
490- guiFunc <- f
491-
492- // Wait until f is done executing.
493- <-guiDone
494-}
495-
496-// Lock freezes all QML activity by blocking the main event loop.
497-// Locking is necessary before updating shared data structures
498-// without race conditions.
499-//
500-// It's safe to use qml functionality while holding a lock, as
501-// long as the requests made do not depend on follow up QML
502-// events to be processed before returning. If that happens, the
503-// problem will be observed as the application freezing.
504-//
505-// The Lock function is reentrant. That means it may be called
506-// multiple times, and QML activities will only be resumed after
507-// Unlock is called a matching number of times.
508-func Lock() {
509- // TODO Better testing for this.
510- RunMain(func() {
511- guiLock++
512- })
513-}
514-
515-// Unlock releases the QML event loop. See Lock for details.
516-func Unlock() {
517- RunMain(func() {
518- if guiLock == 0 {
519- panic("qml.Unlock called without lock being held")
520- }
521- guiLock--
522- })
523-}
524-
525-// Flush synchronously flushes all pending QML activities.
526-func Flush() {
527- // TODO Better testing for this.
528- RunMain(func() {
529- C.applicationFlushAll()
530- })
531-}
532-
533-// Changed notifies all QML bindings that the given field value has changed.
534-//
535-// For example:
536-//
537-// qml.Changed(&value, &value.Field)
538-//
539-func Changed(value, fieldAddr interface{}) {
540- valuev := reflect.ValueOf(value)
541- fieldv := reflect.ValueOf(fieldAddr)
542- for valuev.Kind() == reflect.Ptr {
543- valuev = valuev.Elem()
544- }
545- if fieldv.Kind() != reflect.Ptr {
546- panic("qml.Changed received non-address value as fieldAddr")
547- }
548- fieldv = fieldv.Elem()
549- if fieldv.Type().Size() == 0 {
550- panic("cannot report changes on zero-sized fields")
551- }
552- offset := fieldv.UnsafeAddr() - valuev.UnsafeAddr()
553- if !(0 <= offset && offset < valuev.Type().Size()) {
554- panic("provided field is not a member of the given value")
555- }
556-
557- RunMain(func() {
558- tinfo := typeInfo(value)
559- for _, engine := range engines {
560- fold := engine.values[value]
561- for fold != nil {
562- C.goValueActivate(fold.cvalue, tinfo, C.int(offset))
563- fold = fold.next
564- }
565- // TODO typeNew might also be a linked list keyed by the gvalue.
566- // This would prevent the iteration and the deferrals.
567- for fold, _ = range typeNew {
568- if fold.gvalue == value {
569- // Activate these later so they don't get recursively moved
570- // out of typeNew while the iteration is still happening.
571- defer C.goValueActivate(fold.cvalue, tinfo, C.int(offset))
572- }
573- }
574- }
575- })
576-}
577-
578-// hookIdleTimer is run once per iteration of the Qt event loop,
579-// within the main GUI thread, but only if at least one goroutine
580-// has atomically incremented hookWaiting.
581-//
582-//export hookIdleTimer
583-func hookIdleTimer() {
584- var f func()
585- for {
586- select {
587- case f = <-guiFunc:
588- default:
589- if guiLock > 0 {
590- f = <-guiFunc
591- } else {
592- return
593- }
594- }
595- f()
596- guiDone <- struct{}{}
597- atomic.AddInt32((*int32)(unsafe.Pointer(&hookWaiting)), -1)
598- }
599-}
600-
601-type valueFold struct {
602- engine *Engine
603- gvalue interface{}
604- cvalue unsafe.Pointer
605- init reflect.Value
606- prev *valueFold
607- next *valueFold
608- owner valueOwner
609-}
610-
611-type valueOwner uint8
612-
613-const (
614- cppOwner = 1 << iota
615- jsOwner
616-)
617-
618-// wrapGoValue creates a new GoValue object in C++ land wrapping
619-// the Go value contained in the given interface.
620-//
621-// This must be run from the main GUI thread.
622-func wrapGoValue(engine *Engine, gvalue interface{}, owner valueOwner) (cvalue unsafe.Pointer) {
623- gvaluev := reflect.ValueOf(gvalue)
624- gvaluek := gvaluev.Kind()
625- if gvaluek == reflect.Struct && !hashable(gvalue) {
626- name := gvaluev.Type().Name()
627- if name != "" {
628- name = " (" + name + ")"
629- }
630- panic("cannot hand an unhashable struct value" + name + " to QML logic; use its address instead")
631- }
632- if gvaluek == reflect.Ptr && gvaluev.Elem().Kind() == reflect.Ptr {
633- panic("cannot hand pointer of pointer to QML logic; use a simple pointer instead")
634- }
635-
636- painting := tref.Ref() == atomic.LoadUintptr(&guiPaintRef)
637-
638- prev, ok := engine.values[gvalue]
639- if ok && (prev.owner == owner || owner != cppOwner || painting) {
640- return prev.cvalue
641- }
642-
643- if painting {
644- panic("cannot allocate new objects while painting")
645- }
646-
647- parent := nilPtr
648- if owner == cppOwner {
649- parent = engine.addr
650- }
651- fold := &valueFold{
652- engine: engine,
653- gvalue: gvalue,
654- owner: owner,
655- }
656- fold.cvalue = C.newGoValue(unsafe.Pointer(fold), typeInfo(gvalue), parent)
657- if prev != nil {
658- prev.next = fold
659- fold.prev = prev
660- } else {
661- engine.values[gvalue] = fold
662- }
663- //fmt.Printf("[DEBUG] value alive (wrapped): cvalue=%x gvalue=%x/%#v\n", fold.cvalue, addrOf(fold.gvalue), fold.gvalue)
664- stats.valuesAlive(+1)
665- C.engineSetContextForObject(engine.addr, fold.cvalue)
666- switch owner {
667- case cppOwner:
668- C.engineSetOwnershipCPP(engine.addr, fold.cvalue)
669- case jsOwner:
670- C.engineSetOwnershipJS(engine.addr, fold.cvalue)
671- }
672- return fold.cvalue
673-}
674-
675-func addrOf(gvalue interface{}) uintptr {
676- return reflect.ValueOf(gvalue).Pointer()
677-}
678-
679-// typeNew holds fold values that are created by registered types.
680-// These values are special in two senses: first, they don't have a
681-// reference to an engine before they are used in a context that can
682-// set the reference; second, these values always hold a new cvalue,
683-// because they are created as a side-effect of the registered type
684-// being instantiated (it's too late to reuse an existent cvalue).
685-//
686-// For these reasons, typeNew holds the fold for these values until
687-// their engine is known, and once it's known they may have to be
688-// added to the linked list, since mulitple references for the same
689-// gvalue may occur.
690-var typeNew = make(map[*valueFold]bool)
691-
692-//export hookGoValueTypeNew
693-func hookGoValueTypeNew(cvalue unsafe.Pointer, specp unsafe.Pointer) (foldp unsafe.Pointer) {
694- // Initialization is postponed until the engine is available, so that
695- // we can hand Init the qml.Object that represents the object.
696- init := reflect.ValueOf((*TypeSpec)(specp).Init)
697- fold := &valueFold{
698- init: init,
699- gvalue: reflect.New(init.Type().In(0).Elem()).Interface(),
700- cvalue: cvalue,
701- owner: jsOwner,
702- }
703- typeNew[fold] = true
704- //fmt.Printf("[DEBUG] value alive (type-created): cvalue=%x gvalue=%x/%#v\n", fold.cvalue, addrOf(fold.gvalue), fold.gvalue)
705- stats.valuesAlive(+1)
706- return unsafe.Pointer(fold)
707-}
708-
709-//export hookGoValueDestroyed
710-func hookGoValueDestroyed(enginep unsafe.Pointer, foldp unsafe.Pointer) {
711- fold := (*valueFold)(foldp)
712- engine := fold.engine
713- if engine == nil {
714- before := len(typeNew)
715- delete(typeNew, fold)
716- if len(typeNew) == before {
717- panic("destroying value without an associated engine; who created the value?")
718- }
719- } else if engines[engine.addr] == nil {
720- // Must never do that. The engine holds memory references that C++ depends on.
721- panic(fmt.Sprintf("engine %p was released from global list while its values were still alive", engine.addr))
722- } else {
723- switch {
724- case fold.prev != nil:
725- fold.prev.next = fold.next
726- if fold.next != nil {
727- fold.next.prev = fold.prev
728- }
729- case fold.next != nil:
730- fold.next.prev = fold.prev
731- if fold.prev != nil {
732- fold.prev.next = fold.next
733- } else {
734- fold.engine.values[fold.gvalue] = fold.next
735- }
736- default:
737- before := len(engine.values)
738- delete(engine.values, fold.gvalue)
739- if len(engine.values) == before {
740- panic("destroying value that knows about the engine, but the engine doesn't know about the value; who cleared the engine?")
741- }
742- if engine.destroyed && len(engine.values) == 0 {
743- delete(engines, engine.addr)
744- }
745- }
746- }
747- //fmt.Printf("[DEBUG] value destroyed: cvalue=%x gvalue=%x/%#v\n", fold.cvalue, addrOf(fold.gvalue), fold.gvalue)
748- stats.valuesAlive(-1)
749-}
750-
751-func deref(value reflect.Value) reflect.Value {
752- for {
753- switch value.Kind() {
754- case reflect.Ptr, reflect.Interface:
755- value = value.Elem()
756- continue
757- }
758- return value
759- }
760- panic("cannot happen")
761-}
762-
763-//export hookGoValueReadField
764-func hookGoValueReadField(enginep, foldp unsafe.Pointer, reflectIndex, getIndex, setIndex C.int, resultdv *C.DataValue) {
765- fold := ensureEngine(enginep, foldp)
766-
767- var field reflect.Value
768- if getIndex >= 0 {
769- field = reflect.ValueOf(fold.gvalue).Method(int(getIndex)).Call(nil)[0]
770- } else {
771- field = deref(reflect.ValueOf(fold.gvalue)).Field(int(reflectIndex))
772- }
773- field = deref(field)
774-
775- // Cannot compare Type directly as field may be invalid (nil).
776- if field.Kind() == reflect.Slice && field.Type() == typeObjSlice {
777- // TODO Handle getters that return []qml.Object.
778- // TODO Handle other GoValue slices (!= []qml.Object).
779- resultdv.dataType = C.DTListProperty
780- *(*unsafe.Pointer)(unsafe.Pointer(&resultdv.data)) = C.newListProperty(foldp, C.intptr_t(reflectIndex), C.intptr_t(setIndex))
781- return
782- }
783-
784- fieldk := field.Kind()
785- if fieldk == reflect.Slice || fieldk == reflect.Struct && field.Type() != typeRGBA {
786- if field.CanAddr() {
787- field = field.Addr()
788- } else if !hashable(field.Interface()) {
789- t := reflect.ValueOf(fold.gvalue).Type()
790- for t.Kind() == reflect.Ptr {
791- t = t.Elem()
792- }
793- panic(fmt.Sprintf("cannot access unaddressable and unhashable struct value on interface field %s.%s; value: %#v", t.Name(), t.Field(int(reflectIndex)).Name, field.Interface()))
794- }
795- }
796- var gvalue interface{}
797- if field.IsValid() {
798- gvalue = field.Interface()
799- }
800-
801- // TODO Strings are being passed in an unsafe manner here. There is a
802- // small chance that the field is changed and the garbage collector is run
803- // before C++ has a chance to look at the data. We can solve this problem
804- // by queuing up values in a stack, and cleaning the stack when the
805- // idle timer fires next.
806- packDataValue(gvalue, resultdv, fold.engine, jsOwner)
807-}
808-
809-//export hookGoValueWriteField
810-func hookGoValueWriteField(enginep, foldp unsafe.Pointer, reflectIndex, setIndex C.int, assigndv *C.DataValue) {
811- fold := ensureEngine(enginep, foldp)
812- v := reflect.ValueOf(fold.gvalue)
813- ve := v
814- for ve.Type().Kind() == reflect.Ptr {
815- ve = ve.Elem()
816- }
817- var field, setMethod reflect.Value
818- if reflectIndex >= 0 {
819- // It's a real field rather than a getter.
820- field = ve.Field(int(reflectIndex))
821- }
822- if setIndex >= 0 {
823- // It has a setter.
824- setMethod = v.Method(int(setIndex))
825- }
826-
827- assign := unpackDataValue(assigndv, fold.engine)
828-
829- // TODO Return false to the call site if it fails. That's how Qt seems to handle it internally.
830- err := convertAndSet(field, reflect.ValueOf(assign), setMethod)
831- if err != nil {
832- panic(err.Error())
833- }
834-}
835-
836-func convertAndSet(to, from reflect.Value, setMethod reflect.Value) (err error) {
837- var toType reflect.Type
838- if setMethod.IsValid() {
839- toType = setMethod.Type().In(0)
840- } else {
841- toType = to.Type()
842- }
843- fromType := from.Type()
844- defer func() {
845- if v := recover(); v != nil {
846- err = fmt.Errorf("cannot use %s as a %s", fromType, toType)
847- }
848- }()
849- if fromType == typeList && toType.Kind() == reflect.Slice {
850- list := from.Interface().(*List)
851- from = reflect.MakeSlice(toType, len(list.data), len(list.data))
852- elemType := toType.Elem()
853- for i, elem := range list.data {
854- from.Index(i).Set(reflect.ValueOf(elem).Convert(elemType))
855- }
856- } else if fromType == typeMap && toType.Kind() == reflect.Map {
857- qmap := from.Interface().(*Map)
858- from = reflect.MakeMap(toType)
859- elemType := toType.Elem()
860- for i := 0; i < len(qmap.data); i += 2 {
861- key := reflect.ValueOf(qmap.data[i])
862- val := reflect.ValueOf(qmap.data[i+1])
863- if val.Type() != elemType {
864- val = val.Convert(elemType)
865- }
866- from.SetMapIndex(key, val)
867- }
868- } else if toType != fromType {
869- from = from.Convert(toType)
870- }
871- if setMethod.IsValid() {
872- setMethod.Call([]reflect.Value{from})
873- } else {
874- to.Set(from)
875- }
876- return nil
877-}
878-
879-var (
880- dataValueSize = uintptr(unsafe.Sizeof(C.DataValue{}))
881- dataValueArray [C.MaxParams]C.DataValue
882-)
883-
884-//export hookGoValueCallMethod
885-func hookGoValueCallMethod(enginep, foldp unsafe.Pointer, reflectIndex C.int, args *C.DataValue) {
886- fold := ensureEngine(enginep, foldp)
887- v := reflect.ValueOf(fold.gvalue)
888-
889- // TODO Must assert that v is necessarily a pointer here, but we shouldn't have to manipulate
890- // gvalue here for that. This should happen in a sensible place in the wrapping functions
891- // that can still error out to the user in due time.
892-
893- method := v.Method(int(reflectIndex))
894- methodt := method.Type()
895- methodName := v.Type().Method(int(reflectIndex)).Name
896-
897- // TODO Ensure methods with more parameters than this are not registered.
898- var params [C.MaxParams]reflect.Value
899- var err error
900-
901- numIn := methodt.NumIn()
902- for i := 0; i < numIn; i++ {
903- paramdv := (*C.DataValue)(unsafe.Pointer(uintptr(unsafe.Pointer(args)) + (uintptr(i)+1)*dataValueSize))
904- param := reflect.ValueOf(unpackDataValue(paramdv, fold.engine))
905- if argt := methodt.In(i); param.Type() != argt {
906- param, err = convertParam(methodName, i, param, argt)
907- if err != nil {
908- panic(err.Error())
909- }
910- }
911- params[i] = param
912- }
913-
914- result := method.Call(params[:numIn])
915-
916- if len(result) == 1 {
917- packDataValue(result[0].Interface(), args, fold.engine, jsOwner)
918- } else if len(result) > 1 {
919- if len(result) > len(dataValueArray) {
920- panic("function has too many results")
921- }
922- for i, v := range result {
923- packDataValue(v.Interface(), &dataValueArray[i], fold.engine, jsOwner)
924- }
925- args.dataType = C.DTVariantList
926- *(*unsafe.Pointer)(unsafe.Pointer(&args.data)) = C.newVariantList(&dataValueArray[0], C.int(len(result)))
927- }
928-}
929-
930-func convertParam(methodName string, index int, param reflect.Value, argt reflect.Type) (reflect.Value, error) {
931- out := reflect.New(argt).Elem()
932- err := convertAndSet(out, param, reflect.Value{})
933- if err != nil {
934- err = fmt.Errorf("cannot convert parameter %d of method %s from %s to %s; provided value: %#v",
935- index, methodName, param.Type(), argt, param.Interface())
936- return reflect.Value{}, err
937- }
938- return out, nil
939-}
940-
941-//export hookGoValuePaint
942-func hookGoValuePaint(enginep, foldp unsafe.Pointer, reflectIndex C.intptr_t) {
943- // The main GUI thread is mutex-locked while paint methods are called,
944- // so no two paintings should be happening at the same time.
945- atomic.StoreUintptr(&guiPaintRef, tref.Ref())
946-
947- fold := ensureEngine(enginep, foldp)
948- v := reflect.ValueOf(fold.gvalue)
949-
950- painter := &Painter{fold.engine, &Common{fold.cvalue, fold.engine}}
951-
952- method := v.Method(int(reflectIndex))
953- method.Call([]reflect.Value{reflect.ValueOf(painter)})
954-
955- atomic.StoreUintptr(&guiPaintRef, 0)
956-}
957-
958-func ensureEngine(enginep, foldp unsafe.Pointer) *valueFold {
959- fold := (*valueFold)(foldp)
960- if fold.engine != nil {
961- return fold
962- }
963-
964- if enginep == nilPtr {
965- panic("accessing value without an engine pointer; who created the value?")
966- }
967- engine := engines[enginep]
968- if engine == nil {
969- panic("unknown engine pointer; who created the engine?")
970- }
971- fold.engine = engine
972- prev := engine.values[fold.gvalue]
973- if prev != nil {
974- for prev.next != nil {
975- prev = prev.next
976- }
977- prev.next = fold
978- fold.prev = prev
979- } else {
980- engine.values[fold.gvalue] = fold
981- }
982- before := len(typeNew)
983- delete(typeNew, fold)
984- if len(typeNew) == before {
985- panic("value had no engine, but was not created by a registered type; who created the value?")
986- }
987-
988- // TODO Would be good to preserve identity on the Go side. See unpackDataValue as well.
989- obj := &Common{engine: fold.engine, addr: fold.cvalue}
990- fold.init.Call([]reflect.Value{reflect.ValueOf(fold.gvalue), reflect.ValueOf(obj)})
991-
992- return fold
993-}
994-
995-//export hookPanic
996-func hookPanic(message *C.char) {
997- defer C.free(unsafe.Pointer(message))
998- panic(C.GoString(message))
999-}
1000-
1001-func listSlice(fold *valueFold, reflectIndex C.intptr_t) *[]Object {
1002- field := deref(reflect.ValueOf(fold.gvalue)).Field(int(reflectIndex))
1003- return field.Addr().Interface().(*[]Object)
1004-}
1005-
1006-//export hookListPropertyAt
1007-func hookListPropertyAt(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t, index C.int) (objp unsafe.Pointer) {
1008- fold := (*valueFold)(foldp)
1009- slice := listSlice(fold, reflectIndex)
1010- return (*slice)[int(index)].Common().addr
1011-}
1012-
1013-//export hookListPropertyCount
1014-func hookListPropertyCount(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t) C.int {
1015- fold := (*valueFold)(foldp)
1016- slice := listSlice(fold, reflectIndex)
1017- return C.int(len(*slice))
1018-}
1019-
1020-//export hookListPropertyAppend
1021-func hookListPropertyAppend(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t, objp unsafe.Pointer) {
1022- fold := (*valueFold)(foldp)
1023- slice := listSlice(fold, reflectIndex)
1024- var objdv C.DataValue
1025- objdv.dataType = C.DTObject
1026- *(*unsafe.Pointer)(unsafe.Pointer(&objdv.data)) = objp
1027- newslice := append(*slice, unpackDataValue(&objdv, fold.engine).(Object))
1028- if setIndex >= 0 {
1029- reflect.ValueOf(fold.gvalue).Method(int(setIndex)).Call([]reflect.Value{reflect.ValueOf(newslice)})
1030- } else {
1031- *slice = newslice
1032- }
1033-}
1034-
1035-//export hookListPropertyClear
1036-func hookListPropertyClear(foldp unsafe.Pointer, reflectIndex, setIndex C.intptr_t) {
1037- fold := (*valueFold)(foldp)
1038- slice := listSlice(fold, reflectIndex)
1039- newslice := (*slice)[0:0]
1040- if setIndex >= 0 {
1041- reflect.ValueOf(fold.gvalue).Method(int(setIndex)).Call([]reflect.Value{reflect.ValueOf(newslice)})
1042- } else {
1043- for i := range *slice {
1044- (*slice)[i] = nil
1045- }
1046- *slice = newslice
1047- }
1048-}
1049
1050=== removed directory 'qml.v0/cpp'
1051=== removed file 'qml.v0/cpp/capi.cpp'
1052--- qml.v0/cpp/capi.cpp 2015-02-09 10:57:11 +0000
1053+++ qml.v0/cpp/capi.cpp 1970-01-01 00:00:00 +0000
1054@@ -1,849 +0,0 @@
1055-#include <QApplication>
1056-#include <QQuickView>
1057-#include <QQuickItem>
1058-#include <QtQml>
1059-#include <QDebug>
1060-#include <QQuickImageProvider>
1061-
1062-#include <string.h>
1063-
1064-#include "govalue.h"
1065-#include "govaluetype.h"
1066-#include "connector.h"
1067-#include "capi.h"
1068-
1069-static char *local_strdup(const char *str)
1070-{
1071- char *strcopy = 0;
1072- if (str) {
1073- size_t len = strlen(str) + 1;
1074- strcopy = (char *)malloc(len);
1075- memcpy(strcopy, str, len);
1076- }
1077- return strcopy;
1078-}
1079-
1080-error *errorf(const char *format, ...)
1081-{
1082- va_list ap;
1083- va_start(ap, format);
1084- QString str = QString().vsprintf(format, ap);
1085- va_end(ap);
1086- QByteArray ba = str.toUtf8();
1087- return local_strdup(ba.constData());
1088-}
1089-
1090-void panicf(const char *format, ...)
1091-{
1092- va_list ap;
1093- va_start(ap, format);
1094- QString str = QString().vsprintf(format, ap);
1095- va_end(ap);
1096- QByteArray ba = str.toUtf8();
1097- hookPanic(local_strdup(ba.constData()));
1098-}
1099-
1100-void newGuiApplication(char *deskfile)
1101-{
1102- static char empty[1] = {0};
1103- static char *argv[] = {empty, empty, empty};
1104- static int argc = 1;
1105- if (deskfile) {
1106- argv[argc] = deskfile;
1107- argc++;
1108- }
1109- new QApplication(argc, argv);
1110-
1111- // The event should never die.
1112- qApp->setQuitOnLastWindowClosed(false);
1113-}
1114-
1115-void applicationExec()
1116-{
1117- qApp->exec();
1118-}
1119-
1120-void applicationFlushAll()
1121-{
1122- qApp->processEvents();
1123-}
1124-
1125-void *currentThread()
1126-{
1127- return QThread::currentThread();
1128-}
1129-
1130-void *appThread()
1131-{
1132- return QCoreApplication::instance()->thread();
1133-}
1134-
1135-QQmlEngine_ *newEngine(QObject_ *parent)
1136-{
1137- return new QQmlEngine(reinterpret_cast<QObject *>(parent));
1138-}
1139-
1140-QQmlContext_ *engineRootContext(QQmlEngine_ *engine)
1141-{
1142- return reinterpret_cast<QQmlEngine *>(engine)->rootContext();
1143-}
1144-
1145-void engineSetContextForObject(QQmlEngine_ *engine, QObject_ *object)
1146-{
1147- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
1148- QObject *qobject = reinterpret_cast<QObject *>(object);
1149-
1150- QQmlEngine::setContextForObject(qobject, qengine->rootContext());
1151-}
1152-
1153-void engineSetOwnershipCPP(QQmlEngine_ *engine, QObject_ *object)
1154-{
1155- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
1156- QObject *qobject = reinterpret_cast<QObject *>(object);
1157-
1158- qengine->setObjectOwnership(qobject, QQmlEngine::CppOwnership);
1159-}
1160-
1161-void engineSetOwnershipJS(QQmlEngine_ *engine, QObject_ *object)
1162-{
1163- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
1164- QObject *qobject = reinterpret_cast<QObject *>(object);
1165-
1166- qengine->setObjectOwnership(qobject, QQmlEngine::JavaScriptOwnership);
1167-}
1168-
1169-QQmlComponent_ *newComponent(QQmlEngine_ *engine, QObject_ *parent)
1170-{
1171- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
1172- //QObject *qparent = reinterpret_cast<QObject *>(parent);
1173- QQmlComponent *qcomponent = new QQmlComponent(qengine);
1174- // Qt 5.2.0 returns NULL on qmlEngine(qcomponent) without this.
1175- QQmlEngine::setContextForObject(qcomponent, qengine->rootContext());
1176- return qcomponent;
1177-}
1178-
1179-class GoImageProvider : public QQuickImageProvider {
1180-
1181- // TODO Destroy this when engine is destroyed.
1182-
1183- public:
1184-
1185- GoImageProvider(void *imageFunc) : QQuickImageProvider(QQmlImageProviderBase::Image), imageFunc(imageFunc) {};
1186-
1187- virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
1188- {
1189- QByteArray ba = id.toUtf8();
1190- int width = 0, height = 0;
1191- if (requestedSize.isValid()) {
1192- width = requestedSize.width();
1193- height = requestedSize.height();
1194- }
1195- QImage *image = reinterpret_cast<QImage *>(hookRequestImage(imageFunc, (char*)ba.constData(), ba.size(), width, height));
1196- *size = image->size();
1197- if (requestedSize.isValid() && requestedSize != *size) {
1198- *image = image->scaled(requestedSize, Qt::KeepAspectRatio);
1199- }
1200- return *image;
1201- };
1202-
1203- private:
1204-
1205- void *imageFunc;
1206-};
1207-
1208-void engineAddImageProvider(QQmlEngine_ *engine, QString_ *providerId, void *imageFunc)
1209-{
1210- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
1211- QString *qproviderId = reinterpret_cast<QString *>(providerId);
1212-
1213- qengine->addImageProvider(*qproviderId, new GoImageProvider(imageFunc));
1214-}
1215-
1216-void componentSetData(QQmlComponent_ *component, const char *data, int dataLen, const char *url, int urlLen)
1217-{
1218- QByteArray qdata(data, dataLen);
1219- QByteArray qurl(url, urlLen);
1220- QString qsurl = QString::fromUtf8(qurl);
1221- reinterpret_cast<QQmlComponent *>(component)->setData(qdata, qsurl);
1222-}
1223-
1224-char *componentErrorString(QQmlComponent_ *component)
1225-{
1226- QQmlComponent *qcomponent = reinterpret_cast<QQmlComponent *>(component);
1227- if (qcomponent->isReady()) {
1228- return NULL;
1229- }
1230- if (qcomponent->isError()) {
1231- QByteArray ba = qcomponent->errorString().toUtf8();
1232- return local_strdup(ba.constData());
1233- }
1234- return local_strdup("component is not ready (why!?)");
1235-}
1236-
1237-QObject_ *componentCreate(QQmlComponent_ *component, QQmlContext_ *context)
1238-{
1239- QQmlComponent *qcomponent = reinterpret_cast<QQmlComponent *>(component);
1240- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
1241-
1242- if (!qcontext) {
1243- qcontext = qmlContext(qcomponent);
1244- }
1245- return qcomponent->create(qcontext);
1246-}
1247-
1248-QQuickWindow_ *componentCreateWindow(QQmlComponent_ *component, QQmlContext_ *context)
1249-{
1250- QQmlComponent *qcomponent = reinterpret_cast<QQmlComponent *>(component);
1251- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
1252-
1253- if (!qcontext) {
1254- qcontext = qmlContext(qcomponent);
1255- }
1256- QObject *obj = qcomponent->create(qcontext);
1257- if (!objectIsWindow(obj)) {
1258- QQuickView *view = new QQuickView(qmlEngine(qcomponent), 0);
1259- view->setContent(qcomponent->url(), qcomponent, obj);
1260- view->setResizeMode(QQuickView::SizeRootObjectToView);
1261- obj = view;
1262- }
1263- return obj;
1264-}
1265-
1266-// Workaround for bug https://bugs.launchpad.net/bugs/1179716
1267-struct DoShowWindow : public QQuickWindow {
1268- void show() {
1269- QQuickWindow::show();
1270- QResizeEvent resize(size(), size());
1271- resizeEvent(&resize);
1272- }
1273-};
1274-
1275-void windowShow(QQuickWindow_ *win)
1276-{
1277- reinterpret_cast<DoShowWindow *>(win)->show();
1278-}
1279-
1280-void windowHide(QQuickWindow_ *win)
1281-{
1282- reinterpret_cast<QQuickWindow *>(win)->hide();
1283-}
1284-
1285-uintptr_t windowPlatformId(QQuickWindow_ *win)
1286-{
1287- return reinterpret_cast<QQuickWindow *>(win)->winId();
1288-}
1289-
1290-void windowConnectHidden(QQuickWindow_ *win)
1291-{
1292- QQuickWindow *qwin = reinterpret_cast<QQuickWindow *>(win);
1293- QObject::connect(qwin, &QWindow::visibleChanged, [=](bool visible){
1294- if (!visible) {
1295- hookWindowHidden(win);
1296- }
1297- });
1298-}
1299-
1300-QObject_ *windowRootObject(QQuickWindow_ *win)
1301-{
1302- if (objectIsView(win)) {
1303- return reinterpret_cast<QQuickView *>(win)->rootObject();
1304- }
1305- return win;
1306-}
1307-
1308-QImage_ *windowGrabWindow(QQuickWindow_ *win)
1309-{
1310- QQuickWindow *qwin = reinterpret_cast<QQuickWindow *>(win);
1311- QImage *image = new QImage;
1312- *image = qwin->grabWindow().convertToFormat(QImage::Format_ARGB32_Premultiplied);
1313- return image;
1314-}
1315-
1316-QImage_ *newImage(int width, int height)
1317-{
1318- return new QImage(width, height, QImage::Format_ARGB32_Premultiplied);
1319-}
1320-
1321-void delImage(QImage_ *image)
1322-{
1323- delete reinterpret_cast<QImage *>(image);
1324-}
1325-
1326-void imageSize(QImage_ *image, int *width, int *height)
1327-{
1328- QImage *qimage = reinterpret_cast<QImage *>(image);
1329- *width = qimage->width();
1330- *height = qimage->height();
1331-}
1332-
1333-unsigned char *imageBits(QImage_ *image)
1334-{
1335- QImage *qimage = reinterpret_cast<QImage *>(image);
1336- return qimage->bits();
1337-}
1338-
1339-const unsigned char *imageConstBits(QImage_ *image)
1340-{
1341- QImage *qimage = reinterpret_cast<QImage *>(image);
1342- return qimage->constBits();
1343-}
1344-
1345-void contextSetObject(QQmlContext_ *context, QObject_ *value)
1346-{
1347- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
1348- QObject *qvalue = reinterpret_cast<QObject *>(value);
1349-
1350- // Give qvalue an engine reference if it doesn't yet have one.
1351- if (!qmlEngine(qvalue)) {
1352- QQmlEngine::setContextForObject(qvalue, qcontext->engine()->rootContext());
1353- }
1354-
1355- qcontext->setContextObject(qvalue);
1356-}
1357-
1358-void contextSetProperty(QQmlContext_ *context, QString_ *name, DataValue *value)
1359-{
1360- const QString *qname = reinterpret_cast<QString *>(name);
1361- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
1362-
1363- QVariant var;
1364- unpackDataValue(value, &var);
1365-
1366- // Give qvalue an engine reference if it doesn't yet have one .
1367- QObject *obj = var.value<QObject *>();
1368- if (obj && !qmlEngine(obj)) {
1369- QQmlEngine::setContextForObject(obj, qcontext);
1370- }
1371-
1372- qcontext->setContextProperty(*qname, var);
1373-}
1374-
1375-void contextGetProperty(QQmlContext_ *context, QString_ *name, DataValue *result)
1376-{
1377- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
1378- const QString *qname = reinterpret_cast<QString *>(name);
1379-
1380- QVariant var = qcontext->contextProperty(*qname);
1381- packDataValue(&var, result);
1382-}
1383-
1384-QQmlContext_ *contextSpawn(QQmlContext_ *context)
1385-{
1386- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
1387- return new QQmlContext(qcontext);
1388-}
1389-
1390-void delObject(QObject_ *object)
1391-{
1392- delete reinterpret_cast<QObject *>(object);
1393-}
1394-
1395-void delObjectLater(QObject_ *object)
1396-{
1397- reinterpret_cast<QObject *>(object)->deleteLater();
1398-}
1399-
1400-const char *objectTypeName(QObject_ *object)
1401-{
1402- return reinterpret_cast<QObject *>(object)->metaObject()->className();
1403-}
1404-
1405-int objectGetProperty(QObject_ *object, const char *name, DataValue *result)
1406-{
1407- QObject *qobject = reinterpret_cast<QObject *>(object);
1408-
1409- QVariant var = qobject->property(name);
1410- packDataValue(&var, result);
1411-
1412- if (!var.isValid() && qobject->metaObject()->indexOfProperty(name) == -1) {
1413- // TODO May have to check the dynamic property names too.
1414- return 0;
1415- }
1416- return 1;
1417-}
1418-
1419-error *objectSetProperty(QObject_ *object, const char *name, DataValue *value)
1420-{
1421- QObject *qobject = reinterpret_cast<QObject *>(object);
1422- QVariant var;
1423- unpackDataValue(value, &var);
1424-
1425- // Give qvalue an engine reference if it doesn't yet have one.
1426- QObject *obj = var.value<QObject *>();
1427- if (obj && !qmlEngine(obj)) {
1428- QQmlContext *context = qmlContext(qobject);
1429- if (context) {
1430- QQmlEngine::setContextForObject(obj, context);
1431- }
1432- }
1433-
1434- // Check that the types are compatible. There's probably more to be done here.
1435- const QMetaObject *metaObject = qobject->metaObject();
1436- int propIndex = metaObject->indexOfProperty(name);
1437- if (propIndex == -1) {
1438- return errorf("cannot set non-existent property \"%s\" on type %s", name, qobject->metaObject()->className());
1439- }
1440-
1441- QMetaProperty prop = metaObject->property(propIndex);
1442- int propType = prop.userType();
1443- void *valueArg;
1444- if (propType == QMetaType::QVariant) {
1445- valueArg = (void *)&var;
1446- } else {
1447- int varType = var.userType();
1448- QVariant saved = var;
1449- if (propType != varType && !var.convert(propType)) {
1450- if (varType == QMetaType::QObjectStar) {
1451- return errorf("cannot set property \"%s\" with type %s to value of %s*",
1452- name, QMetaType::typeName(propType), saved.value<QObject*>()->metaObject()->className());
1453- } else {
1454- return errorf("cannot set property \"%s\" with type %s to value of %s",
1455- name, QMetaType::typeName(propType), QMetaType::typeName(varType));
1456- }
1457- }
1458- valueArg = (void *)var.constData();
1459- }
1460-
1461- int status = -1;
1462- int flags = 0;
1463- void *args[] = {valueArg, 0, &status, &flags};
1464- QMetaObject::metacall(qobject, QMetaObject::WriteProperty, propIndex, args);
1465- return 0;
1466-}
1467-
1468-error *objectInvoke(QObject_ *object, const char *method, int methodLen, DataValue *resultdv, DataValue *paramsdv, int paramsLen)
1469-{
1470- QObject *qobject = reinterpret_cast<QObject *>(object);
1471-
1472- QVariant result;
1473- QVariant param[MaxParams];
1474- QGenericArgument arg[MaxParams];
1475- for (int i = 0; i < paramsLen; i++) {
1476- unpackDataValue(&paramsdv[i], &param[i]);
1477- arg[i] = Q_ARG(QVariant, param[i]);
1478- }
1479- if (paramsLen > 10) {
1480- panicf("fix the parameter dispatching");
1481- }
1482-
1483- const QMetaObject *metaObject = qobject->metaObject();
1484- // Walk backwards so descendants have priority.
1485- for (int i = metaObject->methodCount()-1; i >= 0; i--) {
1486- QMetaMethod metaMethod = metaObject->method(i);
1487- QMetaMethod::MethodType methodType = metaMethod.methodType();
1488- if (methodType == QMetaMethod::Method || methodType == QMetaMethod::Slot) {
1489- QByteArray name = metaMethod.name();
1490- if (name.length() == methodLen && qstrncmp(name.constData(), method, methodLen) == 0) {
1491- if (metaMethod.parameterCount() < paramsLen) {
1492- // TODO Might continue looking to see if a different signal has the same name and enough arguments.
1493- return errorf("method \"%s\" has too few parameters for provided arguments", method);
1494- }
1495-
1496- bool ok;
1497- if (metaMethod.returnType() == QMetaType::Void) {
1498- ok = metaMethod.invoke(qobject, Qt::DirectConnection,
1499- arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
1500- } else {
1501- ok = metaMethod.invoke(qobject, Qt::DirectConnection, Q_RETURN_ARG(QVariant, result),
1502- arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
1503- }
1504- if (!ok) {
1505- return errorf("invalid parameters to method \"%s\"", method);
1506- }
1507-
1508- packDataValue(&result, resultdv);
1509- return 0;
1510- }
1511- }
1512- }
1513-
1514- return errorf("object does not expose a method \"%s\"", method);
1515-}
1516-
1517-void objectFindChild(QObject_ *object, QString_ *name, DataValue *resultdv)
1518-{
1519- QObject *qobject = reinterpret_cast<QObject *>(object);
1520- QString *qname = reinterpret_cast<QString *>(name);
1521-
1522- QVariant var;
1523- QObject *result = qobject->findChild<QObject *>(*qname);
1524- if (result) {
1525- var.setValue(result);
1526- }
1527- packDataValue(&var, resultdv);
1528-}
1529-
1530-void objectSetParent(QObject_ *object, QObject_ *parent)
1531-{
1532- QObject *qobject = reinterpret_cast<QObject *>(object);
1533- QObject *qparent = reinterpret_cast<QObject *>(parent);
1534-
1535- qobject->setParent(qparent);
1536-}
1537-
1538-error *objectConnect(QObject_ *object, const char *signal, int signalLen, QQmlEngine_ *engine, void *func, int argsLen)
1539-{
1540- QObject *qobject = reinterpret_cast<QObject *>(object);
1541- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
1542- QByteArray qsignal(signal, signalLen);
1543-
1544- const QMetaObject *meta = qobject->metaObject();
1545- // Walk backwards so descendants have priority.
1546- for (int i = meta->methodCount()-1; i >= 0; i--) {
1547- QMetaMethod method = meta->method(i);
1548- if (method.methodType() == QMetaMethod::Signal) {
1549- QByteArray name = method.name();
1550- if (name.length() == signalLen && qstrncmp(name.constData(), signal, signalLen) == 0) {
1551- if (method.parameterCount() < argsLen) {
1552- // TODO Might continue looking to see if a different signal has the same name and enough arguments.
1553- return errorf("signal \"%s\" has too few parameters for provided function", name.constData());
1554- }
1555- Connector *connector = new Connector(qobject, method, qengine, func, argsLen);
1556- const QMetaObject *connmeta = connector->metaObject();
1557- QObject::connect(qobject, method, connector, connmeta->method(connmeta->methodOffset()));
1558- return 0;
1559- }
1560- }
1561- }
1562- // Cannot use constData here as the byte array is not null-terminated.
1563- return errorf("object does not expose a \"%s\" signal", qsignal.data());
1564-}
1565-
1566-QQmlContext_ *objectContext(QObject_ *object)
1567-{
1568- return qmlContext(static_cast<QObject *>(object));
1569-}
1570-
1571-int objectIsComponent(QObject_ *object)
1572-{
1573- QObject *qobject = static_cast<QObject *>(object);
1574- return dynamic_cast<QQmlComponent *>(qobject) ? 1 : 0;
1575-}
1576-
1577-int objectIsWindow(QObject_ *object)
1578-{
1579- QObject *qobject = static_cast<QObject *>(object);
1580- return dynamic_cast<QQuickWindow *>(qobject) ? 1 : 0;
1581-}
1582-
1583-int objectIsView(QObject_ *object)
1584-{
1585- QObject *qobject = static_cast<QObject *>(object);
1586- return dynamic_cast<QQuickView *>(qobject) ? 1 : 0;
1587-}
1588-
1589-error *objectGoAddr(QObject_ *object, GoAddr **addr)
1590-{
1591- QObject *qobject = static_cast<QObject *>(object);
1592- GoValue *goValue = dynamic_cast<GoValue *>(qobject);
1593- if (goValue) {
1594- *addr = goValue->addr;
1595- return 0;
1596- }
1597- GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject);
1598- if (goPaintedValue) {
1599- *addr = goPaintedValue->addr;
1600- return 0;
1601- }
1602- return errorf("QML object is not backed by a Go value");
1603-}
1604-
1605-QString_ *newString(const char *data, int len)
1606-{
1607- // This will copy data only once.
1608- QByteArray ba = QByteArray::fromRawData(data, len);
1609- return new QString(ba);
1610-}
1611-
1612-void delString(QString_ *s)
1613-{
1614- delete reinterpret_cast<QString *>(s);
1615-}
1616-
1617-GoValue_ *newGoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject_ *parent)
1618-{
1619- QObject *qparent = reinterpret_cast<QObject *>(parent);
1620- if (typeInfo->paint) {
1621- return new GoPaintedValue(addr, typeInfo, qparent);
1622- }
1623- return new GoValue(addr, typeInfo, qparent);
1624-}
1625-
1626-void goValueActivate(GoValue_ *value, GoTypeInfo *typeInfo, int addrOffset)
1627-{
1628- GoMemberInfo *fieldInfo = typeInfo->fields;
1629- for (int i = 0; i < typeInfo->fieldsLen; i++) {
1630- if (fieldInfo->addrOffset == addrOffset) {
1631- if (typeInfo->paint) {
1632- static_cast<GoPaintedValue *>(value)->activate(fieldInfo->metaIndex);
1633- } else {
1634- static_cast<GoValue *>(value)->activate(fieldInfo->metaIndex);
1635- }
1636- return;
1637- }
1638- fieldInfo++;
1639- }
1640-
1641- // TODO Return an error; probably an unexported field.
1642-}
1643-
1644-void unpackDataValue(DataValue *value, QVariant_ *var)
1645-{
1646- QVariant *qvar = reinterpret_cast<QVariant *>(var);
1647- switch (value->dataType) {
1648- case DTString:
1649- *qvar = QString::fromUtf8(*(char **)value->data, value->len);
1650- break;
1651- case DTBool:
1652- *qvar = bool(*(char *)(value->data) != 0);
1653- break;
1654- case DTInt64:
1655- *qvar = *(qint64*)(value->data);
1656- break;
1657- case DTInt32:
1658- *qvar = *(qint32*)(value->data);
1659- break;
1660- case DTUint64:
1661- *qvar = *(quint64*)(value->data);
1662- break;
1663- case DTUint32:
1664- *qvar = *(quint32*)(value->data);
1665- break;
1666- case DTFloat64:
1667- *qvar = *(double*)(value->data);
1668- break;
1669- case DTFloat32:
1670- *qvar = *(float*)(value->data);
1671- break;
1672- case DTColor:
1673- *qvar = QColor::fromRgba(*(QRgb*)(value->data));
1674- break;
1675- case DTVariantList:
1676- *qvar = **(QVariantList**)(value->data);
1677- delete *(QVariantList**)(value->data);
1678- break;
1679- case DTObject:
1680- qvar->setValue(*(QObject**)(value->data));
1681- break;
1682- case DTInvalid:
1683- // null would be more natural, but an invalid variant means
1684- // it has proper semantics when dealing with non-qml qt code.
1685- //qvar->setValue(QJSValue(QJSValue::NullValue));
1686- qvar->clear();
1687- break;
1688- default:
1689- panicf("unknown data type: %d", value->dataType);
1690- break;
1691- }
1692-}
1693-
1694-void packDataValue(QVariant_ *var, DataValue *value)
1695-{
1696- QVariant *qvar = reinterpret_cast<QVariant *>(var);
1697-
1698- // Some assumptions are made below regarding the size of types.
1699- // There's apparently no better way to handle this since that's
1700- // how the types with well defined sizes (qint64) are mapped to
1701- // meta-types (QMetaType::LongLong).
1702- switch ((int)qvar->type()) {
1703- case QVariant::Invalid:
1704- value->dataType = DTInvalid;
1705- break;
1706- case QMetaType::QUrl:
1707- *qvar = qvar->value<QUrl>().toString();
1708- // fallthrough
1709- case QMetaType::QString:
1710- {
1711- value->dataType = DTString;
1712- QByteArray ba = qvar->toByteArray();
1713- *(char**)(value->data) = local_strdup(ba.constData());
1714- value->len = ba.size();
1715- break;
1716- }
1717- case QMetaType::Bool:
1718- value->dataType = DTBool;
1719- *(qint8*)(value->data) = (qint8)qvar->toInt();
1720- break;
1721- case QMetaType::LongLong:
1722- // Some of these entries will have to be fixed when handling platforms
1723- // where sizeof(long long) != 8 or sizeof(int) != 4.
1724- value->dataType = DTInt64;
1725- *(qint64*)(value->data) = qvar->toLongLong();
1726- break;
1727- case QMetaType::ULongLong:
1728- value->dataType = DTUint64;
1729- *(quint64*)(value->data) = qvar->toLongLong();
1730- break;
1731- case QMetaType::Int:
1732- value->dataType = DTInt32;
1733- *(qint32*)(value->data) = qvar->toInt();
1734- break;
1735- case QMetaType::UInt:
1736- value->dataType = DTUint32;
1737- *(quint32*)(value->data) = qvar->toUInt();
1738- break;
1739- case QMetaType::VoidStar:
1740- value->dataType = DTUintptr;
1741- *(uintptr_t*)(value->data) = (uintptr_t)qvar->value<void *>();
1742- break;
1743- case QMetaType::Double:
1744- value->dataType = DTFloat64;
1745- *(double*)(value->data) = qvar->toDouble();
1746- break;
1747- case QMetaType::Float:
1748- value->dataType = DTFloat32;
1749- *(float*)(value->data) = qvar->toFloat();
1750- break;
1751- case QMetaType::QColor:
1752- value->dataType = DTColor;
1753- *(unsigned int*)(value->data) = qvar->value<QColor>().rgba();
1754- break;
1755- case QMetaType::QVariantList:
1756- {
1757- QVariantList varlist = qvar->toList();
1758- int len = varlist.size();
1759- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
1760- for (int i = 0; i < len; i++) {
1761- packDataValue((void*)&varlist.at(i), &dvlist[i]);
1762- }
1763- value->dataType = DTValueList;
1764- value->len = len;
1765- *(DataValue**)(value->data) = dvlist;
1766- }
1767- break;
1768- case QMetaType::QVariantMap:
1769- {
1770- QVariantMap varmap = qvar->toMap();
1771- int len = varmap.size() * 2;
1772- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
1773- QMapIterator<QString, QVariant> it(varmap);
1774- for (int i = 0; i < len; i += 2) {
1775- if (!it.hasNext()) {
1776- panicf("QVariantMap mutated during iteration");
1777- }
1778- it.next();
1779- QVariant key = it.key();
1780- QVariant val = it.value();
1781- packDataValue((void*)&key, &dvlist[i]);
1782- packDataValue((void*)&val, &dvlist[i+1]);
1783- }
1784- value->dataType = DTValueMap;
1785- value->len = len;
1786- *(DataValue**)(value->data) = dvlist;
1787- }
1788- break;
1789- default:
1790- if (qvar->type() == (int)QMetaType::QObjectStar || qvar->canConvert<QObject *>()) {
1791- QObject *qobject = qvar->value<QObject *>();
1792- GoValue *goValue = dynamic_cast<GoValue *>(qobject);
1793- if (goValue) {
1794- value->dataType = DTGoAddr;
1795- *(void **)(value->data) = goValue->addr;
1796- break;
1797- }
1798- GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject);
1799- if (goPaintedValue) {
1800- value->dataType = DTGoAddr;
1801- *(void **)(value->data) = goPaintedValue->addr;
1802- break;
1803- }
1804- value->dataType = DTObject;
1805- *(void **)(value->data) = qobject;
1806- break;
1807- }
1808- {
1809- QQmlListReference ref = qvar->value<QQmlListReference>();
1810- if (ref.isValid() && ref.canCount() && ref.canAt()) {
1811- int len = ref.count();
1812- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
1813- QVariant elem;
1814- for (int i = 0; i < len; i++) {
1815- elem.setValue(ref.at(i));
1816- packDataValue(&elem, &dvlist[i]);
1817- }
1818- value->dataType = DTValueList;
1819- value->len = len;
1820- *(DataValue**)(value->data) = dvlist;
1821- break;
1822- }
1823- }
1824- if (qstrncmp(qvar->typeName(), "QQmlListProperty<", 17) == 0) {
1825- QQmlListProperty<QObject> *list = reinterpret_cast<QQmlListProperty<QObject>*>(qvar->data());
1826- if (list->count && list->at) {
1827- int len = list->count(list);
1828- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
1829- QVariant elem;
1830- for (int i = 0; i < len; i++) {
1831- elem.setValue(list->at(list, i));
1832- packDataValue(&elem, &dvlist[i]);
1833- }
1834- value->dataType = DTValueList;
1835- value->len = len;
1836- *(DataValue**)(value->data) = dvlist;
1837- break;
1838- }
1839- }
1840- panicf("unsupported variant type: %d (%s)", qvar->type(), qvar->typeName());
1841- break;
1842- }
1843-}
1844-
1845-QVariantList_ *newVariantList(DataValue *list, int len)
1846-{
1847- QVariantList *vlist = new QVariantList();
1848- vlist->reserve(len);
1849- for (int i = 0; i < len; i++) {
1850- QVariant var;
1851- unpackDataValue(&list[i], &var);
1852- vlist->append(var);
1853- }
1854- return vlist;
1855-}
1856-
1857-QObject *listPropertyAt(QQmlListProperty<QObject> *list, int i)
1858-{
1859- return reinterpret_cast<QObject *>(hookListPropertyAt(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, i));
1860-}
1861-
1862-int listPropertyCount(QQmlListProperty<QObject> *list)
1863-{
1864- return hookListPropertyCount(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
1865-}
1866-
1867-void listPropertyAppend(QQmlListProperty<QObject> *list, QObject *obj)
1868-{
1869- hookListPropertyAppend(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, obj);
1870-}
1871-
1872-void listPropertyClear(QQmlListProperty<QObject> *list)
1873-{
1874- hookListPropertyClear(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
1875-}
1876-
1877-QQmlListProperty_ *newListProperty(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex)
1878-{
1879- QQmlListProperty<QObject> *list = new QQmlListProperty<QObject>();
1880- list->data = addr;
1881- list->dummy1 = (void*)reflectIndex;
1882- list->dummy2 = (void*)setIndex;
1883- list->at = listPropertyAt;
1884- list->count = listPropertyCount;
1885- list->append = listPropertyAppend;
1886- list->clear = listPropertyClear;
1887- return list;
1888-}
1889-
1890-void internalLogHandler(QtMsgType severity, const QMessageLogContext &context, const QString &text)
1891-{
1892- QByteArray textba = text.toUtf8();
1893- int fileLength = context.file ? strlen(context.file) : 0;
1894- LogMessage message = {severity, textba.constData(), textba.size(), context.file, fileLength, context.line};
1895- hookLogHandler(&message);
1896-}
1897-
1898-void installLogHandler()
1899-{
1900- qInstallMessageHandler(internalLogHandler);
1901-}
1902-
1903-// vim:ts=4:sw=4:et:ft=cpp
1904
1905=== removed file 'qml.v0/cpp/capi.h'
1906--- qml.v0/cpp/capi.h 2014-08-26 19:38:51 +0000
1907+++ qml.v0/cpp/capi.h 1970-01-01 00:00:00 +0000
1908@@ -1,206 +0,0 @@
1909-#ifndef CAPI_H
1910-#define CAPI_H
1911-
1912-#include <stdint.h>
1913-#include <stddef.h>
1914-
1915-#ifdef __cplusplus
1916-extern "C" {
1917-#endif
1918-
1919-// It's surprising that MaximumParamCount is privately defined within qmetaobject.cpp.
1920-// Must fix the objectInvoke function if this is changed.
1921-// This is Qt's MaximuParamCount - 1, as it does not take the result value in account.
1922-enum { MaxParams = 10 };
1923-
1924-typedef void QApplication_;
1925-typedef void QMetaObject_;
1926-typedef void QObject_;
1927-typedef void QVariant_;
1928-typedef void QVariantList_;
1929-typedef void QString_;
1930-typedef void QQmlEngine_;
1931-typedef void QQmlContext_;
1932-typedef void QQmlComponent_;
1933-typedef void QQmlListProperty_;
1934-typedef void QQuickWindow_;
1935-typedef void QQuickView_;
1936-typedef void QMessageLogContext_;
1937-typedef void QImage_;
1938-typedef void GoValue_;
1939-typedef void GoAddr;
1940-typedef void GoTypeSpec_;
1941-
1942-typedef char error;
1943-error *errorf(const char *format, ...);
1944-void panicf(const char *format, ...);
1945-
1946-typedef enum {
1947- DTUnknown = 0, // Has an unsupported type.
1948- DTInvalid = 1, // Does not exist or similar.
1949-
1950- DTString = 10,
1951- DTBool = 11,
1952- DTInt64 = 12,
1953- DTInt32 = 13,
1954- DTUint64 = 14,
1955- DTUint32 = 15,
1956- DTUintptr = 16,
1957- DTFloat64 = 17,
1958- DTFloat32 = 18,
1959- DTColor = 19,
1960-
1961- DTGoAddr = 100,
1962- DTObject = 101,
1963- DTValueMap = 102,
1964- DTValueList = 103,
1965- DTVariantList = 104,
1966- DTListProperty = 105,
1967-
1968- // Used in type information, not in an actual data value.
1969- DTAny = 201, // Can hold any of the above types.
1970- DTMethod = 202
1971-} DataType;
1972-
1973-typedef struct {
1974- DataType dataType;
1975- char data[8];
1976- int len;
1977-} DataValue;
1978-
1979-typedef struct {
1980- char *memberName; // points to memberNames
1981- DataType memberType;
1982- int reflectIndex;
1983- int reflectGetIndex;
1984- int reflectSetIndex;
1985- int metaIndex;
1986- int addrOffset;
1987- char *methodSignature;
1988- char *resultSignature;
1989- int numIn;
1990- int numOut;
1991-} GoMemberInfo;
1992-
1993-typedef struct {
1994- char *typeName;
1995- GoMemberInfo *fields;
1996- GoMemberInfo *methods;
1997- GoMemberInfo *members; // fields + methods
1998- GoMemberInfo *paint; // in methods too
1999- int fieldsLen;
2000- int methodsLen;
2001- int membersLen;
2002- char *memberNames;
2003-
2004- QMetaObject_ *metaObject;
2005-} GoTypeInfo;
2006-
2007-typedef struct {
2008- int severity;
2009- const char *text;
2010- int textLen;
2011- const char *file;
2012- int fileLen;
2013- int line;
2014-} LogMessage;
2015-
2016-void newGuiApplication(char *deskfile);
2017-void applicationExec();
2018-void applicationFlushAll();
2019-
2020-void idleTimerInit(int *hookWaiting);
2021-void idleTimerStart();
2022-
2023-void *currentThread();
2024-void *appThread();
2025-
2026-QQmlEngine_ *newEngine(QObject_ *parent);
2027-QQmlContext_ *engineRootContext(QQmlEngine_ *engine);
2028-void engineSetOwnershipCPP(QQmlEngine_ *engine, QObject_ *object);
2029-void engineSetOwnershipJS(QQmlEngine_ *engine, QObject_ *object);
2030-void engineSetContextForObject(QQmlEngine_ *engine, QObject_ *object);
2031-void engineAddImageProvider(QQmlEngine_ *engine, QString_ *providerId, void *imageFunc);
2032-
2033-void contextGetProperty(QQmlContext_ *context, QString_ *name, DataValue *value);
2034-void contextSetProperty(QQmlContext_ *context, QString_ *name, DataValue *value);
2035-void contextSetObject(QQmlContext_ *context, QObject_ *value);
2036-QQmlContext_ *contextSpawn(QQmlContext_ *context);
2037-
2038-void delObject(QObject_ *object);
2039-void delObjectLater(QObject_ *object);
2040-const char *objectTypeName(QObject_ *object);
2041-int objectGetProperty(QObject_ *object, const char *name, DataValue *result);
2042-error *objectSetProperty(QObject_ *object, const char *name, DataValue *value);
2043-void objectSetParent(QObject_ *object, QObject_ *parent);
2044-error *objectInvoke(QObject_ *object, const char *method, int methodLen, DataValue *result, DataValue *params, int paramsLen);
2045-void objectFindChild(QObject_ *object, QString_ *name, DataValue *result);
2046-QQmlContext_ *objectContext(QObject_ *object);
2047-int objectIsComponent(QObject_ *object);
2048-int objectIsWindow(QObject_ *object);
2049-int objectIsView(QObject_ *object);
2050-error *objectConnect(QObject_ *object, const char *signal, int signalLen, QQmlEngine_ *engine, void *func, int argsLen);
2051-error *objectGoAddr(QObject_ *object, GoAddr **addr);
2052-
2053-QQmlComponent_ *newComponent(QQmlEngine_ *engine, QObject_ *parent);
2054-void componentSetData(QQmlComponent_ *component, const char *data, int dataLen, const char *url, int urlLen);
2055-char *componentErrorString(QQmlComponent_ *component);
2056-QObject_ *componentCreate(QQmlComponent_ *component, QQmlContext_ *context);
2057-QQuickWindow_ *componentCreateWindow(QQmlComponent_ *component, QQmlContext_ *context);
2058-
2059-void windowShow(QQuickWindow_ *win);
2060-void windowHide(QQuickWindow_ *win);
2061-uintptr_t windowPlatformId(QQuickWindow_ *win);
2062-void windowConnectHidden(QQuickWindow_ *win);
2063-QObject_ *windowRootObject(QQuickWindow_ *win);
2064-QImage_ *windowGrabWindow(QQuickWindow_ *win);
2065-
2066-QImage_ *newImage(int width, int height);
2067-void delImage(QImage_ *image);
2068-void imageSize(QImage_ *image, int *width, int *height);
2069-unsigned char *imageBits(QImage_ *image);
2070-const unsigned char *imageConstBits(QImage_ *image);
2071-
2072-QString_ *newString(const char *data, int len);
2073-void delString(QString_ *s);
2074-
2075-GoValue_ *newGoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject_ *parent);
2076-void goValueActivate(GoValue_ *value, GoTypeInfo *typeInfo, int addrOffset);
2077-
2078-void packDataValue(QVariant_ *var, DataValue *result);
2079-void unpackDataValue(DataValue *value, QVariant_ *result);
2080-
2081-QVariantList_ *newVariantList(DataValue *list, int len);
2082-
2083-QQmlListProperty_ *newListProperty(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex);
2084-
2085-int registerType(char *location, int major, int minor, char *name, GoTypeInfo *typeInfo, GoTypeSpec_ *spec);
2086-int registerSingleton(char *location, int major, int minor, char *name, GoTypeInfo *typeInfo, GoTypeSpec_ *spec);
2087-
2088-void installLogHandler();
2089-
2090-void hookIdleTimer();
2091-void hookLogHandler(LogMessage *message);
2092-void hookGoValueReadField(QQmlEngine_ *engine, GoAddr *addr, int memberIndex, int getIndex, int setIndex, DataValue *result);
2093-void hookGoValueWriteField(QQmlEngine_ *engine, GoAddr *addr, int memberIndex, int setIndex, DataValue *assign);
2094-void hookGoValueCallMethod(QQmlEngine_ *engine, GoAddr *addr, int memberIndex, DataValue *result);
2095-void hookGoValueDestroyed(QQmlEngine_ *engine, GoAddr *addr);
2096-void hookGoValuePaint(QQmlEngine_ *engine, GoAddr *addr, intptr_t reflextIndex);
2097-QImage_ *hookRequestImage(void *imageFunc, char *id, int idLen, int width, int height);
2098-GoAddr *hookGoValueTypeNew(GoValue_ *value, GoTypeSpec_ *spec);
2099-void hookWindowHidden(QObject_ *addr);
2100-void hookSignalCall(QQmlEngine_ *engine, void *func, DataValue *params);
2101-void hookSignalDisconnect(void *func);
2102-void hookPanic(char *message);
2103-int hookListPropertyCount(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex);
2104-QObject_ *hookListPropertyAt(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex, int i);
2105-void hookListPropertyAppend(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex, QObject_ *obj);
2106-void hookListPropertyClear(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex);
2107-
2108-#ifdef __cplusplus
2109-} // extern "C"
2110-#endif
2111-
2112-#endif // CAPI_H
2113-
2114-// vim:ts=4:et
2115
2116=== removed file 'qml.v0/cpp/connector.cpp'
2117--- qml.v0/cpp/connector.cpp 2014-08-26 19:38:51 +0000
2118+++ qml.v0/cpp/connector.cpp 1970-01-01 00:00:00 +0000
2119@@ -1,46 +0,0 @@
2120-#include <QObject>
2121-
2122-#include "connector.h"
2123-#include "capi.h"
2124-
2125-Connector::~Connector()
2126-{
2127- hookSignalDisconnect(func);
2128-}
2129-
2130-void Connector::invoke()
2131-{
2132- panicf("should never get called");
2133-}
2134-
2135-int Connector::qt_metacall(QMetaObject::Call c, int idx, void **a)
2136-{
2137- if (c == QMetaObject::InvokeMetaMethod && idx == metaObject()->methodOffset()) {
2138- DataValue args[MaxParams];
2139- QObject *plain = NULL;
2140- for (int i = 0; i < argsLen; i++) {
2141- int paramType = method.parameterType(i);
2142- if (paramType == 0 && a[1 + i] != NULL) {
2143- const char *typeName = method.parameterTypes()[i].constData();
2144- void *addr = a[1 + i];
2145- if (typeName[strlen(typeName)-1] == '*') {
2146- addr = *(void **)addr;
2147- }
2148- plain = new PlainObject(typeName, addr, plain);
2149- QVariant var = QVariant::fromValue((QObject *)plain);
2150- packDataValue(&var, &args[i]);
2151- } else {
2152- QVariant var(method.parameterType(i), a[1 + i]);
2153- packDataValue(&var, &args[i]);
2154- }
2155- }
2156- hookSignalCall(engine, func, args);
2157- if (plain != NULL) {
2158- delete plain;
2159- }
2160- return -1;
2161- }
2162- return standard_qt_metacall(c, idx, a);
2163-}
2164-
2165-// vim:ts=4:sw=4:et
2166
2167=== removed file 'qml.v0/cpp/connector.h'
2168--- qml.v0/cpp/connector.h 2014-08-26 19:38:51 +0000
2169+++ qml.v0/cpp/connector.h 1970-01-01 00:00:00 +0000
2170@@ -1,58 +0,0 @@
2171-#ifndef CONNECTOR_H
2172-#define CONNECTOR_H
2173-
2174-#include <QObject>
2175-
2176-#include <stdint.h>
2177-
2178-class Connector : public QObject
2179-{
2180- Q_OBJECT
2181-
2182- public:
2183-
2184- Connector(QObject *sender, QMetaMethod method, QQmlEngine *engine, void *func, int argsLen)
2185- : QObject(sender), engine(engine), method(method), func(func), argsLen(argsLen) {};
2186-
2187- virtual ~Connector();
2188-
2189- // MOC HACK: s/Connector::qt_metacall/Connector::standard_qt_metacall/
2190- int standard_qt_metacall(QMetaObject::Call c, int idx, void **a);
2191-
2192- public slots:
2193-
2194- void invoke();
2195-
2196- private:
2197-
2198- QQmlEngine *engine;
2199- QMetaMethod method;
2200- void *func;
2201- int argsLen;
2202-};
2203-
2204-class PlainObject : public QObject
2205-{
2206- Q_OBJECT
2207-
2208- Q_PROPERTY(QString plainType READ getPlainType)
2209- Q_PROPERTY(void *plainAddr READ getPlainAddr)
2210-
2211- QString plainType;
2212- void *plainAddr;
2213-
2214- public:
2215-
2216- PlainObject(QObject *parent = 0)
2217- : QObject(parent) {};
2218-
2219- PlainObject(const char *plainType, void *plainAddr, QObject *parent = 0)
2220- : QObject(parent), plainType(plainType), plainAddr(plainAddr) {};
2221-
2222- QString getPlainType() { return plainType; };
2223- void *getPlainAddr() { return plainAddr; };
2224-};
2225-
2226-#endif // CONNECTOR_H
2227-
2228-// vim:ts=4:sw=4:et
2229
2230=== removed file 'qml.v0/cpp/govalue.cpp'
2231--- qml.v0/cpp/govalue.cpp 2014-08-26 19:38:51 +0000
2232+++ qml.v0/cpp/govalue.cpp 1970-01-01 00:00:00 +0000
2233@@ -1,237 +0,0 @@
2234-#include <private/qmetaobjectbuilder_p.h>
2235-
2236-#include <QtOpenGL/QtOpenGL>
2237-#include <QtOpenGL/QGLFunctions>
2238-
2239-#include <QtQml/QtQml>
2240-#include <QQmlEngine>
2241-#include <QDebug>
2242-
2243-#include "govalue.h"
2244-#include "capi.h"
2245-
2246-class GoValueMetaObject : public QAbstractDynamicMetaObject
2247-{
2248-public:
2249- GoValueMetaObject(QObject* value, GoAddr *addr, GoTypeInfo *typeInfo);
2250-
2251- void activatePropIndex(int propIndex);
2252-
2253-protected:
2254- int metaCall(QMetaObject::Call c, int id, void **a);
2255-
2256-private:
2257- QObject *value;
2258- GoAddr *addr;
2259- GoTypeInfo *typeInfo;
2260-};
2261-
2262-GoValueMetaObject::GoValueMetaObject(QObject *value, GoAddr *addr, GoTypeInfo *typeInfo)
2263- : value(value), addr(addr), typeInfo(typeInfo)
2264-{
2265- //d->parent = static_cast<QAbstractDynamicMetaObject *>(priv->metaObject);
2266- *static_cast<QMetaObject *>(this) = *metaObjectFor(typeInfo);
2267-
2268- QObjectPrivate *objPriv = QObjectPrivate::get(value);
2269- objPriv->metaObject = this;
2270-}
2271-
2272-int GoValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
2273-{
2274- //qWarning() << "GoValueMetaObject::metaCall" << c << idx;
2275- switch (c) {
2276- case QMetaObject::ReadProperty:
2277- case QMetaObject::WriteProperty:
2278- {
2279- // TODO Cache propertyOffset, methodOffset (and maybe qmlEngine)
2280- int propOffset = propertyOffset();
2281- if (idx < propOffset) {
2282- return value->qt_metacall(c, idx, a);
2283- }
2284- GoMemberInfo *memberInfo = typeInfo->fields;
2285- for (int i = 0; i < typeInfo->fieldsLen; i++) {
2286- if (memberInfo->metaIndex == idx) {
2287- if (c == QMetaObject::ReadProperty) {
2288- DataValue result;
2289- hookGoValueReadField(qmlEngine(value), addr, memberInfo->reflectIndex, memberInfo->reflectGetIndex, memberInfo->reflectSetIndex, &result);
2290- if (memberInfo->memberType == DTListProperty) {
2291- if (result.dataType != DTListProperty) {
2292- panicf("reading DTListProperty field returned non-DTListProperty result");
2293- }
2294- QQmlListProperty<QObject> *in = *reinterpret_cast<QQmlListProperty<QObject> **>(result.data);
2295- QQmlListProperty<QObject> *out = reinterpret_cast<QQmlListProperty<QObject> *>(a[0]);
2296- *out = *in;
2297- // TODO Could provide a single variable in the stack to ReadField instead.
2298- delete in;
2299- } else {
2300- QVariant *out = reinterpret_cast<QVariant *>(a[0]);
2301- unpackDataValue(&result, out);
2302- }
2303- } else {
2304- DataValue assign;
2305- QVariant *in = reinterpret_cast<QVariant *>(a[0]);
2306- packDataValue(in, &assign);
2307- hookGoValueWriteField(qmlEngine(value), addr, memberInfo->reflectIndex, memberInfo->reflectSetIndex, &assign);
2308- activate(value, methodOffset() + (idx - propOffset), 0);
2309- }
2310- return -1;
2311- }
2312- memberInfo++;
2313- }
2314- QMetaProperty prop = property(idx);
2315- qWarning() << "Property" << prop.name() << "not found!?";
2316- break;
2317- }
2318- case QMetaObject::InvokeMetaMethod:
2319- {
2320- if (idx < methodOffset()) {
2321- return value->qt_metacall(c, idx, a);
2322- }
2323- GoMemberInfo *memberInfo = typeInfo->methods;
2324- for (int i = 0; i < typeInfo->methodsLen; i++) {
2325- if (memberInfo->metaIndex == idx) {
2326- // args[0] is the result if any.
2327- DataValue args[1 + MaxParams];
2328- for (int i = 1; i < memberInfo->numIn+1; i++) {
2329- packDataValue(reinterpret_cast<QVariant *>(a[i]), &args[i]);
2330- }
2331- hookGoValueCallMethod(qmlEngine(value), addr, memberInfo->reflectIndex, args);
2332- if (memberInfo->numOut > 0) {
2333- unpackDataValue(&args[0], reinterpret_cast<QVariant *>(a[0]));
2334- }
2335- return -1;
2336- }
2337- memberInfo++;
2338- }
2339- QMetaMethod m = method(idx);
2340- qWarning() << "Method" << m.name() << "not found!?";
2341- break;
2342- }
2343- default:
2344- break; // Unhandled.
2345- }
2346- return -1;
2347-}
2348-
2349-void GoValueMetaObject::activatePropIndex(int propIndex)
2350-{
2351- // Properties are added first, so the first fieldLen methods are in
2352- // fact the signals of the respective properties.
2353- int relativeIndex = propIndex - propertyOffset();
2354- activate(value, methodOffset() + relativeIndex, 0);
2355-}
2356-
2357-GoValue::GoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent)
2358- : addr(addr), typeInfo(typeInfo)
2359-{
2360- valueMeta = new GoValueMetaObject(this, addr, typeInfo);
2361- setParent(parent);
2362-}
2363-
2364-GoValue::~GoValue()
2365-{
2366- hookGoValueDestroyed(qmlEngine(this), addr);
2367-}
2368-
2369-void GoValue::activate(int propIndex)
2370-{
2371- valueMeta->activatePropIndex(propIndex);
2372-}
2373-
2374-GoPaintedValue::GoPaintedValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent)
2375- : addr(addr), typeInfo(typeInfo)
2376-{
2377- valueMeta = new GoValueMetaObject(this, addr, typeInfo);
2378- setParent(parent);
2379-
2380- QQuickItem::setFlag(QQuickItem::ItemHasContents, true);
2381- QQuickPaintedItem::setRenderTarget(QQuickPaintedItem::FramebufferObject);
2382-}
2383-
2384-GoPaintedValue::~GoPaintedValue()
2385-{
2386- hookGoValueDestroyed(qmlEngine(this), addr);
2387-}
2388-
2389-void GoPaintedValue::activate(int propIndex)
2390-{
2391- valueMeta->activatePropIndex(propIndex);
2392-}
2393-
2394-void GoPaintedValue::paint(QPainter *painter)
2395-{
2396- //qWarning() << "paint: x=" << x() << "; y=" << y() << "; width=" << width() << "; height=" << height();
2397- painter->beginNativePainting();
2398- hookGoValuePaint(qmlEngine(this), addr, typeInfo->paint->reflectIndex);
2399- painter->endNativePainting();
2400-}
2401-
2402-QMetaObject *metaObjectFor(GoTypeInfo *typeInfo)
2403-{
2404- if (typeInfo->metaObject) {
2405- return reinterpret_cast<QMetaObject *>(typeInfo->metaObject);
2406- }
2407-
2408- QMetaObjectBuilder mob;
2409- if (typeInfo->paint) {
2410- mob.setSuperClass(&QQuickPaintedItem::staticMetaObject);
2411- } else {
2412- mob.setSuperClass(&QObject::staticMetaObject);
2413- }
2414- mob.setClassName(typeInfo->typeName);
2415- mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
2416-
2417- GoMemberInfo *memberInfo;
2418-
2419- memberInfo = typeInfo->fields;
2420- int relativePropIndex = mob.propertyCount();
2421- for (int i = 0; i < typeInfo->fieldsLen; i++) {
2422- mob.addSignal("__" + QByteArray::number(relativePropIndex) + "()");
2423- const char *typeName = "QVariant";
2424- if (memberInfo->memberType == DTListProperty) {
2425- typeName = "QQmlListProperty<QObject>";
2426- }
2427- QMetaPropertyBuilder propb = mob.addProperty(memberInfo->memberName, typeName, relativePropIndex);
2428- propb.setWritable(true);
2429- memberInfo->metaIndex = relativePropIndex;
2430- memberInfo++;
2431- relativePropIndex++;
2432- }
2433-
2434- memberInfo = typeInfo->methods;
2435- int relativeMethodIndex = mob.methodCount();
2436- for (int i = 0; i < typeInfo->methodsLen; i++) {
2437- if (*memberInfo->resultSignature) {
2438- mob.addMethod(memberInfo->methodSignature, memberInfo->resultSignature);
2439- } else {
2440- mob.addMethod(memberInfo->methodSignature);
2441- }
2442- memberInfo->metaIndex = relativeMethodIndex;
2443- memberInfo++;
2444- relativeMethodIndex++;
2445- }
2446-
2447- // TODO Support default properties.
2448- //mob.addClassInfo("DefaultProperty", "objects");
2449-
2450- QMetaObject *mo = mob.toMetaObject();
2451-
2452- // Turn the relative indexes into absolute indexes.
2453- memberInfo = typeInfo->fields;
2454- int propOffset = mo->propertyOffset();
2455- for (int i = 0; i < typeInfo->fieldsLen; i++) {
2456- memberInfo->metaIndex += propOffset;
2457- memberInfo++;
2458- }
2459- memberInfo = typeInfo->methods;
2460- int methodOffset = mo->methodOffset();
2461- for (int i = 0; i < typeInfo->methodsLen; i++) {
2462- memberInfo->metaIndex += methodOffset;
2463- memberInfo++;
2464- }
2465-
2466- typeInfo->metaObject = mo;
2467- return mo;
2468-}
2469-
2470-// vim:ts=4:sw=4:et:ft=cpp
2471
2472=== removed file 'qml.v0/cpp/govalue.h'
2473--- qml.v0/cpp/govalue.h 2014-08-26 19:38:51 +0000
2474+++ qml.v0/cpp/govalue.h 1970-01-01 00:00:00 +0000
2475@@ -1,56 +0,0 @@
2476-#ifndef GOVALUE_H
2477-#define GOVALUE_H
2478-
2479-// Unfortunatley we need access to private bits, because the
2480-// whole dynamic meta-object concept is sadly being hidden
2481-// away, and without it this package wouldn't exist.
2482-#include <private/qmetaobject_p.h>
2483-
2484-#include <QQuickPaintedItem>
2485-#include <QPainter>
2486-
2487-#include "capi.h"
2488-
2489-class GoValueMetaObject;
2490-
2491-QMetaObject *metaObjectFor(GoTypeInfo *typeInfo);
2492-
2493-class GoValue : public QObject
2494-{
2495- Q_OBJECT
2496-
2497-public:
2498- GoAddr *addr;
2499- GoTypeInfo *typeInfo;
2500-
2501- GoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent);
2502- virtual ~GoValue();
2503-
2504- void activate(int propIndex);
2505-
2506-private:
2507- GoValueMetaObject *valueMeta;
2508-};
2509-
2510-class GoPaintedValue : public QQuickPaintedItem
2511-{
2512- Q_OBJECT
2513-
2514-public:
2515- GoAddr *addr;
2516- GoTypeInfo *typeInfo;
2517-
2518- GoPaintedValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject *parent);
2519- virtual ~GoPaintedValue();
2520-
2521- void activate(int propIndex);
2522-
2523- virtual void paint(QPainter *painter);
2524-
2525-private:
2526- GoValueMetaObject *valueMeta;
2527-};
2528-
2529-#endif // GOVALUE_H
2530-
2531-// vim:ts=4:sw=4:et:ft=cpp
2532
2533=== removed file 'qml.v0/cpp/govaluetype.cpp'
2534--- qml.v0/cpp/govaluetype.cpp 2014-08-26 19:38:51 +0000
2535+++ qml.v0/cpp/govaluetype.cpp 1970-01-01 00:00:00 +0000
2536@@ -1,254 +0,0 @@
2537-#include "govaluetype.h"
2538-
2539-#define DEFINE_GOVALUETYPE(N) \
2540- template<> QMetaObject GoValueType<N>::staticMetaObject = QMetaObject(); \
2541- template<> GoTypeInfo *GoValueType<N>::typeInfo = 0; \
2542- template<> GoTypeSpec_ *GoValueType<N>::typeSpec = 0;
2543-
2544-#define DEFINE_GOPAINTEDVALUETYPE(N) \
2545- template<> QMetaObject GoPaintedValueType<N>::staticMetaObject = QMetaObject(); \
2546- template<> GoTypeInfo *GoPaintedValueType<N>::typeInfo = 0; \
2547- template<> GoTypeSpec_ *GoPaintedValueType<N>::typeSpec = 0;
2548-
2549-DEFINE_GOVALUETYPE(1)
2550-DEFINE_GOVALUETYPE(2)
2551-DEFINE_GOVALUETYPE(3)
2552-DEFINE_GOVALUETYPE(4)
2553-DEFINE_GOVALUETYPE(5)
2554-DEFINE_GOVALUETYPE(6)
2555-DEFINE_GOVALUETYPE(7)
2556-DEFINE_GOVALUETYPE(8)
2557-DEFINE_GOVALUETYPE(9)
2558-DEFINE_GOVALUETYPE(10)
2559-DEFINE_GOVALUETYPE(11)
2560-DEFINE_GOVALUETYPE(12)
2561-DEFINE_GOVALUETYPE(13)
2562-DEFINE_GOVALUETYPE(14)
2563-DEFINE_GOVALUETYPE(15)
2564-DEFINE_GOVALUETYPE(16)
2565-DEFINE_GOVALUETYPE(17)
2566-DEFINE_GOVALUETYPE(18)
2567-DEFINE_GOVALUETYPE(19)
2568-DEFINE_GOVALUETYPE(20)
2569-DEFINE_GOVALUETYPE(21)
2570-DEFINE_GOVALUETYPE(22)
2571-DEFINE_GOVALUETYPE(23)
2572-DEFINE_GOVALUETYPE(24)
2573-DEFINE_GOVALUETYPE(25)
2574-DEFINE_GOVALUETYPE(26)
2575-DEFINE_GOVALUETYPE(27)
2576-DEFINE_GOVALUETYPE(28)
2577-DEFINE_GOVALUETYPE(29)
2578-DEFINE_GOVALUETYPE(30)
2579-
2580-DEFINE_GOPAINTEDVALUETYPE(1)
2581-DEFINE_GOPAINTEDVALUETYPE(2)
2582-DEFINE_GOPAINTEDVALUETYPE(3)
2583-DEFINE_GOPAINTEDVALUETYPE(4)
2584-DEFINE_GOPAINTEDVALUETYPE(5)
2585-DEFINE_GOPAINTEDVALUETYPE(6)
2586-DEFINE_GOPAINTEDVALUETYPE(7)
2587-DEFINE_GOPAINTEDVALUETYPE(8)
2588-DEFINE_GOPAINTEDVALUETYPE(9)
2589-DEFINE_GOPAINTEDVALUETYPE(10)
2590-DEFINE_GOPAINTEDVALUETYPE(11)
2591-DEFINE_GOPAINTEDVALUETYPE(12)
2592-DEFINE_GOPAINTEDVALUETYPE(13)
2593-DEFINE_GOPAINTEDVALUETYPE(14)
2594-DEFINE_GOPAINTEDVALUETYPE(15)
2595-DEFINE_GOPAINTEDVALUETYPE(16)
2596-DEFINE_GOPAINTEDVALUETYPE(17)
2597-DEFINE_GOPAINTEDVALUETYPE(18)
2598-DEFINE_GOPAINTEDVALUETYPE(19)
2599-DEFINE_GOPAINTEDVALUETYPE(20)
2600-DEFINE_GOPAINTEDVALUETYPE(21)
2601-DEFINE_GOPAINTEDVALUETYPE(22)
2602-DEFINE_GOPAINTEDVALUETYPE(23)
2603-DEFINE_GOPAINTEDVALUETYPE(24)
2604-DEFINE_GOPAINTEDVALUETYPE(25)
2605-DEFINE_GOPAINTEDVALUETYPE(26)
2606-DEFINE_GOPAINTEDVALUETYPE(27)
2607-DEFINE_GOPAINTEDVALUETYPE(28)
2608-DEFINE_GOPAINTEDVALUETYPE(29)
2609-DEFINE_GOPAINTEDVALUETYPE(30)
2610-
2611-static int goValueTypeN = 0;
2612-static int goPaintedValueTypeN = 0;
2613-
2614-template<int N>
2615-int registerSingletonN(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec) {
2616- GoValueType<N>::init(info, spec);
2617- return qmlRegisterSingletonType< GoValueType<N> >(location, major, minor, name, [](QQmlEngine *qmlEngine, QJSEngine *jsEngine) -> QObject* {
2618- QObject *singleton = new GoValueType<N>();
2619- QQmlEngine::setContextForObject(singleton, qmlEngine->rootContext());
2620- return singleton;
2621- });
2622-}
2623-
2624-template<int N>
2625-int registerPaintedSingletonN(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec) {
2626- GoPaintedValueType<N>::init(info, spec);
2627- return qmlRegisterSingletonType< GoPaintedValueType<N> >(location, major, minor, name, [](QQmlEngine *qmlEngine, QJSEngine *jsEngine) -> QObject* {
2628- QObject *singleton = new GoPaintedValueType<N>();
2629- QQmlEngine::setContextForObject(singleton, qmlEngine->rootContext());
2630- return singleton;
2631- });
2632-}
2633-
2634-#define GOVALUETYPE_CASE_SINGLETON(N) \
2635- case N: return registerSingletonN<N>(location, major, minor, name, info, spec);
2636-#define GOPAINTEDVALUETYPE_CASE_SINGLETON(N) \
2637- case N: return registerPaintedSingletonN<N>(location, major, minor, name, info, spec);
2638-
2639-int registerSingleton(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec)
2640-{
2641- if (!info->paint) {
2642- switch (++goValueTypeN) {
2643- GOVALUETYPE_CASE_SINGLETON(1)
2644- GOVALUETYPE_CASE_SINGLETON(2)
2645- GOVALUETYPE_CASE_SINGLETON(3)
2646- GOVALUETYPE_CASE_SINGLETON(4)
2647- GOVALUETYPE_CASE_SINGLETON(5)
2648- GOVALUETYPE_CASE_SINGLETON(6)
2649- GOVALUETYPE_CASE_SINGLETON(7)
2650- GOVALUETYPE_CASE_SINGLETON(8)
2651- GOVALUETYPE_CASE_SINGLETON(9)
2652- GOVALUETYPE_CASE_SINGLETON(10)
2653- GOVALUETYPE_CASE_SINGLETON(11)
2654- GOVALUETYPE_CASE_SINGLETON(12)
2655- GOVALUETYPE_CASE_SINGLETON(13)
2656- GOVALUETYPE_CASE_SINGLETON(14)
2657- GOVALUETYPE_CASE_SINGLETON(15)
2658- GOVALUETYPE_CASE_SINGLETON(16)
2659- GOVALUETYPE_CASE_SINGLETON(17)
2660- GOVALUETYPE_CASE_SINGLETON(18)
2661- GOVALUETYPE_CASE_SINGLETON(19)
2662- GOVALUETYPE_CASE_SINGLETON(20)
2663- GOVALUETYPE_CASE_SINGLETON(21)
2664- GOVALUETYPE_CASE_SINGLETON(22)
2665- GOVALUETYPE_CASE_SINGLETON(23)
2666- GOVALUETYPE_CASE_SINGLETON(24)
2667- GOVALUETYPE_CASE_SINGLETON(25)
2668- GOVALUETYPE_CASE_SINGLETON(26)
2669- GOVALUETYPE_CASE_SINGLETON(27)
2670- GOVALUETYPE_CASE_SINGLETON(28)
2671- GOVALUETYPE_CASE_SINGLETON(29)
2672- GOVALUETYPE_CASE_SINGLETON(30)
2673- }
2674- } else {
2675- switch (++goPaintedValueTypeN) {
2676- GOPAINTEDVALUETYPE_CASE_SINGLETON(1)
2677- GOPAINTEDVALUETYPE_CASE_SINGLETON(2)
2678- GOPAINTEDVALUETYPE_CASE_SINGLETON(3)
2679- GOPAINTEDVALUETYPE_CASE_SINGLETON(4)
2680- GOPAINTEDVALUETYPE_CASE_SINGLETON(5)
2681- GOPAINTEDVALUETYPE_CASE_SINGLETON(6)
2682- GOPAINTEDVALUETYPE_CASE_SINGLETON(7)
2683- GOPAINTEDVALUETYPE_CASE_SINGLETON(8)
2684- GOPAINTEDVALUETYPE_CASE_SINGLETON(9)
2685- GOPAINTEDVALUETYPE_CASE_SINGLETON(10)
2686- GOPAINTEDVALUETYPE_CASE_SINGLETON(11)
2687- GOPAINTEDVALUETYPE_CASE_SINGLETON(12)
2688- GOPAINTEDVALUETYPE_CASE_SINGLETON(13)
2689- GOPAINTEDVALUETYPE_CASE_SINGLETON(14)
2690- GOPAINTEDVALUETYPE_CASE_SINGLETON(15)
2691- GOPAINTEDVALUETYPE_CASE_SINGLETON(16)
2692- GOPAINTEDVALUETYPE_CASE_SINGLETON(17)
2693- GOPAINTEDVALUETYPE_CASE_SINGLETON(18)
2694- GOPAINTEDVALUETYPE_CASE_SINGLETON(19)
2695- GOPAINTEDVALUETYPE_CASE_SINGLETON(20)
2696- GOPAINTEDVALUETYPE_CASE_SINGLETON(21)
2697- GOPAINTEDVALUETYPE_CASE_SINGLETON(22)
2698- GOPAINTEDVALUETYPE_CASE_SINGLETON(23)
2699- GOPAINTEDVALUETYPE_CASE_SINGLETON(24)
2700- GOPAINTEDVALUETYPE_CASE_SINGLETON(25)
2701- GOPAINTEDVALUETYPE_CASE_SINGLETON(26)
2702- GOPAINTEDVALUETYPE_CASE_SINGLETON(27)
2703- GOPAINTEDVALUETYPE_CASE_SINGLETON(28)
2704- GOPAINTEDVALUETYPE_CASE_SINGLETON(29)
2705- GOPAINTEDVALUETYPE_CASE_SINGLETON(30)
2706- }
2707- }
2708- panicf("too many registered types; please contact the Go QML developers");
2709- return 0;
2710-}
2711-
2712-#define GOVALUETYPE_CASE(N) \
2713- case N: GoValueType<N>::init(info, spec); return qmlRegisterType< GoValueType<N> >(location, major, minor, name);
2714-#define GOPAINTEDVALUETYPE_CASE(N) \
2715- case N: GoPaintedValueType<N>::init(info, spec); return qmlRegisterType< GoPaintedValueType<N> >(location, major, minor, name);
2716-
2717-int registerType(char *location, int major, int minor, char *name, GoTypeInfo *info, GoTypeSpec_ *spec)
2718-{
2719- if (!info->paint) {
2720- switch (++goValueTypeN) {
2721- GOVALUETYPE_CASE(1)
2722- GOVALUETYPE_CASE(2)
2723- GOVALUETYPE_CASE(3)
2724- GOVALUETYPE_CASE(4)
2725- GOVALUETYPE_CASE(5)
2726- GOVALUETYPE_CASE(6)
2727- GOVALUETYPE_CASE(7)
2728- GOVALUETYPE_CASE(8)
2729- GOVALUETYPE_CASE(9)
2730- GOVALUETYPE_CASE(10)
2731- GOVALUETYPE_CASE(11)
2732- GOVALUETYPE_CASE(12)
2733- GOVALUETYPE_CASE(13)
2734- GOVALUETYPE_CASE(14)
2735- GOVALUETYPE_CASE(15)
2736- GOVALUETYPE_CASE(16)
2737- GOVALUETYPE_CASE(17)
2738- GOVALUETYPE_CASE(18)
2739- GOVALUETYPE_CASE(19)
2740- GOVALUETYPE_CASE(20)
2741- GOVALUETYPE_CASE(21)
2742- GOVALUETYPE_CASE(22)
2743- GOVALUETYPE_CASE(23)
2744- GOVALUETYPE_CASE(24)
2745- GOVALUETYPE_CASE(25)
2746- GOVALUETYPE_CASE(26)
2747- GOVALUETYPE_CASE(27)
2748- GOVALUETYPE_CASE(28)
2749- GOVALUETYPE_CASE(29)
2750- GOVALUETYPE_CASE(30)
2751- }
2752- } else {
2753- switch (++goPaintedValueTypeN) {
2754- GOPAINTEDVALUETYPE_CASE(1)
2755- GOPAINTEDVALUETYPE_CASE(2)
2756- GOPAINTEDVALUETYPE_CASE(3)
2757- GOPAINTEDVALUETYPE_CASE(4)
2758- GOPAINTEDVALUETYPE_CASE(5)
2759- GOPAINTEDVALUETYPE_CASE(6)
2760- GOPAINTEDVALUETYPE_CASE(7)
2761- GOPAINTEDVALUETYPE_CASE(8)
2762- GOPAINTEDVALUETYPE_CASE(9)
2763- GOPAINTEDVALUETYPE_CASE(10)
2764- GOPAINTEDVALUETYPE_CASE(11)
2765- GOPAINTEDVALUETYPE_CASE(12)
2766- GOPAINTEDVALUETYPE_CASE(13)
2767- GOPAINTEDVALUETYPE_CASE(14)
2768- GOPAINTEDVALUETYPE_CASE(15)
2769- GOPAINTEDVALUETYPE_CASE(16)
2770- GOPAINTEDVALUETYPE_CASE(17)
2771- GOPAINTEDVALUETYPE_CASE(18)
2772- GOPAINTEDVALUETYPE_CASE(19)
2773- GOPAINTEDVALUETYPE_CASE(20)
2774- GOPAINTEDVALUETYPE_CASE(21)
2775- GOPAINTEDVALUETYPE_CASE(22)
2776- GOPAINTEDVALUETYPE_CASE(23)
2777- GOPAINTEDVALUETYPE_CASE(24)
2778- GOPAINTEDVALUETYPE_CASE(25)
2779- GOPAINTEDVALUETYPE_CASE(26)
2780- GOPAINTEDVALUETYPE_CASE(27)
2781- GOPAINTEDVALUETYPE_CASE(28)
2782- GOPAINTEDVALUETYPE_CASE(29)
2783- GOPAINTEDVALUETYPE_CASE(30)
2784- }
2785- }
2786- panicf("too many registered types; please contact the Go QML developers");
2787- return 0;
2788-}
2789-
2790-// vim:sw=4:st=4:et:ft=cpp
2791
2792=== removed file 'qml.v0/cpp/govaluetype.h'
2793--- qml.v0/cpp/govaluetype.h 2014-08-26 19:38:51 +0000
2794+++ qml.v0/cpp/govaluetype.h 1970-01-01 00:00:00 +0000
2795@@ -1,48 +0,0 @@
2796-#ifndef GOVALUETYPE_H
2797-#define GOVALUETYPE_H
2798-
2799-#include "govalue.h"
2800-
2801-template <int N>
2802-class GoValueType : public GoValue
2803-{
2804-public:
2805-
2806- GoValueType()
2807- : GoValue(hookGoValueTypeNew(this, typeSpec), typeInfo, 0) {};
2808-
2809- static void init(GoTypeInfo *info, GoTypeSpec_ *spec)
2810- {
2811- typeInfo = info;
2812- typeSpec = spec;
2813- static_cast<QMetaObject &>(staticMetaObject) = *metaObjectFor(typeInfo);
2814- };
2815-
2816- static GoTypeSpec_ *typeSpec;
2817- static GoTypeInfo *typeInfo;
2818- static QMetaObject staticMetaObject;
2819-};
2820-
2821-template <int N>
2822-class GoPaintedValueType : public GoPaintedValue
2823-{
2824-public:
2825-
2826- GoPaintedValueType()
2827- : GoPaintedValue(hookGoValueTypeNew(this, typeSpec), typeInfo, 0) {};
2828-
2829- static void init(GoTypeInfo *info, GoTypeSpec_ *spec)
2830- {
2831- typeInfo = info;
2832- typeSpec = spec;
2833- static_cast<QMetaObject &>(staticMetaObject) = *metaObjectFor(typeInfo);
2834- };
2835-
2836- static GoTypeSpec_ *typeSpec;
2837- static GoTypeInfo *typeInfo;
2838- static QMetaObject staticMetaObject;
2839-};
2840-
2841-#endif // GOVALUETYPE_H
2842-
2843-// vim:ts=4:sw=4:et
2844
2845=== removed file 'qml.v0/cpp/idletimer.cpp'
2846--- qml.v0/cpp/idletimer.cpp 2014-08-26 19:38:51 +0000
2847+++ qml.v0/cpp/idletimer.cpp 1970-01-01 00:00:00 +0000
2848@@ -1,58 +0,0 @@
2849-#include <QBasicTimer>
2850-#include <QThread>
2851-#include <QDebug>
2852-#include <mutex>
2853-
2854-#include "capi.h"
2855-
2856-class IdleTimer : public QObject
2857-{
2858- Q_OBJECT
2859-
2860- public:
2861-
2862- static IdleTimer *singleton() {
2863- static IdleTimer singleton;
2864- return &singleton;
2865- }
2866-
2867- void init(int *hookWaiting)
2868- {
2869- this->hookWaiting = hookWaiting;
2870- }
2871-
2872- Q_INVOKABLE void start()
2873- {
2874- timer.start(0, this);
2875- }
2876-
2877- protected:
2878-
2879- void timerEvent(QTimerEvent *event)
2880- {
2881- __sync_synchronize();
2882- if (*hookWaiting > 0) {
2883- hookIdleTimer();
2884- } else {
2885- timer.stop();
2886- }
2887- }
2888-
2889- private:
2890-
2891- int *hookWaiting;
2892-
2893- QBasicTimer timer;
2894-};
2895-
2896-void idleTimerInit(int *hookWaiting)
2897-{
2898- IdleTimer::singleton()->init(hookWaiting);
2899-}
2900-
2901-void idleTimerStart()
2902-{
2903- QMetaObject::invokeMethod(IdleTimer::singleton(), "start", Qt::QueuedConnection);
2904-}
2905-
2906-// vim:ts=4:sw=4:et:ft=cpp
2907
2908=== removed file 'qml.v0/cpp/moc_all.cpp'
2909--- qml.v0/cpp/moc_all.cpp 2014-08-26 19:38:51 +0000
2910+++ qml.v0/cpp/moc_all.cpp 1970-01-01 00:00:00 +0000
2911@@ -1,4 +0,0 @@
2912-// This file is automatically generated by cpp/update-moc.sh
2913-#include "cpp/moc_connector.cpp"
2914-#include "cpp/moc_govalue.cpp"
2915-#include "cpp/moc_idletimer.cpp"
2916
2917=== removed file 'qml.v0/cpp/moc_connector.cpp'
2918--- qml.v0/cpp/moc_connector.cpp 2014-08-26 19:38:51 +0000
2919+++ qml.v0/cpp/moc_connector.cpp 1970-01-01 00:00:00 +0000
2920@@ -1,211 +0,0 @@
2921-/****************************************************************************
2922-** Meta object code from reading C++ file 'connector.h'
2923-**
2924-** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
2925-**
2926-** WARNING! All changes made in this file will be lost!
2927-*****************************************************************************/
2928-
2929-#include "connector.h"
2930-#include <QtCore/qbytearray.h>
2931-#include <QtCore/qmetatype.h>
2932-#if !defined(Q_MOC_OUTPUT_REVISION)
2933-#error "The header file 'connector.h' doesn't include <QObject>."
2934-#elif Q_MOC_OUTPUT_REVISION != 67
2935-#error "This file was generated using the moc from 5.2.1. It"
2936-#error "cannot be used with the include files from this version of Qt."
2937-#error "(The moc has changed too much.)"
2938-#endif
2939-
2940-QT_BEGIN_MOC_NAMESPACE
2941-struct qt_meta_stringdata_Connector_t {
2942- QByteArrayData data[3];
2943- char stringdata[19];
2944-};
2945-#define QT_MOC_LITERAL(idx, ofs, len) \
2946- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
2947- offsetof(qt_meta_stringdata_Connector_t, stringdata) + ofs \
2948- - idx * sizeof(QByteArrayData) \
2949- )
2950-static const qt_meta_stringdata_Connector_t qt_meta_stringdata_Connector = {
2951- {
2952-QT_MOC_LITERAL(0, 0, 9),
2953-QT_MOC_LITERAL(1, 10, 6),
2954-QT_MOC_LITERAL(2, 17, 0)
2955- },
2956- "Connector\0invoke\0\0"
2957-};
2958-#undef QT_MOC_LITERAL
2959-
2960-static const uint qt_meta_data_Connector[] = {
2961-
2962- // content:
2963- 7, // revision
2964- 0, // classname
2965- 0, 0, // classinfo
2966- 1, 14, // methods
2967- 0, 0, // properties
2968- 0, 0, // enums/sets
2969- 0, 0, // constructors
2970- 0, // flags
2971- 0, // signalCount
2972-
2973- // slots: name, argc, parameters, tag, flags
2974- 1, 0, 19, 2, 0x0a,
2975-
2976- // slots: parameters
2977- QMetaType::Void,
2978-
2979- 0 // eod
2980-};
2981-
2982-void Connector::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
2983-{
2984- if (_c == QMetaObject::InvokeMetaMethod) {
2985- Connector *_t = static_cast<Connector *>(_o);
2986- switch (_id) {
2987- case 0: _t->invoke(); break;
2988- default: ;
2989- }
2990- }
2991- Q_UNUSED(_a);
2992-}
2993-
2994-const QMetaObject Connector::staticMetaObject = {
2995- { &QObject::staticMetaObject, qt_meta_stringdata_Connector.data,
2996- qt_meta_data_Connector, qt_static_metacall, 0, 0}
2997-};
2998-
2999-
3000-const QMetaObject *Connector::metaObject() const
3001-{
3002- return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
3003-}
3004-
3005-void *Connector::qt_metacast(const char *_clname)
3006-{
3007- if (!_clname) return 0;
3008- if (!strcmp(_clname, qt_meta_stringdata_Connector.stringdata))
3009- return static_cast<void*>(const_cast< Connector*>(this));
3010- return QObject::qt_metacast(_clname);
3011-}
3012-
3013-int Connector::standard_qt_metacall(QMetaObject::Call _c, int _id, void **_a)
3014-{
3015- _id = QObject::qt_metacall(_c, _id, _a);
3016- if (_id < 0)
3017- return _id;
3018- if (_c == QMetaObject::InvokeMetaMethod) {
3019- if (_id < 1)
3020- qt_static_metacall(this, _c, _id, _a);
3021- _id -= 1;
3022- } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
3023- if (_id < 1)
3024- *reinterpret_cast<int*>(_a[0]) = -1;
3025- _id -= 1;
3026- }
3027- return _id;
3028-}
3029-struct qt_meta_stringdata_PlainObject_t {
3030- QByteArrayData data[3];
3031- char stringdata[33];
3032-};
3033-#define QT_MOC_LITERAL(idx, ofs, len) \
3034- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
3035- offsetof(qt_meta_stringdata_PlainObject_t, stringdata) + ofs \
3036- - idx * sizeof(QByteArrayData) \
3037- )
3038-static const qt_meta_stringdata_PlainObject_t qt_meta_stringdata_PlainObject = {
3039- {
3040-QT_MOC_LITERAL(0, 0, 11),
3041-QT_MOC_LITERAL(1, 12, 9),
3042-QT_MOC_LITERAL(2, 22, 9)
3043- },
3044- "PlainObject\0plainType\0plainAddr\0"
3045-};
3046-#undef QT_MOC_LITERAL
3047-
3048-static const uint qt_meta_data_PlainObject[] = {
3049-
3050- // content:
3051- 7, // revision
3052- 0, // classname
3053- 0, 0, // classinfo
3054- 0, 0, // methods
3055- 2, 14, // properties
3056- 0, 0, // enums/sets
3057- 0, 0, // constructors
3058- 0, // flags
3059- 0, // signalCount
3060-
3061- // properties: name, type, flags
3062- 1, QMetaType::QString, 0x00095001,
3063- 2, QMetaType::VoidStar, 0x00095001,
3064-
3065- 0 // eod
3066-};
3067-
3068-void PlainObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
3069-{
3070- Q_UNUSED(_o);
3071- Q_UNUSED(_id);
3072- Q_UNUSED(_c);
3073- Q_UNUSED(_a);
3074-}
3075-
3076-const QMetaObject PlainObject::staticMetaObject = {
3077- { &QObject::staticMetaObject, qt_meta_stringdata_PlainObject.data,
3078- qt_meta_data_PlainObject, qt_static_metacall, 0, 0}
3079-};
3080-
3081-
3082-const QMetaObject *PlainObject::metaObject() const
3083-{
3084- return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
3085-}
3086-
3087-void *PlainObject::qt_metacast(const char *_clname)
3088-{
3089- if (!_clname) return 0;
3090- if (!strcmp(_clname, qt_meta_stringdata_PlainObject.stringdata))
3091- return static_cast<void*>(const_cast< PlainObject*>(this));
3092- return QObject::qt_metacast(_clname);
3093-}
3094-
3095-int PlainObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
3096-{
3097- _id = QObject::qt_metacall(_c, _id, _a);
3098- if (_id < 0)
3099- return _id;
3100-
3101-#ifndef QT_NO_PROPERTIES
3102- if (_c == QMetaObject::ReadProperty) {
3103- void *_v = _a[0];
3104- switch (_id) {
3105- case 0: *reinterpret_cast< QString*>(_v) = getPlainType(); break;
3106- case 1: *reinterpret_cast< void**>(_v) = getPlainAddr(); break;
3107- }
3108- _id -= 2;
3109- } else if (_c == QMetaObject::WriteProperty) {
3110- _id -= 2;
3111- } else if (_c == QMetaObject::ResetProperty) {
3112- _id -= 2;
3113- } else if (_c == QMetaObject::QueryPropertyDesignable) {
3114- _id -= 2;
3115- } else if (_c == QMetaObject::QueryPropertyScriptable) {
3116- _id -= 2;
3117- } else if (_c == QMetaObject::QueryPropertyStored) {
3118- _id -= 2;
3119- } else if (_c == QMetaObject::QueryPropertyEditable) {
3120- _id -= 2;
3121- } else if (_c == QMetaObject::QueryPropertyUser) {
3122- _id -= 2;
3123- } else if (_c == QMetaObject::RegisterPropertyMetaType) {
3124- if (_id < 2)
3125- *reinterpret_cast<int*>(_a[0]) = -1;
3126- _id -= 2;
3127- }
3128-#endif // QT_NO_PROPERTIES
3129- return _id;
3130-}
3131-QT_END_MOC_NAMESPACE
3132
3133=== removed file 'qml.v0/cpp/moc_govalue.cpp'
3134--- qml.v0/cpp/moc_govalue.cpp 2014-08-26 19:38:51 +0000
3135+++ qml.v0/cpp/moc_govalue.cpp 1970-01-01 00:00:00 +0000
3136@@ -1,155 +0,0 @@
3137-/****************************************************************************
3138-** Meta object code from reading C++ file 'govalue.h'
3139-**
3140-** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
3141-**
3142-** WARNING! All changes made in this file will be lost!
3143-*****************************************************************************/
3144-
3145-#include "govalue.h"
3146-#include <QtCore/qbytearray.h>
3147-#include <QtCore/qmetatype.h>
3148-#if !defined(Q_MOC_OUTPUT_REVISION)
3149-#error "The header file 'govalue.h' doesn't include <QObject>."
3150-#elif Q_MOC_OUTPUT_REVISION != 67
3151-#error "This file was generated using the moc from 5.2.1. It"
3152-#error "cannot be used with the include files from this version of Qt."
3153-#error "(The moc has changed too much.)"
3154-#endif
3155-
3156-QT_BEGIN_MOC_NAMESPACE
3157-struct qt_meta_stringdata_GoValue_t {
3158- QByteArrayData data[1];
3159- char stringdata[9];
3160-};
3161-#define QT_MOC_LITERAL(idx, ofs, len) \
3162- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
3163- offsetof(qt_meta_stringdata_GoValue_t, stringdata) + ofs \
3164- - idx * sizeof(QByteArrayData) \
3165- )
3166-static const qt_meta_stringdata_GoValue_t qt_meta_stringdata_GoValue = {
3167- {
3168-QT_MOC_LITERAL(0, 0, 7)
3169- },
3170- "GoValue\0"
3171-};
3172-#undef QT_MOC_LITERAL
3173-
3174-static const uint qt_meta_data_GoValue[] = {
3175-
3176- // content:
3177- 7, // revision
3178- 0, // classname
3179- 0, 0, // classinfo
3180- 0, 0, // methods
3181- 0, 0, // properties
3182- 0, 0, // enums/sets
3183- 0, 0, // constructors
3184- 0, // flags
3185- 0, // signalCount
3186-
3187- 0 // eod
3188-};
3189-
3190-void GoValue::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
3191-{
3192- Q_UNUSED(_o);
3193- Q_UNUSED(_id);
3194- Q_UNUSED(_c);
3195- Q_UNUSED(_a);
3196-}
3197-
3198-const QMetaObject GoValue::staticMetaObject = {
3199- { &QObject::staticMetaObject, qt_meta_stringdata_GoValue.data,
3200- qt_meta_data_GoValue, qt_static_metacall, 0, 0}
3201-};
3202-
3203-
3204-const QMetaObject *GoValue::metaObject() const
3205-{
3206- return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
3207-}
3208-
3209-void *GoValue::qt_metacast(const char *_clname)
3210-{
3211- if (!_clname) return 0;
3212- if (!strcmp(_clname, qt_meta_stringdata_GoValue.stringdata))
3213- return static_cast<void*>(const_cast< GoValue*>(this));
3214- return QObject::qt_metacast(_clname);
3215-}
3216-
3217-int GoValue::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
3218-{
3219- _id = QObject::qt_metacall(_c, _id, _a);
3220- if (_id < 0)
3221- return _id;
3222- return _id;
3223-}
3224-struct qt_meta_stringdata_GoPaintedValue_t {
3225- QByteArrayData data[1];
3226- char stringdata[16];
3227-};
3228-#define QT_MOC_LITERAL(idx, ofs, len) \
3229- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
3230- offsetof(qt_meta_stringdata_GoPaintedValue_t, stringdata) + ofs \
3231- - idx * sizeof(QByteArrayData) \
3232- )
3233-static const qt_meta_stringdata_GoPaintedValue_t qt_meta_stringdata_GoPaintedValue = {
3234- {
3235-QT_MOC_LITERAL(0, 0, 14)
3236- },
3237- "GoPaintedValue\0"
3238-};
3239-#undef QT_MOC_LITERAL
3240-
3241-static const uint qt_meta_data_GoPaintedValue[] = {
3242-
3243- // content:
3244- 7, // revision
3245- 0, // classname
3246- 0, 0, // classinfo
3247- 0, 0, // methods
3248- 0, 0, // properties
3249- 0, 0, // enums/sets
3250- 0, 0, // constructors
3251- 0, // flags
3252- 0, // signalCount
3253-
3254- 0 // eod
3255-};
3256-
3257-void GoPaintedValue::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
3258-{
3259- Q_UNUSED(_o);
3260- Q_UNUSED(_id);
3261- Q_UNUSED(_c);
3262- Q_UNUSED(_a);
3263-}
3264-
3265-const QMetaObject GoPaintedValue::staticMetaObject = {
3266- { &QQuickPaintedItem::staticMetaObject, qt_meta_stringdata_GoPaintedValue.data,
3267- qt_meta_data_GoPaintedValue, qt_static_metacall, 0, 0}
3268-};
3269-
3270-
3271-const QMetaObject *GoPaintedValue::metaObject() const
3272-{
3273- return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
3274-}
3275-
3276-void *GoPaintedValue::qt_metacast(const char *_clname)
3277-{
3278- if (!_clname) return 0;
3279- if (!strcmp(_clname, qt_meta_stringdata_GoPaintedValue.stringdata))
3280- return static_cast<void*>(const_cast< GoPaintedValue*>(this));
3281- return QQuickPaintedItem::qt_metacast(_clname);
3282-}
3283-
3284-int GoPaintedValue::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
3285-{
3286- _id = QQuickPaintedItem::qt_metacall(_c, _id, _a);
3287- if (_id < 0)
3288- return _id;
3289- return _id;
3290-}
3291-QT_END_MOC_NAMESPACE
3292
3293=== removed file 'qml.v0/cpp/moc_idletimer.cpp'
3294--- qml.v0/cpp/moc_idletimer.cpp 2014-08-26 19:38:51 +0000
3295+++ qml.v0/cpp/moc_idletimer.cpp 1970-01-01 00:00:00 +0000
3296@@ -1,108 +0,0 @@
3297-/****************************************************************************
3298-** Meta object code from reading C++ file 'idletimer.cpp'
3299-**
3300-** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
3301-**
3302-** WARNING! All changes made in this file will be lost!
3303-*****************************************************************************/
3304-
3305-#include <QtCore/qbytearray.h>
3306-#include <QtCore/qmetatype.h>
3307-#if !defined(Q_MOC_OUTPUT_REVISION)
3308-#error "The header file 'idletimer.cpp' doesn't include <QObject>."
3309-#elif Q_MOC_OUTPUT_REVISION != 67
3310-#error "This file was generated using the moc from 5.2.1. It"
3311-#error "cannot be used with the include files from this version of Qt."
3312-#error "(The moc has changed too much.)"
3313-#endif
3314-
3315-QT_BEGIN_MOC_NAMESPACE
3316-struct qt_meta_stringdata_IdleTimer_t {
3317- QByteArrayData data[3];
3318- char stringdata[18];
3319-};
3320-#define QT_MOC_LITERAL(idx, ofs, len) \
3321- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
3322- offsetof(qt_meta_stringdata_IdleTimer_t, stringdata) + ofs \
3323- - idx * sizeof(QByteArrayData) \
3324- )
3325-static const qt_meta_stringdata_IdleTimer_t qt_meta_stringdata_IdleTimer = {
3326- {
3327-QT_MOC_LITERAL(0, 0, 9),
3328-QT_MOC_LITERAL(1, 10, 5),
3329-QT_MOC_LITERAL(2, 16, 0)
3330- },
3331- "IdleTimer\0start\0\0"
3332-};
3333-#undef QT_MOC_LITERAL
3334-
3335-static const uint qt_meta_data_IdleTimer[] = {
3336-
3337- // content:
3338- 7, // revision
3339- 0, // classname
3340- 0, 0, // classinfo
3341- 1, 14, // methods
3342- 0, 0, // properties
3343- 0, 0, // enums/sets
3344- 0, 0, // constructors
3345- 0, // flags
3346- 0, // signalCount
3347-
3348- // methods: name, argc, parameters, tag, flags
3349- 1, 0, 19, 2, 0x02,
3350-
3351- // methods: parameters
3352- QMetaType::Void,
3353-
3354- 0 // eod
3355-};
3356-
3357-void IdleTimer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
3358-{
3359- if (_c == QMetaObject::InvokeMetaMethod) {
3360- IdleTimer *_t = static_cast<IdleTimer *>(_o);
3361- switch (_id) {
3362- case 0: _t->start(); break;
3363- default: ;
3364- }
3365- }
3366- Q_UNUSED(_a);
3367-}
3368-
3369-const QMetaObject IdleTimer::staticMetaObject = {
3370- { &QObject::staticMetaObject, qt_meta_stringdata_IdleTimer.data,
3371- qt_meta_data_IdleTimer, qt_static_metacall, 0, 0}
3372-};
3373-
3374-
3375-const QMetaObject *IdleTimer::metaObject() const
3376-{
3377- return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
3378-}
3379-
3380-void *IdleTimer::qt_metacast(const char *_clname)
3381-{
3382- if (!_clname) return 0;
3383- if (!strcmp(_clname, qt_meta_stringdata_IdleTimer.stringdata))
3384- return static_cast<void*>(const_cast< IdleTimer*>(this));
3385- return QObject::qt_metacast(_clname);
3386-}
3387-
3388-int IdleTimer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
3389-{
3390- _id = QObject::qt_metacall(_c, _id, _a);
3391- if (_id < 0)
3392- return _id;
3393- if (_c == QMetaObject::InvokeMetaMethod) {
3394- if (_id < 1)
3395- qt_static_metacall(this, _c, _id, _a);
3396- _id -= 1;
3397- } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
3398- if (_id < 1)
3399- *reinterpret_cast<int*>(_a[0]) = -1;
3400- _id -= 1;
3401- }
3402- return _id;
3403-}
3404-QT_END_MOC_NAMESPACE
3405
3406=== removed directory 'qml.v0/cpp/private'
3407=== removed file 'qml.v0/cpp/private/qmetaobject_p.h'
3408--- qml.v0/cpp/private/qmetaobject_p.h 2014-08-26 19:38:51 +0000
3409+++ qml.v0/cpp/private/qmetaobject_p.h 1970-01-01 00:00:00 +0000
3410@@ -1,2 +0,0 @@
3411-#include "private/qtheader.h"
3412-#include QT_PRIVATE_HEADER(QtCore,qmetaobject_p.h)
3413
3414=== removed file 'qml.v0/cpp/private/qmetaobjectbuilder_p.h'
3415--- qml.v0/cpp/private/qmetaobjectbuilder_p.h 2014-08-26 19:38:51 +0000
3416+++ qml.v0/cpp/private/qmetaobjectbuilder_p.h 1970-01-01 00:00:00 +0000
3417@@ -1,2 +0,0 @@
3418-#include "private/qtheader.h"
3419-#include QT_PRIVATE_HEADER(QtCore,qmetaobjectbuilder_p.h)
3420
3421=== removed file 'qml.v0/cpp/private/qobject_p.h'
3422--- qml.v0/cpp/private/qobject_p.h 2014-08-26 19:38:51 +0000
3423+++ qml.v0/cpp/private/qobject_p.h 1970-01-01 00:00:00 +0000
3424@@ -1,2 +0,0 @@
3425-#include "private/qtheader.h"
3426-#include QT_PRIVATE_HEADER(QtCore,qobject_p.h)
3427
3428=== removed file 'qml.v0/cpp/private/qtheader.h'
3429--- qml.v0/cpp/private/qtheader.h 2014-08-26 19:38:51 +0000
3430+++ qml.v0/cpp/private/qtheader.h 1970-01-01 00:00:00 +0000
3431@@ -1,70 +0,0 @@
3432-#ifndef QTPRIVATE_H
3433-#define QTPRIVATE_H
3434-
3435-#include <QtCore/qglobal.h>
3436-
3437-#define QT_MAJOR_ (QT_VERSION>>16)
3438-#define QT_MINOR_ (QT_VERSION>>8&0xFF)
3439-#define QT_MICRO_ (QT_VERSION&0xFF)
3440-
3441-#if QT_MAJOR_ == 5
3442-#define QT_MAJOR 5
3443-#else
3444-#error Unupported Qt major version. Please report.
3445-#endif
3446-
3447-#if QT_MINOR_ == 0
3448-#define QT_MINOR 0
3449-#elif QT_MINOR_ == 1
3450-#define QT_MINOR 1
3451-#elif QT_MINOR_ == 2
3452-#define QT_MINOR 2
3453-#elif QT_MINOR_ == 3
3454-#define QT_MINOR 3
3455-#elif QT_MINOR_ == 4
3456-#define QT_MINOR 4
3457-#elif QT_MINOR_ == 5
3458-#define QT_MINOR 5
3459-#elif QT_MINOR_ == 6
3460-#define QT_MINOR 6
3461-#elif QT_MINOR_ == 7
3462-#define QT_MINOR 7
3463-#elif QT_MINOR_ == 8
3464-#define QT_MINOR 8
3465-#elif QT_MINOR_ == 9
3466-#define QT_MINOR 9
3467-#elif QT_MINOR_ == 10
3468-#define QT_MINOR 10
3469-#else
3470-#error Unupported Qt minor version. Please report.
3471-#endif
3472-
3473-#if QT_MICRO_ == 0
3474-#define QT_MICRO 0
3475-#elif QT_MICRO_ == 1
3476-#define QT_MICRO 1
3477-#elif QT_MICRO_ == 2
3478-#define QT_MICRO 2
3479-#elif QT_MICRO_ == 3
3480-#define QT_MICRO 3
3481-#elif QT_MICRO_ == 4
3482-#define QT_MICRO 4
3483-#elif QT_MICRO_ == 5
3484-#define QT_MICRO 5
3485-#elif QT_MICRO_ == 6
3486-#define QT_MICRO 6
3487-#elif QT_MICRO_ == 7
3488-#define QT_MICRO 7
3489-#elif QT_MICRO_ == 8
3490-#define QT_MICRO 8
3491-#elif QT_MICRO_ == 9
3492-#define QT_MICRO 9
3493-#elif QT_MICRO_ == 10
3494-#define QT_MICRO 10
3495-#else
3496-#error Unupported Qt micro version. Please report.
3497-#endif
3498-
3499-#define QT_PRIVATE_HEADER(dir,file) <dir/QT_MAJOR.QT_MINOR.QT_MICRO/dir/private/file>
3500-
3501-#endif // QTPRIVATE_H
3502
3503=== removed file 'qml.v0/cpp/update-moc.sh'
3504--- qml.v0/cpp/update-moc.sh 2014-08-26 19:38:51 +0000
3505+++ qml.v0/cpp/update-moc.sh 1970-01-01 00:00:00 +0000
3506@@ -1,19 +0,0 @@
3507-#!/bin/sh
3508-
3509-set -e
3510-cd `dirname $0`
3511-
3512-subdir=`basename $PWD`
3513-
3514-export QT_SELECT=5
3515-
3516-ALL=moc_all.cpp
3517-
3518-echo "// This file is automatically generated by cpp/update-moc.sh" > $ALL
3519-
3520-for file in `grep -l Q_''OBJECT *`; do
3521- mocfile=`echo $file | awk -F. '{print("moc_"$1".cpp")}'`
3522- mochack=`sed -n 's,^ *// MOC HACK: \(.*\),\1,p' $file`
3523- moc $file | sed "$mochack" > $mocfile
3524- echo "#include \"$subdir/$mocfile\"" >> $ALL
3525-done
3526
3527=== removed directory 'qml.v0/cpptest'
3528=== removed file 'qml.v0/cpptest/cpptest.cpp'
3529--- qml.v0/cpptest/cpptest.cpp 2014-08-26 19:38:51 +0000
3530+++ qml.v0/cpptest/cpptest.cpp 1970-01-01 00:00:00 +0000
3531@@ -1,14 +0,0 @@
3532-#include <string.h>
3533-
3534-#include "cpptest.h"
3535-#include "testtype.h"
3536-
3537-TestType_ *newTestType()
3538-{
3539- return new TestType();
3540-}
3541-
3542-int plainTestTypeN(PlainTestType_ *plain)
3543-{
3544- return static_cast<PlainTestType *>(plain)->n;
3545-}
3546
3547=== removed file 'qml.v0/cpptest/cpptest.go'
3548--- qml.v0/cpptest/cpptest.go 2014-08-26 19:38:51 +0000
3549+++ qml.v0/cpptest/cpptest.go 1970-01-01 00:00:00 +0000
3550@@ -1,30 +0,0 @@
3551-// Package cpptest is an internal test helper.
3552-package cpptest
3553-
3554-// #cgo CXXFLAGS: -std=c++0x -Wall -fno-strict-aliasing -I..
3555-// #cgo LDFLAGS: -lstdc++
3556-//
3557-// #cgo pkg-config: Qt5Core
3558-//
3559-// #include "cpptest.h"
3560-//
3561-import "C"
3562-
3563-import (
3564- "unsafe"
3565-
3566- "launchpad.net/ciborium/qml.v0"
3567-)
3568-
3569-func NewTestType(engine *qml.Engine) qml.Object {
3570- var obj qml.Object
3571- qml.RunMain(func() {
3572- addr := C.newTestType()
3573- obj = qml.CommonOf(addr, engine)
3574- })
3575- return obj
3576-}
3577-
3578-func PlainTestTypeN(obj qml.Object) int {
3579- return int(C.plainTestTypeN(unsafe.Pointer(obj.Property("plainAddr").(uintptr))))
3580-}
3581
3582=== removed file 'qml.v0/cpptest/cpptest.h'
3583--- qml.v0/cpptest/cpptest.h 2014-08-26 19:38:51 +0000
3584+++ qml.v0/cpptest/cpptest.h 1970-01-01 00:00:00 +0000
3585@@ -1,23 +0,0 @@
3586-#ifndef UONEAUTH_H
3587-#define UONEAUTH_H
3588-
3589-#include <stdint.h>
3590-#include <stddef.h>
3591-#include <stdlib.h>
3592-
3593-typedef void TestType_;
3594-typedef void PlainTestType_;
3595-
3596-#ifdef __cplusplus
3597-extern "C" {
3598-#endif
3599-
3600-TestType_ *newTestType();
3601-
3602-int plainTestTypeN(PlainTestType_ *plain);
3603-
3604-#ifdef __cplusplus
3605-}
3606-#endif
3607-
3608-#endif // UONEAUTH_H
3609
3610=== removed file 'qml.v0/cpptest/moc_testtype.cpp'
3611--- qml.v0/cpptest/moc_testtype.cpp 2014-08-26 19:38:51 +0000
3612+++ qml.v0/cpptest/moc_testtype.cpp 1970-01-01 00:00:00 +0000
3613@@ -1,202 +0,0 @@
3614-/****************************************************************************
3615-** Meta object code from reading C++ file 'testtype.h'
3616-**
3617-** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
3618-**
3619-** WARNING! All changes made in this file will be lost!
3620-*****************************************************************************/
3621-
3622-#include "testtype.h"
3623-#include <QtCore/qbytearray.h>
3624-#include <QtCore/qmetatype.h>
3625-#if !defined(Q_MOC_OUTPUT_REVISION)
3626-#error "The header file 'testtype.h' doesn't include <QObject>."
3627-#elif Q_MOC_OUTPUT_REVISION != 67
3628-#error "This file was generated using the moc from 5.2.1. It"
3629-#error "cannot be used with the include files from this version of Qt."
3630-#error "(The moc has changed too much.)"
3631-#endif
3632-
3633-QT_BEGIN_MOC_NAMESPACE
3634-struct qt_meta_stringdata_TestType_t {
3635- QByteArrayData data[10];
3636- char stringdata[119];
3637-};
3638-#define QT_MOC_LITERAL(idx, ofs, len) \
3639- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
3640- offsetof(qt_meta_stringdata_TestType_t, stringdata) + ofs \
3641- - idx * sizeof(QByteArrayData) \
3642- )
3643-static const qt_meta_stringdata_TestType_t qt_meta_stringdata_TestType = {
3644- {
3645-QT_MOC_LITERAL(0, 0, 8),
3646-QT_MOC_LITERAL(1, 9, 15),
3647-QT_MOC_LITERAL(2, 25, 0),
3648-QT_MOC_LITERAL(3, 26, 13),
3649-QT_MOC_LITERAL(4, 40, 5),
3650-QT_MOC_LITERAL(5, 46, 15),
3651-QT_MOC_LITERAL(6, 62, 15),
3652-QT_MOC_LITERAL(7, 78, 20),
3653-QT_MOC_LITERAL(8, 99, 9),
3654-QT_MOC_LITERAL(9, 109, 8)
3655- },
3656- "TestType\0plainEmittedCpy\0\0PlainTestType\0"
3657- "plain\0plainEmittedRef\0plainEmittedPtr\0"
3658- "const PlainTestType*\0emitPlain\0voidAddr\0"
3659-};
3660-#undef QT_MOC_LITERAL
3661-
3662-static const uint qt_meta_data_TestType[] = {
3663-
3664- // content:
3665- 7, // revision
3666- 0, // classname
3667- 0, 0, // classinfo
3668- 4, 14, // methods
3669- 1, 44, // properties
3670- 0, 0, // enums/sets
3671- 0, 0, // constructors
3672- 0, // flags
3673- 3, // signalCount
3674-
3675- // signals: name, argc, parameters, tag, flags
3676- 1, 1, 34, 2, 0x06,
3677- 5, 1, 37, 2, 0x06,
3678- 6, 1, 40, 2, 0x06,
3679-
3680- // methods: name, argc, parameters, tag, flags
3681- 8, 0, 43, 2, 0x02,
3682-
3683- // signals: parameters
3684- QMetaType::Void, 0x80000000 | 3, 4,
3685- QMetaType::Void, 0x80000000 | 3, 4,
3686- QMetaType::Void, 0x80000000 | 7, 4,
3687-
3688- // methods: parameters
3689- QMetaType::Void,
3690-
3691- // properties: name, type, flags
3692- 9, QMetaType::VoidStar, 0x00095001,
3693-
3694- 0 // eod
3695-};
3696-
3697-void TestType::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
3698-{
3699- if (_c == QMetaObject::InvokeMetaMethod) {
3700- TestType *_t = static_cast<TestType *>(_o);
3701- switch (_id) {
3702- case 0: _t->plainEmittedCpy((*reinterpret_cast< const PlainTestType(*)>(_a[1]))); break;
3703- case 1: _t->plainEmittedRef((*reinterpret_cast< const PlainTestType(*)>(_a[1]))); break;
3704- case 2: _t->plainEmittedPtr((*reinterpret_cast< const PlainTestType*(*)>(_a[1]))); break;
3705- case 3: _t->emitPlain(); break;
3706- default: ;
3707- }
3708- } else if (_c == QMetaObject::IndexOfMethod) {
3709- int *result = reinterpret_cast<int *>(_a[0]);
3710- void **func = reinterpret_cast<void **>(_a[1]);
3711- {
3712- typedef void (TestType::*_t)(const PlainTestType );
3713- if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestType::plainEmittedCpy)) {
3714- *result = 0;
3715- }
3716- }
3717- {
3718- typedef void (TestType::*_t)(const PlainTestType & );
3719- if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestType::plainEmittedRef)) {
3720- *result = 1;
3721- }
3722- }
3723- {
3724- typedef void (TestType::*_t)(const PlainTestType * );
3725- if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestType::plainEmittedPtr)) {
3726- *result = 2;
3727- }
3728- }
3729- }
3730-}
3731-
3732-const QMetaObject TestType::staticMetaObject = {
3733- { &QObject::staticMetaObject, qt_meta_stringdata_TestType.data,
3734- qt_meta_data_TestType, qt_static_metacall, 0, 0}
3735-};
3736-
3737-
3738-const QMetaObject *TestType::metaObject() const
3739-{
3740- return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
3741-}
3742-
3743-void *TestType::qt_metacast(const char *_clname)
3744-{
3745- if (!_clname) return 0;
3746- if (!strcmp(_clname, qt_meta_stringdata_TestType.stringdata))
3747- return static_cast<void*>(const_cast< TestType*>(this));
3748- return QObject::qt_metacast(_clname);
3749-}
3750-
3751-int TestType::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
3752-{
3753- _id = QObject::qt_metacall(_c, _id, _a);
3754- if (_id < 0)
3755- return _id;
3756- if (_c == QMetaObject::InvokeMetaMethod) {
3757- if (_id < 4)
3758- qt_static_metacall(this, _c, _id, _a);
3759- _id -= 4;
3760- } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
3761- if (_id < 4)
3762- *reinterpret_cast<int*>(_a[0]) = -1;
3763- _id -= 4;
3764- }
3765-#ifndef QT_NO_PROPERTIES
3766- else if (_c == QMetaObject::ReadProperty) {
3767- void *_v = _a[0];
3768- switch (_id) {
3769- case 0: *reinterpret_cast< void**>(_v) = getVoidAddr(); break;
3770- }
3771- _id -= 1;
3772- } else if (_c == QMetaObject::WriteProperty) {
3773- _id -= 1;
3774- } else if (_c == QMetaObject::ResetProperty) {
3775- _id -= 1;
3776- } else if (_c == QMetaObject::QueryPropertyDesignable) {
3777- _id -= 1;
3778- } else if (_c == QMetaObject::QueryPropertyScriptable) {
3779- _id -= 1;
3780- } else if (_c == QMetaObject::QueryPropertyStored) {
3781- _id -= 1;
3782- } else if (_c == QMetaObject::QueryPropertyEditable) {
3783- _id -= 1;
3784- } else if (_c == QMetaObject::QueryPropertyUser) {
3785- _id -= 1;
3786- } else if (_c == QMetaObject::RegisterPropertyMetaType) {
3787- if (_id < 1)
3788- *reinterpret_cast<int*>(_a[0]) = -1;
3789- _id -= 1;
3790- }
3791-#endif // QT_NO_PROPERTIES
3792- return _id;
3793-}
3794-
3795-// SIGNAL 0
3796-void TestType::plainEmittedCpy(const PlainTestType _t1)
3797-{
3798- void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
3799- QMetaObject::activate(this, &staticMetaObject, 0, _a);
3800-}
3801-
3802-// SIGNAL 1
3803-void TestType::plainEmittedRef(const PlainTestType & _t1)
3804-{
3805- void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
3806- QMetaObject::activate(this, &staticMetaObject, 1, _a);
3807-}
3808-
3809-// SIGNAL 2
3810-void TestType::plainEmittedPtr(const PlainTestType * _t1)
3811-{
3812- void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
3813- QMetaObject::activate(this, &staticMetaObject, 2, _a);
3814-}
3815-QT_END_MOC_NAMESPACE
3816
3817=== removed file 'qml.v0/cpptest/testtype.h'
3818--- qml.v0/cpptest/testtype.h 2014-08-26 19:38:51 +0000
3819+++ qml.v0/cpptest/testtype.h 1970-01-01 00:00:00 +0000
3820@@ -1,45 +0,0 @@
3821-#ifndef TESTTYPE_H
3822-#define TESTTYPE_H
3823-
3824-#include <QObject>
3825-
3826-class PlainTestType {
3827-
3828- public:
3829-
3830- PlainTestType(int n) : n(n) {};
3831-
3832- int n;
3833-};
3834-
3835-class TestType : public QObject
3836-{
3837- Q_OBJECT
3838-
3839- Q_PROPERTY(void *voidAddr READ getVoidAddr)
3840-
3841- void *voidAddr;
3842-
3843- public:
3844-
3845- TestType(QObject *parent = 0) : QObject(parent), voidAddr((void*)42) {};
3846-
3847- void *getVoidAddr() { return voidAddr; };
3848-
3849- Q_INVOKABLE void emitPlain() {
3850- PlainTestType plain = PlainTestType(42);
3851- emit plainEmittedCpy(plain);
3852- emit plainEmittedRef(plain);
3853- emit plainEmittedPtr(&plain);
3854- };
3855-
3856- signals:
3857-
3858- void plainEmittedCpy(const PlainTestType plain);
3859- void plainEmittedRef(const PlainTestType &plain);
3860- void plainEmittedPtr(const PlainTestType *plain);
3861-};
3862-
3863-#endif // TESTTYPE_H
3864-
3865-// vim:ts=4:sw=4:et
3866
3867=== removed file 'qml.v0/cpptest/update-moc.sh'
3868--- qml.v0/cpptest/update-moc.sh 2014-08-26 19:38:51 +0000
3869+++ qml.v0/cpptest/update-moc.sh 1970-01-01 00:00:00 +0000
3870@@ -1,12 +0,0 @@
3871-#!/bin/sh
3872-
3873-set -e
3874-cd `dirname $0`
3875-
3876-export QT_SELECT=5
3877-
3878-for file in `grep -l Q_''OBJECT *`; do
3879- mocfile=`echo $file | awk -F. '{print("moc_"$1".cpp")}'`
3880- mochack=`sed -n 's,^ *// MOC HACK: \(.*\),\1,p' $file`
3881- moc $file | sed "$mochack" > $mocfile
3882-done
3883
3884=== removed file 'qml.v0/datatype.go'
3885--- qml.v0/datatype.go 2014-08-26 19:38:51 +0000
3886+++ qml.v0/datatype.go 1970-01-01 00:00:00 +0000
3887@@ -1,527 +0,0 @@
3888-package qml
3889-
3890-// #include <stdlib.h>
3891-// #include "capi.h"
3892-import "C"
3893-
3894-import (
3895- "bytes"
3896- "fmt"
3897- "image/color"
3898- "reflect"
3899- "strings"
3900- "unicode"
3901- "unsafe"
3902-)
3903-
3904-var (
3905- intIs64 bool
3906- intDT C.DataType
3907-
3908- ptrSize = C.size_t(unsafe.Sizeof(uintptr(0)))
3909-
3910- nilPtr = unsafe.Pointer(uintptr(0))
3911- nilCharPtr = (*C.char)(nilPtr)
3912-
3913- typeString = reflect.TypeOf("")
3914- typeBool = reflect.TypeOf(false)
3915- typeInt = reflect.TypeOf(int(0))
3916- typeInt64 = reflect.TypeOf(int64(0))
3917- typeInt32 = reflect.TypeOf(int32(0))
3918- typeFloat64 = reflect.TypeOf(float64(0))
3919- typeFloat32 = reflect.TypeOf(float32(0))
3920- typeIface = reflect.TypeOf(new(interface{})).Elem()
3921- typeRGBA = reflect.TypeOf(color.RGBA{})
3922- typeObjSlice = reflect.TypeOf([]Object(nil))
3923- typeObject = reflect.TypeOf([]Object(nil)).Elem()
3924- typePainter = reflect.TypeOf(&Painter{})
3925- typeList = reflect.TypeOf(&List{})
3926- typeMap = reflect.TypeOf(&Map{})
3927- typeGenericMap = reflect.TypeOf(map[string]interface{}(nil))
3928-)
3929-
3930-func init() {
3931- var i int = 1<<31 - 1
3932- intIs64 = (i+1 > 0)
3933- if intIs64 {
3934- intDT = C.DTInt64
3935- } else {
3936- intDT = C.DTInt32
3937- }
3938-}
3939-
3940-// packDataValue packs the provided Go value into a C.DataValue for
3941-// shiping into C++ land.
3942-//
3943-// For simple types (bool, int, etc) value is converted into a
3944-// native C++ value. For anything else, including cases when value
3945-// has a type that has an underlying simple type, the Go value itself
3946-// is encapsulated into a C++ wrapper so that field access and method
3947-// calls work.
3948-//
3949-// This must be run from the main GUI thread due to the cases where
3950-// calling wrapGoValue is necessary.
3951-func packDataValue(value interface{}, dvalue *C.DataValue, engine *Engine, owner valueOwner) {
3952- datap := unsafe.Pointer(&dvalue.data)
3953- if value == nil {
3954- dvalue.dataType = C.DTInvalid
3955- return
3956- }
3957- switch value := value.(type) {
3958- case string:
3959- dvalue.dataType = C.DTString
3960- cstr, cstrlen := unsafeStringData(value)
3961- *(**C.char)(datap) = cstr
3962- dvalue.len = cstrlen
3963- case bool:
3964- dvalue.dataType = C.DTBool
3965- *(*bool)(datap) = value
3966- case int:
3967- if value > 1<<31-1 {
3968- dvalue.dataType = C.DTInt64
3969- *(*int64)(datap) = int64(value)
3970- } else {
3971- dvalue.dataType = C.DTInt32
3972- *(*int32)(datap) = int32(value)
3973- }
3974- case int64:
3975- dvalue.dataType = C.DTInt64
3976- *(*int64)(datap) = value
3977- case int32:
3978- dvalue.dataType = C.DTInt32
3979- *(*int32)(datap) = value
3980- case uint64:
3981- dvalue.dataType = C.DTUint64
3982- *(*uint64)(datap) = value
3983- case uint32:
3984- dvalue.dataType = C.DTUint32
3985- *(*uint32)(datap) = value
3986- case float64:
3987- dvalue.dataType = C.DTFloat64
3988- *(*float64)(datap) = value
3989- case float32:
3990- dvalue.dataType = C.DTFloat32
3991- *(*float32)(datap) = value
3992- case *Common:
3993- dvalue.dataType = C.DTObject
3994- *(*unsafe.Pointer)(datap) = value.addr
3995- case color.RGBA:
3996- dvalue.dataType = C.DTColor
3997- *(*uint32)(datap) = uint32(value.A)<<24 | uint32(value.R)<<16 | uint32(value.G)<<8 | uint32(value.B)
3998- default:
3999- dvalue.dataType = C.DTObject
4000- if obj, ok := value.(Object); ok {
4001- *(*unsafe.Pointer)(datap) = obj.Common().addr
4002- } else {
4003- *(*unsafe.Pointer)(datap) = wrapGoValue(engine, value, owner)
4004- }
4005- }
4006-}
4007-
4008-// TODO Handle byte slices.
4009-
4010-// unpackDataValue converts a value shipped by C++ into a native Go value.
4011-//
4012-// HEADS UP: This is considered safe to be run out of the main GUI thread.
4013-// If that changes, fix the call sites.
4014-func unpackDataValue(dvalue *C.DataValue, engine *Engine) interface{} {
4015- datap := unsafe.Pointer(&dvalue.data)
4016- switch dvalue.dataType {
4017- case C.DTString:
4018- s := C.GoStringN(*(**C.char)(datap), dvalue.len)
4019- // TODO If we move all unpackDataValue calls to the GUI thread,
4020- // can we get rid of this allocation somehow?
4021- C.free(unsafe.Pointer(*(**C.char)(datap)))
4022- return s
4023- case C.DTBool:
4024- return *(*bool)(datap)
4025- case C.DTInt64:
4026- return *(*int64)(datap)
4027- case C.DTInt32:
4028- return int(*(*int32)(datap))
4029- case C.DTUint64:
4030- return *(*uint64)(datap)
4031- case C.DTUint32:
4032- return *(*uint32)(datap)
4033- case C.DTUintptr:
4034- return *(*uintptr)(datap)
4035- case C.DTFloat64:
4036- return *(*float64)(datap)
4037- case C.DTFloat32:
4038- return *(*float32)(datap)
4039- case C.DTColor:
4040- var c uint32 = *(*uint32)(datap)
4041- return color.RGBA{byte(c >> 16), byte(c >> 8), byte(c), byte(c >> 24)}
4042- case C.DTGoAddr:
4043- return (*(**valueFold)(datap)).gvalue
4044- case C.DTInvalid:
4045- return nil
4046- case C.DTObject:
4047- // TODO Would be good to preserve identity on the Go side. See ensureEngine as well.
4048- obj := &Common{
4049- engine: engine,
4050- addr: *(*unsafe.Pointer)(datap),
4051- }
4052- if len(converters) > 0 {
4053- // TODO Embed the type name in DataValue to drop these calls.
4054- typeName := obj.TypeName()
4055- if typeName == "PlainObject" {
4056- typeName = strings.TrimRight(obj.String("plainType"), "&*")
4057- if strings.HasPrefix(typeName, "const ") {
4058- typeName = typeName[6:]
4059- }
4060- }
4061- if f, ok := converters[typeName]; ok {
4062- return f(engine, obj)
4063- }
4064- }
4065- return obj
4066- case C.DTValueList, C.DTValueMap:
4067- var dvlist []C.DataValue
4068- var dvlisth = (*reflect.SliceHeader)(unsafe.Pointer(&dvlist))
4069- dvlisth.Data = uintptr(*(*unsafe.Pointer)(datap))
4070- dvlisth.Len = int(dvalue.len)
4071- dvlisth.Cap = int(dvalue.len)
4072- result := make([]interface{}, len(dvlist))
4073- for i := range result {
4074- result[i] = unpackDataValue(&dvlist[i], engine)
4075- }
4076- C.free(*(*unsafe.Pointer)(datap))
4077- if dvalue.dataType == C.DTValueList {
4078- return &List{result}
4079- } else {
4080- return &Map{result}
4081- }
4082- }
4083- panic(fmt.Sprintf("unsupported data type: %d", dvalue.dataType))
4084-}
4085-
4086-func dataTypeOf(typ reflect.Type) C.DataType {
4087- // Compare against the specific types rather than their kind.
4088- // Custom types may have methods that must be supported.
4089- switch typ {
4090- case typeString:
4091- return C.DTString
4092- case typeBool:
4093- return C.DTBool
4094- case typeInt:
4095- return intDT
4096- case typeInt64:
4097- return C.DTInt64
4098- case typeInt32:
4099- return C.DTInt32
4100- case typeFloat32:
4101- return C.DTFloat32
4102- case typeFloat64:
4103- return C.DTFloat64
4104- case typeIface:
4105- return C.DTAny
4106- case typeRGBA:
4107- return C.DTColor
4108- case typeObjSlice:
4109- return C.DTListProperty
4110- }
4111- return C.DTObject
4112-}
4113-
4114-var typeInfoSize = C.size_t(unsafe.Sizeof(C.GoTypeInfo{}))
4115-var memberInfoSize = C.size_t(unsafe.Sizeof(C.GoMemberInfo{}))
4116-
4117-var typeInfoCache = make(map[reflect.Type]*C.GoTypeInfo)
4118-
4119-func appendLoweredName(buf []byte, name string) []byte {
4120- var last rune
4121- var lasti int
4122- for i, rune := range name {
4123- if !unicode.IsUpper(rune) {
4124- if lasti == 0 {
4125- last = unicode.ToLower(last)
4126- }
4127- buf = append(buf, string(last)...)
4128- buf = append(buf, name[i:]...)
4129- return buf
4130- }
4131- if i > 0 {
4132- buf = append(buf, string(unicode.ToLower(last))...)
4133- }
4134- lasti, last = i, rune
4135- }
4136- return append(buf, string(unicode.ToLower(last))...)
4137-}
4138-
4139-func typeInfo(v interface{}) *C.GoTypeInfo {
4140- vt := reflect.TypeOf(v)
4141- for vt.Kind() == reflect.Ptr {
4142- vt = vt.Elem()
4143- }
4144-
4145- typeInfo := typeInfoCache[vt]
4146- if typeInfo != nil {
4147- return typeInfo
4148- }
4149-
4150- typeInfo = (*C.GoTypeInfo)(C.malloc(typeInfoSize))
4151- typeInfo.typeName = C.CString(vt.Name())
4152- typeInfo.metaObject = nilPtr
4153- typeInfo.paint = (*C.GoMemberInfo)(nilPtr)
4154-
4155- var setters map[string]int
4156- var getters map[string]int
4157-
4158- // TODO Only do that if it's a struct?
4159- vtptr := reflect.PtrTo(vt)
4160-
4161- if vt.Kind() != reflect.Struct {
4162- panic(fmt.Sprintf("handling of %s (%#v) is incomplete; please report to the developers", vt, v))
4163- }
4164-
4165- numField := vt.NumField()
4166- numMethod := vtptr.NumMethod()
4167- privateFields := 0
4168- privateMethods := 0
4169-
4170- // struct { FooBar T; Baz T } => "fooBar\0baz\0"
4171- namesLen := 0
4172- for i := 0; i < numField; i++ {
4173- field := vt.Field(i)
4174- if field.PkgPath != "" {
4175- privateFields++
4176- continue
4177- }
4178- namesLen += len(field.Name) + 1
4179- }
4180- for i := 0; i < numMethod; i++ {
4181- method := vtptr.Method(i)
4182- if method.PkgPath != "" {
4183- privateMethods++
4184- continue
4185- }
4186- namesLen += len(method.Name) + 1
4187-
4188- // Track setters and getters.
4189- if len(method.Name) > 3 && method.Name[:3] == "Set" {
4190- if method.Type.NumIn() == 2 {
4191- if setters == nil {
4192- setters = make(map[string]int)
4193- }
4194- setters[method.Name[3:]] = i
4195- }
4196- } else if method.Type.NumIn() == 1 && method.Type.NumOut() == 1 {
4197- if getters == nil {
4198- getters = make(map[string]int)
4199- }
4200- getters[method.Name] = i
4201- }
4202- }
4203- names := make([]byte, 0, namesLen)
4204- for i := 0; i < numField; i++ {
4205- field := vt.Field(i)
4206- if field.PkgPath != "" {
4207- continue // not exported
4208- }
4209- names = appendLoweredName(names, field.Name)
4210- names = append(names, 0)
4211- }
4212- for i := 0; i < numMethod; i++ {
4213- method := vtptr.Method(i)
4214- if method.PkgPath != "" {
4215- continue // not exported
4216- }
4217- if _, ok := getters[method.Name]; !ok {
4218- continue
4219- }
4220- if _, ok := setters[method.Name]; !ok {
4221- delete(getters, method.Name)
4222- continue
4223- }
4224- // This is a getter method
4225- names = appendLoweredName(names, method.Name)
4226- names = append(names, 0)
4227- }
4228- for i := 0; i < numMethod; i++ {
4229- method := vtptr.Method(i)
4230- if method.PkgPath != "" {
4231- continue // not exported
4232- }
4233- if _, ok := getters[method.Name]; ok {
4234- continue // getter already handled above
4235- }
4236- names = appendLoweredName(names, method.Name)
4237- names = append(names, 0)
4238- }
4239- if len(names) != namesLen {
4240- panic("pre-allocated buffer size was wrong")
4241- }
4242- typeInfo.memberNames = C.CString(string(names))
4243-
4244- // Assemble information on members.
4245- membersLen := numField - privateFields + numMethod - privateMethods
4246- membersi := uintptr(0)
4247- mnamesi := uintptr(0)
4248- members := uintptr(C.malloc(memberInfoSize * C.size_t(membersLen)))
4249- mnames := uintptr(unsafe.Pointer(typeInfo.memberNames))
4250- for i := 0; i < numField; i++ {
4251- field := vt.Field(i)
4252- if field.PkgPath != "" {
4253- continue // not exported
4254- }
4255- memberInfo := (*C.GoMemberInfo)(unsafe.Pointer(members + uintptr(memberInfoSize)*membersi))
4256- memberInfo.memberName = (*C.char)(unsafe.Pointer(mnames + mnamesi))
4257- memberInfo.memberType = dataTypeOf(field.Type)
4258- memberInfo.reflectIndex = C.int(i)
4259- memberInfo.reflectGetIndex = -1
4260- memberInfo.reflectSetIndex = -1
4261- memberInfo.addrOffset = C.int(field.Offset)
4262- membersi += 1
4263- mnamesi += uintptr(len(field.Name)) + 1
4264- if methodIndex, ok := setters[field.Name]; ok {
4265- memberInfo.reflectSetIndex = C.int(methodIndex)
4266- }
4267- }
4268- for i := 0; i < numMethod; i++ {
4269- method := vtptr.Method(i)
4270- if method.PkgPath != "" {
4271- continue // not exported
4272- }
4273- if _, ok := getters[method.Name]; !ok {
4274- continue // not a getter
4275- }
4276- memberInfo := (*C.GoMemberInfo)(unsafe.Pointer(members + uintptr(memberInfoSize)*membersi))
4277- memberInfo.memberName = (*C.char)(unsafe.Pointer(mnames + mnamesi))
4278- memberInfo.memberType = dataTypeOf(method.Type.Out(0))
4279- memberInfo.reflectIndex = -1
4280- memberInfo.reflectGetIndex = C.int(getters[method.Name])
4281- memberInfo.reflectSetIndex = C.int(setters[method.Name])
4282- memberInfo.addrOffset = 0
4283- membersi += 1
4284- mnamesi += uintptr(len(method.Name)) + 1
4285- }
4286- for i := 0; i < numMethod; i++ {
4287- method := vtptr.Method(i)
4288- if method.PkgPath != "" {
4289- continue // not exported
4290- }
4291- if _, ok := getters[method.Name]; ok {
4292- continue // getter already handled above
4293- }
4294- memberInfo := (*C.GoMemberInfo)(unsafe.Pointer(members + uintptr(memberInfoSize)*membersi))
4295- memberInfo.memberName = (*C.char)(unsafe.Pointer(mnames + mnamesi))
4296- memberInfo.memberType = C.DTMethod
4297- memberInfo.reflectIndex = C.int(i)
4298- memberInfo.reflectGetIndex = -1
4299- memberInfo.reflectSetIndex = -1
4300- memberInfo.addrOffset = 0
4301- signature, result := methodQtSignature(method)
4302- // TODO The signature data might be embedded in the same array as the member names.
4303- memberInfo.methodSignature = C.CString(signature)
4304- memberInfo.resultSignature = C.CString(result)
4305- // TODO Sort out methods with a variable number of arguments.
4306- // It's called while bound, so drop the receiver.
4307- memberInfo.numIn = C.int(method.Type.NumIn() - 1)
4308- memberInfo.numOut = C.int(method.Type.NumOut())
4309- membersi += 1
4310- mnamesi += uintptr(len(method.Name)) + 1
4311-
4312- if method.Name == "Paint" && memberInfo.numIn == 1 && memberInfo.numOut == 0 && method.Type.In(1) == typePainter {
4313- typeInfo.paint = memberInfo
4314- }
4315- }
4316- typeInfo.members = (*C.GoMemberInfo)(unsafe.Pointer(members))
4317- typeInfo.membersLen = C.int(membersLen)
4318-
4319- typeInfo.fields = typeInfo.members
4320- typeInfo.fieldsLen = C.int(numField - privateFields + len(getters))
4321- typeInfo.methods = (*C.GoMemberInfo)(unsafe.Pointer(members + uintptr(memberInfoSize)*uintptr(typeInfo.fieldsLen)))
4322- typeInfo.methodsLen = C.int(numMethod - privateMethods - len(getters))
4323-
4324- if int(membersi) != membersLen {
4325- panic("used more space than allocated for member names")
4326- }
4327- if int(mnamesi) != namesLen {
4328- panic("allocated buffer doesn't match used space")
4329- }
4330- if typeInfo.fieldsLen+typeInfo.methodsLen != typeInfo.membersLen {
4331- panic("lengths are inconsistent")
4332- }
4333-
4334- typeInfoCache[vt] = typeInfo
4335- return typeInfo
4336-}
4337-
4338-func methodQtSignature(method reflect.Method) (signature, result string) {
4339- var buf bytes.Buffer
4340- for i, rune := range method.Name {
4341- if i == 0 {
4342- buf.WriteRune(unicode.ToLower(rune))
4343- } else {
4344- buf.WriteString(method.Name[i:])
4345- break
4346- }
4347- }
4348- buf.WriteByte('(')
4349- n := method.Type.NumIn()
4350- for i := 1; i < n; i++ {
4351- if i > 1 {
4352- buf.WriteByte(',')
4353- }
4354- buf.WriteString("QVariant")
4355- }
4356- buf.WriteByte(')')
4357- signature = buf.String()
4358-
4359- switch method.Type.NumOut() {
4360- case 0:
4361- // keep it as ""
4362- case 1:
4363- result = "QVariant"
4364- default:
4365- result = "QVariantList"
4366- }
4367- return
4368-}
4369-
4370-func hashable(value interface{}) (hashable bool) {
4371- defer func() { recover() }()
4372- return value == value
4373-}
4374-
4375-// unsafeString returns a Go string backed by C data.
4376-//
4377-// If the C data is deallocated or moved, the string will be
4378-// invalid and will crash the program if used. As such, the
4379-// resulting string must only be used inside the implementation
4380-// of the qml package and while the life time of the C data
4381-// is guaranteed.
4382-func unsafeString(data *C.char, size C.int) string {
4383- var s string
4384- sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
4385- sh.Data = uintptr(unsafe.Pointer(data))
4386- sh.Len = int(size)
4387- return s
4388-}
4389-
4390-// unsafeStringData returns a C string backed by Go data. The C
4391-// string is NOT null-terminated, so its length must be taken
4392-// into account.
4393-//
4394-// If the s Go string is garbage collected, the returned C data
4395-// will be invalid and will crash the program if used. As such,
4396-// the resulting data must only be used inside the implementation
4397-// of the qml package and while the life time of the Go string
4398-// is guaranteed.
4399-func unsafeStringData(s string) (*C.char, C.int) {
4400- return *(**C.char)(unsafe.Pointer(&s)), C.int(len(s))
4401-}
4402-
4403-// unsafeBytesData returns a C string backed by Go data. The C
4404-// string is NOT null-terminated, so its length must be taken
4405-// into account.
4406-//
4407-// If the array backing the b Go slice is garbage collected, the
4408-// returned C data will be invalid and will crash the program if
4409-// used. As such, the resulting data must only be used inside the
4410-// implementation of the qml package and while the life time of
4411-// the Go array is guaranteed.
4412-func unsafeBytesData(b []byte) (*C.char, C.int) {
4413- return *(**C.char)(unsafe.Pointer(&b)), C.int(len(b))
4414-}
4415
4416=== removed file 'qml.v0/doc.go'
4417--- qml.v0/doc.go 2014-08-26 19:38:51 +0000
4418+++ qml.v0/doc.go 1970-01-01 00:00:00 +0000
4419@@ -1,166 +0,0 @@
4420-// Package qml offers graphical QML application support for the Go language.
4421-//
4422-// Attention
4423-//
4424-// This package is in an alpha stage, and still in heavy development. APIs may
4425-// change, and things may break.
4426-//
4427-// At this time contributors and developers that are interested in tracking the
4428-// development closely are encouraged to use it. If you'd prefer a more stable
4429-// release, please hold on a bit and subscribe to the mailing list for news. It's
4430-// in a pretty good state, so it shall not take too long.
4431-//
4432-// See http://github.com/go-qml/qml for details.
4433-//
4434-//
4435-// Introduction
4436-//
4437-// The qml package enables Go programs to display and manipulate graphical content
4438-// using Qt's QML framework. QML uses a declarative language to express structure
4439-// and style, and supports JavaScript for in-place manipulation of the described
4440-// content. When using the Go qml package, such QML content can also interact with
4441-// Go values, making use of its exported fields and methods, and even explicitly
4442-// creating new instances of registered Go types.
4443-//
4444-// A simple Go application that integrates with QML may perform the following steps
4445-// for offering a graphical interface:
4446-//
4447-// * Initialize the qml package (see Init)
4448-// * Create an engine for loading and running QML content (see NewEngine)
4449-// * Make Go values and types available to QML (see Context.SetVar and RegisterType)
4450-// * Load QML content (see Engine.LoadString and Engine.LoadFile)
4451-// * Create a new window for the content (see Component.CreateWindow)
4452-// * Show the window and wait for it to be closed (see Window.Show and Window.Wait)
4453-//
4454-// Some of these topics are covered below, and may also be observed in practice
4455-// in the following examples:
4456-//
4457-// https://github.com/go-qml/qml/tree/master/examples
4458-//
4459-//
4460-// Handling QML objects in Go
4461-//
4462-// Any QML object may be manipulated by Go via the Object interface. That
4463-// interface is implemented both by dynamic QML values obtained from a running
4464-// engine, and by Go types in the qml package that represent QML values, such as
4465-// Window, Context, and Engine.
4466-//
4467-// For example, the following logic creates a window and prints its width
4468-// whenever it's made visible:
4469-//
4470-// win := component.CreateWindow(nil)
4471-// win.On("visibleChanged", func(visible bool) {
4472-// if (visible) {
4473-// fmt.Println("Width:", win.Int("width"))
4474-// }
4475-// })
4476-//
4477-// Information about the methods, properties, and signals that are available for QML
4478-// objects may be obtained in the Qt documentation. As a reference, the "visibleChanged"
4479-// signal and the "width" property used in the example above are described at:
4480-//
4481-// http://qt-project.org/doc/qt-5.0/qtgui/qwindow.html
4482-//
4483-// When in doubt about what type is being manipulated, the Object.TypeName method
4484-// provides the type name of the underlying value.
4485-//
4486-//
4487-// Publishing Go values to QML
4488-//
4489-// The simplest way of making a Go value available to QML code is setting it
4490-// as a variable of the engine's root context, as in:
4491-//
4492-// context := engine.Context()
4493-// context.SetVar("person", &Person{Name: "Ale"})
4494-//
4495-// This logic would enable the following QML code to successfully run:
4496-//
4497-// import QtQuick 2.0
4498-// Item {
4499-// Component.onCompleted: console.log("Name is", person.name)
4500-// }
4501-//
4502-//
4503-// Publishing Go types to QML
4504-//
4505-// While registering an individual Go value as described above is a quick way to get
4506-// started, it is also fairly limited. For more flexibility, a Go type may be
4507-// registered so that QML code can natively create new instances in an arbitrary
4508-// position of the structure. This may be achieved via the RegisterType function, as
4509-// the following example demonstrates:
4510-//
4511-// qml.RegisterTypes("GoExtensions", 1, 0, []qml.TypeSpec{{
4512-// Init: func(p *Person, obj qml.Object) { p.Name = "<none>" },
4513-// }})
4514-//
4515-// With this logic in place, QML code can create new instances of Person by itself:
4516-//
4517-// import QtQuick 2.0
4518-// import GoExtensions 1.0
4519-// Item{
4520-// Person {
4521-// id: person
4522-// name: "Ale"
4523-// }
4524-// Component.onCompleted: console.log("Name is", person.name)
4525-// }
4526-//
4527-//
4528-// Lowercasing of names
4529-//
4530-// Independently from the mechanism used to publish a Go value to QML code, its methods
4531-// and fields are available to QML logic as methods and properties of the
4532-// respective QML object representing it. As required by QML, though, the Go
4533-// method and field names are lowercased according to the following scheme when
4534-// being accesed from QML:
4535-//
4536-// value.Name => value.name
4537-// value.UPPERName => value.upperName
4538-// value.UPPER => value.upper
4539-//
4540-//
4541-// Setters and getters
4542-//
4543-// While QML code can directly read and write exported fields of Go values, as described
4544-// above, a Go type can also intercept writes to specific fields by declaring a setter
4545-// method according to common Go conventions. This is often useful for updating the
4546-// internal state or the visible content of a Go-defined type.
4547-//
4548-// For example:
4549-//
4550-// type Person struct {
4551-// Name string
4552-// }
4553-//
4554-// func (p *Person) SetName(name string) {
4555-// fmt.Println("Old name is", p.Name)
4556-// p.Name = name
4557-// fmt.Println("New name is", p.Name)
4558-// }
4559-//
4560-// In the example above, whenever QML code attempts to update the Person.Name field
4561-// via any means (direct assignment, object declarations, etc) the SetName method
4562-// is invoked with the provided value instead.
4563-//
4564-// A setter method may also be used in conjunction with a getter method rather
4565-// than a real type field. A method is only considered a getter in the presence
4566-// of the respective setter, and according to common Go conventions it must not
4567-// have the Get prefix.
4568-//
4569-// Inside QML logic, the getter and setter pair is seen as a single object property.
4570-//
4571-//
4572-// Painting
4573-//
4574-// Custom types implemented in Go may have displayable content by defining
4575-// a Paint method such as:
4576-//
4577-// func (p *Person) Paint(painter *qml.Painter) {
4578-// // ... OpenGL calls with the gopkg.in/qml.v0/gl package ...
4579-// }
4580-//
4581-// A simple example is available at:
4582-//
4583-// https://github.com/go-qml/qml/tree/master/examples/painting
4584-//
4585-package qml
4586
4587=== removed file 'qml.v0/log.go'
4588--- qml.v0/log.go 2014-08-26 19:38:51 +0000
4589+++ qml.v0/log.go 1970-01-01 00:00:00 +0000
4590@@ -1,157 +0,0 @@
4591-package qml
4592-
4593-// #include "capi.h"
4594-//
4595-import "C"
4596-
4597-import (
4598- "fmt"
4599- "log"
4600- "path/filepath"
4601- "strings"
4602-)
4603-
4604-// SetLogger sets the target for messages logged by the qml package,
4605-// including console.log and related calls from within qml code.
4606-//
4607-// The logger value must implement either the StdLogger interface,
4608-// which is satisfied by the standard *log.Logger type, or the QmlLogger
4609-// interface, which offers more control over the logged message.
4610-//
4611-// If no logger is provided, the qml package will send messages to the
4612-// default log package logger. This behavior may also be restored by
4613-// providing a nil logger to this function.
4614-func SetLogger(logger interface{}) {
4615- if logger == nil {
4616- logHandler = defaultLogger{}
4617- return
4618- }
4619- if qmll, ok := logger.(QmlLogger); ok {
4620- logHandler = qmll
4621- return
4622- }
4623- if stdl, ok := logger.(StdLogger); ok {
4624- logHandler = wrappedStdLogger{stdl}
4625- return
4626- }
4627- panic("unsupported logger interface")
4628-}
4629-
4630-// The QmlLogger interface may be implemented to better control how
4631-// log messages from the qml package are handled. Values that
4632-// implement either StdLogger or QmlLogger may be provided to the
4633-// SetLogger function.
4634-type QmlLogger interface {
4635- // QmlOutput is called whenever a new message is available for logging.
4636- // The message value must not be used after the method returns.
4637- QmlOutput(message LogMessage) error
4638-}
4639-
4640-// The StdLogger interface is implemented by standard *log.Logger values.
4641-// Values that implement either StdLogger or QmlLogger may be provided
4642-// to the SetLogger function.
4643-type StdLogger interface {
4644- // Output is called whenever a new message is available for logging.
4645- // See the standard log.Logger type for more details.
4646- Output(calldepth int, s string) error
4647-}
4648-
4649-// NOTE: LogMessage is an interface to avoid allocating and copying
4650-// several strings for each logged message.
4651-
4652-// LogMessage is implemented by values provided to QmlLogger.QmlOutput.
4653-type LogMessage interface {
4654- Severity() LogSeverity
4655- Text() string
4656- File() string
4657- Line() int
4658-
4659- String() string // returns "file:line: text"
4660-
4661- privateMarker()
4662-}
4663-
4664-type LogSeverity int
4665-
4666-const (
4667- LogDebug LogSeverity = iota
4668- LogWarning
4669- LogCritical
4670- LogFatal
4671-)
4672-
4673-var logHandler QmlLogger = defaultLogger{}
4674-
4675-type defaultLogger struct{}
4676-
4677-func (defaultLogger) QmlOutput(msg LogMessage) error {
4678- log.Println(msg.String())
4679- return nil
4680-}
4681-
4682-func init() {
4683- // Install the C++ log handler that diverts calls to the hook below.
4684- C.installLogHandler()
4685-}
4686-
4687-//export hookLogHandler
4688-func hookLogHandler(cmsg *C.LogMessage) {
4689- // Workarund for QTBUG-35943
4690- text := unsafeString(cmsg.text, cmsg.textLen)
4691- if strings.HasPrefix(text, `"Qt Warning: Compose file:`) {
4692- return
4693- }
4694- msg := logMessage{c: cmsg}
4695- logHandler.QmlOutput(&msg)
4696- msg.invalid = true
4697-}
4698-
4699-type wrappedStdLogger struct {
4700- StdLogger
4701-}
4702-
4703-func (l wrappedStdLogger) QmlOutput(msg LogMessage) error {
4704- return l.Output(0, msg.String())
4705-}
4706-
4707-type logMessage struct {
4708- c *C.LogMessage
4709-
4710- // invalid flags that cmsg points to unreliable memory,
4711- // since the log hook has already returned.
4712- invalid bool
4713-}
4714-
4715-func (m *logMessage) assertValid() {
4716- if m.invalid {
4717- panic("attempted to use log message outside of log hook")
4718- }
4719-}
4720-
4721-func (m *logMessage) Severity() LogSeverity {
4722- return LogSeverity(m.c.severity)
4723-}
4724-
4725-func (m *logMessage) Line() int {
4726- m.assertValid()
4727- return int(m.c.line)
4728-}
4729-
4730-func (m *logMessage) String() string {
4731- m.assertValid()
4732- file := unsafeString(m.c.file, m.c.fileLen)
4733- text := unsafeString(m.c.text, m.c.textLen)
4734- return fmt.Sprintf("%s:%d: %s", filepath.Base(file), m.c.line, text)
4735-}
4736-
4737-func (m *logMessage) File() string {
4738- m.assertValid()
4739- return C.GoStringN(m.c.file, m.c.fileLen)
4740-}
4741-
4742-func (m *logMessage) Text() string {
4743- m.assertValid()
4744- return C.GoStringN(m.c.text, m.c.line)
4745-}
4746-
4747-func (*logMessage) privateMarker() {}
4748
4749=== removed file 'qml.v0/qml.go'
4750--- qml.v0/qml.go 2014-08-26 19:38:51 +0000
4751+++ qml.v0/qml.go 1970-01-01 00:00:00 +0000
4752@@ -1,1059 +0,0 @@
4753-package qml
4754-
4755-// #include <stdlib.h>
4756-//
4757-// #include "capi.h"
4758-//
4759-import "C"
4760-
4761-import (
4762- "errors"
4763- "fmt"
4764- "image"
4765- "image/color"
4766- "io"
4767- "io/ioutil"
4768- "os"
4769- "path/filepath"
4770- "reflect"
4771- "strings"
4772- "sync"
4773- "sync/atomic"
4774- "unsafe"
4775-)
4776-
4777-// InitOptions holds options to initialize the qml package.
4778-type InitOptions struct {
4779- // Reserved for coming options.
4780-}
4781-
4782-var initialized int32
4783-
4784-// Init initializes the qml package with the provided parameters.
4785-// If the options parameter is nil, default options suitable for a
4786-// normal graphic application will be used.
4787-//
4788-// Init must be called only once, and before any other functionality
4789-// from the qml package is used.
4790-func Init(options *InitOptions) {
4791- if !atomic.CompareAndSwapInt32(&initialized, 0, 1) {
4792- panic("qml.Init called more than once")
4793- }
4794-
4795- guiLoopReady.Lock()
4796- go guiLoop()
4797- guiLoopReady.Lock()
4798-}
4799-
4800-// Engine provides an environment for instantiating QML components.
4801-type Engine struct {
4802- Common
4803- values map[interface{}]*valueFold
4804- destroyed bool
4805-
4806- imageProviders map[string]*func(providerId string, width, height int) image.Image
4807-}
4808-
4809-var engines = make(map[unsafe.Pointer]*Engine)
4810-
4811-// NewEngine returns a new QML engine.
4812-//
4813-// The Destory method must be called to finalize the engine and
4814-// release any resources used.
4815-func NewEngine() *Engine {
4816- engine := &Engine{values: make(map[interface{}]*valueFold)}
4817- RunMain(func() {
4818- engine.addr = C.newEngine(nil)
4819- engine.engine = engine
4820- engine.imageProviders = make(map[string]*func(providerId string, width, height int) image.Image)
4821- engines[engine.addr] = engine
4822- stats.enginesAlive(+1)
4823- })
4824- return engine
4825-}
4826-
4827-func (e *Engine) assertValid() {
4828- if e.destroyed {
4829- panic("engine already destroyed")
4830- }
4831-}
4832-
4833-// Destroy finalizes the engine and releases any resources used.
4834-// The engine must not be used after calling this method.
4835-//
4836-// It is safe to call Destroy more than once.
4837-func (e *Engine) Destroy() {
4838- if !e.destroyed {
4839- RunMain(func() {
4840- if !e.destroyed {
4841- e.destroyed = true
4842- C.delObjectLater(e.addr)
4843- if len(e.values) == 0 {
4844- delete(engines, e.addr)
4845- } else {
4846- // The engine reference keeps those values alive.
4847- // The last value destroyed will clear it.
4848- }
4849- stats.enginesAlive(-1)
4850- }
4851- })
4852- }
4853-}
4854-
4855-// Load loads a new component with the provided location and with the
4856-// content read from r. The location informs the resource name for
4857-// logged messages, and its path is used to locate any other resources
4858-// referenced by the QML content.
4859-//
4860-// Once a component is loaded, component instances may be created from
4861-// the resulting object via its Create and CreateWindow methods.
4862-func (e *Engine) Load(location string, r io.Reader) (Object, error) {
4863- data, err := ioutil.ReadAll(r)
4864- if err != nil {
4865- return nil, err
4866- }
4867- if colon, slash := strings.Index(location, ":"), strings.Index(location, "/"); colon == -1 || slash <= colon {
4868- if filepath.IsAbs(location) {
4869- location = "file:///" + filepath.ToSlash(location)
4870- } else {
4871- dir, err := os.Getwd()
4872- if err != nil {
4873- return nil, fmt.Errorf("cannot obtain absolute path: %v", err)
4874- }
4875- location = "file:///" + filepath.ToSlash(filepath.Join(dir, location))
4876- }
4877-
4878- }
4879-
4880- cdata, cdatalen := unsafeBytesData(data)
4881- cloc, cloclen := unsafeStringData(location)
4882- comp := &Common{engine: e}
4883- RunMain(func() {
4884- // TODO The component's parent should probably be the engine.
4885- comp.addr = C.newComponent(e.addr, nilPtr)
4886- C.componentSetData(comp.addr, cdata, cdatalen, cloc, cloclen)
4887- message := C.componentErrorString(comp.addr)
4888- if message != nilCharPtr {
4889- err = errors.New(strings.TrimRight(C.GoString(message), "\n"))
4890- C.free(unsafe.Pointer(message))
4891- }
4892- })
4893- if err != nil {
4894- return nil, err
4895- }
4896- return comp, nil
4897-}
4898-
4899-// LoadFile loads a component from the provided QML file.
4900-// Resources referenced by the QML content will be resolved relative to its path.
4901-//
4902-// Once a component is loaded, component instances may be created from
4903-// the resulting object via its Create and CreateWindow methods.
4904-func (e *Engine) LoadFile(path string) (Object, error) {
4905- // TODO Test this.
4906- f, err := os.Open(path)
4907- if err != nil {
4908- return nil, err
4909- }
4910- defer f.Close()
4911- return e.Load(path, f)
4912-}
4913-
4914-// LoadString loads a component from the provided QML string.
4915-// The location informs the resource name for logged messages, and its
4916-// path is used to locate any other resources referenced by the QML content.
4917-//
4918-// Once a component is loaded, component instances may be created from
4919-// the resulting object via its Create and CreateWindow methods.
4920-func (e *Engine) LoadString(location, qml string) (Object, error) {
4921- return e.Load(location, strings.NewReader(qml))
4922-}
4923-
4924-// Context returns the engine's root context.
4925-func (e *Engine) Context() *Context {
4926- e.assertValid()
4927- var ctx Context
4928- ctx.engine = e
4929- RunMain(func() {
4930- ctx.addr = C.engineRootContext(e.addr)
4931- })
4932- return &ctx
4933-}
4934-
4935-// TODO ObjectOf is probably still worth it, but turned out unnecessary
4936-// for GL functionality. Test it properly before introducing it.
4937-
4938-// ObjectOf returns the QML Object representation of the provided Go value
4939-// within the e engine.
4940-//func (e *Engine) ObjectOf(value interface{}) Object {
4941-// // TODO Would be good to preserve identity on the Go side. See unpackDataValue as well.
4942-// return &Common{
4943-// engine: e,
4944-// addr: wrapGoValue(e, value, cppOwner),
4945-// }
4946-//}
4947-
4948-// Painter is provided to Paint methods on Go types that have displayable content.
4949-type Painter struct {
4950- enigne *Engine
4951- obj Object
4952-}
4953-
4954-// Object returns the underlying object being painted.
4955-func (p *Painter) Object() Object {
4956- return p.obj
4957-}
4958-
4959-// AddImageProvider registers f to be called when an image is requested by QML code
4960-// with the specified provider identifier. It is a runtime error to register the same
4961-// provider identifier multiple times.
4962-//
4963-// The imgId provided to f is the requested image source, with the "image:" scheme
4964-// and provider identifier removed. For example, with an image image source of
4965-// "image://myprovider/icons/home.ext", the respective imgId would be "icons/home.ext".
4966-//
4967-// If either the width or the height parameters provided to f are zero, no specific
4968-// size for the image was requested. If non-zero, the returned image should have the
4969-// the provided size, and will be resized if the returned image has a different size.
4970-//
4971-// See the documentation for more details on image providers:
4972-//
4973-// http://qt-project.org/doc/qt-5.0/qtquick/qquickimageprovider.html
4974-//
4975-func (e *Engine) AddImageProvider(prvId string, f func(imgId string, width, height int) image.Image) {
4976- if _, ok := e.imageProviders[prvId]; ok {
4977- panic(fmt.Sprintf("engine already has an image provider with id %q", prvId))
4978- }
4979- e.imageProviders[prvId] = &f
4980- cprvId, cprvIdLen := unsafeStringData(prvId)
4981- RunMain(func() {
4982- qprvId := C.newString(cprvId, cprvIdLen)
4983- defer C.delString(qprvId)
4984- C.engineAddImageProvider(e.addr, qprvId, unsafe.Pointer(&f))
4985- })
4986-}
4987-
4988-//export hookRequestImage
4989-func hookRequestImage(imageFunc unsafe.Pointer, cid *C.char, cidLen, cwidth, cheight C.int) unsafe.Pointer {
4990- f := *(*func(imgId string, width, height int) image.Image)(imageFunc)
4991-
4992- id := unsafeString(cid, cidLen)
4993- width := int(cwidth)
4994- height := int(cheight)
4995-
4996- img := f(id, width, height)
4997-
4998- var cimage unsafe.Pointer
4999-
5000- rect := img.Bounds()
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches