1
Overview:
2
 - Records and playbacks QEvents in any dynamically-linked Qt application
3
 - Useful for testing
4
 - Useful for macros
5
 - Useful for pseudo-screencasts (in a significantly bandwidth-reduced form)
6
7
Requirements:
8
 - Qt 4.5
9
 - QScintilla
10
 - The qtscriptgenerator-generated QtScript bindings
11
12
Directories:
13
 - common: classes used in multiple places.
14
 - hooq: GUI application for day to day use - uses hooqInjector, and generates QtScript
15
 	files from the socket XML. When replaying, the QtScript scripts create the XML which
16
	is sent back to the application.
17
 - hooqbackup: CLI application for manipulating .hqt backup files
18
 - hooqcli: CLI application for testing - uses hooqInjector, and deals with the raw
19
 	XML that goes over the socket between hooqInjector and injectedHooq.
20
 - hooqInjector: library for injecting injectedHooq into another process.
21
 - injectedHooq: spy/event injection library inserted into the other process.
22
 - qscripthighlighter: verbatim copy of a QSyntaxHighlighter for QtScript taken from Qt Creator.
23
 	Used by the hooq GUI application.
24
 - uilib: UI classes that may be directly useful in other applications.
25
26
Method:
27
 - The logger/player libraries are injected into any Qt application's process
28
 - The logger receives all QEvents via QInternal::registerCallback() (sorry for QInternal)
29
 - The player posts events via QCoreApplication::postEvent()
30
31
Injection method:
32
 - Linux/OSX: gdb/gdbserver is attached to the process; then, the extra library is loaded
33
 	via dlopen(), and "startHooq()" is called.
34
 - Windows: we install injectedHooq as a Windows Message hook for the main thread for the
35
 	process; this makes Windows map the DLL into the other processes' memory. On the
36
	first windows message received in that thread, Hooq gets started; we trigger this
37
	by sending a WM_NULL message. Previously, LoadLibrary was called via
38
	CreateRemoteThread - while simpler, this approach didn't end up working, as we need
39
	our setup code to be ran from the GUI thread to setup the network socket.